Update
This commit is contained in:
@@ -12,7 +12,7 @@ html {
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: "Segoe UI", Arial, sans-serif;
|
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;
|
height: 100vh;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -38,8 +38,8 @@ body {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
display: block;
|
display: block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding-left: 5px;
|
padding: 5px;
|
||||||
padding-right: 5px;
|
background:rgba(255, 255, 255, 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo:hover {
|
.logo:hover {
|
||||||
@@ -367,8 +367,8 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.status.ready {
|
.status.ready {
|
||||||
background-color: rgba(34, 60, 131, 0.3);
|
background-color: rgb(0 165 3 / 54%);
|
||||||
border: 2px solid #223c83;
|
border: 2px solid #06ff00;
|
||||||
animation: pulse 1s infinite;
|
animation: pulse 1s infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,7 +379,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.status.running {
|
.status.running {
|
||||||
background-color: rgba(245, 157, 15, 0.3);
|
background-color: rgb(255 91 0 / 65%);
|
||||||
border: 2px solid #f59d0f;
|
border: 2px solid #f59d0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: "Segoe UI", Arial, sans-serif;
|
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;
|
min-height: 100vh;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "master.h"
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
#include <HTTPClient.h>
|
#include <HTTPClient.h>
|
||||||
#include <preferencemanager.h>
|
#include <preferencemanager.h>
|
||||||
|
|
||||||
@@ -78,7 +79,7 @@ UserData checkUser(const String &uid) {
|
|||||||
userData.firstname = responseDoc["firstname"].as<String>();
|
userData.firstname = responseDoc["firstname"].as<String>();
|
||||||
userData.lastname = responseDoc["lastname"].as<String>();
|
userData.lastname = responseDoc["lastname"].as<String>();
|
||||||
userData.alter = responseDoc["alter"] | 0;
|
userData.alter = responseDoc["alter"] | 0;
|
||||||
userData.exists = responseDoc["exists"] | true;
|
userData.exists = responseDoc["exists"] | false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Serial.printf("User check failed, HTTP code: %d\n", httpCode);
|
Serial.printf("User check failed, HTTP code: %d\n", httpCode);
|
||||||
@@ -88,43 +89,6 @@ UserData checkUser(const String &uid) {
|
|||||||
return userData;
|
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.
|
// Holt alle Standorte aus der Datenbank und gibt sie als JSON-Dokument zurück.
|
||||||
JsonDocument getAllLocations() {
|
JsonDocument getAllLocations() {
|
||||||
JsonDocument locations; // Allocate memory for the JSON document
|
JsonDocument locations; // Allocate memory for the JSON document
|
||||||
@@ -159,6 +123,45 @@ JsonDocument getAllLocations() {
|
|||||||
// (Kompatibilitätsfunktion).
|
// (Kompatibilitätsfunktion).
|
||||||
bool userExists(const String &uid) { return checkUser(uid).exists; }
|
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
|
// Richtet die HTTP-Routen für die Backend-API ein (z.B. Health-Check, User- und
|
||||||
// Location-Abfragen).
|
// Location-Abfragen).
|
||||||
void setupBackendRoutes(AsyncWebServer &server) {
|
void setupBackendRoutes(AsyncWebServer &server) {
|
||||||
|
|||||||
10
src/master.h
10
src/master.h
@@ -21,7 +21,7 @@ struct TimerData1 {
|
|||||||
bool isRunning = false;
|
bool isRunning = false;
|
||||||
bool isReady = true; // Status für Bahn 1
|
bool isReady = true; // Status für Bahn 1
|
||||||
bool isArmed = false; // Status für Bahn 1 (armiert/nicht armiert)
|
bool isArmed = false; // Status für Bahn 1 (armiert/nicht armiert)
|
||||||
char RFIDUID = "";
|
char RFIDUID[32] = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
// Timer Struktur für Bahn 2
|
// Timer Struktur für Bahn 2
|
||||||
@@ -34,7 +34,7 @@ struct TimerData2 {
|
|||||||
bool isRunning = false;
|
bool isRunning = false;
|
||||||
bool isReady = true; // Status für Bahn 2
|
bool isReady = true; // Status für Bahn 2
|
||||||
bool isArmed = false; // Status für Bahn 2 (armiert/nicht armiert)
|
bool isArmed = false; // Status für Bahn 2 (armiert/nicht armiert)
|
||||||
char RFIDUID = "";
|
char RFIDUID[32] = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
// Button Konfiguration
|
// Button Konfiguration
|
||||||
@@ -69,9 +69,9 @@ int gamemode; // 0=Individual, 1=Wettkampf
|
|||||||
bool startCompetition = false; // Flag, ob der Timer gestartet wurde
|
bool startCompetition = false; // Flag, ob der Timer gestartet wurde
|
||||||
|
|
||||||
// Lane Configuration
|
// Lane Configuration
|
||||||
int laneConfigType = 0; // 0=Identical, 1=Different
|
int laneConfigType = 0; // 0=Identical, 1=Different
|
||||||
int lane1DifficultyType = 0; // 0=Light, 1=Heavy (difficulty)
|
int lane1DifficultyType = 0; // 0=Light, 1=Heavy (difficulty)
|
||||||
int lane2DifficultyType = 0; // 0=Light, 1=Heavy (difficulty)
|
int lane2DifficultyType = 0; // 0=Light, 1=Heavy (difficulty)
|
||||||
|
|
||||||
// Function Declarations
|
// Function Declarations
|
||||||
void OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len);
|
void OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len);
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <Preferences.h>
|
#include <Preferences.h>
|
||||||
|
|
||||||
#include <master.h>
|
|
||||||
#include <licenceing.h>
|
#include <licenceing.h>
|
||||||
|
#include <master.h>
|
||||||
|
|
||||||
// Persist and load button configuration
|
// Persist and load button configuration
|
||||||
void saveButtonConfig() {
|
void saveButtonConfig() {
|
||||||
@@ -43,8 +43,8 @@ void saveSettings() {
|
|||||||
preferences.putULong("maxTimeDisplay", maxTimeDisplay);
|
preferences.putULong("maxTimeDisplay", maxTimeDisplay);
|
||||||
preferences.putUInt("gamemode", gamemode);
|
preferences.putUInt("gamemode", gamemode);
|
||||||
preferences.putUInt("laneConfigType", laneConfigType);
|
preferences.putUInt("laneConfigType", laneConfigType);
|
||||||
preferences.putUInt("lane1DifficultyType", lane1DifficultyType);
|
preferences.putUInt("lane1Diff", lane1DifficultyType);
|
||||||
preferences.putUInt("lane2DifficultyType", lane2DifficultyType);
|
preferences.putUInt("lane2Diff", lane2DifficultyType);
|
||||||
preferences.end();
|
preferences.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,8 +54,8 @@ void loadSettings() {
|
|||||||
maxTimeDisplay = preferences.getULong("maxTimeDisplay", 20000);
|
maxTimeDisplay = preferences.getULong("maxTimeDisplay", 20000);
|
||||||
gamemode = preferences.getUInt("gamemode", 0);
|
gamemode = preferences.getUInt("gamemode", 0);
|
||||||
laneConfigType = preferences.getUInt("laneConfigType", 0);
|
laneConfigType = preferences.getUInt("laneConfigType", 0);
|
||||||
lane1DifficultyType = preferences.getUInt("lane1DifficultyType", 0);
|
lane1DifficultyType = preferences.getUInt("lane1Diff", 0);
|
||||||
lane2DifficultyType = preferences.getUInt("lane2DifficultyType", 0);
|
lane2DifficultyType = preferences.getUInt("lane2Diff", 0);
|
||||||
preferences.end();
|
preferences.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "databasebackend.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <MFRC522.h>
|
#include <MFRC522.h>
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
|
|
||||||
|
|
||||||
// RFID Konfiguration
|
// RFID Konfiguration
|
||||||
#define RST_PIN 21 // Configurable, see typical pin layout above
|
#define RST_PIN 21 // Configurable, see typical pin layout above
|
||||||
#define SS_PIN 5 // Configurable, see typical pin layout above
|
#define SS_PIN 5 // Configurable, see typical pin layout above
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ void setupRoutes() {
|
|||||||
request->send(SPIFFS, "/settings.html", "text/html");
|
request->send(SPIFFS, "/settings.html", "text/html");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
server.on("/firmware.bin", HTTP_GET, [](AsyncWebServerRequest *request) {
|
server.on("/firmware.bin", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
if (SPIFFS.exists("/firmware.bin")) {
|
if (SPIFFS.exists("/firmware.bin")) {
|
||||||
request->send(SPIFFS, "/firmware.bin", "application/octet-stream");
|
request->send(SPIFFS, "/firmware.bin", "application/octet-stream");
|
||||||
@@ -313,51 +312,69 @@ void setupRoutes() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Lane Configuration API Routes
|
// Lane Configuration API Routes
|
||||||
server.on("/api/set-lane-config", HTTP_POST, [](AsyncWebServerRequest *request) {
|
server.on(
|
||||||
Serial.println("/api/set-lane-config called");
|
"/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");
|
||||||
|
|
||||||
String body = request->getBody();
|
DynamicJsonDocument doc(256);
|
||||||
DynamicJsonDocument doc(256);
|
DeserializationError error = deserializeJson(doc, data, len);
|
||||||
deserializeJson(doc, body);
|
|
||||||
|
|
||||||
if (doc.containsKey("type")) {
|
if (error) {
|
||||||
String laneType = doc["type"];
|
Serial.println("JSON parsing error");
|
||||||
laneConfigType = (laneType == "identical") ? 0 : 1;
|
request->send(400, "application/json",
|
||||||
|
"{\"success\":false,\"error\":\"Invalid JSON\"}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (laneConfigType == 1 && doc.containsKey("lane1Difficulty") && doc.containsKey("lane2Difficulty")) {
|
if (doc.containsKey("type")) {
|
||||||
String lane1Difficulty = doc["lane1Difficulty"];
|
String laneType = doc["type"];
|
||||||
String lane2Difficulty = doc["lane2Difficulty"];
|
laneConfigType = (laneType == "identical") ? 0 : 1;
|
||||||
lane1DifficultyType = (lane1Difficulty == "light") ? 0 : 1;
|
|
||||||
lane2DifficultyType = (lane2Difficulty == "light") ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Serial.printf("Lane configuration set - Type: %s, Lane1: %s, Lane2: %s\n",
|
if (laneConfigType == 1 && doc.containsKey("lane1Difficulty") &&
|
||||||
laneType.c_str(),
|
doc.containsKey("lane2Difficulty")) {
|
||||||
(laneConfigType == 1) ? ((lane1DifficultyType == 0) ? "light" : "heavy") : "identical",
|
String lane1Difficulty = doc["lane1Difficulty"];
|
||||||
(laneConfigType == 1) ? ((lane2DifficultyType == 0) ? "light" : "heavy") : "identical");
|
String lane2Difficulty = doc["lane2Difficulty"];
|
||||||
|
lane1DifficultyType = (lane1Difficulty == "light") ? 0 : 1;
|
||||||
|
lane2DifficultyType = (lane2Difficulty == "light") ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
DynamicJsonDocument response(64);
|
Serial.printf(
|
||||||
response["success"] = true;
|
"Lane configuration set - Type: %s, Lane1: %s, Lane2: %s\n",
|
||||||
String result;
|
laneType.c_str(),
|
||||||
serializeJson(response, result);
|
(laneConfigType == 1)
|
||||||
request->send(200, "application/json", result);
|
? ((lane1DifficultyType == 0) ? "light" : "heavy")
|
||||||
saveSettings();
|
: "identical",
|
||||||
} else {
|
(laneConfigType == 1)
|
||||||
request->send(400, "application/json", "{\"success\":false,\"error\":\"Lane type missing\"}");
|
? ((lane2DifficultyType == 0) ? "light" : "heavy")
|
||||||
}
|
: "identical");
|
||||||
});
|
|
||||||
|
|
||||||
server.on("/api/get-lane-config", HTTP_GET, [](AsyncWebServerRequest *request) {
|
DynamicJsonDocument response(64);
|
||||||
DynamicJsonDocument doc(128);
|
response["success"] = true;
|
||||||
doc["type"] = laneConfigType == 0 ? "identical" : "different";
|
String result;
|
||||||
if (laneConfigType == 1) {
|
serializeJson(response, result);
|
||||||
doc["lane1Difficulty"] = lane1DifficultyType == 0 ? "light" : "heavy";
|
request->send(200, "application/json", result);
|
||||||
doc["lane2Difficulty"] = lane2DifficultyType == 0 ? "light" : "heavy";
|
saveSettings();
|
||||||
}
|
} else {
|
||||||
String result;
|
request->send(400, "application/json",
|
||||||
serializeJson(doc, result);
|
"{\"success\":false,\"error\":\"Lane type missing\"}");
|
||||||
request->send(200, "application/json", result);
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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
|
// Statische Dateien
|
||||||
server.serveStatic("/", SPIFFS, "/");
|
server.serveStatic("/", SPIFFS, "/");
|
||||||
|
|||||||
Reference in New Issue
Block a user