ELX-MODBUS
A bridge between the Modbus bus and an MQTT broker
Polls Modbus devices over Ethernet and the RS-485 serial bus, decodes the raw registers into real values, publishes them to MQTT and writes commands back. Configured entirely in the browser — there are no configuration files to edit.
TCP and serial gateways
Connect over Ethernet — Modbus TCP or RTU over TCP — or through a local port such as /dev/ttyUSB0. Baud rate, parity, stop bits and inter-frame timing are all adjustable.
A library of ready devices
Templates built from the manufacturers' datasheets: registers, scaling, widgets and enumerations are already filled in. Adding a known device takes two clicks instead of an afternoon.
Registers, exactly
Holding, Input, Coil and Discrete; integers, floats and strings; word and byte order; bit masks; multiplier and offset. Any single register can be switched off without touching the rest.
A live dashboard
Device tiles with values updating in place, toggles, sliders and input fields. Dragging a tile also changes the polling order, because the order on screen is the order on the bus.
A protocol terminal
The raw exchange in hexadecimal, with the duration and the error of every request. This is the screen that turns an unknown device into a working one.
One package, no dependencies
A single .deb installs a systemd service on Debian, Ubuntu and Raspberry Pi OS. Builds for amd64, arm64 and armhf; nothing else to install.
Screenshots
The problem it solves
Industrial equipment speaks Modbus — a protocol from 1979 that became the default for sensors, relays, meters and drives. Home and building automation speaks MQTT. The two do not meet on their own, and the usual remedy is a pile of scripts, one per device, each of which stops working when somebody changes a register address.
ELX-MODBUS is that pile of scripts replaced by one service. It polls the bus, converts raw registers into named values, publishes them to your broker, and accepts commands coming back. Everything is configured in a browser.
Modbus devices
Sensors, relays, drives, meters — on RS-485 or Ethernet
ELX-MODBUS
Polling, decoding, publishing, writing back
MQTT broker
Home Assistant, Node-RED, OpenHAB, your own code
Three steps to data in the broker
- Add a gateway. Describe the connection to the bus: the address of an RTU-over-TCP gateway, or the serial port with its baud rate and parity.
- Add a device. Pick a template from the library or build your own register map, then set the slave address and the MQTT prefix.
- Point it at your broker. Enter the address and switch publishing on. Values start flowing into topics immediately, and commands start flowing back.
How values become topics
A raw register becomes a value through value = raw × multiplier + offset, taking the data type, the word and byte order and any bit mask into account. The result is published to {base}/{prefix}/{key}.
home/livingroom/ac/temp → 24.5 (published every poll)
home/livingroom/ac/set_temp ← 22.0 (command topic, written to the register)
home/livingroom/ac/mode → cooling
Read-write channels get a command topic — {topic}/set by default. A value sent there jumps to the front of the polling queue and is written straight away, so control feels immediate rather than delayed by a polling cycle.
The device library
Templates carry the register map, the scaling and the widget already set up from the datasheet. Among them:
| Group | Devices |
|---|---|
| Climate | Air-conditioner adapters over Modbus, boiler controllers with OpenTherm and eBus, ventilation units |
| Relays | Six- and sixteen-channel relay modules with open/close command registers |
| Sensors | Temperature and humidity sensors, multi-sensors, 1-Wire probes |
| Light | Dimmers, LED controllers, DALI gateways |
| Analogue | 0–10 V and 4–20 mA output modules |
| Anything else | A blank custom device where you enter the registers yourself |
At a glance
- Transports
- Modbus TCP, RTU over TCP, RTU over a serial port
- Register types
- Holding, Input, Coil, Discrete
- Data types
- int, float, string, bit masks, word and byte order
- Operating systems
- Debian, Ubuntu, Raspberry Pi OS
- Architectures
- amd64, arm64, armhf
- Configuration
- Web interface; state in SQLite, exportable as JSON
- Web interface port
- 8080 by default
- External dependencies
- None
Frequently asked questions
Which Modbus transports are supported?
/dev/ttyUSB0 or /dev/ttyS1, with configurable baud rate, parity and stop bits.Do I have to edit configuration files?
Can I control devices from MQTT?
{topic}/set by default. A value published there is written to the register, and commands take priority in the polling queue.