arduino-sketches/esp32/ServerConnector.h

179 lines
4.5 KiB
C
Raw Normal View History

#include "alarm.h"
#include "Times.h"
#include <HTTPClient.h>
// #include <Dictionary.h>
// #include <typeinfo>
#include <iostream>
#include <ArduinoJson.h>
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();
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);
}
}
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("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("Update Server not recheable");
return;
}
Dictionary &d = *(new Dictionary());
JsonDocument doc;
// deserializeJson(doc, response);
DeserializationError error = deserializeJson(doc, response);
if (error)
{
Serial.print("Serialize error: ");
Serial.println(error.c_str());
return;
}
if (doc[FIELD_DISARM].is<bool>() && doc[FIELD_DISARM])
{
// disarm requested
// Todo Extract to Disarm method, and add to alarm.h
// same in card reader
Serial.println("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("[HTTPS] Unable to connect\n");
return "";
}
HTTPClient https;
Serial.println("[HTTPS] " + url);
if (!https.begin(*wifiClient, url))
{ // HTTPS
Serial.println("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();
}
};