Crates.io | modbus-mqtt |
lib.rs | modbus-mqtt |
version | 0.3.0 |
source | src |
created_at | 2022-08-30 07:05:34.119583 |
updated_at | 2024-07-12 04:46:36.75463 |
description | A bridge between Modbus devices and MQTT |
homepage | https://github.com/bjeanes/modbus-mqtt/tree/main/modbus-mqtt |
repository | https://github.com/bjeanes/modbus-mqtt |
max_upload_size | |
id | 654993 |
size | 132,768 |
A bridge between Modbus devices and MQTT.
It is early days, but the plan is:
NOTE: For the time being, this does not support MQTTv5.
For now, cargo install
is the easiest way to install. Either run it in a checkout for the latest development version, or run cargo install modbus-mqtt
to install the latest release version.
If you don't want to set up the Rust toolchain, you can likely found built binaries as build artifacts in the GitHub Actions tab above.
$ docker run -it --rm bjeanes/modbus-mqtt:edge --help
Tags:
v#
, v#.#
, v#.#.#
- semver releases (major.minor.patch
)latest
- corresponds to most recently semver-tagged buildedge
- latest buildable branch from main
, likely unstable*-alpine
- alpine versions of aboveStart the binary, passing in the URL to your MQTT server, including any credentials:
$ modbus-mqtt mqtt://$MQTT_HOST[:$MQTT_PORT]/[$CUSTOM_MODBUS_TOPIC]
The supported protocols are currently just tcp://
/mqtt://
, but with intent to support: mqtts://
, ssl://
/tls://
, ws://
, and wss://
.
The default topic which ModbusMQTT monitors and to which it publishes is modbus-mqtt
. You can vary that by changing the path portion of the MQTT URL.
Further, you can change other MQTT options by using query params, such as setting a custom client_id:
"mqtt://1.2.3.4/?client_id=$CUSTOM_CLIENT_ID"
For a full list of supported options, check the MQTT client library's source code.
To connect to a Modbus device, you need to post the connection details to MQTT under a topic of $prefix/$connection_id/connect
. It is intended that such messages are marked as retained so that ModbusMQTT reconnects to your devices when it restarts or if it crashes.
For instance, a simple config might be:
// PUBLISH modbus-mqtt/solar-inverter/connect
{
"host": "10.10.10.219",
"proto": "tcp",
}
If the connection is successful, you will see the following message like the following sent to the MQTT server:
// modbus-mqtt/solar-inverter/state
"connected"
Check the examples/
directory for some examples and please feel free to share your own examples, noting the appropriate vendor/device info.
The following JSON is all supported connection configuration fields, where the optional fields show the default values in use.
{
// Common fields
"address_offset": 0, // optional
"unit": 1, // optional, aliased to "slave"
// TCP:
"proto": "tcp",
"host": "1.2.3.4",
"port": 502, // optional
// RTU / Serial:
"proto": "rtu",
"tty": "/dev/ttyACM0",
"data_bits": "Eight", // optional (TODO: accept numeric and lowercase)
// valid: Five, Six, Seven, Eight
"stop_bits": "One", // optional (TODO: accept numeric and lowercase)
// valid: One, Two
"flow_control": "None", // optional (TODO: accept lowercase)
// valid: None, Software, Hardware
"parity": "None", // optional (TODO: accept lowercase)
// valid: None, Odd, Even
// Sungrow WiNet-S dongle
"proto": "winet-s",
"host": "1.2.3.4",
}
Post to $MODBUS_MQTT_TOPIC/$CONNECTION_ID/$ADDRESS
with the following payload (optional fields show defaults):
{
"address": 5123, // REQUIRED
"register_type": "input", // OPTIONAL
"name": null, // OPTIONAL - gives the register a name which is used in the register MQTT topics (must be a valid topic component)
"interval": "1m", // OPTIONAL - how often to update the registers value to MQTT
// e.g.: 3s (every 3 seconds)
// 2m (every 2 minutes)
// 1h (every 1 hour)
"swap_bytes": false, // OPTIONAL
"swap_words": false, // OPTIONAL
"type": "s16", // OPTIONAL
// valid: s8, s16, s32, s64 (signed)
// u8, u16, u32, u64 (unsigned)
// f32, f64 (floating point)
"scale": 0, // OPTIONAL - number in register will be multiplied by 10^(scale)
// e.g.: to turn kW into W, you would provide scale=3
// to turn W into kW, you would provide scale=-3
"offset": 0, // OPTIONAL - will be added to the final result (AFTER scaling)
}
When issuing the connect
payload, you can optionally include a top-level registers
array, containing the above register schema. When present, these payloads will be replayed to the MQTT server as if the user had specified each register separately, as above.
This is a recommended way to specify connections, but the registers are broken out separately so that they can be dynamically added to too.
TODO: set up something like https://hub.docker.com/r/oitc/modbus-server to test with