Getting state of cover in ESPHome

Hi everyone, is it possible to get in ESPHome the current state of the cover ?

Not the position, I would like to get whether the cover is moving (closing of opening) or it is stopped.
I tried getting all the states I could think of I used a service to log the states in various situations, from the cover to the switches that move the curtain, but I don’t seem to be able to get anything usable.

My goal is to have a service in ESPHome , available in HA, so that I can mimic a open-stop-close-stop button, so to get this in ESPHome I would need to know what the cover is doing in the service of esphome, but I don’t seem to get anything apart from the position.

Any hints really appreciated


Not sure if there’s an easier way, but you can use a lambda call with the cover component to retrieve state internally. Then create a text sensor for ha, and use the lambda to set the text sensor to the matching state. The bottom of the esphome cover docs should be a good hint as to how to do this.

^disregard the above^
I realized you can only get current position that way (I think). So you might be able to do this with a cover template. It has ways to do up/stop/down commands directly.

I used a timebased cover in esphome and it shows all states in HA including transitional states like opening and closing.

Please can you share what you did?

I’m not sure if I understood your question completely. After reading it again, it seems, you want to accomplish this within the ESPhome-Firmware.

I was reffering to all the states beeing accessible within HA.

The Time-Based Cover is documented in ESPhome-Doku:,Time-Based%20Cover,been%20moving%20in%20a%20direction.

Hi seanomat,

what I’m trying to do is to end up with a single button to drive a open-stop-close-stop sequence, to do so I need to store the last direction of movement, so that’s why I would need to do this from inside esphome.

The problem I’m finding is that I can’t seem to find a reliable way to check and store the info in globals , because in esphome the only state I can consistently get is the actual position of the cover


An alternative, and IMO, more reliable way would be to use a Shelly 2.5 to manage the cover from HA or ESPHome and can be configured for 1 button operation, going through a Open>Stop>Close>Stop>Open> sequence with each button press.

1 Like

I am actually using the shelly 2.5.
I created a timebased cover with it.





you can access the current state, save it to a global variable, and write your switch.


are you sure the current_operation is accessible ? I can only find it in the template cover.


I am successfully using it with my timebased cover.

Would you share some code ? I 'm having some real random results with globals in my time-based cover (I’m using a sonoff 4ch, which I think is not the problem), plus the .state is now flagged as deprecated when compiling

Thank you in advance


Sure. But I’m not trying to achieve, what you do. No use of global variables for example.
I have a shelly 2.5 that is connected to two physical momentary switches, one for up and one for down. In ESPhome, they are represented with a binary_sensor.

This is the cover:

  platform: time_based
  name: "${device_name}"
  id: cover1
#  optimistic: true
#  assumed_state: true
    - switch.turn_on: relay1
  open_duration: 25s
    - switch.turn_on: relay2
  close_duration: 25s
    - switch.turn_off: relay2
    - switch.turn_off: relay1

These are the actual relays:

  - platform: gpio
    name: "${device_name}_Relay_01"
    id: relay1
    pin: GPIO4
    interlock: &interlock [relay1, relay2]
    restore_mode: ALWAYS_OFF
  - platform: gpio
    name: "${device_name}_Relay_02"
    id: relay2
    pin: GPIO15
    interlock: *interlock
    restore_mode: ALWAYS_OFF

And this is the binary_sensor, that uses the operational state:

  - platform: gpio
      number: GPIO13
    name: "${device_name}_button_01"
      - lambda: |-
          if (id(cover1).current_operation == COVER_OPERATION_OPENING){
          else {
  - platform: gpio
      number: GPIO5
    name: "${device_name}_button_02"
      - lambda: |-
          if (id(cover1).current_operation == COVER_OPERATION_CLOSING){
          else {

Best of luck!


I see what you mean, infact my problem with globals is that I need to change them within the open/close/stop…_action part of the cover, to store the last movement direction, your lambda code is useful to stop the curtain midway, but it is still a two buttons control.

Well , let’s see where I can get to.

Thank you,


1 Like

Whenever you press your switch, it should evaluate the current state and take the desired action. It shouldn’t be too difficult to adjust the conditions accordingly. I’m not even sure if global variables would be required at all, as you can refer to the current state.

The problem with the 1-botton control, is that when the cover is stopped, it should remember the direction of the last movement, because since it is stopped it has no way of telling if the next step should be open or close.

You can look at my 1-botton control, maybe it will help you, but I used stepper.

Hi @mypost ,

lots to read here :grinning:

I will study this; never thought to use a template cover, but if I can convert it to work as a time-based one switched with relé, why not ?

Thank you a lot


1 Like

Any progress on this? I’m in the same situation