Skip to main content

Heartbeat & Keep-Alive

VWire tracks device health using a combination of MQTT keep-alive (automatic) and optional application-level heartbeats (recommended for long-idle devices).


MQTT keep-alive (automatic)

When the VWire library connects, it negotiates a 60-second keep-alive with the broker:

EventWhat happens
Device publishes dataKeep-alive timer resets
No activity for 30 sLibrary sends MQTT PINGREQ
Broker doesn't respondLibrary considers connection lost
PING acknowledgedTimer resets, connection healthy
Connection truly droppedBroker publishes LWT (status: offline)

This is all handled automatically — you don't need to write any PING code.


Reconnect behavior

The VWire library reconnects automatically after a disconnect:

Disconnect → Wait 5 s → Reconnect attempt
→ Failed → Wait 10 s → Retry
→ Failed → Wait 30 s → Retry
→ ...exponential backoff, cap 120 s

After reconnecting, the library calls Vwire.syncVirtual() for all pins that were registered for sync.


For devices that sleep or have long idle periods, supplement MQTT keep-alive with a periodic data push:

unsigned long lastHeartbeat = 0;
const unsigned long HEARTBEAT_INTERVAL = 30000; // 30 s

void loop() {
Vwire.run();

// Normal sensor data (infrequent)
if (someCondition) {
Vwire.virtualSend(V0, sensorValue);
}

// Heartbeat — just push uptime so the server sees activity
if (millis() - lastHeartbeat >= HEARTBEAT_INTERVAL) {
lastHeartbeat = millis();
Vwire.virtualSend(V9, millis() / 1000); // uptime in seconds
}
}

Bind V9 to a Value Display widget labeled "Uptime (s)" to confirm the device is alive.


Detecting device health in the dashboard

IndicatorMeaning
Green dot (Online)MQTT connection active
Red dot (Offline)MQTT LWT received or connection timed out
"Last Seen" timestampWhen the device last published any data

Watchdog timer (ESP32 / ESP8266)

Enable the hardware watchdog as a safety net against firmware hangs:

#include <esp_task_wdt.h>

void setup() {
esp_task_wdt_init(30, true); // 30 s timeout, panic on hang
esp_task_wdt_add(NULL); // watch current task (loop)
// ...
}

void loop() {
Vwire.run();
esp_task_wdt_reset(); // reset watchdog every loop
// ...
}

If loop() ever stops running (stuck, blocked I/O), the watchdog resets the device and VWire reconnects automatically.