Dos servidores MQTT gratuitos para tus proyectos IoT. Parte 2

Existen muchas opciones a la hora de utilizar un servidor MQTT o broker para nuestros proyectos de IoT. Entre los que podemos encontrar en la red con algún plan gratuito se destacan los de Hive MQ, por sus posibilidades. En un artículo anterior te mostré como acceder y utilizar el servidor gratuito de esta empresa. En esta oportunidad te enseño a hacer lo propio con el servidor privado.

Introducción

El servidor o broker público de Hive MQ que vimos en la primer parte de esta serie de artículos es muy fácil de usar y es ideal para que hagas las primeras pruebas de tus programas con el protocolo MQTT. No hace falta crear un usuario ni emplear contraseñas. Pero esa misma simpleza es su principal desventaja: cualquiera puede leer los datos que publiquemos y lo que es peor, puede escribir en los mismos tópicos.

Por esta razón veremos en esta segunda parte otra alternativa que nos ofrece la misma empresa, que son los servidores privados.

Crear una cuenta

Lo primero que debes hacer es crear una cuenta en Hive MQ.

Para ello debes dirigirte a https://console.hivemq.cloud/ y hacer click en Sign Up.

Puedes crear la cuenta usando GitHUb, Google o introduciendo un nombre de usuario y contraseña, elige el método que te resulte mas cómodo.

Fig. 1. Creación de la cuenta

Una vez completado este primer paso, te pedirán algunos datos personales, como nombre apellido y ocupación.

A continuación, deberás introducir las credenciales que deberán usar los clientes para acceder al servidor. Como ya no es un servidor público, los clientes deberán identificarse con estas credenciales si quieren acceder. Debes elegir un nombre de usuario (username) y una contraseña ( password)

Fig. 2. Credenciales

Con estos pasos completados, podrás ver la página de administración de tus servidores o clusters. No estás limitado a un único servidor MQTT, por el contrario, puedes crear varios de ellos.

Un cluster es un sistema o servidor distribuido que no reside en una máquina física única sino que está “repartido” en varios nodos que se interconectan entre sí. Eso aumenta la seguridad del servidor, porque sigue funcionando aunque haya un problema en algunos de los nodos.

Fig. 3. Página de administración de servidores

En esta página de administración puedes ver todos los cluster o servidores que hayas creado e información importante de cada uno de ellos, como su dirección o URL, el port que usa para realizar conexiones, la fecha de su creación y el estado de funcionamiento.

También puedes ver que el servidor utiliza TLS, es decir que los datos se envían y reciben de forma codificada para mantenerlos privados. Todos los servidores privados que crees usarán TLS.

Si haces click en el botón Manage Cluster, podrás acceder a mayor información de ese cluster en particular:

Fig. 4. Configuraciones del servidor

En esta nueva ventana puedes ver información del tráfico (si recién lo creas verás cero), los clientes conectados y los datos de conexión nuevamente, como la dirección (URL) y port.

Mas abajo puedes ver donde está hospedado el servidor y, lo mas importante, los detalles del plan gratuito, que son mas que suficientes para un pequeño proyecto.

Fig. 5. Configuraciones del servidor

En la parte superior tienes un menú con varias opciones:

ACCESS MANAGEMENT: Te permite administrar credenciales para los clientes que acceden al servidor (usuario y contraseña). Puedes agregar credenciales nuevas o borrar las existentes.

INTEGRATIONS: Permiten conectar tu servidor MQTT con otros servicios (muy limitado para el plan Free).

WEB CLIENT: Desde aquí puedes abrir un cliente Web como el que usamos para probar el servidor público y monitorear los datos que llegan al servidor o publicar datos de prueba.

GETTING STARTED: Una ayuda bastante completa.

Parámetros de conexión

Antes de ir al código del ejemplo, veamos dos parámetros muy importantes del protocolo MQTT que no he tratado hasta ahora: KeepAlive y Qos.

KeepAlive

Es un intervalo de tiempo en segundos que elige el cliente y se lo informa al broker. Define el tiempo máximo que el broker y el cliente esperarán por mensajes.

Keep Alive provee un mecanismo para que el cliente y el broker sepan que aún están conectados o si, por el contrario, esta conexión se rompió (por la falla de una de las dos partes por ejemplo).

Si el cliente envía mensajes al broker con una separación menor al tiempo Keep Alive, no hay nada de que preocuparse. Si los mensajes están mas espaciados, entonces el cliente debe enviar un mensaje especial de control (PING) al broker como un aviso de que aún sigue vivo.

Si el broker no recibe mensajes durante un tiempo igual a 1,5 veces el valor de Keep Alive, asume que se rompió la conexión y la cierra. Lo mismo hace el cliente, si no recibe una respuesta del PING en el mismo tiempo de 1,5 veces Keep Alive, asume que el broker se ha desconectado.

La elección de mantener o no la conexión abierta y fijar el valor de Keep Alive valor dependen de la aplicación. Si se envían datos con cierta frecuencia, conviene dejar la conexión abierta y elegir un valor de Keep Alive mayor a la separación entre mensajes. Si por el contrario, nuestra placa envía un mensaje cada hora y luego se pone en modo de bajo consumo, conviene abrir la conexión y cerrarla luego de enviar el mensaje.

QoS

El parámetro QoS (Quality of Service) permite elegir el mecanismo de entrega y confirmación de recepción de los mensajes. Puede tener 3 valores: 0, 1 y 2.

QoS=0 – At most one (Como máximo una vez). El mensaje se envía una vez sin confirmación de recepción (si hay algún fallo puede que no llegue y no lo sepamos).

QoS=1 – Al least one (Al menos una vez). El mensaje se envía y se espera confirmación de recepción. Si ésta no llega, se lo reenvía hasta recibir la confirmación. Si hay un fallo en la confirmación, puede que se reciban mensajes repetidos.

QoS=2 Only once (Sólo una vez). Se usa un mecanismo de doble confirmación para asegurar que el mensaje llegue y que no llegue repetido.

El módulo umqtt.simple que estamos usando sólo admite QoS 0 y 1.

En realidad existen dos Qos: El valor de QoS que usa el cliente para enviar datos al broker en publicación puede ser distinto del que usa el broker para enviar datos al cliente en la suscripción.

Ejemplo

Veamos a continuación un ejemplo en Micropython que muestra como realizar la conexión con un servidor privado de Hive MQ que ya ha sido creado usando los pasos que vimos antes.

La intención del ejemplo es aclarar como se realiza la conexión con el servidor, por esta razón, asi como hice con el ejemplo del servidor público, los datos a enviar son constantes.

Todos los programas utilizados en esta publicación han sido probados con una placa ESP32 VROOM y una Raspberry Pico W y funcionan correctamente en cualquiera de ellas sin ninguna modificación.

Si tienes planeado utilizar una Raspberry Pico W, deberías instalar previamente el módulo mqtt.simple, ya que no viene incluido en su versión del firmware de Micropython. Para ello te invito a que veas las instrucciones en el Anexo. Esto no es necesario si usas un ESP32.

#Envia temperatura y humedad constantes a Hive MQ
#Usa el broker privado

from umqtt.simple import MQTTClient
import network, time,gc
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   = b"d0cfe849a4aa422ab78b6b45a0321c90.s1.eu.hivemq.cloud"
mqttPort     = 8883
mqttClientID = b"ESP32_Ernesto"  
mqttUser     = b"etolocka_mqtt_hivemq"  
mqttPass     = b"******" 

if conectaWifi (wifiSSID, wifiPass):

    print ("Conexión exitosa!")
    print('Datos de la red (IP/netmask/gw/DNS):', miRed.ifconfig())
      
    #Crear cliente MQTT       
    cliente = MQTTClient(client_id=mqttClientID, server=mqttServer,
        port=mqttPort, user=mqttUser, password=mqttPass,
        keepalive=60,
        ssl=True,
        ssl_params={'server_hostname':'d0cfe849a4aa422ab78b6b45a0321c90.s1.eu.hivemq.cloud'}
    )
        
    cliente.connect ()     
            
    while (True):
        time.sleep (20)

        temp=32
        hum=61 
        
        print ("T={:02d} ºC, H={:02d} %".format (temp,hum))
              
        cliente.publish(topic=b"casa/patio/temperatura", msg=str(temp))
        time.sleep (2)
        cliente.publish(topic=b"casa/patio/humedad",     msg=str(hum))
        
                     
        gc.collect ()
 
else:
       print ("Imposible conectar")
       miRed.active (False)

El funcionamiento del código es bastante parecido al que usamos para el servidor público, así que analicemos las diferencias:

A partir de la línea 23 se definen varios parámetros de conexión. Revisemos cuales son:

wifiSSID: Nombre de tu red Wifi

wifiPass: Contraseña de tu red wifi

mqttServer: Dirección de tu servidor

mqttPort = 8883

mqttClientID: Un identificador cualquiera

mqttUser: El nombre de usuario elegido cuando creaste las credenciales

mqttPass: La contraseña elegida para ese usuario

Lo siguiente novedoso es la creación del cliente en la línea 37.

   #Crear cliente MQTT       
    cliente = MQTTClient(client_id=mqttClientID, server=mqttServer,
        port=mqttPort, user=mqttUser, password=mqttPass,
        keepalive=60,
        ssl=True,
        ssl_params={'server_hostname':'d0cfe849a4aa422ab78b6b45a0321c90.s1.eu.hivemq.cloud'}
    )
        

A diferencia de cuando usamos el servidor público, ahora el constructor emplea mas parámetros, como el usuario y la contraseña.

Como el servidor privado nos exige utilizar una conexión segura, ponemos ssl=True y le pasamos como parámetro la dirección del servidor. No estamos usando un certificado, de manera que esta conexión no será completamente segura. Dejaremos el tema del uso de certificados para otra ocasión.

Finalmente, el valor de Keep Alive está fijado en 60 segundos, lo que significa que si el servidor no recibe nada en 60 * 1,5 = 90 segundos, asume que hubo un inconveniente en el cliente y corta la conexión.

Otra modificación que merece atención es la publicación de los valores de temperatura y humedad en los tópicos correspondientes.

        cliente.publish(topic=b"casa/patio/temperatura", msg=str(temp))
        time.sleep (2)
        cliente.publish(topic=b"casa/patio/humedad",     msg=str(hum))

Como se puede ver, se aprovecha la característica de niveles jerárquicos en los que se pueden organizar los tópicos.

En este caso uso un tópico general llamado casa que puede contener varios tópicos o sub-tópicos, por ejemplo, para cada ambiente de la casa donde instale un sensor. En este ejemplo utilicé un subtópico llamado patio. Y como estoy simulando un sensor de temperatura y humedad, que tiene dos valores para publicar, lo hago en otro nivel aún mas bajo, los tópicos temperatura y humedad.

Entonces, la temperatura se publica en el tópico casa/patio/temperatura y la humedad en casa/patio/humedad. Si tuviera otro sensor en la cocina, podría publicar en los tópicos casa/cocina/temperatura y casa/cocina/humedad, por ejemplo.

Esta organización jerárquica permite tener los tópicos ordenados pero además nos da cierta flexibilidad cuando hacemos suscripciones.

Podemos suscribirnos a un tópico en particular indicando su nombre o ruta completa, como en casa/patio/temperatura o podemos usar “wildcards” (comodines) para suscribirnos a varios tópicos al mismo tiempo.

Existen dos comodines: “+” que reemplaza sólo un nivel de la jerarquía y “#” que reemplaza el nivel donde se encuentra y todos los que estén por debajo.

Por ejemplo, podemos suscribirnos a:

casa/patio/#

Que es equivalente a suscribirse a los dos tópicos

casa/patio/temperatura

casa/patio/humedad

O también podemos suscribirnos a:

casa/#

Que equivale a suscribirse a :

casa/patio/temperatura

casa/patio/humedad

casa/cocina/temperatura

casa/cocina/humedad

En el extremo, si nos suscribimos a:

#

Nos estamos suscribiendo a todos los tópicos que haya en el servidor.

Por otro lado, el comodin “+” se aplica a un solo nivel. Por ejemplo, suscribirse a:

casa/+/temperatura

Equivale a suscribirse simultáneamente a:

casa/patio/temperatura

casa/cocina/temperatura

En esta misma sección del código puedes ver que entre los parámetros del método cliente.publish no especificamos el valor de QoS, así que se toma el valor por omisión que es 0.

Comprobando los datos recibidos

Como hicimos con el servidor público, podemos comprobar que el programa de ejemplo envíe correctamente los datos conectándonos con un cliente. Puedes usar distintos clientes, pero desde la página de administración del servidor tienes un acceso rápido al cliente de Hive MQ en la opción del menú WEB CLIENT.

Usando el cliente debes suscribirte a los tópicos

casa/patio/temperatura

casa/patio/humedad

Fig. 6. Suscripciones

También puedes suscribirte usando el comodín “#” como vimos antes.

Luego, podrás ver los mensajes que se publican en esos tópicos

Fig. 7. Mensajes publicados

Conclusiones

A lo largo de las dos partes de este artículo te mostré como aprovechar las opciones que nos ofrece Hive MQ para que tengas tu propio servidor o broker MQTT para tus proyectos de IoT.

Vimos que en el caso del servidor gratuito la configuración es muy sencilla, pero nuestros datos son accesibles para cualquiera. Luego analizamos la opción de servidor privado y vimos en detalle como crear una cuenta, seleccionar las credenciales y crear un servidor o cluster. Mediante un ejemplo en Micropython te mostré como conectarte a ese servidor privado para enviar datos y como comprobar que los datos llegaron correctamente.

A lo largo de la publicación también revisamos distintos aspectos del funcionamiento de MQTT, para que tengas un conocimiento mas completo del protocolo.

Con lo aprendido se abren numerosas posibilidades que puedes explorar creando tus propios proyectos. Pronto nos volveremos a encontrar para seguir estudiando las inagotables oportunidades que nos ofrece la tecnología IoT.

Anexo: Raspberry Pico W

El firmware de Micropython para Raspberry Pico W no tiene incluido el módulo umqtt.simple, así que antes de probar el código de ejemplo deberás instalarlo en tu placa.

Para ello, conecta la placa, actualiza el firmware a la última versión de Micropython (a la fecha es la 1.19) y realiza una conexión con la red Wifi introduciendo los siguientes comandos en la consola (o REPL). En este caso yo he utilizado Thonny:

Fig. 8

En las partes borroneadas debes introducir el nombre de tu red Wifi y su contraseña.

Con la placa conectada, hay que importar el modulo mip, un instalador que puede descargar módulos de distintas ubicaciones y copiarlos al sistema de archivos de la placa y utilizarlo para instalar umqtt.simple:

Fig. 9

Si no hay ningún error, el módulo umqtt.simple se copia a la carpeta lib y la Pico ya está lista para correr el programa de ejemplo.

Fig. 10

Navegación de la serie<< Dos servidores MQTT gratuitos para tus proyectos IoT. Parte 1

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