Modbus relay status verification when device does not support reading individual coils

This is my device: 8-ch Ethernet Relay Module, Modbus RTU/Modbus TCP Protocol, PoE port Communication
and its docs for Modbus TCP Modbus POE ETH Relay - Waveshare Wiki

It only supports reading all coils, not individual coils. So, I can’t read the
status of individual relays. I can only read the status of all relays at once.

I have tested in this in pymodbus and verified that this is indeed the issue.

Reading one coil fails

# Read coils
try:
    result = client.read_coils(address=0, count=1, unit=1)
    if result.isError():
        print(f"Error reading coils: {result}")
    else:
        print(f"Coil status: {result.bits}")
except Exception as e:
    print(f"Exception occurred: {e}")

# Close the client
client.close()
DEBUG:pymodbus.logging:Connection to Modbus server established. Socket ('192.168.0.129', 51038)
DEBUG:pymodbus.logging:Current transaction state - IDLE
DEBUG:pymodbus.logging:Running transaction 1
DEBUG:pymodbus.logging:SEND: 0x0 0x1 0x0 0x0 0x0 0x6 0x0 0x1 0x0 0x0 0x0 0x1
DEBUG:pymodbus.logging:New Transaction state "SENDING"
DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG:pymodbus.logging:Transaction failed. (Modbus Error: [Invalid Message] No response received, expected at least 8 bytes (0 received)) 
DEBUG:pymodbus.logging:Processing: 
DEBUG:pymodbus.logging:Frame check, no more data!
DEBUG:pymodbus.logging:Getting transaction 1
DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
Error reading coils: Modbus Error: [Input/Output] Modbus Error: [Invalid Message] No response received, expected at least 8 bytes (0 received)

Reading all coils in a row works

# Connect to the client
if client.connect():
    log.debug('Connection to Modbus server established.')
    try:
        # Attempt to read 8 coils
        result = client.read_coils(0, 8, unit=1)
        if result.isError():
            print(f"Error reading coils: {result}")
        else:
            # Print status of each coil
            status = result.bits
            for i in range(len(status)):
                print(f"Relay {i+1} status: {'ON' if status[i] else 'OFF'}")
    except Exception as e:
        print(f"Exception occurred: {e}")
    finally:
        client.close()
        log.debug('Connection to Modbus server closed.')
else:
    log.error('Unable to connect to Modbus server.')
DEBUG:pymodbus.logging:Connection to Modbus server established. Socket ('192.168.0.129', 51039)
DEBUG:root:Connection to Modbus server established.
DEBUG:pymodbus.logging:Current transaction state - IDLE
DEBUG:pymodbus.logging:Running transaction 1
DEBUG:pymodbus.logging:SEND: 0x0 0x1 0x0 0x0 0x0 0x6 0x0 0x1 0x0 0x0 0x0 0x8
DEBUG:pymodbus.logging:New Transaction state "SENDING"
DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG:pymodbus.logging:Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG:pymodbus.logging:RECV: 0x0 0x1 0x0 0x0 0x0 0x4 0x1 0x1 0x1 0x0
DEBUG:pymodbus.logging:Processing: 0x0 0x1 0x0 0x0 0x0 0x4 0x1 0x1 0x1 0x0
DEBUG:pymodbus.logging:Factory Response[ReadCoilsResponse: 1]
DEBUG:pymodbus.logging:Adding transaction 1
DEBUG:pymodbus.logging:Frame check, no more data!
DEBUG:pymodbus.logging:Getting transaction 1
DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
Relay 1 status: OFF
Relay 2 status: OFF
Relay 3 status: OFF
Relay 4 status: OFF
Relay 5 status: OFF
Relay 6 status: OFF
Relay 7 status: OFF
Relay 8 status: OFF
DEBUG:root:Connection to Modbus server closed.

Given all that, how can I use the verify configuration of a Modbus Switch to check the status?

My main issue is that I need to verify the status of the relays so my switches in Home
Assistant are in sync with the actual status of the relays. I’m using “normally closed”
on some relays and those ones in particular are not working as expected in Home
Assistant.

Thanks!

bump … I’m hoping someone has seen this issue before.

I have confirmation from Waveshare that you cannot read a single coil at a time. You need to read all of them. I am hopeful there is a way to read a range and then parse out only the value I need. Still searching …

This might be helpful:

https://community.home-assistant.io/t/modbus-read-coils-not-as-binary/406901/12?u=pspot2

@pspot2 that totally helped!

Thank you !!!