How to interlock current based covers?

I’m building a air conditioning zone controller to replace my 20 year old system. currently there is 3 dampers to direct airflow to various areas of the house.

To do this I use a relay board with 16 relays, a little overkill but I plan on adding extra dampers later! I’ve got an 12c IO expander to control the relays, and a current sensor to measure the current from the 24vac supply for the dampers. with the current sensor setup as a ct clamp I can sense the current when the dampers are moving, the noise when not moving is ~0.002A, and when the damper is moving its up around 0.010A.

The Dampers have 3 wires, a common line, open and close line. in the open and close lines there is a micro switch that essentially makes the circuit go open at the end stops. It makes the setup fairly simple, one relay controls the direction and another controls power going to the first relay. and software is simple with a current based cover, allowing very reasonable position control.

The one issue I have is how to interlock the covers while one is moving? If 2 dampers are moving at the same time the it will effect the current draw due to the common current sensor. I have interlocks on the power control relays, but it doesn’t inhbit the covers. also note I had to disable the malfunction detection due to the single current sensor.


i2c:
  sda: 21
  scl: 22
  scan: true
  id: bus_a

pcf8574:
  - id: 'pcf8574_hub'
    address: 0x27
    pcf8575: true
    
sensor:
  - platform: bme280
    temperature:
      name: "AC Intake Temperature"
      oversampling: 16x
      accuracy_decimals: 2
    pressure:
      name: "AC Intake Pressure"
      accuracy_decimals: 2
    humidity:
      name: "AC Intake Humidity"
    address: 0x77
    update_interval: 30s
  - platform: bme280
    temperature:
      name: "AC Output Temperature"
      oversampling: 16x
      accuracy_decimals: 2
    pressure:
      name: "AC Output Pressure"
      accuracy_decimals: 2
    humidity:
      name: "AC Output Humidity"
    address: 0x76
    update_interval: 30s
  - platform: adc
    pin: GPIO32
    id: adc_1
    attenuation: auto
  - platform: ct_clamp
    sensor: adc_1
    name: "Damper Current Sensor"
    id: current_sensor
    update_interval: 1s
    accuracy_decimals: 4

# Individual outputs
switch:
  - platform: gpio
    name: "DIR_1"
    id: dir_1
    pin:
      pcf8574: pcf8574_hub
      number: 1
      mode:
        output: true
      inverted: true
  - platform: gpio
    name: "DIR_2"
    id: dir_2
    pin:
      pcf8574: pcf8574_hub
      number: 3
      mode:
        output: true
      inverted: true
  - platform: gpio
    name: "DIR_3"
    id: dir_3
    pin:
      pcf8574: pcf8574_hub
      number: 5
      mode:
        output: true
      inverted: true
  - platform: gpio
    name: "EN_1"
    id: en_1
    pin:
      pcf8574: pcf8574_hub
      # Use pin A4
      number: 0
      mode:
        output: true
      inverted: true
  - platform: gpio
    name: "EN_2"
    id: en_2
    pin:
      pcf8574: pcf8574_hub
      # Use pin B4
      number: 2
      mode:
        output: true
      inverted: true
  - platform: gpio
    name: "EN_3"
    id: en_3
    pin:
      pcf8574: pcf8574_hub
      # Use pin A5
      number: 4
      mode:
        output: true
      inverted: true

# Example configuration entry
cover:
  - platform: current_based
    device_class: damper
    name: "Office and Kids Rooms Damper"
    # disable malfunction detection due to common current sensor for open and close
    malfunction_detection: false

    open_sensor: current_sensor
    open_moving_current_threshold: 0.0065
    open_obstacle_current_threshold: 0.015
    open_duration: 14s
    open_action:
      - switch.turn_on: dir_1
      - switch.turn_on: en_1

    close_sensor: current_sensor
    close_moving_current_threshold: 0.0065
    close_obstacle_current_threshold: 0.015
    close_duration: 14s
    close_action:
      - switch.turn_off: dir_1
      - switch.turn_on: en_1

    stop_action:
      - switch.turn_off: en_1
      - switch.turn_off: dir_1

    obstacle_rollback: 10%
    start_sensing_delay: 1s

  - platform: current_based
    device_class: damper
    name: "Kitchen and Living Room Damper"
    # disable malfunction detection due to common current sensor for open and close
    malfunction_detection: false
    # reverse to other damper for some reason
    open_sensor: current_sensor
    open_moving_current_threshold: 0.0065
    open_obstacle_current_threshold: 0.015
    open_duration: 14s
    open_action:
      - switch.turn_off: dir_2
      - switch.turn_on: en_2

    close_sensor: current_sensor
    close_moving_current_threshold: 0.0065
    close_obstacle_current_threshold: 0.015
    close_duration: 14s
    close_action:
      - switch.turn_on: dir_2
      - switch.turn_on: en_2

    stop_action:
      - switch.turn_off: en_2
      - switch.turn_off: dir_2

    obstacle_rollback: 10%
    start_sensing_delay: 1s

  - platform: current_based
    device_class: damper
    name: "Master Bedroon and Upstairs Livingroom Damper"
    # disable malfunction detection due to common current sensor for open and close
    malfunction_detection: false
    # reverse to other damper for some reason
    open_sensor: current_sensor
    open_moving_current_threshold: 0.0055
    open_obstacle_current_threshold: 0.015
    open_duration: 14s
    open_action:
      - switch.turn_off: dir_3
      - switch.turn_on: en_3

    close_sensor: current_sensor
    close_moving_current_threshold: 0.0055
    close_obstacle_current_threshold: 0.015
    close_duration: 14s
    close_action:
      - switch.turn_on: dir_3
      - switch.turn_on: en_3

    stop_action:
      - switch.turn_off: en_3
      - switch.turn_off: dir_3

    obstacle_rollback: 10%
    start_sensing_delay: 1s

I figured a crude way to achieve the same result, by stopping the other covers on the open/close_action sections. now if I move one of the other dampers it just stops the other one wherever it is. still seems to keep pretty good track of where it was too!

Updated code below if it helps anyone.


i2c:
  sda: 21
  scl: 22
  scan: true
  id: bus_a

pcf8574:
  - id: 'pcf8574_hub'
    address: 0x27
    pcf8575: true
    
sensor:
  - platform: bme280
    temperature:
      name: "AC Intake Temperature"
      oversampling: 16x
      accuracy_decimals: 2
    pressure:
      name: "AC Intake Pressure"
      id: ac_ip_press
      accuracy_decimals: 2
    humidity:
      name: "AC Intake Humidity"
    address: 0x76
    update_interval: 30s
  - platform: bme280
    temperature:
      name: "AC Output Temperature"
      oversampling: 16x
      accuracy_decimals: 2
    pressure:
      name: "AC Output Pressure"
      id: ac_op_press
      accuracy_decimals: 2
    humidity:
      name: "AC Output Humidity"
    address: 0x77
    update_interval: 30s
  - platform: adc
    pin: GPIO32
    id: adc_1
    attenuation: auto
  - platform: ct_clamp
    sensor: adc_1
    name: "Damper Current Sensor"
    id: current_sensor
    update_interval: 1s
    accuracy_decimals: 4
  - platform: template
    name: "backpressure"
    id: ac_backpressure
    accuracy_decimals: 2
    lambda: |-
      return (id(ac_op_press).state - id(ac_ip_press).state);
    update_interval: 5s
    unit_of_measurement: hpa
    device_class: pressure


# Individual outputs
switch:
  - platform: gpio
    name: "DIR_1"
    id: dir_1
    pin:
      pcf8574: pcf8574_hub
      number: 1
      mode:
        output: true
      inverted: true
  - platform: gpio
    name: "DIR_2"
    id: dir_2
    pin:
      pcf8574: pcf8574_hub
      number: 3
      mode:
        output: true
      inverted: true
  - platform: gpio
    name: "DIR_3"
    id: dir_3
    pin:
      pcf8574: pcf8574_hub
      number: 5
      mode:
        output: true
      inverted: true
  - platform: gpio
    name: "EN_1"
    id: en_1
    pin:
      pcf8574: pcf8574_hub
      # Use pin A4
      number: 0
      mode:
        output: true
      inverted: true
    interlock: &interlock [en_1, en_2, en_3]
    interlock_wait_time: 500ms
  - platform: gpio
    name: "EN_2"
    id: en_2
    pin:
      pcf8574: pcf8574_hub
      # Use pin B4
      number: 2
      mode:
        output: true
      inverted: true
    interlock: *interlock
    interlock_wait_time: 500ms
  - platform: gpio
    name: "EN_3"
    id: en_3
    pin:
      pcf8574: pcf8574_hub
      # Use pin A5
      number: 4
      mode:
        output: true
      inverted: true
    interlock: *interlock
    interlock_wait_time: 500ms

# Example configuration entry
cover:
  - platform: current_based
    device_class: damper
    name: "Office and Kids Rooms Damper"
    id: cover1
    # disable malfunction detection due to common current sensor for open and close
    malfunction_detection: false

    open_sensor: current_sensor
    open_moving_current_threshold: 0.0065
    open_obstacle_current_threshold: 0.025
    open_duration: 14s
    open_action:
      - cover.stop: cover2
      - cover.stop: cover3
      - switch.turn_on: dir_1
      - switch.turn_on: en_1

    close_sensor: current_sensor
    close_moving_current_threshold: 0.0065
    close_obstacle_current_threshold: 0.025
    close_duration: 14s
    close_action:
      - cover.stop: cover2
      - cover.stop: cover3
      - switch.turn_off: dir_1
      - switch.turn_on: en_1

    stop_action:
      - switch.turn_off: en_1
      - switch.turn_off: dir_1

    obstacle_rollback: 10%
    start_sensing_delay: 1s

  - platform: current_based
    device_class: damper
    name: "Kitchen and Living Room Damper"
    id: cover2
    # disable malfunction detection due to common current sensor for open and close
    malfunction_detection: false
    # reverse to other damper for some reason
    open_sensor: current_sensor
    open_moving_current_threshold: 0.0065
    open_obstacle_current_threshold: 0.025
    open_duration: 14s
    open_action:
      - cover.stop: cover1
      - cover.stop: cover3
      - switch.turn_off: dir_2
      - switch.turn_on: en_2

    close_sensor: current_sensor
    close_moving_current_threshold: 0.0065
    close_obstacle_current_threshold: 0.025
    close_duration: 14s
    close_action:
      - cover.stop: cover1
      - cover.stop: cover3
      - switch.turn_on: dir_2
      - switch.turn_on: en_2

    stop_action:
      - switch.turn_off: en_2
      - switch.turn_off: dir_2

    obstacle_rollback: 10%
    start_sensing_delay: 1s

  - platform: current_based
    device_class: damper
    name: "Master Bedroon and Upstairs Livingroom Damper"
    id: cover3
    # disable malfunction detection due to common current sensor for open and close
    malfunction_detection: false
    # reverse to other damper for some reason
    open_sensor: current_sensor
    open_moving_current_threshold: 0.0055
    open_obstacle_current_threshold: 0.025
    open_duration: 14s
    open_action:
      - cover.stop: cover1
      - cover.stop: cover2
      - switch.turn_off: dir_3
      - switch.turn_on: en_3

    close_sensor: current_sensor
    close_moving_current_threshold: 0.0055
    close_obstacle_current_threshold: 0.025
    close_duration: 14s
    close_action:
      - cover.stop: cover1
      - cover.stop: cover2
      - switch.turn_on: dir_3
      - switch.turn_on: en_3

    stop_action:
      - switch.turn_off: en_3
      - switch.turn_off: dir_3

    obstacle_rollback: 10%
    start_sensing_delay: 1s