#define BLYNK_TEMPLATE_ID "TMPL6uIOMDz8j"
#define BLYNK_TEMPLATE_NAME "Alarm1"
#define BLYNK_AUTH_TOKEN "1Ena-fwqx2RVz4yAtBwVFYVJhtCa2j0D"
#include <Wire.h>
#include <WiFi.h>
#include <LiquidCrystal_I2C.h>
#include "DHTesp.h"

// #define BLYNK_TEMPLATE_ID "TMPL6jRDk7QLJ"
// #define BLYNK_TEMPLATE_NAME "Alarm"
// #define BLYNK_AUTH_TOKEN "OfWIf0NDw9pLRbU-cwI_slRCs8R6crAD"

// Địa chỉ I2C của màn hình LCD
#include <BlynkSimpleEsp32.h>
#define LCD_ADDR 0x27

// Khởi tạo LCD
LiquidCrystal_I2C lcd(LCD_ADDR, 20, 4);

// Chân cảm biến
#define LED_PIN1 23
#define LED_PIN2 18
#define DHT_PIN1 15
#define DHT_PIN2 33
#define DHT_PIN3 25
#define DHT_PIN4 27
#define BUZZER_PIN 26
#define coi 16 
#define LEDbao 17

DHTesp dht1, dht2, dht3, dht4;

const int nutbam = 4;
const int nutbam2 = 5;
int bam = 0;
int bam2 = 0;
int lastBlinkTime = 0;
const int blinkInterval = 500;

char ssid[] = "Wokwi-GUEST";  // WiFi của Wokwi
char pass[] = "";  // Không có mật khẩu

void setup() {
  Serial.begin(115200);
  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass); // Kết nối với Blynk

  WiFi.begin(ssid, pass); 

  dht1.setup(DHT_PIN1, DHTesp::DHT22);
  dht2.setup(DHT_PIN2, DHTesp::DHT22);
  dht3.setup(DHT_PIN3, DHTesp::DHT22);
  dht4.setup(DHT_PIN4, DHTesp::DHT22);

  lcd.init();
  lcd.backlight();

  pinMode(LED_PIN1, OUTPUT);
  pinMode(LED_PIN2, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(nutbam, INPUT);
  pinMode(coi, OUTPUT);
  pinMode(nutbam2, INPUT);
  pinMode(LEDbao, OUTPUT);
}

void loop() {  
    Blynk.run();  // Duy trì kết nối với Blynk  

    // Đọc dữ liệu từ cảm biến DHT  
    float temp1 = dht1.getTemperature();  
    float temp2 = dht2.getTemperature();  
    float temp3 = dht3.getTemperature();  
    float temp4 = dht4.getTemperature();  

    // Kiểm tra xem các giá trị đọc được có hợp lệ không  
    if (isnan(temp1) || isnan(temp2) || isnan(temp3) || isnan(temp4)) {  
        Serial.println("Không thể đọc từ cảm biến DHT.");  
        return;  // Thoát khỏi vòng lặp nếu có lỗi  
    }  

    // Gửi dữ liệu lên Blynk  
    Blynk.virtualWrite(V0, temp1);  
    Blynk.virtualWrite(V1, temp2);  
    Blynk.virtualWrite(V2, temp3);  
    Blynk.virtualWrite(V3, temp4);  

    // Hiển thị dữ liệu lên LCD  
    lcd.clear();  // Xóa dữ liệu trước đó (cẩn thận với nhấp nháy)  
    lcd.setCursor(0, 0);  
    lcd.print("T1: " + String(temp1) + "C");  

    lcd.setCursor(0, 1);  
    lcd.print("T2: " + String(temp2) + "C");  

    lcd.setCursor(0, 2);  
    lcd.print("T3: " + String(temp3) + "C");  

    lcd.setCursor(0, 3);  
    lcd.print("T4: " + String(temp4) + "C");  

    // Xử lý còi báo động  
    bam = digitalRead(nutbam);  
    if (bam == HIGH || temp1 > 50 || temp2 > 50 || temp3 > 50 || temp4 > 50) {  
        digitalWrite(coi, HIGH);  
        tone(coi, 1000);  
        tone(BUZZER_PIN, 1000);  
        delay(1000);  
    } else {  
        digitalWrite(coi, LOW);  
        noTone(coi);  
        noTone(BUZZER_PIN);  
    }  

    // Xử lý LED báo động  
    bam2 = digitalRead(nutbam2);  
    if (bam2 == HIGH || temp1 > 50 || temp2 > 50 || temp3 > 50 || temp4 > 50) {  
        digitalWrite(LED_PIN1, HIGH);  
        digitalWrite(LED_PIN2, HIGH);  
        int currentMillis = millis();  
        if (currentMillis - lastBlinkTime >= blinkInterval) {  
            digitalWrite(LEDbao, !digitalRead(LEDbao));  
            lastBlinkTime = currentMillis;  
        }  
    } else {  
        digitalWrite(LEDbao, LOW);  
        digitalWrite(LED_PIN1, LOW);  
        digitalWrite(LED_PIN2, LOW);  
    }  

    delay(100);  
}