DeepSleep is activated immediately by, probably wrong `on_message`

I’ve been trying for hours to switch OTA mode via MQTT. DeepSleep runs correctly so far, but as soon as I set the on_message block, the board immediately activates deepsleep mode again. Here is the relevant configuration:

deep_sleep:
  run_duration: 30s
  sleep_duration: 10s
  id: this_deep_sleep
...
mqtt:
  broker: 192.168.178.80
  username: !secret mqtt_user
  password: !secret mqtt_pass
  discovery: true
  discovery_retain: true
  birth_message:
    topic: $devicename/status
    payload: online
    retain: true
  will_message:
    topic: $devicename/status
    payload: offline
    retain: true
  on_message:
   - topic: $devicename/ota_mode
     payload: 'ON'
     then:
       - deep_sleep.prevent: this_deep_sleep
   - topic: $devicename/ota_mode
     payload: 'OFF'
     then:
       - deep_sleep.enter: this_deep_sleep
...
sensor:
  - platform: mqtt_subscribe
    name: "Sleep time topic"
    id: custom_sleep_time
    unit_of_measurement: ms
    accuracy_decimals: 0
    topic: $devicename/sleep_mode_time
    on_value:
      then:
       - lambda: |-
           id(this_deep_sleep).set_sleep_duration(id(custom_sleep_time).state);

Is there a possibility to show the value for this_deep_sleep in the log? I suspect that this is set incorrectly (i.e. to zero).
The result is independent of which value I publish under $devicename/ota_mode (I send raw with the MQTT explorer for testing).

I tested something else, this switch works a bit strange: as soon as i publish off, the board immediately goes into DeepSleep and wakes up again after 10 sec. But: it stays awake afterwards and does not go into DeepSleep automatically. Provided I publish off retain, it goes to sleep again immediately after startup until this value is changed. The run_duration is completely ignored after the first òff`…

Maybe I have misunderstood something, but deep sleep is to be prevented with OTA=ON and switched on and off automatically with all other values as specified above.

After switching once to off, I got this log:

[13:31:33][I][deep_sleep:041]: Scheduling Deep Sleep to start in 20000 ms
[13:31:33][I][app:062]: setup() finished successfully!
[13:31:33][I][app:102]: ESPHome version 2022.4.0 compiled on May 17 2022, 12:57:52
[13:31:33][I][deep_sleep:104]: Beginning Deep Sleep
[13:31:47][I][mqtt:216]: MQTT Connected!
[13:31:47][I][deep_sleep:041]: Scheduling Deep Sleep to start in 20000 ms
[13:31:47][I][app:062]: setup() finished successfully!
[13:31:47][I][app:102]: ESPHome version 2022.4.0 compiled on May 17 2022, 12:57:52
[13:31:47][I][deep_sleep:104]: Beginning Deep Sleep
...

I can’t reactivate the run_duration via MQTT.

OK, with payload = on deep sleep can be deactivated so far. But if payload = off is set, deep sleep is activated again so fast (1-2sec) that the values are not sent anymore. The run_duration is completely ignored.

You need to delete the retained message on topic: $devicename/ota_mode. You can do this by sending a empty message to the topic

Thank you, that was obviously the problem. The topic must be deleted again immediately, so no simple switch in HA helps. I have now included this directly in ESPHome, but it takes 3 reboots until the Topic is deleted, because the device switches too quickly into deep sleep. Can the deep sleep here be delayed a little so that the topic is deleted before?

  on_message:
   - topic: $devicename/ota_mode
     payload: 'on'
     then:
       - logger.log: "payload on, kein DS"
       - deep_sleep.prevent: this_deep_sleep
   - topic: $devicename/ota_mode
     payload: 'off'
     then:
       - logger.log: "payload off, enter DS"
       - mqtt.publish:
            topic: "$devicename/ota_mode"
            retain: true
            payload:
       - deep_sleep.enter: this_deep_sleep

You can clear the retained message from inside HA, aside from esphome. Either that or add a delay before deep sleep enter, there is not enough time to send the blank message. you may need to adjust the time delay from 1s

       - mqtt.publish:
            topic: "$devicename/ota_mode"
            retain: true
            payload:
       - delay: 1s
       - deep_sleep.enter: this_deep_sleep

Thank you very much, perfect! I prefer to delete the topic in ESPHome, so that the status of the switch in HA remains unchanged. That is easier. Works fine now!!

1 Like

Unfortunately, I still have the problem that the deep sleep duration is only a few seconds regardless of the values and the device shuts down again immediately. The on_value blocks are cycled on new values, like here:

sensor:
  - platform: mqtt_subscribe
    name: "Sleep time topic"
    id: custom_sleep_time
    unit_of_measurement: min
    accuracy_decimals: 0
    topic: homeassistant/input_number/dth11_deepsleep_dauer/state
    on_value:
      then:
       - logger.log: "neuer Wert!"
       - lambda: |-
           id(this_deep_sleep).set_sleep_duration(id(custom_sleep_time).state * 1000 * 60);
       - delay: 1s
       - deep_sleep.enter: this_deep_sleep

The sleep values are also received and logged correctly via MQTT:

  - platform: template
    name: sleep-zeit
    lambda: |-
      return id(custom_sleep_time).state;
    accuracy_decimals: 0
    update_interval: 10s
  - platform: template
    name: run-zeit
    lambda: |-
      return id(custom_run_time).state;
    accuracy_decimals: 0
    update_interval: 10s

Deleting the OTA topic also works.
After 1-2 sec always deep sleep starts, although it is logged: Run Duration: 300000 ms.

INFO Reading configuration /config/esphome/esensor-01.yaml...
INFO Starting log output from esp-dht11-01/debug
INFO Connected to MQTT broker!
[16:58:59][I][deep_sleep:116]: Beginning Deep Sleep
[16:59:11][I][mqtt:216]: MQTT Connected!
[16:59:11][V][mqtt:314]: subscribe(topic='homeassistant/switch/ota_dht11_modus/state')
[16:59:11][V][mqtt.component:062]: 'Sleep time topic': Sending discovery...
[16:59:11][V][json:031]: Attempting to allocate 512 bytes for JSON serialization
[16:59:11][V][json:051]: Size after shrink 352 bytes
[16:59:11][V][mqtt:414]: Publish(topic='homeassistant/sensor/esp-dht11-01/sleep_time_topic/config' payload='{"unit_of_meas":"min","name":"Sleep time topic","stat_t":"esp-dht11-01/sensor/sleep_time_topic/state","avty_t":"esp-dht11-01/status","uniq_id":"ESPsensorsleep_time_topic","dev":{"ids":"84cca8a32288","name":"esp-dht11-01","sw":"esphome v2022.5.0 May 18 2022, 15:20:08","mdl":"esp01_1m","mf":"espressif"}}' retain=1)
[16:59:11][V][mqtt:314]: subscribe(topic='homeassistant/input_number/dth11_deepsleep_dauer/state')
[16:59:11][V][mqtt.component:062]: 'Run time topic': Sending discovery...
[16:59:11][V][json:031]: Attempting to allocate 512 bytes for JSON serialization
[16:59:11][V][json:051]: Size after shrink 344 bytes
[16:59:11][V][mqtt:414]: Publish(topic='homeassistant/sensor/esp-dht11-01/run_time_topic/config' payload='{"unit_of_meas":"s","name":"Run time topic","stat_t":"esp-dht11-01/sensor/run_time_topic/state","avty_t":"esp-dht11-01/status","uniq_id":"ESPsensorrun_time_topic","dev":{"ids":"84cca8a32288","name":"esp-dht11-01","sw":"esphome v2022.5.0 May 18 2022, 15:20:08","mdl":"esp01_1m","mf":"espressif"}}' retain=1)
[16:59:11][V][mqtt:314]: subscribe(topic='homeassistant/input_number/dth11_laufdauer_sec/state')
[16:59:11][V][mqtt.component:062]: 'Temperatur': Sending discovery...
[16:59:11][V][json:031]: Attempting to allocate 512 bytes for JSON serialization
[16:59:11][V][mqtt.component:062]: 'run-zeit': Sending discovery...
[16:59:11][V][json:031]: Attempting to allocate 512 bytes for JSON serialization
[16:59:11][V][json:051]: Size after shrink 308 bytes
[16:59:11][V][mqtt:414]: Publish(topic='homeassistant/sensor/esp-dht11-01/run-zeit/config' payload='{"name":"run-zeit","stat_t":"esp-dht11-01/sensor/run-zeit/state","avty_t":"esp-dht11-01/status","uniq_id":"ESPsensorrun-zeit","dev":{"ids":"84cca8a32288","name":"esp-dht11-01","sw":"esphome v2022.5.0 May 18 2022, 15:20:08","mdl":"esp01_1m","mf":"espressif"}}' retain=1)
[16:59:11][V][mqtt:414]: Publish(topic='esp-dht11-01/sensor/run-zeit/state' payload='nan' retain=1)
[16:59:11][V][mqtt:314]: subscribe(topic='homeassistant/switch/ota_dht11_modus/state')
[16:59:11][C][deep_sleep:037]: Setting up Deep Sleep...
[16:59:11][I][deep_sleep:042]: Scheduling Deep Sleep to start in 60000 ms
[16:59:11][V][mqtt.component:062]: 'Luftfeuchtigkeit relativ': Sending discovery...
[16:59:11][V][json:031]: Attempting to allocate 512 bytes for JSON serialization
[16:59:11][V][json:051]: Size after shrink 428 bytes
...
[16:59:11][D][main:150]: payload off, enter DS
[16:59:11][V][mqtt:414]: Publish(topic='homeassistant/switch/ota_dht11_modus/state' payload='' retain=1)
[16:59:11][V][sensor:074]: 'Sleep time topic': Received new state 1.000000
[16:59:11][D][sensor:124]: 'Sleep time topic': Sending state 1.00000 min with 0 decimals of accuracy
[16:59:11][D][main:341]: neuer Wert!
[16:59:11][V][mqtt:414]: Publish(topic='esp-dht11-01/sensor/sleep_time_topic/state' payload='1' retain=1)
[16:59:12][V][sensor:074]: 'Run time topic': Received new state 300.000000
[16:59:12][D][sensor:124]: 'Run time topic': Sending state 300.00000 s with 0 decimals of accuracy
[16:59:12][D][main:147]: neuer Wert!
[16:59:12][V][mqtt:414]: Publish(topic='esp-dht11-01/sensor/run_time_topic/state' payload='300' retain=1)
[16:59:12][D][main:150]: payload off, enter DS
...
[16:59:12][V][mqtt.component:062]: 'sleep-zeit': Sending discovery...
[16:59:12][V][json:031]: Attempting to allocate 512 bytes for JSON serialization
[16:59:12][V][json:051]: Size after shrink 316 bytes
[16:59:12][V][mqtt:414]: Publish(topic='homeassistant/sensor/esp-dht11-01/sleep-zeit/config' payload='{"name":"sleep-zeit","stat_t":"esp-dht11-01/sensor/sleep-zeit/state","avty_t":"esp-dht11-01/status","uniq_id":"ESPsensorsleep-zeit","dev":{"ids":"84cca8a32288","name":"esp-dht11-01","sw":"esphome v2022.5.0 May 18 2022, 15:20:08","mdl":"esp01_1m","mf":"espressif"}}' retain=1)
[16:59:12][V][mqtt:414]: Publish(topic='esp-dht11-01/sensor/sleep-zeit/state' payload='nan' retain=1)
[16:59:12][V][component:199]: Component mqtt took a long time for an operation (0.06 s).
[16:59:12][V][component:200]: Components should block for at most 20-30ms.
...
[16:59:12][C][mqtt:601]: MQTT Message Trigger:
[16:59:12][C][mqtt:602]:   Topic: 'homeassistant/switch/ota_dht11_modus/state'
[16:59:12][C][mqtt:603]:   QoS: 0
[16:59:12][C][mqtt.sensor:027]: MQTT Sensor 'Sleep time topic':
[16:59:12][C][mqtt.sensor:031]:   State Topic: 'esp-dht11-01/sensor/sleep_time_topic/state'
[16:59:12][C][mqtt_subscribe.sensor:031]: MQTT Subscribe 'Sleep time topic'
[16:59:12][C][mqtt_subscribe.sensor:031]:   State Class: ''
[16:59:12][C][mqtt_subscribe.sensor:031]:   Unit of Measurement: 'min'
[16:59:12][C][mqtt_subscribe.sensor:031]:   Accuracy Decimals: 0
[16:59:12][C][mqtt_subscribe.sensor:032]:   Topic: homeassistant/input_number/dth11_deepsleep_dauer/state
[16:59:12][C][mqtt.sensor:027]: MQTT Sensor 'Run time topic':
[16:59:12][C][mqtt.sensor:031]:   State Topic: 'esp-dht11-01/sensor/run_time_topic/state'
[16:59:12][C][mqtt_subscribe.sensor:031]: MQTT Subscribe 'Run time topic'
[16:59:12][C][mqtt_subscribe.sensor:031]:   State Class: ''
[16:59:12][C][mqtt_subscribe.sensor:031]:   Unit of Measurement: 's'
[16:59:12][C][mqtt_subscribe.sensor:031]:   Accuracy Decimals: 0
[16:59:12][C][mqtt_subscribe.sensor:032]:   Topic: homeassistant/input_number/dth11_laufdauer_sec/state
...
[16:59:12][C][mqtt.sensor:027]: MQTT Sensor 'sleep-zeit':
[16:59:12][C][mqtt.sensor:031]:   State Topic: 'esp-dht11-01/sensor/sleep-zeit/state'
[16:59:12][C][mqtt.sensor:027]: MQTT Sensor 'run-zeit':
[16:59:12][C][mqtt.sensor:031]:   State Topic: 'esp-dht11-01/sensor/run-zeit/state'
[16:59:12][C][mqtt:601]: MQTT Message Trigger:
[16:59:12][C][mqtt:602]:   Topic: 'homeassistant/switch/ota_dht11_modus/state'
[16:59:12][C][mqtt:603]:   QoS: 0
[16:59:12][C][deep_sleep:049]: Setting up Deep Sleep...
[16:59:12][C][deep_sleep:052]:   Sleep Duration: 60000 ms
[16:59:12][C][deep_sleep:055]:   Run Duration: 300000 ms
[16:59:12][I][deep_sleep:116]: Beginning Deep Sleep

Note: the OTA topic is of course deleted, so empty.
The following is the current deep sleep block in ESPHome. The OTA state is detected correctly.

  on_message:
   - topic: homeassistant/switch/ota_dht11_modus/state
     payload: 'on'
     then:
       - logger.log: "payload on, no DS"
       - deep_sleep.prevent: this_deep_sleep
   - topic: homeassistant/switch/ota_dht11_modus/state
     payload: 'off'
     then:
       - logger.log: "payload off, enter DS"
       - mqtt.publish:
            topic: homeassistant/switch/ota_dht11_modus/state
            retain: true
            payload:
       - delay: 2s
       - deep_sleep.enter: this_deep_sleep

deep_sleep:
  run_duration: 60s
  sleep_duration: 1min
  id: this_deep_sleep

It’s publishing ‘nan’ try payload: '' instead.

If you hard code the 300000ms will it wait the 5 minutes?

I’ll do. Do you mean - deep_sleep.enter: 300000ms instead of - deep_sleep.enter: this_deep_sleep?

The original sleep entry

deep_sleep:
  run_duration: 300000ms
  sleep_duration: 1min
  id: this_deep_sleep

Maybe instead than do everything in this sensor set a global

      - globals.set:
          id: sleep_time
          value: !lambda 'return id(custom_sleep_time).state * 60000;'

Then on_value of the global to set then enter sleep. I see that nan, single quotes '' is the right way to send a blank message though, was from a sensor and that it seems to be getting the correct value. idk maybe going round about will work.

Hmm, I get error Unable to find action with the name 'globals.set'.
script is now:

    on_value:
      then:
       - logger.log: "neuer Wert!"
       - globals.set:
           id: sleep_time
           value: !lambda 'return id(custom_sleep_time).state * 60000;'
       - delay: 1s
       - deep_sleep.enter: this_deep_sleep

Is the line deep_sleep.enter: this_deep_sleep correct here?

I have completely removed the on_value blocks in the sleep time topic and run time topic and now the times are correct. Apparently the values are not set correctly. Does the value perhaps still have to be converted as integer?

    on_value:
      then:
       - logger.log: "new value!"
       - lambda: |-
           id(this_deep_sleep).set_sleep_duration(id(custom_sleep_time).state * 1000 * 60);
       - delay: 1s
       - deep_sleep.enter: this_deep_sleep

Sorry about that, globals need to be defined in the sketch. .state is not used with globals.

 globals:
   - id: sleep_time
     type: int
     restore_value: no
     initial_value: '0'
     on_value:
       - lambda: |-
           id(this_deep_sleep).set_sleep_duration(id(sleep_time)
       - delay: 1s
       - deep_sleep.enter: this_deep_sleep

will it compile like this?

    - deep_sleep.enter:
        id: this_deep_sleep
        sleep_duration: !lambda 'return id(sleep_time);'

Thank you very much! I had looked into the log yesterday and indeed the problem is that the value for run_duration is lost by deep sleep. After the reboot the default value is used for the runtime and only then the custom value is read in again. Thus the custom value is always ignored. The correct solution for deep sleep are therefore actually global variables, here is actually missing a hint in the FAQ of ESPHome.

When compiling I unfortunately get the following error in the global area:

[on_value] is an invalid option for [0]. Did you mean [restore_value], [initial_value]?

And: the sleep_duration works, because the board has enough time to reset the value to custom. My problem is the run_duration. Where actually both values should be declared globally in case the network is not available.

I also tried a ‘dirty solution’ with disabling and enabling deespleep after reading custom run_duration, but without success:

    on_value:
      then:
       - logger.log: "new run_duration"
       - lambda: |-
          id(this_deep_sleep).set_run_duration(id(custom_run_time).state * 1000);
       - delay: 1s
       - deep_sleep.prevent: this_deep_sleep
       - delay: 1s
       - deep_sleep.allow: this_deep_sleep

same with deep_sleep.enter: this_deep_sleep in last line. Is there any way to set a new run_time in this way? Or use delay instead, but without disabling the sensors…

I think I’ll just ignore the run_duration issue, more important is the deep sleep after all. And then also a long deep sleep, e.g. overnight.
Thanks for the help, the script runs so far already well!

1 Like