Appearance
Connecting External Systems
This page shows how to connect Exaplay to the systems around a show: a Stream Deck at the operator desk, a media controller such as Crestron or Q-SYS, a home-automation or building system, smart plugs and other network devices, and your own software. It covers which route to use for which system, and walks through the four most common setups step by step.
Exaplay talks to other systems in three ways:
| Direction | What it is for | How |
|---|---|---|
| Into Exaplay | Another system starts compositions, fires cues, switches Blank | TCP, OSC, UDP, HTTP, MQTT, Art-Net |
| Back from Exaplay | The other system shows what is playing, which cue, how long until the next one | the /status WebSocket |
| Out of Exaplay | A cue or a button switches a light, a plug, a projector, tells the building a scene began | the cue lines OSC>, TCP> / UDP>, HTTP>, MQTT>, ARTNET>, DALI> |
Which route for which system
| System | Recommended route | Ready-made start |
|---|---|---|
| Stream Deck (via Bitfocus Companion) | The Exaplay Companion module: commands over TCP, live status on the keys | integrations\companion — step-by-step guide |
| Crestron, AMX, Q-SYS, Extron | TCP for commands, /status for feedback | integrations\crestron, amx, qsys, extron |
| Medialon, Alcorn McBride | A generic TCP device with the command strings from the recipe | integrations\medialon, alcorn-mcbride |
| Lighting desk (ETC Eos, grandMA …) | OSC, or Art-Net / timecode | integrations\etc-eos; ArtNet & DMX |
| QLab / CueLab | OSC or TCP network cues | integrations\qlab-cuelab |
| Home Assistant, Node-RED, IoT sensors | MQTT in both directions, or REST | integrations\home-assistant, node-red — guide below |
| Smart plugs, REST devices, webhooks (Shelly, a camera's REST API) | The HTTP> cue line | guide below |
| TouchDesigner | OSC or TCP for commands, /status for feedback | integrations\touchdesigner |
| Your own panel or script | TCP or HTTP for commands, /status for feedback | integrations\generic — guide below |
The integrations folder is installed with Exaplay (by default C:\Program Files\Exaplay 3\integrations, also in the Start menu as Show-control integrations) — or download them in any browser that can open Exaplay under Control → Integrations. Each template states in its README.md what has been tested and what has not. Most have not been run on the vendor's own hardware, so treat them as a head start rather than certified drivers.
Build sequences in Exaplay, press them from outside
When an outside system needs to run several steps (start two timelines, wait, fade the lobby), build them once as a command button in the Control tab and press it by its ID: POST /control/fire {"id":"…"}. The sequence then lives in the show file, the operator can see and test it, and the outside system only needs to know one ID.
Stream Deck with Bitfocus Companion
Bitfocus Companion turns a Stream Deck into a control surface. The Exaplay module puts transport, your cue lists (one key per cue), command buttons, Blank and Show Mode on its keys, and the keys light up from Exaplay's live status. On a Stream Deck+ its dials set volume, opacity and the master volume, seek, and pick a cue to fire.
The module package ships with Exaplay — integrations\companion\vioso-exaplay-<version>.tgz in the Exaplay folder, or Control → Integrations → Download from any browser — and Companion 4.2 or later imports it under Modules → Import module package.
→ Step by step: Stream Deck with Bitfocus Companion — import, connection, presets, your own keys, troubleshooting, and updating from the earlier module.
Home Assistant and Node-RED over MQTT
MQTT is the common language of home automation and IoT: a broker passes messages between everything that is connected. Exaplay can listen to the broker (a door sensor starts a cue) and send to it (a cue switches the room light). Home Assistant brings a broker as its Mosquitto broker add-on; Node-RED has broker nodes; or run Mosquitto on any PC in the show network.
Before you start
- The broker must be on the local network (an address like 10.x, 172.16–31.x or 192.168.x, or the Exaplay PC itself). Exaplay speaks plain MQTT without encryption (TLS), so a cloud broker is refused.
- Create a broker account just for Exaplay that may only read and write the topics the show needs. The password is saved in the show file, and anyone who can reach the Exaplay machine's web port can read it back. In Home Assistant: Settings → People → Users → Add user, then use that user in Exaplay.
Listening: a sensor starts a cue
- Open Control → Inputs, press + Device and choose MQTT.
- Enter the broker's address in Broker (port
1883unless your broker uses another). Under More…, enter the User and Password of the Exaplay account. - In Topic, enter the topic the sensor publishes to, for example
zigbee2mqtt/front_door. If the message is JSON, name the field in JSON field, for examplecontact. - Watch Shows: it displays the last message Exaplay received on that topic. If it stays empty, check the topic name in your broker (Home Assistant: Settings → Devices & services → MQTT → Configure → Listen to a topic).
- Add a rule to the channel (
mqtt, or the name you gave it): press + Rule on the channel and choose, for example, rises above 0.5 → Go to CueWelcome(or Custom command…comp1.cue.go=Welcome).
The value can also be shown on the wall: type {src:mqtt} into a Text clip, or bind a generator parameter to it. See Inputs › MQTT for every setting.
Sending: a cue switches a light
Add a line to a cue's script or a command button:
MQTT>Home Assistant,zigbee2mqtt/lobby_light/set,{"state":"ON","brightness":120}- The first field names the MQTT device you created in Inputs (here it was named Home Assistant), so its address and login are used and no password is ever typed into a cue.
- The second field is the topic, the rest is the message, sent exactly as written.
- The Command Wizard builds the line for you: choose MQTT, type the MQTT device's name into the address field, then enter topic and payload.
In Home Assistant an automation can react to any topic Exaplay publishes, for example exaplay/scene with the message act2 — trigger MQTT, topic exaplay/scene, payload act2.
See Cue Script Reference › MQTT for the exact rules.
Node-RED
Node-RED can use the same MQTT route (its mqtt in / mqtt out nodes against the same broker). It can also talk to Exaplay directly: the importable flow integrations\node-red\exaplay-flow.json sends commands over TCP and HTTP and listens to Exaplay's live status. Import it with Menu → Import, then set the Exaplay address in its config nodes.
Switching a network device with HTTP>
Many devices are switched by calling a web address: a Shelly smart plug, a camera's REST API, a projector with a web interface, a webhook in Home Assistant or Node-RED. The cue line HTTP> does that from a cue or a command button.
Example: a Shelly plug switches on with the show.
Open the cue and press ⚡ Wizard under its script box (on a command button: Add with Wizard).
Choose HTTP, method GET, URL
http://10.0.0.30/relay/0?turn=on.Apply. The cue's script now holds:
HTTP>GET http://10.0.0.30/relay/0?turn=onRun the cue and open Control → Monitor. An OUT row reads Cue → GET http://10.0.0.30/relay/0?turn=on — 200, followed by the start of the device's answer. A failure is an ERROR row ending in FAILED: and the reason, for example the device does not accept a connection — is it on, and is the port right?.
More examples
HTTP>POST http://homeassistant.local:8123/api/webhook/show-start,{"scene":"act2"}
HTTP>PUT http://10.0.0.40/api/preset,{"id":3}
HTTP>GET http://${Plug}/relay/0?turn=off- A message (body) follows the first comma after the address. It is sent as JSON when it starts with
{or[, otherwise as plain text. ${Name}uses a show variable, so the device's address is entered once.- No user name or password in the address: Exaplay refuses
http://user:pass@…, because anyone on the network could read it back from the show. Use a device that accepts requests without a login on the show network, or a webhook with a secret in its path. - A device on
https://with a self-signed certificate is refused; on the local network usehttp://. - The request runs in the background and never holds up playback. Exaplay waits at most a few seconds for a connection and ten seconds for the answer.
See Cue Script Reference › HTTP for the exact rules.
Live status for your own panel
A control panel is only trustworthy if it shows what Exaplay is really doing, not what was last pressed. Exaplay pushes its state over the WebSocket ws://<exaplay-ip>:8123/status as soon as something changes:
json
{
"type": "status", "v": 1,
"show-mode": true, "blank": false,
"compositions": [
{ "id": "comp1", "name": "Main Show", "state": "playing", "time": 12.3,
"cue": { "index": 3, "name": "Blackout" }, "next-cue-in": 4.2 }
]
}- Connect a WebSocket client to
ws://<exaplay-ip>:8123/status. The first message is the complete picture. - Update your display from each
statusmessage. A new message replaces the previous one completely. - Optionally send
{"rate": 10}to receive up to 10 messages per second (default 5). When nothing changes, Exaplay sends only a shortalivemessage every 5 seconds; if you hear nothing for 15 seconds, reconnect. - Send commands the usual way, over TCP or HTTP. The next status message confirms the result.
Two rules keep a panel honest: ignore keys you do not know (later versions add keys), and show a missing key as unknown, not as off.
The Status Push reference lists every key and has a short Python example. The Companion module, the Node-RED flow and the TouchDesigner template already read it.
In a multi-client show
- Connect outside systems to the master. Commands to the master reach every client through the normal sync, and
/statuson the master reports the show. - An MQTT device in Inputs connects on the master only and hands its values to the clients. Rules that do something (start a cue) fire on the master only.
HTTP>andMQTT>lines go out from the master only, wherever they are written — a cue that plays on every machine still switches the plug or calls the webhook once. Command buttons and Inputs actions run on the master anyway. (OSC>,TCP>andUDP>lines in a cue are still sent by every machine that plays the cue; put a line that must go out exactly once into a command button.)
Ports
Allow these through every firewall between Exaplay and the outside systems:
| Port | Direction | Used by |
|---|---|---|
TCP 8100 | into Exaplay | TCP commands (Companion, Crestron, Q-SYS, Extron, Medialon …) |
UDP 8000 | into Exaplay | OSC (lighting desks, QLab, Companion's Outlines / Raw wall …) |
UDP 8200 | into Exaplay | text UDP commands |
TCP 8123 | into Exaplay | HTTP API, command buttons, the /status WebSocket, the web interface |
TCP 1883 | out of Exaplay | MQTT to the broker |
TCP 80 / 443 | out of Exaplay | HTTP> to devices (or the port in the address) |
The ports into Exaplay can be changed under ☰ → Settings → Communication. They have no authentication: keep Exaplay on an isolated show network and never expose these ports to the internet. See Network configuration.
Troubleshooting
| Symptom | Check |
|---|---|
| Companion shows Connection red | Is the IP address the master's? Is TCP 8100 open? Does telnet <ip> 8100, then hello, answer hallo? |
Companion keys stay unlit, text ? | The status feed is not reaching Companion: TCP 8123 blocked, or Use the status feed switched off in the module's settings. |
| MQTT device reads The broker refused the user name or password | Check the account in the broker; Exaplay retries every 30 seconds after a refused login. |
| MQTT device refuses the broker address | The broker must be on the local network; a cloud broker is not supported in this version. |
| MQTT Shows stays empty | The topic does not match: compare it letter by letter with what the broker shows; use # to test (zigbee2mqtt/#). |
HTTP> gives the device answered HTTP 401 | The device wants a login. Exaplay sends none; use a device or webhook that accepts the request without one. |
| Nothing happens and the Monitor shows nothing | Switch monitoring on (Control → Monitor). A line that uses an unknown ${Name} is refused before it is sent and shows as Cue NOT SENT — unknown variable. |
See also
- External Show Control — every incoming and outgoing protocol with examples
- Status Push (WebSocket)
- Cue Script Reference
- Inputs — MQTT, Web data and every other input device
- Custom Controls — command buttons
- Monitor — see every command in and out
