Modbus#
The Modbus service manages Modbus TCP polling clients for devices and groups. Each client connects to a Modbus TCP device on a configured schedule, reads the specified registers or coils, formats the result as a JSON payload, and publishes it as a platform message on behalf of the associated device.
On startup, the service loads all persisted clients and begins scheduling polls according to each client's frequency setting.
How it works#
- You create a Modbus client linked to a device, specifying the target device address, slave ID, function code, poll schedule, and the data fields to read.
- On each scheduled interval, the service connects to the Modbus TCP device, reads the configured registers or coils, and decodes the raw values according to the data field definitions.
- The result is published to the platform as a JSON object keyed by field name, for example:
{"temperature": 23.5, "humidity": 61, "status": true}
This message is then available to the rest of the platform — including storage, rules, and webhooks — just like any other device message.
Function codes#
| Function code | Modbus FC | Description |
|---|---|---|
ReadCoils |
01 | Read output coils (digital output) |
ReadDiscreteInputs |
02 | Read discrete inputs (digital input) |
ReadHoldingRegisters |
03 | Read holding registers (analog R/W) |
ReadInputRegisters |
04 | Read input registers (analog R/O) |
Poll schedule#
The scheduler object controls when and how often the client polls the device.
| Field | Description |
|---|---|
frequency |
Poll frequency: once, minutely, hourly, daily, or weekly |
time_zone |
IANA timezone name (e.g. Europe/Berlin, UTC) |
date_time |
Date and time in YYYY-MM-DD HH:MM format. Required when frequency is once; ignored otherwise |
minute |
Minute interval. Used with minutely frequency |
hour |
Hour interval. Used with hourly frequency |
day_time |
Time of day in HH:MM format. Used with daily frequency |
week |
Weekly schedule: {"days": [...], "time": "HH:MM"}. Used with weekly frequency |
Data fields#
Each entry in data_fields describes one register or coil to read and how to decode it.
| Field | Description |
|---|---|
name |
Field name used as the JSON key in the published message |
address |
Starting register or coil address |
type |
Data type: bool, int16, uint16, int32, uint32, float32, or string |
byte_order |
Word order for multi-byte values: ABCD (big-endian), DCBA (little-endian), CDAB, or BADC |
unit |
Optional unit label (e.g. °C, %, bar) |
scale |
Optional multiplier applied to the raw numeric value before publishing |
length |
Register count. Calculated automatically from type for numeric types; set manually for string only |
Managing clients#
Modbus clients are registered per device. Multiple clients can be registered for a single device.
Create clients#
curl -s -S -i -X POST \
-H "Authorization: Bearer <user_token>" \
-H "Content-Type: application/json" \
-d '[
{
"name": "Boiler sensor",
"ip_address": "192.168.1.100",
"port": "502",
"slave_id": 1,
"function_code": "ReadHoldingRegisters",
"scheduler": {"frequency": "minutely", "minute": 5},
"data_fields": [
{"name": "temperature", "address": 100, "type": "float32", "byte_order": "ABCD", "unit": "°C"},
{"name": "pressure", "address": 102, "type": "uint16", "unit": "bar"}
]
}
]' \
https://localhost/svcmodbus/things/<thing_id>/clients
Response
{
"clients": [
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"name": "Boiler sensor",
"ip_address": "192.168.1.100",
"port": "502",
"slave_id": 1,
"function_code": "ReadHoldingRegisters",
"scheduler": {"frequency": "minutely", "minute": 5},
"data_fields": [
{"name": "temperature", "address": 100, "type": "float32", "byte_order": "ABCD", "unit": "°C"},
{"name": "pressure", "address": 102, "type": "uint16", "unit": "bar"}
],
"thing_id": "111e4567-e89b-12d3-a456-426614174000",
"group_id": "211e4567-e89b-12d3-a456-426614174000"
}
]
}
List clients#
# All clients for a specific device
curl -s -S -i \
-H "Authorization: Bearer <user_token>" \
https://localhost/svcmodbus/things/<thing_id>/clients
# All clients for a group
curl -s -S -i \
-H "Authorization: Bearer <user_token>" \
https://localhost/svcmodbus/groups/<group_id>/clients
View a client#
curl -s -S -i \
-H "Authorization: Bearer <user_token>" \
https://localhost/svcmodbus/clients/<client_id>
Update a client#
curl -s -S -i -X PUT \
-H "Authorization: Bearer <user_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Boiler sensor",
"ip_address": "192.168.1.100",
"port": "502",
"slave_id": 1,
"function_code": "ReadHoldingRegisters",
"scheduler": {"frequency": "hourly", "hour": 1},
"data_fields": [
{"name": "temperature", "address": 100, "type": "float32", "unit": "°C"}
]
}' \
https://localhost/svcmodbus/clients/<client_id>
Remove clients#
curl -s -S -i -X PATCH \
-H "Authorization: Bearer <user_token>" \
-H "Content-Type: application/json" \
-d '{"client_ids": ["<client_id>"]}' \
https://localhost/svcmodbus/clients
For the full API reference, see the API documentation.