Erweitere Planung um Templates und Provisionierung
This commit is contained in:
parent
de15ee2e63
commit
ceaecaa234
8 changed files with 1161 additions and 2 deletions
|
|
@ -76,6 +76,21 @@ Beispiel-Endpunkte:
|
|||
- `GET /api/v1/screens/:screenId/status`
|
||||
- `GET /api/v1/screens/:screenId/snapshots/latest`
|
||||
|
||||
### 3a. Provisionierung
|
||||
|
||||
Zweck:
|
||||
|
||||
- neue Screens im Admin-Backend anlegen und technisch ausrollen
|
||||
- Provisionierungslaeufe starten, beobachten und auswerten
|
||||
|
||||
Beispiel-Endpunkte:
|
||||
|
||||
- `POST /api/v1/screens/provision`
|
||||
- `GET /api/v1/provisioning-jobs`
|
||||
- `GET /api/v1/provisioning-jobs/:jobId`
|
||||
- `POST /api/v1/provisioning-jobs/:jobId/retry`
|
||||
- `POST /api/v1/provisioning-jobs/:jobId/cancel`
|
||||
|
||||
### 4. Medien
|
||||
|
||||
Zweck:
|
||||
|
|
@ -108,6 +123,28 @@ Beispiel-Endpunkte:
|
|||
- `PATCH /api/v1/screens/:screenId/playlist/items/:itemId`
|
||||
- `DELETE /api/v1/screens/:screenId/playlist/items/:itemId`
|
||||
|
||||
### 5a. Globale Templates und Kampagnen
|
||||
|
||||
Zweck:
|
||||
|
||||
- globale monitoruebergreifende Templates verwalten
|
||||
- Kampagnen konfigurieren, aktivieren und deaktivieren
|
||||
- Screens gezielt global uebersteuern
|
||||
|
||||
Beispiel-Endpunkte:
|
||||
|
||||
- `GET /api/v1/templates`
|
||||
- `POST /api/v1/templates`
|
||||
- `GET /api/v1/templates/:templateId`
|
||||
- `PATCH /api/v1/templates/:templateId`
|
||||
- `POST /api/v1/templates/:templateId/scenes`
|
||||
- `PATCH /api/v1/templates/:templateId/scenes/:sceneId`
|
||||
- `POST /api/v1/campaigns`
|
||||
- `PATCH /api/v1/campaigns/:campaignId`
|
||||
- `POST /api/v1/campaigns/:campaignId/activate`
|
||||
- `POST /api/v1/campaigns/:campaignId/deactivate`
|
||||
- `PUT /api/v1/campaigns/:campaignId/assignments`
|
||||
|
||||
### 6. Player-Sync
|
||||
|
||||
Zweck:
|
||||
|
|
@ -120,6 +157,7 @@ Beispiel-Endpunkte:
|
|||
- `POST /api/v1/player/register`
|
||||
- `GET /api/v1/player/config`
|
||||
- `GET /api/v1/player/playlist`
|
||||
- `GET /api/v1/player/campaign`
|
||||
- `GET /api/v1/player/media-manifest`
|
||||
- `GET /api/v1/player/media/:mediaId/download`
|
||||
- `POST /api/v1/player/status`
|
||||
|
|
@ -139,6 +177,48 @@ Beispiel-Endpunkte:
|
|||
- `POST /api/v1/screens/:screenId/commands/display-on`
|
||||
- `POST /api/v1/screens/:screenId/commands/display-off`
|
||||
|
||||
## Provisionierungs-API
|
||||
|
||||
### `POST /api/v1/screens/provision`
|
||||
|
||||
Legt einen neuen Screen an und startet einen Provisionierungsjob.
|
||||
|
||||
Erwartete Eingaben mindestens:
|
||||
|
||||
- `screen_slug` oder `display_id`
|
||||
- `screen_name`
|
||||
- `tenant_id` optional, falls direkt zugeordnet werden soll
|
||||
- `target_ip`
|
||||
- `target_port` optional, Default 22
|
||||
- `remote_user`, Default `root`
|
||||
- `auth_mode`
|
||||
- `password` oder `private_key_ref` fuer die Erstverbindung
|
||||
- optionale technische Parameter wie `rotation`, `resolution`, `fallback_dir`
|
||||
|
||||
Serverseitiger Ablauf:
|
||||
|
||||
1. Screen-Datensatz anlegen
|
||||
2. Provisionierungsjob anlegen
|
||||
3. Secret nur kurzlebig oder referenziert speichern
|
||||
4. Worker/Jobrunner startet Ansible- oder SSH-gestuetzten Rollout
|
||||
5. nach Erfolg meldet sich der Screen kuenftig regulaer ueber seinen Agenten
|
||||
|
||||
Antwort mindestens:
|
||||
|
||||
- `screen_id`
|
||||
- `provisioning_job_id`
|
||||
- `status`
|
||||
|
||||
### `GET /api/v1/provisioning-jobs/:jobId`
|
||||
|
||||
Liefert:
|
||||
|
||||
- Jobstatus
|
||||
- aktuelle Stage
|
||||
- Zeitstempel
|
||||
- letzte Meldungen
|
||||
- Fehlerursache bei Fehlschlag
|
||||
|
||||
## API-Antworten fuer den Player
|
||||
|
||||
### `GET /api/v1/player/config`
|
||||
|
|
@ -178,6 +258,37 @@ Jedes Item enthaelt mindestens:
|
|||
- `valid_until`
|
||||
- `enabled`
|
||||
|
||||
### `GET /api/v1/player/campaign`
|
||||
|
||||
Liefert die fuer den Screen aktuell relevante globale Uebersteuerung.
|
||||
|
||||
Liefert:
|
||||
|
||||
- `campaign_revision`
|
||||
- `active_campaign` nullable
|
||||
|
||||
Wenn `active_campaign` gesetzt ist, enthaelt es mindestens:
|
||||
|
||||
- `campaign_id`
|
||||
- `template_id`
|
||||
- `name`
|
||||
- `priority`
|
||||
- `valid_from`
|
||||
- `valid_until`
|
||||
- `override_mode`
|
||||
- `scenes[]`
|
||||
|
||||
Jede Scene enthaelt mindestens:
|
||||
|
||||
- `id`
|
||||
- `type`
|
||||
- `src`
|
||||
- `duration_seconds`
|
||||
- `load_timeout_seconds`
|
||||
- `cache_policy`
|
||||
- `on_error`
|
||||
- `layout_json`
|
||||
|
||||
### `GET /api/v1/player/media-manifest`
|
||||
|
||||
Liefert:
|
||||
|
|
@ -256,6 +367,7 @@ Payload-Beispiel:
|
|||
Typische Events:
|
||||
|
||||
- `playlist_changed`
|
||||
- `campaign_changed`
|
||||
- `sync_completed`
|
||||
- `sync_failed`
|
||||
- `item_failed`
|
||||
|
|
@ -327,6 +439,8 @@ Der Server signalisiert aktiv:
|
|||
- es gibt neue Playlist-Daten
|
||||
- fuehre einen Befehl aus
|
||||
|
||||
Die eigentliche Erstprovisionierung laeuft nicht ueber MQTT, sondern ueber einen serverseitigen Job mit SSH/Ansible.
|
||||
|
||||
Beispielablauf bei Playlist-Aenderung:
|
||||
|
||||
1. Benutzer speichert Playlist in der Web-UI
|
||||
|
|
@ -336,6 +450,16 @@ Beispielablauf bei Playlist-Aenderung:
|
|||
5. Player synchronisiert fehlende Medien
|
||||
6. Player bestaetigt erfolgreichen Reload
|
||||
|
||||
Beispielablauf bei Aktivierung einer globalen Kampagne:
|
||||
|
||||
1. Admin aktiviert eine Kampagne
|
||||
2. Server erhoeht `campaign_revision`
|
||||
3. Server sendet Event oder Command `reload`
|
||||
4. Player ruft `GET /api/v1/player/campaign` ab
|
||||
5. Player synchronisiert kampagnenbezogene Medien
|
||||
6. Player setzt den Inhaltsmodus auf `campaign`
|
||||
7. Nach Deaktivierung oder Ablauf faellt der Player wieder auf `tenant_playlist` oder `fallback` zurueck
|
||||
|
||||
## Offline-Verhalten
|
||||
|
||||
### Wenn HTTPS ausfaellt
|
||||
|
|
|
|||
173
DATENMODELL.md
173
DATENMODELL.md
|
|
@ -111,6 +111,64 @@ Zweck:
|
|||
- sichere Kommunikation mit API und Broker
|
||||
- technische Inventarisierung
|
||||
|
||||
### `provisioning_job`
|
||||
|
||||
Repraesentiert einen Provisionierungslauf fuer einen neuen oder neu aufzubauenden Screen.
|
||||
|
||||
Felder:
|
||||
|
||||
- `id`
|
||||
- `screen_id`
|
||||
- `requested_by_user_id`
|
||||
- `target_ip`
|
||||
- `target_port`
|
||||
- `remote_user`
|
||||
- `auth_mode` (`password`, `key`)
|
||||
- `provided_secret_ref`
|
||||
- `ssh_key_fingerprint` nullable
|
||||
- `status` (`queued`, `running`, `succeeded`, `failed`, `cancelled`)
|
||||
- `stage` (`connect`, `bootstrap`, `key_install`, `package_install`, `deploy`, `verify`, `done`)
|
||||
- `log_excerpt` nullable
|
||||
- `error_message` nullable
|
||||
- `started_at` nullable
|
||||
- `finished_at` nullable
|
||||
- `created_at`
|
||||
- `updated_at`
|
||||
|
||||
Regeln:
|
||||
|
||||
- das eigentliche Passwort wird nicht im Klartext in der Datenbank gespeichert
|
||||
- `provided_secret_ref` verweist auf einen kurzlebigen oder extern geschuetzten Secret-Eintrag
|
||||
- pro Job soll klar erkennbar sein, in welchem Schritt ein Fehler aufgetreten ist
|
||||
|
||||
### `screen_group`
|
||||
|
||||
Optionale logische Gruppierung von Screens.
|
||||
|
||||
Felder:
|
||||
|
||||
- `id`
|
||||
- `slug`
|
||||
- `name`
|
||||
- `description`
|
||||
- `created_at`
|
||||
- `updated_at`
|
||||
|
||||
### `screen_group_member`
|
||||
|
||||
Zuordnung eines Screens zu einer Gruppe.
|
||||
|
||||
Felder:
|
||||
|
||||
- `id`
|
||||
- `screen_group_id`
|
||||
- `screen_id`
|
||||
- `created_at`
|
||||
|
||||
Zweck:
|
||||
|
||||
- praktische Zielauswahl fuer Kampagnen und Provisionierungsaktionen
|
||||
|
||||
### `media_asset`
|
||||
|
||||
Repraesentiert ein verwaltetes Medium.
|
||||
|
|
@ -163,6 +221,95 @@ Regeln:
|
|||
- pro Screen gibt es in v1 genau eine aktive Playlist
|
||||
- spaeter koennen mehrere Playlists mit Umschaltung moeglich werden
|
||||
|
||||
### `display_template`
|
||||
|
||||
Repraesentiert ein globales Admin-Template zur monitoruebergreifenden Orchestrierung.
|
||||
|
||||
Beispiele:
|
||||
|
||||
- Schriftzug ueber mehrere Monitore
|
||||
- saisonales Motiv auf allen Monitoren
|
||||
- Veranstaltungslayout fuer einen befristeten Zeitraum
|
||||
|
||||
Felder:
|
||||
|
||||
- `id`
|
||||
- `slug`
|
||||
- `name`
|
||||
- `description`
|
||||
- `template_type` (`message_wall`, `full_screen_media`, `screen_specific_scene`)
|
||||
- `enabled`
|
||||
- `created_by_user_id`
|
||||
- `created_at`
|
||||
- `updated_at`
|
||||
|
||||
### `template_scene`
|
||||
|
||||
Repraesentiert die konkrete Auspraegung eines Templates fuer einen oder mehrere Screens.
|
||||
|
||||
Felder:
|
||||
|
||||
- `id`
|
||||
- `display_template_id`
|
||||
- `screen_id` nullable
|
||||
- `screen_slot` nullable
|
||||
- `type` (`image`, `video`, `pdf`, `web`, `html`)
|
||||
- `src`
|
||||
- `duration_seconds`
|
||||
- `load_timeout_seconds`
|
||||
- `cache_policy`
|
||||
- `on_error`
|
||||
- `layout_json`
|
||||
- `created_at`
|
||||
- `updated_at`
|
||||
|
||||
Hinweise:
|
||||
|
||||
- `screen_id` erlaubt die direkte Zuweisung zu einem konkreten Monitor
|
||||
- `screen_slot` erlaubt spaeter abstrakte Wand-Slots wie `row1-col2`
|
||||
- `layout_json` kann z. B. Textpositionen, Farben oder Teilbereiche des Gesamtmotivs beschreiben
|
||||
|
||||
### `campaign`
|
||||
|
||||
Repraesentiert eine aktivierbare globale Kampagne auf Basis eines Templates.
|
||||
|
||||
Felder:
|
||||
|
||||
- `id`
|
||||
- `display_template_id`
|
||||
- `name`
|
||||
- `description`
|
||||
- `priority`
|
||||
- `active`
|
||||
- `valid_from` nullable
|
||||
- `valid_until` nullable
|
||||
- `override_mode` (`replace_tenant_content`, `replace_all`, `merge_reserved_slots`)
|
||||
- `created_by_user_id`
|
||||
- `created_at`
|
||||
- `updated_at`
|
||||
|
||||
Regeln:
|
||||
|
||||
- Kampagnen ueberschreiben in v1 standardmaessig den Firmencontent
|
||||
- nach Ende oder Deaktivierung greift automatisch wieder der tenantbezogene Normalbetrieb
|
||||
|
||||
### `template_assignment`
|
||||
|
||||
Repraesentiert die Zuordnung einer Kampagne oder eines Templates zu einem oder mehreren Screens.
|
||||
|
||||
Felder:
|
||||
|
||||
- `id`
|
||||
- `campaign_id`
|
||||
- `screen_id`
|
||||
- `enabled`
|
||||
- `created_at`
|
||||
- `updated_at`
|
||||
|
||||
Zweck:
|
||||
|
||||
- Auswahl einzelner Monitore, Gruppen oder aller Monitore
|
||||
|
||||
### `playlist_item`
|
||||
|
||||
Repraesentiert einen einzelnen Eintrag in einer Playlist.
|
||||
|
|
@ -226,6 +373,8 @@ Felder:
|
|||
- `last_sync_at`
|
||||
- `current_playlist_id`
|
||||
- `current_playlist_item_id` nullable
|
||||
- `current_content_source` (`campaign`, `tenant_playlist`, `fallback`)
|
||||
- `current_campaign_id` nullable
|
||||
- `current_item_type` nullable
|
||||
- `current_item_label` nullable
|
||||
- `current_item_started_at` nullable
|
||||
|
|
@ -312,6 +461,11 @@ Zweck:
|
|||
- ein `tenant` hat viele `media_assets`
|
||||
- ein `screen` hat genau eine aktive `playlist` in v1
|
||||
- eine `playlist` hat viele `playlist_items`
|
||||
- ein `display_template` hat viele `template_scenes`
|
||||
- ein `display_template` hat viele `campaigns`
|
||||
- eine `campaign` hat viele `template_assignments`
|
||||
- ein `screen` hat viele `provisioning_jobs`
|
||||
- eine `screen_group` hat viele `screen_group_members`
|
||||
- ein `screen` hat genau einen aktuellen `screen_status`
|
||||
- ein `screen` hat viele `screen_snapshots`
|
||||
- ein `screen` hat viele `device_commands`
|
||||
|
|
@ -353,12 +507,31 @@ Sinnvoll sind mindestens:
|
|||
- `playlist_revision`
|
||||
- `media_revision`
|
||||
- `config_revision`
|
||||
- `campaign_revision`
|
||||
|
||||
Der Player kann damit erkennen:
|
||||
|
||||
- ob neue Konfiguration vorliegt
|
||||
- ob Medien nachgeladen werden muessen
|
||||
- ob die lokale Kopie noch gueltig ist
|
||||
- ob sich globale Uebersteuerungen geaendert haben
|
||||
|
||||
## Prioritaetsmodell der Inhaltsauswahl
|
||||
|
||||
Der Player wertet Inhalte in dieser Reihenfolge aus:
|
||||
|
||||
1. aktive Kampagne mit gueltigem Zeitfenster und Assignment fuer den Screen
|
||||
2. aktive tenantbezogene Playlist des Screens
|
||||
3. Fallback-Verzeichnis
|
||||
|
||||
Eine Kampagne ist aktiv, wenn:
|
||||
|
||||
- `active = true`
|
||||
- `valid_from` leer oder erreicht ist
|
||||
- `valid_until` leer oder noch nicht abgelaufen ist
|
||||
- eine `template_assignment` fuer den Screen aktiv ist
|
||||
|
||||
Dadurch ist die globale Uebersteuerung ein Kernbestandteil und kein nachtraeglicher Sonderfall.
|
||||
|
||||
## Beispiel fuer aktive Playlist-Auswertung
|
||||
|
||||
|
|
|
|||
117
PLAN.md
117
PLAN.md
|
|
@ -12,6 +12,7 @@ Ziele:
|
|||
- Fallback auf sequentielle Anzeige aller Medien aus einem konfigurierten Verzeichnis
|
||||
- mandantenfaehige Pflegeoberflaeche pro Monitor/Firma
|
||||
- Admin-Oberflaeche fuer Gesamtsteuerung aller Monitore
|
||||
- globale Admin-Templates zur monitoruebergreifenden Orchestrierung
|
||||
- autonomer Offline-Betrieb bei Serverausfall
|
||||
- einfache Verteilung per Ansible
|
||||
- moeglichst geringe Abhaengigkeit vom Unterbau innerhalb Debian-/Raspberry-Pi-OS-Welt
|
||||
|
|
@ -36,6 +37,14 @@ Ziele:
|
|||
- Player: kein Voll-Docker-Ansatz fuer den Grafikpfad in Version 1
|
||||
- Player besser als native Dienste mit systemd + Chromium-Kiosk
|
||||
|
||||
### Sprach- und Laufzeitstrategie
|
||||
|
||||
- `Go` ist die bevorzugte Sprache fuer systemnahe und portable Komponenten
|
||||
- insbesondere gilt das fuer den `player-agent` und nach Moeglichkeit auch fuer zentrale Backend-Komponenten
|
||||
- Ziel ist eine geringe Zahl externer Laufzeitabhaengigkeiten und moeglichst einfache Verteilung per Ansible
|
||||
- fuer Browser-Oberflaechen bleibt JavaScript/TypeScript im Frontend natuerlich zulaessig
|
||||
- falls einzelne Server-Bausteine spaeter aus pragmatischen Gruenden anders umgesetzt werden, soll das begruendet und dokumentiert werden
|
||||
|
||||
## Gesamtarchitektur
|
||||
|
||||
Das System besteht aus zwei Hauptteilen:
|
||||
|
|
@ -89,6 +98,49 @@ Funktionen:
|
|||
- Dienste neu starten
|
||||
- Monitore rebooten
|
||||
- Monitore an- und ausschalten
|
||||
- globale Templates erstellen, testen und aktivieren
|
||||
- temporaere Kampagnen fuer mehrere oder alle Monitore einschalten und wieder abschalten
|
||||
- neue Monitore initial provisionieren und betriebsbereit ausrollen
|
||||
|
||||
### Globale Template-Orchestrierung
|
||||
|
||||
Die Admin-Seite bekommt zusaetzlich einen globalen Orchestrierungsbereich.
|
||||
|
||||
Ziele:
|
||||
|
||||
- grossformatige monitoruebergreifende Botschaften wie `SCHOENE FERIEN` oder `MORZ-INFO`
|
||||
- saisonale oder veranstaltungsbezogene globale Motive, z. B. Weihnachten
|
||||
- schnelles temporäres Ueberstimmen des Firmencontents
|
||||
- Rueckkehr zum normalen Firmencontent auf Knopfdruck
|
||||
|
||||
Grundprinzip:
|
||||
|
||||
- globale Templates sind administrative Kampagnen mit hoeherer Prioritaet als tenantbezogene Inhalte
|
||||
- sie koennen auf einzelne Monitore, Monitorgruppen oder alle Monitore angewendet werden
|
||||
- sie sind zeitlich planbar oder manuell aktivierbar
|
||||
- nach Deaktivierung faellt der Bildschirm automatisch auf seine normale tenantbezogene Playlist zurueck
|
||||
|
||||
### Automatische Screen-Provisionierung
|
||||
|
||||
Die Admin-Oberflaeche soll neue Bildschirme nicht nur fachlich anlegen, sondern technisch in Betrieb nehmen koennen.
|
||||
|
||||
Zielablauf:
|
||||
|
||||
- Admin gibt `display_id`, Ziel-IP und initiale Root-Zugangsdaten an
|
||||
- das System stellt per SSH eine Erstverbindung her
|
||||
- ein Deploy-Key oder dedizierter Verwaltungsschluessel wird hinterlegt
|
||||
- noetige Pakete und Komponenten werden installiert
|
||||
- Konfiguration fuer den neuen Screen wird ausgerollt
|
||||
- der Player wird gestartet und meldet sich selbststaendig am Server an
|
||||
|
||||
Der Vorgang soll moeglichst als gefuehrter Provisionierungs-Workflow im Admin-Backend verfuegbar sein.
|
||||
|
||||
Wichtige Randbedingungen:
|
||||
|
||||
- Root-Passwoerter duerfen nicht dauerhaft im Klartext gespeichert werden
|
||||
- Provisionierungsdaten sind nur fuer Admins sichtbar
|
||||
- jeder Provisionierungslauf muss nachvollziehbar protokolliert werden
|
||||
- die eigentliche Ausbringung soll auf einem automatisierbaren Ansible- oder SSH-Workflow basieren, nicht auf ad-hoc-Shellmagie im Browser
|
||||
|
||||
## Datenmodell
|
||||
|
||||
|
|
@ -100,6 +152,10 @@ Funktionen:
|
|||
- `media_asset`
|
||||
- `playlist`
|
||||
- `playlist_item`
|
||||
- `display_template`
|
||||
- `template_scene`
|
||||
- `template_assignment`
|
||||
- `campaign`
|
||||
- `screen_status`
|
||||
- `screen_snapshot`
|
||||
- `device_command`
|
||||
|
|
@ -193,6 +249,23 @@ Eigenschaften:
|
|||
- medientypgerechte Anzeigezeiten
|
||||
- funktioniert komplett lokal aus dem Cache oder Dateisystem
|
||||
|
||||
### Prioritaetsregel fuer globale Templates
|
||||
|
||||
Die Inhaltsauswahl pro Screen folgt in v1 einer klaren Prioritaetskette:
|
||||
|
||||
1. aktive globale Kampagne bzw. aktives Admin-Template
|
||||
2. normale tenantbezogene Playlist des Monitors
|
||||
3. lokaler Fallback aus dem konfigurierten Verzeichnis
|
||||
|
||||
Das verhindert spaeteres Anflanschen und macht die Uebersteuerung von Beginn an explizit.
|
||||
|
||||
Wichtige Regeln:
|
||||
|
||||
- globale Templates sind immer explizit aktiv oder inaktiv
|
||||
- sie koennen `valid_from` und `valid_until` besitzen
|
||||
- sie koennen manuell sofort deaktiviert werden
|
||||
- nach Ablauf oder Deaktivierung setzt der Screen automatisch beim normalen Inhalt fort
|
||||
|
||||
## Offline- und Cache-Strategie
|
||||
|
||||
Offline-Betrieb ist Pflicht.
|
||||
|
|
@ -244,6 +317,12 @@ Empfohlene Umsetzung:
|
|||
- Anzeige des letzten Screenshots in Admin- und Firmen-Oberflaeche
|
||||
- ergaenzt durch strukturierte Statusdaten
|
||||
|
||||
Die Vorschau soll auch sichtbar machen, ob ein Screen gerade:
|
||||
|
||||
- tenantbezogenen Normalbetrieb zeigt
|
||||
- von einer globalen Kampagne uebersteuert wird
|
||||
- im Fallback-Modus laeuft
|
||||
|
||||
Statusdaten:
|
||||
|
||||
- aktuelles Item
|
||||
|
|
@ -309,6 +388,11 @@ Aufgaben:
|
|||
- Screenshot-Erzeugung
|
||||
- Ueberwachung lokaler Dienste
|
||||
|
||||
Technische Vorgabe:
|
||||
|
||||
- Implementierung bevorzugt in `Go`
|
||||
- Auslieferung moeglichst als einzelnes Binary
|
||||
|
||||
### `player-ui`
|
||||
|
||||
Aufgaben:
|
||||
|
|
@ -330,6 +414,18 @@ Aufgaben:
|
|||
- Datenbank
|
||||
- Media-Storage
|
||||
|
||||
Zusaetzliche fachliche Server-Faehigkeiten:
|
||||
|
||||
- Verwaltung globaler Templates
|
||||
- Konfiguration monitoruebergreifender Layouts und Szenen
|
||||
- Aktivierung, Deaktivierung und Zeitplanung globaler Kampagnen
|
||||
- technische Provisionierung neuer Screens ueber einen gefuehrten Admin-Workflow
|
||||
|
||||
Technische Vorgabe:
|
||||
|
||||
- Backend bevorzugt in `Go`, sofern die Entwicklungsdynamik nicht klar dagegen spricht
|
||||
- Frontends als Web-Anwendungen mit ueblichem Browser-Stack
|
||||
|
||||
### Betriebsform
|
||||
|
||||
- bevorzugt per Docker Compose
|
||||
|
|
@ -344,7 +440,7 @@ Bevorzugt:
|
|||
- Raspberry Pi OS Lite
|
||||
- Xorg-Minimalstack
|
||||
- Chromium
|
||||
- ein eigenes Player-Binary oder eine sehr schlanke Laufzeit
|
||||
- ein eigenes Player-Binary in `Go` oder eine gleichwertig schlanke Laufzeit
|
||||
- systemd
|
||||
|
||||
Vermeiden:
|
||||
|
|
@ -361,6 +457,21 @@ Vermeiden:
|
|||
- `signage_player`
|
||||
- `signage_display`
|
||||
- `signage_server`
|
||||
- `signage_provision`
|
||||
|
||||
### Provisionierungsmodell
|
||||
|
||||
Die Erstinstallation eines neuen Screens soll auf Ansible aufsetzen.
|
||||
|
||||
Vorgesehener Ablauf:
|
||||
|
||||
1. Screen im Admin-Backend anlegen
|
||||
2. einmalige technische Zugangsdaten fuer die Erstverbindung angeben
|
||||
3. Backend startet einen Provisionierungsjob
|
||||
4. der Job nutzt SSH/Ansible fuer Basis-Setup, Key-Deployment, Paketinstallation und Konfiguration
|
||||
5. nach erfolgreicher Provisionierung verwendet der Screen nur noch den hinterlegten Verwaltungsschluessel und seine technische Geraeteidentitaet
|
||||
|
||||
Damit wird die GUI zur komfortablen Steuerschicht ueber einem reproduzierbaren Automatisierungsprozess.
|
||||
|
||||
### Konfigurationspfade auf dem Client
|
||||
|
||||
|
|
@ -383,6 +494,10 @@ Vermeiden:
|
|||
9. Einen Pilotmonitor migrieren
|
||||
10. Restliche Monitore sukzessive migrieren
|
||||
|
||||
Parallel von Anfang an mitdenken:
|
||||
|
||||
- globale Template-Orchestrierung darf kein Nachbau sein, sondern muss im Inhalts- und Prioritaetsmodell direkt vorgesehen werden
|
||||
|
||||
## Teststrategie
|
||||
|
||||
Zu testen sind mindestens:
|
||||
|
|
|
|||
14
README.md
14
README.md
|
|
@ -14,11 +14,23 @@ Die Trennung von `/srv/docker/infoboard-netboot` ist sinnvoll, damit:
|
|||
- Umsetzungs-Todo: `TODO.md`
|
||||
- Datenmodell: `DATENMODELL.md`
|
||||
- API- und MQTT-Vertrag: `API-MQTT-VERTRAG.md`
|
||||
- Technologieentscheidungen: `TECH-STACK.md`
|
||||
- Template-/Kampagnenkonzept: `docs/TEMPLATE-KONZEPT.md`
|
||||
- Provisionierungskonzept: `docs/PROVISIONIERUNGSKONZEPT.md`
|
||||
|
||||
## Empfohlene spaetere Struktur
|
||||
## Projektstruktur
|
||||
|
||||
- `docs/` fuer weitere Architektur- und Betriebsdokumente
|
||||
- `server/` fuer Backend, Frontends und Compose-Dateien
|
||||
- `player/` fuer Agent, UI und lokale Startlogik
|
||||
- `ansible/` fuer Rollen, Inventories und Deployments
|
||||
- `compose/` fuer Container-Definitionen und Stack-Bausteine
|
||||
- `scripts/` fuer Hilfsskripte
|
||||
|
||||
## Naechste sinnvolle Inhalte in der Struktur
|
||||
|
||||
- `docs/` fuer weitere technische Detaildokumente
|
||||
- `server/` fuer API, Admin-UI und Tenant-UI
|
||||
- `player/` fuer `player-agent`, `player-ui` und lokale Startlogik
|
||||
- `ansible/` fuer Rollen und Inventories
|
||||
- `compose/` fuer den zentralen Server-Stack
|
||||
|
|
|
|||
147
TECH-STACK.md
Normal file
147
TECH-STACK.md
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
# Info-Board Neu - Tech Stack
|
||||
|
||||
## Ziel
|
||||
|
||||
Dieses Dokument zieht die Technologieentscheidungen verbindlich zusammen, damit sie nicht nur verteilt in Plan und Todo-Liste stehen.
|
||||
|
||||
Leitlinien:
|
||||
|
||||
- moeglichst wenige Laufzeitabhaengigkeiten
|
||||
- gute Portabilitaet zwischen Raspberry Pi OS und Debian
|
||||
- einfache Verteilung per Ansible
|
||||
- robuste Offline-Faehigkeit
|
||||
- moeglichst wenig Ballast auf den Playern
|
||||
|
||||
## Verbindliche Entscheidungen
|
||||
|
||||
### Betriebssysteme
|
||||
|
||||
- Player: aktuelles Raspberry Pi OS Lite auf Debian-13-Basis
|
||||
- Server: Debian-artiges System, bevorzugt mit Docker Compose betrieben
|
||||
|
||||
### Display-Stack auf dem Player
|
||||
|
||||
- Version 1 basiert auf X11
|
||||
- keine volle Desktop-Umgebung
|
||||
- kein LXDE, kein LightDM als Pflichtbestandteil
|
||||
- Chromium laeuft im Kiosk-Modus gegen eine lokale Player-Oberflaeche
|
||||
|
||||
Begruendung:
|
||||
|
||||
- X11 ist fuer Chromium-Kiosk auf Raspberry Pi aktuell konservativer und besser vorhersehbar als Wayland
|
||||
- weniger Ueberraschungen bei Screenshot-Erzeugung, Display-Steuerung und Watchdog-Verhalten
|
||||
|
||||
### Programmiersprachen
|
||||
|
||||
- `Go` ist die bevorzugte Sprache fuer systemnahe Komponenten
|
||||
- `Go` ist die Standardwahl fuer den `player-agent`
|
||||
- `Go` ist die bevorzugte Sprache fuer das Server-Backend, solange keine zwingenden Gruende dagegensprechen
|
||||
- Browser-Oberflaechen werden mit einem normalen Web-Frontend-Stack umgesetzt
|
||||
|
||||
Begruendung:
|
||||
|
||||
- statische oder weitgehend selbstgenuegsame Binaries
|
||||
- geringe Laufzeitabhaengigkeiten
|
||||
- gute Cross-Compile- und Deploy-Eigenschaften
|
||||
- passend fuer Debian- und Raspberry-Pi-Umgebungen
|
||||
|
||||
### Frontend-Stack
|
||||
|
||||
- Admin-UI: Web-Anwendung
|
||||
- Tenant-/Monitor-UI: Web-Anwendung
|
||||
- Player-UI: lokale Web-Anwendung fuer den Renderer
|
||||
|
||||
Noch offen, aber bewusst klein zu halten:
|
||||
|
||||
- Framework-Auswahl fuer Server-UIs, bevorzugt leichtgewichtig
|
||||
- keine unnötig schwere Fullstack-Plattform nur aus Gewohnheit
|
||||
|
||||
### Server-Betrieb
|
||||
|
||||
- zentrale Komponenten bevorzugt in Docker Compose
|
||||
- getrennte Services fuer Backend, Datenbank, MQTT und Reverse Proxy
|
||||
- persistente Daten ausserhalb fluechtiger Container-Dateisysteme
|
||||
- Provisionierungsjobs laufen serverseitig ueber einen dedizierten Worker oder Jobrunner
|
||||
|
||||
### Player-Betrieb
|
||||
|
||||
- keine Voll-Containerisierung des Grafikpfads in Version 1
|
||||
- native systemd-Dienste fuer `player-agent` und Browser-Startlogik
|
||||
- lokale Verzeichnisse fuer Cache, Medien, Status und Logs
|
||||
|
||||
### Provisionierung und Deployment
|
||||
|
||||
- die technische Erstinstallation neuer Screens wird ueber SSH + Ansible umgesetzt
|
||||
- das Admin-Backend ist die steuernde Oberflaeche, aber nicht der Ort fuer eigentliche Shell-Logik
|
||||
- Root-Passwoerter dienen nur als Bootstrap-Mittel und sollen nicht dauerhaft gespeichert werden
|
||||
- nach der Erstinstallation erfolgt die weitere Verwaltung schluesselbasiert
|
||||
|
||||
## Zielkomponenten
|
||||
|
||||
### Player
|
||||
|
||||
- `player-agent` in `Go`
|
||||
- `player-ui` als lokale Web-Oberflaeche
|
||||
- Chromium als Renderer
|
||||
- Xorg-Minimalstack
|
||||
- systemd fuer Start, Neustart und Watchdog-Integration
|
||||
|
||||
### Server
|
||||
|
||||
- Backend-API in `Go`
|
||||
- Admin-UI als Web-Frontend
|
||||
- Tenant-UI als Web-Frontend
|
||||
- PostgreSQL
|
||||
- MQTT-Broker, bevorzugt Mosquitto
|
||||
- Reverse Proxy
|
||||
- Dateispeicher fuer Uploads, Caches und Screenshots
|
||||
|
||||
## Kommunikationsstack
|
||||
|
||||
- HTTPS fuer API, Upload, Download, Authentifizierung und Screenshots
|
||||
- MQTT fuer Heartbeat, Status, Kommandos und Acknowledgements
|
||||
|
||||
Nicht vorgesehen:
|
||||
|
||||
- Medienuebertragung ueber MQTT
|
||||
- permanente Spezial-Streams fuer den Regelbetrieb
|
||||
|
||||
## Laufzeit-Minimum auf dem Player
|
||||
|
||||
Anzustreben sind nur diese grossen Bausteine:
|
||||
|
||||
- Raspberry Pi OS Lite
|
||||
- Xorg-Minimalstack
|
||||
- Chromium
|
||||
- eigenes `Go`-Binary fuer den Agenten
|
||||
- systemd
|
||||
|
||||
Moeglichst zu vermeiden:
|
||||
|
||||
- komplette Desktop-Umgebungen
|
||||
- mehrere externe Viewer wie `feh`, `vlc`, `wmctrl`, `xdg-open`
|
||||
- umfangreiche Python- oder Node-Laufzeitstapel direkt auf dem Player
|
||||
|
||||
## Build- und Deployment-Richtung
|
||||
|
||||
- `Go`-Binaries sollen zentral gebaut und per Ansible verteilt werden koennen
|
||||
- Konfiguration soll dateibasiert und gut templatisierbar sein
|
||||
- Frontend-Artefakte sollen versioniert und reproduzierbar baubar sein
|
||||
|
||||
## Architekturfolgen aus diesen Entscheidungen
|
||||
|
||||
- der Player bleibt moeglichst nah an einem Appliance-Modell
|
||||
- Browserfehler duerfen nicht direkt die eigentliche Logik bestimmen
|
||||
- Renderer und Systemlogik bleiben getrennt
|
||||
- Serverlogik ist zentralisiert, Playerlogik minimal und robust
|
||||
|
||||
## Bewusst vertagte Entscheidungen
|
||||
|
||||
- moeglicher spaeterer Wechsel auf Wayland
|
||||
- exakte Frontend-Framework-Wahl
|
||||
- genaue Auspraegung des Build-Systems fuer Frontend-Artefakte
|
||||
- eventuelle Objekt-Storage-Einfuehrung statt einfachem Dateispeicher
|
||||
|
||||
## Aktueller technischer Grundsatz
|
||||
|
||||
Wenn zwei Varianten funktional gleichwertig sind, wird die Variante mit weniger Laufzeitabhaengigkeiten, einfacherem Deployment und besserem Offline-Verhalten bevorzugt.
|
||||
17
TODO.md
17
TODO.md
|
|
@ -7,6 +7,7 @@
|
|||
- [ ] Dokumentationsstruktur fuer Architektur, Betrieb und Deployment anlegen
|
||||
- [ ] Entscheidung fuer Server-Tech-Stack dokumentieren
|
||||
- [ ] Entscheidung fuer Player-Implementierung dokumentieren
|
||||
- [ ] Sprachentscheidung dokumentieren: `Go` als bevorzugte Sprache fuer Agent und moeglichst viele Backend-Komponenten
|
||||
|
||||
## Phase 1 - Fachliches Fundament
|
||||
|
||||
|
|
@ -16,6 +17,8 @@
|
|||
- [ ] Fallback-Regel fuer ungeplante oder leere Inhalte verbindlich definieren
|
||||
- [ ] Statusmodell fuer Online/Offline/Degraded/Error definieren
|
||||
- [ ] Kommandokatalog fuer Admin-Aktionen finalisieren
|
||||
- [ ] Template- und Kampagnenmodell fuer globale monitoruebergreifende Uebersteuerung finalisieren
|
||||
- [ ] Prioritaetsregel `campaign > tenant_playlist > fallback` verbindlich festschreiben
|
||||
|
||||
## Phase 2 - Technische Zielarchitektur
|
||||
|
||||
|
|
@ -26,6 +29,9 @@
|
|||
- [ ] Screenshot-/Vorschaustrategie spezifizieren
|
||||
- [ ] Offline- und Cache-Strategie bis auf Dateiebene festlegen
|
||||
- [ ] Sicherheitsmodell fuer Uploads, Login und Rechte pruefen
|
||||
- [ ] API fuer Templates, Kampagnen, Aktivierung und Deaktivierung ausarbeiten
|
||||
- [ ] Provisionierungs-Workflow fuer neue Screens technisch durchplanen
|
||||
- [ ] Secret-Handling fuer initiale Root-Passwoerter oder Bootstrap-Zugaenge definieren
|
||||
|
||||
## Phase 3 - Player-Design
|
||||
|
||||
|
|
@ -49,6 +55,11 @@
|
|||
- [ ] Authentifizierungskonzept festlegen
|
||||
- [ ] Mandantentrennung im Datenmodell und in den APIs absichern
|
||||
- [ ] Logging- und Monitoring-Konzept definieren
|
||||
- [ ] Template-Editor fuer globale Kampagnen fachlich schneiden
|
||||
- [ ] Aktivierungsoberflaeche fuer saisonale oder temporäre Kampagnen planen
|
||||
- [ ] Gruppierung oder Slot-Modell fuer monitoruebergreifende Layouts planen
|
||||
- [ ] Provisionierungs-UI fuer neue Screens fachlich und technisch schneiden
|
||||
- [ ] Jobrunner-Konzept fuer Ansible-gestuetzte Erstinstallation planen
|
||||
|
||||
## Phase 5 - Prototyping
|
||||
|
||||
|
|
@ -60,6 +71,8 @@
|
|||
- [ ] `valid_from`/`valid_until` im Prototyp pruefen
|
||||
- [ ] Offline-Sync mit lokalem Cache pruefen
|
||||
- [ ] MQTT-Kommandos `reload`, `restart_player`, `reboot`, `display_on`, `display_off` testweise durchspielen
|
||||
- [ ] globale Kampagne testen, die tenantbezogenen Content temporär ueberschreibt
|
||||
- [ ] Rueckfall auf Normalbetrieb nach manueller Deaktivierung pruefen
|
||||
|
||||
## Phase 6 - Betriebsfaehigkeit
|
||||
|
||||
|
|
@ -76,10 +89,12 @@
|
|||
- [ ] Rolle `signage_player` erstellen
|
||||
- [ ] Rolle `signage_display` erstellen
|
||||
- [ ] Rolle `signage_server` erstellen
|
||||
- [ ] Rolle `signage_provision` erstellen
|
||||
- [ ] Inventar-/Variablenmodell fuer mehrere Monitore entwerfen
|
||||
- [ ] Screen-spezifische Variablen wie `screen_id`, Rotation und Aufloesung abbilden
|
||||
- [ ] Erstinstallation eines neuen Players automatisieren
|
||||
- [ ] Update-Rollout eines bestehenden Players automatisieren
|
||||
- [ ] Bootstrap ueber Root-Passwort auf SSH-Key und dauerhafte Verwaltung umstellen
|
||||
|
||||
## Phase 8 - Pilotbetrieb
|
||||
|
||||
|
|
@ -88,8 +103,10 @@
|
|||
- [ ] Verbindung zum Zentralserver herstellen
|
||||
- [ ] Upload- und Playlist-Pflege mit einem Testmandanten pruefen
|
||||
- [ ] Admin-Funktionen am Pilotmonitor pruefen
|
||||
- [ ] globale Template-Aktivierung fuer einen oder mehrere Monitore im Pilot testen
|
||||
- [ ] Offline-Betrieb real testen
|
||||
- [ ] Browser-/Renderer-Stabilitaet ueber laengeren Zeitraum beobachten
|
||||
- [ ] komplette Neu-Provisionierung eines frischen Test-Screens aus dem Admin-Backend pruefen
|
||||
|
||||
## Phase 9 - Migration der Bestandsmonitore
|
||||
|
||||
|
|
|
|||
294
docs/PROVISIONIERUNGSKONZEPT.md
Normal file
294
docs/PROVISIONIERUNGSKONZEPT.md
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
# Info-Board Neu - Provisionierungskonzept
|
||||
|
||||
## Ziel
|
||||
|
||||
Neue Displays sollen aus dem Admin-Backend heraus technisch in Betrieb genommen werden koennen.
|
||||
|
||||
Der Workflow soll mindestens leisten:
|
||||
|
||||
- neuen Screen fachlich anlegen
|
||||
- initiale Verbindung per IP und Bootstrap-Zugang herstellen
|
||||
- SSH-Key fuer dauerhafte Verwaltung hinterlegen
|
||||
- noetige Komponenten installieren
|
||||
- Screen-spezifische Konfiguration ausrollen
|
||||
- Display in lauffaehigen Zustand versetzen
|
||||
|
||||
Das Konzept ist ausdruecklich nicht auf 9 Monitore begrenzt. Es muss auch kuenftige Einzelanzeigen wie Vertretungsplan-Displays sauber abbilden.
|
||||
|
||||
## Grundprinzip
|
||||
|
||||
Die Admin-Oberflaeche ist der Einstiegspunkt, aber die eigentliche Ausbringung erfolgt reproduzierbar ueber einen serverseitigen Provisionierungsjob.
|
||||
|
||||
Technische Leitlinie:
|
||||
|
||||
- GUI sammelt Eingaben und zeigt Fortschritt
|
||||
- Backend erzeugt Provisionierungsjob
|
||||
- Jobrunner fuehrt SSH-/Ansible-Schritte aus
|
||||
- Ergebnis wird protokolliert und in der UI sichtbar gemacht
|
||||
|
||||
## Eingaben fuer einen neuen Screen
|
||||
|
||||
Mindestens erforderlich:
|
||||
|
||||
- `display_id` bzw. `screen_slug`
|
||||
- Anzeigename
|
||||
- Ziel-IP-Adresse
|
||||
- Bootstrap-Benutzer, Default `root`
|
||||
- Bootstrap-Passwort oder alternativer Initial-Key
|
||||
- gewuenschte Orientierung
|
||||
- optionale Rotation
|
||||
- Screen-Klasse oder Geraetetyp
|
||||
- Tenant-Zuordnung, falls direkt bekannt
|
||||
|
||||
Optional sinnvoll:
|
||||
|
||||
- Aufloesung
|
||||
- Fallback-Verzeichnis
|
||||
- Snapshot-Intervall
|
||||
- Zugehoerigkeit zu Gruppen
|
||||
- Standortbeschreibung
|
||||
|
||||
## Orientierung und Rotationsmodell
|
||||
|
||||
Die Ausrichtung ist von Anfang an ein Pflichtfeld.
|
||||
|
||||
### Fachliche Orientierung
|
||||
|
||||
- `portrait`
|
||||
- `landscape`
|
||||
|
||||
### Technische Rotation
|
||||
|
||||
- `0`
|
||||
- `90`
|
||||
- `180`
|
||||
- `270`
|
||||
|
||||
Grundregel:
|
||||
|
||||
- die Orientierung ist die fachliche Voreinstellung fuer Templates und Layouts
|
||||
- die Rotation ist die technische Ableitung fuer den Display-Stack auf dem Geraet
|
||||
|
||||
Beispiele:
|
||||
|
||||
- Infowand-Displays: typischerweise `portrait`
|
||||
- Vertretungsplan-Displays: typischerweise `landscape`
|
||||
|
||||
Diese Werte muessen in Provisionierung, Player-Konfiguration und Kampagnenlogik gleichermassen sichtbar sein.
|
||||
|
||||
## Screen-Klassen
|
||||
|
||||
Um skalierbar zu bleiben, sollte die Provisionierung mit Klassen oder Profilen arbeiten.
|
||||
|
||||
Empfohlene Startklassen:
|
||||
|
||||
- `info_wall_display`
|
||||
- `single_info_display`
|
||||
- `vertretungsplan_display`
|
||||
|
||||
Diese Klassen koennen Defaults liefern fuer:
|
||||
|
||||
- Orientierung
|
||||
- Rotation
|
||||
- Aufloesung
|
||||
- Gruppenmitgliedschaften
|
||||
- Fallback-Verzeichnis
|
||||
- spezielle UI- oder Template-Voreinstellungen
|
||||
|
||||
## Provisionierungsablauf
|
||||
|
||||
### 1. Fachliches Anlegen
|
||||
|
||||
Im Admin-Backend wird der Screen angelegt mit:
|
||||
|
||||
- Name
|
||||
- ID
|
||||
- Klasse
|
||||
- Orientierung
|
||||
- Tenant-Zuordnung
|
||||
- Standort
|
||||
|
||||
### 2. Start des Provisionierungsjobs
|
||||
|
||||
Der Admin gibt die technischen Zugangsdaten fuer die Erstverbindung an.
|
||||
|
||||
Wichtig:
|
||||
|
||||
- Passwort nur fuer den aktuellen Job verwenden
|
||||
- keine dauerhafte Klartextspeicherung
|
||||
|
||||
### 3. Verbindungsaufbau
|
||||
|
||||
Der Jobrunner versucht per SSH die Verbindung herzustellen.
|
||||
|
||||
Pruefpunkte:
|
||||
|
||||
- Erreichbarkeit
|
||||
- SSH-Port
|
||||
- gueltige Zugangsdaten
|
||||
- Architektur und Betriebssystem grob erkennen
|
||||
|
||||
### 4. Bootstrap
|
||||
|
||||
Auf dem Zielsystem werden vorbereitet:
|
||||
|
||||
- Verwaltungsschluessel installieren
|
||||
- optional dedizierten Verwaltungsbenutzer anlegen
|
||||
- Basisverzeichnisse anlegen
|
||||
- Systemvoraussetzungen pruefen
|
||||
|
||||
### 5. Basisinstallation
|
||||
|
||||
Installiert werden mindestens:
|
||||
|
||||
- noetige Systempakete
|
||||
- X11-Minimalstack
|
||||
- Chromium
|
||||
- Player-Agent
|
||||
- Player-UI oder deren Artefakte
|
||||
- systemd-Units
|
||||
|
||||
### 6. Screen-Konfiguration
|
||||
|
||||
Ausgerollt werden mindestens:
|
||||
|
||||
- `screen_id`
|
||||
- Server-URL
|
||||
- MQTT-Parameter
|
||||
- Orientierung und Rotation
|
||||
- Snapshot-Intervall
|
||||
- Fallback-Verzeichnis
|
||||
- Gruppen oder Zielprofile
|
||||
|
||||
### 7. Verifikation
|
||||
|
||||
Der Job prueft mindestens:
|
||||
|
||||
- Dienste laufen
|
||||
- lokaler Player-Endpunkt ist erreichbar
|
||||
- Agent registriert sich am Server
|
||||
- Heartbeat kommt an
|
||||
- Screenshot oder Statusmeldung funktioniert
|
||||
|
||||
### 8. Abschluss
|
||||
|
||||
Der Provisionierungsjob wird als erfolgreich markiert und der Screen ist regulär verwaltbar.
|
||||
|
||||
## Sicherheitsmodell
|
||||
|
||||
### Bootstrap-Geheimnisse
|
||||
|
||||
Regeln:
|
||||
|
||||
- Root-Passwoerter nicht dauerhaft im Klartext speichern
|
||||
- wenn Speicherung noetig ist, nur kurzlebig und stark geschuetzt
|
||||
- besser: nur Referenz auf temporären Secret-Speicher
|
||||
|
||||
### Verwaltung nach Erstinstallation
|
||||
|
||||
Nach erfolgreicher Provisionierung gilt:
|
||||
|
||||
- weitere Verwaltung nur noch per SSH-Key
|
||||
- der Screen besitzt eine technische Geraeteidentitaet
|
||||
- API- und MQTT-Zugangsdaten sind geraetebezogen
|
||||
|
||||
### Protokollierung
|
||||
|
||||
Jeder Provisionierungslauf muss auditierbar sein.
|
||||
|
||||
Mindestens sichtbar:
|
||||
|
||||
- wer den Job gestartet hat
|
||||
- wann er gestartet wurde
|
||||
- fuer welchen Screen
|
||||
- gegen welche Ziel-IP
|
||||
- welche Stage aktiv war
|
||||
- ob Fehler auftraten
|
||||
|
||||
## Skalierung ueber die bestehende Wand hinaus
|
||||
|
||||
Das Modell muss von Anfang an mit mehreren Geraetetypen umgehen koennen.
|
||||
|
||||
### Heute
|
||||
|
||||
- 9 Displays in der Infowand, Hochformat
|
||||
|
||||
### Perspektivisch
|
||||
|
||||
- mindestens 4 zusaetzliche Vertretungsplan-Anzeigen, Querformat
|
||||
- eventuell weitere Einzelanzeigen
|
||||
|
||||
Konsequenz:
|
||||
|
||||
- Provisionierung darf nicht implizit von einer 3x3-Wand ausgehen
|
||||
- Gruppen, Klassen, Orientierung und technische Defaults muessen explizit modelliert werden
|
||||
|
||||
## Ansible-Rolle `signage_provision`
|
||||
|
||||
Die Provisionierung sollte auf einer eigenen Rolle oder einem eigenen Playbook aufbauen.
|
||||
|
||||
Sinnvolle Teilbereiche:
|
||||
|
||||
- `bootstrap`
|
||||
- `base`
|
||||
- `display`
|
||||
- `player`
|
||||
- `verify`
|
||||
|
||||
Damit bleibt die Erstinstallation klar getrennt von spaeteren Updates.
|
||||
|
||||
## Fehlerfaelle
|
||||
|
||||
Der Jobrunner soll Fehler moeglichst frueh und verstaendlich melden.
|
||||
|
||||
Typische Fehlerfaelle:
|
||||
|
||||
- Host nicht erreichbar
|
||||
- falsches Passwort
|
||||
- SSH blockiert
|
||||
- unpassendes Betriebssystem
|
||||
- Paketinstallation fehlgeschlagen
|
||||
- Chromium oder X11 startet nicht
|
||||
- Player-Agent registriert sich nicht
|
||||
|
||||
Zu jedem Fehler soll sichtbar sein:
|
||||
|
||||
- Stage
|
||||
- kurzer Fehlertext
|
||||
- ob Retry sinnvoll ist
|
||||
|
||||
## Zielbild im Admin-Backend
|
||||
|
||||
Die UI fuer neue Screens sollte mindestens enthalten:
|
||||
|
||||
- Screen anlegen
|
||||
- Klasse waehlen
|
||||
- Orientierung waehlen
|
||||
- Rotation festlegen oder automatisch vorbelegen
|
||||
- Tenant zuordnen
|
||||
- IP und Bootstrap-Zugang angeben
|
||||
- Provisionierungsjob starten
|
||||
- Fortschritt live oder halb-live sehen
|
||||
- Erfolg/Fehler mit Details sehen
|
||||
|
||||
## Spaetere Erweiterungen
|
||||
|
||||
Moegliche Ausbaustufen:
|
||||
|
||||
- Provisionierung ohne Passwort nur mit Bootstrap-Key
|
||||
- Zero-touch-Registrierung ueber vorbereitete Images
|
||||
- automatische Gruppenzuordnung nach Klasse
|
||||
- Massenprovisionierung mehrerer Screens
|
||||
- Neu-Provisionierung oder Rebuild eines bestehenden Screens
|
||||
|
||||
## Fazit
|
||||
|
||||
Provisionierung ist nicht nur Deployment, sondern ein eigener fachlicher Workflow.
|
||||
|
||||
Wesentliche Grundpfeiler sind:
|
||||
|
||||
- Admin-gesteuerter Start
|
||||
- Ansible-/SSH-basierte reproduzierbare Ausbringung
|
||||
- explizite Orientierung und Rotation pro Screen
|
||||
- Unterstuetzung fuer Wand-Screens und Einzelanzeigen
|
||||
- sichere Umstellung von Bootstrap-Zugang auf dauerhafte schluesselbasierte Verwaltung
|
||||
277
docs/TEMPLATE-KONZEPT.md
Normal file
277
docs/TEMPLATE-KONZEPT.md
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
# Info-Board Neu - Template- und Kampagnenkonzept
|
||||
|
||||
## Ziel
|
||||
|
||||
Dieses Dokument konkretisiert die globale Orchestrierung im Admin-Backend.
|
||||
|
||||
Es geht um drei Kernpunkte:
|
||||
|
||||
1. Template-Typen und ihr fachlicher Zweck
|
||||
2. Konfiguration und Bearbeitung dieser Templates
|
||||
3. Zielmodell fuer Monitorwand, Einzelanzeigen und Aktivierung als Kampagne
|
||||
|
||||
Das Ziel ist, dass globale Inhalte von Anfang an sauber in das Systemmodell integriert sind und nicht spaeter als Sonderfall angebaut werden muessen.
|
||||
|
||||
## 1. Template-Typen
|
||||
|
||||
### `message_wall`
|
||||
|
||||
Dieser Typ dient fuer grosse monitoruebergreifende Botschaften.
|
||||
|
||||
Typische Beispiele:
|
||||
|
||||
- `SCHOENE FERIEN`
|
||||
- `MORZ-INFO`
|
||||
- `WEIHNACHTSFEIER`
|
||||
|
||||
Eigenschaften:
|
||||
|
||||
- ein Gesamtmotiv oder Gesamttext wird auf mehrere Displays verteilt
|
||||
- jedes Display zeigt nur einen Ausschnitt oder einen zugewiesenen Teil des Gesamtlayouts
|
||||
- sinnvoll vor allem fuer die bestehende Infowand mit hochkant montierten Bildschirmen
|
||||
|
||||
Technische Anforderungen:
|
||||
|
||||
- logisches Slot-Modell fuer die Wand
|
||||
- definierte Zielgruppe von Screens
|
||||
- klare Zuordnung `welcher Ausschnitt auf welchem Screen`
|
||||
|
||||
### `full_screen_media`
|
||||
|
||||
Dieser Typ dient fuer ein identisches oder pro Zielgeraet passend skaliertes Vollbildmotiv.
|
||||
|
||||
Typische Beispiele:
|
||||
|
||||
- Weihnachtsmotiv auf allen Screens
|
||||
- Sommerferiengrafik
|
||||
- Veranstaltungslogo
|
||||
- identisches Informationsvideo auf mehreren Displays
|
||||
|
||||
Eigenschaften:
|
||||
|
||||
- alle ausgewaehlten Monitore zeigen denselben fachlichen Inhalt
|
||||
- die technische Darstellung kann je nach Ausrichtung variieren
|
||||
- ideal fuer schnelle globale Uebersteuerungen
|
||||
|
||||
Technische Anforderungen:
|
||||
|
||||
- medientypgerechte Darstellung fuer Hoch- und Querformat
|
||||
- optionale getrennte Assets pro Orientierungsgruppe
|
||||
- einfache Aktivierung/Deaktivierung im Admin-Backend
|
||||
|
||||
### `screen_specific_scene`
|
||||
|
||||
Dieser Typ dient fuer kampagnenweite, aber monitorindividuelle Szenen.
|
||||
|
||||
Typische Beispiele:
|
||||
|
||||
- auf der Infowand ein Schriftzug
|
||||
- auf zusaetzlichen Vertretungsplan-Anzeigen parallel ein passendes Seitenlayout
|
||||
- auf bestimmten Screens ein Veranstaltungsprogramm, auf anderen ein Wegweiser
|
||||
|
||||
Eigenschaften:
|
||||
|
||||
- ein Template besteht aus mehreren gezielten Szenen
|
||||
- jede Szene ist bestimmten Screens, Gruppen oder Slots zugeordnet
|
||||
- hoechste Flexibilitaet fuer spaetere Ausbaustufen
|
||||
|
||||
Technische Anforderungen:
|
||||
|
||||
- Zuordnung zu konkreten Screens oder Gruppen
|
||||
- getrennte Assets je Zielgeraet moeglich
|
||||
- definierte Prioritaet gegenueber tenantbezogenem Content
|
||||
|
||||
## 2. Template-Konfiguration im Admin-Backend
|
||||
|
||||
### Grundaufbau eines Templates
|
||||
|
||||
Ein Template besteht mindestens aus:
|
||||
|
||||
- technischem Namen (`slug`)
|
||||
- Anzeigenamen
|
||||
- Template-Typ
|
||||
- Beschreibung
|
||||
- Zieldefinition
|
||||
- einem oder mehreren Szenen-/Medieneintraegen
|
||||
- optionalen Standardwerten fuer Dauer, Timeouts und Fehlerverhalten
|
||||
|
||||
### Konfigurierbare Felder
|
||||
|
||||
Pro Template sollen mindestens pflegbar sein:
|
||||
|
||||
- `name`
|
||||
- `slug`
|
||||
- `description`
|
||||
- `template_type`
|
||||
- Standarddauer
|
||||
- Standard-Timeout
|
||||
- Standard-Fehlerstrategie
|
||||
- Zielmenge (`alle Screens`, `Screen-Gruppe`, `einzelne Screens`, `Wall-Slots`)
|
||||
|
||||
### Szenen-/Asset-Konfiguration
|
||||
|
||||
Pro Szene oder Teilbereich sollen mindestens konfigurierbar sein:
|
||||
|
||||
- Medientyp (`image`, `video`, `pdf`, `web`, `html`)
|
||||
- Quelle oder Asset
|
||||
- Dauer
|
||||
- `valid_from`
|
||||
- `valid_until`
|
||||
- Fehlerverhalten
|
||||
- Zielscreen oder Zielslot
|
||||
- Layout-Metadaten
|
||||
|
||||
### Aktivierung als Kampagne
|
||||
|
||||
Templates werden nicht direkt abgespielt, sondern als Kampagnen aktiviert.
|
||||
|
||||
Eine Kampagne ist die operative Auspraegung eines Templates und enthaelt:
|
||||
|
||||
- Name der Kampagne
|
||||
- referenziertes Template
|
||||
- Prioritaet
|
||||
- Aktiv-Status
|
||||
- `valid_from`
|
||||
- `valid_until`
|
||||
- Zielmenge
|
||||
- Override-Modus
|
||||
|
||||
### Wichtige Admin-Funktionen
|
||||
|
||||
Im Admin-Backend soll es dafuer geben:
|
||||
|
||||
- Template-Liste
|
||||
- Template-Editor
|
||||
- Kampagnenliste
|
||||
- Aktivieren/Deaktivieren auf Knopfdruck
|
||||
- Zeitgesteuerte Aktivierung
|
||||
- Vorschau, welche Screens betroffen sind
|
||||
- Anzeige, welche Screens aktuell von einer Kampagne uebersteuert werden
|
||||
|
||||
## 3. Zielmodell fuer Monitorwand und Einzelanzeigen
|
||||
|
||||
## Ausgangslage
|
||||
|
||||
Das System darf nicht auf die aktuelle 9er-Infowand beschraenkt bleiben.
|
||||
|
||||
Perspektivisch sind mindestens zwei Klassen von Displays zu erwarten:
|
||||
|
||||
- Infowand-Screens im Hochformat
|
||||
- zusaetzliche Einzelanzeigen wie Vertretungsplan-Displays im Querformat
|
||||
|
||||
Deshalb wird von Anfang an zwischen logischem Ziel und physischer Darstellung unterschieden.
|
||||
|
||||
### Screen-Klassen
|
||||
|
||||
Sinnvolle fachliche Klassen:
|
||||
|
||||
- `info_wall`
|
||||
- `single_info_display`
|
||||
- `vertretungsplan_display`
|
||||
|
||||
Diese Klassen koennen spaeter fuer Voreinstellungen, Templates und Provisionierung genutzt werden.
|
||||
|
||||
### Orientierung als Kernattribut
|
||||
|
||||
Jeder Screen braucht von Anfang an eine fest definierte Orientierung.
|
||||
|
||||
Mindestens:
|
||||
|
||||
- `portrait`
|
||||
- `landscape`
|
||||
|
||||
Optional spaeter:
|
||||
|
||||
- exakte Rotation `0`, `90`, `180`, `270`
|
||||
|
||||
Warum das wichtig ist:
|
||||
|
||||
- Assets muessen passend skaliert oder getrennt gepflegt werden
|
||||
- globale Kampagnen koennen fuer Hoch- und Querformat unterschiedliche Szenen brauchen
|
||||
- Provisionierung und Display-Setup muessen die Orientierung kennen
|
||||
|
||||
### Gruppen- und Slot-Modell
|
||||
|
||||
Es werden zwei Zielmodelle parallel unterstuetzt.
|
||||
|
||||
#### Gruppenmodell
|
||||
|
||||
Gruppen fassen Screens logisch zusammen, z. B.:
|
||||
|
||||
- `all`
|
||||
- `wall-all`
|
||||
- `wall-row-1`
|
||||
- `vertretungsplan-all`
|
||||
|
||||
Dieses Modell ist ideal fuer:
|
||||
|
||||
- globale Motive
|
||||
- saisonale Kampagnen
|
||||
- Massenaktionen im Admin-Bereich
|
||||
|
||||
#### Slot-Modell
|
||||
|
||||
Slots beschreiben feste Positionen innerhalb einer Monitorwand.
|
||||
|
||||
Beispiele:
|
||||
|
||||
- `wall-r1-c1`
|
||||
- `wall-r1-c2`
|
||||
- `wall-r1-c3`
|
||||
- `wall-r2-c1`
|
||||
|
||||
Dieses Modell ist ideal fuer:
|
||||
|
||||
- verteilte Schriftzuege
|
||||
- zusammengesetzte Grossmotive
|
||||
- geordnete Layouts ueber mehrere Screens
|
||||
|
||||
### Empfohlene Grundregel fuer Kampagnen
|
||||
|
||||
Jede Kampagne definiert ihren Zielraum explizit:
|
||||
|
||||
- `all_screens`
|
||||
- `screen_group`
|
||||
- `specific_screens`
|
||||
- `wall_slots`
|
||||
|
||||
Die Inhaltsprioritaet bleibt dabei immer:
|
||||
|
||||
1. aktive Kampagne
|
||||
2. tenantbezogene Playlist
|
||||
3. Fallback
|
||||
|
||||
### Beispiel 1 - Schriftzug ueber die Infowand
|
||||
|
||||
- Template-Typ: `message_wall`
|
||||
- Ziel: Gruppe `wall-all`
|
||||
- Layout: Text wird in neun Segmente geteilt
|
||||
- jeder Slot bekommt seinen Ausschnitt
|
||||
- die 4 kuenftigen Vertretungsplan-Screens bleiben unberuehrt
|
||||
|
||||
### Beispiel 2 - Weihnachtsmotiv auf allen Screens
|
||||
|
||||
- Template-Typ: `full_screen_media`
|
||||
- Ziel: Gruppe `all`
|
||||
- fuer Portrait-Screens wird Portrait-Asset verwendet
|
||||
- fuer Landscape-Screens wird Landscape-Asset verwendet
|
||||
|
||||
### Beispiel 3 - Veranstaltungstag mit gemischten Anzeigen
|
||||
|
||||
- Template-Typ: `screen_specific_scene`
|
||||
- Infowand zeigt Event-Motto
|
||||
- Vertretungsplan-Screens zeigen Programm oder Wegweiser
|
||||
- alles als eine Kampagne administrierbar
|
||||
|
||||
## Auswirkung auf Datenmodell und Implementierung
|
||||
|
||||
Von Beginn an mitzudenken sind:
|
||||
|
||||
- Template-Typen
|
||||
- Kampagnen als aktivierbare Instanzen
|
||||
- Gruppenmodell
|
||||
- Slot-Modell fuer die Wand
|
||||
- Orientierung pro Screen
|
||||
- moegliche getrennte Assets fuer Portrait und Landscape
|
||||
|
||||
Damit ist die globale Orchestrierung ein tragender Bestandteil des Systems und kein nachtraeglicher Sonderbau.
|
||||
Loading…
Add table
Reference in a new issue