From 57a6cdac5d005312d603b138437c7743a13a365b Mon Sep 17 00:00:00 2001 From: Guillermo Marcel Date: Sat, 17 May 2025 00:28:37 -0300 Subject: [PATCH] final details on field testing --- esp32/CardReader.h | 6 +- esp32/ServerConnector.h | 152 ++++++++++++++++++++++++++++++---------- esp32/doorSensor.h | 35 +++++---- esp32/esp32.ino | 17 +++-- 4 files changed, 152 insertions(+), 58 deletions(-) diff --git a/esp32/CardReader.h b/esp32/CardReader.h index 9c2073f..c8bc264 100644 --- a/esp32/CardReader.h +++ b/esp32/CardReader.h @@ -3,7 +3,6 @@ #include #include #include "alarm.h" -// #include #include "Dict.h" #include "Times.h" @@ -14,8 +13,6 @@ MFRC522DriverPinSimple ss_pin(5); class CardReader{ private: - String user1="0438768a2c6a80"; - String user2="23141f2d"; MFRC522DriverSPI driver{ss_pin}; // Create SPI driver //MFRC522DriverI2C driver{}; // Create I2C driver @@ -89,7 +86,8 @@ public: return; } // Serial.print("Card reader - Restart ok: "); - MFRC522Debug::PCD_DumpVersionToSerial(mfrc522, Serial); + // No logs for successful restart + //MFRC522Debug::PCD_DumpVersionToSerial(mfrc522, Serial); return; } diff --git a/esp32/ServerConnector.h b/esp32/ServerConnector.h index 296e9e1..6957c43 100644 --- a/esp32/ServerConnector.h +++ b/esp32/ServerConnector.h @@ -1,8 +1,7 @@ +#include "freertos/portable.h" #include "alarm.h" #include "Times.h" #include -// #include -// #include #include #include @@ -11,7 +10,7 @@ class ServerConnector private: AlarmStatus *status; long lastUpdate; - WiFiClient *wifiClient; + // WiFiClient wifiClient; CardReader *_cardReader; const String AUTHORIZED_ENTRANCE = "AUTHORIZE_ENTRANCE"; @@ -25,16 +24,44 @@ private: const String FIELD_ALLOWED_CARDS = "cards"; int failedAttempts; + bool running; + + // long lastHeapSize=0; + // long initHeapSize=0; void HandTask() { - // ServerConnector * this = (ServerConnector *) pvParameters; + // if(initHeapSize == 0) + // { + // initHeapSize=xPortGetFreeHeapSize(); + // } + // long currentHeapSize=0; + running = true; for (;;) { // every 15 seconds ask for update: DISSARM & CARDS - if (lastUpdate + FromSeconds(15) < millis()) + unsigned long currentMillis = millis(); + if (lastUpdate + FromSeconds(15) < currentMillis) { - lastUpdate = millis(); + lastUpdate = currentMillis; + // currentHeapSize= xPortGetFreeHeapSize(); + // if(abs(currentHeapSize - lastHeapSize) > 32) + // { + // Serial.print("[MEMORY] xPortGetFreeHeapSize: "); Serial.print(currentHeapSize); + // Serial.print( "| Total Variation: "); Serial.print(currentHeapSize - initHeapSize); + // Serial.print(" | Variation: "); Serial.println(currentHeapSize - lastHeapSize); + // lastHeapSize=currentHeapSize; + // } + + + if(failedAttempts == 5) + { + Serial.println("[HTTP] 5 fail connections, restarting thread."); + failedAttempts=6; + running=false; + vTaskDelete(NULL); + return; + } if(!CheckWifiConnection()){ Serial.println("[HTTP] could not recconect, trying later"); @@ -50,7 +77,7 @@ private: } if (status->sendNotif) { - status->eventId = millis(); + status->eventId = currentMillis; } SendAlarm(); status->sendNotif = false; @@ -60,8 +87,10 @@ private: bool CheckWifiConnection() { - if(failedAttempts > 5) + + if(failedAttempts >= 10) { + Serial.println("[HTTP] Too many faliures, restarting system"); ESP.restart(); } @@ -80,6 +109,7 @@ private: { String eventtype = status->sendNotif ? EVEN_TYPE_FIRED : EVENT_TYPE_EVENT_UPDATE; String url = "http://" + ServerAddress + "/?eventId=" + String(status->eventId) + "&eventType=" + eventtype + "&eventData=t"; + Serial.println("[HTTP] Contacting Alarm Server: " + url); String response = MakeHttpCall(url); if (response == "") { @@ -98,7 +128,24 @@ private: void RequestUpdate() { - String url = "http://" + ServerAddress + "/?eventId=0&eventType=" + EVENT_TYPE_UPDATE + "&eventData=t"; + StaticJsonDocument<200> docStatus; + docStatus["doorStatus"] = status->doorStatus; + docStatus["armed"] = status->isArmed; + docStatus["fireing"] = status->isFired; + docStatus["lastUser"] = status->userAllowed; + docStatus["lastEntrance"] = status->lastEntrance; + docStatus["millis"] = millis(); + + String jsonString; + serializeJson(docStatus, jsonString); + + String encodedJson = standardUrlEncode(jsonString); + + String url = "http://" + ServerAddress + "/?eventId=0&eventType=" + EVENT_TYPE_UPDATE + "&eventData=" + encodedJson; + + // Serial.println(url); + + String response = MakeHttpCall(url); if (response == "") { @@ -106,9 +153,8 @@ private: return; } - Dictionary &d = *(new Dictionary()); JsonDocument doc; - // deserializeJson(doc, response); + deserializeJson(doc, response); DeserializationError error = deserializeJson(doc, response); @@ -140,36 +186,32 @@ private: } String MakeHttpCall(String url) - { - if (!wifiClient) - { - Serial.printf("[HTTP] Unable to connect\n"); - failedAttempts= failedAttempts + 1; - return ""; - } + { + HTTPClient http; + http.setReuse(false); - HTTPClient https; - https.setReuse(false); - - Serial.println("[HTTP] " + url); - - if (!https.begin(*wifiClient, url)) - { // HTTPS + // if (!http.begin(wifiClient, url)) + if (!http.begin(url)) + { failedAttempts= failedAttempts + 1; Serial.println("[HTTP] not able to start http call"); - https.end(); + http.end(); return ""; } - // Serial.print("[HTTPS] GET...\n"); - // start connection and send HTTP header - int httpCode = https.GET(); + + int httpCode = http.GET(); // httpCode will be negative on error + // Serial.printf("[HTTP] wifi.available: %d, connected: %d \r\n", wifiClient.available(), wifiClient.connected()); + // Serial.printf("[HTTP] http.connected: %d \r\n", http.connected()); + + if (httpCode <= 0) { failedAttempts= failedAttempts + 1; - Serial.printf("[HTTP] GET... failed, error: %s\r\n", https.errorToString(httpCode).c_str()); - https.end(); + Serial.printf("[HTTP] Failed connetion - code: %d , error: %s\r\n", httpCode, http.errorToString(httpCode).c_str()); + + http.end(); return ""; } @@ -180,29 +222,67 @@ private: { failedAttempts= failedAttempts + 1; Serial.println("[HTTP] Server responded non 200 code"); - https.end(); + http.end(); return ""; } // print server response payload failedAttempts=0; - String payload = https.getString(); - https.end(); + + String payload = http.getString(); + http.end(); return payload; } + String standardUrlEncode(const String &str) { + String encoded = ""; + char c; + char code0; + char code1; + for (size_t i = 0; i < str.length(); i++) { + c = str.charAt(i); + // Check if character is unreserved per RFC 3986 + if ((c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || + c == '-' || c == '_' || c == '.' || c == '~') { + encoded += c; + } else { + encoded += '%'; + code0 = (c >> 4) & 0xF; + code1 = c & 0xF; + encoded += (code0 < 10) ? char(code0 + '0') : char(code0 - 10 + 'A'); + encoded += (code1 < 10) ? char(code1 + '0') : char(code1 - 10 + 'A'); + } + } + return encoded; + } + public: + ServerConnector(AlarmStatus *statusObj, CardReader *cardReader) { status = statusObj; - wifiClient = new WiFiClient(); + running = false; + // wifiClient = new WiFiClient(); _cardReader = cardReader; failedAttempts=0; } + bool IsRunning() + { + return running; + } + void StartNotifierAsync() { - xTaskCreate(this->asynTask, "sendNotif", 6000, (void *)this, 2, NULL); + running = true; + BaseType_t xReturned; + TaskHandle_t xHandle = NULL; + xReturned = xTaskCreate(this->asynTask, "sendNotif", 3000, (void *)this, 2, &xHandle); + failedAttempts=0; + Serial.print("Start: "); Serial.println(xReturned == pdPASS ? "Pass" : "Not pass"); + Serial.print("Status: "); Serial.println(eTaskGetState(xHandle)); } static void asynTask(void *pvParameter) diff --git a/esp32/doorSensor.h b/esp32/doorSensor.h index f02cf12..6b68735 100644 --- a/esp32/doorSensor.h +++ b/esp32/doorSensor.h @@ -1,4 +1,5 @@ #include "alarm.h" +#include "Times.h" AlarmStatus* status; @@ -6,7 +7,8 @@ class DoorSensor { private: int DOOR_SENSOR_PIN = 14; AlarmStatus* status; - int lastDoorState=1; + int lastDoorState = 1; // Last instantaneous reading + unsigned long lastDebounceTime = 0; // Time when a change was first detected public: @@ -23,6 +25,7 @@ public: void Init(){ pinMode(DOOR_SENSOR_PIN, INPUT_PULLUP); status->doorStatus = digitalRead(DOOR_SENSOR_PIN); + lastDoorState = status->doorStatus; } bool IsDoorOpen(){ @@ -33,19 +36,27 @@ public: } void HandleDoor(){ + // Read the current state of the door sensor + int reading = digitalRead(DOOR_SENSOR_PIN); - //status->doorStatus = digitalRead(DOOR_SENSOR_PIN); - lastDoorState = status->doorStatus; // save the last state - status->doorStatus = digitalRead(DOOR_SENSOR_PIN); // read new state - // state change: LOW -> HIGH - if (lastDoorState == DOOR_CLOSED && status->doorStatus == DOOR_OPEN) { - //handleOpen(); - status->doorChanged=true; + // If the reading has changed from the previous instantaneous reading, + // reset the debounce timer. + if (reading != lastDoorState) { + lastDebounceTime = millis(); } - else - if (lastDoorState == DOOR_OPEN && status->doorStatus == DOOR_CLOSED) { // state change: HIGH -> LOW - // handleClose(); - status->doorChanged=true; + + // If the new reading has remained stable longer than the debounce delay, + // then update the door state. + if ((millis() - lastDebounceTime) >= FromSeconds(1)) { + // If the reading is different from the last stable door state, + // update the status and mark that a change has occurred. + if (reading != status->doorStatus) { + status->doorStatus = reading; + status->doorChanged = true; + } } + + // Save the current reading for the next iteration. + lastDoorState = reading; } }; diff --git a/esp32/esp32.ino b/esp32/esp32.ino index 8c157c6..29192af 100644 --- a/esp32/esp32.ino +++ b/esp32/esp32.ino @@ -7,6 +7,7 @@ #include "Siren.h" #include "CardReader.h" #include "soc/rtc_wdt.h" +//#include #include #include "ServerConnector.h" // #include @@ -70,7 +71,7 @@ void setup() void addUsers(){ cardReader.AddUser("0438768a2c6a80", "pin verizure"); - // cardReader.AddUser("23141f2d", "pin azul"); + cardReader.AddUser("23141f2d", "pin azul"); cardReader.AddUser("91cf3e02", "card access"); } @@ -107,18 +108,22 @@ void loop() } led.Update(); - // delay(1000); + if(!serverConnector.IsRunning()) + { + Serial.println("Restarting communication thread."); + serverConnector.StartNotifierAsync(); + } } void DoorEvent() { if (doorSensor.IsDoorOpen()) { - Serial.println("The door-opening"); + Serial.print("[Door] The door-opening: "); if (!s.isArmed) { - Serial.println("Alarm is dissarmed, not fireing"); + Serial.println("Alarm not armed"); return; } if(s.isFired){ // Already fired. @@ -131,7 +136,7 @@ void DoorEvent() else { // delay(500); - Serial.println("The door-closing"); + Serial.println("[Door] The door-closing"); s.isArmed = true; } } @@ -156,7 +161,7 @@ void AutoRearm(){ //Auto Rearm if door is closed. if(s.doorStatus == DOOR_CLOSED){ - Serial.println("5m Passed, AutoArming again"); + Serial.println("[Door] 5m Passed, AutoArming again"); s.isArmed= true; }