#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 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 // Initialisiert den RFID-Reader und das SPI-Interface. void setupRFID() { // SPI und RFID initialisieren 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 } // Liest automatisch eine RFID-Karte ein und blockiert die UID für eine // bestimmte Zeit. void handleAutomaticRFID() { if (!mfrc522.PICC_IsNewCardPresent()) { 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 // Liest eine RFID-Karte im API-Modus ein (für Web-Requests). 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; } // UID für API lesen (ohne Doppelpunkt-Trenner, Großbuchstaben) String uid = ""; for (byte i = 0; i < mfrc522.uid.size; i++) { 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(); Serial.println("RFID API UID gelesen: " + uid); // Ergebnis speichern lastReadUID = uid; rfidReadSuccess = true; rfidReadRequested = false; // Karte "halt" setzen mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); } // API Funktion: RFID Lesevorgang starten // Startet einen neuen RFID-Lesevorgang über die API. void startRFIDRead() { Serial.println("RFID API Lesevorgang gestartet..."); rfidReadRequested = true; rfidReadSuccess = false; lastReadUID = ""; rfidReadStartTime = millis(); } // API Funktion: Prüfen ob Lesevorgang abgeschlossen // Prüft, ob der aktuelle RFID-Lesevorgang abgeschlossen ist. bool isRFIDReadComplete() { return !rfidReadRequested; } // API Funktion: Ergebnis des Lesevorgangs abrufen // Gibt das Ergebnis des letzten RFID-Lesevorgangs zurück. String getRFIDReadResult(bool &success) { success = rfidReadSuccess; return lastReadUID; } // Richtet die HTTP-API-Routen für RFID-Operationen ein. 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"] | ""; String geburtsdatum = doc["geburtsdatum"] | ""; int alter = doc["alter"] | 0; // Validate the data if (uid.isEmpty() || vorname.isEmpty() || nachname.isEmpty() || geburtsdatum.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, geburtsdatum, 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 // Prüft, ob der RFID-Reader korrekt funktioniert und gibt den Status zurück. 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 // Entfernt UIDs aus der Blockliste, deren Blockdauer abgelaufen ist. 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; } } } // Hauptschleife für das RFID-Handling (automatisch und API-basiert). void loopRFID() { // Originale Funktionalität für automatisches Lesen if (!rfidReadRequested) { handleAutomaticRFID(); } // API-basiertes Lesen verarbeiten if (rfidReadRequested) { handleAPIRFIDRead(); } }