feat(mqtt): finalize dashboard screenshot payload v2 and trigger flow

- switch dashboard payload to grouped schema v2.0 in simclient
- support immediate event-triggered screenshot sends via meta.json signaling
- update README and copilot instructions to document v2 payload and trigger behavior
- update migration checklist to reflect completed client/server rollout
This commit is contained in:
RobbStarkAustria
2026-03-30 17:53:58 +02:00
parent 77db2bc565
commit 25cf4e3322
4 changed files with 85 additions and 70 deletions

View File

@@ -698,19 +698,6 @@ def _build_dashboard_payload(client_id: str, screenshot_info: dict, health: dict
}
payload = {
# Legacy fields kept during migration so existing server parsing remains intact.
"timestamp": published_at,
"client_id": client_id,
"status": "alive",
"screenshot_type": capture_type,
"screenshot": screenshot_info,
"screenshot_age_s": screenshot_age_s,
"system_info": {
"hostname": socket.gethostname(),
"ip": get_ip(),
"uptime": time.time() # Could be replaced with actual uptime
},
# New grouped schema (v2-compat)
"message": {
"client_id": client_id,
"status": "alive",
@@ -727,7 +714,7 @@ def _build_dashboard_payload(client_id: str, screenshot_info: dict, health: dict
"process_health": process_health_payload,
},
"metadata": {
"schema_version": "2.0-compat",
"schema_version": "2.0",
"producer": "simclient",
"published_at": published_at,
"capture": capture_meta,
@@ -739,9 +726,6 @@ def _build_dashboard_payload(client_id: str, screenshot_info: dict, health: dict
},
}
if process_health_payload:
payload["process_health"] = process_health_payload
return payload
@@ -766,10 +750,14 @@ def send_screenshot_heartbeat(client, client_id, capture_type: str = "periodic",
payload = json.dumps(heartbeat_data)
res = client.publish(dashboard_topic, payload, qos=0)
if res.rc == mqtt.MQTT_ERR_SUCCESS:
age_str = f", age={heartbeat_data['metadata']['capture']['age_s']}s" if heartbeat_data['metadata']['capture']['age_s'] is not None else ""
if screenshot_info:
logging.info(f"Dashboard heartbeat sent with screenshot: {screenshot_info['filename']} ({screenshot_info['size']} bytes)")
logging.info(
f"Dashboard published: schema=2.0 type={capture_type}"
f" screenshot={screenshot_info['filename']} ({screenshot_info['size']} bytes){age_str}"
)
else:
logging.info("Dashboard heartbeat sent (no screenshot available)")
logging.info(f"Dashboard published: schema=2.0 type={capture_type} (no screenshot)")
elif res.rc == mqtt.MQTT_ERR_NO_CONN:
logging.warning("Dashboard heartbeat publish returned NO_CONN; will retry on next interval")
else: