// Logiciel de gestion de portail électrique via une application smartphone via le web
// F6GSG 2023
// (20/05/23) Version 10c - en exploitaion avec wachdog de time out sur NO RX
// -----------------------------------------------------------------------------------------

#include <dummy.h>
#include "ESP8266WiFi.h"
#include "DHT.h" // Library capteur temperature

// HARDWARE
const int relayPin=13; //D7 RELAIS de Commande
const int sensorPin=14; //D5 data du capeur DHT11
const int posPin=16; //D0 Détecteur contact portail fermé
const int ledblue=2; //D4 La led bleue sur le module ESP8266 (témoin actitivé)

DHT dht(sensorPin,DHT11);

// RESEAU
const char* ssid = "***********"; // votre identifiant wifi
const char* password = "**********"; // mot de passe du wifi
IPAddress staticIP(192, 168, 0, 152); // IP en 152 en cohérence avec le plan des adresses de votre réseau (151-179 réservé domotique pour moi)
IPAddress gateway(192, 168, 0, 254);
IPAddress subnet(255, 255, 255, 0);
WiFiServer wifiServer(10052); // Start du serveur en port 10052

//VARIABLES
byte HUMIDITE;
byte TEMPERATURE;

unsigned long previousMillis = 0; // pour le time out perte de réseau wifi
unsigned long interval = 30000;

char RXwifi; // variables de réception de la chaine de commande
String dataRX = "";
String dataRX2 = "";

String nummod = "052"; // numéro du module suivant le protocole GS-NET
String nummas = "000"; // numéro du maitre suivant le protocole GS-NET (en général 000)

// SETUP
void setup() {
  pinMode(relayPin, OUTPUT); // définition des pins du module ESP8266
  pinMode(sensorPin,OUTPUT);
  pinMode(ledblue,OUTPUT);
  pinMode(posPin,INPUT_PULLUP);
  
  Serial.begin(115200); // le port série ne sert que pour le débug

  WiFi.config(staticIP, gateway, subnet); // configuration de la connexion wifi
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) { // Boucle attente de connexion wifi
    digitalWrite(ledblue, LOW); // led bleue clignote rapidement en RECHERCHE RESEAU
    delay(50);
    digitalWrite(ledblue, HIGH);
    delay(100);
  }
  wifiServer.begin(); // c'est OK, c'est parti en mode serveur
}

void loop() {

  // le void loop boucle sur l'attente d'un client qui se connecte au module (serveur) et si c'est OK se met en attente d'une chaine caractère de commande (GS-NET)
  WiFiClient client = wifiServer.available();
  digitalWrite(ledblue, LOW);
  delay(150);
  digitalWrite(ledblue, HIGH);
  delay(800);
  
  if (client) { // il y a un client qui se présente ....
    Serial.println("OK"+nummod+"CON"); // Si connexion réponse OK du module concerné sur le port série (debug)

    client.println("OK"+nummod+"CON"); // Si connexion réponse OK du module concerné sur le port wifi pour accueillir le client

    unsigned long wdstart_millis = millis(); // on démarre le time-out
    unsigned long wd_millis = wdstart_millis;
    
    dataRX = "";
    while (client.connected()) {
      dataRX = "";
      wd_millis = millis();
        if (wd_millis > wdstart_millis + 120000) { //test watchdog si pas de réeption de data pendant plus de 120 secondes on stop le client
            client.println("TIME OUT DECONNEXION");
            delay (1000);
            client.stop();
            digitalWrite(ledblue,HIGH); // led bleue OFF DECONNECTION
        }
        digitalWrite(ledblue, LOW);
      while (client.available() > 0) { // boucle de réception de la chaine de commande
        RXwifi = client.read(); // on reçoit caractère par caractère pour créer la chaine dataRX
        if (RXwifi != 13) { // si cara différent de 13 on cré la chaine
          dataRX = dataRX + RXwifi;
          dataRX2=dataRX;
        }
        if (RXwifi == 13) { // si réception du cara 13 (CR), la chaine est finie on part en analyse de la chaine

// TR199999 ------------------------------------------------ Mise en marche du relais pour 2 secondes (pas permanent)
          if (dataRX2 == ("ATX"+nummas+nummod+"TR199999")) {
            client.println("OK"+nummod+"TR199999"); // on répond au client qu'on a compris la commande
            digitalWrite(relayPin,HIGH); // relais ON avec une tempo de 2 secondes
            delay(2000);
            digitalWrite(relayPin,LOW);
        }
        // RC0 ------------------------------------------------ ENVOI ETAT de tous les capteurs (3 dans ce cas- POSITION / TEMPERATURE / HUMIODITE)
         if (dataRX2 == ("ATX"+nummas+nummod+"RC0")) {
          delay (1500);
          client.print("OK"+nummod+"RC0#"); // on répond au client qu'on a compris la commande avec en plus les informations demandées (état du portail)
          if(digitalRead(posPin) == LOW){ // mise ne forme de la réponse suiavnt l'état du contact ILS
            client.print("0;");
          }
          if(digitalRead(posPin) == HIGH) {
            client.print("1;");
          }
          
          dhtSensorReading();
          if (TEMPERATURE > 100) {
          TEMPERATURE = 99;
           }
          if (HUMIDITE > 100){
          HUMIDITE = 99;
           }
          
          if (TEMPERATURE < 100) {
            client.print("0");
          }
          if (TEMPERATURE < 10) {
            client.print("0");
          }
         client.print(TEMPERATURE);
         client.print(";");

          if (HUMIDITE < 100) {
            client.print("0");
          }
           if (HUMIDITE < 10) {
            client.print("0");
          }
          client.println(HUMIDITE);
        }
        //RST ------------------------------------------------- ENVOI STATE (Informations sur le module)
        if (dataRX2 == ("ATX"+nummas+nummod+"RST")) {
          client.print("NESTOR V10c - MOD: "+nummod+" WD: "+wd_millis+" - "+wdstart_millis);
        }
        // RC1 ------------------------------------------------ ENVOI ETAT du capteur N°1
        if (dataRX2 == ("ATX"+nummas+nummod+"RC1")) {
          client.print("OK"+nummod+"RC1#");
          if(digitalRead(posPin) == LOW) {
            client.print("0");
          }
          if(digitalRead(posPin) == HIGH) {
            client.print("1");
          }
        }
          dataRX = "";
          wdstart_millis = millis();
        }
      }
    } // gestion de reconnexion au wifi sur time-out

      unsigned long currentMillis = millis();
      currentMillis = millis();
      if ((WiFi.status() != WL_CONNECTED) && (currentMillis - previousMillis >=interval)) {
        Serial.print(millis());
        Serial.println("Reconnecting to WiFi...");
        digitalWrite(ledblue,HIGH); // led bleue OFF DECONNEXION
        WiFi.disconnect();
        WiFi.reconnect();
        previousMillis = currentMillis;
       }
        client.stop();
        digitalWrite(ledblue,HIGH); // led bleue OFF DECONNEXION
      
     }
else
    client.stop()
  }

void dhtSensorReading() {
  TEMPERATURE=dht.readTemperature();
  delay(1000);
  HUMIDITE=dht.readHumidity();
  }