From 3329a5dc5ab012f9bf6ab73c51d8a82ac35561e5 Mon Sep 17 00:00:00 2001 From: Christian Mueller Date: Thu, 23 Apr 2026 23:45:17 +0200 Subject: [PATCH] docs: complete README rewrite with webhook, segments, CSV format, troubleshooting Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 158 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 124 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 7b5c06c..5d4ca27 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,30 @@ # Busylight WLED Controller -Web-Anwendung zur Steuerung von WLED-Busylights basierend auf Microsoft Teams Presence-Status und AIDA-Zeiterfassung. +Web-Anwendung zur Steuerung von WLED-Busylights basierend auf Microsoft Teams Presence-Status, AIDA-Zeiterfassung und Telefonanlage (Webhook). -Jedes WLED-Geraet verfuegt ueber zwei Segmente (oben/unten), die jeweils einem Benutzer zugeordnet werden. Die Farbe des Segments wird automatisch anhand des Anwesenheitsstatus (AIDA) und des Teams-Status gesetzt. +Jedes WLED-Geraet verfuegt ueber zwei Segmente (oben/unten), die jeweils einem Benutzer zugeordnet werden. Die Farbe des Segments wird automatisch anhand des Anwesenheitsstatus (AIDA), des Teams-Status und des Telefonstatus gesetzt. ## Features -- **Dashboard** mit Echtzeit-Uebersicht aller Busylights und deren aktuellem Status +- **Dashboard** mit Echtzeit-Uebersicht aller Busylights (AIDA-, Teams- und Telefon-Status als Badges) - **Benutzer-Verwaltung** mit automatischem Sync aus Azure AD -- **WLED-Geraete** hinzufuegen, bearbeiten, entfernen und Live-Status pruefen (online/offline, LED-Anzahl, Firmware-Version) -- **Zuordnung** von Benutzern zu WLED-Segmenten per Dropdown (statt UUID-Mapping in einer Config-Datei) -- **Farb-Regeln** mit Color-Picker fuer jeden Teams-/Anwesenheitsstatus +- **WLED-Geraete** hinzufuegen, bearbeiten, entfernen mit automatischem Status-Check (online/offline, LED-Anzahl, Firmware) +- **Zuordnung** von Benutzern zu WLED-Segmenten per Dropdown +- **Farb-Regeln** mit Color-Picker fuer jeden Status +- **Telefon-Webhook** fuer Telefonanlage (callstart/callend auf Port 8081) - **Einstellungen** fuer Azure AD, Polling-Intervall und AIDA-CSV-Pfad - **Protokoll** der letzten Statusaenderungen +## Funktionsweise + +| Quelle | Beschreibung | Auswirkung auf WLED | +|--------|-------------|---------------------| +| AIDA Zeiterfassung | Anwesend / Abwesend / Homeoffice | Grundfarbe (gruen / aus / gelb) | +| Microsoft Teams | Verfuegbar / Beschaeftigt / Nicht stoeren / etc. | Farbe wenn anwesend | +| Telefonanlage (Webhook) | Telefoniert / Frei | Rot wenn aktiv, danach zurueck auf AIDA-Status | + +**Prioritaet:** Telefon > Teams > AIDA. Die WLED-Farbe wird nur gesetzt wenn der Mitarbeiter laut AIDA anwesend oder im Homeoffice ist. + ## Voraussetzungen - Linux-Server (Debian 12+/Ubuntu 22.04+) @@ -21,6 +32,7 @@ Jedes WLED-Geraet verfuegt ueber zwei Segmente (oben/unten), die jeweils einem B - Netzwerkzugriff auf die WLED-Geraete (HTTP Port 80) - Azure AD App-Registrierung (siehe unten) - Zugriff auf die AIDA-Zeiterfassungs-CSV (lokal oder per SMB-Mount) +- Optional: Telefonanlage mit Webhook-Unterstuetzung ## Installation @@ -128,38 +140,88 @@ python migrate.py Die alte `config.cfg` wird danach nicht mehr benoetigt. -## AIDA-CSV auf Linux bereitstellen +## AIDA-CSV bereitstellen -Die Zeiterfassungs-CSV liegt typischerweise auf einem Windows-Server. -Fuer den Zugriff von Linux empfiehlt sich ein SMB/CIFS-Mount: +Die Zeiterfassungs-CSV liegt typischerweise auf einem Windows-Server (z.B. `\\192.168.30.224\export`). + +### Option A: Lokale Kopie + +Die CSV-Datei direkt auf den Server kopieren (z.B. per Cronjob/rsync): + +```bash +# CSV-Pfad in den Web-Einstellungen eintragen: +/opt/busylight/Status.csv +``` + +### Option B: SMB/CIFS-Mount ```bash # Paket installieren sudo apt install cifs-utils -# Mount-Punkt erstellen -sudo mkdir -p /mnt/zeiterfassung - -# Credentials-Datei erstellen +# Mount-Punkt und Credentials erstellen +sudo mkdir -p /mnt/aida sudo bash -c 'cat > /etc/samba/creds << EOF -username=DOMAIN\user -password=geheim +username=BENUTZER +password=PASSWORT +domain=DOMAIN EOF' sudo chmod 600 /etc/samba/creds # Eintrag in /etc/fstab (eine Zeile) -# //SERVERNAME/Zeiterfassung /mnt/zeiterfassung cifs credentials=/etc/samba/creds,uid=busylight,gid=busylight,ro 0 0 +# //192.168.30.224/export /mnt/aida cifs credentials=/etc/samba/creds,ro 0 0 # Mounten -sudo mount /mnt/zeiterfassung +sudo mount /mnt/aida ``` +**Hinweis:** In LXC-Containern (Proxmox) muss CIFS-Mount erst in den Container-Features aktiviert werden. + In den Web-Einstellungen dann als CSV-Pfad eintragen: ``` -/mnt/zeiterfassung/Aida/profiles/aida/Transfer/Export/Status.csv +/mnt/aida/Status.csv ``` -Alternativ: Per Cronjob die CSV regelmaessig per `scp` oder `rsync` kopieren. +### CSV-Format + +Die AIDA-CSV hat folgendes Format (eine Zeile pro Mitarbeiter): +``` +~~00341~~,~~1~~ +~~00412~~,~~0~~ +~~00433~~,~~2~~ +``` + +Dabei bedeuten die Status-Codes (konfigurierbar in den Einstellungen): +- `~~0~~` = Abwesend +- `~~1~~` = Anwesend +- `~~2~~` = Homeoffice + +## Telefonanlage (Webhook) + +Die Anwendung startet automatisch einen Webhook-Server auf **Port 8081** fuer die Anbindung einer Telefonanlage. + +### Webhook-Endpoints + +``` +GET/POST http://SERVER:8081/{durchwahl}/callstart - Anruf gestartet (WLED -> Rot) +GET/POST http://SERVER:8081/{durchwahl}/callend - Anruf beendet (WLED -> zurueck auf Zeiterfassungs-Status) +``` + +Die Info-Seite unter `http://SERVER:8081/` zeigt eine Uebersicht der Endpoints. + +### Einrichtung + +1. Unter **Benutzer** im Web-Interface die **Durchwahl** pro User eintragen (z.B. `123`) +2. In der Telefonanlage den Webhook konfigurieren: + - Anrufbeginn: `http://SERVER-IP:8081/123/callstart` + - Anrufende: `http://SERVER-IP:8081/123/callend` + +### Verhalten + +- `callstart`: Setzt WLED auf Telefon-Farbe (Standard: Rot), aber **nur** wenn der Mitarbeiter laut AIDA anwesend oder im Homeoffice ist +- `callend`: Setzt WLED zurueck auf den AIDA-Status (anwesend=gruen, homeoffice=gelb). Der Teams-Status wird beim naechsten Polling-Zyklus (15s) automatisch aktualisiert +- Waehrend eines aktiven Telefonats ueberschreibt das Teams-Polling die Farbe nicht +- Die Telefon-Farbe (`phone_active`) ist unter **Farb-Regeln** konfigurierbar ## Starten @@ -171,15 +233,13 @@ source venv/bin/activate python app.py ``` -Die Web-Oberflaeche ist dann erreichbar unter: **http://SERVER-IP:8080** +Dabei werden zwei Server gestartet: +- **Port 8080**: Web-Oberflaeche +- **Port 8081**: Webhook-Server fuer Telefonanlage ### Als systemd-Service (Produktivbetrieb) ```bash -# Service-User anlegen -sudo useradd -r -s /usr/sbin/nologin busylight -sudo chown -R busylight:busylight /opt/busylight - # Service installieren sudo cp busylight.service /etc/systemd/system/ sudo systemctl daemon-reload @@ -190,6 +250,10 @@ sudo systemctl status busylight # Logs anzeigen sudo journalctl -u busylight -f + +# Neustart nach Updates +cd /opt/busylight && git pull +sudo systemctl restart busylight ``` ## Benutzung @@ -203,17 +267,18 @@ Unter **Einstellungen** die Azure AD Credentials (Client ID, Tenant ID) und den Unter **Benutzer** auf "Aus Azure synchronisieren" klicken. Alle Azure AD Benutzer werden importiert. Anschliessend: - Benutzer aktivieren/deaktivieren (nur aktive Benutzer werden abgefragt) - AIDA-Personalnummer zuordnen (Format: `~~00341~~`) +- Telefon-Durchwahl zuordnen (z.B. `123`) ### 3. WLED-Geraete anlegen Unter **WLED-Geraete** die Hostnamen/IP-Adressen der WLED-Busylights eintragen. -Die Seite zeigt automatisch den Online-Status, LED-Anzahl und Firmware-Version jedes Geraets an. +Der Status (online/offline, LEDs, Firmware) wird automatisch alle 4 Minuten geprueft. ### 4. Zuordnungen erstellen Unter **Zuordnungen** jeden aktiven Benutzer einem WLED-Geraet und Segment zuweisen: -- Segment 0 = oben -- Segment 1 = unten +- Segment 0 = unten +- Segment 1 = oben ### 5. Farben anpassen @@ -223,6 +288,7 @@ Unter **Farb-Regeln** die Farben fuer jeden Status per Color-Picker anpassen: |--------|-------------| | `abwesend` | Benutzer laut AIDA nicht anwesend | | `homeoffice` | Benutzer im Homeoffice | +| `phone_active` | Benutzer telefoniert (Webhook) | | `teams_available` | Teams: Verfuegbar | | `teams_busy` | Teams: Beschaeftigt | | `teams_donotdisturb` | Teams: Nicht stoeren | @@ -237,25 +303,35 @@ Unter **Farb-Regeln** die Farben fuer jeden Status per Color-Picker anpassen: ### 6. Dashboard -Das **Dashboard** zeigt alle Busylights mit dem aktuellen Status in Echtzeit an und aktualisiert sich automatisch alle 10 Sekunden. +Das **Dashboard** zeigt alle Busylights mit dem aktuellen Status in Echtzeit an und aktualisiert sich automatisch alle 10 Sekunden. Pro Benutzer werden drei Status-Badges angezeigt: -- Farbige Segmente = Status wurde erfolgreich abgefragt -- Graue Segmente mit "Warte auf Status..." = Zuordnung vorhanden, aber noch kein Polling-Ergebnis (z.B. AIDA-CSV nicht erreichbar) -- "Nicht zugeordnet" = kein Benutzer diesem Segment zugewiesen +- **AIDA**: Anwesend (gruen) / Abwesend (grau) / Homeoffice (gelb) +- **Teams**: Verfuegbar / Beschaeftigt / Nicht stoeren / Offline / etc. +- **Telefon**: Telefoniert (rot) / Frei (grau) ### 7. Protokoll Unter **Protokoll** werden die letzten 200 Statusaenderungen mit Zeitstempel, WLED-URL und Ergebnis angezeigt. +## Hintergrund-Jobs + +Die Anwendung fuehrt automatisch folgende Jobs im Hintergrund aus: + +| Job | Intervall | Beschreibung | +|-----|-----------|-------------| +| Status-Polling | 15 Sekunden (konfigurierbar) | Teams-Presence und AIDA-Status abfragen, WLED aktualisieren | +| Device-Check | 240 Sekunden | Alle WLED-Geraete auf Erreichbarkeit pruefen | + ## Projektstruktur ``` busylight/ -├── app.py # FastAPI Web-Anwendung + CLI Auth +├── app.py # FastAPI Web-Anwendung + CLI Auth + Startup +├── webhook.py # Webhook-Server fuer Telefonanlage (Port 8081) ├── database.py # SQLite Datenbank-Schema und Hilfsfunktionen ├── graph_client.py # Microsoft Graph API Client ├── wled_client.py # WLED HTTP API Client -├── scheduler.py # Hintergrund-Polling (AIDA + Teams -> WLED) +├── scheduler.py # Hintergrund-Jobs (Polling + Device-Check) ├── migrate.py # Import aus alter config.cfg ├── requirements.txt # Python-Abhaengigkeiten ├── busylight.service # systemd Service-Datei @@ -277,6 +353,7 @@ busylight/ | Port | Richtung | Zweck | |------|----------|-------| | 8080/tcp | Eingehend | Web-Oberflaeche | +| 8081/tcp | Eingehend | Webhook-API fuer Telefonanlage | | 80/tcp | Ausgehend | WLED HTTP API | | 443/tcp | Ausgehend | Microsoft Graph API | @@ -287,11 +364,24 @@ busylight/ - Benutzer muessen aktiviert sein UND eine Personalnummer haben - Zuordnung Benutzer -> WLED-Geraet + Segment muss vorhanden sein +### Teams-Status wird nicht angezeigt +- Teams-Status wird immer abgefragt, auch ohne AIDA +- Azure-Authentifizierung pruefen (Sidebar zeigt "Azure verbunden") +- API-Berechtigungen in Azure pruefen (Presence.Read.All) + +### Telefon-Webhook reagiert nicht +- Port 8081 erreichbar? `curl http://SERVER:8081/` +- Durchwahl beim Benutzer eingetragen? +- Benutzer muss laut AIDA anwesend oder im Homeoffice sein + ### Azure Auth schlaegt fehl - "Oeffentliche Clientflows zulassen" muss in der Azure App aktiviert sein - Auth-Tenant muss die Tenant-ID sein (nicht "common"), wenn die App auf "Nur meine Organisation" steht - Bei erneutem Auth: `python app.py --auth` loescht automatisch den alten Token ### WLED-Geraete offline -- Unter WLED-Geraete den Status pruefen (Wifi-Button) +- Unter WLED-Geraete den Status pruefen (Wifi-Button oder "Alle jetzt pruefen") - Netzwerkverbindung vom Linux-Server zu den WLED-Geraeten pruefen: `curl http://HOSTNAME/json/info` + +### Nach git pull aendern sich nichts +- Service neustarten: `sudo systemctl restart busylight`