RFID Implementierung

This commit is contained in:
Carsten Graf
2025-09-20 01:04:00 +02:00
parent 1ed3a30340
commit 7e9705902e
10 changed files with 715 additions and 554 deletions

View File

@@ -62,7 +62,7 @@
type="button"
id="readUidBtn"
class="read-uid-btn"
onclick="readRFIDUID()"
onclick="toggleRFIDReading()"
>
📡 Read Chip
</button>
@@ -70,47 +70,16 @@
</div>
<div class="form-group">
<label for="vorname">Vorname <span class="required">*</span></label>
<label for="name">Name <span class="required">*</span></label>
<input
type="text"
id="vorname"
name="vorname"
placeholder="Vorname eingeben"
id="name"
name="name"
placeholder="Name eingeben"
required
/>
</div>
<div class="form-group">
<label for="nachname">Nachname <span class="required">*</span></label>
<input
type="text"
id="nachname"
name="nachname"
placeholder="Nachname eingeben"
required
/>
</div>
<div class="form-group">
<label for="geburtsdatum"
>Geburtsdatum <span class="required">*</span></label
>
<div class="date-input-group">
<input
type="date"
id="geburtsdatum"
name="geburtsdatum"
required
max=""
/>
<div
id="ageDisplay"
class="age-display"
style="display: none"
></div>
</div>
</div>
<div class="btn-container">
<button type="submit" class="btn btn-primary">💾 Speichern</button>
<button type="button" class="btn btn-secondary" onclick="clearForm()">
@@ -124,60 +93,8 @@
// Globale Variablen
let rfidData = [];
let isLoading = false;
let DBUrl = "ninja.reptilfpv.de:3000";
var APIKey;
// Maximales Datum auf heute setzen
document.addEventListener("DOMContentLoaded", function () {
const today = new Date().toISOString().split("T")[0];
document.getElementById("geburtsdatum").setAttribute("max", today);
});
// Alter berechnen und anzeigen
function calculateAge(birthDate) {
const today = new Date();
const birth = new Date(birthDate);
let age = today.getFullYear() - birth.getFullYear();
const monthDiff = today.getMonth() - birth.getMonth();
if (
monthDiff < 0 ||
(monthDiff === 0 && today.getDate() < birth.getDate())
) {
age--;
}
return age;
}
// Geburtsdatum Change Event
document
.getElementById("geburtsdatum")
.addEventListener("change", function (e) {
const birthDate = e.target.value;
const ageDisplay = document.getElementById("ageDisplay");
if (birthDate) {
const age = calculateAge(birthDate);
if (age >= 0 && age <= 150) {
ageDisplay.textContent = `${age} Jahre`;
ageDisplay.style.display = "block";
} else {
ageDisplay.style.display = "none";
if (age < 0) {
showErrorMessage(
"Das Geburtsdatum kann nicht in der Zukunft liegen!"
);
e.target.value = "";
} else {
showErrorMessage("Bitte überprüfen Sie das Geburtsdatum!");
e.target.value = "";
}
}
} else {
ageDisplay.style.display = "none";
}
});
// Lokale Benutzer-Speicherung (geht bei Neustart verloren)
let localUsers = [];
// Form Submit Handler
document
@@ -189,46 +106,40 @@
// Daten aus dem Formular holen
const uid = document.getElementById("uid").value.trim();
const vorname = document.getElementById("vorname").value.trim();
const nachname = document.getElementById("nachname").value.trim();
const geburtsdatum = document.getElementById("geburtsdatum").value;
const name = document.getElementById("name").value.trim();
// Validierung
if (!uid || !vorname || !nachname || !geburtsdatum) {
if (!uid || !name) {
showErrorMessage("Bitte füllen Sie alle Pflichtfelder aus!");
return;
}
// Alter berechnen
const alter = calculateAge(geburtsdatum);
if (alter < 0) {
showErrorMessage(
"Das Geburtsdatum kann nicht in der Zukunft liegen!"
);
return;
}
// Loading State
setLoadingState(true);
try {
// API Aufruf zum Erstellen des Benutzers
// API Aufruf zum Erstellen des Benutzers (lokal)
const requestData = {
uid: uid,
name: name,
};
console.log("Sende Daten:", requestData);
console.log("JSON String:", JSON.stringify(requestData));
const response = await fetch(`/api/users/insert`, {
method: "POST",
headers: {
"Content-Type": "application/json",
...(APIKey && { Authorization: `Bearer ${APIKey}` }),
},
body: JSON.stringify({
uid: uid,
vorname: vorname,
nachname: nachname,
geburtsdatum: geburtsdatum,
alter: alter, // Berechnetes Alter wird mit gesendet
}),
body: JSON.stringify(requestData),
});
console.log("Response Status:", response.status);
console.log("Response Headers:", response.headers);
const result = await response.json();
console.log("Response Result:", result);
if (result.success) {
// Erfolg anzeigen
@@ -313,7 +224,6 @@
function clearForm() {
document.getElementById("rfidForm").reset();
document.getElementById("ageDisplay").style.display = "none";
document.getElementById("uid").focus();
}
@@ -321,14 +231,13 @@
window.addEventListener("load", function () {
document.getElementById("uid").focus();
checkServerStatus();
loadLicence();
});
// Enter-Taste in UID Feld zum nächsten Feld springen
document.getElementById("uid").addEventListener("keydown", function (e) {
if (e.key === "Enter") {
e.preventDefault();
document.getElementById("vorname").focus();
document.getElementById("name").focus();
}
});
@@ -340,34 +249,170 @@
e.target.value = value;
});
// RFID UID lesen
let rfidReadingMode = false;
let statusInterval = null;
// Toggle RFID Reading Mode
async function toggleRFIDReading() {
const readBtn = document.getElementById("readUidBtn");
try {
const response = await fetch(`/api/rfid/toggle`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
const result = await response.json();
if (result.success) {
rfidReadingMode = result.reading_mode;
if (rfidReadingMode) {
// RFID Reading gestartet
readBtn.innerHTML = "🛑 Stop Reading";
readBtn.className = "read-uid-btn reading";
showSuccessMessage("RFID Lesen gestartet - Karte auflegen!");
// Status Polling starten
startStatusPolling();
} else {
// RFID Reading gestoppt
readBtn.innerHTML = "📡 Read Chip";
readBtn.className = "read-uid-btn";
showSuccessMessage("RFID Lesen gestoppt");
// Status Polling stoppen
stopStatusPolling();
}
} else {
showErrorMessage("Fehler beim Toggle RFID: " + result.message);
}
} catch (error) {
console.error("Toggle RFID Error:", error);
showErrorMessage("Fehler beim Toggle RFID");
}
}
// Status Polling für kontinuierliches Lesen
function startStatusPolling() {
if (statusInterval) {
clearInterval(statusInterval);
}
statusInterval = setInterval(async () => {
try {
const response = await fetch(`/api/rfid/status`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const result = await response.json();
if (result.success && result.last_uid && result.last_uid !== "") {
// Neue UID gelesen - automatisch stoppen
const uidInput = document.getElementById("uid");
uidInput.value = result.last_uid;
// Visuelles Feedback
uidInput.style.borderColor = "#28a745";
setTimeout(() => {
uidInput.style.borderColor = "#e1e5e9";
}, 2000);
showSuccessMessage("UID gelesen: " + result.last_uid);
// Automatisch zum nächsten Feld springen
setTimeout(() => {
document.getElementById("name").focus();
}, 500);
// RFID Lesen automatisch stoppen
stopRFIDReading();
// UID im Backend zurücksetzen
clearBackendUID();
}
} catch (error) {
console.error("Status Poll Error:", error);
}
}, 500); // Alle 500ms prüfen
}
// Status Polling stoppen
function stopStatusPolling() {
if (statusInterval) {
clearInterval(statusInterval);
statusInterval = null;
}
}
// RFID Reading komplett stoppen (Frontend + Backend)
async function stopRFIDReading() {
// Status Polling stoppen
stopStatusPolling();
// Backend stoppen
try {
const response = await fetch(`/api/rfid/toggle`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
const result = await response.json();
if (result.success && !result.reading_mode) {
rfidReadingMode = false;
// Button zurücksetzen
const readBtn = document.getElementById("readUidBtn");
readBtn.innerHTML = "📡 Read Chip";
readBtn.className = "read-uid-btn";
}
} catch (error) {
console.error("Stop RFID Error:", error);
}
}
// UID im Backend zurücksetzen
async function clearBackendUID() {
try {
await fetch(`/api/rfid/clear`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
} catch (error) {
console.error("Clear UID Error:", error);
}
}
// Einzelnes Lesen (für Kompatibilität)
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";
readBtn.innerHTML = "📡 Lese UID...";
readBtn.innerHTML = "📡 Lese...";
try {
// API Aufruf zum RFID Reader
const response = await fetch(`/api/rfid/read`, {
method: "GET",
headers: {
"Content-Type": "application/json",
...(APIKey && { Authorization: `Bearer ${APIKey}` }),
},
});
const result = await response.json();
if (result.success && result.uid) {
// UID in das Eingabefeld setzen
uidInput.value = result.uid
.match(/.{1,2}/g)
.join(":")
.toUpperCase();
uidInput.value = result.uid;
uidInput.focus();
// Visuelles Feedback
@@ -376,38 +421,20 @@
uidInput.style.borderColor = "#e1e5e9";
}, 2000);
showSuccessMessage("UID erfolgreich gelesen!");
showSuccessMessage("UID gelesen: " + result.uid);
// Automatisch zum nächsten Feld springen
setTimeout(() => {
document.getElementById("vorname").focus();
document.getElementById("name").focus();
}, 500);
} else {
// Fehler beim Lesen
const errorMsg = result.error || "Keine UID gefunden";
showErrorMessage(`RFID Fehler: ${errorMsg}`);
// UID Feld rot markieren
uidInput.style.borderColor = "#dc3545";
setTimeout(() => {
uidInput.style.borderColor = "#e1e5e9";
}, 10000);
showErrorMessage("Keine Karte erkannt");
}
} 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);
console.error("RFID Read Error:", error);
showErrorMessage("Fehler beim Lesen");
} finally {
// Button Status zurücksetzen
readBtn.disabled = false;
readBtn.className = "read-uid-btn";
readBtn.innerHTML = "📡 Read Chip";
}
}
@@ -415,9 +442,7 @@
async function checkServerStatus() {
try {
const response = await fetch("/api/health", {
headers: {
...(APIKey && { Authorization: `Bearer ${APIKey}` }),
},
headers: {},
});
const data = await response.json();
@@ -436,16 +461,19 @@
}
}
function loadLicence() {
fetch("/api/get-licence")
.then((response) => response.json())
.then((data) => {
APIKey = data.licence || "";
})
.catch((error) =>
showMessage("Fehler beim Laden der Lizenz", "error")
);
}
// Seite laden - RFID Status initialisieren
document.addEventListener("DOMContentLoaded", function () {
// Status Polling stoppen falls aktiv
stopStatusPolling();
// Server Status prüfen
checkServerStatus();
});
// Seite verlassen - RFID Reading komplett stoppen
window.addEventListener("beforeunload", function () {
stopRFIDReading();
});
</script>
</body>
</html>