docs: complete README rewrite with webhook, segments, CSV format, troubleshooting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
844f5b1fdb
commit
3329a5dc5a
158
README.md
158
README.md
@ -1,19 +1,30 @@
|
|||||||
# Busylight WLED Controller
|
# 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
|
## 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
|
- **Benutzer-Verwaltung** mit automatischem Sync aus Azure AD
|
||||||
- **WLED-Geraete** hinzufuegen, bearbeiten, entfernen und Live-Status pruefen (online/offline, LED-Anzahl, Firmware-Version)
|
- **WLED-Geraete** hinzufuegen, bearbeiten, entfernen mit automatischem Status-Check (online/offline, LED-Anzahl, Firmware)
|
||||||
- **Zuordnung** von Benutzern zu WLED-Segmenten per Dropdown (statt UUID-Mapping in einer Config-Datei)
|
- **Zuordnung** von Benutzern zu WLED-Segmenten per Dropdown
|
||||||
- **Farb-Regeln** mit Color-Picker fuer jeden Teams-/Anwesenheitsstatus
|
- **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
|
- **Einstellungen** fuer Azure AD, Polling-Intervall und AIDA-CSV-Pfad
|
||||||
- **Protokoll** der letzten Statusaenderungen
|
- **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
|
## Voraussetzungen
|
||||||
|
|
||||||
- Linux-Server (Debian 12+/Ubuntu 22.04+)
|
- 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)
|
- Netzwerkzugriff auf die WLED-Geraete (HTTP Port 80)
|
||||||
- Azure AD App-Registrierung (siehe unten)
|
- Azure AD App-Registrierung (siehe unten)
|
||||||
- Zugriff auf die AIDA-Zeiterfassungs-CSV (lokal oder per SMB-Mount)
|
- Zugriff auf die AIDA-Zeiterfassungs-CSV (lokal oder per SMB-Mount)
|
||||||
|
- Optional: Telefonanlage mit Webhook-Unterstuetzung
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@ -128,38 +140,88 @@ python migrate.py
|
|||||||
|
|
||||||
Die alte `config.cfg` wird danach nicht mehr benoetigt.
|
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.
|
Die Zeiterfassungs-CSV liegt typischerweise auf einem Windows-Server (z.B. `\\192.168.30.224\export`).
|
||||||
Fuer den Zugriff von Linux empfiehlt sich ein SMB/CIFS-Mount:
|
|
||||||
|
### 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
|
```bash
|
||||||
# Paket installieren
|
# Paket installieren
|
||||||
sudo apt install cifs-utils
|
sudo apt install cifs-utils
|
||||||
|
|
||||||
# Mount-Punkt erstellen
|
# Mount-Punkt und Credentials erstellen
|
||||||
sudo mkdir -p /mnt/zeiterfassung
|
sudo mkdir -p /mnt/aida
|
||||||
|
|
||||||
# Credentials-Datei erstellen
|
|
||||||
sudo bash -c 'cat > /etc/samba/creds << EOF
|
sudo bash -c 'cat > /etc/samba/creds << EOF
|
||||||
username=DOMAIN\user
|
username=BENUTZER
|
||||||
password=geheim
|
password=PASSWORT
|
||||||
|
domain=DOMAIN
|
||||||
EOF'
|
EOF'
|
||||||
sudo chmod 600 /etc/samba/creds
|
sudo chmod 600 /etc/samba/creds
|
||||||
|
|
||||||
# Eintrag in /etc/fstab (eine Zeile)
|
# 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
|
# 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:
|
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
|
## Starten
|
||||||
|
|
||||||
@ -171,15 +233,13 @@ source venv/bin/activate
|
|||||||
python app.py
|
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)
|
### Als systemd-Service (Produktivbetrieb)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Service-User anlegen
|
|
||||||
sudo useradd -r -s /usr/sbin/nologin busylight
|
|
||||||
sudo chown -R busylight:busylight /opt/busylight
|
|
||||||
|
|
||||||
# Service installieren
|
# Service installieren
|
||||||
sudo cp busylight.service /etc/systemd/system/
|
sudo cp busylight.service /etc/systemd/system/
|
||||||
sudo systemctl daemon-reload
|
sudo systemctl daemon-reload
|
||||||
@ -190,6 +250,10 @@ sudo systemctl status busylight
|
|||||||
|
|
||||||
# Logs anzeigen
|
# Logs anzeigen
|
||||||
sudo journalctl -u busylight -f
|
sudo journalctl -u busylight -f
|
||||||
|
|
||||||
|
# Neustart nach Updates
|
||||||
|
cd /opt/busylight && git pull
|
||||||
|
sudo systemctl restart busylight
|
||||||
```
|
```
|
||||||
|
|
||||||
## Benutzung
|
## 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:
|
Unter **Benutzer** auf "Aus Azure synchronisieren" klicken. Alle Azure AD Benutzer werden importiert. Anschliessend:
|
||||||
- Benutzer aktivieren/deaktivieren (nur aktive Benutzer werden abgefragt)
|
- Benutzer aktivieren/deaktivieren (nur aktive Benutzer werden abgefragt)
|
||||||
- AIDA-Personalnummer zuordnen (Format: `~~00341~~`)
|
- AIDA-Personalnummer zuordnen (Format: `~~00341~~`)
|
||||||
|
- Telefon-Durchwahl zuordnen (z.B. `123`)
|
||||||
|
|
||||||
### 3. WLED-Geraete anlegen
|
### 3. WLED-Geraete anlegen
|
||||||
|
|
||||||
Unter **WLED-Geraete** die Hostnamen/IP-Adressen der WLED-Busylights eintragen.
|
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
|
### 4. Zuordnungen erstellen
|
||||||
|
|
||||||
Unter **Zuordnungen** jeden aktiven Benutzer einem WLED-Geraet und Segment zuweisen:
|
Unter **Zuordnungen** jeden aktiven Benutzer einem WLED-Geraet und Segment zuweisen:
|
||||||
- Segment 0 = oben
|
- Segment 0 = unten
|
||||||
- Segment 1 = unten
|
- Segment 1 = oben
|
||||||
|
|
||||||
### 5. Farben anpassen
|
### 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 |
|
| `abwesend` | Benutzer laut AIDA nicht anwesend |
|
||||||
| `homeoffice` | Benutzer im Homeoffice |
|
| `homeoffice` | Benutzer im Homeoffice |
|
||||||
|
| `phone_active` | Benutzer telefoniert (Webhook) |
|
||||||
| `teams_available` | Teams: Verfuegbar |
|
| `teams_available` | Teams: Verfuegbar |
|
||||||
| `teams_busy` | Teams: Beschaeftigt |
|
| `teams_busy` | Teams: Beschaeftigt |
|
||||||
| `teams_donotdisturb` | Teams: Nicht stoeren |
|
| `teams_donotdisturb` | Teams: Nicht stoeren |
|
||||||
@ -237,25 +303,35 @@ Unter **Farb-Regeln** die Farben fuer jeden Status per Color-Picker anpassen:
|
|||||||
|
|
||||||
### 6. Dashboard
|
### 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
|
- **AIDA**: Anwesend (gruen) / Abwesend (grau) / Homeoffice (gelb)
|
||||||
- Graue Segmente mit "Warte auf Status..." = Zuordnung vorhanden, aber noch kein Polling-Ergebnis (z.B. AIDA-CSV nicht erreichbar)
|
- **Teams**: Verfuegbar / Beschaeftigt / Nicht stoeren / Offline / etc.
|
||||||
- "Nicht zugeordnet" = kein Benutzer diesem Segment zugewiesen
|
- **Telefon**: Telefoniert (rot) / Frei (grau)
|
||||||
|
|
||||||
### 7. Protokoll
|
### 7. Protokoll
|
||||||
|
|
||||||
Unter **Protokoll** werden die letzten 200 Statusaenderungen mit Zeitstempel, WLED-URL und Ergebnis angezeigt.
|
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
|
## Projektstruktur
|
||||||
|
|
||||||
```
|
```
|
||||||
busylight/
|
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
|
├── database.py # SQLite Datenbank-Schema und Hilfsfunktionen
|
||||||
├── graph_client.py # Microsoft Graph API Client
|
├── graph_client.py # Microsoft Graph API Client
|
||||||
├── wled_client.py # WLED HTTP 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
|
├── migrate.py # Import aus alter config.cfg
|
||||||
├── requirements.txt # Python-Abhaengigkeiten
|
├── requirements.txt # Python-Abhaengigkeiten
|
||||||
├── busylight.service # systemd Service-Datei
|
├── busylight.service # systemd Service-Datei
|
||||||
@ -277,6 +353,7 @@ busylight/
|
|||||||
| Port | Richtung | Zweck |
|
| Port | Richtung | Zweck |
|
||||||
|------|----------|-------|
|
|------|----------|-------|
|
||||||
| 8080/tcp | Eingehend | Web-Oberflaeche |
|
| 8080/tcp | Eingehend | Web-Oberflaeche |
|
||||||
|
| 8081/tcp | Eingehend | Webhook-API fuer Telefonanlage |
|
||||||
| 80/tcp | Ausgehend | WLED HTTP API |
|
| 80/tcp | Ausgehend | WLED HTTP API |
|
||||||
| 443/tcp | Ausgehend | Microsoft Graph API |
|
| 443/tcp | Ausgehend | Microsoft Graph API |
|
||||||
|
|
||||||
@ -287,11 +364,24 @@ busylight/
|
|||||||
- Benutzer muessen aktiviert sein UND eine Personalnummer haben
|
- Benutzer muessen aktiviert sein UND eine Personalnummer haben
|
||||||
- Zuordnung Benutzer -> WLED-Geraet + Segment muss vorhanden sein
|
- 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
|
### Azure Auth schlaegt fehl
|
||||||
- "Oeffentliche Clientflows zulassen" muss in der Azure App aktiviert sein
|
- "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
|
- 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
|
- Bei erneutem Auth: `python app.py --auth` loescht automatisch den alten Token
|
||||||
|
|
||||||
### WLED-Geraete offline
|
### 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`
|
- 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`
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user