#include <TridentTD_LineNotify.h> // เรียกใช้ไลบรารี่สำหรับ Line Notify
#define LINE_TOKEN "HyLyeiNusIoVDn4ktzE1uBlvxxrlNf8kpaf4hqTkyIt"

#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

#define BLYNK_TEMPLATE_ID "TMPLHfmhNBgM"
#define BLYNK_DEVICE_NAME "Quickstart Template"
#define BLYNK_AUTH_TOKEN "R1JEtPUVfDFGrDWNH-EeZ_ih3p7uoWLI" // Blynk Token สำหรับการ Authen แอพ Blynk

#define WiFiSSID "Wokwi-GUEST"
#define WiFiPASSWORD ""

const int BuzzerPin = 15; // กำหนดขาลำโพง Buzzer
const int GasSensorPin = 34; // กำหนดขา input เซ็นเซอร์
int sensorValue = 0; // ตัวแปรค่า Analog
int outputValue = 0; // ตัวแปรสำหรับ Map เพื่อคิด %

void setup() 
{
  pinMode(GasSensorPin, INPUT); // ตั้ง Pin รับค่า Input จาก Gas Sensor
  pinMode(BuzzerPin, OUTPUT); // ตั้ง Pin ลำโพง Buzzer เป็น Output
  
  Serial.begin(9600); // ตั้งค่า Baud rate Serial Port
  
  Serial.println();
  Serial.println("NodeMCU ESP8266 Run"); // แสดงข้อความออก Serial Port

  WiFi.begin(WiFiSSID, WiFiPASSWORD); // WiFi เริ่มทำงาน
  Serial.printf("WiFi connecting to %s\n",  WiFiSSID);
  while (WiFi.status() != WL_CONNECTED) // check การเชื่อมต่อ WiFi วนลูปจนกว่าจะต่อ WiFi ได้
  {
    Serial.print("."); // แสดงข้อความออก Serial Port
    delay(400);
  }
  Serial.printf("\nWiFi connected\nIP : "); // แสดงข้อความออก Serial Port
  Serial.println(WiFi.localIP()); // แสดงค่า IP Address ที่ต่อ WiFi ได้ ออกทาง Serial Port

  Blynk.begin(BLYNK_AUTH_TOKEN, WiFiSSID, WiFiPASSWORD, "blynk.cloud", 80);

  int mytimeout = millis() / 1000; // ตั้งค่า Timeout การต่อ WiFi
  while (Blynk.connect() == false)  // try to connect to server for 10 seconds
  {
    if((millis() / 1000) > mytimeout + 8) // try local server if not connected within 9 seconds
    {
       break;
       Serial.println("Cannot connect BLYNK..."); // แสดงข้อความออก Serial Port
    }
  }
  
  Serial.println(LINE.getVersion()); // แสดง Line Version ออก Serial Port
  LINE.setToken(LINE_TOKEN); // ตั้งค่า Line Token ที่ใช้
  LINE.notify("Gas & Smoke Sensor Start."); // แจ้งเตือนไลน์ ว่าเซนเซอร์อุณหภูมิเริ่มทำงาน
  
  Serial.println("ESP8266 Start."); // แสดงข้อความออก Serial Port
}

void loop() 
{
  Blynk.run();
  
  sensorValue = analogRead(GasSensorPin);
  outputValue = map(sensorValue, 0, 1023, 0, 100); //แปลงค่าจาก
  Serial.print(outputValue); // แสดงข้อความออก Serial Port
  Serial.println(" %"); // แสดงข้อความออก Serial Port
  
  Blynk.virtualWrite(V0, outputValue); // ส่งค่า outputValue ไปยัง Blynk Server App ที่ตัวแปร V0

  String SendData;
  
  //ตั้งค่า 0-100% ที่ต้องการให้แจ้งเตือนผ่านไลน์ และ Blynk
  if (outputValue >= 70) // ถ้าค่า Gas มากกว่า 70%
  {
    SendData = String(outputValue) + " %" + "\n\t\tDangerous!!!";
    LINE.notify(SendData); // ส่งข้อความไปยัง Line "แจ้งเตือน : ตรวจพบควันเกินค่ากำหนด"
    //LINE.notify("Dangerous!!!"); // ส่งข้อความไปยัง Line "แจ้งเตือน : ตรวจพบควันเกินค่ากำหนด"

     Blynk.virtualWrite(V1, "Dangerous!!!"); // ส่งคำว่า "Dangerous!!!" ไปยัง Blynk Server App ที่ตัวแปร V1
     Blynk.virtualWrite(V2, 0); // ส่งค่า LED LOW ไปยัง Blynk Server App ที่ตัวแปร V2
     Blynk.virtualWrite(V3, 0); // ส่งค่า LED LOW ไปยัง Blynk Server App ที่ตัวแปร V3
     Blynk.virtualWrite(V4, 1); // ส่งค่า LED HIGH ไปยัง Blynk Server App ที่ตัวแปร V4
     
  }
  else if (outputValue >= 40) // ถ้าค่า Gas มากกว่า 40%
  {
    SendData = String(outputValue) + " %" + "\n\t\tSmoke Detected!!!";
    LINE.notify(SendData); // ส่งข้อความไปยัง Line "แจ้งเตือน : ตรวจพบควันเกินค่ากำหนด"
    //LINE.notify("Smoke Detected!!!"); // ส่งข้อความไปยัง Line "แจ้งเตือน : ตรวจพบควันเกินค่ากำหนด"

     Blynk.virtualWrite(V1, "Warning!!!"); // ส่งคำว่า "Warning!!!" ไปยัง Blynk Server App ที่ตัวแปร V1
     Blynk.virtualWrite(V2, 0); // ส่งค่า LED LOW ไปยัง Blynk Server App ที่ตัวแปร V2
     Blynk.virtualWrite(V3, 1); // ส่งค่า LED HIGH ไปยัง Blynk Server App ที่ตัวแปร V3
     Blynk.virtualWrite(V4, 0); // ส่งค่า LED LOW ไปยัง Blynk Server App ที่ตัวแปร V4
     
  }
  else // ถ้าค่า Gas น้อยกว่า 40%
  {
    //SendData = String(outputValue) + " %" + "\n\t\tNormal";
    //LINE.notify(SendData);
    //LINE.notify("ปกติ");
    Blynk.virtualWrite(V1, "Normal"); // ส่งคำว่า "Normal" ไปยัง Blynk Server App ที่ตัวแปร V1
    Blynk.virtualWrite(V2, 1); // ส่งค่า LED HIGH ไปยัง Blynk Server App ที่ตัวแปร V2
    Blynk.virtualWrite(V3, 0); // ส่งค่า LED LOW ไปยัง Blynk Server App ที่ตัวแปร V3
    Blynk.virtualWrite(V4, 0); // ส่งค่า LED LOW ไปยัง Blynk Server App ที่ตัวแปร V4
  }

  if (outputValue >= 50)  //ตั้งค่า 0-100% ที่ต้องการให้แจ้งเตือนผ่านลำโพง Buzzer
  {
    digitalWrite(BuzzerPin, HIGH); // ลำโพง Buzzer ดัง
  }
  else
  {
    digitalWrite(BuzzerPin, LOW); // ลำโพง Buzzer เงียบ
  }
  
  delay(1000);
}