Audio failover: press FOH Backup by itself when Studio B dies; Companion button presses as fixes
A new fix kind "companion_press" presses any Companion button over its HTTP API (page, row, col). A fix marked "failover" runs by itself within seconds of its check failing: inside the "failover" windows (Sunday 06:30-13:30), even while ALARMS is muted, once per fault, never back the other way. The hidden STB AUDIO key (inside AUDIO) watches Studio B's ping every second, Pro Tools over SSH every 2 s and its Dante device; each check's fix is the FOH Backup press. The keys say ON FOH BACKUP until STREAM STB on the Restart page switches back. Settings page: the press builder, the failover tick and undo, the Failover calendar, help entry "A fallback button". Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -23,17 +23,17 @@ NAMES = {"cfg": "top", "config": "top", "chk": "check", "c": "check", "fix": "fi
|
||||
"tile": "tile", "k": "restart_key", "key": "restart_key", "rp": "restart_page", "w": "window",
|
||||
"names": "variables", "host": "host", "h": "host", "windows": "windows", "site": "site", "rc": "ready"}
|
||||
ATTRS = {"self.cfg": "top", "engine.cfg": "top", "self.net": "network", "self.auto": "auto", "self.site": "site",
|
||||
"self.atem": "atem", "self.ready_cfg": "ready",
|
||||
"self.atem": "atem", "self.ready_cfg": "ready", "self.failover_cfg": "failover",
|
||||
"self.tiles": "tiles", "engine.tiles": "tiles", "self.restart_keys": "restart_keys",
|
||||
"engine.restart_keys": "restart_keys"}
|
||||
# A key of a top-level dict that holds a record of another kind.
|
||||
TOP = {"companion": "companion", "network": "network", "variables": "variables", "auto_fix": "auto", "site": "site",
|
||||
"atem": "atem", "spotify": "spotify", "timing": "timing", "flap": "flap", "hosts": "hosts", "fixes": "fixes",
|
||||
"tiles": "tiles", "restart_page": "restart_page", "gear": "gears", "service_windows": "windows",
|
||||
"ready": "ready", "ready_page": "ready_page"}
|
||||
"ready": "ready", "ready_page": "ready_page", "failover": "failover"}
|
||||
SUB = {("auto", "windows"): "windows", ("site", "live_services"): "windows", ("tile", "checks"): "checks",
|
||||
("restart_page", "keys"): "restart_keys", ("tile", "members"): "names", ("ready", "due"): "windows",
|
||||
("ready_page", "keys"): "tiles"}
|
||||
("ready_page", "keys"): "tiles", ("failover", "windows"): "windows"}
|
||||
ELEMENT = {"tiles": "tile", "checks": "check", "restart_keys": "restart_key", "windows": "window", "fixes": "fix",
|
||||
"hosts": "host", "gears": "gear"}
|
||||
# Keys the code reads that are the watchdog's own working data, not settings.
|
||||
@@ -145,7 +145,8 @@ def path_of(kind, key):
|
||||
"restart_key": "restart_page.keys[].", "restart_page": "restart_page.", "auto": "auto_fix.",
|
||||
"network": "network.", "variables": "variables.", "site": "site.", "atem": "atem.", "spotify": "spotify.",
|
||||
"companion": "companion.", "timing": "timing.", "flap": "flap.", "gear": "gear.*.",
|
||||
"window": "auto_fix.windows[].", "ready": "ready.", "ready_page": "ready_page."}.get(kind)
|
||||
"window": "auto_fix.windows[].", "ready": "ready.", "ready_page": "ready_page.",
|
||||
"failover": "failover."}.get(kind)
|
||||
return None if prefix is None else prefix + key
|
||||
|
||||
|
||||
@@ -188,7 +189,8 @@ class TestSchemaMatchesCode(unittest.TestCase):
|
||||
"site.live_services[].days", "site.live_services[].start", "site.live_services[].end"}
|
||||
for w in ("days", "start", "end"):
|
||||
if "auto_fix.windows[]." + w in read:
|
||||
read |= {"service_windows[].%s" % w, "site.live_services[].%s" % w, "ready.due[].%s" % w}
|
||||
read |= {"service_windows[].%s" % w, "site.live_services[].%s" % w, "ready.due[].%s" % w,
|
||||
"failover.windows[].%s" % w}
|
||||
dead = sorted(p for p in schema.F if p not in read and p not in ui_only)
|
||||
self.assertEqual(dead, [], "declared settings nothing reads")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user