The LTC write happens by itself: READY fixes ticked for auto-fix act on the checklist, any hour for ready_ltc

Auto-fix now looks at the READY page's keys too, for the READY fixes ticked under Settings > Auto-fix,
and acts on a checklist gap while it is still amber. A fix marked anytime (only a READY fix may be)
runs outside the auto-fix hours as well, never while ALARMS is muted; the window's own fixes keep
their hours and start fresh each window. ready_ltc is ticked and marked anytime at North Attleboro:
once the weekend's set is on Tracks, every song's timecode goes into all four campuses' plans.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-10-19 14:08:33 -04:00
co-authored by Claude Fable 5.1
parent f1cd42a437
commit b7af31ea6f
6 changed files with 82 additions and 22 deletions
+39
View File
@@ -975,6 +975,45 @@ class TestFixes(unittest.TestCase):
self.assertEqual(self.engine.auto_fix(self.snap, comp, weekday + 30), [])
self.assertEqual(ran, [])
def test_a_ready_fix_marked_anytime_runs_on_a_weekday(self):
"""The LTC write, ticked for auto-fix and marked anytime, fills an amber TIMECODE gap on a
Thursday morning; the window's fixes (Ableton closed) still wait for the window."""
cfg = json.loads(json.dumps(CONFIG))
cfg["auto_fix"]["fixes"] = cfg["auto_fix"]["fixes"] + ["ready_ltc"]
cfg["fixes"]["ready_ltc"]["anytime"] = True
thursday = SUNDAY - 3 * 86400
self.engine = sp.Engine(cfg)
self.engine.autolog = sp.AutoLog(tempfile.mkdtemp())
self.engine.service.set(True, thursday) # ALARMS on all week, as at NA
ran, comp = self.auto_setup()
self.snap.ready = {"items": {"timecode": {"faults": [[sp.ERR, "NO LTC JEHOVAH"]], "info": ""}}}
self.snap.remote["tracks\0pgrep -xq Live"] = False
run_steps(self.engine, self.snap, thursday, 10)
self.assertEqual(self.engine.auto_fix(self.snap, comp, thursday + 10), []) # not 20 s yet
done = self.engine.auto_fix(self.snap, comp, thursday + 30)
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(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())
self.engine.service.set(True, thursday)
ran, comp = self.auto_setup()
run_steps(self.engine, self.snap, thursday, 25)
self.assertEqual(self.engine.auto_fix(self.snap, comp, thursday + 30), [])
run_steps(self.engine, self.snap, SUNDAY, 25)
done = self.engine.auto_fix(self.snap, comp, SUNDAY + 30)
time.sleep(0.2)
self.assertIn("rd_timecode", done) # in the window it acts
self.assertIn("ready_ltc", ran)
import schema
bad = json.loads(json.dumps(CONFIG))
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_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