# Info-Board Neu - Architekturplan ## Zielbild Das neue System ersetzt die bestehende `pictur`-/LXDE-basierte Loesung durch eine schlanke, zentral verwaltete Signage-Plattform. Ziele: - moeglichst wenig Ballast auf den Player-Clients - Anzeige von Bildern, Videos, PDFs und Webseiten - flexible Playlist pro Monitor - Fallback auf sequentielle Anzeige aller Medien aus einem konfigurierten Verzeichnis - mandantenfaehige Pflegeoberflaeche pro Monitor/Firma - Admin-Oberflaeche fuer Gesamtsteuerung aller Monitore - autonomer Offline-Betrieb bei Serverausfall - einfache Verteilung per Ansible - moeglichst geringe Abhaengigkeit vom Unterbau innerhalb Debian-/Raspberry-Pi-OS-Welt ## Basisentscheidungen ### Betriebssystem - Player-Basis: aktuelles Raspberry Pi OS Lite auf Debian-13-Basis - Server-Basis: Debian-artiges System, bevorzugt containerisiert - keine volle Desktop-Umgebung auf den Playern ### Display-Stack - fuer Version 1 X11 statt Wayland - Grund: konservativer, besser vorhersehbar fuer Chromium-Kiosk, Screenshot-Erzeugung, Watchdogs und Raspberry-spezifische Display-Steuerung - kein LXDE, kein LightDM als Komfortschicht, nur ein minimaler X11-Kiosk-Stack ### Container-Strategie - Server: Docker Compose ist sinnvoll und empfohlen - Player: kein Voll-Docker-Ansatz fuer den Grafikpfad in Version 1 - Player besser als native Dienste mit systemd + Chromium-Kiosk ## Gesamtarchitektur Das System besteht aus zwei Hauptteilen: 1. zentraler Server fuer Verwaltung, API, Medien, Rechte und Steuerung 2. schlanke Player-Clients auf den Monitoren ### Server-Komponenten - Reverse Proxy - Backend API - Admin-Oberflaeche - mandantenbezogene Management-Oberflaeche - PostgreSQL - MQTT-Broker - Dateispeicher fuer Uploads, Vorschaubilder und Screenshots ### Player-Komponenten - `player-agent` als nativer systemd-Dienst - `player-ui` als lokale Web-Anwendung - Chromium im Kiosk-Modus, der nur die lokale `player-ui` rendert - lokaler Cache fuer Playlist, Medien und Status ## Rollenmodell ### Monitor-/Firmen-Oberflaeche Jede Firma sieht nur den ihr zugeordneten Monitor bzw. Kanal. Funktionen: - Medien hochladen - Medien loeschen und ordnen - Playlist pflegen - Anzeigedauer je Eintrag festlegen - `valid_from` und `valid_until` setzen - lokale Vorschau des eigenen Monitors sehen ### Admin-Oberflaeche Die Administration der Schule sieht und steuert die gesamte Anlage. Funktionen: - Inhalte aller Monitore verwalten - Monitore global uebersichtlich sehen - Vorschau/Screenshots aller Monitore sehen - Reload des Players ausloesen - Seite neu laden - Dienste neu starten - Monitore rebooten - Monitore an- und ausschalten ## Datenmodell ### Zentrale Entitaeten - `tenant` - `screen` - `user` - `media_asset` - `playlist` - `playlist_item` - `screen_status` - `screen_snapshot` - `device_command` - `sync_state` ### Wichtige Felder #### `screen` - `id` - `name` - `tenant_id` - `location` - `rotation` - `resolution` - `enabled` #### `media_asset` - `id` - `tenant_id` - `type` (`image`, `video`, `pdf`, `web`) - `source_kind` (`upload`, `remote_url`) - `storage_path` - `original_url` - `checksum` - `mime_type` - `created_at` #### `playlist_item` - `id` - `playlist_id` - `screen_id` - `order_index` - `type` - `src` - `duration` - `valid_from` - `valid_until` - `load_timeout` - `cache_policy` - `on_error` - `enabled` #### `screen_status` - `screen_id` - `online` - `last_heartbeat` - `current_item` - `current_type` - `current_since` - `last_sync_at` - `server_connected` - `cache_state` - `error_state` #### `screen_snapshot` - `screen_id` - `captured_at` - `image_path` ## Playlist-Konzept ### Unterstuetzte Typen - Bild - Video - PDF - Webseite - Verzeichnisreferenz als Fallback-/Sammelquelle ### Pro Eintrag steuerbar - Dauer - Gueltigkeit ueber `valid_from` und `valid_until` - Reihenfolge - Timeout fuer das Laden - Cache-Strategie - Fehlerverhalten (`skip`, `retry`, `fallback`) ### Fallback-Regel Wenn keine aktive Playlist vorhanden ist oder kein gueltiges Item aktiv ist, zeigt der Player alle Medien aus einem konfigurierten Fallback-Verzeichnis nacheinander an. Eigenschaften: - deterministische Reihenfolge, standardmaessig alphabetisch - medientypgerechte Anzeigezeiten - funktioniert komplett lokal aus dem Cache oder Dateisystem ## Offline- und Cache-Strategie Offline-Betrieb ist Pflicht. Der Player speichert lokal: - die letzte gueltige Playlist - alle noetigen Medien - letzten bekannten Status - letzte Server-/Sync-Metadaten Bei Serverausfall: - Wiedergabe laeuft lokal weiter - ein kleines Overlay-Symbol zeigt den Offline-Zustand an - Heartbeat wird lokal gepuffert oder beim Wiederverbinden aktualisiert ### Overlay-Zustaende - gruen: online - gelb: Verbindung instabil oder Daten veraltet - rot: keine Verbindung zum Server ## Vermeidung von Chromium-Haengern Chromium rendert niemals direkt externe Medien- oder Playlist-URLs. Stattdessen: - Chromium zeigt nur `http://127.0.0.1:/player` - die lokale `player-ui` kapselt alle Medien und Fehlerzustande - externe Medien werden vorher geladen oder lokal gespiegelt, wo immer moeglich Konsequenzen: - keine haengenden 404-Fehlerseiten als Hauptansicht - Timeouts pro Inhalt moeglich - bei Fehlern: Skip oder Fallback statt Stehenbleiben - lokaler Watchdog kann Anzeige und Browser neu initialisieren ## Vorschaukonzept Eine Vorschau ist sinnvoll, aber nicht als permanenter Livestream. Empfohlene Umsetzung: - Screenshot bei Item-Wechsel - zusaetzlicher Screenshot in Intervallen, z. B. alle 30 bis 60 Sekunden - Anzeige des letzten Screenshots in Admin- und Firmen-Oberflaeche - ergaenzt durch strukturierte Statusdaten Statusdaten: - aktuelles Item - Typ - Startzeit - Restlaufzeit - letzter Heartbeat - letzter Sync - Fehlerstatus ## Kommunikation ### HTTPS Fuer: - Login - Uploads - API-Aufrufe - Playlist-Bearbeitung - Download von Medien und Konfiguration - Abruf von Screenshots und Status ### MQTT Fuer: - Heartbeat - Statusmeldungen - Kommandos - Acknowledgements - Hinweis auf Playlist-Aenderungen ### MQTT-Topics - `signage/screen//heartbeat` - `signage/screen//status` - `signage/screen//event` - `signage/screen//command` - `signage/screen//ack` ### Befehle - `reload` - `restart_player` - `reboot` - `display_on` - `display_off` - `refresh_snapshot` - `clear_cache` ## Player-Aufbau ### `player-agent` Aufgaben: - Registrierung des Geraets - HTTPS-Sync - MQTT-Kommunikation - Cache-Verwaltung - Befehlsausfuehrung - Screenshot-Erzeugung - Ueberwachung lokaler Dienste ### `player-ui` Aufgaben: - lokale Wiedergabeoberflaeche - Darstellung von Bild, Video, PDF und Web - Auswertung von Zeitfenstern - Umschalten zwischen Playlist und Fallback - Offline-/Fehler-Overlay ## Server-Aufbau ### Kernkomponenten - API-Backend - Admin-Frontend - Tenant-Frontend - MQTT-Broker - Datenbank - Media-Storage ### Betriebsform - bevorzugt per Docker Compose - klare Trennung von persistenten Daten, Konfiguration und Deploy-Code ## Minimale Abhaengigkeiten auf dem Player Das Ziel ist ein moeglichst kleiner Satz an Laufzeitabhaengigkeiten. Bevorzugt: - Raspberry Pi OS Lite - Xorg-Minimalstack - Chromium - ein eigenes Player-Binary oder eine sehr schlanke Laufzeit - systemd Vermeiden: - voller Desktop - mehrere externe Viewer wie `feh`, `vlc`, `wmctrl`, `xdg-open` - Python-/Node-Laufzeiten mit grossem Paketbaum direkt auf dem Client, wenn vermeidbar ## Ansible-Zielstruktur ### Rollen - `signage_base` - `signage_player` - `signage_display` - `signage_server` ### Konfigurationspfade auf dem Client - `/etc/signage/config.yml` - `/var/lib/signage/cache/` - `/var/lib/signage/media/` - `/var/lib/signage/state/` - `/var/log/signage/` ## Migrationsstrategie 1. Architektur finalisieren 2. Datenmodell finalisieren 3. Minimalen Player-Prototyp bauen 4. Server-Minimalversion bauen 5. Referenz-Raspi aufsetzen 6. Offline-/Netzfehler-/Timeout-Szenarien testen 7. Management-Oberflaechen ausbauen 8. Ansible-Rollen erstellen 9. Einen Pilotmonitor migrieren 10. Restliche Monitore sukzessive migrieren ## Teststrategie Zu testen sind mindestens: - kurzer Netzverlust - kompletter Serverausfall - MQTT-Ausfall bei funktionierendem HTTPS - HTTPS-Ausfall bei funktionierendem MQTT - kaputte URL in Playlist - defekte PDF-Datei - grosses Video - Wechsel von `valid_from`/`valid_until` waehrend des laufenden Betriebs - Reload aus der Admin-Oberflaeche - Dienstneustart aus der Admin-Oberflaeche - Reboot aus der Admin-Oberflaeche - Display an/aus - Screenshot-Erzeugung unter Last ## Projektstruktur-Empfehlung Ein separates Projektverzeichnis ist sinnvoll, um die neue Architektur sauber von der bestehenden Netboot-Struktur zu trennen. Empfohlener Pfad: - `/srv/docker/info-board-neu` Dieses Verzeichnis sollte mindestens enthalten: - `PLAN.md` - `TODO.md` - spaeter `compose/`, `ansible/`, `server/`, `player/`, `docs/`