Deep Sleep even with "deep_sleep.prevent"

Deep Sleep on an ESP32 is driving me nuts. This is on an M5Stack Core Ink, here is the relevant config.

deep_sleep:
  id: deep_sleep_mode
  run_duration: 60s 
  sleep_duration: 1min 

esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  name_add_mac_suffix: false
  project:
    name: esphome.web
    version: '1.0'
  on_boot:
    priority: -100
    then:
      - wait_until:
          condition:
            wifi.connected
      - delay: 60s
      - deep_sleep.enter: deep_sleep_mode

binary_sensor:
  - platform: gpio
    id: bnt_left
    name: BTN Left
    pin: GPIO37
    on_press:
      then:
        - logger.log: "LEFT was pressed - No Sleep"
        - deep_sleep.prevent: deep_sleep_mode
  - platform: gpio
    id: bnt_right
    name: BTN Right
    pin: GPIO39
    on_press:
      then:
        - logger.log: "Right was pressed - Sleep Resumed"
        - deep_sleep.allow: deep_sleep_mode

As far as I understand, this should mean that the ESP32 will start and stay awake for 60s, deep sleep for 60s, wakes up for 60s…repeat. If I press the “Left” button, it will no longer deep sleep, until I press right. But that is simply not the case, as shown below:

The code snipped is the only code in my entire project related to deep_sleep. It shows the log “LEFT was pressed - No Sleep” then seconds later sleeps anyways. What in the name of PEBKAC am I missing?

I think what might be happening here is that the deep_sleep.prevent actually only blocks deep sleep enters triggered by the run_duration (not the deep_sleep.enter).

I think I was caught out by this in the past and the docs aren’t so clear about this.

So you could for example create a template switch (or binary sensor) to track the desired deep sleep prevent state, set it from your physical buttons, and then add an if condition into this bit.

deep_sleep.enter: deep_sleep_mode

You’ll see a lot of people find it more to useful create this helper on the HA side (rather than in ESPHome) and import it so that you can pre-set it in advance while the esp is still asleep. Google around on that. There’s plenty of examples.

So the answer here is that the deep_sleep.prevent does nothing to the on_boot sleep block. Which is silly and not documented, but ok.

But the real answer here is that the on_boot block AND the top level deep_sleep: block are redundant. I removed the on_boot and everything is working normally.

1 Like

I’m probably just re-stating the obvious, but I believe that what is happening is that the deep_sleep: section sets up a default pattern of 1 minute on and 1 minute off.

This is modified with the deep-sleep_prevent and deep_sleep_allow … exactly as you expected.

The deep_sleep_enter command is executed immediately - despite the current state of the deep-sleep cycle, and over-riding the deep_sleep_prevent. The deep_sleep_enter happens 60 seconds after the wi-fi connects … which i think will mostly happen after the default 1 minute awake period … and so will probably only be noticed while the left button is pressed.

To get the operation you expected, just remove the on_boot section. Note however that if wi-fi doesn’t connect quickly, it is possible the ESP will go back to sleep before it gets a chance to report any values to HA, and they will get lost.

This is where having deep_sleep_enter in the on_boot: ensures that ESPHome will get 1 minute to report values before going back to sleep. If you prefer this option, remove the run_duration from deep_sleep (or set to a high value as a backup).
If you want the Left and Right buttons to affect this operation, check the status in on_boot before calling deep_sleep_enter.