morz-infoboard/DEVELOPMENT.md
Jesko Anschütz bbcf0a1228 Baue Ebene 1: Player-UI, Kiosk-Display und vollstaendiges Ansible-Deployment
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>
2026-03-22 22:34:16 +01:00

10 KiB
Raw Blame History

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 Fachkonzepte
  • server/backend/ fuer das zentrale Go-Backend
  • player/agent/ fuer den Go-basierten Player-Agent
  • ansible/ fuer Deployment und Provisionierung
  • compose/ 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:

  • git
  • go in Version 1.24.x
  • make

Spaeter zusaetzlich sinnvoll:

  • docker und docker compose
  • postgresql-client
  • mosquitto-clients
  • golangci-lint

Fuer Container-Builds liegen erste Dockerfiles in:

  • server/backend/Dockerfile
  • player/agent/Dockerfile

Schnellstart

Repository klonen:

git clone git.az-it.net:az/morz-infoboard.git
cd morz-infoboard

Dokumentationsbasis lesen:

  1. README.md
  2. PLAN.md
  3. TECH-STACK.md
  4. docs/SCHEMA.md
  5. docs/OFFENE-ARCHITEKTURFRAGEN.md
  6. docs/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 build baut Backend und Agent
  • make build-backend baut nur server/backend
  • make build-agent baut nur player/agent
  • make run-backend startet das Backend
  • make run-agent startet den Agenten
  • make fmt formatiert beide Go-Module
  • make lint prueft beide Go-Module mit golangci-lint

Hinweis:

  • auf dem aktuellen System dieser Session sind make und go nicht 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-screen
  • MORZ_INFOBOARD_SERVER_URL=http://127.0.0.1:8080
  • MORZ_INFOBOARD_MQTT_BROKER= (leer = MQTT wird uebersprungen)
  • MORZ_INFOBOARD_PLAYER_ADDR=127.0.0.1:8090
  • MORZ_INFOBOARD_PLAYER_CONTENT_URL= (leer = kein Inhalt eingebettet)

Optional:

  • MORZ_INFOBOARD_MQTT_USERNAME MQTT-Benutzername
  • MORZ_INFOBOARD_MQTT_PASSWORD MQTT-Passwort
  • MORZ_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 Gruppen
  • ansible/host_vars/<host>/vars.yml host-spezifische Variablen (screen_id, ansible_host, ansible_user)
  • ansible/group_vars/signage_players/vars.yml globale Defaults
  • ansible/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:

  1. Agent-Binary cross-kompilieren (lokal, GOOS=linux GOARCH=arm64)
  2. Binary und Konfiguration auf den Zielrechner uebertragen
  3. systemd-Unit fuer den Agent anlegen und starten
  4. journald auf RAM-Speicherung konfigurieren (SD-Karte schonen)
  5. X11-Paketstack und Chromium installieren
  6. Kiosk-Startskript und systemd-Unit fuer die Anzeige anlegen

Rollen

  • signage_player Agent, Konfiguration, systemd-Unit, journald
  • signage_display X11, Chromium, Kiosk-Service

Aktuelle Architekturentscheidungen mit direkter Auswirkung auf Entwicklung

  • message_wall wird serverseitig in konkrete Screen-Szenen aufgeloest
  • Kampagnengruppen werden serverseitig in konkrete Screen-Assignments expandiert
  • playlist_items haben im finalen Implementierungsschema keinen direkten screen_id-Fremdschluessel
  • Provisionierung wird worker-/jumphost-faehig geplant
  • API-Fehler sollen einen einheitlichen Fehlerumschlag nutzen

Empfohlene naechste Implementierungsschritte

  1. Backend: einheitliches Fehlerformat und Routing-Grundstruktur anlegen
  2. Backend: Konfigurations- und App-Lifecycle stabilisieren
  3. Agent und Backend: den HTTP-Statuspfad als Grundlage fuer Identitaet, Persistenz und spaetere Admin-Vorschau erweitern
  4. Agent: danach MQTT-spezifische Reachability und feinere Connectivity-Schwellenlogik aufsetzen
  5. Danach die Netzwerk-, Sync- und Kommandopfade schrittweise produktionsnah ausbauen

End-to-End-Entwicklungstest (Backend + Agent)

Backend und Agent koennen lokal gegeneinander laufen. Reihenfolge:

  1. Backend starten (Terminal 1):
cd server/backend
MORZ_INFOBOARD_STATUS_STORE_PATH=/tmp/screen-status.json go run ./cmd/api
  1. 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
  1. 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_at und eine einfache stale-Ableitung
  • Backend bietet zusaetzlich eine kleine Uebersicht aller zuletzt meldenden Screens
  • Backend validiert den Statuspfad jetzt enger auf erlaubte Lifecycle-/Connectivity-Werte und leitet stale aus dem gemeldeten Intervall ab
  • Backend leitet im Read-Pfad zusaetzlich ein kompaktes derived_state fuer Diagnosekonsumenten ab
  • Backend liefert unter /status eine 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) aus stale, server_connectivity und status ab
  • 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 status auch server_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 (/player HTML-Kiosk, /api/now-playing JSON)
  • Ansible-Rollen signage_player und signage_display fuer 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 --rebase oder gleichwertig den aktuellen Stand holen
  • bei paralleler Arbeit zuerst in den Dokumenten pruefen, ob neue Architekturentscheidungen getroffen wurden
  • falls lokale Tools abweichen, mindestens go version und make --version pruefen