//https://forum.arduino.cc/index.php?topic=521697.0
//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 <BH1750.h>
#include "Adafruit_VEML6070.h"
#include "Adafruit_TCS34725.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");
Adafruit_VEML6070 uv = Adafruit_VEML6070();
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_700MS, TCS34725_GAIN_1X);
uint16_t r, g, b, c, teplotaBarev, lux;

Timestamps ts(3600);
BH1750 lightMeter;

// definice pro MySQL
IPAddress server_addr(192,168,88,210);
char mysqluser[] = "senzor";
char mysqlpassword[] = "02.pROsince";
WiFiClient client;
MySQL_Connection conn((Client *)&client);
//##########################################

// definice pro prenos dat pomoci I2C
int lock = 0;
int y = 0;
char x = {0};
int z = 0;
char data[8] = {0};
float input[6];
boolean Run = false;
//##########################################


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();
delay(200);
svetlo();
delay(200);
if (lux > 2) {
  uvindex();
  delay(200);
  TCS34725();
  delay(200);
  senzorMQ135()
  delay(500);
  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 uvindex(){
 uv.begin(VEML6070_1_T);
 int uvindex = uv.readUV();
 Serial.print("UV light level: "); Serial.println(uv.readUV());  
}

//#############################################################
void TCS34725(){
// zapnutí přisvětlovací LED na modulu s krátkou pauzou
  // pro ustálení
  tcs.setInterrupt(false);
  delay(60);
  // načtení dat ze senzoru do proměnných
  tcs.getRawData(&r, &g, &b, &c);
  // vypnutí přisvětlovací LED diody
  tcs.setInterrupt(true);
  // výpočet teploty barvy a uložení do proměnné
  teplotaBarev = tcs.calculateColorTemperature(r, g, b);
  // vypočtení intenzity osvětlení a uložení do proměnné
  lux = tcs.calculateLux(r, g, b);
  // vytištění všech údajů po sériové lince
  Serial.print("Teplota barev: "); Serial.print(teplotaBarev, DEC); Serial.print(" Kelvin - ");
  Serial.print("Intenzita osvetleni: "); Serial.print(lux, DEC); Serial.print(" lux - ");
  Serial.print("R: "); Serial.print(r, DEC); Serial.print(" ");
  Serial.print("G: "); Serial.print(g, DEC); Serial.print(" ");
  Serial.print("B: "); Serial.print(b, DEC); Serial.print(" ");
  Serial.print("C: "); Serial.print(c, DEC); Serial.print(" ");
  Serial.println(" ");
  
  int teplota = (teplotaBarev, DEC);
  int intenzita = (lux, DEC);
  int modra = (b, DEC);
  int cervena = (r, DEC);
  int zelena = (g, DEC);
  int cista = (c, DEC);
  
}

//###################################################################
void svetlo(){
 lightMeter.begin();
 float lux = lightMeter.readLightLevel();
 Serial.print("Light: ");
  Serial.print(lux);
  Serial.println(" lx"); 
}

//###########################################################
void senzorMQ135(){
Wire.begin(0x02); // start komunikace master>slave ...tady jsem skončil s kódem
Wire.beginTransmission(0x01);
Wire.write('S'); // "S" jako start mereni
Wire.onReceive(receiveEvent);

}
void receiveEvent(int bytes) {
  x = Wire.read();    // read one character from the I2C
  if (Run) {
    if (lock == 1) {
      if (x != '#') {
        data[y] = x;
        y++;
      }
      else {
        input[z] = atof (data);
        data[0] = (char)0; // clears char array !
        lock = 0;
        y = 0;
        z++;
      }
    }
    else if (x == '$' && lock == 0) {
      lock = 1;
    }
    else if (x == '*' && lock == 0) {
      z = 0;
      Run = false;
      testVals();
    }
  }
  if (x == '&') {
    Run = true;
  }
}
//#################################################
void testVals() {
  //first value
  Serial.print(F("\nCO: "));
  Serial.println(input[0]);
  int CO = input[0];// https://cs.wikipedia.org/wiki/Oxid_uhelnat%C3%BD
  //next value
  Serial.print(F("Alkohol: "));
  Serial.println(int(input[1]));
  int Alkohol = input[1];//https://cs.wikipedia.org/wiki/Ethanol
  //next value
  Serial.print(F("CO2: "));
  Serial.println(input[2]);
  int CO2 = input[2];//https://cs.wikipedia.org/wiki/Oxid_uhli%C4%8Dit%C3%BD
  //next value
  Serial.print(F("Toluen: "));
  Serial.println(int(input[3]));
  int Toluen = input[3];//https://cs.wikipedia.org/wiki/Toluen
  //next value
  Serial.print(F("NH4: "));
  Serial.println(input[4]);
  int NH4 = input[4];//https://cs.wikipedia.org/wiki/Amonn%C3%BD_kation
  //next value
  Serial.print(F("Aceton: "));
  Serial.println(int(input[5]));
  int Aceton = input[5];//https://cs.wikipedia.org/wiki/Aceton
}
//##################################################

//############################################################
void datadodatabase(){
char INSERT_SQL[] = "INSERT INTO balkon.archive (`dateTime`,`usUnits`,`interval`,'extraTemp1','extraTemp2','extraTemp3','extraTemp4','extraTemp5','extraTemp6','UV') VALUES (epochtime,16,5,r,g,b,c,teplotaBarev,lux,uvindex )";
  MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
  cur_mem->execute(INSERT_SQL);
  delete cur_mem;
}

//############################################################
void httpclient(){

  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
}
}
