Cloud, DevOps e IoT en español

Parte 19 de 22 de la serie Domótica con ESP32 y AWS desde cero

Saber si un ESP32 está conectado: eventos de ciclo de vida en AWS IoT

11 de octubre de 2026 · Steven Carvajal · Tutoriales

Código de este artículo en GitHub →

El Device Shadow guarda el estado aunque el dispositivo esté apagado (parte 5). Eso es bueno para no perder órdenes, pero tiene un efecto secundario: la app puede mostrar "encendido" para una luz cuyo ESP32 lleva horas desconectado. El usuario necesita saber si el dispositivo está en línea.

AWS IoT Core publica un evento cada vez que un cliente MQTT se conecta o se desconecta. En esta parte vemos cómo leerlos, cómo guardar el estado de conexión para la app y qué hacer con los nodos que no hablan directamente con AWS.

Los eventos de conexión

AWS IoT publica en dos tópicos reservados:

$aws/events/presence/connected/<clientId>
$aws/events/presence/disconnected/<clientId>

Un evento de desconexión se ve así:

{
  "clientId": "mi-esp32",
  "timestamp": 1760180400000,
  "eventType": "disconnected",
  "clientInitiatedDisconnect": false,
  "sessionIdentifier": "00000000-0000-0000-0000-000000000000",
  "principalIdentifier": "…",
  "disconnectReason": "MQTT_KEEP_ALIVE_TIMEOUT",
  "versionNumber": 12
}

El campo disconnectReason es oro para depurar:

MotivoQué significa
CLIENT_INITIATED_DISCONNECTEl dispositivo cerró la conexión a propósito
MQTT_KEEP_ALIVE_TIMEOUTDejó de responder: sin energía, sin Wi-Fi o bloqueado
CONNECTION_LOSTSe cortó la conexión de red
DUPLICATE_CLIENTIDOtro cliente se conectó con el mismo client ID
AUTHORIZATION_FAILUREIntentó algo que su política no permite

Para verlos en vivo, suscríbete a $aws/events/presence/# desde el MQTT test client de la consola y reinicia tu ESP32.

Cuánto tarda en detectarse una desconexión

Si el dispositivo se desconecta limpiamente, el evento es inmediato. Si se queda sin energía, AWS no se entera hasta que vence el keepalive: espera 1,5 veces el intervalo de keepalive sin recibir nada. Con el valor por defecto de muchas librerías (60 segundos), son 90 segundos.

Para detectarlo antes, baja el keepalive en el ESP32. Con la librería MQTT de 256dpi:

client.setKeepAlive(30);  // segundos; AWS detectaría la caída en unos 45 s

Un keepalive más bajo envía más pings (un mensaje pequeño cada intervalo), con un costo de conexión y de batería algo mayor.

Guardar el estado de conexión en el Shadow

La app podría suscribirse a los eventos, pero si abre después de la desconexión, se la pierde. Es mejor guardar el estado donde la app ya mira: el Shadow. Una regla de IoT (parte 14) lo hace sin código. La consulta arma el documento con el formato del Shadow:

SELECT { 'reported': { 'conectado': eventType = 'connected', 'desde': timestamp } } AS state
FROM '$aws/events/presence/+/+'

Con la acción Republish al tópico de un Shadow con nombre:

$$aws/things/${topic(5)}/shadow/name/conexion/update

La app lee conectado y muestra el dispositivo en gris cuando es false.

El orden de los eventos

Los eventos pueden llegar desordenados: si un ESP32 se reinicia rápido, el connected de la sesión nueva puede llegar antes que el disconnected de la vieja. Si guardas el último que llega, el dispositivo aparecería desconectado estando en línea.

Dos formas de protegerse:

Para un panel doméstico, una alternativa simple: cuando la app ve conectado: false, pide el Shadow de estado; si el dispositivo responde a una orden, está en línea.

Last Will: el aviso del propio dispositivo

MQTT tiene un mecanismo estándar: al conectar, el dispositivo registra un mensaje de última voluntad (Last Will and Testament). Si la conexión se pierde sin un cierre limpio, el broker lo publica en su nombre:

client.setWill("casa-demo/mi-esp32/estado", "{\"conectado\":false}", true, 1);
client.connect(THING_NAME);
client.publish("casa-demo/mi-esp32/estado", "{\"conectado\":true}", true, 1);

AWS IoT Core admite Last Will y mensajes retenidos. La política del dispositivo debe permitir publicar en ese tópico (y iot:RetainPublish si el mensaje es retenido).

Eventos de ciclo de vidaLast Will
Configuración en el dispositivoNingunaSí, al conectar
Incluye el motivoSíNo
Estándar MQTTNo, propio de AWSSí

Nodos detrás de un hub

Los nodos ESP-NOW no se conectan a AWS: para AWS IoT, solo existe el hub. Si el hub está en línea pero un nodo se quedó sin energía, ningún evento lo dirá.

La solución es que el hub vigile a los nodos:

Consultar la conexión sin guardar nada

Si activas la indexación de flota (Fleet Indexing) con datos de conectividad, puedes consultar qué dispositivos están conectados:

aws iot search-index --query-string "connectivity.connected:false"

Útil para un panel de administración con muchos dispositivos. Tiene un costo propio por indexación y consultas.

Preguntas frecuentes

¿Los eventos de conexión cuestan algo?

Se publican como mensajes MQTT y se cobran como tales cuando alguien los recibe (una suscripción o una regla). Para una casa, fracciones de centavo.

¿Por qué mi dispositivo aparece y desaparece cada pocos segundos?

Mira el disconnectReason. DUPLICATE_CLIENTID indica dos clientes con el mismo client ID; AUTHORIZATION_FAILURE, un permiso que falta en la política.

¿Y si el Wi-Fi funciona pero el dispositivo está bloqueado?

Si el programa se bloquea, deja de responder a los pings y AWS lo verá como MQTT_KEEP_ALIVE_TIMEOUT. Para que se recupere solo, activa el watchdog del ESP32.

Sigue leyendo