#include <Arduino.h>

#include <Wire.h>

#include "SHT31.h"

#include <LiquidCrystal.h>

#define Fan1 3              // pin3 devient le pin du relai(Fan 1

#define Fan2 4               // pin4 devient le pin du relai(Fan 2

#define Cooler 6                      // pin6 devient le pin du Cooler

#define Heating 5                     // pin5 devient le pin du chauffage

#define Watering 0                    // pin0 devient le pin de l'arrosage

#define Moisturing 13                 // pin13 devient le pin de l'humidification

#define OK 2                          // pin2 devient le pin du bouton OK

#define Select 1                      // pin1 devient le pin du bouton Select

SHT31 sht31 = SHT31();                // initie le SHT31

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);    // connexion des ports de l'écran LCD

int GroundSensor = A0;         // attribution du pin analogique A0 comme entrée du signal du capteur d'humidité du sol

int Poten = A2;                // attribution du pin analogique A2 comme entrée du signal du potentiomètre

int PotenFine = A3;            // attribution du pin analogique A3 comme entrée su signal du potentiomètre de réglage fin

// Les variables suivantes sont pour les réglages

int T = 10;

int H = 0;

int W = 0;

// Les variables suivantes sont pour le bacup

int T1 = 0;

int H1 = 0;

int W1 = 0;

// Les variable suivantes sont pour naviguer entre les menus de réglage

int Menu = 1;

int Valider = 0;

// Les variables suivantes sont pour savoir si les relais sont ouverts ou fermé

int Fan1Mode = 0;

int Fan2Mode = 0;

int CoolerMode = 0;

int HeatingMode = 0;

int WateringMode = 0;

int MoisturingMode = 0;

//La variable suivante sert à corriger un bug d'affichage... J'éspère...

int Offset = 0;

// Définition de toute les fonctions secondaires de ce code...

void Ventilation();

void Chauffage ();

void Refroidissement ();

void Arrosage ();

void Humidification ();

void Set_T ();

void Set_H ();

void Set_W ();

void Validation ();

void off ();

void whipe ();




void setup() {

  sht31.begin();  

  pinMode(Fan1, OUTPUT);      // règle le pin 3 en output

  pinMode(Fan2, OUTPUT);      // règle le pin 4 en output

  pinMode(Poten, INPUT);      // règle le pin A0 (analogique) comme entrée du signal du potentiomètre

  pinMode(PotenFine, INPUT);

  pinMode(Cooler, OUTPUT);

  pinMode(Heating, OUTPUT);

  pinMode(Watering, OUTPUT);

  pinMode(Moisturing, OUTPUT);

  pinMode(OK, INPUT_PULLUP);

  pinMode(Select, INPUT_PULLUP);

  Serial.begin(9600);          // initialise la comm.
  
  lcd.begin(16, 2);

  lcd.setCursor(0, 0);

  lcd.println("                ");

  lcd.setCursor(0, 1);

  lcd.println("                ");

}






void loop () {

  if (Menu =! 0) {

    off ();

  }

  if (Menu == 1) {

    whipe ();

    lcd.setCursor(0, 0);

    lcd.println("Set temp           ");

    lcd.setCursor(0, 1);

    lcd.println("Current :          ");

    lcd.setCursor(8, 1);

    lcd.println(T);

    Offset = strlen(T);

    lcd.setCursor(8+Offset, 1);

    lcd.println(" C          ");

    delay (2000);

    lcd.setCursor(15, 1);

    lcd.println("X");

    while (Menu == 1) {

      if (digitalRead(OK) == LOW) {

        Set_T ();

      }

      if (digitalRead(Select) == LOW) {

        Menu = 2;
        
      }

      delay(100);

    }

  }




  if (Menu == 2) {

    whipe ();

    lcd.setCursor(0, 0);

    lcd.println("Set hum           ");

    lcd.setCursor(0, 1);

    lcd.println("Current :        ");

    lcd.setCursor(8, 1);

    lcd.println(H);

    Offset = strlen(H);

    lcd.setCursor(8+Offset, 1);

    lcd.println(" %          ");

    delay (2000);

    lcd.setCursor(15, 1);

    lcd.println("X");

    while (Menu == 2) {

      if (digitalRead(OK) == LOW) {

        Set_H ();

        
      }
      if (digitalRead(Select) == LOW) {

        Menu = 3;

      }

      delay(100);

    }

  }




  if (Menu == 3) {

    whipe ();

    lcd.setCursor(0, 0);

    lcd.println("Set watering       ");

    lcd.setCursor(0, 1);

    lcd.println("Current :          ");

    lcd.setCursor(8, 1);

    lcd.println(W);

    Offset = strlen(W);

    lcd.setCursor(8+Offset, 1);

    lcd.println(" %          ");

    delay (2000);

    lcd.setCursor(15, 1);

    lcd.println("X");

    while (Menu == 3) {

      if (digitalRead(OK) == LOW) {

        Set_W ();

      }

      if (digitalRead(Select) == LOW) {
        
        Menu = 0;

        Validation ();
      }

      delay(100);

    }

  }




  if (digitalRead(Select) == LOW) {

    Menu = 1;

    off ();

  }


  if (Valider == 0) {

    off ();

    Validation ();

  }




  if ((Menu == 0) && (Valider == 1)) {

    whipe ();

    lcd.setCursor(0, 1);

    lcd.println("T=   H=    W=   ");

    lcd.setCursor(2, 1);

    lcd.println(T);

    lcd.setCursor(8, 1);

    lcd.println(H);

    lcd.setCursor(14, 1);

    lcd.println(W);

    lcd.setCursor(0, 0);

    lcd.println("T=   H=    W=   ");

    lcd.setCursor(2, 0);

    lcd.println(sht31.getTemperature());

    lcd.setCursor(8, 1);

    lcd.println(sht31.getHumidity());

    lcd.setCursor(13, 1);

    lcd.println(analogRead(GroundSensor));

    Ventilation ();

    Chauffage ();

    Refroidissement ();

    Arrosage ();

    Humidification ();

  }

  delay(1000);

}






void Ventilation() {

  if ((sht31.getTemperature() >= T) && (Fan1Mode == 0)) {

    digitalWrite(Fan1, LOW);          // le relai se ferme => le ventilateur s'allume
    
    Fan1Mode = 1;

  }

  if ((sht31.getTemperature() >= T+1) && (Fan1Mode == 1) && (Fan2Mode == 0)) {

    digitalWrite(Fan2, LOW);

    Fan2Mode = 1;

  }

  if ((T >= sht31.getTemperature()) && (Fan2Mode == 1)) {

    digitalWrite(Fan2, HIGH);

    Fan2Mode = 0;

  }

  if (T-1 >= sht31.getTemperature()) {

    digitalWrite(Fan1, HIGH);

    Fan1Mode = 0;

    digitalWrite(Fan2, HIGH);

    Fan2Mode = 0;

  }

}






void Chauffage () {

  if ((T-3 >= sht31.getTemperature()) && (HeatingMode == 0)) {

    digitalWrite(Heating, LOW);

    HeatingMode = 1;

  }

  if ((sht31.getTemperature() >= T-2) && (HeatingMode == 1)) {

    digitalWrite(Heating, HIGH);

    HeatingMode = 0;

  }

}






void Refroidissement () {

  if ((sht31.getTemperature() >= T+5) && (CoolerMode == 0)) {

    digitalWrite(Cooler, LOW);

    CoolerMode = 1;

  }

  if ((T >= sht31.getTemperature()) && (CoolerMode == 1)) {

    digitalWrite(Cooler, HIGH);

    CoolerMode = 0;

  }

}






void Arrosage () {

  if (W+100 >= (analogRead(GroundSensor)) && (WateringMode == 0)) {

    digitalWrite(Watering, LOW);

    WateringMode = 1;

  }

  if ((analogRead(GroundSensor) >= W-100) && (WateringMode == 1)) {

    digitalWrite(Watering, HIGH);

    WateringMode = 0;

  }

}





void Humidification () {

  if ((H-10 >= sht31.getHumidity()) && (MoisturingMode == 0)) {

    digitalWrite(Moisturing, LOW);

    MoisturingMode = 1;

  }

  if ((sht31.getHumidity() >= H) && (MoisturingMode == 1)) {

    digitalWrite(Moisturing, HIGH);

    MoisturingMode = 0;

  }

}





void Set_T () {

  T1 = T;

  T = ((10+analogRead(Poten)/40)+(analogRead(PotenFine)/125));   // poten prend comme valeur celle envoyée par le potentiomètre, divisée par 10 pour avoir un interval de température entre 0 et 70°C à laquelle on ajoutte celle d'un deuxième potentiomètre divisé par 100 pour avoir plus de précision

  Serial.println(T);

  whipe ();

  lcd.setCursor(0, 0);

  lcd.println("Set temp to:    ");

  lcd.setCursor(0, 1);

  lcd.println("T=              ");

  lcd.setCursor(2, 1);

  lcd.println(T);

  Offset = strlen(T);

  lcd.setCursor (2+Offset, 1);

  lcd.println(" C          ");

  delay (2000);

  while (Menu == 1) {

    T = int((10+analogRead(Poten)/40)+(analogRead(PotenFine)/125));   // poten prend comme valeur celle envoyée par le potentiomètre, divisée par 10 pour avoir un interval de température entre 0 et 70°C à laquelle on ajoutte celle d'un deuxième potentiomètre divisé par 100 pour avoir plus de précision

    Serial.println(T);

    whipe ();

    lcd.setCursor(0, 0);

    lcd.println("Set temp to:    ");

    lcd.setCursor(0, 1);

    lcd.println("T=              ");

    lcd.setCursor(2, 1);

    lcd.println(T);

    Offset = strlen(T);

    lcd.setCursor (4+Offset, 1);

    lcd.println(" C          ");

    lcd.setCursor(15, 1);

    lcd.println("X");

    if (digitalRead(OK) == LOW) {

      Menu = 2;

    }

    if (digitalRead(Select) == LOW) {

      Menu = 2;
      
      T=T1;

    }

    delay(100);

  }

}






void Set_H () {

  H1 = H;

  Serial.println(H);

  whipe ();

  lcd.setCursor(0, 0);

  lcd.println("Set hum to:     ");

  lcd.setCursor(0, 1);

  lcd.println("H=              ");

  lcd.setCursor(2, 1);

  lcd.println(H);

  Offset = strlen(H);

  lcd.setCursor (2+Offset, 1);

  lcd.println(" %           ");

  delay (2000);

  while (Menu == 2) {

    H = 1; // insérer un réglage d'humidité coérrent

    Serial.println(H);

    whipe ();

    lcd.setCursor(0, 0);

    lcd.println("Set hum to:     ");

    lcd.setCursor(0, 1);

    lcd.println("H=              ");

    lcd.setCursor(2, 1);

    lcd.println(H);

    Offset = strlen(H);

    lcd.setCursor (2+Offset, 1);

    lcd.println(" %           ");

    lcd.setCursor(15, 1);

    lcd.println("X");

    if (digitalRead(OK) == LOW) {

      Menu = 3;

    }

    if (digitalRead(Select) == LOW) {

      Menu = 3;
      
      H=H1;

    }

    delay(100);

  }

}






void Set_W () {

  W1 = W;

  W = 1; // insérer un réglage d'humidité coérrent

  Serial.println(W);

  whipe ();

  lcd.setCursor(0, 0);

  lcd.println("Set watering to:");

  lcd.setCursor(0, 1);

  lcd.println("W=              ");

  lcd.setCursor(2, 1);

  lcd.println(W);

  Offset = strlen(W);

  lcd.setCursor (2+W, 1);

  lcd.println("/1000       ");

  delay (2000);

  while (Menu == 3) {

    W = 1; // insérer un réglage d'humidité coérrent

    Serial.println(W);

    whipe ();

    lcd.setCursor(0, 0);

    lcd.println("Set watering to:");

    lcd.setCursor(0, 1);

    lcd.println("W=              ");

    lcd.setCursor(2, 1);

    lcd.println(W);

    Offset = strlen(W);

    lcd.setCursor (2+W, 1);

    lcd.println("/1000       ");

    lcd.setCursor(15, 1);

    lcd.println("X");

    if (digitalRead(OK) == LOW) {

      Menu = 0;

    }

    if (digitalRead(Select) == LOW) {

      Menu = 0;
      
      W=W1;

    }

    delay(100);

  }

}





void Validation () {

  Valider = 0;

  Menu = 0;

  off();

  whipe ();

  lcd.setCursor(0, 1);

  lcd.println("T=   H=    W=   ");

  lcd.setCursor(2, 1);

  lcd.println(T);

  lcd.setCursor(8, 1);

  lcd.println(H);

  lcd.setCursor(14, 1);

  lcd.println(W);

  lcd.setCursor(0, 0);

  lcd.println("    Valider?    ");

  delay (2000);

  lcd.setCursor(0, 15);

  lcd.println("X");

  while ((Valider == 0) && (Menu == 0)) {

    if (digitalRead(OK) == LOW) {

      Valider = 1;

    }

    if (digitalRead(Select) == LOW) {

      Menu = 1;

    }
    
    delay(100);

  }

}





void off () {

  digitalWrite(Fan1, HIGH);

  digitalWrite(Fan2, HIGH);

  digitalWrite(Heating, HIGH);

  digitalWrite(Cooler, HIGH);

  digitalWrite(Watering, HIGH);

  digitalWrite(Moisturing, HIGH);

  MoisturingMode = 0;

  CoolerMode = 0;

  HeatingMode = 0;

  Fan1Mode = 0;

  Fan2Mode = 0;

  WateringMode = 0;

}




void whipe () {

  lcd.setCursor(0, 0);

  lcd.println("                ");

  lcd.setCursor(0, 1);

  lcd.println("                ");

}