//import knihoven
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti wifiMulti;
#define DEVICE "ESP8266"
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#include <InfluxDbClient.h>
#include <InfluxDbCloud.h>
#include <Adafruit_PCF8591.h>
// Make sure that this is set to the value in volts of VCC
#define ADC_REFERENCE_VOLTAGE 3.3
Adafruit_PCF8591 pcf = Adafruit_PCF8591();

//Údaje pro připojení k Wi-Fi a InfluxDB
// WiFi AP SSID
#define WIFI_SSID "T-u3uc4t"//"T-u3uc4t"//"Vitovo"
// WiFi password
#define WIFI_PASSWORD "xxducuxu73t3"//"xxducuxu73t3"//"2K-5r201"
// InfluxDB v2 server url, e.g. https://eu-central-1-1.aws.cloud2.influxdata.com (Use: InfluxDB UI -> Load Data -> Client Libraries)
#define INFLUXDB_URL "https://eu-central-1-1.aws.cloud2.influxdata.com"
// InfluxDB v2 server or cloud API token (Use: InfluxDB UI -> Data -> API Tokens -> Generate API Token)
#define INFLUXDB_TOKEN "mZnwgCpa2ai_3TROBeZVCaKxmkj5YSXvkd-7gL3kLlG_RYuMnIVx-tR4AR5xUVlZoYz5B84rU2F6ShTiPhV1ew=="
// InfluxDB v2 organization id (Use: InfluxDB UI -> User -> About -> Common Ids )
#define INFLUXDB_ORG "Brno University Of Technology"
// InfluxDB v2 bucket name (Use: InfluxDB UI ->  Data -> Buckets)
#define INFLUXDB_BUCKET "test4"

// Set timezone string according to https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
#define TZ_INFO "CET-1CEST,M3.5.0,M10.5.0/3"

// InfluxDB client instance with preconfigured InfluxCloud certificate
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN, InfluxDbCloud2CACert);

// Data point
Point Wifip("Wifi_status");
Point Batteryp("Battery_voltage");
Point DHTp("DHT_values");
Point Analogp("Analog_values");

//Zadefinování DHT11
#define DHTPIN D6     // Digital pin connected to the DHT sensor 
#define DHTTYPE DHT11     // DHT 11

DHT_Unified dht(DHTPIN, DHTTYPE);

//proměnné pro převodník

uint8_t dac_counter = 0;
float int_to_volts(uint16_t dac_value, uint8_t bits, float logic_level) {
  return (((float)dac_value / ((1 << bits) - 1)) * logic_level);
}

void setup() {
  Serial.begin(9600);

  // Setup wifi
  WiFi.mode(WIFI_STA);
  wifiMulti.addAP(WIFI_SSID, WIFI_PASSWORD);

  Serial.print("Connecting to wifi");
  while (wifiMulti.run() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
  }
  Serial.println(" ");
  Serial.println("connected!");

  // Add tags
  Wifip.addTag("device", DEVICE);
  Wifip.addTag("SSID", WiFi.SSID());

  timeSync(TZ_INFO, "pool.ntp.org", "time.nis.gov");
  // Check server connection
  if (client.validateConnection()) {
    Serial.print("Connected to InfluxDB: ");
    Serial.println(client.getServerUrl());
  } else {
    Serial.print("InfluxDB connection failed: ");
    Serial.println(client.getLastErrorMessage());
  }
  //Inicializace DHT
  dht.begin();
  //Inicializace převodníku
  pcf.begin();
  pcf.enableDAC(true);
  //Nastaveni pinu
  pinMode(D5, OUTPUT);
  pinMode(D4, OUTPUT);
}

void loop() {
  //nastaveni pinu
  digitalWrite(D5, LOW);
  digitalWrite(D4, HIGH);
  delay(1000);
  // Clear fields for reusing the point. Tags will remain untouched
  Wifip.clearFields();
  Batteryp.clearFields();
  DHTp.clearFields();
  Analogp.clearFields();
  // Check WiFi connection and reconnect if needed
  if (wifiMulti.run() != WL_CONNECTED) {
    Serial.println("Wifi connection lost");
  }
  //čtení hodnot DHT
  sensors_event_t event;
  dht.temperature().getEvent(&event);
  Serial.print(F("Temperature: "));
  Serial.print(event.temperature);
  Serial.println(F("°C"));
  DHTp.addField("Temperature",event.temperature);

  dht.humidity().getEvent(&event);
  Serial.print(F("Humidity: "));
  Serial.print(event.relative_humidity);
  Serial.println(F("%"));
  DHTp.addField("Humidity",event.relative_humidity);

  //čtení analogových hodnot
  Serial.print("Battery voltage: ");
  Serial.println(int_to_volts(analogRead(A0), 10, ADC_REFERENCE_VOLTAGE));
  Batteryp.addField("Battery_voltage",2*(int_to_volts(analogRead(A0), 10, ADC_REFERENCE_VOLTAGE)));
  Serial.print("Light intensity: ");
  Serial.println(256-(pcf.analogRead(0)));
  Analogp.addField("Light_intensity",256-(pcf.analogRead(0)));
  Serial.print("Soil humidity: ");
  Serial.println(256-(pcf.analogRead(1)));
  Analogp.addField("Soil_humidity",256-(pcf.analogRead(1)));
  Wifip.addField("rssi",WiFi.RSSI());

  // Print what are we exactly writing
  Serial.print("Writing: ");
  Serial.println(Wifip.toLineProtocol());
  Serial.println(DHTp.toLineProtocol());
  Serial.println(Analogp.toLineProtocol());
  Serial.println(Batteryp.toLineProtocol());

  delay(2000);
  // Write point
  if (!client.writePoint(Wifip)) {
    Serial.print("InfluxDB write failed: ");
    Serial.println(client.getLastErrorMessage());
  }

  if (!client.writePoint(DHTp)) {
    Serial.print("InfluxDB write failed: ");
    Serial.println(client.getLastErrorMessage());
  }

   if (!client.writePoint(Analogp)) {
    Serial.print("InfluxDB write failed: ");
    Serial.println(client.getLastErrorMessage());
  }
   if (!client.writePoint(Batteryp)) {
    Serial.print("InfluxDB write failed: ");
    Serial.println(client.getLastErrorMessage());
  }


  delay(2000);
   // Delay between measurements.

  ESP.deepSleep(1800e6);
 }
