Home Assistant sets MQTT connected ESPHome device "Unavailable" before it processes MQTT "Last Will message". Can this be reversed?

Hi all

I am trying to make a cheap and compact solution, where I use an ESP01 connected to a 230V AC source via a 3.3v power supply, to signal to Home Assistant that the 230V AC source has turned On and Off.

I have this ESPHome configuration. In the configuration I call the 230V AC source for “Gadelys” (Street light in Danish).

mqtt:
  broker: !secret HGV10_MQTT_Broker_IP
  username: !secret HGV10_MQTT_Broker_username
  password: !secret HGV10_MQTT_Broker_password
  discovery: true
  birth_message:
    topic: eh-osg21-u-gadelys/sensor/Gadelys/state
    payload: "On"
  will_message:
    topic: eh-osg21-u-gadelys/sensor/Gadelys/state
    payload: "Off"

captive_portal:

binary_sensor:
  - platform: status
    name: "Gadelys"
    device_class: light
    icon: "mdi:coach-lamp-variant"

As you can see I use the “birth_message” and “will_message” in an unconventional manner to set the state of the Sensor called “Gadelys” to either “On” og “Off”. However in Home Assistant the “will message” is not processed before the device state becomes “Unavailable” as you can see in this screenshot.
2022-07-10 HomeAssistant set device unavailable before it processes LastWill message

Does anyone have an idea for how I can configure the ESP01 device or Home Assistant, get Home Assistant to process the “will message” before setting the ESP01 device to “Unavailable”?

Kind regards Jakob

Not sure if it behave the same with mqtt but when using the api you can just add deep_sleep to your yaml (without making use of it) and then the sensors don’t become unavailable.

Also, did you try the native api for your use case? It got some recent changes that ha will connect to that esphome node right after it joins wifi (and announces that it is present) so the times that it could take ~30 seconds before a esphome node gets available after boot should be over :muscle:

1 Like

Thanks for pitching in here @orange-assistant :+1:

I just tried adding deep_sleep: to the ESPHome configuration of the ESP01 device, however Home Assistant retained its behavior.

I am only using MQTT instead of the Native API because the ESP01 device is on the other side of an OpenVPN tunnel (it’s at another house we are building, where it will be some time yet before it will be possible to install a local device/server to run Home Assistant). My previous experimentation showed that only with MQTT could I get the ESPHome devices to route back to Home Assistant at our primary house).

My hope here was that I could implement something really simple in the ESP device to add the monitoring I was looking for. But I guess I’ll then simply base my by automation on if the “Gadelys” sensor is showing its state as “On” and if not then assume the street light is off. I just liked the cleanliness of the sensor switching between “On”/“Off” and not “On”/“Unavailable” :grinning:.

/Jakob

2 Likes

Did you try this here :point_down:

If the birth message and last will message have empty topics or topics that are different from each other, availability reporting will be disabled.
https://esphome.io/components/mqtt.html#last-will-and-birth-messages

Looks like it’s what you want? :raised_hands:

1 Like

Good point, I’ve now set only the “will_message” which then means that the availability reporting is disabled and that the “Gadelys” sensor is set to Off when I turn off power to the ESP01.
Now my challenge is figure out how to manually set the sensor value to “On” when the ESP01 has booted.

Using the on_boot event to call the lambda function publish_state(true) is not working :cry:
But its beyond bed time, so I’ll fiddle some more with this tomorrow. Thanks for the help so far :+1:

esphome:
  name: eh-osg21-u-gadelys
  on_boot:
    priority: 600
    then:
      lambda: !lambda |-
        id(Gadelys).publish_state(true);
1 Like

Ups, totally forget that you used part of the function for your availability reporting :thinking:

But it’s a new day now :sunrise_over_mountains:

Maybe just publishing the mqtt topic directly like this:

esphome:
  name: eh-osg21-u-gadelys
  on_boot:
    priority: 600
    then:
      - mqtt.publish:
          topic: eh-osg21-u-gadelys/sensor/Gadelys/state
          payload: "On"

or maybe even better, send it directly after the node is connect to the mqtt broker:

mqtt:
  # ...
  on_connect:
      - mqtt.publish:
          topic: eh-osg21-u-gadelys/sensor/Gadelys/state
          payload: "On"
1 Like

Bahh, I can’t get it to work… For some reason the MQTT on_connect event doesn’t seem to fire (even adding to log doesn’t work). And the override of the last will and birth messages didn’t really give me anything I didn’t have already.

So I’ve gone back to the most simple configuration I think will do and I’ll simply automate based on the “Gadelys” entity switching between “On” and “Unavailable” states :grin:

But I really appreciate your effort here @orange-assistant :+1:

esphome:
  name: eh-osg21-u-gadelys

esp8266:
  board: esp01_1m

# Enable logging
logger:

ota:
  password: !secret ESPHome_API_password

wifi:
  networks:
  - ssid: !secret OSG21_WiFi_SSID
    password: !secret OSG21_WiFi_password
    manual_ip:
      static_ip: 192.168.21.98
      gateway: 192.168.21.1
      subnet: 255.255.255.0  
  - ssid: !secret HGV10_WiFi_SSID
    password: !secret HGV10_WiFi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "eh-osg21-0-gadelys"
    password: !secret WiFi_ESPHomeFallbackAP_password

captive_portal:

mqtt:
  broker: !secret HGV10_MQTT_Broker_IP
  username: !secret HGV10_MQTT_Broker_username
  password: !secret HGV10_MQTT_Broker_password
  discovery: true

binary_sensor:
  - platform: status
    id: Gadelys
    name: "Gadelys"
    device_class: light
    icon: "mdi:coach-lamp-variant"
1 Like