Sending data after wakeup from deep sleep by wakeup_pin

I have a ESP32 with a switch connected to pin 13. Since the device is battery powered, I want it to stay in deep sleep, unless the switch is toggled. When that happens, I want it to send the switch status and the status (state of charge) of the battery.

When I don’t add deep sleep, everything works well with this config:

 esphome:
  name: test
  includes:
  - BQ27441.h
  libraries:
  - Wire
  - "SparkFun BQ27441 LiPo Fuel Gauge Arduino Library"

sensor:
- platform: custom
  lambda: |-
    auto BQ27441 = new Dyli_BQ27441();
    App.register_component(BQ27441);
    return {BQ27441};

  sensors:
    name: "battery level"

binary_sensor:
  - platform: gpio
    pin: 13
    name: "switch status"
    device_class: window


esp32:
  board: esp32dev
  framework:
    type: arduino

When I add deep sleep configuration like this:

esphome:
  name: test
  includes:
  - BQ27441.h
  libraries:
  - Wire
  - "SparkFun BQ27441 LiPo Fuel Gauge Arduino Library"

  on_boot:
    then:
      - deep_sleep.enter

sensor:
- platform: custom
  lambda: |-
    auto BQ27441 = new my_BQ27441();
    App.register_component(BQ27441);
    return {BQ27441};

  sensors:
    name: "battery status"

deep_sleep:
  wakeup_pin: 13
  wakeup_pin_mode: INVERT_WAKEUP

binary_sensor:
  - platform: gpio
    pin: 13
    name: "switch status"
    device_class: window


esp32:
  board: esp32dev
  framework:
    type: arduino

I see in the log that the device goes into deep sleep:

[I][app:029]: Running through setup()...
[I][i2c.arduino:161]: Performing I2C bus recovery
Connected to BQ27441!
[D][binary_sensor:034]: 'Switch status': Sending initial state OFF
[I][deep_sleep:116]: Beginning Deep Sleep

When I toggle the switch, I also see it waking up and logging that it is sending the switch state:

[I][logger:243]: Log initialized
[C][ota:465]: There have been 0 suspected unsuccessful boot attempts.
[D][esp32.preferences:113]: Saving 1 preferences to flash...
[D][esp32.preferences:142]: Saving 1 preferences to flash: 0 cached, 1 written, 0 failed
[I][app:029]: Running through setup()...
[I][i2c.arduino:161]: Performing I2C bus recovery
Connected to BQ27441!
[D][binary_sensor:034]: 'Switchstatus': Sending initial state ON
[I][deep_sleep:116]: Beginning Deep Sleep

The status change is however not visible in HA. Any idea what I should change to fix that?
I also couldn’t really figure out how to send the battery status before it’s going into deep sleep again, any ideas?

I suggest getting rid of the on_boot: deep sleep command, you are sending it straight back into deep sleep on wakeup.

Try this in deep_sleep:

  run_duration: 20s # whatever value gives best result vs battery life - you will force into deep sleep anyhow
  wakeup_pin: 13
  wakeup_pin_mode: INVERT_WAKEUP
  id: deep_sleep_1

And in your battery sensor:

sensor:
- platform: custom
  lambda: |-
    auto BQ27441 = new my_BQ27441();
    App.register_component(BQ27441);
    return {BQ27441};
  sensors:
    name: "battery status"
  force_update: true # makes battery update every time
  on_value:
    then:
      - delay: 5s
      - deep_sleep.enter: deep_sleep_1    
1 Like

Thanks for the suggestion. It seems however that I cannot use “on_value:” in the custom sensor:

[on_value] is an invalid option for [sensor.custom]. Please check the indentation

I thought that I could maybe bypass it by making a template sensor:

- platform: template
  name: "Template Sensor"
  lambda: |-
    return id(battery_status).state
  force_update: true
  on_value:
    then:
      - delay: 5s
      - deep_sleep.enter: deep_sleep_1    

But that gave me a error at compile time:

/config/esphome/test.yaml: In lambda function:
/config/esphome/test.yaml:30:29: error: 'const class esphome::custom::CustomSensorConstructor' has no member named 'state'
     return id(battery_status).state
                             ^

I wondered about that - they don’t inherit all sensor components.

What happens if you move it under the sensor definition, i.e.

- platform: custom
  lambda: |-
    auto BQ27441 = new my_BQ27441();
    App.register_component(BQ27441);
    return {BQ27441};
  sensors:
    name: "battery status"
    force_update: true # makes battery update every time
    on_value:
      then:
        - delay: 5s
        - deep_sleep.enter: deep_sleep_1   

Otherwise you might have to do the fiddling with setup priority which is beyond me.

2 Likes

Thanks! That actually worked!

Now i just have to filddle a bit with the run_duration to see what works best. I have to say it’s a bit slow when in deep sleep, takes about 10 seconds before the status change is visible in HA.