"Location", never "campus", in everything people read; SC FOH joined with its MIDI links

- pages (NA 98 Locations / 99 Location, re-imported via PAGES_VERSION), keys, settings page, setup and
  install messages, alerts, docs, the Apollo Beach kit; python3 -m settings.location and /location/...
  addresses (the old names still answer for installed Macs)
- Apply reads the before settings from the file: an in-place edit skipped the watchdog restart
- SC: SUPERRACK (+SoundGrid) and X32 EDIT from SC FOH; FOH TRACKS and TRACKS LIGHTS MIDI links watched

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-21 13:42:22 -04:00
co-authored by Claude Opus 5.5
parent d0c755824b
commit 7068244ba4
31 changed files with 951 additions and 788 deletions
+20 -20
View File
@@ -1,15 +1,15 @@
"""A campus that sets itself up.
"""A location that sets itself up.
On the campus's Mac that runs Companion, one line installs the panel from another campus's settings
On the location's Mac that runs Companion, one line installs the panel from another location's settings
page and runs `setup`: Companion gets the panel's custom variables and blink clock, two free pages
are picked, the gear is found (settings/discover.py) and turned into keys (settings/autoconf.py),
and that config is applied like any Apply on the page. Each other computer runs one join line
(Terminal on a Mac, an administrator PowerShell on a PC); from then on the settings page looks again
every ten minutes and adds what is new by itself (Settings > Site: "Add new gear by itself").
python3 -m settings.campus setup --id ab [--name "Apollo Beach"]
python3 -m settings.campus look what it finds (nothing changes)
python3 -m settings.campus add add what is new now
python3 -m settings.location setup --id ab [--name "Apollo Beach"]
python3 -m settings.location look what it finds (nothing changes)
python3 -m settings.location add add what is new now
"""
import argparse
import base64
@@ -35,7 +35,7 @@ VARIABLES = ("sp_state", "sp_hb", "sp_cmd", "flash_tick")
TRIGGER_NAME = "flash_tick_500"
LOOK_EVERY = 600
SEEN, LAST = "discover-seen.json", "discover-last.json"
# What the program kit carries (no settings, keys or history of the campus that serves it).
# What the program kit carries (no settings, keys or history of the location that serves it).
KIT_FILES = ("status_panel.py", "readiness.py", "coremidi.py", "netgear.py", "schema.py", "make_page.py", "push_page.py",
"nav_keys.py", "atem_watch.js", "atem_state.js", "nav_templates.json")
KIT_DIRS = ("settings", "remote-access", "companion-objects", "backup")
@@ -165,21 +165,21 @@ def companion_version_problem(cfg, standalone=False):
if standalone:
return ("This Companion is older than version 5. The panel needs Companion 5.0.7: download it for Mac from\n"
" https://bitfocus.io/companion (5.0.7, the .dmg), then on this Mac run\n"
" cd \"$HOME/Library/Application Support/status-panel\" && /usr/bin/python3 -m settings.campus upgrade-companion --from ~/Downloads/<the .dmg>\n"
" cd \"$HOME/Library/Application Support/status-panel\" && /usr/bin/python3 -m settings.location upgrade-companion --from ~/Downloads/<the .dmg>\n"
"(its settings come along; the old version stays installed), then run the installer again.")
return ("This Companion is older than version 5 (Woonsocket ran 4.0.3). The panel needs 5.0.7, as North "
"Attleboro runs. Upgrade it from NA's copy (its settings come along; the old version stays installed):\n"
" cd \"$HOME/Library/Application Support/status-panel\" && /usr/bin/python3 -m settings.campus upgrade-companion\n"
" cd \"$HOME/Library/Application Support/status-panel\" && /usr/bin/python3 -m settings.location upgrade-companion\n"
"then paste the install line again.")
except OSError:
return "Companion does not answer on port 8000: open Companion (and its HTTP API, Settings > Protocols), then paste the line again."
def setup(data_dir, cid, name=None, say=print, home=None, standalone=False):
"""The first setup of a campus (or, when it is set up already, a look for what is new).
"""The first setup of a location (or, when it is set up already, a look for what is new).
Standalone: it reports to nobody and nobody else sees it (Apollo Beach runs its own)."""
from settings import server, campuses
if home or standalone: # where it was installed from: the campus list lives there
if home or standalone: # where it was installed from: the location list lives there
data = campuses.load(data_dir)
if standalone:
data.pop("home", None)
@@ -191,7 +191,7 @@ def setup(data_dir, cid, name=None, say=print, home=None, standalone=False):
site = server.Site(data_dir)
cfg = site.load()
if not is_fresh(cfg):
say("%s is set up already: looking for what is new." % (cfg.get("site") or {}).get("name", "This campus"))
say("%s is set up already: looking for what is new." % (cfg.get("site") or {}).get("name", "This location"))
return look_and_add(site, say=say, force=True)
name = name or CAMPUSES.get(cid) or cid.upper()
problem = companion_version_problem(cfg, standalone)
@@ -223,7 +223,7 @@ def setup(data_dir, cid, name=None, say=print, home=None, standalone=False):
def rebuild(data_dir, say=print, pages=None):
"""A campus's setup made again from what is found now (today's recipes), keeping its name, PIN,
"""A location's setup made again from what is found now (today's recipes), keeping its name, PIN,
pages and site details. Applied like any Apply (it waits for a recording; history keeps the old one)."""
from settings import server
site = server.Site(data_dir)
@@ -236,7 +236,7 @@ def rebuild(data_dir, say=print, pages=None):
if not rp:
rp = next(p for p in pick_pages(cfg, 3) if p != cfg["page"])
pages = tuple(pages or (cfg["page"], rp))
if pages != (cfg["page"], rp): # moving (19/20 like every campus): only onto pages that are free or ours
if pages != (cfg["page"], rp): # moving (19/20 like every location): only onto pages that are free or ours
comp = cfg.get("companion") or {}
for p in pages:
ok, why = push_page.safe_target(push_page.fetch_page(comp.get("host", "127.0.0.1"), int(comp.get("port", 8000)), p))
@@ -390,7 +390,7 @@ def blocked(cfg, applier, now=None, asked=False):
def look_and_add(site, say=lambda s: None, force=False):
"""Look, and add what is new (when the campus allows it, and not during a service)."""
"""Look, and add what is new (when the location allows it, and not during a service)."""
cfg = site.load()
inv = discover.look(cfg, site.data_dir)
seen = load_seen(site.data_dir)
@@ -488,7 +488,7 @@ def shq(s):
def install_script(base, cid, support_key=None):
"""What a new campus's Companion Mac runs: install from `base` (this page), then set itself up."""
"""What a new location's Companion Mac runs: install from `base` (this page), then set itself up."""
m = re.match(r"[a-z0-9]+", str(cid).lower())
cid = m.group(0)[:8] if m else "new"
name = CAMPUSES.get(cid, cid.upper())
@@ -506,7 +506,7 @@ fi
DIR="$HOME/status-panel-install"
mkdir -p "$DIR" && cd "$DIR"
echo "Downloading the status panel from $SRC ..."
/usr/bin/curl -fsSL "$SRC/campus/program.tgz" | /usr/bin/tar -xz
/usr/bin/curl -fsSL "$SRC/location/program.tgz" | /usr/bin/tar -xz
[[ -f "$HOME/.ssh/id_status_panel" ]] || { mkdir -p "$HOME/.ssh" && chmod 700 "$HOME/.ssh" && /usr/bin/ssh-keygen -q -t ed25519 -N "" -C "status-panel@$(scutil --get LocalHostName)" -f "$HOME/.ssh/id_status_panel"; }
SUPPORT=%(key)s
if [[ -n "$SUPPORT" ]]; then
@@ -515,7 +515,7 @@ if [[ -n "$SUPPORT" ]]; then
fi
zsh install.sh --site %(cid)s
cd "$HOME/Library/Application Support/status-panel"
/usr/bin/python3 -m settings.campus setup --id %(cid)s --name %(qname)s --home "$SRC"
/usr/bin/python3 -m settings.location setup --id %(cid)s --name %(qname)s --home "$SRC"
if ! /usr/bin/nc -z -G 2 127.0.0.1 22 >/dev/null 2>&1; then
echo
echo "One more thing: turn on Remote Login (System Settings > General > Sharing), so North Attleboro can help remotely."
@@ -604,9 +604,9 @@ def main(argv=None):
ap.add_argument("--id", default="new")
ap.add_argument("--name")
ap.add_argument("--data-dir", default=PARENT)
ap.add_argument("--home", help="the settings page this campus was installed from (the campus list lives there)")
ap.add_argument("--pages", help="rebuild onto these Status,Restart pages (19,20 on every campus)")
ap.add_argument("--standalone", action="store_true", help="a campus that runs on its own: reports to no other campus")
ap.add_argument("--home", help="the settings page this location was installed from (the location list lives there)")
ap.add_argument("--pages", help="rebuild onto these Status,Restart pages (19,20 on every location)")
ap.add_argument("--standalone", action="store_true", help="a location that runs on its own: reports to no other location")
ap.add_argument("--from", dest="source", help="upgrade-companion: a Companion .dmg or .zip downloaded from bitfocus.io")
a = ap.parse_args(argv)
if a.what == "setup":