#if defined(ESP8266)
#include <ESP8266WiFi.h>
#elif defined(ESP32)
#include <WiFi.h>
#endif

#include "ThingsBoard.h"

#define WIFI_SSID           "Wokwi-GUEST"
#define WIFI_PASSWORD       ""
#define TOKEN               "stKVnOfJkBffH5DwWZoV"
#define THINGSBOARD_SERVER  "thingsboard.cloud"

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

// Main application loop delay
int quant = 20;
int send_delay = 2000;
int send_passed = 0;

void InitWiFi()
{
  Serial.println("Connecting to AP ...");
  // attempt to connect to WiFi network

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {

    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected to AP");
}

void reconnect() {
  // Loop until we're reconnected
  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");
  }
}

#include <ESP32Servo.h>
Servo PintuAirMasuk;
Servo Aerator;
Servo PintuAirKeluar;

#define ECHO_PIN 26
#define TRIG_PIN 25

#define RelayPinWH  4
#define RelayPinPintuAir 5
#define RelayPinAerator 27

#define LED_Biru  13
#define LED_Merah 12
#define LED_Hijau 14

#include <DHTesp.h> 
DHTesp dht;
#define DHT_PIN 15
float temperature = 0;
float humidity = 0;

float readDistanceCM() 
{
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  int duration = pulseIn(ECHO_PIN, HIGH);
  return duration * 0.034 / 2;
}

void setup()
{
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  Serial.begin(115200);

  dht.setup(DHT_PIN, DHTesp::DHT22);

  pinMode(RelayPinWH, OUTPUT);
  pinMode(RelayPinPintuAir, OUTPUT);
  
  PintuAirMasuk.attach(2);
  Aerator.attach(18);
  PintuAirKeluar.attach(21);

  digitalWrite( RelayPinPintuAir, HIGH);

  pinMode(LED_Biru, OUTPUT);
  pinMode(LED_Merah, OUTPUT);
  pinMode(LED_Hijau, OUTPUT);
    
  InitWiFi();    
}

void  loop()
{
  delay(quant);
  send_passed += quant;

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

    if (!tb.connected())
    {
    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;
      }
    }
  

  TempAndHumidity lastValues = dht.getTempAndHumidity();    
  float distance = readDistanceCM();
  
  if (send_passed > send_delay)
  {
    if (isnan(lastValues.humidity) || isnan(lastValues.temperature))
    {
      Serial.println("Failed to read from DHT sensor!");
    } 
    else 
    {
      temperature = lastValues.temperature;
      Serial.println();
      Serial.print("Sending data... ");
      Serial.print("Temperature: ");
      Serial.print(temperature);
      Serial.print("  Tinggi Air : ");
      Serial.println(readDistanceCM());
      tb.sendTelemetryFloat("temperature", temperature);
      tb.sendTelemetryFloat("tinggi air", distance);
    }
    send_passed = 0;
  }

  checkTemperature();
  tb.loop();

}

void checkTemperature()
{
    if(temperature<26)
    {
      digitalWrite( RelayPinWH, HIGH);
      PintuAirMasuk.write(0);
      digitalWrite(LED_Biru, HIGH);
      digitalWrite(LED_Merah, LOW);
      digitalWrite(LED_Hijau, LOW);
      tb.sendTelemetryString("Status Suhu Air", "Dingin");
      tb.sendTelemetryString("Pemanas Air", "Menyala");
      tb.sendTelemetryString("Pintu Air Masuk", "Tertutup");
    }
  else if(temperature>34)
  {
      digitalWrite( RelayPinWH, LOW);
      PintuAirMasuk.write(90);
      digitalWrite(LED_Biru, LOW);
      digitalWrite(LED_Merah, HIGH);
      digitalWrite(LED_Hijau, LOW);
      tb.sendTelemetryString("Status Suhu Air", "Panas");
      tb.sendTelemetryString("Pemanas Air", "Mati");
      checkTinggiAir();
  }

  else
  {
    PintuAirMasuk.write(0);
    digitalWrite( RelayPinWH, LOW);
    digitalWrite(LED_Biru, LOW);
    digitalWrite(LED_Merah, LOW);
    digitalWrite(LED_Hijau, HIGH);
    tb.sendTelemetryString("Status Suhu Air", "Normal");
    tb.sendTelemetryString("Pemanas Air", "Mati");
    tb.sendTelemetryString("Pintu Air Masuk", "Tertutup");
  }

}

void checkTinggiAir()
{
  float distance = readDistanceCM();

  if (distance>120)
  {
    PintuAirMasuk.write(90);
    tb.sendTelemetryString("Pintu Air Masuk", "Terbuka");
    PintuAirKeluar.write(90);
    tb.sendTelemetryString("Pintu Air Keluar", "Terbuka");
    digitalWrite(RelayPinAerator, HIGH);
    tb.sendTelemetryString("Aerator", "Menyala");
    Aerator.write(90);
    delay(200);
    Aerator.write(0);
    delay(200);
  }
  else
  {
    PintuAirMasuk.write(90);
    digitalWrite(RelayPinAerator, LOW);
    PintuAirKeluar.write(0);
    tb.sendTelemetryString("Pintu Air Masuk", "Terbuka");
    tb.sendTelemetryString("Pintu Air Keluar", "Tertutup");
    tb.sendTelemetryString("Aerator", "Mati");
  }

}