Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
12 KiB
Info-Board Neu - API- und MQTT-Vertrag
Ziel
Dieses Dokument beschreibt die technische Arbeitsteilung zwischen HTTPS-API und MQTT.
Grundregel:
- HTTPS fuer Daten, Uploads, Konfiguration und Authentifizierung
- MQTT fuer Ereignisse, Heartbeats, Status und Fernsteuerung
Architekturprinzip
Der Player arbeitet autonom aus lokalem Zustand.
Das bedeutet:
- die API liefert Konfiguration, Playlist und Medieninformationen
- der Player cached diese Daten lokal
- MQTT informiert ueber Aenderungen und traegt leichte Steuerkommandos
- bei Ausfall der Verbindung laeuft der Player mit dem letzten gueltigen Stand weiter
HTTPS-API
Authentifizierung
Die Web-Oberflaechen nutzen benutzerbezogene Sessions oder Tokens.
Die Player nutzen ein geraetebezogenes Token.
Empfohlene Aufteilung:
- Browser-UI: Cookie-Session oder JWT
- Player: statischer oder rotierbarer API-Token je Screen
API-Bereiche
1. Auth
Zweck:
- Login
- Logout
- Session-Pruefung
Beispiel-Endpunkte:
POST /api/v1/auth/loginPOST /api/v1/auth/logoutGET /api/v1/auth/me
2. Tenants und Benutzer
Zweck:
- Verwaltung von Firmen und Benutzern
Beispiel-Endpunkte:
GET /api/v1/tenantsPOST /api/v1/tenantsGET /api/v1/tenants/:tenantId/usersPOST /api/v1/tenants/:tenantId/users
3. Screens
Zweck:
- technische und fachliche Verwaltung der Monitore
Beispiel-Endpunkte:
GET /api/v1/screensGET /api/v1/screens/:screenIdPATCH /api/v1/screens/:screenIdGET /api/v1/screens/:screenId/statusGET /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/provisionGET /api/v1/provisioning-jobsGET /api/v1/provisioning-jobs/:jobIdPOST /api/v1/provisioning-jobs/:jobId/retryPOST /api/v1/provisioning-jobs/:jobId/cancel
4. Medien
Zweck:
- Uploads
- Listenansicht
- Loeschen
- Metadatenbearbeitung
Beispiel-Endpunkte:
GET /api/v1/mediaPOST /api/v1/media/uploadPOST /api/v1/media/import-urlPATCH /api/v1/media/:mediaIdDELETE /api/v1/media/:mediaId
5. Playlists
Zweck:
- Playlist lesen und bearbeiten
- Reihenfolge und Zeitfenster verwalten
Beispiel-Endpunkte:
GET /api/v1/screens/:screenId/playlistPUT /api/v1/screens/:screenId/playlistPOST /api/v1/screens/:screenId/playlist/itemsPATCH /api/v1/screens/:screenId/playlist/items/:itemIdDELETE /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/templatesPOST /api/v1/templatesGET /api/v1/templates/:templateIdPATCH /api/v1/templates/:templateIdPOST /api/v1/templates/:templateId/scenesPATCH /api/v1/templates/:templateId/scenes/:sceneIdPOST /api/v1/campaignsPATCH /api/v1/campaigns/:campaignIdPOST /api/v1/campaigns/:campaignId/activatePOST /api/v1/campaigns/:campaignId/deactivatePUT /api/v1/campaigns/:campaignId/assignments
6. Player-Sync
Zweck:
- geraeteseitiger Abruf von Konfiguration und Daten
- differenzieller Sync ueber Revisionen
Beispiel-Endpunkte:
POST /api/v1/player/registerGET /api/v1/player/configGET /api/v1/player/playlistGET /api/v1/player/campaignGET /api/v1/player/media-manifestGET /api/v1/player/media/:mediaId/downloadPOST /api/v1/player/statusPOST /api/v1/player/snapshot
Aktuelle Entwicklungsstufe
Bevor das volle Player-Sync- und MQTT-Modell umgesetzt ist, existiert fuer die Entwicklung bereits ein bewusst kleiner HTTP-Statuspfad.
Aktuell gilt:
POST /api/v1/player/statusist der erste reale Backend-Agent-Pfad- die Payload enthaelt zunaechst Health- und Laufzeitdaten aus dem Agenten
- das Backend validiert den Request und bestaetigt ihn mit
status=accepted - Persistenz, Authentifizierung und die spaetere Trennung zwischen HTTP-Status und MQTT-Heartbeat folgen in spaeteren Schritten
7. Admin-Kommandos
Zweck:
- Ausloesen von Fernaktionen
Beispiel-Endpunkte:
POST /api/v1/screens/:screenId/commands/reloadPOST /api/v1/screens/:screenId/commands/restart-playerPOST /api/v1/screens/:screenId/commands/rebootPOST /api/v1/screens/:screenId/commands/display-onPOST /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_slugoderdisplay_idscreen_nametenant_idoptional, falls direkt zugeordnet werden solltarget_iptarget_portoptional, Default 22remote_user, Defaultrootauth_modepasswordoderprivate_key_reffuer die Erstverbindung- optionale technische Parameter wie
rotation,resolution,fallback_dir
Serverseitiger Ablauf:
- Screen-Datensatz anlegen
- Provisionierungsjob anlegen
- Secret nur kurzlebig oder referenziert speichern
- Worker/Jobrunner startet Ansible- oder SSH-gestuetzten Rollout
- nach Erfolg meldet sich der Screen kuenftig regulaer ueber seinen Agenten
Antwort mindestens:
screen_idprovisioning_job_idstatus
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
Liefert:
screen_idscreen_slugconfig_revisionplayer_settingsfallback_dirsnapshot_interval_secondsoffline_overlay_enabledrotation
GET /api/v1/player/playlist
Liefert:
playlist_idplaylist_revisiondefault_duration_secondsfallback_enableditems[]
Jedes Item enthaelt mindestens:
idtypesrcduration_secondsload_timeout_secondscache_policyon_errorretry_countvalid_fromvalid_untilenabled
GET /api/v1/player/campaign
Liefert die fuer den Screen aktuell relevante globale Uebersteuerung.
Liefert:
campaign_revisionactive_campaignnullable
Wenn active_campaign gesetzt ist, enthaelt es mindestens:
campaign_idtemplate_idnamepriorityvalid_fromvalid_untiloverride_modescenes[]
Jede Scene enthaelt mindestens:
idtypesrcduration_secondsload_timeout_secondscache_policyon_errorlayout_json
GET /api/v1/player/media-manifest
Liefert:
media_revisionassets[]
Jeder Asset-Eintrag enthaelt mindestens:
idtypesource_kinddownload_urlnullableoriginal_urlnullablechecksumsize_bytesmime_typecache_required
MQTT-Verwendung
MQTT dient nur der schnellen, leichten Signal- und Statuskommunikation.
Nicht ueber MQTT transportieren:
- Datei-Uploads
- grosse JSON-Payloads fuer komplette Medienlisten
- eigentliche Mediendateien
MQTT-Topics
Heartbeat
signage/screen/<screen-id>/heartbeat
Payload-Beispiel:
{
"screen_id": "info01",
"ts": "2026-03-22T12:00:00Z",
"online": true,
"server_connected": true,
"mqtt_connected": true,
"player_version": "0.1.0",
"uptime_seconds": 86400
}
Status
signage/screen/<screen-id>/status
Payload-Beispiel:
{
"screen_id": "info01",
"ts": "2026-03-22T12:00:00Z",
"current_item_id": "pli_123",
"current_item_type": "image",
"current_item_label": "Begruessung",
"current_item_started_at": "2026-03-22T11:59:45Z",
"current_item_duration_seconds": 20,
"overlay_state": "online",
"cache_state": "ok",
"error_code": null,
"error_message": null
}
Events
signage/screen/<screen-id>/event
Typische Events:
playlist_changedcampaign_changedsync_completedsync_faileditem_failedbrowser_restartedsnapshot_uploaded
Commands
signage/screen/<screen-id>/command
Payload-Beispiel:
{
"command_id": "cmd_456",
"type": "reload",
"payload": {},
"requested_at": "2026-03-22T12:00:00Z"
}
ACK
signage/screen/<screen-id>/ack
Payload-Beispiel:
{
"command_id": "cmd_456",
"screen_id": "info01",
"ts": "2026-03-22T12:00:02Z",
"result": "ok",
"message": "playlist reloaded"
}
QoS- und Broker-Hinweise
Empfehlung:
- Heartbeat: QoS 0 oder 1
- Status: QoS 0 oder 1
- Commands: QoS 1
- ACK: QoS 1
Zusatzempfehlungen:
- Last-Will fuer Offline-Erkennung nutzen
- retained Messages nur sparsam und gezielt einsetzen
- kein Missbrauch von retained Commands
Trennung von Pull und Push
Pull ueber HTTPS
Der Player holt aktiv:
- Konfiguration
- Playlist
- Medienmanifest
- eigentliche Medien
Push ueber MQTT
Der Server signalisiert aktiv:
- es gibt neue Konfiguration
- 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:
- Benutzer speichert Playlist in der Web-UI
- Server erhoeht
playlist_revision - Server sendet Event oder Command
reload - Player ruft
GET /api/v1/player/playlistab - Player synchronisiert fehlende Medien
- Player bestaetigt erfolgreichen Reload
Beispielablauf bei Aktivierung einer globalen Kampagne:
- Admin aktiviert eine Kampagne
- Server erhoeht
campaign_revision - Server sendet Event oder Command
reload - Player ruft
GET /api/v1/player/campaignab - Player synchronisiert kampagnenbezogene Medien
- Player setzt den Inhaltsmodus auf
campaign - Nach Deaktivierung oder Ablauf faellt der Player wieder auf
tenant_playlistoderfallbackzurueck
Offline-Verhalten
Wenn HTTPS ausfaellt
- Player nutzt letzte lokale Konfiguration
- Player nutzt letzte lokale Playlist
- Player nutzt lokalen Mediencache
- Overlay signalisiert Offline-Zustand
Wenn MQTT ausfaellt
- Player laeuft normal weiter
- periodischer HTTPS-Sync erkennt spaetere Aenderungen trotzdem
- Admin-Kommandos werden ggf. verzoegert, aber nicht die Anzeige selbst
Wenn beides ausfaellt
- Player bleibt autonom betriebsfaehig
- keine frischen Inhalte oder Befehle mehr
- bestehende Playlist/Fallback laufen weiter
Web-Inhalte und Fehlerstrategie
Webseiten sind der stoeranfaelligste Medientyp.
Regeln:
- Chromium zeigt immer nur die lokale
player-ui player-uibettet Web-Inhalte kontrolliert ein- jedes Web-Item hat einen
load_timeout_seconds - bei Fehler gilt
on_error
Typische Fehlerpfade:
- 404 oder DNS-Problem ->
skipoderfallback - langsamer Ladevorgang -> Timeout ->
retryoderskip - Renderer-Fehler -> lokaler Watchdog startet den Renderer neu
Screenshot-Upload
Der Player erstellt Screenshots:
- bei Item-Wechsel
- zyklisch
- auf Admin-Anforderung
Ablauf:
- Player erzeugt Bild lokal
- Player sendet es per HTTPS an
POST /api/v1/player/snapshot - Server speichert das Bild und aktualisiert die letzte Vorschau des Screens
Sicherheitsgrundsaetze
- jeder Player hat eine eigene technische Identitaet
- API und MQTT werden authentifiziert
- Tenant-Benutzer sehen nur tenantbezogene Objekte
- Admin-Kommandos werden serverseitig protokolliert
- Screenshots und Statusdaten sind nur fuer berechtigte Nutzer sichtbar
Minimale API-Frequenzen
Sinnvolle Startwerte:
- Heartbeat alle 30 Sekunden
- Status-Update bei Item-Wechsel und zusaetzlich alle 60 Sekunden
- Konfigurations-/Playlist-Poll als Fallback alle 5 Minuten
- Snapshot alle 60 Sekunden oder bei Item-Wechsel
V1-Abgrenzung
Fuer Version 1 bewusst nicht zwingend enthalten:
- Live-Video-Stream der Monitore
- komplexe Kampagnenlogik mit Prioritaeten
- Multi-Screen-Synchronisation auf Frame-Ebene
- serverseitiges Video-Transcoding
Empfohlene naechste Dokumente
Als direkte Folge sollten entstehen:
- technisches Player-Konzept
- Server-Komponentenplan
- Ansible-Deploymentplan
- Rechte- und Authentifizierungskonzept