ATEM: alarm when ATEM Software Control's MIDI control is turned on
New 'pref' check reads an app setting on NA Ingest (defaults read) every 10 s; ATEM shows ATEM SW MIDI ON if midiEnabled is not 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+4
-1
@@ -171,7 +171,10 @@
|
||||
] },
|
||||
|
||||
{ "id": "service", "label": "ALARMS", "pos": [3, 0], "kind": "service" },
|
||||
{ "id": "atem", "label": "ATEM", "pos": [3, 1], "checks": [{ "type": "conn", "conn": "ATEM" }] },
|
||||
{ "id": "atem", "label": "ATEM", "pos": [3, 1], "checks": [
|
||||
{ "type": "conn", "conn": "ATEM" },
|
||||
{ "type": "pref", "domain": "com.blackmagic-design.ATEM Software Control", "key": "midiEnabled", "want": "0", "msg": "ATEM SW MIDI ON" }
|
||||
] },
|
||||
{ "id": "obs", "label": "OBS", "pos": [3, 2], "checks": [{ "type": "conn", "conn": "OBS-Youtube", "service_only": true, "fix": "obs" }] },
|
||||
{ "id": "resi", "label": "RESI", "pos": [3, 3], "checks": [
|
||||
{ "type": "conn", "conn": "RESI_Decoder", "tag": "DECODER" },
|
||||
|
||||
+14
-1
@@ -149,6 +149,7 @@ class Snapshot:
|
||||
self.remote_midi_time = {} # host -> when it last reported
|
||||
self.peer_addr = {} # (host or "", session, peer) -> address it was last seen at
|
||||
self.conn_hosts = {} # Companion connection label -> its "host" setting
|
||||
self.prefs = {} # (preferences domain, key) -> value as "defaults read" prints it
|
||||
self.midi_time = 0.0
|
||||
self.mdns = set() # Bonjour _apple-midi._udp instance names
|
||||
self.mdns_time = 0.0
|
||||
@@ -415,6 +416,14 @@ def check_http(chk, snap, ctx):
|
||||
return [("http", Result(OK))]
|
||||
|
||||
|
||||
def check_pref(chk, snap, ctx):
|
||||
"""An app setting on NA Ingest, e.g. ATEM Software Control's "Enable MIDI control" must stay off."""
|
||||
value = snap.prefs.get((chk["domain"], chk["key"]))
|
||||
if value is None or value == str(chk["want"]):
|
||||
return [("pref", Result(OK))] # not read yet, or as it should be
|
||||
return [("pref", Result(ERR, chk["msg"], named=True))]
|
||||
|
||||
|
||||
def check_disk(chk, snap, ctx):
|
||||
free = snap.disk.get(chk["path"])
|
||||
if free is None:
|
||||
@@ -496,7 +505,7 @@ def check_remote(chk, snap, ctx):
|
||||
CHECKS = {
|
||||
"conn": check_conn, "hyperdeck": check_hyperdeck, "dante": check_dante, "shure": check_shure,
|
||||
"psm": check_psm, "tascam": check_tascam, "ping": check_ping, "launchd": check_launchd,
|
||||
"process": check_process, "http": check_http, "disk": check_disk, "midi_peer": check_midi_peer,
|
||||
"process": check_process, "http": check_http, "disk": check_disk, "midi_peer": check_midi_peer, "pref": check_pref,
|
||||
"mdns": check_mdns, "midi_rx": check_midi_rx, "remote": check_remote, "artnet": check_artnet,
|
||||
}
|
||||
|
||||
@@ -1451,6 +1460,10 @@ def poll_system(snap, cfg):
|
||||
elif c["type"] == "disk":
|
||||
usage = shutil.disk_usage(c["path"])
|
||||
snap.disk = dict(snap.disk, **{c["path"]: int(usage.free / 1e9)})
|
||||
elif c["type"] == "pref":
|
||||
r = subprocess.run(["/usr/bin/defaults", "read", c["domain"], c["key"]], capture_output=True,
|
||||
text=True, timeout=5)
|
||||
snap.prefs[(c["domain"], c["key"])] = r.stdout.strip() if r.returncode == 0 else None
|
||||
snap.procs = procs
|
||||
|
||||
|
||||
|
||||
@@ -275,6 +275,14 @@ class TestChecks(unittest.TestCase):
|
||||
self.assertIn("solo_afl", CONFIG["auto_fix"]["fixes"])
|
||||
self.assertIn('"bad":true', chk["cmd"])
|
||||
|
||||
def test_atem_software_midi_control_must_stay_off(self):
|
||||
key = ("com.blackmagic-design.ATEM Software Control", "midiEnabled")
|
||||
engine = sp.Engine(CONFIG)
|
||||
self.snap.prefs[key] = "0"
|
||||
self.assertEqual(run_steps(engine, self.snap, self.now, 4)[0]["atem"]["x"], "ATEM\nOK")
|
||||
self.snap.prefs[key] = "1"
|
||||
self.assertEqual(run_steps(engine, self.snap, self.now + 5, 4)[0]["atem"]["x"], "ATEM\nATEM SW MIDI ON")
|
||||
|
||||
def test_propresenter_yellow_warning_is_ignored(self):
|
||||
engine = sp.Engine(CONFIG)
|
||||
self.snap.conns["Propresenter-API"].update(category="warning", message="Socket closed")
|
||||
|
||||
Reference in New Issue
Block a user