Help a newbie getting Modbus TCP to work

Hi community!

I’ve recently got a Nibe Heatpump and the electrician installed a Siemens PAC2200 energy meter right before it. To monitor the work of the heatpump and later on control it to mostly use solar power, I’ve installed Home Assistant.
Now, I’d like to get the readings of the PAC2200 logged in HA. To do so, I’ve added the following to my configuration.yaml:

  - name: "hub1"
    close_comm_on_error: false
    retry_on_empty: true
    delay: 5
    timeout: 5
    type: tcp
    host: 192.168.1.20
    port: 502
    sensors:
      - name: "frequency"
        data_type: float32
        count: 2
        address: 55

In the logs, I get the message

2023-07-17 23:17:03.179 DEBUG (SyncWorker_9) [homeassistant.components.modbus.modbus] Pymodbus: hub1: Modbus Error: [Input/Output] Modbus Error: [Invalid Message] No response received, expected at least 8 bytes (0 received)
2023-07-17 23:17:18.180 DEBUG (SyncWorker_5) [homeassistant.components.modbus.modbus] Pymodbus: hub1: Modbus Error: [Input/Output] No Response received from the remote slave/Unable to decode response

I’ve already experimented a bit with the address (54,55,56, 40055 and so on), because I’ve ready somwhere, that you had to add or substract 1. Neither helped here :frowning:
Using the tool “Modbus poll”, I was able to read data from the device. So something seems to be wrong with my HA config. Can you please give me a hint on what could be wrong? Is there maybe a way to view the raw communication packet that HA sent out via Modbus TCP so I can compare them to the packet from the “Modbus poll”?

Regards,
JohnPower

Can you show the modbus poll command that works?

Having used the PAC3200 meters before (same register layout) elsewhere I know that we were reading register 56 for the frequency but it is a float IEEE reversed data type so I can only assume in HA you would need a data_type: custom and use structure: “<f” or “>f”. If I am reading the docs correctly < is little-endian and > is big-endian whilst f is 4 byte float. I am not sure of the correct syntax. This may help but equally I may be completely wrong.

Here are two reads of the frequency (timestamp first)

Tx:000022-21:01:51.602- 00 42 00 00 00 06 01 03 00 37 00 02
Rx:000023-21:01:51.616- 00 42 00 00 00 07 01 03 04 42 47 F0 4B
Tx:000024-21:01:52.606- 00 43 00 00 00 06 01 03 00 37 00 02
Rx:000025-21:01:52.616- 00 43 00 00 00 07 01 03 04 42 47 F3 94

@noobsRus : I’ve set Modbus Poll to display float32 big-endian:


and it displays a plausible value for the frequency. That’s why I went for float32 in the first place :slight_smile:
Also, from my understanding, the wrong data type wouldn’t explain why I get a “0 byte” error from HA, right?
Is it important to add the “count: 2” when I already have a 2-byte datatype defined or is it enough to set the datatype and HA chooses to read 2 registers on its own?

I’d try to break this up into two parts. First let’s see if we can get HASS to read the register at all and then work on getting it to interpret the data.

    sensors:
      - name: test
        address: 55
        data_type: uint16
        scan_interval: 10  

If that works then verify you see the same value at that register in the other tool when reading a uint16. If not then it may be the off by one issue on the address.

If that works then try changing the data type to Float32 and see what happens.

I don’t think you’ll need to specify count, that could be the whole issue.

If you get the wrong value for the float there are some setting to swap the bytes, experiment with those.

Look at this post, I think it has the solve.

As the suggested configs didn’t work, I stumbled upon a solution to show the transmitted data: add

logger:
  default: warning
  logs:
    homeassistant.components.modbus: debug
    pymodbus: debug

to the configuration.yaml and restart! (I didn’t restart before but just reloaded the yaml files).
Anyway, that’s how I nailed down the problem on a byte level.

HA sents

0x0 0x4 0x0 0x0 0x0 0x6 0x0 0x3 0x0 0x37 0x0 0x1

but it should be

0x0 0x4 0x0 0x0 0x0 0x6 0x1 0x3 0x0 0x37 0x0 0x2

this brought me to the culprit here: Even though I changed the sensor parameters in the configuration.yaml, just reloading the yaml files didn’t do anything to the packet sent via modbus. You have to restart HA for the changes to take effect.

Long story short: The following configuration works fine for me

modbus:
  - name: "pac2200"
    type: tcp
    host: 192.168.1.20
    port: 502
    sensors:
      - name: "active_power_heatpump"
        slave: 1
        input_type: holding
        count: 2
        data_type: float32 
        address: 65