- Python 72.2%
- HTML 20.2%
- CSS 6.4%
- Shell 1%
- Dockerfile 0.2%
| agent | ||
| docs | ||
| maintain | ||
| server | ||
| .env.example | ||
| .gitignore | ||
| ansible.cfg | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| README.md | ||
| send-testclients.sh | ||
Störungstracker (Intranet)
Ein lokales Klassenraum-Tool zum schnellen Erfassen von Unterrichtsstörungen: Lehrkräfte erfassen Störungen per Klick, Schüler:innen sehen die Eskalationsstufe auf dem Klassenmonitor bzw. als Vollbild-Popup auf ihrem Rechner. Bei Stufe 3 werden automatisch Laufzettel und Rückkehrschein als PDF erzeugt und über CUPS gedruckt.
Funktionen
- Lehrerdashboard mit Sitzplätzen (3×9-Raster) und einem Klick pro Störung.
- Automatische Zuordnung Platz → eingeloggter Benutzer per Client-Agent.
- Anzeige-Seite für den Klassenmonitor mit den aktuellen Eskalationsstufen.
- Konfigurierbare Texte und Popup-Dauern je Stufe 1–3.
- Lehrer-Login per OIDC/SSO gegen den edulution-Keycloak, inkl. Silent Auth fürs iframe; LDAP wird nur noch für den Schüler-Lookup genutzt.
- Automatische PDF-Erstellung (Laufzettel, Rückkehrschein) und CUPS-Druck bei Stufe 3 – genau einmal, kein Mehrfachdruck bei weiteren Klicks.
- Lehrerrechner-Schutz: der Platz
*-pc01je Raum wird nie gesperrt und nicht als sperrbar angeboten. - Angemeldeten-Zähler im Dashboard-Titel.
- Defekt-Flag für offline/kaputte Rechner mit Toggle im Dashboard.
- Undo der letzten Eskalation – schließt das laufende Popup auf dem betroffenen Rechner sofort.
- Automatisches Agent-Update auf den Clients per Ansible, vom Server aus angestoßen (konfigurierbar im Admin-UI).
- Foto-Unterstützung:
username.jpg/pngwird als Avatar angezeigt. - Persistente Speicherung in SQLite.
Komponenten
server/: FastAPI + SQLite (Docker, Intranet)agent/: Unified Client-Agent (Python + PySide6) – läuft als root, startet das Popup als der jeweils eingeloggte Nutzermaintain/: Ansible-Playbooks für Agent-Deploy und -Updatephotos/: Avatare (optional, nicht versioniert)data/: SQLite-Datenbank (nicht versioniert)
Server-Setup (Docker)
.envim Projekt anlegen (Vorlage:.env.example)- LDAP-Zugangsdaten für den Schüler-Lookup setzen
- OIDC-Zugangsdaten für den Lehrer-Login setzen (
OIDC_CLIENT_SECRETetc.)
- Container starten
docker compose up -d --build - Aufrufen
- Dashboard:
http://<server>:8000/dashboard - Anzeige:
http://<server>:8000/display - Admin:
http://<server>:8000/admin
- Dashboard:
- Fotos hinterlegen (optional)
- Dateien in
photos/ablegen, z. B.m.mustermann.jpgoderm.mustermann.png - Werden automatisch im Dashboard angezeigt
- Dateien in
Client-Agent (Debian/Ubuntu)
Deployment und Update laufen über Ansible, nicht per manueller Installation:
ansible-playbook -i maintain/inventory maintain/playbook.yml
Das Playbook installiert agent.py samt Assets nach /opt/stoerung, legt eine venv an, installiert agent/requirements.txt und richtet den Systemd-Service kerbholz-agent.service ein (ein einzelner Service pro Rechner, läuft als root – kein Pro-Nutzer-Template mehr). Die Backend-URL wird dabei per Override-Datei gesetzt.
Für reine Agent-Updates auf bereits eingerichteten Clients gibt es das schlankere maintain/playbook-update-agent.yml; dieses wird bei Bedarf auch automatisch vom Server ausgelöst (siehe Admin-UI, „Automatisches Agent-Update“).
Daten- und Foto-Pfade
- SQLite-Datei:
data/stoerungen.sqlite - Foto-Verzeichnis:
photos/(gemountet nach/app/app/static/photosim Container)
Lehrer-Login (OIDC/SSO)
Authentifizierung läuft gegen den edulution-Keycloak (Authorization Code + PKCE), inklusive Silent Auth (prompt=none) für den Einsatz im edulution-iframe. Relevante .env-Variablen (siehe .env.example):
OIDC_ISSUER,OIDC_CLIENT_ID,OIDC_CLIENT_SECRET,OIDC_REDIRECT_URIOIDC_TEACHER_GROUP– exakter Gruppenpfad (Default/role-teacher); Teilstring-Prüfungen sind unbrauchbar, weil Lehrkräfte auch in/all-studentsund/studentsstehen
LDAP-Konfiguration (Schüler-Lookup)
LDAP wird ausschließlich noch genutzt, um Anzeigename und Klasse zu Schüler-Logins nachzuschlagen. Beispiel .env (siehe .env.example):
LDAP_URL=ldaps://server.morz.de:636LDAP_BIND_DN=CN=morz-stoerenfried,OU=Management,OU=GLOBAL,DC=morz,DC=deLDAP_BIND_PASSWORD=...LDAP_BASE_DN=dc=morz,dc=deLDAP_USER_FILTER=(&(objectClass=person)(|(sophomorixRole=teacher)(sophomorixRole=student)))LDAP_USERNAME_ATTR=sAMAccountNameLDAP_DISPLAYNAME_ATTR=displayNameLDAP_CLASS_ATTR=sophomorixAdminClass
Admin-UI (/admin)
Zur Laufzeit konfigurierbar, ohne Neustart:
- Stufentexte 1–3
- CUPS-Druckername
- Anzeige-Timing (Ausblende-/Fade-Sekunden, Flash-Intervall und -Zyklen)
- Session-Timeout, Agent-Heartbeat-Intervall
- Popup-Dauer (Standard sowie separat je Stufe 1–3), Popup an/aus
- Sperrbildschirm-Nachricht
- Lehrer:in-Name für den Laufzettel
- Ignorierte Nutzernamen (z. B.
gdm,sddm) - Sichtbarkeit einzelner Dashboard-Kachel-Elemente (Foto, Reihe/Platz, Hostname, PC-Nummer, Zähler, Popup-Status, Badge, freie Plätze)
- Globale Topbar-Aktionen (alle Rechner einschalten/ausschalten/abmelden)
- Automatisches Agent-Update (an/aus, Intervall, SSH-Key-Pfad, SSH-User)
Hinweise zur Zuordnung der Plätze
Hostnamen werden automatisch geparst, Format {raumcode}-pc{Reihe}{Spalte} – der Raumcode-Präfix ist beliebig, produktiv im Einsatz ist z. B. a106:
a106-pc11→ Reihe 1, Platz 1a106-pc12→ Reihe 1, Platz 2a106-pc21→ Reihe 2, Platz 1a106-pc23→ Reihe 2, Platz 3
Das Raster ist fest auf 3×9 (27 Plätze) ausgelegt. Der Platz *-pc01 gilt je Raum als Lehrerrechner und wird nie gesperrt, unabhängig von Sperrbildschirm-Events.
Bekannte Einschränkungen
- Mehrere Räume: Das Datenmodell ist dafür vorbereitet (eigene
rooms-Tabelle, raumcode-agnostischer Hostname-Parser), aber Dashboard und Anzeige zeigen weiterhin alle Sitzplätze gemeinsam in einem einzigen 3×9-Raster ohne Trennung nach Raum. Für echten Mehrraum-Betrieb fehlt noch die Raum-Auswahl in Dashboard/Anzeige.