#include <WiFi.h>
#include <PubSubClient.h>
#include <DHTesp.h>
///////////////////////////////////////////////////////////////
const int DHT_PIN = 15; // Pin donde está conectado el sensor DHT (GPIO 15)
DHTesp dht;
const char* ssid = "Wokwi-GUEST"; // *** CAMBIA ESTO POR TU SSID DE WIFI ***
const char* password = ""; // *** CAMBIA ESTO POR TU CONTRASEÑA DE WIFI ***
const char* mqtt_server = "3.138.124.212"; // Dirección IP de tu broker MQTT (EMQXBROKER)
/////////////////////////////////////////////////////////////////
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0; // Para controlar el tiempo de publicación de mensajes
////////////////////////////////////////////////////////////////////
// Definición de los pines para los LEDs (Asegúrate de que estos pines sean los correctos en tu ESP32)
const int LED_GREEN_PIN = 18; // Pin para el LED Verde (ahora controlado por Temp/Hum)
const int LED_RED_PIN = 16; // Pin para el LED Rojo (puedes darle otra función o dejarlo apagado)
const int LED_YELLOW_PIN = 2; // Pin para el LED Amarillo (puedes darle otra función o dejarlo apagado)
/////////////////////////////////////////////////////////////////////
// Función para configurar la conexión WiFi
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros()); // Inicializa la semilla para números aleatorios (usado en el ID de cliente MQTT)
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
//////////////////////////////////////////////////////////////////
// Función de Callback: Se llama cuando el ESP32 recibe un mensaje MQTT suscrito
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
// Convierte el payload (byte array) a String para facilitar la comparación
String message = "";
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.println(message);
// ************************************************************
// *** LÓGICA DE CONTROL DEL LED VERDE BASADA EN EL MENSAJE DE NODE-RED ***
// ************************************************************
// Verifica si el tópico recibido es el de control de alerta (sistema/alerta)
// Este tópico lo publica Node-RED con un '1' (encender) o '0' (apagar) para el LED VERDE.
if (String(topic) == "sistema/alerta") {
if (message == "1") {
// Recibido '1' de Node-RED: Encender el LED VERDE
Serial.println("Recibido de Node-RED: 1. Encendiendo LED VERDE.");
digitalWrite(LED_GREEN_PIN, HIGH); // Enciende el LED Verde
// Asegúrate de que los otros LEDs estén apagados si solo quieres controlar el verde
digitalWrite(LED_RED_PIN, LOW);
digitalWrite(LED_YELLOW_PIN, LOW);
} else if (message == "0") {
// Recibido '0' de Node-RED: Apagar el LED VERDE
Serial.println("Recibido de Node-RED: 0. Apagando LED VERDE.");
digitalWrite(LED_GREEN_PIN, LOW); // Apaga el LED Verde
// Asegúrate de que los otros LEDs estén apagados
digitalWrite(LED_RED_PIN, LOW);
digitalWrite(LED_YELLOW_PIN, LOW);
} else {
Serial.println("Mensaje no reconocido en sistema/alerta: " + message);
}
}
// Puedes añadir más 'else if' para otros tópicos si tu ESP32 se suscribe a más cosas
else if (String(topic) == "/ThinkIOT/Subscribe") {
Serial.println("Mensaje recibido en /ThinkIOT/Subscribe: " + message);
}
}
////////////////////////////////////////////////////////////////////
// Función para reconectar al broker MQTT si se pierde la conexión
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
String clientId = "ESP32Client-";
clientId += String(random(0xffff), HEX);
if (client.connect(clientId.c_str())) {
Serial.println("Connected to MQTT Broker.");
client.publish("/ThinkIOT/Publish", "ESP32 Conectado");
client.subscribe("/ThinkIOT/Subscribe");
Serial.println("Subscribed to /ThinkIOT/Subscribe");
// Suscripción al tópico de control que Node-RED publicará para el LED VERDE
client.subscribe("sistema/alerta"); // ¡IMPORTANTE! Este es el tópico que Node-RED publica.
Serial.println("Subscribed to sistema/alerta (para LED VERDE)");
} else {
Serial.print("Failed to connect, rc=");
Serial.print(client.state());
Serial.println(". Trying again in 5 seconds.");
delay(5000);
}
}
}
/////////////////////////////////////////////////////////////////////
// Función de configuración inicial del ESP32 (se ejecuta una vez al inicio)
void setup() {
Serial.begin(115200);
// Configura los pines de los LEDs como salida y asegúrate de que estén apagados al inicio
pinMode(LED_GREEN_PIN, OUTPUT);
digitalWrite(LED_GREEN_PIN, LOW); // LED Verde apagado al inicio
pinMode(LED_RED_PIN, OUTPUT);
digitalWrite(LED_RED_PIN, LOW); // LED Rojo apagado al inicio
pinMode(LED_YELLOW_PIN, OUTPUT);
digitalWrite(LED_YELLOW_PIN, LOW); // LED Amarillo apagado al inicio
setup_wifi(); // Conecta el ESP32 a la red WiFi
client.setServer(mqtt_server, 1883); // Configura el servidor MQTT
client.setCallback(callback); // Asigna la función 'callback' para manejar los mensajes MQTT entrantes
dht.setup(DHT_PIN, DHTesp::DHT22); // Inicializa el sensor DHT
}
///////////////////////////////////////////////////////////////////
// Función principal del ESP32 (se ejecuta repetidamente después de setup)
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop(); // Permite al cliente MQTT procesar mensajes entrantes y mantener la conexión
// Lógica para leer el sensor DHT y publicar datos cada 2 segundos
unsigned long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
TempAndHumidity data = dht.getTempAndHumidity();
String temp_str = String(data.temperature, 2);
client.publish("/ThinkIOT/temputs", temp_str.c_str());
Serial.print("Published Temperature: ");
Serial.println(temp_str);
String hum_str = String(data.humidity, 1);
client.publish("/ThinkIOT/humuts", hum_str.c_str());
Serial.print("Published Humidity: ");
Serial.println(hum_str);
// *** IMPORTANTE: La lógica de control de los LEDs (encender/apagar)
// ya NO va aquí en el loop. Se manejará completamente en el 'callback'
// cuando el ESP32 reciba un mensaje de Node-RED.
}
}