ABLESET switch (Restart page): hold to stop AbleSet being watched and opened

The user has an AbleSet bug and needs auto-open off for now. A bypass key can now hold off fixes
(bypass.fixes): their checks stay green and nothing runs them. The status page is full, so a Restart
page key with toggle shows the switch and its hold flips it. Switched off live 2026-10-25 07:18.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-25 07:19:51 -04:00
co-authored by Claude Opus 5.5
parent 0f3471bf51
commit 0ecec5f112
7 changed files with 93 additions and 15 deletions
+22 -4
View File
@@ -592,6 +592,8 @@ def bypass_apply(cfg, tile, on, entry, comp, names_ips, lock=None):
taken out ({host, session, peer, address}), so taking it back puts exactly those back; the MIDI
checks naming it are reconnected too. Its Companion connections are switched off, then on again."""
b = tile.get("bypass") or {}
if not b.get("peers") and not b.get("conns"):
return # a key that only holds off fixes: nothing to hand over
names, ips = set(b.get("peers") or []), set(names_ips[1]) if on else set()
hosts = b.get("hosts") or [""] + sorted({c["host"] for t in cfg["tiles"] for c in t.get("checks", [])
if c.get("type") == "midi_peer" and c.get("peer") in names and c.get("host")})
@@ -1410,7 +1412,7 @@ class Engine:
def evaluate(self, snap, now, service_on):
ctx = {"now": now, "service": service_on, "any_recording": False, "dante_all": {},
"ready_due": in_windows(self.ready_cfg.get("due", []), now), "ready_done": self.ready_done(now),
"bypassed": self.bypass_names()[0], "autofix_windows": (self.cfg.get("auto_fix") or {}).get("windows", [])}
"bypassed": self.bypass_names()[0], "bypassed_fixes": self.bypass_fixes(), "autofix_windows": (self.cfg.get("auto_fix") or {}).get("windows", [])}
for t in all_tiles(self.cfg):
for chk in t.get("checks", []):
if chk["type"] == "dante":
@@ -1426,6 +1428,8 @@ class Engine:
for i, chk in enumerate(t.get("checks", [])):
try:
results = CHECKS[chk["type"]](chk, snap, ctx)
if isinstance(chk.get("fix"), str) and chk["fix"] in ctx["bypassed_fixes"]:
results = [(sub, Result(OK)) for sub, _ in results] # switched off by its bypass key
except Exception as e: # a bad check must not take the panel down
log.exception("check %s/%s failed", t["id"], chk["type"])
results = [("error", Result(WARN, "CHECK BUG"))]
@@ -1748,6 +1752,10 @@ class Engine:
ips.add(str(ip))
return names, ips
def bypass_fixes(self):
"""Fixes a bypass key holds off (an ABLESET key: AbleSet not watched nor opened while it is on)."""
return {f for tid in self.bypass for f in (((self.tiles.get(tid) or {}).get("bypass") or {}).get("fixes") or [])}
def toggle_bypass(self, tile_id, comp, now):
"""A hold on a bypass key: hand it to an operator (take its MIDI links out, switch its Companion
connections off), or take it back (put everything back, as it was)."""
@@ -1763,8 +1771,13 @@ class Engine:
entry = self.bypass[tile_id] = {"since": now, "dropped": []}
on = True
self.state.set("bypass", self.bypass)
log.info("BYPASS %s: %s", tile["label"], "handed to an operator" if on else "back to the panel")
self.note(tile_id, "TAKING\nMIDI OUT" if on else "PUTTING\nMIDI BACK", "fixing", now, 6)
b = tile.get("bypass") or {}
if b.get("peers") or b.get("conns"):
log.info("BYPASS %s: %s", tile["label"], "handed to an operator" if on else "back to the panel")
self.note(tile_id, "TAKING\nMIDI OUT" if on else "PUTTING\nMIDI BACK", "fixing", now, 6)
else: # a switch that only holds off fixes: its face says it all
log.info("BYPASS %s: %s", tile["label"], "switched off (%s not watched or run)" % ", ".join(b.get("fixes") or [])
if on else "back on")
self.bypass_last = now
self.start_bypass_job(tile_id, on, entry, comp)
@@ -2409,7 +2422,9 @@ def render(engine, service_on):
if kind == "bypass":
# Handed to an operator: steady blue, says so; otherwise the panel runs it.
on = tid in engine.bypass
out[tid] = colored("%s\n%s" % (tile["label"], "OPERATOR\nMIDI OFF" if on else "AUTO"), "service" if on else "ok")
b = tile.get("bypass") or {}
face = (b.get("on_text") or "OPERATOR\nMIDI OFF") if on else (b.get("off_text") or "AUTO")
out[tid] = colored("%s\n%s" % (tile["label"], face), "service" if on else "ok")
continue
if kind == "master":
# Idle faults are expected outside service; they do not stop "ALL OK".
@@ -2461,6 +2476,9 @@ def render(engine, service_on):
else:
text = tile["label"] + "\n" + (infos[0] if infos else "OK")
out[tid] = colored(text + failover_line(engine, [tid]), level)
for kid, key in engine.restart_keys.items(): # a Restart page key that is a switch shows the switch
if key.get("toggle") in out:
out[kid] = out[key["toggle"]]
return out