diff --git a/README.md b/README.md index 0a641ec..288e321 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ During that window, with ALARMS on, the panel fixes a problem by itself once it - Never automatic: restarting a running ProPresenter, Bible app, ProdCom (or DVS on NA Ingest, which restarts ProdCom), captions or the bridge, power-cycling a switch port, or turning on a connection someone switched off. `load_config` refuses an auto fix that closes a program. - **Daily log:** everything auto-fix does is written as it happens to `~/Desktop/Auto-Fix Logs/ Auto-Fix.log` on NA Ingest (e.g. `2026-10-11 Sunday Auto-Fix.log`): the problem, what it did, whether it worked, when the fault cleared, when it gave up or held back. Double-click it to open it in Console, which shows new lines live. One file per day; each is deleted a calendar month after its date (the 11 Oct file on 11 Nov). - Press ALARMS to mute the panel for maintenance: that also stops auto-fix. The window and the list are `"auto_fix"` in `config.json`. -- **READY page fixes** ticked under Settings › Auto-fix act on the checklist's gaps too, amber or red. A fix marked `"anytime": true` (only a READY fix may be; today the LTC write, `ready_ltc`) runs at any hour, not only in the auto-fix hours: once the weekend's set is on Tracks, every song's timecode is written into Planning Center for all four campuses by itself. ALARMS muted still stops it. +- **READY page fixes** ticked under Settings › Auto-fix act on the checklist's gaps too, amber or red. A fix marked `"anytime": true` (only a READY fix may be; today the LTC write, `ready_ltc`) runs at any hour, not only in the auto-fix hours: once the weekend's set is on Tracks, every song's timecode is written into Planning Center for all four campuses by itself, even while ALARMS is muted (nothing in the room notices a note in Planning Center). ## Audio failover (Studio B -> FOH Backup) diff --git a/schema.py b/schema.py index 903351b..0704f04 100644 --- a/schema.py +++ b/schema.py @@ -218,7 +218,7 @@ field("fixes.*.reconnect", "bool", False, "Reconnect the Companion connection af field("fixes.*.conn", "str", None, "The Companion connection it reconnects.", "Fixes") field("fixes.*.restart_ok", "bool", False, "May close a running program (and still run by itself).", "Fixes") field("fixes.*.never_auto", "bool", False, "Never runs by itself.", "Fixes") -field("fixes.*.anytime", "bool", False, "Ticked for auto-fix, runs by itself at any hour, not only in the auto-fix hours (a READY fix that only writes to Planning Center).", "Fixes") +field("fixes.*.anytime", "bool", False, "Ticked for auto-fix, runs by itself at any hour, not only in the auto-fix hours, muted or not (a READY fix that only writes to Planning Center).", "Fixes") field("fixes.*.part", "enum", None, "Which part of the switcher.", "Fixes", options=["audio", "camera"]) field("fixes.*.verify_seconds", "int", 20, "Wait this long before judging a reconnect.", "Fixes", advanced=True, lo=5, hi=120) diff --git a/status_panel.py b/status_panel.py index 376d5e6..51886bd 100644 --- a/status_panel.py +++ b/status_panel.py @@ -1501,12 +1501,12 @@ class Engine: # ALARMS muted (maintenance) stops auto-fix, except the harmless fixes in "while_muted" # (playing the Spotify playlist): those keep running inside the window. muted = not self.service.on(now) - keep = set(a.get("while_muted", [])) if muted else None hours = in_windows(a.get("windows", []), now) - # A fix marked "anytime" (writing the timecode into Planning Center) runs by itself at any - # hour, not only in the auto-fix hours - still never while ALARMS is muted. + # A fix marked "anytime" (writing the timecode into Planning Center: nothing in the room + # notices) runs by itself at any hour, not only in the auto-fix hours, muted or not. anytime = {f for f in a.get("fixes", []) if self.cfg["fixes"].get(f, {}).get("anytime") and not self.cfg["fixes"].get(f, {}).get("never_auto") and not self.cfg["fixes"].get(f, {}).get("disabled")} + keep = (set(a.get("while_muted", [])) | anytime) if muted else None if not hours or (muted and not keep): if self.auto_on and self.autolog: self.autolog.write(now, "PANEL", "auto-fix off (%s)" % ("ALARMS muted" if hours else "end of the window")) @@ -1514,7 +1514,7 @@ class Engine: for ident in [i for i in self.auto_tries if not (i[0] == "fix" and i[1] in anytime)]: del self.auto_tries[ident] # the window's fixes start fresh next time self.auto_seen.pop(ident, None) - if muted or not anytime: + if not anytime: return [] else: if (not self.auto_on or self.auto_muted != muted) and self.autolog: # opens today's file, so it can be watched from the start diff --git a/tests/test_status_panel.py b/tests/test_status_panel.py index 26db56b..ec498ec 100644 --- a/tests/test_status_panel.py +++ b/tests/test_status_panel.py @@ -994,8 +994,10 @@ class TestFixes(unittest.TestCase): time.sleep(0.2) self.assertEqual((done, ran), (["rd_timecode"], ["ready_ltc"])) # never "ableton" self.assertEqual(self.engine.auto_fix(self.snap, comp, thursday + 60), []) # 90 s between tries - self.engine.service.set(False, thursday + 61) # ALARMS muted: nothing - self.assertEqual(self.engine.auto_fix(self.snap, comp, thursday + 200), []) + self.engine.service.set(False, thursday + 61) # ALARMS muted: it still writes + self.assertEqual(self.engine.auto_fix(self.snap, comp, thursday + 200), ["rd_timecode"]) + time.sleep(0.2) + self.assertEqual(ran, ["ready_ltc", "ready_ltc"]) # and still never "ableton" self.engine.service.set(True, thursday + 201) del cfg["fixes"]["ready_ltc"]["anytime"] # not marked: the window only self.engine = sp.Engine(cfg)