/*
  Wokwi | questions
  help me please with it

  elded— 1/12/2025 4:41 PM
*/

#include <WiFi.h>
#include <Adafruit_SSD1306.h>
//#include <ESPAsyncTCP.h>
#include <ESPAsyncWebSrv.h>

// Credenciales Wi-Fi
const char* ssid = "Wokwi-GUEST";
const char* password = "";

// Configuración del servidor web
AsyncWebServer server(80);

// Configuración de pines y sensores
#define TRIG_TANK1 18
#define ECHO_TANK1 5
#define TRIG_TANK2 17
#define ECHO_TANK2 16
#define PUMP1_PIN 12
#define PUMP2_PIN 14
#define BUZZER_PIN 27
#define LED_PIN 26
#define BUTTON_PIN 19

// Configuración del 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 de distancias del tanque
const int emptyTank1Distance = 400;
const int fullTank1Distance = 50;
const int emptyTank2Distance = 400;
const int fullTank2Distance = 50;

// Variables
int waterLevel1 = 0, waterLevel2 = 0;
bool pump1State = false, pump2State = false;
bool manualOverride = false;
SemaphoreHandle_t xMutex;

// Función para medir niveles
void measureTankLevels() {
  int localWaterLevel1, localWaterLevel2;

  digitalWrite(TRIG_TANK1, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_TANK1, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_TANK1, LOW);
  float duration1 = pulseIn(ECHO_TANK1, HIGH);
  float distance1 = (duration1 / 2) * 0.034;
  localWaterLevel1 = constrain(map(distance1, emptyTank1Distance, fullTank1Distance, 0, 100), 0, 100);

  digitalWrite(TRIG_TANK2, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_TANK2, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_TANK2, LOW);
  float duration2 = pulseIn(ECHO_TANK2, HIGH);
  float distance2 = (duration2 / 2) * 0.034;
  localWaterLevel2 = constrain(map(distance2, emptyTank2Distance, fullTank2Distance, 0, 100), 0, 100);

  xSemaphoreTake(xMutex, portMAX_DELAY);
  waterLevel1 = localWaterLevel1;
  waterLevel2 = localWaterLevel2;
  xSemaphoreGive(xMutex);
}

// Página principal del servidor web
String getHTMLPage() {
  xSemaphoreTake(xMutex, portMAX_DELAY);
  String html = "<html><body>";
  html += "<h1>Monitoreo de Tanques</h1>";
  html += "<p>Tanque 1: " + String(waterLevel1) + "%</p>";
  html += "<p>Tanque 2: " + String(waterLevel2) + "%</p>";
  html += "<p>Bomba 1: " + String(pump1State ? "Encendida" : "Apagada") + "</p>";
  html += "<p>Bomba 2: " + String(pump2State ? "Encendida" : "Apagada") + "</p>";
  html += "<p>Modo Manual: " + String(manualOverride ? "Activado" : "Desactivado") + "</p>";
  html += "</body></html>";
  xSemaphoreGive(xMutex);
  return html;
}

// Tarea para manejar el servidor web
void webServerTask(void* parameter) {
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(200, "text/html", getHTMLPage());
  });
  server.begin();

  //for (;;) {
  //delay(1000); // Mantiene la tarea activa
  //}
}

void setup() {
  Serial.begin(115200);

  pinMode(TRIG_TANK1, OUTPUT);
  pinMode(ECHO_TANK1, INPUT);
  pinMode(TRIG_TANK2, OUTPUT);
  pinMode(ECHO_TANK2, INPUT);
  pinMode(PUMP1_PIN, OUTPUT);
  pinMode(PUMP2_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);

  // initialize OLED
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(25, 10);
  display.print("Connecting...");
  display.display();

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Conectando a Wi-Fi...");
  }
  Serial.println("Conectado a Wi-Fi");
  Serial.println(WiFi.localIP());

  display.clearDisplay();
  display.setCursor(25, 10);
  display.print("WiFi connected");
  display.setCursor(35, 30);
  display.print(WiFi.localIP());
  display.display();

  /*
    xMutex = xSemaphoreCreateMutex();

    // Crear tarea para el servidor web
    xTaskCreate(
      webServerTask,         // Función de la tarea
      "WebServerTask",       // Nombre de la tarea
      4096,                  // Tamaño del stack
      NULL,                  // Parámetro
      1,                     // Prioridad
      NULL                   // Handle
    );
  */
}

void loop() {
  //measureTankLevels();
  delay(1000);
}
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module