Files
infoscreen-dev/TV_POWER_HANDOFF_SERVER.md
RobbStarkAustria 82f43f75ba docs: refactor docs structure and tighten assistant instruction policy
shrink root README into a landing page with a docs map and focused contributor guidance
add TV_POWER_RUNBOOK as the canonical TV power rollout and canary runbook
add CHANGELOG and move project history out of README-style docs
refactor src README into a developer-focused guide (architecture, runtime files, MQTT, debugging)
prune redundant older HDMI docs and keep a canonical HDMI_CEC_SETUP path
update copilot instructions to a high-signal policy format with strict anti-shadow-README design rules
align references across docs to current files, scripts, and TV power behavior
2026-04-01 10:01:58 +02:00

2.7 KiB

Server Handoff: TV Power Coordination

Purpose

Implement server-side MQTT power intent publishing so clients can keep TVs on across adjacent events and power off safely after schedules end.

Source of Truth

  • Shared full plan: TV_POWER_COORDINATION_TASKLIST.md

Scope (Server Team)

  • Scheduler-to-intent mapping
  • MQTT publishing semantics (retain, QoS, expiry)
  • Conflict handling (group vs client)
  • Observability for intent lifecycle

MQTT Contract (Server Responsibilities)

Topics

  • Primary (per-client): infoscreen/{client_id}/power/intent
  • Optional (group-level): infoscreen/groups/{group_id}/power/intent

Delivery Semantics

  • QoS: 1
  • retained: true
  • Always publish UTC timestamps (ISO 8601 with Z)

Intent Payload (v1)

{
  "schema_version": "1.0",
  "intent_id": "uuid-or-monotonic-id",
  "issued_at": "2026-03-31T12:00:00Z",
  "expires_at": "2026-03-31T12:10:00Z",
  "target": {
    "client_id": "optional-if-group-topic",
    "group_id": "optional"
  },
  "power": {
    "desired_state": "on",
    "reason": "event_window_active",
    "grace_seconds": 30
  },
  "event_window": {
    "start": "2026-03-31T12:00:00Z",
    "end": "2026-03-31T13:00:00Z"
  }
}

Required Behavior

Adjacent/Overlapping Events

  • Never publish an intermediate off intent when windows are contiguous/overlapping.
  • Maintain continuous desired_state=on coverage across adjacent windows.

Reconnect/Restart

  • On scheduler restart, republish effective retained intent.
  • On event edits/cancellations, replace retained intent with a fresh intent_id.

Conflict Policy

  • If both group and client intent exist: per-client overrides group.

Expiry Safety

  • expires_at must be set for every intent.
  • Server should avoid publishing already-expired intents.

Implementation Tasks

  1. Add scheduler mapping layer that computes effective desired_state per client timeline.
  2. Add intent publisher with retained QoS1 delivery.
  3. Generate unique intent_id for each semantic transition.
  4. Emit issued_at/expires_at and event_window consistently in UTC.
  5. Add group-vs-client precedence logic.
  6. Add logs/metrics for publish success, retained payload age, and transition count.
  7. Add integration tests for adjacent events and reconnect replay.

Acceptance Criteria

  1. Adjacent events do not create OFF gap intents.
  2. Fresh client receives retained intent after reconnect and gets correct desired state.
  3. Intent payloads are schema-valid, UTC-formatted, and include expiry.
  4. Publish logs and metrics allow intent timeline reconstruction.

Operational Notes

  • Keep intent publishing idempotent and deterministic.
  • Preserve backward compatibility while clients run in hybrid mode.