Migrating Cover from Tasmota to ESPHome

Last night my tasmota based garage door opener died, and I decided to change to ESPHome. One thing that I really miss and cant figure out is how to get the moving state of the garage door, how do I know if I actually hit the button without waiting the 35seconds for the high lift garage door to trigger on the door open limit switch?

In tasmota i had states Closed, Opening, Open and Closing… and also Stopped once the function timed out after 35seconds without reaching the limit switch, but I think that gave warnings. these states seem to be reflected with the icons on my dashboard changing.

here is my current setup in ESPHome

switch:
  - platform: gpio
    pin:
      number: D6
      inverted: true
    id: relay_pin
    # If ESP reboots, do not attempt to restore switch state
    restore_mode: always off
    on_turn_on:
    - delay: 500ms
    - switch.turn_off: relay_pin
    
binary_sensor:
  - platform: gpio
    pin:
      number: D2
      mode:
        input: true
        pullup: true
    name: "Garage Door Open Reed"
    id: open_switch
    filters:
      - delayed_on: 10ms
      - delayed_off: 10ms
  - platform: gpio
    pin:
      number: D1
      mode:
        input: true
        pullup: true
    name: "Garage Door Close Reed"
    id: close_switch
    filters:
      - delayed_on: 10ms
      - delayed_off: 10ms
    
cover:
  - platform: template
    name: "Garage Door"
    device_class: garage
    lambda: |-
      if (id(close_switch).state) {
        return COVER_CLOSED;
      } else if (id(open_switch).state) {
        return COVER_OPEN;
      } else {
        return {};
      }
    open_action:
      - switch.turn_on: relay_pin
    close_action:
      - switch.turn_on: relay_pin
    stop_action:
      - switch.turn_on: relay_pin
    optimistic: true

So thinking aloud an option would be to define a global, called Garage_State
and set the global using something along the lines of

garage door open reed → on press → set Garage_State = “open”
garage door open reed → on release → set Garage_State = “closing”
garage door close reed → on press → set Garage_State = “closed”
garage door close reed → on release → set Garage_State = “opening”

then for both of the on release start a 35sec timer, which when expires then set the state to stopped

I would also like some sort of interlock so if the state is opening or closing then the open and close actions wont work, only the stop action.

Is there a better way to do this? can it be done directly in the lambda?

the endstop cover is almost perfect, however i need to check the stop action and if it get triggered when a endstop is reached, perhaps setting the stop action to do nothing will work? but then how do i stop the door if something is in the way? and ideally send a notification if it doesnt open/close within the time limit… hmm

Given you know the time it takes to open/close, would a time based cover work better? Time Based Cover — ESPHome

I would prefer to compare the usual time to the limit switches to identify if the door has not closed or opened correctly.

the end stop cover is working ok at the moment, it at least gives me the opening/closing status. its doing my head in though because every time I try and wireless flash the device it wont connect to wifi after the update, but USB with same code works every time. I’ve had to pull out the ladder 5 times tonight!

I will need to dig into the source code to make it work for me I think, a bit of cut and paste magic to create my own custom cover!.

What I need is

  • the stop command to not be triggered at the end stops. as my door opener has its own independent limit switches built in and will auto stop at required places
  • the stop command to send a single button press to stop the door wherever it is (only when opening/closing, do nothing if closed or open)
  • an alert/status Boolean set if the door takes longer than the maximum time to open.
  • recording of open/close times over time… to see if its slowing down as the spring loses tension etc.
  • do the alert/time recording if triggered by esphome OR with the remote control directly to the opener…

For testing I want to make a copy of the endstop_cover and then modify it to suit. Whats the best way to do this?

i tried copying the 3 files cover.py, endstop_cover.cpp and endstop_cover.h to my custom components folder. i renamed them to endswitch_cover… and updated the classes etc in the files to match, replacing endstop with endswitch and EndstopCover with EndswitchCover. i updated the namespace too so to not conflict with the standard ones

im getting the error

File "/config/esphome/custom_components/cover.py", line 18, in <module>
    EndswitchCover = endswitch_ns.class_("EndswitchCover", cover.Cover, cg.Component)
AttributeError: partially initialized module 'esphome.components.cover' has no attribute 'Cover' (most likely due to a circular import)
Failed config

edit: the files in the custom components i created above seem to have messed up the cover component in all my devices, not just the one with the include. so i have removed them as clearly i have no idea what im doing!

But still i have the issue that neither the template cover or endstop cover are fit for purpose. i have discovered today that the manual opening and closing of the door messes up the endstop cover, it loses track of where it is, making the limit switches pointless. i would have thought my setup would be pretty standard for a retrofit to an old remote control garage door opener or gate opener?

the template cover turned out to be a better option as the endstop cover gave problems when opened via the remote

hopefully this will help someone, the setup is simple, a cheap relay module (mine requires the GPIO to be inverted) connected to D6, and 2x door reed switches, connected to GND and D1/D2. the reed switches are cabletied to the main bar and the magnets to the chain at the right places for open and close.

the current_operation gets updated by the reed switches opening, and the state is just as per the template cover lambda. this is the bit that was missing in my original post, and should be included in the example on ESP home

switch:
  - platform: gpio
    pin:
      number: D6
      inverted: true
    id: relay_pin
    # If ESP reboots, do not attempt to restore switch state
    restore_mode: always off
    on_turn_on:
    - delay: 500ms
    - switch.turn_off: relay_pin
    
binary_sensor:
  - platform: gpio
    pin:
      number: D2
      mode:
        input: true
        pullup: true
    name: "Garage Door Open Reed"
    id: open_switch
    filters:
      - delayed_on: 50ms
      - delayed_off: 50ms
    on_release:
      - cover.template.publish:
          id: garage_door
          current_operation: "closing"
    on_press:
      - cover.template.publish:
          id: garage_door
          current_operation: "idle" 
  - platform: gpio
    pin:
      number: D1
      mode:
        input: true
        pullup: true
    name: "Garage Door Close Reed"
    id: close_switch
    filters:
      - delayed_on: 50ms
      - delayed_off: 50ms
    on_release:
      - cover.template.publish:
          id: garage_door
          current_operation: "opening"
    on_press:
      - cover.template.publish:
          id: garage_door
          current_operation: "idle"    
      
cover:
  - platform: template
    name: "Garage Door"
    id: garage_door
    device_class: garage
    lambda: |-
      if (id(close_switch).state) {
        return COVER_CLOSED;
      } else if (id(open_switch).state) {
        return COVER_OPEN;
      } else {
        return {};
      }
    open_action:
      - switch.turn_on: relay_pin
    close_action:
      - switch.turn_on: relay_pin
    stop_action:
      - switch.turn_on: relay_pin
    optimistic: true

next version will log the open/close times and send notifications if it takes longer than expected to open or close

If you have reed switch, then End stop Cover is more suitable for you.
This will help you

endstop cover has some limitations for my application as described above. I think its more designed if you are fitting it to a cover where the ESP controls the motor.

in my use case I want to leave the original system as-is, the original system includes the current sensing/auto reverse when closing on something, and the built in limit switches that control how far the door opens before it comes off the rails etc.

I want to make the door a little more connected, so I can remotely open it to let visitors in to borrow tools, or check that its actually closed after I left. there is only the 2 inputs for open and closed and a relay to “press the button” to toggle the door, or stop it if opening or closing

Having said that the endstop cover is probably a better starting point for my application, and I was trying to figure out how to make an offline version of it to hack about with. if anyone can help me set that up as per my post 4 above