Resi Cues becomes a real module, and Companion keeps the stage timer
Yesterday's version of this was a Python script under `modules/` with a LaunchAgent to keep it alive — which the guide rules out in as many words: everything a module does runs inside its server entry, no companion programs or daemons an operator starts by hand. It also could not put anything on a dashboard, which is half of what it was wanted for. Both halves are now in the right place. `modules/resi-cues/` is an ordinary module. Its tile is one number as large as the tile allows — the countdown to the next Resi cue, the cue's name above it, the playhead and the cue just passed underneath, and the whole cue list behind a tile switch. It also declares `"provides": ["timers"]` and serves `/timers` and `/timers/stream`, so the countdown and the playhead turn up among the ProPresenter timers in the Timers module without either side knowing about the other. The countdown ticks in the browser. The server sends the playhead with the instant it was true and whether playback is running, and the tile adds the elapsed time since; the Timers module extrapolates from `startedAt` the same way. So a snapshot only has to be sent when something structural changes — a new cue, a pause, a seek — rather than at 1 Hz to every open dashboard. `resi.js` holds the part worth reading twice. Resi republishes a decoder's position only every few seconds, on an irregular cadence, and each reading is already stale when it appears; a countdown built straight from it sits seconds behind and lurches. So every reading is kept as media time minus wall time and the largest recent value is trusted — the reading that arrived with the least delay — which a slow round trip cannot drag backwards. A reading outside the link's measured noise floor counts as a seek: drop the lock, snap, and re-read the cue list at once instead of on its timer. Playback is only called paused once the playhead has been still for longer than Resi's own cadence, because a fixed timeout mistakes a slow update for a stop and freezes the countdown mid-service. Driving the ProPresenter timer on the stage screen is Companion's job now. It is already a service on that machine, so nothing new has to be kept alive, and this module no longer has to reach ProPresenter at all — it only has to be right about Resi, which is the hard part. `resi.test.js` drives the estimator on a fake clock against nine simulated Resi profiles — cadences of one to twelve seconds, staleness to three, irregular timing, variable round trips — covering lock-on, a fired cue, a seek backwards, a pause, and a pause longer than the offset window. A punctual fixture proves nothing here: against one, three separate breakages of the estimator go unnoticed. `server.test.js` runs the real server entry against a canned Resi account and checks what the two consumers actually read, including the `/timers` shape field by field. Every mutation tried against either turns them red. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -365,6 +365,22 @@ below. Nothing is installed without someone clicking.
|
||||
as `Label | Message` — add `| #channel` to bind one to a channel — and up
|
||||
to eight quick emojis).
|
||||
Tile settings: avatars, timestamps, names and channel notices.
|
||||
- **Resi Cues** — how long until the next Resi cue point, for a campus
|
||||
running video from another site. The tile is one number, as large as it
|
||||
will go: the countdown to the next cue, its name above it, and the playhead
|
||||
and the cue just passed underneath. It also offers that countdown and the
|
||||
playhead to the **Timers** module, so they can sit among the ProPresenter
|
||||
timers instead of in a tile of their own.
|
||||
Both the cue list and the decoder's position come from Resi's cloud rather
|
||||
than the decoder — the decoder reports upstream and central.resi.io hands it
|
||||
back — so nothing is installed at the decoder end. Resi republishes a
|
||||
position only every few seconds and each reading is already stale, so the
|
||||
playhead is estimated between readings rather than repeated; a countdown
|
||||
built straight from Resi's number sits seconds behind and moves in lurches.
|
||||
Admin config: Resi login and password, which decoder to follow (the list is
|
||||
read from the account), and a folded **Timing** group for the poll
|
||||
intervals and a position trim.
|
||||
Tile settings: cue name, previous cue, playhead, cue list.
|
||||
- **Band Lineup** — the backstage stage board: everyone on stage in their mic
|
||||
slot with photo, name and mic/pack label, on one shared board that every
|
||||
screen sees the same way — whoever edits it changes it everywhere, over SSE.
|
||||
@@ -400,12 +416,6 @@ board — a plan, its team members, birthdays and photos — run ProdDash with
|
||||
`BAND_LINEUP_API_BASE=http://127.0.0.1:24710`). See the testing section of
|
||||
the [module guide](docs/MODULE-GUIDE.md).
|
||||
|
||||
One folder under `modules/` is not a tile: **`resi-studio-cues/`** is a standalone
|
||||
helper that puts a countdown to the next Resi cue on the stage screen, by driving a
|
||||
ProPresenter timer directly. It has no `module.json`, so the shell's scan skips it and
|
||||
it never appears in the + picker. It is documented in its own folder rather than
|
||||
above, because there is nothing here to install or configure.
|
||||
|
||||
## Install as a desktop web app
|
||||
|
||||
Open the page in a browser first, then:
|
||||
|
||||
Reference in New Issue
Block a user