* [x] Support custom Modbus transports (Sungrow WiNet-S has been implemented)
* Modbus RTU has not been tested because I don't have a serial Modbus device, but in principle it should work. Please let me know
* [x] Support reading input registers
* [x] Support reading holding registers
* [ ] Support _setting_ holding registers
* [ ] Support optional auto-configuration of Home Assistant entities, including using [MQTT Number](https://www.home-assistant.io/integrations/number.mqtt/) et al for holding registers, to allow setting the value.
* [ ] TLS MQTT connections
* [ ] WebSocket MQTT connections
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](https://github.com/bjeanes/modbus-mqtt/actions?query=is%3Asuccess+branch%3Amain+workflow%3ACI).
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:
```sh
"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](https://github.com/bytebeamio/rumqtt/blob/c6dc1f7cfb26f6c1f676954a51b398708d49091a/rumqttc/src/lib.rs#L680-L768).
### Connecting to Modbus devices
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.
For instance, a simple config might be:
```jsonc
// 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:
```jsonc
// modbus-mqtt/solar-inverter/state
"connected"
```
#### Full connection examples
All fields accepted (optional fields show defaults)
```jsonc
{
// 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)
Post to `$MODBUS_MQTT_TOPIC/$CONNECTION_ID/$TYPE/$ADDRESS` where `$TYPE` is one of `input` or `holding` with the following payload (optional fields show defaults):
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.