# Modbus TCP
Polls **Modbus TCP** devices — the lingua franca of energy meters, remote I/O, and
countless industrial devices. All four register areas are supported, with
configurable endianness and register order for multi-register values.
| | |
|---|---|
| Connection string | `modbus.tcp://HOST:PORT` (port defaults to `502`) |
| Reads | ✔ (poll) |
| Writes | — |
| Subscriptions | — |
## Device options
| Key | Values | Default | Meaning |
|---|---|---|---|
| `unitId` | int | `1` | Modbus unit / slave id. |
| `endianness` | `BE`, `LE` | `BE` | Byte endianness. |
| `byteorder` | `R0R1R2R3`, `R3R2R1R0`, `R2R3R0R1`, `R1R0R3R2` | `R0R1R2R3` | Register/word order for values spanning multiple registers. |
## Address format
```
REGISTER::TYPE::START::LENGTH[::BIT]
```
- `REGISTER` — `CO` (coils), `CI` (discrete inputs), `DI`/`IR` (input registers),
`HR` (holding registers).
- `TYPE` — `string`, `bytes`, `bits`, `16int`, `16uint`, `16float`, `32int`,
`32uint`, `32float`, `64int`, `64uint`, `64float`.
- `START` / `LENGTH` — register position and count (`0` → default length of the type).
- `BIT` — bit position, required when `TYPE = bits`.
Examples:
| Address | Reads |
|---|---|
| `HR::16uint::0::1` | Holding register 0 as unsigned 16-bit integer. |
| `HR::32float::100::2` | Registers 100–101 as 32-bit float. |
| `CO::bits::0::1::3` | Bit 3 of coil block 0 as Boolean. |
| `IR::16int::20::1` | Input register 20 as signed 16-bit integer. |
## Example configuration
```json
{
"devices": [
{
"objectId": "meter1",
"name": "EnergyMeter",
"connectionString": "modbus.tcp://10.0.0.5:502",
"interval": 2000,
"enabled": true,
"options": { "unitId": 1, "endianness": "BE", "byteorder": "R0R1R2R3" },
"extraOptions": { "host": "broker:1883", "clientId": "openconnect" }
}
],
"items": [
{
"objectId": "power",
"DeviceID": { "objectId": "meter1" },
"address": "HR::32float::100::2",
"label": "Active power",
"type": "Number",
"unit": "kW",
"source": { "tag": "hall1/meter" },
"enabled": true,
"onChange": false,
"extraOptions": {}
}
]
}
```