- POST /config/schedule and /config/dim-schedule accept a disabled per-day
schedule with every day off (config.template.json's own shape); a day
that is off keeps its posted times.
- POST /config/main sets restart_required from what the save changed:
brightness, mode durations and plugin sections are applied live.
- /health is degraded (display_loop: stopped) when the service is inactive,
the socket does not answer and there is no live heartbeat.
- /display/current-status no longer serves a stopped display's cached state
when the socket and heartbeat both say it is gone (display_gone).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds state.get / state.subscribe to the display's control socket (StateHub in src/ipc/server.py). The web interface holds one subscription per process (web_interface/display_state.py) and reads current-status, on-demand status, plugin runtime and /health's display_loop from it, falling back to the cache keys and heartbeat file. While the socket serves readers, display_current_state and plugin_runtime_snapshot are written less often (about 1.5 instead of 5 cache writes a minute for 15 s screens).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>