MQTT messages. Button anleren, Wifi frontend
This commit is contained in:
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -10,7 +10,10 @@
|
|||||||
"vector": "cpp",
|
"vector": "cpp",
|
||||||
"string_view": "cpp",
|
"string_view": "cpp",
|
||||||
"initializer_list": "cpp",
|
"initializer_list": "cpp",
|
||||||
"regex": "cpp"
|
"regex": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"xstring": "cpp",
|
||||||
|
"xutility": "cpp"
|
||||||
},
|
},
|
||||||
"liveServer.settings.multiRootWorkspaceName": "AquaMasterMQTT"
|
"liveServer.settings.multiRootWorkspaceName": "AquaMasterMQTT"
|
||||||
}
|
}
|
||||||
@@ -134,8 +134,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section" d="wifiSection" style="display: none;">
|
<div class="section" id="wifiSection">
|
||||||
<h2>📡 WLAN-Konfiguration</h2>
|
<h2>📡 WLAN-Konfiguration</h2>
|
||||||
|
<div id="wifiRestrictionNotice" class="restriction-notice" style="display: none;">
|
||||||
|
🔒 WLAN-Konfiguration ist nur mit Lizenz Level 3 oder höher verfügbar. Aktuelle Lizenz: Level <span id="currentLicenseLevel">0</span>
|
||||||
|
</div>
|
||||||
<form id="wifiForm">
|
<form id="wifiForm">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="wifi-ssid">WLAN Name (SSID):</label>
|
<label for="wifi-ssid">WLAN Name (SSID):</label>
|
||||||
@@ -157,7 +160,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<button type="submit" class="btn btn-primary">
|
<button type="submit" id="wifiSubmitBtn" class="btn btn-primary">
|
||||||
💾 WLAN-Einstellungen speichern
|
💾 WLAN-Einstellungen speichern
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -413,6 +416,7 @@
|
|||||||
|
|
||||||
// Check license level and update OTA button accordingly
|
// Check license level and update OTA button accordingly
|
||||||
updateOTAButtonAccess(data.tier || 0);
|
updateOTAButtonAccess(data.tier || 0);
|
||||||
|
updateWifiButtonAccess(data.tier || 0)
|
||||||
})
|
})
|
||||||
.catch((error) => console.log("Info konnte nicht geladen werden"));
|
.catch((error) => console.log("Info konnte nicht geladen werden"));
|
||||||
}
|
}
|
||||||
@@ -501,8 +505,8 @@
|
|||||||
// Update OTA button access based on license level
|
// Update OTA button access based on license level
|
||||||
function updateOTAButtonAccess(licenseLevel) {
|
function updateOTAButtonAccess(licenseLevel) {
|
||||||
const otaButton = document.getElementById("otaUpdateBtn");
|
const otaButton = document.getElementById("otaUpdateBtn");
|
||||||
const restrictionNotice = document.getElementById("otaRestrictionNotice");
|
const otarestrictionNotice = document.getElementById("otaRestrictionNotice");
|
||||||
const currentLevelSpan = document.getElementById("currentLicenseLevel");
|
const otacurrentLevelSpan = document.getElementById("currentLicenseLevel");
|
||||||
|
|
||||||
const level = parseInt(licenseLevel) || 0;
|
const level = parseInt(licenseLevel) || 0;
|
||||||
|
|
||||||
@@ -510,16 +514,44 @@
|
|||||||
// License level 2 or higher - enable OTA
|
// License level 2 or higher - enable OTA
|
||||||
otaButton.classList.remove("btn-disabled");
|
otaButton.classList.remove("btn-disabled");
|
||||||
otaButton.disabled = false;
|
otaButton.disabled = false;
|
||||||
restrictionNotice.style.display = "none";
|
otarestrictionNotice.style.display = "none";
|
||||||
} else {
|
} else {
|
||||||
// License level below 2 - disable OTA
|
// License level below 2 - disable OTA
|
||||||
otaButton.classList.add("btn-disabled");
|
otaButton.classList.add("btn-disabled");
|
||||||
otaButton.disabled = true;
|
otaButton.disabled = true;
|
||||||
restrictionNotice.style.display = "block";
|
otarestrictionNotice.style.display = "block";
|
||||||
currentLevelSpan.textContent = level;
|
otacurrentLevelSpan.textContent = level;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateWifiButtonAccess(licenseLevel) {
|
||||||
|
const wifiSubmitBtn = document.getElementById("wifiSubmitBtn");
|
||||||
|
const wifiForm = document.getElementById("wifiForm");
|
||||||
|
const wifiRestrictionNotice = document.getElementById("wifiRestrictionNotice");
|
||||||
|
const wifiCurrentLevelSpan = document.getElementById("currentLicenseLevel");
|
||||||
|
|
||||||
|
const level = parseInt(licenseLevel) || 0;
|
||||||
|
|
||||||
|
if (level >= 3) {
|
||||||
|
// License level 3 or higher - enable form
|
||||||
|
wifiSubmitBtn.classList.remove("btn-disabled");
|
||||||
|
wifiSubmitBtn.disabled = false;
|
||||||
|
wifiForm.querySelectorAll('input').forEach(input => {
|
||||||
|
input.disabled = false;
|
||||||
|
});
|
||||||
|
wifiRestrictionNotice.style.display = "none";
|
||||||
|
} else {
|
||||||
|
// License level below 3 - disable form
|
||||||
|
wifiSubmitBtn.classList.add("btn-disabled");
|
||||||
|
wifiSubmitBtn.disabled = true;
|
||||||
|
wifiForm.querySelectorAll('input').forEach(input => {
|
||||||
|
input.disabled = true;
|
||||||
|
});
|
||||||
|
wifiRestrictionNotice.style.display = "block";
|
||||||
|
wifiCurrentLevelSpan.textContent = level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// OTA Update function with license check
|
// OTA Update function with license check
|
||||||
function performOTAUpdate() {
|
function performOTAUpdate() {
|
||||||
const otaButton = document.getElementById("otaUpdateBtn");
|
const otaButton = document.getElementById("otaUpdateBtn");
|
||||||
|
|||||||
@@ -20,6 +20,11 @@ lib_compat_mode = strict
|
|||||||
[env:wemos_d1_mini32]
|
[env:wemos_d1_mini32]
|
||||||
board = wemos_d1_mini32
|
board = wemos_d1_mini32
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
build_flags =
|
||||||
|
-DBOARD_HAS_PSRAM
|
||||||
|
-mfix-esp32-psram-cache-issue
|
||||||
|
targets = uploadfs
|
||||||
|
board_build.psram = disabled
|
||||||
lib_deps =
|
lib_deps =
|
||||||
bblanchon/ArduinoJson@^7.4.1
|
bblanchon/ArduinoJson@^7.4.1
|
||||||
esp32async/ESPAsyncWebServer@^3.7.7
|
esp32async/ESPAsyncWebServer@^3.7.7
|
||||||
|
|||||||
99
src/buttonassigh.h
Normal file
99
src/buttonassigh.h
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "master.h"
|
||||||
|
// Aquacross Timer - ESP32 Master (Webserver + ESP-NOW + Anlernmodus)
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void handleLearningMode(const uint8_t* mac) {
|
||||||
|
// Prüfen ob MAC bereits einem anderen Button zugewiesen ist
|
||||||
|
if (buttonConfigs.start1.isAssigned && memcmp(buttonConfigs.start1.mac, mac, 6) == 0) {
|
||||||
|
Serial.println("Diese MAC ist bereits zugewiesen - wird ignoriert");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (buttonConfigs.stop1.isAssigned && memcmp(buttonConfigs.stop1.mac, mac, 6) == 0) {
|
||||||
|
Serial.println("Diese MAC ist bereits zugewiesen - wird ignoriert");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (buttonConfigs.start2.isAssigned && memcmp(buttonConfigs.start2.mac, mac, 6) == 0) {
|
||||||
|
Serial.println("Diese MAC ist bereits zugewiesen - wird ignoriert");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (buttonConfigs.stop2.isAssigned && memcmp(buttonConfigs.stop2.mac, mac, 6) == 0) {
|
||||||
|
Serial.println("Diese MAC ist bereits zugewiesen - wird ignoriert");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MAC ist noch nicht zugewiesen, normal fortfahren
|
||||||
|
switch(learningStep) {
|
||||||
|
case 0: // Start1
|
||||||
|
memcpy(buttonConfigs.start1.mac, mac, 6);
|
||||||
|
buttonConfigs.start1.isAssigned = true;
|
||||||
|
Serial.println("Start1 Button zugewiesen");
|
||||||
|
break;
|
||||||
|
case 1: // Stop1
|
||||||
|
memcpy(buttonConfigs.stop1.mac, mac, 6);
|
||||||
|
buttonConfigs.stop1.isAssigned = true;
|
||||||
|
Serial.println("Stop1 Button zugewiesen");
|
||||||
|
break;
|
||||||
|
case 2: // Start2
|
||||||
|
memcpy(buttonConfigs.start2.mac, mac, 6);
|
||||||
|
buttonConfigs.start2.isAssigned = true;
|
||||||
|
Serial.println("Start2 Button zugewiesen");
|
||||||
|
break;
|
||||||
|
case 3: // Stop2
|
||||||
|
memcpy(buttonConfigs.stop2.mac, mac, 6);
|
||||||
|
buttonConfigs.stop2.isAssigned = true;
|
||||||
|
Serial.println("Stop2 Button zugewiesen");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
learningStep++;
|
||||||
|
if (learningStep >= 4) {
|
||||||
|
learningMode = false;
|
||||||
|
learningStep = 0;
|
||||||
|
saveButtonConfig();
|
||||||
|
Serial.println("Lernmodus beendet!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleStartLearning() {
|
||||||
|
learningMode = true;
|
||||||
|
|
||||||
|
// Count assigned buttons and set appropriate learning step
|
||||||
|
int assignedButtons = 0;
|
||||||
|
if (buttonConfigs.start1.isAssigned) assignedButtons++;
|
||||||
|
if (buttonConfigs.stop1.isAssigned) assignedButtons++;
|
||||||
|
if (buttonConfigs.start2.isAssigned) assignedButtons++;
|
||||||
|
if (buttonConfigs.stop2.isAssigned) assignedButtons++;
|
||||||
|
|
||||||
|
learningStep = assignedButtons;
|
||||||
|
|
||||||
|
Serial.printf("Learning mode started - %d buttons already assigned, continuing at step %d\n",
|
||||||
|
assignedButtons, learningStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleLearningStatus() {
|
||||||
|
DynamicJsonDocument doc(256);
|
||||||
|
doc["active"] = learningMode;
|
||||||
|
doc["step"] = learningStep;
|
||||||
|
|
||||||
|
String response;
|
||||||
|
serializeJson(doc, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlearnButton() {
|
||||||
|
|
||||||
|
memset(buttonConfigs.start1.mac, 0, 6);
|
||||||
|
buttonConfigs.start1.isAssigned = false;
|
||||||
|
memset(buttonConfigs.stop1.mac, 0, 6);
|
||||||
|
buttonConfigs.stop1.isAssigned = false;
|
||||||
|
memset(buttonConfigs.start2.mac, 0, 6);
|
||||||
|
buttonConfigs.start2.isAssigned = false;
|
||||||
|
memset(buttonConfigs.stop2.mac, 0, 6);
|
||||||
|
buttonConfigs.stop2.isAssigned = false;
|
||||||
|
|
||||||
|
saveButtonConfig();
|
||||||
|
Serial.println("Buttons wurden verlernt.");
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "master.h"
|
#include "master.h"
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
@@ -6,6 +7,8 @@
|
|||||||
|
|
||||||
#include <statusled.h>
|
#include <statusled.h>
|
||||||
#include "timesync.h"
|
#include "timesync.h"
|
||||||
|
#include "buttonassigh.h"
|
||||||
|
#include "helper.h"
|
||||||
|
|
||||||
|
|
||||||
// Datenstruktur für ESP-NOW Nachrichten
|
// Datenstruktur für ESP-NOW Nachrichten
|
||||||
@@ -19,31 +22,110 @@ typedef struct {
|
|||||||
} ButtonMessage;
|
} ButtonMessage;
|
||||||
|
|
||||||
PicoMQTT::Server mqtt;
|
PicoMQTT::Server mqtt;
|
||||||
|
PicoMQTT::ServerLocalSubscribe localsubscribe;
|
||||||
|
|
||||||
|
|
||||||
|
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 == 2)) {
|
||||||
|
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 == 2)) {
|
||||||
|
handleStop2();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flash status LED to indicate received message
|
||||||
|
updateStatusLED(3);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void setupMqttServer() {
|
void setupMqttServer() {
|
||||||
|
|
||||||
// Set up the MQTT server with the desired port
|
// Set up the MQTT server with the desired port
|
||||||
// Subscribe to a topic pattern and attach a callback
|
// Subscribe to a topic pattern and attach a callback
|
||||||
mqtt.subscribe("#", [](const char * topic, const char * payload) {
|
mqtt.subscribe("#", [](const char * topic, const char * payload) {
|
||||||
Serial.printf("Received message in topic '%s': %s\n", topic, payload);
|
Serial.printf("Received message in topic '%s': %s\n", topic, payload);
|
||||||
|
readButtonJSON(topic, payload);
|
||||||
updateStatusLED(3); // Flash LED on message received
|
updateStatusLED(3); // Flash LED on message received
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Add the button subscription
|
||||||
|
|
||||||
// Start the MQTT server
|
// Start the MQTT server
|
||||||
mqtt.begin();
|
mqtt.begin();
|
||||||
|
|
||||||
Serial.println("MQTT server started on port 1883");
|
Serial.println("MQTT server started on port 1883");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void loopMqttServer() {
|
void loopMqttServer() {
|
||||||
// Handle incoming MQTT messages
|
|
||||||
mqtt.loop();
|
mqtt.loop();
|
||||||
|
|
||||||
// Optionally, you can publish a message periodically
|
|
||||||
static unsigned long lastPublish = 0;
|
static unsigned long lastPublish = 0;
|
||||||
if (millis() - lastPublish > 5000) { // Publish every 5 seconds
|
if (millis() - lastPublish > 30000) {
|
||||||
mqtt.publish("heartbeat/live", "Alive!");
|
// Convert timestamp to string before publishing
|
||||||
|
char timeStr[32];
|
||||||
|
snprintf(timeStr, sizeof(timeStr), "%llu", getCurrentTimestampMs());
|
||||||
|
mqtt.publish("sync/time", timeStr);
|
||||||
lastPublish = millis();
|
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());
|
||||||
|
}
|
||||||
10
src/helper.h
Normal file
10
src/helper.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "master.h"
|
||||||
|
|
||||||
|
std::array<uint8_t, 6> macStringToBytes(const char* macStr) {
|
||||||
|
std::array<uint8_t, 6> bytes;
|
||||||
|
sscanf(macStr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
||||||
|
&bytes[0], &bytes[1], &bytes[2], &bytes[3], &bytes[4], &bytes[5]);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
@@ -24,100 +24,11 @@ const char* firmwareversion = "1.0.0"; // Version der Firmware
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void handleLearningMode(const uint8_t* mac) {
|
|
||||||
// Prüfen ob MAC bereits einem anderen Button zugewiesen ist
|
|
||||||
if (buttonConfigs.start1.isAssigned && memcmp(buttonConfigs.start1.mac, mac, 6) == 0) {
|
|
||||||
Serial.println("Diese MAC ist bereits zugewiesen - wird ignoriert");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (buttonConfigs.stop1.isAssigned && memcmp(buttonConfigs.stop1.mac, mac, 6) == 0) {
|
|
||||||
Serial.println("Diese MAC ist bereits zugewiesen - wird ignoriert");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (buttonConfigs.start2.isAssigned && memcmp(buttonConfigs.start2.mac, mac, 6) == 0) {
|
|
||||||
Serial.println("Diese MAC ist bereits zugewiesen - wird ignoriert");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (buttonConfigs.stop2.isAssigned && memcmp(buttonConfigs.stop2.mac, mac, 6) == 0) {
|
|
||||||
Serial.println("Diese MAC ist bereits zugewiesen - wird ignoriert");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MAC ist noch nicht zugewiesen, normal fortfahren
|
|
||||||
switch(learningStep) {
|
|
||||||
case 0: // Start1
|
|
||||||
memcpy(buttonConfigs.start1.mac, mac, 6);
|
|
||||||
buttonConfigs.start1.isAssigned = true;
|
|
||||||
Serial.println("Start1 Button zugewiesen");
|
|
||||||
break;
|
|
||||||
case 1: // Stop1
|
|
||||||
memcpy(buttonConfigs.stop1.mac, mac, 6);
|
|
||||||
buttonConfigs.stop1.isAssigned = true;
|
|
||||||
Serial.println("Stop1 Button zugewiesen");
|
|
||||||
break;
|
|
||||||
case 2: // Start2
|
|
||||||
memcpy(buttonConfigs.start2.mac, mac, 6);
|
|
||||||
buttonConfigs.start2.isAssigned = true;
|
|
||||||
Serial.println("Start2 Button zugewiesen");
|
|
||||||
break;
|
|
||||||
case 3: // Stop2
|
|
||||||
memcpy(buttonConfigs.stop2.mac, mac, 6);
|
|
||||||
buttonConfigs.stop2.isAssigned = true;
|
|
||||||
Serial.println("Stop2 Button zugewiesen");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
learningStep++;
|
|
||||||
if (learningStep >= 4) {
|
|
||||||
learningMode = false;
|
|
||||||
learningStep = 0;
|
|
||||||
saveButtonConfig();
|
|
||||||
Serial.println("Lernmodus beendet!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleStartLearning() {
|
|
||||||
learningMode = true;
|
|
||||||
|
|
||||||
// Count assigned buttons and set appropriate learning step
|
|
||||||
int assignedButtons = 0;
|
|
||||||
if (buttonConfigs.start1.isAssigned) assignedButtons++;
|
|
||||||
if (buttonConfigs.stop1.isAssigned) assignedButtons++;
|
|
||||||
if (buttonConfigs.start2.isAssigned) assignedButtons++;
|
|
||||||
if (buttonConfigs.stop2.isAssigned) assignedButtons++;
|
|
||||||
|
|
||||||
learningStep = assignedButtons;
|
|
||||||
|
|
||||||
Serial.printf("Learning mode started - %d buttons already assigned, continuing at step %d\n",
|
|
||||||
assignedButtons, learningStep);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleLearningStatus() {
|
|
||||||
DynamicJsonDocument doc(256);
|
|
||||||
doc["active"] = learningMode;
|
|
||||||
doc["step"] = learningStep;
|
|
||||||
|
|
||||||
String response;
|
|
||||||
serializeJson(doc, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
void unlearnButton() {
|
|
||||||
|
|
||||||
memset(buttonConfigs.start1.mac, 0, 6);
|
|
||||||
buttonConfigs.start1.isAssigned = false;
|
|
||||||
memset(buttonConfigs.stop1.mac, 0, 6);
|
|
||||||
buttonConfigs.stop1.isAssigned = false;
|
|
||||||
memset(buttonConfigs.start2.mac, 0, 6);
|
|
||||||
buttonConfigs.start2.isAssigned = false;
|
|
||||||
memset(buttonConfigs.stop2.mac, 0, 6);
|
|
||||||
buttonConfigs.stop2.isAssigned = false;
|
|
||||||
|
|
||||||
saveButtonConfig();
|
|
||||||
Serial.println("Buttons wurden verlernt.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleStart1() {
|
void handleStart1() {
|
||||||
if (!timerData.isRunning1) {
|
if (!timerData.isRunning1 && timerData.isReady1) {
|
||||||
|
timerData.isReady1 = false; // Setze auf "Nicht bereit" bis Stopp
|
||||||
timerData.startTime1 = millis();
|
timerData.startTime1 = millis();
|
||||||
timerData.isRunning1 = true;
|
timerData.isRunning1 = true;
|
||||||
timerData.endTime1 = 0;
|
timerData.endTime1 = 0;
|
||||||
@@ -141,7 +52,8 @@ void handleStop1() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handleStart2() {
|
void handleStart2() {
|
||||||
if (!timerData.isRunning2) {
|
if (!timerData.isRunning2 && timerData.isReady2) {
|
||||||
|
timerData.isReady2 = false; // Setze auf "Nicht bereit" bis Stopp
|
||||||
timerData.startTime2 = millis();
|
timerData.startTime2 = millis();
|
||||||
timerData.isRunning2 = true;
|
timerData.isRunning2 = true;
|
||||||
timerData.endTime2 = 0;
|
timerData.endTime2 = 0;
|
||||||
@@ -185,6 +97,7 @@ void checkAutoReset() {
|
|||||||
timerData.startTime1 = 0;
|
timerData.startTime1 = 0;
|
||||||
timerData.endTime1 = 0;
|
timerData.endTime1 = 0;
|
||||||
timerData.finishedSince1 = 0;
|
timerData.finishedSince1 = 0;
|
||||||
|
timerData.isReady1 = true; // Zurücksetzen auf "Bereit"
|
||||||
Serial.println("Bahn 1 automatisch auf 'Bereit' zurückgesetzt");
|
Serial.println("Bahn 1 automatisch auf 'Bereit' zurückgesetzt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,6 +107,7 @@ void checkAutoReset() {
|
|||||||
timerData.startTime2 = 0;
|
timerData.startTime2 = 0;
|
||||||
timerData.endTime2 = 0;
|
timerData.endTime2 = 0;
|
||||||
timerData.finishedSince2 = 0;
|
timerData.finishedSince2 = 0;
|
||||||
|
timerData.isReady2 = true; // Zurücksetzen auf "Bereit"
|
||||||
Serial.println("Bahn 2 automatisch auf 'Bereit' zurückgesetzt");
|
Serial.println("Bahn 2 automatisch auf 'Bereit' zurückgesetzt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,5 +242,4 @@ void setup() {
|
|||||||
void loop() {
|
void loop() {
|
||||||
checkAutoReset();
|
checkAutoReset();
|
||||||
loopMqttServer(); // MQTT Server in der Loop aufrufen
|
loopMqttServer(); // MQTT Server in der Loop aufrufen
|
||||||
delay(100);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ struct TimerData {
|
|||||||
bool isRunning2 = false;
|
bool isRunning2 = false;
|
||||||
unsigned long finishedSince1 = 0;
|
unsigned long finishedSince1 = 0;
|
||||||
unsigned long finishedSince2 = 0;
|
unsigned long finishedSince2 = 0;
|
||||||
|
bool isReady1 = true; // Status für Bahn 1
|
||||||
|
bool isReady2 = true; // Status für Bahn 2
|
||||||
};
|
};
|
||||||
|
|
||||||
// Button Konfiguration
|
// Button Konfiguration
|
||||||
|
|||||||
@@ -196,3 +196,9 @@ bool isValidDateTime(int year, int month, int day, int hour, int minute, int sec
|
|||||||
|
|
||||||
return day <= daysInMonth[month - 1];
|
return day <= daysInMonth[month - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t getCurrentTimestampMs() {
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
return (uint64_t)tv.tv_sec * 1000LL + (uint64_t)tv.tv_usec / 1000LL;
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
#include <SPIFFS.h>
|
#include <SPIFFS.h>
|
||||||
#include <esp_wifi.h>
|
#include <esp_wifi.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include <buttonassigh.h>
|
||||||
|
|
||||||
AsyncWebServer server(80);
|
AsyncWebServer server(80);
|
||||||
|
|
||||||
void setupRoutes(){
|
void setupRoutes(){
|
||||||
|
|||||||
Reference in New Issue
Block a user