the start of structure, using extern and proper imports

This commit is contained in:
Matthew Frost 2024-01-30 17:33:00 +01:00
parent 74cc87fe65
commit cdd41bb660
8 changed files with 252 additions and 196 deletions

2
.gitignore vendored
View file

@ -3,7 +3,7 @@
.vscode/c_cpp_properties.json .vscode/c_cpp_properties.json
.vscode/launch.json .vscode/launch.json
.vscode/ipch .vscode/ipch
include/secrets.h src/secrets.cpp
.DS_Store .DS_Store
upload_params.ini upload_params.ini
platformio.ini platformio.ini

View file

@ -7,10 +7,13 @@
#include "settings.h" #include "settings.h"
#include <HTTPClient.h> #include <HTTPClient.h>
#include <ArduinoJson.h> #include <ArduinoJson.h>
Settings settings;
#ifdef WIFI #ifdef WIFI
#include "WiFi.h" #include "WiFi.h"
#ifdef WEBHOOKS
// #include "webhooks.h"
#endif
#endif #endif
#ifdef LOCAL_ACL #ifdef LOCAL_ACL
#include "acl.h" #include "acl.h"
@ -24,6 +27,10 @@
#include <sstream> #include <sstream>
#endif #endif
#ifdef TINANCE2_BACKEND
#include "tinance2.h"
#endif
#ifdef WEB_SERVER #ifdef WEB_SERVER
#include <AsyncTCP.h> #include <AsyncTCP.h>
#include "ESPAsyncWebServer.h" #include "ESPAsyncWebServer.h"

30
include/secrets.h Normal file
View file

@ -0,0 +1,30 @@
#ifndef SECRETS_H
#define SECRETS_H
#ifdef WIFI
extern const char* ssid;
extern const char* password;
#endif
#ifdef TINANCE2_BACKEND
extern const char* tinance2_url_validatecard;
extern const char* tinance2_url_readerinfo;
extern const char* tinance2_url_acls;
extern const char* tinance2_reader_identifer;
extern const char* tinance2_reader_key;
#endif
#ifdef WEB_SERVER
extern const char* http_username;
extern const char* http_password;
#endif
#ifdef WEBHOOKS
#ifdef WEBHOOKS_UNLOCK
extern const char* webhook_unlock_url;
#endif
#ifdef WEBHOOKS_LOCK
extern const char* webhook_lock_url;
#endif
#endif
#endif

View file

@ -21,4 +21,6 @@ public:
String getDoorMode(); String getDoorMode();
}; };
extern Settings settings;
#endif // SETTINGS_H #endif // SETTINGS_H

18
include/tinance2.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef tinance2_h
#define tinance2_h
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include "settings.h"
#include "secrets.h"
#include "hardware.h"
#include "buzzer_ctl.h"
void tinance2SyncTaskFunction(void *parameter);
void tinance2authrequest(String fullCardID, String cardID);
#endif

View file

@ -7,7 +7,6 @@ const unsigned long displayDelay = 1000; // Delay in milliseconds after which th
const unsigned long wifiRebootTimeout = 20000; // Delay before reboot after disconnect const unsigned long wifiRebootTimeout = 20000; // Delay before reboot after disconnect
unsigned int bitCount = 0; // Variable to keep track of the bit count unsigned int bitCount = 0; // Variable to keep track of the bit count
unsigned int maxReaderWaitTime = 9000; // Variable to timeout reader after too long of no data. unsigned int maxReaderWaitTime = 9000; // Variable to timeout reader after too long of no data.
HTTPClient http;
#ifdef LOCAL_ACL #ifdef LOCAL_ACL
void localAcl(String cardID) { void localAcl(String cardID) {
@ -168,202 +167,10 @@ void handleData1Interrupt() {
handleInterrupt(1); handleInterrupt(1);
} }
#ifdef TINANCE2_BACKEND
class Tinance2HttpClient {
public:
Tinance2HttpClient() {}
std::pair<String, int> sendHttpRequest(String url, String method, String payload) {
if (!http.begin(url)) {
#ifdef SERIAL_DEBUG
Serial.println("Failed to begin HTTP request");
#endif
http.end();
return std::make_pair("", -1);
}
// Set the headers
http.addHeader("Content-Type", "application/json");
http.addHeader("X-Identifier", tinance2_reader_identifer);
http.addHeader("X-Access-Key", tinance2_reader_key);
// Set the HTTP timeout to 5 seconds
http.setTimeout(5000);
// Send the POST request
int httpResponseCode;
if (method == "POST") {
httpResponseCode = http.POST(payload);
} else if (method == "GET") {
httpResponseCode = http.GET();
} else {
// Handle invalid method
#ifdef SERIAL_DEBUG
Serial.println("Invalid HTTP method");
#endif
http.end();
return std::make_pair("", -1);
}
if (httpResponseCode <= 0) {
#ifdef SERIAL_DEBUG
Serial.println("Request Failed (response less than 0)");
#endif
http.end();
return std::make_pair("", httpResponseCode);
}
String responseBody = http.getString();
// Cleanup
http.end();
return std::make_pair(responseBody, httpResponseCode);
}
// Function to decode JSON response
DynamicJsonDocument decodeJsonResponse(const String& json) {
DynamicJsonDocument doc(1024); // Adjust the size as per your JSON data
DeserializationError error = deserializeJson(doc, json);
if (error) {
#ifdef SERIAL_DEBUG
Serial.print("Failed to parse JSON: ");
Serial.println(error.c_str());
#endif
}
return doc;
}
};
// Function to send the authentication request to Tinance2
void tinance2authrequest(String fullCardID, String cardID) {
#ifdef SERIAL_DEBUG
Serial.println("WIFI Status: " + String(WiFi.status()));
#endif
if (WiFi.status() == WL_CONNECTED) {
#ifdef SERIAL_DEBUG
Serial.println("Sending Request to Tinance2 for card: " + fullCardID);
#endif
// Create the JSON payload
String payload = "{\"full_card_id\":\"" + String(fullCardID) + "\"}";
// Send the HTTP request and get the response
Tinance2HttpClient httpClient;
std::pair<String, int> responsePair = httpClient.sendHttpRequest(tinance2_url_validatecard, "POST", payload);
String response = responsePair.first;
int httpResponseCode = responsePair.second;
#ifdef SERIAL_DEBUG
// Print the response
Serial.println("HTTP Response: " + response);
#endif
// Process the response
if (httpResponseCode != 200 && httpResponseCode != 401 && httpResponseCode != 402 && httpResponseCode != 403) {
#ifdef LOCAL_ACL
#ifdef SERIAL_DEBUG
Serial.println("Got unexpected http response using offline auth.");
#endif
localAcl(String(cardID));
#endif
return;
}
// Check the response code
if (httpResponseCode == 200) {
Serial.println("Tinance2 Door Access Granted");
if (settings.getDoorMode() == "LATCH") {
if (!settings.getDoorDisabled()) {
unlockDoor(false);
delay(RELAY_DELAY);
lockDoor(false);
}
}
if (settings.getDoorMode() == "TOGGLE") {
if (!settings.getDoorDisabled()) {
toggleDoor();
delay(RELAY_DELAY);
}
}
} else if (httpResponseCode == 400 || httpResponseCode == 401 || httpResponseCode == 402 || httpResponseCode == 403) {
#ifdef SERIAL_DEBUG
Serial.println("Tinance2 Door Access Denied");
#endif
#ifdef BUZZER
denied_beep();
#endif
}
} else {
#ifdef SERIAL_DEBUG
Serial.println("Tinance2 Wifi Disconnected using offline processes.");
#endif
#ifdef LOCAL_ACL
localAcl(String(cardID));
#endif
}
}
#ifdef TINANCE2_BACKEND_SYNC
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
void tinance2SyncTaskFunction(void *parameter) {
while (true) {
// Your code here
#ifdef SERIAL_DEBUG
Serial.println("Syncing Tinance2");
#endif
vTaskDelay(pdMS_TO_TICKS(15000)); // Delay for 15 seconds
if (WiFi.status() == WL_CONNECTED) {
Tinance2HttpClient httpClient;
std::pair<String, int> responsePair = httpClient.sendHttpRequest(tinance2_url_readerinfo, "GET", "");
String response = responsePair.first;
int httpResponseCode = responsePair.second;
#ifdef SERIAL_DEBUG
// Print the response
Serial.println("HTTP Response: " + response);
Serial.println("HTTP Response Code: " + String(httpResponseCode));
#endif
// Process the response
DynamicJsonDocument json = httpClient.decodeJsonResponse(response);
if (json.containsKey("enabled")) {
bool DisableDoor = json["enabled"].as<bool>();
settings.setDisableDoor(!DisableDoor);
#ifdef SERIAL_DEBUG
Serial.println("JSON Reader Enabled: " + json["enabled"].as<String>());
#endif
}
if (json.containsKey("mode")) {
String doorMode = json["mode"].as<String>();
settings.setDoorMode(doorMode);
#ifdef SERIAL_DEBUG
Serial.println("JSON Reader Mode: " + json["mode"].as<String>());
#endif
}
}
}
}
#endif
#endif
void setup() { void setup() {
// allow reuse (if server supports it)
http.setReuse(true);
#if defined SERIAL_DEBUG || defined SERIAL_ACL #if defined SERIAL_DEBUG || defined SERIAL_ACL
Serial.begin(9600); Serial.begin(9600);
#endif #endif

View file

@ -50,3 +50,5 @@ void Settings::setDoorMode(const String mode) {
String Settings::getDoorMode() { String Settings::getDoorMode() {
return doorMode; return doorMode;
} }
Settings settings;

190
src/tinance2.cpp Normal file
View file

@ -0,0 +1,190 @@
#include "tinance2.h"
#include <HTTPClient.h>
HTTPClient tinance2_http;
class Tinance2HttpClient {
public:
Tinance2HttpClient() {}
std::pair<String, int> sendHttpRequest(String url, String method, String payload) {
if (!tinance2_http.begin(url)) {
#ifdef SERIAL_DEBUG
Serial.println("Failed to begin HTTP request");
#endif
tinance2_http.end();
return std::make_pair("", -1);
}
// Set the headers
tinance2_http.addHeader("Content-Type", "application/json");
tinance2_http.addHeader("X-Identifier", tinance2_reader_identifer);
tinance2_http.addHeader("X-Access-Key", tinance2_reader_key);
// Set the HTTP timeout to 5 seconds
tinance2_http.setTimeout(5000);
// Send the POST request
int httpResponseCode;
if (method == "POST") {
httpResponseCode = tinance2_http.POST(payload);
} else if (method == "GET") {
httpResponseCode = tinance2_http.GET();
} else {
// Handle invalid method
#ifdef SERIAL_DEBUG
Serial.println("Invalid HTTP method");
#endif
tinance2_http.end();
return std::make_pair("", -1);
}
if (httpResponseCode <= 0) {
#ifdef SERIAL_DEBUG
Serial.println("Request Failed (response less than 0)");
#endif
tinance2_http.end();
return std::make_pair("", httpResponseCode);
}
String responseBody = tinance2_http.getString();
// Cleanup
tinance2_http.end();
return std::make_pair(responseBody, httpResponseCode);
}
// Function to decode JSON response
DynamicJsonDocument decodeJsonResponse(const String& json) {
DynamicJsonDocument doc(1024); // Adjust the size as per your JSON data
DeserializationError error = deserializeJson(doc, json);
if (error) {
#ifdef SERIAL_DEBUG
Serial.print("Failed to parse JSON: ");
Serial.println(error.c_str());
#endif
}
return doc;
}
};
// Function to send the authentication request to Tinance2
void tinance2authrequest(String fullCardID, String cardID) {
#ifdef SERIAL_DEBUG
Serial.println("WIFI Status: " + String(WiFi.status()));
#endif
if (WiFi.status() == WL_CONNECTED) {
#ifdef SERIAL_DEBUG
Serial.println("Sending Request to Tinance2 for card: " + fullCardID);
#endif
// Create the JSON payload
String payload = "{\"full_card_id\":\"" + String(fullCardID) + "\"}";
// Send the HTTP request and get the response
Tinance2HttpClient httpClient;
std::pair<String, int> responsePair = httpClient.sendHttpRequest(tinance2_url_validatecard, "POST", payload);
String response = responsePair.first;
int httpResponseCode = responsePair.second;
#ifdef SERIAL_DEBUG
// Print the response
Serial.println("HTTP Response: " + response);
#endif
// Process the response
if (httpResponseCode != 200 && httpResponseCode != 401 && httpResponseCode != 402 && httpResponseCode != 403) {
#ifdef LOCAL_ACL
#ifdef SERIAL_DEBUG
Serial.println("Got unexpected http response using offline auth.");
#endif
localAcl(String(cardID));
#endif
return;
}
// Check the response code
if (httpResponseCode == 200) {
Serial.println("Tinance2 Door Access Granted");
if (settings.getDoorMode() == "LATCH") {
if (!settings.getDoorDisabled()) {
unlockDoor(false);
delay(RELAY_DELAY);
lockDoor(false);
}
}
if (settings.getDoorMode() == "TOGGLE") {
if (!settings.getDoorDisabled()) {
toggleDoor();
delay(RELAY_DELAY);
}
}
} else if (httpResponseCode == 400 || httpResponseCode == 401 || httpResponseCode == 402 || httpResponseCode == 403) {
#ifdef SERIAL_DEBUG
Serial.println("Tinance2 Door Access Denied");
#endif
#ifdef BUZZER
denied_beep();
#endif
}
} else {
#ifdef SERIAL_DEBUG
Serial.println("Tinance2 Wifi Disconnected using offline processes.");
#endif
#ifdef LOCAL_ACL
localAcl(String(cardID));
#endif
}
}
void tinance2SyncTaskFunction(void *parameter) {
while (true) {
// Your code here
#ifdef SERIAL_DEBUG
Serial.println("Syncing Tinance2");
#endif
vTaskDelay(pdMS_TO_TICKS(15000)); // Delay for 15 seconds
if (WiFi.status() == WL_CONNECTED) {
Tinance2HttpClient httpClient;
std::pair<String, int> responsePair = httpClient.sendHttpRequest(tinance2_url_readerinfo, "GET", "");
String response = responsePair.first;
int httpResponseCode = responsePair.second;
#ifdef SERIAL_DEBUG
// Print the response
Serial.println("HTTP Response: " + response);
Serial.println("HTTP Response Code: " + String(httpResponseCode));
#endif
// Process the response
DynamicJsonDocument json = httpClient.decodeJsonResponse(response);
if (json.containsKey("enabled")) {
bool DisableDoor = json["enabled"].as<bool>();
settings.setDisableDoor(!DisableDoor);
#ifdef SERIAL_DEBUG
Serial.println("JSON Reader Enabled: " + json["enabled"].as<String>());
#endif
}
if (json.containsKey("mode")) {
String doorMode = json["mode"].as<String>();
settings.setDoorMode(doorMode);
#ifdef SERIAL_DEBUG
Serial.println("JSON Reader Mode: " + json["mode"].as<String>());
#endif
}
}
}
}