#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#define LIGHT_PIN 4
const char *mqttUrl = "broker.hivemq.com";
const int mqttPort = 1883;
const char *mqttTopicCC = "home/commands";
const char *mqttTopicESP = "home/feedback";
String clientId = "ESP32-" + String(WiFi.macAddress());
WiFiClient espClient;
PubSubClient client(espClient);
JsonDocument parseInput(String input) {
JsonDocument doc;
DeserializationError error = deserializeJson(doc, input);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
}
return doc;
}
void makeResponse(JsonDocument command, char *status, char *buffer, size_t size) {
JsonDocument response;
response["action"] = command["action"];
response["deviceId"] = command["deviceId"];
response["meta"] = command["meta"];
if (status != NULL) {
response["status"] = status;
}
serializeJson(response, buffer, size);
}
void executeCommand(JsonDocument command) {
const char *action = command["action"];
const char *device = command["deviceId"];
Serial.print("action ->");
Serial.println(action);
Serial.print("device ->");
Serial.println(device);
if (strcmp(action, "turn_on") == 0) {
digitalWrite(LIGHT_PIN, HIGH);
char res[200];
makeResponse(command, "on", res, sizeof(res));
Serial.print("Enviando respuesta: ");
Serial.println(res);
client.publish(mqttTopicESP, res);
} else if (strcmp(action, "turn_off") == 0) {
digitalWrite(LIGHT_PIN, LOW);
char res[200];
makeResponse(command, "off", res, sizeof(res));
} else if (strcmp(action, "get_status") == 0) {
int status = digitalRead(LIGHT_PIN);
char output[200];
JsonDocument response;
response["action"] = "get_status";
response["deviceId"] = device;
response["status"] = status == 0 ? "off" : "on";
response["meta"] = command["meta"];
serializeJson(response, output);
client.publish(mqttTopicESP, output);
Serial.print("Status sent: ");
Serial.println(output);
}
}
void callback(char* topic, byte* payload, unsigned int length) {
String rawInput;
JsonDocument command;
for (unsigned int i = 0; i < length; i++) {
rawInput += (char)payload[i];
}
Serial.print("Mensaje recibido [");
Serial.print(topic);
Serial.print("]: ");
Serial.print(rawInput);
Serial.print(" -> ");
Serial.println(length);
command = parseInput(rawInput);
executeCommand(command);
}
void reconnect() {
while (!client.connected()) {
Serial.print("Intentando conectar al broker MQTT...");
client.setKeepAlive(60);
if (client.connect(clientId.c_str())) {
Serial.println("Conectado!");
// Subscribe to CC topic
client.subscribe(mqttTopicCC);
} else {
Serial.print("Fallo, rc=");
Serial.print(client.state());
Serial.println(" reintentando en 2s");
delay(2000);
}
}
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Hello, ESP32!");
// Initialize pins
pinMode(LIGHT_PIN, OUTPUT);
// Connect to the internet
Serial.println("Connecting to WiFi");
WiFi.begin("Wokwi-GUEST", "", 6);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println(" Connected!");
// Setup MQTT client
client.setServer(mqttUrl, mqttPort);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}