Files
infoscreen/TV_POWER_COORDINATION_TASKLIST.md

7.5 KiB

TV Power Coordination Task List (Server + Client)

Goal

Prevent unintended TV power-off during adjacent events while enabling coordinated, server-driven power intent via MQTT with robust client-side fallback.

Scope

  • Server publishes explicit TV power intent and event-window context.
  • Client executes HDMI-CEC power actions with timer-safe behavior.
  • Client falls back to local schedule/end-time logic if server intent is missing or stale.
  • Existing event playback behavior remains backward compatible.

Ownership Proposal

  • Server team: Scheduler integration, power-intent publisher, reliability semantics.
  • Client team: MQTT handler, state machine, CEC execution, fallback and observability.

Server PR-1 Pointer

  • For the strict, agreed server-first implementation path, use:
    • TV_POWER_SERVER_PR1_IMPLEMENTATION_CHECKLIST.md
  • Treat that checklist as the execution source of truth for Phase 1.

1. MQTT Contract (Shared Spec)

Phase-1 scope note:

  • Group-level power intent is the only active server contract in Phase 1.
  • Per-client power intent and client power state topics are deferred to Phase 2.

1.1 Topics

  • Command/intent topic (retained):
    • infoscreen/groups/{group_id}/power/intent

Phase-2 (deferred):

  • Optional per-client command/intent topic (retained):
    • infoscreen/{client_id}/power/intent
  • Client state/ack topic:
    • infoscreen/{client_id}/power/state

1.2 QoS and retain

  • intent topics: QoS 1, retained=true
  • state topic: QoS 0 or 1 (recommend QoS 0 initially), retained=false (Phase 2)

1.3 Intent payload schema (v1)

{
  "schema_version": "1.0",
  "intent_id": "uuid-or-monotonic-id",
  "group_id": 12,
  "desired_state": "on",
  "reason": "active_event",
  "issued_at": "2026-03-31T12:00:00Z",
  "expires_at": "2026-03-31T12:01:30Z",
  "poll_interval_sec": 15,
  "event_window_start": "2026-03-31T12:00:00Z",
  "event_window_end": "2026-03-31T13:00:00Z",
  "source": "scheduler"
}

1.4 State payload schema (client -> server)

Phase-2 (deferred).

{
  "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"
  }
}

1.5 Idempotency and ordering rules

  • Client applies only newest valid intent by issued_at then intent_id tie-break.
  • Duplicate intent_id must be ignored after first successful apply.
  • Expired intents must not trigger new actions.
  • Retained intent must be immediately usable after client reconnect.

1.6 Safety rules

  • desired_state=on cancels any pending delayed-off timer before action.
  • desired_state=off may schedule delayed-off, never immediate off during an active event window.
  • If payload is malformed, client logs and ignores it.

2. Server Team Task List

2.1 Contract + scheduler mapping

  • Finalize field names and UTC timestamp format with client team.
  • Define when scheduler emits on/off intents for adjacent/overlapping events.
  • Ensure contiguous events produce uninterrupted desired_state=on coverage.

2.2 Publisher implementation

  • Add publisher for infoscreen/groups/{group_id}/power/intent.
  • Support retained messages and QoS 1.
  • Include expires_at based on scheduler poll interval (max(3 x poll, 90s)).
  • Emit new intent_id only for semantic state transitions.

2.3 Reconnect and replay behavior

  • On scheduler restart, republish current effective intent as retained.
  • On event edits/cancellations, publish replacement retained intent.

2.4 Conflict policy

  • Phase 1: not applicable (group-only intent).
  • Phase 2: define precedence when both group and per-client intents exist.
  • Recommended for Phase 2: per-client overrides group intent.

2.5 Monitoring and diagnostics

  • Record publish attempts, broker ack results, and active retained payload.
  • Add operational dashboard panels for intent age and last transition.

2.6 Server acceptance criteria

  • Adjacent event windows do not produce off intent between events.
  • Reconnect test: fresh client receives retained intent and powers correctly.
  • Expired intent is never acted on by a conforming client.

3. Client Team Task List

3.1 MQTT subscription + parsing

  • Phase 1: Subscribe to infoscreen/groups/{group_id}/power/intent.
  • Phase 2 (optional): Subscribe to infoscreen/{client_id}/power/intent for per-device overrides.
  • Parse schema_version=1.0 payload with strict validation.

3.2 Power state controller integration

  • Add power-intent handler in display manager path that owns HDMI-CEC decisions.
  • On desired_state=on:
    • cancel delayed-off timer
    • call CEC on only if needed
  • On desired_state=off:
    • schedule delayed off using configured grace_seconds (or local default)
    • re-check active event before executing off

3.3 Fallback behavior (critical)

  • If MQTT unreachable, intent missing, invalid, or expired:
    • fall back to existing local event-time logic
    • use event end as off trigger with existing delayed-off safety
  • If local logic sees active event, enforce cancel of pending off timer.

3.4 Adjacent-event race hardening

  • Guarantee pending off timer is canceled on any newly active event.
  • Ensure event switch path never requests off while next event is active.
  • Add explicit logging for timer create/cancel/fire with reason and event_id.

3.5 State publishing

  • Publish apply results to infoscreen/{client_id}/power/state.
  • Include source=mqtt_intent or local_fallback.
  • Include last intent_id and result details for troubleshooting.

3.6 Config flags

  • Add feature toggle:
    • POWER_CONTROL_MODE=local|mqtt|hybrid (recommend default: hybrid)
  • hybrid behavior:
    • prefer valid mqtt intent
    • automatically fall back to local logic

3.7 Client acceptance criteria

  • Adjacent events: no unintended off between two active windows.
  • Broker outage during event: TV remains on via local fallback.
  • Broker recovery: retained intent reconciles state without oscillation.
  • Duplicate/old intents do not cause repeated CEC toggles.

4. Integration Test Matrix (Joint)

4.1 Happy paths

  • Single event start -> on intent -> TV on.
  • Event end -> off intent -> delayed off -> TV off.
  • Adjacent events (end==start or small gap) -> uninterrupted TV on.

4.2 Failure paths

  • Broker down before event start.
  • Broker down during active event.
  • Malformed retained intent at reconnect.
  • Delayed off armed, then new event starts before timer fires.

4.3 Consistency checks

  • Client state topic reflects actual applied source and result.
  • Logs include intent_id correlation across server and client.

5. Rollout Plan

Phase 1: Contract and feature flags

  • Freeze schema and topic naming for group-only intent.
  • Ship client support behind POWER_CONTROL_MODE=hybrid.

Phase 2: Server publisher rollout

  • Enable publishing for test group only.
  • Verify retained and reconnect behavior.

Phase 3: Production enablement

  • Enable hybrid mode fleet-wide.
  • Observe for 1 week: off-between-adjacent-events incidents must be zero.

Phase 4: Optional tightening

  • If metrics are stable, evaluate mqtt-first policy while retaining local safety fallback.

6. Definition of Done

  • Shared MQTT contract approved by both teams.
  • Server and client implementations merged with tests.
  • Adjacent-event regression test added and passing.
  • Operational runbook updated (topics, payloads, fallback behavior, troubleshooting).
  • Production monitoring confirms no unintended mid-schedule TV power-off.