##
## DIO-430-R1 — ESPHome Modbus package (v0.2.0)
##
## Single package file — include from your ESPHome YAML:
##   packages:
##     dio: github://isystemsautomation/homemaster-dev/DIO-430-R1/Firmware/v0.2.0/default_dio_430_r1_plc/default_dio_430_r1_plc.yaml
##
## Requires global `modbus:` with id `modbus_bus`. If UART/Modbus are not defined yet, uncomment:
# uart:
#   id: rs485_uart
#   tx_pin: GPIO4
#   rx_pin: GPIO5
#   baud_rate: 19200
#   parity: NONE
#   stop_bits: 1
# modbus:
#   id: modbus_bus
#   uart_id: rs485_uart
##
## Input Registers (FC=04, read) — contiguous 0..29 (one merged poll per cycle):
##   0 DI_STATE_MASK · 1 RLY_STATE_MASK · 2 BTN_STATE_MASK · 3 LED_STATE_MASK
##   4 STATUS_FLAGS (bit1=linkOk, bit3=cfgDirty) · 5 LOCK_MASK
##   6..29 event counters (EVT_BASE=6, source*4+type; sources DI1..4=0..3, Btn1..2=4..5)
##
## Coils (FC=05/15): 0..2 relays · 3 ALL_OFF · 4 reserved · 5 IDENTIFY
##   6 SAVE_CFG · 7 REBOOT · 8..10 LED_HA · 11..14 DI_LOCK
##
## Relay/LED/lock state in HA: FC04 @1 / @3 / @5 (not coil read-back — ESPHome
## deduplicates FC01 on coils 0..3+5+8..14 and read-back becomes unreliable).
##
## Holding (FC=03) — config/identity; do not poll in the main loop.

substitutions:
  dio_id: dio
  dio_address: "3"
  dio_prefix: "DIO"
  dio_update_interval: 1s
  dio_command_throttle: 0ms

modbus_controller:
  - id: ${dio_id}
    address: ${dio_address}
    modbus_id: modbus_bus
    command_throttle: ${dio_command_throttle}
    update_interval: ${dio_update_interval}

binary_sensor:
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI1"
    register_type: read
    address: 0
    bitmask: 0x0001
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI2"
    register_type: read
    address: 0
    bitmask: 0x0002
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI3"
    register_type: read
    address: 0
    bitmask: 0x0004
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI4"
    register_type: read
    address: 0
    bitmask: 0x0008

  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} Btn1"
    register_type: read
    address: 2
    bitmask: 0x0001
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} Btn2"
    register_type: read
    address: 2
    bitmask: 0x0002

  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_led1_state
    name: "${dio_prefix} LED1"
    register_type: read
    address: 3
    bitmask: 0x0001
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_led2_state
    name: "${dio_prefix} LED2"
    register_type: read
    address: 3
    bitmask: 0x0002
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_led3_state
    name: "${dio_prefix} LED3"
    register_type: read
    address: 3
    bitmask: 0x0004

  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} Link OK"
    register_type: read
    address: 4
    bitmask: 0x0002
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} Config dirty"
    register_type: read
    address: 4
    bitmask: 0x0008

  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_di1_lock_state
    name: "${dio_prefix} DI1 lock"
    register_type: read
    address: 5
    bitmask: 0x0001
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_di2_lock_state
    name: "${dio_prefix} DI2 lock"
    register_type: read
    address: 5
    bitmask: 0x0002
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_di3_lock_state
    name: "${dio_prefix} DI3 lock"
    register_type: read
    address: 5
    bitmask: 0x0004
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_di4_lock_state
    name: "${dio_prefix} DI4 lock"
    register_type: read
    address: 5
    bitmask: 0x0008

  # Relay state @ IREG 1 — same FC04 block as DI; used by template switches below
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_rly1_state
    name: "${dio_prefix} Relay 1 state"
    internal: true
    register_type: read
    address: 1
    bitmask: 0x0001
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_rly2_state
    name: "${dio_prefix} Relay 2 state"
    internal: true
    register_type: read
    address: 1
    bitmask: 0x0002
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_rly3_state
    name: "${dio_prefix} Relay 3 state"
    internal: true
    register_type: read
    address: 1
    bitmask: 0x0004

sensor:
  # Event counters: registers 6..29 (all sources × single/double/triple/long)
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI1 single"
    register_type: read
    address: 6
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI1 double"
    register_type: read
    address: 7
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI1 triple"
    register_type: read
    address: 8
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI1 long"
    register_type: read
    address: 9
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI2 single"
    register_type: read
    address: 10
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI2 double"
    register_type: read
    address: 11
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI2 triple"
    register_type: read
    address: 12
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI2 long"
    register_type: read
    address: 13
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI3 single"
    register_type: read
    address: 14
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI3 double"
    register_type: read
    address: 15
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI3 triple"
    register_type: read
    address: 16
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI3 long"
    register_type: read
    address: 17
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI4 single"
    register_type: read
    address: 18
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI4 double"
    register_type: read
    address: 19
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI4 triple"
    register_type: read
    address: 20
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} DI4 long"
    register_type: read
    address: 21
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} Btn1 single"
    register_type: read
    address: 22
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} Btn1 double"
    register_type: read
    address: 23
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} Btn1 triple"
    register_type: read
    address: 24
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} Btn1 long"
    register_type: read
    address: 25
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} Btn2 single"
    register_type: read
    address: 26
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} Btn2 double"
    register_type: read
    address: 27
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} Btn2 triple"
    register_type: read
    address: 28
    unit_of_measurement: "events"
    accuracy_decimals: 0
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} Btn2 long"
    register_type: read
    address: 29
    unit_of_measurement: "events"
    accuracy_decimals: 0

switch:
  # Write-only coils — no FC01 read-back (avoids duplicate coil poll blocks)
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_relay1_coil
    register_type: coil
    address: 0
    internal: true
    assumed_state: true
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_relay2_coil
    register_type: coil
    address: 1
    internal: true
    assumed_state: true
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_relay3_coil
    register_type: coil
    address: 2
    internal: true
    assumed_state: true
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_di1_lock_coil
    register_type: coil
    address: 11
    internal: true
    assumed_state: true
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_di2_lock_coil
    register_type: coil
    address: 12
    internal: true
    assumed_state: true
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_di3_lock_coil
    register_type: coil
    address: 13
    internal: true
    assumed_state: true
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_di4_lock_coil
    register_type: coil
    address: 14
    internal: true
    assumed_state: true
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_cmd_all_off
    register_type: coil
    address: 3
    internal: true
    assumed_state: true
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    id: ${dio_id}_cmd_identify
    register_type: coil
    address: 5
    internal: true
    assumed_state: true

  # Public switches — state from FC04, command via write-only coils above
  - platform: template
    name: "${dio_prefix} Relay 1"
    id: ${dio_id}_relay1
    lambda: |-
      return id(${dio_id}_rly1_state).state;
    turn_on_action:
      - switch.turn_on: ${dio_id}_relay1_coil
    turn_off_action:
      - switch.turn_off: ${dio_id}_relay1_coil
  - platform: template
    name: "${dio_prefix} Relay 2"
    id: ${dio_id}_relay2
    lambda: |-
      return id(${dio_id}_rly2_state).state;
    turn_on_action:
      - switch.turn_on: ${dio_id}_relay2_coil
    turn_off_action:
      - switch.turn_off: ${dio_id}_relay2_coil
  - platform: template
    name: "${dio_prefix} Relay 3"
    id: ${dio_id}_relay3
    lambda: |-
      return id(${dio_id}_rly3_state).state;
    turn_on_action:
      - switch.turn_on: ${dio_id}_relay3_coil
    turn_off_action:
      - switch.turn_off: ${dio_id}_relay3_coil
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} LED1 HA"
    register_type: coil
    address: 8
    assumed_state: true
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} LED2 HA"
    register_type: coil
    address: 9
    assumed_state: true
  - platform: modbus_controller
    modbus_controller_id: ${dio_id}
    name: "${dio_prefix} LED3 HA"
    register_type: coil
    address: 10
    assumed_state: true
  - platform: template
    name: "${dio_prefix} DI1 child lock"
    lambda: |-
      return id(${dio_id}_di1_lock_state).state;
    turn_on_action:
      - switch.turn_on: ${dio_id}_di1_lock_coil
    turn_off_action:
      - switch.turn_off: ${dio_id}_di1_lock_coil
  - platform: template
    name: "${dio_prefix} DI2 child lock"
    lambda: |-
      return id(${dio_id}_di2_lock_state).state;
    turn_on_action:
      - switch.turn_on: ${dio_id}_di2_lock_coil
    turn_off_action:
      - switch.turn_off: ${dio_id}_di2_lock_coil
  - platform: template
    name: "${dio_prefix} DI3 child lock"
    lambda: |-
      return id(${dio_id}_di3_lock_state).state;
    turn_on_action:
      - switch.turn_on: ${dio_id}_di3_lock_coil
    turn_off_action:
      - switch.turn_off: ${dio_id}_di3_lock_coil
  - platform: template
    name: "${dio_prefix} DI4 child lock"
    lambda: |-
      return id(${dio_id}_di4_lock_state).state;
    turn_on_action:
      - switch.turn_on: ${dio_id}_di4_lock_coil
    turn_off_action:
      - switch.turn_off: ${dio_id}_di4_lock_coil

button:
  - platform: template
    name: "${dio_prefix} All off"
    on_press:
      - switch.turn_on: ${dio_id}_cmd_all_off
  - platform: template
    name: "${dio_prefix} Identify"
    on_press:
      - switch.turn_on: ${dio_id}_cmd_identify
