Pulling my hair with ESPHome today, in so many ways

Terrible title, sorry for that. I keep getting frustratingly odd results.

Trying to add a new ESP32 module to my stable today. A TTGO T-Higrow with a set of sensors for air and soil measurements. It has a wake-up button connected to GPIO35.

I’ll rant about two issues – if anyone has ideas for what is happening here and how to fix it, I’m all ears.

Loosely based some of this on this post: 🔋 ESPHome: Batteries, Deep Sleep, and Over-the-Air Updates – Tatham Oddie

Issue 1, fetching data from HA. I can’t seem to fetch any sensor or state data from Home Assistant. I want a native way to block deep sleep when necessary. Was trying to use a helper entity, but even a regular sensor or input entity doesn’t seem to work for me. Tried the simple way as in the example above. Tried to force some kind of fetch of state with lambda, and even calls to id(xxx).setup(). Can’t get anything, from any type of HA entity, this way. I have another ESP8266 running a display, which fetches data from variables it itself updates, and that works fine. I haven’t updated that in a while though, since I’m now worried maybe it’ll break.

Issue 2, deep sleep. I want to dynamically call deep sleep via deep_sleep.enter using a configured deep_sleep component, to allow for some logic for when to sleep (relevant once issue 1 above is resolved). However, only some of the configuration in this deep_sleep component seems to be applied, and somewhat weirdly. First, “sleep_duration” in the deep_sleep component is not used when called this way, so I need to specify a duration in the “deep_sleep.enter” call. Second, I try to add a wakeup via the button connected to GPIO35. Not sure how this is wired on the board. Reading the variable gives a default-high state, so seems to be using a pull-up. When I configure “wakeup_pin: GPIO35” for the deep_sleep component, it always interrupts the deep sleep immediately. Even with “wakeup_pin_mode” at (what’s supposedly the default) “IGNORE”, it wakes up immediately. Configuring the pin as “inverted: true” doesn’t do anything for the deep_sleep mode.

esphome:
  name: esp32module
  on_boot:
    then:
      - script.execute: consider_deep_sleep

binary_sensor:
  - platform: gpio
    id: gpio_wakeup_pin
    pin:
      number: GPIO35
      mode:
        input: true
      ##mode: INPUT_PULLUP
      ## GPIO35 does not support setting pullup or pulldown mode in software
      ## but, seems to already be pulled up on this board so may need to set inverted to true for a default-low state
      inverted: true
    name: "Wake Button"
    internal: true

deep_sleep:
  id: deep_sleep_control
  sleep_duration: 15s
  wakeup_pin: GPIO35

script:
  - id: consider_deep_sleep
    mode: queued
    then:
      - delay: 10s
      - logger.log: 'Entering sleep'
      - deep_sleep.enter:
          id: deep_sleep_control
          sleep_duration: 15s
      - script.execute: consider_deep_sleep

End rant. Suggestions welcome.

Running HA 2022.2.5, and ESPHome 2022.2.6.

Seeing some error logging output from the web API. No idea whether they are related to this specific ESP device, nor how to confirm this…

Logger: homeassistant.components.websocket_api.http.connection
Source: components/websocket_api/http.py:126
Integration: Home Assistant WebSocket API ([documentation](https://www.home-assistant.io/integrations/websocket_api), [issues](https://github.com/home-assistant/home-assistant/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+websocket_api%22))
First occurred: 7 March 2022, 21:32:57 (22 occurrences)
Last logged: 00:27:11

* [1683472640] Client unable to keep up with pending messages. Stayed over 512 for 5 seconds
* [1688268296] Client unable to keep up with pending messages. Stayed over 512 for 5 seconds
* [1743478640] Client unable to keep up with pending messages. Stayed over 512 for 5 seconds
* [1699829240] Client unable to keep up with pending messages. Stayed over 512 for 5 seconds
* [1693840792] Client unable to keep up with pending messages. Stayed over 512 for 5 seconds

You might show your code for 1).
Also, check that the ESP device is properly recognized in HA.

The ESPHome integration shows the ESP device, and receives data from the sensors I defined. The code I’ve tried for transferring state data from an HA entity is for example like the one in the linked post.

It’s basically the same as this:

binary_sensor:
  – platform: homeassistant
    id: prevent_deep_sleep
    entity_id: input_boolean.prevent_deep_sleep

When I call the “setup()” function for the HA sensor in ESPHome, I get no output. Calling “dump_config()” shows two lines.

Code with dump_config(), and resulting output:

      - lambda: 'id(prevent_deep_sleep).dump_config();'

[10:27:13][C][homeassistant.binary_sensor:039]: Homeassistant Binary Sensor 'prevent_deep_sleep'
[10:27:13][C][homeassistant.binary_sensor:040]:   Entity ID: 'input_boolean.prevent_deep_sleep'

Code with setup(), which gives no output:

      - lambda: 'id(prevent_deep_sleep).setup();'

If the “setup()” function could subscribe to HA and the state received was one in the enum “esphome::ParseOnOffState” then I would expect some additional logging output.

References
homeassistant_binary_sensor.cpp - ESPHome: /opt/build/esphome/esphome/components/homeassistant/binary_sensor/homeassistant_binary_sensor.cpp Source File
esphome::ParseOnOffState - ESPHome: esphome Namespace Reference

Sorry to state the obvious, but did you try to change the binary sensor on HA?
It seems esphome actually subscribes to events, rather than polling.

Also, I’m pretty sure you don’t need the explicit “setup()”. That’s part of the normal esphome firmware startup.

Obvious things are good to go over again too, no worries. Yes, I have tried flipping the toggle or changing the value of all different HA entities I’ve tried to read from this ESPHome device. Doesn’t do anything differently.

I suspected “setup()” would be executed automatically and that this would be redundant. I was still hoping for some output, but there was none, unfortunately.

Not sure where to go next to continue the troubleshooting. As is too often the case, troubleshooting these things is way harder than it should be. And it’s quite possible that there are things I am doing wrong, yet it seems almost impossible to get necessary feedback from the system to figure out what that may be.

So, I seem to have solved it.

Seems that although I had the ESP device in my Integrations list and showing all my configured sensors, it wasn’t fully “integrated” enough to fetch HA entity states, possibly missing some changes or additions I may have made to this HA entity link since first launch.

(I found that there’s a “safe mode” switch, and thought this might be good. I added that to the ESP code, re-flashed, and it didn’t show up in HA…) So I went to the integration view for this ESP unit and hit “Reload”. The new switch showed up, and more importantly, the ESP device now also receives the input_boolean entity’s state!

There are also some more log entries related to the Home Assistant API handshake (it apparently wasn’t enough with the API being connected), and the HA input_boolean helper is properly sent to the ESP device.

[19:14:09][D][api:102]: Accepted ::FFFF:A00:16F
[19:14:09][V][api.connection:808]: Hello from client: 'Home Assistant 2022.2.5 (::FFFF:A00:16F)'
[19:14:09][D][api.connection:826]: Home Assistant 2022.2.5 (::FFFF:A00:16F): Connected successfully
[19:14:09][D][homeassistant.binary_sensor:026]: 'input_boolean.prevent_deep_sleep': Got state ON
[19:14:09][D][binary_sensor:034]: 'prevent_deep_sleep': Sending initial state ON
1 Like

To be clear, I only solved issue 1 so far. Deep sleep is still problematic.

I think that one should be inverted, and you don’t need (want?) the gpio sensor on it.

deep_sleep:
  id: deep_sleep_control
  sleep_duration: 15s
  wakeup_pin: 
    number: GPIO35
    inverted: true
1 Like

The wakeup pin doesn’t need to be a sensor, true enough.

And you are very right indeed, it of course needs to be inverted in the deep_sleep! It doesn’t help to only invert it in the “sensor” entry! Thank you! I was not reading how to use the “Pin Schema” in the documentation properly.

One of the other issues is still strange. The “wakeup_pin_mode: IGNORE” option doesn’t seem to work for me. If it had been working, then the GPIO wakeup would still be working without inverting, only it should trigger on a “button release” type input instead of the “button press”. If there was something “glitchy” with this button HW design, such as it momentarily going low and back up high upon entering deep_sleep and thus triggering the wakeup, then I would assume that this behavior should continue even with “inverted: true” set, so that doesn’t sound plausible.

Thank you!

As far as I understand it, wakeup_pin_mode basically tells what to do if the button is pressed while deep_sleep is requested.

IGNORE, well, ignores the state of the button, but you still need inverted to tell esphome when to wakeup.
The other options are for special behaviors, I guess