Integrate Modbus with MQTT, the free, easy way.

Claudio Petrini
Instathings
Published in
6 min readApr 20, 2020
Photo by Clint Patterson on Unsplash

Machineries and hardware devices can be connected to a network using many different protocols that require a specific knowledge to be used and integrated. Instathings’ mission is to convert these protocols into a simple API that any developer can consume with little or no knowledge of the technology stack that is used to deploy and manage hardware.

Instathings has two main components:

  • a gateway (based on Docker and Node.js) that manages different automation protocols and convert them to MQTT;
  • a cloud service, that is used to:
    1) manage the gateway and the devices connected to it;
    2) collect the data from the gateway via MQTT and make them available via REST API or websocket.
Architectural overview

Using Instathings, the integration of any hardware device becomes seamless and fast. While I’m writing this post, we support two different automation protocols: Zigbee and Modbus. In both cases, we use a bridge to translate the protocols to MQTT.

In this post, I will show you:

  1. how to create a driver that describes a Modbus device contributing to Instathings open source catalogue of drivers;
  2. test the driver via API using a Raspberry Pi, a Modbus USB dongle DSD TECH SH-U10 and Instathings Cloud.

Requirements

To write the driver you’ll need:

  • a Modbus device (check if it’s already in the supported devices list);
  • the device datasheet or proper documentation regarding the Modbus protocol on the device;
  • Git.

To test the driver you’ll need:

  • a Raspberry Pi and a Modbus dongle (or any equivalent Linux based hardware that can be connected to a device via Modbus);
  • an Instathings account (or an MQTT server).

In this tutorial I’ll show how to add support for the Eastron SDM120 energy meter. You can download the technical documentation of the device as a PDF file from the manufacturer’s website.

Modbus2MQTT

Modbus2MQTT is an open source bridge that we created to manage the communication between a Modbus device and an MQTT broker.

The bridge depends on modbus-herdsman-converters, which is the actual library of drivers. Anyone can contribute.

To support a specific device, you need to:

  1. write a descriptor;
  2. contribute with a pull request.

Create a Modbus driver

The driver is a Javascript object, for most of the devices you can think it as a JSON descriptor (an example).

For our example let’s define the structure of our new driver:

{
"model": "SDM120",
"vendor": "Eastron",
"supports": "",
"description": "Energy meter",
"fromModbus": {
"input": {},
"keep": {}
},
"toModbus": {}
}

Required keys:

  • model (string): this is by far the most important key, it describes the device model and you can think it like a device id
  • vendor (string): the device vendor
  • supports (string): a small but readable description of the data that the device will read. This is only used for documentation.
  • description (string): a concise description of the device
  • fromModbus (object): an object that contains 2 keys input, keep.
    Those keys will describe the device addresses to read in order to retrieve data, we’ll dig into this in a bit
  • toModbus (object): unused so far.

Now let’s populate the input key.
From the device document we read that:

  • we can read Voltage at address 30001
  • we can read Current at address 30007
  • etc.

Our descriptor will become:

{
"model": "SDM120",
"vendor": "Eastron",
"supports": "",
"description": "Energy meter",
"fromModbus": {
"input": {
"voltage": {
"address": 30001
},
"current": {
"address": 30007
}
},
"keep": {}
},
"toModbus": {}
}

If this were the complete driver, then Modbus2MQTT would publish a JSON message like the following:

{
"voltage": < value read at address 30001 > ,
"current": < value read at address 30007 >
}

We’re using the key as a key of the output object and the address as an actual address to read the data from.

The descriptor supports additional parameters which, for the sake of this tutorial, are not described here (for instance you can post process data read before it gets published).
The complete descriptor is available here.

Note: So far we read from the input registers only but we’ll improve this :)

Make a pull request

After your descriptor is ready make a pull request to the modbus-herdsman-converter repo or contact us at Instathings.

Testing the device

Once your pull request has been accepted, you’ll be able to use Instathings to read data from the device seamlessly.

First, set up the Gateway in order to connect it to the Instathings Cloud.
Here’s a detailed step by step guide on how to do this.

When the Gateway is connected you’ll see something like this:

Gateway correctly connected

You can now plug in the USB Modbus adapter and click on the “Install” button in the “Protocols” section.
When the protocol is correctly installed the Protocols section will look like this:

Modbus software support installed successfully

We can now add your device to the Gateway; to do so go to the “Devices” tab and select the device from the list.

Just click on Create.

We now need to “Pair” the Modbus device; this case requires only to specify the Modbus Id of the device.

Again, just click “Pair”.
If everything went well, you’ll see a success message and the Instathings Editor will report the device as “Paired”.

From now on, the Instathings Gateway will poll every 10s the device in order to report data to the Cloud.
You’ll see data flowing in the “Data” section.

You can access this data via API as well, check out this detailed guide about how to enable API access.

Using Modbus2MQTT without Instathings

After your contribution wait for a new release that includes your descriptor and then just use the Modbus2MQTT bridge.

In order to pair the bridge with the device you’ll need to publish a message to:

modbus2mqtt/configure/set

With the following payload:

{
"id": "uniqueidentifier",
"modbus_id": "the modbus id of the device",
"baud_rate": "the baud rate to use",
"interval": 10000, // in ms the polling interval
"model": "SDM120" // this must be the same model of the descriptor
}

You’ll receive an ACK message here:

modbus2mqtt/bridge/log

Then you’ll need to subscribe to the topic with the format:

modbus2mqtt/<id> 

where in this case id = uniqueidentifier and you’ll see data flowing :)

Conclusions

In this article, I introduced Modbus2MQTT and illustrated how to add and test a driver to the library of supported devices using Instathings.

Finally, I showed how to use Modbus2MQTT as a stand alone library to translate Modbus to MQTT (viceversa coming soon).

--

--