Files
infoscreen/README.md
Olaf 03e3c11e90 feat: crash recovery, service_failed monitoring, broker health fields, command expiry sweep
- Add GET /api/clients/crashed endpoint (process_status=crashed or stale heartbeat)
- Add restart_app command action with same lifecycle + lockout as reboot_host
- Scheduler: crash auto-recovery loop (CRASH_RECOVERY_ENABLED flag, lockout, MQTT publish)
- Scheduler: unconditional command expiry sweep per poll cycle (sweep_expired_commands)
- Listener: subscribe to infoscreen/+/service_failed; persist service_failed_at + unit
- Listener: extract broker_connection block from health payload; persist reconnect_count + last_disconnect_at
- DB migration b1c2d3e4f5a6: service_failed_at, service_failed_unit, mqtt_reconnect_count, mqtt_last_disconnect_at on clients
- Add GET /api/clients/service_failed and POST /api/clients/<uuid>/clear_service_failed
- Monitoring overview API: include mqtt_reconnect_count + mqtt_last_disconnect_at per client
- Frontend: orange service-failed alert panel (hidden when empty, auto-refresh, quittieren action)
- Frontend: MQTT reconnect count + last disconnect in client detail panel
- MQTT auth hardening: listener/scheduler/server use env credentials; broker enforces allow_anonymous false
- Client command lifecycle foundation: ClientCommand model, reboot_host/shutdown_host, full ACK lifecycle
- Docs: TECH-CHANGELOG, DEV-CHANGELOG, MQTT_EVENT_PAYLOAD_GUIDE, copilot-instructions updated
- Add implementation-plans/, RESTART_VALIDATION_CHECKLIST.md, TODO.md
2026-04-05 10:17:56 +00:00

9.0 KiB
Raw Blame History

Infoscreen 2025

Docker React Flask MariaDB MQTT

Multi-service digital signage platform for educational institutions.

Core stack:

  • Dashboard: React + Vite + Syncfusion
  • API: Flask + SQLAlchemy + Alembic
  • DB: MariaDB
  • Messaging: MQTT (Mosquitto)
  • Background jobs: Redis + RQ + Gotenberg

Latest Release Highlights (2026.1.0-alpha.16)

  • Dashboard holiday status banner now updates reliably after hard refresh and after switching between settings and dashboard.
  • Production startup now auto-initializes and auto-activates the academic period for the current date.
  • Dashboard German UI wording was polished with proper Umlauts.
  • User-facing changelog source: dashboard/public/program-info.json

Architecture (Short)

  • Dashboard talks only to API (/api/... via Vite proxy in dev).
  • API is the single writer to MariaDB.
  • Listener consumes MQTT discovery/heartbeat/log/screenshot topics and updates API state.
  • Scheduler expands recurring events, applies exceptions, and publishes active content to retained MQTT topics.
  • Worker handles document conversions asynchronously.

Quick Start

Prerequisites

  • Docker + Docker Compose
  • Git

Development

  1. Clone
git clone https://github.com/RobbStarkAustria/infoscreen_2025.git
cd infoscreen_2025
  1. Configure environment
cp .env.example .env
# edit values as needed
  1. Start stack
make up
# or: docker compose up -d --build
  1. Initialize DB (first run)
python server/initialize_database.py
  1. Open services

Holiday Calendar (Quick Usage)

Settings path:

  • Settings -> Academic Calendar -> Ferienkalender: Import/Anzeige

Workflow summary:

  1. Select target academic period (archived periods are read-only/not selectable).
  2. Import CSV/TXT or add/edit holidays manually.
  3. Validation is period-scoped (out-of-period ranges are blocked).
  4. Duplicate/overlap policy:
    • exact duplicates: skipped/prevented
    • same normalized name+region overlaps (including adjacent ranges): merged
    • different-identity overlaps: conflict (manual blocked, import skipped with details)
  5. Recurring events with skip_holidays are recalculated automatically after holiday changes.

Common Commands

# Start/stop
make up
make down

# Logs
make logs
make logs-server

# Health
make health

# Build/push/deploy
make build
make push
make pull-prod
make up-prod

Scheduler Runtime Flags

Scheduler runtime defaults can be tuned with environment variables:

  • POLL_INTERVAL_SECONDS (default: 30)
  • REFRESH_SECONDS (default: 0, disabled)

TV power coordination (server Phase 1, group-level intent only):

  • POWER_INTENT_PUBLISH_ENABLED (default: false)
  • POWER_INTENT_HEARTBEAT_ENABLED (default: true)
  • POWER_INTENT_EXPIRY_MULTIPLIER (default: 3)
  • POWER_INTENT_MIN_EXPIRY_SECONDS (default: 90)

Power intent topic contract for Phase 1:

  • Topic: infoscreen/groups/{group_id}/power/intent
  • QoS: 1
  • Retained: true
  • Publish mode: transition publish + heartbeat republish each poll
  • Schema version: v1
  • Intent ID behavior: stable across unchanged heartbeat cycles; new UUID only on semantic transition (desired_state or reason change)
  • Expiry rule: max(3 × poll_interval, 90 seconds)

Rollout strategy (Phase 1):

  1. Keep POWER_INTENT_PUBLISH_ENABLED=false by default (disabled).
  2. Enable in test environment first: set POWER_INTENT_PUBLISH_ENABLED=true on one canary group's scheduler instance.
  3. Verify no unintended OFF between adjacent/overlapping events over 12 days.
  4. Expand to 20% of production groups for 2 days (canary soak).
  5. Monitor power-intent publish metrics (success rate, error rate, transition frequency) in scheduler logs.
  6. Roll out to 100% once canary is stable (zero off-between-adjacent-events incidents).
  7. Phase 2 (future): per-client override intents and state acknowledgments.

Documentation Map

Deployment

Backend & Database

Authentication & Authorization

Monitoring, Screenshots, Health

MQTT & Payloads

Events, Calendar, WebUntis

Historical Background

Conversion / Media

Historical / Archived Docs

Frontend

Project / Contributor Guidance

Active Implementation Plans

API Highlights

  • Core resources: clients, groups, events, academic periods
  • Client command lifecycle:
    • POST /api/clients/<uuid>/restart
    • POST /api/clients/<uuid>/shutdown
    • GET /api/clients/commands/<command_id>
  • Holidays: GET/POST /api/holidays, POST /api/holidays/upload, PUT/DELETE /api/holidays/<id>
  • Media: upload/download/stream + conversion status
  • Auth: login/logout/change-password
  • Monitoring: logs and monitoring overview endpoints

For full endpoint details, use source route files under server/routes/ and the docs listed above.

Project Structure (Top Level)

infoscreen_2025/
├── dashboard/        # React frontend
├── server/           # Flask API + migrations + worker
├── listener/         # MQTT listener
├── scheduler/        # Event scheduler/publisher
├── models/           # Shared SQLAlchemy models
├── mosquitto/        # MQTT broker config
├── certs/            # TLS certs (prod)
└── docker-compose*.yml

Contributing

  1. Create branch
  2. Implement change + tests
  3. Update relevant docs
  4. Open PR

Guidelines:

License

MIT License. See LICENSE.