#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Cấu hình WiFi
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// URL Google Apps Script
const char* scriptUrl = "https://script.google.com/macros/s/AKfycby9g5FLEIaEKnrKYzcUn2X2A5tudltXxE3UITc5l3gy17QaZySnm-r1qfBfDbAghay5/exec";
// Pin nút bấm
const int buttonSelectPin = 2; // Nút chọn
const int buttonUpPin = 4; // Nút lên
const int buttonDownPin = 5; // Nút xuống
int lastSelectState = HIGH;
int lastUpState = HIGH;
int lastDownState = HIGH;
bool emailSent = false;
// Khởi tạo LCD 20x4 I2C
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Danh sách loại sự cố
String issues[] = {"Ngap_nuoc", "Ket_xe", "Tai_nan", "Duong_hong", "Chay", "Dong_dat", "Su_co_an_ninh"};
String issueNames[] = {"Ngap nuoc", "Ket xe", "Tai nan", "Duong hong", "Chay", "Dong dat","Su co an ninh"};
int currentIssue = 0;
void setup() {
Serial.begin(115200);
pinMode(buttonSelectPin, INPUT_PULLUP);
pinMode(buttonUpPin, INPUT_PULLUP);
pinMode(buttonDownPin, INPUT_PULLUP);
// Khởi tạo LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("ESP32 Alert System");
lcd.setCursor(0, 1);
lcd.print("Connecting to WiFi...");
// Kết nối WiFi
WiFi.begin(ssid, password);
Serial.print("Đang kết nối WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi kết nối thành công! IP: " + WiFi.localIP().toString());
// Cập nhật trạng thái LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Chon su co:");
lcd.setCursor(0, 1);
lcd.print("> " + issueNames[currentIssue]);
delay(1000);
}
void loop() {
int selectState = digitalRead(buttonSelectPin);
int upState = digitalRead(buttonUpPin);
int downState = digitalRead(buttonDownPin);
// Nút lên: Chuyển lên loại sự cố trước
if (upState == LOW && lastUpState == HIGH) {
currentIssue = (currentIssue == 0) ? 6 : currentIssue - 1;
updateLCD();
Serial.println("Chọn sự cố: " + issueNames[currentIssue]);
delay(200); // Debounce
}
// Nút xuống: Chuyển xuống loại sự cố sau
if (downState == LOW && lastDownState == HIGH) {
currentIssue = (currentIssue + 1) % 7;
updateLCD();
Serial.println("Chọn sự cố: " + issueNames[currentIssue]);
delay(200); // Debounce
}
// Nút chọn: Gửi email
if (selectState == LOW && lastSelectState == HIGH && !emailSent) {
Serial.println("Nút chọn! Đang gửi email cảnh báo...");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Sending Email...");
String result = sendEmailAlert(issues[currentIssue]);
// Hiển thị kết quả trên LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ESP32 Alert System");
lcd.setCursor(0, 1);
if (result == "success") {
lcd.print("Email sent OK!");
lcd.setCursor(0, 2);
lcd.print("Issue: ");
lcd.print(issueNames[currentIssue]);
lcd.setCursor(0, 3);
lcd.print("Time: ");
lcd.print(getCurrentTime());
} else {
lcd.print("Email failed!");
lcd.setCursor(0, 2);
lcd.print("Issue: ");
lcd.print(issueNames[currentIssue]);
lcd.setCursor(0, 3);
lcd.print("Error: ");
lcd.print(result.substring(0, 12));
}
emailSent = true;
delay(1000); // Debounce
}
// Reset flag khi thả nút chọn
if (selectState == HIGH) {
emailSent = false;
}
lastSelectState = selectState;
lastUpState = upState;
lastDownState = downState;
delay(50);
}
void updateLCD() {
lcd.setCursor(0, 1);
lcd.print(" "); // Xóa dòng cũ
lcd.setCursor(0, 1);
lcd.print("> " + issueNames[currentIssue]);
}
String sendEmailAlert(String issue) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
// Thêm tham số issue vào URL
String url = String(scriptUrl) + "?issue=" + issue;
Serial.println("Gửi yêu cầu đến: " + url);
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
http.setTimeout(10000);
http.begin(url);
http.addHeader("Content-Type", "application/json");
int httpCode = http.GET();
Serial.println("HTTP Code: " + String(httpCode));
if (httpCode > 0) {
String payload = http.getString();
Serial.println("Phản hồi từ script: " + payload);
if (payload.indexOf("\"status\":\"success\"") > 0) {
Serial.println("✅ Email gửi thành công!");
return "success";
} else {
Serial.println("❌ Lỗi gửi email: " + payload);
int start = payload.indexOf("\"message\":\"") + 11;
int end = payload.indexOf("\"", start);
return payload.substring(start, end);
}
} else {
Serial.println("❌ Lỗi HTTP: " + String(httpCode));
return "HTTP Error: " + String(httpCode);
}
http.end();
} else {
Serial.println("❌ WiFi không kết nối!");
return "WiFi Error";
}
}
// Hàm lấy thời gian hiện tại (giả lập)
String getCurrentTime() {
unsigned long seconds = millis() / 1000;
int hour = (seconds / 3600) % 24;
int minute = (seconds / 60) % 60;
int second = seconds % 60;
char timeStr[9];
sprintf(timeStr, "%02d:%02d:%02d", hour, minute, second);
return String(timeStr);
}