// Configuración de MQTT
//const char* mqtt_server = "broker.hivemq.com"; // Usar un broker público para la simulación
// broker.emqx.io - test.mosquitto.org
// Configuración MQTT
// const char* mqtt_server = "broker.hivemq.com";
// const char* tempTopic   = "rlopera/AGRO/matera/temperatura";
// const char* humeTopic   = "rlopera/AGRO/matera/humedad";
// const char* contTopic   = "rlopera/AGRO/ingresos/contador";
// const char* relay1Topic = "rlopera/AGRO/riegojardin/relay1"; // Tópico MQTT para el primer Relay
// const char* relay2Topic = "rlopera/AGRO/puertagaraje/relay2"; // Tópico MQTT para el segundo Relay
/*
 0.96 inch SSD1306 OLED display
Pin    --> ESP32
Vin    --> 3.3V
GND    --> GND
SCL    --> GPIO 22
SDA    --> GPIO 21
 */
#include "myimages.h"
#include <WiFi.h>
#include <PubSubClient.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <stdlib.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
// Configuración OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Configuración del DHT11
#define DHTPIN 23
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
// Configuración de los relays
const int relayPin1 = 32;
const int relayPin2 = 33;
// Configuración WiFi
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// Configuración MQTT (Topics separados para comandos y estados)
const char* mqtt_server = "broker.hivemq.com";
const char* tempTopic = "rlopera/AGRO/matera/temperatura";
const char* humeTopic = "rlopera/AGRO/matera/humedad";
const char* contTopic = "rlopera/AGRO/ingresos/contador";
const char* relay1CmdTopic = "rlopera/AGRO/riegojardin/relay1/cmd";    // Comandos para Relay1
const char* relay1StatusTopic = "rlopera/AGRO/riegojardin/relay1/status"; // Estados Relay1
const char* relay2CmdTopic = "rlopera/AGRO/puertagaraje/relay2/cmd";    // Comandos para Relay2
const char* relay2StatusTopic = "rlopera/AGRO/puertagaraje/relay2/status"; // Estados Relay2
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
int contador = 0;
float temperatura = 0;
float humedad = 0;
void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Conectando a ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi conectado");
  Serial.println("Dirección IP: ");
  Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* message, unsigned int length) {
  String msg;
  for (int i = 0; i < length; i++) {
    msg += (char)message[i];
  }
  // Control del relay1
  if (String(topic) == relay1CmdTopic) {
    if (msg == "ON") {
      digitalWrite(relayPin1, HIGH);
      client.publish(relay1StatusTopic, "ON");  // Publicar estado actual
      Serial.println("relay 1 ON");
    } else if (msg == "OFF") {
      digitalWrite(relayPin1, LOW);
      client.publish(relay1StatusTopic, "OFF");
      Serial.println("relay 1 OFF");
    }
  }
  // Control del relay2
  if (String(topic) == relay2CmdTopic) {
    if (msg == "ON") {
      digitalWrite(relayPin2, HIGH);
      client.publish(relay2StatusTopic, "ON");
      Serial.println("relay 2 ON");
    } else if (msg == "OFF") {
      digitalWrite(relayPin2, LOW);
      client.publish(relay2StatusTopic, "OFF");
      Serial.println("relay 2 OFF");
    }
  }
}
void reconnect() {
  while (!client.connected()) {
    Serial.print("Conectando al servidor MQTT...");
    if (client.connect("clientId-AGRORamiro123")) {
      Serial.println("Conectado");
      
      // Suscribirse solo a los tópicos de comando
      client.subscribe(relay1CmdTopic);
      client.subscribe(relay2CmdTopic);
      
      // Publicar estado inicial al reconectar
      client.publish(relay1StatusTopic, digitalRead(relayPin1) ? "ON" : "OFF");
      client.publish(relay2StatusTopic, digitalRead(relayPin2) ? "ON" : "OFF");
    } else {
      Serial.print("Fallo, rc=");
      Serial.print(client.state());
      Serial.println(" Intentando de nuevo en 5 segundos...");
      delay(5000);
    }
  }
}
void setup() {
  Serial.begin(115200);
  
  // Configuración relays
  pinMode(relayPin1, OUTPUT);
  pinMode(relayPin2, OUTPUT);
  digitalWrite(relayPin1, LOW);
  digitalWrite(relayPin2, LOW);
  dht.begin();
  // Configurar OLED
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("No se encuentra la pantalla OLED"));
    while (true);
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.print("Conectando WiFi...");
  display.display();
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  // Publicar estado inicial de los relays
  client.publish(relay1StatusTopic, "OFF");
  client.publish(relay2StatusTopic, "OFF");
}
void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    
    // Lectura de sensores (simulada)
    temperatura = random(200,500)/10.00;
    humedad = random(10,999)/10.00;
    contador++;
    // Publicar datos
    char tempString[8];
    dtostrf(temperatura, 1, 2, tempString);
    client.publish(tempTopic, tempString);
    char humeString[8];
    dtostrf(humedad, 1, 2, humeString);
    client.publish(humeTopic, humeString);
    char contString[8];
    itoa(contador, contString, 10);
    client.publish(contTopic, contString);
  }
  // Actualizar display
  display.clearDisplay();
  display.setCursor(0, 0);
  display.print("Riego "); display.print(digitalRead(relayPin1) ? "ON " : "OFF ");
  display.print("Garaje "); display.println(digitalRead(relayPin2) ? "ON" : "OFF");
  display.print(contador); display.print(" ");
  display.print(temperatura,1); display.print("C ");
  display.print(humedad,0); display.println("%");
  display.println(ssid);
  display.print(WiFi.localIP()); display.print(" (");
  display.print(WiFi.RSSI()); display.print("dBm)");
  display.display();
  delay(1000);
}