Implement Phase 4 integrations and display telemetry
Add MQTT playback control, durable Home Assistant incident notifications, and display heartbeat telemetry on top of the verified Phase 3B playback authority. No playback logic is duplicated: every MQTT command and every observed condition goes through the existing playback service, and all integration work happens after the authoritative SQLite commit. MQTT (server/src/mqtt) subscribes the exact required command topics under a configurable prefix that defaults to announcements. Durable commands use QoS 1; next and previous stay at QoS 0 because they are not idempotent and carry no command ID. Retained authoritative state is published only on the separate availability, mode/state, and playback/state topics, never onto a command topic, and only after a mutation commits. A registered last will reports an ungraceful disappearance, a clean shutdown retracts it, and a broker outage degrades status while playback, HTTP, and the display protocol continue untouched. Notifications (server/src/notifications) use the Phase 1 incident and outbox tables. A failing condition opens one incident and queues exactly one notification; continued failure only updates its observation time; recovery queues exactly one recovery; a later failure is a new episode. Delivery retries on a documented capped schedule with a stable notification ID, survives restart, and never blocks playback. With no webhook URL configured, incidents are still recorded but no delivery work is queued. Conditions come from storage health transitions, committed playback state, display heartbeat staleness, and newly failed uploads. Displays (server/src/displays) ingest validated, bounded display:heartbeat telemetry keyed by persistent client ID rather than socket ID. Telemetry is read-only and never touches playback or playlist revisions. Offline is decided by heartbeat staleness, not by a closed socket, and a startup grace period keeps an API restart from manufacturing offline alerts. Adds GET /api/displays and meaningful-change display:status events. Health and status now report redacted storage, MQTT, notification, playback, and display state. External integrations degrade status and never affect readiness, so no integration outage can cause a restart loop. No MQTT password, S3 credential, webhook URL, or webhook secret is exposed. Uses the existing Phase 1 schema unchanged; no migration was required. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
+16
-1
@@ -38,9 +38,24 @@ UPLOAD_MAX_FILES=20
|
||||
IMAGE_MAX_INPUT_PIXELS=40000000
|
||||
# UPLOAD_TEMP_DIRECTORY=/tmp/announcements-uploads
|
||||
|
||||
# Optional integrations. Leave blank to disable them during Phase 2.
|
||||
# Optional integrations. Leave MQTT_URL blank to disable the MQTT integration
|
||||
# and HA_WEBHOOK_URL blank to disable outgoing notifications entirely.
|
||||
MQTT_URL=
|
||||
MQTT_USERNAME=
|
||||
MQTT_PASSWORD=
|
||||
# With the default prefix the command topics are announcements/mode,
|
||||
# announcements/next, announcements/previous, announcements/pause,
|
||||
# announcements/resume, announcements/reload, and announcements/static.
|
||||
MQTT_TOPIC_PREFIX=announcements
|
||||
MQTT_RECONNECT_PERIOD_MS=5000
|
||||
MQTT_CONNECT_TIMEOUT_MS=10000
|
||||
|
||||
# Outgoing Home Assistant webhook. The URL is a secret: it is never returned by
|
||||
# any API response or status document.
|
||||
HA_WEBHOOK_URL=
|
||||
HA_WEBHOOK_SECRET=
|
||||
HA_WEBHOOK_TIMEOUT_MS=10000
|
||||
|
||||
# A display is reported offline after this long without a valid heartbeat.
|
||||
# The display client is expected to send one every 10-15 seconds.
|
||||
DISPLAY_OFFLINE_THRESHOLD_MS=45000
|
||||
|
||||
Reference in New Issue
Block a user