WATCHOUT 6 Protocol
WATCHOUT 7 includes a backward-compatible WATCHOUT 6 command interface. It is intended for existing control-system integrations and custom scripts that already speak WO6 command syntax.
WATCHOUT emulates the v6 WATCHMAKER role. From the perspective of a legacy control system, the node appears as a WATCHMAKER host accepting commands on the standard WATCHMAKER port.
This page documents behavior as implemented in the current WO6 compatibility source code.
Transport and Framing
- Ports:
3040(WATCHMAKER) and3039(WATCHPOINT). - Protocols: TCP and UDP listeners start on both ports.
- Frame delimiter:
\r\n(CRLF). - Max incoming frame size: 4096 bytes.
- Text format: command-oriented text protocol, one command per frame.
Use CRLF in clients even if some line-ending variants may be tolerated.
Request IDs ([id] Prefix)
Commands may be prefixed with an ID tag: [my-id]ping
- TCP replies echo this prefix:
[my-id]Ready ... - For commands that return an empty success payload, the response is just the tag plus CRLF:
[my-id]\r\n - For subscription commands with IDs, the first tagged response is empty acknowledgement; streamed updates then arrive untagged
Main Timeline Behavior
Commands that omit a timeline name target a timeline named exactly Main Timeline.
If that timeline does not exist, those commands fail with runtime error responses.
"Main Timeline" also appears in the list returned by getAuxTimelines. It is not filtered out from auxiliary timeline listings.
Syntax Rules
- Command names are case-sensitive (
getStatus, notgetstatus). - Boolean arguments are
trueorfalse. - An unquoted name stops at the first space. A name that contains a space must be wrapped in double quotes.
run Timeline 2reads the name asTimeline, notTimeline 2. - Extra unexpected tokens cause parse/runtime errors.
- Time values accept:
- milliseconds:
5000 - timestamp:
HH:MM:SS.FFF - slash separator:
HH:MM:SS/FFF
- milliseconds:
Response Formats
The Error wire format is Error <code> 0 "<message>", where the code is a number from 1 to 8.
| Type | Wire format | Used by |
|---|---|---|
Ready | Ready "<version>" "WATCHMAKER" "<OS>" <bool> | ping, authenticate, final phase of load |
Status (old style) | Reply ... | getStatus (no args) |
Status (new style) | Status "" ... | getStatus 1/2 (general) |
Timeline status | Status "TaskList:mItemList:mItems:TimelineTask \"<name>\"" <state> <pos> <world_clock> | timeline variant of getStatus |
Busy | Busy "Open" "" 0 | first phase of load |
Reply JSON | Reply { ... } | getInputs, getAuxTimelines, getControlCues |
Empty | empty payload (blank line) | most action commands on success |
Error | Error <code 1-8> 0 "<message>" | parse/runtime/auth/unsupported failures |
getStatus Modes
getStatus is one command with multiple modes (including timeline status and subscriptions).
| Request | Behavior | Response |
|---|---|---|
getStatus | old WO6 polling style | one Reply ... |
getStatus 2 | one-shot general status | one Status "" ... |
getStatus 1 | subscribe general status | status stream (Status "" ...) |
getStatus 0 | unsubscribe general status | empty |
getStatus 2 "TaskList:mItemList:mItems:TimelineTask \"Timeline 1\"" | one-shot timeline status | one timeline Status ... |
getStatus 1 "TaskList:mItemList:mItems:TimelineTask \"Timeline 1\"" | subscribe timeline status | timeline status stream |
getStatus 0 "TaskList:mItemList:mItems:TimelineTask \"Timeline 1\"" | unsubscribe timeline status | empty |
Timeline state values in timeline-status responses are:
0= stopped1= paused2= running
Implemented Commands
| Command | Syntax | Success response | Notes |
|---|---|---|---|
authenticate | authenticate <level> | Ready ... | level is accepted; current implementation always returns ready |
ping | ping | Ready ... | keepalive/version check; program name is always "WATCHMAKER", license field is always true |
run | run [timeline_name] | empty | no name = Main Timeline. An unquoted name stops at the first space. Quote a name that contains spaces |
halt | halt [timeline_name] | empty | no name = Main Timeline. An unquoted name stops at the first space. Quote a name that contains spaces |
kill | kill <timeline_name> | empty | timeline name required. An unquoted name stops at the first space. Quote a name that contains spaces |
reset | reset | empty | stops aux timelines, sets main timeline to paused at time 0 |
getStatus | see mode table above | Reply ... / Status ... / stream / empty | replaces separate legacy status commands |
gotoTime | gotoTime <time> [timeline_name] | empty | preserves run/pause state; stopped timelines are resumed as paused after jump |
gotoControlCue | gotoControlCue <cue_name> [reverse_only] [timeline_name] | empty | default search is forward then backward fallback |
setInput | setInput <input_name> <value_or_delta> [transition_ms] | empty | +x/-x are relative changes |
setInputs | setInputs <transition_ms> <input_name> <value_or_delta> ... | empty | transition is required; use 0 for immediate |
getInputs | getInputs [input_name] | Reply {"Inputs":...} | returns one or all mapped inputs |
getAuxTimelines | getAuxTimelines [tree] | Reply { ... } | tree selects tree-shaped reply payload |
getControlCues | getControlCues <filter 0-7> [timeline_name] | Reply {"Layers":...} | filter bitmask: 1 no-op, 2 cross-timeline target, 4 unnamed |
load | load <path> [condition] [go_online] | Busy ... then Ready ... | condition/go_online are parsed for compatibility; relative paths resolve via configured show directory |
online | online <bool> | empty | accepted for compatibility; currently no-op |
Response Details
pingresponse: The program name field is always"WATCHMAKER"and the license field is alwaystrue, regardless of the actual WATCHOUT license state.getStatusresponse (old style): The show name field returns the show file name (the file stem). It is an empty string when no show is loaded. Theactivefield reflects whether a show is loaded. Thebusy,status,open, andprogrammerfields are hardcoded values for compatibility and do not reflect actual WATCHOUT state.loadgo_onlineparameter: This parameter is parsed but currently ignored. WATCHOUT 7 does not have an offline mode equivalent to WO6.
setInput and setInputs value syntax:
- absolute:
1.0 - relative increase:
+0.5 - relative decrease:
-0.5
Parsed but Not Implemented
These commands are parsed, but currently return runtime unimplemented errors (Error 7 0 "Request ... is not implemented in WATCHOUT 7 yet.") on TCP:
hitTest <x> <y>list <magic_path> [depth]getStagestandBy <bool> [transition_ms]setRate <float>timecodeMode <option> [offset]powerDownsetLogoString <string>getFile [look_in_shows] <magic_path>serialPort <open> <name> [protocol] [baud] [data_bits] [stop_bits] [parity]enableLayerCond <condition>wait
Discover Compatibility Command
discover <digits> is accepted for legacy compatibility traffic.
- TCP: returns empty response
- UDP: ignored (no response)
UDP Behavior
UDP support is fire-and-forget: no responses are sent.
- Side-effect commands (for example
run,halt,gotoTime,setInput) are executed - Response-oriented commands are ignored on UDP, including
getStatus,getInputs,getAuxTimelines,getControlCues,list,getStage,getFile, andhitTest
Differences from Older WO6 Integrations
getTimelineStatus,subscribeStatus, and related timeline-subscribe commands are represented throughgetStatusmode variantsloadShowisloadonlineis accepted but does not change runtime behavior- Main-timeline defaults require a timeline named
Main Timeline hitTestis not implemented in this protocol path
Migration Guidance
Use WO6 protocol compatibility to keep existing control systems running, but prefer newer interfaces for new development:
- HTTP REST API for complete control surface and modern integrations
- OSC Protocol for OSC-native show control systems
The WO6 layer is a compatibility bridge, not a full feature surface for WATCHOUT 7-specific workflows.
Related
- HTTP REST API — the full WATCHOUT control surface.
- OSC Protocol — show control over OSC.