This is part of a series explaining different concepts of MQTT. If you are new to MQTT, please read the Fundaments of MQTT first.
How does MQTT Last Will and Testament(LWT) Work?
Normally if you want the client to disconnect you can simply run a disconnect() function. But if the client disconnects without the function being executed, you want to know about it. That is where Last Will & Testament comes in. How it works:
- Client sets last will & testament message payload and topic name before connecting to the broker.
- Broker stores the LWT message until a disconnect() function is called. If a disconnect() function is called the broker discards the LWT message.
- If the client unexpectantly disconnects, the broker publishes the LWT message to the LWT topic.
Best Practices For MQTT Last Will & Testament
Not all MQTT Clients have this feature. I suggest using this feature whenever it is available as long as it doesn’t cost too much to increase the number of messages published.
- Set a topic specific to a device. For example: “device1/status“. Make sure no other device uses this topic.
- If the device goes offline send a message to that topic saying “Offline” or similar. But also send a message saying “Online” when it reconnects to the broker.
- Use retained messages feature when publishing to that topic. The broker will always store the last retained message on that topic. So if you publish a message “Online” to “device1/status”, you can simply have another client subscribe to that topic to see its status. See more about Retained messages:
MQTT Retained Messages
Paho-MQTT Python Example
This example assumes you know the basics of Paho-MQTT. If not see this post:
MQTT Python With Paho-MQTT Client (Step-by-Step Guide With Examples)
will_set()function which is a function of the
mqtt.clientconstructor. The Syntax for will_set() is:
will_set(topic, payload=None, qos=0, retain=False)
import paho.mqtt.client as mqtt def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) client.publish("device1/status",payload="Online", qos=0, retain=True) client = mqtt.Client() client.on_connect = on_connect client.will_set("device1/status", payload="Offline", qos=0, retain=True) client.connect("iot.eclipse.org", 1883, 60) client.loop_forever()
What is going on in the code above?
- I created the
on_connect()callback function. If you notice, I have set a publish function to publish a message to the status “device1/status” to make sure the status changes to Online once the device reconnects.
- I created an instance of the mqtt client constructor and assigned it to client.
- I set the last will & testament function for the broker. I set the payload message to “Offline”. So if the client disconnects, the message will be published to the topic “device1/status”
Run this program and check the messages in that topic. Try stopping the client forcefully and see if the message “Offline” gets published to that topic. This is how the output should look: