#define BLYNK_TEMPLATE_ID "TMPL3xOPT0mp5"
#define BLYNK_TEMPLATE_NAME "SOIL NUTRIENT MANAGEMENT"
#define BLYNK_AUTH_TOKEN "n73DP-iyPHmPop9IEiuNqUIqVtYkg-2q"
#define BLYNK_PRINT Serial

#include <DHTesp.h>
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <ESP32Servo.h>

// Blynk and WiFi details
char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "Wokwi-GUEST";
char pass[] = "";

// Pin definitions
int dhtPin = 13;
int nitro = 34;
int phos = 35;
int potas = 32;
int servoPin1 = 25; // Servo pin 1
int servoPin2 = 26; // Servo pin 2

// Thresholds
const int temperatureThreshold = 24; // Temperature threshold in degrees Celsius
const int phosphorusThreshold = 20;  // Phosphorus threshold in percentage

struct previousValues {
  int temperature;
  int humidity;
  int nitro;
  int phos;
  int potas;
};

previousValues potValues = {0, 0, 0, 0, 0};
DHTesp dht;
Servo servo1; // Servo object for window 1
Servo servo2; // Servo object for window 2

BLYNK_WRITE(V0) {
  // Handle virtual pin 0 write
}

BLYNK_WRITE(V1) {
  // Handle virtual pin 1 write
}

BLYNK_WRITE(V2) {
  // Handle virtual pin 2 write
}

BLYNK_WRITE(V3) {
  // Handle virtual pin 3 write
}

BLYNK_WRITE(V4) {
  // Handle virtual pin 4 write
}

void setup() {
  Serial.begin(9600);
  Serial.print("Connecting to WiFi");
  WiFi.begin(ssid, pass, 6);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" Connected!");
  Blynk.begin(auth, ssid, pass); 

  dht.setup(dhtPin, DHTesp::DHT22);
  pinMode(nitro, INPUT);
  pinMode(phos, INPUT);
  pinMode(potas, INPUT);

  // Attach the servos
  servo1.attach(servoPin1);
  servo2.attach(servoPin2);
}

void loop() {
  Blynk.run();

  TempAndHumidity dhtData = dht.getTempAndHumidity();
  float temperature = dhtData.temperature;
  float humidity = dhtData.humidity;
  int nitrogenValue = analogRead(nitro);
  float phosphorusValue = analogRead(phos) / 4095.0 * 100; // Calculate phosphorus percentage
  float potassiumValue = analogRead(potas) / 4095.0 * 100; // Calculate potassium percentage

  if (potValues.temperature != temperature)
    Blynk.virtualWrite(V0, temperature);
  if (potValues.humidity != humidity)
    Blynk.virtualWrite(V1, humidity);
  if (potValues.nitro != nitrogenValue)
    Blynk.virtualWrite(V2, nitrogenValue / 4095.0 * 100);
  if (potValues.phos != phosphorusValue)
    Blynk.virtualWrite(V3, phosphorusValue);
  if (potValues.potas != potassiumValue)
    Blynk.virtualWrite(V4, potassiumValue);

  potValues = {temperature, humidity, (int)(nitrogenValue / 4095.0 * 100), (int)phosphorusValue, (int)potassiumValue};

  // Servo control based on temperature and phosphorus threshold
  if (temperature >= temperatureThreshold && phosphorusValue >= phosphorusThreshold) {
    servo1.write(0); // Open window 1
    servo2.write(0); // Open window 2
  } else {
    servo1.write(90); // Close window 1
    servo2.write(90); // Close window 2
  }

  delay(2000);
}