Summary
The X-320 is an industrial I/O monitoring and control module with two configurable digital I/Os, two pulse counters, one frequency input, four analog inputs, and up to six digital temperature/humidity sensor inputs. This spec covers control over TCP/IP via an HTTP/XML interface, Modbus/TCP, and SNMP. A built-in BASIC interpreter allows user-defined automation scripts.
Transport
# The X-320 supports three transport interfaces:
# - HTTP/XML GET requests (default port 80, configurable 0-65535)
# - Modbus/TCP (default port 502, configurable 0-65535)
# - SNMP (default port 161, trap port 162)
#
# Base URL is derived from the device's IP address (default 192.168.1.2).
# Auth on the Control Page is optional (HTTP Basic, Base64 of "none:password");
# Modbus/TCP has no auth (Modbus disabled when Control Password enabled).
protocols:
- tcp
addressing:
port: 80
auth:
type: basic # optional Control Password; Modbus disabled when enabled
Traits
# - powerable (relay on/off and pulse commands present)
# - routable (digital I/O can be configured as input or output)
# - queryable (state.xml, eventX.xml, diagnostics.xml read queries)
# - levelable (pulse duration parameter)
# - scriptable (onboard BASIC interpreter for custom automation)
Actions
# All XML/GET request commands documented in source. relayXState covers
# Output 1 (relay1State) and Output 2 (relay2State).
- id: output1_on
label: Turn Output 1 ON
kind: action
command: "GET /state.xml?relay1State=1"
params: []
- id: output1_off
label: Turn Output 1 OFF
kind: action
command: "GET /state.xml?relay1State=0"
params: []
- id: output2_on
label: Turn Output 2 ON
kind: action
command: "GET /state.xml?relay2State=1"
params: []
- id: output2_off
label: Turn Output 2 OFF
kind: action
command: "GET /state.xml?relay2State=0"
params: []
- id: output1_pulse_default
label: Pulse Output 1 (preset duration)
kind: action
command: "GET /state.xml?relay1State=2"
params: []
- id: output2_pulse_default
label: Pulse Output 2 (preset duration)
kind: action
command: "GET /state.xml?relay2State=2"
params: []
- id: output1_pulse_custom
label: Pulse Output 1 (custom duration)
kind: action
command: "GET /state.xml?relay1State=2&pulseTime1={seconds}"
params:
- name: seconds
type: number
description: Pulse duration in seconds
- id: output2_pulse_custom
label: Pulse Output 2 (custom duration)
kind: action
command: "GET /state.xml?relay2State=2&pulseTime2={seconds}"
params:
- name: seconds
type: number
description: Pulse duration in seconds
- id: output1_on_noreply
label: Turn Output 1 ON (no XML reply)
kind: action
command: "GET /state.xml?relay1State=1&noReply=1"
params: []
- id: output1_off_noreply
label: Turn Output 1 OFF (no XML reply)
kind: action
command: "GET /state.xml?relay1State=0&noReply=1"
params: []
- id: set_counter1
label: Set Counter 1
kind: action
command: "GET /state.xml?count1={value}"
params:
- name: value
type: integer
description: Counter value to set
- id: get_state_xml
label: Read state.xml (all I/O, counters, sensors)
kind: query
command: "GET /state.xml"
params: []
- id: get_event_xml
label: Read event XML (event 0-99)
kind: query
command: "GET /event{n}.xml"
params:
- name: n
type: integer
description: Event number 0-99
- id: get_diagnostics_xml
label: Read diagnostics.xml
kind: query
command: "GET /diagnostics.xml"
params: []
- id: get_log_txt
label: Read data log file
kind: query
command: "GET /log.txt"
params: []
- id: erase_log_txt
label: Erase data log file
kind: action
command: "GET /log.txt?erase=1"
params: []
- id: get_syslog_txt
label: Read system log file
kind: query
command: "GET /syslog.txt"
params: []
- id: erase_syslog_txt
label: Erase system log file
kind: action
command: "GET /syslog.txt?erase=1"
params: []
- id: clear_rtc_powerup_flag
label: Clear RTC power-up flag
kind: action
command: "GET /diagnostics.xml?memoryPowerUpFlag=0"
params: []
- id: clear_device_powerup_flag
label: Clear device power-up flag
kind: action
command: "GET /diagnostics.xml?devicePowerUpFlag=0"
params: []
- id: clear_power_loss_counter
label: Clear power loss counter
kind: action
command: "GET /diagnostics.xml?powerLossCounter=0"
params: []
- id: configure_event
label: Configure scheduled event
kind: action
command: "GET /eventSetup.srv?e{n}={epoch};{period};{units};{count};{sched};{action};{pulse};0;{desc};{days};{actnum};"
params:
- name: n
type: integer
description: Event number 0-99
- name: epoch
type: integer
description: Start time in seconds since 1970-01-01
- name: period
type: integer
description: Period value
- name: units
type: integer
description: Period units (0=S, 1=M, 2=H, 3=D, 4=W)
- name: count
type: integer
description: Number of occurrences (0=continuous)
- name: sched
type: integer
description: Schedule number 0-4
- name: action
type: integer
description: "0=No Action, 1=On, 2=Off, 3=Pulse, 4=Toggle, 5=Change sched, 7=Set extVar0, 8=Clear extVar0"
- name: pulse
type: number
description: Pulse duration
- name: desc
type: string
description: Description up to 20 chars
- name: days
type: integer
description: "Days-of-week bitmask (Bit0=Sat, Bit6=Sun); 127=all days"
- name: actnum
type: integer
description: "Output/schedule bitmask (Bit0=Output1/Sched1)"
# --- Modbus/TCP actions ---
- id: modbus_read_coils
label: Modbus Read Coils (Outputs 1-2)
kind: query
command: "Modbus FC01 addr=0x0000 qty=1-2"
params: []
- id: modbus_read_discrete_inputs
label: Modbus Read Discrete Inputs (1-6)
kind: query
command: "Modbus FC02 addr=0x0000-0x0005 qty=1-6"
params: []
- id: modbus_read_analog_inputs
label: Modbus Read Analog Inputs (1-4)
kind: query
command: "Modbus FC03 addr=0x0010-0x0016 qty=2 step=2"
params: []
- id: modbus_read_sensors
label: Modbus Read Sensors (1-6)
kind: query
command: "Modbus FC03 addr=0x0110-0x011A qty=2 step=2"
params: []
- id: modbus_read_counters
label: Modbus Read Counters (1-2)
kind: query
command: "Modbus FC03 addr=0x0210-0x0212 qty=2 step=2"
params: []
- id: modbus_read_frequency
label: Modbus Read Frequency Input
kind: query
command: "Modbus FC03 addr=0x0214 qty=2"
params: []
- id: modbus_read_pulse_rate
label: Modbus Read Pulse Rate (1-2)
kind: query
command: "Modbus FC03 addr=0x0216-0x0218 qty=2 step=2"
params: []
- id: modbus_read_extvars
label: Modbus Read Extvars (0-3)
kind: query
command: "Modbus FC03 addr=0x0410-0x0416 qty=2 step=2"
params: []
- id: modbus_write_single_coil
label: Modbus Write Single Coil (Output 1-2)
kind: action
command: "Modbus FC05 addr=0x0000-0x0001 value=0x00|0xFF"
params: []
- id: modbus_write_multiple_coils
label: Modbus Write Multiple Coils
kind: action
command: "Modbus FC15 addr=0x0000-0x0001 qty=1-2 value=0x00-0x03"
params: []
- id: modbus_pulse_coils
label: Modbus Pulse Outputs
kind: action
command: "Modbus FC16 addr=0x0310-0x0312 value=float_seconds"
params:
- name: value
type: number
description: "Pulse time in seconds (0.1-86400, IEEE754 float)"
- id: modbus_set_counter
label: Modbus Set Counter (1-2)
kind: action
command: "Modbus FC16 addr=0x0210-0x0212 value=uint32"
params: []
- id: modbus_write_extvars
label: Modbus Write Extvars (0-3)
kind: action
command: "Modbus FC16 addr=0x0410-0x0416 value=float32"
params: []
# --- SNMP set actions ---
- id: snmp_set_output1
label: SNMP Set Output 1
kind: action
command: "SNMP SET x320OutputOne=0|1|2"
params: []
- id: snmp_set_output2
label: SNMP Set Output 2
kind: action
command: "SNMP SET x320OutputTwo=0|1|2"
params: []
# --- Remote relay control via XML ---
- id: rmt_relay1_on
label: Remote Relay 1 ON (BASIC)
kind: action
command: "LET rmt_relay1 = 1"
params: []
- id: rmt_relay1_off
label: Remote Relay 1 OFF (BASIC)
kind: action
command: "LET rmt_relay1 = 0"
params: []
- id: rmt_relay1_pulse
label: Remote Relay 1 pulse (BASIC)
kind: action
command: "LET rmt_relay1 = 2"
params: []
- id: rmt_relay1_toggle
label: Remote Relay 1 toggle (BASIC)
kind: action
command: "LET rmt_relay1 = 5"
params: []
- id: rmt_relay2_on
label: Remote Relay 2 ON (BASIC)
kind: action
command: "LET rmt_relay2 = 1"
params: []
- id: rmt_relay2_off
label: Remote Relay 2 OFF (BASIC)
kind: action
command: "LET rmt_relay2 = 0"
params: []
- id: rmt_relay2_pulse
label: Remote Relay 2 pulse (BASIC)
kind: action
command: "LET rmt_relay2 = 2"
params: []
- id: rmt_relay2_toggle
label: Remote Relay 2 toggle (BASIC)
kind: action
command: "LET rmt_relay2 = 5"
params: []
- id: rmt_relay3_on
label: Remote Relay 3 ON (BASIC)
kind: action
command: "LET rmt_relay3 = 1"
params: []
- id: rmt_relay3_off
label: Remote Relay 3 OFF (BASIC)
kind: action
command: "LET rmt_relay3 = 0"
params: []
# --- External Variables (XML + BASIC accessible) ---
- id: set_extvar1
label: Set ExtVar 1
kind: action
command: "GET /state.xml?extvar1={value}"
params:
- name: value
type: number
description: Float value
# --- Logging config (setup) ---
- id: load_basic_script
label: Upload BASIC script (max 2 KB)
kind: action
command: "POST /upload (script .txt file, max 2048 bytes)"
params: []
Feedbacks
# state.xml fields observable via GET /state.xml
- id: io1_state
type: enum
values: [0, 1]
description: Digital I/O 1 state (0=OFF, 1=ON)
- id: io2_state
type: enum
values: [0, 1]
description: Digital I/O 2 state (0=OFF, 1=ON)
- id: hightime1
type: number
description: Seconds Input 1 was last held ON
- id: hightime2
type: number
description: Seconds Input 2 was last held ON
- id: raw_count1
type: integer
description: Pulse counter 1 OFF→ON transitions
- id: count1
type: number
description: Scaled counter 1 value (raw * multiplier + offset)
- id: raw_count2
type: integer
description: Pulse counter 2 OFF→ON transitions
- id: count2
type: number
description: Scaled counter 2 value
- id: raw_rate1
type: number
description: Raw pulse rate 1
- id: rate1
type: number
description: Scaled pulse rate 1
- id: raw_rate2
type: number
description: Raw pulse rate 2
- id: rate2
type: number
description: Scaled pulse rate 2
- id: raw_frequency
type: number
description: Frequency input raw Hz
- id: frequency
type: number
description: Scaled frequency input
- id: freq_alrm
type: enum
values: [0, 1, 2]
description: Frequency alarm state (0=Normal, 1=Alarm1, 2=Alarm2)
- id: an1_state
type: number
description: Scaled analog input 1
- id: an2_state
type: number
description: Scaled analog input 2
- id: an3_state
type: number
description: Scaled analog input 3
- id: an4_state
type: number
description: Scaled analog input 4
- id: an1_alrm
type: enum
values: [0, 1, 2]
- id: an2_alrm
type: enum
values: [0, 1, 2]
- id: an3_alrm
type: enum
values: [0, 1, 2]
- id: an4_alrm
type: enum
values: [0, 1, 2]
- id: units
type: enum
values: [F, C]
description: Temperature units
- id: sensor1_temp
type: string
description: Sensor 1 reading (x.x=not attached, 77.3=temperature, H24.9=humidity)
- id: sensor2_temp
type: string
- id: sensor3_temp
type: string
- id: sensor4_temp
type: string
- id: sensor5_temp
type: string
- id: sensor6_temp
type: string
- id: s1_alrm
type: enum
values: [0, 1, 2]
- id: s2_alrm
type: enum
values: [0, 1, 2]
- id: s3_alrm
type: enum
values: [0, 1, 2]
- id: s4_alrm
type: enum
values: [0, 1, 2]
- id: s5_alrm
type: enum
values: [0, 1, 2]
- id: s6_alrm
type: enum
values: [0, 1, 2]
- id: extvar0
type: number
- id: extvar1
type: number
- id: extvar2
type: number
- id: extvar3
type: number
- id: serial_number
type: string
description: MAC-derived serial number (00:0C:C8:xx:xx:xx)
- id: time_epoch
type: integer
description: Unix epoch seconds
# diagnostics.xml fields
- id: internal_temp
type: number
description: Internal device temperature
- id: vin
type: number
description: DC voltage on Vin+/Vin-
- id: internal_6volt
type: number
description: Internal 6V supply
- id: memory_powerup_flag
type: enum
values: [0, 1]
description: RTC power-loss flag
- id: device_powerup_flag
type: enum
values: [0, 1]
description: Device power-loss flag
- id: power_loss_counter
type: integer
description: Count of main power losses
# event0.xml fields (representative; event 0-99)
- id: event_active
type: enum
values: [yes, no]
- id: event_current_time
type: string
- id: event_next_event
type: string
- id: event_period
type: string
description: "Period with unit suffix (s/m/h/d/w); 0=disabled"
- id: event_count
type: integer
description: Remaining occurrences (0=always on if active)
- id: event_relay
type: integer
description: Output 1 or 2
- id: event_action
type: string
description: "turn relay(s) on, off, pulse, toggle, set extVar0, clear extVar0, change schedules"
- id: event_pulse_duration
type: string
Variables
# External Variables are settable parameters exposed via XML and BASIC.
- id: extvar0
type: float
range: null # UNRESOLVED: full range not stated; used as script-accessible numeric
description: "External variable 0, accessible via XML and BASIC scripts"
- id: extvar1
type: float
range: null # UNRESOLVED: full range not stated
description: "External variable 1, settable via /state.xml?extvar1="
- id: extvar2
type: float
range: null # UNRESOLVED: full range not stated
description: "External variable 2"
- id: extvar3
type: float
range: null # UNRESOLVED: full range not stated
description: "External variable 3"
- id: pulse_time1
type: number
description: One-shot pulse duration for Output 1 (seconds)
- id: pulse_time2
type: number
description: One-shot pulse duration for Output 2 (seconds)
Events
# SNMP Traps sent unsolicited from the X-320.
# Community string = Control Password (or none if password disabled).
- id: trap_output1_change
oid: 1.3.6.1.4.1.30556.75 # UNRESOLVED: full OID prefix not given in source
description: Relay 1 state change (0=OFF, 1=ON)
- id: trap_output2_change
oid: 1.3.6.1.4.1.30556.76 # UNRESOLVED: full OID prefix not given in source
description: Relay 2 state change
- id: trap_input1_change
oid: 1.3.6.1.4.1.30556.95
description: Input 1 state change
- id: trap_input2_change
oid: 1.3.6.1.4.1.30556.96
description: Input 2 state change
- id: trap_input3_change
oid: 1.3.6.1.4.1.30556.97
- id: trap_input4_change
oid: 1.3.6.1.4.1.30556.98
- id: trap_input5_change
oid: 1.3.6.1.4.1.30556.99
- id: trap_input6_change
oid: 1.3.6.1.4.1.30556.100
- id: trap_analog1_alarm
oid: 1.3.6.1.4.1.30556.120
description: Analog 1 alarm (xxx.x)
- id: trap_analog2_alarm
oid: 1.3.6.1.4.1.30556.121
- id: trap_analog3_alarm
oid: 1.3.6.1.4.1.30556.122
- id: trap_analog4_alarm
oid: 1.3.6.1.4.1.30556.123
- id: trap_frequency1_alarm
oid: 1.3.6.1.4.1.30556.150
description: Frequency 1 alarm (xxx.xxxxx)
- id: trap_sensor1_alarm
oid: 1.3.6.1.4.1.30556.65
description: Sensor 1 alarm (xx.x)
- id: trap_sensor2_alarm
oid: 1.3.6.1.4.1.30556.66
- id: trap_sensor3_alarm
oid: 1.3.6.1.4.1.30556.67
- id: trap_sensor4_alarm
oid: 1.3.6.1.4.1.30556.68
- id: trap_sensor5_alarm
oid: 1.3.6.1.4.1.30556.69
- id: trap_sensor6_alarm
oid: 1.3.6.1.4.1.30556.70
Macros
# BASIC script statements documented in source Appendix G.
- id: basic_let
description: "LET <var> = <expr> - assign variable"
- id: basic_if_then
description: "IF <var> <op> <expr> THEN ... ELSE ... END IF"
- id: basic_for
description: "FOR <var> = <expr> TO <expr> ... NEXT <var>"
- id: basic_do_while
description: "DO WHILE <var> <op> <expr> ... LOOP"
- id: basic_log
description: "LOG - log per Logging setup"
- id: basic_email
description: "EMAIL [relayX|inputX|tempX] - send status email"
- id: basic_call
description: "CALL <subname>"
- id: basic_sub
description: "SUB <name> ... END SUB (follows END statement)"
- id: basic_print
description: "PRINT - PC interpreter only (not supported on device)"
Safety
confirmation_required_for:
- remote_relay_control # source warns remote relay states cannot be read; not for safety-critical use
interlocks:
- modbus_disabled_when_control_password_enabled # Modbus cannot carry passwords
- diagnostics_xml_no_password_required # source states diagnostics.xml requests do not require a password
# UNRESOLVED: voltage/current ratings not stated in source; max supply voltage "DO NOT EXCEED" referenced on pinout (9-28 VDC for X-320-I, 5 VDC for X-320-POE) - populate as safety constraints if confirmed.
Notes
- Default HTTP port is 80; Modbus default is 502; both configurable 0–65535 in setup. Source recommends ports >8000 to avoid conflicts.
- Default IP 192.168.1.2, subnet 255.255.255.0, gateway 192.168.1.1.
- Control Password is independent of Setup Password; default for both is
webrelay. Setup username isadmin. - HTTP Basic auth header is Base64 of
none:<password>for Control Page access. - Modbus TCP uses IEEE 754 float (little- or big-endian per setting); sensor addresses/registers must be even.
- Pulse via Modbus FC16 range: 0.1 to 86400 seconds (clamped). New commands before pulse expires cancel it.
- Remote Services: device initiates outgoing TCP to a server (default port 8000); ideal for installations without router forwarding.
- Power-cycle required after Network tab changes; remote services apply immediately.
- Logging reduces Pulse Counter max rate to 25 Hz when enabled; Frequency >95 kHz affected by high logging rate.
- BASIC script limit: 2 KB (1900 bytes reserved for scripts per source memory note).
Provenance
source_domains:
- controlbyweb.com
source_urls:
- https://controlbyweb.com/wp-content/uploads/2024/01/X-320_um_v1.5.pdf
- https://controlbyweb.com/legacy/x320/
- https://www.controlbyweb.com
retrieved_at: 2026-06-30T14:54:35.269Z
last_checked_at: 2026-07-07T11:14:47.648Z
Verification Summary
verdict: verified
checked_at: 2026-07-07T11:14:47.648Z
matched_actions: 49
action_count: 49
confidence: medium
summary: "All 49 spec actions confirmed verbatim in source across XML/GET, Modbus/TCP, SNMP, and BASIC protocol sections; transport port 80 and HTTP Basic auth supported. (6 unresolved item(s) noted in Known Gaps.)"
Known Gaps
- "list any major gaps here"
- "full range not stated; used as script-accessible numeric"
- "full range not stated"
- "full OID prefix not given in source"
- "voltage/current ratings not stated in source; max supply voltage \"DO NOT EXCEED\" referenced on pinout (9-28 VDC for X-320-I, 5 VDC for X-320-POE) - populate as safety constraints if confirmed."
- "full SNMP enterprise OID prefix for Xytronix not stated in source excerpt; only relative identifiers (X320.65 etc.) given. Firmware version not stated. Analog voltage ranges (V in single-ended/differential) not stated. Full event0.xml–event99.xml range enumerated only as pattern."
From the AI4AV catalog (https://ai4av.net) · ODbL-1.0