Heartbead und Indicators

This commit is contained in:
Carsten Graf
2025-07-03 20:47:44 +02:00
parent ed0be38350
commit da8b21fda9
10 changed files with 740 additions and 64 deletions

View File

@@ -54,7 +54,7 @@ void readButtonJSON(const char * topic, const char * payload) {
// Extract values from JSON
int pressType = doc["type"] | 0;
const char* buttonId = doc["buttonmac"] | "unknown";
uint64_t timestamp = doc["timestamp"] | 0;
uint64_t timestamp = doc["timestamp"] | 0ULL;
// Print received data
Serial.printf("Button Press Received:\n");
@@ -87,6 +87,47 @@ void readButtonJSON(const char * topic, const char * payload) {
}
}
void handleHeartbeatTopic(const char* topic, const char* payload) {
// Topic-Format: heartbeat/alive/CC:DB:A7:2F:95:08
String topicStr(topic);
int lastSlash = topicStr.lastIndexOf('/');
if (lastSlash < 0) return;
String macStr = topicStr.substring(lastSlash + 1);
auto macBytes = macStringToBytes(macStr.c_str());
String buttonType = "unknown";
if (memcmp(macBytes.data(), buttonConfigs.start1.mac, 6) == 0) {
buttonType = "start1";
} else if (memcmp(macBytes.data(), buttonConfigs.stop1.mac, 6) == 0) {
buttonType = "stop1";
} else if (memcmp(macBytes.data(), buttonConfigs.start2.mac, 6) == 0) {
buttonType = "start2";
} else if (memcmp(macBytes.data(), buttonConfigs.stop2.mac, 6) == 0) {
buttonType = "stop2";
}
// Parse payload for timestamp (optional, falls im Payload enthalten)
uint64_t timestamp = millis();
StaticJsonDocument<128> payloadDoc;
if (payload && strlen(payload) > 0 && deserializeJson(payloadDoc, payload) == DeserializationError::Ok) {
if (payloadDoc.containsKey("timestamp")) {
timestamp = payloadDoc["timestamp"];
}
}
// JSON bauen
StaticJsonDocument<128> doc;
doc["button"] = buttonType;
doc["mac"] = macStr;
doc["timestamp"] = timestamp;
String json;
serializeJson(doc, json);
pushUpdateToFrontend(json); // Diese Funktion schickt das JSON an alle WebSocket-Clients
//Serial.printf("Published heartbeat JSON: %s\n", json.c_str());
}
void readRFIDfromButton(const char * topic, const char * payload) {
// Create a JSON document to hold the button press data
StaticJsonDocument<256> doc;
@@ -175,7 +216,12 @@ void setupMqttServer() {
} else if (strncmp(topic, "aquacross/button/rfid/", 22) == 0) {
readRFIDfromButton(topic, payload);
// Handle RFID read messages
}
else if (strncmp(topic, "heartbeat/alive/", 16) == 0) {
handleHeartbeatTopic(topic, payload);
}
else {
Serial.printf("Unhandled topic '%s' with payload '%s'\n", topic, payload);
}
updateStatusLED(3);
});

View File

@@ -17,8 +17,6 @@ time_t now;
struct tm timeinfo;
//Prototypen für Zeit-Management-Funktionen
void setupRTC();
void setRTC(DateTime dt);
void setupTimeAPI(AsyncWebServer& server);
String getCurrentTimeJSON();
bool setSystemTime(long timestamp);
@@ -56,7 +54,6 @@ bool setSystemTime(long timestamp) {
if (settimeofday(&tv, NULL) == 0) {
Serial.println("Zeit erfolgreich gesetzt: " + String(timestamp));
setRTC(DateTime(timestamp));
return true;
} else {
Serial.println("Fehler beim Setzen der Zeit");
@@ -66,7 +63,7 @@ bool setSystemTime(long timestamp) {
void setupTimeAPI(AsyncWebServer& server) {
setupRTC();
//setupRTC();
// API-Endpunkt: Aktuelle Zeit abrufen
server.on("/api/time", HTTP_GET, [](AsyncWebServerRequest *request){
@@ -212,37 +209,3 @@ uint64_t getCurrentTimestampMs() {
gettimeofday(&tv, NULL);
return (uint64_t)tv.tv_sec * 1000LL + (uint64_t)tv.tv_usec / 1000LL;
}
void setupRTC() {
Wire.begin();
Serial.println("Initialisiere RTC...");
// Versuche RTC mit Wire zu initialisieren
if (!rtc.begin()) { // Versuche RTC zu initialisieren, Timeout nach 10 Sekunden
Serial.println("RTC nicht gefunden! Versuche erneut...");
}
if (!rtc.initialized()) {
Serial.println("RTC nicht initialisiert, versuche Initialisierung...");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
} else {
Serial.println("RTC bereits initialisiert.");
}
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Setze die RTC auf die Kompilierungszeit
Serial.println("RTC initialisiert.");
// Aktuelle Zeit vom RTC abrufen
DateTime now = rtc.now();
Serial.printf("Aktuelle RTC-Zeit: %04d-%02d-%02d %02d:%02d:%02d\n",
now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
rtc.start(); // RTC starten, falls gestoppt
}
// Funktion zum Setzen der RTC-Zeit
void setRTC(DateTime dt) {
rtc.adjust(dt);
DateTime newtime = rtc.now();
Serial.printf("RTC-Zeit gesetzt: %04d-%02d-%02d %02d:%02d:%02d\n",
newtime.year(), newtime.month(), newtime.day(), newtime.hour(), newtime.minute(), newtime.second());
}

View File

@@ -32,9 +32,15 @@ void setupRoutes(){
request->send(SPIFFS, "/rfid.html", "text/html");
});
server.on("/about", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/about.html", "text/html");
});
server.on("/button.bin", HTTP_GET, [](AsyncWebServerRequest *request) {
if (SPIFFS.exists("/button.bin")) {
request->send(SPIFFS, "/button.bin", "application/octet-stream");
Serial.println("Firmware file served: /button.bin");
} else {
request->send(404, "application/json", "{\"error\":\"File not found\"}");
Serial.println("Firmware file not found: /button.bin");
}
});
server.on("/api/data", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "application/json", getTimerDataJSON());
@@ -248,9 +254,6 @@ server.on("/api/set-location", HTTP_POST, [](AsyncWebServerRequest *request) {
});
// Statische Dateien
server.serveStatic("/", SPIFFS, "/");
server.begin();
@@ -258,8 +261,6 @@ server.on("/api/set-location", HTTP_POST, [](AsyncWebServerRequest *request) {
}
void setupWebSocket() {
ws.onEvent([](AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
if (type == WS_EVT_CONNECT) {

View File

@@ -31,21 +31,30 @@ void setupWifi() {
WiFi.begin(ssidSTA, passwordSTA);
WiFi.softAP(ssidAP, passwordAP);
while (WiFi.status() != WL_CONNECTED){
// Add timeout for WiFi connection
unsigned long startAttemptTime = millis();
while (WiFi.status() != WL_CONNECTED &&
millis() - startAttemptTime < 10000) { // 10 seconds timeout
delay(500);
Serial.print(".");
}
}
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Fehler: Verbindung zum WLAN fehlgeschlagen!");
Serial.println("Starte Access Point...");
WiFi.mode(WIFI_MODE_AP);
WiFi.softAP(ssidAP, passwordAP);
}
else {
Serial.println("Erfolgreich mit WLAN verbunden!");
Serial.print("IP Adresse: ");
Serial.println(WiFi.localIP());
}
//Only wait for connection if ssidSTA and passwordSTA are set
Serial.println("");
Serial.println("Verbunden mit WLAN!");
Serial.print("IP-Adresse: ");
Serial.println(WiFi.localIP());
Serial.println("WiFi AP gestartet");
Serial.print("SSID: ");
Serial.println(WiFi.softAPSSID());
@@ -59,6 +68,7 @@ void setupWifi() {
} else {
Serial.println("Fehler beim Starten von mDNS!");
}
}
}
void setupOTA(AsyncWebServer *server) {