// Wajib disertakan untuk komunikasi dengan 
// web server (Blynk)
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

// Tidak Wajib, tergantung dari perangkat kerasnya
#include "DHTesp.h"
#include <LiquidCrystal_I2C.h>

#define ECHO_PIN 12
#define TRIG_PIN 13

const int DHT_PIN = 15;
LiquidCrystal_I2C lcd(0x27, 16, 2);

DHTesp dhtSensor;

// Alamat Blynk, diambil dari web server
#define BLYNK_TEMPLATE_ID "TMPL6Th7sUe_J"
#define BLYNK_TEMPLATE_NAME "Monitoring Kondisi Air Laut"
#define BLYNK_AUTH_TOKEN "YLGxQ_vS1ZuohnUUS7_D1HtDxc72IqtE"

// Komunikasi wifi yang disediakan wokwi
char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "Wokwi-GUEST";
char pass[] = "";

BlynkTimer timer;

void baca_sensor_jarak(){
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  int duration = pulseIn(ECHO_PIN, HIGH);
  float distance = duration * 0.034 / 2;
  delay(100);

  if (distance > 250){
    lcd.setCursor (0,0);
    lcd.print("Cm. Air :");
    lcd.println(distance);
    lcd.setCursor (0,1);
    lcd.print("Air Normal");     
    Blynk.virtualWrite(V0, "Ketinggian Air Normal : "+String(distance)+" CM ");   
    Blynk.virtualWrite(V7, "Alaram Tidak Aktif");
    digitalWrite(2, LOW);
}

if (distance >=200 && distance < 250){
  lcd.setCursor (0,0);
    lcd.print("Cm Air :");
    lcd.println(distance);
    lcd.setCursor (0,1);
    lcd.print("Air Mulai Pasang");
    Blynk.virtualWrite(V0, "Air Mulai Pasang : "+String(distance)+" CM ");
    Blynk.virtualWrite(V7, "Alaram Tidak Aktif");
    digitalWrite(2, LOW);
}

if (distance <200){
   lcd.setCursor (0,0);
    lcd.print("Cm. Air :");
    lcd.println(distance);
    lcd.setCursor (0,1);
    lcd.print("Air Pasang");
    Blynk.virtualWrite(V0, "Air Pasang : "+String(distance)+" CM ");
    Blynk.virtualWrite(V7, "Alaram Aktif");
    digitalWrite(2, HIGH);
}
  delay(3000);
}

void baca_Laju_air (){
  int input_value = analogRead (32);
  int output_value = map(input_value, 0, 4095, 0, 300);
  lcd.setCursor(0,0);
  lcd.print("Laju Air : ");
  lcd.println(output_value);

  if (output_value > 250){
    lcd.setCursor(0,1);    
    lcd.print("Arus Air Tinggi ");
    Blynk.virtualWrite(V1, "Arus Air Tinggi : "+String(output_value)+" DPL/menit ");
    Blynk.virtualWrite(V7, "Alaram Aktif");
    digitalWrite(2, HIGH);
  }
  if (output_value < 250){
    lcd.setCursor(0,1);
    lcd.print("Arus Air Normal ");    
    Blynk.virtualWrite(V7, "Alaram Tidak Aktif");
    Blynk.virtualWrite(V1, "Arus Air Normal : "+String(output_value)+" DPL/menit "); 
    digitalWrite(2, LOW);
  }
  delay(3000);
}

void baca_Keruh_air (){
  int input_value = analogRead (34);
  int output_value = map(input_value, 0, 4095, 0, 50);
  lcd.setCursor(0,0);
  lcd.print("Kon. Air : ");
  lcd.println(output_value);

  if (output_value > 25){
    lcd.setCursor(0,1);    
    lcd.print("Air Tidak Keruh ");
    Blynk.virtualWrite(V2, "Kondisi Air Tidak Keruh : "+String(output_value)+" NTU ");
    Blynk.virtualWrite(V7, "Alaram Tidak Aktif");
    digitalWrite(2, LOW);
  }
  if (output_value < 25){
    lcd.setCursor(0,1);
    lcd.print("Air Keruh       "); 
    Blynk.virtualWrite(V2, "Kondisi Air Keruh : "+String(output_value)+" NTU ");    
    Blynk.virtualWrite(V7, "Alaram Aktif");
    digitalWrite(2, HIGH);
  }
  delay(3000);
}

void baca_Oksigen_air (){
  int input_value = analogRead (33);
  int output_value = map(input_value, 0, 4095, 0, 9);
  lcd.setCursor(0,0);
  lcd.print("Oksigen Air : ");
  lcd.println(output_value);

  if (output_value > 6){
    lcd.setCursor(0,1);    
    lcd.print("Tidak Tercemar  ");
    Blynk.virtualWrite(V3, "Kondisi Air Tidak Tercemar : "+String(output_value)+" ML ");
    Blynk.virtualWrite(V7, "Alaram Tidak Aktif");
    digitalWrite(2, LOW); 
  }
  if (output_value >= 4 && output_value <= 6){
    lcd.setCursor(0,1);
    lcd.print("Tercemar Ringan "); 
    Blynk.virtualWrite(V3, "Kondisi Air Tercemar Ringan : "+String(output_value)+" ML ");    
    Blynk.virtualWrite(V7, "Alaram Tidak Aktif");
    digitalWrite(2, LOW); 
  }
  if (output_value >= 2 && output_value <= 4){
    lcd.setCursor(0,1);
    lcd.print("Tercemar Sedang ");  
    Blynk.virtualWrite(V3, "Kondisi Air Tercemar Sedang: "+String(output_value)+" ML ");   
    Blynk.virtualWrite(V7, "Alaram Tidak Aktif");
    digitalWrite(2, LOW); 
  }
  if (output_value < 2){
    lcd.setCursor(0,1);
    lcd.print("Tercemar Berat  "); 
    Blynk.virtualWrite(V3, "Kondisi Air Tercemar Berat: "+String(output_value)+" ML ");    
    Blynk.virtualWrite(V7, "Alaram Aktif");
    digitalWrite(2, HIGH); 
  }
  delay(3000);
}

void baca_pH_air (){
  int input_value = analogRead (35);
  int output_value = map(input_value, 0, 4095, 0, 14);
  lcd.setCursor(0,0);
  lcd.print("PH Air : ");
  lcd.println(output_value);

  if (output_value == 7){
    lcd.setCursor(0,1);    
    lcd.print("Normal          ");
    Blynk.virtualWrite(V4, "Kondisi PH Air Normal : "+String(output_value));
    Blynk.virtualWrite(V7, "Alaram Tidak Aktif");
    digitalWrite(2, LOW); 
  }
  if (output_value > 7){
    lcd.setCursor(0,1);
    lcd.print("Basa            ");   
    Blynk.virtualWrite(V4, "Kondisi PH Air Basa : "+String(output_value));
    Blynk.virtualWrite(V7, "Alaram Aktif");
    digitalWrite(2, HIGH);  
  }
  if (output_value < 7){
    lcd.setCursor(0,1);
    lcd.print("Asam            ");     
    Blynk.virtualWrite(V4, "Kondisi PH Air Asam : "+String(output_value));  
    Blynk.virtualWrite(V7, "Alaram Aktif");
    digitalWrite(2, HIGH); 
  }
  delay(3000);
}

void setup() {
  Blynk.begin(auth, ssid, pass);
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  pinMode(2, OUTPUT);
  timer.setInterval(3000L, sendSensor);
  dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
  lcd.init();
  lcd.backlight();   
}

void loop() {    
  Blynk.run();
  timer.run(); 

  lcd.clear();
  baca_sensor_jarak();
  lcd.clear();
  sendSensor();
  lcd.clear();
  baca_pH_air ();
  lcd.clear();
  baca_Keruh_air ();
  lcd.clear();
  baca_Laju_air ();
  lcd.clear();
  baca_Oksigen_air ();

  delay(1000);  
}
  
void sendSensor(){
  TempAndHumidity  data = dhtSensor.getTempAndHumidity();
  lcd.setCursor(0, 0);
  lcd.print("Temp Air = ");  
  lcd.print(data.temperature);
  lcd.print(" C");
  Blynk.virtualWrite(V5, data.temperature);
  lcd.setCursor(0, 1);
  lcd.print("Hum Air = "); 
  lcd.print(data.humidity);
  lcd.print(" %");  
  Blynk.virtualWrite(V6, data.humidity); 
  delay(3000);  
}