- 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
243 lines
9.0 KiB
Markdown
243 lines
9.0 KiB
Markdown
# Infoscreen 2025
|
||
|
||
[](https://www.docker.com/)
|
||
[](https://reactjs.org/)
|
||
[](https://flask.palletsprojects.com/)
|
||
[](https://mariadb.org/)
|
||
[](https://mosquitto.org/)
|
||
|
||
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](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
|
||
```bash
|
||
git clone https://github.com/RobbStarkAustria/infoscreen_2025.git
|
||
cd infoscreen_2025
|
||
```
|
||
|
||
2. Configure environment
|
||
```bash
|
||
cp .env.example .env
|
||
# edit values as needed
|
||
```
|
||
|
||
3. Start stack
|
||
```bash
|
||
make up
|
||
# or: docker compose up -d --build
|
||
```
|
||
|
||
4. Initialize DB (first run)
|
||
```bash
|
||
python server/initialize_database.py
|
||
```
|
||
|
||
5. Open services
|
||
- Dashboard: http://localhost:5173
|
||
- API: http://localhost:8000
|
||
- MariaDB: localhost:3306
|
||
- MQTT: localhost:1883 (WS: 9001)
|
||
|
||
## 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
|
||
|
||
```bash
|
||
# 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 1–2 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
|
||
- [deployment-debian.md](deployment-debian.md)
|
||
- [deployment-ubuntu.md](deployment-ubuntu.md)
|
||
- [setup-deployment.sh](setup-deployment.sh)
|
||
|
||
### Backend & Database
|
||
- [DATABASE_GUIDE.md](DATABASE_GUIDE.md)
|
||
- [TECH-CHANGELOG.md](TECH-CHANGELOG.md)
|
||
- [server/alembic](server/alembic)
|
||
|
||
### Authentication & Authorization
|
||
- [AUTH_SYSTEM.md](AUTH_SYSTEM.md)
|
||
- [AUTH_QUICKREF.md](AUTH_QUICKREF.md)
|
||
- [userrole-management.md](userrole-management.md)
|
||
- [SUPERADMIN_SETUP.md](SUPERADMIN_SETUP.md)
|
||
|
||
### Monitoring, Screenshots, Health
|
||
- [CLIENT_MONITORING_SPECIFICATION.md](CLIENT_MONITORING_SPECIFICATION.md)
|
||
- [SCREENSHOT_IMPLEMENTATION.md](SCREENSHOT_IMPLEMENTATION.md)
|
||
|
||
### MQTT & Payloads
|
||
- [MQTT_EVENT_PAYLOAD_GUIDE.md](MQTT_EVENT_PAYLOAD_GUIDE.md)
|
||
|
||
### Events, Calendar, WebUntis
|
||
- [WEBUNTIS_EVENT_IMPLEMENTATION.md](WEBUNTIS_EVENT_IMPLEMENTATION.md)
|
||
|
||
### Historical Background
|
||
- [docs/archive/ACADEMIC_PERIODS_IMPLEMENTATION_SUMMARY.md](docs/archive/ACADEMIC_PERIODS_IMPLEMENTATION_SUMMARY.md)
|
||
- [docs/archive/ACADEMIC_PERIODS_CRUD_BUILD_PLAN.md](docs/archive/ACADEMIC_PERIODS_CRUD_BUILD_PLAN.md)
|
||
- [docs/archive/PHASE_3_CLIENT_MONITORING_IMPLEMENTATION.md](docs/archive/PHASE_3_CLIENT_MONITORING_IMPLEMENTATION.md)
|
||
- [docs/archive/CLEANUP_SUMMARY.md](docs/archive/CLEANUP_SUMMARY.md)
|
||
|
||
### Conversion / Media
|
||
- [pptx_conversion_guide_gotenberg.md](pptx_conversion_guide_gotenberg.md)
|
||
|
||
### Historical / Archived Docs
|
||
- [docs/archive/CLIENT_MONITORING_IMPLEMENTATION_GUIDE.md](docs/archive/CLIENT_MONITORING_IMPLEMENTATION_GUIDE.md) - completed implementation plan/history
|
||
- [docs/archive/MQTT_DASHBOARD_V1_TO_V2_MIGRATION.md](docs/archive/MQTT_DASHBOARD_V1_TO_V2_MIGRATION.md) - completed MQTT payload migration notes
|
||
- [docs/archive/PPTX_CONVERSION_LEGACY_APPROACH.md](docs/archive/PPTX_CONVERSION_LEGACY_APPROACH.md) - legacy conversion approach (superseded)
|
||
- [docs/archive/TV_POWER_PHASE_1_COORDINATION.md](docs/archive/TV_POWER_PHASE_1_COORDINATION.md) - TV power Phase 1 coordination tasklist
|
||
- [docs/archive/TV_POWER_PHASE_1_SERVER_HANDOFF.md](docs/archive/TV_POWER_PHASE_1_SERVER_HANDOFF.md) - TV power Phase 1 server handoff notes
|
||
- [docs/archive/TV_POWER_PHASE_1_CANARY_VALIDATION.md](docs/archive/TV_POWER_PHASE_1_CANARY_VALIDATION.md) - TV power Phase 1 canary validation checklist
|
||
- [docs/archive/TV_POWER_PHASE_1_IMPLEMENTATION_CHECKLIST.md](docs/archive/TV_POWER_PHASE_1_IMPLEMENTATION_CHECKLIST.md) - TV power Phase 1 implementation checklist
|
||
|
||
### Frontend
|
||
- [FRONTEND_DESIGN_RULES.md](FRONTEND_DESIGN_RULES.md)
|
||
- [dashboard/README.md](dashboard/README.md)
|
||
|
||
### Project / Contributor Guidance
|
||
- [.github/copilot-instructions.md](.github/copilot-instructions.md)
|
||
- [AI-INSTRUCTIONS-MAINTENANCE.md](AI-INSTRUCTIONS-MAINTENANCE.md)
|
||
- [DEV-CHANGELOG.md](DEV-CHANGELOG.md)
|
||
|
||
### Active Implementation Plans
|
||
- [implementation-plans/reboot-implementation-handoff-share.md](implementation-plans/reboot-implementation-handoff-share.md)
|
||
- [implementation-plans/reboot-implementation-handoff-client-team.md](implementation-plans/reboot-implementation-handoff-client-team.md)
|
||
- [implementation-plans/reboot-kickoff-summary.md](implementation-plans/reboot-kickoff-summary.md)
|
||
|
||
## 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)
|
||
|
||
```text
|
||
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:
|
||
- Match existing architecture and naming conventions
|
||
- Keep frontend aligned with [FRONTEND_DESIGN_RULES.md](FRONTEND_DESIGN_RULES.md)
|
||
- Keep service/API behavior aligned with [.github/copilot-instructions.md](.github/copilot-instructions.md)
|
||
|
||
## License
|
||
|
||
MIT License. See [LICENSE](LICENSE).
|