#include <WiFi.h>
#include <WebServer.h>
#include <HTTPClient.h>
// --- WIFI CREDENTIALS (Wokwi Virtual WiFi) ---
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASS = "";
// --- FIREBASE DETAILS ---
const String FB_URL = "https://esp32-monitor-b9dee-default-rtdb.firebaseio.com/";
WebServer server(80);
unsigned long lastUpdate = 0;
String DEVICE_MAC = "";
String currentAlarmStatus = "false";
void setup() {
Serial.begin(115200);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
DEVICE_MAC = WiFi.macAddress();
DEVICE_MAC.replace(":", "");
Serial.println("\nWiFi Connected!");
Serial.print("Local IP Address: ");
Serial.println(WiFi.localIP());
Serial.println("Device ID (MAC): " + DEVICE_MAC);
server.on("/", handleRoot);
server.on("/update", handleUpdate);
server.begin();
// Read existing alarm state from Firebase before writing
readFromFirebase();
// Now sync with correct alarm state
syncToFirebase();
}
void loop() {
server.handleClient();
if (millis() - lastUpdate > 30000) {
lastUpdate = millis();
syncToFirebase();
}
}
// ✅ Read current alarm state from Firebase on boot
void readFromFirebase() {
if (WiFi.status() != WL_CONNECTED) return;
HTTPClient http;
String path = FB_URL + "Devices/" + DEVICE_MAC + "/status.json";
http.begin(path);
int response = http.GET();
if (response == 200) {
String body = http.getString();
body.replace("\"", ""); // remove JSON quotes
Serial.println("Firebase Read: " + body);
// Parse alarm field (index 4 in CSV)
int commaCount = 0;
String alarmVal = "";
for (char c : body) {
if (c == ',') commaCount++;
else if (commaCount == 4) alarmVal += c;
else if (commaCount > 4) break;
}
alarmVal.trim();
if (alarmVal == "true" || alarmVal == "false") {
currentAlarmStatus = alarmVal;
Serial.println("Restored alarm state: " + currentAlarmStatus);
}
} else {
Serial.println("No existing data, starting fresh.");
}
http.end();
}
void handleRoot() {
String html = "<html><head><meta name='viewport' content='width=device-width, initial-scale=1'>";
html += "<style>body{background:#000b1a; color:white; font-family:sans-serif; text-align:center;} ";
html += ".btn{background:#ff4b2b; color:white; padding:25px; border:none; border-radius:15px; width:90%; font-size:20px; font-weight:bold; cursor:pointer;}";
html += ".safe-btn{background:#00B4DB; margin-top:20px;}</style></head>";
html += "<body><h2>AlertX TEST PANEL</h2>";
html += "<p style='color:#00B4DB;'>Testing MAC: " + DEVICE_MAC + "</p>";
html += "<p style='color:white;'>IP: " + WiFi.localIP().toString() + "</p>";
html += "<br><a href='/update?alm=true'><button class='btn'>🚨 TRIGGER FIRE ALERT</button></a><br>";
html += "<a href='/update?alm=false'><button class='btn safe-btn'>✅ SET TO SAFE</button></a>";
html += "</body></html>";
server.send(200, "text/html", html);
}
void handleUpdate() {
currentAlarmStatus = server.arg("alm");
syncToFirebase();
String msg = (currentAlarmStatus == "true") ? "ALARM SENT!" : "SYSTEM SAFE";
server.send(200, "text/html", "<h3>" + msg + "</h3><p>App Dashboard updated.</p><a href='/'>Back</a>");
}
void syncToFirebase() {
String uptime = String(millis() / 1000) + "s";
String csvData = "12,WiFi,Online,98," + currentAlarmStatus + ",None," + uptime;
sendToFirebase(csvData);
}
void sendToFirebase(String data) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String path = FB_URL + "Devices/" + DEVICE_MAC + "/status.json";
http.begin(path);
http.addHeader("Content-Type", "application/json");
String payload = "\"" + data + "\"";
int response = http.PUT(payload);
if (response > 0) {
Serial.println("Firebase Sync Successful: " + data);
} else {
Serial.printf("Error: %s\n", http.errorToString(response).c_str());
}
http.end();
}
}