// Channel ID: 2394230
// Channel API Key: 2JDDLP1FEEBMN8LV

#include <WiFi.h>
#include "DHTesp.h"
#include "ThingSpeak.h"

#define BOMBA_ALIM 12    // Primer LED rojo: Bomba Alimentación
#define BOMBA_EFLU 14    // Segundo LED rojo: Bomba Efluente
#define AGITADOR 27      // LED Celeste: Agitador
#define ELECVAL_ALIM 32  // Primer LED Amarillo: Electroválvula Alimentación 
#define ELECVAL_EFLU 33  // Segundo LED Amarillo: Electroválvula Efluente
// #define SENSOR_PH 34     // Sensor DHT22: Simula un MQ4
// #define SENSOR_MQ4 35    // Potenciometro: Simula un Sensor PH

#define INICIO 4         // Inicio de proceso
#define STOP 5           // Parar proceso
#define ALIM 16          // Pulsador de alimentación
#define EXTR 17          // Pulsador de extracción

const int DHT_PIN = 15;
// const int LED_PIN = 13;
const char* WIFI_NAME = "Wokwi-GUEST";
const char* WIFI_PASSWORD = "";
const int myChannelNumber = 2394230;
const char* myApiKey = "2JDDLP1FEEBMN8LV";
const char* server = "api.thingspeak.com";

DHTesp dhtSensor;
WiFiClient client;

bool PROCESO_ACTIVO = false;

void setup() {
  Serial.begin(115200);
  dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
  WiFi.begin(WIFI_NAME, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED){
    delay(1000);
    Serial.println("Wifi not connected");
  }
  Serial.println("Wifi connected !");
  Serial.println("Local IP: " + String(WiFi.localIP()));
  WiFi.mode(WIFI_STA);
  ThingSpeak.begin(client);

  pinMode(BOMBA_ALIM, OUTPUT);    // Salida: Bomba Alimentación
  pinMode(BOMBA_EFLU, OUTPUT);    // Salida: Bomba Efluente
  pinMode(AGITADOR, OUTPUT);      // Salida: Agitador 
  pinMode(ELECVAL_ALIM, OUTPUT);  // Salida: Electroválvula Alimentación
  pinMode(ELECVAL_EFLU, OUTPUT);  // Salida: Electroválvula Efluente

  pinMode(INICIO, INPUT_PULLUP);  // Entrada: Pulsador Inicio
  pinMode(STOP, INPUT_PULLUP);    // Entrada: Pulsador Stop
  pinMode(ALIM, INPUT_PULLUP);    // Entrada: Alimentación
  pinMode(EXTR, INPUT_PULLUP);    // Entrada: Extracción Sedimento
  
}

unsigned long tiempoActual = 0;
unsigned long agitadorTiempo = 0;
unsigned long bombaAlimTiempo = 0;
unsigned long bombaEfluTiempo = 0;
const int agitadorDuracion = 5000;
const int bombaAlimDuracion = 5000;
const int bombaEfluDuracion = 5000;

void loop() {
  tiempoActual = millis();

  if (digitalRead(INICIO) == LOW && !PROCESO_ACTIVO) {
    PROCESO_ACTIVO = true;
    agitadorTiempo = tiempoActual;
    bombaAlimTiempo = tiempoActual;
    bombaEfluTiempo = tiempoActual;

    while (PROCESO_ACTIVO) {

      TempAndHumidity  data = dhtSensor.getTempAndHumidity();

      ThingSpeak.setField(1,data.temperature);
      ThingSpeak.setField(2,data.humidity);
      
      int x = ThingSpeak.writeFields(myChannelNumber,myApiKey);
      
      Serial.println("Temp: " + String(data.temperature, 2) + "°C");
      Serial.println("Humidity: " + String(data.humidity, 1) + "%");
      
      if(x == 200){
        Serial.println("Data pushed successfull");
      }else{
        Serial.println("Push error" + String(x));
      }
      Serial.println("---");

      delay(10000);

      if (digitalRead(STOP) == LOW) {
        PROCESO_ACTIVO = false;
      }
    }
  }

  if (PROCESO_ACTIVO) {
    // Agitator control
    if (tiempoActual - agitadorTiempo >= agitadorDuracion) {
      digitalWrite(AGITADOR, LOW);
    } else {
      digitalWrite(AGITADOR, HIGH);
    }

    // Pump and valve controls for Alimentacion
    if (digitalRead(ALIM) == LOW) {
      if (tiempoActual - bombaAlimTiempo >= bombaAlimDuracion) {
        digitalWrite(BOMBA_ALIM, LOW);
        digitalWrite(ELECVAL_ALIM, LOW);
      } else {
        digitalWrite(BOMBA_ALIM, HIGH);
        digitalWrite(ELECVAL_ALIM, HIGH);
      }
    }

    // Pump and valve controls for Efluente
    if (digitalRead(EXTR) == LOW) {
      if (tiempoActual - bombaEfluTiempo >= bombaEfluDuracion) {
        digitalWrite(BOMBA_EFLU, LOW);
        digitalWrite(ELECVAL_EFLU, LOW);
      } else {
        digitalWrite(BOMBA_EFLU, HIGH);
        digitalWrite(ELECVAL_EFLU, HIGH);
      }
    }
  }

  // Update time variables when ALIM or EXTR is pressed during an active process
  if ((digitalRead(ALIM) == LOW || digitalRead(EXTR) == LOW) && PROCESO_ACTIVO) {
    if (digitalRead(ALIM) == LOW) {
      bombaAlimTiempo = tiempoActual;
    }
    if (digitalRead(EXTR) == LOW) {
      bombaEfluTiempo = tiempoActual;
    }
  }

  // Check if the 5 seconds have passed and turn off the LEDs
  if (PROCESO_ACTIVO) {
    if (tiempoActual - bombaAlimTiempo >= bombaAlimDuracion) {
      digitalWrite(BOMBA_ALIM, LOW);
      digitalWrite(ELECVAL_ALIM, LOW);
    }

    if (tiempoActual - bombaEfluTiempo >= bombaEfluDuracion) {
      digitalWrite(BOMBA_EFLU, LOW);
      digitalWrite(ELECVAL_EFLU, LOW);
    }
  }

  if (digitalRead(STOP) == LOW && PROCESO_ACTIVO) {
    digitalWrite(BOMBA_ALIM, LOW);
    digitalWrite(BOMBA_EFLU, LOW);
    digitalWrite(AGITADOR, LOW);
    digitalWrite(ELECVAL_ALIM, LOW);
    digitalWrite(ELECVAL_EFLU, LOW);
    PROCESO_ACTIVO = false;
  }
}
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module