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) <noreply@anthropic.com>
This commit is contained in:
2026-08-21 08:37:26 +00:00
co-authored by Claude Opus 5
parent 086b21dc2b
commit 11c8042de0
2 changed files with 57 additions and 7 deletions
+5 -3
View File
@@ -205,9 +205,11 @@ erst per Knopfdruck.
Segment ausgeschaltet. Segment ausgeschaltet.
- **Zurueck auf mein Tuerschild**: Der gemerkte Platz wird wiederhergestellt und die - **Zurueck auf mein Tuerschild**: Der gemerkte Platz wird wiederhergestellt und die
Zentrale freigegeben (Farbe `abwesend`, Standard: aus). Zentrale freigegeben (Farbe `abwesend`, Standard: aus).
- **Vorgaenger**: Wer die Zentrale abgibt, bleibt zunaechst ohne Zuordnung - er ist - **Vorgaenger**: Wer die Zentrale abgibt, wird dabei automatisch auf sein eigenes
ja nicht da. Sein gemerkter Heimatplatz bleibt erhalten, er kann jederzeit Tuerschild zurueckgesetzt. Er muss also nicht erst selbst "zurueck" klicken, damit
zurueckkehren. 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 - **Belegter Heimatplatz**: Ist das eigene Tuerschild inzwischen jemand anderem
zugeordnet, wird die Rueckkehr abgelehnt und nichts geaendert. Dann muss der zugeordnet, wird die Rueckkehr abgelehnt und nichts geaendert. Dann muss der
Administrator die Zuordnung aufloesen. Administrator die Zuordnung aufloesen.
+52 -4
View File
@@ -626,7 +626,7 @@ async def zentrale_takeover(request: Request, extension: str = Form(...)):
""", (user["azure_id"],)).fetchone() """, (user["azure_id"],)).fetchone()
predecessor = conn.execute(""" 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 FROM assignments a JOIN users u ON u.azure_id = a.user_azure_id
WHERE a.wled_device_id = ? AND a.segment = ? WHERE a.wled_device_id = ? AND a.segment = ?
""", (target["id"], target["segment"])).fetchone() """, (target["id"], target["segment"])).fetchone()
@@ -645,21 +645,69 @@ async def zentrale_takeover(request: Request, extension: str = Form(...)):
conn.execute(""" conn.execute("""
INSERT INTO assignments (user_azure_id, wled_device_id, segment) VALUES (?, ?, ?) INSERT INTO assignments (user_azure_id, wled_device_id, segment) VALUES (?, ?, ?)
""", (user["azure_id"], target["id"], target["segment"])) """, (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() conn.commit()
# Licht sofort setzen - das Polling wuerde bei unveraendertem Status nichts senden # Licht sofort setzen - das Polling wuerde bei unveraendertem Status nichts senden
scheduler.push_user_light(user["azure_id"], user["display_name"], scheduler.push_user_light(user["azure_id"], user["display_name"],
target["hostname"], target["segment"], conn) 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) 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, 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']})." msg = f"{user['display_name']} sitzt jetzt auf der Zentrale ({target['name']})."
if own: if own:
msg += f" Das eigene Tuerschild ({own['name'] or own['hostname']}) ist bis zur Rueckkehr ausgeschaltet." 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) return _zentrale_view(request, conn, target, extension=extension, user=user, message=msg)
finally: finally:
conn.close() conn.close()