#include <WiFi.h>
#include "ThingsBoard.h"
#include "DHTesp.h"

#define CURRENT_FIRMWARE_TITLE    "TEST"
#define CURRENT_FIRMWARE_VERSION  "1.0.0"

#define WIFI_SSID           "Wokwi-GUEST"
#define WIFI_PASSWORD       ""

#define TOKEN               "OBSPQpBneyrcXwxgE3TU"
#define THINGSBOARD_SERVER  "thingsboard.cloud"

const int DHT_PIN = 15;
#define Pendingin 18
#define Pengembunan 19
#define PompaAir 14
#define Trig 13
#define Echo 12
float jarak = 0;
float ketinggian_air = 0;
float jarakair;
#define tinggitang 25
#define GrowLight 2
#define buzzer 22

const float GAMMA = 0.7;
const float RL10 = 50;

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

void InitWiFi()
{
  Serial.println("Connecting to AP ...");
  WiFi.begin(WIFI_SSID, 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_SSID, WIFI_PASSWORD);
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }
    Serial.println("Connected to AP");
  }
}

void baca_jarak()
{
  digitalWrite(Trig, LOW);
  delayMicroseconds(2);
  digitalWrite(Trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig, LOW);

  int duration = pulseIn(Echo, HIGH);
  jarak = duration * 0.034 / 2;
  float y = (1E-06*jarak*jarak) + (1.0055*jarak) + 0.0012; //kalibrasi sensor
  ketinggian_air = constrain((tinggitang - y), 0,tinggitang);
}

void setup() {
  // initialize serial for debugging
  Serial.begin(115200);
  Serial.println();
  InitWiFi();
  dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
  pinMode(Trig, OUTPUT);
  pinMode(Echo, INPUT);
  pinMode(Pendingin, OUTPUT);
  pinMode(Pengembunan, OUTPUT);
  pinMode(PompaAir, OUTPUT);
  pinMode(GrowLight, OUTPUT);
  pinMode(buzzer, OUTPUT);
}

void loop() {
  delay(2000);

  if (WiFi.status() != WL_CONNECTED) {
    reconnect();
  }

  if (!tb.connected()) {
    // Connect to the ThingsBoard
    Serial.print("Connecting to: ");
    Serial.print(THINGSBOARD_SERVER);
    Serial.print(" with token ");
    Serial.println(TOKEN);
    if (!tb.connect(THINGSBOARD_SERVER, TOKEN)) {
      Serial.println("Failed to connect");
      return;
    }
  }

  //Read LDR
  baca_jarak();
  Serial.println("Smart Microgreen Joyoboyo Sending data...");
  int analogValue = analogRead(36);
  float voltage = analogValue * 5/4095.0;
  float resistance = 2000 * voltage / (1 - voltage / 5);
  float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
  Serial.print((String)"Vol: " + voltage);
  Serial.print((String)"| Resistansi: " + resistance);
  Serial.print((String)"| Analog Value: " + analogValue);
  Serial.print((String)"| Lux: " + lux);
  Serial.println(lux);
  tb.sendTelemetryFloat("LUX", lux);

  if (lux >= 700){
    Serial.print("Status: ");
    Serial.println("Terang");
    digitalWrite(GrowLight, LOW);
    tb.sendTelemetryInt("Lampu",0);
    Serial.println("===================> Growlight OFF");
  } else {
    Serial.print("Status: ");
    Serial.println("Gelap");
    digitalWrite(GrowLight, HIGH);
    tb.sendTelemetryInt("Lampu",1);
    Serial.println("===================> Growlight ON");
  }

  TempAndHumidity  data = dhtSensor.getTempAndHumidity();
  tb.sendTelemetryFloat("Suhu", data.temperature);
  tb.sendTelemetryFloat("Kelembaban", data.humidity);
  tb.sendTelemetryFloat("Tinggi Air", ketinggian_air);
  Serial.print("Suhu: ");
  Serial.print(data.temperature);
  Serial.print(" Kelembaban: ");
  Serial.print(data.humidity);
  Serial.print(" Ketinggian Air: ");
  Serial.print(ketinggian_air);
  Serial.println(" CM");

  if(data.temperature > 27)
  { 
      tb.sendTelemetryInt("Pendingin", 1);
      digitalWrite(Pendingin, HIGH);
      Serial.println("===================> Proses Pendinginan Media Tanam");
  }
  else if(data.temperature > 19 && data.temperature < 27 ){
      tb.sendTelemetryInt("Pendingin", 0);
      digitalWrite(Pendingin, LOW);
  }
  else if(data.temperature < 19){
    digitalWrite(GrowLight, HIGH);
    tb.sendTelemetryInt("Lampu",1);
    Serial.println("===================> Proses Penghangatan Media Tanam");
  }
  if(data.humidity < 40){ 
      tb.sendTelemetryInt("Pengembunan", 1);
      digitalWrite(Pengembunan, HIGH);
      Serial.println("===================> Proses Pengembunan Media Tanam");}
  else if(data.humidity > 40 && data.humidity < 60){ 
      tb.sendTelemetryInt("Pengembunan", 0);
      digitalWrite(Pengembunan, LOW);}

  if (ketinggian_air <= 10 && ketinggian_air > 5){
    digitalWrite(PompaAir, HIGH);
    tb.sendTelemetryInt("Pompa", 1);
    tb.sendTelemetryInt("Alarm", 0);
    Serial.println("===================> Proses Pengairan Media Tanam");
  }
  else if(ketinggian_air > 10 && ketinggian_air <= 15){
    digitalWrite(PompaAir,LOW);
    tb.sendTelemetryInt("Pompa", 0);
  }
  else if(ketinggian_air < 5){
    tone(buzzer, 1000);
    delay(100);
    noTone(buzzer);
    delay(100);
    tb.sendTelemetryInt("Alarm", 1);
    Serial.println("===================> Pompa Air tidak bekerja!");
  }

  tb.loop();
}