Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Hannah WebUI

pipeline status Latest Release

Flask-Verwaltungsoberfläche für Hannah — Räume/Gruppen-, Satelliten-, User-, Settings- und Trigger-Verwaltung, plus eine Self-Service-Startseite für alle Bewohner (Passwort, Telegram-Verknüpfung, Wecker, Nachrichten). Spricht ausschließlich per gRPC mit Hannah Core — kein direkter DB-/Dateizugriff, Core bleibt alleiniger Owner aller Daten.

Extrahiert aus dem Hannah-Monorepo (webui/), siehe CHANGELOG.md. Architektur-/Protokoll-Hintergrund zu Hannah Core: CLAUDE.md.


Was kann die WebUI?

  • Räume & Gruppen — Räume read-only anzeigen, Gruppen anlegen/bearbeiten/löschen und Satelliten zuweisen
  • Satelliten — einem Raum zuordnen, Anzeigenamen setzen
  • Trigger — Wenn/Und/Außer-wenn/Dann-Regelbuilder (Bedingungstyp state/time/phrase), löste die frühere separate Routinen-Verwaltung ab
  • Settings — No-Code-Editor für Core-Settings, Render-Typ (Text/Zeilen-Builder/Key-Value/rohes JSON) wird automatisch aus der Werteform abgeleitet
  • BLE-Tags & Fahrzeuge — CRUD inkl. Owner-Zuweisung
  • Nutzerverwaltung — User anlegen/bearbeiten/löschen, Trust-Level setzen, mit Residents verknüpfen
  • Verlauf — eigene geloggte Interaktionen (Transkript, Kanal, Intent, Antworttext) mit Audio-Wiedergabe; Trust-Level 10 sieht wahlweise den Verlauf anderer User
  • Nachrichten — passive Mailbox mit Antwort-Flow, Badge mit ungelesener Anzahl in der Navigation
  • Self-Service (/me) — eigenes Passwort ändern, Telegram-Konto verknüpfen/trennen (bevorzugt per Deep-Link zum Bot, sobald Core einen verbundenen Telegram-Adapter meldet; sonst über das Login Widget, WebUI verifiziert die Signatur selbst), Microsoft-Entra-Konto verknüpfen/trennen (OIDC-Login, Objekt-ID oid landet als entra-Account in Core), Wecker verwalten

Ausführliche Bedienungsanleitung je Seite: docs/usage.md.


Seiten-Übersicht & Berechtigungen

Jeder Nutzer braucht einen Hannah-Core-Account; der Zugriff auf Admin-Seiten ist per Trust-Level gestaffelt (hannah_webui/extensions.py: TRUST_LEVELS). Self-Service-Seiten (/me, /messages) sind für jeden eingeloggten User offen.

Seite Route Min. Trust-Level
Startseite / Self-Service /me jeder eingeloggte User
Nachrichten /messages jeder eingeloggte User
Verlauf (eigener) /activity-log jeder eingeloggte User
Verlauf (fremder, per Filter) /activity-log 10
Räume /rooms 3
Satelliten /satellites 5
Trigger anzeigen /triggers 5
Trigger anlegen/bearbeiten/löschen /triggers/... 7
Gruppen, Settings, BLE-Tags, Fahrzeuge, User /groups, /settings, /ble-tags, /cars, /users 10

Architektur

Flask-App-Factory (create_app, hannah_webui/app.py) registriert einen Blueprint je Routen-Gruppe (hannah_webui/blueprints/), hängt den gRPC-Client als app.extensions["hannah"] ein und rendert bei nicht erreichbarer Core eine eigene Fehlerseite statt eines 500ers. Session-basiertes Login gegen Core's Login-RPC. Details, gRPC-Client-Methoden, Blueprint-Liste: CLAUDE.md.


Voraussetzungen

  • Eine erreichbare Hannah-Core-Instanz (gRPC) — siehe Hannah-Repo
  • Python 3.11+ (nur für lokale Entwicklung/systemd-Deployment, nicht für Docker nötig)

Lokale Entwicklung

python -m venv venv
venv/Scripts/pip install -r requirements.txt -r tests/requirements-test.txt
cp config.example.yaml config.yaml   # secret_key + gRPC-Host anpassen
venv/Scripts/python main.py

Tests:

pytest tests/ -v

tests/ nutzt FakeHannahClient, einen In-Memory-Stand-in mit echten hannah_pb2-Messages — keine echte Hannah Core nötig.


Konfiguration

config.yaml (siehe config.example.yaml) oder Env-Vars — welcher Weg gilt, hängt davon ab, ob am gestarteten Pfad eine config.yaml existiert:

host: "127.0.0.1"
port: 5000

# Signiert die Flask-Session-Cookie — muss über alle gunicorn-Worker und
# Neustarts hinweg stabil sein, sonst werden Nutzer zufällig ausgeloggt.
# Generieren mit: python3 -c "import secrets; print(secrets.token_hex(32))"
secret_key: "..."

# Telegram Login Widget (Account-Verknüpfung in /me) — Bot-Token via
# @BotFather, Domain muss dort per /setdomain auf diese WebUI-Instanz
# freigeschaltet sein.
telegram_bot_token: ""
telegram_bot_username: ""

# Microsoft Entra (Account-Verknüpfung in /me, OIDC-Login) — Single-Tenant-App-
# Registration mit Client-Secret, keine API-Permissions nötig. Redirect-URI (Typ
# "Web") dort eintragen: https://<webui-host>/me/entra/callback
entra_client_id: ""
entra_client_secret: ""
entra_tenant: ""    # Tenant-ID (GUID)

grpc:
  host: "127.0.0.1"
  port: 50051

# Native TLS-Terminierung (#61), z.B. fürs Telegram-Login-Widget in /me (verlangt
# HTTPS). Bei leerem cert_file/key_file wird beim ersten Start ein selbstsigniertes
# Zertifikat generiert und dauerhaft persistiert (Neustarts erzeugen es nie neu).
tls:
  enabled: false
  cert_file: ""
  key_file: ""

Äquivalente Env-Vars (Docker-Pfad, kein config.yaml im Image): HANNAH_WEBUI_SECRET_KEY, HANNAH_WEBUI_TELEGRAM_BOT_TOKEN, HANNAH_WEBUI_TELEGRAM_BOT_USERNAME, HANNAH_WEBUI_ENTRA_CLIENT_ID, HANNAH_WEBUI_ENTRA_CLIENT_SECRET, HANNAH_WEBUI_ENTRA_TENANT, HANNAH_WEBUI_GRPC_HOST, HANNAH_WEBUI_GRPC_PORT, HANNAH_WEBUI_TLS_ENABLED, HANNAH_WEBUI_TLS_CERT_FILE, HANNAH_WEBUI_TLS_KEY_FILE. HANNAH_WEBUI_HOST/HANNAH_WEBUI_PORT existieren zwar auch, wirken aber nur bei main.py (lokaler Dev-Server) — der Docker-Entrypoint wsgi.py liest cfg.host/cfg.port gar nicht, die Bind-Adresse steckt fest in gunicorn.conf.py (0.0.0.0:5000, siehe unten).

Das selbstsignierte TLS-Zertifikat landet standardmäßig unter /var/lib/hannah-webui/tls/ (systemd) bzw. /data/tls/ (Docker, siehe docker-compose.example.yml für den nötigen Volume-Mount) — beides Pfade, die Updates/Neustarts überstehen. Ein eigenes Cert/Key lässt sich über cert_file/key_file bzw. die Env-Vars stattdessen fest hinterlegen.


Deployment

Zwei unabhängige Wege, kein Auto-Update beim Container-Pfad:

systemd

curl -fsSL https://dev.kernstock.net/gessinger/voice/hannah-webui/-/raw/master/deploy/install.sh | sudo bash

Lädt das aktuellste Release vom Hannah Update Server (Channel webui-stable), richtet venv, System-User hannah und den systemd-Service ein. Config danach unter /etc/hannah-webui/config.yaml ablegen und starten:

sudo systemctl enable --now hannah-webui

Erneuter Aufruf des Skripts aktualisiert auf die neueste Version; --uninstall entfernt den Service (Config bleibt erhalten). Im laufenden Betrieb hält AutoDeploy (hannah-autodeploy) die Installation automatisch aktuell: pollt den Update Server auf Channel webui-stable, tauscht Dateien, führt pip install -r requirements.txt aus und restartet den Service — install.sh ist nur für Erst-Install/manuelle Reinstalls nötig.

Bind-Adresse/Worker-Anzahl stehen in der .service-Unit, nicht in config.yaml (gunicorn bindet den Socket vor dem WSGI-App-Import).

Docker

Multi-Arch-Image (amd64/arm64), Konfiguration ausschließlich per Env-Vars:

docker build -t hannah-webui .
docker run -d \
  -p 5000:5000 \
  -e HANNAH_WEBUI_SECRET_KEY="..." \
  -e HANNAH_WEBUI_GRPC_HOST=hannah-core \
  -e HANNAH_WEBUI_GRPC_PORT=50051 \
  hannah-webui

Beispiel-Compose-Datei: docker-compose.example.yml.


Weiterführend

Aktueller Stand und Änderungshistorie: CHANGELOG.md. Offene Bugs/Features werden als GitLab Issues geführt, nicht hier dupliziert. Architektur-/Entwicklungs-Details: CLAUDE.md.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages