diff --git a/README.md b/README.md index 0fc2557..1c35faf 100644 --- a/README.md +++ b/README.md @@ -256,7 +256,7 @@ The **page number key** on every page follows the ALL button. It's green when ev | LED | VX1000 and UHD Jr: Companion connection **and** each one answers ping (the NovaStar module keeps saying "Connected" after a processor is switched off). "UHDJR NO PING" = processor off or unreachable; "UHDJR OFFLINE" = Companion's connection failed; "UHDJR DISABLED" (amber) = connection turned off in Companion. | | DANTE | All 19 Dante devices ("19/19"), named when one drops: "WING GONE", "TRACKS GONE", "PROP MAC GONE". | | MIDI | All six network MIDI links on the FOH / Studio B checklist, each named when it drops: **LIGHT PC** (Ingest → Lighting), **SUPERRACK** (Ingest → Livebox), **FX LIGHTS** (Tracks → Lighting, the FX lighting cues), **TRK LIVEBOX** (Tracks → Livebox), **TRK STUDIO B** (Tracks → Studio B), **PROP LIGHTS** (ProPresenter → Lighting). NA Ingest's own session is read locally; NA Tracks' and NA ProP's over SSH every 5 s. Also: the Lighting PC and NA Tracks MIDI sessions still announced on the network. A clean disconnect shows within about 10 s; a crash or pulled cable takes about a minute (macOS's own timeout, measured). Hold 2 s reconnects whichever links dropped. | -| APPS | ProPresenter API (offline or error only: its harmless yellow warning, every 15–20 min, is ignored with `"ignore_warning": true`); Ableton OSC; tracks Mac pings; Bible TV app answering on :8080 (every 5 s); Bible TV OSC. Messages name the app ("PROPRES OFFLINE", "BIBLE APP DOWN"). Hold 2 s restarts the ProPresenter, Ableton and Bible TV Companion connections.; **Pro Tools on the Studio B Mac Studio** set to Solo Mode **AFL + Latch** ("PT SOLO NOT AFL"; hold, or Sunday auto-fix, ticks them back). A helper on that Mac (`remote-access/solo-mode-agent.swift`, installed with `install-solo-mode.sh`) reads the menu; it needs Accessibility allowed once, then a restart of the helper. "PT SOLO CHECK OFF" = that helper is not running or not allowed. | +| APPS | ProPresenter API (offline or error only: its harmless yellow warning, every 15–20 min, is ignored with `"ignore_warning": true`); Ableton OSC; tracks Mac pings; Bible TV app answering on :8080 (every 5 s); Bible TV OSC; **AbleSet** running on the Tracks Mac (ProdDash shows it): **ABLESET NOT RUNNING**, and the hold (and auto-fix) opens it in the background and minimizes its window (`mac_start` with *Minimized*). Messages name the app ("PROPRES OFFLINE", "BIBLE APP DOWN"). Hold 2 s restarts the ProPresenter, Ableton and Bible TV Companion connections.; **Pro Tools on the Studio B Mac Studio** set to Solo Mode **AFL + Latch** ("PT SOLO NOT AFL"; hold, or Sunday auto-fix, ticks them back). A helper on that Mac (`remote-access/solo-mode-agent.swift`, installed with `install-solo-mode.sh`) reads the menu; it needs Accessibility allowed once, then a restart of the helper. "PT SOLO CHECK OFF" = that helper is not running or not allowed. | | VISTA | Vista on the Lighting PC: its Art-Net poll (sent every 0.5 s) must be heard within 5 s, otherwise **SILENT** (Vista closed or crashed, or the Lighting PC is off the network). Hold 2 s starts Vista if it is not running; Vista then opens **Prop Takeover** from its show folder (`E:\media\Documents\Vista 3\Shows`) by itself, through its own autoload preference (`` in `E:\media\Documents\Vista 3\.preferences`, set 2026-10-08). Resolume is the ARENA button. | | RESI | decoder (RossTalk connection and ping, 10.1.10.203); **encoder** (ping and its web page, 10.1.10.202, LAOEncoder); resi-studio-cues; Resi cloud reachable. Only shows they are on the network, not that the encoder is streaming. | | NET | NA Ingest's link; gateway 10.1.0.1 pings; **4+ connections from 3+ groups dropping within 10 s** (what happened Sunday 10/5 at 10:21). A blip **flashes amber** for 5 minutes, then goes by itself; press NET to stop the flashing, hold NET 2 s to clear it now. | diff --git a/config.json b/config.json index 9ae466f..e558d90 100644 --- a/config.json +++ b/config.json @@ -24,6 +24,7 @@ "arena", "obs", "ableton", + "ableset", "translate", "dvs_prop", "dvs_tracks", @@ -530,6 +531,20 @@ "label": "build this week's Ableton sets (Sunday and special services) from Planning Center", "never_auto": true, "short": "START" + }, + "ableset": { + "host": "tracks", + "kind": "ssh", + "label": "start AbleSet on the Tracks Mac if it is not running (minimized, for ProdDash)", + "params": { + "host": "tracks", + "process": "AbleSet", + "app": "AbleSet", + "minimized": true + }, + "run": "pgrep -xq AbleSet || { open -g -a AbleSet; i=0; while [ $i -lt 20 ]; do sleep 1; i=$((i+1)); n=$(osascript -e 'tell application \"System Events\" to count windows of process \"AbleSet\"' 2>/dev/null); if [ \"${n:-0}\" -gt 0 ]; then osascript -e 'tell application \"System Events\" to tell process \"AbleSet\" to set value of attribute \"AXMinimized\" of every window to true' >/dev/null 2>&1; break; fi; done; }", + "short": "ABLESET", + "template": "mac_start" } }, "flap": { @@ -2246,6 +2261,18 @@ "template": "mac_program", "type": "remote" }, + { + "cmd": "pgrep -xq AbleSet", + "fix": "ableset", + "host": "tracks", + "msg": "ABLESET NOT RUNNING", + "params": { + "host": "tracks", + "process": "AbleSet" + }, + "template": "mac_program", + "type": "remote" + }, { "cmd": "pgrep -xq 'Church Translate'", "fix": "translate", diff --git a/schema.py b/schema.py index 1f213e3..db77144 100644 --- a/schema.py +++ b/schema.py @@ -535,7 +535,7 @@ GLOSSARY = { "NOT PLAYING", "WRONG PLAYLIST", "SPOTIFY CLOSED", "STOPPED", "NOT LOADED", "MIDI LOST", "MIDI", "GONE", "DISABLED", "OFFLINE", "NO SESSION", "NOT RUNNING", "DOWN", "NOT REC", "SILENT", "WARNING", "STARTING", "ATEM AUDIO WRONG", "ATEM CAMERA WRONG", "ATEM SW MIDI ON", "PT SOLO NOT AFL", "PROPRES NOT RUNNING", - "ABLETON NOT RUNNING", "TRANSLATE NOT RUNNING", "PROP TV DOWN", "BIBLE APP DOWN", "PRODCOM DOWN", "PRODDASH DOWN", + "ABLETON NOT RUNNING", "ABLESET NOT RUNNING", "TRANSLATE NOT RUNNING", "PROP TV DOWN", "BIBLE APP DOWN", "PRODCOM DOWN", "PRODDASH DOWN", "ENCODER WEB DOWN", "PT SOLO CHECK OFF", "UNREACH", "DROPPED", ], "check the device or the cable": [ diff --git a/settings/builders.py b/settings/builders.py index 60ad338..fae1d63 100644 --- a/settings/builders.py +++ b/settings/builders.py @@ -99,6 +99,16 @@ ABLETON_SET = ("L=$(ls -td ~/Library/Preferences/Ableton/Live*/ | head -1); S=$( "| grep -v '/Templates/' | tail -1 | sed -E 's/^.*Loading document \"(.*)\"[^\"]*$/\\1/'); ") +def mac_minimize(process, wait=20): + """Once the program has a window (up to `wait` s), minimize every window it has (System Events: osascript + has Accessibility on the computer).""" + ax = "tell application \"System Events\" to %s process \"%s\"" % ("%s", str(process).replace('"', '')) + count = q(ax % "count windows of") + mini = q((ax % "tell") + " to set value of attribute \"AXMinimized\" of every window to true") + return ("i=0; while [ $i -lt %d ]; do sleep 1; i=$((i+1)); n=$(osascript -e %s 2>/dev/null); " + "if [ \"${n:-0}\" -gt 0 ]; then osascript -e %s >/dev/null 2>&1; break; fi; done;" % (wait, count, mini)) + + def ableton_open(app): return "if [ -n \"$S\" ] && [ -f \"$S\" ]; then %s; else %s; fi" % (mac_open(app, arg="\"$S\""), mac_open(app)) @@ -126,9 +136,12 @@ TEMPLATES = { "os": "mac", "start_only": True, "params": [P_HOST, ("process", "Process name", "As pgrep sees it (Activity Monitor's process name).", "str", None), ("app", "App to open", "Its name, the full /Applications/... path, or $APP with 'newest of' below.", "str", None), - ("newest_of", "Newest of", "A pattern like /Applications/ProPresenter*.app: the newest installed version opens.", "str", "")], + ("newest_of", "Newest of", "A pattern like /Applications/ProPresenter*.app: the newest installed version opens.", "str", ""), + ("minimized", "Minimized", "Open it in the background and minimize its window (AbleSet: open, out of the way).", "bool", False)], "render": lambda p, cfg: ("pgrep -xq %s || { %s%s; }" % (q(p["process"]), newest_app(p["newest_of"]), mac_open("$APP")) - if p.get("newest_of") else "pgrep -xq %s || %s" % (q(p["process"]), mac_open(p["app"]))), + if p.get("newest_of") else + "pgrep -xq %s || { %s; %s }" % (q(p["process"]), mac_open(p["app"], background=True), mac_minimize(p["process"])) + if p.get("minimized") else "pgrep -xq %s || %s" % (q(p["process"]), mac_open(p["app"]))), "suggest": lambda p, cfg: "start %s if it is not running" % p["app"], }, "mac_restart": { diff --git a/tests/test_builders.py b/tests/test_builders.py index 900262f..ac05d75 100644 --- a/tests/test_builders.py +++ b/tests/test_builders.py @@ -35,7 +35,7 @@ class TestTodaysFixes(unittest.TestCase): if c.get("template"): self.assertEqual(b.build_check(CFG, c)["cmd"], c["cmd"]) n += 1 - self.assertEqual(n, 6) + self.assertEqual(n, 7) # 7th: AbleSet on the Tracks Mac (2026-10-25) def test_a_changed_command_is_refused_by_validate(self): cfg = json.loads(json.dumps(CFG))