// Les librairies
#include "WiFiEsp.h"        // https://github.com/bportaluri/WiFiEsp
#include <HTS221Sensor.h>
#include <LPS22HBSensor.h>

#define I2C2_SCL    PB10
#define I2C2_SDA    PB11

HTS221Sensor  *HumTemp;
LPS22HBSensor *PressTemp;
TwoWire *dev_i2c;

float humidity, HTS221Sensor_temperature;
float pressure, LPS22HBSensor_temperature;

// on défini une 2eme com serie en D0 et D1 pour communiquer avec l'ESP
HardwareSerial ESP(D0, D1); // RX, TX 

char ssid[] = "XXXXX";                // Votre réseau wifi
char pass[] = "YYYYY";                // Votre mdp du réseau wifi
int status = WL_IDLE_STATUS;          // l'état du réseau wifi

WiFiEspServer serveur(80);            // On definit le serveur web sur le port 80

unsigned long previousMillis = 0;     // varaible pour millis
const long interval = 10000;          // interval pour millis

void setup() {
  Serial.begin(115200);               // On démmarre la com série avec le pc a 115200 baud
  ESP.begin(115200);                  // On démmarre la com série avec l'ESP a 115200 baud
  WiFi.init(&ESP);                    // On initialisle la connection au réseau  

  // On test si on a le réseau à travers l'esp
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("Je tourve pas l'ESP");    
    while (true);  // On ne continue pas
  }
  
  // On essaye de se connécter au réseau wifi
  while ( status != WL_CONNECTED) {
    Serial.print("J'essaye de me connecter au réseau wifi : ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, pass);
  }
  // On affiche les infos de connexions
  Serial.print("Connécté à : ");
  Serial.println(WiFi.SSID());  
  IPAddress ip = WiFi.localIP();
  Serial.print("Mon ip est : ");
  Serial.println(ip);  
  // on démmarre le serveur web
  serveur.begin();
  dev_i2c = new TwoWire(I2C2_SDA, I2C2_SCL);
  dev_i2c->begin();
  HumTemp = new HTS221Sensor (dev_i2c);
  HumTemp->Enable();
  PressTemp = new LPS22HBSensor(dev_i2c);
  PressTemp->Enable();
}

// Fonction qui lit la sonde dht22 toutes les 10s (variable interval)
void get_presstemp() { 
  // On stock le temps écoulé depuis le début du programme dans la variable currentMillis
  unsigned long currentMillis = millis();     
  // si le temps actuel - le temps précédent dépasse l'interval        
  if (currentMillis - previousMillis >= interval) {
    // le temps précédent vaut le temps actuel (réinitialise le compteur) 
    previousMillis = currentMillis;    
    HumTemp->GetHumidity(&humidity);
    HumTemp->GetTemperature(&HTS221Sensor_temperature);   
    PressTemp->GetPressure(&pressure);
    PressTemp->GetTemperature(&LPS22HBSensor_temperature);
    Serial.println("***************");
    Serial.println("HTS221 Sensor : ");
    Serial.print("Température : ");
    Serial.print(HTS221Sensor_temperature, 2);
    Serial.print(" °C");
    Serial.print(" | Humidité : ");
    Serial.print(humidity, 2);
    Serial.println(" %");
    Serial.println("***************");
    Serial.println("LPS22HB Sensor : ");
    Serial.print("Pression : ");
    Serial.print(pressure, 2);
    Serial.print(" hPa");
    Serial.print(" | Température : ");
    Serial.print(LPS22HBSensor_temperature, 2);
    Serial.println(" °C");
    Serial.println("***************");    
  }
}

void loop() {
  // On lance notre fonction pour récupérer les datas de la sonde
  get_presstemp();
  // On définit l'objet client qui sera l'écoute si un client se connecte 
  WiFiEspClient client = serveur.available();
  // si un client est connecté
  if (client) {
    Serial.println("Un nouveau client est connecté");       
    // flag pour definire la fin d'une requête http (ligne vierge)
    boolean currentLineIsBlank = true;
    // quand un client est connecté 
    while (client.connected()) {
      // si il envoie quel que chose
      if (client.available()) {
        // on lit ce qu'il envoie
        char c = client.read();
        // et on l'écrit dans la comme serie avec le pc
        Serial.write(c);
        // si on reçoit \n, et que le flag currentLineIsBlank est vrai, la demande http est terminée
        if (c == '\n' && currentLineIsBlank) {          
          Serial.println("Envoie de la réponse"); 
          // on envoye une réponse          
          client.print(
            "HTTP/1.1 200 OK\r\n"           
            "Content-Type: text/html\r\n"    // le type de la réponse
            "Connection: close\r\n"          // on fermera la connexion aprés l'envoie de la réponse           
            "\r\n");
          client.print(SendHTML(HTS221Sensor_temperature,humidity,LPS22HBSensor_temperature,pressure)); // on envoie notre page html comme réponse 
          break;                             // on quitte la boucle while apres la déconnection avec l'esp  
        }
        if (c == '\n') {                     // si le caractère reçu est \n          
          currentLineIsBlank = true;         // le flag currentLineIsBlank vaut true
        }
        else if (c != '\r') {                // si le caractère reçu est \r          
          currentLineIsBlank = false;        // le flag currentLineIsBlank vaut false
        }
      }
    }
    // un petit delay pour le temps de réception de la réponse
    delay(10);

    // on ferme la connexion
    client.stop();
    Serial.println("Client déconnecté");
    delay(10);
  }
}

// la fonction qui construit la page html (datas rafraichies par ajax toutes les 10s (fonction js setInterval)
String SendHTML(float Temp1,float Humidity,float Temp2,float Press){
  String ptr="<!DOCTYPE html>\n";
  ptr +="<meta charset=\"utf-8\">\n";
  ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr +="<title>STM32-Discovery-L475-IOT + ESP01</title>\n";
  ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n";
  ptr +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
  ptr +="</style>\n";
  ptr +="<script>\n";
  ptr +="setInterval(loadDoc,10000);\n";                               // rafraichie ttes les 10s
  ptr +="function loadDoc() {\n";
  ptr +="var xhttp = new XMLHttpRequest();\n";
  ptr +="xhttp.onreadystatechange = function() {\n";
  ptr +="if (this.readyState == 4 && this.status == 200) {\n";
  ptr +="document.getElementById(\"data\").innerHTML =this.responseText}\n";
  ptr +="};\n";
  ptr +="xhttp.open(\"GET\", \"/\", true);\n";
  ptr +="xhttp.send();\n";
  ptr +="}\n";
  ptr +="</script>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<div id=\"data\">\n";
  ptr +="<h1>STM32-Discovery-L475-IOT + ESP01</h1>\n";  
  ptr +="<h2>HTS221 Sensor</h2>\n";  
  ptr +="<p>Temperature: ";
  ptr +=Temp1;
  ptr +=" °C</p>";
  ptr +="<p>Humidity: ";
  ptr +=Humidity;
  ptr +=" %</p>";
  ptr +="<h2>LPS22HB Sensor</h2>\n";  
  ptr +="<p>Temperature: ";
  ptr +=Temp2;
  ptr +=" °C</p>";
  ptr +="<p>Pressure: ";
  ptr +=Press;
  ptr +=" hPa</p>"; 
  ptr +="</div>\n";
  ptr +="</body>\n";
  ptr +="</html>\n";
  return ptr;
}