#deepsleep #deep-sleep (I think the community should have a deepsleep or similar tag, but I have no idea how to request for it to be added)
I have the E1002 from Seeed Studio with inbuilt battery. Have been trying to make optimisation to minimise power consumption on the device so to maximise battery life. The display shows some key stats around the place, refreshes regularly when I am home, and less regularly when I am not.
A few learnings here I thought I would share with the community. I think this type of power consumption optimisation is “every little bit helps” so there are multiple small ideas here.
WiFi Fast Connect and output power
The device is not far from router, can power down the transmission to the lowest possible 8.5dB. This caused absolutely no problems in connectivity reliability (that I can observe)
fast_connect is very handy - it doesnt do a scan before trying to connect. BUT I learnt that (at least paired with my router) when the ESP32 tries to connect to the router/AP the router declines the connection possibly because of some old key is used
actual error message: Disconnected ssid=‘SOMESSID’ bssid=[redacted] reason=‘Authentication Failed’
this failure happens twice without the fast_connect, three times when fast_connect is turned on. This makes the wifi connection time fairly long.
This is the basic configuration:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
min_auth_mode: wpa3
output_power: 8.5dB
fast_connect: true
manual_ip:
static_ip: 172.16.xxx.yyy
gateway: 172.16.xxx.1
subnet: 255.255.255.0
The way to solve the Authentication Failed problem is to disassociate from the router/AP (by disabling wifi) before going to deep sleep (see below). So when it wakes up again it will assume a fresh association and connection works first time. This reduces the WiFi connection time each time the device comes up from deep sleep from 6-15seconds to 1second consistently. That is many seconds potentially saved from having the ESP32 CPU powered up just waiting for WiFi (and the API connection). I have noticed that after the ESP32 wifi is disabled, the ESP32 device disappears from router’s client list - that confirms the ESP32 is disassociated from the router/AP.
Deep Sleep - basic setup
I have a default configuration for deep sleep - runs for 90 seconds, then sleep for 20 minutes. But in practice these are not used because they are overridden by instructions to go to sleep at the appropriate moment. This below is a slightly cleaned up basic deep_sleep configuration.
deep_sleep:
id: my_deep_sleep
run_duration: 90s
sleep_duration: 20min
When can the device go to sleep?
Home Assistant API is the key for the display refresh - the API must be connected for the ESP32 to obtain latest values from HA I want to display, and once all the values are fetched the display can immediately refresh, and the device can go to sleep ASAP after that.
The code below are commented to tell what each bit does. The section is the Home Assistant/ESPHome native API configuration:
api:
encryption:
key: !secret livingroom_eink_apikey
on_client_connected:
then:
- delay: 2s
# Check if sensors have data before updating display
- if:
condition:
lambda: |-
return !isnan(id(outdoor_temp).state) &&
!isnan(id(indoor_temp).state);
then:
- component.update: eink_display
- logger.log: "Display refreshed - all sensors valid"
else:
- logger.log: "Delaying display refresh - waiting for sensor data"
- delay: 3s
- component.update: eink_display
# this checks whether someone is home, and sets sleep period based on that
- lambda: |-
if (id(is_somebody_home_ha).state == "Someonehome") {
id(my_deep_sleep).set_sleep_duration(8 * 60 * 1000);
ESP_LOGD("deep_sleep", "Setting sleep to 8min - somebody home");
} else {
id(my_deep_sleep).set_sleep_duration(60 * 60 * 1000);
ESP_LOGD("deep_sleep", "Setting sleep to 60min - nobody home");
}
- delay: 20s #wait for the display to finish refreshing before sleeping - normally that is 17-18seconds from initiation to completion
- wifi.disable: #this is the magic that allows fast_connection to work
- deep_sleep.enter: #go to sleep!
Notes:
- there is still a large variability on when HA reaches out to the ESP32 for API connection and there is no way for the ESP32 to reach out to HA due to the architecture. I know there is way around that (MQTT). Maybe something to do next
- Many of the “delay” times that can probably be optimised and order of events can probably be optimised more (wifi can be turned off much earlier, maybe). To be tested - but I feel I have achieved most of the gains with the above already.
- in practice I dont think that else statement “Delaying display refresh - waiting for sensor data” is needed - as soon as the API is connected all the sensors seems to be pushed from HA to ESP32.
I hope some of these is helpful to someone.