diff --git a/src/main.cpp b/src/main.cpp index a238ef4..5482c0a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,7 @@ #include #include #include -//#include -#include - +#include #define BUTTON_PIN D3 // GPIO-Pin verbunden mit Taster (D3 entspricht GPIO0) @@ -12,32 +10,24 @@ const uint32_t connectTimeoutMs = 10000; // WLAN Timeout // Globale Variablen unsigned long lastUpdateTime = 0; // Zeitstempel der letzten Aktion -unsigned long refreshRate = 2500; // Aktualisierungsrate in Millisekunden +unsigned long refreshRate = refreshrate_power; // Aktualisierungsrate in Millisekunden bool isModeChanged = false; // Zustand, ob eine Nachricht angezeigt wird int lastButtonState = HIGH; // Letzter Zustand des Buttons int currentButtonState; // Array für die Werte -String ip_netzbezug_values[5]; -String ip_erzeugung_values[5]; +String tasmota_smr_ip_values[6]; +String tasmota_plug_ip_values[6]; -String ip_netzbezug_values_old[5]; -String ip_erzeugung_values_old[5]; +String tasmota_smr_ip_values_old[6]; +String tasmota_plug_ip_values_old[6]; // Modus-Definitionen int currentMode = 0; -const char* modeNames[] = {"Leistung", "1.8.0", "1.8.1", "1.8.2", "2.8.0"}; +const char* modeNames[] = {"Leistung", "1.8.0", "1.8.1", "1.8.2", "2.8.0"}; // Nur für Seriellen Monitor - -String netzbezug; -String netzbezug_alt; -String erzeugung; -String erzeugung_alt; -String e_in_180; -String e_in_180_old; - // LCD initialisieren (16x2 Display) LiquidCrystal_I2C lcd(0x27, 16, 2); @@ -58,6 +48,12 @@ byte customChar_wlan[] = { }; void _lcd_display_text(int row = 0, const char* text = " ", const char* alignment = "left", bool returnToStart = false) { + + // Funktion die das Anzeigen von Text auf dem 1602 Display etwas erleichtert. + // Mit alignment kann die Ausrichtung des Texts angegeben werden. (alignment = "left", "center", "right") + // Mit returnToStart wird das Verhalten von zu langem Text festgelegt. Dieser Scrollt einmal durch und springt danch + // wieder an Position 1 (returnToStart = true) oder verbleibt nach dem durchscrollen am Ende (returnToStart = false) + int textLength = strlen(text); if (row < 0 || row > 1) { @@ -103,11 +99,11 @@ void _lcd_display_text(int row = 0, const char* text = " ", const } } -void extractTasmotaValues(const String& url, String values[5]) { +void extractTasmotaValues(const String& url, String values[6], int decimalPlaces = -1) { WiFiClient client; HTTPClient http; - for (int i = 0; i < 5; i++) { + for (int i = 0; i < 6; i++) { values[i] = "?"; // Standardwert, falls Tasmota Gerät nicht antwortet } @@ -119,10 +115,17 @@ void extractTasmotaValues(const String& url, String values[5]) { http.end(); // Array mit den Schlüsseln der gewünschten Werte - const String keys[5] = {json_prefix_Power, json_prefix_1_8_0, json_prefix_1_8_1, json_prefix_1_8_2, json_prefix_2_8_0}; + const String keys[6] = { + tasmota_plug_json_prefix_power, + tasmota_smr_json_prefix_power, + tasmota_smr_json_prefix_1_8_0, + tasmota_smr_json_prefix_1_8_1, + tasmota_smr_json_prefix_1_8_2, + tasmota_smr_json_prefix_2_8_0 + }; - // Werte initialisieren - for (int i = 0; i < 5; i++) { + // Werte extrahieren + for (int i = 0; i < 6; i++) { values[i] = "?"; // Standardwert, falls Key nicht gefunden wird int keyIndex = response.indexOf("\"" + keys[i] + "\":"); if (keyIndex != -1) { @@ -134,13 +137,23 @@ void extractTasmotaValues(const String& url, String values[5]) { if (valueEnd != -1) { values[i] = response.substring(valueStart, valueEnd); values[i].trim(); // Entfernt überflüssige Leerzeichen + + // Anzahl der Nachkommastellen begrenzen + if (decimalPlaces >= 0) { + int dotIndex = values[i].indexOf('.'); + if (dotIndex != -1) { + int truncateIndex = dotIndex + 1 + decimalPlaces; + if (truncateIndex < values[i].length()) { + values[i] = values[i].substring(0, truncateIndex); + } + } + } } } } } else { Serial.println("HTTP Fehler: " + String(httpResponseCode)); - - } + } http.end(); } else { Serial.println("Verbindung zur URL fehlgeschlagen: " + url); @@ -149,6 +162,8 @@ void extractTasmotaValues(const String& url, String values[5]) { + + void connectToWiFi() { Serial.println("WLAN Verbindungsaufbau zu: " + String(ssidList[current_ap])); Serial.println("Passwort: " + String(passwordList[current_ap])); @@ -199,38 +214,38 @@ void update_power_values() { lcd.setCursor(10, 0); lcd.print(" "); - lcd.setCursor(16 - (ip_netzbezug_values[0].length() + 1), 0); - lcd.print(ip_netzbezug_values[0]); + lcd.setCursor(16 - (tasmota_smr_ip_values[1].length() + 1), 0); + lcd.print(tasmota_smr_ip_values[1]); lcd.print("W"); lcd.setCursor(10, 1); lcd.print(" "); - lcd.setCursor(16 - (ip_erzeugung_values[0].length() + 1), 1); - lcd.print(ip_erzeugung_values[0]); + lcd.setCursor(16 - (tasmota_plug_ip_values[0].length() + 1), 1); + lcd.print(tasmota_plug_ip_values[0]); lcd.print("W"); - ip_netzbezug_values_old[0] = ip_netzbezug_values[0]; - ip_erzeugung_values_old[0] = ip_erzeugung_values[0]; + tasmota_smr_ip_values_old[1] = tasmota_smr_ip_values[1]; + tasmota_plug_ip_values_old[0] = tasmota_plug_ip_values[0]; } void update_180_values() { - _lcd_display_text(1, (ip_netzbezug_values[1] + "kWh").c_str(), "center"); - ip_netzbezug_values_old[1] = ip_netzbezug_values[1]; + _lcd_display_text(1, (tasmota_smr_ip_values[2] + "kWh").c_str(), "center"); + tasmota_smr_ip_values_old[2] = tasmota_smr_ip_values[2]; } void update_181_values() { - _lcd_display_text(1, (ip_netzbezug_values[2] + "kWh").c_str(), "center"); - ip_netzbezug_values_old[2] = ip_netzbezug_values[2]; + _lcd_display_text(1, (tasmota_smr_ip_values[3] + "kWh").c_str(), "center"); + tasmota_smr_ip_values_old[3] = tasmota_smr_ip_values[3]; } void update_182_values() { - _lcd_display_text(1, (ip_netzbezug_values[3] + "kWh").c_str(), "center"); - ip_netzbezug_values_old[3] = ip_netzbezug_values[3]; + _lcd_display_text(1, (tasmota_smr_ip_values[4] + "kWh").c_str(), "center"); + tasmota_smr_ip_values_old[4] = tasmota_smr_ip_values[4]; } void update_280_values() { - _lcd_display_text(1, (ip_netzbezug_values[4] + "kWh").c_str(), "center"); - ip_netzbezug_values_old[4] = ip_netzbezug_values[4]; + _lcd_display_text(1, (tasmota_smr_ip_values[5] + "kWh").c_str(), "center"); + tasmota_smr_ip_values_old[5] = tasmota_smr_ip_values[5]; } void handleButtonPress() { @@ -247,9 +262,9 @@ void handleButtonPress() { Serial.println(modeNames[currentMode]); if (currentMode == 0) { - refreshRate = 2500; + refreshRate = refreshrate_power; } else { - refreshRate = 15000; + refreshRate = refreshrate_consumption; } Serial.print("Aktualisierungsrate: "); @@ -298,10 +313,15 @@ void loop() { if (millis() - lastUpdateTime >= refreshRate) { lastUpdateTime = millis(); - extractTasmotaValues("http://" + ip_netzbezug + "/cm?cmnd=Status%208", ip_netzbezug_values); + extractTasmotaValues("http://" + tasmota_smr_ip + "/cm?cmnd=Status%208", tasmota_smr_ip_values, tasmota_decimalplaces); if (currentMode == 0) { - extractTasmotaValues("http://" + ip_erzeugung + "/cm?cmnd=Status%208", ip_erzeugung_values); + if (isModeChanged == true) { + _lcd_display_text(0, "Netzbezug:", "left"); + _lcd_display_text(1, "Erzeugung:", "left"); + update_power_values(); + } + extractTasmotaValues("http://" + tasmota_plug_ip + "/cm?cmnd=Status%208", tasmota_plug_ip_values, tasmota_decimalplaces); } } } @@ -309,7 +329,7 @@ void loop() { switch (currentMode) { case 0: - if (ip_netzbezug_values[0] != ip_netzbezug_values_old[0] || isModeChanged == true) { + if (tasmota_smr_ip_values[1] != tasmota_smr_ip_values_old[1] || isModeChanged == true) { isModeChanged = false; _lcd_display_text(0, "Netzbezug:", "left"); _lcd_display_text(1, "Erzeugung:", "left"); @@ -318,28 +338,28 @@ void loop() { } break; case 1: - if (ip_netzbezug_values[1] != ip_netzbezug_values_old[1] || isModeChanged == true) { + if (tasmota_smr_ip_values[2] != tasmota_smr_ip_values_old[2] || isModeChanged == true) { isModeChanged = false; _lcd_display_text(0, "1.8.0 (HT+NT):", "center"); update_180_values(); } break; case 2: - if (ip_netzbezug_values[2] != ip_netzbezug_values_old[2] || isModeChanged == true) { + if (tasmota_smr_ip_values[3] != tasmota_smr_ip_values_old[3] || isModeChanged == true) { isModeChanged = false; _lcd_display_text(0, "1.8.1 (HT):", "center"); update_181_values(); } break; case 3: - if (ip_netzbezug_values[3] != ip_netzbezug_values_old[3] || isModeChanged == true) { + if (tasmota_smr_ip_values[4] != tasmota_smr_ip_values_old[4] || isModeChanged == true) { isModeChanged = false; _lcd_display_text(0, "1.8.2 (NT):", "center"); update_182_values(); } break; case 4: - if (ip_netzbezug_values[4] != ip_netzbezug_values_old[4] || isModeChanged == true) { + if (tasmota_smr_ip_values[5] != tasmota_smr_ip_values_old[5] || isModeChanged == true) { isModeChanged = false; _lcd_display_text(0, "2.8.0 (Einsp.):", "center"); update_280_values(); diff --git a/src/settings.h b/src/settings.h index e6a87af..cc315c4 100644 --- a/src/settings.h +++ b/src/settings.h @@ -1,4 +1,3 @@ -#include #ifndef SETTINGS_H #define SETTINGS_H @@ -21,21 +20,31 @@ const char* passwordList[] = { // Weitere Passwörter hier hinzufügen }; -// ####################### Tasmota IPs ######################## +// ################## Tasmota Einstellungen ################### -String ip_netzbezug = "192.168.178.236"; -String ip_erzeugung = "192.168.178.237"; +// Zwischenstecker am Balkonkraftwerk +String tasmota_plug_ip = "192.168.178.222"; +String tasmota_plug_json_prefix_power = "Power"; -// ################ SmartMeterReader Script ################### -// aus dem SmartMeterReader Script -// Beispiel: 1,1-0:1.8.0*255(@1,Verbrauch,kWh,E_in_180,3 -// json_prefix_1_8_0 = E_in_180 +// SmartMeterReader +String tasmota_smr_ip = "192.168.178.236"; +String tasmota_smr_json_prefix_power = "Power"; +String tasmota_smr_json_prefix_1_8_0 = "E_in_180"; +String tasmota_smr_json_prefix_1_8_1 = "E_in_181"; +String tasmota_smr_json_prefix_1_8_2 = "E_in_182"; +String tasmota_smr_json_prefix_2_8_0 = "E_in_280"; -String json_prefix_Power = "Power"; -String json_prefix_1_8_0 = "E_in_180"; -String json_prefix_1_8_1 = "E_in_181"; -String json_prefix_1_8_2 = "E_in_182"; -String json_prefix_2_8_0 = "E_in_280"; +// Anzahl Nachkommastellen bei den ausgelesenen Tasmota Werten +// -1 = Alle / 0 = Keine / 2 = 2 Nachkommastellen +int tasmota_decimalplaces = 2; + +// ################# Allgemeine Einstellungen ################# + +// Aktualisierungsrate im Bildschirm aktuelle Leistung (in Millisekunden) +unsigned long refreshrate_power = 2500; + +// Aktualisierungsrate in den Bildschirmen der Verbrauchsdaten (in Millisekunden) +unsigned long refreshrate_consumption = 15000; // ############################################################