#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>
#include "ClosedCube_OPT3002.h"

ClosedCube_OPT3002 opt3002;

// Replace with your network credentials
const char* ssid     = "C3PO";
const char* password = "pass4321word";

// REPLACE with your Domain name and URL path or IP address with path
const char* serverName = "http://164273.9e.cz/zapis.php";

// Keep this API Key value to be compatible with the PHP code provided in the project page. 
// If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key 
String apiKeyValue = "tPmAT5Ab3j7F9";

String sensorName = "OPT3002";
String sensorLocation = "Kurník";

float intenzita;

void setup() {
 snimani();
 sql();
}

void snimani(){
    Wire.begin();
  Serial.begin(115200);
  Serial.println("\nI2C Scanner");
  int adresa = 0;
  byte error, address;
  int nDevices;
  Serial.println("Scanning...");
  nDevices = 0;
  for(address = 1; address < 127; address++ ) {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address<16) {
        Serial.print("0");
      }
      Serial.println(address,HEX);
      Serial.println(address,DEC);
      adresa = address;
      nDevices++;
    }
    else if (error==4) {
      Serial.print("Unknow error at address 0x");
      if (address<16) {
        Serial.print("0");
      }
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0) {
    Serial.println("No I2C devices found\n");
  }
  else {
    Serial.println("done\n");
  }
  delay(5000); 
  if (adresa == 69) {
    Serial.println("externí senzor\n");
#define OPT3002_ADDRESS 0x45
Serial.println("ClosedCube OPT3002 Arduino Test");

  opt3002.begin(OPT3002_ADDRESS);
  Serial.print("OPT3002 Manufacturer ID:");
  Serial.print(opt3002.readManufacturerID());
  Serial.print(" Device ID:");
  Serial.println(opt3002.readDeviceID());

  configureSensor();
  printResult("High-Limit", opt3002.readHighLimit());
  printResult("Low-Limit", opt3002.readLowLimit());
  Serial.println("----");
    
  }
   else {
    Serial.println("interní senzor\n");
#define OPT3002_ADDRESS 0x44
Serial.println("ClosedCube OPT3002 Arduino Test");

  opt3002.begin(OPT3002_ADDRESS);
  Serial.print("OPT3002 Manufacturer ID:");
  Serial.print(opt3002.readManufacturerID());
  Serial.print(" Device ID:");
  Serial.println(opt3002.readDeviceID());

  configureSensor();
  printResult("High-Limit", opt3002.readHighLimit());
  printResult("Low-Limit", opt3002.readLowLimit());
  Serial.println("----");
  }
  OPT3002 result = opt3002.readResult();
  printResult("OPT3002", result);
  delay(500);
}
 
void loop() {
         
}

void sql(){
   WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) { 
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
  //Check WiFi connection status
  if(WiFi.status()== WL_CONNECTED){
    WiFiClient client;
    HTTPClient http;
    
    // Your Domain name with URL path or IP address with path
    http.begin(client, serverName);
    
    // Specify content-type header
    http.addHeader("Content-Type", "application/x-www-form-urlencoded");
    
    // Prepare your HTTP POST request data
    String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName
                          + "&location=" + sensorLocation + "&value1=" + float(intenzita)
                          + "&value2=" + String("opt3002.readResult") + "&value3=" + float(intenzita) + "";
    Serial.print("httpRequestData: ");
    Serial.println(httpRequestData);
    
    int httpResponseCode = http.POST(httpRequestData);
       
    if (httpResponseCode>0) {
      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
    }
    else {
      Serial.print("Error code: ");
      Serial.println(httpResponseCode);
    }
    // Free resources
    http.end();
  }
  else {
    Serial.println("WiFi Disconnected");
  }
  //Send an HTTP POST request every 30 seconds
  delay(30000);
}

void printResult(String text, OPT3002 result) {
  if (result.error == NO_ERROR) {
    Serial.print(text);
    Serial.print(": ");
    Serial.print(result.lux);
    intenzita = result.lux;
    Serial.println(" nW/cm2");
  }
  else {
    printError(text, result.error);
  }
}

void printError(String text, OPT3002_ErrorCode error) {
  Serial.print(text);
  Serial.print(": [ERROR] Code #");
  Serial.println(error);
}

void configureSensor() {
  OPT3002_Config newConfig;

  newConfig.RangeNumber = B1100;
  newConfig.ConvertionTime = B0;
  newConfig.Latch = B1;
  newConfig.ModeOfConversionOperation = B11;

  OPT3002_ErrorCode errorConfig = opt3002.writeConfig(newConfig);
  if (errorConfig != NO_ERROR)
    printError("OPT3002 configuration", errorConfig);
  else {
    OPT3002_Config sensorConfig = opt3002.readConfig();
    Serial.println("OPT3002 Current Config:");
    Serial.println("------------------------------");

    Serial.print("Conversion ready (R):");
    Serial.println(sensorConfig.ConversionReady, HEX);

    Serial.print("Conversion time (R/W):");
    Serial.println(sensorConfig.ConvertionTime, HEX);

    Serial.print("Fault count field (R/W):");
    Serial.println(sensorConfig.FaultCount, HEX);

    Serial.print("Flag high field (R-only):");
    Serial.println(sensorConfig.FlagHigh, HEX);

    Serial.print("Flag low field (R-only):");
    Serial.println(sensorConfig.FlagLow, HEX);

    Serial.print("Latch field (R/W):");
    Serial.println(sensorConfig.Latch, HEX);

    Serial.print("Mask exponent field (R/W):");
    Serial.println(sensorConfig.MaskExponent, HEX);

    Serial.print("Mode of conversion operation (R/W):");
    Serial.println(sensorConfig.ModeOfConversionOperation, HEX);

    Serial.print("Polarity field (R/W):");
    Serial.println(sensorConfig.Polarity, HEX);

    Serial.print("Overflow flag (R-only):");
    Serial.println(sensorConfig.OverflowFlag, HEX);

    Serial.print("Range number (R/W):");
    Serial.println(sensorConfig.RangeNumber, HEX);

    Serial.println("------------------------------");
  }

}
