diff --git a/data/rfid.html b/data/rfid.html
index 9709e92..5721f70 100644
--- a/data/rfid.html
+++ b/data/rfid.html
@@ -88,7 +88,7 @@
try {
// API Aufruf zum Erstellen des Benutzers
- const response = await fetch(`/api/users`, {
+ const response = await fetch(`/api/users/insert`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -109,10 +109,7 @@
// Formular zurücksetzen
clearForm();
-
- // Daten neu laden
- await loadUserData();
-
+
// UID Feld fokussieren für nächsten Eintrag
setTimeout(() => {
document.getElementById('uid').focus();
@@ -214,7 +211,7 @@
async function readRFIDUID() {
const readBtn = document.getElementById('readUidBtn');
const uidInput = document.getElementById('uid');
-
+
// Button Status ändern
readBtn.disabled = true;
readBtn.className = 'read-uid-btn reading';
@@ -223,7 +220,7 @@
try {
// API Aufruf zum RFID Reader
const response = await fetch(`/api/rfid/read`, {
- method: 'POST',
+ method: 'GET',
headers: {
'Content-Type': 'application/json',
}
@@ -233,17 +230,17 @@
if (result.success && result.uid) {
// UID in das Eingabefeld setzen
- uidInput.value = result.uid.toUpperCase();
+ uidInput.value = result.uid.match(/.{1,2}/g).join(':').toUpperCase();
uidInput.focus();
-
+
// Visuelles Feedback
uidInput.style.borderColor = '#28a745';
setTimeout(() => {
uidInput.style.borderColor = '#e1e5e9';
}, 2000);
-
+
showSuccessMessage('UID erfolgreich gelesen!');
-
+
// Automatisch zum nächsten Feld springen
setTimeout(() => {
document.getElementById('vorname').focus();
@@ -253,7 +250,7 @@
// Fehler beim Lesen
const errorMsg = result.error || 'Keine UID gefunden';
showErrorMessage(`RFID Fehler: ${errorMsg}`);
-
+
// UID Feld rot markieren
uidInput.style.borderColor = '#dc3545';
setTimeout(() => {
@@ -264,13 +261,13 @@
} catch (error) {
console.error('Fehler beim Lesen der UID:', error);
showErrorMessage('Verbindungsfehler zum RFID Reader. Bitte prüfen Sie die Verbindung.');
-
+
// UID Feld rot markieren
uidInput.style.borderColor = '#dc3545';
setTimeout(() => {
uidInput.style.borderColor = '#e1e5e9';
}, 3000);
-
+
} finally {
// Button Status zurücksetzen
readBtn.disabled = false;
diff --git a/platformio.ini b/platformio.ini
index 8b70908..5262536 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -14,7 +14,6 @@ default_envs = esp32dev
[env]
platform = https://github.com/platformio/platform-espressif32.git
framework = arduino
-lib_deps = esp32async/ESPAsyncWebServer@^3.7.7
lib_compat_mode = strict
[env:wemos_d1_mini32]
diff --git a/src/databasebackend.h b/src/databasebackend.h
index 22f1b87..704ab08 100644
--- a/src/databasebackend.h
+++ b/src/databasebackend.h
@@ -81,6 +81,43 @@ UserData checkUser(const String& uid) {
return userData;
}
+//Function to enter user data into the database
+bool enterUserData(const String& uid, const String& firstname, const String& lastname, int alter) {
+ if (!backendOnline()) {
+ Serial.println("No internet connection, cannot enter user data.");
+ return false;
+ }
+
+ HTTPClient http;
+ http.begin(String(BACKEND_SERVER) + "/api/users/insert");
+ http.addHeader("Content-Type", "application/json");
+ http.addHeader("Authorization", String("Bearer ") + BACKEND_TOKEN);
+
+ // Create JSON payload
+ StaticJsonDocument<256> requestDoc;
+ requestDoc["uid"] = uid;
+ requestDoc["vorname"] = firstname;
+ requestDoc["nachname"] = lastname;
+ requestDoc["alter"] = alter;
+
+ 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;
+ }
+}
+
+
+
// Keep this for backward compatibility
bool userExists(const String& uid) {
return checkUser(uid).exists;
diff --git a/src/master.cpp b/src/master.cpp
index cf96831..a97188a 100644
--- a/src/master.cpp
+++ b/src/master.cpp
@@ -19,7 +19,7 @@
#include
#include
#include
-
+#include
const char* firmwareversion = "1.0.0"; // Version der Firmware
@@ -249,8 +249,9 @@ void setup() {
setupTimeAPI(server);
setupLicenceAPI(server);
setupDebugAPI(server);
- setupBackendRoutes(server);// Speichere WLAN-Einstellungen, falls noch nicht vorhanden
-
+ setupBackendRoutes(server);
+ setupRFIDRoute(server);
+
// Gespeicherte Daten laden
loadButtonConfig();
@@ -264,6 +265,7 @@ void setup() {
setupWebSocket();
setupLED();
setupMqttServer(); // MQTT Server initialisieren
+ setupRFID();
}
@@ -272,4 +274,5 @@ void loop() {
checkAutoReset();
loopMqttServer(); // MQTT Server in der Loop aufrufen
loopWebSocket();
+ loopRFID(); // RFID Loop aufrufen
}
diff --git a/src/rfid.h b/src/rfid.h
index a840930..89c5837 100644
--- a/src/rfid.h
+++ b/src/rfid.h
@@ -1,141 +1,289 @@
#pragma once
#include
-#include
#include
#include
#include
// RFID Konfiguration
-#define SS_PIN 21
-#define RST_PIN 22
-MFRC522 mfrc522(SS_PIN, RST_PIN);
+#define RST_PIN 21 // Configurable, see typical pin layout above
+#define SS_PIN 5 // Configurable, see typical pin layout above
-// Webserver auf Port 80
-WebServer server(80);
-// Struktur für Benutzerdaten
-struct User {
- String uid;
- String vorname;
- String nachname;
- int alter;
- unsigned long timestamp;
-};
+MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
+std::map blockedUIDs; // Map to store blocked UIDs and their timestamps
+const unsigned long BLOCK_DURATION = 10 * 1000; // 10 Seconds in milliseconds
+
+// Neue Variablen für API-basiertes Lesen
+bool rfidReadRequested = false;
+String lastReadUID = "";
+bool rfidReadSuccess = false;
+unsigned long rfidReadStartTime = 0;
+const unsigned long RFID_READ_TIMEOUT = 10000; // 10 Sekunden Timeout für API Requests
+
void setupRFID() {
// SPI und RFID initialisieren
- SPI.begin();
- mfrc522.PCD_Init();
-
+ SPI.begin(); // Init SPI bus
+ mfrc522.PCD_Init(); // Init MFRC522
+ delay(4); // Optional delay. Some boards need more time after init to be ready
+ mfrc522.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader details
}
-void setupRoutes() {
- // CORS Header für alle Anfragen
- server.onNotFound([]() {
- if (server.method() == HTTP_OPTIONS) {
- server.sendHeader("Access-Control-Allow-Origin", "*");
- server.sendHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
- server.sendHeader("Access-Control-Allow-Headers", "Content-Type");
- server.send(200);
- } else {
- server.send(404, "text/plain", "Not Found");
- }
- });
-
- // API: RFID UID lesen
- server.on("/api/rfid/read", HTTP_POST, []() {
- server.sendHeader("Access-Control-Allow-Origin", "*");
- server.sendHeader("Content-Type", "application/json");
-
- String uid = readRFIDCard();
-
- DynamicJsonDocument doc(200);
-
- if (uid != "") {
- doc["success"] = true;
- doc["uid"] = uid;
- Serial.println("UID gelesen: " + uid);
- } else {
- doc["success"] = false;
- doc["error"] = "Keine RFID Karte gefunden";
- }
-
- String response;
- serializeJson(doc, response);
- server.send(200, "application/json", response);
- });
-
- // API: Neuen Benutzer erstellen
- server.on("/api/users", HTTP_POST, []() {
- server.sendHeader("Access-Control-Allow-Origin", "*");
- server.sendHeader("Content-Type", "application/json");
-
- DynamicJsonDocument doc(1024);
- DeserializationError error = deserializeJson(doc, server.arg("plain"));
-
- if (error) {
- DynamicJsonDocument errorDoc(200);
- errorDoc["success"] = false;
- errorDoc["error"] = "Ungültige JSON Daten";
- String response;
- serializeJson(errorDoc, response);
- server.send(400, "application/json", response);
- return;
- }
-
- // Daten aus JSON extrahieren
- String uid = doc["uid"].as();
- String vorname = doc["vorname"].as();
- String nachname = doc["nachname"].as();
- int alter = doc["alter"].as();
-
-
- // Prüfen ob UID bereits existiert
-
-
-
- // Benutzer hinzufügen
- // Erfolgreiche Antwort
- DynamicJsonDocument successDoc(200);
- successDoc["success"] = true;
- successDoc["message"] = "Benutzer erfolgreich gespeichert";
- String response;
- serializeJson(successDoc, response);
- server.send(201, "application/json", response);
-
- Serial.println("Neuer Benutzer: " + vorname + " " + nachname + " (UID: " + uid + ")");
- });
-}
-
-// RFID Karte lesen
-String readRFIDCard() {
- // Prüfen ob neue Karte vorhanden
+void handleAutomaticRFID() {
if (!mfrc522.PICC_IsNewCardPresent()) {
- return "";
+ return;
+ }
+
+ // Select one of the cards
+ if (!mfrc522.PICC_ReadCardSerial()) {
+ return;
+ }
+
+ // Read the UID
+ String uid = "";
+ for (byte i = 0; i < mfrc522.uid.size; i++) {
+ if (i > 0)
+ uid += ":";
+ if (mfrc522.uid.uidByte[i] < 0x10)
+ uid += "0";
+ uid += String(mfrc522.uid.uidByte[i], HEX);
+ }
+
+ // Check if the UID is blocked
+ unsigned long currentTime = millis();
+ if (blockedUIDs.find(uid) != blockedUIDs.end()) {
+ if (currentTime - blockedUIDs[uid] < BLOCK_DURATION) {
+ Serial.print(F("UID blocked for 10 seconds. Remaining time: "));
+ Serial.print((BLOCK_DURATION - (currentTime - blockedUIDs[uid])) / 1000);
+ Serial.println(F(" seconds."));
+ Serial.println(uid);
+ return;
+ } else {
+ // Remove the UID from the blocked list if the block duration has passed
+ blockedUIDs.erase(uid);
+ }
+ }
+
+ // Process the UID
+ Serial.print(F("UID: "));
+ Serial.println(uid);
+
+ // Block the UID for 10 seconds
+ blockedUIDs[uid] = currentTime;
+ //show the remaining time for the block
+ Serial.print(F("UID blocked for 10 seconds. Remaining time: "));
+ Serial.print((BLOCK_DURATION - (currentTime - blockedUIDs[uid])) / 1000);
+ Serial.println(F(" seconds."));
+
+ // Halt the card
+ mfrc522.PICC_HaltA();
+}
+
+// Neue Funktion für API-basiertes RFID Lesen
+void handleAPIRFIDRead() {
+ unsigned long currentTime = millis();
+
+ // Timeout prüfen
+ if (currentTime - rfidReadStartTime > RFID_READ_TIMEOUT) {
+ Serial.println("RFID API Timeout - keine Karte erkannt");
+ rfidReadRequested = false;
+ rfidReadSuccess = false;
+ lastReadUID = "";
+ return;
+ }
+
+ // Prüfen ob neue Karte vorhanden ist
+ if (!mfrc522.PICC_IsNewCardPresent()) {
+ return;
}
// Karte auswählen
if (!mfrc522.PICC_ReadCardSerial()) {
- return "";
+ return;
}
- // UID zusammensetzen
+ // UID für API lesen (ohne Doppelpunkt-Trenner, Großbuchstaben)
String uid = "";
for (byte i = 0; i < mfrc522.uid.size; i++) {
- if (i > 0) uid += ":";
- if (mfrc522.uid.uidByte[i] < 0x10) uid += "0";
+ if (mfrc522.uid.uidByte[i] < 0x10) {
+ uid += "0"; // Leading Zero für einstellige Hex-Werte
+ }
uid += String(mfrc522.uid.uidByte[i], HEX);
}
+
+ // UID in Großbuchstaben konvertieren
uid.toUpperCase();
- // Karte deaktivieren
- mfrc522.PICC_HaltA();
+ Serial.println("RFID API UID gelesen: " + uid);
- return uid;
+ // Ergebnis speichern
+ lastReadUID = uid;
+ rfidReadSuccess = true;
+ rfidReadRequested = false;
+
+ // Karte "halt" setzen
+ mfrc522.PICC_HaltA();
+ mfrc522.PCD_StopCrypto1();
}
+
+// API Funktion: RFID Lesevorgang starten
+void startRFIDRead() {
+ Serial.println("RFID API Lesevorgang gestartet...");
+ rfidReadRequested = true;
+ rfidReadSuccess = false;
+ lastReadUID = "";
+ rfidReadStartTime = millis();
+}
+
+// API Funktion: Prüfen ob Lesevorgang abgeschlossen
+bool isRFIDReadComplete() {
+ return !rfidReadRequested;
+}
+
+// API Funktion: Ergebnis des Lesevorgangs abrufen
+String getRFIDReadResult(bool& success) {
+ success = rfidReadSuccess;
+ return lastReadUID;
+}
+
+void setupRFIDRoute(AsyncWebServer& server) {
+ server.on("/api/rfid/read", HTTP_GET, [](AsyncWebServerRequest *request) {
+ Serial.println("api/rfid/read");
+
+ // Start RFID-Lesevorgang
+ startRFIDRead();
+ unsigned long startTime = millis();
+
+ // Warten, bis eine UID gelesen wird oder Timeout eintritt
+ while (!isRFIDReadComplete()) {
+ if (millis() - startTime > RFID_READ_TIMEOUT) {
+ break;
+ }
+ delay(10); // Kurze Pause, um die CPU nicht zu blockieren
+ }
+
+ DynamicJsonDocument response(200);
+
+ if (rfidReadSuccess && lastReadUID.length() > 0) {
+ response["success"] = true;
+ response["uid"] = lastReadUID;
+ response["message"] = "UID erfolgreich gelesen";
+ } else {
+ response["success"] = false;
+ response["error"] = "Keine RFID Karte erkannt oder Timeout";
+ response["uid"] = "";
+ }
+
+ String jsonString;
+ serializeJson(response, jsonString);
+ request->send(200, "application/json", jsonString);
+ });
+
+server.on("/api/users/insert", HTTP_POST, [](AsyncWebServerRequest *request) {}, NULL, [](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) {
+ Serial.println("/api/users/insert");
+
+ // Parse the incoming JSON payload
+ DynamicJsonDocument doc(512);
+ DeserializationError error = deserializeJson(doc, data, len);
+
+ DynamicJsonDocument response(200);
+
+ if (error) {
+ Serial.println("Fehler beim Parsen der JSON-Daten");
+ response["success"] = false;
+ response["error"] = "Ungültige JSON-Daten";
+ } else {
+ // Extract user data from the JSON payload
+ String uid = doc["uid"] | "";
+ String vorname = doc["vorname"] | "";
+ String nachname = doc["nachname"] | "";
+ int alter = doc["alter"] | 0;
+
+ // Validate the data
+ if (uid.isEmpty() || vorname.isEmpty() || nachname.isEmpty() || alter <= 0) {
+ Serial.println("Ungültige Eingabedaten");
+ response["success"] = false;
+ response["error"] = "Ungültige Eingabedaten";
+ } else {
+ // Process the data using the enterUserData function
+ Serial.println("Benutzerdaten empfangen:");
+ Serial.println("UID: " + uid);
+ Serial.println("Vorname: " + vorname);
+ Serial.println("Nachname: " + nachname);
+ Serial.println("Alter: " + String(alter));
+
+ bool dbSuccess = enterUserData(uid, vorname, nachname, alter);
+
+ if (dbSuccess) {
+ response["success"] = true;
+ response["message"] = "Benutzer erfolgreich gespeichert";
+ } else {
+ response["success"] = false;
+ response["error"] = "Fehler beim Speichern in der Datenbank";
+ }
+ }
+ }
+
+ // Send the response back to the client
+ String jsonString;
+ serializeJson(response, jsonString);
+ request->send(200, "application/json", jsonString);
+});
+
+
+
+
+
+
+
+}
+
+
+
+// API Funktion: RFID Reader Status prüfen
+bool checkRFIDReaderStatus() {
+ byte version = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
+
+ // Bekannte MFRC522 Versionen: 0x91, 0x92
+ if (version == 0x91 || version == 0x92) {
+ Serial.println("RFID Reader OK (Version: 0x" + String(version, HEX) + ")");
+ return true;
+ } else {
+ Serial.println("RFID Reader Fehler (Version: 0x" + String(version, HEX) + ")");
+ return false;
+ }
+}
+
+// Hilfsfunktion: Blockierte UIDs aufräumen
+void cleanupBlockedUIDs() {
+ unsigned long currentTime = millis();
+
+ // Iterator für sicheres Löschen während der Iteration
+ for (auto it = blockedUIDs.begin(); it != blockedUIDs.end();) {
+ if (currentTime - it->second >= BLOCK_DURATION) {
+ it = blockedUIDs.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
+void loopRFID(){
+ // Originale Funktionalität für automatisches Lesen
+ if (!rfidReadRequested) {
+ handleAutomaticRFID();
+ }
+
+ // API-basiertes Lesen verarbeiten
+ if (rfidReadRequested) {
+ handleAPIRFIDRead();
+ }
+}
+
+