My Garage Door: I have cover states Open, Opening, Closing and Closed using a D1 Mini and two reed switches plus a WS2812 LED strip indicating parking position

Nice. I do a lot with presense too but, it just doesnt alwsys work right or it doesnt update fast enough for me. My other problem with doing presense alone is my daughter and I ride bikes alot, ride the golf cart or walk the dog, etc. I dont always and by choice carry my phone. Something small i can put in my pocket to shut the door or arm alarm was something else i liked about having an rf remote. To each his own though! The ability for everyone to make what works for them, thats the beauty of HA.

Has anyone used this code with the ratgdo door opener? The only entities i could us is cover.ratgdov25i_ee88b2_door which shows if closed or open. I also have the light.ratgdov25i_ee88b2_light entity which turns on when door opens then turns off 30sec later. Would i have to change a lot of dburnts code for it to work?

That entity alone is not enough. My code is based on an ESP32 with two door sensors: one indicates closed/not closed and the other open/not open.

Hi.
Is your integration still works?

Any chances you could share your ymal with me?

I do have esp32 and would like to operate my garage door with two sensors.

Thanks Andy.

Here you go…

esphome:
  name: my-garage-door
  friendly_name: My Garage Door
  on_boot:
    priority: 100
    then:
      - binary_sensor.template.publish:
          id: open_movement_sensor
          state: False
      - binary_sensor.template.publish:
          id: close_movement_sensor
          state: False
      - if: 
          condition:
            binary_sensor.is_on:
              id: open_contact_sensor
          then:
            light.turn_on:
              id: parking_light_indicator
              effect: Slow Pulse
              brightness: 100%
              red: 100%
              green: 0%
              blue: 0%
        
esp8266:
  board: d1_mini
  restore_from_flash: True

logger:

api:
  encryption:
    key: "<redacted>"

ota:
  - platform: esphome
    password: "<redacted>"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  ap:
    ssid: "Distance-Sensor Fallback Hotspot"
    password: "<redacted>"

captive_portal:

binary_sensor:
  - platform: template
    name: Vehicle
    device_class: presence
    lambda:
      if (id(parking_sensor).state < id(yellow_trigger_level).state) {
        return true;
      } else {
        return false;
      }

  - platform: gpio
    pin:
      number: D5
      mode: INPUT_PULLUP
      inverted: True
    name: "is Open"
    id: open_contact_sensor
    disabled_by_default: True
    internal: False
    on_press:
      - then:
        - binary_sensor.template.publish:
            id: open_movement_sensor
            state: False
        - binary_sensor.template.publish:
            id: close_movement_sensor
            state: False
        - sensor.duty_time.reset: parking_light_duty_time
        - light.turn_on: 
            id: parking_light_indicator
            effect: Scan Effect
#            effect: Red Color Wipe
            brightness: 50%
            red: 100%
            green: 0%
            blue: 0%

    on_release:
      - binary_sensor.template.publish:
          id: close_movement_sensor
          state: True

  - platform: template
    name: "is Opening"
    id: open_movement_sensor
    disabled_by_default: True
    on_press:
      then:
        - sensor.duty_time.reset: parking_light_duty_time
        - light.turn_on: 
            id: parking_light_indicator
            effect: Blue Progress
            brightness: 100%
    
  - platform: gpio
    pin:
      number: D6
      mode: INPUT_PULLUP
      inverted: True
    name: "is Closed"
    id: closed_contact_sensor
    disabled_by_default: True
    internal: False
    on_press:
      then:
        - sensor.duty_time.reset: parking_light_duty_time
        - light.turn_off:
            id: parking_light_indicator
        - binary_sensor.template.publish:
            id: open_movement_sensor
            state: False
        - binary_sensor.template.publish:
            id: close_movement_sensor
            state: False
    on_release:
      - sensor.duty_time.start: parking_light_duty_time
      - binary_sensor.template.publish:
          id: open_movement_sensor
          state: True

  - platform: template
    name: "is Closing"
    id: close_movement_sensor
    disabled_by_default: True
    on_press:
      then:
        - sensor.duty_time.reset: parking_light_duty_time
        - light.turn_on:
            id: parking_light_indicator
            effect: Erase
        - delay: 600ms
        - light.turn_on:
            id: parking_light_indicator
            effect: Yellow Progress
            brightness: 100%
            red: 0%
            green: 0%
            blue: 0%

cover:
  - platform: feedback
    name: "Garage Door"
    id: endstop_cover
    device_class: garage
    has_built_in_endstop: True
    max_duration: 12s

    open_action:
      - switch.turn_on: relay
    open_duration: 10s
    open_endstop: open_contact_sensor
    open_sensor: open_movement_sensor

    close_action:
      - switch.turn_on: relay
    close_duration: 10s
    close_endstop: closed_contact_sensor
    close_sensor: close_movement_sensor

    stop_action:
      - switch.turn_on: relay

light:
  - platform: neopixelbus
    variant: WS2812
    pin: D8
    num_leds: 30
    type: grb
    name: "Parking Light Indicator"
    id: parking_light_indicator
    restore_mode: ALWAYS_OFF
    effects:
      - pulse:
          name: "Slow Pulse"
          transition_length: 500ms
          update_interval: 750ms
          min_brightness: 0%
          max_brightness: 100%
      - pulse:
          name: "Fast Pulse"
          transition_length: 50ms
          update_interval: 100ms
          min_brightness: 0%
          max_brightness: 100%
      - addressable_scan:
          name: "Scan Effect"
          move_interval: 15ms
          scan_width: 5
      - addressable_color_wipe:
          name: Blue Progress
          colors:
            - red: 0%
              green: 0%
              blue: 100%
              num_leds: 30
          add_led_interval: 300ms
          reverse: False
      - addressable_color_wipe:
          name: Yellow Progress
          colors:
            - red: 100%
              green: 100%
              blue: 0%
              num_leds: 30
          add_led_interval: 300ms
          reverse: True
      - addressable_color_wipe:
          name: Erase
          colors:
            - red: 0%
              green: 0%
              blue: 0%
              num_leds: 30
          add_led_interval: 15ms
          reverse: False

sensor:
  - platform: duty_time
    id: parking_light_duty_time
    name: Parking Light Duty Time
    update_interval: 1s
    lambda: "return id(closed_contact_sensor).state == false;"
    restore: false
    last_time:
      name: Parking Light Last Turn-On Time
    on_value_range:
      above: 60
      then:
        - light.turn_off: parking_light_indicator

  - platform: ultrasonic
    id: parking_sensor
    trigger_pin: D1
    echo_pin: D2
    unit_of_measurement: "m"
    accuracy_decimals: 1
    update_interval: 1s
    timeout: 4.0m
    pulse_time: 10us
    filters:
      - delta: .02
    on_value:
      then:
        - if:
            condition:
              and:
                - binary_sensor.is_on: open_contact_sensor
                - sensor.duty_time.is_running: parking_light_duty_time
            then:
              - if:
                  condition:
                    - lambda: |-
                       return id(red_trigger_level).state < id(parking_sensor).state;
                    - lambda: |- 
                       return id(parking_light_duty_time).state < 60;
                  then:
                    light.turn_on: 
                      id: parking_light_indicator
                      effect: Slow Pulse
                      brightness: 100%
                      red: 100%
                      green: 0%
                      blue: 0%
              - if:
                  condition:
                    - lambda: |-
                       return (id(green_trigger_level).state < id(parking_sensor).state && id(parking_sensor).state < id(red_trigger_level).state);
                    - lambda: |- 
                       return id(parking_light_duty_time).state < 60;
                  then:
                    light.turn_on: 
                      id: parking_light_indicator
                      effect: none
                      brightness: 100%
                      red: !lambda |-
                        return ((id(parking_sensor).state - id(green_trigger_level).state) / (id(red_trigger_level).state - id(green_trigger_level).state));
                      green: !lambda |-
                        return ((id(red_trigger_level).state - id(parking_sensor).state) / (id(red_trigger_level).state - id(green_trigger_level).state));
                      blue: 0%
              - if:
                  condition:
                    - lambda: |-
                       return  id(parking_sensor).state < id(green_trigger_level).state and id(parking_sensor).state < id(green_trigger_level).state - 0.2;
                    - lambda: |- 
                       return id(parking_light_duty_time).state < 60;
                  then:
                    - light.turn_on: 
                        id: parking_light_indicator
                        effect: Fast Pulse
                        brightness: 100%
                        red: 0%
                        green: 100%
                        blue: 0%
                    - delay : 1s
                    - light.dim_relative:
                        id: parking_light_indicator
                        relative_brightness: 50%
                        transition_length: 5s
              - if:
                  condition:
                    - lambda: |-
                       return  id(parking_sensor).state < id(green_trigger_level).state - 0.2;
                    - lambda: |- 
                       return id(parking_light_duty_time).state < 60;
                  then:
                    - light.turn_on:
                        id: parking_light_indicator
                        effect: none
                        brightness: 75%
                        red: 0%
                        green: 100%
                        blue: 0%

  - platform: copy
    name: 'parking_sensor'
    source_id: parking_sensor
    filters:
      - delta: 0.05

  - platform: homeassistant
    name: "Red Trigger Level"
    id: "red_trigger_level"
    entity_id: input_number.red_trigger_level

  - platform: homeassistant
    name: "Yellow Trigger Level"
    id: "yellow_trigger_level"
    entity_id: input_number.yellow_trigger_level

  - platform: homeassistant
    name: "Green Trigger Level"
    id: "green_trigger_level"
    entity_id: input_number.green_trigger_level

switch:
  - platform: gpio
    pin: D7
    name: "Garage Door Relay"
    id: relay
    internal: False
    # Toggle the relay with a 0.5s pulse simulating a manual button press
    on_turn_on:
    - delay : 500ms
    - switch.turn_off: relay

time:
  - platform: sntp
    id: my_time
1 Like

Thank you for your reply!
I end up implementing cover in ESPHome and works ok from HA and even from HomeKit. Only one issue is when I’m using wall switch, not updating state at all.
Any chances to implement this?
Im using 16 IN/OUT (esp32) module, so maybe I was thinking of using x2 spares inputs as a wall switch to integrate this.
Could you please support me?
Please see my yaml:

esphome:
  name: kc868-a16

esp32:
  board: esp32dev
  framework:
    type: esp-idf

wifi:
  ssid: xxx
  password: xxx
# Enable fallback hotspot (captive portal) in case wifi connection fails
  
captive_portal:

logger:

# Enable Home Assistant API
api:
  encryption:
    key: "xxx
ota:
  - platform: esphome
    password: xxx



uart:
  - id: rs485
    tx_pin: GPIO13
    rx_pin: GPIO16
    baud_rate: 9600

remote_receiver:
  pin:
    number: GPIO2
    ignore_strapping_warning: true

remote_transmitter:
  pin:
    number: GPIO15
    ignore_strapping_warning: true
  carrier_duty_percent: 100%

i2c:
  sda: GPIO4
  scl:
    number: GPIO5
    ignore_strapping_warning: true

pcf8574:
  - id: inputs_1_8
    address: 0x22
  - id: inputs_9_16
    address: 0x21
  - id: outputs_1_8
    address: 0x24
  - id: outputs_9_16
    address: 0x25

sensor:
  - platform: adc
    name: "KC868-A16-HT1"
    pin:
      number: GPIO32
      inverted: true

  - platform: adc
    name: "KC868-A16-HT2"
    pin:
      number: GPIO33
      inverted: true
      
  - platform: adc
    name: "KC868-A16-A1"
    pin: GPIO36
   
  - platform: adc
    name: "KC868-A16-A2"
    pin: GPIO34
    
  - platform: adc
    name: "KC868-A16-A3"
    pin: GPIO35

  - platform: adc
    name: "KC868-A16-A4"
    pin: GPIO39
    
binary_sensor:
  - platform: gpio
    name: "KC868-A16-X01"
    id: in_x01
    pin:
      pcf8574: inputs_1_8
      number: 0
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-X02"
    id: in_x02
    pin:
      pcf8574: inputs_1_8
      number: 1
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-X03"
    id: in_x03
    pin:
      pcf8574: inputs_1_8
      number: 2
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-X04"
    id: in_x04
    pin:
      pcf8574: inputs_1_8
      number: 3
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-X05"
    id: in_x05
    pin:
      pcf8574: inputs_1_8
      number: 4
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-X06"
    id: in_x06
    pin:
      pcf8574: inputs_1_8
      number: 5
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-X07"
    id: in_x07
    pin:
      pcf8574: inputs_1_8
      number: 6
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-X08"
    id: in_x08
    pin:
      pcf8574: inputs_1_8
      number: 7
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-X09"
    id: in_x09
    pin:
      pcf8574: inputs_9_16
      number: 0
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-X10"
    id: in_x10
    pin:
      pcf8574: inputs_9_16
      number: 1
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-X11"
    id: in_x11
    pin:
      pcf8574: inputs_9_16
      number: 2
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-X12"
    id: in_x12
    pin:
      pcf8574: inputs_9_16
      number: 3
      mode: INPUT
      inverted: true
      
  - platform: gpio
    name: "KC868-A16-X13"
    id: in_x13
    pin:
      pcf8574: inputs_9_16
      number: 4
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-X14"
    id: in_x14
    pin:
      pcf8574: inputs_9_16
      number: 5
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-X15"
    id: in_x15
    pin:
      pcf8574: inputs_9_16
      number: 6
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-X16"
    id: in_x16
    pin:
      pcf8574: inputs_9_16
      number: 7
      mode: INPUT
      inverted: true

switch:
  - platform: gpio
    name: "KC868-A16-Y01"
    id: out_y01
    pin:
      pcf8574: outputs_1_8
      number: 0
      mode: OUTPUT
      inverted: true
      
  - platform: gpio
    name: "KC868-A16-Y02"
    id: out_y02
    pin:
      pcf8574: outputs_1_8
      number: 1
      mode: OUTPUT
      inverted: true
    on_turn_on:
      - delay : 5s
      - switch.turn_off: out_y02

  - platform: gpio
    name: "KC868-A16-Y03"
    id: out_y03
    pin:
      pcf8574: outputs_1_8
      number: 2
      mode: OUTPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-Y04"
    id: out_y04
    pin:
      pcf8574: outputs_1_8
      number: 3
      mode: OUTPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-Y05"
    id: out_y05
    pin:
      pcf8574: outputs_1_8
      number: 4
      mode: OUTPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-Y06"
    id: out_y06
    pin:
      pcf8574: outputs_1_8
      number: 5
      mode: OUTPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-Y07"
    id: out_y07
    pin:
      pcf8574: outputs_1_8
      number: 6
      mode: OUTPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-Y08"
    id: out_y08
    pin:
      pcf8574: outputs_1_8
      number: 7
      mode: OUTPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-Y09"
    id: out_y09
    pin:
      pcf8574: outputs_9_16
      number: 0
      mode: OUTPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-Y10"
    id: out_y10
    pin:
      pcf8574: outputs_9_16
      number: 1
      mode: OUTPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-Y11"
    id: out_y11
    pin:
      pcf8574: outputs_9_16
      number: 2
      mode: OUTPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-Y12"
    id: out_y12
    pin:
      pcf8574: outputs_9_16
      number: 3
      mode: OUTPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-Y13"
    id: out_y13
    pin:
      pcf8574: outputs_9_16
      number: 4
      mode: OUTPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-Y14"
    id: out_y14
    pin:
      pcf8574: outputs_9_16
      number: 5
      mode: OUTPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-Y15"
    id: out_y15
    pin:
      pcf8574: outputs_9_16
      number: 6
      mode: OUTPUT
      inverted: true

  - platform: gpio
    name: "KC868-A16-Y16"
    id: out_y16
    pin:
      pcf8574: outputs_9_16
      number: 7
      mode: OUTPUT
      inverted: true
cover:
  - platform: endstop
    name: "Garage Gate"

    open_action:
      - switch.turn_on: out_y03
    open_duration: 40sec
    open_endstop: in_x01

    close_action:
      - switch.turn_on: out_y04
    close_duration: 40sec
    close_endstop: in_x02

    stop_action:
      - switch.turn_off: out_y03
      - switch.turn_off: out_y04

type or paste code here

I’d like to but I’m not all that familiar with esp32. I’m just good at figuring things out when I have to but I really don’t have time right now to help. That said, have you had a look at this post?