ESPhome and deep sleep

@moci and @tom_l You could actually use this method…

Set up a ESP like this (code below) and it will subscribe to the message on the MQTT server, se it when it wakes up and take that value and set it to be the deep sleep duration value. Make sure the value you are sending as the topic however is in milliseconds.

I believe this call:

    on_value:
      then:
       - lambda: |-
          id(deep_sleep_1).set_sleep_duration(id(custom_sleep_time).state);

is not is not documented but it works fine for me :).

substitutions:
  devicename: wemos_weather_station
  friendly_devicename: weather station

esphome:
  name: $devicename
  platform: ESP8266
  board: d1_mini_pro

wifi:
  fast_connect: true
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: 192.168.1.201
    gateway: 192.168.1.1
    subnet: 255.255.255.0

# Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Wemos WS Fallback Hotspot"
    password: !secret ota_password

# NO API when using battery device
# api:
#   password: !secret api_password

mqtt:
  broker: '192.168.1.7'
  username: !secret mqtt_username
  password: !secret mqtt_password
  discovery: false
  discovery_retain: false
  birth_message:
  will_message:
  on_message:
    - topic: esp/ota_mode
      payload: 'ON'
      then:
        - deep_sleep.prevent: deep_sleep_1

# Enable logging
logger:
  level: INFO

ota:
  password: !secret ota_password

sensor:
  - platform: wifi_signal
    name: $friendly_devicename signal strength

  - platform: mqtt_subscribe
    name: "Sleep time topic"
    id: custom_sleep_time
    unit_of_measurement: ms
    accuracy_decimals: 0
    topic: esp/sleep_mode_time
    on_value:
      then:
       - lambda: |-
          id(deep_sleep_1).set_sleep_duration(id(custom_sleep_time).state);

switch:
  - platform: restart
    id: reboot_esp
    name: $friendly_devicename restart switch

deep_sleep:
  id: deep_sleep_1
  sleep_duration: 300s
  run_duration: 1s
6 Likes

I moved to different projects and didn’t pay attention. I wrote my code for this… But this is great :+1:. @runevad Thank you very much for sharing. Appreciate. I’ll try it.

I experiment with @runevad solution. It works for me. However I found some things that I don’t like.
First, here is mine code, it’s basically copy paste:

deep_sleep:
  id: deep_sleep_mode
  sleep_duration: 600s
  run_duration: 1s
  
switch:
  - platform: restart
    id: living_room_temperature_restart
    name: restart

mqtt:
  broker: '192.168.0.27'
  username: !secret mqtt_username
  password: !secret mqtt_password
  discovery: false
  discovery_retain: false
  birth_message:
  will_message:
  on_message:
    - topic: living-room-temperature/sensor/ota_update
      payload: 'ON'
      then:
        - deep_sleep.prevent: deep_sleep_mode
    
sensor:
  - platform: mqtt_subscribe
    name: "Deep Sleep Timer"
    id: deep_sleep_timer
    unit_of_measurement: min
    accuracy_decimals: 0
    topic: living-room-temperature/sensor/deep_sleep_timer/state
    on_value:
      then:
       - lambda: |-
          id(deep_sleep_mode).set_sleep_duration(id(deep_sleep_timer).state * 1000 * 60); 

  - platform: dht
    pin: D3
    model: DHT11
    temperature:
      name: "Temperature"
      accuracy_decimals: 2
    humidity:
      name: "Humidity"
      accuracy_decimals: 2
    update_interval: 2s

As you can see I set unit_of_measurement to minutes, but I compensate this in lambda expression.
Problem that I noticed is burst of messages which are catch in MQTT Broker when I listen topic:

living-room-temperature/sensor/deep_sleep_timer/state

Every time board wakes up it receives not one message, but the whole burst of spamming messages.
See here:

Anyone knows why is that and how to improve it?
Along with those messages, I can see debug traces spamming log when board restarted:

I think that this is not related with home assistant part, where I set deep sleep timer just once. I even disabled some automation I have for deep sleep timer.
I would say that sensor on device (mqtt_subscribe) actually enters a loop where it sets state and generate messages over again until board enters deep sleep. Could that be the reason? If so, how could be fixed?

@exiledyorkie I’m curious, if you still have this project working… How long were you able to keep the Wemos alive and reporting on one battery cycle? Thanks for your time! Do you have any pictures as well?

@exiledyorkie I too would be interested in how long your batteries lasted. What capacity and voltage info would be useful to know too.

Why no API with deep sleep? Are there known problems with this combination?
It works sort of for me, except that all sensors are most of the time marked as “unknown”, which is a bit annoying (expire_after is only available with mqtt, which I do not use atm) :slight_smile:

I m also interested to the API / deep sleep topic

If I remember rightly, it depends on how long the node is awake, as it can take a while to connect to wifi and make the API connection

Apparently there have been enhancements along the way and as long as your mdns is working similarly then API is a solid choice these days.

That was the feedback from one of the devs I had when I asked on Discord a while back.

Hmmm nice to know… :thinking:. Before (have not tested how it behaves nowadays) the issue was that you can’t get the API to behave with “keep alive”-settings. The moment the ESP goes down to sleep the sensorns and everything gets the state “Unavaliable” in Home Assistant (wich is the correct behaviour with the API since you want to know when the ESP is down).

But… this is not the best for like a weather station or similar projects when you (probably) want the sensors to be set to the latest state until a new value is sent and only be set to the state “Unavailiable” if no new value has been sent for a set period of time, the keep alive-setting.

1 Like

I believe that’s still the API behaviour (for my projects anyways). Haven’t double checked to confirm though.

I used a template in HA to normalise data coming from a weather station. Scrub out states you don’t want

I essentially use the method described at the below link, which uses API to prevent deep sleep from reoccurring. I haven’t fully implemented my final product, but the deep sleep/prevention works fine. It’s set to delay going back into deep sleep for 10s, and that seems to be plenty of time to connect to the api.

I haven’t played around with it enough to see how low I can get the delay to be, but 10s doesn’t seem that bad to me.

:battery: ESPHome: Batteries, Deep Sleep, and Over-the-Air Updates – Tatham Oddie

Hi, I’ve just tried to use that link - I got to this thread after trying to do the setup - exactly as described and I just get errors about not being allow to map id: when the yaml is parsed. Can you please share what you have done if it is something different?
I’m working with an esp8266 by that shouldn’t matter as I’m not getting past the binary_sensor/homeassistant config for some reason.

Relevant code below (also note that my helper boolean is created within Home Assistant, not the ESPHome YAML:

substitutions:
  device_name: water-pump-01
  name_: water_pump_01
  name_pretty: Water Pump
  # sleep parameters
  sleep_time: 10min

esphome:
  name: "${device_name}"
  platform: ESP8266
  board: esp01_1m
  on_boot:
    then:
      - script.execute: consider_deep_sleep

# --- DEEP SLEEP CONFIG ---
deep_sleep:
  id: deep_sleep_control
  sleep_duration: ${sleep_time}

# pull in Helper from Home Assistant for deep sleep config
binary_sensor:
  - platform: homeassistant
    id: prevent_deep_sleep
    name: Prevent Deep Sleep
    entity_id: input_boolean.prevent_deep_sleep

# deep sleep script
script:
  - id: consider_deep_sleep
    mode: queued
    then:
      - delay: 10s
      - if:
          condition:
            binary_sensor.is_on: prevent_deep_sleep
          then:
            - logger.log: 'Skipping sleep, per prevent_deep_sleep'
          else:
            - deep_sleep.enter: deep_sleep_control
      - script.execute: consider_deep_sleep

Hello everyone!

i need some help with deep sleep…
so i what to make doors to open at 7 in the morning and close in evening at 6.
i have “cover” to open and close doors and it already works… BUT… now i would
like to sleep between this two times…

im reading topics but i just dont get it how to set deep sleep to make it work.
(mostly is just wake up every 20min and go back to sleep after 15s)

This is what times when to open and close doors look like right now:


time:
  - platform: homeassistant       
    on_time:
      - seconds: 0
        minutes: 00
        hours: 07
        days_of_week: MON-SUN
        then:
          - cover.open: vrata_kurnik    
        
  - platform: homeassistant     
    on_time:
      - seconds: 0
        minutes: 0
        hours: 18
        days_of_week: MON-SUN
        then:
          - cover.close: vrata_kurnik

there is some more code but it is just buttons,relays and cover + stuff that
must be there…

someone may ask why… im planing to put it on battery + solar

Thanks in advance for any help :slight_smile:

You can look at deep_sleep.enter
until:

Thanks for your reply

yes i did find this… but didnt figured out where to put it and didnt find any more
detailed example… Do you mind giving me some more details? like do i just put it
in there between times i alredy have or do i need to compleatly replace what i
alredy have,…?

sorry if its a stupid question but i really cant figure it out or find what i am looking
for.

Thanks in advance

You could probably just add a delay action after this (however long it takes the cover to open) and then add the deep sleep action there too.

Similar to what I’ve done under time: here:

Thanks for your time. Your code looks very good.

for now i just did this and will test it out:

deep_sleep:
  id: deep_sleep_1
  run_duration: 30s

time:
  - platform: homeassistant     
    id: homeassistant_time

  - platform: homeassistant      
    on_time:
      - seconds: 5
        minutes: 00
        hours: 07
        days_of_week: MON-SUN
        then:
          - cover.open: vrata_kurnik   
          - delay: 25s
          - deep_sleep.enter:
             id: deep_sleep_1
             until: "18:00:00"
             time_id: homeassistant_time

  - platform: homeassistant    
    on_time:
      - seconds: 5
        minutes: 00
        hours: 18
        days_of_week: MON-SUN
        then:
          - cover.close: vrata_kurnik 
          - delay: 25s             
          - deep_sleep.enter:
             id: deep_sleep_1
             until: "07:00:00"
             time_id: homeassistant_time

will later add things if needed. would love to hear any pro tip / comment on what i have right now :slight_smile:

Thanks again

1 Like