ESPhome and deep sleep

Hello,

I’ve just set up my first node using a Wemos D1 Mini and a DHT22, as a test. All worked perfectly. Then I added a static IP, as I was having issues and now, after some reading and repeating steps, that all seems fine. My next step was to install ‘deep sleep’ as I plan to run this node on 18650 batteries but it just does not work.

I’ve played around with the interval time of the DHT and I’ve changed the run and sleep durations but nothing works. I can see the Wemos is reconnecting to HA but no values are been transferred over. The dashboard remains blank, like it is never seeing a value. If I try and upload any code, when it has reconnected to HA, it can’t connect to the IP and throws an error out. If I reconnect the Wemos and flash with a cable, removing the sleep mode, OA updates can then be resumed.

I’ve read on other threads that the api of HA can take 60 seconds to reconnect/configure so I extended the awake time but nothing. Ideally I want the Wemos to sleep for 15/20 minutes and maybe wake up for 20 seconds, a minute at the longest. Reading online, this may not be possible.

Any input would be greatly appreciated


esphome:
  name: green_house
  platform: ESP8266
  board: d1_mini

wifi:
  ssid: ""
  password: ""

# Optional manual IP
  manual_ip:
    # Set this to the IP of the ESP
    static_ip: X.X.X.X
    # Set this to the IP address of the router. Often ends with .1
    gateway: X.X.X.X
    # The subnet of the network. 255.255.255.0 works for most home networks.
    subnet: X.X.X.X

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Green House Fallback Hotspot"
    password: ""
    



captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

# Example configuration entry
sensor:
  - platform: dht
    pin: D3
    model: DHT22
    temperature:
      name: "Green House Temperature"
    humidity:
      name: "Green House Humidity"
    update_interval: 10s
    
deep_sleep:
  run_duration: 120s
  sleep_duration: 15min

1 Like

Don’t use the api with deep sleep. Use mqtt.

1 Like

Ah okay. I’ll look into using that. I have mqtt setup and just assumed that worked automatically

There’s also a fast connect option for the wifi section that can reduce your connection times if you really want to cut down the time it is awake and you only have the one SSID.

fast_connect ( Optional , boolean): If enabled, directly connects to WiFi network without doing a full scan first. This is required for hidden networks and can significantly improve connection times. Defaults to off . The downside is that this option connects to the first network the ESP sees, even if that network is very far away and better ones are available.

Okay, brilliant. I’ll look into that also. Many thanks

Did you have this working? If so, would you please share your code? thanks

Hi, I did. I’ll post it up later once I’m finished with work.

1 Like

@laca75tn hey. I’m so sorry but I completely forgot about your request! Newish job and hectic couple of weeks.

Here it is. This is the test script which I got working and then I apply this to other applications when I want MQTT. Notice that ‘api’ is commented out, as it clashes with deep sleep as it can take a minute or two to connect to the HA api. Just adjust the sleep time accordingly.

I also set up a static ip, just to save hassle of that getting changed. Hope this helps, if not too late


captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
#api:

ota:

# Example configuration entry
sensor:
  - platform: dht
    pin: D3
    model: DHT22
    temperature:
      name: "Green House Temperature"
    humidity:
      name: "Green House Humidity"
    update_interval: 6s
    
deep_sleep:
  run_duration: 30s
  sleep_duration: 1min

mqtt:
  broker: 192.....
  username:
  password: 
  topic_prefix: /chris
  log_topic: /home/outside/greenhousetemperature
  birth_message:
   topic: /home/outside/greenhousetemperature
   payload: ""
  will_message:
   topic: /home/outside/greenhousetemperature
   payload: ""

5 Likes

Hi guys,

Is there a way that we can control deep sleep duration from home assistant?
I would like to set in home assistant duration for a deep sleep on a slider, don’t want to be hardcoded.

@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.