Can I wake from sleep without mqtt?

I have a solar-powered node that currently only reports the temperature from a DS18B20. But I am having trouble getting into OTA.

I am using mqtt persistent messages to enable or disable sleep, but I also have api enabled. I understand why I don’t want both api and mqtt, but without api, all of my entities are “unavailable”.

The only thing mqtt does here is to control the sleep mode.

I would like to stop using mqtt to control sleep, but I am curious if anyone has a suggestion to how I should proceed?

Hi
I had problem getting my solar weather station go in/out of ota using MQTT.
so I set up in automations

  • id: ‘1639255763593’
    alias: esp12f1 ota off
    description: ‘’
    trigger:

    • platform: state
      entity_id: input_boolean.esp12f1_ota
      from: ‘on’
      to: ‘off’
      condition: []
      action:
    • service: mqtt.publish
      data:
      topic: esp12f1/ota_mode
      payload: ‘OFF’
      retain: true
      qos: ‘1’
  • id: ‘1639255980225’
    alias: esp12f1 ota on
    description: ‘’
    trigger:

    • platform: state
      entity_id: input_boolean.esp12f1_ota
      from: ‘off’
      to: ‘on’
      condition: []
      action:

    • service: mqtt.publish
      data:
      topic: esp12f1/ota_mode
      payload: ‘ON’
      qos: ‘1’
      retain: true

      then set up a helper (didn’t know what use these were before)

Seems bit too easy like your setting up nothing, but it works.

Once the helper switch is turned on the next time it comes out of deepsleep it goes into ota mode. Update the esp. Then turn ota helper off again and it returns to deepsleep.

Interesting- I hadn’t thought of doing it in an automation, but it looks like you are still using MQTT in the espHome node?

I tried creating a dummy switch that I could turn on and off from the front end, then in the espHome yaml file, I just need to test the entity. Here’s my latest test, but the yaml code is messed up:

# ###### Sleep #####

#Deep Sleep handler
deep_sleep:
  id: deep_sleep_handler
  run_duration: 15s
  sleep_duration: 120s  


binary_sensor:
  - platform: homeassistant
    id: ota_mode_test
    entity_id: switch.solar_otamode


# This switch is controlled from the front end.
switch:
  - platform: gpio
    name: ${device_name} otamode
    pin:
      number: D4
      mode: output
    id: ${device_name}_d4


# Script to test if the otamode switch is on or off
script:
  – id: test_sleep
    mode: queued
    then:
      – delay: 10s
      – if:
          condition:
            binary_sensor.is_on: ota_mode_test
          then:
            – logger.log: 'Skipping sleep, per ota_mode_test'
          else:
            – deep_sleep.enter: deep_sleep_handler
            
      – script.execute: test_sleep

Is there no easy way to test an entity state (on or off)?

The error here is in the line: “mode: queued”
that “Mapping values are not allowed here”.

Any ideas?

I stuck with mqtt to make it all as fast as possible to preserve battery in the dark months. I setup a mqtt to go into deepsleep early as soon as HA got temp and pressure readings. Shaves 8-9 seconds each time esp come out of deepsleep. I also set it up via mqtt to come out of deepsleep earlier to give readings more often if battery capacity is higher based on voltage of my 18650.

Update.
I created a virtual switch that I can control from the front-end (Lovelace).
But, I am having a heck of a time testing it in the yaml code. (Why isn’t there a simple if-then-else)?

Can someone point me in the right direction to at least not get format errors? Do I need a script or is there a better way to test the status of switch.solar_otamode?

My goal is to not need MQTT just to enable OTA.

(This script doesn’t work, but am I even on the right track)?

# Script to test if the otamode switch is on or off
script:
  - id: test_sleep
    then:
      – if:
          condition:
            lambda: 'return id(switch.solar_otamode).state == "ON";'
          then:
            – logger.log: 'Skipping sleep, per ota_mode switch'
          else:
            – deep_sleep.enter: deep_sleep_handler

Following might help

AFAIK there is no magic wake packet, like windows, to wake a sleeping esp. To accomplish this you’d need a switch and status sensor in esphome.

switch:
  - platform: template
    name: "Turn off sleep"
    turn_on_action:
      - deep_sleep.prevent: deep_sleep_1
    turn_off_action:
      - deep_sleep.enter: deep_sleep_1

binary_sensor:
  - platform: status
    name: "Node name Status"

Then when you want to do an ota, in home assistant you turn on an automation

alias: New Automation
description: ''
mode: single
trigger:
  - platform: state
    entity_id: binary_sensor.node_name_status
    to: 'on'
condition: []
action:
  - service: switch.turn_on
    data: {}
    target:
      entity_id: switch.turn_off_sleep

Once the ota completes shut the switch off and it will go back to sleep. Then shut off the automation until next time you need it

Thanks, but how do you get into the OTA mode? As you said there’s no way to wake a sleeping ESP.

The entities Temp and Humidity or whatever else setup on the ESP will be available under MQTT.

Esphome

mqtt:
  broker: 192.168.***.***
  username: *****
  password: ***********
  birth_message:
    topic: esp12f1/birthdisable
    payload: disable
  will_message:
    topic: esp12f1/willdisable
    payload: disable
  discovery: true
  discovery_retain: true    
  on_message:
    - topic: esp12f1/ota_mode
      payload: 'ON'
      then:
        - logger.log: 'OTA Mode ON - Deep sleep DISABLED'
        - deep_sleep.prevent: deep_sleep_1

When the switch is on it won’t sleep. There is no ota mode. As long as the node is connected, you start the ota process by clicking update.

Setting that ha automation active will turn off sleep the next time the node wakes up. Then perform ota shut the switch off and it’s back to the sleep schedule.

Your esp is on a sleep rhythm based on the sleep duration, when it wakes up it checks if it is meant to remain awake, if yes then deep sleep is prevented, if no then it goes back to sleep. With deep sleep duration you can instruct the time until the next “awakening”

In HA / with the API method you essentially need 2 entities to achieve this, a boolean /switch and an input number. If you check my script above you will see the first as a binary sensor, the second as a sensor; both will need to be setup in HA as well (helper entities).

The script is run whenever the esp awakes.

My use case was that I wanted a device to sleep as long as we were asleep, saving maximum battery but not losing functionality during day time. As there is indeed no magic button I worked with dynamic sleep cycles moving from a longer cycle at midnight to shorter cycles early in the morning; once certain presence detectors were activated I disabled deep sleep.

Thanks for the assistance. Yes, I know how sleep works- I’ve been using it on Arduino projects for years. What confuses me is yaml.

Your code is one of the multitude of things I’ve tried, but when I try to toggle the entity: input_button.prevent_deep_sleep, the state becomes the date and time??

Also, I want to have eyes into my device yaml execution, so I tried using logger.log, but I can’t even get that to work. (See: Can anyone tell me why I am not seeing "Hello World" in my log file?).

Since I can’t even get logger.log to work, today I plan to add some LEDs to unused pins on the Wemos as state indicators.

It should be input_boolean instead of input_button.

Thanks- I think I am beginning to see my way out of this rabbit hole called yaml.

Hi all. Old topic, I realise… :slight_smile:
I did the same ting you did but for some reason it does not seem to work. My ESP32 gets the state ON, but it appears it never enters the if-statement.

Code:

deep_sleep:
  id: deep_sleep_control
  sleep_duration: 2min
  run_duration: 5min   

# Will only pick up a value if this device is configured in Home Assistant > Integrations
# If the device isn't configured, or Home Assistant is offline, it'll default to false
binary_sensor:
  - platform: homeassistant
    id: prevent_deep_sleep
    name: Prevent Deep Sleep
    entity_id: input_boolean.prevent_deep_sleep
    publish_initial_state: True

script:
  - id: consider_deep_sleep
    mode: queued
    then:
      - delay: 10s
      - if:
          condition:
            binary_sensor.is_on: prevent_deep_sleep
          then:
            - logger.log: 'Skipping sleep, per prevent_deep_sleep'
            - deep_sleep.prevent: deep_sleep_control
          else:
            - logger.log: 'Going to bed!!'
            - lambda: |-
                id(deep_sleep_control).set_sleep_duration(id(deep_sleep_duration).state);
            - delay: 1s
            - deep_sleep.enter: deep_sleep_control
      - script.execute: consider_deep_sleep

sensor:
  - platform: homeassistant
    id: deep_sleep_duration
    name: Deep sleep run_duration
    entity_id: input_number.deep_sleep_duration

The log never shows the logger.log results…

[12:06:38][D][homeassistant.binary_sensor:026]: ‘input_boolean.prevent_deep_sleep’: Got state ON
[12:06:38][D][binary_sensor:034]: ‘Prevent Deep Sleep’: Sending initial state ON
[12:06:38][D][homeassistant.sensor:024]: ‘input_number.deep_sleep_duration’: Got state 0.00
[12:06:38][D][sensor:094]: ‘Deep sleep run_duration’: Sending state 0.00000 with 1 decimals of accuracy
[12:07:10][D][sensor:094]: ‘Battery Raw Voltage’: Sending state 3.94000 V with 2 decimals of accuracy
[12:07:28][D][sensor:094]: ‘Lawn Moisture Raw Voltage’: Sending state 0.14200 V with 2 decimals of accuracy
[12:11:37][I][deep_sleep:060]: Beginning Deep Sleep
[12:11:37][I][deep_sleep:062]: Sleeping for 120000000us
[12:11:37][D][esp32.preferences:114]: Saving 1 preferences to flash…

Any pointers?

Never mind… after reading through the example for the umpteenth time I realised I never added the on_boot instruction… :upside_down_face: