#include <WiFi.h>
#include <HTTPClient.h>
#include "LiquidCrystal_I2C.h"
#include "DHTesp.h"
#include <RTClib.h>
#include <ArduinoJson.h>
#include <ESP32Servo.h>


const char* ssid = "Wokwi-GUEST";
const char* password = "";
String server = "https://api.thingspeak.com/update?api_key=";
String serverGetServoValue = "https://api.thingspeak.com/channels/2759396/fields/3/last.json?api_key=HSGYRXPQD6YYVEAX";
String fieldsuhu = "&field1=";
String fieldkelembaban = "&field2=";
String apiKey = "FD598R0GHO3FACH3";


LiquidCrystal_I2C LCD(0x27, 16, 2);
DHTesp dhtSensor;
RTC_DS1307 rtc;
Servo myServo;


unsigned long previousSendTime = 0;
unsigned long previousGetTime = 0;
const unsigned long sendInterval = 15000; 
const unsigned long getInterval = 1000;  

struct DHTDto {
  float TEMP;
  float HUM;
};

DHTDto dataSensorDHT;
void setup() {
  Serial.begin(9600);
  LCD.init();
  LCD.backlight();
  myServo.attach(14); // Pin servo
  
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    LCD.setCursor(0, 0);LCD.print("Connecting. ");
    delay(100);
    LCD.clear();
    LCD.setCursor(0, 0);LCD.print("Connecting.. ");
    delay(100);
    LCD.clear();
    LCD.setCursor(0, 0);LCD.print("Connecting...");
    delay(100);
    LCD.clear();
    Serial.println("Connecting to WiFi...");
  }
  LCD.setCursor(0, 0);
  LCD.print("Wifi Connected");  
  Serial.println("Wifi Connected");
  delay(1000);

  dhtSensor.setup(15, DHTesp::DHT22);
  LCD.clear();
  Wire.begin();
  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  
  if (!rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  LCD.setCursor(0, 0);LCD.print("RTC is running");  
  delay(1000);
  LCD.clear();
  
  LCD.setCursor(0, 0);LCD.print("Testing servo");

  // for(int posDegrees = 0; posDegrees <= 180; posDegrees++) {
  //   myServo.write(posDegrees);
  //   LCD.setCursor(0, 1);LCD.print("Degr : ");
  //   LCD.setCursor(6, 1);LCD.print(posDegrees);
  //   LCD.setCursor(12, 1);LCD.print("*");
  //   delay(5);
  // }
  
  // LCD.clear();
  // for(int posDegrees = 180; posDegrees >= 0; posDegrees--) {
  //   myServo.write(posDegrees);
  //   LCD.setCursor(0, 1);LCD.print("Degr : ");
  //   LCD.setCursor(6, 1);LCD.print(posDegrees);
  //   LCD.setCursor(12, 1);LCD.print("*");
  //   delay(5);
  // }
  dataSensorDHT.TEMP = 0.0;
  dataSensorDHT.HUM = 0.0;
  LCD.clear();
  // getDataFromThingSpeak(dataSensorDHT);

}

void loop() {
  unsigned long currentMillis = millis();
    // Task 1: Kirim data ke ThingSpeak setiap 15 detik
  
  if (currentMillis - previousSendTime >= sendInterval) {
    dataSensorDHT = sendDataToThingSpeak();
    previousSendTime = currentMillis;
  }

  // Task 2: Ambil data servo setiap 1 detik
  if (currentMillis - previousGetTime >= getInterval) {
    getDataFromThingSpeak(dataSensorDHT);
    previousGetTime = currentMillis;
  }
}

DHTDto sendDataToThingSpeak() {
    TempAndHumidity data = dhtSensor.getTempAndHumidity();
    float t = data.temperature;
    float h = data.humidity;

    DHTDto mydata ;
    mydata.TEMP = t;
    mydata.HUM = h;

    if (isnan(h) || isnan(t)) {
      Serial.println("Failed to read from DHT sensor!");
      LCD.setCursor(0, 0);LCD.print("Failed to read DHT!");  
    } else {
      LCD.setCursor(0, 1);LCD.print("Temp : ");
      LCD.setCursor(6, 1);LCD.print(t);
      LCD.setCursor(12, 1);LCD.print("C'");
      LCD.setCursor(0, 2);LCD.print("Humd : ");
      LCD.setCursor(6, 2);LCD.print(h);
      LCD.setCursor(12, 2);LCD.print("RH");
      Serial.println(" ");
      Serial.println("========================= POST =================================");

      String url = server + apiKey + fieldsuhu + String(t) + fieldkelembaban + String(h);
      Serial.println(url);

      if (WiFi.status() == WL_CONNECTED) {
        HTTPClient http1;
        Serial.println("[POST] Start POST data to ThingSpeak");
        http1.begin(url); 
        int httpCode = http1.GET();
        if (httpCode > 0) {
          String payload = http1.getString();
          Serial.print("[POST] POS successful");
          Serial.print(" Response: ");
          Serial.print(payload);
        } else {
          Serial.println("[POST] Unexpected error");
        }
      Serial.println(" ");
      Serial.println("========================= POST =================================");
        http1.end();
      }
    }
    return mydata;
}