From 8d178eac6d42f6e87aa03f1a9a6b382617bc85d4 Mon Sep 17 00:00:00 2001 From: Christian Mueller Date: Thu, 23 Apr 2026 22:14:43 +0200 Subject: [PATCH] feat: poll Teams presence independently of AIDA CSV - Teams status is now always queried, even without AIDA CSV - Users without personal_nr are also polled (Teams-only mode) - If AIDA is unavailable, default to 'anwesend' and use Teams color - Dashboard will now show Teams status even without SMB mount Co-Authored-By: Claude Opus 4.6 (1M context) --- scheduler.py | 49 ++++++++++++++++++++----------------------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/scheduler.py b/scheduler.py index 2076194..1025e9a 100644 --- a/scheduler.py +++ b/scheduler.py @@ -12,10 +12,9 @@ graph = None def read_aida_csv(csv_path): - """Read AIDA status CSV. Returns dict: personal_nr -> line content.""" + """Read AIDA status CSV. Returns list of lines.""" if not csv_path or not os.path.exists(csv_path): - logger.warning("AIDA CSV nicht gefunden: %s", csv_path) - return {} + return [] try: with open(csv_path, "r", encoding="utf-8", errors="replace") as f: lines = f.read().splitlines() @@ -35,11 +34,11 @@ def determine_aida_status(lines, personal_nr, settings): return None line = matching[0] - if line.endswith(settings["aida_status_abwesend"]): + if line.endswith(settings.get("aida_status_abwesend", "~~0~~")): return "abwesend" - if line.endswith(settings["aida_status_anwesend"]): + if line.endswith(settings.get("aida_status_anwesend", "~~1~~")): return "anwesend" - if line.endswith(settings["aida_status_homeoffice"]): + if line.endswith(settings.get("aida_status_homeoffice", "~~2~~")): return "homeoffice" return None @@ -68,7 +67,7 @@ def poll_status(): for row in conn.execute("SELECT key, value FROM settings").fetchall(): settings[row["key"]] = row["value"] - # Get all active users with assignments + # Get all active users with assignments (auch ohne personal_nr) users_with_assignments = conn.execute(""" SELECT u.azure_id, u.display_name, u.personal_nr, a.segment, d.hostname, @@ -77,14 +76,14 @@ def poll_status(): JOIN assignments a ON a.user_azure_id = u.azure_id JOIN wled_devices d ON d.id = a.wled_device_id LEFT JOIN state s ON s.user_azure_id = u.azure_id - WHERE u.active = 1 AND u.personal_nr != '' + WHERE u.active = 1 """).fetchall() if not users_with_assignments: logger.debug("Keine aktiven User mit Zuordnungen gefunden") return - # Read AIDA CSV + # Read AIDA CSV (kann leer sein) aida_lines = read_aida_csv(settings.get("aida_csv_path", "")) for user in users_with_assignments: @@ -113,35 +112,30 @@ def _process_user(user, aida_lines, settings, conn): last_aida = user["last_aida_status"] or "" last_teams = user["last_teams_status"] or "" - # Determine AIDA status + # Determine AIDA status (kann None sein wenn keine CSV oder keine Personalnr) aida_status = determine_aida_status(aida_lines, personal_nr, settings) - if aida_status is None: - return - # Determine Teams status + # Immer Teams-Status abfragen teams_status = "" - if aida_status == "anwesend": - presence = graph.get_presence(azure_id) - if presence and "activity" in presence: - teams_status = "teams_" + presence["activity"].lower() + presence = graph.get_presence(azure_id) + if presence and "activity" in presence: + teams_status = "teams_" + presence["activity"].lower() + + # Wenn AIDA nicht verfuegbar, nur Teams-Status nutzen + if aida_status is None: + aida_status = "anwesend" # Default: anwesend wenn AIDA nicht verfuegbar # Check if status changed - if aida_status == last_aida: - if aida_status == "anwesend": - if teams_status == last_teams: - return # No change - else: - return # No change + if aida_status == last_aida and teams_status == last_teams: + return # No change # Determine color if aida_status == "abwesend": color = get_color_for_status("abwesend", conn) elif aida_status == "homeoffice": color = get_color_for_status("homeoffice", conn) - elif aida_status == "anwesend" and teams_status: + elif teams_status: color = get_color_for_status(teams_status, conn) - if not color: - color = get_color_for_status("teams_available", conn) else: color = get_color_for_status("available", conn) @@ -153,7 +147,6 @@ def _process_user(user, aida_lines, settings, conn): success, result_text = call_wled(url) if success: - # Update state conn.execute(""" INSERT INTO state (user_azure_id, last_aida_status, last_teams_status, updated_at) VALUES (?, ?, ?, ?) @@ -169,7 +162,6 @@ def _process_user(user, aida_lines, settings, conn): display_name, aida_status, teams_status, result_text, ) else: - # Reset state on failure conn.execute(""" INSERT INTO state (user_azure_id, last_aida_status, last_teams_status, updated_at) VALUES (?, '', '', ?) @@ -178,7 +170,6 @@ def _process_user(user, aida_lines, settings, conn): """, (azure_id, datetime.now(), datetime.now())) conn.commit() - # Log activity log_activity( azure_id, display_name, aida_status, teams_status, url, result_text )