I have a keypad connected to an ESP32 that its in deep sleep. With a button i wake it up, and then i type a code with the keypad.
As soon as the code is sent to HA i want to go to deep sleep again (i dont want to extra seconds waiting enough time, as i find it power consuming).
The problem is, with the current code, the ESP32 goes to deep sleep before sending the code. If i wait some seconds before sending the code, it works as expected.
So, what is a reliable way to wait just as much as needed before going to sleep? I tried api.connected, but it looks like its still not enough time to send the message.
I tried to make something out of this but it doesnt work (looks to stuck in wait_until forever):
#on esphome device
api:
encryption:
key: ""
actions:
- action: deep_sleep.enter: deep_sleep_1
#action on HA in an automation
action: esphome.nameofyouresp_deep_sleep.enter
I assume when you type in the digits the state of something changes and that could be used as a trigger to call the deepsleep action on the esphome device from HA. The action above in HA may need adjusted.
I do this with MQTT. When HA receives a payload it publishes a payload to a different topic. The esphome device is subscribed to this subject and on reception of this message it goes straight to deepsleep. It works very well in MQTT.
Thanks for the quick answer, although i didnt use MQTT it helped me through another way.
After a lot of searching, I found this very helpful. This worked fine for me after several adjustments and tests.
In order to help others the solution is:
Create a binary sensor in HA:
Go to Settings, Devices and services, Helpers, Toggle, name: prevent_deep_sleep, icon: mdi:sleep-on. A new helper with entity id: input_boolean.prevent_deep_sleep will be created.
Set this to ON and leave this to ON forever. Also, if you want to do OTA, you can prevent deep sleep by setting temporary to OFF.
The logic, is that the esphome device (i.e. ESP32) will wait forever until it can read this value from HA. This means that when it reads this sensor, it has established communication with HA. After that we can send our valuable data to HA and be sure it will reach it (the keypad code in my example).
In my esphome yaml:
binary_sensor:
- platform: homeassistant
id: prevent_deep_sleep
entity_id: input_boolean.prevent_deep_sleep
icon: "mdi:sleep-on"
entity_category: diagnostic
internal: False
...
key_collector:
- id: pincode_reader
source_id: mykeypad
min_length: 2
max_length: 4
end_keys: "#"
end_key_required: true
# back_keys: "C"
clear_keys: "*"
allowed_keys: "0123456789ABCD"
timeout: 25s
on_progress:
- lambda: id(keycode).publish_state(x.c_str());
on_result:
# turn off my display to save energy while waiting to connect to HA
- lambda: |-
id(myDisplay).turn_off();
# establish connection with HA
- wait_until:
condition:
- binary_sensor.is_on: prevent_deep_sleep
# must be after wait_until
- lambda: id(keycodeResult).publish_state(x.c_str());
- deep_sleep.enter:
id: deep_sleep_1
on_timeout:
- logger.log:
format: "input timeout: '%s', started by '%c'"
args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ]
Ensure the keypad code is correct.
Go to Developer settings, states in HA (http://HA_IP:8123/developer-tools/state) and see if the myKeycodeResult is correct (i found that the dashboard results are not refreshed immediately).