From 11c8042de0f039fb70110a8d30f10f229c43a982 Mon Sep 17 00:00:00 2001 From: Christian Mueller Date: Fri, 21 Aug 2026 08:37:26 +0000 Subject: [PATCH] fix: Vorgaenger bei Uebernahme der Zentrale zurueckstellen Bisher blieb der bisherige Besetzer der Zentrale nach einer Uebernahme ohne Zuordnung. In der Praxis heisst das: er hat gar kein Licht mehr, und es musste immer erst jemand "zurueck auf mein Tuerschild" klicken, damit der Zustand wieder stimmte. Die Uebernahme setzt den Vorgaenger jetzt selbst auf seinen gemerkten Heimatplatz zurueck. Ist der inzwischen jemand anderem zugeordnet oder war keiner gemerkt, bleibt er ohne Zuordnung - die Meldung auf der Seite nennt den jeweiligen Grund. Dabei darf das eben freigegebene Segment des neuen Besetzers nicht ausgeschaltet werden, wenn der Vorgaenger genau dorthin zurueckkehrt - sonst waere sein Licht sofort wieder aus. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 8 +++++--- app.py | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0d48406..cff80d3 100644 --- a/README.md +++ b/README.md @@ -205,9 +205,11 @@ erst per Knopfdruck. Segment ausgeschaltet. - **Zurueck auf mein Tuerschild**: Der gemerkte Platz wird wiederhergestellt und die Zentrale freigegeben (Farbe `abwesend`, Standard: aus). -- **Vorgaenger**: Wer die Zentrale abgibt, bleibt zunaechst ohne Zuordnung - er ist - ja nicht da. Sein gemerkter Heimatplatz bleibt erhalten, er kann jederzeit - zurueckkehren. +- **Vorgaenger**: Wer die Zentrale abgibt, wird dabei automatisch auf sein eigenes + Tuerschild zurueckgesetzt. Er muss also nicht erst selbst "zurueck" klicken, damit + der Nachfolger uebernehmen kann. Ist sein Tuerschild inzwischen jemand anderem + zugeordnet oder war keines gemerkt, bleibt er ohne Zuordnung - die Meldung auf der + Seite sagt, welcher der beiden Faelle vorliegt. - **Belegter Heimatplatz**: Ist das eigene Tuerschild inzwischen jemand anderem zugeordnet, wird die Rueckkehr abgelehnt und nichts geaendert. Dann muss der Administrator die Zuordnung aufloesen. diff --git a/app.py b/app.py index a48c6de..f14b789 100644 --- a/app.py +++ b/app.py @@ -626,7 +626,7 @@ async def zentrale_takeover(request: Request, extension: str = Form(...)): """, (user["azure_id"],)).fetchone() predecessor = conn.execute(""" - SELECT u.display_name + SELECT u.azure_id, u.display_name FROM assignments a JOIN users u ON u.azure_id = a.user_azure_id WHERE a.wled_device_id = ? AND a.segment = ? """, (target["id"], target["segment"])).fetchone() @@ -645,21 +645,69 @@ async def zentrale_takeover(request: Request, extension: str = Form(...)): conn.execute(""" INSERT INTO assignments (user_azure_id, wled_device_id, segment) VALUES (?, ?, ?) """, (user["azure_id"], target["id"], target["segment"])) + + # Vorgaenger automatisch auf sein Tuerschild zurueckschicken. Ohne das muesste + # er erst selbst "zurueck" klicken, bevor die Uebernahme fuer ihn stimmt - und + # bis dahin haette er gar kein Licht. + pred_back = None + pred_blocked = None + if predecessor and predecessor["azure_id"] != user["azure_id"]: + pred_home = conn.execute(""" + SELECT h.wled_device_id, h.segment, d.hostname, d.name + FROM home_assignments h JOIN wled_devices d ON d.id = h.wled_device_id + WHERE h.user_azure_id = ? + """, (predecessor["azure_id"],)).fetchone() + if pred_home: + taken = conn.execute(""" + SELECT u.display_name FROM assignments a JOIN users u ON u.azure_id = a.user_azure_id + WHERE a.wled_device_id = ? AND a.segment = ? + """, (pred_home["wled_device_id"], pred_home["segment"])).fetchone() + if taken: + pred_blocked = taken["display_name"] + else: + conn.execute(""" + INSERT INTO assignments (user_azure_id, wled_device_id, segment) VALUES (?, ?, ?) + """, (predecessor["azure_id"], pred_home["wled_device_id"], pred_home["segment"])) + conn.execute("DELETE FROM home_assignments WHERE user_azure_id = ?", + (predecessor["azure_id"],)) + pred_back = pred_home + conn.commit() # Licht sofort setzen - das Polling wuerde bei unveraendertem Status nichts senden scheduler.push_user_light(user["azure_id"], user["display_name"], target["hostname"], target["segment"], conn) - if own: + + # Das eigene Segment nur ausschalten, wenn nicht gerade der Vorgaenger + # dorthin zurueckgekehrt ist - sonst wuerde sein Licht sofort wieder ausgehen. + if own and not (pred_back + and pred_back["wled_device_id"] == own["wled_device_id"] + and pred_back["segment"] == own["segment"]): scheduler.clear_segment(own["hostname"], own["segment"], conn) - logger.info("Zentrale uebernommen von %s (Durchwahl %s), Vorgaenger: %s", + if pred_back: + scheduler.push_user_light(predecessor["azure_id"], predecessor["display_name"], + pred_back["hostname"], pred_back["segment"], conn) + + logger.info("Zentrale uebernommen von %s (Durchwahl %s), Vorgaenger: %s (%s)", user["display_name"], extension, - predecessor["display_name"] if predecessor else "-") + predecessor["display_name"] if predecessor else "-", + "zurueck auf eigenem Tuerschild" if pred_back + else f"Tuerschild belegt von {pred_blocked}" if pred_blocked + else "kein Tuerschild gemerkt") msg = f"{user['display_name']} sitzt jetzt auf der Zentrale ({target['name']})." if own: msg += f" Das eigene Tuerschild ({own['name'] or own['hostname']}) ist bis zur Rueckkehr ausgeschaltet." + if pred_back: + msg += (f" {predecessor['display_name']} wurde auf das eigene Tuerschild " + f"({pred_back['name'] or pred_back['hostname']}) zurueckgesetzt.") + elif pred_blocked: + msg += (f" {predecessor['display_name']} konnte nicht zurueckgesetzt werden, " + f"weil das eigene Tuerschild inzwischen {pred_blocked} zugeordnet ist.") + elif predecessor and predecessor["azure_id"] != user["azure_id"]: + msg += (f" Fuer {predecessor['display_name']} war kein eigenes Tuerschild gemerkt, " + "er ist jetzt ohne Zuordnung.") return _zentrale_view(request, conn, target, extension=extension, user=user, message=msg) finally: conn.close()