//potrebne knihovny
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <NTPClient.h> // knihovna pro komunikaci s NTP servery
#include <WiFiUdp.h> // pomocna knihovna pro NTP
#include <Timestamps.h> // převadi cas na epoch time
#include <TimeLib.h> //pomocna knihovna na cas
#include <Wire.h> //I2C komunikace
#include <SparkFunBME280.h> //Click here to get the library: http://librarymanager/All#SparkFun_BME280
#include <SparkFunCCS811.h> //Click here to get the library: http://librarymanager/All#SparkFun_CCS811
#include "PMS.h"
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>
//#################################################

//definice promennych
const char *ssid     = "KVETINKOVA345_mAP";
const char *password = "kdjsiu12";
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "0.cz.pool.ntp.org");

#define CCS811_ADDR 0x5B //Default I2C Address
//#define CCS811_ADDR 0x5A //Alternate I2C Address
#define PIN_NOT_WAKE 5
Timestamps ts(3600);

CCS811 myCCS811(CCS811_ADDR);
BME280 myBME280;

PMS pms(Serial);
PMS::DATA data;

// definice pro MySQL
IPAddress server_addr(192,168,88,210);
char mysqluser[] = "senzor";
char mysqlpassword[] = "02.pROsince";
WiFiClient client;
MySQL_Connection conn((Client *)&client);
//##########################################



void setup() {
  Serial.begin(115200);
  Wire.begin();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());  
}
void loop() {

cas();
senzorBME280();
senzorccs811();
senzorPMS5003();
datadodatabase();  
delay(1000*60*5); //delay 5 minut
}
//##########################################################

void cas(){
timeClient.update();
unsigned long epochTime = timeClient.getEpochTime();
int currentHour = timeClient.getHours();
int currentMinute = timeClient.getMinutes();
int currentSecond = timeClient.getSeconds();
struct tm *ptm = gmtime ((time_t *)&epochTime); 
int monthDay = ptm->tm_mday;
int currentMonth = ptm->tm_mon+1;
int currentYear = ptm->tm_year+1900;
}

//#########################################################
void dejmicas(){
timeClient.update();

  unsigned long epochTime = timeClient.getEpochTime();
  Serial.print("Epoch Time: ");
  Serial.println(epochTime);
  
  
  String formattedTime = timeClient.getFormattedTime();
  Serial.print("Formatted Time: ");
  Serial.println(formattedTime);  

  int currentHour = timeClient.getHours();
  Serial.print("Hour: ");
  Serial.println(currentHour);  

  int currentMinute = timeClient.getMinutes();
  Serial.print("Minutes: ");
  Serial.println(currentMinute); 
   
  int currentSecond = timeClient.getSeconds();
  Serial.print("Seconds: ");
  Serial.println(currentSecond);  
  
  struct tm *ptm = gmtime ((time_t *)&epochTime); 

  int monthDay = ptm->tm_mday;
  Serial.print("Month day: ");
  Serial.println(monthDay);

  int currentMonth = ptm->tm_mon+1;
  Serial.print("Month: ");
  Serial.println(currentMonth);

  int currentYear = ptm->tm_year+1900;
  Serial.print("Year: ");
  Serial.println(currentYear);

  
  String currentDate = String(currentYear) + "-" + String(currentMonth) + "-" + String(monthDay);
  Serial.print("Current date: ");
  Serial.println(currentDate);
  Serial.println(ts.getTimestampUNIX((currentYear), (currentMonth), (monthDay), (currentHour), (currentMinute), (currentSecond)));
  }

//#############################################################
void senzorBME280(){
  myBME280.settings.commInterface = I2C_MODE;
  myBME280.settings.I2CAddress = 0x77;
  /*myBME280.settings.commInterface = I2C_MODE;
  myBME280.settings.I2CAddress = 0x77;*/
  myBME280.settings.runMode = 3; //Normal mode
  myBME280.settings.tStandby = 0;
  myBME280.settings.filter = 4;
  myBME280.settings.tempOverSample = 5;
  myBME280.settings.pressOverSample = 5;
  myBME280.settings.humidOverSample = 5;
  myBME280.begin();
}

//###################################################################
void senzorccs811(){
CCS811Core::CCS811_Status_e returnCode = myCCS811.beginWithStatus();
  Serial.print("CCS811 begin exited with: ");
  Serial.println(myCCS811.statusString(returnCode));
  if (myCCS811.dataAvailable())
  {
    myCCS811.readAlgorithmResults();
    printInfoSerial();

    float BMEtempC = myBME280.readTempC();
    float BMEhumid = myBME280.readFloatHumidity();

    Serial.print("Applying new values (deg C, %): ");
    Serial.print(BMEtempC);
    Serial.print(",");
    Serial.println(BMEhumid);
    Serial.println();

    myCCS811.setEnvironmentalData(BMEhumid, BMEtempC);
  }
  else if (myCCS811.checkForStatusError())
  {
    printSensorError();
  }

  
}

//#################################################################
void printInfoSerial()
{
  Serial.println("CCS811 data:");
  Serial.print(" CO2 concentration : ");
  Serial.print(myCCS811.getCO2());
  int co2 = myCCS811.getCO2();
  Serial.println(" ppm");

  Serial.print(" TVOC concentration : ");
  Serial.print(myCCS811.getTVOC());
  int tovc = myCCS811.getTVOC();
  Serial.println(" ppb");

  Serial.println("BME280 data:");
  Serial.print(" Temperature: ");
  Serial.print(myBME280.readTempC(), 2);
  int teplota = myBME280.readTempC();
  Serial.println(" degrees C");

  Serial.print(" Temperature: ");
  Serial.print(myBME280.readTempF(), 2);
  Serial.println(" degrees F");

  Serial.print(" Pressure: ");
  Serial.print(myBME280.readFloatPressure(), 2);
  Serial.println(" Pa");

  Serial.print(" Pressure: ");
  Serial.print((myBME280.readFloatPressure() * 0.0002953), 2);
  int tlak = myBME280.readFloatPressure() * 0.0002953;
  Serial.println(" InHg");

  Serial.print(" Altitude: ");
  Serial.print(myBME280.readFloatAltitudeMeters(), 2);
  Serial.println("m");

  Serial.print(" Altitude: ");
  Serial.print(myBME280.readFloatAltitudeFeet(), 2);
  Serial.println("ft");

  Serial.print(" %RH: ");
  Serial.print(myBME280.readFloatHumidity(), 2);
  int vlhkost = myBME280.readFloatHumidity();
  Serial.println(" %");

  Serial.println();
}

//##############################################################
void printSensorError()
{
  uint8_t error = myCCS811.getErrorRegister();

  if (error == 0xFF) //comm error
  {
    Serial.println("Failed to get ERROR_ID register.");
  }
  else
  {
    Serial.print("Error: ");
    if (error & 1 << 5)
      Serial.print("HeaterSupply");
    if (error & 1 << 4)
      Serial.print("HeaterFault");
    if (error & 1 << 3)
      Serial.print("MaxResistance");
    if (error & 1 << 2)
      Serial.print("MeasModeInvalid");
    if (error & 1 << 1)
      Serial.print("ReadRegInvalid");
    if (error & 1 << 0)
      Serial.print("MsgInvalid");
    Serial.println();
  }
}

//###################################################
void senzorPMS5003(){
if (pms.read(data))
  {
    Serial1.print("PM 1.0 (ug/m3): ");
    Serial1.println(data.PM_AE_UG_1_0);
int prach01 = (data.PM_AE_UG_1_0);
    Serial1.print("PM 2.5 (ug/m3): ");
    Serial1.println(data.PM_AE_UG_2_5);
int prach25 = (data.PM_AE_UG_2_5);
    Serial1.print("PM 10.0 (ug/m3): ");
    Serial1.println(data.PM_AE_UG_10_0);
int prach10 = (data.PM_AE_UG_10_0);
    Serial1.println();
  
}
}

//#############################################################
void datadodatabase(){
char INSERT_SQL[] = "INSERT INTO balkon.archive (`dateTime`,`usUnits`,`interval`, 'co2', 'extraHumid2','appTemp1','extraHumid1','pressure','pm10_0','pm1_0','pm2_5' ) VALUES (epochtime,16,5,co2,teplota,vlhkost,tlak,prach10,prach1,prach25)";
  MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
  cur_mem->execute(INSERT_SQL);
  delete cur_mem;
}

//############################################################
void httpclient(){
/*const String endpoint = "http://api.openweathermap.org/data/2.5/weather?q=Lisbon,pt&APPID=";
const String key = "yourAPIkey";
http.begin(endpoint + key); //Specify the URL
    int httpCode = http.GET();  //Make the request
 
    if (httpCode > 0) { //Check for the returning code
 
        String payload = http.getString();
        Serial.println(httpCode);
        Serial.println(payload);}
 
    else {
      Serial.println("Error on HTTP request");
    }
 
    http.end(); //Free the resources
  }*/
  HTTPClient http;  //Declare an object of class HTTPClient
 
    http.begin("http://api.sunrise-sunset.org/json?lat=50.0874654&lng=14.4212535&formatted=0");  //Specify request destination
    int httpCode = http.GET();                                  //Send the request
 
    if (httpCode > 0) { //Check the returning code
 
      String payload = http.getString();   //Get the request response payload
      Serial.println(payload);             //Print the response payload
}
}
