#include <DHT.h>
#include <ESP32Servo.h> 
#include <LiquidCrystal_I2C.h>
#include <GyverTM1637.h>
#include <RTClib.h>

#define DHTPIN 25
#define DHTTYPE DHT22
#define pinServo 17
#define buzzerPin 16
#define CLK 18
#define DIO 15

#define tempThresholdHigh 40
#define tempThresholdLow 10
#define humidityThresholdLow 50
#define humidityThresholdHigh 70

#define servoOpenPosition 180
#define servoClosePosition 0

GyverTM1637 disp(CLK, DIO);
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27, 20, 4);
DHT dht(DHTPIN, DHT22);
Servo myservo;

void setup() {
  Serial.begin(115200);
  pinMode(buzzerPin, OUTPUT);
  myservo.attach(pinServo);
  myservo.write(servoClosePosition);
  dht.begin();
  disp.clear();
  disp.brightness(7);
  disp.point(1);
  rtc.begin();
  lcd.init();
  lcd.backlight();
}

void loop() {
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  DateTime now = rtc.now();
  int currentHour = now.hour();
  int currentMinute = now.minute();

  // แสดงค่าความชื้นและอุณหภูมิบนจอ LCD
  lcd.setCursor(0, 0);
  lcd.print("Temp = ");
  lcd.print(t);
  lcd.setCursor(0, 1);
  lcd.print("Humidity = ");
  lcd.print(h);

  // เงื่อนไขควบคุมเซอร์โว
  if ((t > tempThresholdHigh && h < humidityThresholdLow) ||      // เงื่อนไข 1
      (currentHour == 8 && currentMinute >= 0 && currentMinute < 10) ||   // เงื่อนไข 2
      (currentHour == 16 && currentMinute >= 0 && currentMinute < 10)) { // เงื่อนไข 3
    openSprinkler();
  } else if (!(t > tempThresholdHigh && h < humidityThresholdLow) &&
             !(currentHour == 8 && currentMinute >= 0 && currentMinute < 10) &&
             !(currentHour == 16 && currentMinute >= 0 && currentMinute < 10)) {
    closeSprinkler();
  }

  // เงื่อนไขควบคุมบัซเซอร์
  if ((t > tempThresholdHigh && h < humidityThresholdLow) || // เงื่อนไข 1
      (h < humidityThresholdLow) ||                          // เงื่อนไข 2
      (h > humidityThresholdHigh) ||                         // เงื่อนไข 3
      (t > tempThresholdHigh) ||                             // เงื่อนไข 4
      (t < tempThresholdLow)) {                              // เงื่อนไข 5
    tone(buzzerPin, 1000); // เปิดเสียงบัซเซอร์
  } else {
    noTone(buzzerPin); // ปิดเสียงบัซเซอร์
  }

  dispTime();
  dispSec();
}

void dispSec(void) {
  disp.point(1);
  delay(1000);
  disp.point(0);
  delay(1000);
}

void dispTime(void) {
  DateTime now = rtc.now();
  byte hrs = now.hour();
  byte mins = now.minute();
  disp.displayClock(hrs, mins);
}

void openSprinkler() {
  myservo.write(servoOpenPosition);
}

void closeSprinkler() {
  myservo.write(servoClosePosition);
}
GND5VSDASCLSQWRTCDS1307+
4-Digit Display
NOCOMNCVCCGNDINLED1PWRRelay Module