Cómo comunicar App en VueJs con ESP32 a través de MQTT Deja un comentario

Continuamos con la serie de entradas dedicadas a comunicación con el ESP8266 / ESP32, viendo cómo comunicar una aplicación en Vue a través de MQTT.

Recordamos que en la entrada anterior hemos visto cómo comunicar un ESP8266 o ESP32 con una página web servida desde el mismo a través de MQTT gracias a la librería PAHO.

En este tutorial empleamos vanila JavaScript para leer el formato Json y añadir el valor recibido a la página. Pero, conociéndonos, sabíamos que el siguiente paso iba a ser integrarlo en una App en VueJs.

Ya que estamos, vamos a modificar el ejemplo para que, en vez de simplemente enviar el valor de millis(), envía información más interesante. Como, por ejemplo, el estado de un GPIO, simulando la recepción de una alarma.

Anuncio:

En definitiva, vamos a hacer algo así.

No obstante, en este ejemplo el estado del GPIO va a ser simulado, porque únicamente nos interesa ilustrar la comunicación. Depende de vosotros adaptarlo al hardware y necesidades de vuestro proyecto.

Así que manos a la obra. Por un lado, el bucle principal del programa no se ha modificado respecto al ejemplo anterior. Recordamos que era el siguiente.

#include 
#include 
#include 
#include 
#include 

#include "config.h"  // Sustituir con datos de vuestra red
#include "Server.hpp"
#include "MQTT.hpp"
#include "ESP32_Utils.hpp"
#include "ESP32_Utils_MQTT_Async.hpp"

void setup(void)
{
	Serial.begin(115200);
	SPIFFS.begin();

	delay(500);

	WiFi.onEvent(WiFiEvent);
	InitMqtt();

	ConnectWiFi_STA();
	InitServer();
}

void loop()
{
	PublishMqtt();

	delay(1000);
}

Si ha cambiado es el fichero ‘MQTT.hpp’, en el que hemos separado la lógica asociada a la comunicación MQTT de nuestro programa.

#pragma once

const IPAddress MQTT_HOST(192, 168, 1, 150);
const int MQTT_PORT = 1883;

AsyncMqttClient mqttClient;

String GetPayloadContent(char* data, size_t len)
{
	String content = "";
	for(size_t i = 0; i < len; i++)
	{
		content.concat(data[i]);
	}
	return content;
}

void SuscribeMqtt()
{
	uint16_t packetIdSub = mqttClient.subscribe("hello/world", 0);
	Serial.print("Subscribing at QoS 2, packetId: ");
	Serial.println(packetIdSub);
}

void PublishMqtt()
{
	String payload = "";

	// obtendriamos datos de GPIO, estado...
	StaticJsonDocument<300> jsonDoc;
	jsonDoc["id"] = random(0, 10);
	jsonDoc["status"] = random(0, 2);
	serializeJson(jsonDoc, payload);

	mqttClient.publish("hello/world", 0, true, (char*)payload.c_str());
}

void OnMqttReceived(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total)
{
	Serial.print("Received on ");
	Serial.print(topic);
	Serial.print(": ");

	String content = GetPayloadContent(payload, len);

	StaticJsonDocument<200> doc;
	DeserializationError error = deserializeJson(doc, content);
	if(error) return;

	int id = doc["id"];
	bool ledStatus = doc["status"];

	Serial.print(" Id:");
	Serial.print(id);
	Serial.print(" Status:");
	Serial.println(ledStatus);
}

Tampoco hay grandes modificaciones. Únicamente hemos cambiado el Json que enviamos para que contenga el Id del GPIO y el estado. Que, simplemente estamos rellenando como valores aleatorios.

Lo que sí va a cambiar sustancialmente es el frontend que servimos al cliente. Que, como hemos dicho, pasará a ser una App en VueJs. Así, el fichero ‘index.html’ pasa a ser el siguiente.





  ESP32 MQTT
  
  
  
  
  



  
  
  

  
    ESP32 MQTT
    
      

        
          
            
              
                Received
              

              
            
             
            
          

        
      
    
  

  
  
  
  
  

  
  
  



Por su parte, tenemos el fichero ‘API.js’ que contiene la lógica del front asociada con la comunicación MQTT.

function onConnect() {

    var options = {
      qos: 0,
      onSuccess: onSubSuccess,
      onFailure: onSubFailure
    };
    client.subscribe('hello/world', options);
  }
  
  function onFailure(message) {
    console.log(message)
  }
  
  function onConnectionLost(responseObject) {
    if (responseObject.errorCode !== 0) {
      console.log("onConnectionLost:" + responseObject.errorMessage);
    }
  }
  
  function onMessageArrived(message) {
    console.log(message)
    var topic = message.destinationName;
    var payload = message.payloadString;
  
    let json = JSON.parse(payload);
  
    var mqtt_message = new Object();
    mqtt_message.id = json.id;
    mqtt_message.status = json.status;
    mqtt_message.date = new Date().toISOString().replace("T", " ").replace("Z", " ");
    app.mqtt_message_list.unshift(mqtt_message);
  }
  
  function onSubFailure(message) {
    console.log(message)
  }
  
  function onSubSuccess(message) {
    console.log(message)
  }
  
  function createGuid() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
      var r = Math.random() * 16 | 0,
        v = c === 'x' ? r : (r & 0x3 | 0x8);
      return v.toString(16);
    });
  }

Finalmente, el fichero ‘App.js’ contiene la aplicación en Vue, y tiene la siguiente forma.

  Vue.component('mqtt-message', {
    props: ['mqtt_message'],
    template: `
        
        
            
            {{mqtt_message.date}}
            
            
            GPIO: {{mqtt_message.id}}
            
Status: {{mqtt_message.status}}
` }) var app = new Vue({ el: '#app', data: function () { return { mqtt_message_list: [ ] } }, mounted() { client = new Paho.MQTT.Client("192.168.1.150", 9001, createGuid()) var options = { onSuccess: onConnect, onFailure: onFailure }; client.onConnectionLost = onConnectionLost; client.onMessageArrived = onMessageArrived; client.connect(options); }, })

Subimos todo esto a nuestro ESP8266/ESP32, y veremos que los mensajes simulados se reciben cada segundo, y se añaden al listado de alertas.

De igual forma, en el puerto serie del ESP32 también vemos los mensajes recibidos. Que, en este caso, son enviados por el propio dispositivo, para evitarnos tener que usar varios. Pero, si tuviéramos varios dispositivos, todos recibirían simultáneamente.

Hasta aquí la entrada de hoy, y la penúltima de esta serie de comunicación. En la siguiente y última entrada, veremos cómo ampliar este proyecto para hacer un interface web completo a través de MQTT. Nos vemos en la siguiente.

Descarga el código

Todo el código de esta entrada está disponible para su descarga en Github.

Versión para el ESP8266: https://github.com/luisllamasbinaburo/ESP8266-Examples

Versión para el ESP32: https://github.com/luisllamasbinaburo/ESP32-Examples

Si te ha gustado esta entrada y quieres leer más sobre ESP8266 o el ESP32 puedes consultar la sección tutoriales de ESP8266/32
5 1 vote
Article Rating

Anuncio:

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

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

Enviar Whatsapp
Hola 👋
¿En qué podemos ayudarte?