void handleRoot() { String html = ""; html += ""; html += ""; html += "powerMC (ESP32) "+String(FIRMWARE_VERSION)+""; html += "

powerMC (ESP32) "+String(FIRMWARE_VERSION)+"

"; html += "
"; html += "

JSON Daten


"; html += "

Start demo mode charge and discharge

"; html += "

Start demo mode charge to max

"; html += "

Start demo mode discharge to zero


"; html += "

Reset ESP32

"; html += "

Reset Wifi settings


"; html += "

Firmware update


"; html += "

Config

"; html += "
 "; html += "

Busvoltage: 0 V

"; html += "

Shuntvoltage: 0 V

"; html += "

Strom: 0 A

"; html += "

Leistung: 0 W

"; html += "

Energie: 0 Wh

"; html += "

Temp: 0 °C

"; html += "

Humidity: 0 %

"; html += "

Shunt max voltage drop: "+String(globalConfigData.shunt_voltage_drop,0)+" mV

"; html += "

Shunt max current: "+String(globalConfigData.shunt_max_current,0)+" A

"; html += "

Current factor: "+String(globalConfigData.current_fact/100,2)+" (div. by 100)

"; html += "

Max capacity: "+String(globalConfigData.max_capacity,0)+" Wh

"; html += "

Ina226 refresh period: "+String(globalConfigData.time_ina226_refresh,0)+" s

"; html += "

Error code: 0

"; html += "
"; html += ""; server.send(200, cs_textHtml, html); } void handleJson() { // JSON-Daten aus globalen Variablen erstellen DynamicJsonDocument doc(200); doc[cs_busVoltageID] = globalBusVoltage; doc[cs_shuntVoltageID] = globalShuntVoltage; doc[cs_currentID] = globalCurrent; doc[cs_powerID] = globalPower; doc[cs_energyID] = globalEnergy; doc[cs_tempID] = globalTemp; doc[cs_humidityID] = globalHumidity; doc[cs_errorCodeID] = globalErrorCode; doc["shuntValue"] = globalShuntValue; doc["ina226Status"] = ina226Status; doc["ina226ShuntValue"] = ina226.getShunt(); doc["ina226AlertFlag"] = ina226.getAlertFlag(); doc["ina226AlertLimit"] = ina226.getAlertLimit(); doc["ina226CurrentLSB"] = ina226.getCurrentLSB(); String jsonData; serializeJson(doc, jsonData); server.send(200, cs_applicationJson, jsonData); } void handleConfig() { String html = ""; html += "powerMC (ESP32) "+String(FIRMWARE_VERSION)+" - configuration"; html += ""; html += ""; html += ""; html += "

powerMC (ESP32) "+String(FIRMWARE_VERSION)+" - configuration

"; html += "

Main


"; html += "
"; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += "
 "; html += "" + String(globalConfigData.max_capacity, 0) + "Wh
 "; html += "" + String(globalConfigData.shunt_voltage_drop, 0) + "mV
 "; html += "" + String(globalConfigData.shunt_max_current, 0) + "A
 "; html += "" + String(globalConfigData.temp_min, 0) + "°C
 "; html += "" + String(globalConfigData.temp_max, 0) + "°C
 "; html += "" + String(globalConfigData.humi_min, 0) + "%
 "; html += "" + String(globalConfigData.humi_max, 0) + "%
 "; html += "" + String(globalConfigData.current_min, 0) + "A
 "; html += "" + String(globalConfigData.current_max, 0) + "A
 "; html += "" + String(globalConfigData.current_fact/100,2) + "(div. by 100)
 "; html += "" + String(globalConfigData.time_ina226_refresh,0) + "sek.

"; html += "
"; html += ""; html += "
"; html += ""; server.send(200, cs_textHtml, html); } void handleSaveConfig() { if (server.hasArg("plain")) { Serial.println("Received new config data:"); Serial.println(server.arg("plain")); // JSON-Payload analysieren DynamicJsonDocument jsonDoc(1024); deserializeJson(jsonDoc, server.arg("plain")); // Parameter überprüfen und in die Konfiguration übertragen if (jsonDoc.containsKey("temp_min")) { float temp_min = jsonDoc["temp_min"]; // Hier prüfen und in die globale Konfiguration übertragen globalConfigData.temp_min = temp_min; } if (jsonDoc.containsKey("temp_max")) { float temp_max = jsonDoc["temp_max"]; // Hier prüfen und in die globale Konfiguration übertragen globalConfigData.temp_max = temp_max; } if (jsonDoc.containsKey("humi_min")) { float humi_min = jsonDoc["humi_min"]; // Hier prüfen und in die globale Konfiguration übertragen globalConfigData.humi_min = humi_min; } if (jsonDoc.containsKey("humi_max")) { float humi_max = jsonDoc["humi_max"]; // Hier prüfen und in die globale Konfiguration übertragen globalConfigData.humi_max = humi_max; } if (jsonDoc.containsKey("current_min")) { float current_min = jsonDoc["current_min"]; // Hier prüfen und in die globale Konfiguration übertragen globalConfigData.current_min = current_min; } if (jsonDoc.containsKey("current_max")) { float current_max = jsonDoc["current_max"]; // Hier prüfen und in die globale Konfiguration übertragen globalConfigData.current_max = current_max; } if (jsonDoc.containsKey("shunt_voltage_drop")) { float shunt_voltage_drop = jsonDoc["shunt_voltage_drop"]; // Hier prüfen und in die globale Konfiguration übertragen globalConfigData.shunt_voltage_drop = shunt_voltage_drop; } if (jsonDoc.containsKey("shunt_max_current")) { float shunt_max_current = jsonDoc["shunt_max_current"]; // Hier prüfen und in die globale Konfiguration übertragen globalConfigData.shunt_max_current = shunt_max_current; } if (jsonDoc.containsKey("max_capacity")) { float max_capacity = jsonDoc["max_capacity"]; // Hier prüfen und in die globale Konfiguration übertragen globalConfigData.max_capacity = max_capacity; } if (jsonDoc.containsKey("time_ina226_refresh")) { float time_ina226_refresh = jsonDoc["time_ina226_refresh"]; // Hier prüfen und in die globale Konfiguration übertragen globalConfigData.time_ina226_refresh = time_ina226_refresh; } if (jsonDoc.containsKey("current_fact")) { float current_fact = jsonDoc["current_fact"]; // Hier prüfen und in die globale Konfiguration übertragen globalConfigData.current_fact = current_fact; } writeConfigToEEPROM(); if (ina226.reset()) { Serial.println("Ina226 reset"); configureIna226(); checkError(); } else { Serial.println("Ina226 error: can't reset and reconfigure."); } // Schicke eine Bestätigung zurück server.send(200, "application/json", "{\"message\": \"ok\"}"); } else { // Ungültige Anfrage server.send(400, "text/plain", "Invalid request"); } } void handleDemoMode1() { demoMode1 = true; demoMode2 = false; demoMode3 = false; globalBusVoltage = 25.6; globalEnergy = globalConfigData.max_capacity / 2; handleRoot(); } void handleDemoMode2() { demoMode1 = false; demoMode2 = true; demoMode3 = false; globalBusVoltage = 25.6; globalEnergy = globalConfigData.max_capacity * 0.97; handleRoot(); } void handleDemoMode3() { demoMode1 = false; demoMode2 = false; demoMode3 = true; globalBusVoltage = 25.6; globalEnergy = globalConfigData.max_capacity * 0.03; handleRoot(); } void handleResetESP() { String message = "powerMC (ESP32) "+String(FIRMWARE_VERSION)+" - reset" "" "" "" "

powerMC (ESP32) "+String(FIRMWARE_VERSION)+" - reset

" "Rebooting...
" ""; server.send(200, cs_textHtml, message); delay(5000); // manual reset after restart is required ESP.restart(); } void handleResetWifi() { String message = "powerMC (ESP32) "+String(FIRMWARE_VERSION)+" - reset WiFi configuration" "" "" "" "

owerMC (ESP32) "+String(FIRMWARE_VERSION)+" - reset WiFi configuration

" "Reset WifiManager config, rebooting...
" ""; server.send(200, cs_textHtml, message); // Erase WiFi Credentials, enable, compile, flash, disable and reflash. wifiManager.resetSettings(); delay(5000); // manual reset after restart is required ESP.restart(); } void handleUpdateFirmware() { String message = "powerMC (ESP32) " + String(FIRMWARE_VERSION) + " - firmware update" "" "" "

powerMC (ESP32) " + String(FIRMWARE_VERSION) + " - firmware update

" "

Main


" "" ""; server.send(200, cs_textHtml, message); } void handleUpdateFirmwareAction() { if (fwUpdate_isRunning) { Serial.println("Firmware-Update is running..."); if (updateStatus == "") { updateStatus = "Firmware-Update is running...
"; } server.send(200, cs_textHtml, updateStatus); } else { String message = "powerMC (ESP32) " + String(FIRMWARE_VERSION) + " - firmware update" "" "" "" "

powerMC (ESP32) " + String(FIRMWARE_VERSION) + " - firmware update


" "

Updating...

" "
" ""; server.send(200, cs_textHtml, message); disableWatchdog(); updateStatus = ""; Serial.print(cs_startingFirmwareUpdate); ESPhttpUpdate.rebootOnUpdate(false); t_httpUpdate_return ret = ESPhttpUpdate.update(String(FIRMWARE_UPDATE_URL)); fwUpdate_isRunning = true; Serial.println(cs_finish); switch (ret) { case HTTP_UPDATE_FAILED: Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); updateStatus = "Firmware-Update failed.
"; updateStatus += "Last error: "+String(ESPhttpUpdate.getLastError())+"
"; updateStatus += "Last error message: "+ESPhttpUpdate.getLastErrorString()+"
"; fwUpdate_isRunning = false; enableWatchdog(); break; case HTTP_UPDATE_NO_UPDATES: Serial.println(cs_noUpdatesAvailable); updateStatus = "No Updates available.
"; fwUpdate_isRunning = false; enableWatchdog(); break; case HTTP_UPDATE_OK: Serial.println(cs_fwUpdSuccess); updateStatus = "Firmware update successful, resetting in a few seconds.
"; fwUpdate_isRunning = false; break; default: // other Serial.println(cs_unknownStatus); updateStatus = "Unknown status.
"; fwUpdate_isRunning = false; } } } void handleReadUpdateFirmwareStatus() { if (fwUpdate_isRunning) { Serial.println(cs_fwUpdRunning); if (updateStatus == "") { updateStatus = "Firmware-Update is running...
"; } } server.send(200, cs_textHtml, updateStatus); } void handleCSS() { // "" String customCSS = R"( body { font-family: Arial, sans-serif; margin: 20px; } h1 { color: #333; } p { margin: 5px 0; } a { color: #0066cc; text-decoration: none; } #busVoltage, #current, #power, #energy, #temp, #humidity, #errorCode { margin-bottom: 10px; } span { font-weight: bold; } td { vertical-align: top; padding: 10px; } .success-notification { position: fixed; bottom: 0; left: 0; width: 100%; background-color: #4CAF50; color: #fff; text-align: center; padding: 10px; } .error-notification { position: fixed; bottom: 0; left: 0; width: 100%; background-color: #f44336; color: #fff; text-align: center; padding: 10px; } button { font-family: Arial, sans-serif; background-color: #d3d3d3; color: #000; padding: 10px 20px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; } button:active { background-color: #a9a9a9; /* Dunkleres Grau beim Drücken */ } )"; server.send(200, cs_textCSS, customCSS); }