/*
  Projet Web Server - Serrure Connectée
  ******************************************************************************************************************************************************************************************************************
  Circuit:
   Ethernet shield relié aux broches du BUS MOSI + broche 2
   Relais relié à la broche A3 (gâche lectrique)
   Entrée Analogique Vin reliée aux broches A0 (tension batterie)

  Créé le 18 Sept 2022
  par Pascal Eugé (Lycée JB VUILLAUME - pascal.euge@ac-nancy-metz.fr)

  Liste des caractères spéciaux en HTLM : https://www.journaldunet.com/solutions/dsi/1195751-accents-caracteres-speciaux-html/

  è &#232; &egrave;
  é &#233; &eacute;
  º &#186; &ordm;
  " " &nbsp;
*/

#include <LiquidCrystal.h>
#include <UIPEthernet.h>  //décommenter pour simulation : permet de simuler l'accès au réseau
//#include <SPI.h>        //décommenter pour pour prototypage
//#include <Ethernet.h>   //décommenter pour pour prototypage

//OPTION : Utilisation de la librairie Duinoedu_Utility (Arduino Augmenté) pour mesure niv Batterie et Affichage/debogage par TIMER toute les 2 sec
#include <Duinoedu_Utility.h>

/*
  // Paramétrage du shield Ethernet sur Réseau local (domicile)
  byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //Adresse MAC
  byte ip[] = { 192, 168, 1, 6 }; // Adresse IP
  byte DNS[] = { 192, 168, 1, 1 };  //DNS
  byte gateway[] = { 192, 168, 1, 1 }; // Passerelle
  byte subnet[] = { 255, 255, 255, 0 }; //Masque de sous-réseau
*/

// Paramétrage du shield Ethernet sur Réseau lycée
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //Adresse MAC
byte ip[] = { 172, 17, 8, 20 }; // Adresse IP
byte DNS[] = { 172, 17, 1, 1 };  //DNS
byte gateway[] = { 172, 17, 0, 1 }; // Passerelle
byte subnet[] = { 255, 255, 0, 0 }; //Masque de sous-réseau
unsigned int PORT = 80;


//Sorties utilisées
int pinGACHE = A3;

//initialise le module Ethernet
EthernetServer server(PORT); // (port d'écoute 80 -> par défaut pour HTTP):

String readString = String(30); //Chaine reçu sur le module Ethernet
boolean bACCES = false; //flag : état de l'accès


//Variables de mesure niveau Batterie
float nivBATT = 0.0;
int N = 0;  //variable de CAN

String message = "";  // variable String pour affichage des messages par concaténation

LiquidCrystal lcd(46, 44, 42, 40, 38, 36);

//*********************************************
// SETUP
//*********************************************

void setup()
{
  Serial.begin(9600);
  lcd.begin(16, 2);

  pinMode(pinGACHE, OUTPUT);
  digitalWrite(pinGACHE, LOW);

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, DNS, gateway, subnet);// Lancement du serveur
  server.begin();

  Serial.print("Port : ");
  Serial.println(PORT);
  Serial.print("localIP: ");
  Serial.println(Ethernet.localIP());
  Serial.print("subnetMask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("gatewayIP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("dnsServerIP: ");
  Serial.println(Ethernet.dnsServerIP());
  Serial.println("SERVER READY : Wait Client...");
}

//*********************************************
// LOOP
//*********************************************

void loop()
{

  // listen for incoming clients
  EthernetClient client = server.available();

  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        readString = readString + c;

        // si le caractère \n est reçu alors on traite le message
        if (c == '\n') {
          Serial.println("Recu readstring:");
          Serial.println(readString);

          delay(100);
          
/*  *************  PARTIE 2 *********************************** */
          //------------ CONTROLE DE L'ACCES -------------
          //Test si "ACCES" est contenu dans la chaine de caractère reçue
          if (readString.indexOf("ACCES") > -1)
          {

            Serial.println("Recu ACCES"); //Debug
            //--------------
            //Test si "ON" est contenu dans la chaine de caractère reçue
            if (readString.indexOf("ON") > -1)
            {
              //Si OUI alors mettre à 1 la sortie pour RELAIS (ON)
              digitalWrite(pinGACHE, HIGH); // activation du Relais
              bACCES = true;
              Serial.println("ACCES = ON");
            } else
            {
              //Sinon mettre à 0 la sortie (OFF)
              digitalWrite(pinGACHE, LOW); // désactivation du Relais
              bACCES = false;
              Serial.println("ACCES = OFF");
            }
          }
          //---------------------------------------
/*  *********************************************************** */


          //------------- EMISSION PAGE HTML ---------------
          // émission de la réponse http - entête header
          client.println( "<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">");
          client.println("<html xmlns=""http://www.w3.org/1999/xhtml"">");
          client.println("<head>");
          client.println("<meta http-equiv=""Content-Type"" content=""text/html; charset=iso-8859-1"" />");

          client.println( "<meta http-equiv= ""Refresh"" content =""5"" /> ");
          client.println( "<meta http-equiv= ""Connection"" content =""close"" /> ");
          client.println("<title>STI2D Serveur Web</title>");
          client.println("</head>");

          //Affiche du début : tableau avec image liée au site JBV + Titre
          client.println("<body>");
          client.println("<table width=""707"" height=""95"" border=""0"">");
          client.println("<tr>");
          client.println("      <td width=""131""><p><img src=""https://www.sciener.my/wp-content/uploads/2019/11/A2-02-1.jpg"" width=""127"" height=""142"" /></p></td>");
          client.println("      <td width=""566"" align=""center"" valign=""middle""><font size='5'>Bienvenue sur le Serveur Web STI2D-SIN </font></td>");
          client.println("    </tr>");
          client.println("    <tr>");
          client.println("      <td align=""center""><em><font size='2'>contact : <a href=""mailto:pascal.euge@ac-nancy-metz.fr"">Pascal Eug&eacute;</em></td>");
          client.println("      <td align=""center"" valign=""middle""><font size='4' color='#FF6600'><strong><em>Lyc&eacute;e JB VUILLAUME - MIRECOURT </strong></em></font></td>");
          client.println("    </tr>");
          client.println("  </table>");
          client.println("<br /><hr />");//plusieurs espaces entre les lignes

/*  *************  PARTIE 2 *********************************** */
          //Control de l'accès par bouton
          client.println("<font color='red' size='2'><h1>Control de l'acc&egrave;s &agrave; distance : </h1></font>");
          client.println("<br />");//plusieurs espaces entre les lignes


          // ---------  Affiche commande des sorties en Fonction de l'état ON ou OFF -----------------------
          // Voici une bonne modification : permet d'envoyer les commandes par appui sur le bouton ON ou OFF ?ACCES=ON ou ?ACCES=OFF
          // Le bouton change suivant l'état des sorties, la commande change ainsi évitant un clignotement des sorties
          // car la commande HTTP reste figée dans la barre URL (ex : http://172.17.0.177/?ACCES=ON) :
          //ACCES = ON ->  Etat ACCES : |OFF| \ ON    sinon ACCES = OFF ->  Etat ACCES : OFF \ |ON|

          //Remarque :  la série de caractères "&nbsp;" permet d'ajouter des espaces sur la page Web afin d'aligner les commnandes
          if (bACCES) {
            client.print("<form method=get name=BOUTON1>ACCES : &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type=submit name=ACCES value=OFF><font color='red'> / ON </font></form>");
          }
          else {
            client.print("<form method=get name=BOUTON1>ACCES : &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OFF /  <input type=submit name=ACCES value=ON> </form>");
          }
          client.println("<font color='black'></font>");
          client.println("<br />");


          //Ici le code pour changer la couleur du texte dans l'interface web
          client.print("<font size='5'>Etats de l'actionneur : </font>");
          if (bACCES)
          {
            client.println("<font color='red' size='5'> ACC&Egrave;S AUTORIS&Eacute;</font>");
          }
          else
          {
            client.println("<font color='gray' size='4'> ACC&Egrave;S VERROUILL&Eacute;</font>");
          }

          client.println("</body></html><br />");
          client.println("<br /><hr />");//plusieurs espaces entre les lignes
          //--------------------------------
/*  ********************FIN PARTIE 2********************************* */

/*  ************* CODE PARTIE 3 *********************************** */
          // ----------- Mesure des CAPTEURS -> A0 (TEMP) ----------
          client.println("<font color='red' size='2'><h1>Information des CAPTEURS : </h1></font>");
          client.println("<br />");
          SurveillanceBatterie();

          // AFFICHAGE DU MESSAGE Niveau de Batterie SUR la PAGE WEB
          client.print("<font color='blue' size='5'>");
          client.print(" Niveau de Batterie : </font><font color='green' size='4'>");
          client.print(DoubleToString(double(nivBATT), 0));
          client.print(" % </font><br />");

          //Debogage
          message = " N : ";
          message.concat(N);
          message.concat(" nivBATT : ");
          message.concat(DoubleToString(double(nivBATT), 0));
          message.concat(" % ");
          Serial.println (message);
/*  *************  FIN PARTIE 3*********************************** */

          //---------------------------FIN TRANSMISSION-----------------------------------
          break;
        }       
      }
    }
    delay(1); //temporise
    readString = ""; // vide la chaine ReadString
    client.stop();  // ferme la connexion
    Serial.print("Port : ");
    Serial.println(PORT);
    Serial.print("localIP: ");
    Serial.println(Ethernet.localIP());
    Serial.println("SERVER READY : Wait Client...");
  }

/*  ************* CODE PARTIE 3 *********************************** */
  //OPTION : Mesure du niveau de batterie et affichage des infos LCD toutes les 2 sec (2000 ms) par TIMER
  ONLY_EVERY(2000, _ABVAR_1_Repeat)
    SurveillanceBatterie();
    AffichageLCD();
  END_ONLY_EVERY
/*  ************* FIN PARTIE 3 *********************************** */
}
