How to get "last known value" while sensor is in deep sleep

@asouthernboy, did you work this out at all? I have the same desire for a battery powered esp8266 based temperature logging device.

Try adding empty LWT payloads:

  birth_message:
    topic: wemos_plantmonitor/status
    payload: ''
  will_message:
    topic: wemos_plantmonitor/status
    payload: ''

I’ve tested this and it seems to work just fine (as stated in the docs).
My problem was that I already had my device auto discovered so I needed to do this in several steps.

  1. Remove MQTT integration
  2. Clean retained messages (esphome configuration.yaml clean-mqtt)
  3. Change MQTT settings to run off auto discovery (discovery: false)
  4. Run configuration again (with birth message still active since home assistant had turned the device off)
  5. Restart Home assistant
  6. Change MQTT settings so that both birth and will messages were empty.
  7. Run configuration again.

I hope I remember the sequence correctly.
I double checked that the device was removed from the integrations view of home assistant and all values seems to be updated correctly.

Bonjour,

Avez vous pu trouver une solution a cette problématique ?
J’ai la même volonté d’affichage des dernières données quand l’ESP se met en sommeil profond.
Merci d’avance
Giloris

This is an English forum you will get a better response by using it.

The answer to your question is contained in the two posts above yours.

Hi
Sorry i forgot to convert it !
I dont use mqtt on Esphome
I use this code

i2c:
  sda: 4
  scl: 5
  scan: True
  


deep_sleep :
  run_duration : 1 min
  sleep_duration : 5 min



binary_sensor:
  - platform: gpio
    pin: D5
    name: "Capteur magnetique"
    device_class: window

light:
  - platform: binary
    name: "Simple LED"
    output: red_led
    
  - platform: binary  
    name: "Simple LED1"
    output: red_led1
    
  - platform: binary 
    name: "Simple LED2"
    output: red_led2

output:
  - platform: gpio
    id: red_led
    pin: D3
   
  - platform: gpio  
    id: red_led1
    pin: D4
  
  - platform: gpio  
    id: red_led2
    pin: D7
   
       

sensor:
  - platform: dht
    pin:
      number: D6
    temperature :  
      name: "Température"
    humidity :
      name: "Humidité"
    update_interval : 30s
    model: dht22

  - platform: adc
    pin: VCC
    name: "VCC Voltage"
    update_interval : 30s
  
  - platform: ina219
    address: 0x40
    shunt_resistance: 0.1 ohm
    current:
      name: "Solar Current"
      accuracy_decimals: 3
      filters:
       - multiply: 120
    power:
      name: "Solar Power"
      filters:
       - multiply: 120
    bus_voltage:
      name: "Bus Voltage"
      accuracy_decimals: 3
    shunt_voltage:
      name: "Shunt Voltage"
      filters:
      - multiply: 120
      accuracy_decimals: 3
    max_voltage: 10.0V
    max_current: 3.2A
    update_interval: 30s 
    
  - platform: wifi_signal
    name: "WiFi Signal Sensor"
    update_interval: 60s

Regards

I assume you are using the api then?

You must have cropped that bit.

Otto (the ESPhome developer) has mentioned that it is better to use mqtt rather than the api if using deep sleep.

Hi I seem to be 95% of the way to completing this and the last reading is sustained correctly while in deep sleep. However when the ESP wakes up and reports new readings the the Lovelace card ‘flickers’ when the readings come through (I’m using a gauge style card). It seems like the card is flip flopping between nan and a reading. Any ideas?

esphome:
  name: pool_temperature
  platform: ESP32
  board: esp-wrover-kit

wifi:
  ssid: "ssid"
  password: "pwd"
  fast_connect: true
  
  manual_ip:
    # Set this to the IP of the ESP
    static_ip: 192.168.100.34
    # Set this to the IP address of the router. Often ends with .1
    gateway: 192.168.100.1
    # The subnet of the network. 255.255.255.0 works for most home networks.
    subnet: 255.255.255.0

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Pool Temperature"
    password: "pwd"

captive_portal:

# Enable logging
logger:

# Example configuration entry
switch:
  - platform: restart
    name: "Pool Temperature Reboot"

# Enable Home Assistant API
#api:
#  password: "pwd"

ota:
  password: "pwd"
  
  # Example configuration entry
dallas:
  - pin: GPIO23
    update_interval: 1s

# Individual sensors
sensor:
  - platform: dallas
    address: 0xDD021463593BFF28
    name: "Pool Temperature"


mqtt:
  broker: 192.168.1.10
  username: usr
  password: pwd
  discovery: true
  
  birth_message:
    topic: pool_temperature/status
    payload: ''
  will_message:
    topic: pool_temperature/status
    payload: ''
# ...
  on_message:
    topic: livingroom/ota_mode
    payload: 'ON'
    then:
      - deep_sleep.prevent: deep_sleep_1
      - logger.log: "******Deep Sleep Inhibited********"
      
# Deep Sleep to save power
deep_sleep:
  run_duration: 3s
  sleep_duration: 30s
  id: deep_sleep_1
1 Like

Try sending the states as retained mqtt messages.

I did this but no change:

  birth_message:
    topic: pool_temperature/status
    payload: ''
    retain: true
  will_message:
    topic: pool_temperature/status
    payload: ''
    retain: true

Try the sensor states.

Being new to HASS and ESPhome and mqtt (all at the same time!)I’m struggling to understand a number of issues.

I’ve added a retain: true here but again no change.

# Individual sensors
sensor:
  - platform: dallas
    address: 0xDD021463593BFF28
    name: "Pool Temperature"
    retain: true

I rebooted hass (and “clean MQTT” in ESPhome) and now no flickering - I think it’s sorted.
I need to go back to the classroom and try understand all these different hooks and integrations. Its making my head spin!

I don’t use mqtt, but with esphome, you can use a template sensor like this (for car battery voltage) to feed the outdated template sensor data into it when it’s unavailable, and only update it with real values when the sensor is available.

  - platform: template
    sensors:
       car_battery_voltage:
          friendly_name: Car Battery Voltage
          unit_of_measurement: 'V'
          value_template: >
            {% if states('sensor.car_battery_voltage') == "unavailable" %}
              {{states('sensor.car_battery_voltage_2')}}
            {% else %}
            {{states('sensor.car_battery_voltage')}}
            {% endif %}
1 Like

I’ve had the same issue and just won with it.

TL;DR set entire birth_message and will_message to be empty and it all works, retaining last sensor values.

As per Esphome documentation: https://esphome.io/components/mqtt.html#last-will-and-birth-messages the birth and will messages should have empty topics, not payloads. It’s actually impossible because Esphome complains then about empty string where it can’t be. There’s a fix in discussion in this Esphome issue: https://github.com/esphome/issues/issues/352 , it will work if entire will_message and birth_message are empty, without any sub-keys.
No need for any sensor templates in Homeassistant, I’m actually still running a pretty vanilla installation with autogenerated Lovelace dashboard and almost zero handwritten yaml.

My working Esphome yaml fragment:

mqtt:
  broker: ...
  port: ...
  username: ...
  password: ...
  client_id: $devicename
  topic_prefix: $devicename
  birth_message:
  will_message:
  on_message: 
    topic: ${devicename}/ota_mode 
    then: 
      - deep_sleep.prevent: deep_sleep_1

This should definitely be updated in Esphome documentation :wink:

2 Likes

1,000 thanks!!! :pray:

This solved my problem. Now HA retains my sleeping sensors during sleeping and after HA restarts.

MQTT Explorer shows exactly what you said and it explains why HA was showing unavailable after restarts.

esphome/roof_deck_door.yaml

mqtt:
  broker: "192.168.69.10"
  username: !secret mqtt_user
  password: !secret mqtt_pass
  # DO NOT DO THIS:
  birth_message:
    topic: $devicename/status
    payload: ""
  will_message:
    topic: $devicename/status
    payload: ""

Results as this in MQTT Explorer:

{
  "device_class": "door",
  "name": "Roof Deck Door",
  "state_topic": "esp_roof_deck_door/binary_sensor/roof_deck_door/state",
  "availability_topic": "esp_roof_deck_door/status",
  "payload_available": "",
  "payload_not_available": "",
  "unique_id": "ESPbinary_sensorroof_deck_door",
  "device": {
    "identifiers": "246f289de560",
    "name": "esp_roof_deck_door",
    "sw_version": "esphome v1.15.3 Jan 24 2021, 10:58:21",
    "model": "DOIT ESP32 DEVKIT V1",
    "manufacturer": "espressif"
  }
}

But, your solution:

esphome/front_door.yaml

mqtt:
  broker: "192.168.69.10"
  username: !secret mqtt_user
  password: !secret mqtt_pass
  # This makes Home Assistant always show a status (instead of "unavailable")
  birth_message:
  will_message:

causes this in MQTT Explorer:

{
  "device_class": "door",
  "name": "Front Door",
  "state_topic": "esp_front_door/binary_sensor/front_door/state",
  "unique_id": "ESPbinary_sensorfront_door",
  "device": {
    "identifiers": "246f28a26c48",
    "name": "esp_front_door",
    "sw_version": "esphome v1.15.3 Jan 27 2021, 20:10:00",
    "model": "DOIT ESP32 DEVKIT V1",
    "manufacturer": "espressif"
  }
}

With

  "payload_available": "",
  "payload_not_available": "",

now missing, HA justs used the retained topics on startup and while the sensor is sleeping (becuase it doesn’t publish anything before going to sleep).

Thanks again!

1 Like

Phew, I was afraid digging up 6-month old topics is going to be frowned upon here :grinning: Glad that it helped you! I wonder where it should be in the documentation, ESPHome or HomeAssistant? Or maybe just hope this thread will be recommended by search engines whenever someone stumbles upon this problems.

I think the ESPHome docs should show the differences between:

birth_message:
will_message:

and

birth_message:
topic: $devicename/status
payload: “”
will_message:
topic: $devicename/status
payload: “”

It is so subtle that an explaination seems like it makes sense.

Thank you. This worked.

I came across this as the solution for my own ESPHome sensor that goes into deep sleep. This seems to work well for me.

Now, what I want is for the sensor to become “unavailable” if it does not phone home in the requested time interval. Let’s say it’s supposed to report a value every hour, then go back to sleep. How can I set up the sensor so that it will show as unavailable if a value has not been reported in the last hour? Would this have to be done via a template sensor that checks when the last reported value was?