Southcoast matches NA, per its startup checklist: X32s, ProPresenter to Lighting MIDI, pages 19/20
- An explicit look or rebuild may apply inside the auto-fix hours (never while live) - A page move clears the page left behind when only our keys are on it - A rebuild keeps MIDI links that are down now; first-setup import waits for the keys to land - ProPresenter port drift fixed automatically (kind propresenter_port) - sites/sc/config.json kept with the others Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+54
-2
@@ -283,14 +283,23 @@ def items(inv, nets):
|
||||
"checks": [{"type": spec["kind"], "conn": label, "channels": n}, {"type": "ping", "conn": label}], "fixes": {}})
|
||||
continue
|
||||
checks = [{"type": "conn", "conn": label}]
|
||||
fixes = {}
|
||||
if conn.get("module") == "renewedvision-propresenter-api":
|
||||
# ProPresenter changes its network port now and then: the fix finds the new one.
|
||||
fid = slug("prop_port_" + label)
|
||||
where = computer_by_ip(inv, ip_of(conn.get("host")) or conn.get("host"))
|
||||
fixes[fid] = dict({"kind": "propresenter_port", "template": "propresenter_port", "params": {}, "conn": label, "short": "PROP PORT",
|
||||
"label": "find ProPresenter's network port and reconnect Companion's %s to it" % label}, **({"on": where} if where else {}))
|
||||
checks[0]["fix"] = fid
|
||||
if spec.get("ping") and conn.get("host"):
|
||||
checks.append({"type": "ping", "conn": label})
|
||||
app_item = apps_at.get((spec.get("app"), ip_of(conn.get("host")))) if spec.get("app") else None
|
||||
if app_item: # the program's own key carries its connection too
|
||||
app_item["checks"] = checks + app_item["checks"]
|
||||
app_item["fixes"].update(fixes)
|
||||
app_item["also"].append(ident)
|
||||
continue
|
||||
out.append({"ident": ident, "group": spec["group"], "label": text, "checks": checks, "fixes": {}, "restart": [], "also": []})
|
||||
out.append({"ident": ident, "group": spec["group"], "label": text, "checks": checks, "fixes": fixes, "restart": [], "also": []})
|
||||
# Network MIDI: every peer in the sessions here and on the other Macs, at its wired address.
|
||||
midi_checks = []
|
||||
# Whose session a peer is, by its name: a peer joined by name or by an IPv6 address gets that Mac's wired address.
|
||||
@@ -555,6 +564,49 @@ def merge_parts(cfg, it, fresh):
|
||||
return words
|
||||
|
||||
|
||||
def keep_from(new, old):
|
||||
"""A rebuild keeps what is down right now and so was not found: MIDI links that dropped (Southcoast's
|
||||
ProPresenter to Lighting lost its MIDI key, 2026-10-21) and computers that are off, with their keys."""
|
||||
cfg = copy.deepcopy(new)
|
||||
have = referenced(cfg)
|
||||
kept = []
|
||||
# Computers in the old setup that did not answer this time, and the keys that check them.
|
||||
gone = {a: h for a, h in (old.get("hosts") or {}).items() if not h.get("self") and a not in cfg["hosts"]}
|
||||
for alias, h in gone.items():
|
||||
cfg["hosts"][alias] = h
|
||||
for t in old.get("tiles", []):
|
||||
if t.get("checks") and all(c.get("host") == alias or (c.get("params") or {}).get("host") == alias for c in t["checks"]) \
|
||||
and t["id"] not in {x["id"] for x in cfg["tiles"]}:
|
||||
for c in t["checks"]:
|
||||
for fid in ([c["fix"]] if isinstance(c.get("fix"), str) else []):
|
||||
if fid in old.get("fixes", {}):
|
||||
cfg["fixes"].setdefault(fid, old["fixes"][fid])
|
||||
place_new(cfg, {k: v for k, v in t.items() if k != "pos"})
|
||||
kept.append(t["label"])
|
||||
for k in (old.get("restart_page") or {}).get("keys", []):
|
||||
f = old.get("fixes", {}).get(k.get("fix"), {})
|
||||
if (f.get("host") == alias or (f.get("params") or {}).get("host") == alias) and cfg.get("restart_page"):
|
||||
cfg["fixes"].setdefault(k["fix"], f)
|
||||
restart_layout(cfg, [{"label": k["label"], "fix": k["fix"]}])
|
||||
# MIDI links that are down now.
|
||||
lost = [c for t in old.get("tiles", []) for c in t.get("checks", []) if c.get("type") == "midi_peer"
|
||||
and "midi:%s|%s|%s" % (c.get("host", ""), c["session"], c["peer"]) not in have and (not c.get("host") or c["host"] in cfg["hosts"])]
|
||||
if lost:
|
||||
midi = next((t for t in cfg["tiles"] if any(c.get("type") in ("midi_peer", "midi_wired") for c in t.get("checks", []))), None)
|
||||
if midi is None:
|
||||
wired = [c for t in old.get("tiles", []) for c in t.get("checks", []) if c.get("type") == "midi_wired"]
|
||||
midi = {"id": slug("midi", {t["id"] for t in cfg["tiles"]}), "label": "MIDI", "checks": wired[:1], "_group": "SHOW"}
|
||||
place_new(cfg, midi)
|
||||
midi = cfg["tiles"][-1]
|
||||
at = next((i for i, c in enumerate(midi["checks"]) if c.get("type") == "midi_wired"), len(midi["checks"]))
|
||||
midi["checks"][at:at] = lost
|
||||
cfg["fixes"].setdefault("midi_reconnect", dict(SHARED_FIXES["midi_reconnect"]))
|
||||
if "midi_reconnect" not in cfg["auto_fix"]["fixes"]:
|
||||
cfg["auto_fix"]["fixes"].append("midi_reconnect")
|
||||
kept += ["MIDI link %s" % c["peer"] for c in lost]
|
||||
return cfg, kept
|
||||
|
||||
|
||||
def finish(cfg):
|
||||
"""Fixes and remote checks built by their builders, words filled in, as the page would."""
|
||||
for fid, f in list(cfg["fixes"].items()):
|
||||
@@ -578,7 +630,7 @@ def gentle(cfg):
|
||||
for fid, f in cfg["fixes"].items():
|
||||
if fid.startswith("restart_") or f.get("restart_ok") or f.get("never_auto"):
|
||||
continue
|
||||
if f.get("kind") in ("hyperdeck", "midi_connect", "reconnect") or (f.get("template") in ("mac_start", "win_start", "ableton")
|
||||
if f.get("kind") in ("hyperdeck", "midi_connect", "reconnect", "propresenter_port") or (f.get("template") in ("mac_start", "win_start", "ableton")
|
||||
and not (f.get("params") or {}).get("restart")):
|
||||
out.append(fid)
|
||||
return out
|
||||
|
||||
Reference in New Issue
Block a user