# Client Handoff: TV Power Coordination ## Purpose Implement robust client-side TV power control that applies server MQTT intents when valid and falls back to local event timing when server/broker data is missing or stale. ## Source of Truth - Shared full plan: TV_POWER_COORDINATION_TASKLIST.md ## Scope (Client Team) - Intent subscription/validation - CEC state transitions and timer cancellation safety - Hybrid fallback using local event windows - Power state acknowledgment publishing ## MQTT Contract (Client Responsibilities) ### Subscribe - infoscreen/{client_id}/power/intent - Optional: infoscreen/groups/{group_id}/power/intent ### Publish state - infoscreen/{client_id}/power/state ### State Payload (v1) ```json { "schema_version": "1.0", "intent_id": "last-applied-intent-id", "client_id": "...", "reported_at": "2026-03-31T12:00:01Z", "power": { "applied_state": "on", "source": "mqtt_intent|local_fallback", "result": "ok|skipped|error", "detail": "free text" } } ``` ## Required Runtime Rules ### Intent Validation and Ordering - Accept only schema_version=1.0 (or explicitly version-gated supported set). - Ignore malformed payloads. - Ignore expired intents (expires_at in past). - Apply only newest valid intent by issued_at, intent_id tie-break. - Deduplicate already-applied intent_id. ### Power Action Safety - desired_state=on: - cancel pending delayed-off timer immediately - turn on via CEC only if needed - desired_state=off: - schedule delayed off (grace_seconds or local default) - re-check active event before executing actual off ### Fallback (Critical) - If MQTT unavailable, intent missing, invalid, or stale: - use existing local event start/end logic - use event end as off trigger plus delayed-off safety - Any active event must cancel pending off timers. ## Configuration - Add POWER_CONTROL_MODE with values: - local - mqtt - hybrid (recommended default) ### Hybrid Mode - Prefer valid MQTT intent. - Automatically fall back to local schedule logic when intent channel is not trustworthy. ## Implementation Tasks 1. Add intent topic handlers and schema validation. 2. Integrate intent application into display power control path. 3. Add timer race hardening for adjacent event transitions. 4. Add fallback decision branch for stale/missing intents. 5. Add power state publisher with intent_id/source/result. 6. Add logs for timer arm/cancel/fire with reason and event_id. 7. Add tests for adjacent events, broker outage, reconnect, duplicate intent. ## Acceptance Criteria 1. No unintended TV off between adjacent events. 2. Broker outage during active event does not power off TV prematurely. 3. Reconnect with retained intent reconciles state without oscillation. 4. Duplicate/old intents do not trigger repeated CEC toggles. 5. State messages clearly show mqtt_intent vs local_fallback source. ## Target Integration Points - Main runtime orchestration: src/display_manager.py - MQTT plumbing and topic handlers: src/simclient.py ## Operational Notes - Keep fallback logic enabled even after MQTT rollout. - Ensure all new timestamps are UTC ISO format.