Modbus configuration problem

Trying to get a set of binary sensors returned via function call 0x01 coils.
While I get the 14 sensors populated with data, the sequence is not correct.
The spec for the coil register is:
Function call: 0x01
Register address: 0x01
Byte count: 2
Byte 1: coils output (bitwise) x, x, 14, 13, 12, 11, 10, 9
Byte 2: coils output (bitwise) 8, 7, 6, 5, 4, 3, 2, 1

My configuration.yamt for the sensor is:

  • name: heatpump_relay
    slave: 0x01
    address: 0x01
    input_type: coil
    slave-count: 13
    scan_interval: 15

I suspect the slave_count and/or the sequence is the issue, but cannot really understand the result. Coil #9 is indication of compressor running, and that output in the sensor list I cannot identify.

Please format code correctly; but if that’s copy-pasted, note that you have slave-count rather than slave_count.

Hi Troon. The code was all just typed in and so made that hyphen error in the text. The code is however correct, as I can populate all 14 binary sensors. However, I cannot match their state to those of the controllers actual state for those relays(coils).
It’s like the mapping of addresses are wrong maybe?

I have managed to get the reading from the machine’s 14 temp sensors via function call 0x04, thus the Modbus connection works correctly.
I will upload the code from my conf.yaml file.

  - name: modbus_dvi
    type: serial
    port: /dev/ttyACM0
    baudrate: 9600
    bytesize: 8
    method: rtu
    parity: N
    stopbits: 1
    delay: 0
    message_wait_milliseconds: 30
    timeout: 5
      - name: "Heatpump evaporator"
        slave: 0x10
        address: 0x06
        input_type: input
        unit_of_measurement: °C
        state_class: measurement
        scan_interval: 15
        scale: 0.1
        offset: 0
        precision: 1
        data_type: int16
      - name: heatpump_relay
        slave: 0x10
        address: 0x01
        input_type: coil
        slave_count: 13
        scan_interval: 15

This is from the spec of the interface:

The actual spec of those registers are:

Appreciate some hints.

not sure I understand your point here. The indentation is not the problem as the temp sensor works correctly, and that the binary sensor creates the 14 discrete binary sensors.

Also, the structure is exactly as described in the MODBUS HA help page. Are you saying that there is a new structure which is not captured in the help page?

What I think is the problem is the translation bitwise of the coil registers into the 14 different binary sensors. Here the slave_count may be the issue and that I maybe first need to return the 2 byte value of the registers and then afterwards use a sensor template to read each bit value per sensor?

I don’t think there’s anything wrong with your indentation.

I’m not sure we can answer your very specific issue though. Do you not need 16 binary sensors and just ignore the first two?

I tried that also, and I do get 16 binary sensors when I increase the slave_count to 15.
The state of the sensors do not however match what is going on in the machine. The slave_count functions it seems by adding 1 to the address at each loop. Is that actually what will work with the registry structure I am looking at?
I.e. is my starting address really at bit level so that each increment will move to the next bit of the register?

Finally, I think I know what is wrong. This particular implementation of Modbus on my heatpump is maybe a bit unconventional. It seems that for each function call 0x01, 0x02, 0x03, 0x04, and 0x06, the first register address is always 0x01.
Because the coils are contained bitwise in the 2 byte register starting with 0x01, using the coil input_type in HA will not let me first read the int16 content of the register and then subsequent use sensor templates to extract the content bitwise into each binary sensor.
Using another input_type to allow this type of data (int16) would point to another location.
So, caught between a rock and a hard place. Function 0x01 assumes the read is one bit, using slave_count increases the register address with 2 byte. i.e to an address which is not used under function code 0x01 (Coils)

How can I possibly crack this one?

Did some Modbus logging on a different but somewhat related issue. Trying to get a uint32 value our of two registers. some error makes this impossible. Modbus logging says:

2024-02-08 06:37:09.564 DEBUG (MainThread) [pymodbus.logging] Adding transaction 17
2024-02-08 06:37:09.729 DEBUG (SyncWorker_2) [pymodbus.logging] Incomplete message received, Expected 9 bytes Received 7 bytes !!!!
2024-02-08 06:37:09.729 DEBUG (SyncWorker_2) [pymodbus.logging] Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
2024-02-08 06:37:09.729 DEBUG (SyncWorker_2) [pymodbus.logging] RECV: 0x10 0x4 0x2 0x0 0x0 0x45 0x33
2024-02-08 06:37:09.729 DEBUG (SyncWorker_2) [pymodbus.logging] Processing: 0x10 0x4 0x2 0x0 0x0 0x45 0x33
2024-02-08 06:37:09.730 DEBUG (SyncWorker_2) [pymodbus.logging] Getting Frame - 0x4 0x2 0x0 0x0
2024-02-08 06:37:09.730 DEBUG (SyncWorker_2) [pymodbus.logging] Factory Response[ReadInputRegistersResponse': 4]
2024-02-08 06:37:09.730 DEBUG (SyncWorker_2) [pymodbus.logging] Frame advanced, resetting header!!
2024-02-08 06:37:09.730 DEBUG (SyncWorker_2) [pymodbus.logging] Adding transaction 16
2024-02-08 06:37:09.730 DEBUG (SyncWorker_2) [pymodbus.logging] Getting transaction 16
2024-02-08 06:37:09.731 DEBUG (SyncWorker_2) [pymodbus.logging] Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
2024-02-08 06:37:09.764 ERROR (MainThread) [homeassistant.components.modbus.base_platform] Received 2 bytes, unpack error unpack requires a buffer of 4 bytes

One register = 2 bytes


0x10 id
0x4 function
0x2 size
0x0 byte 1
0x0 byte 2
0x45 0x33 crc crc

Thanks a lot. It appears that this Modbus implementation does not allow read of two registers in one go. I have not set it up with two raw sensors and is now getting a sensor template set up to combine the two registers into one number.

Follow up: now that issue with the combined two registers is solved. Did some sensor template states calculations :slight_smile:

The original issue with reading a full 16 bit/2 Byte register with function code 0x01 persist. What should I do to hack the HA modbus implementation to allow this?

Thanks for those who responded.

Turned out that my problem in reality was not so big after all. had to use the slave_count: 15 to get all bits of the coil register, and then re-map each binary_sensor to the actual address of each specific relay. The order was somewhat upside-down.

Closing this one