Tutorial to read Modbus Registers in NodeRed and sent to MQTT

Since 0.108 1-3 the modbus integration is broken (status from April 14th). And as I already run a NodeRed instance in HA I want to share my solution to poll “input registers” from my SMA Inverter in NodeRed and post the register values via MQTT. So in HA you only configure corresponding MQTT sensors and everything works again.

OK let’s start:

grab a “Modbus Read” block and drag in in your working area.
in the server field create a new modbus client and enter the same data you used in the modbus intzegration in HA.

my modbus integration looked like this:

  name: sma
  type: tcp
  port: 502

and this is the corresponding modbus client in NodeRed

to read a group of input registers into a buffer you specify the start register and number of 16 bit values to read.

so my modbus sensors definition looked like this:

  - platform: modbus
    scan_interval: 30
      - name: yield_total
        hub: sma
        unit_of_measurement: kWh   
        slave: 3
        register: 30513
        register_type: input 
        count: 4      
      - name: yield_day
        hub: sma
        unit_of_measurement: kWh   
        slave: 3
        register: 30517
        register_type: input 
        count: 4      

and this is the corresponding modbus read block

this results in a buffer with 8 values representing input register addresses 30513-30520.

Now use an inject block and configure it to trigger a repeating message in the interval you want the modbus registers to be polled and connect the output of the inject block with the modbus read block.

Now we need a JavaScript function to read the buffer and grab the two register values and create two messages containing the register values as payload. So grab a function block and configure it with two outputs and enter the following code

now drag two “mqtt out” blocks and configure them to send the payload to a mqtt topic of your choice.

the end result looks like this

in HA define two mqtt sensor instead of the modbus sensors like this

  - platform: mqtt
    name: "yield_total"
    state_topic: "sma/4/4"
    device_class: "power"
    unit_of_measurement: "Wh"
  - platform: mqtt
    name: "yield_day"
    state_topic: "sma/4/8"
    device_class: "power"
    unit_of_measurement: "Wh"

This should do the trick.

Interesting and thanks for the tutorial. What’s the reason behind making a single MODBUS call to retrieve 30513-30520 which equates to 2 registers? What about retrieve of each value separately and end up with a much simpler JavaScript block?

Hi I experienced that when I work with two blocks only one at a time returns with a value. I assume that the two requests at the same will result in only one request being processed.

I also saw a solution with the “modbus flex getter” block and a js function feeding all register details into the fleet getter block. I already approached the author to show us how he prepared the input of the flex getter. I will add this to the tutorial.


1 Like

Hi mate,

So just to make sure I got it right… I currently get about 10 different values from Registers 30565 through to 40745 (count of 2) using HA. But using Node-Red, you’re saying is that I should consider getting all 10,181 values, choose the ones I’m interested in and discard the rest?


Oh wait. Turns out that the node will only return up to 125 values. Anything above that and it returns nothing at all.

In which case I can only think of dropping multiple MODBUS nodes on the flow. Any thoughts?

Just define as many Read block as you need considering that up to 125 Registers can be red at once. You will come up with a small number of read blocks. Then use an inject node and choose a repeating rate. I my experiment with two read blocks connected to the same trigger block calling every 60 seconds I got results alternating between the two read blocks. So with calling every 30s I got results of both in a 60s raster. But this experience is based solely on trial & error

Hi Chris, not sure if you still have this running but how would this look like if I only want current solar production ( register 30775 - AC active power across all phases)?