//-------------------------------nacteni potrebnych knihoven-------------------------------------------
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_Sensor.h> 
#include <Adafruit_BME280.h>
#include <HTTPClient.h>
#include <ESPAsyncWebServer.h>
#include <EEPROM.h>
#include <OneButton.h>


//--------------------------------------definice konstnant-----------------------------------------------
#define EEPROM_SIZE 500 //inicializace EEPROM pameti o velikosti 500
#define BME280_ADRESA (0x76) //adresa zarizeni na I2C sbernici


//----------------------------------iniciaizace pinu----------------------------------------------------
#define SCL 22 //BME280 I2C pin GPIO22
#define SDA 21 //BME280 I2C pin GPIO21
#define LED_DATA 23 //led signalizujici odeslani dat do databaze
#define LED_ON 18 //led signalizujici napajeni zarizeni
#define LED_WIFI 19 //led signalizujici pripojeni k WiFi
#define LED_RESET 2 //led signalizujici resetovani konfigurace ESP32
#define BUTTON 17 //inicializace pinu pro tlacitko reset_button
#define DI1 4 //pin pro pripojeni vystupu z rele/ventil
#define DI2 16 //inicializace pinu GPIO16 (digital)
#define DI3 5 //inicializace pinu GPIO5 (digital)
#define DI4 25 //inicializace pinu GPIO25 (digital)
#define AI1 34 //inicializace pinu GPI34 (analog)
#define AI2 33 //inicializace pinu GPI33 (analog)


//----------------------------------inicializace potrebnych trid ke knihovnam----------------------------
TwoWire I2CBME = TwoWire(0);
Adafruit_BME280 bme; //promenna pro BME280 senzor
OneButton reset_button(BUTTON, true); //inicializace tlacitka reset


//-------------------------------nastaveni potrebnych promennych-----------------------------------------
unsigned variable = 0;

int lastButtonState = 0;
int buttonState = 0;

unsigned configuration = 0;
unsigned change_WIFI = 0;

float vlhkost = 0;
float teplota = 0;
float tlak = 0;

int CISLO_STROJE = 0;

int IP1 = 0;
int IP2 = 0;
int IP3 = 0;
int IP4 = 0;

int dns1 = 0;
int dns2 = 0;
int dns3 = 0;
int dns4 = 0;

int subnet1 = 0;
int subnet2 = 0;
int subnet3 = 0;
int subnet4 = 0;

int gateway1 = 0;
int gateway2 = 0;
int gateway3 = 0;
int gateway4 = 0;


//-----------------------------------udaje k prihlaseni k ESP32---------------------------------------
char *ssid_ESP32 = "ESP32";
char *password_ESP32 = "123456789";

//-------------------------------nastaveni WIFI ESP32-----------------------------------------------
IPAddress ip_ESP32(192, 168, 4, 200);
IPAddress gateway_ESP32(192, 168, 4, 1);
IPAddress subnet_ESP32(255, 255, 255, 0);


//---------------------------------inicializace sitovych adres----------------------------------------
IPAddress ip_WIFI(0, 0, 0, 0);
IPAddress dns_WIFI(0, 0, 0, 0);
IPAddress gateway_WIFI(0, 0, 0, 0);
IPAddress subnet_WIFI(0, 0, 0, 0);


//----------------------------------promenne do html kodu--------------------------------------------
const char* PARAM_INPUT_1 = "cislo_stroje"; //cislo stroje

const char* PARAM_INPUT_2 = "IP1"; //IP adresa
const char* PARAM_INPUT_3 = "IP2";
const char* PARAM_INPUT_4 = "IP3";
const char* PARAM_INPUT_5 = "IP4";

const char* PARAM_INPUT_8 = "dns1"; //dns 
const char* PARAM_INPUT_9 = "dns2";
const char* PARAM_INPUT_10 = "dns3";
const char* PARAM_INPUT_11 = "dns4";

const char* PARAM_INPUT_12 = "gateway1"; //gateway
const char* PARAM_INPUT_13 = "gateway2";
const char* PARAM_INPUT_14 = "gateway3";
const char* PARAM_INPUT_15 = "gateway4";

const char* PARAM_INPUT_16 = "subnet1"; //subnet
const char* PARAM_INPUT_17 = "subnet2";
const char* PARAM_INPUT_18 = "subnet3";
const char* PARAM_INPUT_19 = "subnet4";

const char* PARAM_INPUT_6 = "newssid_WIFI"; //nastaveni wifi
const char* PARAM_INPUT_7 = "newpassword_WIFI";

char* new_ssid_WIFI = "";
char* new_password_WIFI = "";

String ip_1 = "";
String ip_2 = "";
String ip_3 = "";
String ip_4 = "";

String subnet_1 = "";
String subnet_2 = "";
String subnet_3 = "";
String subnet_4 = "";

String dns_1 = "";
String dns_2 = "";
String dns_3 = "";
String dns_4 = "";

String gateway_1 = "";
String gateway_2 = "";
String gateway_3 = "";
String gateway_4 = "";


//---------------------------------------nastaveni portu serveru------------------------------------------------------
AsyncWebServer server(80);


//---------------------------------------inicializace vlaken---------------------------------------------------------
TaskHandle_t Task1, Task2, Task3; 


//-------------------------------vysledna HTML stranka serveru----------------------------------------------------------
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
  <title align=center>Konfigurace ESP32</title>
  <meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1">
  </head><body>
    <div align="center">
  <h1>Konfigurace ESP32</h1>
  <h2>Změna čísla zařízení </h2>
  <form action="/get">
    Číslo zařzení: <input type="text" name="cislo_stroje">
    <input type="submit" value="Submit">
  </form><br>
  <h2>Změna IP adresy</h2>
    <form action="/get">
        IP Address: <input type="text" name="IP1">
        . <input type="text" name="IP2">
        . <input type="text" name="IP3">
        . <input type="text" name="IP4">
    <input type="submit" value="Submit">
  </form><br>
    <h2>Změna DNS</h2>
    <form action="/get">
        DNS: <input type="text" name="dns1">
        . <input type="text" name="dns2">
        . <input type="text" name="dns3">
        . <input type="text" name="dns4">
    <input type="submit" value="Submit">
  </form><br>
    <h2>Změna masky sítě</h2>
    <form action="/get">
        Subnet Mask: <input type="text" name="subnet1">
        . <input type="text" name="subnet2">
        . <input type="text" name="subnet3">
        . <input type="text" name="subnet4">
    <input type="submit" value="Submit">
  </form><br>
    <h2>Změna IP adresy brány</h2>
  <form action="/get">
      Gateway: <input type="text" name="gateway1">
      . <input type="text" name="gateway2">
      . <input type="text" name="gateway3">
      . <input type="text" name="gateway4">
   <input type="submit" value="Submit">
  </form><br>
  <h2>Nastavení WIFI</h2>
    <form action="/get">
        Název WIFI: <input type="text" name="newssid_WIFI">
        Heslo: <input type="text" name="newpassword_WIFI">
    <input type="submit" value="Submit">
  </form><br>
  <h3>------------------------------------------------------------- Poznámky -------------------------------------------------------------</h3><br>
  <h4>Nejprve postupně nastavte jednotlivé síťové adresy (potvrzujte tlačítkem 'Submit').</h4><br>
  <h4>Vyplňte Nastavení WIFI (Název WIFI a Heslo) a potvrďte tlačítkem 'Submit'.</h4><br>
  <h4>Potvrzením tlačítka 'Submit' u Nastavení WIFI a následného stisknutí tlačítka reset (EN)<br>na modulu ESP32 dojde k přenastavení režimu ESP32 do režimu 1, tedy do pracovního režimu.</h4><br>
  <h4>Nyní je vaše zařízení připraveno k provozu.</h4><br>
  </div>
</body></html>)rawliteral";



//-------------------------------------------------funkce pro zobrazeni stranka nenaezena---------------------------------------------
void notFound(AsyncWebServerRequest *request) 
{
  request->send(404, "text/plain", "Not found");
}


//------------------------------------------funkce po dlouhem (cca 3s) stisknuti tlacitka reset_button--------------------------------
void reset_function()
{
  variable = 0;
  EEPROM.put(0, variable);
  EEPROM.commit();
  digitalWrite(LED_WIFI, HIGH);
  delay(500);
  digitalWrite(LED_WIFI, LOW);
  delay(500);
  digitalWrite(LED_WIFI, HIGH);
  delay(500);
  digitalWrite(LED_WIFI, LOW);
}


//---------------------------------------------funkce nahrani (UPDATE) promenne typu string do EEPROM pameti-----------------------------
void StringToEEPROM_UPDATE(int addressOffset, const String &StringToWrite)
{
  int delka = StringToWrite.length();
  EEPROM.put(addressOffset, delka);
  EEPROM.commit();

  for(int i = 0; i<delka; i++)
  {
    EEPROM.put(addressOffset + 1 + i, StringToWrite[i]);
    EEPROM.commit();
  }
}


//------------------------------------------funkce nahrani (WRITE) promenne typu string do EEPROM pameti---------------------------------
void StringToEEPROM_WRITE(int addressOffset, const String &StringToWrite)
{
  int delka = StringToWrite.length();
  EEPROM.write(addressOffset, delka);
  EEPROM.commit();

  for(int i = 0; i<delka; i++)
  {
    EEPROM.write(addressOffset + 1 + i, StringToWrite[i]);
    EEPROM.commit();
  }
}


//-------------------------------------    funkce pro cteni promenne typu string z EEPROM pameti--------------------------------------------
String readStringFromEEPROM(int addressOffset)
{
  int newStrLen = EEPROM.read(addressOffset);
  char data[newStrLen+1];
  for (int i = 0; i < newStrLen; i++)
  {
    data[i] = EEPROM.read(addressOffset + 1 + i);
  }
  data[newStrLen] = '\0';
  return String(data);
}


//--------------------------------------setup funkce------------------------------------------------------------------
void setup() 
{
  Serial.begin(115200);
  digitalWrite(LED_ON, HIGH);
  I2CBME.begin(SDA, SCL, 100000);
  //--------------------------------------inicializace jednotlivych pinu na desce ESP32---------------------------------
  pinMode(DI1, INPUT_PULLUP); 
  pinMode(DI2, INPUT_PULLUP);
  pinMode(DI3, INPUT_PULLUP);
  pinMode(DI4, INPUT);
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(AI1, INPUT);
  pinMode(AI2, INPUT);
  pinMode(LED_DATA, OUTPUT);
  pinMode(LED_ON, OUTPUT);
  pinMode(LED_WIFI, OUTPUT);
  pinMode(LED_RESET, OUTPUT);
  
  //------------------------------------------nastaveni EEPROM pameti-------------------------------------------------------
  EEPROM.begin(EEPROM_SIZE); 

  //----------------------------------pocatecni nastaveni sitovych adres pro nove WIFI pripojeni-----------------------------
  if(EEPROM.read(0) != 1)
  {
  EEPROM.write(5, CISLO_STROJE);
  
  EEPROM.write(10, ip_WIFI[0]);
  EEPROM.write(11, ip_WIFI[1]);
  EEPROM.write(12, ip_WIFI[2]);
  EEPROM.write(13, ip_WIFI[3]);
  
  EEPROM.write(20, dns_WIFI[0]);
  EEPROM.write(21, dns_WIFI[1]);
  EEPROM.write(22, dns_WIFI[2]);
  EEPROM.write(23, dns_WIFI[3]);
  
  EEPROM.write(30, gateway_WIFI[0]);
  EEPROM.write(31, gateway_WIFI[1]);
  EEPROM.write(32, gateway_WIFI[2]);
  EEPROM.write(33, gateway_WIFI[3]);
  
  EEPROM.write(40, subnet_WIFI[0]);
  EEPROM.write(41, subnet_WIFI[1]);
  EEPROM.write(42, subnet_WIFI[2]);
  EEPROM.write(43, subnet_WIFI[3]);

  StringToEEPROM_WRITE(100, new_ssid_WIFI);
  StringToEEPROM_WRITE(200, new_password_WIFI);
  
  EEPROM.write(0, variable);
  EEPROM.commit();
  }

  //-------------------------------------------------spusteni a nastaveni ESP32 WIFI--------------------------------
  if(EEPROM.read(0) == 0)
  {
  WiFi.softAP(ssid_ESP32, password_ESP32);
  WiFi.softAPConfig (ip_ESP32, gateway_ESP32, subnet_ESP32);
  Serial.println(WiFi.softAPIP());
  }

  //--------------------------------------------spusteni a nastaveni noveho WIFI pripojeni---------------------------
  if((EEPROM.read(0)) == 1)
  {
   EEPROM.get(10, ip_WIFI[0]);
   EEPROM.get(11, ip_WIFI[1]);
   EEPROM.get(12, ip_WIFI[2]);
   EEPROM.get(13, ip_WIFI[3]);
   
   EEPROM.get(20, dns_WIFI[0]);
   EEPROM.get(21, dns_WIFI[1]);
   EEPROM.get(22, dns_WIFI[2]);
   EEPROM.get(23, dns_WIFI[3]);
   
   EEPROM.get(30, gateway_WIFI[0]);
   EEPROM.get(31, gateway_WIFI[1]);
   EEPROM.get(32, gateway_WIFI[2]);
   EEPROM.get(33, gateway_WIFI[3]);
   
   EEPROM.get(40, subnet_WIFI[0]);
   EEPROM.get(41, subnet_WIFI[1]);
   EEPROM.get(42, subnet_WIFI[2]);
   EEPROM.get(43, subnet_WIFI[3]);

   unsigned var = 0;
   
   unsigned int ssid_length = (readStringFromEEPROM(100).length()+1);
   unsigned int password_length = (readStringFromEEPROM(200).length()+1);

   char ssid[ssid_length];
   char password[password_length];
   
   String string_password = readStringFromEEPROM(200);
   String string_ssid = readStringFromEEPROM(100);
   
   string_password.toCharArray(password, password_length);
   string_ssid.toCharArray(ssid, ssid_length);

   WiFi.config(ip_WIFI, gateway_WIFI, subnet_WIFI, dns_WIFI);
   WiFi.begin(ssid, password);
   
   while (WiFi.status() != WL_CONNECTED) 
    { 
      if(var == 10)
      {
        break;
      }
    digitalWrite(LED_WIFI,LOW);
    delay(1000);
    var = var + 1;
    Serial.println("Connecting to WiFi...");
    }
    if(var == 10)
    {
      Serial.println("No connection to the WiFi network");
      variable = 0;
      digitalWrite(LED_WIFI, LOW);
      EEPROM.put(0, variable);
      EEPROM.commit();
    }
    else
    {
    Serial.println("Connected to the WiFi network");
    Serial.print("IP Adresa: ");
    Serial.println(WiFi.localIP());
    digitalWrite(LED_WIFI, HIGH);
    }
    
   }
   

  //---------------------------------------------------------------- zaslani webove stranky se vstupnimi parametry ----------------------------------------------------------------
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });

  //----------------------------------------------------------------  zaslani webove stranky s parametry a GET funkci -----------------------------------------
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) 
  {
    String inputMessage;

    //-----------------------------------------------------parametr CISLO_STROJE---------------------------
    if (request->hasParam(PARAM_INPUT_1)) 
    {
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      CISLO_STROJE = inputMessage.toInt();
      EEPROM.put(5, CISLO_STROJE);
      EEPROM.commit();
      request->send(200, "text/html", "Uspesna zmena cisla zarizeni: " + String(CISLO_STROJE) + "<br><a href=\"/\">Return to Home Page</a>");
    }

    //----------------------------------------------------parametr IP adresy------------------------------
    
      else if((request->hasParam(PARAM_INPUT_2))&&(request->hasParam(PARAM_INPUT_3))&&(request->hasParam(PARAM_INPUT_4))&&(request->hasParam(PARAM_INPUT_5)))
      {
      ip_1 = request->getParam(PARAM_INPUT_2)->value();
      IP1 = ip_1.toInt();
      ip_2 = request->getParam(PARAM_INPUT_3)->value();
      IP2 = ip_2.toInt();
      ip_3 = request->getParam(PARAM_INPUT_4)->value();
      IP3 = ip_3.toInt();
      ip_4 = request->getParam(PARAM_INPUT_5)->value();
      IP4 = ip_4.toInt();
      ip_WIFI[0] = IP1;
      ip_WIFI[1] = IP2;
      ip_WIFI[2] = IP3;
      ip_WIFI[3] = IP4;
      EEPROM.put(10, ip_WIFI[0]);
      EEPROM.commit();
      EEPROM.put(11, ip_WIFI[1]);
      EEPROM.commit();
      EEPROM.put(12, ip_WIFI[2]);
      EEPROM.commit();
      EEPROM.put(13, ip_WIFI[3]);
      EEPROM.commit();
       request->send(200, "text/html", "Uspesna zmena IP adresy: " + String(IP1) + "." + String(IP2) +"." + String(IP3) + "." + String(IP4) + "<br><a href=\"/\">Return to Home Page</a>");
       configuration = 1;
       delay(1000);
       configuration = 0;
      }

      //-------------------------------------------------parametr DNS----------------------------
      
      else if((request->hasParam(PARAM_INPUT_8))&&(request->hasParam(PARAM_INPUT_9))&&(request->hasParam(PARAM_INPUT_10))&&(request->hasParam(PARAM_INPUT_11)))
      {
      dns_1 = request->getParam(PARAM_INPUT_8)->value();
      dns1 = dns_1.toInt();
      dns_2 = request->getParam(PARAM_INPUT_9)->value();
      dns2 = dns_2.toInt();
      dns_3 = request->getParam(PARAM_INPUT_10)->value();
      dns3 = dns_3.toInt();
      dns_4 = request->getParam(PARAM_INPUT_11)->value();
      dns4 = dns_4.toInt();
      dns_WIFI[0] = dns1;
      dns_WIFI[1] = dns2;
      dns_WIFI[2] = dns3;
      dns_WIFI[3] = dns4;
      EEPROM.put(20, dns_WIFI[0]);
      EEPROM.commit();
      EEPROM.put(21, dns_WIFI[1]);
      EEPROM.commit();
      EEPROM.put(22, dns_WIFI[2]);
      EEPROM.commit();
      EEPROM.put(23, dns_WIFI[3]);
      EEPROM.commit();
       request->send(200, "text/html", "Uspesna zmena DNS: " + String(dns1) + "." + String(dns2) +"." + String(dns3) + "." + String(dns4) + "<br><a href=\"/\">Return to Home Page</a>");
       configuration = 1;
       delay(1000);
       configuration = 0;
      }

      //---------------------------------------------parametr gateway---------------------------
      
      else if((request->hasParam(PARAM_INPUT_12))&&(request->hasParam(PARAM_INPUT_13))&&(request->hasParam(PARAM_INPUT_14))&&(request->hasParam(PARAM_INPUT_15)))
      {
      gateway_1 = request->getParam(PARAM_INPUT_12)->value();
      gateway1 = gateway_1.toInt();
      gateway_2 = request->getParam(PARAM_INPUT_13)->value();
      gateway2 = gateway_2.toInt();
      gateway_3 = request->getParam(PARAM_INPUT_14)->value();
      gateway3 = gateway_3.toInt();
      gateway_4 = request->getParam(PARAM_INPUT_15)->value();
      gateway4 = gateway_4.toInt();
      gateway_WIFI[0] = gateway1;
      gateway_WIFI[1] = gateway2;
      gateway_WIFI[2] = gateway3;
      gateway_WIFI[3] = gateway4;
      EEPROM.put(30, gateway_WIFI[0]);
      EEPROM.commit();
      EEPROM.put(31, gateway_WIFI[1]);
      EEPROM.commit();
      EEPROM.put(32, gateway_WIFI[2]);
      EEPROM.commit();
      EEPROM.put(33, gateway_WIFI[3]);
      EEPROM.commit();
       request->send(200, "text/html", "Uspesna zmena IP adresy brany (GATEWAY): " + String(gateway1) + "." + String(gateway2) +"." + String(gateway3) + "." + String(gateway4) + "<br><a href=\"/\">Return to Home Page</a>");
       configuration = 1;
       delay(1000);
       configuration = 0;
      }

      //----------------------------------------------------parametr subnet mask---------------------------
      
      else if((request->hasParam(PARAM_INPUT_16))&&(request->hasParam(PARAM_INPUT_17))&&(request->hasParam(PARAM_INPUT_18))&&(request->hasParam(PARAM_INPUT_19)))
      {
      subnet_1 = request->getParam(PARAM_INPUT_16)->value();
      subnet1 = subnet_1.toInt();
      subnet_2 = request->getParam(PARAM_INPUT_17)->value();
      subnet2 = subnet_2.toInt();
      subnet_3 = request->getParam(PARAM_INPUT_18)->value();
      subnet3 = subnet_3.toInt();
      subnet_4 = request->getParam(PARAM_INPUT_19)->value();
      subnet4 = subnet_4.toInt();
      subnet_WIFI[0] = subnet1;
      subnet_WIFI[1] = subnet2;
      subnet_WIFI[2] = subnet3;
      subnet_WIFI[3] = subnet4;
      EEPROM.put(40, subnet_WIFI[0]);
      EEPROM.commit();
      EEPROM.put(41, subnet_WIFI[1]);
      EEPROM.commit();
      EEPROM.put(42, subnet_WIFI[2]);
      EEPROM.commit();
      EEPROM.put(43, subnet_WIFI[3]);
      EEPROM.commit();
       request->send(200, "text/html", "Uspesna zmena masky site SubnetMask: " + String(subnet1) + "." + String(subnet2) +"." + String(subnet3) + "." + String(subnet4) + "<br><a href=\"/\">Return to Home Page</a>");
       configuration = 1;
       delay(1000);
       configuration = 0;
      }

      //--------------------------------------------------------parametry nastaveni WIFI----------------------
      else if((request->hasParam(PARAM_INPUT_6))&&(request->hasParam(PARAM_INPUT_7)))
      {
        String new_ssid1_WIFI = request->getParam(PARAM_INPUT_6)->value();
        String new_password1_WIFI = request->getParam(PARAM_INPUT_7)->value();

        StringToEEPROM_UPDATE(100, new_ssid1_WIFI);
        StringToEEPROM_UPDATE(200, new_password1_WIFI);
        
        variable = 1;
        EEPROM.put(0, variable);
        EEPROM.commit();
        request->send(200, "text/html", "Uspesne nastaveni WIFI site! <br> NAZEV WIFI: "+new_ssid1_WIFI+ "<br> HESLO: " +new_password1_WIFI+" <br><a href=\"/\">Return to Home Page</a>");
      }
      
      //-------------------------------------------------------nedoslo k odeslani zadost GET--------------------
      
    else {
      request->send(200, "text/html", "Nedoslo k odeslani zpravy! <br><a href=\"/\">Return to Home Page</a>");
    }  
    //--------------------------------------------------------konec GET funkce-------------------------------------------------------------------------------------------------------------                           
  });  
  //---------------------------------------------------------konec formulare---------------------------------------------------------------------------------------------------------------------------------
   
  server.onNotFound(notFound);
  server.begin(); 

  //------------------------------------------------inicializace dlouheho stisknuti tlacitka reset_button---------------------
  reset_button.attachLongPressStop(reset_function);

  //-------------------------------------------------------inicializace a nastaveni vlaken----------------------------
 xTaskCreatePinnedToCore( //vlakno pro snimani stavu STOP
    loop_STOP,
    "LIS_STOP", //string pro jmeno vlakna
    10000, //velikost zasobniku
    NULL, //task handle
    1, //priorita
    &Task1, //task, kde bezi program
    1); //jadro, na kterem bezi program

 delay(500);  // start-up 

 xTaskCreatePinnedToCore( //vlakno pro snimani stavu RUN
    loop_RUN, 
    "LIS_RUN", //string pro jmeno vlakna
    10000, //velikost zasobniku
    NULL, //task handle
    1, //priorita
    &Task2, //task, kde bezi program
    0); //jadro, na kterem bezi program

   delay(500);  // start-up 

 xTaskCreatePinnedToCore( //vlakno pro zmenu IP adresy
    IP_config, 
    "IP_config", //string pro jmeno vlakna
    10000, //velikost zasobniku
    NULL, //task handle
    1, //priorita
    &Task3, //task, kde bezi program
    0); //jadro, na kterem bezi program
    //------------------------------------------------------konec inicializace vlaken--------------------------------
}



//-----------------------------------------vlakno pro nastavovani novych sitovych adres-----------------
void IP_config( void * parameter)
{
  for(;;)
  {
   delay(1);
   reset_button.tick();
   
   if((EEPROM.read(0) == 1) && (configuration == 1))
   {  
   EEPROM.get(10, ip_WIFI[0]);
   EEPROM.get(11, ip_WIFI[1]);
   EEPROM.get(12, ip_WIFI[2]);
   EEPROM.get(13, ip_WIFI[3]);
   
   EEPROM.get(20, dns_WIFI[0]);
   EEPROM.get(21, dns_WIFI[1]);
   EEPROM.get(22, dns_WIFI[2]);
   EEPROM.get(23, dns_WIFI[3]);
   
   EEPROM.get(30, gateway_WIFI[0]);
   EEPROM.get(31, gateway_WIFI[1]);
   EEPROM.get(32, gateway_WIFI[2]);
   EEPROM.get(33, gateway_WIFI[3]);
   
   EEPROM.get(40, subnet_WIFI[0]);
   EEPROM.get(41, subnet_WIFI[1]);
   EEPROM.get(42, subnet_WIFI[2]);
   EEPROM.get(43, subnet_WIFI[3]);

   WiFi.config(ip_WIFI, gateway_WIFI, subnet_WIFI, dns_WIFI);
   }
  }
}



//-------------------------------------------------vlakno pro odesilani STOP stavu do databaze----------------------------------
void loop_STOP( void * parameter )
{
  for (;;) 
  {
 delay(55000); 
 if ((WiFi.status() == WL_CONNECTED)) 
  {
   HTTPClient http_STOP;

   http_STOP.begin("http://192.168.80.202/lisovna/ESP_savedata.aspx?id_op=1&id_str=" +String(EEPROM.read(5))+ "&takt=0");//url adresa pro zapsani stavu stop do databaze
                                                                                                                      // id_op - identifikátor operace, id_str - identifikátor stroje, takt (0 nebo 1)
   int httpCode_STOP = http_STOP.GET(); //nacteni odpovedi ze serveru
 
   if (httpCode_STOP > 0) //kontrola zapsani dat
   { 
      Serial.println("Upload STOP!");
      digitalWrite(LED_DATA, HIGH);
      delay(100);
      digitalWrite(LED_DATA, LOW);
      delay(100);
      digitalWrite(LED_DATA, HIGH);
      delay(100);
      digitalWrite(LED_DATA, LOW);
    }
    else 
    {
      Serial.println("Error on HTTP_STOP request"); //nedoslo k zapsani dat
    }
    http_STOP.end(); //uvolneni http klienta
    }
  }
}



//-------------------------------------------------------------vlakno pro kontrolu a zapsani stavu RUN do databaze-------------------------------
void loop_RUN( void * parameter )
{
  for (;;) 
  {
  if ((WiFi.status() == WL_CONNECTED)) 
   {
    buttonState = digitalRead(DI2);
    if (buttonState != lastButtonState)
    {
      delay(1);
    if((digitalRead(DI2) == LOW)) //doslo k taktu
    {
   HTTPClient http_RUN; //vytvoreni klienta pro odeslani dat RUN
   Serial.println(EEPROM.read(5));
   http_RUN.begin("http://192.168.80.202/lisovna/ESP_savedata.aspx?id_op=1&id_str=" +String(EEPROM.read(5))+ "&takt=1");//url adresa pro zapsani stavu run do databaze
   
   int httpCode_RUN = http_RUN.GET(); //nacteni odpovedi ze serveru 
 
   if (httpCode_RUN > 0) //kontrola zapsani dat
   {
        Serial.println("Upload RUN!");
        digitalWrite(LED_DATA, HIGH);
        delay(100);
        digitalWrite(LED_DATA, LOW);
        delay(100);
        digitalWrite(LED_DATA, HIGH);
        delay(100);
        digitalWrite(LED_DATA, LOW);           
       }
   else 
   {
   Serial.println("Error on HTTP RUN request"); //nedoslo k zapsani dat
   Serial.println(httpCode_RUN);
   }
   http_RUN.end(); //uvolneni http klienta 
   }
  }
  lastButtonState = buttonState;
 }
 delay(1);
 }
}



//--------------------------------------------loop smycka (vlakno) pro cteni dat ze senzoru BME280 a odeslani dat do databaze-----------------------------------------
void loop() 
{ 
 bool status = bme.begin(0x76, &I2CBME); //pripojeni ke sbernici I2C

//-----------------------------nedoslo ke spojeni BME280 ke sbernici I2C--------------------------
 if (!status) 
 {
   Serial.println("Could not find a valid BME280 sensor, check wiring!");
   if ((WiFi.status() == WL_CONNECTED)) 
    {
    HTTPClient http_BME280_ERROR; //vytvoreni klienta pro odeslani ERROR stavu do databaze
 
    http_BME280_ERROR.begin("http://192.168.80.202/lisovna/ESP_savedata.aspx?id_op=2&id_str=" +String(EEPROM.read(5))+ "ip_addr=" +String(ip_WIFI[3])+ "&tepl=0&vlh=0&tlak=0&ip_addr=");
    //url adresa pro zapsani stavu ERROR do databaze
    // id_op - identifikátor operace, id_str - identifikátor stroje, odesílaná data (teplota, vlhkost, tlak), koncovka IP adresy
    
    int httpCode_BME280_ERROR = http_BME280_ERROR.GET(); //nacteni odpovedi ze serveru
 
    if (httpCode_BME280_ERROR > 0) //kontrola zapsani data 
    { 
      Serial.println("Upload BME280 ERROR!");
      digitalWrite(LED_DATA, HIGH);
      delay(100);
      digitalWrite(LED_DATA, LOW);
      delay(100);
      digitalWrite(LED_DATA, HIGH);
      delay(100);
      digitalWrite(LED_DATA, LOW);
    }
   else 
   {
     Serial.println("Error on HTTP_RUN request"); //nedoslo k zapsani dat
   }
   http_BME280_ERROR.end(); //uvolneni http klienta 
   }
   delay(3600000);
 }

 //--------------------------doslo ke spojeni BME280 ke sbernici I2C---------------------------
 else
 {
  Serial.println("BME280 connected!");
  
    vlhkost = bme.readHumidity(); //nacteni vlhkosti
    teplota = bme.readTemperature(); //nacteni teploty
    tlak = (bme.readPressure()/100.0F); //nacteni tlaku 
    
    if ((WiFi.status() == WL_CONNECTED)) 
    {
    HTTPClient http_BME280; //vytvoreni klienta pro odeslani dat ze sensoru
    
    http_BME280.begin("http://192.168.80.202/lisovna/ESP_savedata.aspx?id_op=2&id_str=" +String(EEPROM.read(5))+ "&ip_addr=" +String(ip_WIFI[3])+ "&tepl=" +String(teplota)+ "&vlh=" +String(vlhkost)+ "&tlak=" +String(tlak)+ "");
    // url adresa pro zapsani hodnot ze senzoru do databaze 
    // id_op - identifikátor operace, id_str - identifikátor stroje, odesílaná data (teplota, vlhkost, tlak), koncovka IP adresy
    
    int httpCode_BME280 = http_BME280.GET(); //nacteni odpovedi ze serveru
 
    if (httpCode_BME280 > 0) //kontrola zapsani data 
    { 
      Serial.println("Upload BME280!");
      digitalWrite(LED_DATA, HIGH);
      delay(100);
      digitalWrite(LED_DATA, LOW);
      delay(100);
      digitalWrite(LED_DATA, HIGH);
      delay(100);
      digitalWrite(LED_DATA, LOW);
    }
   else 
   {
     Serial.println("Error on HTTP_RUN request"); //nedoslo k zapsani dat
   }
   http_BME280.end(); //uvolneni http klienta 
   }
   delay(3600000); 
 }
}
 
