/*
    Ejemplo básico MQTT con ESP32
    Utiliza la librería PubSubClient: https://github.com/knolleary/pubsubclient

    Lucas Martin Treser
    Septiembre de 2022

    Lucas Martin Treser
    Octubre de 2023
*/

#include <WiFi.h>
#include <PubSubClient.h>
#include "DHT.h"
#include "credenciales.h"

WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(4, DHT22);

// Constantes y variables
const int LED_ROJO = 33;
const int MSG_SIZE = 50;
char mensaje[MSG_SIZE];
bool status_led = LOW;

void setup() {

  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(LED_ROJO, OUTPUT);
  Serial.begin(9600);

  // -- Iniciar DHT22 --
  dht.begin();

  // -- Conexión a la red WiFi --
  WiFi.begin(ssid, password, 6);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(250);
  }

  Serial.println("");
  Serial.println("WiFi conectado con IP: ");
  Serial.println(WiFi.localIP());

  // -- Conexión al broker MQTT --
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);

  // -- Tratar de conectarse al broker MQTT --
  while (!client.connected()) {
    Serial.print("Tratando de conectar al broker MQTT...");
    if (client.connect(mqtt_id)) {  // id, user, password
      Serial.println("conectado");
    } else {
      Serial.print("fallo, error=");
      Serial.print(client.state());
      Serial.println(" intentando nuevamente en 2 segundos");
      delay(2000);
    }
  }

  // -- Subscribirse a un topic --
  client.subscribe(mqtt_topic_1);
}

void loop() {

  client.loop();

  // Obtener datos desde el sensor
  float humedad = dht.readHumidity();
  float temperatura = dht.readTemperature();

  // Formatear los datos a enviar
  // https://cplusplus.com/reference/cstdio/snprintf/
  // snprintf(mensaje, MSG_SIZE, "%.2f, %.2f", humedad, temperatura);
  String datos = String(humedad) + String(",") + String(temperatura);
  datos.toCharArray(mensaje, MSG_SIZE);

  // Publicar en un topic
  client.publish(mqtt_topic_2, mensaje);

  // Mostrar en el monitor serie los datos
  Serial.print("Humedad: ");
  Serial.print(humedad);
  Serial.print("\t Temperatura: ");
  Serial.println(temperatura);
  Serial.print("Mensaje publicado: ");
  Serial.println(mensaje);
  delay(3000);
}

// Función callback mqtt
void callback(char *topic, byte *payload, unsigned int length) {

  // Manejar una salida de si recibe un mensaje
  status_led = !status_led;
  digitalWrite(LED_ROJO, status_led);

  // Mostrar el contenido del payload
  Serial.print("Mensaje recibido desde el topic \"");
  Serial.print(topic);
  Serial.print("\": ");

  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}
NOCOMNCVCCGNDINLED1PWRRelay Module