Summary
The ControlByWeb X21S is an Ethernet-connected industrial I/O module supporting HTTP GET control, Modbus/TCP (slave), SNMP v1/v2c/v3, MQTT 3.1.1 with Sparkplug B, and optional ControlByWeb.Cloud DAT URL integration. The source document describes the ControlByWeb X-400 Series family generically; X21S-specific pinouts, serial configuration, and firmware behaviors are not stated in the source.
Transport
# Source describes multiple network transports. The known protocol label for this spec is
# RS-232C, but the refined source contains no RS-232/serial detail for the X21S specifically.
# HTTP (port 80 default, with :8000 example) and Modbus/TCP (port 502) are documented.
protocols:
- http
- tcp
addressing:
port: 502 # Modbus/TCP default per source
# HTTP default port 80 implied by examples (http://192.168.1.2/...); source notes port can be changed.
auth:
type: basic # HTTP Basic Auth (Base64) optional when User account enabled; Modbus disabled when User account enabled
# inferred: source describes optional HTTP Basic Auth via Base64 "name:password"
Traits
# - powerable # UNRESOLVED: source does not enumerate power on/off commands for X21S (relay states control outputs, not device power)
# - routable # UNRESOLVED: source does not describe input/output routing matrix for X21S
- queryable # inferred from state.xml/json read commands and Modbus read function codes
Actions
# Source documents HTTP GET control patterns (relays, pulse, counters, registers, logs)
# and Modbus/TCP function codes (01, 02, 03, 05, 15, 16). X21S-specific I/O counts and
# Modbus addresses are referenced as "refer to Modbus map in setup pages" - not enumerated.
# --- HTTP: state read ---
- id: http_get_state_xml
label: HTTP GET state.xml
kind: query
command: "GET /state.xml HTTP/1.1\r\n\r\n"
params: []
- id: http_get_state_json
label: HTTP GET state.json
kind: query
command: "GET /state.json HTTP/1.1\r\n\r\n"
params: []
- id: http_get_custom_state_xml
label: HTTP GET customState.xml
kind: query
command: "GET /customState.xml HTTP/1.1\r\n\r\n"
params: []
- id: http_get_custom_state_json
label: HTTP GET customState.json
kind: query
command: "GET /customState.json HTTP/1.1\r\n\r\n"
params: []
# --- HTTP: relay control (X = 1..N, X21S channel count not stated in source) ---
- id: http_set_relay
label: HTTP Set Relay State
kind: action
command: "GET /state.xml?relay{X}={state} HTTP/1.1\r\n\r\n"
params:
- name: X
type: integer
description: Relay number (1-based; X21S max not stated in source)
- name: state
type: enum
values: ["0", "1", "2"]
description: "0=OFF, 1=ON, 2=PULSE"
- id: http_pulse_relay_default
label: HTTP Pulse Relay (preset duration)
kind: action
command: "GET /state.json?relay{X}=2 HTTP/1.1\r\n\r\n"
params:
- name: X
type: integer
description: Relay number
- id: http_pulse_relay_custom
label: HTTP Pulse Relay (custom duration)
kind: action
command: "GET /state.json?pulseTime{X}={seconds}&relay{X}=2 HTTP/1.1\r\n\r\n"
params:
- name: X
type: integer
description: Relay number
- name: seconds
type: integer
description: Pulse duration in seconds (pulseTime must precede relay command per source)
# --- HTTP: counters, on-time, registers ---
- id: http_set_ontime
label: HTTP Set On Time
kind: action
command: "GET /state.xml?onTime{X}={seconds} HTTP/1.1\r\n\r\n"
params:
- name: X
type: integer
- name: seconds
type: integer
- id: http_set_totalontime
label: HTTP Set Total On Time
kind: action
command: "GET /state.xml?totalOnTime{X}={seconds} HTTP/1.1\r\n\r\n"
params:
- name: X
type: integer
- name: seconds
type: integer
- id: http_set_counter
label: HTTP Set Counter
kind: action
command: "GET /state.json?count{X}={value} HTTP/1.1\r\n\r\n"
params:
- name: X
type: integer
- name: value
type: integer
- id: http_set_register
label: HTTP Set Register
kind: action
command: "GET /state.xml?register{X}={value} HTTP/1.1\r\n\r\n"
params:
- name: X
type: integer
- name: value
type: number
description: Numeric value (e.g. 10.5)
# --- HTTP: log files ---
- id: http_get_log
label: HTTP GET log.txt
kind: query
command: "GET /log.txt HTTP/1.1\r\n\r\n"
params: []
- id: http_erase_log
label: HTTP Erase log.txt
kind: action
command: "GET /log.txt?erase=1 HTTP/1.1\r\n\r\n"
params: []
- id: http_get_syslog
label: HTTP GET syslog.txt
kind: query
command: "GET /syslog.txt HTTP/1.1\r\n\r\n"
params: []
- id: http_erase_syslog
label: HTTP Erase syslog.txt
kind: action
command: "GET /syslog.txt?erase=1 HTTP/1.1\r\n\r\n"
params: []
# --- Modbus/TCP function codes (host → X21S slave on port 502) ---
- id: modbus_read_coils
label: Modbus Read Coils (FC01)
kind: query
command: "Modbus FC 0x01 - Read coils (relays / digital outputs)"
params:
- name: start_address
type: integer
description: Per X21S Modbus map (not enumerated in source)
- name: quantity
type: integer
- id: modbus_read_discrete_inputs
label: Modbus Read Discrete Inputs (FC02)
kind: query
command: "Modbus FC 0x02 - Read discrete inputs"
params:
- name: start_address
type: integer
- name: quantity
type: integer
- id: modbus_read_holding_registers
label: Modbus Read Holding Registers (FC03)
kind: query
command: "Modbus FC 0x03 - Read holding registers (Vin, sensors, registers, counters, analog inputs)"
params:
- name: start_address
type: integer
- name: quantity
type: integer
description: Must be even (pairs of 16-bit → 32-bit float)
- id: modbus_write_single_coil
label: Modbus Write Single Coil (FC05)
kind: action
command: "Modbus FC 0x05 - Write coil (0x00=Off, 0xFF=On)"
params:
- name: start_address
type: integer
- name: value
type: enum
values: ["0x00", "0xFF"]
- id: modbus_write_multiple_coils
label: Modbus Write Multiple Coils (FC15)
kind: action
command: "Modbus FC 0x0F - Write multiple coils"
params:
- name: start_address
type: integer
- name: quantity
type: integer
- name: byte_count
type: integer
description: Quantity / 8
- name: value
type: integer
description: 0x0000-0xFFFF bit pattern
- id: modbus_write_multiple_registers
label: Modbus Write Multiple Registers (FC16)
kind: action
command: "Modbus FC 0x10 - Write multiple registers (IEEE 754 float, endianness per setup)"
params:
- name: start_address
type: integer
- name: quantity
type: integer
description: Must be even
- name: values
type: number
description: IEEE 754 32-bit float
# --- UNRESOLVED: Modbus pulse-relay function code variant ---
# Source describes pulse via FC16 at addresses 512-513 in 2.1.3 example but does not
# enumerate this as a distinct device-wide function; treat as same FC16 with address params.
# --- UNRESOLVED: RS-232/serial commands for X21S ---
# Source contains no RS-232 command set, framing, or payload syntax for the X21S.
Feedbacks
# Source documents Modbus error response pattern (function code + 0x80 + exception code).
- id: modbus_error
type: object
description: |
Error response = (original function code OR 0x80) + exception code byte.
Exception codes: 0x01 (function not supported / Modbus disabled), 0x02 (bad address/quantity).
Specific error function codes: 0x81 (FC01), 0x82 (FC02), 0x83 (FC03), 0x85 (FC05), 0x8F (FC15), 0x90 (FC16).
# --- HTTP state.xml/json tags (X-400 family; X21S subset UNRESOLVED) ---
- id: relay_state
type: enum
values: ["0", "1"]
description: 0=off (coil off), 1=on (coil energized)
- id: digital_input_state
type: enum
values: ["0", "1"]
description: 0=off (no voltage), 1=on (voltage applied)
- id: analog_input
type: number
description: Value of analog input X (engineering units)
- id: vin
type: number
description: Scaled internal Vin measurement
- id: register
type: number
description: Value of register X
- id: counter
type: number
description: Count value associated with input X
- id: on_time
type: number
description: Seconds input/relay was on since last coming on
- id: total_on_time
type: number
description: Total seconds input/relay has been on
- id: frequency
type: number
description: Frequency associated with input X
- id: utc_time
type: integer
description: Current UTC time, seconds since 1970-01-01
- id: timezone_offset
type: integer
description: Offset to apply to utcTime for local time
- id: serial_number
type: string
description: 00:00:00:00:00:00 device serial
- id: one_wire_sensor
type: string
description: "x.x = read error; 77.3 = value; 77.3 F = value with units (showUnits=1)"
# UNRESOLVED: which of the above tags apply to X21S specifically - source describes X-400 family generally
Variables
# Settable numeric parameters beyond discrete actions.
- name: register_value
type: number
range: "" # UNRESOLVED: register range not stated in source
description: Internal register settable via HTTP GET or Modbus FC16
- name: pulse_duration
type: integer
unit: seconds
description: Per-pulse override duration; does not change configured Pulse Duration
- name: endianness
type: enum
values: ["little-endian", "big-endian"]
description: Modbus floating-point byte order, configured in Advanced Network tab
# UNRESOLVED: default value not stated in source
Events
# Source documents unsolicited device-originated notifications.
- id: snmp_trap
description: |
Sent on relay state change, sensor threshold crossing, or Vin out-of-range.
Configured as actions in Conditional and Scheduled tasks.
- id: snmp_notification
description: |
SNMPv2c/v3 notification requiring acknowledgement; retries if manager does not respond.
- id: remote_services_state_push
description: |
When Remote Services is enabled and a connection is open, the device sends state.xml
on logic events with "send state" actions. Connection String includes static device info
plus user-defined string; expects 3-char "ACK" reply within 10 seconds or connection closes.
# UNRESOLVED: HTTP-level unsolicited events (if any) - source does not describe SSE, WebSocket, or async HTTP push.
Macros
# Multi-step sequences described explicitly in source.
# None documented in the refined source. Remove this section if not applicable.
# UNRESOLVED: no multi-step command sequences described in source
Safety
confirmation_required_for: []
interlocks: []
# Source notes:
# - Modbus/TCP is DISABLED whenever the User account is enabled (no password mechanism).
# - HTTP syslog.txt requires setup username/password.
# No safety interlocks or power-on sequencing described in source for X21S.
Notes
Source is the ControlByWeb "Integrating with ControlByWeb Devices" reference, covering the X-400 Series family. The X21S-specific subset of channels, Modbus addresses, and serial/RS-232 parameters is not enumerated; addresses must be looked up via the device's setup pages ("View Modbus Address Table" button under Advanced Network). Modbus TCP connections idle >50s time out; two TCP sockets available. HTTP Basic Auth (Base64 of name:password) is optional via User account; default credentials example shown in source are none:webrelay (Base64 bm9uZTp3ZWJyZWxheQ==). MQTT version 3.1.1, Sparkplug B supported. SNMP v1/v2c/v3 with default community strings webrelay. Cloud access via https://api.controlbyweb.cloud/{dat_url}/state.xml|.json. 32-bit float encoding per IEEE 754, register pairs must be read/written together.
Provenance
source_domains:
- controlbyweb.com
source_urls:
- https://controlbyweb.com/wp-content/uploads/2025/05/cbw-integration-and-protocols-manual.pdf
- https://controlbyweb.com/wp-content/uploads/2024/01/X-21s_manual_v1.0.pdf
- https://controlbyweb.com/support/cbw-integration-manual/
- https://controlbyweb.com/support/
retrieved_at: 2026-06-30T15:07:00.358Z
last_checked_at: 2026-07-07T11:12:33.163Z
Verification Summary
verdict: verified
checked_at: 2026-07-07T11:12:33.163Z
matched_actions: 21
action_count: 21
confidence: medium
summary: "All 21 spec actions match source documentation exactly; transport parameters verified; complete command coverage. (13 unresolved item(s) noted in Known Gaps.)"
Known Gaps
- "source does not enumerate power on/off commands for X21S (relay states control outputs, not device power)"
- "source does not describe input/output routing matrix for X21S"
- "Modbus pulse-relay function code variant ---"
- "RS-232/serial commands for X21S ---"
- "which of the above tags apply to X21S specifically - source describes X-400 family generally"
- "register range not stated in source"
- "default value not stated in source"
- "HTTP-level unsolicited events (if any) - source does not describe SSE, WebSocket, or async HTTP push."
- "no multi-step command sequences described in source"
- "X21S-specific serial/RS-232 framing, baud, parity, pinout"
- "X21S-specific relay/digital I/O count and Modbus address map"
- "firmware version compatibility range"
- "default HTTP port (80) is implied by examples but not explicitly stated as default"
From the AI4AV catalog (https://ai4av.net) · ODbL-1.0