Resi cue countdowns on ProPresenter and in Companion
The Resi -> ProPresenter bridge, its installer and site kit, and the Companion module resi-studio-cues, as running at North Attleboro. Bridge (resi_to_propresenter.py) - Follows a Resi decoder's playhead and keeps ProPresenter's NextCue timer counting down to the next cue; optional cue name as a stage message, sent once per cue (ProPresenter flashes it on every send) and off by default. - Playhead estimate no longer learns a cadence from the partial first gap after a start, so a 30s Resi doesn't read as paused half the time. - Backs off on 429, holds 2 min before retrying a failed startup login, and logs Resi's actual reason (wrong password, USER_LOCKED, rate limit). - --setup asks for the login, decoder, ProPresenter and timer. install_bridge.sh installs it as a login service (outside ~/Documents, which launchd may not read); make_kit.sh builds the kit for another site. Companion module resi-studio-cues 0.1.4 (source/, package committed) - Same playhead fix; login and request hold-off (15s doubling to 5 min); a 401/403 on a fresh session is a permission, not a reason to sign in again; init never fails on a Resi problem, so Companion can't restart it into a login loop. Tests: test_playhead.py, test_stage_message.py, test_rate_limit.py and source/backoff_test.js run offline; test_end_to_end.py drives a real ProPresenter and refuses to run without an explicit flag. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
# Resi → ProPresenter countdown
|
||||
|
||||
Shows a countdown to the next Resi cue on ProPresenter's stage display, and optionally
|
||||
the cue's name as a stage message. ProPresenter does the counting, so it's smooth; a small
|
||||
background service on a Mac keeps it pointed at the right cue.
|
||||
|
||||
```
|
||||
Resi (cloud) ──► always-on Mac (this service) ──► ProPresenter (timer, optional stage message)
|
||||
```
|
||||
|
||||
It talks to Resi directly. Companion isn't needed for the countdown; the Companion
|
||||
module in this kit is optional, for buttons and Stream Deck displays.
|
||||
|
||||
## What you need
|
||||
|
||||
- **An always-on Mac** on the same network as ProPresenter, ideally one that logs in
|
||||
automatically (an ingest or utility Mac). It can be the ProPresenter Mac itself.
|
||||
- **A Resi login** that can see the campus's decoder.
|
||||
- **ProPresenter 7.9 or newer.**
|
||||
|
||||
## 1. Set up ProPresenter (once per site)
|
||||
|
||||
1. **Settings → Network**: turn on **Enable Network**. Note the IP address and port.
|
||||
2. **Timers**: add a **Countdown** timer named **`NextCue`** (any length; it gets overwritten).
|
||||
3. **Stage layout**: in the layout your stage screen uses, add a **Timer** object set to
|
||||
**NextCue**. Add a **Stage Message** object only if you'll turn cue-name messages on.
|
||||
|
||||
## 2. Install the service (on the always-on Mac)
|
||||
|
||||
Copy this folder onto that Mac, open **Terminal**, and run:
|
||||
|
||||
```bash
|
||||
zsh ~/Desktop/resi-propresenter-kit/install_bridge.sh
|
||||
```
|
||||
|
||||
(adjust the path to wherever you put the folder). It asks for:
|
||||
|
||||
1. **Resi login email and password.** The password goes in that Mac's Keychain, not a file.
|
||||
2. **Which decoder** feeds this campus, picked from a numbered list.
|
||||
3. **ProPresenter's address**, e.g. `192.168.1.50:1025`. It checks it can reach it.
|
||||
4. **Which timer** to drive (`NextCue`). It checks the timer exists.
|
||||
5. **Whether to show cue names as a stage message.** Default is **no**: just the countdown.
|
||||
If yes, the name is sent once per cue (never repeated), so it won't keep flashing.
|
||||
|
||||
Then it starts the service and shows the first lines of its log. You should see
|
||||
`NextCue -> <cue name> in 00:12:34`. From then on it starts at login, restarts itself if
|
||||
it stops, and follows whatever event the decoder is playing. Nobody has to do anything on
|
||||
service day.
|
||||
|
||||
If the installer warns that the Mac doesn't log in automatically, turn on **System
|
||||
Settings → Users & Groups → Automatically log in as …** (FileVault must be off).
|
||||
Otherwise the countdown won't come back after a reboot until someone logs in.
|
||||
|
||||
Run only **one copy per ProPresenter**: two copies fight over the same timer.
|
||||
|
||||
## 3. Optional: Companion module
|
||||
|
||||
In Companion: **Modules → Import module package** → `resi-studio-cues-0.1.2.tgz`, then add a
|
||||
**Rey Kroona: Resi Studio Cues** connection. It provides variables such as
|
||||
`next_cue_name`, `next_cue_time_in_hms` and `playback_state` for buttons.
|
||||
|
||||
## Day to day
|
||||
|
||||
| To… | Run (on that Mac) |
|
||||
|---|---|
|
||||
| Watch what it's doing | `tail -f ~/Library/Logs/resi-propresenter.log` |
|
||||
| Change decoder / ProPresenter / password / stage message on-off | `zsh install_bridge.sh --setup` |
|
||||
| Update to a newer script | run `zsh install_bridge.sh` from the new kit (keeps settings) |
|
||||
| Remove it | `zsh install_bridge.sh --uninstall` |
|
||||
|
||||
## If something's wrong
|
||||
|
||||
- **`Resi rejected the login`**: the password changed. Run `--setup` again.
|
||||
- **`Cannot reach ProPresenter`**: ProPresenter is closed, its IP changed, or Network is
|
||||
off. Run `--setup` to enter the new address.
|
||||
- **`playback stopped — timer held`**: the decoder isn't moving, or Resi isn't reporting.
|
||||
It picks back up by itself when playback resumes.
|
||||
- **Stage shows the cue name but no countdown**: the stage layout's timer object isn't set
|
||||
to `NextCue`.
|
||||
- **Over SSH**: the installer asks for that Mac's login password first, to unlock its
|
||||
Keychain. Remote sessions keep it locked.
|
||||
|
||||
Resi's API is undocumented and unsupported, so don't open a Resi ticket about this tool.
|
||||
|
||||
## Working on it
|
||||
|
||||
| Path | What it is |
|
||||
|---|---|
|
||||
| `resi_to_propresenter.py` | The bridge. Python 3, standard library only. |
|
||||
| `install_bridge.sh` | Installs it as a login service on the Mac it runs on, and runs `--setup` when needed. |
|
||||
| `make_kit.sh` | Builds `resi-propresenter-kit.zip` for another site (no site settings inside). |
|
||||
| `source/` | The Companion module `resi-studio-cues` (`dist/` is what ships, plus `manifest.json` and `HELP.md`). |
|
||||
| `resi-studio-cues-0.1.4.tgz` | The current Companion package: import it in Companion → Modules. |
|
||||
|
||||
Tests. All run offline against fakes, except the end-to-end one:
|
||||
|
||||
```bash
|
||||
python3 test_playhead.py # the playhead estimator, nine Resi profiles plus slow-start cases
|
||||
python3 test_stage_message.py # stage message sent once per cue, never when switched off
|
||||
python3 test_rate_limit.py # backs off when Resi says "too many requests"
|
||||
node source/backoff_test.js # Companion module: login hold-off, no crash loop on a locked account
|
||||
```
|
||||
|
||||
`source/tick_test.js` is the Companion module's estimator test (run with JavaScriptCore's
|
||||
`jsc`, with `var TARGET='dist/main.js'` loaded first). `test_end_to_end.py` drives a **real**
|
||||
ProPresenter's `NextCue` timer and stage message, so it refuses to run without
|
||||
`<address> --touch-live-propresenter`. Stop the installed bridge before using it.
|
||||
|
||||
The Companion package is `source/dist`, `source/manifest.json` and `source/HELP.md` (under
|
||||
`companion/`), plus a vendored `node_modules` with `@companion-module/base` 1.14.1
|
||||
(`source/npm_vendor.py` assembles one). Bump the version in `manifest.json` and the
|
||||
package's `package.json` on every change.
|
||||
|
||||
**Running at North Attleboro:** the bridge, Companion and ProdDash all run on the NA Ingest
|
||||
Mac, and all three use the `media@waters.church` Resi login. Keep them polling no faster than
|
||||
every 3 seconds: Resi rate-limits the account when tools share it.
|
||||
Reference in New Issue
Block a user