feat: remote commands, systemd units, process observability, broker auth split
- Command intake (reboot/shutdown) on infoscreen/{uuid}/commands with ack lifecycle
- MQTT_USER/MQTT_PASSWORD_BROKER split from identity vars; configure_mqtt_security() updated
- infoscreen-simclient.service: Type=notify, WatchdogSec=60, Restart=on-failure
- infoscreen-notify-failure@.service + script: retained MQTT alert when systemd gives up (Gap 3)
- _sd_notify() watchdog keepalive in simclient main loop (Gap 1)
- broker_connection block in health payload: reconnect_count, last_disconnect_at (Gap 2)
- COMMAND_MOCK_REBOOT_IMMEDIATE_COMPLETE canary flag with safety guard
- SERVER_TEAM_ACTIONS.md: server-side integration action items
- Docs: README, CHANGELOG, src/README, copilot-instructions updated
- 43 tests passing
This commit is contained in:
@@ -22,23 +22,52 @@ Primary runtime flow:
|
||||
## Key Files
|
||||
|
||||
- `display_manager.py`: display lifecycle, HDMI-CEC, screenshots, local fallback logic.
|
||||
- `simclient.py`: MQTT callbacks, event persistence, dashboard publishing, power-intent validation.
|
||||
- `simclient.py`: MQTT callbacks, event persistence, dashboard publishing, power-intent validation, command intake.
|
||||
- `current_event.json`: active event state consumed by the display manager.
|
||||
- `current_process_health.json`: local health bridge for monitoring.
|
||||
- `power_intent_state.json`: latest validated power intent from MQTT.
|
||||
- `power_state.json`: latest applied power action telemetry.
|
||||
- `screenshots/meta.json`: screenshot metadata used by the dashboard path.
|
||||
- `../scripts/start-simclient.sh`: launcher for `simclient.py` (used by the systemd unit).
|
||||
- `../scripts/start-display-manager.sh`: launcher for `display_manager.py`.
|
||||
- `../scripts/infoscreen-simclient.service`: systemd unit for `simclient.py`.
|
||||
- `../scripts/infoscreen-display.service`: systemd unit for `display_manager.py`.
|
||||
- `../scripts/infoscreen-notify-failure@.service`: systemd template unit; fires on `OnFailure=`.
|
||||
- `../scripts/infoscreen-notify-failure.sh`: publishes `service_failed` MQTT alert when a unit gives up.
|
||||
|
||||
## Developer Workflow
|
||||
|
||||
Typical local workflow:
|
||||
On deployed devices, both processes are managed by systemd:
|
||||
|
||||
```bash
|
||||
# Start / stop / restart
|
||||
sudo systemctl start infoscreen-simclient infoscreen-display
|
||||
sudo systemctl restart infoscreen-simclient infoscreen-display
|
||||
|
||||
# Follow logs
|
||||
journalctl -u infoscreen-simclient -u infoscreen-display -f
|
||||
```
|
||||
|
||||
First-time systemd setup:
|
||||
|
||||
```bash
|
||||
sudo cp scripts/infoscreen-simclient.service /etc/systemd/system/
|
||||
sudo cp scripts/infoscreen-display.service /etc/systemd/system/
|
||||
sudo cp scripts/infoscreen-notify-failure@.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable infoscreen-simclient infoscreen-display
|
||||
```
|
||||
|
||||
Or run `src/pi-setup.sh` which includes the above as step 14.
|
||||
|
||||
For local development without systemd:
|
||||
|
||||
```bash
|
||||
cd ~/infoscreen-dev
|
||||
source venv/bin/activate
|
||||
|
||||
# Terminal 1
|
||||
./scripts/start-dev.sh
|
||||
./scripts/start-simclient.sh
|
||||
|
||||
# Terminal 2
|
||||
./scripts/start-display-manager.sh
|
||||
@@ -51,6 +80,7 @@ Useful helpers:
|
||||
- `./scripts/test-mqtt.sh`
|
||||
- `./scripts/test-screenshot.sh`
|
||||
- `./scripts/test-power-intent.sh`
|
||||
- `./scripts/test-progress-bars.sh`
|
||||
|
||||
## MQTT Topics
|
||||
|
||||
@@ -59,8 +89,11 @@ Useful helpers:
|
||||
- `infoscreen/discovery`
|
||||
- `infoscreen/{client_id}/heartbeat`
|
||||
- `infoscreen/{client_id}/dashboard`
|
||||
- `infoscreen/{client_id}/health`
|
||||
- `infoscreen/{client_id}/health` — includes `broker_connection` block with `reconnect_count`, `last_disconnect_at`
|
||||
- `infoscreen/{client_id}/power/state`
|
||||
- `infoscreen/{client_id}/commands/ack` — command acknowledgement (states: `accepted`, `rejected`, `execution_started`, `completed`, `failed`)
|
||||
- `infoscreen/{client_id}/command/ack` — legacy ack topic (also published for compatibility)
|
||||
- `infoscreen/{client_id}/service_failed` — retained alert published by `infoscreen-notify-failure.sh` when systemd gives up restarting a unit
|
||||
|
||||
### Server → Client
|
||||
|
||||
@@ -68,6 +101,7 @@ Useful helpers:
|
||||
- `infoscreen/{client_id}/group_id`
|
||||
- `infoscreen/events/{group_id}`
|
||||
- `infoscreen/groups/{group_id}/power/intent`
|
||||
- `infoscreen/{client_id}/commands` — remote command intake (`reboot`, `shutdown`)
|
||||
|
||||
## Event and Display Notes
|
||||
|
||||
@@ -118,6 +152,8 @@ cat ~/infoscreen-dev/src/screenshots/meta.json
|
||||
|
||||
- `ENV=development` disables HDMI-CEC in the display manager.
|
||||
- `POWER_CONTROL_MODE` controls local vs hybrid vs mqtt power behavior.
|
||||
- `COMMAND_HELPER_PATH` points to the shell script that executes privileged commands (reboot/shutdown). Use `mock-command-helper.sh` for local testing.
|
||||
- `COMMAND_MOCK_REBOOT_IMMEDIATE_COMPLETE=1` makes a mock reboot complete immediately instead of waiting for process restart. Only works when the helper basename is `mock-command-helper.sh`.
|
||||
- File download host rewriting is handled in `simclient.py` using `FILE_SERVER_*` settings.
|
||||
|
||||
## Related Documents
|
||||
|
||||
Reference in New Issue
Block a user