ALARMS key stops every auto-fix too, and says so

Muted, nothing fixes itself at all: no Spotify exception (while_muted is gone) and no any-hour
READY fix; holds still fix and the Sunday stream-audio failover still switches. The key reads
ALARMS OFF / AUTO-FIX OFF / TIL 12AM, and its note says both. The settings page's switch says the same.

The mute's end is worked out at the press and kept: a watchdog that was not running at 23:59 no
longer leaves the alarms muted until the next schedule change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-19 14:46:20 -04:00
co-authored by Claude Opus 5.5
parent 5d918d60af
commit b41b8a49d2
8 changed files with 121 additions and 47 deletions
+9 -6
View File
@@ -522,8 +522,8 @@ class TestFixes(unittest.TestCase):
self.assertFalse(any("/clips/" in path for _, path in calls)) # never plays a clip by itself
class TestSpotifyWhileMuted(unittest.TestCase):
def test_spotify_still_plays_with_alarms_muted(self):
class TestSpotifyAndMute(unittest.TestCase):
def test_alarms_muted_stops_spotify_too(self):
cfg = json.loads(json.dumps(CONFIG))
cfg["auto_fix"]["log_dir"] = __import__("tempfile").mkdtemp(prefix="sp-autolog-")
engine, snap = sp.Engine(cfg, None), sp.Snapshot()
@@ -538,14 +538,17 @@ class TestSpotifyWhileMuted(unittest.TestCase):
engine.auto_fix(snap, None, wed + 40)
for th in engine.fix_threads:
th.join(2)
self.assertEqual(ran, ["spotify_play"])
cfg["auto_fix"]["while_muted"] = [] # without it: nothing while muted
self.assertEqual(ran, []) # muted: nothing, not even Spotify
engine2 = sp.Engine(cfg, None)
engine2.service.set(False, wed)
engine2.service.set(True, wed) # alarms on: it plays
engine2.executor = engine.executor
snap.remote = {}
for t in range(0, 40, 2):
engine2.step(snap, wed + t)
self.assertEqual(engine2.auto_fix(snap, None, wed + 40), [])
engine2.auto_fix(snap, None, wed + 40)
for th in engine2.fix_threads:
th.join(2)
self.assertEqual(ran, ["spotify_play"])
if __name__ == "__main__":
+21 -4
View File
@@ -610,7 +610,7 @@ class TestBehaviour(unittest.TestCase):
self.assertEqual(level(tiles["x32"]), "quiet")
self.assertEqual(tiles["all"]["x"], "1 DOWN\nX32 OFFLINE")
self.assertEqual(level(tiles["all"]), "quiet")
self.assertEqual(tiles["service"]["x"], "SERVICE\nOFF")
self.assertEqual(tiles["service"]["x"], "SERVICE OFF\nAUTO-FIX OFF")
for t in tiles.values():
self.assertEqual((t["b"], t["f"]), (t["b2"], t["f2"]), t["x"]) # no blinking anywhere
@@ -994,11 +994,12 @@ 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: it still writes
self.assertEqual(self.engine.auto_fix(self.snap, comp, thursday + 200), ["rd_timecode"])
self.engine.service.set(False, thursday + 61) # ALARMS muted: nothing at all
self.assertEqual(self.engine.auto_fix(self.snap, comp, thursday + 200), [])
self.engine.service.set(True, thursday + 201) # back on: it catches up
self.assertEqual(self.engine.auto_fix(self.snap, comp, thursday + 210), ["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)
self.engine.autolog = sp.AutoLog(tempfile.mkdtemp())
@@ -1016,6 +1017,22 @@ class TestFixes(unittest.TestCase):
bad["fixes"]["ableton"]["anytime"] = True
self.assertTrue(any("anytime" in e for e in schema.validate(bad)[0])) # only a READY fix may
def test_alarms_key_says_alarms_and_auto_fix_and_when_they_come_back(self):
cfg = json.loads(json.dumps(CONFIG))
cfg["service_windows"] = [{"days": list(sp.DAYS), "start": "00:00", "end": "23:59"}] # NA: armed all day
engine = sp.Engine(cfg)
monday = datetime(2026, 10, 19, 14, 30).timestamp()
tiles = engine.step(self.snap, monday)
self.assertEqual(tiles["service"]["x"], "SERVICE ON\nAUTO-FIX ON")
engine.service.set(False, monday) # pressed
tiles = engine.step(self.snap, monday + 1)
self.assertEqual(tiles["service"]["x"], "SERVICE OFF\nAUTO-FIX OFF\nTIL 12AM")
self.assertTrue(engine.service.on(datetime(2026, 10, 20, 0, 0, 30).timestamp())) # back by itself
note = [ctl for row in make_page.build(cfg)["page"]["controls"].values() for ctl in row.values()
if ctl and "'service'" in (ctl.get("options") or {}).get("notes", "")][0]["options"]["notes"]
self.assertIn("stop every auto-fix", note)
self.assertIn("at midnight", note)
def test_restart_keys_flash_when_their_thing_is_down(self):
devices = json.loads(self.snap.vars[("audinate-dantecontroller", "devices")])
devices.remove("NA-Tracks") # DVS on the Tracks Mac gone