Wiring: layouts (Hub, Columns, Groups, Free), All/None, Dante in its own box, gentle trackpad zoom; fix the Keys pages (a second wireLayout) and Computers > Setup (a second setupHtml)

RossTalk and OSC: the watchdog reads Companion's RossTalk port (ROSSTALK OFF, PROP ROSSTALK LOST at NA/WS/SC),
Bible TV and Ableton must be listening for Companion's OSC (BIBLE OSC OFF, ABLETON OSC OFF), and both are their own
connection types on the Wiring screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-27 13:45:09 -04:00
co-authored by Claude Opus 5.5
parent 26804e4ce2
commit 5d0263a9b9
11 changed files with 490 additions and 165 deletions
+19 -1
View File
@@ -109,8 +109,12 @@ class TestServer(unittest.TestCase):
json.dump(live, open(os.path.join(self.data, "machines-live.json"), "w"))
snap = json.load(open(os.path.join(self.data, "snapshot.json")))
snap.update({"conns": {"ATEM": {"category": "good", "enabled": True}, "x32": {"category": "error", "enabled": True},
"BibleTV": {"category": "good", "enabled": True}, "RESI_Decoder": {"category": "good", "enabled": True},
"HyperDeck_1": {"category": "good", "enabled": True}, "tcp-HyperDeck-1": {"category": "good", "enabled": True}},
"conn_hosts": {"ATEM": "10.1.10.2", "x32": "10.1.1.112", "HyperDeck_1": "10.1.10.11", "tcp-HyperDeck-1": "10.1.10.11"},
"conn_hosts": {"ATEM": "10.1.10.2", "x32": "10.1.1.112", "HyperDeck_1": "10.1.10.11", "tcp-HyperDeck-1": "10.1.10.11",
"BibleTV": "10.6.7.13", "RESI_Decoder": "10.1.10.203"},
"conn_info": {"BibleTV": {"module": "generic-osc", "port": 3333}, "RESI_Decoder": {"module": "resi-decoders", "port": None}},
"rosstalk": {"listen": True, "clients": [{"ip": "10.1.14.225", "cmd": ""}], "targets": ["10.1.10.203"], "time": time.time()},
"remote_midi": {"tracks": {"NA Tracks": {"peers": [{"address": "10.1.13.140:5004", "name": "SuperRack-LiveBox", "state": "running"}]}}},
"dante_map": {"NA-Tracks": {"switch": "10.66.1.100", "port": "0/6", "seen": time.time()},
"FOH-SuperRack-LiveBox": {"switch": "10.66.1.102", "port": "0/9", "seen": time.time()},
@@ -134,6 +138,9 @@ class TestServer(unittest.TestCase):
self.assertIn(("dante", "h:tracks", "sw:10.66.1.100", "ok"), edges) # NA-Tracks is the Tracks Mac
self.assertIn("FOH-SuperRack-LiveBox", nodes["d:10.1.13.140"]["names"]) # same box as its MIDI peer
self.assertIn("d:studiobmon", nodes) # a monitor, not the Studio B Mac
self.assertIn(("osc", "h:ingest", "h:bibletv", "ok"), edges) # OSC to the Bible TV PC
self.assertIn(("rosstalk", "h:ingest", "d:10.1.10.203", "ok"), edges) # RossTalk to the Resi decoder
self.assertIn(("rosstalk", "h:prop", "h:ingest", "ok"), edges) # ProPresenter's cues into Companion
self.assertEqual({t["id"] for t in w["types"]} >= {"companion", "midi", "watch", "dante"}, True)
def test_gear_and_keys_and_pages(self):
@@ -416,6 +423,17 @@ class TestBindingAndProbes(unittest.TestCase):
tasks={"\\StatusPanel\\Start Vista": "Running", "\\StatusPanel\\Start rtpMIDI": "Ready"})
self.assertEqual([(x["name"], x["running"]) for x in win], [("Start Vista", True), ("start-vista.ps1", True), ("Start rtpMIDI", False)])
def test_the_page_script_has_no_two_functions_with_one_name(self):
# 2026-10-27: a second wireLayout (the Wiring screen's) replaced the Keys screen's and broke it ("null errors"),
# and a second setupHtml had broken Computers > Setup the same way.
import collections
import re
js = open(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "settings", "ui", "app.js")).read()
# the page's own names: two spaces in, inside its one (function () { ... })
names = collections.Counter(re.findall(r"^ (?:async )?function\s+([A-Za-z0-9_$]+)\s*\(", js, re.M))
names.update(re.findall(r"^ (?:const|let)\s+([A-Za-z0-9_$]+)\s*=", js, re.M))
self.assertEqual([n for n, c in names.items() if c > 1], [])
def test_probe_commands_never_carry_names_from_the_settings(self):
cfg = json.loads(json.dumps(CONFIG))
cfg["hosts"]["tracks"]["runs"][1]["process"] = "x; rm -rf ~" # a hostile name in the settings