๐ŸŽƒPick The Lights

The agent & MadMapper

The agent is a small Python program that runs next to MadMapper. It never opens inbound ports: it polls Pick The Lights over HTTPS and talks to MadMapper over OSC (UDP) and OSC Query (HTTP/WebSocket) on your local network.

Install

macOS or Windows with Python 3.11+ installed:

pip install ptl-agent
ptl-agent setup        # paste your show token from Settings โ†’ Account & API
ptl-agent discover     # lists the timelines it sees in MadMapper
ptl-agent run

Or run it from the source checkout: python -m ptl_agent run. Configuration lives in ~/.pickthelights/agent.toml; environment variables PTL_API_BASE, PTL_SHOW_TOKEN, PTL_MADMAPPER_HOST, PTL_MADMAPPER_OSC_PORT override it.

Keep it running during show hours (a login item, launchd, or a scheduled task is fine). It reconnects automatically.

What it does

  1. Heartbeat every 10 s and pulls your settings (mode, bank, hand-off address).
  2. Sync: reads every timeline in the active bank (name, column, duration) and creates/updates sequences. Timelines that disappear are marked inactive. Timelines named Cue-* are ignored by default (ignore_timelines in the config).
  3. Watch: subscribes to each timeline's position over OSC Query so the dashboard and viewer page show what's playing and a progress timer.
  4. Play: when the current timeline has ~3 s left (or immediately if Interrupt playing is on) it asks for the next item and sends /timelines/<Bank>/by_name/<Timeline>/play_from_beginning. Group requests play each member in order; leaders and PSAs are inserted automatically.

Working with automation modules

If a MadMapper module advances your show on its own (for example a Timeline Automation module that loops through columns), set Settings โ†’ MadMapper โ†’ Hand-off OSC address to that module's active address, e.g. /modules/Timeline_Automation/active. The agent sets it to 0 while playing requests and back to 1 when the queue empties, so the two never fight.

Idle timeline

Optionally choose a timeline to play when nothing is queued and nothing is playing โ€” a looping ambient scene, for instance.

MadMapper settings that matter

  • Preferences โ†’ OSC/MIDI: OSC input enabled on port 8010 (default). OSC Query runs on the next port (8011).
  • Timeline names are the identity: renaming a timeline creates a new sequence (your display name, artist and artwork stay with the old name until you rename it in the panel).
  • Durations come from the timeline's loop end.

Troubleshooting

  • "MadMapper not reachable": MadMapper isn't running, OSC Query is disabled, or the port differs. Run ptl-agent discover.
  • "Show token rejected": you rotated the token. Run ptl-agent setup again.
  • Requests never play: viewer control is off, or the current timeline loops forever and Interrupt playing is off. Either set a hand-off address, enable interrupts, or make the idle scene finite.