Publicando datos en Thingspeak. Parte 5: Usando MQTT

Siguiendo con la serie de artículos dedicados a los distintos métodos y protocolos disponibles para enviar datos de sensores a Thingspeak, en esta oportunidad toca revisar como podemos hacerlo empleando el conocido protocolo MQTT.

Introducción

En artículos anteriores de esta serie vimos como usar el protocolo HTTP para enviar datos a Thingspeak. HTTP es sencillo de utilizar pero es un protocolo pensado para computadoras que acceden a los datos almacenados en un servidor y no para pequeños dispositivos de IOT con recursos limitados. Para este uso es mas eficiente utilizar un protocolo especialmente creado con esta finalidad como MQTT, que veremos a continuación.

El protocolo MQTT

Lo que sigue es una muy breve introducción al tema para luego presentar el código en Micropython que utilizaremos para enviar datos a Thingspeak. En otro artículo te prometo que voy a hacer un tutorial mas completo, porque el tema se lo merece.

MQTT (MQ Telemetry Transport) es un protocolo de comunicaciones pensado para la transmisión de datos desde pequeños dispositivos a un servidor o pequeños dispositivos entre si.

Es mas liviano que HTTP, en el sentido de que utiliza paquetes de datos mas pequeños, sin tanta información adicional. Paquetes mas pequeños significan menos tiempo de transmisión y por lo tanto un ahorro de energía, algo sumamente importante en dispositivos alimentados a batería (mientas mas datos haya que transmitir, mas tiempo deberá estar prendida la radio y mas energía se consumirá desde la batería).

A diferencia de HTTP, que tiene un esquema petición-respuesta (el cliente hace una petición al servidor y este le da una respuesta), MQTT funciona con un esquema de suscripción en el que la información fluye en los dos sentidos.

Broker y clientes

El servidor que controla el flujo de información en MQTT recibe el nombre de Broker.

Los dispositivos que se conectan al broker para enviar y/o recibir información se denominan clientes.

Los clientes pueden enviar datos al broker o recibirlos de él, pero no pueden intercambiar datos directamente entre ellos. Es decir que el broker es un intermediario obligado en el flujo de información.

Fig. 1. Esquema de conexión clientes-broker

Entonces, si queremos enviar y recibir datos empleando MQTT vamos a necesitar un broker. Podemos descargar un software gratuito de broker e instalarlo nosotros mismos en una Raspberry Pi o en un servidor de nuestra propiedad o alquilado, o podemos usar los servicios de un broker que ya esté funcionando, que puede ser comercial o gratuito.

Uno de los programas de broker mas populares es Mosquitto. Podemos descargarlo libremente e instalarlo nosotros o usarlo de manera gratuita, al menos para hacer pruebas.

En este artículo enviaremos datos a Thingspeak así que utilizaremos el broker que ellos ponen a nuestra disposición.

Publicación y suscripción

En MQTT los clientes pueden tener dos roles: publicador y suscriptor (publisher y suscriber).

Un cliente publicador envía datos al broker, mientras que un suscriptor los recibe del broker.

El broker organiza los datos en los llamados “tópicos” (topics). Cuando un publicador envía datos al broker, debe indicarle a que tópico (o tópicos) está destinado. Para recibir información, los suscriptores deben suscribirse a uno o varios tópicos.

El funcionamiento es similar al de un canal de Youtube. El o los creadores de contenido (publicadores) suben videos al canal (tópico). Quienes están interesados en los videos (suscriptores), se suscriben a ese canal y cuando hay un video nuevo (información), Youtube (el broker) les envía una notificación para que lo vean.

Esta es una de las principales diferencias con HTTP: en MQTT cuando un suscriptor se ha suscripto a un tópico, no necesita estar enviando peticiones al servidor consultando si hay datos para el. Puede quedarse a la espera y el broker le avisará cuando tenga los datos disponibles.

Preparando MQTT en Thingspeak

Para poder acceder al servidor MQTT de Thingspeak debemos hacer primero algunas configuraciones.

Para esta parte asumo que ya tienes una cuenta creada en Thingspeak, así como un canal preparado. Si no es así puedes ver en detalle como se hace en el segundo artículo de esta serie

Publicando datos en Thingspeak. Parte 2: Usando un canal

Con esos requisitos ya completados, debes ingresar a Thingspeak y en el menú principal seleccionar Devices – MQTT y en la página que se abre hacer click sobre el botón Add a new device

Fig. 2. Añadiendo un dispositivo MQTT

A continuación, aparece otra ventana donde nos pide el nombre del dispositivo (el que nosotros queramos), una descripción opcional y que elijamos a que canal va a estar asociado este dispositivo (el canal ya debe existir). Selecciona un canal y pulsa Add channel. Luego para terminar pulsa Add device

Fig. 3.

Una vez creado el dispositivo MQTT Thingspeak nos va a proporcionar información muy importante que debemos guardar: las credenciales para acceder al servidor, a saber un identificador de cliente (Client ID), un nombre de usuario (Username) y la contraseña (Password).

Es importante que guardemos estos datos, sobre todo la contraseña, porque si la perdemos Thingspeak no la puede recuperar. Si puede generar una nueva pero esto es un trastorno porque deberemos actualizarla en todos los clientes que la utilicen.

Fig. 4.

Al pulsar sobre Done habremos terminado el proceso y ya tendremos nuestro dispositivo MQTT listo.

Fig. 5.

En la imagen anterior se puede ver que el dispositivo está autorizado para publicar y suscribirse, aunque en lo que sigue lo vamos a usar sólo para publicar.

Probando con MQTT X

Antes de empezar a escribir código en la ESP32, hagamos algunas pruebas mas controladas para afianzar los conceptos y poner en claro la información que necesitamos.

Para ello vamos a enviar datos usando un programa gratuito llamado MQTT X que puedes descargar desde su página web.

Es multiplataforma así que lo podemos usar en los principales sistemas operativos e incluso hay una versión web.

Yo lo descargué para Windows y al ejecutarlo presenta una interface como la siguiente:

Fig. 6. Pantalla inicial de MQTT X

Lo primero que debemos hacer es crear una conexión (Connection) con el servidor de Thingspeak.

Para ello hacemos click en el botón New Connection y cargamos los siguientes datos:

Name: Un nombre a nuestra elección

Client ID: El ID que nos dió Thingspeak cuando agregamos el dispositivo (te dije que lo guardaras)

Host: mqtt://mqtt3.thingspeak.com

Port: 1883

Username: El nombre de usuario que nos dio Thingspeak

Password: La contraseña que también te dije que guardaras cuidadosamente.

SSL/TTS: Lo dejamos desmarcado porque no vamos a usar una conexión segura.

Fig. 7.

Y un poco mas abajo también tenemos que cargar unos datos:

Fig. 8.
Fig. 9.

Con todas estas configuraciones completas, vamos a la parte superior derecha y pulsamos Connect. Si hemos cargado todo correctamente nos dirá que se ha conectado con éxito.

Ya estamos listos para enviar información.. o está faltando algo?

Lo que falta es a que tópico (topic) debemos enviar y en que formato.

El tópico es:

channels/1275680/publish

En lugar de 1275680 debes poner el número de tu canal (el que está en la fig. 3, cuando autorizamos el dispositivo).

Y el formato de los datos esperado por Thingspeak es igual al que usamos cuando empleamos el método GET de HTTP, sólo que debemos agregarle una especie de comando siguiendo la palabra status, de esta forma:

field1=”valor”&field2=”valor”&status=MQTTPUBLISH

Por ejemplo:

field1=45&field2=60&status=MQTTPUBLISH

Esto lo debemos escribir en los campos que están ubicados en la parte inferior de la aplicación:

Fig. 10.

Pulsamos el símbolo de enviar y se actualiza la ventana con los datos enviados:

Fig. 11.

Vamos a Thingspeak a ver que llego al canal…

Fig. 12.

..y vemos que se han recibido correctamente los datos: 45 grados de temperatura y 60% de humedad.

¿Y como hacemos todo esto en Micropython desde el ESP32? Bueno, ahora veamos.

MQTT y Micropython

Existen varios módulos o librerías para usar mqtt en Micropython. En la versión 1.19 (si tienes una anterior te sugiero que hagas una actualización) vienen incluidas dos: mqtt.simple y mqtt.robust

Fig. 13. Módulos incluidos en Micropython

En este ejemplo usaremos mqtt.simple y el circuito del DHT11 conectado al ESP32 que venimos usando desde el tercer artículo de la serie:

Fig. 14. Circuito de conexión del ESP32 y el sensor

El programa para enviar los datos de temperatura y humedad usando mqtt se puede ver a continuación. Es una versión simple que luego habrá que perfeccionar para gestionar los errores que se pudieran producir y no es otra cosa que una variación del código que ya usamos con HTTP con ligeras modificaciones:

#Envia temperatura y humedad a Thingspeak usando MQTT

from umqtt.simple import MQTTClient

import network, time, gc
from dht import DHT11
from machine import Pin

def conectaWifi (red, password):
      global miRed
      miRed = network.WLAN(network.STA_IF)     
      if not miRed.isconnected():              #Si no está conectado…
          miRed.active(True)                   #activa la interface
          miRed.connect(red, password)         #Intenta conectar con la red
          print('Conectando a la red', red +"…")
          timeout = time.time ()
          while not miRed.isconnected():           #Mientras no se conecte..
              if (time.ticks_diff (time.time (), timeout) > 10):
                  return False
      return True

# Valores a reemplazar
wifiSSID     = "Tu red"
wifiPass     = "Tu contraseña"
mqttServer   = "mqtt3.thingspeak.com"
mqttClientID = "Tu ID"  
mqttUser     = "Tu usuario"  
mqttPass     = "Tu contraseña"
mqttTopic    = "channels/1275680/publish"  #Cambiar!


sensorDHT = DHT11 (Pin(5))

if conectaWifi (wifiSSID, wifiPass):

    print ("Conexión exitosa!")
    print('Datos de la red (IP/netmask/gw/DNS):', miRed.ifconfig())
      
    #Crear cliente MQTT
    cliente = MQTTClient (mqttClientID, mqttServer, port=1883, user=mqttUser, password=mqttPass)
    
    cliente.connect ()
    
        
    while (True):
        time.sleep (60)
        sensorDHT.measure ()

        temp=sensorDHT.temperature ()
        hum=sensorDHT.humidity()
        
        print ("T={:02d} ºC, H={:02d} %".format (temp,hum))
        
        datos = "field1="+str(temp)+"&field2="+str(hum)
        
        cliente.publish(topic=mqttTopic, msg=datos)
               
        gc.collect ()
 
else:
       print ("Imposible conectar")
       miRed.active (False)

¿No es tan complicado verdad?

Analicemos el código:

En la línea 3 importamos la clase MQTTClient desde el módulo mqtt.simple.

En las líneas 5, 6 y 7 importamos otras clases y módulos que venimos usando para distintas funciones.

A continuación tenemos la función conectaWifi que estamos usando en todos los programas de esta serie de artículos.

def conectaWifi (red, password):
      global miRed
      miRed = network.WLAN(network.STA_IF)     
      if not miRed.isconnected():              #Si no está conectado…
          miRed.active(True)                   #activa la interface
          miRed.connect(red, password)         #Intenta conectar con la red
          print('Conectando a la red', red +"…")
          timeout = time.time ()
          while not miRed.isconnected():           #Mientras no se conecte..
              if (time.ticks_diff (time.time (), timeout) > 10):
                  return False
      return True

En la línea 22 tenemos algo muy importante. Allí he agrupado todos los valores que debes modificar para tu caso particular, que son:

wifiSSID y wifiPass: El nombre de la red Wifi a la que se va a conectar el ESP32 y su contraseña.

mqttServer: La dirección del servidor de thingspeak (la debes dejar igual)

mqttClientID, mqttUser y mqttPass: El identificador de cliente, nombre de usuario y contraseña que te dió Thingspeak y que ya usamos con MQTT X.

mqttTopic: El nombre del tópico para publicar, donde debes cambiar el número por el de tu canal, igual a como hicimos con MQTT X.

En la línea 32 se crea el objeto para el sensor de temperatura y humedad y en la 34 se intenta la conexión a la red Wifi.

Si la conexión fue exitosa llegaremos a la línea 40 donde creamos el objeto cliente, o hablando con mas rigor, empleando un constructor, creamos una instancia de la clase MQTTClient que usaremos para comunicarnos con el servidor de Thingspeak.

    #Crear cliente MQTT
    cliente = MQTTClient (mqttClientID, mqttServer, port=1883, user=mqttUser, password=mqttPass)

A ese constructor le pasamos algunos parámetros, como:

mqttClientID: El ID de cliente

mqttServer: El server de Thingspeak

port: El número de puerto donde el servidor está “escuchando” por conexiones (1883)

user: Nuestro nombre de usuario

password: Nuestra contraseña

Una vez preparado el cliente, en la línea 42 realizamos la conexión.

    cliente.connect ()

En la línea 45 se comienza un bucle infinito donde se hace una lectura cada 60 segundos (línea 47), se imprimen los valores leídos (línea 52), se “arma” el string datos conteniendo los valores medidos por el sensor con el formato que requiere el servidor MQTT (sin el agregado de status=MQTTPUBLISH) en la línea 54 y finalmente se envía ese string al servidor en la línea 56 empleando el método publish

        cliente.publish(topic=mqttTopic, msg=datos)

En la línea el método g.collect hace una “limpieza” en la memoria, eliminando objetos que ya no se usen.

Conclusiones

MQTT es un protocolo liviano especialmente útil en aplicaciones de IoT donde dispositivos con recursos escasos (en términos de procesamiento, memoria y capacidad de energía) envían y reciben pequeñas cantidades de información.

En este artículo hice una breve introducción al funcionamiento y los principales elementos del protocolo y te mostré como enviar datos a Thingspeak, empleando un programa como MQTT X y luego en Micropython empleando el módulo mqtt.simple.

Queda mucho por ver de MQTT, así que seguramente lo retomaré en próximos artículos. Mientras tanto, espero que este contenido te sea de utilidad para crear tus propios proyectos usando MQTT.

Cualquier duda o sugerencia, como siempre, la puedes dejar mas abajo en la sección de comentarios.

Nos vemos!

Navegación de la serie<< Publicando datos en Thingspeak. Parte 4: Usando POST

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Habilitar notificaciones OK No, gracias