Files
infoscreen-dev/README.md
RobbStarkAustria 0cd0d95612 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
2026-04-05 08:36:50 +02:00

8.6 KiB

Infoscreen Client

Digital signage client for Raspberry Pi that displays presentations, videos, and web content in kiosk mode. It is managed centrally via MQTT and includes HDMI-CEC TV control, screenshot-based dashboard monitoring, and process health reporting.

Dashboard screenshots can contain visible on-screen content. Keep that in mind when enabling or documenting remote monitoring.

Key Features

  • Server-side PPTX to PDF rendering; client displays PDFs with Impressive.
  • Presentation auto-advance, loop mode, and progress indicators.
  • Video playback with python-vlc when available and external VLC fallback.
  • Web and WebUntis display in kiosk mode.
  • HDMI-CEC TV power control with local fallback and MQTT-coordinated power intent.
  • MQTT discovery, heartbeat, group assignment, and event delivery.
  • Screenshot dashboard with Wayland/X11 capture tool fallbacks.
  • Process health bridge between display_manager.py and simclient.py.

Quick Start

1. Install Dependencies

cd ~/
git clone <repository-url> infoscreen-dev
cd infoscreen-dev

sudo apt-get update
sudo apt-get install -y \
    python3 python3-pip python3-venv \
    impressive \
    chromium-browser vlc \
    cec-utils \
    scrot imagemagick

# For Wayland systems:
# sudo apt-get install grim gnome-screenshot

python3 -m venv venv
source venv/bin/activate
pip install -r src/requirements.txt

2. Configure .env

Copy .env.template to .env and set at least:

ENV=production
DEBUG_MODE=0
LOG_LEVEL=INFO

MQTT_BROKER=192.168.1.100
MQTT_PORT=1883
MQTT_USER=<broker-username>
MQTT_PASSWORD_BROKER=<broker-password>
MQTT_USERNAME=infoscreen-client-<client-uuid-prefix>
MQTT_PASSWORD=<per-device-random-password>
MQTT_TLS_ENABLED=0

HEARTBEAT_INTERVAL=60
SCREENSHOT_INTERVAL=180
SCREENSHOT_CAPTURE_INTERVAL=180
DISPLAY_CHECK_INTERVAL=15

FILE_SERVER_HOST=
FILE_SERVER_PORT=8000
FILE_SERVER_SCHEME=http

CEC_ENABLED=true
CEC_DEVICE=0
CEC_TURN_OFF_DELAY=30
CEC_POWER_ON_WAIT=5
CEC_POWER_OFF_WAIT=5

POWER_CONTROL_MODE=local

COMMAND_HELPER_PATH=/usr/local/bin/infoscreen-cmd-helper.sh
COMMAND_EXEC_TIMEOUT_SEC=15
COMMAND_DEDUPE_TTL_HOURS=24
COMMAND_DEDUPE_MAX_ENTRIES=5000
COMMAND_MOCK_REBOOT_IMMEDIATE_COMPLETE=0

MQTT auth/TLS notes:

  • MQTT_USER / MQTT_PASSWORD_BROKER are the broker credentials used at connection time.
  • MQTT_USERNAME / MQTT_PASSWORD are legacy per-device identity fields kept for fallback and identity purposes.
  • Store real broker credentials only in the local /.env, which is gitignored.
  • When TLS is enabled, also set MQTT_TLS_CA_CERT, and if client certificates are used, MQTT_TLS_CERT and MQTT_TLS_KEY.
  • Keep the local /.env readable only by the service user and admins, for example mode 600.

Mode summary:

  • POWER_CONTROL_MODE=local: local event-time CEC only.
  • POWER_CONTROL_MODE=hybrid: prefer fresh MQTT intent, fallback to local timing.
  • POWER_CONTROL_MODE=mqtt: MQTT intent authoritative, with safe fallback behavior.

3. Start Services

The preferred method on deployed devices is systemd:

sudo systemctl start infoscreen-simclient infoscreen-display
sudo systemctl status infoscreen-simclient infoscreen-display
sudo journalctl -u infoscreen-simclient -u infoscreen-display -f

For first-time setup, run src/pi-setup.sh to install and enable the units. See src/README.md for the systemd setup steps.

For local development without systemd:

# Terminal 1
./scripts/start-simclient.sh

# Terminal 2
./scripts/start-display-manager.sh

Runtime Model

The client runs as two cooperating processes:

  • src/simclient.py: MQTT communication, discovery, heartbeats, event ingestion, dashboard publishing, power intent intake.
  • src/display_manager.py: display orchestration, HDMI-CEC, screenshots, local runtime health state.

Important runtime files:

  • src/current_event.json: active event from scheduler.
  • src/current_process_health.json: process health bridge for dashboard and monitoring.
  • src/power_intent_state.json: latest validated MQTT power intent.
  • src/power_state.json: last applied power action telemetry.
  • src/screenshots/: shared screenshot directory.

Content Types

Presentations

Presentations are rendered server-side to PDF and displayed with Impressive. Auto-advance, loop, page progress, and auto-progress are supported.

See IMPRESSIVE_INTEGRATION.md for full behavior, event examples, and troubleshooting.

Videos

Video events support:

  • url
  • autoplay
  • loop
  • volume

The Display Manager prefers python-vlc; if unavailable it falls back to the external VLC binary.

Web Pages

Web and WebUntis events are displayed in Chromium kiosk mode.

TV Power Intent

Phase 1 TV power coordination uses the group topic:

  • infoscreen/groups/{group_id}/power/intent

Key references:

Testing

Use the helper scripts in scripts/ for focused tests:

  • ./scripts/test-display-manager.sh: event and process testing.
  • ./scripts/test-impressive.sh: single-play presentation.
  • ./scripts/test-impressive-loop.sh: looping presentation.
  • ./scripts/test-mqtt.sh: MQTT broker connectivity.
  • ./scripts/test-reboot-command.sh: end-to-end reboot/shutdown command lifecycle canary (accepted -> execution_started -> completed/failed).
  • ./scripts/test-screenshot.sh: screenshot capture.
  • ./scripts/test-hdmi-cec.sh: HDMI-CEC diagnostics and runtime state inspection.
  • ./scripts/test-power-intent.sh: MQTT power intent publishing, rejection tests, and telemetry checks.

Troubleshooting

Use the specialist docs instead of treating this file as the full troubleshooting manual:

Quick checks:

  • Follow logs: tail -f logs/display_manager.log src/simclient.log
  • Inspect screenshots: ls -lh src/screenshots/
  • Inspect power state: cat src/power_intent_state.json and cat src/power_state.json
  • Restart services (systemd): sudo systemctl restart infoscreen-simclient infoscreen-display
  • Restart services (dev): ./scripts/restart-all.sh

Deployment

For production you typically run both simclient.py and display_manager.py via systemd or Docker.

If running directly on the host, ensure:

  • the display session is available (DISPLAY / XAUTHORITY for X11),
  • the screenshot tools for your session type are installed,
  • ENV=production is set when you want HDMI-CEC active.

Documentation Map

Operator / Deployment

Feature-Specific

Development / Internal

Contributing

Before changing runtime behavior:

  • test with the relevant helper scripts,
  • verify logs stay clean,
  • update the specialist doc for the feature you changed.

When editing AI assistant guidance files:

  • keep .github/copilot-instructions.md policy-focused,
  • follow its "Instruction File Design Rules" section,
  • avoid turning it into a shadow README.

Recent project history is tracked in CHANGELOG.md.

License

[Add your license here]