#include <WiFi.h>
#include <ESP32Servo.h>
#include <ThingsBoard.h>
#include <DHTesp.h>
#include <PubSubClient.h>

#define WIFI_AP_NAME "Wokwi-GUEST"
#define WIFI_PASSWORD ""
#define THINGSBOARD_SERVER "thingsboard.cloud"
#define THINGSBOARD_ACCESTOKEN "AfVwzQeAM4zbutWfM7xb"

#define SERIAL_DEBUG_BAUD 115200

#define LDR_PIN 36
#define PH_PIN 35
const float GAMMA = 0.7;
// const float RL10 =33;
const float RL10 =50;

WiFiClient espClient;
ThingsBoard tb(espClient);
int status = WL_IDLE_STATUS;

DHTesp dht;
#define DHT_PIN 15

#define SERVO_PIN 13
Servo myservo;

// #define relayBohlam 12
#define relayPenyiramAir 12

boolean isRoofOpen = false;
boolean kondisiPh = false;
int val;
static int counterSiram = 0;

unsigned long lastLogTime = 0;
int logInterval = 0.2*60*1000;

void setup() {
  pinMode(LDR_PIN, INPUT);
  Serial.begin(SERIAL_DEBUG_BAUD);
  initialWifi();
  myservo.attach(SERVO_PIN,500,2400);
  dht.setup (DHT_PIN, DHTesp:: DHT22);
  pinMode(relayPenyiramAir, OUTPUT);
}

void loop()
{
  int analogValue = analogRead(LDR_PIN);
  float voltage = analogValue / 4095. * 5;
  float resistance = 2000 * voltage / (1 - voltage / 5);
  // float lux = (pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA))) *1.8118;
  float lux = (pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA)));
  
  Serial.print("lux : ");
  Serial.print(lux);

  TempAndHumidity lastValues = dht.getTempAndHumidity();
  float temp = lastValues.temperature;
  float hum = lastValues.humidity;
  Serial.printf("   Temperature : %.2f %s", temp, "'C");
  Serial.printf("   Humidity: %.1f %s", hum, "%");


  //logic kondisi LDR mix DHT
  if (temp < 20 && hum > 85 && lux < 1750) {
    myservo.write(90);
    isRoofOpen = false;
    Serial.println ("Status Atap : Tutup\n");
    // digitalWrite(relayBohlam, HIGH);
  }
  else{
    myservo.write(0);
    isRoofOpen = true;
    Serial.println ("Status Atap: Buka\n");
    // digitalWrite(relayBohlam, LOW);
  }


  // logic ph sensor
  val = analogRead(PH_PIN);            // reads the value of the potentiometer (value between 0 and 1023)
  val = map(val, 0, 1023, 0, 14); 
  if (val <6 ) {   
    kondisiPh = false;
    Serial.println ("Info PH : need Kapur\n");
    digitalWrite(relayPenyiramAir, HIGH);
  }
  else {   
    kondisiPh = true;
    Serial.println ("Info PH: Normal\n");
    digitalWrite(relayPenyiramAir, LOW);
  }

// koneksi kembali Wifi, 
  if(WiFi.status() !=WL_CONNECTED) {
  reconnect();
  return;
    }

//koneksi kembali Thingsboard
  if (!tb.connected()){
    Serial.print ("sambung ke: ");
    Serial.print (THINGSBOARD_SERVER);
    Serial.print ("dgn token ");
    Serial.println (THINGSBOARD_ACCESTOKEN);
    }
  if(!tb.connect(THINGSBOARD_SERVER, THINGSBOARD_ACCESTOKEN)){
    Serial.println("kesalahan koneksi");
    return;
  }

unsigned long currentLogTime = millis();
if (currentLogTime - lastLogTime > logInterval){
  lastLogTime = currentLogTime;
  Serial.println();
  Serial.print("kirim data...");
  }
  if(isnan(hum) || isnan(temp)) {
  Serial.println("DHT salah baca pak!");
  } 
  if (isnan(lux)) {
  Serial.println("LDR salah baca pak!");
  }
  else {
// kirim nilai temp dan hum
  tb.sendTelemetryFloat("temperature",temp);
  tb.sendTelemetryFloat("humidity", hum);
  tb.sendTelemetryFloat("lux",lux);
  tb.sendTelemetryBool("isroofopen", isRoofOpen);
  tb.sendTelemetryString("ROOF STATUS", (isRoofOpen? "ROOF OPEN" : "ROOF CLOSE"));
  tb.sendTelemetryBool("kondisiPH", kondisiPh);
  tb.sendTelemetryString("PH STATUS", (kondisiPh? "NORMAL" : "NEED KAPUR"));

  Serial.println("Sending data selesai");
  }

  tb.loop();

  delay(1000);
}

void initialWifi()
{
  Serial.println("Connecting to AP....");
  WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
  while (WiFi.status() !=WL_CONNECTED){
    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected to AP");
}

void reconnect(){
  status =WiFi.status();
  if (status = !WL_CONNECTED){
    WiFi.begin(WIFI_AP_NAME,WIFI_PASSWORD);
    while (WiFi.status() != WL_CONNECTED){
      delay(500);
      Serial.print(".");
    }
    Serial.println("Connected to AP");
  }
}