# Sesión 6: MQTT ## 1. Introducción a MQTT MQTT (Message Queuing Telemetry Transport) es un protocolo de mensajería de publicación/suscripción que se utiliza comúnmente en soluciones de Internet de las Cosas (IoT) debido a su ligereza y eficiencia, lo que lo hace especialmente adecuado para entornos donde los dispositivos tienen recursos limitados y la conexión de red puede ser inestable. ### Historia de MQTT El protocolo MQTT fue desarrollado por Andy Stanford-Clark de IBM y Arlen Nipper de Arcom (ahora Eurotech) en 1999 para permitir el monitoreo de un oleoducto a través del desierto, donde el ancho de banda de red y el suministro de energía eran limitados. En 2013, MQTT se convirtió en un protocolo de estándar abierto bajo la supervisión de la Organización de Normas y Tecnología de la Información (OASIS) y en 2014 MQTT fue publicado como un estándar ISO (ISO/IEC 20922). ### MQTT en IoT MQTT ha sido ampliamente adoptado en el campo de IoT por varias razones clave: - **Ligero y eficiente:** El protocolo MQTT está diseñado para ser ligero tanto en términos de ancho de banda como de requisitos de procesamiento, lo que lo hace adecuado para dispositivos IoT con recursos limitados. Además, el protocolo utiliza un pequeño encabezado de protocolo y admite mensajes de tamaño variable, lo que contribuye a su eficiencia. - **Modelo de publicación/suscripción:** MQTT utiliza un modelo de comunicación de publicación/suscripción que facilita la creación de aplicaciones IoT que requieren comunicación entre múltiples dispositivos. Esto significa que los dispositivos pueden comunicarse entre sí sin necesidad de establecer una conexión directa, ya que la comunicación se maneja a través de un intermediario, el broker MQTT. - **QoS y entrega de mensajes garantizada:** MQTT proporciona diferentes niveles de Calidad de Servicio (QoS) y mecanismos para garantizar la entrega de mensajes, lo que es útil en redes inestables. Los mensajes pueden ser marcados con diferentes niveles de QoS para indicar la importancia de la entrega del mensaje. - **Retención de mensajes y testamentos de última voluntad:** Los mensajes pueden ser retenidos en un topic específico para que cualquier nuevo suscriptor pueda recibir la última actualización de inmediato. Además, un mensaje de "última voluntad" puede ser especificado por un dispositivo para enviar en caso de que la conexión se interrumpa inesperadamente. ### Ventajas y aplicabilidad de MQTT Gracias a estas características, MQTT tiene varias ventajas en el contexto de IoT: 1. **Bajo consumo de energía:** Debido a su ligereza y eficiencia, MQTT es particularmente útil en escenarios donde el ahorro de energía es crucial, como en dispositivos alimentados por baterías. 2. **Transmisión confiable de datos:** Con la capacidad de garantizar la entrega de mensajes, MQTT es una buena opción para aplicaciones donde es esencial la transmisión confiable de datos. 3. **Comunicación bidireccional:** MQTT permite tanto la publicación de mensajes desde los dispositivos como la recepción de comandos desde el servidor, lo que facilita la creación de soluciones IoT interactivas. 4. **Escala bien con un gran número de dispositivos:** El modelo de publicación/suscripción de MQTT hace que sea fácil escalar a un gran número de dispositivos sin aumentar la complejidad de la comunicación entre dispositivos. Dado lo anterior, MQTT es especialmente útil en una amplia gama de campos de aplicación en IoT, incluyendo: - **Telemetría:** El protocolo fue diseñado originalmente para la telemetría, y sigue siendo una excelente opción para la recopilación y transmisión de datos de telemetría desde dispositivos remotos. - **Automatización del hogar y de edificios:** MQTT se utiliza a menudo en sistemas de automatización del hogar y de edificios para permitir la comunicación entre diferentes dispositivos y sistemas. - **Industria 4.0:** MQTT es también una opción popular para la comunicación de máquina a máquina (M2M) en entornos industriales, donde la eficiencia y la confiabilidad son esenciales. - **Vehículos conectados:** MQTT puede utilizarse para transmitir datos desde vehículos a la nube, para aplicaciones como el seguimiento de la ubicación, el monitoreo del estado del vehículo y la entrega de actualizaciones de software. ## 2. Conceptos clave de MQTT ### Cliente y Broker En el contexto de MQTT, un cliente es cualquier dispositivo que se conecta al broker MQTT para publicar o suscribirse a mensajes. El cliente puede ser cualquier tipo de dispositivo, desde un microcontrolador con capacidad de conexión a Internet hasta una aplicación de servidor de gran escala. Ejemplos de clientes MQTT podrían incluir: - Un dispositivo IoT, como un sensor de temperatura, que publica lecturas de temperatura. - Un servidor de backend que se suscribe a las lecturas de los sensores para procesarlos y tomar decisiones en función de los datos. - Un smartphone que se suscribe a las notificaciones para informar al usuario cuando se detecta un evento. Un broker MQTT es un servidor que recibe todos los mensajes de los clientes y los redirige a los clientes correspondientes que se han suscrito a esos mensajes. Ejemplos de brokers MQTT incluyen: - Mosquitto: Un broker MQTT de código abierto muy popular que es fácil de configurar y usar. - HiveMQ: Un broker MQTT de alto rendimiento que ofrece muchas funciones avanzadas, como soporte para WebSockets y una interfaz de gestión web. - AWS IoT Core: Un servicio de Amazon que actúa como un broker MQTT y proporciona una serie de características adicionales, como autenticación y autorización, y la capacidad de enrutar mensajes a otros servicios de AWS. ### Puertos, TCP y UDP MQTT utiliza el protocolo TCP (Transmission Control Protocol) para la transmisión de datos. A diferencia de UDP (User Datagram Protocol), TCP proporciona un canal de comunicación confiable que garantiza que todos los datos lleguen al destino y que lo hagan en el mismo orden en que fueron enviados. En la comunicación por red, un puerto es un punto final de comunicación en un sistema operativo que permite a las aplicaciones enviar y recibir datos. MQTT utiliza por defecto el puerto 1883 para la comunicación no cifrada y el puerto 8883 para la comunicación cifrada con SSL/TLS. Es importante destacar que aunque MQTT utiliza TCP para la transmisión de datos, hay una variante del protocolo llamada MQTT-SN (MQTT para redes de sensores) que está diseñada para ser utilizada sobre UDP, y que puede ser útil en escenarios donde se necesita una mayor eficiencia en el uso de la red. ### Modelo de Publicación/Suscripción MQTT utiliza un modelo de publicación/suscripción, lo que significa que los clientes publican mensajes en topics, y los clientes que se suscriben a esos topics reciben esos mensajes. Este modelo permite que los mensajes sean distribuidos de manera eficiente a uno, muchos o todos los clientes, según sea necesario. ![](https://hackmd.io/_uploads/S1z_cbtwh.jpg) ### Topics y Payload #### Topics Los topics en MQTT son cadenas de caracteres utilizadas como una forma de organizar y filtrar los mensajes. Se puede pensar en ellos como "canales" a través de los cuales se envían los mensajes. Cada mensaje que un cliente publica debe tener un topic asociado y los clientes que deseen recibir esos mensajes deben suscribirse a ese topic específico. Un topic debe tener al menos un carácter y puede utilizar barras ("/") para definir diferentes niveles, similar a la estructura de un sistema de archivos. Por ejemplo, "casa/sala/temperatura" podría ser un topic que un sensor de temperatura en la sala de una casa podría utilizar para publicar sus lecturas. Los topics también admiten dos caracteres especiales para suscripciones: el signo más ("+") y el signo de hash ("#"). Un "+" puede ser usado para sustituir un nivel en un topic (por ejemplo, "casa/+/temperatura" se suscribiría a los mensajes de temperatura de todas las habitaciones de la casa), mientras que un "#" puede ser usado para suscribirse a todos los niveles subsiguientes de un topic (por ejemplo, "casa/#" se suscribiría a todos los mensajes que comiencen con "casa"). ![](https://hackmd.io/_uploads/r1669ZYPn.png) ##### Payload El payload en MQTT es el contenido real del mensaje que se está enviando. Este puede ser cualquier tipo de datos, desde texto sin formato hasta datos binarios codificados en cualquier formato. La interpretación del payload queda a cargo del cliente que recibe el mensaje. Por ejemplo, en el caso del sensor de temperatura mencionado anteriormente, el payload podría ser simplemente la lectura de la temperatura en formato de texto ("22.5"), o podría ser un objeto JSON más complejo que incluya información adicional, como la hora de la lectura o la identidad del sensor. `{'sensor': 'sensor1', 'timestamp': '2023-06-15T12:34:56Z', 'temperature': 22.5}` En MQTT, el tamaño máximo de un mensaje (la suma del topic y el payload) es de 256 MB, aunque en la práctica es recomendable mantener los mensajes lo más pequeños posible para minimizar la utilización de la red y la memoria, especialmente en dispositivos con recursos limitados. ### QoS (Quality of Service) MQTT ofrece tres niveles de calidad de servicio que determinan cómo se realiza la entrega de un mensaje. #### QoS 0 (At most once) Este es el nivel más bajo de QoS y simplemente garantiza que el mensaje se entregará a lo sumo una vez, pero no garantiza que el mensaje llegue al destinatario. No hay reconocimiento de los mensajes y no hay reintentos de entrega. Este nivel puede ser útil en situaciones donde no es crítico perder algún mensaje ocasional. Por ejemplo, si un sensor envía lecturas de temperatura cada segundo, perder una lectura de vez en cuando probablemente no sea un problema. #### QoS 1 (At least once) Este nivel garantiza que el mensaje se entregará al menos una vez al destinatario. Si no se recibe un acuse de recibo, el mensaje se reenvía. Esto puede resultar en mensajes duplicados. Este nivel puede ser útil cuando es importante asegurarse de que el mensaje llega al destinatario, pero no es un problema si se recibe más de una vez. Un ejemplo podría ser un sistema de monitoreo de alarmas que envía alertas. Es esencial que las alertas lleguen, pero no es un problema si se reciben duplicados. #### QoS 2 (Exactly once) Este es el nivel más alto de QoS y garantiza que cada mensaje se entregará exactamente una vez al destinatario. Esto se logra a través de un intercambio de cuatro mensajes entre el cliente y el broker. Este nivel puede ser útil cuando es crítico que el mensaje llegue exactamente una vez. Esto podría ser importante, por ejemplo, en un sistema de control de automatización del hogar en el que un mensaje duplicado (por ejemplo, "encender la luz") podría tener efectos no deseados. Es importante tener en cuenta que, a medida que aumenta el nivel de QoS, también lo hace la sobrecarga de red y procesamiento necesaria para entregar los mensajes. Por lo tanto, es importante elegir el nivel de QoS apropiado para cada aplicación en función de sus requisitos específicos. ![](https://hackmd.io/_uploads/SkYH2ZKD3.png) ### Retained Messages Los mensajes retenidos son una característica de MQTT que permite que un mensaje se marque como "retenido" en un topic específico. Cuando un mensaje está marcado de esta manera, el broker lo almacena y lo envía inmediatamente a cualquier cliente que se suscriba a ese topic en el futuro. Este mensaje retenido se mantiene hasta que se publique un nuevo mensaje retenido en el mismo topic. Los mensajes retenidos son útiles en situaciones donde un cliente puede necesitar conocer inmediatamente el último estado conocido de un topic sin tener que esperar a que se publique un nuevo mensaje. Por ejemplo, imagina un dispositivo que controla la iluminación de una habitación y que publica el estado actual de la luz ("encendido" o "apagado") en un topic específico. Si este mensaje se configura como retenido, cualquier nuevo cliente que se suscriba a ese topic recibirá inmediatamente el último estado de la luz. Esto es especialmente útil si el estado de la luz cambia con poca frecuencia, ya que un nuevo cliente no tendría que esperar a que la luz cambie de estado para conocer el estado actual. Otro ejemplo podría ser un sensor de temperatura que envía lecturas cada cierto tiempo. Si un cliente se conecta entre dos lecturas, no tendría información sobre la última lectura de temperatura. Pero si el sensor envía sus lecturas como mensajes retenidos, cualquier cliente que se suscriba a ese topic recibirá inmediatamente la última lectura, proporcionando una mejor experiencia de usuario. Es importante recordar que solo el último mensaje retenido se guarda para cada topic. Cuando se publica un nuevo mensaje retenido en un topic, este reemplaza cualquier mensaje anterior que haya sido retenido en ese topic. ### Last Will Testament El Last Will Testament (Testamento) es un mensaje que un cliente puede preparar para que el broker lo envíe automáticamente en caso de que la conexión del cliente se pierda inesperadamente. Cuando un cliente se conecta a un broker, puede especificar su testamento. Este testamento es un mensaje normal de MQTT con un topic, un payload y un QoS especificados. Si el broker no recibe el ping del cliente (mensaje de keep-alive) o si el cliente no se desconecta limpiamente, el broker asume que la conexión se ha perdido y publica el mensaje del testamento. Esta característica es muy útil en situaciones en las que es importante para otros clientes conocer el estado de conexión de un cliente. Por ejemplo, imagina un sistema de alarma donde un sensor se conecta a un broker y otros dispositivos se suscriben a los mensajes de ese sensor. Si el sensor se desconecta inesperadamente (por ejemplo, debido a un fallo de energía), sería importante que los otros dispositivos supieran que el sensor no está operativo. Esto podría hacerse configurando un mensaje de testamento en el sensor que diga algo como "sensor desconectado". Otro ejemplo podría ser un sistema de chat donde cada cliente publica su estado de conexión en un topic específico. Cuando un cliente se conecta, podría configurar un mensaje de testamento que diga "desconectado". De esta manera, si la conexión del cliente se pierde inesperadamente, los otros clientes verían el mensaje "desconectado" y sabrían que ese cliente ya no está disponible. Es importante recordar que los mensajes de testamento sólo se publican cuando el broker detecta que la conexión del cliente se ha perdido. Si un cliente se desconecta de forma limpia enviando un mensaje de desconexión, el broker no publicará su mensaje de testamento. ### Versiones del Protocolo MQTT MQTT ha pasado por varias revisiones desde su creación. A continuación, se describen las dos versiones más utilizadas hoy en día: #### MQTT 3.1.1 MQTT 3.1.1, que fue estandarizado por OASIS en 2014, es la versión más comúnmente usada del protocolo. Esta versión es un gran avance con respecto a la versión anterior 3.1 y se considera ligera, fácil de implementar y adecuada para dispositivos de baja potencia. En esta versión, MQTT es un protocolo basado en la publicación/suscripción de mensajes, que usa TCP/IP para la entrega de paquetes y ofrece tres niveles de calidad de servicio para el envío de mensajes. #### MQTT 5.0 MQTT 5.0 es la versión más reciente del protocolo, estandarizada en 2019. Esta versión introdujo varias mejoras y características adicionales en comparación con MQTT 3.1.1. Algunas de estas mejoras incluyen: - Propiedades del mensaje: MQTT 5.0 introduce más de 30 propiedades de mensajes que se pueden incluir en los paquetes de MQTT para proporcionar información adicional, como un campo de descripción para los códigos de retorno, el vencimiento del mensaje y el máximo tamaño del paquete. - Retorno de funciones: En MQTT 3.1.1, si un cliente publica un mensaje con QoS 1 o 2 y el broker no puede entregarlo, el mensaje se perderá. En MQTT 5.0, el broker puede informar al cliente de que no pudo entregar el mensaje. - Shared subscriptions: En las versiones anteriores de MQTT, si varios clientes se suscriben al mismo topic, todos reciben los mensajes publicados en ese topic. MQTT 5.0 introduce las suscripciones compartidas, que permiten que los mensajes se distribuyan entre varios clientes en una suscripción. Aunque MQTT 5.0 proporciona características avanzadas y mejora la funcionalidad en comparación con MQTT 3.1.1, su adopción aún está en curso y MQTT 3.1.1 todavía se utiliza ampliamente debido a su simplicidad y al hecho de que ya está implementado en muchas soluciones de IoT existentes. ## Parte Práctica: Trabajando con MQTT Después de aprender los fundamentos teóricos de MQTT, es momento de poner en práctica lo aprendido. A continuación, te propongo una serie de ejercicios prácticos que puedes realizar para familiarizarte con MQTT. #### Ejercicio 1: Publicación y suscripción a topics 1.1 Descargar e instalar un cliente MQTT en tu ordenador. Puede ser cualquier cliente MQTT que soporte MQTT 3.1.1, como MQTT.fx, [MQTT Explorer](http://mqtt-explorer.com/) o el cliente [Mosquitto](https://mosquitto.org/download/). 1.2 Usar el cliente para conectarse a un broker MQTT proporcionado por los organizadores del bootcamp. 1.3 Publicar un mensaje en un topic de tu elección. 1.4 Suscribirse al mismo topic y verificar que el mensaje se recibe correctamente. #### Ejercicio 2: Experimentando con QoS y mensajes retenidos 2.1 Publicar mensajes en un topic utilizando diferentes niveles de QoS y observar cómo se comporta cada uno. 2.2 Publicar un mensaje retenido en un topic, desconectarse, volver a conectarse y suscribirse al mismo topic para verificar que el mensaje retenido se recibe correctamente. #### Ejercicio 3: Trabajando con Last Will Testament 3.1 Configurar un mensaje de testamento en el cliente MQTT. 3.2 Interrumpir la conexión del cliente sin enviar un mensaje de desconexión y verificar que el broker publica el mensaje de testamento.