feat(monitoring): add priority screenshot pipeline with screenshot_type + docs cleanup
Implement end-to-end support for typed screenshots and priority rendering in monitoring. Added - Accept and forward screenshot_type from MQTT screenshot/dashboard payloads (periodic, event_start, event_stop) - Extend screenshot upload handling to persist typed screenshots and metadata - Add dedicated priority screenshot serving endpoint with fallback behavior - Extend monitoring overview with priority screenshot fields and summary count - Add configurable PRIORITY_SCREENSHOT_TTL_SECONDS window for active priority state Fixed - Ensure screenshot cache-busting updates reliably via screenshot hash updates - Preserve normal periodic screenshot flow while introducing event_start/event_stop priority path Improved - Monitoring dashboard now displays screenshot type badges - Adaptive polling: faster refresh while priority screenshots are active - Priority screenshot presentation is surfaced immediately to operators Docs - Update README and copilot-instructions to match new screenshot_type behavior, priority endpoint, TTL config, monitoring fields, and retention model - Remove redundant/duplicate documentation blocks and improve troubleshooting section clarity
This commit is contained in:
@@ -158,14 +158,25 @@ def apply_monitoring_update(client_obj, *, event_id=None, process_name=None, pro
|
||||
def _extract_image_and_timestamp(data):
|
||||
image_value = None
|
||||
timestamp_value = None
|
||||
screenshot_type = None
|
||||
|
||||
if not isinstance(data, dict):
|
||||
return None, None
|
||||
return None, None, None
|
||||
|
||||
screenshot_obj = data.get("screenshot") if isinstance(data.get("screenshot"), dict) else None
|
||||
metadata_obj = data.get("metadata") if isinstance(data.get("metadata"), dict) else None
|
||||
screenshot_meta_obj = screenshot_obj.get("metadata") if screenshot_obj and isinstance(screenshot_obj.get("metadata"), dict) else None
|
||||
|
||||
for container in (data, screenshot_obj, metadata_obj, screenshot_meta_obj):
|
||||
if not isinstance(container, dict):
|
||||
continue
|
||||
raw_type = container.get("screenshot_type") or container.get("screenshotType")
|
||||
if raw_type is not None:
|
||||
normalized_type = str(raw_type).strip().lower()
|
||||
if normalized_type in ("periodic", "event_start", "event_stop"):
|
||||
screenshot_type = normalized_type
|
||||
break
|
||||
|
||||
for key in ("image", "data"):
|
||||
if isinstance(data.get(key), str) and data.get(key):
|
||||
image_value = data.get(key)
|
||||
@@ -183,9 +194,9 @@ def _extract_image_and_timestamp(data):
|
||||
value = container.get(key)
|
||||
if value is not None:
|
||||
timestamp_value = value
|
||||
return image_value, timestamp_value
|
||||
return image_value, timestamp_value, screenshot_type
|
||||
|
||||
return image_value, timestamp_value
|
||||
return image_value, timestamp_value, screenshot_type
|
||||
|
||||
|
||||
def handle_screenshot(uuid, payload):
|
||||
@@ -197,12 +208,14 @@ def handle_screenshot(uuid, payload):
|
||||
# Try to parse as JSON first
|
||||
try:
|
||||
data = json.loads(payload.decode())
|
||||
image_b64, timestamp_value = _extract_image_and_timestamp(data)
|
||||
image_b64, timestamp_value, screenshot_type = _extract_image_and_timestamp(data)
|
||||
if image_b64:
|
||||
# Payload is JSON with base64 image
|
||||
api_payload = {"image": image_b64}
|
||||
if timestamp_value is not None:
|
||||
api_payload["timestamp"] = timestamp_value
|
||||
if screenshot_type:
|
||||
api_payload["screenshot_type"] = screenshot_type
|
||||
headers = {"Content-Type": "application/json"}
|
||||
logging.debug(f"Forwarding base64 screenshot from {uuid} to API")
|
||||
else:
|
||||
@@ -261,12 +274,14 @@ def on_message(client, userdata, msg):
|
||||
try:
|
||||
payload_text = msg.payload.decode()
|
||||
data = json.loads(payload_text)
|
||||
image_b64, ts_value = _extract_image_and_timestamp(data)
|
||||
image_b64, ts_value, screenshot_type = _extract_image_and_timestamp(data)
|
||||
if image_b64:
|
||||
logging.debug(f"Dashboard enthält Screenshot für {uuid}; Weiterleitung an API")
|
||||
dashboard_payload = {"image": image_b64}
|
||||
if ts_value is not None:
|
||||
dashboard_payload["timestamp"] = ts_value
|
||||
if screenshot_type:
|
||||
dashboard_payload["screenshot_type"] = screenshot_type
|
||||
api_payload = json.dumps(dashboard_payload).encode("utf-8")
|
||||
handle_screenshot(uuid, api_payload)
|
||||
# Update last_alive if status present
|
||||
|
||||
Reference in New Issue
Block a user