/*
 Provided By : UTS - (unique technology solution)
 Contact us for further assistance (Indrajeet Patil - +919511217526) 
*/
#define BLYNK_TEMPLATE_ID           "TMPLAhc6Dcpm"
#define BLYNK_DEVICE_NAME           "UTS"
#define BLYNK_AUTH_TOKEN            "bqtqGLkqOuV-3XQUHBfHLGTVIbMZ91Sm"
#define BLYNK_PRINT Serial

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

char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "Wokwi-GUEST";
char pass[] = "";

//===================================

#define SMS1 "sensor1"
#define SMS2 "sensor2"
#define SMS3 "sensor3"
#define SMS4 "sensor4"

const int ledPin1 = 18;
const int ledPin2 = 4;
const int ledPin3 = 2;
const int ledPin4 = 15;

const int btnPin1 = 26;
const int btnPin2 = 33;
const int btnPin3 = 27;
const int btnPin4 = 13;

const int sensor1 = 23;
const int sensor2 = 21;
const int sensor3 = 19;
const int sensor4 = 5;

const int spin = 22;

BlynkTimer timer;
void checkPhysicalButton();

int ledState1 = LOW;
int ledState2 = LOW;
int ledState3 = LOW;
int ledState4 = LOW;

int btnState1 = HIGH;
int btnState2 = HIGH;
int btnState3 = HIGH;
int btnState4 = HIGH;

bool Alarm;
bool mili = 1;

BLYNK_CONNECTED()
{
  Blynk.syncVirtual(V1);
  Blynk.syncVirtual(V2);
  Blynk.syncVirtual(V3);
  Blynk.syncVirtual(V4);
  Blynk.syncVirtual(V5);
}

BLYNK_WRITE(V1)
{
  ledState1 = param.asInt();
  digitalWrite(ledPin1, ledState1);
}

BLYNK_WRITE(V2)
{
  ledState2 = param.asInt();
  digitalWrite(ledPin2, ledState2);
}

BLYNK_WRITE(V3)
{
  ledState3 = param.asInt();
  digitalWrite(ledPin3, ledState3);
}

BLYNK_WRITE(V4)
{
  ledState4 = param.asInt();
  digitalWrite(ledPin4, ledState4);
}

BLYNK_WRITE(V5)
{
  Alarm = param.asInt();
}

void checkPhysicalButton()
{
  if (Alarm == 1)
  {
    bool SENSOR1 = !digitalRead(sensor1);
    bool SENSOR2 = !digitalRead(sensor2);
    bool SENSOR3 = !digitalRead(sensor3);
    bool SENSOR4 = !digitalRead(sensor4);

    if (SENSOR1 || SENSOR2 || SENSOR3 || SENSOR4)
    {
      if (Get_time())
      {
        if (SENSOR1)
        {
          Blynk.logEvent("uts", SMS1);
        }
        if (SENSOR2)
        {
          Blynk.logEvent("uts", SMS2);
        }
        if (SENSOR3)
        {
          Blynk.logEvent("uts", SMS3);
        }
        if (SENSOR4)
        {
          Blynk.logEvent("uts", SMS4);
        }
      }
    }
  }
  if (digitalRead(btnPin1) == LOW)
  {
    if (btnState1 != LOW)
    {
      ledState1 = !ledState1;
      digitalWrite(ledPin1, ledState1);

      Blynk.virtualWrite(V1, ledState1);
    }
    btnState1 = LOW;
  }
  else
  {
    btnState1 = HIGH;
  }

  if (digitalRead(btnPin2) == LOW)
  {
    if (btnState2 != LOW)
    {
      ledState2 = !ledState2;
      digitalWrite(ledPin2, ledState2);

      Blynk.virtualWrite(V2, ledState2);
    }
    btnState2 = LOW;
  }
  else
  {
    btnState2 = HIGH;
  }

  if (digitalRead(btnPin3) == LOW)
  {
    if (btnState3 != LOW)
    {
      ledState3 = !ledState3;
      digitalWrite(ledPin3, ledState3);

      Blynk.virtualWrite(V3, ledState3);
    }
    btnState3 = LOW;
  }
  else
  {
    btnState3 = HIGH;
  }

  if (digitalRead(btnPin4) == LOW)
  {
    if (btnState4 != LOW)
    {
      ledState4 = !ledState4;
      digitalWrite(ledPin4, ledState4);

      Blynk.virtualWrite(V4, ledState4);
    }
    btnState4 = LOW;
  }
  else
  {
    btnState4 = HIGH;
  }
}

void setup()
{
  Serial.begin(115200);

  pinMode(spin, OUTPUT);
  digitalWrite(spin, LOW);

  Blynk.begin(auth, ssid, pass);

  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);

  pinMode(btnPin1, INPUT_PULLUP);
  pinMode(btnPin2, INPUT_PULLUP);
  pinMode(btnPin3, INPUT_PULLUP);
  pinMode(btnPin4, INPUT_PULLUP);

  pinMode(sensor1, INPUT_PULLUP);
  pinMode(sensor2, INPUT_PULLUP);
  pinMode(sensor3, INPUT_PULLUP);
  pinMode(sensor4, INPUT_PULLUP);

  digitalWrite(ledPin1, ledState1);
  digitalWrite(ledPin2, ledState2);
  digitalWrite(ledPin3, ledState3);
  digitalWrite(ledPin4, ledState4);

  timer.setInterval(100L, checkPhysicalButton);
}

void loop()
{
  Blynk.run();
  timer.run();
  delay(100);
  if (mili == 1)
  {
    if (millis() > 15000)
    {
      digitalWrite(spin, HIGH);
      mili = 0;
    }
  }
}


#define Time_delay 10
bool One_time = 1;
unsigned long Next_time;

bool Get_time()
{
  unsigned long live_time = millis() / 1000;

  //Serial.println(Now_time);

  if (live_time >= Next_time || One_time)
  {
    Next_time = live_time + Time_delay;
    One_time = 0;
    //Serial.println("Hii");
    return 1;
  }
  else
  {
    return 0;
  }
}