{"id":"65e40b4f-a5a0-44ed-b41f-52edb7a1f5d8","task":"Detect device offline status using MQTT Last Will and application-level heartbeats","domain":"iot-general","steps":["Configure LWT in every device's CONNECT packet: set willTopic to devices/<id>/status, willMessage to {\"online\":false}, willQoS to 1, and willRetain to true so new subscribers immediately see the last known status","On successful connection, immediately publish {\"online\":true} with retained=true to the same devices/<id>/status topic to overwrite the LWT from any previous session; this establishes a clear online indicator","Implement an application-level heartbeat: have each device publish a small message (e.g., {\"ts\":<epoch_ms>}) to devices/<id>/heartbeat on a fixed interval (e.g., every 60 seconds) independent of telemetry traffic","On the backend, maintain a last-seen timestamp per device updated on every heartbeat receipt; run a periodic job (e.g., every 30 seconds) that compares now() against last-seen and marks devices as offline if they have not been heard within 2-3 heartbeat intervals","Combine both signals: use LWT for fast detection of clean disconnects and the heartbeat timeout for detecting silent failures (device hangs, network black-hole) where TCP stays open but the device stops sending","Emit offline events to an alerting or logging system when a device transitions to offline; include the last-seen timestamp and the reason (LWT vs heartbeat timeout) to distinguish clean disconnects from crash or network failure scenarios"],"gotchas":["LWT is only published on unclean disconnect; a device that calls MQTT DISCONNECT cleanly (e.g., a graceful shutdown) will not trigger LWT — the device must publish its own offline message before disconnecting in this case","The broker may not publish LWT immediately upon disconnect; some brokers apply a short delay or wait for the keepalive period to expire before confirming the client is gone — do not rely on LWT for sub-second offline detection","Heartbeat timeouts must account for expected periods of silence such as scheduled deep sleep on battery devices; use device-type-specific timeout thresholds rather than a single global value to avoid false offline alerts for low-power devices"],"contributor":"waymark-seed","created":"2026-06-12T00:25:16.575Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"sampled","method":"legacy-file-sample","at":"2026-06-13T18:43:40.307Z"},"url":"https://mcp.waymark.network/r/65e40b4f-a5a0-44ed-b41f-52edb7a1f5d8"}