Der Uno Wifi Rev 2 hatte halt viele Vorteile. Steckpins, WLAN die runde Powerbuchse....alles auf einem Board.
Den Sketch kann ich gerne hinzufügen. Vielleicht hilft das bei der Unterstützung.
#include <WiFiNINA.h>
#include <AccelStepper.h>
#include <TimeLib.h>
#include <WiFiUdp.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include "secrets.h"
#define dirPin 2
#define stepPin 4
#define motorInterfaceType 1
#define PIN_BUTTON 12
#define SECRET_MQTT_USER "MQTT_USER"
#define SECRET_MQTT_PW "MQTT_PASSWORD"
const char* mqtt_server = "192.168.2.2"; // IP-Adresse oder Domain des MQTT-Brokers
const int mqtt_port = 1883; // MQTT-Port (standardmäßig 1883)
const char* mqtt_user = MQTT_USER; // MQTT-Benutzername
const char* mqtt_password = MQTT_PASSWORD; // MQTT-Passwort
unsigned long WindschutzTimer;
boolean Warteposition_aktiv = false;
unsigned long WindWartezeit_ms = 900000;
const long Startposition = 17000;
const long Vormittag1 = 9000;
const long Vormittag2 = 2000;
const long Mittag1 = 0;
const long Mittag2 = -6000;
const long Nachmittag1 = -12000;
const long Nachmittag2 = -15000;
const long Nachmittag3 = -18000;
const long Endposition = -24000;
const long Windschutz = 0;
const int timeZoneOffset = 1; // Winterzeit (UTC+1)
AccelStepper stepper(motorInterfaceType, stepPin, dirPin);
char ssid[] = WIFI_SSID; // WLAN-SSID aus SECRETS.h
char pass[] = WIFI_PASSWORD; // WLAN-Passwort aus SECRETS.h
int timeZone = 2;
unsigned long currentTimestamp = 0; // Variable für den aktuellen Zeitstempel
time_t currentTime; // Variable für die aktuelle Zeit
WiFiUDP ntpUDP;
IPAddress timeServerIP;
//########################
WiFiUDP udp;
WiFiClient wifiClient;
PubSubClient client(wifiClient);
WiFiServer server(80);
#define WIFI_CHECK_INTERVAL 600000 // Intervall für die Überprüfung der WLAN-Verbindung (10 Minuten)
unsigned long wifiCheckTimer = 0; // Timer für die WLAN-Verbindung
bool isDaylightSavingTime(time_t currentTime);
int getLastSundayDay(int year, int month);
bool isDaylightSavingTime(time_t currentTime);
int getLastSundayDay(int year, int month);
bool isDaylightSavingTime(time_t currentTime) {
int currentYear = year(currentTime);
int currentMonth = month(currentTime);
int currentDay = day(currentTime);
// Letzter Sonntag im März
int lastSundayMarch = getLastSundayDay(currentYear, 3);
Serial.print("Letzter Sonntag im März: ");
Serial.println(lastSundayMarch);
// Letzter Sonntag im Oktober
int lastSundayOctober = getLastSundayDay(currentYear, 10);
Serial.print("Letzter Sonntag im Oktober: ");
Serial.println(lastSundayOctober);
// Sommerzeit beginnt am letzten Sonntag im März und endet am letzten Sonntag im Oktober
bool isDST = ((currentMonth > 3 && currentMonth < 10) ||
(currentMonth == 3 && currentDay > lastSundayMarch) ||
(currentMonth == 10 && currentDay <= lastSundayOctober));
if (isDST) {
Serial.println("Es ist Sommerzeit.");
} else {
Serial.println("Es ist Winterzeit.");
}
return isDST;
}
int getLastSundayDay(int year, int month) {
const int lastDays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // Tage in jedem Monat
int lastSunday = lastDays[month - 1]; // Annahme: Monat hat maximal 31 Tage
tmElements_t timeInfo;
// Bestimme den letzten Tag des Monats
while (lastSunday > 0) {
timeInfo.Year = year - 1970; // Year offset from 1970
timeInfo.Month = month;
timeInfo.Day = lastSunday;
time_t time = makeTime(timeInfo);
int dayOfWeek = weekday(time);
if (dayOfWeek == 1) { // Sonntag hat den Wert 1, unabhängig davon, wann die Woche beginnt
return lastSunday;
}
lastSunday--;
}
return -1; // Fehler, falls der letzte Sonntag nicht gefunden wird
}
void setup() {
Serial.begin(9600);
while (!Serial)
;
Serial.println("#### SETUP - START ####");
Serial.println("");
Serial.println("#### MOTOR - Geschwindigkeit eingestellen ####");
stepper.setMaxSpeed(1400);
stepper.setAcceleration(550);
Serial.println("#### MOTOR - Geschwindigkeit eingestellen - ERFOLGREICH ####");
Serial.println("");
Serial.println("#### PIN-Belegung wird hinterlegt ####");
pinMode(PIN_BUTTON, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT); // Pin für die eingebaute LED
Serial.println("#### PIN-Belegung wird hinterlegt - ERFOLGREICH ####");
Serial.println("");
Serial.println("#### WLAN-Verbindung####");
connectWiFi();
Serial.println("#### WLAN-Verbindung - ERFOLGREICH ####");
Serial.println("");
Serial.println("#### ZEIT ####");
setSyncProvider(getNtpTime);
setSyncInterval(3600); // Synchronisiere die Zeit alle 1 Stunde
Serial.println("#### ZEIT - ERFOLGREICH ####");
Serial.println("");
//server.begin();
// Verbindung zum MQTT-Broker herstellen, einschließlich Benutzername und Passwort
Serial.println("#### MQTT - Server-Verbindung herstellen ####");
client.setServer(mqtt_server, mqtt_port);
Serial.println("#### MQTT - Server-Verbindung herstellen - ERFOLGREICH ####");
Serial.println("");
Serial.println("#### MQTT - Callback-Funktion initialisieren ####");
client.setCallback(callback);
if (!client.connected()) {
reconnect();
}
Serial.println("#### MQTT - Callback-Funktion initialisieren - ERFOLGREICH ####");
Serial.println("");
// Abonnement für das gewünschte Topic einrichten
Serial.println("#### MQTT - Steuerungstopic Abo ####");
client.subscribe("solar/bkw-steuerung/app");
Serial.println("#### MQTT - Steuerungstopic Abo - ERFOLGREICH ####");
Serial.println("");
// Sende Autodiscovery-Nachrichten
sendMQTTAutoDiscovery();
Serial.println("");
Serial.println("#### MQTT - Loop aktivieren ####");
client.loop();
Serial.println("#### MQTT - Loop aktivieren - ERFOLGREICH ####");
Serial.println("");
Serial.println("#### Setup - ENDE ####");
Serial.println("");
}
void loop() {
checkWiFiConnection();
checkWindsensor();
//handleRoot();
// Daten an Home Assistant senden
sendMQTTData();
// MQTT Auto Discovery
// MQTT-Verbindung und Verarbeitung von Nachrichten in einer separaten Funktion
//mqttLoop();
client.loop();
}
void checkWiFiConnection() {
if (millis() - wifiCheckTimer >= WIFI_CHECK_INTERVAL) {
wifiCheckTimer = millis(); // Timer zurücksetzen
// Überprüfe die WLAN-Verbindung
if (WiFi.status() != WL_CONNECTED) {
Serial.println("");
Serial.println("#### WLAN - Verbindungstest ####");
Serial.println("");
Serial.println("WLAN - Verbinung - NICHT AKTIV (Verbinde neu)");
Serial.println("");
Serial.println("#### WLAN - Verbindungstest ####");
Serial.println("");
// Trenne WLAN-Verbindung
WiFi.disconnect();
// Warte, um sicherzustellen, dass die Verbindung getrennt wurde
delay(1000);
// Stelle die WLAN-Verbindung neu her
connectWiFi();
} else {
Serial.println("");
Serial.println("#### WLAN - Verbindungstest ####");
Serial.println("");
Serial.println("WLAN - Verbindung - AKTIV.");
Serial.println("");
Serial.println("#### WLAN - Verbindungstest ####");
Serial.println("");
}
}
}
void connectWiFi() {
int connectAttempts = 0;
while (connectAttempts < 10) {
WiFi.begin(ssid, pass);
unsigned long startTime = millis();
while (WiFi.status() != WL_CONNECTED && millis() - startTime < 30000) {
delay(1000);
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("Verbindung hergestellt");
IPAddress ip = WiFi.localIP();
Serial.print("IP-Adresse: ");
Serial.println(ip);
return; // Verbindung erfolgreich, beende die Funktion
}
// Verbindung nicht erfolgreich, trenne die Verbindung
WiFi.disconnect();
// Warte 30 Sekunden vor dem nächsten Versuch
delay(30000);
connectAttempts++;
}
Serial.println("WiFi-Verbindung fehlgeschlagen");
}
time_t getNtpTime() {
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
}
WiFi.hostByName("pool.ntp.org", timeServerIP);
Serial.println("Zeitserver IP-Adresse erhalten");
const int NTP_PACKET_SIZE = 48;
byte packetBuffer[NTP_PACKET_SIZE];
memset(packetBuffer, 0, NTP_PACKET_SIZE);
packetBuffer[0] = 0b11100011;
packetBuffer[1] = 0;
packetBuffer[2] = 6;
packetBuffer[3] = 0xEC;
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
WiFiUDP udp;
udp.begin(123);
udp.beginPacket(timeServerIP, 123);
udp.write(packetBuffer, NTP_PACKET_SIZE);
udp.endPacket();
uint32_t beginWait = millis();
while (millis() - beginWait < 5000) {
int size = udp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
udp.read(packetBuffer, NTP_PACKET_SIZE);
unsigned long secsSince1900 = (unsigned long)packetBuffer[40] << 24 | (unsigned long)packetBuffer[41] << 16 | (unsigned long)packetBuffer[42] << 8 | (unsigned long)packetBuffer[43];
time_t ntpTime = secsSince1900 - 2208988800UL;
// Hier wird die DST-Offset-Korrektur angewendet
ntpTime += (isDaylightSavingTime(ntpTime) ? 3600 : 0);
ntpTime += (timeZoneOffset * 3600); // Zeitzonenverschiebung hinzufügen
// Aktuelles Datum und Uhrzeit ausgeben
Serial.print("Datum: ");
Serial.print(day(ntpTime));
Serial.print("-");
Serial.print(month(ntpTime));
Serial.print("-");
Serial.print(year(ntpTime));
Serial.println(" ");
Serial.print("Uhrzeit: ");
Serial.print(hour(ntpTime));
Serial.print(":");
Serial.print(minute(ntpTime));
Serial.print(":");
Serial.println(second(ntpTime));
return ntpTime;
}
delay(10);
}
Serial.println("Keine Antwort vom Zeitserver");
return 0;
}
void moveStepper(int position) {
Serial.println("#### MOTOR - BEWEGUNG - START ####");
Serial.println("");
if (stepper.currentPosition() != position) {
stepper.moveTo(position);
stepper.runToPosition();
}
Serial.println("#### MOTOR - BEWEGUNG - ENDE ####");
Serial.println("");
}
void managePositions() {
Serial.println("#### MOTOR - POSITIONEN - START ####");
Serial.println("");
currentTime = now(); // Aktualisiere den Wert der globalen Variable currentTime
int currentMonth = month(currentTime);
int currentDay = day(currentTime);
int currentHour = hour(currentTime);
int currentMinute = minute(currentTime);
int currentSecond = second(currentTime);
int currentTimeInSeconds = currentHour * 3600 + currentMinute * 60;
Serial.print("Zeit: ");
Serial.print(day(currentTime));
Serial.print(".");
Serial.print(month(currentTime));
Serial.print(".");
Serial.print(year(currentTime));
Serial.print(" ");
// Führende Null für einstellige Stunden
Serial.print(currentHour < 10 ? "0" + String(currentHour) : String(currentHour));
Serial.print(":");
// Führende Null für einstellige Minuten
Serial.print(currentMinute < 10 ? "0" + String(currentMinute) : String(currentMinute));
Serial.print(":");
// Führende Null für einstellige Sekunden
Serial.println(currentSecond < 10 ? "0" + String(currentSecond) : String(currentSecond));
Serial.println("");
// Überprüfe, ob Sommerzeit oder Winterzeit aktiv ist
bool isDST = isDaylightSavingTime(currentTime);
struct PositionThreshold {
int thresholdHour;
int thresholdMinute;
long position;
};
PositionThreshold PositionenSommer[] = {
{ 6, 0, Startposition },
{ 11, 0, Vormittag1 },
{ 12, 0, Vormittag2 },
{ 12, 30, Mittag1 },
{ 13, 0, Mittag2 },
{ 13, 30, Nachmittag1 },
{ 14, 0, Nachmittag2 },
{ 15, 0, Nachmittag3 },
{ 16, 0, Endposition },
{ 21, 0, Windschutz }
};
PositionThreshold PositionenWinter[] = {
{ 8, 0, Vormittag1 },
{ 10, 30, Vormittag2 },
{ 12, 0, Mittag1 },
{ 12, 30, Mittag2 },
{ 13, 0, Nachmittag1 },
{ 14, 0, Nachmittag2 },
{ 15, 0, Nachmittag3 },
{ 17, 30, Windschutz }
};
PositionThreshold PositionenZwischen[] = {
{ 7, 0, Startposition },
{ 9, 0, Vormittag1 },
{ 11, 0, Vormittag2 },
{ 12, 0, Mittag1 },
{ 13, 0, Mittag2 },
{ 14, 0, Nachmittag1 },
{ 15, 0, Nachmittag2 },
{ 16, 0, Nachmittag3 },
{ 17, 0, Endposition },
{ 18, 30, Windschutz }
};
int numThresholds;
PositionThreshold *thresholds;
if (currentMonth == 1 || currentMonth == 2 || currentMonth == 11 || currentMonth == 12) {
thresholds = PositionenWinter;
numThresholds = sizeof(PositionenWinter) / sizeof(PositionenWinter[0]);
} else if (currentMonth == 3 || currentMonth == 4 || currentMonth == 9 || currentMonth == 10) {
thresholds = PositionenZwischen;
numThresholds = sizeof(PositionenZwischen) / sizeof(PositionenZwischen[0]);
} else if (currentMonth >= 5 && currentMonth <= 8) {
thresholds = PositionenSommer;
numThresholds = sizeof(PositionenSommer) / sizeof(PositionenSommer[0]);
} else {
// Standardpositionen oder eine andere Logik hier einfügen, wenn erforderlich
thresholds = PositionenSommer;
numThresholds = sizeof(PositionenSommer) / sizeof(PositionenSommer[0]);
}
long position = Startposition; // Standardposition
for (int i = 0; i < numThresholds; i++) {
if (currentHour > thresholds[i].thresholdHour || (currentHour == thresholds[i].thresholdHour && currentMinute >= thresholds[i].thresholdMinute)) {
position = thresholds[i].position;
} else {
break; // Schleife abbrechen, da der Rest der Schwellenwerte nicht mehr relevant ist
}
}
moveStepper(position);
Serial.println("");
Serial.print("Aktive Positionen: ");
if (currentMonth == 1 || currentMonth == 2 || currentMonth == 11 || currentMonth == 12) {
Serial.println("Winterpositionen");
} else if (currentMonth == 3 || currentMonth == 4 || currentMonth == 9 || currentMonth == 10) {
Serial.println("Zwischenpositionen");
} else if (currentMonth >= 5 && currentMonth <= 8) {
Serial.println("Sommerpositionen");
} else {
Serial.println("Standardpositionen"); // Standardpositionen oder eine andere Bezeichnung hier einfügen, wenn erforderlich
}
Serial.print("Position: ");
Serial.println(stepper.currentPosition());
Serial.println("#### MOTOR - POSITIONEN - ENDE ####");
Serial.println("");
}
void checkWindsensor() {
//currentTime = now(); // Aktualisiere den Wert der globalen Variable currentTime
Serial.println("");
Serial.println("#### WINDSENSOR - CHECK - START ####");
Serial.println("");
if (digitalRead(PIN_BUTTON) == HIGH) {
Warteposition_aktiv = true;
WindschutzTimer = millis();
Serial.println("WINDSENSOR - AUSGELÖST");
Serial.print("WINDSENSOR - ");
Serial.println(WindschutzTimer);
Serial.println("");
stepper.moveTo(Windschutz);
stepper.runToPosition();
Serial.print("WINDSENSOR - AKTIVIERT - Position: ");
Serial.println(stepper.currentPosition());
Serial.println("");
}
if (millis() - WindschutzTimer >= WindWartezeit_ms) {
Warteposition_aktiv = false;
Serial.println("");
Serial.println("Windsensor deaktiviert");
Serial.println("");
}
Serial.println("#### WINDSENSOR - CHECK - ENDE ####");
Serial.println("");
if (!Warteposition_aktiv) {
managePositions(); // Nur wenn der Windsensor nicht aktiv ist, rufe managePositions auf
}
}
void handleRoot() {
WiFiClient client = server.available();
if (client) {
String request = client.readStringUntil('\r');
client.flush();
if (request.indexOf("/deaktivieren") != -1) {
// Logik zum Deaktivieren des Windsensors hier
Warteposition_aktiv = false;
Serial.println("Windsensor deaktiviert");
} else if (request.indexOf("/aktivieren") != -1) {
// Logik zum Aktivieren des Windsensors hier
Warteposition_aktiv = true;
WindschutzTimer = millis();
Serial.println("Windsensor aktiviert");
// Setze die Zielposition für den Windschutz und bewege den Motor zur Windschutzposition
stepper.moveTo(Windschutz);
stepper.runToPosition();
Serial.print(stepper.currentPosition());
} else if (request.indexOf("/position_setzen") != -1) {
// Logik zum Setzen der Windschutzposition hier
Warteposition_aktiv = true;
WindschutzTimer = millis();
Serial.println("Windsensor aktiviert");
// Setze die Zielposition für den Windschutz und bewege den Motor zur Windschutzposition
stepper.moveTo(Endposition);
stepper.runToPosition();
Serial.print(stepper.currentPosition());
} else if (request.indexOf("/startposition_setzen") != -1) {
// Logik zum Setzen der Startposition hier
Warteposition_aktiv = true;
WindschutzTimer = millis();
Serial.println("Windsensor aktiviert");
// Setze die Zielposition für den Motor zur Startposition und bewege den Motor dorthin
stepper.moveTo(Startposition);
stepper.runToPosition();
Serial.print(stepper.currentPosition());
} else if (request.indexOf("/drehen_plus_1000") != -1) {
// Logik zum Drehen des Motors um +1000 Schritte hier
stepper.move(1000); // Motor um 1000 Schritte erhöhen
stepper.runToPosition(); // Motor zur neuen Position bewegen
Serial.print("Motor um 1000 Schritte erhöht. Aktuelle Position: ");
Serial.println(stepper.currentPosition());
// Aktiviere den Windsensor, um die neue Position zu halten
Warteposition_aktiv = true;
WindschutzTimer = millis();
Serial.println("Windsensor aktiviert");
} else if (request.indexOf("/drehen_minus_1000") != -1) {
// Logik zum Drehen des Motors um -1000 Schritte hier
stepper.move(-1000); // Motor um 1000 Schritte reduzieren
stepper.runToPosition(); // Motor zur neuen Position bewegen
Serial.print("Motor um 1000 Schritte reduziert. Aktuelle Position: ");
Serial.println(stepper.currentPosition());
// Aktiviere den Windsensor, um die neue Position zu halten
Warteposition_aktiv = true;
WindschutzTimer = millis();
Serial.println("Windsensor aktiviert");
}
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("<html><body>");
client.println("<h1><strong>Balkonkraftwerk</strong></h1>");
// IP-Adresse
client.print("<p><strong>IP-Adresse:</strong> ");
client.print(WiFi.localIP());
client.println("</p>");
// Datum und Uhrzeit
client.print("<strong>Datum:</strong> ");
client.print(day(currentTime));
client.print(".");
client.print(month(currentTime));
client.print(".");
client.print(year(currentTime));
client.print("<br>");
client.print("<strong>Uhrzeit:</strong> ");
client.print((hour(currentTime) < 10 ? "0" : ""));
client.print(hour(currentTime));
client.print(":");
client.print((minute(currentTime) < 10 ? "0" : ""));
client.print(minute(currentTime));
client.print(":");
client.print((second(currentTime) < 10 ? "0" : ""));
client.print(second(currentTime));
client.print("<br>");
// Sommer- oder Winterzeit
client.print("<strong>S/W-Zeit:</strong> ");
client.print(isDaylightSavingTime(currentTime) ? "Sommerzeit" : "Winterzeit");
client.print("");
// Aktuelle Position
client.print("<p><strong>Aktuelle Position:</strong> ");
client.print(stepper.currentPosition());
client.print("<br>");
// Positionsset
int currentMonth = month(currentTime); // Den aktuellen Monat holen
client.print("<strong>Positionsset:</strong> ");
if (currentMonth == 1 || currentMonth == 2 || currentMonth == 11 || currentMonth == 12) {
client.print("Winter");
} else if (currentMonth == 3 || currentMonth == 4 || currentMonth == 9 || currentMonth == 10) {
client.print("Zwischen");
} else if (currentMonth >= 5 and currentMonth <= 8) {
client.print("Sommer");
} else {
client.print("Standard");
}
client.print("<br>");
// Status des Windsensors
client.print("<p><strong>Windsensor:</strong> ");
if (Warteposition_aktiv) {
// Wenn der Windsensor aktiviert ist, den Text in Rot anzeigen
client.print("<span style='color:red;'>Aktiviert</span>");
} else {
// Wenn der Windsensor deaktiviert ist, den Text in Grün anzeigen
client.print("<span style='color:green;'>Deaktiviert</span>");
}
// Zeitdauer des aktiven Windsensors
if (Warteposition_aktiv) {
unsigned long currentTimeInSeconds = (millis() - WindschutzTimer) / 1000;
int minutes = currentTimeInSeconds / 60;
int seconds = currentTimeInSeconds % 60;
client.print(" - ");
// Wenn der Windsensor aktiviert ist, die Zeit in Rot anzeigen
client.print("<span style='color:red;'>");
client.print(minutes);
client.print(" Min ");
client.print(seconds);
client.print(" Sek");
client.print("</span>");
}
// Formular zum Deaktivieren und Aktivieren des Windsensors
client.println("<div style='display: flex;'><form action='/deaktivieren' method='get'><input type='submit' value='Windsensor deaktivieren'></form>");
client.println("<form action='/aktivieren' method='get' style='margin-left: 10px;'><input type='submit' value='Windsensor aktivieren'></form></div>");
client.println("<form action='/position_setzen' method='get' style='margin-left: 10px;'><input type='submit' value='Endposition'></form>");
client.println("<form action='/startposition_setzen' method='get' style='margin-left: 10px;'><input type='submit' value='Startposition'></form>");
client.println("<form action='/drehen_plus_1000' method='get' style='margin-left: 10px;'><input type='submit' value='Motor um +1000 erhöhen'></form>");
client.println("<form action='/drehen_minus_1000' method='get' style='margin-left: 10px;'><input type='submit' value='Motor um -1000 reduzieren'></form>");
client.println("</body></html>");
client.stop();
}
}
void reconnect() {
// Loop, bis eine Verbindung hergestellt wird
while (!client.connected()) {
Serial.print("MQTT - Broker - ");
// Verbindung mit MQTT-Broker herstellen, einschließlich Benutzername und Passwort
if (client.connect("ArduinoClient", mqtt_user, mqtt_password)) {
Serial.println("verbunden");
} else {
Serial.print("Fehlgeschlagen, rc=");
Serial.print(client.state());
Serial.println(" Versuche es in 5 Sekunden erneut");
// 5 Sekunden warten und erneut versuchen
delay(5000);
}
}
}
unsigned long lastSendTime = 0; // Variable, um die Zeit des letzten Sendens zu speichern
void sendMQTTData() {
// Überprüfe, ob eine Verbindung zum MQTT-Broker besteht
//if (!client.connected()) {
// reconnect();
//}
// Erfasse die aktuellen Zeit
unsigned long currentTime = millis();
// Sende die MQTT-Nachrichten nur, wenn seit dem letzten Senden mehr als 5 Sekunden vergangen sind
if (currentTime - lastSendTime >= 15000) {
// Erfasse die Daten, die du übertragen möchtest
int motorPosition = stepper.currentPosition();
String windsensorStatus = Warteposition_aktiv ? "Aktiviert" : "Deaktiviert";
String zeitzone = isDaylightSavingTime(currentTime) ? "Sommerzeit" : "Winterzeit";
String positionsset;
int currentMonth = month(currentTime);
if (currentMonth == 1 || currentMonth == 2 || currentMonth == 11 || currentMonth == 12) {
positionsset = "Winter";
} else if (currentMonth == 3 || currentMonth == 4 || currentMonth == 9 || currentMonth == 10) {
positionsset = "Zwischen";
} else if (currentMonth >= 5 && currentMonth <= 8) {
positionsset = "Sommer";
} else {
positionsset = "Standard";
}
// Erfasse die aktuelle Uhrzeit
String currentTimeStr = String(hour()) + ":" + minute() + ":" + second();
// Debugging-Ausgabe, um sicherzustellen, dass der Codeabschnitt erreicht wird
Serial.println("");
Serial.println("");
Serial.println("##### MQTT-Nachrichtenversand #####");
// Veröffentliche die MQTT-Nachrichten mit den erfassten Daten
Serial.print("Motorposition: ");
Serial.println(motorPosition);
client.publish("solar/bkw-steuerung/motorposition", String(motorPosition).c_str());
Serial.print("Windsensor-Status: ");
Serial.println(windsensorStatus);
client.publish("solar/bkw-steuerung/windsensor", windsensorStatus.c_str());
Serial.print("Zeitzone: ");
Serial.println(zeitzone);
client.publish("solar/bkw-steuerung/zeitzone", zeitzone.c_str());
Serial.print("Positionsset: ");
Serial.println(positionsset);
client.publish("solar/bkw-steuerung/positionsset", positionsset.c_str());
Serial.print("Aktuelle Uhrzeit: ");
Serial.println(currentTimeStr);
client.publish("solar/bkw-steuerung/uhrzeit", currentTimeStr.c_str());
Serial.println("##### MQTT-Nachrichtenversand - ERFOLGREICH #####");
Serial.println("");
Serial.println("");
// Setze die Zeit des letzten Sendens auf die aktuelle Zeit
lastSendTime = currentTime;
}
}
void sendDiscoveryMessage(const char* topic, const char* name, const char* stateTopic, const char* stateClass = "") {
// Erstelle die Entdeckungsnachricht im JSON-Format
String discoveryMessage = "{";
discoveryMessage += "\"name\":\"" + String(name) + "\",";
discoveryMessage += "\"state_topic\":\"" + String(stateTopic) + "\"";
// Füge den state_class-Parameter hinzu, wenn er übergeben wurde
if (strlen(stateClass) > 0) {
discoveryMessage += ",\"state_class\":\"" + String(stateClass) + "\"";
}
discoveryMessage += "}";
// Sende die Entdeckungsnachricht
client.publish(("homeassistant/sensor/bkw-steuerung/" + String(name) + "/config").c_str(), discoveryMessage.c_str(), true);
}
void sendMQTTAutoDiscovery() {
Serial.println("#### AutoDiscovery-Nachricht - Versand ####");
sendDiscoveryMessage("solar/BKW-Steuerung/motorposition", "Motorposition", "solar/bkw-steuerung/motorposition", "measurement");
sendDiscoveryMessage("solar/BKW-Steuerung/windsensor", "Windsensor", "solar/bkw-steuerung/windsensor");
sendDiscoveryMessage("solar/BKW-Steuerung/zeitzone", "Zeitzone", "solar/bkw-steuerung/zeitzone");
sendDiscoveryMessage("solar/BKW-Steuerung/positionsset", "Positionsset", "solar/bkw-steuerung/positionsset");
sendDiscoveryMessage("solar/BKW-Steuerung/uhrzeit", "Uhrzeit", "solar/bkw-steuerung/uhrzeit");
Serial.println("#### AutoDiscovery-Nachricht - Versand - ERFOLGREICH ####");
}
void callback(char* topic, byte* payload, unsigned int length) {
// Debugging-Ausgabe, um sicherzustellen, dass die callback-Funktion aufgerufen wird
Serial.println("Callback-Funktion wurde aufgerufen!");
Serial.print("Nachricht empfangen [");
Serial.print(topic);
Serial.print("] ");
String message = "";
for (int i = 0; i < length; i++) {
message += (char)payload[i]; // Füge jeden Byte des Payloads zum String hinzu
}
message.trim(); // Entferne führende und abschließende Leerzeichen
Serial.println(message);
if (strcmp(topic, "solar/bkw-steuerung/app") == 0) {
if (message.equals("Windsensor aktivieren")) {
// Führe Logik zum Bewegen des Motors in die Windschutzposition durch
// Hier können Sie die entsprechenden Stepper-Motorbefehle einfügen
stepper.moveTo(Windschutz);
stepper.runToPosition();
Serial.println("Motor fährt in die Windschutzposition.");
Warteposition_aktiv = true; // Setze die Warteposition auf aktiv
} else if (message.equals("Windsensor deaktivieren")) {
Warteposition_aktiv = false; // Setze die Warteposition auf inaktiv
Serial.println("Windsensor wurde deaktiviert.");
// Führen Sie hier den normalen Programmablauf fort
} else if (message.equals("position_setzen")) {
// Logik zum Setzen der Windschutzposition hier
// Hier könnte zusätzliche Logik zur Handhabung der Position gesetzt werden
Warteposition_aktiv = true; // Setze die Warteposition auf aktiv
} else if (message.equals("Startposition")) {
stepper.moveTo(Startposition);
stepper.runToPosition();
Serial.println("Motor fährt zur Startposition.");
Warteposition_aktiv = true; // Setze die Warteposition auf aktiv
} else if (message.equals("Endposition")) {
stepper.moveTo(Endposition);
stepper.runToPosition();
Serial.println("Motor fährt zur Endposition.");
Warteposition_aktiv = true; // Setze die Warteposition auf aktiv
} else if (message.equals("+1000")) {
int newPos = stepper.currentPosition() + 1000;
stepper.moveTo(newPos);
stepper.runToPosition();
Serial.println("Motor fährt um +1000 Positionen.");
Warteposition_aktiv = true; // Setze die Warteposition auf aktiv
} else if (message.equals("-1000")) {
int newPos = stepper.currentPosition() - 1000;
stepper.moveTo(newPos);
stepper.runToPosition();
Serial.println("Motor fährt um -1000 Positionen.");
Warteposition_aktiv = true; // Setze die Warteposition auf aktiv
} else if (message.equals("-17000")) {
int newPos = stepper.currentPosition() - 17000;
stepper.moveTo(newPos);
stepper.runToPosition();
Serial.println("Motor fährt um -17500 Positionen.");
Warteposition_aktiv = true; // Setze die Warteposition auf aktiv
} else if (message.equals("+24000")) {
int newPos = stepper.currentPosition() + 24000;
stepper.moveTo(newPos);
stepper.runToPosition();
Serial.println("Motor fährt um +24000 Positionen.");
Warteposition_aktiv = true; // Setze die Warteposition auf aktiv
}
// Aktualisiere den Status und die Zeit für den Windschutz außerhalb der Windsensor-Abfrage
WindschutzTimer = millis();
}
}