Extract data from modbus multiple register

According the following post: ModBus how to read multiple registers? How to use data_type and structure? I am trying to get two register.
The modbus config:

- name: "Test_modbus"
  slave: 1
  address: 85
  count: 2
  input_type: holding
  data_type: custom
  structure: ">2h"
  unique_id: "test_modbus"

This part seems to work.


A list with 2 entries reportedly comes up.
How can I get the first and the second entry now?
If I enter {{ states('sensor.test_modbus')[0]}} I would expect 5000. But it only gives me back “the first letter” i.e. 5.

Is the problem already in the Modbus configuration? The modbus documentation is very sparse on this topic (“structure” field).

a double-quoted Python struct is expected, to format the string to unpack the value. See Python documentation for details.

No idea what a “a double-quoted Python struct” is and I can’t find anything helpful in the python documentation.

Thank you

Try:

{{ states('sensor.test_modbus').split(',')[0] }}

1 Like

Great! It works.

But I didn’t even realise that it could be easier. :laughing:

- name: "Test_modbus"
  slave: 1
  address: 85
  count: 2
  slave_count: 1
  input_type: holding
  data_type: int16
  unique_id: "test_modbus"

This automatically creates 2 entities that contain exactly this data.

  • sensor.test_modbus
  • sensor.test_modbus_1

That will work if all of your registers are int16.
But if you have a mixture of int16 and uint16 you will need to use the split method. As ideally you want to limit the amount of Modbus requests you do.

You will put a lot less load on the Modbus device doing a single request for 100 registers in a block compared to requesting 50 blocks of 2 registers for example.

Yes, I know they have to have the same type. For another block I need to read 8x uint32 and 1x int16. But I have still no idea how to define the structure. Where can I find this information? Thank

Going back to your first post, the answer is in “See Python documentation for details” so look for ‘Python struct documentation’.

HA is, I believe, mostly written in Python. To process a data buffer, the Python language has a library (module of code) called ‘struct’ that can be called upon to do the hard work of packing and unpacking data into or from a buffer.

You can find the details of struct at
https://docs.python.org/3/library/struct.html

in particular the bit on Format Strings, and format characters provides all the information you require.

To make it work, ensure that the amount of data read (the buffer size) matches the unpacking size of the format string, make sure that you have the correct endian for your Modbus device, and make sure you choose signed/unsigned correctly.

My guess is that you want something like (with a buffer read of 17)

">8Lh"

And if you are still confused about the “double quote”, then " is a double quote, and ’ a single quote. Both are commonly used to be able to quote a string within a string - hence ‘structure: “>8LH” ’ can be unpicked by a computer into a string within a string (I added a space between " and ’ as "’ is rather difficult to read)

1 Like

Thank you. Yeah… I realised late that it was the documentation of “struct”. Probably while you were writing the answer :wink:
Well, it works. I have defined the following structure:
>8Li
Here is the yaml:

- name: "Real Energy"
  slave: 1
  address: 226
  count: 18
  input_type: holding
  data_type: custom
  structure: ">8Li"
  unique_id: "real_energy"
  scan_interval: 5