Reading temperature and posting MQTT message on wake up

I’m creating a battery powered temperature sensor for my compost bin. I want the sensor to deep sleep for a while, wake up and measure the temperature using a DS18B20 and post the result on a MQTT topic, and then go back to sleep.

I’ve got the sensor working, deep sleep working and MQTT broker connection working. But how do I tie it all together? How can I get it to read a measurement from the DS18B20 on wakeup and then post it to a MQTT topic, before going back to sleep?

Here’s my configuration so far:

esphome:
  name: compost_bin
  platform: ESP32
  board: nodemcu-32s

wifi:
  ssid: xxx
  password: xxx
  manual_ip:
    static_ip: 192.168.2.41
    gateway: 192.168.2.1
    subnet: 255.255.255.0
    dns1: 192.168.2.1

ota:
  password: xxx
      
# Enable logging
logger:

mqtt:
  broker: 192.168.2.10
  username: xxx
  password: xxx
  topic_prefix: home/outside/compost_bin
  birth_message:
    topic: home/outside/compost_bin/availability
    payload: online
  will_message:
    topic: home/outside/compost_bin/availability
    payload: offline
  on_message:
    - topic: home/outside/compost_bin/ota_mode
      payload: 'ON'
      then:
        - deep_sleep.prevent: deep_sleep_1
    - topic: home/outside/compost_bin/ota_mode
      payload: 'OFF'
      then:
        - deep_sleep.enter: deep_sleep_1

deep_sleep:
  run_duration: 10s
  sleep_duration: 20s
  id: deep_sleep_1

dallas:
  - pin: GPIO13

sensor:
  - platform: dallas
    address: 0xDC0417A20D78FF28
    name: "temperature"

Change your run duration to a time long enough for the ESP to connect to wifi and send a message. Practically I’ve found 45 seconds is about the minimum. Though I use 2 minutes as my remote esp device is right on the edge of my wifi range and I want to make sure at least one message gets through.

I dont expect your compost temperature will be changing every 30 seconds (it has a lot of thermal mass). So a run time of one to two minutes and a sleep time of five to ten minutes should work.

Note: you will get the sensor reporting as unavailable while the ESP is asleep. If this is important you can set a blank birth and will topic (and clear the retained ones out of your broker) to prevent this.

Ok, so there’s no way to directly affect the device’s behavior when it boots up (e.g. run actions after a trigger)? My only option is to give the device long enough time to send read the sensor and send a MQTT message? This will reduce the battery life then, since you always have to have a longer running time than you actually need.

There’s the on_boot function. See here:

But you still have to wait for the first reading from the sensor.

Both my mailbox and lane gate binary sensors wake for 2 minutes but as they only have to wake when something changes (or every 6 hours to report the are still there) they spend 99% of their time asleep and one 18650 cell and a 5W 5V solar panel runs them forever.

It’s a different story for analogue sensors that have to report in regularly as you are discovering.

Your previous 10s wake 20s sleep duty cycle is the exactly equivalent battery drain to 2 min wake 4min sleep. So if you designed your battery for that, then longer wake and sleep should be the same average drain. It just means you only get an update every 4 minutes. And to be honest even that is probably overkill for a compost heap. You could take a reading every 15 to 30 minutes and get the same sort of graph, except at the the times right when you turn the pile (if you ever do).

1 Like

Thanks for the input - I’ll see what I can do. Good point about removing the availability topic. No need when going into deep sleep. :slight_smile:

I’m currently testing with these settings:

deep_sleep:
run_duration: 60s
sleep_duration: 120s
id: deep_sleep_1

I don’t plan to keep this sleep_duration - I just use it for testing. But when looking at the MQTT log, I see that each measurement comes in at a 2 minute (120 second) interval. Why isn’t the interval 180 seconds (run_duration + sleep_duration)? When reading the documentation, it gives the impression that the device first runs the run_duration period, and then sleeps the sleep_duration. But for some reason that’s not the case…

  • Your device sends a reading right before sleeping then it sleeps.
  • 120s elapses
  • The device wakes, connects, and readings are sent for 60 sec, one reading occurs right before sleep
  • The device sleeps for 120 sec.
  • The device wakes, connects, and readings are sent for 60 sec.
  • etc…

So I would expect you to receive reading gaps of the sleep duration + time to connect wifi and the broker + time to get the first reading.

What is your update interval for sensor readings?

I’m guessing it is quite quick.

It is also interesting that your wifi and broker connection is occurring very quickly.

I’m not quite sure what you mean about update interval for sensor readings. The configuration is as in the initial post, except the changes to the run_duration and sleep_duration.

The interval I observe when subscribing to the temperature topic is 120 seconds, not 180 seconds (i.e. the ESP32 is publishing the measurements every 120 seconds). Since sleep_duration is specified to be 120 seconds and run_duration is specified to be 60 seconds, I don’t understand a 120 second MQTT publish interval. It seems like it just disregards the run_duration setting.

Aha, it suddenly dawned on me what the problem was that caused run_duration to be ignored. I had set the ota_mode to “OFF” with retain so that deep sleep wouldn’t be prevented. My config has a trigger to enter deep sleep when receiving “OFF” payload on the ota_mode topic. I thought I was simply enabling deep sleep, but I was actually starting deep sleep basically immediately when MQTT got up. Learning something new every day. :slight_smile:

1 Like

I am facing challenges with deep_sleep too. I did some testing on my network and my bme280 + esp32 was waking and sending readings and going back to sleep within 2 seconds, then sleeping for an hour. A run duration of zero was working. When I deploy this on another remote network I get different behavior. Otto has told me that run_duration starts being counted after MQTT is connected, this is important to know, so that should take care of variable time connecting to wifi and connecting to mqtt broker. It is important to know that if your sensor update_interval is longer that your run_time it has no effect, or at least that is what I was told by Otto, the update_interval time elapsed is not stored anywhere on non volatile storage, so gets reinitialized every time the device wakes from sleep. My update interval was set to 43mins, I have removed it for now, and am inclined to set it to something very small and rely on my automation to make the device sleep again. At the moment it seems that readings are scheduled on a variable basis. I also had blank birth and will messages to disable availability reporting and make the graphs look better, I don’t know if that exposes different behaviour. In the above config blank birth/will are now commented out.
Here is my config:

  broker:********.co.uk
  port: 23046
  username: scott
  password:********
#  birth_message:
#  will_message:
  on_message:
    - topic: bedford/ota_mode
      payload: 'ON'
      then:
        - deep_sleep.prevent: deep_sleep_1
    - topic: bedford/sleep_mode
      payload: 'ON'
      then:
        - deep_sleep.enter: deep_sleep_1


logger:
#  level: INFO

ota:
  password: ********

i2c:
  sda: 16
  scl: 17


sensor:
  - platform: bme280
    temperature:
      name: "bford temp"
      oversampling: 2x
    pressure:
      name: "bford pres"
      oversampling: 2x
    humidity:
      name: "bford humi"
      oversampling: 2x
    address: 0x76

deep_sleep:
  id: deep_sleep_1
  run_duration: 10s
  sleep_duration: 60min

I have an automation that publishes a MQTT message which triggers deep_sleep.enter when the reading from the BME280 is received by HA. THis config worked fine for almost a whole day, then I see MQTT connections on my broker with no readings being sent. 10s should be enough time?

My device is in a inaccessible place at another address so difficult to debug/troubleshoot. I will go there later today and attempt to reflash it by setting ota_mode, I have set that just now to see if it now needs more than 10secs wake time, it would be a bit absurd to have to use on_boot to force sensor readings in a timely manner. I also seem to be having wifi and mobile data issues too, because the sensor does not connect every hour, so that can be influencing stuff, off to install a better router too.

update: I think deleting the retained messages for the readings messes it up. I cleared out all the retained messages to start afresh, including the homeassistant discovery ones and it started working again. You have to be careful what messages are posted when on mqtt, my automation got out of sync, and the message to sleep was being acted on before the readings

  alias: bedford sleep after mqtt receipt
  trigger:
  - platform: mqtt
    topic: bedford/sensor/bford_humi/state
  action:
  - delay: 00:00:02
  - data:
      payload: 'ON'
      topic: bedford/sleep_mode
    service: mqtt.publish
  - delay: 00:00:10
  - data:
      topic: bedford/sleep_mode
    service: mqtt.publish

Here I decide to disable the sleep mode 10s after it fires, if you edit the automation or restart ha it fires on its own due to the retained message.

Is there a way to just call deep sleep after 1 loop? So sensors are read and once the push to mqtt happens have it enter deep sleep and then wake up and do it all over again?

Hello Tom,

would you please be so kind and share your deep_sleep MQTT sensor configuration for the mailbox or lane gate? There is so little information how to create proper deep sleep sensor, that makes connection, a reading and then goes to deep sleep immediately, that you are one of the few who got it working well. Thank you very much, Jan

esphome:
  name: mailbox
  platform: ESP32
  board: nodemcu-32s

wifi:
  ssid: 'WAPOS'
  password: !secret wifi_pwd
  fast_connect: true
  manual_ip:
    static_ip: 10.1.1.77
    gateway: 10.1.1.1
    subnet: 255.255.255.0

logger:
  level: WARN

mqtt:
  broker: 10.1.1.100
  username: !secret mqtt_usr
  password: !secret mqtt_pwd

ota:
  password: !secret esp_pwd

deep_sleep:
  run_duration: 120s
  sleep_duration: 720min
  wakeup_pin_mode: INVERT_WAKEUP
  wakeup_pin: GPIO12

sensor:
  - platform: wifi_signal
    name: "Mailbox WiFi Signal"
    update_interval: 4s
    filters:
      - sliding_window_moving_average:
          window_size: 15
          send_every: 15
          send_first_at: 1

  - platform: adc
    pin: GPIO36
    name: "Mailbox Battery"
    attenuation: 6db
    unit_of_measurement: "V"
    update_interval: 4s
    filters:
      - multiply: 1.89
      - sliding_window_moving_average:
          window_size: 15
          send_every: 15
          send_first_at: 1

binary_sensor:
  - platform: status
    name: "Mailbox Status"
  - platform: gpio
    pin:
      number: GPIO25
    name: "Mailbox Lid"
    device_class: door
    filters:
      - delayed_on: 100ms
      - delayed_off: 10s
  - platform: gpio
    pin:
      number: GPIO26
    name: "Mailbox Door"
    device_class: door
    filters:
      - delayed_on: 100ms
      - delayed_off: 10s
  - platform: gpio
    pin:
      number: 12
      mode: INPUT_PULLDOWN
    name: "Mailbox Wake Pin"
1 Like

This is amazing… I was looking for a way to replace my old 433Mhz mailbox sensor and found this!
I read in the post above that you use a 18650 and solar panel, mind sharing some info on this setup?

I have removed this and now use a zigbee door/window sensor. Much more reliable, even if I do have to replace the battery every couple of years.