#define BLYNK_TEMPLATE_ID "TMPL4KEgvOB2I"
#define BLYNK_TEMPLATE_NAME "Quickstart Template"

#include <WiFi.h>
#include <Wire.h>
#include <MPU6050_tockn.h>
#include <BlynkSimpleEsp32.h>

MPU6050 mpu(Wire);

const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* auth = "SysKtqjk0MhL_2xG-ClNYZOX07XgGDee";

const int FALL_THRESHOLD = 1; // Adjust this threshold based on your accelerometer readings
const int LED_PIN = 27; // Pin for the LED to indicate fall detection

BlynkTimer timer;
bool fallDetected = false; // Flag to track if fall has been detected

// Blynk virtual pin configuration
#define VIRTUAL_PIN_NOTIFICATION V1

void setup_wifi() {
  Serial.begin(115200);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void notifyFall() {
  Blynk.logEvent("ALERT", "An Industry Fall detected!");
  Serial.println("Alert notification sent."); // Print alert notification to Serial monitor
}

void setup() {
  pinMode(LED_PIN, OUTPUT);
  setup_wifi();
  Wire.begin();
  mpu.begin();

  Blynk.begin(auth, ssid, password);

  // Setup a timer to check for falls every 5 seconds
  timer.setInterval(5000L, []() {
    mpu.update();
    int16_t accX = mpu.getAccX();
    int16_t accY = mpu.getAccY();
    int16_t accZ = mpu.getAccZ();
    float accMagnitude = sqrt(accX * accX + accY * accY + accZ * accZ);

    Serial.print("Acceleration Magnitude: ");
    Serial.println(accMagnitude);

    if (accMagnitude > FALL_THRESHOLD && !fallDetected) { // Check if fall detected and not already flagged
      Serial.println("Fall detected!");
      digitalWrite(LED_PIN, HIGH); // Turn on the LED to indicate fall detection
      Blynk.virtualWrite(VIRTUAL_PIN_NOTIFICATION, accMagnitude); // Notify Blynk app
      notifyFall(); // Trigger Blynk notification
      fallDetected = true; // Set flag to true
      delay(5000); // Wait for 5 seconds before resuming to prevent rapid fall detection
      digitalWrite(LED_PIN, LOW); // Turn off the LED
    }
  });
}

void loop() {
  Blynk.run();
  timer.run();
}