Add the Companion status page and its watchdog for NA Ingest.
status_panel.py runs on NA Ingest as a LaunchAgent. Every second it reads Companion's connection statuses and module variables, adds what Companion cannot see (network MIDI peers, Bonjour sessions, pings, launchd services, disk, Resi cloud, the Bible TV app), and writes one JSON custom variable that page 19 renders. Buttons acknowledge alarms, mute them, and restart a stuck Companion connection on a two second hold. If the watchdog stops, the page turns purple instead of freezing on stale green. make_page.py builds the page export from config.json; tests/ runs offline against a fake Companion and a CoreMIDI loopback. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+59
@@ -0,0 +1,59 @@
|
||||
#!/bin/zsh
|
||||
# Install or update the status panel watchdog on this Mac (NA Ingest) as a LaunchAgent.
|
||||
# Re-run after changing status_panel.py, coremidi.py or config.json in this folder.
|
||||
#
|
||||
# zsh install.sh install / update and (re)start
|
||||
# zsh install.sh --remove stop it and remove the LaunchAgent (files stay)
|
||||
set -e
|
||||
SRC=${0:A:h}
|
||||
LABEL=org.waterschurch.status-panel
|
||||
# App Support, not ~/Documents: launchd-run python3 cannot read ~/Documents.
|
||||
DEST="$HOME/Library/Application Support/status-panel"
|
||||
PLIST="$HOME/Library/LaunchAgents/$LABEL.plist"
|
||||
DOMAIN="gui/$(id -u)"
|
||||
|
||||
if [[ "$1" == "--remove" ]]; then
|
||||
launchctl bootout "$DOMAIN/$LABEL" 2>/dev/null || true
|
||||
rm -f "$PLIST"
|
||||
echo "removed $LABEL (files left in $DEST)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
/usr/bin/python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$SRC/config.json"
|
||||
mkdir -p "$DEST"
|
||||
if [[ -f "$DEST/config.json" ]] && ! cmp -s "$SRC/config.json" "$DEST/config.json"; then
|
||||
cp "$DEST/config.json" "$DEST/config.json.bak-$(date +%Y%m%d-%H%M%S)"
|
||||
fi
|
||||
cp "$SRC/status_panel.py" "$SRC/coremidi.py" "$SRC/config.json" "$DEST/"
|
||||
|
||||
cat > "$PLIST" <<EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key><string>$LABEL</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/usr/bin/python3</string>
|
||||
<string>$DEST/status_panel.py</string>
|
||||
<string>--data-dir</string>
|
||||
<string>$DEST</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key><true/>
|
||||
<key>KeepAlive</key><true/>
|
||||
<key>ThrottleInterval</key><integer>10</integer>
|
||||
<key>StandardErrorPath</key><string>$HOME/Library/Logs/status-panel.err.log</string>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
|
||||
launchctl bootout "$DOMAIN/$LABEL" 2>/dev/null || true
|
||||
# bootout returns before the old job is gone; bootstrapping too early fails with "5: Input/output error".
|
||||
for i in {1..50}; do launchctl print "$DOMAIN/$LABEL" >/dev/null 2>&1 || break; sleep 0.2; done
|
||||
for attempt in 1 2 3; do
|
||||
launchctl bootstrap "$DOMAIN" "$PLIST" && break
|
||||
[[ $attempt == 3 ]] && { echo "launchctl bootstrap failed" >&2; exit 1; }
|
||||
sleep 1
|
||||
done
|
||||
echo "installed $LABEL -> $DEST"
|
||||
echo "log: ~/Library/Logs/status-panel.log"
|
||||
Reference in New Issue
Block a user