Modbus Monitoring
NetXMS supports monitoring industrial devices and equipment using the Modbus protocol. This enables integration with PLCs, sensors, building automation systems, power meters, and other industrial equipment that communicate via Modbus TCP.
Overview
Modbus is a communication protocol widely used in industrial automation. NetXMS supports Modbus TCP — Modbus over TCP/IP networks. Serial Modbus (RTU) devices are not supported directly; they must be reachable through a Modbus TCP gateway.
Data is collected from Modbus registers and coils, which can be mapped to DCIs for monitoring, trending, and alerting.
Modbus Concepts
Modbus organizes data into four register types:
| Type | Address Range | Description |
|---|---|---|
Coils |
00001–09999 |
Single-bit read/write values (digital outputs) |
Discrete Inputs |
10001–19999 |
Single-bit read-only values (digital inputs) |
Input Registers |
30001–39999 |
16-bit read-only values (analog inputs) |
Holding Registers |
40001–49999 |
16-bit read/write values (configuration, setpoints) |
Each register holds a 16-bit value. Multi-register values (32-bit integers, floats) are stored across consecutive registers.
Configuration
Node Configuration
To enable Modbus monitoring on a node:
-
Open the node properties in the management client
-
Go to the dedicated Modbus property page
-
Configure:
-
Modbus TCP port (default: 502)
-
Unit ID (slave address, default: 255)
-
Proxy (optional agent that performs Modbus communication on behalf of the server)
-
Creating Modbus DCIs
-
Create a new DCI on the Modbus-enabled node
-
Set the origin to Modbus
-
In the metric field, specify the register address using the Modbus address notation
Address Notation
NetXMS uses the following Modbus address notation in DCI metric fields:
[[unit-id:]register-type:]address[|conversion]
Components:
| Component | Description |
|---|---|
|
Optional Modbus unit (slave) ID, 0-255 for server-side DCIs. If omitted, uses the node’s default unit ID. Must be followed by a register type when present. Note that agent proxy metrics (see below) enforce a 1-255 range. |
|
Register type (see table below). Default: |
|
Register address, 0-65535. Supports hex notation with |
|
Optional data type conversion, separated by pipe |
Register type names:
| Name | Type | Description |
|---|---|---|
|
Holding Register |
Read/write register (16-bit), default |
|
Input Register |
Read-only analog input (16-bit) |
|
Coil |
Read/write digital output (bit value) |
|
Discrete Input |
Read-only digital input (bit value) |
Data type conversions:
| Conversion | Description |
|---|---|
|
16-bit unsigned integer, 1 register (default) |
|
16-bit signed integer, 1 register |
|
32-bit unsigned integer, 2 registers |
|
32-bit signed integer, 2 registers |
|
64-bit unsigned integer, 4 registers |
|
64-bit signed integer, 4 registers |
|
32-bit IEEE 754 float, ABCD byte order, 2 registers |
|
32-bit IEEE 754 float, CDAB byte order, 2 registers |
|
32-bit IEEE 754 float, BADC byte order, 2 registers |
|
32-bit IEEE 754 float, DCBA byte order, 2 registers |
|
64-bit IEEE 754 double, big-endian, 4 registers |
|
64-bit IEEE 754 double, little-endian, 4 registers |
|
String of N characters, reads (N+1)/2 registers |
|
String of N characters with codepage CP |
Examples
Read a holding register as a 32-bit float with ABCD byte order (e.g., temperature sensor):
hold:100|float
Read input register 8 as 16-bit unsigned integer (default conversion):
input:8
Read a coil status (on/off):
coil:100
Read from unit 2, holding register as 32-bit signed integer:
2:hold:1000|int32
Read a 32-character string from holding register:
hold:2000|string-32
Read a float with CDAB byte order (for devices with swapped word order):
hold:200|float-cdab
Read a hex-addressed register:
0x2A|int16
Byte Order
The byte order for multi-register values is specified directly in the conversion suffix (e.g., float-abcd, float-cdab, float-badc, float-dcba).
This allows per-DCI byte order control.
Common byte orders:
-
ABCD — most significant byte first (Modbus standard, default for
float) -
CDAB — word-swapped (common in many devices)
-
BADC — byte-swapped within words
-
DCBA — fully reversed byte order
If values appear incorrect (very large or very small numbers), try a different byte order suffix to match your device’s format.
Agent Proxy Mode
When using an agent as a Modbus proxy, the agent exposes these metrics directly:
| Metric | Description |
|---|---|
|
Read holding register via agent proxy |
|
Read input register via agent proxy |
|
Read coil value (0 or 1) via agent proxy |
|
Read discrete input (0 or 1) via agent proxy |
|
Modbus TCP connection status via agent proxy |
In these metrics unit-id must be in the 1-255 range (unlike server-side DCI addresses, which accept 0-255).
Enable Modbus proxy mode in the agent configuration:
EnableModbusProxy = yes
The Modbus.DeviceIdentification(ip,port,unit-id[,useSymbolicNames]) list returns device identification objects (vendor, product, revision, etc.).
The optional fourth boolean argument (default: true) selects between symbolic names (VendorName=…) and numeric object IDs in the output.
Polling Considerations
-
Modbus devices often have limited connection capacity — avoid excessive polling
-
Use appropriate polling intervals (30–300 seconds is common for industrial metrics)
-
Group registers in consecutive address ranges when possible for efficient reading
-
Some devices limit the number of concurrent Modbus TCP connections
| Incorrect Modbus configuration can affect device operation. Verify register addresses and data types against the device’s Modbus register map before creating DCIs. |