#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
#include <RTClib.h>

// OLED display parameters
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Pin definitions
int ldrPin = A0;
int ledPin = 3;
int dhtPin = 2;

// DHT sensor parameters
#define DHTTYPE DHT11   // Change to DHT22 if using DHT22
DHT dht(dhtPin, DHTTYPE);

// RTC module
RTC_DS3231 rtc;

void setup() {
  // Initialize serial communication for debugging
  Serial.begin(9600);

   // Initialize OLED display
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) 
  {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.display();

  // Initialize the LDR and LED pins
  pinMode(ldrPin, INPUT);
  pinMode(ledPin, OUTPUT);

  // Initialize the DHT sensor
  dht.begin();

  // Initialize the RTC module
  if (!rtc.begin()) {
    Serial.println(F("Couldn't find RTC"));
    while (1);
  }
  if (rtc.lostPower()) {
    Serial.println(F("RTC lost power, setting the time!"));
    // Set the RTC to the current date & time
    // This line sets the RTC with an explicit date & time, adjust accordingly
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
}

void loop() {
  // Read the LDR value
  int ldrValue = analogRead(ldrPin);

  // Read humidity and temperature from the DHT sensor
  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();

  // Check if any reads failed and exit early (to try again).
  if (isnan(humidity) || isnan(temperature)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

  // Get the current time from the RTC
  DateTime now = rtc.now();

  // Clear the display
  display.clearDisplay();

  // Display the current time on the OLED
  display.setCursor(0, 0);
  display.print(now.year(), DEC);
  display.print('/');
  display.print(now.month(), DEC);
  display.print('/');
  display.print(now.day(), DEC);
  display.print(' ');
  display.print(now.hour(), DEC);
  display.print(':');
  display.print(now.minute(), DEC);
  display.print(':');
  display.print(now.second(), DEC);

  // Display the LDR value on the OLED
  display.setCursor(0, 10);
  display.print("LDR Value: ");
  display.print(ldrValue);

  // Display the temperature on the OLED
  display.setCursor(0, 20);
  display.print("Temp: ");
  display.print(temperature);
  display.print(" *C");

  // Display the humidity on the OLED
  display.setCursor(0, 30);
  display.print("Humidity: ");
  display.print(humidity);
  display.print(" %");

  display.setCursor(0, 40);
  if (digitalRead(ledPin) == HIGH) 
  {
    display.print("Light: ON");  // Display pump is on
  } 
  else 
  {
    display.print("Light: OFF");  // Display pump is off
  }
  
  // Update the display
  display.display();

  // Print the values to the serial monitor (for debugging)
  Serial.print("Time: ");
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(' ');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();
  Serial.print("LDR Value: ");
  Serial.println(ldrValue);
  Serial.print("Temperature: ");
  Serial.print(temperature);
  Serial.println(" *C");
  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.println(" %");

  // Control the LED based on the LDR value
  if (ldrValue < 500) { // Adjust the threshold value as needed
    digitalWrite(ledPin, HIGH); // Turn on the LED
  } else {
    digitalWrite(ledPin, LOW); // Turn off the LED
  }

  // Delay for a short period
  delay(125);
}
GND5VSDASCLSQWRTCDS1307+