Summary
The ControlByWeb X19S is a networked I/O controller that exposes its state and accepts commands over TCP/IP via HTTP GET requests to state.xml / state.json / customState.xml / customState.json endpoints, via Modbus/TCP on port 502, via SNMP (v1/v2c/v3), and via MQTT 3.1.1 (with optional Sparkplug B). This spec documents the integration protocol surfaces as described in the ControlByWeb 400-Series integration manual.
Transport
# Source confirms: HTTP over TCP/IP, Modbus/TCP port 502, SNMP, MQTT 3.1.1.
# No serial (RS-232) interface mentioned for the X19S in source.
protocols:
- tcp
- http
addressing:
port: 80 # default HTTP port per source examples (http://192.168.1.2/...) ; configurable per Advanced Network tab
modbus_port: 502 # stated in source: "open a connection with the module on port 502"
auth:
type: basic # source: HTTP Basic with Base64-encoded "name:password"; auth only when User account enabled
notes: "Authorization header example: 'Authorization: Basic bm9uZTp3ZWJyZWxheQ==' (Base64 of none:webrelay)"
Traits
# Populated from explicit evidence in source:
# - queryable (state.xml / state.json GET; Read Holding Registers; SNMP GetRequest; etc.)
# - routable # inferred from per-relay control commands and digital I/O routing
# - powerable # inferred from relay on/off/pulse commands (relays control attached loads)
queryable: true
routable: true # inferred from relay and digital I/O control commands
powerable: true # inferred from relay on/off control commands
Actions
# Coverage note: source describes the X-400 Series command surface generically.
# Commands below are documented at the family level; X19S-specific I/O numbering
# (which relays/digital inputs/registers exist on the X19S) is UNRESOLVED.
# Commands use literal payloads from the source.
# --- HTTP GET: relay control (state.xml / state.json) ---
- id: relay_off
label: Turn Relay Off (HTTP)
kind: action
command: "GET /state.xml?relay{relay}=0 HTTP/1.1\r\n\r\n"
params:
- name: relay
type: integer
description: Relay number (e.g. 1 for relay1)
- id: relay_on
label: Turn Relay On (HTTP)
kind: action
command: "GET /state.xml?relay{relay}=1 HTTP/1.1\r\n\r\n"
params:
- name: relay
type: integer
description: Relay number (e.g. 1 for relay1)
- id: relay_pulse
label: Pulse Relay (HTTP, default duration)
kind: action
command: "GET /state.json?relay{relay}=2 HTTP/1.1\r\n\r\n"
params:
- name: relay
type: integer
description: Relay number (e.g. 1 for relay1)
- id: relay_pulse_time
label: Pulse Relay for Specified Seconds (HTTP)
kind: action
command: "GET /state.json?pulseTime{relay}={seconds}&relay{relay}=2 HTTP/1.1\r\n\r\n"
params:
- name: relay
type: integer
description: Relay number
- name: seconds
type: integer
description: Pulse duration in seconds; must precede the relay command in URL
# --- HTTP GET: set on-time / total on-time ---
- id: set_on_time
label: Set onTime (HTTP)
kind: action
command: "GET /state.xml?onTime{io}=0 HTTP/1.1\r\n\r\n"
params:
- name: io
type: integer
description: Local I/O number
- name: value
type: integer
description: Seconds to set onTime to
- id: set_total_on_time
label: Set totalOnTime (HTTP)
kind: action
command: "GET /state.xml?totalOnTime{io}=0 HTTP/1.1\r\n\r\n"
params:
- name: io
type: integer
description: Local I/O number
- name: value
type: integer
description: Seconds to set totalOnTime to
# --- HTTP GET: counter / register ---
- id: set_counter
label: Set Counter (HTTP)
kind: action
command: "GET /state.json?count{io}={value} HTTP/1.1\r\n\r\n"
params:
- name: io
type: integer
description: Local I/O number
- name: value
type: integer
description: Counter value to set
- id: set_register
label: Set Register (HTTP)
kind: action
command: "GET /state.xml?register{io}={value} HTTP/1.1\r\n\r\n"
params:
- name: io
type: integer
description: Register number (e.g. 1)
- name: value
type: number
description: Register value (numeric; example used 10.5)
# --- HTTP GET: read state ---
- id: get_state_xml
label: Read state.xml
kind: query
command: "GET /state.xml HTTP/1.1\r\n\r\n"
- id: get_state_json
label: Read state.json
kind: query
command: "GET /state.json HTTP/1.1\r\n\r\n"
- id: get_custom_state_xml
label: Read customState.xml
kind: query
command: "GET /customState.xml HTTP/1.1\r\n\r\n"
- id: get_custom_state_json
label: Read customState.json
kind: query
command: "GET /customState.json HTTP/1.1\r\n\r\n"
# --- HTTP GET: combined commands ---
- id: multi_command_custom
label: Combined customState.xml command
kind: action
command: "GET /customState.xml?relay1=1&relay2=0 HTTP/1.1\r\n\r\n"
notes: "Multiple arguments combined into one URL; example from source."
- id: multi_command_state_json
label: Combined state.json command
kind: action
command: "GET /state.json?relay1=1&relay2=0 HTTP/1.1\r\n\r\n"
# --- HTTP GET: log access ---
- id: get_log
label: Read log.txt
kind: query
command: "GET /log.txt HTTP/1.1\r\n\r\n"
notes: "Requires password if User account enabled."
- id: erase_log
label: Erase log.txt
kind: action
command: "GET /log.txt?erase=1 HTTP/1.1\r\n\r\n"
- id: get_syslog
label: Read syslog.txt
kind: query
command: "GET /syslog.txt HTTP/1.1\r\n\r\n"
notes: "Requires setup username and password."
- id: erase_syslog
label: Erase syslog.txt
kind: action
command: "GET /syslog.txt?erase=1 HTTP/1.1\r\n\r\n"
# --- Modbus/TCP: per source, function code payloads are not literal ASCII ---
- id: modbus_read_coils
label: Modbus Read Coils (FC 01)
kind: query
command: "0x01" # UNRESOLVED at X19S level: start address and quantity depend on device Modbus map
notes: "Function code 0x01. Start address and quantity per device Modbus address table."
- id: modbus_read_discrete_inputs
label: Modbus Read Discrete Inputs (FC 02)
kind: query
command: "0x02"
notes: "Function code 0x02. Addresses per device Modbus address table."
- id: modbus_read_holding_registers
label: Modbus Read Holding Registers (FC 03)
kind: query
command: "0x03"
notes: "Function code 0x03. 32-bit floats read as register pairs; little- or big-endian per device config."
- id: modbus_write_single_coil
label: Modbus Write Single Coil (FC 05)
kind: action
command: "0x05"
notes: "Function code 0x05. Output value 0x00 = Off, 0xFF = On."
- id: modbus_write_multiple_coils
label: Modbus Write Multiple Coils (FC 15)
kind: action
command: "0x0F"
notes: "Function code 0x0F (15). Values 0x0000-0xFFFF; byte count = quantity/8."
- id: modbus_write_multiple_registers
label: Modbus Write Multiple Registers (FC 16)
kind: action
command: "0x10"
notes: "Function code 0x10 (16). 32-bit IEEE 754 floats; endianness per device config."
# --- SNMP: per source, MIB objects generated from device setup ---
- id: snmp_get
label: SNMP GetRequest
kind: query
command: "GetRequest"
notes: "Supports v1, v2c, v3. Object IDs (OIDs) generated per device; see device MIB file."
- id: snmp_set
label: SNMP SetRequest
kind: action
command: "SetRequest"
notes: "Supports v1, v2c, v3. Object IDs (OIDs) generated per device."
- id: snmp_trap
label: SNMP Trap
kind: event
command: "Trap"
notes: "Sent on relay state change, sensor threshold, or out-of-range Vin. Configured as action in Conditional/Scheduled tasks."
- id: snmp_notification
label: SNMP Notification
kind: event
command: "Notification"
notes: "Supported on v2c and v3; expects response from manager (retries on no-response)."
# --- MQTT ---
- id: mqtt_publish
label: MQTT Publish
kind: action
command: "publish"
notes: "MQTT 3.1.1. Topic and broker defined in device Broker tab. Payload may include MQTT tokens (e.g. ${relay1}, ${vin})."
- id: mqtt_subscribe
label: MQTT Subscribe
kind: action
command: "subscribe"
notes: "MQTT 3.1.1. Subscribes to topics defined in device Broker tab to receive I/O from other devices."
Feedbacks
# Observable state per source XML/JSON tag tables. The presence and numbering of
# each tag on the X19S specifically is UNRESOLVED - source describes the family.
- id: relay_state
type: enum
values: [0, 1]
description: "From <relayX> in state.xml/json: 0=off (coil off), 1=on (coil energized)."
- id: digital_input_state
type: enum
values: [0, 1]
description: "From <digitalInputX> / <digitalIOX>: 0=off (no voltage), 1=on (voltage applied)."
- id: analog_input_value
type: number
description: "From <analogInputX>: value of analog input X."
- id: vin_value
type: number
description: "From <vin>: scaled internal Vin measurement. Always present in state.xml/json."
- id: register_value
type: number
description: "From <registerX>: value of register X."
- id: on_time
type: number
description: "From <onTimeX>: seconds input has been on since last coming on."
- id: total_on_time
type: number
description: "From <totalOnTimeX>: total seconds input has been on."
- id: count_value
type: number
description: "From <countX>: count value associated with input X."
- id: frequency_value
type: number
description: "From <frequencyX>: frequency associated with input X."
- id: frequency_input
type: number
description: "From <frequencyInput>: value of frequency input (X-420 per source)."
- id: one_wire_sensor
type: string
description: "From <oneWireSensorX>: 'x.x' if sensor could not be read; numeric value otherwise (units suffix with showUnits=1)."
- id: utc_time
type: integer
description: "From <utcTime>: seconds since January 1, 1970."
- id: timezone_offset
type: integer
description: "From <timezoneOffset>: offset applied to utcTime for local time."
- id: serial_number
type: string
description: "From <serialNumber>: device MAC address (00:00:00:00:00:00 format)."
- id: modbus_read_register_response
type: number
description: "Modbus FC03 response: IEEE 754 32-bit float returned as register pair; little- or big-endian per device config. NaN (0xFFFFFFFF) if sensor not installed."
Variables
# Per source: registers are settable numeric values.
- id: register
type: number
description: "Writable numeric register; set via HTTP (state.xml?registerX={value}) or Modbus FC16."
range: "" # UNRESOLVED: register value range not stated in source
Events
# Source documents:
- id: snmp_trap_relay_change
description: "SNMP Trap sent when a relay changes state."
- id: snmp_trap_sensor_threshold
description: "SNMP Trap sent when a configured sensor threshold is reached."
- id: snmp_trap_vin_range
description: "SNMP Trap sent when supply voltage is out of desired range."
- id: remote_services_state_push
description: "When Remote Services connection is open and a 'send state' action fires, state.xml is sent to the external server. Server must return a 3-character 'ACK' within 10 seconds or the device closes the connection."
- id: cloud_dat_url_push
description: "ControlByWeb.Cloud forwards device state via DAT URLs; HTTPS endpoint returns state.json/xml."
Macros
# UNRESOLVED: no explicit multi-step sequences documented in source beyond the
# combined-URL pattern (relay1=1&relay2=0) which is captured under multi_command_* actions.
Safety
confirmation_required_for: []
interlocks: []
# UNRESOLVED: source contains no safety warnings, interlock procedures, or
# power-on sequencing requirements specific to the X19S.
Notes
- Auth disabled by default. Source: "Modbus communications are disabled whenever the User account is enabled. This is because Modbus/TCP does not provide a mechanism for password protection. Make sure the User account is disabled (default) and Modbus functionality is enabled on the Advanced Network." → Enabling HTTP Basic auth effectively disables Modbus.
- Modbus connection timeout: "if no data is transferred for 50 seconds, the connection will time out and close." Send periodic reads to keep open.
- Modbus socket limit: "The module has two TCP sockets available for Modbus/TCP. ... Requests for more than two open connections will be rejected."
- Pulse-time ordering: Source: "The pulseTime argument MUST come before the relay1=2 command."
- Endianness: Modbus holding register values are IEEE 754 32-bit floats; little- or big-endian is configured per-device in Advanced Network tab. Source gives worked example 81.25 → 0x800042A2 little-endian.
- Default community strings (SNMP v1/v2c): both read and write default to
webrelay. - MQTT version: MQTT 3.1.1; optional Sparkplug B.
- HTTP port default: source examples use port 80 (
http://192.168.1.2/...); explicitly notes port 8000 as a non-default example. Port is configurable under Advanced Network tab. - syslog.txt access: requires setup username/password (separate from HTTP Basic for state.xml).
Provenance
source_domains:
- controlbyweb.com
source_urls:
- https://controlbyweb.com/wp-content/uploads/2025/05/cbw-integration-and-protocols-manual.pdf
- https://controlbyweb.com/support/cbw-integration-manual/
- https://controlbyweb.com/wp-content/uploads/2024/01/x-19s_users_manual_v1.0.pdf
- https://controlbyweb.com/support/
retrieved_at: 2026-06-30T15:12:47.777Z
last_checked_at: 2026-07-07T11:12:31.505Z
Verification Summary
verdict: verified
checked_at: 2026-07-07T11:12:31.505Z
matched_actions: 30
action_count: 30
confidence: medium
summary: "All 30 actions verified against source; every HTTP endpoint, Modbus function code, SNMP operation, and MQTT capability matched with literal command evidence. (9 unresolved item(s) noted in Known Gaps.)"
Known Gaps
- "source document describes the X-400 Series family generically; X19S-specific I/O count, relay count, register count, and analog input count not explicitly enumerated."
- "whether the X19S exposes every transport (HTTP/Modbus/SNMP/MQTT) is not separately confirmed in source — protocol list is inferred from family documentation."
- "register value range not stated in source"
- "no explicit multi-step sequences documented in source beyond the"
- "source contains no safety warnings, interlock procedures, or"
- "X19S-specific I/O counts (number of relays, digital inputs, analog inputs, 1-Wire sensors, registers, counters) — source describes the X-400 Series family, not the X19S model specifically."
- "whether X19S supports all four transports (HTTP, Modbus, SNMP, MQTT) — inferred from family docs; X19S-specific confirmation not in source."
- "device Modbus address map (start addresses for coils, discrete inputs, holding registers) — source defers to device-specific Modbus address table."
- "firmware version compatibility — not stated in source."
From the AI4AV catalog (https://ai4av.net) · ODbL-1.0