From 02a60d84cf14fd28026a830295e8bc8e99052b98 Mon Sep 17 00:00:00 2001 From: Carsten Graf Date: Thu, 18 Sep 2025 23:21:14 +0200 Subject: [PATCH] Update --- data/index.css | 12 ++--- data/settings.css | 2 +- src/databasebackend.h | 81 +++++++++++++++--------------- src/master.h | 10 ++-- src/preferencemanager.h | 10 ++-- src/rfid.h | 2 + src/webserverrouter.h | 107 +++++++++++++++++++++++----------------- 7 files changed, 123 insertions(+), 101 deletions(-) diff --git a/data/index.css b/data/index.css index 1269fa9..51ee23f 100644 --- a/data/index.css +++ b/data/index.css @@ -12,7 +12,7 @@ html { body { font-family: "Segoe UI", Arial, sans-serif; - background: linear-gradient(135deg, #49bae4 0%, #223c83 100%); + background: linear-gradient(0deg, #0d1733 0%, #223c83 100%); height: 100vh; width: 100vw; display: flex; @@ -38,8 +38,8 @@ body { text-decoration: none; display: block; cursor: pointer; - padding-left: 5px; - padding-right: 5px; + padding: 5px; + background:rgba(255, 255, 255, 0.6); } .logo:hover { @@ -367,8 +367,8 @@ body { } .status.ready { - background-color: rgba(34, 60, 131, 0.3); - border: 2px solid #223c83; + background-color: rgb(0 165 3 / 54%); + border: 2px solid #06ff00; animation: pulse 1s infinite; } @@ -379,7 +379,7 @@ body { } .status.running { - background-color: rgba(245, 157, 15, 0.3); + background-color: rgb(255 91 0 / 65%); border: 2px solid #f59d0f; } diff --git a/data/settings.css b/data/settings.css index 9d91852..d57bb40 100644 --- a/data/settings.css +++ b/data/settings.css @@ -6,7 +6,7 @@ body { font-family: "Segoe UI", Arial, sans-serif; - background: linear-gradient(135deg, #49bae4 0%, #223c83 100%); + background: linear-gradient(0deg, #0d1733 0%, #223c83 100%); min-height: 100vh; padding: 20px; } diff --git a/src/databasebackend.h b/src/databasebackend.h index 6435533..75c32b3 100644 --- a/src/databasebackend.h +++ b/src/databasebackend.h @@ -1,6 +1,7 @@ #pragma once -#include "master.h" #include +#include +#include #include #include @@ -78,7 +79,7 @@ UserData checkUser(const String &uid) { userData.firstname = responseDoc["firstname"].as(); userData.lastname = responseDoc["lastname"].as(); userData.alter = responseDoc["alter"] | 0; - userData.exists = responseDoc["exists"] | true; + userData.exists = responseDoc["exists"] | false; } } else { Serial.printf("User check failed, HTTP code: %d\n", httpCode); @@ -88,43 +89,6 @@ UserData checkUser(const String &uid) { return userData; } -// Fügt einen neuen Benutzer mit den angegebenen Daten in die Datenbank ein. -bool enterUserData(const String &uid, const String &firstname, - const String &lastname, const String &geburtsdatum, - int alter) { - if (!backendOnline()) { - Serial.println("No internet connection, cannot enter user data."); - return false; - } - - HTTPClient http; - http.begin(String(BACKEND_SERVER) + "/v1/private/create-player"); - http.addHeader("Content-Type", "application/json"); - http.addHeader("Authorization", String("Bearer ") + BACKEND_TOKEN); - - // Create JSON payload - StaticJsonDocument<256> requestDoc; - requestDoc["rfiduid"] = uid; - requestDoc["firstname"] = firstname; - requestDoc["lastname"] = lastname; - requestDoc["birthdate"] = geburtsdatum; - - String requestBody; - serializeJson(requestDoc, requestBody); - - int httpCode = http.POST(requestBody); - - if (httpCode == HTTP_CODE_CREATED) { - Serial.println("User data entered successfully."); - http.end(); - return true; - } else { - Serial.printf("Failed to enter user data, HTTP code: %d\n", httpCode); - http.end(); - return false; - } -} - // Holt alle Standorte aus der Datenbank und gibt sie als JSON-Dokument zurück. JsonDocument getAllLocations() { JsonDocument locations; // Allocate memory for the JSON document @@ -159,6 +123,45 @@ JsonDocument getAllLocations() { // (Kompatibilitätsfunktion). bool userExists(const String &uid) { return checkUser(uid).exists; } +// Fügt einen neuen Benutzer in die Datenbank ein +bool enterUserData(const String &uid, const String &vorname, + const String &nachname, const String &geburtsdatum, + int alter) { + if (!backendOnline()) { + Serial.println("No internet connection, cannot enter user data."); + return false; + } + + HTTPClient http; + http.begin(String(BACKEND_SERVER) + "/v1/private/users/insert"); + http.addHeader("Content-Type", "application/json"); + http.addHeader("Authorization", String("Bearer ") + BACKEND_TOKEN); + + // Create JSON payload + StaticJsonDocument<512> requestDoc; + requestDoc["uid"] = uid; + requestDoc["firstname"] = vorname; + requestDoc["lastname"] = nachname; + requestDoc["geburtsdatum"] = geburtsdatum; + requestDoc["alter"] = alter; + + String requestBody; + serializeJson(requestDoc, requestBody); + + int httpCode = http.POST(requestBody); + + bool success = (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_CREATED); + + if (success) { + Serial.println("User data successfully entered into database"); + } else { + Serial.printf("Failed to enter user data, HTTP code: %d\n", httpCode); + } + + http.end(); + return success; +} + // Richtet die HTTP-Routen für die Backend-API ein (z.B. Health-Check, User- und // Location-Abfragen). void setupBackendRoutes(AsyncWebServer &server) { diff --git a/src/master.h b/src/master.h index 811c415..71fffe7 100644 --- a/src/master.h +++ b/src/master.h @@ -21,7 +21,7 @@ struct TimerData1 { bool isRunning = false; bool isReady = true; // Status für Bahn 1 bool isArmed = false; // Status für Bahn 1 (armiert/nicht armiert) - char RFIDUID = ""; + char RFIDUID[32] = ""; }; // Timer Struktur für Bahn 2 @@ -34,7 +34,7 @@ struct TimerData2 { bool isRunning = false; bool isReady = true; // Status für Bahn 2 bool isArmed = false; // Status für Bahn 2 (armiert/nicht armiert) - char RFIDUID = ""; + char RFIDUID[32] = ""; }; // Button Konfiguration @@ -69,9 +69,9 @@ int gamemode; // 0=Individual, 1=Wettkampf bool startCompetition = false; // Flag, ob der Timer gestartet wurde // Lane Configuration -int laneConfigType = 0; // 0=Identical, 1=Different -int lane1DifficultyType = 0; // 0=Light, 1=Heavy (difficulty) -int lane2DifficultyType = 0; // 0=Light, 1=Heavy (difficulty) +int laneConfigType = 0; // 0=Identical, 1=Different +int lane1DifficultyType = 0; // 0=Light, 1=Heavy (difficulty) +int lane2DifficultyType = 0; // 0=Light, 1=Heavy (difficulty) // Function Declarations void OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len); diff --git a/src/preferencemanager.h b/src/preferencemanager.h index bcfc7ee..ec056f7 100644 --- a/src/preferencemanager.h +++ b/src/preferencemanager.h @@ -2,8 +2,8 @@ #include #include -#include #include +#include // Persist and load button configuration void saveButtonConfig() { @@ -43,8 +43,8 @@ void saveSettings() { preferences.putULong("maxTimeDisplay", maxTimeDisplay); preferences.putUInt("gamemode", gamemode); preferences.putUInt("laneConfigType", laneConfigType); - preferences.putUInt("lane1DifficultyType", lane1DifficultyType); - preferences.putUInt("lane2DifficultyType", lane2DifficultyType); + preferences.putUInt("lane1Diff", lane1DifficultyType); + preferences.putUInt("lane2Diff", lane2DifficultyType); preferences.end(); } @@ -54,8 +54,8 @@ void loadSettings() { maxTimeDisplay = preferences.getULong("maxTimeDisplay", 20000); gamemode = preferences.getUInt("gamemode", 0); laneConfigType = preferences.getUInt("laneConfigType", 0); - lane1DifficultyType = preferences.getUInt("lane1DifficultyType", 0); - lane2DifficultyType = preferences.getUInt("lane2DifficultyType", 0); + lane1DifficultyType = preferences.getUInt("lane1Diff", 0); + lane2DifficultyType = preferences.getUInt("lane2Diff", 0); preferences.end(); } diff --git a/src/rfid.h b/src/rfid.h index 84c1c18..6c7e800 100644 --- a/src/rfid.h +++ b/src/rfid.h @@ -1,9 +1,11 @@ #pragma once +#include "databasebackend.h" #include #include #include #include + // RFID Konfiguration #define RST_PIN 21 // Configurable, see typical pin layout above #define SS_PIN 5 // Configurable, see typical pin layout above diff --git a/src/webserverrouter.h b/src/webserverrouter.h index 5c20ef2..d7d17a4 100644 --- a/src/webserverrouter.h +++ b/src/webserverrouter.h @@ -33,7 +33,6 @@ void setupRoutes() { request->send(SPIFFS, "/settings.html", "text/html"); }); - server.on("/firmware.bin", HTTP_GET, [](AsyncWebServerRequest *request) { if (SPIFFS.exists("/firmware.bin")) { request->send(SPIFFS, "/firmware.bin", "application/octet-stream"); @@ -313,51 +312,69 @@ void setupRoutes() { }); // Lane Configuration API Routes - server.on("/api/set-lane-config", HTTP_POST, [](AsyncWebServerRequest *request) { - Serial.println("/api/set-lane-config called"); - - String body = request->getBody(); - DynamicJsonDocument doc(256); - deserializeJson(doc, body); - - if (doc.containsKey("type")) { - String laneType = doc["type"]; - laneConfigType = (laneType == "identical") ? 0 : 1; - - if (laneConfigType == 1 && doc.containsKey("lane1Difficulty") && doc.containsKey("lane2Difficulty")) { - String lane1Difficulty = doc["lane1Difficulty"]; - String lane2Difficulty = doc["lane2Difficulty"]; - lane1DifficultyType = (lane1Difficulty == "light") ? 0 : 1; - lane2DifficultyType = (lane2Difficulty == "light") ? 0 : 1; - } - - Serial.printf("Lane configuration set - Type: %s, Lane1: %s, Lane2: %s\n", - laneType.c_str(), - (laneConfigType == 1) ? ((lane1DifficultyType == 0) ? "light" : "heavy") : "identical", - (laneConfigType == 1) ? ((lane2DifficultyType == 0) ? "light" : "heavy") : "identical"); - - DynamicJsonDocument response(64); - response["success"] = true; - String result; - serializeJson(response, result); - request->send(200, "application/json", result); - saveSettings(); - } else { - request->send(400, "application/json", "{\"success\":false,\"error\":\"Lane type missing\"}"); - } - }); + server.on( + "/api/set-lane-config", HTTP_POST, [](AsyncWebServerRequest *request) {}, + NULL, + [](AsyncWebServerRequest *request, uint8_t *data, size_t len, + size_t index, size_t total) { + Serial.println("/api/set-lane-config called"); - server.on("/api/get-lane-config", HTTP_GET, [](AsyncWebServerRequest *request) { - DynamicJsonDocument doc(128); - doc["type"] = laneConfigType == 0 ? "identical" : "different"; - if (laneConfigType == 1) { - doc["lane1Difficulty"] = lane1DifficultyType == 0 ? "light" : "heavy"; - doc["lane2Difficulty"] = lane2DifficultyType == 0 ? "light" : "heavy"; - } - String result; - serializeJson(doc, result); - request->send(200, "application/json", result); - }); + DynamicJsonDocument doc(256); + DeserializationError error = deserializeJson(doc, data, len); + + if (error) { + Serial.println("JSON parsing error"); + request->send(400, "application/json", + "{\"success\":false,\"error\":\"Invalid JSON\"}"); + return; + } + + if (doc.containsKey("type")) { + String laneType = doc["type"]; + laneConfigType = (laneType == "identical") ? 0 : 1; + + if (laneConfigType == 1 && doc.containsKey("lane1Difficulty") && + doc.containsKey("lane2Difficulty")) { + String lane1Difficulty = doc["lane1Difficulty"]; + String lane2Difficulty = doc["lane2Difficulty"]; + lane1DifficultyType = (lane1Difficulty == "light") ? 0 : 1; + lane2DifficultyType = (lane2Difficulty == "light") ? 0 : 1; + } + + Serial.printf( + "Lane configuration set - Type: %s, Lane1: %s, Lane2: %s\n", + laneType.c_str(), + (laneConfigType == 1) + ? ((lane1DifficultyType == 0) ? "light" : "heavy") + : "identical", + (laneConfigType == 1) + ? ((lane2DifficultyType == 0) ? "light" : "heavy") + : "identical"); + + DynamicJsonDocument response(64); + response["success"] = true; + String result; + serializeJson(response, result); + request->send(200, "application/json", result); + saveSettings(); + } else { + request->send(400, "application/json", + "{\"success\":false,\"error\":\"Lane type missing\"}"); + } + }); + + server.on( + "/api/get-lane-config", HTTP_GET, [](AsyncWebServerRequest *request) { + DynamicJsonDocument doc(128); + doc["type"] = laneConfigType == 0 ? "identical" : "different"; + if (laneConfigType == 1) { + doc["lane1Difficulty"] = lane1DifficultyType == 0 ? "light" : "heavy"; + doc["lane2Difficulty"] = lane2DifficultyType == 0 ? "light" : "heavy"; + } + String result; + serializeJson(doc, result); + request->send(200, "application/json", result); + }); // Statische Dateien server.serveStatic("/", SPIFFS, "/");