Comments und add licence
This commit is contained in:
26
LICENCE.md
Normal file
26
LICENCE.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Lizenzvereinbarung (License Agreement)
|
||||||
|
|
||||||
|
Dieses Softwareprojekt ("Ninjacross Timer") sowie sämtliche zugehörigen Quellcodes, Dokumentationen und Ressourcen sind urheberrechtlich geschützt und stehen ausschließlich unter folgender Lizenz:
|
||||||
|
|
||||||
|
## Exklusive Lizenz
|
||||||
|
|
||||||
|
Die Nutzung, Vervielfältigung, Veränderung, Verbreitung oder Veröffentlichung dieses Projekts ist ausschließlich Carsten Graf (@reptil1990) vorbehalten. Jede Weitergabe, Nutzung oder Bearbeitung durch Dritte ist ohne ausdrückliche, schriftliche Genehmigung von Carsten Graf untersagt.
|
||||||
|
|
||||||
|
## Rechte des Lizenznehmers
|
||||||
|
|
||||||
|
- Exklusives, zeitlich und räumlich uneingeschränktes Nutzungsrecht für alle privaten, gewerblichen und wissenschaftlichen Zwecke
|
||||||
|
- Recht zur Modifikation, Erweiterung und Integration in eigene Projekte
|
||||||
|
- Recht zur Weitergabe an Dritte nur mit ausdrücklicher, schriftlicher Zustimmung des Rechteinhabers
|
||||||
|
|
||||||
|
## Pflichten und Einschränkungen
|
||||||
|
|
||||||
|
- Die Software darf nicht ohne Genehmigung veröffentlicht, verkauft oder anderweitig Dritten zugänglich gemacht werden
|
||||||
|
- Der Urheberrechtshinweis und diese Lizenzvereinbarung müssen in allen Kopien und abgeleiteten Werken enthalten bleiben
|
||||||
|
|
||||||
|
## Haftungsausschluss
|
||||||
|
|
||||||
|
Die Software wird ohne jegliche Gewährleistung bereitgestellt. Der Rechteinhaber übernimmt keine Haftung für Schäden, die aus der Nutzung der Software entstehen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
© 2025 Carsten Graf (@reptil1990). Alle Rechte vorbehalten.
|
||||||
20
TODO.md
20
TODO.md
@@ -1,19 +1,17 @@
|
|||||||
- KOMPLETTES Messageing System auf MQTT Server und Broker umstellen. DONE
|
- KOMPLETTES Messageing System auf MQTT Server und Broker umstellen. DONE
|
||||||
- Testen wie zuverlässig das ist
|
- Testen wie zuverlässig das ist
|
||||||
|
|
||||||
|
- message system überarbeiten. Sehr unzuverlässig mit dem peering DONE jetzt MQTT
|
||||||
|
- Uhrzeit abfragen (Eingabe der Zeitzone) DONE
|
||||||
- message system überarbeiten. Sehr unzuverlässig mit dem peering DONE jetzt MQTT
|
- Sync der Buttons mit echtzeit DONE
|
||||||
- Uhrzeit abfragen (Eingabe der Zeitzone) DONE
|
|
||||||
- Sync der Buttons mit echtzeit
|
|
||||||
- implementierung einer RTC
|
- implementierung einer RTC
|
||||||
|
|
||||||
v2.0
|
v2.0
|
||||||
- ADD Hotspot Manager to connect to a Wifi
|
|
||||||
|
- ADD Hotspot Manager to connect to a Wifi DONE
|
||||||
- ADD Licence Management (generate a programm where i can generate keys that get checked agains a private seed in the firmware)
|
- ADD Licence Management (generate a programm where i can generate keys that get checked agains a private seed in the firmware)
|
||||||
enables the Wifimanager to connect DONE
|
enables the Wifimanager to connect DONE
|
||||||
|
|
||||||
- ADD option point for location (read from online table and select the location via dropdown)
|
|
||||||
- ADD option to enter a name, age DONE
|
|
||||||
- ADD upload to a Online Database () DONE
|
|
||||||
|
|
||||||
|
- ADD option point for location (read from online table and select the location via dropdown) DONE
|
||||||
|
- ADD option to enter a name, age DONE
|
||||||
|
- ADD upload to a Online Database () DONE
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
// Aquacross Timer - ESP32 Master (Webserver + ESP-NOW + Anlernmodus)
|
// Aquacross Timer - ESP32 Master (Webserver + ESP-NOW + Anlernmodus)
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
// Weist im Lernmodus eine MAC-Adresse dem nächsten freien Button zu, sofern sie
|
||||||
|
// noch nicht vergeben ist
|
||||||
void handleLearningMode(const uint8_t *mac) {
|
void handleLearningMode(const uint8_t *mac) {
|
||||||
// Prüfen ob MAC bereits einem anderen Button zugewiesen ist
|
// Prüfen ob MAC bereits einem anderen Button zugewiesen ist
|
||||||
if (buttonConfigs.start1.isAssigned &&
|
if (buttonConfigs.start1.isAssigned &&
|
||||||
@@ -61,6 +63,8 @@ void handleLearningMode(const uint8_t *mac) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Startet den Lernmodus und setzt den Lernschritt entsprechend der bereits
|
||||||
|
// zugewiesenen Buttons
|
||||||
void handleStartLearning() {
|
void handleStartLearning() {
|
||||||
learningMode = true;
|
learningMode = true;
|
||||||
|
|
||||||
@@ -82,6 +86,7 @@ void handleStartLearning() {
|
|||||||
assignedButtons, learningStep);
|
assignedButtons, learningStep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Erstellt ein JSON mit Status und aktuellem Lernschritt des Lernmodus
|
||||||
void handleLearningStatus() {
|
void handleLearningStatus() {
|
||||||
DynamicJsonDocument doc(256);
|
DynamicJsonDocument doc(256);
|
||||||
doc["active"] = learningMode;
|
doc["active"] = learningMode;
|
||||||
@@ -91,6 +96,7 @@ void handleLearningStatus() {
|
|||||||
serializeJson(doc, response);
|
serializeJson(doc, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setzt alle Button-Zuweisungen zurück und speichert die Konfiguration
|
||||||
void unlearnButton() {
|
void unlearnButton() {
|
||||||
|
|
||||||
memset(buttonConfigs.start1.mac, 0, 6);
|
memset(buttonConfigs.start1.mac, 0, 6);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
|
||||||
#include <PicoMQTT.h>
|
#include <PicoMQTT.h>
|
||||||
|
|
||||||
#include "buttonassigh.h"
|
#include "buttonassigh.h"
|
||||||
@@ -15,18 +14,24 @@
|
|||||||
#include "webserverrouter.h"
|
#include "webserverrouter.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Struktur zur Speicherung von Zeitdaten für jedes Gerät/MAC.
|
||||||
|
* lastMessageTimestamp: Timestamp vom Gerät (z.B. Button)
|
||||||
|
* lastLocalTimestamp: Lokaler Timestamp beim Empfang der Nachricht
|
||||||
|
* drift: Berechneter Drift zwischen Gerät und Master
|
||||||
|
*/
|
||||||
struct TimestampData {
|
struct TimestampData {
|
||||||
uint64_t lastMessageTimestamp; // Timestamp from the device
|
uint64_t lastMessageTimestamp;
|
||||||
uint64_t lastLocalTimestamp; // Our local timestamp when message was received
|
uint64_t lastLocalTimestamp;
|
||||||
uint64_t drift; // Calculated drift
|
uint64_t drift;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Map to store timestamp data for each MAC address
|
// Map zur Speicherung der Zeitdaten für jede MAC-Adresse
|
||||||
std::map<String, TimestampData> deviceTimestamps;
|
std::map<String, TimestampData> deviceTimestamps;
|
||||||
|
|
||||||
// Datenstruktur für ESP-NOW Nachrichten
|
/**
|
||||||
// Datenstruktur für ESP-NOW Nachrichten
|
* Datenstruktur für eine Button-Nachricht (optional, falls benötigt)
|
||||||
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t messageType;
|
uint8_t messageType;
|
||||||
uint8_t buttonId;
|
uint8_t buttonId;
|
||||||
@@ -35,8 +40,13 @@ typedef struct {
|
|||||||
char messageId[33]; // 32 hex chars + null terminator for 128-bit ID
|
char messageId[33]; // 32 hex chars + null terminator for 128-bit ID
|
||||||
} ButtonMessage;
|
} ButtonMessage;
|
||||||
|
|
||||||
|
// MQTT-Server-Instanz
|
||||||
PicoMQTT::Server mqtt;
|
PicoMQTT::Server mqtt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Liest eine Button-JSON-Nachricht, extrahiert Typ, MAC und Timestamp,
|
||||||
|
* prüft die Button-Zuordnung und ruft die entsprechende Handler-Funktion auf.
|
||||||
|
*/
|
||||||
void readButtonJSON(const char *topic, const char *payload) {
|
void readButtonJSON(const char *topic, const char *payload) {
|
||||||
|
|
||||||
const char *prefix = "aquacross/button/";
|
const char *prefix = "aquacross/button/";
|
||||||
@@ -94,6 +104,10 @@ void readButtonJSON(const char *topic, const char *payload) {
|
|||||||
updateStatusLED(3);
|
updateStatusLED(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verarbeitet Heartbeat-Nachrichten von Buttons, erkennt den Button-Typ,
|
||||||
|
* extrahiert MAC und Timestamp und sendet ein JSON an das Frontend.
|
||||||
|
*/
|
||||||
void handleHeartbeatTopic(const char *topic, const char *payload) {
|
void handleHeartbeatTopic(const char *topic, const char *payload) {
|
||||||
// Topic-Format: heartbeat/alive/CC:DB:A7:2F:95:08
|
// Topic-Format: heartbeat/alive/CC:DB:A7:2F:95:08
|
||||||
String topicStr(topic);
|
String topicStr(topic);
|
||||||
@@ -138,6 +152,10 @@ void handleHeartbeatTopic(const char *topic, const char *payload) {
|
|||||||
// Serial.printf("Published heartbeat JSON: %s\n", json.c_str());
|
// Serial.printf("Published heartbeat JSON: %s\n", json.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verarbeitet Batteriestands-Nachrichten von Buttons, erkennt den Button-Typ,
|
||||||
|
* berechnet den Ladezustand und sendet ein JSON an das Frontend.
|
||||||
|
*/
|
||||||
void handleBatteryTopic(const char *topic, const char *payload) {
|
void handleBatteryTopic(const char *topic, const char *payload) {
|
||||||
int batteryLevel = 0;
|
int batteryLevel = 0;
|
||||||
String topicStr(topic);
|
String topicStr(topic);
|
||||||
@@ -194,6 +212,10 @@ void handleBatteryTopic(const char *topic, const char *payload) {
|
|||||||
// Serial.printf("Published heartbeat JSON: %s\n", json.c_str());
|
// Serial.printf("Published heartbeat JSON: %s\n", json.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verarbeitet RFID-Lese-Nachrichten von Buttons, prüft Userdaten,
|
||||||
|
* sendet diese ggf. als JSON an das Frontend.
|
||||||
|
*/
|
||||||
void readRFIDfromButton(const char *topic, const char *payload) {
|
void readRFIDfromButton(const char *topic, const char *payload) {
|
||||||
// Create a JSON document to hold the button press data
|
// Create a JSON document to hold the button press data
|
||||||
StaticJsonDocument<256> doc;
|
StaticJsonDocument<256> doc;
|
||||||
@@ -270,6 +292,10 @@ void readRFIDfromButton(const char *topic, const char *payload) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialisiert den MQTT-Server, richtet Subscriptions und Callback-Handler
|
||||||
|
* ein.
|
||||||
|
*/
|
||||||
void setupMqttServer() {
|
void setupMqttServer() {
|
||||||
|
|
||||||
// Set up the MQTT server with the desired port
|
// Set up the MQTT server with the desired port
|
||||||
@@ -296,6 +322,10 @@ void setupMqttServer() {
|
|||||||
Serial.println("MQTT server started on port 1883");
|
Serial.println("MQTT server started on port 1883");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Muss regelmäßig im Loop aufgerufen werden, damit der MQTT-Server arbeitet.
|
||||||
|
* Sendet außerdem alle 5 Sekunden einen Zeit-Sync.
|
||||||
|
*/
|
||||||
void loopMqttServer() {
|
void loopMqttServer() {
|
||||||
mqtt.loop();
|
mqtt.loop();
|
||||||
|
|
||||||
@@ -309,12 +339,18 @@ void loopMqttServer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sendet eine einfache Textnachricht an ein MQTT-Topic.
|
||||||
|
*/
|
||||||
void sendMQTTMessage(const char *topic, const char *message) {
|
void sendMQTTMessage(const char *topic, const char *message) {
|
||||||
// Publish a message to the specified topic
|
// Publish a message to the specified topic
|
||||||
mqtt.publish(topic, message);
|
mqtt.publish(topic, message);
|
||||||
Serial.printf("Published message to topic '%s': %s\n", topic, message);
|
Serial.printf("Published message to topic '%s': %s\n", topic, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sendet ein JSON-Dokument als Nachricht an ein MQTT-Topic.
|
||||||
|
*/
|
||||||
void sendMQTTJSONMessage(const char *topic, const JsonDocument &doc) {
|
void sendMQTTJSONMessage(const char *topic, const JsonDocument &doc) {
|
||||||
String jsonString;
|
String jsonString;
|
||||||
serializeJson(doc, jsonString);
|
serializeJson(doc, jsonString);
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ struct UserData {
|
|||||||
bool exists;
|
bool exists;
|
||||||
};
|
};
|
||||||
|
|
||||||
// UserData checkUser(const String& uid) is defined only once to avoid
|
// Prüft, ob ein Benutzer mit der angegebenen UID in der Datenbank existiert und
|
||||||
// redefinition errors.
|
// gibt dessen Daten zurück.
|
||||||
UserData checkUser(const String &uid) {
|
UserData checkUser(const String &uid) {
|
||||||
|
|
||||||
UserData userData = {"", "", "", 0, false};
|
UserData userData = {"", "", "", 0, false};
|
||||||
@@ -85,7 +85,7 @@ UserData checkUser(const String &uid) {
|
|||||||
return userData;
|
return userData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to enter user data into the database
|
// Fügt einen neuen Benutzer mit den angegebenen Daten in die Datenbank ein.
|
||||||
bool enterUserData(const String &uid, const String &firstname,
|
bool enterUserData(const String &uid, const String &firstname,
|
||||||
const String &lastname, const String &geburtsdatum,
|
const String &lastname, const String &geburtsdatum,
|
||||||
int alter) {
|
int alter) {
|
||||||
@@ -123,6 +123,7 @@ bool enterUserData(const String &uid, const String &firstname,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
@@ -152,11 +153,12 @@ JsonDocument getAllLocations() {
|
|||||||
return locations; // Return the populated JSON document
|
return locations; // Return the populated JSON document
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep this for backward compatibility
|
// Prüft, ob ein Benutzer mit der angegebenen UID existiert
|
||||||
|
// (Kompatibilitätsfunktion).
|
||||||
bool userExists(const String &uid) { return checkUser(uid).exists; }
|
bool userExists(const String &uid) { return checkUser(uid).exists; }
|
||||||
|
|
||||||
// Routes from the Frontend into here and then into DB backend.
|
// Richtet die HTTP-Routen für die Backend-API ein (z.B. Health-Check, User- und
|
||||||
|
// Location-Abfragen).
|
||||||
void setupBackendRoutes(AsyncWebServer &server) {
|
void setupBackendRoutes(AsyncWebServer &server) {
|
||||||
|
|
||||||
server.on("/api/health", HTTP_GET, [](AsyncWebServerRequest *request) {
|
server.on("/api/health", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
const char *ssidAP;
|
const char *ssidAP;
|
||||||
const char *passwordAP = nullptr;
|
const char *passwordAP = nullptr;
|
||||||
|
|
||||||
|
|||||||
17
src/rfid.h
17
src/rfid.h
@@ -4,7 +4,6 @@
|
|||||||
#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
|
||||||
@@ -22,6 +21,7 @@ unsigned long rfidReadStartTime = 0;
|
|||||||
const unsigned long RFID_READ_TIMEOUT =
|
const unsigned long RFID_READ_TIMEOUT =
|
||||||
10000; // 10 Sekunden Timeout für API Requests
|
10000; // 10 Sekunden Timeout für API Requests
|
||||||
|
|
||||||
|
// Initialisiert den RFID-Reader und das SPI-Interface.
|
||||||
void setupRFID() {
|
void setupRFID() {
|
||||||
|
|
||||||
// SPI und RFID initialisieren
|
// SPI und RFID initialisieren
|
||||||
@@ -32,6 +32,8 @@ void setupRFID() {
|
|||||||
// Reader details
|
// Reader details
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Liest automatisch eine RFID-Karte ein und blockiert die UID für eine
|
||||||
|
// bestimmte Zeit.
|
||||||
void handleAutomaticRFID() {
|
void handleAutomaticRFID() {
|
||||||
if (!mfrc522.PICC_IsNewCardPresent()) {
|
if (!mfrc522.PICC_IsNewCardPresent()) {
|
||||||
return;
|
return;
|
||||||
@@ -83,6 +85,8 @@ void handleAutomaticRFID() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Neue Funktion für API-basiertes RFID Lesen
|
// Neue Funktion für API-basiertes RFID Lesen
|
||||||
|
|
||||||
|
// Liest eine RFID-Karte im API-Modus ein (für Web-Requests).
|
||||||
void handleAPIRFIDRead() {
|
void handleAPIRFIDRead() {
|
||||||
unsigned long currentTime = millis();
|
unsigned long currentTime = millis();
|
||||||
|
|
||||||
@@ -130,6 +134,8 @@ void handleAPIRFIDRead() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// API Funktion: RFID Lesevorgang starten
|
// API Funktion: RFID Lesevorgang starten
|
||||||
|
|
||||||
|
// Startet einen neuen RFID-Lesevorgang über die API.
|
||||||
void startRFIDRead() {
|
void startRFIDRead() {
|
||||||
Serial.println("RFID API Lesevorgang gestartet...");
|
Serial.println("RFID API Lesevorgang gestartet...");
|
||||||
rfidReadRequested = true;
|
rfidReadRequested = true;
|
||||||
@@ -139,14 +145,18 @@ void startRFIDRead() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// API Funktion: Prüfen ob Lesevorgang abgeschlossen
|
// API Funktion: Prüfen ob Lesevorgang abgeschlossen
|
||||||
|
|
||||||
|
// Prüft, ob der aktuelle RFID-Lesevorgang abgeschlossen ist.
|
||||||
bool isRFIDReadComplete() { return !rfidReadRequested; }
|
bool isRFIDReadComplete() { return !rfidReadRequested; }
|
||||||
|
|
||||||
// API Funktion: Ergebnis des Lesevorgangs abrufen
|
// API Funktion: Ergebnis des Lesevorgangs abrufen
|
||||||
|
// Gibt das Ergebnis des letzten RFID-Lesevorgangs zurück.
|
||||||
String getRFIDReadResult(bool &success) {
|
String getRFIDReadResult(bool &success) {
|
||||||
success = rfidReadSuccess;
|
success = rfidReadSuccess;
|
||||||
return lastReadUID;
|
return lastReadUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Richtet die HTTP-API-Routen für RFID-Operationen ein.
|
||||||
void setupRFIDRoute(AsyncWebServer &server) {
|
void setupRFIDRoute(AsyncWebServer &server) {
|
||||||
server.on("/api/rfid/read", HTTP_GET, [](AsyncWebServerRequest *request) {
|
server.on("/api/rfid/read", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
Serial.println("api/rfid/read");
|
Serial.println("api/rfid/read");
|
||||||
@@ -240,6 +250,8 @@ void setupRFIDRoute(AsyncWebServer &server) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// API Funktion: RFID Reader Status prüfen
|
// API Funktion: RFID Reader Status prüfen
|
||||||
|
|
||||||
|
// Prüft, ob der RFID-Reader korrekt funktioniert und gibt den Status zurück.
|
||||||
bool checkRFIDReaderStatus() {
|
bool checkRFIDReaderStatus() {
|
||||||
byte version = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
|
byte version = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
|
||||||
|
|
||||||
@@ -255,6 +267,8 @@ bool checkRFIDReaderStatus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hilfsfunktion: Blockierte UIDs aufräumen
|
// Hilfsfunktion: Blockierte UIDs aufräumen
|
||||||
|
|
||||||
|
// Entfernt UIDs aus der Blockliste, deren Blockdauer abgelaufen ist.
|
||||||
void cleanupBlockedUIDs() {
|
void cleanupBlockedUIDs() {
|
||||||
unsigned long currentTime = millis();
|
unsigned long currentTime = millis();
|
||||||
|
|
||||||
@@ -268,6 +282,7 @@ void cleanupBlockedUIDs() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hauptschleife für das RFID-Handling (automatisch und API-basiert).
|
||||||
void loopRFID() {
|
void loopRFID() {
|
||||||
// Originale Funktionalität für automatisches Lesen
|
// Originale Funktionalität für automatisches Lesen
|
||||||
if (!rfidReadRequested) {
|
if (!rfidReadRequested) {
|
||||||
|
|||||||
@@ -6,11 +6,13 @@
|
|||||||
unsigned long lastLedBlink = 0;
|
unsigned long lastLedBlink = 0;
|
||||||
bool ledState = false;
|
bool ledState = false;
|
||||||
|
|
||||||
|
// Initialisiert die Status-LED (setzt Pin-Modus und schaltet sie aus).
|
||||||
void setupLED() {
|
void setupLED() {
|
||||||
pinMode(LED_PIN, OUTPUT);
|
pinMode(LED_PIN, OUTPUT);
|
||||||
digitalWrite(LED_PIN, LOW); // LED aus
|
digitalWrite(LED_PIN, LOW); // LED aus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Steuert die Status-LED je nach übergebenem Blinkmuster (Statusanzeige).
|
||||||
void updateStatusLED(int blinkPattern) {
|
void updateStatusLED(int blinkPattern) {
|
||||||
unsigned long currentTime = millis();
|
unsigned long currentTime = millis();
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
RTC_PCF8523 rtc;
|
RTC_PCF8523 rtc;
|
||||||
|
|
||||||
// Globale Zeitvariablen
|
// Globale Zeitvariablen
|
||||||
@@ -17,12 +16,14 @@ struct timezone tz;
|
|||||||
time_t now;
|
time_t now;
|
||||||
struct tm timeinfo;
|
struct tm timeinfo;
|
||||||
|
|
||||||
// Prototypen für Zeit-Management-Funktionen
|
// Initialisiert die Zeit-API und richtet die HTTP-Endpunkte ein.
|
||||||
void setupTimeAPI(AsyncWebServer &server);
|
void setupTimeAPI(AsyncWebServer &server);
|
||||||
|
// Gibt die aktuelle Zeit als JSON-String zurück.
|
||||||
String getCurrentTimeJSON();
|
String getCurrentTimeJSON();
|
||||||
|
// Setzt die Systemzeit auf den angegebenen Zeitstempel (Sekunden seit 1970).
|
||||||
bool setSystemTime(long timestamp);
|
bool setSystemTime(long timestamp);
|
||||||
|
|
||||||
// Hilfsfunktionen für Zeit-Management
|
// Hilfsfunktion: Gibt die aktuelle Zeit als JSON-String zurück.
|
||||||
String getCurrentTimeJSON() {
|
String getCurrentTimeJSON() {
|
||||||
gettimeofday(&tv, &tz);
|
gettimeofday(&tv, &tz);
|
||||||
now = tv.tv_sec;
|
now = tv.tv_sec;
|
||||||
@@ -48,6 +49,7 @@ String getCurrentTimeJSON() {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hilfsfunktion: Setzt die Systemzeit auf den angegebenen Zeitstempel.
|
||||||
bool setSystemTime(long timestamp) {
|
bool setSystemTime(long timestamp) {
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
tv.tv_sec = timestamp;
|
tv.tv_sec = timestamp;
|
||||||
@@ -62,6 +64,7 @@ bool setSystemTime(long timestamp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialisiert die Zeit-API und richtet die HTTP-Endpunkte ein.
|
||||||
void setupTimeAPI(AsyncWebServer &server) {
|
void setupTimeAPI(AsyncWebServer &server) {
|
||||||
|
|
||||||
// setupRTC();
|
// setupRTC();
|
||||||
@@ -185,6 +188,7 @@ void setupTimeAPI(AsyncWebServer &server) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hilfsfunktion: Zeit-Validierung
|
// Hilfsfunktion: Zeit-Validierung
|
||||||
|
// Prüft, ob die übergebenen Datums- und Zeitwerte gültig sind.
|
||||||
bool isValidDateTime(int year, int month, int day, int hour, int minute,
|
bool isValidDateTime(int year, int month, int day, int hour, int minute,
|
||||||
int second) {
|
int second) {
|
||||||
if (year < 2020 || year > 2099)
|
if (year < 2020 || year > 2099)
|
||||||
@@ -211,6 +215,7 @@ bool isValidDateTime(int year, int month, int day, int hour, int minute,
|
|||||||
return day <= daysInMonth[month - 1];
|
return day <= daysInMonth[month - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gibt den aktuellen Zeitstempel in Millisekunden seit 1970 zurück.
|
||||||
uint64_t getCurrentTimestampMs() {
|
uint64_t getCurrentTimestampMs() {
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
|
|||||||
@@ -10,15 +10,14 @@ void sendMQTTMessage(const char *topic, const char *message);
|
|||||||
#include <SPIFFS.h>
|
#include <SPIFFS.h>
|
||||||
#include <esp_wifi.h>
|
#include <esp_wifi.h>
|
||||||
|
|
||||||
|
|
||||||
#include "communication.h"
|
#include "communication.h"
|
||||||
#include <buttonassigh.h>
|
#include <buttonassigh.h>
|
||||||
#include <wificlass.h>
|
#include <wificlass.h>
|
||||||
|
|
||||||
|
|
||||||
AsyncWebServer server(80);
|
AsyncWebServer server(80);
|
||||||
AsyncWebSocket ws("/ws");
|
AsyncWebSocket ws("/ws");
|
||||||
|
|
||||||
|
// Richtet alle HTTP-Routen für den Webserver ein (API und statische Dateien).
|
||||||
void setupRoutes() {
|
void setupRoutes() {
|
||||||
// Web Server Routes
|
// Web Server Routes
|
||||||
|
|
||||||
@@ -281,6 +280,7 @@ void setupRoutes() {
|
|||||||
Serial.println("Web Server gestartet");
|
Serial.println("Web Server gestartet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialisiert den WebSocket-Server und definiert die Event-Handler.
|
||||||
void setupWebSocket() {
|
void setupWebSocket() {
|
||||||
ws.onEvent([](AsyncWebSocket *server, AsyncWebSocketClient *client,
|
ws.onEvent([](AsyncWebSocket *server, AsyncWebSocketClient *client,
|
||||||
AwsEventType type, void *arg, uint8_t *data, size_t len) {
|
AwsEventType type, void *arg, uint8_t *data, size_t len) {
|
||||||
@@ -295,10 +295,12 @@ void setupWebSocket() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sendet eine Nachricht an alle verbundenen WebSocket-Clients (Frontend).
|
||||||
void pushUpdateToFrontend(const String &message) {
|
void pushUpdateToFrontend(const String &message) {
|
||||||
ws.textAll(message); // Send the message to all connected clients
|
ws.textAll(message); // Send the message to all connected clients
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bereinigt getrennte WebSocket-Clients (sollte regelmäßig aufgerufen werden).
|
||||||
void loopWebSocket() {
|
void loopWebSocket() {
|
||||||
ws.cleanupClients(); // Clean up disconnected clients
|
ws.cleanupClients(); // Clean up disconnected clients
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,16 @@
|
|||||||
#include <esp_now.h>
|
#include <esp_now.h>
|
||||||
#include <esp_wifi.h>
|
#include <esp_wifi.h>
|
||||||
|
|
||||||
|
|
||||||
#include "licenceing.h"
|
#include "licenceing.h"
|
||||||
#include "master.h"
|
#include "master.h"
|
||||||
|
|
||||||
|
|
||||||
String uniqueSSID;
|
String uniqueSSID;
|
||||||
|
|
||||||
PrettyOTA OTAUpdates;
|
PrettyOTA OTAUpdates;
|
||||||
|
|
||||||
String getUniqueSSID();
|
String getUniqueSSID();
|
||||||
|
|
||||||
|
// Initialisiert das WLAN als Access Point oder Station und startet mDNS/OTA.
|
||||||
void setupWifi() {
|
void setupWifi() {
|
||||||
|
|
||||||
uniqueSSID = getUniqueSSID();
|
uniqueSSID = getUniqueSSID();
|
||||||
@@ -69,6 +68,7 @@ void setupWifi() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialisiert das OTA-Update-System (PrettyOTA) für Firmware-Updates.
|
||||||
void setupOTA(AsyncWebServer *server) {
|
void setupOTA(AsyncWebServer *server) {
|
||||||
// Initialize PrettyOTA
|
// Initialize PrettyOTA
|
||||||
OTAUpdates.Begin(server);
|
OTAUpdates.Begin(server);
|
||||||
@@ -83,6 +83,7 @@ void setupOTA(AsyncWebServer *server) {
|
|||||||
PRETTY_OTA_SET_CURRENT_BUILD_TIME_AND_DATE();
|
PRETTY_OTA_SET_CURRENT_BUILD_TIME_AND_DATE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generiert eine eindeutige SSID auf Basis der MAC-Adresse.
|
||||||
String getUniqueSSID() {
|
String getUniqueSSID() {
|
||||||
uint8_t mac[6];
|
uint8_t mac[6];
|
||||||
esp_wifi_get_mac(WIFI_IF_STA, mac);
|
esp_wifi_get_mac(WIFI_IF_STA, mac);
|
||||||
|
|||||||
Reference in New Issue
Block a user