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()