RFID message ins backend geht, websocket fürs frontend
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
#include "helper.h"
|
||||
#include <debug.h>
|
||||
#include <map>
|
||||
#include <databasebackend.h>
|
||||
#include <webserverrouter.h>
|
||||
|
||||
struct TimestampData {
|
||||
uint64_t lastMessageTimestamp; // Timestamp from the device
|
||||
@@ -35,52 +37,6 @@ typedef struct {
|
||||
|
||||
PicoMQTT::Server mqtt;
|
||||
|
||||
void processHeartbeat(const char* topic, const char* payload) {
|
||||
String macAddress = String(topic).substring(15);
|
||||
|
||||
StaticJsonDocument<200> doc;
|
||||
DeserializationError error = deserializeJson(doc, payload);
|
||||
|
||||
if (error) {
|
||||
Serial.printf("JSON parsing failed for MAC %s: %s\n", macAddress.c_str(), error.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t messageTimestamp = doc["timestamp"] | 0;
|
||||
uint64_t currentLocalTime = getCurrentTimestampMs();
|
||||
|
||||
// Update timestamps for current device
|
||||
if (deviceTimestamps.count(macAddress) > 0) {
|
||||
TimestampData& data = deviceTimestamps[macAddress];
|
||||
uint64_t messageDiff = messageTimestamp - data.lastMessageTimestamp;
|
||||
uint64_t localDiff = currentLocalTime - data.lastLocalTimestamp;
|
||||
data.drift = localDiff - messageDiff;
|
||||
}
|
||||
|
||||
// Calculate drift relative to all other devices
|
||||
Serial.printf("\nDrift analysis for device %s:\n", macAddress.c_str());
|
||||
Serial.println("----------------------------------------");
|
||||
|
||||
for (const auto& device : deviceTimestamps) {
|
||||
if (device.first != macAddress) { // Skip comparing to self
|
||||
int64_t timeDiff = messageTimestamp - device.second.lastMessageTimestamp;
|
||||
int64_t relativeDrift = timeDiff - (currentLocalTime - device.second.lastLocalTimestamp);
|
||||
|
||||
Serial.printf("Relative to %s:\n", device.first.c_str());
|
||||
Serial.printf(" Time difference: %lld ms\n", timeDiff);
|
||||
Serial.printf(" Relative drift: %lld ms\n", relativeDrift);
|
||||
Serial.println("----------------------------------------");
|
||||
}
|
||||
}
|
||||
|
||||
// Update stored timestamps for current device
|
||||
deviceTimestamps[macAddress] = {
|
||||
messageTimestamp,
|
||||
currentLocalTime,
|
||||
deviceTimestamps[macAddress].drift
|
||||
};
|
||||
}
|
||||
|
||||
void readButtonJSON(const char * topic, const char * payload) {
|
||||
|
||||
if(strcmp(topic, "aquacross/button/press") == 0){
|
||||
@@ -133,22 +89,99 @@ void readButtonJSON(const char * topic, const char * payload) {
|
||||
}
|
||||
}
|
||||
|
||||
void readRFIDfromButton(const char * topic, const char * payload) {
|
||||
// Create a JSON document to hold the button press data
|
||||
StaticJsonDocument<256> doc;
|
||||
DeserializationError error = deserializeJson(doc, payload);
|
||||
if (!error) {
|
||||
const char* mac = doc["buttonmac"] | "unknown";
|
||||
const char* uid = doc["uid"] | "unknown";
|
||||
|
||||
Serial.printf("RFID Read from Button:\n");
|
||||
Serial.printf(" Button MAC: %s\n", mac);
|
||||
Serial.printf(" UID: %s\n", uid);
|
||||
|
||||
// Convert buttonmac to byte array for comparison
|
||||
auto macBytes = macStringToBytes(mac);
|
||||
|
||||
// Check if the buttonmac matches buttonConfigs.start1.mac
|
||||
if (memcmp(macBytes.data(), buttonConfigs.start1.mac, 6) == 0) {
|
||||
// Fetch user data
|
||||
UserData userData = checkUser(uid);
|
||||
if (userData.exists) {
|
||||
// Log user data
|
||||
Serial.printf("User found for start1: %s %s, Alter: %d\n",
|
||||
userData.firstname.c_str(),
|
||||
userData.lastname.c_str(),
|
||||
userData.alter);
|
||||
|
||||
// Create JSON message to send to the frontend
|
||||
StaticJsonDocument<128> messageDoc;
|
||||
messageDoc["firstname"] = userData.firstname;
|
||||
messageDoc["lastname"] = userData.lastname;
|
||||
messageDoc["lane"] = "start1"; // Add lane information
|
||||
|
||||
String message;
|
||||
serializeJson(messageDoc, message);
|
||||
|
||||
// Push the message to the frontend
|
||||
pushUpdateToFrontend(message);
|
||||
Serial.printf("Pushed user data for start1 to frontend: %s\n", message.c_str());
|
||||
} else {
|
||||
Serial.println("User not found for UID: " + String(uid));
|
||||
}
|
||||
}
|
||||
// Check if the buttonmac matches buttonConfigs.start2.mac
|
||||
else if (memcmp(macBytes.data(), buttonConfigs.start2.mac, 6) == 0) {
|
||||
// Fetch user data
|
||||
UserData userData = checkUser(uid);
|
||||
if (userData.exists) {
|
||||
// Log user data
|
||||
Serial.printf("User found for start2: %s %s, Alter: %d\n",
|
||||
userData.firstname.c_str(),
|
||||
userData.lastname.c_str(),
|
||||
userData.alter);
|
||||
|
||||
// Create JSON message to send to the frontend
|
||||
StaticJsonDocument<128> messageDoc;
|
||||
messageDoc["firstname"] = userData.firstname;
|
||||
messageDoc["lastname"] = userData.lastname;
|
||||
messageDoc["lane"] = "start2"; // Add lane information
|
||||
|
||||
String message;
|
||||
serializeJson(messageDoc, message);
|
||||
|
||||
// Push the message to the frontend
|
||||
pushUpdateToFrontend(message);
|
||||
Serial.printf("Pushed user data for start2 to frontend: %s\n", message.c_str());
|
||||
} else {
|
||||
Serial.println("User not found for UID: " + String(uid));
|
||||
}
|
||||
} else {
|
||||
Serial.println("Button MAC does not match start1.mac or start2.mac");
|
||||
}
|
||||
} else {
|
||||
Serial.println("Failed to parse RFID JSON");
|
||||
}
|
||||
}
|
||||
|
||||
void setupMqttServer() {
|
||||
|
||||
// Set up the MQTT server with the desired port
|
||||
// Subscribe to a topic pattern and attach a callback
|
||||
mqtt.subscribe("#", [](const char * topic, const char * payload) {
|
||||
if (strncmp(topic, "heartbeat/alive/", 15) == 0) {
|
||||
processHeartbeat(topic, payload);
|
||||
} else if (strcmp(topic, "aquacross/button/press") == 0) {
|
||||
//Message received callback
|
||||
//Serial.printf("Received message on topic '%s': %s\n", topic, payload);
|
||||
if (strcmp(topic, "aquacross/button/press") == 0) {
|
||||
readButtonJSON(topic, payload);
|
||||
} else if (strncmp(topic, "aquacross/button/rfid/", 22) == 0) {
|
||||
readRFIDfromButton(topic, payload);
|
||||
// Handle RFID read messages
|
||||
|
||||
}
|
||||
updateStatusLED(3);
|
||||
});
|
||||
|
||||
// Add the button subscription
|
||||
|
||||
|
||||
// Start the MQTT server
|
||||
mqtt.begin();
|
||||
|
||||
@@ -168,6 +201,7 @@ void loopMqttServer() {
|
||||
mqtt.publish("sync/time", timeStr);
|
||||
lastPublish = millis();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void sendMQTTMessage(const char * topic, const char * message) {
|
||||
@@ -187,3 +221,5 @@ void sendMQTTJSONMessage(const char * topic, const JsonDocument & doc) {
|
||||
Serial.printf("Published JSON message to topic '%s': %s\n", topic, jsonString.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include <HTTPClient.h>
|
||||
#include "master.h"
|
||||
@@ -17,34 +18,76 @@ bool backendOnline() {
|
||||
http.addHeader("Authorization", String("Bearer ") + BACKEND_TOKEN);
|
||||
|
||||
int httpCode = http.GET();
|
||||
bool isOnline = (httpCode == HTTP_CODE_OK);
|
||||
|
||||
if (httpCode == HTTP_CODE_OK) {
|
||||
return true;
|
||||
if (isOnline) {
|
||||
Serial.println("Database server connection successful");
|
||||
} else {
|
||||
return false;
|
||||
Serial.printf("Database server connection failed, error: %d\n", httpCode);
|
||||
}
|
||||
|
||||
http.end();
|
||||
return isOnline;
|
||||
}
|
||||
|
||||
bool userExists(const String& userId) {
|
||||
struct UserData {
|
||||
String uid;
|
||||
String firstname;
|
||||
String lastname;
|
||||
int alter;
|
||||
bool exists;
|
||||
};
|
||||
|
||||
// UserData checkUser(const String& uid) is defined only once to avoid redefinition errors.
|
||||
UserData checkUser(const String& uid) {
|
||||
|
||||
UserData userData = {"", "", "", 0, false};
|
||||
|
||||
if (!backendOnline()) {
|
||||
Serial.println("No internet connection, cannot check user existence.");
|
||||
return false;
|
||||
Serial.println("No internet connection, cannot check user.");
|
||||
return userData;
|
||||
}
|
||||
|
||||
HTTPClient http;
|
||||
http.begin(String(BACKEND_SERVER) + "/api/users/" + userId);
|
||||
http.begin(String(BACKEND_SERVER) + "/api/users/find");
|
||||
http.addHeader("Content-Type", "application/json");
|
||||
http.addHeader("Authorization", String("Bearer ") + BACKEND_TOKEN);
|
||||
|
||||
//Post request to check if user exists
|
||||
int httpCode = http.POST("");
|
||||
// Create JSON payload
|
||||
StaticJsonDocument<200> requestDoc;
|
||||
requestDoc["uid"] = uid;
|
||||
String requestBody;
|
||||
serializeJson(requestDoc, requestBody);
|
||||
|
||||
int httpCode = http.POST(requestBody);
|
||||
|
||||
if (httpCode == HTTP_CODE_OK) {
|
||||
String payload = http.getString();
|
||||
StaticJsonDocument<512> responseDoc;
|
||||
DeserializationError error = deserializeJson(responseDoc, payload);
|
||||
|
||||
if (!error) {
|
||||
userData.uid = responseDoc["uid"].as<String>();
|
||||
userData.firstname = responseDoc["firstname"].as<String>();
|
||||
userData.lastname = responseDoc["lastname"].as<String>();
|
||||
userData.alter = responseDoc["alter"] | 0;
|
||||
userData.exists = true;
|
||||
}
|
||||
} else {
|
||||
Serial.printf("User check failed, HTTP code: %d\n", httpCode);
|
||||
}
|
||||
|
||||
http.end();
|
||||
return userData;
|
||||
}
|
||||
|
||||
// Keep this for backward compatibility
|
||||
bool userExists(const String& uid) {
|
||||
return checkUser(uid).exists;
|
||||
}
|
||||
|
||||
void setupBackendRoutes(AsyncWebServer& server) {
|
||||
|
||||
server.on("/api/health", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
|
||||
DynamicJsonDocument doc(64);
|
||||
|
||||
@@ -162,10 +162,26 @@ void saveWifiSettings() {
|
||||
}
|
||||
|
||||
void loadWifiSettings() {
|
||||
preferences.begin("wifi", true);
|
||||
ssidSTA = preferences.getString("ssid", "").c_str();
|
||||
passwordSTA = preferences.getString("password", "").c_str();
|
||||
preferences.end();
|
||||
preferences.begin("wifi", true);
|
||||
|
||||
// Speicher freigeben, falls bereits zugewiesen
|
||||
if (ssidSTA) {
|
||||
free(ssidSTA);
|
||||
}
|
||||
if (passwordSTA) {
|
||||
free(passwordSTA);
|
||||
}
|
||||
|
||||
// Neue Werte laden und dynamisch zuweisen
|
||||
String ssid = preferences.getString("ssid", "");
|
||||
String password = preferences.getString("password", "");
|
||||
ssidSTA = strdup(ssid.c_str());
|
||||
passwordSTA = strdup(password.c_str());
|
||||
|
||||
preferences.end();
|
||||
|
||||
// Debug-Ausgabe
|
||||
Serial.printf("WLAN-Einstellungen geladen: SSID=%s, Passwort=%s\n", ssidSTA, passwordSTA);
|
||||
}
|
||||
|
||||
int checkLicence() {
|
||||
@@ -179,7 +195,6 @@ String getTimerDataJSON() {
|
||||
DynamicJsonDocument doc(1024);
|
||||
|
||||
unsigned long currentTime = millis();
|
||||
|
||||
// Bahn 1
|
||||
if (timerData.isRunning1) {
|
||||
doc["time1"] = (currentTime - timerData.startTime1) / 1000.0;
|
||||
@@ -234,7 +249,7 @@ void setup() {
|
||||
setupTimeAPI(server);
|
||||
setupLicenceAPI(server);
|
||||
setupDebugAPI(server);
|
||||
setupBackendRoutes(server);
|
||||
setupBackendRoutes(server);// Speichere WLAN-Einstellungen, falls noch nicht vorhanden
|
||||
|
||||
|
||||
// Gespeicherte Daten laden
|
||||
@@ -246,6 +261,7 @@ void setup() {
|
||||
setupOTA(&server);
|
||||
|
||||
setupRoutes();
|
||||
setupWebSocket();
|
||||
setupLED();
|
||||
setupMqttServer(); // MQTT Server initialisieren
|
||||
|
||||
@@ -255,4 +271,5 @@ void setup() {
|
||||
void loop() {
|
||||
checkAutoReset();
|
||||
loopMqttServer(); // MQTT Server in der Loop aufrufen
|
||||
loopWebSocket();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include <WebServer.h>
|
||||
#include <ArduinoJson.h>
|
||||
@@ -21,10 +22,6 @@ struct User {
|
||||
unsigned long timestamp;
|
||||
};
|
||||
|
||||
// Array für Benutzer (max 100 Benutzer)
|
||||
User users[100];
|
||||
int userCount = 0;
|
||||
|
||||
void setupRFID() {
|
||||
|
||||
// SPI und RFID initialisieren
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include "master.h"
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <AsyncWebSocket.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <SPIFFS.h>
|
||||
#include <esp_wifi.h>
|
||||
|
||||
|
||||
#include <buttonassigh.h>
|
||||
#include <wificlass.h>
|
||||
|
||||
AsyncWebServer server(80);
|
||||
AsyncWebSocket ws("/ws");
|
||||
|
||||
void setupRoutes(){
|
||||
// Web Server Routes
|
||||
// Web Server Routes
|
||||
|
||||
// Attach WebSocket to the server
|
||||
server.addHandler(&ws);
|
||||
|
||||
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(SPIFFS, "/index.html", "text/html");
|
||||
@@ -166,34 +173,35 @@ void setupRoutes(){
|
||||
});
|
||||
|
||||
// Setze WLAN-Name und Passwort (POST)
|
||||
server.on("/api/set-wifi", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||
server.on("/api/set-wifi", HTTP_POST, [](AsyncWebServerRequest *request) {
|
||||
Serial.println("/api/set-wifi called");
|
||||
String ssid, password;
|
||||
if (request->hasParam("ssid", true)) {
|
||||
ssid = request->getParam("ssid", true)->value();
|
||||
ssid = request->getParam("ssid", true)->value();
|
||||
}
|
||||
if (request->hasParam("password", true)) {
|
||||
password = request->getParam("password", true)->value();
|
||||
password = request->getParam("password", true)->value();
|
||||
}
|
||||
if (ssid.length() > 0) {
|
||||
// Hier speichern wir die neuen Werte (z.B. in Preferences oder global)
|
||||
// Beispiel: strcpy(ssidSTA, ssid.c_str());
|
||||
// Beispiel: strcpy(passwordSTA, password.c_str());
|
||||
// In deinem Projekt ggf. persistent speichern!
|
||||
// Hier als global (unsicher, nach Neustart verloren!):
|
||||
ssidSTA = strdup(ssid.c_str());
|
||||
passwordSTA = strdup(password.c_str());
|
||||
// Rückmeldung
|
||||
DynamicJsonDocument doc(64);
|
||||
doc["success"] = true;
|
||||
String result;
|
||||
serializeJson(doc, result);
|
||||
request->send(200, "application/json", result);
|
||||
Serial.println("WiFi-Settings updated (nur bis zum Neustart aktiv!)");
|
||||
// Speicher freigeben, bevor neue Werte zugewiesen werden
|
||||
free(ssidSTA);
|
||||
free(passwordSTA);
|
||||
|
||||
// Neue Werte zuweisen
|
||||
ssidSTA = strdup(ssid.c_str());
|
||||
passwordSTA = strdup(password.c_str());
|
||||
|
||||
// Rückmeldung
|
||||
DynamicJsonDocument doc(64);
|
||||
doc["success"] = true;
|
||||
String result;
|
||||
serializeJson(doc, result);
|
||||
request->send(200, "application/json", result);
|
||||
Serial.println("WiFi-Settings updated (nur bis zum Neustart aktiv!)");
|
||||
} else {
|
||||
request->send(400, "application/json", "{\"success\":false,\"error\":\"SSID fehlt\"}");
|
||||
request->send(400, "application/json", "{\"success\":false,\"error\":\"SSID fehlt\"}");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Liefert aktuelle WLAN-Einstellungen (GET)
|
||||
server.on("/api/get-wifi", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
@@ -210,4 +218,25 @@ void setupRoutes(){
|
||||
server.begin();
|
||||
Serial.println("Web Server gestartet");
|
||||
|
||||
}
|
||||
|
||||
void setupWebSocket() {
|
||||
ws.onEvent([](AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
|
||||
if (type == WS_EVT_CONNECT) {
|
||||
Serial.printf("WebSocket client connected: %u\n", client->id());
|
||||
} else if (type == WS_EVT_DISCONNECT) {
|
||||
Serial.printf("WebSocket client disconnected: %u\n", client->id());
|
||||
} else if (type == WS_EVT_DATA) {
|
||||
// Handle incoming WebSocket messages if needed
|
||||
Serial.printf("WebSocket message received: %s\n", (char *)data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void pushUpdateToFrontend(const String &message) {
|
||||
ws.textAll(message); // Send the message to all connected clients
|
||||
}
|
||||
|
||||
void loopWebSocket() {
|
||||
ws.cleanupClients(); // Clean up disconnected clients
|
||||
}
|
||||
@@ -13,8 +13,8 @@ String uniqueSSID;
|
||||
const char* ssidAP;
|
||||
const char* passwordAP = nullptr;
|
||||
|
||||
const char* ssidSTA = "Obiwlankenobi";
|
||||
const char* passwordSTA = "Delfine1!";
|
||||
char* ssidSTA = strdup("Obiwlankenobi");
|
||||
char* passwordSTA = strdup("Delfine1!");
|
||||
|
||||
PrettyOTA OTAUpdates;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user