MIDI key: every network MIDI peer must come over the wired network

The Macs are also on Wi-Fi and the Dante networks, and Bonjour lists each MIDI session once per
network. ProdDash's Vista Cues module had Tracks and Companion set to their Wi-Fi addresses, so
lighting MIDI rode Wi-Fi. A midi_wired check now names any peer, in NA Ingest's session or the
other Macs', whose address is outside the wired network (10.1.0.0/16 at NA).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-20 10:09:34 -04:00
co-authored by Claude Opus 5.5
parent b41b8a49d2
commit 79318976c5
6 changed files with 84 additions and 2 deletions
+35 -1
View File
@@ -18,6 +18,7 @@ import argparse
import calendar
import hashlib
import http.client
import ipaddress
import json
import logging
import math
@@ -507,6 +508,39 @@ def check_midi_peer(chk, snap, ctx):
return [("peer", Result(ERR, "MIDI LOST"))]
def peer_ip(address):
"""The IPv4 address of a MIDI peer ("10.1.1.1:5040"), or None for a Bonjour name or IPv6."""
host = str(address or "").strip().rsplit(":", 1)[0]
try:
ip = ipaddress.ip_address(host)
except ValueError:
return None
return ip if ip.version == 4 else None
def check_midi_wired(chk, snap, ctx):
"""Every peer in the network MIDI sessions (here and on the other Macs) comes over the wired
network. The Macs are also on Wi-Fi and the Dante networks, and Bonjour lists each session once
per network: a peer joined through the wrong copy works until Wi-Fi hiccups mid-service
(2026-10-20: ProdDash joined Tracks over both Macs' Wi-Fi). Names the peer and the Mac."""
nets = [ipaddress.ip_network(n, strict=False) for n in chk["nets"]]
groups = [("", snap.midi if snap.midi_time else None)]
groups += [(h, s) for h, s in snap.remote_midi.items() if ctx["now"] - snap.remote_midi_time.get(h, 0) <= 12]
out, seen = [], set()
for host, sessions in groups:
for sname, sess in (sessions or {}).items():
for p in sess.get("peers", []):
ip = peer_ip(p.get("address"))
if ip is None or ip.is_loopback or any(ip in n for n in nets) or (p["name"], str(ip)) in seen:
continue
seen.add((p["name"], str(ip)))
name = p["name"].upper()
name = name if len(name) <= 14 else name[:13] + "."
out.append(("%s|%s|%s" % (host, sname, p["name"]),
Result(ERR, "%s NOT WIRED" % name, named=True)))
return out or [("wired", Result(OK))]
def check_mdns(chk, snap, ctx):
if snap.mdns_time and chk["instance"] not in snap.mdns:
return [("mdns", Result(ERR, chk.get("name", chk["instance"]) + " GONE", named=True))]
@@ -597,7 +631,7 @@ READY_ACTIONS = ("recheck", "lineup_sync", "led_cross", "copy_tracks", "ltc_to_p
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, "pref": check_pref, "spotify": check_spotify,
"process": check_process, "http": check_http, "disk": check_disk, "midi_peer": check_midi_peer, "midi_wired": check_midi_wired, "pref": check_pref, "spotify": check_spotify,
"mdns": check_mdns, "midi_rx": check_midi_rx, "remote": check_remote, "artnet": check_artnet,
"ready": check_ready, "ready_manual": check_ready_manual,
}