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

//RGB led
#define PIN_RED    12
#define PIN_GREEN  14
#define PIN_BLUE   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_7500 45
#define UNDER_10000 90
#define UNDER_15000 135
//Seuil temperature (Scenario 2)
#define SEUIL_TEMP 23

void climatiseur(){
  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 (23 °C) => Cooling");
      analogWrite(PIN_RED,   0);
      analogWrite(PIN_GREEN, 0);
      analogWrite(PIN_BLUE,  255);
    }else{
      Serial.println("smaller then threshold (23 °C) => Heating");
      analogWrite(PIN_RED,   255);
      analogWrite(PIN_GREEN, 0);
      analogWrite(PIN_BLUE,  0);
    }
  }
}

void fenetre(){

  //lire valeur du potentiometre
  int potValue = analogRead(POT_PIN);
  potValue = map(potValue, 0, 4095, 0, 17000);//concentration du CO2 (0ppm - 3000ppm)
  
  //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 < 7500){
    angle = UNDER_7500;
    Serial.print("CO2 concentration below 7500ppm, open window by ");
    Serial.println(UNDER_7500);
  }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;
}

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(PIN_RED, OUTPUT);
  pinMode(PIN_GREEN, OUTPUT);
  pinMode(PIN_BLUE, OUTPUT);
  delay(2000);
}

void loop() {

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

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

  delay(5000);
}