226 lines
7.5 KiB
C++
226 lines
7.5 KiB
C++
#pragma once
|
|
#include <Arduino.h>
|
|
#include "master.h"
|
|
#include <ArduinoJson.h>
|
|
|
|
#include <PicoMQTT.h>
|
|
|
|
#include "statusled.h"
|
|
#include "timesync.h"
|
|
#include "buttonassigh.h"
|
|
#include "helper.h"
|
|
#include "debug.h"
|
|
#include <map>
|
|
#include "databasebackend.h"
|
|
#include "webserverrouter.h"
|
|
|
|
struct TimestampData {
|
|
uint64_t lastMessageTimestamp; // Timestamp from the device
|
|
uint64_t lastLocalTimestamp; // Our local timestamp when message was received
|
|
uint64_t drift; // Calculated drift
|
|
};
|
|
|
|
// Map to store timestamp data for each MAC address
|
|
std::map<String, TimestampData> deviceTimestamps;
|
|
|
|
|
|
|
|
// Datenstruktur für ESP-NOW Nachrichten
|
|
// Datenstruktur für ESP-NOW Nachrichten
|
|
typedef struct {
|
|
uint8_t messageType;
|
|
uint8_t buttonId;
|
|
int buttonPressed;
|
|
uint32_t timestamp;
|
|
char messageId[33]; // 32 hex chars + null terminator for 128-bit ID
|
|
} ButtonMessage;
|
|
|
|
PicoMQTT::Server mqtt;
|
|
|
|
void readButtonJSON(const char * topic, const char * payload) {
|
|
|
|
if(strcmp(topic, "aquacross/button/press") == 0){
|
|
|
|
// Create a JSON document to parse the incoming message
|
|
JsonDocument doc;
|
|
DeserializationError error = deserializeJson(doc, payload);
|
|
|
|
if (error) {
|
|
Serial.print("JSON parsing failed: ");
|
|
Serial.println(error.c_str());
|
|
return;
|
|
}
|
|
|
|
// Extract values from JSON
|
|
int pressType = doc["type"] | 0;
|
|
const char* buttonId = doc["buttonmac"] | "unknown";
|
|
const char* messageId = doc["messageId"] | "unknown";
|
|
uint64_t timestamp = doc["timestamp"] | 0;
|
|
|
|
// Print received data
|
|
Serial.printf("Button Press Received:\n");
|
|
Serial.printf(" Type: %d\n", pressType);
|
|
Serial.printf(" Button MAC: %s\n", buttonId);
|
|
Serial.printf(" Message ID: %s\n", messageId);
|
|
Serial.printf(" Timestamp: %llu\n", timestamp);
|
|
|
|
|
|
auto macBytes = macStringToBytes(buttonId);
|
|
|
|
if (learningMode) {
|
|
handleLearningMode(macBytes.data());
|
|
return;
|
|
}
|
|
|
|
// Button-Zuordnung prüfen und entsprechende Aktion ausführen
|
|
if (memcmp(macBytes.data(), buttonConfigs.start1.mac, 6) == 0 && (pressType == 2)) {
|
|
handleStart1();
|
|
} else if (memcmp(macBytes.data(), buttonConfigs.stop1.mac, 6) == 0 && (pressType == 1)) {
|
|
handleStop1();
|
|
} else if (memcmp(macBytes.data(), buttonConfigs.start2.mac, 6) == 0 && (pressType == 2)) {
|
|
handleStart2();
|
|
} else if (memcmp(macBytes.data(), buttonConfigs.stop2.mac, 6) == 0 && (pressType == 1)) {
|
|
handleStop2();
|
|
}
|
|
|
|
// Flash status LED to indicate received message
|
|
updateStatusLED(3);
|
|
|
|
}
|
|
}
|
|
|
|
void readRFIDfromButton(const char * topic, const char * payload) {
|
|
// Create a JSON document to hold the button press data
|
|
StaticJsonDocument<256> doc;
|
|
DeserializationError error = deserializeJson(doc, payload);
|
|
if (!error) {
|
|
const char* mac = doc["buttonmac"] | "unknown";
|
|
const char* uid = doc["uid"] | "unknown";
|
|
|
|
Serial.printf("RFID Read from Button:\n");
|
|
Serial.printf(" Button MAC: %s\n", mac);
|
|
Serial.printf(" UID: %s\n", uid);
|
|
|
|
// Convert buttonmac to byte array for comparison
|
|
auto macBytes = macStringToBytes(mac);
|
|
|
|
// Check if the buttonmac matches buttonConfigs.start1.mac
|
|
if (memcmp(macBytes.data(), buttonConfigs.start1.mac, 6) == 0) {
|
|
// Fetch user data
|
|
UserData userData = checkUser(uid);
|
|
if (userData.exists) {
|
|
// Log user data
|
|
Serial.printf("User found for start1: %s %s, Alter: %d\n",
|
|
userData.firstname.c_str(),
|
|
userData.lastname.c_str(),
|
|
userData.alter);
|
|
|
|
// Create JSON message to send to the frontend
|
|
StaticJsonDocument<128> messageDoc;
|
|
messageDoc["firstname"] = userData.firstname;
|
|
messageDoc["lastname"] = userData.lastname;
|
|
messageDoc["lane"] = "start1"; // Add lane information
|
|
|
|
String message;
|
|
serializeJson(messageDoc, message);
|
|
|
|
// Push the message to the frontend
|
|
pushUpdateToFrontend(message);
|
|
Serial.printf("Pushed user data for start1 to frontend: %s\n", message.c_str());
|
|
} else {
|
|
Serial.println("User not found for UID: " + String(uid));
|
|
}
|
|
}
|
|
// Check if the buttonmac matches buttonConfigs.start2.mac
|
|
else if (memcmp(macBytes.data(), buttonConfigs.start2.mac, 6) == 0) {
|
|
// Fetch user data
|
|
UserData userData = checkUser(uid);
|
|
if (userData.exists) {
|
|
// Log user data
|
|
Serial.printf("User found for start2: %s %s, Alter: %d\n",
|
|
userData.firstname.c_str(),
|
|
userData.lastname.c_str(),
|
|
userData.alter);
|
|
|
|
// Create JSON message to send to the frontend
|
|
StaticJsonDocument<128> messageDoc;
|
|
messageDoc["firstname"] = userData.firstname;
|
|
messageDoc["lastname"] = userData.lastname;
|
|
messageDoc["lane"] = "start2"; // Add lane information
|
|
|
|
String message;
|
|
serializeJson(messageDoc, message);
|
|
|
|
// Push the message to the frontend
|
|
pushUpdateToFrontend(message);
|
|
Serial.printf("Pushed user data for start2 to frontend: %s\n", message.c_str());
|
|
} else {
|
|
Serial.println("User not found for UID: " + String(uid));
|
|
}
|
|
} else {
|
|
Serial.println("Button MAC does not match start1.mac or start2.mac");
|
|
}
|
|
} else {
|
|
Serial.println("Failed to parse RFID JSON");
|
|
}
|
|
}
|
|
|
|
void setupMqttServer() {
|
|
|
|
// Set up the MQTT server with the desired port
|
|
// Subscribe to a topic pattern and attach a callback
|
|
mqtt.subscribe("#", [](const char * topic, const char * payload) {
|
|
//Message received callback
|
|
//Serial.printf("Received message on topic '%s': %s\n", topic, payload);
|
|
if (strcmp(topic, "aquacross/button/press") == 0) {
|
|
readButtonJSON(topic, payload);
|
|
} else if (strncmp(topic, "aquacross/button/rfid/", 22) == 0) {
|
|
readRFIDfromButton(topic, payload);
|
|
// Handle RFID read messages
|
|
|
|
}
|
|
updateStatusLED(3);
|
|
});
|
|
|
|
// Start the MQTT server
|
|
mqtt.begin();
|
|
|
|
Serial.println("MQTT server started on port 1883");
|
|
}
|
|
|
|
|
|
|
|
void loopMqttServer() {
|
|
mqtt.loop();
|
|
|
|
static unsigned long lastPublish = 0;
|
|
if (millis() - lastPublish > 5000) {
|
|
// Convert timestamp to string before publishing
|
|
char timeStr[32];
|
|
snprintf(timeStr, sizeof(timeStr), "%llu", getCurrentTimestampMs());
|
|
mqtt.publish("sync/time", timeStr);
|
|
lastPublish = millis();
|
|
}
|
|
|
|
}
|
|
|
|
void sendMQTTMessage(const char * topic, const char * message) {
|
|
// Publish a message to the specified topic
|
|
mqtt.publish(topic, message);
|
|
Serial.printf("Published message to topic '%s': %s\n", topic, message);
|
|
}
|
|
|
|
void sendMQTTJSONMessage(const char * topic, const JsonDocument & doc) {
|
|
String jsonString;
|
|
serializeJson(doc, jsonString);
|
|
|
|
// Publish the JSON string to the specified topic
|
|
auto publish = mqtt.begin_publish(topic, measureJson(doc));
|
|
serializeJson(doc, publish);
|
|
publish.send();
|
|
Serial.printf("Published JSON message to topic '%s': %s\n", topic, jsonString.c_str());
|
|
}
|
|
|
|
|
|
|