EspHome Cover Template for garage door >> multiple commands in actions

I’ve got a Wemos d1 Mini connected to my Hörmann Promatic 3 Garage door and am a bit stuck on implementing the cover within ESPHome…
The Garage Door has the typical “one-button-interface” for up-stop-down. I’m using 3 Relays as binory_sensor for detecting “Door fully closed”, “Door closing” and “Door opening”. I’d like to somehow chain some commands under open_action and close_action depending on the current state of the door (e.g.: door was closing, someone triggers open_action >>> button has to be pressed twice with a short delay inbetween)

This is the current code:

 globals:
  - id: last_direction
    type: int
    restore_value: false
    initial_value: '2'
    # 2= Neustart, 1=oeffnen, 0=schliessen

binary_sensor:
  - platform: gpio
    name: "garage_door_closed"
    id: garage_door_closed
    pin:
      number: GPIO12
      inverted: true
      mode:
        input: true
        pullup: true

  - platform: gpio
    name: "garage_door_opening"
    id: garage_door_opening
    pin:
      number: GPIO13
      inverted: true
      mode:
        input: true
        pullup: true

  - platform: gpio
    name: "garage_door_closing"
    id: garage_door_closing
    pin: 
      number: GPIO14
      inverted: true
      mode:
        input: true
        pullup: true
      
switch:
  - platform: gpio
    name: "Blue_LED_State"
    pin:
      number: GPIO2
      inverted: true
      mode:
        output: true
        pullup: false

  - platform: gpio
    name: "Relais_Pushbutton"
    id: relais_pushbutton
    pin: 
      number: GPIO5
      inverted: true
      mode: 
        output: True
        open_drain: True
    on_turn_on:
      - delay: 300ms
      - switch.turn_off: relais_pushbutton
    restore_mode: ALWAYS_OFF

cover:
  - platform: template
    name: Garagentor
    id: garatentor
    lambda: >-
      if ( id(garage_door_closed) ) {
        return COVER_CLOSED;
      }  else if ( !id(garage_door_closed) && !id(garage_door_closing) && !id(garage_door_opening) ) {
        return COVER_OPEN;
      } else if ( id(garage_door_closing) ) {
        return COVER_OPERATION_CLOSING;
      } else if ( id(garage_door_opening) ) {
        return COVER_OPERATION_OPENING;
      } else {
        return COVER_OPERATION_IDLE;
      }
    open_action:
      - switch.turn_on: relais_pushbutton
    close_action:
      - switch.turn_on: relais_pushbutton
    stop_action:
      - switch.turn_on: relais_pushbutton
    optimistic: true

What kind of circuit is that?
Also, what circuit is that open drain relais_pushbutton?

Can we assume that if all binary sensors are off, your gate is in static open state?

All inputs are made by a 24V DC-Relay module which pulls the input down. I’m detecting movement/direction by polarity of the motor with two relays (and diodes to prevent shortcuts). Door closed detection is realized by a 24V DC output on the drive which will then trigger one of my 24V Relays. The output is simply a ESP1-S Relay module(the only one which was laying around) without an ESP01, obviously.

So the open action could be:

    open_action:
      - if:
          condition:
            binary_sensor.is_on: garage_door_closing
          then:
            - switch.turn_on: relais_pushbutton
            - delay: 0.7s
            - switch.turn_on: relais_pushbutton
          else:
            - switch.turn_on: relais_pushbutton

Be aware that you have undefined state there if you operate the door also “manually”. You don’t actually know if door is open or stopped half-open.

Also, would be more reliable if you substitute all relays with optocouplers.

Agree to optocouplers being more reliable. I already tried to implement the time-base cover, but there’s no lambda in the template?
I’ll try your yaml for open_action. Will have to create a state-machine first.

Other question: Is it possible to define functions in ESPHome, which could be called instead of heaving redundant parts in the code?

I’m not sure what you mean here. Time based cover has the state calculated by duration parameter.

You can use script component.
https://esphome.io/components/script/

Hey!
my thoughts on this:
garage_door_closed >> Door fully closed
garage_door_closed && (garage_door_closing || garage_door_opening) >> should not happen
!garage_door_closed && garage_door_closing >> Door is closing
!garage_door_closed && garage_door_opening >> Door is opening
!garage_door_closed && !garage_door_closing && !garage_door_opening >> Not so simple. Door is somewhat open, but maybe not fully open. Need the delta time for garage_door_opening being active to determine the ~percentage

So I’d like to use the cover template and keep the duration of the last movement (and maybe the diffs). Therefore, multiple commands are needed in the actions but I failed simply on adding these…

This leads me to my main problem: I assume I know what I want to write… but yaml “bad indentation”-errors are driving me crazy.

Yeah, it’s PITA.
You could try some yaml editor with auto indentation.