#include "alarm.h" #include "Times.h" #include // #include // #include #include #include class ServerConnector { private: AlarmStatus *status; long lastUpdate; WiFiClient *wifiClient; CardReader *_cardReader; const String AUTHORIZED_ENTRANCE = "AUTHORIZE_ENTRANCE"; const String ServerAddress = "alarm.int.francelsoft.com"; // const String ServerAddress = "10.88.88.169:9003"; const String EVEN_TYPE_FIRED = "Fired"; const String EVENT_TYPE_EVENT_UPDATE = "EventUpdate"; const String EVENT_TYPE_UPDATE = "Update"; const String FIELD_DISARM = "disarm"; const String FIELD_ALLOWED_CARDS = "cards"; void HandTask() { // ServerConnector * this = (ServerConnector *) pvParameters; for (;;) { // every 15 seconds ask for update: DISSARM & CARDS if (lastUpdate + FromSeconds(15) < millis()) { lastUpdate = millis(); if(!CheckWifiConnection()){ Serial.println("[HTTP] could not recconect, trying later"); continue; } RequestUpdate(); } if (!status->sendNotif && !status->isFired) { vTaskDelay(100 / portTICK_PERIOD_MS); continue; } if (status->sendNotif) { status->eventId = millis(); } SendAlarm(); status->sendNotif = false; vTaskDelay(FromSeconds(3) / portTICK_PERIOD_MS); } } bool CheckWifiConnection() { if(WiFi.status() == WL_CONNECTED){ return true; } Serial.println("[HTTP] Reconnecting to WiFi..."); WiFi.disconnect(); bool response = WiFi.reconnect(); return (WiFi.status() == WL_CONNECTED); } void SendAlarm() { String eventtype = status->sendNotif ? EVEN_TYPE_FIRED : EVENT_TYPE_EVENT_UPDATE; String url = "http://" + ServerAddress + "/?eventId=" + String(status->eventId) + "&eventType=" + eventtype + "&eventData=t"; String response = MakeHttpCall(url); if (response == "") { Serial.println("[HTTP] Alarm Server not recheable"); return; } if (response == AUTHORIZED_ENTRANCE) { // Todo Extract to Disarm method Serial.println("[HTTP] Entrace authorized by server."); status->isFired = false; status->isArmed = status->doorStatus == DOOR_CLOSED; } } void RequestUpdate() { String url = "http://" + ServerAddress + "/?eventId=0&eventType=" + EVENT_TYPE_UPDATE + "&eventData=t"; String response = MakeHttpCall(url); if (response == "") { Serial.println("[HTTP] Update Server not recheable"); return; } Dictionary &d = *(new Dictionary()); JsonDocument doc; // deserializeJson(doc, response); DeserializationError error = deserializeJson(doc, response); if (error) { Serial.print("[HTTP] Serialize error: "); Serial.println(error.c_str()); return; } if (doc[FIELD_DISARM].is() && doc[FIELD_DISARM]) { // disarm requested // Todo Extract to Disarm method, and add to alarm.h // same in card reader Serial.println("[HTTP] Disarm request by server"); status->isArmed = false; status->isFired = false; status->lastEntrance = millis(); } // Serial.print(FIELD_ALLOWED_CARDS); int cardsNo = doc[FIELD_ALLOWED_CARDS].size(); for (int i = 0; i < cardsNo; i++) { _cardReader->AddUser(doc[FIELD_ALLOWED_CARDS][i]["id"], doc[FIELD_ALLOWED_CARDS][i]["name"]); } } String MakeHttpCall(String url) { if (!wifiClient) { Serial.printf("[HTTP] Unable to connect\n"); return ""; } HTTPClient https; Serial.println("[HTTP] " + url); if (!https.begin(*wifiClient, url)) { // HTTPS Serial.println("[HTTP] not able to start http call"); return ""; } // Serial.print("[HTTPS] GET...\n"); // start connection and send HTTP header int httpCode = https.GET(); // httpCode will be negative on error if (httpCode <= 0) { Serial.printf("[HTTP] GET... failed, error: %s\n", https.errorToString(httpCode).c_str()); return ""; } // HTTP header has been send and Server response header has been handled // Serial.printf("[HTTPS] GET Finished... code: %d\n", httpCode); // file found at server if (httpCode != HTTP_CODE_OK) { https.end(); return ""; } // print server response payload String payload = https.getString(); https.end(); return payload; } public: ServerConnector(AlarmStatus *statusObj, CardReader *cardReader) { status = statusObj; wifiClient = new WiFiClient(); _cardReader = cardReader; } void StartNotifierAsync() { xTaskCreate(this->asynTask, "sendNotif", 6000, (void *)this, 2, NULL); } static void asynTask(void *pvParameter) { ServerConnector *serverInstance = (ServerConnector *)pvParameter; serverInstance->HandTask(); } };