En la anterior entrada con título «Mosquitto», realicé la descripción del broker Mosquitto, explicando las tareas de instalación, estructuras de carpetas y uso del Broker desde la consola del sistema. En esta entrada, «Cliente Mosquitto: Paho-mqtt», me centraré en cómo los dispositivos se pueden conectar al broker Mosquitto utilizando la librería Paho-mqtt.
Paho-mqtt es aquella librería cliente en lenguaje Python la cual implementa la versión 3.1 y 3.1.1 del protocolo MQTT.
Creación del proyecto
Para la realización de los ejemplos con el cliente Paho-mqtt, reallizaré la creación de un proyecto Python con el cliente Paho-mqtt. El proceso de creación consistirá en lo siguiente:
- Creación de un proyecto Python en el IDE.
- Desde la carpeta del proyecto y en la consola del sistema, creación del entorno virtual del proyecto ejecutando el siguiente comando:
python3 -m venv venv
- Desde la carpeta del proyecto y en la consola del sistema, instalación del cliente Paho-mqtt ejecutando el siguiente comando:
pip install paho-mqtt
Una vez realizado los pasos anteriores, tenemos creado un proyecto Python con el cliente Paho-mqtt para desarrollar los publicadores y subscriptores del broker Mosquitto.
Broker Mosquitto
Para realizar las pruebas, necesitamos arrancar el broker Mosquitto, un publicador y un subscriptor para realizar las pruebas. Los pasos a seguir y la estructura de topics serán los mismos que en la entrada anterior. Los comandos a ejecutar son los siguientes:
- Para el arranque del broker Mosquitto en el puerto por defecto en la línea de comandos, se realiza con el siguiente comando:
sudo /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf
- Para el arranque de un publicador en la línea de comandos, se realiza con el siguiente comando:
mosquitto_pub -t "casa/habitaciones/hab1/luz" -m "ON"
- Para el arranque de un subscriptor en la línea de comandos, se realiza con el siguiente comando:
mosquitto_sub -t "casa/habitaciones/hab1/luz" -v
Una vez realizados estos pasos, tenemos el broker levantado, las consolas del publicador y subscriptor abiertas para ver la actividad existente.
Publicadores
En el presente apartado, me centraré en presentar tres ejemplos de publicación de mensajes en un topic del broker Mosquitto. El publicador es aquel elemento que genera mensajes que son enviados al broker Mosquitto.
Ejemplo básico
El primer ejemplo, lo realizamos en un fichero Python con nombre publicador_ejem1.py, es aquel ejemplo básico de creación de un cliente, conexión al broker y publicación del mensaje «Ejemplo desde Python» en el topic del broker Mosquitto.
El snippet del código es el siguiente:
import paho.mqtt.client as mqtt broker_address = "localhost" client = mqtt.Client('Publicador_ejem1') # Creación del cliente client.connect(broker_address) topic = "casa/habitaciones/hab1/luz" client.publish(topic, "Ejemplo desde Python")
Tras la ejecución de publicador_ejem1.py, la salida en la consola del subscriptor Mosquitto, abierta conforme lo descrito en el apartado anterior, es la siguiente:
casa/habitaciones/hab1/luz Ejemplo desde Python
Ejemplo publicador de un mensaje
El segundo ejemplo, lo realizamos en un fichero Python con nombre publicador_ejem2.py, es aquel ejemplo de creación de un publicador, definición del topic al cual informar, y envío del mensaje «Ejemplo de publicador simple desde Python» al broker Mosquitto mediante la función single del publicador. El snippet del código es el siguiente:
import paho.mqtt.publish as publish broker_address = "localhost" topic = "casa/habitaciones/hab1/luz" publish.single(topic, "Ejemplo de publicador simple desde Python", hostname=broker_address, client_id='publicador_ejem2.py')
Tras la ejecución de publicador_ejem2.py, la salida en la consola del subscriptor Mosquitto, abierta conforme lo descrito en el apartado anterior, es la siguiente:
casa/habitaciones/hab1/luz Ejemplo de publicador simple desde Python
Ejemplo publicador de mensaje múltiple
El tercer ejemplo, lo realizamos en un fichero Python con nombre publicador_ejem3.py, es aquel que utiliza un publicador, se definen tres mensajes (mensaje1, mensaje2 y mensaje3) para ser enviados al broker Mosquitto mediante la función multiple del publicador. El snippet del código es el siguiente:
import paho.mqtt.publish as publish broker_address = "localhost" topic = "casa/habitaciones/hab1/luz" mensaje1 = "Mensaje 1 de un envío multiple" mensaje2 = "Mensaje 2 de un envío multiple" mensaje3 = "Mensaje 3 de un envío multiple" msgs = [{'topic': topic, 'payload': mensaje1}, (topic, mensaje2, 0, False), (topic, mensaje3, 0, False)] publish.multiple(msgs, hostname=broker_address)
Tras la ejecución de publicador_ejem3.py, la salida en la consola del subscriptor Mosquitto, abierta conforme lo descrito en el apartado anterior, es la siguiente:
casa/habitaciones/hab1/luz Mensaje 3 de un envío multiple casa/habitaciones/hab1/luz Mensaje 2 de un envío multiple casa/habitaciones/hab1/luz Mensaje 1 de un envío multiple
Subscriptores
En el presente apartado, me centraré en presentar tres ejemplos de subscriptores de mensajes en un topic del broker Mosquitto. El subscriptor es aquel elemento que recibe mensajes de un topic del broker Mosquitto originados en un publicador determinado.
Ejemplo básico de subscriptor
El primer ejemplo, lo realizamos en el fichero subscriptor_ejem1.py, es aquel que utiliza un cliente MQTT con las siguientes tareas: definición de un callback para la recepción de mensajes del topic en la función on_message; conexión al broker con la función connect;y, la subscripción al topic del broker de Mosquitto, mediante la función subscribe. El presente ejemplo realiza solo una iteración por las funciones loop_start() y loop_stop. El snippet del código es el siguiente:
import time import paho.mqtt.client as mqtt # import the client1 broker_address = "localhost" broker_port = 1883 topic = "casa/habitaciones/hab1/luz" def on_message(client, userdata, message): print("Mensaje recibido=", str(message.payload.decode("utf-8"))) print("Topic=", message.topic) print("Nivel de calidad [0|1|2]=", message.qos) print("Flag de retención o nuevo?=", message.retain) client = mqtt.Client("Subscriptor_ejem1") client.on_message = on_message client.connect(broker_address) client.loop_start() # Inicio del bucle client.subscribe(topic) time.sleep(10) # Paramos el hilo para recibir mensajes. client.loop_stop() # Fin del bucle
Tras la ejecución del subscriptor_ejem1.py y tras la publicación de un mensaje en la consola Mosquitto, conforme a lo descrito en el apartado anterior, la salida es la siguiente:
Mensaje recibido= PRUEBA Topic= casa/habitaciones/hab1/luz Nivel de calidad [0|1|2]= 0 Flag de retención o nuevo?= 0
Ejemplo de subscriptor de N mensajes
El segundo ejemplo, lo realizamos en el fichero subscriptor_ejem2.py, es aquel ejemplo que espera infinitos mensajes de un topic del broker Mosquitto. Las operaciones son casi las mismas al apartado anterior, estando las diferencias en la definición de un bucle infinito con la función loop_forever(). El snippet del código es el siguiente:
import paho.mqtt.client as mqtt broker_address = "localhost" broker_port = 1883 topic = "casa/habitaciones/hab1/luz" def on_message(client, userdata, message): print("Mensaje recibido=", str(message.payload.decode("utf-8"))) print("Topic=", message.topic) print("Nivel de calidad [0|1|2]=", message.qos) print("Flag de retención =", message.retain) client = mqtt.Client('Cliente1') client.on_message = on_message client.connect(broker_address, broker_port, 60) client.subscribe(topic) # Subscripción al topic client.loop_forever()
Tras la ejecución del subscriptor_ejem2.py y tras la publicación de dos mensajes en el consola Mosquitto, conforme a lo descrito en el apartado anterior, la salida es la siguiente:
Mensaje recibido= PRUEBA1 Topic= casa/habitaciones/hab1/luz Nivel de calidad [0|1|2]= 0 Flag de retención = 0 Mensaje recibido= PRUEBA2 Topic= casa/habitaciones/hab1/luz Nivel de calidad [0|1|2]= 0 Flag de retención = 0
Ejemplo con control de conexión al topic
El tercer ejemplo, lo realizamos en el fichero subscriptor_ejem3.py, es aquel ejemplo que espera infinitos mensaje de un topic del broker Mosquitto pero se define un callback para realizar la conexión definida en la función on_connect; este callback, si se pierde la conexión, realiza la reconexión al topic. El snippet del código es el siguiente:
import paho.mqtt.client as mqtt broker_address = "localhost" broker_port = 1883 topic = "casa/habitaciones/hab1/luz" def on_connect(client, userdata, flags, rc): print("Connected with result code " + str(rc)) print("UserData= " + str(userdata)) print("flags= " + str(flags)) print("") client.subscribe(topic) def on_message(client, userdata, message): print("Mensaje recibido=", str(message.payload.decode("utf-8"))) print("Topic=", message.topic) print("Nivel de calidad [0|1|2]=", message.qos) print("Flag de retención=", message.retain) print("---------------------------------------------") print("") client = mqtt.Client('Cliente1', userdata="UsuarioDePrueba") client.on_connect = on_connect client.on_message = on_message client.connect(broker_address, broker_port, 60) client.loop_forever()
Tras la ejecución del subscriptor_ejem3.py y tras la publicación de un mensaje en el consola Mosquitto, conforme a lo descrito en el apartado anterior, la salida es la siguiente:
Connected with result code 0 UserData= UsuarioDePrueba flags= {'session present': 0} Mensaje recibido= PRUEBA Topic= casa/habitaciones/hab1/luz Nivel de calidad [0|1|2]= 0 Flag de retención= 0 ---------------------------------------------
La definición de componentes software con la librería Paho-mqtt para la comunicación con el broker Mosquitto, es una tarea sencilla teniendo claro el modelo productor/consumidor. En los ejemplos descritos, se centran en la comunicación con el broker faltando el desarrollo de captura de datos de los sensores o componentes los cuales han sido simulados desde la consola de Mosquitto.