/*
  Smart Garden IoT — NodeMCU ESP8266 + Blynk
  Program pelatihan Abdimas IoT 2024 (Telkom University x SMK Telkom Bandung).

  CATATAN KEAMANAN: token Blynk, nama WiFi, dan password sudah DIHAPUS dari versi publik ini.
  Isi sendiri nilai YOUR_... di bawah dengan data milik Anda. Jangan pernah mengunggah token/password asli.
*/

//BLYNK CONNECT TO ESP8266
#define BLYNK_TEMPLATE_ID "YOUR_TEMPLATE_ID"
#define BLYNK_TEMPLATE_NAME "Smart Garden"
#define BLYNK_AUTH_TOKEN "YOUR_BLYNK_AUTH_TOKEN"

//Library
#include <DallasTemperature.h> // Sensor Temperatur Untuk Sensor DS18B20
#include <OneWire.h> // Akses sensor suhu 1 kabel, memori
#include <DHT.h> // Sensor Mengukur Suhu Untuk DHT22
#include <LiquidCrystal_I2C.h> // LCD 16x2
#include <Blynk.h> // Bylnk
#include <ESP8266WiFi.h> //Nodemcu esp8266
#include <BlynkSimpleEsp8266.h>
#include <TimeLib.h>
#include <WidgetRTC.h> // Untuk Waktu

//PIN yang digunakan
#define BLYNK_PRINT Serial
#define ONE_WIRE_BUS D5
#define DHTPIN D3
#define DHTTYPE DHT11
#define pump D7
#define lampu D4

DHT dht(DHTPIN, DHTTYPE); //DHT22
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire); //Sensor Temperatur
LiquidCrystal_I2C lcd(0x27, 16, 2); //LCD

//Waktu
BlynkTimer timer;
WidgetRTC rtc;

//Kondisi Awal
const int AirValue = 620;
const int WaterValue = 310;
int soilMoistureValue = 0;
int soilmoist=0;
int humi,temp,fp,sistem,tempu;
int kondisip, kondisil;
int buttonState;

//SET POINT KELEMBAPAN TANAH
int SP_LOW=40;
int SP_HIGH=60;

//Connect ke jaringan yang digunakan (ISI DENGAN DATA ANDA)
char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "YOUR_WIFI_SSID";
char pass[] = "YOUR_WIFI_PASSWORD";
//==========================================
//Konfigurasi dari blynk untuk menganti mode yang digunakan pada sistem
BLYNK_WRITE(V4){
  buttonState = param.asInt();
  if(buttonState==HIGH){
    sistem=1;//automatic
    fp=0;
  }
  else if(buttonState==LOW){
    sistem=0;//manual
  }
}
//==========================================
//Mengatur Hidup dan Mati Pompa Air (Mode Manual)
BLYNK_WRITE(V5){
  buttonState = param.asInt();
  if(sistem==0){
    if(buttonState==LOW){
      digitalWrite(pump,HIGH);
      lcd.setCursor(13,1);
      lcd.print("OFF ");
      kondisip=0;
      }
    else if(buttonState==HIGH){
      digitalWrite(pump,LOW);
      lcd.setCursor(13,1);
      lcd.print("ON ");
      kondisip=1;
      }
  }
}
//=====================================
//Mengatur Hidup dan Mati Lampu
BLYNK_WRITE(V6){
  buttonState = param.asInt();
    if(buttonState==LOW){
      digitalWrite(lampu,HIGH);
      kondisil=0;
      }
    else if(buttonState==HIGH){
      digitalWrite(lampu,LOW);
      kondisil=1;
      }
}
//=====================================

// Menampilkan Waktu
void clockDisplay()
{

  String currentTime = String(hour()) + ":" + minute() + ":" + second();
  String currentDate = String(day()) + "/" + month() + "/" + year();
  Serial.print("Current time: ");
  Serial.print(currentTime);
  Serial.print(" ");
  Serial.print(currentDate);
  Serial.println();

  // Mengirim Data Waktu ke Blynk
  Blynk.virtualWrite(V10, currentTime);

  //Lampu Hidup pada pukul 17.30
  if (hour()==22 && minute()==23){
    digitalWrite(lampu,LOW); //LAMPU HIDUP
    kondisil=1;
  }

  //Lampu Mati pada pukul 06.50
  else if (hour()==22 && minute()==25){
    digitalWrite(lampu,HIGH); //LAMPU MATI
    kondisil=0;
  }
}

BLYNK_CONNECTED() {
  // Synchronize time on connection
  rtc.begin();
}

void setup(void)
{
  // LCD Konfigurasi
  lcd.begin(16,2);
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.print("  SMART GARDEN  ");
  lcd.setCursor(0, 1);
  lcd.print("   NODEMCU  ");

  Serial.begin(9600);
  sensors.begin(); // Sensor Temperatur
  dht.begin();   // Sensor DHT22

  // Konfigurasi Pompa Air
  pinMode(pump,OUTPUT);
  digitalWrite(pump,LOW);
  delay(1200);
  digitalWrite(pump,HIGH);
  delay(1200);
  digitalWrite(pump,LOW);
  delay(1200);
  digitalWrite(pump,HIGH);
  delay(1200);

  // Konfigurasi Lampu
  pinMode(lampu,OUTPUT);
  digitalWrite(lampu,LOW);
  delay(1200);
  digitalWrite(lampu,HIGH);
  delay(1200);
  digitalWrite(lampu,LOW);
  delay(1200);
  digitalWrite(lampu,HIGH);

  // Menyambungkan ke jaringan yang digunakan
  Blynk.begin(auth, ssid, pass);
  delay(1500);

  setSyncInterval(10 * 60); // Sync interval

  // Display digital clock every 10 seconds
  timer.setInterval(1000L, clockDisplay);

  // Konfigurasi tampilan LCD
  lcd.clear();
  lcd.print("Mst:   %, T:   C");
  lcd.setCursor(0, 1);
  lcd.print("Hum:   %, P: OFF");

  sistem=1;
}
//=====================================
void loop(void)
{
  Blynk.run();
  timer.run();
  sensors.requestTemperatures();
  temp=sensors.getTempCByIndex(0);
  Serial.print("Temperatur : ");
  Serial.println(temp);
  lcd.setCursor(12,0);
  lcd.print(temp);
  soilMoistureValue = analogRead(A0);
  soilmoist= map(soilMoistureValue, AirValue, WaterValue, 0, 100);
  if(soilmoist >= 100)
    {
      soilmoist=100;
    }
  else if(soilmoist <=0)
    {
      soilmoist=0;
    }
  Serial.print("Soil Moisture : ");
  Serial.print(soilmoist);
  Serial.println(" %");
  Serial.print("Air Temperature : ");
  Serial.print(tempu);
  Serial.println(" C");
  lcd.setCursor(4,0);
  lcd.print(soilmoist);
  lcd.print(" ");
  humi = dht.readHumidity();
  tempu = dht.readTemperature();

  if (isnan(humi) ) {
    Serial.println("DHT22 tidak terbaca... !");
    return;
  }
  else{
  Serial.print("Humidity:");
  Serial.println(humi);
  Serial.println();
  lcd.setCursor(4,1);
  lcd.print(humi);
  }

  //Mengatur Hidup dan Mati Pompa Air (Mode Auto)
  if(sistem==1){
  if((soilmoist<SP_LOW)&&(fp==0)){
    digitalWrite(pump,LOW);
    lcd.setCursor(13,1);
    lcd.print("ON ");
    kondisip=1;
    fp=1;
  }
  else if((soilmoist>SP_HIGH)&&(fp==1)){
    digitalWrite(pump,HIGH);
    lcd.setCursor(13,1);
    lcd.print("OFF");
    kondisip=0;
    fp=0;
  }
  }
  // Konfigurasi Data yang dikirim ke Blynk
  Blynk.virtualWrite(V1, temp); //Data Sensor Temperatur Tanah
  Blynk.virtualWrite(V2,soilmoist); // Data Kelembapan Tanah
  Blynk.virtualWrite(V3,humi); // Data Kelembapan Udara
  Blynk.virtualWrite(V4,sistem); // Mengirim Kondisi Sistem
  Blynk.virtualWrite(V5,kondisip); // Mengirim Kondisi Pompa
  Blynk.virtualWrite(V6,kondisil); // Mengirim Kondisi Lampu
  Blynk.virtualWrite(V11,tempu); //Data Sensor Temperatur Udara

//Mengirimkan Kondisi Mode Sistem ke Blynk
if (sistem==1){
  Blynk.virtualWrite(V7,"MODE AUTO");
}
else if (sistem==0){
  Blynk.virtualWrite(V7,"MODE MANUAL");
}

//Mengirimkan Kondisi Pompa ke Blynk
if (kondisip==1){
  Blynk.virtualWrite(V8,"POMPA HIDUP");
}

else if (kondisip==0){
  Blynk.virtualWrite(V8,"POMPA MATI");
}

//Mengirimkan Kondisi Lampu ke Blynk
if (kondisil==1){
  Blynk.virtualWrite(V9,"LAMPU HIDUP");
}

else if (kondisil==0){
  Blynk.virtualWrite(V9,"LAMPU MATI");
}

  Serial.print("Sistem : ");
  Serial.println(sistem);
  Serial.print("fp : ");
  Serial.println(fp);

  delay(1500);
}
