From 38b6616e3f7bbbdc524efc6be832d3f93b5f482b Mon Sep 17 00:00:00 2001 From: christian Date: Thu, 8 Oct 2026 09:15:46 -0400 Subject: [PATCH] Make the DANTE button count all 19 watched devices. It now reads 19/19 to match Dante Controller. NA-Tracks, SuperRack and the ProPresenter Mac still alarm on their own buttons, so a drop is not flagged twice; DANTE just shows 18/19 while one of them is missing. Co-Authored-By: Claude Opus 5.5 --- README.md | 2 +- config.json | 2 +- status_panel.py | 13 +++++++++++-- tests/test_status_panel.py | 11 ++++++++++- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ebde987..6d9f937 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ Row 0 holds the group tiles. Each one shows the first problem in its group, plus | | HD2 and HD4 are `"optional": true` in `config.json`: with no disk they sit grey with no alarm, and once a disk is in they are watched like the others. Add or remove `"optional": true` on any deck to change that. | | TASCAM | connection; the recorder's own Error / Caution | | X32, ATEM, ARENA, LED, OBS | Companion connection | -| DANTE | 16 devices present: DiGiCo DMIs, WING, DQ rack, AD4Qs, Studio A X32 / Resi AJA / Ingest, Translation, and Studio B (RedNet TNX, TB, TB MON, MON, SOLO MON, Tascam). NA-Tracks, SuperRack and the ProPresenter Mac are on their own buttons. | +| DANTE | Shows all 19 watched Dante devices as "19/19" (matches Dante Controller). Alarms for 16 of them: DiGiCo DMIs, WING, DQ rack, AD4Qs, Studio A X32 / Resi AJA / Ingest, Translation, and Studio B (RedNet TNX, TB, TB MON, MON, SOLO MON, Tascam). NA-Tracks, SuperRack and the ProPresenter Mac are on their own buttons. | | TRACKS | NA-Tracks Dante device; tracks Mac pings; "NA Tracks" MIDI session still on the network; Ableton OSC connection | | LIGHT PC | Lighting PC still joined to NA Ingest's network MIDI session; its MIDI session still on the network | | RACK | SuperRack-LiveBox still joined to the MIDI session; its Dante device | diff --git a/config.json b/config.json index cdca780..8017403 100644 --- a/config.json +++ b/config.json @@ -41,7 +41,7 @@ { "id": "x32", "label": "X32", "pos": [2, 1], "checks": [{ "type": "conn", "conn": "x32" }] }, { "id": "dante", "label": "DANTE", "pos": [2, 2], "checks": [ - { "type": "dante", "conn": "audinate-dantecontroller", "devices": { + { "type": "dante", "conn": "audinate-dantecontroller", "count_all": true, "devices": { "FOH-DiGiCo-DMI-1": "DMI-1", "FOH-DiGiCo-DMI-2": "DMI-2", "BOH-WING": "WING", "BOH-DQ-Rack": "DQ RACK", "BOH-AD4Q-A": "AD4Q-A", "BOH-AD4Q-B": "AD4Q-B", "STUDIO-A-X32": "STA X32", "STUDIO-A-Resi-AJA-SDI": "RESI AJA", "STUDIO-A-Ingest": "INGEST", "NA-Translation": "TRANSL", diff --git a/status_panel.py b/status_panel.py index 54ea983..d2f3fbf 100644 --- a/status_panel.py +++ b/status_panel.py @@ -268,7 +268,12 @@ def check_dante(chk, snap, ctx): out.append((name, Result(OK))) else: out.append((name, Result(ERR, alias + " GONE", service_only=chk.get("service_only", False)))) - if len(devices) > 1: + if chk.get("count_all"): + # Count every Dante device watched anywhere on the page, so the number + # matches Dante Controller; alarms still belong to each device's own button. + everything = ctx["dante_all"].get(label, set()) + out.insert(0, ("conn", Result(OK, info="%d/%d" % (len(everything & present), len(everything))))) + elif len(devices) > 1: out.insert(0, ("conn", Result(OK, info="%d/%d" % (seen, len(devices))))) return out @@ -571,7 +576,11 @@ class Engine: # raw results for every check key def evaluate(self, snap, now, service_on): - ctx = {"now": now, "service": service_on, "any_recording": False} + ctx = {"now": now, "service": service_on, "any_recording": False, "dante_all": {}} + for t in self.cfg["tiles"]: + for chk in t.get("checks", []): + if chk["type"] == "dante": + ctx["dante_all"].setdefault(chk["conn"], set()).update(chk["devices"]) for t in self.cfg["tiles"]: for chk in t.get("checks", []): if chk["type"] == "hyperdeck" and chk.get("rec_sync", True): diff --git a/tests/test_status_panel.py b/tests/test_status_panel.py index 31d66db..a1be75e 100644 --- a/tests/test_status_panel.py +++ b/tests/test_status_panel.py @@ -100,7 +100,7 @@ class TestChecks(unittest.TestCase): self.assertEqual(bad, {}) self.assertEqual(tiles["all"]["x"], "ALL OK") self.assertEqual(tiles["hd1"]["x"], "HD1\n28h") - self.assertEqual(tiles["dante"]["x"], "DANTE\n16/16") + self.assertEqual(tiles["dante"]["x"], "DANTE\n19/19") def test_connection_states(self): c = self.snap.conns["ATEM"] @@ -167,6 +167,15 @@ class TestChecks(unittest.TestCase): out = dict(sp.check_dante({"conn": "audinate-dantecontroller", "devices": ["BOH-WING"]}, self.snap, self.ctx)) self.assertEqual(out["conn"].msg, "NO DATA") + def test_dante_count_includes_other_buttons(self): + devices = json.loads(self.snap.vars[("audinate-dantecontroller", "devices")]) + devices.remove("NA-Tracks") + self.snap.vars[("audinate-dantecontroller", "devices")] = json.dumps(devices) + tiles, _ = run_steps(sp.Engine(CONFIG), self.snap, self.now, 4) + self.assertEqual(tiles["dante"]["x"], "DANTE\n18/19") + self.assertEqual(level(tiles["dante"]), "ok") # the alarm is on TRACKS, not twice + self.assertEqual(tiles["tracks"]["x"], "TRACKS\nDANTE GONE") + def test_shure_psm_tascam(self): s = self.snap s.vars[("Axient_1", "ch_1_battery_bars")] = "1"