#include <DHT.h>
#include <ESP32Servo.h>
#include <WiFi.h>
#include "ThingSpeak.h"
#include <HTTPClient.h>
#include <UrlEncode.h>

// Configuration WiFi
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASS = "";

// Configuration ThingSpeak
const int THINGSPEAK_CHANNEL = 2550097;
const char* THINGSPEAK_WRITE_API_KEY = "QI0F26NW2L4QVW4K";
WiFiClient wifiClient;

// Configuration des capteurs et composants
#define DHT_PIN 12
#define DHT_TYPE DHT22
#define LDR_PIN 33
#define LED_1 23
#define LED_2 22
#define LED_3 21
#define LED_4 19
#define RGB_R 25
#define RGB_G 27
#define RGB_B 26
#define SERVO_PIN 13
#define POTENTIOMETER_PIN 35

// Seuils
const float CO2_VALUE_MAX = 350;
const float TEMPERATURE_VALUE = 30;

// Variables globales
float temperature = 0;
float humidity = 0;
int co2 = 0;
int luminosity = 0;
int var;

// Configurations du capteur
const float GAMMA = 0.7;
const float RL10 = 50;

DHT dht(DHT_PIN, DHT_TYPE);
Servo servo;

// Configuration API CallMeBot
String phoneNumber = "212651334219";
String apiKey = "4122894";

// Fonction pour envoyer un message via CallMeBot
void sendMessage(String message) {
  String url = "https://api.callmebot.com/whatsapp.php?phone=" + phoneNumber + "&apikey=" + apiKey + "&text=" + urlEncode(message);
  
  HTTPClient http;
  http.begin(url);
  int httpResponseCode = http.GET();  // Utilisation de GET au lieu de POST
  
  if (httpResponseCode == 200) {
    Serial.println("Message sent successfully");
  } else {
    Serial.println("Error sending the message");
    Serial.print("HTTP response code: ");
    Serial.println(httpResponseCode);
  }
  
  http.end();
}

// Fonction de connexion WiFi
void connectToWiFi() {
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("WiFi not connected");
  }
  Serial.println("WiFi connected!");
  Serial.print("Local IP: ");
  Serial.println(WiFi.localIP());
  WiFi.mode(WIFI_STA);
  ThingSpeak.begin(wifiClient);
}

// Fonction setup
void setup() {
  Serial.begin(9600);
  
  connectToWiFi();

  dht.begin();  // Initialisation du capteur DHT
  
  pinMode(LDR_PIN, INPUT);
  pinMode(RGB_R, OUTPUT);
  pinMode(RGB_G, OUTPUT);
  pinMode(RGB_B, OUTPUT);
  pinMode(LED_1, OUTPUT);
  pinMode(LED_2, OUTPUT);
  pinMode(LED_3, OUTPUT);
  pinMode(LED_4, OUTPUT);

  servo.attach(SERVO_PIN);
  servo.write(90);
}

// Fonction loop
void loop() {
  //Scénario 1
  // Lire et afficher les niveaux de CO2
  co2 = analogRead(POTENTIOMETER_PIN);
  co2 = map(co2, 0, 4095, 0, 1000);
  Serial.print("CO2 Level: ");
  Serial.print(co2);
  Serial.println(" ppm");

  if (co2 > CO2_VALUE_MAX) {
    servo.write(180);
    sendMessage("CO2 Trés élevée, FAITES ATTENTION !");
  } else {
    servo.write(90);
  }

  //Scénario 2
  // Lire et afficher la température et l'humidité
  temperature = dht.readTemperature();
  humidity = dht.readHumidity();
  Serial.print("Temperature: ");
  Serial.print(temperature);
  Serial.println(" °C");
  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.println(" %");

  if (temperature > TEMPERATURE_VALUE) {
    digitalWrite(RGB_R, HIGH);
    digitalWrite(RGB_G, HIGH);
    digitalWrite(RGB_B, LOW);
  } else {
    digitalWrite(RGB_R, LOW);
    digitalWrite(RGB_G, HIGH);
    digitalWrite(RGB_B, HIGH);
  }

  //Scénario 3
  // Lire et afficher la luminosité
  luminosity = analogRead(LDR_PIN);
  float voltage = luminosity * 5.0 / 4095.0;
  float resistance = 2000.0 * voltage / (1.0 - voltage / 5.0);
  luminosity = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, 1 / GAMMA);
  Serial.print("Luminosity: ");
  Serial.print(luminosity);
  Serial.println(" lux");

  if (luminosity < 1000) {
    digitalWrite(LED_1, HIGH);
    digitalWrite(LED_2, LOW);
    digitalWrite(LED_3, LOW);
    digitalWrite(LED_4, LOW);
    var = 1;
  } else if ((luminosity >= 1000) && (luminosity < 2500)) {
    digitalWrite(LED_1, HIGH);
    digitalWrite(LED_2, HIGH);
    digitalWrite(LED_3, LOW);
    digitalWrite(LED_4, LOW);
    var = 2;
  } else if ((luminosity >= 2500) && (luminosity < 4000)) {
    digitalWrite(LED_1, HIGH);
    digitalWrite(LED_2, HIGH);
    digitalWrite(LED_3, HIGH);
    digitalWrite(LED_4, LOW);
    var = 2;
  } else {
    digitalWrite(LED_1, HIGH);
    digitalWrite(LED_2, HIGH);
    digitalWrite(LED_3, HIGH);
    digitalWrite(LED_4, HIGH);
    var = 3;
  }

  delay(1000);

  sendDataToThingSpeak();
}

// Fonction pour envoyer les données à ThingSpeak
void sendDataToThingSpeak() {
  ThingSpeak.setField(1, temperature);
  delay(500);
  ThingSpeak.setField(2, humidity);
  delay(500);
  ThingSpeak.setField(3, co2);
  delay(500);
  ThingSpeak.setField(4, var);
  delay(500);

  int writeResult = ThingSpeak.writeFields(THINGSPEAK_CHANNEL, THINGSPEAK_WRITE_API_KEY);

  if (writeResult == 200) {
    Serial.println("Data pushed successfully");
  } else {
    Serial.println("Error pushing data: " + String(writeResult));
  }
  Serial.println("---");
}


// Réalisé par: BOUCHRA IDBAATMANI 
// OUSSAMA GOUSSA
// SOUMAYA TOMZEN
$abcdeabcde151015202530354045505560fghijfghij