Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Status Indicators — Companion STATUS page for NA Ingest
One Companion page (page 19, "19 Status") that is solid green when everything is fine and blinks red with the actual problem ("HD3 NO DISK", "LIGHT PC MIDI LOST") when something needs attention. The page number key on every other page follows the same colour, so you see a problem from any page.
There are two parts:
status_panel.py— a watchdog that runs on NA Ingest as the LaunchAgentorg.waterschurch.status-panel. Every second it reads Companion's connection statuses and module variables. It also checks what Companion can't see: network MIDI peers, Bonjour MIDI sessions, pings, launchd services, disk space, the Bible TV app, and whether the Resi cloud is reachable. It writes the result into one Companion custom variable.status-page.companionconfig— the page. Every button just draws what the watchdog wrote and blinks on your existingflash_ticktrigger.
Layout (Stream Deck XL; MK.2 and Mini show the top-left corner)
| col 0 | col 1 | col 2 | col 3 | col 4 | col 5 | col 6 | col 7 | |
|---|---|---|---|---|---|---|---|---|
| row 0 | UP | ALL | REC | AUDIO | RF | SHOW | VIDEO | STREAM |
| row 1 | page | HD1 | HD2 | HD3 | HD4 | HD5 | HD6 | TASCAM |
| row 2 | DOWN | X32 | DANTE | MIDI | APPS | VISTA | RESTART PAGE | SPOTIFY |
| row 3 | ALARMS | ATEM | OBS | RESI | NET | INGEST | LED | ARENA |
Row 0 holds the group buttons. Each one shows the first problem in its group, plus "+N" if there are more:
- REC: HD1–6 and the Tascam.
- AUDIO: X32 and Dante.
- RF: all six Shure units (AD4Q ×2, ULXD4, PSM1000 ×3).
- SHOW: MIDI, APPS, VISTA and SPOTIFY.
- VIDEO: ATEM, LED and Arena.
- STREAM: OBS and Resi.
Colours
| Colour | Meaning |
|---|---|
| Green | OK. The second line shows something useful, like 28h of record time or 19/19 Dante devices. |
| Blinking red | Something is wrong. |
| Solid dark red | Acknowledged. It stays red until the problem clears, then goes green. A new failure blinks again. |
| Amber | Warning: low disk, battery at 2 bars, RF interference, a device that keeps dropping out ("WING GONE x3"), a network blip in the last 3 minutes ("BLIP 10:21"). |
| Dim red, not blinking | A fault while alarms are muted. |
| Grey | Not in use: an optional HyperDeck with no disk, or a disabled connection. |
| Purple | The watchdog has stopped. The master shows WATCHDOG DOWN and Companion's own error count. |
Buttons
-
Press any button: acknowledge its alarms (stops the blinking). Press ALL to acknowledge everything.
-
Hold any button for 2 seconds: fix what that button is failing on right now. A green button does nothing, the same fix won't re-run within 60 s, and every command comes from
"fixes"inconfig.json. Hold a group button to fix all its members.Failing Hold does APPS: PROPRES OFFLINE / NOT RUNNING restarts ProPresenter on its Mac (the newest version installed) APPS: ABLETON / TRANSLATE NOT RUNNING starts Ableton on the Tracks Mac / Church Translate on NA Translation APPS: BIBLE APP DOWN restarts the Bible app on the Sanctuary TV PC (SSH + its "Start BibleApp" task from remote-access/windows-setup.ps1)VISTA: SILENT starts Vista on the Lighting PC if it is not running. A running Vista is never closed. ARENA starts Resolume Arena on the Lighting PC if it is not running, then reconnects Companion OBS starts OBS on the LiveStream PC if it is not running, then reconnects Companion. If the PC is off, it is woken (Wake-on-LAN) and the button shows WAKING PC; hold again once someone has logged in. MIDI: LIGHT PC / FX LIGHTS / SUPERRACK MIDI LOST reconnects that peer to the session it dropped out of, from the Mac's side (NA Ingest's own session, or NA Tracks' over SSH), like Connect in Audio MIDI Setup. Other peers are left alone and nothing is restarted. The address is where the peer was last seen, else "address"on the check. Not for a missing Bonjour advert ("... MIDI GONE"). Keep the Lighting PC's network on Public: its Bonjour firewall rules only allow Public, and on Private it vanishes from the MIDI directory and cannot rejoin a session (2026-10-08). Never restart rtpMIDI as a fix: it drops every session and does not rejoin them.MIDI: LIGHT PC MIDI GONE starts rtpMIDI on the Lighting PC if it is not running (its service, then the tray app). Its service also restarts itself if it crashes (Windows service recovery, set by windows-setup.ps1). Audio MIDI Setup does not need to be open on the Macs: their sessions run in macOS's MIDI server (tested 2026-10-08: quitting it left NA Ingest's session connected).DANTE: PROP MAC / TRACKS / TRANSL / INGEST GONE starts Dante Virtual Soundcard's engine on that Mac ( remote-access/mac-dvs-helper.sh)DANTE: any device powered by its switch port (today the four Studio B boxes) power-cycles the port it is on now, found by its MAC on the Netgear Dante switches DANTE: any other device GONE restarts Companion's Dante module (hardware: if still gone, it is off or unplugged) INGEST: BRIDGE / CAPTIONS / CAPTION SCREEN / PRODCOM / PRODDASH restarts that one on NA Ingest TASCAM (always, even when it looks fine) reconnects Companion to the recorder and looks again after 20 s. HUNG - POWER CYCLE IT: the recorder answers ping but its control port has hung (only a power-cycle at the rack fixes that; it has no network reboot). NO NETWORK / CHECK POWER: it does not answer at all. any button whose Companion connection is disabled turns the connection back on (nothing else) HD1–6 (always, even when it looks fine) switches Companion's connection to that deck off and on, which is what gets a restarted deck green, and checks again after 15 s. Never reboots the deck, and leaves a recording deck alone. anything else with a Companion connection restarts that Companion connection The Dante map is automatic. Every 10 minutes the watchdog maps each Dante device: its name and IP from Companion, its MAC from NA Ingest's Dante port, and its switch port and PoE from the Netgear switches listed in
"dante_switches". It saves the map todante-map.jsonin its data folder. Re-patching, adding or renaming a device needs no config change. A device that has been dead for a while ages out of the switch tables, so its last known port is used, but only if no other device has appeared there. A port carrying more than 2 devices (an uplink) is never power-cycled. The switch login is in NA Ingest's login keychain (servicenetgear-status-panel).It checks over SSH every 10 s that ProPresenter, Ableton and Church Translate are running, using NA Ingest's key
~/.ssh/id_status_panel. That key was authorized on the Macs withremote-access/mac-authorize.sh. -
ALARMS: alarms are armed all the time (
service_windowsinconfig.json: every day, 00:00–23:59). Press ALARMS to mute the blinking, for example during maintenance. It re-arms itself at midnight.
Auto-fix on Sundays (06:30–13:30)
During that window, with ALARMS on, the panel fixes a problem by itself once it has lasted 20 s, but only with gentle fixes: Companion reconnects, HyperDeck off/on, the Tascam reconnect, MIDI reconnects, starting rtpMIDI, and starting Vista, Resolume, OBS, Ableton or Church Translate if they are closed, playing the Spotify playlist, plus DVS on one Mac that dropped out of Dante. The key shows AUTO-FIXING.
- At most 2 tries per problem, 90 s apart; then it is yours to hold.
- It waits while the network is having a blip, and does nothing to Dante when several devices vanish at once (that is NA Ingest's view or the Dante network, not the Macs).
- Never automatic: restarting a running ProPresenter, Bible app, ProdCom (or DVS on NA Ingest, which restarts ProdCom), captions or the bridge, power-cycling a switch port, or turning on a connection someone switched off.
load_configrefuses an auto fix that closes a program. - Daily log: everything auto-fix does is written as it happens to
~/Desktop/Auto-Fix Logs/<date> <weekday> Auto-Fix.logon NA Ingest (e.g.2026-10-11 Sunday Auto-Fix.log): the problem, what it did, whether it worked, when the fault cleared, when it gave up or held back. Double-click it to open it in Console, which shows new lines live. One file per day; each is deleted a calendar month after its date (the 11 Oct file on 11 Nov). - Press ALARMS to mute the panel for maintenance: that also stops auto-fix. The window and the list are
"auto_fix"inconfig.json.
Restart page (page 20)
Tap RESTART PAGE on the status page (row 2). Each key restarts one thing even when the status page says it is fine; hold it 2 s. A key flashes red (HOLD TO FIX) while the thing it restarts is down, so you can see which one to hold. It shows RESTARTING, then DONE (or FAILED / what to do). The same thing will not run twice within a minute. STATUS PAGE (bottom left) goes back.
| Key | Restarts |
|---|---|
| DVS PROP / TRACKS / TRANSL / INGEST | Dante Virtual Soundcard's engine on that Mac (audio to and from it drops 5–10 s). DVS INGEST also restarts ProdCom afterwards, which otherwise keeps a dead input. |
| PROPRESENTER | ProPresenter (quits and reopens the newest version) |
| ABLETON | Ableton on the Tracks Mac, reopening the set it had open (from Live's own log; templates skipped). Unsaved changes are lost, and Live may ask to recover - click it on the Tracks Mac. APPS's hold, which starts a closed Ableton, opens that set too. |
| TRANSLATE | Church Translate on NA Translation |
| PRODCOM | ProdCom on NA Ingest (lobby captions blank for 5–15 s) |
| PRODDASH / CAPTIONS / BRIDGE | that service on NA Ingest |
| TASCAM | reconnects Companion to the recorder (see TASCAM above) |
| SPOTIFY | plays the Christian EDM 2026 playlist on NA Ingest (opens Spotify first if it is closed) |
Add or move keys in "restart_page" in config.json, then python3 make_page.py and python3 push_page.py --which restart. push_page.py refuses any page that holds real buttons unless it already is that page.
Page keys on every page
The page number key on every page follows the ALL button. It's green when everything is fine, flashes red when something is wrong, and turns purple if the watchdog stops. UP and DOWN stay normal. Which keys follow ALL is "nav_keys" in config.json (["pagenum"]; add "pageup" / "pagedown" to colour those too). The coloured key is Companion's own key converted to a regular button (nav_templates.json).
-
Tap the page number: go to page 1 (
"nav_tap_page"inconfig.json). It acts when you let go, not when you press. -
Hold the page number for 1 second: jump to the status page (page 19). The hold time is
"nav_hold_ms"inconfig.json. -
python3 nav_keys.pyapplies them to every page. Run it again after adding pages. -
python3 nav_keys.py --revertputs Companion's built-in nav keys back.
What each button checks
| Button | Checks |
|---|---|
| HD1–HD6 | Companion connection; NO DISK; record time LOW (<30 min, amber) / FULL (<5 min); NOT REC when another deck is recording and this one isn't |
HD2 and HD4 are "optional": true in config.json: with no disk they sit grey with no alarm, and once a disk is in they are watched like the others. Add or remove "optional": true on any deck to change that. |
|
| TASCAM | connection; the recorder's own Error / Caution. Use the 1.3.1-quiet Tascam module (see below) so Companion's log isn't flooded.; pinged at the address on its Companion connection. |
| X32, ARENA, OBS | Companion connection |
| ATEM | Companion connection; the switcher's audio (every Fairlight input's on/off/AFV and fader, e.g. Resi on input 16 ON, TRS off) and camera settings (iris, white balance, shutter, gain, detail, ND, lift/gamma/gain/offset, contrast, saturation) must match the restore file atem-reference.xml (a copy of 4k plus 2026-10-07 14-59-55.xml from Google Drive Backup/NA/ATEM): ATEM AUDIO WRONG / ATEM CAMERA WRONG; ATEM Software Control's Enable MIDI control must be off: ATEM SW MIDI ON. Hold 2 s (and Sunday auto-fix) sends back only what differs; MIDI is fixed by quitting the app, switching it off and reopening it (the switcher is not affected). atem_watch.js keeps one connection to the switcher. New restore file: copy it over atem-reference.xml and re-run install.sh. |
| LED | VX1000 and UHD Jr: Companion connection and each one answers ping (the NovaStar module keeps saying "Connected" after a processor is switched off). "UHDJR NO PING" = processor off or unreachable; "UHDJR OFFLINE" = Companion's connection failed; "UHDJR DISABLED" (amber) = connection turned off in Companion. |
| DANTE | All 19 Dante devices ("19/19"), named when one drops: "WING GONE", "TRACKS GONE", "PROP MAC GONE". |
| MIDI | All six network MIDI links on the FOH / Studio B checklist, each named when it drops: LIGHT PC (Ingest → Lighting), SUPERRACK (Ingest → Livebox), FX LIGHTS (Tracks → Lighting, the FX lighting cues), TRK LIVEBOX (Tracks → Livebox), TRK STUDIO B (Tracks → Studio B), PROP LIGHTS (ProPresenter → Lighting). NA Ingest's own session is read locally; NA Tracks' and NA ProP's over SSH every 5 s. Also: the Lighting PC and NA Tracks MIDI sessions still announced on the network. A clean disconnect shows within about 10 s; a crash or pulled cable takes about a minute (macOS's own timeout, measured). Hold 2 s reconnects whichever links dropped. |
| APPS | ProPresenter API (offline or error only: its harmless yellow warning, every 15–20 min, is ignored with "ignore_warning": true); Ableton OSC; tracks Mac pings; Bible TV app answering on :8080 (every 5 s); Bible TV OSC. Messages name the app ("PROPRES OFFLINE", "BIBLE APP DOWN"). Hold 2 s restarts the ProPresenter, Ableton and Bible TV Companion connections.; Pro Tools on the Studio B Mac Studio set to Solo Mode AFL + Latch ("PT SOLO NOT AFL"; hold, or Sunday auto-fix, ticks them back). A helper on that Mac (remote-access/solo-mode-agent.swift, installed with install-solo-mode.sh) reads the menu; it needs Accessibility allowed once, then a restart of the helper. "PT SOLO CHECK OFF" = that helper is not running or not allowed. |
| VISTA | Vista on the Lighting PC: its Art-Net poll (sent every 0.5 s) must be heard within 5 s, otherwise SILENT (Vista closed or crashed, or the Lighting PC is off the network). Hold 2 s starts Vista if it is not running; Vista then opens Prop Takeover from its show folder (E:\media\Documents\Vista 3\Shows) by itself, through its own autoload preference (<autoloadpath> in E:\media\Documents\Vista 3\.preferences, set 2026-10-08). Resolume is the ARENA button. |
| RESI | decoder (RossTalk connection and ping, 10.1.10.203); encoder (ping and its web page, 10.1.10.202, LAOEncoder); resi-studio-cues; Resi cloud reachable. Only shows they are on the network, not that the encoder is streaming. |
| NET | NA Ingest's link; gateway 10.1.0.1 pings; 4+ connections from 3+ groups dropping within 10 s (what happened Sunday 10/5 at 10:21). A blip flashes amber for 5 minutes, then goes by itself; press NET to stop the flashing, hold NET 2 s to clear it now. |
| INGEST | the bridge (makes ProPresenter's stage screen count down to the next Resi cue), lobby captions server and caption screen, ProdCom (transcription, answering on :24480), ProdDash (running and its page on :24500); free disk |
| SPOTIFY | Spotify on NA Ingest during Sunday services (06:30–13:30) must be playing the Christian EDM 2026 playlist (spotify:playlist:2uTpJVYQLFnKF1WnSOuco8): SPOTIFY CLOSED, NOT PLAYING, or WRONG PLAYLIST (the song list comes from Spotify's public playlist page, refreshed every 6 h; it shows the first 100 of the playlist's songs, so the alarm needs 3 songs in a row that are not on it). Outside services it just shows PLAYING / PAUSED / CLOSED. Hold 2 s (and Sunday auto-fix) plays the playlist, opening Spotify first if needed. |
| RF (group) | Shure connections; battery ≤1 bar red, 2 bars amber; RF interference (only while that transmitter is on); PSM RF muted; each receiver pinged every 3 s ("AXIENT 1 NO PING" in about 6–9 s; Companion's Shure modules take 18–27 s to notice). The address is the one set on its Companion connection, read from Companion's settings every minute, so changing it there is enough; "host" in config.json is only the fallback. |
A problem has to last 3 seconds before it shows, so one bad reading doesn't trigger an alarm. Recovery shows immediately.
One-time Companion setup
- Variables → Custom Variables: add three variables. Leave the start values empty and "persist" off:
sp_statesp_hbsp_cmd
- Import / Export → Import: choose
status-page.companionconfig(it's on NA Ingest's Desktop) and import it into page 19. Page 19 is empty today. - Make sure the flash_tick_500 trigger stays enabled. It's the blink clock.
Changing things
This folder is the source of truth. Edit config.json here, then copy the folder to NA Ingest:
scp status_panel.py coremidi.py netgear.py config.json install.sh checklist-ingest:status-panel-install/
Then run the installer there. It backs up the old config and restarts the watchdog:
ssh checklist-ingest 'zsh ~/status-panel-install/install.sh'
If you add or move tiles, rebuild the page:
python3 make_page.py
Then import it into page 19, either by hand (Import/Export → Import) or with:
python3 push_page.py
push_page.py does the same import over Companion's own API. It refuses to overwrite page 19 unless that page is empty or already the status page.
Other commands:
python3 status_panel.py --once # poll once and print every tile; writes nothing
python3 -m unittest discover -s tests # offline tests, no Companion or gear needed
zsh install.sh --remove # stop the watchdog
The log is ~/Library/Logs/status-panel.log on NA Ingest. Every fault and clear is written there with a timestamp, which is handy for a post-service review.
Optional: see what the tracks send to the lights
The TRACKS tile can show when the tracks rig last sent MIDI ("TRK MIDI 3s"). For that, NA Ingest has to listen to the "NA Tracks" session. Use a separate session so nothing Companion sends can reach Ableton:
- On NA Ingest, open Audio MIDI Setup → Window → Show MIDI Studio → Network (the globe icon).
- Under My Sessions, press +, rename the new session to
NA Ingest Listen, and tick it to enable it. - With
NA Ingest Listenselected, choose NA Tracks in the Directory and press Connect.
The watchdog picks it up within about 10 seconds. Until then that line just stays hidden.
The LIGHT PC tile can do the same in the other direction. If the lighting software can send a heartbeat note back to NA Ingest every few seconds, set "max_silence_seconds": 10 on the LIGHT PC midi_rx check. The tile then goes amber if the lighting PC stops answering during service.
Quiet Tascam module
The stock Tascam DA-6400 module (1.3.0) polls the recorder 5 times a second, the recorder rejects one of those polls, and the module logs a warning every time: about 430,000 lines a day in Companion's log. tascam-quiet/make_quiet_tascam.py builds 1.3.1-quiet from the stock module: the same module, but that warning is logged at most once a minute and names the commands that were just sent.
- In Companion: Modules → Import module package, choose
tascam-da-6400-1.3.1-quiet.tgz(on NA Ingest's Desktop). - Connections → Tascam → edit, set the module version to 1.3.1-quiet, save.
To go back, pick 1.3.0 on the connection again.
Windows PCs
remote-access/windows-setup.ps1 sets each PC up once (SSH for NA Ingest, start tasks, Wake-on-LAN). An app ticked "Run this program as an administrator" (OBS on the LiveStream PC) gets a start task that runs with highest privileges; otherwise Windows refuses to start it (error 0x800702E4). Windows restarts the SSH service and rtpMIDI by itself if they stop.
Files
| File | Purpose |
|---|---|
status_panel.py |
the watchdog |
netgear.py |
reads the Netgear Dante switches (MAC tables, PoE) and power-cycles one PoE port |
coremidi.py |
reads network MIDI sessions and listens to MIDI sources (ctypes, no extra installs) |
config.json |
tiles, positions, checks, service windows |
make_page.py |
builds status-page.companionconfig from config.json |
install.sh |
installs or updates the LaunchAgent on NA Ingest |
push_page.py |
imports the status page into page 19 over Companion's API |
nav_keys.py |
colours (or restores) the page nav keys on every page |
nav_templates.json |
Companion's own nav key designs, coloured by make_page.py |
remote-access/ |
one-time setup scripts for SSH to the Macs and Windows PCs |
tascam-quiet/ |
builds the quiet Tascam module |
tests/ |
offline tests, including a fake Companion and a MIDI loopback |