Improve efficiency of Modbus Switch component for Relays

Caused by discussion - Modbus Switch toggle doesn't work with latest code · Issue #50010 · home-assistant/core · GitHub

I was always wondering why it’s mandatory to continuously very state of relay if there is only one master on the line. Isn’t it possible to make state verification only after the command is send during configured N seconds time-out period?

Yes, I understand both use cases are possible - switch can be triggered manually. Still in installations where you need just to confirm execution of the command a request loop is an overhead - it just bring a lot of waste traffic in the modbus network.

Let me explain what I mean by use case. Relay board can receive command and send it’s state. Its configured as switch.

- name: foo_relay
  slave: 8
  input_type: holding
  address: 5
  command_on: 0x0100
  command_off: 0x0200
  state_on: 0x0001
  state_off: 0x0000

I see the state of relay requested in a loop with configured interval. The log is full of such requests:

2021-05-04 12:29:08 DEBUG (SyncWorker_1) [pymodbus.transaction] SEND: 0x8 0x3 0x0 0x5 0x0 0x1 0x94 0x92
2021-05-04 12:29:08 DEBUG (SyncWorker_1) [pymodbus.transaction] Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2021-05-04 12:29:08 DEBUG (SyncWorker_1) [pymodbus.transaction] Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
2021-05-04 12:29:08 DEBUG (SyncWorker_1) [pymodbus.transaction] RECV: 0x8 0x3 0x2 0x0 0x0 0x64 0x45

As result scan_interval is 20-30 seconds and after button pressed in HA the status change has a huge delay.

Instead of this loop state pooling I propose to request state during N seconds only after the change state command is sent.

For example a parameter

  #scan_interval: 15 <- if not defined, then no rescans
  verify_state: 3
  verify_timeout: 15

This configuration will tell modbus component to request state of the switch 3 time each 15 seconds after the switch command send. If no response after 45 seconds then switch becomes unavailable. Stop request on first successful response.