Modbus- Verify attributes

Hey There,

Trying again,

I am using modbus module

According to the modbus settings it is required to define verfication per each channel
I could not understand from the manual which and how I should define the attributes switch in order to get live status of the coil.

modbus:
  - type: rtuovertcp
    host: 192.168.1.7
    port: 501
    timeout: 2
    switches:
      - name: Switch1
        slave: 3
        address: 0
        write_type: coil
      - name: Switch2
        slave: 3
        address: 1
        write_type: coil
      - name: Switch3
        slave: 3
        address: 2
        write_type: coil
      - name: Switch4
        slave: 3
        address: 3
        write_type: coil
      - name: Switch5
        slave: 3
        address: 4
        write_type: coil
      - name: Switch6
        slave: 3
        address: 5
        write_type: coil
      - name: Switch7
        slave: 3
        address: 6
        write_type: coil
      - name: Switch8
        slave: 3
        address: 7
        write_type: coil
   
         verify:
       - name: Register1
         address: 7
         command_on: 1
         command_off: 0
         verify:
             input_type: holding
             address: 127
             state_on: 1
             state_off: 0 

OK, so I can see that you have been asking this question for some time. I don’t use Modbus in HA directly as I do this in Node-RED (I find that it is just easier, more adaptable, and quicker to develop and change).

However, I have looked at HA Modbus, and decided that here was an opportunity to try and gain better understanding in how it works by looking (again) at your problem.

I do not have a Modbus device with coils, so I downloaded a free Modbus slave simulator and set that up on my PC. I added some Modbus setup code to my config yaml, and I have experimented with three binary/coil entities in HA.

I can confirm that
Modbus (over TCP) works on HA as expected
Switches and binary sensors work as expected
The ‘verify’ option for switches works as expected

Here is my config entry for the Modbus testing. Note that my test slave has unit/slave id of 1

modbus:
  - name: testslave
    type: tcp
    host: 192.168.0.137
    port: 502
    binary_sensors:
      - name: mbbSensor3
        slave: 1
        address: 3
        scan_interval: 20
        device_class: connectivity
        input_type: coil
    switches:
      - name: mbSwitch2
        slave: 1
        address: 2
        write_type: coil
      - name: mbSwitch4V
        slave: 1
        address: 4
        write_type: coil
        verify:
            delay: 10

And here is my testbed setup.
I am using a simulated Modbus client on my PC, which allows me to change coil register values, to see when the change, and importantly to trace the Modbus communication (top left).

I added three entities in my config.

mbbSensor3 is a binary sensor, which just polls the slave coil address 3 every 20 seconds and reads the value of the coil. This cannot be changed in HA, but it responds to any changes made in the slave at the next poll read.

mbSwitch2 is a switch, connected to coil address 2. Being a switch I can change it in HA. On change, it sends a write command to the slave (0 or 1 according to the updated HA switch setting) and toggles the switch. Changing the coil in the slave has no change on the switch as this switch does not read, just write. In effect, HA assumes that the switch and the coil are following each other.

mbSwitch4V is also a switch, connected to coil address 4, but with the ‘verify’ option. This causes the switch to write any changes to the coil, and then to attempt to read back from the coil and update the switch accordingly. This is positive feedback.

Without ‘verify’ HA will only write to a coil. Adding ‘verify’ turns on a read after the write. Playing around with the verification option shows that, as just the default with no sub-values, HA attempts to read the same coil after each switch change. This means a manual toggle of the HA switch causes HA to immediately toggle the switch status, write to the coil, toggle the switch back again, read from the coil, and finally set the switch according to the true coil value. Thus HA is, assuming a successful write, then restoring the switch, and finally reading the coil to set the switch value.
Adding a delay option to the verify option caused HA to being polling the coil every 10 seconds - and this was ongoing, so that any change to the coil in the slave would cause the switch to update at the next poll read.

Conclusion: it all works and was very easy to set up, however the resulting functionality is very dependent on the precise settings, and I would always want to test this very carefully before using it. Especially if I wanted the switch to follow the coil (ie if I wanted to switch in HA and change the coil and I also wanted to change the coil elsewhere and for this to update the HA switch setting).

So, now to your problem.
Using the trace option I captured the communication between HA and the test slave on my PC.

Transaction ID 2 : Protocol ID 2 : Length field 2 : Unit ID 1 : Function Code 1 : Data n (address / value to write)

                                            ID FC <add> <val>
                                                  <no v>

[TCP]>Rx > 11:33:40:854 - 00 4D 00 00 00 06 01 05 00 04 00 00          write coil, address 4, value 0
[TCP]>Tx > 11:33:40:856 - 00 4D 00 00 00 06 01 05 00 04 00 00          response

[TCP]>Rx > 11:33:50:850 - 00 4E 00 00 00 06 01 01 00 04 00 01          read coil, address 4, one value
[TCP]>Tx > 11:33:50:850 - 00 4E 00 00 00 04 01 01 01 00                response 0
 
[TCP]>Rx > 11:33:52:079 - 00 4F 00 00 00 06 01 01 00 03 00 01          read coil, address 3
[TCP]>Tx > 11:33:52:079 - 00 4F 00 00 00 04 01 01 01 01                response 1
 
[TCP]>Rx > 11:33:52:337 - 00 50 00 00 00 06 01 01 00 04 00 01          read coil, address 4
[TCP]>Tx > 11:33:52:337 - 00 50 00 00 00 04 01 01 01 00                response 0
 
[TCP]>Rx > 11:34:07:338 - 00 51 00 00 00 06 01 01 00 04 00 01          read coil, address 4
[TCP]>Tx > 11:34:07:338 - 00 51 00 00 00 04 01 01 01 00                response 0
 
[TCP]>Rx > 11:34:12:076 - 00 52 00 00 00 06 01 01 00 03 00 01          read coil, address 3
[TCP]>Tx > 11:34:12:076 - 00 52 00 00 00 04 01 01 01 01                response 1
 
[TCP]>Rx > 11:34:22:335 - 00 53 00 00 00 06 01 01 00 04 00 01          read coil, address 4
[TCP]>Tx > 11:34:22:335 - 00 53 00 00 00 04 01 01 01 01                response 1
 
[TCP]>Rx > 11:34:32:077 - 00 54 00 00 00 06 01 01 00 03 00 01          read coil, address 3
[TCP]>Tx > 11:34:32:077 - 00 54 00 00 00 04 01 01 01 01                response 1

As this is Modbus over TCP, the message is the transaction ID, protocol ID, length field
then the important bits - unit id (the slave address), the Modbus function code, and the data

So, for a write to a coil (I change HA switch, HA turns coil off) for address 4 the command is:
Function code 5, address 00 04, value 00 00

Then for the read coil verification, by default HA will just read back from the same register
Function code 1, address 00 04, value 00 01
NOTE HA is sending 00 04 00 01 and getting back 01 00

Here the Modbus command being issued is the command to read one value from address 4. And my test slave responds accordingly sending back the value 01 00 - which is “I am sending you back 1 byte, and the value is 00”. In Modbus, a read of coils sends back the number of bytes of data and a value where the individual bits hold the results (with extra packing up to multiples of 8 bits).

In other words, if I asked for 3 values and they were 1, 0, 1 I would get back 01 05.

Now, if I turn to your device (Ahatos - REL 0808) user guide, I see that the ‘read channel state’ request, read coil function code 1, requires a data block of

“start channel number to read 0x00, 0x00-0x07, number of channels to read 0x00-0x01…0x08”
and the important bit is that
“number of channels to read should be 8 - (minus) starting channel to be read”

I don’t have your device to test, but this suggests to me that what your device wants, in order to read just one coil at address 4 is , 00 04 00 04
And it puts the values of coil 4, 5, 6 and 7 into the return.

I think that, to read 1 coil at address 1 requires 00 01 00 07, but HA is sending 00 01 00 01, and so on.

I think your problem actually is - your device requires 00 04 00 04 to read coil 4, but HA is sending 00 04 00 01 with the verify setting.

My suggestion is that you set up a test with your device and check out what is actually required in order to read just one coil. These manuals are not always correct or helpful - and I would personally want to check what is required to read, for example, coil 4.

After that, if I am right, your problem becomes one of how to send the verify read command correctly.

Hey thank you very much …

I don’t believe this was just a simple thing as adding “verify:”…

How should I modify what HA is sending?

If there a way to understand what was happening in the older version ?

Doing this has been ‘fun’ and as helped me understand Modbus, HA, and the HA documentation better. There is a limit to how much I can and want to do with this though.

I have no idea what HA Modbus was doing, or what it will be doing in the future. I just know what it apparently does when I tested it on a simple slave simulator. Your device may well respond differently, and you will have to test this out to see what, exactly, your device needs as a Modbus command to read one coil register.

You could live with no verification.
You could try ‘verify’ on its own and see if I works - I assume it will not.

If it was my device, I would now try to send different ‘read coil’ commands to work out what is needed to read, say, coil 3 and only coil 3.

One solution may be to read coil 0 to 7 in one go, ie send ‘read starting 00 and read 08’. Then you will have to pick out the bit required, something like a bitwise AND (return & 0x4) for bit 3.

thanks you very much for your inputs it is very helpful…
will try and update

I assume device is working normally as it is working great in old version…
I will try …

So first of all thanks!

it is fully working now just by adding “verify:” to each switch ,

I am tying to split switches into different YAML file and getting multiple errors

if i am using configuration file

modbus: 
  - type: rtuovertcp
    host: 192.168.1.7
    port: 501
    timeout: 2
    switches: 
    - name: Switch1
      slave: 1
      address: 0
      write_type: coil
      verify:

assuming i want to slip content into include files, what would be the right way to do it?

Should I keep cumulative indents per each YMAL file?

For example:

modbus: !include modbus.yaml
  # - type: rtuovertcp
    # host: 192.168.1.7
    # port: 501
    # timeout: 2
    switches: 
    - name: Switch1
      slave: 1
      address: 0
      write_type: coil
      verify:

while modbus file consist:

#modbus:
  - type: rtuovertcp
    host: 192.168.1.7
    port: 501
    timeout: 2
    message_wait_milliseconds: 50
   # retry_on_empty: true
    retries: 10

this is the error i get


Error loading /home/homeassistant/.homeassistant/configuration.yaml: while parsing a block mapping
in "/home/homeassistant/.homeassistant/configuration.yaml", line 3, column 1
expected <block end>, but found '<block mapping start>'
in "/home/homeassistant/.homeassistant/configuration.yaml", line 26, column 5

No idea.

https://www.home-assistant.io/docs/configuration/splitting_configuration/

I suggest you start with the above link. Hint - it is all about getting the include inserted at the correct level within the yaml structure, which you clearly are not doing.

Hi all,
I also try to integrate modbus modul to HA. Therefore, I studied the modbus tutorial and integrated the following lines to my configuration.yaml:

modbus:
  - name: "BMHG_1"
    close_comm_on_error: true
    delay: 5
#    retries: 10
#    retry_on_empty: true
#    message_wait_milliseconds: 10
    timeout: 5
    type: tcp
    host: 192.168.178.80
    port: 502
    switches:
      - name: "BMHG_Licht1"
 #       slave: 1
        address: 0
        write_type: coil
        scan_interval: 2
        verify:

The #-lines shows several tests I tried, also.

Now, the communication itselfs works, but with two problems:

  1. every 2 seconds (scan_interval) the switch state goes to ‘not available’, after 2 seconds again, it shows the correct state again… and so on, continously.
  2. When trying to toggle the switch, its always necessary to tap twice - the first click always is not forwarded.

Does someone has any idea?
The server device is an ABB PLC device which works properly e.g. together with any HMI.
Many thanks!

What are the settings of the modbus master

- type: tcp

  host: 
  port: 502
  name: HUB2 
  timeout: 2
  message_wait_milliseconds: 30
  retry_on_empty: true
  retries: 2

try above

Hi,

First of all, thanks for the research back then. I know I’m replying to an old topic, but I can’t find any other related topics.
I have a setup with HA talking with a Siemens 1200 PLC setup through Modbus.
I’m facing a problem with the verify option. It works, but it has a delay from appr. 10 seconds.
When I toggle the holding register in the PLC, it takes 10 seconds before the state of the light changes in HA. If I toggle the Light in HA, the state changes immediately.
I’m pretty sure I managed to change the state without delay last year.
Is something changed in the modbus behaviour of HA?

Thanks!
Snipaste_2023-10-29_22-46-15

update:
I get it working with a workaround by adding a binary sensor. This sensor controls the state of the switch.
If there’s a easier way I would love to hear it.
Snipaste_2023-10-30_10-03-36

I do not use HA directly but rather Node-RED for all my Modbus work.

That said, I always understood the ‘verify’ option to be a write-read combination so as to ensure a successful write. Ask HA to change a switch, send a Modbus write command, then perform a read and present the switch-change based on that. This kind of suggests that HA is not going to be as responsive (if at all) if the Modbus register changes remotely, unless you are polling the register also.