From f7346d6f5e0aab810be910c5d3a5dc5752d12039 Mon Sep 17 00:00:00 2001 From: christian Date: Thu, 8 Oct 2026 16:21:19 -0400 Subject: [PATCH] Vista gets its own button (row 2, next to APPS) The Art-Net heartbeat moves from APPS to a VISTA tile ("VISTA / SILENT"; "VISTA SILENT" on SHOW and ALL), hold starts Vista if it is not running. SHOW now groups MIDI, APPS and VISTA. Tested live before the move: closing Vista and Resolume alarmed, and each hold brought them back (Vista 5 s, Arena 9 s after the hold). Co-Authored-By: Claude Opus 5.5 --- README.md | 9 +++++---- config.json | 6 ++++-- status_panel.py | 3 ++- tests/test_status_panel.py | 9 ++++++++- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 86da83f..3611d43 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ There are two parts: |--------|-------|-------|-------|-------|-------|-------|-------|-------| | row 0 | UP | **ALL** | REC | AUDIO | RF | SHOW | VIDEO | STREAM | | row 1 | page | HD1 | HD2 | HD3 | HD4 | HD5 | HD6 | TASCAM | -| row 2 | DOWN | X32 | DANTE | MIDI | APPS | | | | +| row 2 | DOWN | X32 | DANTE | MIDI | APPS | VISTA | | | | row 3 | ALARMS | ATEM | OBS | RESI | NET | INGEST | LED | ARENA | Row 0 holds the group buttons. Each one shows the first problem in its group, plus "+N" if there are more: @@ -21,7 +21,7 @@ Row 0 holds the group buttons. Each one shows the first problem in its group, pl - REC: HD1–6 and the Tascam. - AUDIO: X32 and Dante. - RF: all six Shure units (AD4Q ×2, ULXD4, PSM1000 ×3). -- SHOW: MIDI and APPS. +- SHOW: MIDI, APPS and VISTA. - VIDEO: ATEM, LED and Arena. - STREAM: OBS and Resi. @@ -47,7 +47,7 @@ Row 0 holds the group buttons. Each one shows the first problem in its group, pl | APPS: PROPRES OFFLINE / NOT RUNNING | restarts ProPresenter on its Mac (the newest version installed) | | APPS: ABLETON / TRANSLATE NOT RUNNING | starts Ableton on the Tracks Mac / Church Translate on NA Translation | | APPS: BIBLE APP DOWN | restarts the Bible app on the Sanctuary TV PC (SSH + its "Start BibleApp" task from `remote-access/windows-setup.ps1`) | - | APPS: VISTA SILENT | starts Vista on the Lighting PC if it is not running. A running Vista is never closed. | + | VISTA: SILENT | starts Vista on the Lighting PC if it is not running. A running Vista is never closed. | | ARENA | starts Resolume Arena on the Lighting PC if it is not running, then reconnects Companion | | OBS | starts OBS on the LiveStream PC if it is not running, then reconnects Companion. If the PC is off, it is woken (Wake-on-LAN) and the button shows WAKING PC; hold again once someone has logged in. | | MIDI: LIGHT PC / FX LIGHTS / SUPERRACK MIDI LOST | reconnects that peer to the session it dropped out of, from the Mac's side (NA Ingest's own session, or NA Tracks' over SSH), like Connect in Audio MIDI Setup. Other peers are left alone and nothing is restarted. The address is where the peer was last seen, else `"address"` on the check. Not for a missing Bonjour advert ("... MIDI GONE"). **Keep the Lighting PC's network on Public:** its Bonjour firewall rules only allow Public, and on Private it vanishes from the MIDI directory and cannot rejoin a session (2026-10-08). Never restart rtpMIDI as a fix: it drops every session and does not rejoin them. | @@ -86,7 +86,8 @@ 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; Ableton OSC; tracks Mac pings; Bible TV app answering on :8080 (every 5 s); Bible TV OSC; **Vista** on the Lighting PC: its Art-Net poll (sent every 0.5 s) must be heard within 5 s, otherwise "VISTA SILENT" (Vista closed, crashed, or the Lighting PC is off the network). Resolume is checked by the ARENA button. Messages name the app ("PROPRES OFFLINE", "BIBLE APP DOWN"). Hold 2 s restarts the ProPresenter, Ableton and Bible TV Companion connections. | +| APPS | ProPresenter API; 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. | +| 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. Resolume is the ARENA button. | | RESI | decoder (RossTalk connection and ping); resi-studio-cues; Resi cloud reachable | | 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) | | INGEST | Resi bridge and lobby captions services running; ProdDash running; free disk | diff --git a/config.json b/config.json index 66f971b..14c3ca6 100644 --- a/config.json +++ b/config.json @@ -72,7 +72,7 @@ { "id": "rec", "label": "REC", "pos": [0, 2], "members": ["hd1", "hd2", "hd3", "hd4", "hd5", "hd6", "tascam"] }, { "id": "audio", "label": "AUDIO", "pos": [0, 3], "members": ["x32", "dante"] }, { "id": "rf", "label": "RF", "pos": [0, 4], "members": ["axient1", "axient2", "ulxd", "psm1", "psm2", "psm3"] }, - { "id": "show", "label": "SHOW", "pos": [0, 5], "members": ["midi", "apps"] }, + { "id": "show", "label": "SHOW", "pos": [0, 5], "members": ["midi", "apps", "vista"] }, { "id": "video", "label": "VIDEO", "pos": [0, 6], "members": ["atem", "led", "arena"] }, { "id": "stream", "label": "STREAM", "pos": [0, 7], "members": ["obs", "resi"] }, @@ -109,6 +109,9 @@ { "type": "mdns", "instance": "NA Tracks", "name": "TRACKS MIDI" }, { "type": "midi_rx", "source": "Network NA Ingest Listen", "name": "TRACKS IN" } ] }, + { "id": "vista", "label": "VISTA", "pos": [2, 5], "checks": [ + { "type": "artnet", "source": "10.1.10.206", "max_silence_seconds": 5, "fix": "vista" } + ] }, { "id": "apps", "label": "APPS", "pos": [2, 4], "checks": [ { "type": "conn", "conn": "Propresenter-API", "tag": "PROPRES", "fix": "propresenter" }, { "type": "remote", "host": "prop", "cmd": "pgrep -xq ProPresenter", "msg": "PROPRES NOT RUNNING", "fix": "propresenter" }, @@ -116,7 +119,6 @@ { "type": "remote", "host": "tracks", "cmd": "pgrep -xq Live", "msg": "ABLETON NOT RUNNING", "fix": "ableton" }, { "type": "remote", "host": "translation", "cmd": "pgrep -xq 'Church Translate'", "msg": "TRANSLATE NOT RUNNING", "fix": "translate" }, { "type": "ping", "host": "10.1.3.227", "name": "TRACKS MAC" }, - { "type": "artnet", "source": "10.1.10.206", "max_silence_seconds": 5, "msg": "VISTA SILENT", "fix": "vista" }, { "type": "http", "url": "http://10.6.7.13:8080/", "msg": "BIBLE APP DOWN", "interval_seconds": 5, "fix": "bibleapp" }, { "type": "conn", "conn": "BibleTV", "tag": "BIBLE OSC" } ] }, diff --git a/status_panel.py b/status_panel.py index e572823..b70a976 100644 --- a/status_panel.py +++ b/status_panel.py @@ -449,7 +449,8 @@ def check_artnet(chk, snap, ctx): return [("artnet", Result(OK))] last = snap.artnet_last.get(chk["source"]) if last is None or ctx["now"] - last > limit: - return [("artnet", Result(ERR, chk.get("msg", "ART-NET SILENT"), named=True))] + # A custom "msg" names the program itself ("VISTA SILENT"); on its own button plain "SILENT" will do. + return [("artnet", Result(ERR, chk.get("msg", "SILENT"), named="msg" in chk))] return [("artnet", Result(OK))] diff --git a/tests/test_status_panel.py b/tests/test_status_panel.py index 8abd0b4..881195a 100644 --- a/tests/test_status_panel.py +++ b/tests/test_status_panel.py @@ -226,6 +226,12 @@ class TestChecks(unittest.TestCase): self.assertEqual(sp.check_artnet(chk, self.snap, self.ctx)[0][1].level, sp.OK) self.snap.artnet_since = None # could not listen: no verdict self.assertEqual(sp.check_artnet(chk, self.snap, self.ctx)[0][1].level, sp.OK) + # its own button: "VISTA / SILENT", and the groups say "VISTA SILENT" + self.snap.artnet_since, self.snap.artnet_last = self.now - 60, {"10.1.10.206": self.now - 8} + tiles, _ = run_steps(sp.Engine(CONFIG), self.snap, self.now, 4) + self.assertEqual(tiles["vista"]["x"], "VISTA\nSILENT") + self.assertEqual(tiles["show"]["x"], "SHOW\nVISTA SILENT") + self.assertEqual(tiles["apps"]["x"], "APPS\nOK") def test_artnet_listener_hears_a_poll(self): import socket as _s @@ -527,7 +533,8 @@ class TestFixes(unittest.TestCase): self.snap.mdns = self.snap.mdns - {"Lighting PC"} self.assertEqual(self.plan("obs"), [("fix", "obs")]) self.assertEqual(self.plan("arena"), [("fix", "arena")]) - self.assertEqual(self.plan("apps"), [("fix", "vista")]) + self.assertEqual(self.plan("vista"), [("fix", "vista")]) + self.assertEqual(self.plan("apps"), []) # Restarting rtpMIDI drops every session and does not rejoin them (2026-10-08): the hold # starts rtpMIDI only if it is not running, and reconnects the peer from the Mac's side. self.assertEqual(sorted(self.plan("midi")), [("fix", "midi_reconnect"), ("fix", "rtpmidi_start")])