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


const char* WIFI_NAME = "Wokwi-GUEST";
const char* WIFI_PASSWORD = "";
const int myChannelNumber = 2546940;
const char* myApiKey = "ZG8URGVKKIP17OCO";
const char* server = "api.thingspeak.com";

WiFiClient client;

//RGB led
#define RED_PIN   12
#define GREEN_PIN  14
#define BLUE_PIN   27

//slide potentiometer
#define POT_PIN 4

//servo
#define SERVO_PIN 22
Servo servo;
int CURRENT_ANGLE = 0;

//dht
#define DHT_PIN 13
#define DHTTYPE DHT22
DHT dht(DHT_PIN, DHTTYPE);

//Seuil CO2 (Scenario 1)
#define UNDER_5000 45
#define UNDER_10000 90
#define UNDER_15000 150
//Seuil temperature (Scenario 2)
#define SEUIL_TEMP 25

//Capteur de luminosité (Scenario 3)

#define LDR_PIN 34
int lightValue = 0;

// Pins des LED
const int led1 = 23;
const int led2 = 21;
const int led3 = 19;
const int led4 = 18;


void climat(){
  float temp = dht.readTemperature();
  if(isnan(temp)){
    Serial.println(F("Failed to read Temperature"));
  }else{
    Serial.print("Current temperature is ");
    Serial.print(temp);
    Serial.print(" °C, ");
    if(temp > SEUIL_TEMP){
      Serial.println("bigger then threshold (25 °C) => Cooling");
      analogWrite(RED_PIN,   0);
      analogWrite(GREEN_PIN, 0);
      analogWrite(BLUE_PIN,  255);
    }else{
      Serial.println("smaller then threshold (25 °C) => Heating");
      analogWrite(RED_PIN,   255);
      analogWrite(GREEN_PIN, 0);
      analogWrite(BLUE_PIN,  0);
    }
    ThingSpeak.setField(1, temp);

  }
}

void fenetre(){

  //lire valeur du potentiometre
  int potValue = analogRead(POT_PIN);
  potValue = map(potValue, 0, 4095, 0, 15000);//concentration du CO2 (0ppm - 30000ppm)
  
  //choisir l'angle d'ouverture de la fenetre
  int angle = 0;
  if(potValue <400){
    angle = 0;
    Serial.println("CO2 concentration below 400ppm, close window");
  }else if(potValue < 5000){
    angle = UNDER_5000;
    Serial.print("CO2 concentration below 5000ppm, open window by ");
    Serial.println(UNDER_5000);
  }else if(potValue < 10000){
    angle = UNDER_10000;
    Serial.print("CO2 concentration below 10000ppm, open window by ");
    Serial.println(UNDER_10000);
  }else if(potValue < 15000){
    angle = UNDER_15000;
    Serial.print("CO2 concentration below 15000ppm, open window by ");
    Serial.println(UNDER_15000);
  }else{
    Serial.println("CO2 concentration over 15000ppm, open window fully");
    angle = 180;
  }
  Serial.println();
  //changer l'angle d'ouverture du servo
  int difference = CURRENT_ANGLE - angle;
  if(difference < 0){
    ouvrirServo(abs(difference));
  }else{
    fermerServo(difference);
  }
  CURRENT_ANGLE = angle;

   ThingSpeak.setField(2, potValue);

}

void ouvrirServo(int angle){
  for(int i = 0 ; i <= angle ; i++){
    servo.write(CURRENT_ANGLE + i);
    delay(15);
  }
}

void fermerServo(int angle){
  for(int i = 0 ; i <= angle ; i++){
    servo.write(CURRENT_ANGLE - i);
    delay(15);
  }
}

void setup() {
  Serial.begin(9600);
  dht.begin();
  servo.attach(SERVO_PIN);
  servo.write(0);
  pinMode(POT_PIN, INPUT);
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
  pinMode(LDR_PIN, INPUT);
  delay(1500);

  // Initialisation des broches LED comme sorties
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);

 // Connect to Wi-Fi
    WiFi.begin(WIFI_NAME, WIFI_PASSWORD);
    Serial.print("Connecting to ");
    Serial.print(WIFI_NAME);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println();
    Serial.println("WiFi connected");
    ThingSpeak.begin(client);

}

void loop() {

  //2. Scénario : Température
  climat();

  //1. Scénario : CO2 élevé
  fenetre();

  delay(5000);

//3. Scénario : Capteur de luminosité

 int lightLevel = analogRead(LDR_PIN);
  // float voltage = analogValue / 1024. * 3;
  // float resistance = 2000 * voltage / (1 - voltage / 5);
  // float lightLevel = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
  if (lightLevel > 3092) {
    digitalWrite(23, HIGH);
    digitalWrite(21, LOW);
    digitalWrite(19, LOW);
    digitalWrite(18, LOW);
  } else if (lightLevel <= 3092 && lightLevel > 998) {
    digitalWrite(23, HIGH);
    digitalWrite(21, HIGH);
    digitalWrite(19, LOW);
    digitalWrite(18, LOW);
  }  
  if (lightLevel <= 998 && lightLevel >= 600) {
    digitalWrite(23, HIGH);
    digitalWrite(21, HIGH);
    digitalWrite(19, HIGH);
    digitalWrite(18, LOW);
  } else if (lightLevel < 600) {
    digitalWrite(23, HIGH);
    digitalWrite(21, HIGH);
    digitalWrite(19, HIGH);
    digitalWrite(18, HIGH);
  }
  Serial.println(lightLevel);
  delay(100);
  
  ThingSpeak.setField(3, lightValue);
   // Write to ThingSpeak
    int x = ThingSpeak.writeFields(myChannelNumber, myApiKey);
    if (x == 200) {
        Serial.println("Channel update successful.");
    } else {
        Serial.println("Problem updating channel. HTTP error code " + String(x));
    }
    
  delay(1000); // Attendre 1 seconde avant de lire la prochaine valeur
}