#include <Arduino.h>
#include <WiFi.h>
#include <ThingerESP32.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Mailer.h>
#include <preferences.h>
#include <driver/adc.h>

OneWire oneWire(27);
DallasTemperature sensors(&oneWire);
Preferences preferences;
WiFiClient client;

#define BUTTON_PIN_BITMASK 0xC00000000 // pro piny 34,35


//RTC proměnné
RTC_DATA_ATTR int bootCount = 0;
RTC_DATA_ATTR uint64_t time_in_us = 300000000;  //5 min default nastaveni
RTC_DATA_ATTR double zaznamNapeti[10];
RTC_DATA_ATTR double prumNapeti;
RTC_DATA_ATTR float teplota;
RTC_DATA_ATTR uint64_t lastBatteryReport=0;
RTC_DATA_ATTR boolean Fill = true;
RTC_DATA_ATTR int smtp_port;

//globalni proměnné - naplněny z Flash paměti
char menuheslo[100];
char hostname[100];
char ssid[100];
char password[100];
float limitniNapeti;
boolean pin34;
boolean pin35;

char smtp_username[100];       //email
char smtp_password[100];
char smtp_from_address[100];
char smtp_hostname[100];
char to_address[100];

Mailer mail(smtp_username, smtp_password, smtp_from_address, smtp_port, smtp_hostname);


char writeAPIKey[100];                                            //Thingspeak
const char* server = "api.thingspeak.com";                        //Thingspeak

char USERNAME[100];                                             //thingerio
char DEVICE_ID[100];                                            //thingerio
char DEVICE_CREDENTIAL[100];                                    //thingerio
ThingerESP32 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);     //thingerio

char variable_id1[100];    //ubidots
char variable_id2[100];    //ubidots
char variable_id3[100];    //ubidots
char variable_id4[100];    //ubidots
char tokenUbidots[100];    //ubidots




void LoadPreferencesVariables(){
preferences.getBytes("ssid", ssid, 100);
preferences.getBytes("password", password, 100);
preferences.getBytes("hostname", hostname, 100);
preferences.getBytes("menuheslo", menuheslo, 100);
limitniNapeti = preferences.getFloat("limitniNapeti", 2.9);
preferences.getBytes("smtp_username", smtp_username, 100);
preferences.getBytes("smtp_password", smtp_password, 100);
preferences.getBytes("smtp_from_add", smtp_from_address, 100);
preferences.getBytes("smtp_hostname", smtp_hostname, 100);
preferences.getBytes("to_address", to_address, 100);
preferences.getBytes("writeAPIKey", writeAPIKey, 100);
preferences.getBytes("USERNAME",USERNAME,100);
preferences.getBytes("DEVICE_ID",DEVICE_ID,100);
preferences.getBytes("DEV-CREDENTIAL",DEVICE_CREDENTIAL,100);
preferences.getBytes("tokenUbidots", tokenUbidots, 100);
preferences.getBytes("variable_id1", variable_id1, 100);
preferences.getBytes("variable_id2", variable_id2, 100);
preferences.getBytes("variable_id3", variable_id3, 100);
preferences.getBytes("variable_id4", variable_id4, 100);
}


void SaveChangedPreferencesVariables(){
char pomocny[100];
preferences.getBytes("ssid", pomocny, 100);
if(strcmp(pomocny,ssid) != 0){preferences.putBytes("ssid", ssid, 100);}

preferences.getBytes("password", pomocny, 100);
if(strcmp(pomocny,password) != 0){preferences.putBytes("password", password, 100);}

preferences.getBytes("hostname", pomocny, 100);
if(strcmp(pomocny,hostname) != 0){preferences.putBytes("hostname", hostname, 100);}

preferences.getBytes("menuheslo", pomocny, 100);
if(strcmp(pomocny,menuheslo) != 0){preferences.putBytes("menuheslo", menuheslo, 100);}

if(limitniNapeti != preferences.getFloat("limitniNapeti", 2.9)){Serial.println("pip0");
preferences.putFloat("limitniNapeti", limitniNapeti);}

preferences.getBytes("smtp_username", pomocny, 100);
if(strcmp(pomocny,smtp_username) != 0){preferences.putBytes("smtp_username", smtp_username, 100);}

preferences.getBytes("smtp_password", pomocny, 100);
if(strcmp(pomocny,smtp_password) != 0){preferences.putBytes("smtp_password", smtp_password, 100);}

preferences.getBytes("smtp_from_add", pomocny, 100);
if(strcmp(pomocny,smtp_from_address) != 0){preferences.putBytes("smtp_from_add", smtp_from_address, 100);}

preferences.getBytes("smtp_hostname", pomocny, 100);
if(strcmp(pomocny,smtp_hostname) != 0){preferences.putBytes("smtp_hostname", smtp_hostname, 100);}

preferences.getBytes("to_address", pomocny, 100);
if(strcmp(pomocny,to_address) != 0){preferences.putBytes("to_address", to_address, 100);}


preferences.getBytes("writeAPIKey", pomocny, 100);
if(strcmp(pomocny,writeAPIKey) != 0){preferences.putBytes("writeAPIKey", writeAPIKey, 100);}

preferences.getBytes("USERNAME", pomocny, 100);
if(strcmp(pomocny,USERNAME) != 0){preferences.putBytes("USERNAME",USERNAME,100);}

preferences.getBytes("DEVICE_ID", pomocny, 100);
if(strcmp(pomocny,DEVICE_ID) != 0){preferences.putBytes("DEVICE_ID",DEVICE_ID,100);}

preferences.getBytes("DEV-CREDENTIAL", pomocny, 100);
if(strcmp(pomocny,DEVICE_CREDENTIAL) != 0){preferences.putBytes("DEV-CREDENTIAL",DEVICE_CREDENTIAL,100);}

preferences.getBytes("tokenUbidots", pomocny, 100);
if(strcmp(pomocny,tokenUbidots) != 0){preferences.putBytes("tokenUbidots",tokenUbidots,100);}

preferences.getBytes("variable_id1", pomocny, 100);
if(strcmp(pomocny,variable_id1) != 0){preferences.putBytes("variable_id1",variable_id1,100);}

preferences.getBytes("variable_id2", pomocny, 100);
if(strcmp(pomocny,variable_id2) != 0){preferences.putBytes("variable_id2",variable_id2,100);}

preferences.getBytes("variable_id3", pomocny, 100);
if(strcmp(pomocny,variable_id3) != 0){preferences.putBytes("variable_id3",variable_id3,100);}

preferences.getBytes("variable_id4", pomocny, 100);
if(strcmp(pomocny,variable_id4) != 0){preferences.putBytes("variable_id4",variable_id4,100);}


}


void zapisDoThingSpeaku(String body){
  if (client.connect(server, 80)) {
      client.print("POST /update HTTP/1.1\n");
      client.print("Host: api.thingspeak.com\n");
      client.print("Connection: close\n");
      client.print("X-THINGSPEAKAPIKEY: " + String(writeAPIKey) + "\n");
      client.print("Content-Type: application/x-www-form-urlencoded\n");
      client.print("Content-Length: ");
      client.print(body.length());
      client.print("\n\n");
      client.print(body);
      client.print("\n\n");
    }
    Serial.println("Posilam data na thingspeak");

    client.stop();
};


void zapisDoUbidots(String variable_id, String value, String context)
{
  String var = "{\"value\": " + value +",\"context\": {\"popis\": \""+context+"\"}"+ "}";
  String length = String(var.length());
  if (client.connect("things.ubidots.com", 80))
      {client.println("POST /api/v1.6/variables/"+variable_id+"/values HTTP/1.1");
      client.println("Content-Type: application/json");
      client.println("Content-Length: "+ length);
      client.println("X-Auth-Token: "+ String(tokenUbidots));
      client.println("Host: things.ubidots.com\n");
      client.print(var);
      }

  client.stop();
}



boolean pripojenikWifi(){
     Serial.println();
     Serial.println("Pripojuji k Wifi");
     WiFi.begin(ssid, password);
     WiFi.setHostname(hostname);
     int i = 0;
     int j = 0;
     int k = 1;
     while (WiFi.status() != WL_CONNECTED)
          {
            i++;
            delay(1);
            //delay(250);

            if((i/k)>250){Serial.println("Cekani na lokalni sit - " + String(k));k++;}
             if(i>2500){ i=0;k=1;  j++;
                          if(j==2){break;}
                          Serial.println("Nový pokus o připojení.");
                          WiFi.begin(ssid, password);

                        }

          }
    if(WiFi.status() == WL_CONNECTED){
return true;
 }

 else{
   digitalWrite(15,HIGH);
   delay(300);
   digitalWrite(15,LOW);
   delay(300);
   digitalWrite(15,HIGH);
   delay(300);
   digitalWrite(15,LOW);
   delay(300);
   digitalWrite(15,HIGH);
   delay(300);
   digitalWrite(15,LOW);
   delay(300);
   return false;}

}

String SerialInput()
{
//  int autologout = millis();
  String output="";
  String a="";
  while(1){
    while(Serial.available()==0)
     {
     }
    a = Serial.readString();
    output+=a;

if(a.indexOf("\n") > 0){ output[output.length()-2]=0;
                         return output;}
    a="";
          }
}


void menu(){
  boolean MenuAlive = true;

char heslo[100]="";
  while(strcmp(heslo, menuheslo) != 0){
  int openTime=millis();
    String output="";
    String a="";
    Serial.println();
    Serial.println("Zadejte heslo: ");
    while(1){
      while(Serial.available()==0)
       {
         if((millis()-openTime)>60000){break;}
       }
      a = Serial.readString();
      output+=a;
    if(a.indexOf("\n") > 0){
                           output[output.length()-2]=0;
                           output.toCharArray(heslo,100);
                           if(strcmp(heslo, menuheslo) != 0){Serial.println("Spatne heslo.");}
                           if(strcmp(heslo, menuheslo) == 0){Serial.println("Spravne heslo!");}
                           break;}

      a="";
      if((millis()-openTime)>60000){break;}
            }
if((millis()-openTime)>60000){MenuAlive=false;Serial.println("Neaktivni uzivatel - automaticky prechod do deep sleep rezimu.");break;}




  }


  String pomocnyString="";
  while(MenuAlive){
  boolean MenuLevelTwoAlive = true;
  Serial.println("MENU:");
  Serial.println("1: Nastavit parametry wifi");
  Serial.println("2: Nastavit parametry emailu");
  Serial.println("3: Nastavit parametry thingspeaku");
  Serial.println("4: Nastavit parametry thingerIO");
  Serial.println("5: Nastavit parametry Ubidots");
  Serial.println("6: Nastavit interval probouzeni");
  Serial.println("7: Nastavit dolni hranici napeti baterie");
  Serial.println("8: Zmenit heslo pro vstup do MENU");
  Serial.println("9: Vypis vsech nastavitelnych parametru");
  Serial.println("10: Konec");
  switch(SerialInput().toInt()){
  case 1:  while(MenuLevelTwoAlive)
              { Serial.println();
                Serial.println("Nastaveni parametru wifi");
                Serial.println("1: Nastavit SSID");
                Serial.println("2: Nastavit Heslo");
                Serial.println("3: Nastavit Hostname zarizeni");
                Serial.println("4: Zpet");
                switch(SerialInput().toInt())
                  {
                  case 1:   Serial.println("zadejte SSID:");
                  SerialInput().toCharArray(ssid,100);


                            break;
                  case 2:   Serial.println("zadejte Heslo:");
                            SerialInput().toCharArray(password,100);
                            break;
                  case 3:   Serial.println("Zadejte hostname zarizeni:");
                            SerialInput().toCharArray(hostname,100);
                            break;

                  case 4:   MenuLevelTwoAlive = false;
                            break;
                  default:  Serial.println("Zadaná hodnota je nevyhovující");
                            break;
                  }
             }
          break;

  case 2: while(MenuLevelTwoAlive)
              { Serial.println();
                Serial.println("Nastaveni parametru emailu");
                Serial.println("1: Nastavit emailovou adresu ze ktere bude zarizeni odesilat hlaseni (napr.: jmeno@gmail.com)");
                Serial.println("2: Nastavit uzivatelske jmeno (typicky odpovida emailove adrese)");
                Serial.println("3: Nastavit prihlasovaci heslo");
                Serial.println("4: Nastavit hostname serveru (napr.: pro gmail = smtp.gmail.com ) ");
                Serial.println("5: Nastavit smtp port (typicky 25, 465 nebo 587)");
                Serial.println("6: Nastavit adresu na kterou budou ohlasovany udalosti (napr.: jmeno@gmail.com)");
                Serial.println("7: Zpet");
                switch(SerialInput().toInt())
                  {
                  case 1:   Serial.println("zadejte smtp_from_address");
                            SerialInput().toCharArray(smtp_from_address,100);
                            break;
                  case 2:   Serial.println("zadejte smtp_username:");
                            SerialInput().toCharArray(smtp_username,100);
                            break;
                  case 3:   Serial.println("zadejte smtp_password:");
                            SerialInput().toCharArray(smtp_password,100);
                            break;
                  case 4:   Serial.println("zadejte smtp_hostname:");
                            SerialInput().toCharArray(smtp_hostname,100);
                            break;
                  case 5:   Serial.println("zadejte smtp_port:");
                            smtp_port = SerialInput().toInt();
                            break;
                  case 6:   Serial.println("zadejte to_address:");
                            SerialInput().toCharArray(to_address,100);
                            break;
                  case 7:   MenuLevelTwoAlive = false;
                            break;
                  default:  Serial.println("Zadaná hodnota je nevyhovující");
                            break;
                  }
             }
          break;
    case 3:  while(MenuLevelTwoAlive)
              { Serial.println();
                Serial.println("Nastaveni parametru thingspeaku");
                Serial.println("1: Nastavit writeAPIKey");
                Serial.println("2: Zpet");
                switch(SerialInput().toInt())
                    {     case 1:   Serial.println("zadejte writeAPIKey:");
                                    SerialInput().toCharArray(writeAPIKey,100);
                                    break;
                          case 2:   MenuLevelTwoAlive = false;
                                    break;
                          default:  Serial.println("Zadaná hodnota je nevyhovující");
                                    break;
                    }
              }
            break;

   case 4:  while(MenuLevelTwoAlive)
                { Serial.println();
                  Serial.println("Nastaveni parametru thingerIO");
                  Serial.println("1: Nastavit USERNAME");
                  Serial.println("2: Nastavit DEVICE_ID");
                  Serial.println("3: Nastavit DEVICE_CREDENTIAL");
                  Serial.println("4: Zpet");
                  switch(SerialInput().toInt())
                    {
                    case 1:   Serial.println("zadejte USERNAME:");
                              SerialInput().toCharArray(USERNAME,100);
                              break;
                    case 2:   Serial.println("zadejte DEVICE_ID:");
                              SerialInput().toCharArray(DEVICE_ID,100);
                              break;
                    case 3:   Serial.println("zadejte DEVICE_CREDENTIAL:");
                              SerialInput().toCharArray(DEVICE_CREDENTIAL,100);
                              break;
                    case 4:   MenuLevelTwoAlive = false;
                              break;
                    default:  Serial.println("Zadaná hodnota je nevyhovující");
                              break;
                    }
               }
            break;

  case 5: while(MenuLevelTwoAlive)
               { Serial.println();
                 Serial.println("Nastaveni parametru Ubidots");
                 Serial.println("1: Nastavit Authentication Token");
                 Serial.println("2: Nastavit Variable ID - Napeti");
                 Serial.println("3: Nastavit Variable ID - Teplota");
                 Serial.println("4: Nastavit Variable ID - Magneticky kontakt");
                 Serial.println("5: Nastavit Variable ID - PANIC kontakt");
                 Serial.println("6: Zpet");
                 switch(SerialInput().toInt())
                   {
                   case 1:   Serial.println("zadejte Authentication Token:");
                             SerialInput().toCharArray(tokenUbidots,100);
                             break;
                   case 2:   Serial.println("zadejte Variable ID - Napeti:");
                             SerialInput().toCharArray(variable_id1,100);
                             break;
                   case 3:   Serial.println("zadejte Variable ID - Teplota");
                             SerialInput().toCharArray(variable_id2,100);
                             break;
                   case 4:   Serial.println("zadejte Variable ID - Magneticky kontakt");
                             SerialInput().toCharArray(variable_id3,100);
                             break;
                   case 5:   Serial.println("zadejte Variable ID - PANIC kontakt");
                             SerialInput().toCharArray(variable_id4,100);
                             break;
                   case 6:   MenuLevelTwoAlive = false;
                             break;
                   default:  Serial.println("Zadaná hodnota je nevyhovující");
                             break;
                   }
              }
           break;

  case 6: Serial.println("Zadejte interval probouzeni (v sekundach):");
          time_in_us=(SerialInput().toInt())*1000000;
          break;
  case 7: while(1){
          Serial.println("Zadejte limitni napeti baterie (pouzivejte desetinou tecku, ne carku!):");
          pomocnyString=SerialInput();
          limitniNapeti=pomocnyString.toFloat();
          if(limitniNapeti<2.4){Serial.println("Nelze zadat mensi napeti nez 2.4 Voltu");}else{break;}
          delay(1000);
          }
          break;

  case 8: Serial.println("zadejte heslo pro vstup do MENU: ");
  SerialInput().toCharArray(menuheslo,100);
          break;
  case 9: Serial.println("____Vypis vsech nastavitelnych parametru____");
          Serial.print("SSID: ");
          Serial.println(ssid);
          Serial.print("Heslo(wifi): ");
          Serial.println(password);
          Serial.print("Hostname zarizeni(wifi): ");
          Serial.println(hostname);
          Serial.print("Emailova adresa odesilatele: ");
          Serial.println(smtp_from_address);
          Serial.print("Uzivatelske jmeno: ");
          Serial.println(smtp_username);
          Serial.print("Heslo(email): ");
          Serial.println(smtp_password);
          Serial.print("Hostname serveru: ");
          Serial.println(smtp_hostname);
          Serial.print("SMTP port: ");
          Serial.println(smtp_port);
          Serial.print("Emailova adresa prijemce: ");
          Serial.println(to_address);
          Serial.print("writeAPIKey(thingspeak): ");
          Serial.println(writeAPIKey);
          Serial.print("USERNAME(thingerIO): ");
          Serial.println(USERNAME);
          Serial.print("DEVICE_ID(thingerIO): ");
          Serial.println(DEVICE_ID);
          Serial.print("DEVICE_CREDENTIAL(thingerIO): ");
          Serial.println(DEVICE_CREDENTIAL);
          Serial.print("Authentication Token(Ubidots): ");
          Serial.println(tokenUbidots);
          Serial.print("Variable ID - Napeti(Ubidots): ");
          Serial.println(variable_id1);
          Serial.print("Variable ID - Teplota(Ubidots): ");
          Serial.println(variable_id2);
          Serial.print("Variable ID - Magneticky kontakt(Ubidots): ");
          Serial.println(variable_id3);
          Serial.print("Variable ID - PANIC kontakt(Ubidots): ");
          Serial.println(variable_id4);
          Serial.print("Interval probouzeni: ");
          Serial.print(((int)time_in_us)/1000000);
          Serial.println(" sec");
          Serial.print("Hranicni napeti baterie: ");
          Serial.println(limitniNapeti);
          Serial.print("Heslo pro vstup do MENU: ");
          Serial.println(menuheslo);
          Serial.println("______________________________________________ ");


          break;

  case 10: Serial.println("Ukoncuji...");

          while(digitalRead(35)==HIGH){
            Serial.println("Odpojte prosim vase zarizeni a uzavrete krabicku, zarizeni zacne automaticky pracovat");
            delay(2500);
          }

          MenuAlive = false;
          break;

  default:  Serial.println("Zadaná hodnota je nevyhovující");
            break;

                              }


                  }

}

void startConfig(){ //prvni boot - zaznamNapeti je prazdny - funkce naplni vsechny hodnoty aktualni hodnotou napeti aby nedoslo k nahlaseni slabe baterie

  pinMode(12,OUTPUT);
  digitalWrite(12,HIGH);
  pinMode(33, INPUT);
  delay(500);
  adc1_config_width(ADC_WIDTH_12Bit);
  adc1_config_channel_atten(ADC1_CHANNEL_5,ADC_ATTEN_0db);
  double aktualNapeti = adc1_get_voltage(ADC1_CHANNEL_5);
   aktualNapeti = aktualNapeti/1202.0;
  //Serial.print(aktualNapeti);
  for(int i = 0;i<10;i++){
    zaznamNapeti[i]=aktualNapeti;
      }
  digitalWrite(12,LOW);
  Fill = false;
}

void OsetriUdalost() {
  esp_sleep_wakeup_cause_t wakeup_reason;
  wakeup_reason = esp_sleep_get_wakeup_cause();//_deep

  switch (wakeup_reason)
  {
    case 1  : Serial.println("Wakeup caused by external signal using RTC_IO"); break; //nevyuzito
    case 2  : {
        Serial.print("Probuzeni zpusobeno RTC GPIO pinem");



      if(pin34==LOW&&pin35==LOW){
        Serial.println("Zarizeni bylo znovu uvedeno do bezneho stavu detekce");
      }
   //  if(((uint64_t)esp_sleep_get_ext1_wakeup_status())==0b00000000000000000000000000001000){
       if(pin35==HIGH){
          Serial.println("Probuzeni zpusobeno PANIC kontaktem (pin35)");
          digitalWrite(15,HIGH);
          delay(1000);
          digitalWrite(15,LOW);
          delay(1000);
          digitalWrite(15,HIGH);
          delay(1000);
          digitalWrite(15,LOW);
          delay(1000);
            if(pripojenikWifi()==true)
              { Serial.println("Pripojeno");
                Serial.println("Odesilam email");
                mail.send(to_address, "ESP32 POPLACH", "Bylo detekovano rozpojeni PANIC kontaktu (GPIO 35)"); //mail
                zapisDoThingSpeaku("field4=Probuzeno pinem 35 - PANIC kontakt");     //thingspeak
                thing["PANIC"] >> outputValue("Probuzeno pinem 35 - PANIC kontakt"); //thingerio
                thing.handle();                                                      //thingerio
                thing.write_bucket("PANIC_Kontakt", "PANIC");                        //thingerio
                Serial.println("Posilam data na thingerio");
                zapisDoUbidots(String(variable_id4), String(1), "Naposledy probuzeno pinem 35 - PANIC kontakt"); //ubidots
                Serial.println("Posilam data na unidots");
              }else{ Serial.println("Nepodařilo se pripojit");
                   }

          menu();
          pin35 = digitalRead(35);
                                 }
      //if(((uint32_t)esp_sleep_get_ext1_wakeup_status())==0b00000000000000000000000000000100){
        if(pin34==HIGH){
          Serial.println("Probuzeni zpusobeno magnetickym kontaktem (pin34)");
          digitalWrite(15,HIGH);
          delay(1000);
          digitalWrite(15,LOW);

            if(pripojenikWifi()==true)
              { Serial.println("Pripojeno");
                Serial.println("Odesilam email");
                mail.send(to_address, "ESP32 POPLACH", "Bylo detekovano rozpojeni magnetickeho kontaktu (GPIO 34)"); //mail
                zapisDoThingSpeaku("field3=Probuzeno pinem 34 - Magneticky kontakt");        //thingspeak
                thing["Magnet"] >> outputValue("Probuzeno pinem 34 - Magneticky kontakt");   //thingerio
                thing.handle();                                                              //thingerio
                thing.write_bucket("MagnetKontakt", "Magnet");                               //thingerio
                Serial.println("Posilam data na thingerio");
                zapisDoUbidots(String(variable_id3), String(1), "Naposledy probuzeno pinem 34 - Magneticky kontakt"); //ubidots
                Serial.println("Posilam data na unidots");
              }else{ Serial.println("Nepodařilo se pripojit");
                   }
                                 }

      break;}

    case 3  :{ Serial.println("Probuzeni zpusobeno timerem");
    pinMode(12,OUTPUT);
    digitalWrite(12,HIGH);
    sensors.begin();
    sensors.requestTemperatures();
    digitalWrite(12,HIGH);
    adc1_config_width(ADC_WIDTH_12Bit);
    adc1_config_channel_atten(ADC1_CHANNEL_5,ADC_ATTEN_0db);
    double aktualNapeti = adc1_get_voltage(ADC1_CHANNEL_5);
    Serial.print("Aktualne namerene napeti baterie: ");
    Serial.print(aktualNapeti/(1202));
    Serial.println(" V");
    for(int i = 9;i>0;i--){
    zaznamNapeti[i]=zaznamNapeti[i-1] ;
  }
    zaznamNapeti[0]=(aktualNapeti/(1202));
    double pomocnyPrumer=0;
    for(int i = 0;i<10;i++){
      pomocnyPrumer+=zaznamNapeti[i];
        }
    prumNapeti=pomocnyPrumer/10;
    Serial.print("Prumerne napeti baterie (za poslednich 10 mereni): ");
    Serial.print(prumNapeti);
    Serial.println(" V");
    aktualNapeti=0; pomocnyPrumer=0;
    float teplotaPom;

teplotaPom = sensors.getTempCByIndex(0);

if(teplotaPom==-127||teplotaPom==85){}else{teplota = teplotaPom;} //"ošetřeni" nahodne chyby teplomeru
Serial.print("Temperature is: ");
Serial.println(teplota);
if(pripojenikWifi()==true)  {
      Serial.println("Pripojeno");
zapisDoUbidots(String(variable_id1), String(prumNapeti), "Napeti baterie");       //ubidots
zapisDoUbidots(String(variable_id2), String(teplota), "Teplota");                 //ubidots
Serial.println("Posilam data na unidots");
 zapisDoThingSpeaku("field1="+String(prumNapeti)+"&field2="+String(teplota));     //thingspeak

 thing.handle();                                                                  //thingerio
 pson data;                                                                       //thingerio
 data["Napeti"] = prumNapeti;                                                     //thingerio
 data["Teplota"] = teplota;                                                       //thingerio
 thing.write_bucket("NapetiaTeplota", data);                                      //thingerio
 Serial.println("Posilam data na thingerio");

}else{ Serial.println("Nepodařilo se pripojit");}
digitalWrite(12,LOW);
     break;}

    case 4  : Serial.println("Wakeup caused by touchpad"); break; //nevyuzito
    case 5  : Serial.println("Wakeup caused by ULP program"); break; //nevyuzito
    default : Serial.println("Wakeup was not caused by deep sleep"); break;
  }
}


void setup() {
  Serial.begin(921600);
//  Serial.begin(115200);
pin34 = digitalRead(34);
pin35 = digitalRead(35);
  preferences.begin("ESP-preferences", false);
  LoadPreferencesVariables();
    pinMode(15, OUTPUT);
  if(Fill==true){startConfig();}
  ++bootCount;
    Serial.println();
    Serial.println();
  Serial.println("Boot number: " + String(bootCount));
 OsetriUdalost();

  Serial.print("Uptime(sec): ");
  time_t cas;
  Serial.println(time(&cas));

//________Kontrola baterie____///
  if((WiFi.status() == WL_CONNECTED)&&(prumNapeti<limitniNapeti)&&(((time(&cas)-lastBatteryReport)>3600)||(lastBatteryReport==0))){ // ==0 je poprve kdy dojde k "podkroceni "
    lastBatteryReport=time(&cas);
    Serial.println("Odesilam email");
    mail.send(to_address, "ESP32 LOW BATTERY", "Bylo detekovano nizke napeti baterie, prosim dobijte akumulator");
  }

  if((pin34==LOW)&&(pin35==LOW)){
  //Serial.println(esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK, ESP_EXT1_WAKEUP_ANY_HIGH));//_deep
  esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK, ESP_EXT1_WAKEUP_ANY_HIGH); //normalni spanek - probere se po timer nebo při otevreni panic/magnet
}else{
 Serial.println(esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK, ESP_EXT1_WAKEUP_ALL_LOW));// spanek po udalosti - cekani na zavreni panic/magnet + normalni timer jede furt
}

  SaveChangedPreferencesVariables();
  preferences.end();
  Serial.println("Going to sleep now");


esp_sleep_enable_timer_wakeup(time_in_us);

}

void loop() {}
