modbus-tcppymodbushome-assistant

Waveshare POE TCP Modbus Relay configuration connecting but not reading or writing


I have a Waveshare 8-channel Modbus POE ETH Relay and I’m really struggling with getting it integrated into Home Assistant.

I have been able to connect in python using pymodbus TCP client, and I also see the connect in HA logs, but I can’t get the relays to toggle on\off using HA or in the Python REPL with pymodbus.

This is my test config.

modbus:
  - name: waveshare_relay
    type: tcp
    host: 192.168.0.107
    port: 502
    binary_sensors:
      - name: relay_1_status
        slave: 1
        address: 0
        input_type: coil
        scan_interval: 5
    switches:
      - name: relay_1
        slave: 1
        address: 0
        write_type: coil

This is what I see in the HA logs

2024-05-19 13:40:18.364 INFO (MainThread) [homeassistant.setup]
    Setting up modbus
2024-05-19 13:40:18.376 INFO (MainThread) [homeassistant.setup]
    Setting up switch
2024-05-19 13:40:18.378 INFO (MainThread) [homeassistant.setup]
    Setup of domain switch took 0.00 seconds
2024-05-19 13:40:18.381 INFO (MainThread) [homeassistant.setup]
    Setup of domain modbus took 0.02 seconds
2024-05-19 13:40:18.388 INFO (MainThread) [homeassistant.components.modbus.modbus]
    modbus waveshare_relay communication open
2024-05-19 13:40:29.088 INFO (MainThread) [homeassistant.components.binary_sensor]
    Setting up modbus.binary_sensor
2024-05-19 13:40:29.092 INFO (MainThread) [homeassistant.components.switch] 
    Setting up modbus.switch
2024-05-19 13:40:42.084 ERROR (MainThread) [homeassistant.components.modbus.modbus]
    Pymodbus: waveshare_relay:
    Error: device: 1 address: 0 -> Modbus Error: [Input/Output] 
    ERROR: No response received after 3 retries

The VirCOM config looks like this

enter image description here

And when I try to do the same thing with pymodbus, I see a similar issue.

Python 3.12.2 (main, Feb 14 2024, 00:14:50) [Clang 15.0.0 (clang-1500.1.0.2.5)]
on darwin
Type "help", "copyright", "credits" or "license" for more information.

>>> from pymodbus.client import ModbusTcpClient
>>>
>>> WAVESHARE_IP = '192.168.0.107'
>>> WAVESHARE_PORT = 502
>>>
>>> client = ModbusTcpClient(WAVESHARE_IP, port=WAVESHARE_PORT)
>>> client.connect()
True
>>> print(client.__dict__)

{'comm_params': CommParams(comm_name='comm', comm_type=<CommType.TCP: 1>,
reconnect_delay=0.1, reconnect_delay_max=300.0, timeout_connect=3,
host='192.168.0.107', port=502, source_address=None, handle_local_echo=False,
sslctx=None, baudrate=None, bytesize=None, parity=None, stopbits=None),
'params': ModbusBaseSyncClient._params(retries=3, retry_on_empty=False,
broadcast_enable=False, reconnect_delay=None, source_address=None),
'retry_on_empty': 0, 'no_resend_on_retry': False, 'slaves': [], 'framer':
<pymodbus.framer.socket_framer.ModbusSocketFramer object at 0x102453320>,
'transaction': <pymodbus.transaction.ModbusTransactionManager object at
0x1031fa420>, 'reconnect_delay_current': 0, 'use_udp': False, 'state': 0,
'last_frame_end': 0, 'silent_interval': 0, 'transport': None, 'socket':
<socket.socket fd=3, family=2, type=1, proto=6, laddr=('192.168.0.100', 61189),
raddr=('192.168.0.107', 502)>}

>>> result = client.read_coils(0, 1)

>>> print(result.__dict__)
{'fcode': 1, 'message': '[Input/Output] Modbus Error: [Invalid Message]
 No response received, expected at least 8 bytes (0 received)', 'string':
 '[Input/Output] Modbus Error: [Invalid Message] No response received, expected
 at least 8 bytes (0 received)'}

>>> client.close()


Solution

  • Removing the Sensor section fixed the issue.

    modbus:
      - name: waveshare_relay
        type: tcp
        host: 192.168.0.107  # Replace with your device's IP address
        port: 502           # Replace with your device's port
        switches:
          - name: Relay 1
            address: 0
            slave: 1
            write_type: coil
          - name: Relay 2
            address: 1
            slave: 1
            write_type: coil
          - name: Relay 3
            address: 2
            slave: 1
            write_type: coil
          - name: Relay 4
            address: 3
            slave: 1
            write_type: coil
          - name: Relay 5
            address: 4
            slave: 1
            write_type: coil
          - name: Relay 6
            address: 5
            slave: 1
            write_type: coil
          - name: Relay 7
            address: 6
            slave: 1
            write_type: coil
          - name: Relay 8
            address: 7
            slave: 1
            write_type: coil