#include <DHTesp.h>
#include <ESP32Servo.h>

const int PIN_LED = 13;    // LED
const int PIN_INTERRUPTOR1 = 21; // Interruptor 1
const int PIN_INTERRUPTOR2 = 23; // Interruptor 2
const int PIN_BUZZER = 25; // BUZZER
const int PIN_DHT = 22;    // DHT
const int PIN_SERVO = 18;  // SERVO

// VARIABLES GLOBALES
// INTERRUPTORES
boolean interruptor1Activado = false;
boolean interruptor2Activado = false;

// BUZZER
boolean encendidoBuzzer = false;

// DHT22
DHTesp dhtSensor;
unsigned long tiempoAnteriorDHT = 0;
const unsigned long intervaloDHT = 2000; // 2 segundos
unsigned long tiempoUltimaDHT = 0;

// Servo
Servo servo;
unsigned long tiempoAnteriorServo = 0;
const unsigned long intervaloServo = 3000; // 3 segundos
unsigned long tiempoUltimoServo = 0;

void setup() {
    Serial.begin(115200);
    
    // LED
    pinMode(PIN_LED, OUTPUT);

    // INTERRUPTORES
    pinMode(PIN_INTERRUPTOR1, INPUT_PULLUP);
    pinMode(PIN_INTERRUPTOR2, INPUT_PULLUP);

    // BUZZER
    pinMode(PIN_BUZZER, OUTPUT);

    // DHT
    dhtSensor.setup(PIN_DHT, DHTesp::DHT22);

    // SERVO
    servo.attach(PIN_SERVO);
}

float accionDHT() {
    unsigned long tiempoActualDHT = millis();
    TempAndHumidity data = dhtSensor.getTempAndHumidity();

    if (tiempoActualDHT - tiempoAnteriorDHT >= intervaloDHT) {
        tiempoAnteriorDHT = tiempoActualDHT;

        Serial.println("Temp: " + String(data.temperature, 2) + "°C");
        Serial.println("----------------");
    }
    
    return data.temperature;
}

void accionServo(float temperatura) {
    unsigned long tiempoActualServo = millis();

    if (tiempoActualServo - tiempoAnteriorServo >= intervaloServo) {
        tiempoAnteriorServo = tiempoActualServo;
        
        temperatura = accionDHT();

        float angulo = 0;
        if (temperatura < 20) {
            servo.write(angulo);
            Serial.println("Está funcionando 0");
        } else if (temperatura >= 21 && temperatura <= 26) {
            angulo = 90;
            servo.write(angulo);
            Serial.println("Está funcionando 90");
        } else {
            angulo = 180;
            servo.write(angulo);
            Serial.println("Está funcionando 180");
        }
        delay(1000);
    }
}

void accionInterruptor1() {
    interruptor1Activado = digitalRead(PIN_INTERRUPTOR1) == HIGH; // Invertir la lectura del interruptor 1
}

void accionInterruptor2() {
    interruptor2Activado = digitalRead(PIN_INTERRUPTOR2) == HIGH; // Invertir la lectura del interruptor 2
}

void loop() {
    accionInterruptor1();
    accionInterruptor2();

    digitalWrite(PIN_LED, interruptor1Activado ? HIGH : LOW);

    if (!interruptor1Activado) {
        encendidoBuzzer = interruptor2Activado; // Activar el buzzer si el interruptor 2 está activado y el LED está encendido
    } else {
        encendidoBuzzer = false;
    }

    if (interruptor1Activado) {
        unsigned long tiempoActual = millis();
        float temperatura;

        if (tiempoActual - tiempoUltimaDHT >= intervaloDHT) {
            temperatura = accionDHT();
            tiempoUltimaDHT = tiempoActual;
        }

        if (tiempoActual - tiempoUltimoServo >= intervaloServo) {
            accionServo(temperatura);
            tiempoUltimoServo = tiempoActual;
        }
    }

    if (encendidoBuzzer) {
        tone(PIN_BUZZER, 400); // Encender el buzzer
    } else {
        noTone(PIN_BUZZER);    // Apagar el buzzer
    }

    delay(50);
}