Modbus MSB / LSB structure

I have a question regarding to modbus settings. I have read the documentation carefully, tried to search some topics, but unfortunately I did not find an answer to my problem.

I have a heat pump, which is able to communicate through modbus. In the past without HA I had my own application on ESP8266, reading the data, uploading them, etc. Now I would like to move it into HA. I found the modbus protocol is implemented in HA, which is great.

Now, in my custom app I had to read the registry and modify the respond for each value as the device has MSB implementation, let me provide an example:

From the device documentation, the only things I know (and it seems to be enough as I was able to implement the app) are: The heat pump communicates on … IP address, on … port. It uses slave and the slave ID is … All values are represented in MSB (most significant byte). Now about the values, for example outside temperature is on address 0, type is read only and the scale is 100 (for modbus in configuration file it should be 0.01 - lets ignore it for now), unit is °C.

So, my configuration look like:

# Modbus configuration
modbus:
  - name: ...
    type: tcp
    host: ...
    port: ...
    delay: 5
    timeout: 5
    sensors:
      - name: Heat pump outside temperature
        address: 0
        slave: 1
        input_type: holding
        device_class: temperature
        state_class: measurement
        data_type: uint16
        unique_id: "ac_heating_outside_temp"

This results to value of 65436 on this entity, which is wrong obviously. The real value at this moment is -1. The biggest value for uint16 is 65535, 65436-65535 = -99, multiplied by 0.01 (or divided by 100) is -0.99, which is (if we deduct zero) -1.00 degree… This is the value which I need. Well, in my C app, I have been doing this recalculation on my own (in bytes). Unfortunately I have no idea how to do that in “our” modbus yaml description.

I have been looking to SWAP, DATA_TYPE as well as STRUCTURE in the documentation: DOCUMENTATION (documentation link) unfortunately nothing is working for me. I know I have to set custom data_type if I would like to provide structure, but defining the custom type and “>I” in the structure requires 2 registries to read, but the address of the entity is 0, which is 1 registry. Even like that I tried that, but I am not able to get the proper value. Having the data_type to uint16 with the swap byte or even swap word does not seems to work. I tried to play (out of necessity) with uint8, 2 registries and swap together, but no combination leads to the proper result.

Can anybody help me with this one?

datatype int16 maybe

1 Like

You get me an idea which is working!!! Thanks!

The solution is really using an int16, BUT that is not the only one (because even like that I have to swap the bytes)… But following implementation:

# Modbus configuration
modbus:
  - name: ...
    type: tcp
    host: ...
    port: ...
    delay: 5
    timeout: 5
    sensors:
      - name: Heat pump outside temperature
        address: 0
        slave: 1
        input_type: holding
        device_class: temperature
        state_class: measurement
        count: 1
        swap: word
        data_type: int16
        unique_id: "ac_heating_outside_temp"

seems to be returning me -100 which is pretty much everything (together with scale of 0.01) what I need. Hopefully this will work with positive numbers as well (I have to test it)

EDIT: it is working!!! Thanks a lot!

1 Like