Player-UI (playerserver): - Lokale Kiosk-Seite unter /player mit orientierungsgerechtem Splash-Bild - Splash-PNGs (Portrait/Landscape) eingebettet via go:embed - Unteres-Drittel-Overlay mit erweiterbaren Sysinfo-Items (Hostname, Uptime) - /api/now-playing und /api/sysinfo JSON-Endpunkte - iframe-Overlay fuer spaetere Inhalts-URL Ansible-Rolle signage_display (neu): - Pakete: xserver-xorg-core, xinit, openbox, chromium, unclutter - Kiosk-Skript mit openbox als WM (noetig fuer korrektes --kiosk-Vollbild) - systemd-Unit mit Conflicts=getty@tty1 (behebt TTY-Blockierung beim Start) - Chromium Managed Policy: TranslateEnabled=false, Notifications/Geolocation blockiert - --lang=de Flag gegen Sprachauswahl-Dialog Ansible-Rolle signage_player (erweitert): - Legt signage_user an falls nicht vorhanden - PlayerListenAddr und PlayerContentURL in Konfiguration - journald volatile Storage (SD-Karten-Schonung) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
10 KiB
Info-Board Neu - Entwicklung
Ziel
Dieses Dokument soll den Einstieg auf einem anderen Entwicklungsrechner moeglichst reibungsfrei machen.
Es beschreibt:
- minimale Voraussetzungen
- wichtige Verzeichnisse
- Build- und Run-Kommandos
- aktuelle Annahmen fuer den lokalen Entwicklungsbetrieb
Repository
- Remote:
git.az-it.net:az/morz-infoboard.git - Standard-Branch:
main
Projektwurzel:
/srv/docker/info-board-neu
Wichtige Verzeichnisse
docs/fuer Architektur- und Fachkonzepteserver/backend/fuer das zentrale Go-Backendplayer/agent/fuer den Go-basierten Player-Agentansible/fuer Deployment und Provisionierungcompose/spaeter fuer den zentralen Server-Stack
Aktueller Entwicklungsstand
Bereits vorhanden:
- fachliche Architektur- und Betriebskonzepte
- relationaler Schema-Entwurf in
docs/SCHEMA.md - erstes Go-Geruest fuer
server/backend - erstes Go-Geruest fuer
player/agent
Noch nicht vorhanden:
- produktive API-Endpunkte mit Datenbankanbindung
- Player-Sync und Playlist-Management
- Compose-Stack fuer lokale Serverdienste (Grundgeruest liegt in
compose/)
Voraussetzungen auf dem Entwicklungsrechner
Mindestens empfohlen:
gitgoin Version1.24.xmake
Spaeter zusaetzlich sinnvoll:
dockerunddocker composepostgresql-clientmosquitto-clientsgolangci-lint
Fuer Container-Builds liegen erste Dockerfiles in:
server/backend/Dockerfileplayer/agent/Dockerfile
Schnellstart
Repository klonen:
git clone git.az-it.net:az/morz-infoboard.git
cd morz-infoboard
Dokumentationsbasis lesen:
README.mdPLAN.mdTECH-STACK.mddocs/SCHEMA.mddocs/OFFENE-ARCHITEKTURFRAGEN.mddocs/LAYOUT-JSON.md
Build-Kommandos
Backend bauen
cd server/backend
go build ./...
Agent bauen
cd player/agent
go build ./...
Alternativ ueber Makefile
make build
Aktuell bedeutet das:
make buildbaut Backend und Agentmake build-backendbaut nurserver/backendmake build-agentbaut nurplayer/agentmake run-backendstartet das Backendmake run-agentstartet den Agentenmake fmtformatiert beide Go-Modulemake lintprueft beide Go-Module mitgolangci-lint
Hinweis:
- auf dem aktuellen System dieser Session sind
makeundgonicht installiert; die Befehle sind fuer den Entwicklungsrechner vorbereitet
Lokaler Start
Backend lokal starten
cd server/backend
go run ./cmd/api
Standard:
- HTTP-Adresse:
:8080 - Health-Endpunkt:
GET /healthz - Basis-Endpunkt:
GET /api/v1
Konfigurierbar ueber:
MORZ_INFOBOARD_HTTP_ADDR– HTTP-Adresse (Standard::8080)MORZ_INFOBOARD_STATUS_STORE_PATH– Pfad zur JSON-Datei fuer persistenten Status-Store; leer lassen fuer reinen In-Memory-Betrieb
Beispiele:
MORZ_INFOBOARD_HTTP_ADDR=:18080 go run ./cmd/api
MORZ_INFOBOARD_HTTP_ADDR=:8080 \
MORZ_INFOBOARD_STATUS_STORE_PATH=/tmp/screen-status.json \
go run ./cmd/api
Agent lokal starten
cd player/agent
go run ./cmd/agent
Standardwerte:
MORZ_INFOBOARD_SCREEN_ID=unset-screenMORZ_INFOBOARD_SERVER_URL=http://127.0.0.1:8080MORZ_INFOBOARD_MQTT_BROKER=(leer = MQTT wird uebersprungen)MORZ_INFOBOARD_PLAYER_ADDR=127.0.0.1:8090MORZ_INFOBOARD_PLAYER_CONTENT_URL=(leer = kein Inhalt eingebettet)
Optional:
MORZ_INFOBOARD_MQTT_USERNAME– MQTT-BenutzernameMORZ_INFOBOARD_MQTT_PASSWORD– MQTT-PasswortMORZ_INFOBOARD_CONFIG=/etc/signage/config.json– dateibasierte Konfiguration
Eine Beispielkonfiguration liegt in player/config/config.example.json.
Der Agent stellt unter http://127.0.0.1:8090/player eine lokale Kiosk-Seite bereit.
Beispiel ohne MQTT:
MORZ_INFOBOARD_SCREEN_ID=info01-dev \
MORZ_INFOBOARD_SERVER_URL=http://127.0.0.1:8080 \
go run ./cmd/agent
Beispiel mit MQTT:
MORZ_INFOBOARD_SCREEN_ID=info01-dev \
MORZ_INFOBOARD_SERVER_URL=http://127.0.0.1:8080 \
MORZ_INFOBOARD_MQTT_BROKER=tcp://127.0.0.1:1883 \
MORZ_INFOBOARD_MQTT_USERNAME=user \
MORZ_INFOBOARD_MQTT_PASSWORD=pass \
go run ./cmd/agent
Ansible-Deployment auf einen Zielrechner
Der ansible/-Ordner enthaelt ein vollstaendiges Playbook fuer das Deployment auf einen Pi oder ein Debian-System.
Voraussetzungen
- Ansible auf dem Entwicklungsrechner
- SSH-Key fuer den Zielrechner hinterlegt
- Ansible Vault fuer MQTT-Zugangsdaten
Inventory und Konfiguration
ansible/inventory.yml– Hosts und Gruppenansible/host_vars/<host>/vars.yml– host-spezifische Variablen (screen_id,ansible_host,ansible_user)ansible/group_vars/signage_players/vars.yml– globale Defaultsansible/group_vars/signage_players/vault.yml– verschluesselte Zugangsdaten (gitignored)
Vault-Datei anlegen:
ansible-vault create ansible/group_vars/signage_players/vault.yml
Inhalt:
vault_mqtt_username: "benutzername"
vault_mqtt_password: "passwort"
In vars.yml referenzieren:
morz_mqtt_username: "{{ vault_mqtt_username }}"
morz_mqtt_password: "{{ vault_mqtt_password }}"
Deployment ausfuehren
cd ansible
ansible-playbook site.yml -i inventory.yml --ask-vault-pass
Das Playbook erledigt:
- Agent-Binary cross-kompilieren (lokal,
GOOS=linux GOARCH=arm64) - Binary und Konfiguration auf den Zielrechner uebertragen
- systemd-Unit fuer den Agent anlegen und starten
- journald auf RAM-Speicherung konfigurieren (SD-Karte schonen)
- X11-Paketstack und Chromium installieren
- Kiosk-Startskript und systemd-Unit fuer die Anzeige anlegen
Rollen
signage_player– Agent, Konfiguration, systemd-Unit, journaldsignage_display– X11, Chromium, Kiosk-Service
Aktuelle Architekturentscheidungen mit direkter Auswirkung auf Entwicklung
message_wallwird serverseitig in konkrete Screen-Szenen aufgeloest- Kampagnengruppen werden serverseitig in konkrete Screen-Assignments expandiert
playlist_itemshaben im finalen Implementierungsschema keinen direktenscreen_id-Fremdschluessel- Provisionierung wird worker-/jumphost-faehig geplant
- API-Fehler sollen einen einheitlichen Fehlerumschlag nutzen
Empfohlene naechste Implementierungsschritte
- Backend: einheitliches Fehlerformat und Routing-Grundstruktur anlegen
- Backend: Konfigurations- und App-Lifecycle stabilisieren
- Agent und Backend: den HTTP-Statuspfad als Grundlage fuer Identitaet, Persistenz und spaetere Admin-Vorschau erweitern
- Agent: danach MQTT-spezifische Reachability und feinere Connectivity-Schwellenlogik aufsetzen
- Danach die Netzwerk-, Sync- und Kommandopfade schrittweise produktionsnah ausbauen
End-to-End-Entwicklungstest (Backend + Agent)
Backend und Agent koennen lokal gegeneinander laufen. Reihenfolge:
- Backend starten (Terminal 1):
cd server/backend
MORZ_INFOBOARD_STATUS_STORE_PATH=/tmp/screen-status.json go run ./cmd/api
- Agent starten (Terminal 2):
cd player/agent
MORZ_INFOBOARD_SCREEN_ID=info01-dev \
MORZ_INFOBOARD_SERVER_URL=http://127.0.0.1:8080 \
go run ./cmd/agent
- Status pruefen:
# JSON-Uebersicht
curl http://127.0.0.1:8080/api/v1/screens/status
# HTML-Diagnoseseite
open http://127.0.0.1:8080/status
# Einzelner Screen
curl http://127.0.0.1:8080/api/v1/screens/info01-dev/status
# Screen loeschen
curl -X DELETE http://127.0.0.1:8080/api/v1/screens/info01-dev/status
Die Datei /tmp/screen-status.json enthaelt nach dem ersten Heartbeat den persistierten Status-Store.
Ergaenzt seit dem ersten Geruest:
message_wall-Resolver im Backend- Basisendpunkte und
message_wall-Validierung im Backend testseitig breiter abgedeckt - erster
POST /api/v1/player/status-Endpunkt im Backend - letzter bekannter Player-Status wird im Backend pro Screen in-memory vorgehalten und lesbar gemacht
- Backend ergaenzt den Read-Pfad um
received_atund eine einfachestale-Ableitung - Backend bietet zusaetzlich eine kleine Uebersicht aller zuletzt meldenden Screens
- Backend validiert den Statuspfad jetzt enger auf erlaubte Lifecycle-/Connectivity-Werte und leitet
staleaus dem gemeldeten Intervall ab - Backend leitet im Read-Pfad zusaetzlich ein kompaktes
derived_statefuer Diagnosekonsumenten ab - Backend liefert unter
/statuseine erste sichtbare HTML-Diagnoseseite auf Basis derselben Statusdaten, inklusive Auto-Refresh, leichten Filtern und JSON-Drill-down - Backend unterstuetzt
q=(Screen-ID-Substring),derived_state=,server_connectivity=,stale=,updated_since=,limit=als Query-Filter - Backend leitet
derived_state(online / degraded / offline) ausstale,server_connectivityundstatusab - Backend erlaubt das Loeschen einzelner Screen-Eintraege via
DELETE /api/v1/screens/{screenId}/status - Backend persistiert den Status-Store optional in einer JSON-Datei (
MORZ_INFOBOARD_STATUS_STORE_PATH) - dateibasierte Agent-Konfiguration zusaetzlich zu Env-Overrides
- strukturierte Agent-Logs mit internem Health-Snapshot und signalgesteuertem Shutdown
- erster periodischer HTTP-Status-Reporter im Agent
- Server-Connectivity-Zustand im Agent (
unknown,online,degraded,offline) auf Basis der Report-Ergebnisse - der HTTP-Statuspfad transportiert jetzt neben
statusauchserver_connectivity - lokales Compose-Grundgeruest fuer PostgreSQL und Mosquitto
- MQTT-Heartbeat im Agent (optional; wird uebersprungen wenn kein Broker konfiguriert)
- MQTT-Authentifizierung mit Username und Password
- Player-UI im Agent (
/playerHTML-Kiosk,/api/now-playingJSON) - Ansible-Rollen
signage_playerundsignage_displayfuer vollstaendiges Deployment - journald auf volatile Storage konfiguriert (SD-Karte schonen)
Arbeitsweise
Empfohlen:
- kleine, klar umrissene Commits
- zuerst Konzepte anpassen, dann Code
- Schema und API-Vertrag synchron halten
- neue Fachentscheidungen immer in
docs/dokumentieren
Hinweise fuer einen zweiten Entwicklungsrechner
- vor Arbeitsbeginn
git pull --rebaseoder gleichwertig den aktuellen Stand holen - bei paralleler Arbeit zuerst in den Dokumenten pruefen, ob neue Architekturentscheidungen getroffen wurden
- falls lokale Tools abweichen, mindestens
go versionundmake --versionpruefen