Modbus switch write command open close

Hi

I’m trying to find an easy way to setup the N4D8B08 8-channel RS485 IO input and output controller.

So far I am able to control the outputs but the setup for each output is as follows

  - platform: modbus_controller
    modbus_controller_id: control_2
    address: 0x0002
    register_type: holding
    name: "test 22"
    write_lambda: |-
      bool open = x == 1;
      payload.push_back(0x02); // device address
      payload.push_back(0x06); // force single register
      payload.push_back(0x00); // high byte address of the coil
      payload.push_back(0x02); // low byte address of the coil
      if (open)
        payload.push_back(0x01); // command
      else
        payload.push_back(0x02); // command
      payload.push_back(0x00); // delay
      return open;

So I was wondering if there is an easier way to set this up without the need to repeat the same open or closed logic and without needing to repeat the device and coil address. I tried simply doing

  - platform: modbus_controller
    modbus_controller_id: control_2
    address: 0x0002
    register_type: holding
    name: "test 22"

but this sends the command 02.06.00.02.FF.FF.89.29 and I need to send 01 to open and 02 for close. The reading of the registers works as expected.

So I found a pretty good solution using yaml !include. For anyone having a similar issue see the follwing steps:

  1. Create an extra file named modbus-N4D8B08.yaml with the contents of the switch definition:
platform: modbus_controller
name: ${name}
id: ${id}
address: ${address}
register_type: holding
modbus_controller_id: ${modbus_controller_id}
write_lambda: |-
  bool open = x == 1;
  payload.push_back(${modbus_controller_address}); // device address / not working because protected: payload.push_back(item->parent_->address_); 
  payload.push_back(0x06); // force single register
  payload.push_back(0x00); // high byte address of the coil
  payload.push_back(${address}); // low byte address of the coil
  payload.push_back(open ? 0x01 : 0x02); // command
  payload.push_back(0x00); // delay
  return open;
  1. Include the file in the device config to reuse the same logic like:
switch:
  - !include 
    file: modbus-N4D8B08.yaml
    vars:
      name: "test 2"
      id: test_2
      modbus_controller_id: control_2
      modbus_controller_address: 0x02
      address: 0x02
3 Likes

Configuration for N4D8B08 using standard Modbus switch config with state control:

code

modbus:

  • name: modbus_hub
    type: serial
    port: /dev/ttyUSB0
    baudrate: 9600
    bytesize: 8
    method: rtu
    parity: N
    stopbits: 1
    switches:
    • name: switch_ALL
      slave: 1
      address: 0
      write_type: holding
      command_on: 0x0700
      command_off: 0x0800
    • name: switch_1
      slave: 1
      address: 1
      write_type: holding
      command_on: 0x0100
      command_off: 0x0200
      verify:
      delay: 1
      input_type: holding
      address: 1
      state_on: 1
      state_off: 0
    • name: switch_2
      slave: 1
      address: 2
      write_type: holding
      command_on: 0x0100
      command_off: 0x0200
      verify:
      delay: 1
      input_type: holding
      address: 2
      state_on: 1
      state_off: 0
    • name: switch_3
      slave: 1
      address: 3
      write_type: holding
      command_on: 0x0100
      command_off: 0x0200
      verify:
      delay: 1
      input_type: holding
      address: 3
      state_on: 1
      state_off: 0
    • name: switch_4
      slave: 1
      address: 4
      write_type: holding
      command_on: 0x0100
      command_off: 0x0200
      verify:
      delay: 1
      input_type: holding
      address: 4
      state_on: 1
      state_off: 0
    • name: switch_5
      slave: 1
      address: 5
      write_type: holding
      command_on: 0x0100
      command_off: 0x0200
      verify:
      delay: 1
      input_type: holding
      address: 5
      state_on: 1
      state_off: 0
    • name: switch_6
      slave: 1
      address: 6
      write_type: holding
      command_on: 0x0100
      command_off: 0x0200
      verify:
      delay: 1
      input_type: holding
      address: 6
      state_on: 1
      state_off: 0
    • name: switch_7
      slave: 1
      address: 7
      write_type: holding
      command_on: 0x0100
      command_off: 0x0200
      verify:
      delay: 1
      input_type: holding
      address: 7
      state_on: 1
      state_off: 0
    • name: switch_8
      slave: 1
      address: 8
      write_type: holding
      command_on: 0x0100
      command_off: 0x0200
      verify:
      delay: 1
      input_type: holding
      address: 8
      state_on: 1
      state_off: 0

I can’t seem to find the documentation of your configuration. On the modbus component, which you seem to use, i can’t find the swithes structure or most other variables used. Where did you find your configuration and where can I find it’s documentation?

These code is not use modbus switch component, it uses switch interation, which is controled by direct modbus commands. If you need modbus switch to use - look for my code, it`s original modbus switch with state control as it should be used