READY: LIGHT TIMING (flash and FX cues against the drum hits); auto-fix on for testing
- LIGHT TIMING: every blinder flash / FX cue is timed against the Drums (Live) stem under it (deactivated clips count) on the Tracks Mac; cues a strong hit is more than 25 ms away from are named with song and bar - Settings Overview: "Auto-fix on for testing" for 15 min to 2 h, outside the hours and over a pause; the AUTO-FIX key says TESTING, and it goes back to the hours by itself Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+32
-7
@@ -817,7 +817,7 @@ def check_ready_manual(chk, snap, ctx):
|
||||
|
||||
|
||||
# What readiness.py looks at (check type "ready") and what a "ready" fix can do.
|
||||
READY_ITEMS = ("tracks", "mix_foh", "lights", "keys", "tune", "routing", "ears", "prop", "timecode", "backgrounds", "led_cross", "lineup", "mics",
|
||||
READY_ITEMS = ("tracks", "mix_foh", "lights", "light_timing", "keys", "tune", "routing", "ears", "prop", "timecode", "backgrounds", "led_cross", "lineup", "mics",
|
||||
"track_bundle", "prop_bundle")
|
||||
READY_ACTIONS = ("recheck", "lineup_sync", "led_cross", "copy_tracks", "ltc_to_pco", "ableton_mix")
|
||||
|
||||
@@ -1132,6 +1132,7 @@ class ServiceMode:
|
||||
self.override, self.last_sched = saved.get("override"), saved.get("last_sched")
|
||||
self.edge = saved.get("edge")
|
||||
self.hold = bool(saved.get("hold")) # a pause that lasts through the hours, not just to the next edge
|
||||
self.test = bool(saved.get("test")) # AUTO-FIX turned on for testing: on until its edge, then the hours again
|
||||
|
||||
def scheduled(self, now):
|
||||
return in_windows(self.windows, now)
|
||||
@@ -1153,6 +1154,12 @@ class ServiceMode:
|
||||
self._save()
|
||||
return sched
|
||||
return False
|
||||
if self.test:
|
||||
if self.edge is None or now >= self.edge:
|
||||
self.override, self.test, self.edge, self.last_sched = None, False, None, sched
|
||||
self._save()
|
||||
return sched
|
||||
return True
|
||||
if self.override is not None and self.edge is None:
|
||||
self.edge = self.next_change(now) # an override saved before edges were kept
|
||||
self._save()
|
||||
@@ -1168,7 +1175,7 @@ class ServiceMode:
|
||||
Looked up once a minute."""
|
||||
if self.override is None:
|
||||
return None
|
||||
if self.hold:
|
||||
if self.hold or self.test:
|
||||
return self.edge
|
||||
minute = int(now // 60)
|
||||
cached = getattr(self, "_back", None)
|
||||
@@ -1191,7 +1198,7 @@ class ServiceMode:
|
||||
self.last_sched = sched
|
||||
self.override = None if value == sched else value
|
||||
self.edge = self.next_change(now) if self.override is not None else None
|
||||
self.hold = False
|
||||
self.hold = self.test = False
|
||||
self._save()
|
||||
|
||||
def pause(self, now):
|
||||
@@ -1199,13 +1206,19 @@ class ServiceMode:
|
||||
(2026-10-21: a press on Saturday night used to do nothing for Sunday)."""
|
||||
sched = self.scheduled(now)
|
||||
start = now if sched else self.next_change(now)
|
||||
self.override, self.hold, self.last_sched = False, True, sched
|
||||
self.override, self.hold, self.test, self.last_sched = False, True, False, sched
|
||||
self.edge = self.next_change(start) if start else None
|
||||
self._save()
|
||||
|
||||
def resume(self, now):
|
||||
"""Back to the hours."""
|
||||
self.override, self.hold, self.edge, self.last_sched = None, False, None, self.scheduled(now)
|
||||
self.override, self.hold, self.test, self.edge, self.last_sched = None, False, False, None, self.scheduled(now)
|
||||
self._save()
|
||||
|
||||
def test_on(self, now, minutes):
|
||||
"""On for testing, whatever the hours, for `minutes` (5 to 240); then back to the hours by itself."""
|
||||
self.override, self.hold, self.test, self.last_sched = True, False, True, self.scheduled(now)
|
||||
self.edge = now + max(5, min(240, int(minutes))) * 60
|
||||
self._save()
|
||||
|
||||
@property
|
||||
@@ -1213,7 +1226,8 @@ class ServiceMode:
|
||||
return self.hold and self.override is False
|
||||
|
||||
def _save(self):
|
||||
self.state.set(self.name, {"override": self.override, "last_sched": self.last_sched, "edge": self.edge, "hold": self.hold})
|
||||
self.state.set(self.name, {"override": self.override, "last_sched": self.last_sched, "edge": self.edge, "hold": self.hold,
|
||||
"test": self.test})
|
||||
|
||||
def until(self, now):
|
||||
"""When the state shown now next changes by itself (an override's end, else the schedule's next edge),
|
||||
@@ -2379,6 +2393,8 @@ def render(engine, service_on):
|
||||
when = ("" if same_day else datetime.fromtimestamp(until).strftime("%a ").upper()) + clock12(until)
|
||||
if engine.autofix.paused:
|
||||
text = "%s\nPAUSED" % tile["label"] + ("\nTIL " + when if when else "")
|
||||
elif engine.autofix.test and on:
|
||||
text = "%s\nTESTING" % tile["label"] + ("\nTIL " + when if when else "")
|
||||
elif on:
|
||||
text = "%s\nON" % tile["label"] + ("\nTIL " + when if when else "")
|
||||
else:
|
||||
@@ -3751,7 +3767,8 @@ def snapshot_summary(snap, engine, now):
|
||||
"service_on": engine.service.on(now),
|
||||
"alarms_override": engine.service.override,
|
||||
"auto_fix": {"on": engine.auto_on, "net_wait": engine.auto_paused, "split": engine.split,
|
||||
"switch": engine.autofix.on(now), "override": engine.autofix.override, "paused": engine.autofix.paused},
|
||||
"switch": engine.autofix.on(now), "override": engine.autofix.override, "paused": engine.autofix.paused,
|
||||
"test_until": engine.autofix.edge if engine.autofix.test else None},
|
||||
"bypass": {tid: {"since": b.get("since")} for tid, b in engine.bypass.items()},
|
||||
"failover": dict(engine.failed),
|
||||
"burst": engine.burst and {"start": engine.burst["start"], "conns": sorted(engine.burst["conns"]),
|
||||
@@ -3797,6 +3814,14 @@ def handle_commands(text, engine, comp, snap, now):
|
||||
target = {"on": True, "off": False}.get(arg, not engine.service.on(now))
|
||||
engine.service.set(target, now)
|
||||
log.info("SERVICE %s (button)", "ON" if target else "OFF")
|
||||
elif verb == "autofix" and arg == "test":
|
||||
# The settings page: "autofix test <minutes>" turns auto-fix on now, outside its hours, to try it out.
|
||||
mins = int(words[2]) if len(words) > 2 and words[2].isdigit() else 60
|
||||
engine.autofix.test_on(now, mins)
|
||||
log.info("AUTO-FIX ON FOR TESTING until %s", datetime.fromtimestamp(engine.autofix.edge).strftime("%H:%M"))
|
||||
if engine.autolog:
|
||||
engine.autolog.write(now, "PANEL", "auto-fix on for testing (settings page) until %s"
|
||||
% datetime.fromtimestamp(engine.autofix.edge).strftime("%H:%M"))
|
||||
elif verb == "autofix":
|
||||
# The AUTO-FIX key pauses and resumes; "off"/"pause" and "on"/"auto"/"resume" say which (NA's ALL AUTO-FIX key).
|
||||
pause = {"off": True, "pause": True, "on": False, "auto": False, "resume": False}.get(arg, not engine.autofix.paused)
|
||||
|
||||
Reference in New Issue
Block a user