Retained Messages and Last Will with ESP32: Online/Offline Status
An IoT dashboard needs to show more than the last sensor value. If an ESP32 loses power or Wi-Fi, the broker may still have the last temperature reading. Without an availability signal and freshness timestamp, the dashboard can make an old reading look current.
MQTT offers two useful mechanisms: retained publications let a new subscriber receive the latest retained value for a topic, and Last Will and Testament (LWT) lets a broker publish a preconfigured message if a client disconnects unexpectedly. Used carefully, they provide an online/offline indicator for an ESP32.
1. Choose a status topic
Use a dedicated availability topic such as solderhub/lab/esp32-01/status. Register a retained offline message as the Last Will during connection setup, then publish retained online after the device connects successfully and is ready to report.
Keep status distinct from telemetry and commands. A status message says something about connection availability; a temperature message says what a sensor measured; a command tells the device what a controller wants. Those are different facts and should not overwrite each other.
2. Configure Last Will in PubSubClient
PubSubClient offers a connect overload that accepts a will topic, QoS, retained flag and will payload. The fragment below shows the pattern. It assumes the MQTT object has already been configured and Wi-Fi is connected. Use the appropriate overload with username/password if broker authentication is enabled.
This is a focused fragment, not a complete firmware sketch. Define mqtt and broker settings in your project. Do not hard-code production secrets into public source files. In the main loop, reconnect with a controlled interval and call mqtt.loop() regularly while connected. Do not assume the broker can publish a Will instantly at the moment a cable is unplugged.
3. What retained status changes
If a dashboard subscribes after the device has connected, the broker can immediately send the latest retained online status. Without retention, a new subscriber normally waits until the next publication to learn status.
Retained status is not a full history. If multiple systems publish different values to the same status topic, the latest retained message wins. Establish one authoritative publisher for each device's availability. When decommissioning a device, clear its retained status deliberately using the broker/client behavior documented for your setup.
4. Availability is not the same as fresh sensor data
A device can remain connected while a sensor read fails. It can also publish online and then stop sending measurements due to a firmware bug. Keep the last time a valid telemetry message arrived as a separate field or timestamp.
For a dashboard, show connection status, last valid sample time, the measurement and unit, and a stale indicator after a documented timeout. Do not translate missing messages into zero temperature or zero humidity. Zero may be valid for some measurements.
5. Test the behavior
- Start a subscriber on the status topic.
- Boot the ESP32 and confirm retained online status.
- Disconnect device power or force an unexpected network loss.
- Wait for the broker to detect the disconnect; offline may not publish instantly.
- Connect a new subscriber and confirm it receives the latest retained status.
- Reconnect the ESP32 and confirm it publishes online again.
Test graceful shutdown separately. If firmware publishes offline before a planned disconnect, that differs from a broker publishing LWT after unexpected loss. Record observed detection time under your keep-alive and network conditions.
Avoid unsafe retained commands
Do not casually retain one-shot command payloads such as TOGGLE, UNLOCK, OPEN or PULSE. A device that reconnects and resubscribes may receive an old command and repeat an action. For many actuator designs, use non-retained commands and retain reported state instead.
If a system needs desired-state retention, implement it as an explicit policy. Firmware must validate the value, establish a safe boot state and publish what it actually applied. A retained MQTT value is not a safety-rated control or proof that a physical output moved.
Troubleshooting
Offline never appears: the broker needs to detect the unexpected disconnect. Check keep-alive behavior and broker logs. A graceful disconnect may not trigger the Will.
A new subscriber sees no state: check topic and retained flag, and confirm another publisher has not overwritten the retained value.
Status flips between devices: each device should use its own unique topic and client ID.
Dashboard still shows stale temperature: availability and telemetry freshness are separate; track the last valid sensor timestamp.
Next steps
- MQTT Explained: Broker, Topics, QoS, Retained Messages and Last Will
- MQTT Topic Naming Best Practices
- Non-Blocking MQTT Auto-Reconnect on ESP32
Official references: Mosquitto documentation and the documentation for the exact PubSubClient release used by your sketch.