ESPHome custom Garage Door integration

Good Morning,

my Plan ist to integrate my toggle Button (up - stop - down - stop - up) operated Garage Doors into Homeassistant. For me it was essential to get two additional States:

  • opening / closing / stopped
  • Percentage of opening

My Idea was to get the opening / closing and percentage State of the Door from an encoder. State of the Encoder will be reset if Door hits Endstops to calibrate the Values on each complete cycle. The Encoder will finally be attached to the Motor shaft of the Garage Door by a toothed Belt.

First i asked a question about a new “on_stopped” trigger for Rotary Encoder integration of ESPHome on GitHub, but got helped to archivew this goal on another way. Feature Request is here.

Nagyrobi then asked me a question on how i wanted to properly combine that with a cover component - and here we are.

At first i planned to use the single entities and build a custom Card, but is there a better way to do this?

Here is the Code:

esphome:
  name: testdevice

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "gapzG2GR1h0OjvKWxKzDqjt0tUJoghl+a1kmTBpuVeg="

ota:
  password: "1a8050b50419c4c4e88fb2b20738e4cf"

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Testdevice Fallback Hotspot"
    password: "O4Pr0bsQvYvt"

captive_portal:

output:
  - platform: gpio
    pin: 32
    id: output1

button:
  - platform: output
    name: "Garage Door"
    output: output1
    duration: 500ms

binary_sensor:
  - platform: gpio
    name: "Door open"
    id: door_open
    pin:
      number: 33
      inverted: true
      mode:
        input: true
        pullup: true
    on_press:
      - sensor.rotary_encoder.set_value:
          id: encoder
          value: 500
  - platform: gpio      
    name: "Door closed"
    id: door_closed
    pin: 
      number: 25
      inverted: true
      mode:
        input: true
        pullup: true
    on_press:
      - sensor.rotary_encoder.set_value:
          id: encoder
          value: 0

sensor:
  - platform: template
    name: "Direction Sensor"
    id: direction_sensor 
     
  - platform: rotary_encoder
    name: "Öffnung"
    id: encoder
    min_value: 0
    max_value: 500
    on_clockwise:
      - sensor.template.publish:
          id: direction_sensor
          state: 1
      - script.execute: stopped
    on_anticlockwise:
      - sensor.template.publish:
          id: direction_sensor
          state: -1
      - script.execute: stopped
    pin_a:
      number: 12
      mode:
        input: true
        pullup: true
    pin_b: 
      number: 14
      mode:
        input: true 
        pullup: true 
    filters: 
    - lambda: |-
        auto first_mass = 100;
        auto first_value = 500;
        auto second_mass = 0;
        auto second_value = 5;

        auto r = map (x, first_value, second_value, first_mass, second_mass);
        if (r >0) return r;
        return 0;
    unit_of_measurement: "%"

script:
  - id: stopped
    mode: restart
    then:
      - delay: 500ms
      - sensor.template.publish:
          id: direction_sensor
          state: 0

Have you had a look at the cover component? It would be the same for a Garage door.

Yeah i did, but didnt find a Way to use my absolute position for the cover component. But perhaps im missing something here.