1.9 KiB
1.9 KiB
Server Handoff: TV Power Coordination
Status
Server PR-1 is implemented and merged (Phase 1).
Source of Truth
- Contract: TV_POWER_INTENT_SERVER_CONTRACT_V1.md
- Implementation: scheduler/scheduler.py and scheduler/db_utils.py
- Validation checklist: TV_POWER_PHASE_1_CANARY_VALIDATION.md
Active Phase 1 Scope
- Topic: infoscreen/groups/{group_id}/power/intent
- QoS: 1
- Retained: true
- Scope: group-level only
- Per-client intent/state topics: deferred to Phase 2
Publish Semantics (Implemented)
- Semantic transition (
desired_stateorreasonchanged): newintent_idand immediate publish - Heartbeat (no semantic change): same
intent_id, refreshedissued_atandexpires_at - Scheduler startup: immediate publish before first poll wait
- MQTT reconnect: immediate retained republish of cached intents
Payload Contract (Phase 1)
{
"schema_version": "1.0",
"intent_id": "uuid4",
"group_id": 12,
"desired_state": "on",
"reason": "active_event",
"issued_at": "2026-04-01T06:00:03.496Z",
"expires_at": "2026-04-01T06:01:33.496Z",
"poll_interval_sec": 15,
"active_event_ids": [148],
"event_window_start": "2026-04-01T06:00:00Z",
"event_window_end": "2026-04-01T07:00:00Z"
}
Expiry rule:
- expires_at = issued_at + max(3 x poll_interval_sec, 90 seconds)
Operational Notes
- Adjacent/overlapping events are merged into one active coverage window; no OFF blip at boundaries.
- Feature flag defaults are safe for rollout:
- POWER_INTENT_PUBLISH_ENABLED=false
- POWER_INTENT_HEARTBEAT_ENABLED=true
- POWER_INTENT_EXPIRY_MULTIPLIER=3
- POWER_INTENT_MIN_EXPIRY_SECONDS=90
- Keep this handoff concise and defer full details to the stable contract document.
Phase 2 (Deferred)
- Per-client override topic: infoscreen/{client_uuid}/power/intent
- Client power state topic and acknowledgments
- Listener persistence of client-level power state