MQTT availability topic

I have an mqtt sensor defined like this:

- platform: mqtt
  name: "Left Recliner Availability"  
  state_topic: "home/left-recliner/available"
  availability:
    - topic: "home/left-recliner/available"

And then I have an esp8266 board which publishes to that topic (arduino sdk and cannot use esphome for this) when it is powered on.
My problem is that when it loses power I need HA to detect it as offline but that only happens if I reboot HA server.
In the esp8266 code I cannot set it to offline as it can lose power at any time so how can HA detect it as offline the correct way?

Have you thought about using ping? The ESP has an IP address, so when offline, the ping will fail.

Good idea, it does what is needed and easier to manage, I was complicating things
Thanks for the suggesttion
:grinning:

1 Like

That’s what MQTT’s last will and testament is for. E.g. with pubsubclient, you can specify the last will message when calling connect.

I think that’s a better solution than ping, simply because it’s the standard way to detect availability of MQTT entities in Home Assistant.
It could also potentially be more reliable, in case the ESP was connected to the network but for some reason it couldn’t connect to the MQTT broker.

I am using that yes, and it’s worth just trying for testing at the very least.
I set up the client like so:

while (!client.connected()) {       // Loop until connected to MQTT server
    Serial.print("Attempting MQTT connection...");
    if (client.connect(HOSTNAME, mqtt_username, mqtt_password)) {       //Connect to MQTT server
      Serial.println("connected"); 
      client.publish(AVAILABILITY_TOPIC_LEFT, "online");         // Once connected, publish online to the availability topic
      client.subscribe(EXTEND_LEFT);       //Subscribe to tare topic for remote extension
      client.subscribe(RETRACT_LEFT);       //Subscribe to tare topic for remote retraction
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);  // Will attempt connection again in 5 seconds
    }
  }

I know I need to update this: client.connect(HOSTNAME, mqtt_username, mqtt_password) but not sure on syntax
As is the topic would only change when rebooting HA which makes sense as there is nothing setting it to offline yet

Try this patch:

--- old.cpp	2021-12-21 19:01:44.666893073 +0100
+++ new.cpp	2021-12-21 19:03:04.806553084 +0100
@@ -1,8 +1,8 @@
 while (!client.connected()) {       // Loop until connected to MQTT server
     Serial.print("Attempting MQTT connection...");
-    if (client.connect(HOSTNAME, mqtt_username, mqtt_password)) {       //Connect to MQTT server
+    if (client.connect(HOSTNAME, mqtt_username, mqtt_password, AVAILABILITY_TOPIC_LEFT, 2, true, "offline")) {       //Connect to MQTT server
       Serial.println("connected"); 
-      client.publish(AVAILABILITY_TOPIC_LEFT, "online");         // Once connected, publish online to the availability topic
+      client.publish(AVAILABILITY_TOPIC_LEFT, "online", true);         // Once connected, publish online to the availability topic
       client.subscribe(EXTEND_LEFT);       //Subscribe to tare topic for remote extension
       client.subscribe(RETRACT_LEFT);       //Subscribe to tare topic for remote retraction
     } else {
1 Like

Trying it now and it compiles, thanks.
How about my HA sensor, is that created correctly?
Also, how will it get the “offline” value if the device loses power? I would have thought on the HA sensor need to set some TTL or something?

If availability is all you care about, then I guess it is.
Normally, you’d use something like this:

sensor:
  - platform: mqtt
    name: Temperature
    state_topic: "device/tele/temperature"
    availability_topic: "device/tele/availability"
    unit_of_measurement: "°C"
    device_class: temperature
    state_class: measurement  # long-term statistics

The MQTT broker handles that. It’s called LWT (last will and testament).

Sweet, yes that does work that way :grinning:

Almost there.
If I reboot HA it goes from online to unavailable
image

I assume it has to do with the code above, it only sets it to online when it initially connects and it needs to be set periodically inside the main loop?

That’s why I set retained to true here:

client.publish(AVAILABILITY_TOPIC_LEFT, "online", true);

Again, the MQTT broker will handle it for you.

If you have that in your code and it still doesn’t work, there’s something weird going on.

Ah yes I missed that part :slight_smile: