#define BLYNK_TEMPLATE_ID           "Enter Template ID"
#define BLYNK_TEMPLATE_NAME         "Enter Template Name"
#define BLYNK_AUTH_TOKEN            "Enter Auth Token"
#define BLYNK_PRINT Serial

#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <HTTPClient.h>

// WiFi credentials
const char* ssid = "Enter SSID";
const char* password = "Enter Password";

// Pin definitions
#define WATER_SENSOR_PIN 32  // Analog pin for water sensor

// Water sensor threshold
#define WATER_THRESHOLD 1000  // Adjust based on your sensor's readings

// Make.com webhook URL for notifications
const char* makeWebhookUrl = "Enter Webhook URL";

// Variables
bool alarmEnabled = false;
bool waterDetected = false;
bool notificationSent = false;
unsigned long lastCheckTime = 0;
const unsigned long CHECK_INTERVAL = 5000;  // Check every 5 seconds

// Add this variable to track previous water state
bool previousWaterState = false;

// This function will be called every time V3 changes
BLYNK_WRITE(V3) {
  alarmEnabled = param.asInt();
  Serial.print("Alarm status changed to: ");
  Serial.println(alarmEnabled ? "ON" : "OFF");
}

void setup() {
  Serial.begin(115200);
  Serial.println("\nStarting Dog Water Monitor");
  
  // Connect to WiFi
  Serial.print("Connecting to WiFi");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWiFi Connected!");

  // Connect to Blynk
  Serial.print("Connecting to Blynk...");
  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, "");
  Serial.println("Connected!");

  // Get and send initial water status
  int initialWaterLevel = analogRead(WATER_SENSOR_PIN);
  waterDetected = (initialWaterLevel > WATER_THRESHOLD);
  previousWaterState = waterDetected;  // Set initial previous state
  
  // Send initial status to Blynk V8
  Blynk.virtualWrite(V8, waterDetected ? "Bowl is FULL" : "NOTICE! Bowl is EMPTY");
  Serial.print("Initial water status: ");
  Serial.println(waterDetected ? "FULL" : "EMPTY");
}

void loop() {
  Blynk.run();
  
  unsigned long currentTime = millis();
  
  // Check water sensor every CHECK_INTERVAL
  if (currentTime - lastCheckTime >= CHECK_INTERVAL) {
    int waterLevel = analogRead(WATER_SENSOR_PIN);
    waterDetected = (waterLevel > WATER_THRESHOLD);
    
    // Check if water state has changed
    if (waterDetected != previousWaterState) {
      // Send updated status to Blynk V8
      Blynk.virtualWrite(V8, waterDetected ? "Bowl is FULL" : "NOTICE! Bowl is EMPTY");
      Serial.print("Water status changed to: ");
      Serial.println(waterDetected ? "FULL" : "EMPTY");
      previousWaterState = waterDetected;
    }
    
    Serial.print("Water Level: ");
    Serial.print(waterLevel);
    Serial.print(" | Water Detected: ");
    Serial.print(waterDetected ? "YES" : "NO");
    Serial.print(" | Alarm Enabled: ");
    Serial.println(alarmEnabled ? "YES" : "NO");
    
    // Check conditions and send notification if needed
    if (alarmEnabled && !waterDetected && !notificationSent) {
      sendMakeNotification();
      notificationSent = true;  // Prevent spam notifications
    }
    
    // Reset notification flag if conditions change
    if (!alarmEnabled || waterDetected) {
      notificationSent = false;
    }
    
    lastCheckTime = currentTime;
  }
  
  delay(100);
}

void sendMakeNotification() {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    http.begin(makeWebhookUrl);
    http.addHeader("Content-Type", "application/json");
    
    // Create JSON payload
    String payload = "{\"alert\":\"No water detected while alarm is enabled!\"}";
    
    // Send POST request
    int httpResponseCode = http.POST(payload);
    
    if (httpResponseCode > 0) {
      Serial.print("Make.com notification sent. Response code: ");
      Serial.println(httpResponseCode);
    } else {
      Serial.print("Error sending notification. Error code: ");
      Serial.println(httpResponseCode);
    }
    
    http.end();
  }
} 