#include <WiFi.h>
#include <FirebaseESP32.h>
#include <addons/RTDBHelper.h>
#include <time.h>
// WiFi
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
// Firebase
#define API_KEY "AIzaSyBCpw2Ih8NmYFknTCvlCDe2Vd39017DXFo"
#define DATABASE_URL "https://smart-door-guard-91f0b-default-rtdb.europe-west1.firebasedatabase.app/"
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;
// Pins
const int PIN_DOOR = 32;
const int PIN_LED = 18;
const int PIN_BUZ = 25;
// States
bool systemActive = true; // يقرأ من Firebase
bool alarmLatched = false; // يكتب إلى Firebase , حالة الانذار
bool remoteClear = false; // يقرأ من Firebase (one-shot)
bool manualLed = false; // يقرأ من Firebase
bool manualBuz = false; // يقرأ من Firebase
bool lastDoorOpen = false;
unsigned long lastPublishMs = 0;
unsigned long lastCtrlReadMs = 0;
time_t nowTS() {
return time(nullptr);
}
void ensureDefaults() {
Firebase.setBool (fbdo, "systemActive", true);
Firebase.setBool (fbdo, "manualLed", false);
Firebase.setBool (fbdo, "manualBuz", false);
Firebase.setBool (fbdo, "clearAlarm", false);
Firebase.setString(fbdo, "door", "CLOSED");
Firebase.setBool (fbdo, "alarmLatched", false);
Firebase.setInt (fbdo, "ts", (int)nowTS());
}
void readControls() {
if (Firebase.getBool(fbdo, "systemActive")) systemActive = fbdo.to<bool>();
if (Firebase.getBool(fbdo, "manualLed")) manualLed = fbdo.to<bool>();
if (Firebase.getBool(fbdo, "manualBuz")) manualBuz = fbdo.to<bool>();
if (Firebase.getBool(fbdo, "clearAlarm")) {
if (fbdo.to<bool>()) {
remoteClear = true;
Firebase.setBool(fbdo, "clearAlarm", false); // one-shot
}
}
}
void publishStatus(bool doorOpen) {
Firebase.setString(fbdo, "door", doorOpen ? "OPEN" : "CLOSED");
Firebase.setBool (fbdo, "alarmLatched", alarmLatched);
Firebase.setInt (fbdo, "ts", (int)nowTS());
}
void logEvent(const char* state) {
FirebaseJson j;
j.set("state", state);
j.set("ts", (int)nowTS());
Firebase.pushJSON(fbdo, "logs", j);
}
void setup() {
Serial.begin(115200);
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_BUZ, OUTPUT);
pinMode(PIN_DOOR, INPUT); // LOW=OPEN
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(200);
}
Serial.println("✅ WiFi Connected");
config.api_key = API_KEY;
config.database_url = DATABASE_URL;
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
while (!Firebase.signUp(&config, &auth, "", "")) {
delay(1000);
}
Serial.println("✅ Firebase signed up");
Firebase.begin(&config, &auth);
Firebase.reconnectWiFi(true);
ensureDefaults();
}
void loop() {
bool doorOpen = (digitalRead(PIN_DOOR) == LOW); // LOW = الباب مفتوح
// قراءة تحكّمات Firebase دوريًا
if (millis() - lastCtrlReadMs > 300) {
readControls();
lastCtrlReadMs = millis();
}
// تنفيذ أمر الإيقاف (Clear): يوقف التنبيهات
if (remoteClear) {
alarmLatched = false;
remoteClear = false;
}
if (!systemActive || (!manualLed && !manualBuz) ) {
alarmLatched = false;
if (!systemActive && manualLed) {
manualLed = false;
Firebase.setBool(fbdo, "manualLed", false);
}
if (!systemActive && manualBuz) {
manualBuz = false;
Firebase.setBool(fbdo, "manualBuz", false);
}
}
if (systemActive && (manualLed || manualBuz) && doorOpen) {
alarmLatched = true;
}
bool ledOn = systemActive && manualLed && alarmLatched ;
bool buzOn = systemActive && manualBuz && alarmLatched;
if (ledOn) digitalWrite(PIN_LED, HIGH);
else digitalWrite(PIN_LED, LOW);
if (buzOn) tone(PIN_BUZ, 1000);
else noTone(PIN_BUZ);
// سجل تغيير حالة الباب
if (doorOpen != lastDoorOpen) {
logEvent(doorOpen ? "OPEN" : "CLOSED");
lastDoorOpen = doorOpen;
}
// نشر الحالة كل ثانية
if (millis() - lastPublishMs > 1000) {
publishStatus(doorOpen);
lastPublishMs = millis();
}
delay(20);
}