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


#include "DHTesp.h"
#include "LiquidCrystal_I2C.h"

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

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

// See https://thingsboard.io/docs/getting-started-guides/helloworld/
// to understand how to obtain an access token
#define TOKEN               "3Rj8e1uJP4fume65vmdm"


// Baud rate for debug serial
#define SERIAL_DEBUG_BAUD   115200
//define sound speed in cm/uS
#define SOUND_SPEED 0.034

const byte trigPin = 32;
const byte echoPin = 35;

const byte DHT_PIN = 15;
const byte DRAIN_PIN = 26; //LED Biru
const byte CHILLER_PIN = 27;//LED Merah
String chillerState = "";
String drainState = "";

// LED Indicator in ThingsBoard
int ledState[3];

long duration;
float distanceCm;
float ketinggianAir;



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");
  }
}

void setup() {
  // initialize serial for debugging
  Serial.begin(SERIAL_DEBUG_BAUD);
  Serial.println();
  
  InitWiFi();
  
  dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
  
  lcd.init();
  lcd.backlight();

  lcd.setCursor(1, 0);
  lcd.print("==INDOBOT ACADEMY==");
  lcd.setCursor(3, 1);
  lcd.print("Penyetabil Suhu");
  lcd.setCursor(3, 2);
  lcd.print("Budidaya Udang");
  lcd.setCursor(7, 3);
  lcd.print("Vaname");
  delay(10000);
  lcd.clear();

  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input

  pinMode(DRAIN_PIN, OUTPUT);
  pinMode(CHILLER_PIN, OUTPUT);

  // Set Air Panas, Heater and Chiller OFF
  digitalWrite(DRAIN_PIN, LOW);
  digitalWrite(CHILLER_PIN, LOW);
}

void loop() {
  delay(1000);
  lcd.clear();

  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;
    }
  }

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

  // Uploads new telemetry to ThingsBoard using MQTT.
  // See https://thingsboard.io/docs/reference/mqtt-api/#telemetry-upload-api
  // for more details

  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  
  // Tinggi kolam udang vaname 1.2 meter
  // Pompa penguras berhenti jika tinggi air kolam mencapai 1/2 meter
  // Pompa pengisi berhenti jika tinggi air kolam mencapai 1 meter

  // Calculate the distance
  distanceCm = duration * SOUND_SPEED / 2;
 // ketinggianAir = 120 - distanceCm;
   ketinggianAir =distanceCm ; //simulasi
  TempAndHumidity data = dhtSensor.getTempAndHumidity();

  // Kondisi temperatur air kolam
  if (data.temperature < 26 )  {
     if (ketinggianAir >= 50) { 
      digitalWrite(DRAIN_PIN, HIGH);  ledState[1] = 1;
      digitalWrite(CHILLER_PIN, HIGH); ledState[2] = 1;

    drainState = "ON";
    chillerState = "ON";
   }
  else if(ketinggianAir <50) {
    digitalWrite(DRAIN_PIN, LOW);  ledState[1] = 0;
    digitalWrite(CHILLER_PIN, HIGH); ledState[2] = 1;
    chillerState = "ON";
    drainState = "OFF";
   }
   }
  if (data.temperature >= 26 && data.temperature <= 30) {
    if(ketinggianAir <50) {
    digitalWrite(DRAIN_PIN, LOW);   ledState[1] = 0;
    digitalWrite(CHILLER_PIN,HIGH); ledState[2] = 1;
    chillerState = "ON";
     drainState = "OFF";
    }
    else if ((ketinggianAir >=50) && (ketinggianAir <100)){
    digitalWrite(DRAIN_PIN, LOW);   ledState[1] = 0;
    digitalWrite(CHILLER_PIN, LOW); ledState[2] = 0;
    chillerState = "OFF";
     drainState = "OFF";
    }
   else if(ketinggianAir >=100) {
    digitalWrite(DRAIN_PIN, HIGH);   ledState[1] = 1;
    digitalWrite(CHILLER_PIN, LOW); ledState[2] = 0;
    chillerState = "OFF";
     drainState = "ON";
    }
   }
if (data.temperature > 30 && ketinggianAir < 50) {
    digitalWrite(DRAIN_PIN, LOW);     ledState[1] = 0;
    digitalWrite(CHILLER_PIN, HIGH);  ledState[2] = 1;
    chillerState = "ON";
    drainState = "OFF";
  }
if (data.temperature > 30 && ketinggianAir >= 50) {
    digitalWrite(DRAIN_PIN, HIGH);     ledState[1] = 1;
    digitalWrite(CHILLER_PIN, HIGH);  ledState[2] = 1;
    chillerState = "ON";
    drainState = "ON";
  }

  tb.sendTelemetryFloat("temperature", data.temperature);
  tb.sendTelemetryFloat("thermometer", data.temperature);
  tb.sendTelemetryFloat("ketinggianAir", ketinggianAir);
  tb.sendTelemetryFloat("ketinggianAirMaps", ketinggianAir);

  // Rumah (-7.0678957,107.7074779)
  // Rumah saya(3.504826,98.634351)
  tb.sendTelemetryFloat("lat", 3.504826);
  tb.sendTelemetryFloat("long", 98.634351);

  // LED Indicator in ThingsBoard
  tb.sendTelemetryInt("led1", ledState[0]);
  tb.sendTelemetryInt("led2", ledState[1]);
  tb.sendTelemetryInt("led3", ledState[2]);


  // Serial Visualization
  Serial.print("Suhu (°C): ");
  Serial.print(data.temperature);
  Serial.print(heaterState);
  Serial.print(", Chiller: ");
  Serial.print(chillerState);
  Serial.print(", Drain: ");
  Serial.print(drainState);
  Serial.print(", Ketinggian Air (Cm): ");
  Serial.println(ketinggianAir);

  tb.loop();
}