From 05978a01f85761aac6f0e4645677c146d644aace Mon Sep 17 00:00:00 2001 From: DanielR92 Date: Sat, 11 May 2024 23:12:42 +0200 Subject: [PATCH 01/14] some notes for tibber problems & format zeroexport --- src/platformio.ini | 46 +++++++----- src/plugins/zeroExport/powermeter.h | 7 +- src/plugins/zeroExport/zeroExport.h | 105 ++++++++++------------------ 3 files changed, 74 insertions(+), 84 deletions(-) diff --git a/src/platformio.ini b/src/platformio.ini index 8d36207c..763ac041 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -40,7 +40,6 @@ build_flags = build_unflags = -std=gnu++11 - [env:esp8266-minimal] platform = espressif8266 board = esp12e @@ -148,7 +147,7 @@ monitor_filters = esp8266_exception_decoder [env:esp32-wroom32-minimal] -platform = espressif32@6.5.0 +platform = espressif32@6.6.0 board = lolin_d32 build_flags = ${env.build_flags} -DUSE_HSPI_FOR_EPD @@ -156,7 +155,7 @@ monitor_filters = esp32_exception_decoder [env:esp32-wroom32] -platform = espressif32@6.5.0 +platform = espressif32@6.6.0 board = lolin_d32 build_flags = ${env:esp32-wroom32-minimal.build_flags} -DENABLE_MQTT @@ -167,7 +166,7 @@ monitor_filters = esp32_exception_decoder [env:esp32-wroom32-de] -platform = espressif32@6.5.0 +platform = espressif32@6.6.0 board = lolin_d32 build_flags = ${env:esp32-wroom32.build_flags} -DLANG_DE @@ -175,7 +174,7 @@ monitor_filters = esp32_exception_decoder [env:esp32-wroom32-prometheus] -platform = espressif32@6.5.0 +platform = espressif32@6.6.0 board = lolin_d32 build_flags = ${env:esp32-wroom32.build_flags} -DENABLE_PROMETHEUS_EP @@ -183,7 +182,7 @@ monitor_filters = esp32_exception_decoder [env:esp32-wroom32-prometheus-de] -platform = espressif32@6.5.0 +platform = espressif32@6.6.0 board = lolin_d32 build_flags = ${env:esp32-wroom32-prometheus.build_flags} -DLANG_DE @@ -219,7 +218,7 @@ monitor_filters = esp32_exception_decoder [env:esp32-s2-mini] -platform = espressif32@6.5.0 +platform = espressif32@6.6.0 board = lolin_s2_mini build_flags = ${env.build_flags} -DUSE_HSPI_FOR_EPD @@ -242,7 +241,7 @@ monitor_filters = esp32_exception_decoder [env:esp32-s2-mini-de] -platform = espressif32@6.5.0 +platform = espressif32@6.6.0 board = lolin_s2_mini build_flags = ${env:esp32-s2-mini.build_flags} -DLANG_DE @@ -250,7 +249,7 @@ monitor_filters = esp32_exception_decoder [env:esp32-c3-mini] -platform = espressif32@6.5.0 +platform = espressif32@6.6.0 board = lolin_c3_mini build_flags = ${env.build_flags} -DUSE_HSPI_FOR_EPD @@ -273,7 +272,7 @@ monitor_filters = esp32_exception_decoder [env:esp32-c3-mini-de] -platform = espressif32@6.5.0 +platform = espressif32@6.6.0 board = lolin_c3_mini build_flags = ${env:esp32-c3-mini.build_flags} -DLANG_DE @@ -281,7 +280,7 @@ monitor_filters = esp32_exception_decoder [env:opendtufusion-minimal] -platform = espressif32@6.5.0 +platform = espressif32@6.6.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin build_flags = ${env.build_flags} @@ -306,19 +305,18 @@ monitor_filters = esp32_exception_decoder, colorize [env:opendtufusion] -platform = espressif32@6.5.0 +platform = espressif32@6.6.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin build_flags = ${env:opendtufusion-minimal.build_flags} -DENABLE_MQTT -DPLUGIN_DISPLAY -DENABLE_HISTORY - -DPLUGIN_ZEROEXPORT monitor_filters = esp32_exception_decoder, colorize [env:opendtufusion-de] -platform = espressif32@6.5.0 +platform = espressif32@6.6.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin build_flags = ${env:opendtufusion.build_flags} @@ -326,8 +324,24 @@ build_flags = ${env:opendtufusion.build_flags} monitor_filters = esp32_exception_decoder, colorize +[env:opendtufusion-zero_export] +platform = espressif32@6.6.0 +board = esp32-s3-devkitc-1 +upload_protocol = esp-builtin +build_flags = ${env:opendtufusion.build_flags} + -DPLUGIN_ZEROEXPORT +monitor_filters = + esp32_exception_decoder, colorize + +[env:opendtufusion-zero_export-de] +platform = espressif32@6.6.0 +board = esp32-s3-devkitc-1 +upload_protocol = esp-builtin +build_flags = ${env:opendtufusion-zero_export.build_flags} + -DLANG_DE + [env:opendtufusion-ethernet] -platform = espressif32@6.5.0 +platform = espressif32@6.6.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin build_flags = ${env:opendtufusion-minimal.build_flags} @@ -347,7 +361,7 @@ monitor_filters = esp32_exception_decoder, colorize [env:opendtufusion-ethernet-de] -platform = espressif32@6.5.0 +platform = espressif32@6.6.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin build_flags = ${env:opendtufusion-ethernet.build_flags} diff --git a/src/plugins/zeroExport/powermeter.h b/src/plugins/zeroExport/powermeter.h index f6053d8c..780005bc 100644 --- a/src/plugins/zeroExport/powermeter.h +++ b/src/plugins/zeroExport/powermeter.h @@ -91,6 +91,11 @@ class powermeter { break; #endif #if defined(ZEROEXPORT_POWERMETER_TIBBER) + /* Anscheinend nutzt bei mir Tibber auch diese Freq. + 862.75 MHz - keine Verbindung + 863.00 MHz - geht (standard) jedoch hat Tibber dann Probleme... => 4 & 5 Balken + 863.25 MHz - geht (ohne Tibber Probleme) => 3 & 4 Balken + */ case zeroExportPowermeterType_t::Tibber: result = getPowermeterWattsTibber(*mLog, group, &power); mPreviousTsp += 2000; // Zusätzliche Pause @@ -247,7 +252,7 @@ class powermeter { PubMqttType *mMqtt = nullptr; JsonObject *mLog; - unsigned long mPreviousTsp = 0; + unsigned long mPreviousTsp = millis(); float mPowermeterBuffer[ZEROEXPORT_MAX_GROUPS][5] = {0}; short mPowermeterBufferPos[ZEROEXPORT_MAX_GROUPS] = {0}; diff --git a/src/plugins/zeroExport/zeroExport.h b/src/plugins/zeroExport/zeroExport.h index d0c215ff..32091680 100644 --- a/src/plugins/zeroExport/zeroExport.h +++ b/src/plugins/zeroExport/zeroExport.h @@ -637,40 +637,28 @@ class ZeroExport { if (obj["path"] == "ctrl" && obj["cmd"] == "zero") { int8_t topicGroup = getGroupFromTopic(topic.c_str()); - if (topicGroup != -1) - mLog["g"] = topicGroup; int8_t topicInverter = getInverterFromTopic(topic.c_str()); - if (topicInverter == -1) - mLog["i"] = topicInverter; + + if (topicGroup != -1) mLog["g"] = topicGroup; + if (topicInverter == -1) mLog["i"] = topicInverter; + + mLog["k"] = topic; // "topic":"ctrl/zero/enabled" - if (topic.indexOf("ctrl/zero/enabled") != -1) { - mCfg->enabled = (bool)obj["val"]; - mLog["k"] = "ctrl/zero/enabled"; - mLog["v"] = mCfg->enabled; - } + if (topic.indexOf("ctrl/zero/enabled") != -1) mCfg->enabled = mLog["v"] = (bool)obj["val"]; // "topic":"ctrl/zero/sleep" - if (topic.indexOf("ctrl/zero/sleep") != -1) { - mCfg->sleep = (bool)obj["val"]; - mLog["k"] = "ctrl/zero/sleep"; - mLog["v"] = mCfg->sleep; - } + else if (topic.indexOf("ctrl/zero/sleep") != -1) mCfg->sleep = mLog["v"] = (bool)obj["val"]; + + else if ((topicGroup >= 0) && (topicGroup < ZEROEXPORT_MAX_GROUPS)) + { + String stopicGroup = String(topicGroup); - if ((topicGroup >= 0) && (topicGroup < ZEROEXPORT_MAX_GROUPS)) { // "topic":"ctrl/zero/groups/+/enabled" - if (topic.indexOf("ctrl/zero/groups/" + String(topicGroup) + "/enabled") != -1) { - mCfg->groups[topicGroup].enabled = (bool)obj["val"]; - mLog["k"] = "ctrl/zero/groups/" + String(topicGroup) + "/enabled"; - mLog["v"] = mCfg->groups[topicGroup].enabled; - } + if (topic.endsWith("/enabled")) mCfg->groups[topicGroup].enabled = mLog["v"] = (bool)obj["val"]; // "topic":"ctrl/zero/groups/+/sleep" - if (topic.indexOf("ctrl/zero/groups/" + String(topicGroup) + "/sleep") != -1) { - mCfg->groups[topicGroup].sleep = (bool)obj["val"]; - mLog["k"] = "ctrl/zero/groups/" + String(topicGroup) + "/sleep"; - mLog["v"] = mCfg->groups[topicGroup].sleep; - } + else if (topic.endsWith("/sleep")) mCfg->groups[topicGroup].sleep = mLog["v"] = (bool)obj["val"]; // Auf Eis gelegt, dafür 2 Gruppen mehr // 0.8.103008.2 @@ -695,55 +683,37 @@ class ZeroExport { // } // "topic":"ctrl/zero/groups/+/battery/switch" - if (topic.indexOf("ctrl/zero/groups/" + String(topicGroup) + "/battery/switch") != -1) { - mCfg->groups[topicGroup].battSwitch = (bool)obj["val"]; - mLog["k"] = "ctrl/zero/groups/" + String(topicGroup) + "/battery/switch"; - mLog["v"] = mCfg->groups[topicGroup].battSwitch; - } + else if (topic.endsWith("/battery/switch")) mCfg->groups[topicGroup].battSwitch = mLog["v"] = (bool)obj["val"]; - // "topic":"ctrl/zero/groups/+/advanced/setPoint" - if (topic.indexOf("ctrl/zero/groups/" + String(topicGroup) + "/advanced/setPoint") != -1) { - mCfg->groups[topicGroup].setPoint = (int16_t)obj["val"]; - mLog["k"] = "ctrl/zero/groups/" + String(topicGroup) + "/advanced/setPoint"; - mLog["v"] = mCfg->groups[topicGroup].setPoint; - } + else if (topic.indexOf("/advanced/") != -1) + { + // "topic":"ctrl/zero/groups/+/advanced/setPoint" + if (topic.endsWith("/setPoint")) mCfg->groups[topicGroup].setPoint = mLog["v"] = (int16_t)obj["val"]; - // "topic":"ctrl/zero/groups/+/advanced/powerTolerance" - if (topic.indexOf("ctrl/zero/groups/" + String(topicGroup) + "/advanced/powerTolerance") != -1) { - mCfg->groups[topicGroup].powerTolerance = (uint8_t)obj["val"]; - mLog["k"] = "ctrl/zero/groups/" + String(topicGroup) + "/advanced/powerTolerance"; - mLog["v"] = mCfg->groups[topicGroup].powerTolerance; - } + // "topic":"ctrl/zero/groups/+/advanced/powerTolerance" + else if (topic.endsWith("/powerTolerance")) mCfg->groups[topicGroup].powerTolerance = mLog["v"] = (uint8_t)obj["val"]; - // "topic":"ctrl/zero/groups/+/advanced/powerMax" - if (topic.indexOf("ctrl/zero/groups/" + String(topicGroup) + "/advanced/powerMax") != -1) { - mCfg->groups[topicGroup].powerMax = (uint16_t)obj["val"]; - mLog["k"] = "ctrl/zero/groups/" + String(topicGroup) + "/advanced/powerMax"; - mLog["v"] = mCfg->groups[topicGroup].powerMax; + // "topic":"ctrl/zero/groups/+/advanced/powerMax" + else if (topic.endsWith("/powerMax")) mCfg->groups[topicGroup].powerMax = mLog["v"] = (uint16_t)obj["val"]; } + else if (topic.indexOf("/inverter/") != -1) + { + if ((topicInverter >= 0) && (topicInverter < ZEROEXPORT_GROUP_MAX_INVERTERS)) + { + // "topic":"ctrl/zero/groups/+/inverter/+/enabled" + if (topic.endsWith("/enabled")) mCfg->groups[topicGroup].inverters[topicInverter].enabled = mLog["v"] = (bool)obj["val"]; - if ((topicInverter >= 0) && (topicInverter < ZEROEXPORT_GROUP_MAX_INVERTERS)) { - // "topic":"ctrl/zero/groups/+/inverter/+/enabled" - if (topic.indexOf("ctrl/zero/groups/" + String(topicGroup) + "/inverter/" + String(topicInverter) + "/enabled") != -1) { - mCfg->groups[topicGroup].inverters[topicInverter].enabled = (bool)obj["val"]; - mLog["k"] = "ctrl/zero/groups/" + String(topicGroup) + "/inverter/" + String(topicInverter) + "/enabled"; - mLog["v"] = mCfg->groups[topicGroup].inverters[topicInverter].enabled; - } - - // "topic":"ctrl/zero/groups/+/inverter/+/powerMin" - if (topic.indexOf("ctrl/zero/groups/" + String(topicGroup) + "/inverter/" + String(topicInverter) + "/powerMin") != -1) { - mCfg->groups[topicGroup].inverters[topicInverter].powerMin = (uint16_t)obj["val"]; - mLog["k"] = "ctrl/zero/groups/" + String(topicGroup) + "/inverter/" + String(topicInverter) + "/powerMin"; - mLog["v"] = mCfg->groups[topicGroup].inverters[topicInverter].powerMin; - } - - // "topic":"ctrl/zero/groups/+/inverter/+/powerMax" - if (topic.indexOf("ctrl/zero/groups/" + String(topicGroup) + "/inverter/" + String(topicInverter) + "/powerMax") != -1) { - mCfg->groups[topicGroup].inverters[topicInverter].powerMax = (uint16_t)obj["val"]; - mLog["k"] = "ctrl/zero/groups/" + String(topicGroup) + "/inverter/" + String(topicInverter) + "/powerMax"; - mLog["v"] = mCfg->groups[topicGroup].inverters[topicInverter].powerMax; + // "topic":"ctrl/zero/groups/+/inverter/+/powerMin" + else if (topic.endsWith("/powerMin")) mCfg->groups[topicGroup].inverters[topicInverter].powerMin = mLog["v"] = (uint16_t)obj["val"]; + + // "topic":"ctrl/zero/groups/+/inverter/+/powerMax" + else if (topic.endsWith("/powerMax")) mCfg->groups[topicGroup].inverters[topicInverter].powerMax = mLog["v"] = (uint16_t)obj["val"]; + else mLog["k"] = "error"; } } + else { + mLog["k"] = "error"; + } } } @@ -791,6 +761,7 @@ class ZeroExport { while (*pGroupSection != '/' && digitsCopied < 2) strGroup[digitsCopied++] = *pGroupSection++; strGroup[digitsCopied] = '\0'; int8_t group = atoi(strGroup); + mLog["getGroupFromTopic"] = group; return group; } From d1535ea18841785ec9e2e98c59ab59059ea75c2a Mon Sep 17 00:00:00 2001 From: DanielR92 Date: Sun, 12 May 2024 14:00:55 +0200 Subject: [PATCH 02/14] changes tibber things --- src/plugins/zeroExport/powermeter.h | 12 +----------- src/web/RestApi.h | 12 ++++++++++-- src/web/html/setup.html | 2 +- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/plugins/zeroExport/powermeter.h b/src/plugins/zeroExport/powermeter.h index 780005bc..3457aef0 100644 --- a/src/plugins/zeroExport/powermeter.h +++ b/src/plugins/zeroExport/powermeter.h @@ -14,7 +14,6 @@ #include "config/settings.h" #if defined(ZEROEXPORT_POWERMETER_TIBBER) -#include #include #include @@ -493,16 +492,7 @@ class powermeter { logObj["mod"] = "getPowermeterWattsTibber"; - String auth; - if (strlen(mCfg->groups[group].pm_user) > 0 && strlen(mCfg->groups[group].pm_pass) > 0) { - auth = base64::encode(String(mCfg->groups[group].pm_user) + String(":") + String(mCfg->groups[group].pm_pass)); - snprintf(mCfg->groups[group].pm_user, ZEROEXPORT_GROUP_MAX_LEN_PM_USER, "%s", DEF_ZEXPORT); - snprintf(mCfg->groups[group].pm_pass, ZEROEXPORT_GROUP_MAX_LEN_PM_PASS, "%s", auth.c_str()); - //@TODO:mApp->saveSettings(false); - } else { - auth = mCfg->groups[group].pm_pass; - } - + String auth = mCfg->groups[group].pm_pass; String url = String("http://") + mCfg->groups[group].pm_url + String("/") + String(mCfg->groups[group].pm_jsonPath); setHeader(&http); diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 21123be6..602c8843 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -20,6 +20,7 @@ #include "ESPAsyncWebServer.h" #include "plugins/history.h" +#include #if defined(F) && defined(ESP32) #undef F @@ -1161,8 +1162,15 @@ class RestApi { mConfig->plugin.zeroExport.groups[group].pm_type = jsonIn[F("pm_type")]; snprintf(mConfig->plugin.zeroExport.groups[group].pm_url, ZEROEXPORT_GROUP_MAX_LEN_PM_URL, "%s", jsonIn[F("pm_url")].as()); snprintf(mConfig->plugin.zeroExport.groups[group].pm_jsonPath, ZEROEXPORT_GROUP_MAX_LEN_PM_JSONPATH, "%s", jsonIn[F("pm_jsonPath")].as()); - snprintf(mConfig->plugin.zeroExport.groups[group].pm_user, ZEROEXPORT_GROUP_MAX_LEN_PM_USER, "%s", jsonIn[F("pm_user")].as()); - snprintf(mConfig->plugin.zeroExport.groups[group].pm_pass, ZEROEXPORT_GROUP_MAX_LEN_PM_PASS, "%s", jsonIn[F("pm_pass")].as()); + + + if (jsonIn[F("pm_pass")] != F("****")) + { + String auth = base64::encode(String(jsonIn[F("pm_user")]) + String(":") + String(jsonIn[F("pm_pass")])); + snprintf(mConfig->plugin.zeroExport.groups[group].pm_user, ZEROEXPORT_GROUP_MAX_LEN_PM_USER, "%s", String(jsonIn[F("pm_user")]).c_str()); + snprintf(mConfig->plugin.zeroExport.groups[group].pm_pass, ZEROEXPORT_GROUP_MAX_LEN_PM_PASS, "%s", auth.c_str()); + } + mConfig->plugin.zeroExport.groups[group].pm_target = jsonIn[F("pm_target")]; // Inverters for(uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 761e9f42..7cc49b5d 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -1400,7 +1400,7 @@ ml("input", {name: "pm_jsonPath", class: "text", type: "text", value: obj.pm_jsonPath}, null), ]), divRow("{#ZE_GROUP_TAB_POWERMETER_USER}", - ml("input", {name: "pm_user", class: "text", type: "text", value: "" }, null), + ml("input", {name: "pm_user", class: "text", type: "text", value: obj.pm_user }, null), ), divRow("{#ZE_GROUP_TAB_POWERMETER_PASS}", ml("input", {name: "pm_pass", class: "text", type: "password", value: "****"}, null), From 7b9b2bd1274e2b9976e1edc2af4294ba10c6f806 Mon Sep 17 00:00:00 2001 From: Patrick Amrhein Date: Sun, 12 May 2024 14:10:20 +0200 Subject: [PATCH 03/14] 0.8.1030014 --- src/defines.h | 2 +- src/plugins/zeroExport/powermeter.h | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/defines.h b/src/defines.h index e3415824..6cd6f4dd 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 1030013 +#define VERSION_PATCH 1030014 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/plugins/zeroExport/powermeter.h b/src/plugins/zeroExport/powermeter.h index f6053d8c..6f795960 100644 --- a/src/plugins/zeroExport/powermeter.h +++ b/src/plugins/zeroExport/powermeter.h @@ -65,15 +65,22 @@ class powermeter { if (millis() - mPreviousTsp <= 1000) return; // skip when it is to fast mPreviousTsp = millis(); + if (mCfg->debug) DBGPRINTLN(F("pm Takt:")); + bool result = false; float power = 0.0; for (u_short group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { if ((!mCfg->groups[group].enabled) || (mCfg->groups[group].sleep)) continue; - if ((millis() - mCfg->groups[group].pm_peviousTsp) <= ((uint16_t)mCfg->groups[group].pm_refresh * 1000)) continue; + if ((millis() - mCfg->groups[group].pm_peviousTsp) < ((uint16_t)mCfg->groups[group].pm_refresh * 1000)) continue; mCfg->groups[group].pm_peviousTsp = millis(); + if (mCfg->debug) DBGPRINTLN(F("pm Do:")); + + result = false; + power = 0.0; + switch (mCfg->groups[group].pm_type) { #if defined(ZEROEXPORT_POWERMETER_SHELLY) case zeroExportPowermeterType_t::Shelly: @@ -107,19 +114,19 @@ class powermeter { bufferWrite(power, group); // MQTT - Powermeter - if (mCfg->debug) { +// if (mCfg->debug) { if (mMqtt->isConnected()) { // P - mqttObj["Sum"] = ah::round1(power); +// mqttObj["Sum"] = ah::round1(power); // mqttObj["L1"] = ah::round1(power.P1); // mqttObj["L2"] = ah::round1(power.P2); // mqttObj["L3"] = ah::round1(power.P3); - mMqtt->publish(String("zero/state/groups/" + String(group) + "/powermeter/P").c_str(), mqttDoc.as().c_str(), false); - mqttDoc.clear(); + mMqtt->publish(String("zero/state/groups/" + String(group) + "/powermeter/P").c_str(), String(ah::round1(power)).c_str(), false); +// mqttDoc.clear(); // W (TODO) } - } +// } } } } From 58f6a5f4fceca897bfcfccfd3827a9279de43e5e Mon Sep 17 00:00:00 2001 From: Patrick Amrhein Date: Tue, 14 May 2024 17:09:49 +0200 Subject: [PATCH 04/14] 0.8.103..15 --- src/config/settings.h | 12 ++++----- src/defines.h | 2 +- src/plugins/zeroExport/powermeter.h | 42 ++++++++++------------------- src/plugins/zeroExport/zeroExport.h | 12 ++++----- src/web/RestApi.h | 4 +-- src/web/html/setup.html | 25 ++++++++--------- src/web/lang.json | 11 +++----- 7 files changed, 45 insertions(+), 63 deletions(-) diff --git a/src/config/settings.h b/src/config/settings.h index bdcd25e0..2b653fb9 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -206,7 +206,7 @@ typedef struct { #define ZEROEXPORT_MAX_QUEUE_ENTRIES 64 #define ZEROEXPORT_MAX_GROUPS 8 #define ZEROEXPORT_GROUP_MAX_LEN_NAME 25 -#define ZEROEXPORT_GROUP_MAX_LEN_PM_URL 100 +#define ZEROEXPORT_GROUP_MAX_LEN_PM_SRC 100 #define ZEROEXPORT_GROUP_MAX_LEN_PM_JSONPATH 100 #define ZEROEXPORT_GROUP_MAX_LEN_PM_USER 25 #define ZEROEXPORT_GROUP_MAX_LEN_PM_PASS 25 @@ -288,7 +288,7 @@ typedef struct { uint8_t pm_refresh; unsigned long pm_peviousTsp; uint8_t pm_type; - char pm_url[ZEROEXPORT_GROUP_MAX_LEN_PM_URL]; + char pm_src[ZEROEXPORT_GROUP_MAX_LEN_PM_SRC]; char pm_jsonPath[ZEROEXPORT_GROUP_MAX_LEN_PM_JSONPATH]; char pm_user[ZEROEXPORT_GROUP_MAX_LEN_PM_USER]; char pm_pass[ZEROEXPORT_GROUP_MAX_LEN_PM_PASS]; @@ -674,7 +674,7 @@ class settings { mCfg.plugin.zeroExport.groups[group].pm_refresh = 5; mCfg.plugin.zeroExport.groups[group].pm_peviousTsp = 0; mCfg.plugin.zeroExport.groups[group].pm_type = zeroExportPowermeterType_t::None; - snprintf(mCfg.plugin.zeroExport.groups[group].pm_url, ZEROEXPORT_GROUP_MAX_LEN_PM_URL, "%s", DEF_ZEXPORT); + snprintf(mCfg.plugin.zeroExport.groups[group].pm_src, ZEROEXPORT_GROUP_MAX_LEN_PM_SRC, "%s", DEF_ZEXPORT); snprintf(mCfg.plugin.zeroExport.groups[group].pm_jsonPath, ZEROEXPORT_GROUP_MAX_LEN_PM_JSONPATH, "%s", DEF_ZEXPORT); snprintf(mCfg.plugin.zeroExport.groups[group].pm_user, ZEROEXPORT_GROUP_MAX_LEN_PM_USER, "%s", DEF_ZEXPORT); snprintf(mCfg.plugin.zeroExport.groups[group].pm_pass, ZEROEXPORT_GROUP_MAX_LEN_PM_PASS, "%s", DEF_ZEXPORT); @@ -1033,7 +1033,7 @@ class settings { // Powermeter obj[F("pm_refresh")] = mCfg.plugin.zeroExport.groups[group].pm_refresh; obj[F("pm_type")] = mCfg.plugin.zeroExport.groups[group].pm_type; - obj[F("pm_url")] = mCfg.plugin.zeroExport.groups[group].pm_url; + obj[F("pm_src")] = mCfg.plugin.zeroExport.groups[group].pm_src; obj[F("pm_jsonPath")] = mCfg.plugin.zeroExport.groups[group].pm_jsonPath; obj[F("pm_user")] = mCfg.plugin.zeroExport.groups[group].pm_user; obj[F("pm_pass")] = mCfg.plugin.zeroExport.groups[group].pm_pass; @@ -1067,8 +1067,8 @@ class settings { getVal(obj, F("pm_refresh"), &mCfg.plugin.zeroExport.groups[group].pm_refresh); if (obj.containsKey(F("pm_type"))) getVal(obj, F("pm_type"), &mCfg.plugin.zeroExport.groups[group].pm_type); - if (obj.containsKey(F("pm_url"))) - getChar(obj, F("pm_url"), mCfg.plugin.zeroExport.groups[group].pm_url, ZEROEXPORT_GROUP_MAX_LEN_PM_URL); + if (obj.containsKey(F("pm_src"))) + getChar(obj, F("pm_src"), mCfg.plugin.zeroExport.groups[group].pm_src, ZEROEXPORT_GROUP_MAX_LEN_PM_SRC ); if (obj.containsKey(F("pm_jsonPath"))) getChar(obj, F("pm_jsonPath"), mCfg.plugin.zeroExport.groups[group].pm_jsonPath, ZEROEXPORT_GROUP_MAX_LEN_PM_JSONPATH); if (obj.containsKey(F("pm_user"))) diff --git a/src/defines.h b/src/defines.h index 6cd6f4dd..dcd61ab6 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 1030014 +#define VERSION_PATCH 1030015 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/plugins/zeroExport/powermeter.h b/src/plugins/zeroExport/powermeter.h index 6f795960..1072a837 100644 --- a/src/plugins/zeroExport/powermeter.h +++ b/src/plugins/zeroExport/powermeter.h @@ -116,15 +116,7 @@ class powermeter { // MQTT - Powermeter // if (mCfg->debug) { if (mMqtt->isConnected()) { - // P -// mqttObj["Sum"] = ah::round1(power); - // mqttObj["L1"] = ah::round1(power.P1); - // mqttObj["L2"] = ah::round1(power.P2); - // mqttObj["L3"] = ah::round1(power.P3); mMqtt->publish(String("zero/state/groups/" + String(group) + "/powermeter/P").c_str(), String(ah::round1(power)).c_str(), false); -// mqttDoc.clear(); - - // W (TODO) } // } } @@ -156,8 +148,10 @@ class powermeter { float min = 0.0; for (int i = 0; i < 5; i++) { - if (i == 0) min = mPowermeterBuffer[group][i]; - if ( min > mPowermeterBuffer[group][i]) min = mPowermeterBuffer[group][i]; + if (i == 0) + min = mPowermeterBuffer[group][i]; + if (min > mPowermeterBuffer[group][i]) + min = mPowermeterBuffer[group][i]; } return min; @@ -170,12 +164,12 @@ class powermeter { #if defined(ZEROEXPORT_POWERMETER_MQTT) for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { - if (!strcmp(mCfg->groups[group].pm_jsonPath, "")) continue; + if (!strcmp(mCfg->groups[group].pm_src, "")) continue; if (!mCfg->groups[group].enabled) continue; if (mCfg->groups[group].pm_type == zeroExportPowermeterType_t::Mqtt) { - mMqtt->subscribeExtern(String(mCfg->groups[group].pm_jsonPath).c_str(), QOS_2); + mMqtt->subscribeExtern(String(mCfg->groups[group].pm_src).c_str(), QOS_2); } } @@ -195,9 +189,9 @@ class powermeter { if (!mCfg->groups[group].pm_type == zeroExportPowermeterType_t::Mqtt) continue; - if (!strcmp(mCfg->groups[group].pm_jsonPath, "")) continue; + if (!strcmp(mCfg->groups[group].pm_src, "")) continue; - if (strcmp(mCfg->groups[group].pm_jsonPath, String(topic).c_str())) continue; + if (strcmp(mCfg->groups[group].pm_src, String(topic).c_str())) continue; float power = 0.0; power = (uint16_t)obj["val"]; @@ -207,15 +201,7 @@ class powermeter { // MQTT - Powermeter if (mCfg->debug) { if (mMqtt->isConnected()) { - // P - mqttObj["Sum"] = ah::round1(power); - /// mqttObj["L1"] = ah::round1(power.P1); - /// mqttObj["L2"] = ah::round1(power.P2); - /// mqttObj["L3"] = ah::round1(power.P3); - mMqtt->publish(String("zero/state/groups/" + String(group) + "/powermeter/P").c_str(), mqttDoc.as().c_str(), false); - mqttDoc.clear(); - - // W (TODO) + mMqtt->publish(String("zero/state/groups/" + String(group) + "/powermeter/P").c_str(), String(ah::round1(power)).c_str(), false); } } @@ -287,7 +273,7 @@ class powermeter { setHeader(&http); - String url = String("http://") + String(mCfg->groups[group].pm_url) + String("/") + String(mCfg->groups[group].pm_jsonPath); + String url = String("http://") + String(mCfg->groups[group].pm_src) + String("/") + String(mCfg->groups[group].pm_jsonPath); logObj["HTTP_URL"] = url; http.begin(url); @@ -380,8 +366,8 @@ class powermeter { http.addHeader("Content-Type", "application/json"); http.addHeader("Accept", "application/json"); - // String url = String("http://") + String(mCfg->groups[group].pm_url) + String("/") + String(mCfg->groups[group].pm_jsonPath); - String url = String(mCfg->groups[group].pm_url); + // String url = String("http://") + String(mCfg->groups[group].pm_src) + String("/") + String(mCfg->groups[group].pm_jsonPath); + String url = String(mCfg->groups[group].pm_src); logObj["HTTP_URL"] = url; http.begin(url); @@ -505,7 +491,7 @@ class powermeter { auth = mCfg->groups[group].pm_pass; } - String url = String("http://") + mCfg->groups[group].pm_url + String("/") + String(mCfg->groups[group].pm_jsonPath); + String url = String("http://") + mCfg->groups[group].pm_src + String("/") + String(mCfg->groups[group].pm_jsonPath); setHeader(&http); http.begin(url); @@ -558,7 +544,7 @@ class powermeter { setHeader(&http); String url = - String("http://") + String(mCfg->groups[group].pm_url) + + String("http://") + String(mCfg->groups[group].pm_src) + String("/") + String(mCfg->groups[group].pm_jsonPath + String("?user=") + String(mCfg->groups[group].pm_user) + String("&password=") + String(mCfg->groups[group].pm_pass)); http.begin(url); diff --git a/src/plugins/zeroExport/zeroExport.h b/src/plugins/zeroExport/zeroExport.h index d0c215ff..d13093b0 100644 --- a/src/plugins/zeroExport/zeroExport.h +++ b/src/plugins/zeroExport/zeroExport.h @@ -676,14 +676,14 @@ class ZeroExport { // 0.8.103008.2 // // "topic":"ctrl/zero/groups/+/pm_ip" // if (topic.indexOf("ctrl/zero/groups/" + String(topicGroup) + "/pm_ip") != -1) { - // snprintf(mCfg->groups[topicGroup].pm_url, ZEROEXPORT_GROUP_MAX_LEN_PM_URL, "%s", obj[F("val")].as()); + // snprintf(mCfg->groups[topicGroup].pm_src, ZEROEXPORT_GROUP_MAX_LEN_PM_SRC, "%s", obj[F("val")].as()); /// TODO: - // snprintf(mCfg->groups[topicGroup].pm_url, ZEROEXPORT_GROUP_MAX_LEN_PM_URL, "%s", obj[F("val")].as()); - // strncpy(mCfg->groups[topicGroup].pm_url, obj[F("val")], ZEROEXPORT_GROUP_MAX_LEN_PM_URL); - // strncpy(mCfg->groups[topicGroup].pm_url, String(obj[F("val")]).c_str(), ZEROEXPORT_GROUP_MAX_LEN_PM_URL); - // snprintf(mCfg->groups[topicGroup].pm_url, ZEROEXPORT_GROUP_MAX_LEN_PM_URL, "%s", String(obj[F("val")]).c_str()); + // snprintf(mCfg->groups[topicGroup].pm_src, ZEROEXPORT_GROUP_MAX_LEN_PM_SRC, "%s", obj[F("val")].as()); + // strncpy(mCfg->groups[topicGroup].pm_src, obj[F("val")], ZEROEXPORT_GROUP_MAX_LEN_PM_SRC); + // strncpy(mCfg->groups[topicGroup].pm_src, String(obj[F("val")]).c_str(), ZEROEXPORT_GROUP_MAX_LEN_PM_SRC); + // snprintf(mCfg->groups[topicGroup].pm_src, ZEROEXPORT_GROUP_MAX_LEN_PM_SRC, "%s", String(obj[F("val")]).c_str()); // mLog["k"] = "ctrl/zero/groups/" + String(topicGroup) + "/pm_ip"; - // mLog["v"] = mCfg->groups[topicGroup].pm_url; + // mLog["v"] = mCfg->groups[topicGroup].pm_src; // } // // // "topic":"ctrl/zero/groups/+/pm_jsonPath" diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 21123be6..95a1d8d9 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -839,7 +839,7 @@ class RestApi { // Powermeter objGroup[F("pm_refresh")] = (uint8_t)mConfig->plugin.zeroExport.groups[group].pm_refresh; objGroup[F("pm_type")] = (uint8_t)mConfig->plugin.zeroExport.groups[group].pm_type; - objGroup[F("pm_url")] = String(mConfig->plugin.zeroExport.groups[group].pm_url); + objGroup[F("pm_src")] = String(mConfig->plugin.zeroExport.groups[group].pm_src); objGroup[F("pm_jsonPath")] = String(mConfig->plugin.zeroExport.groups[group].pm_jsonPath); objGroup[F("pm_user")] = String(mConfig->plugin.zeroExport.groups[group].pm_user); objGroup[F("pm_pass")] = String(mConfig->plugin.zeroExport.groups[group].pm_pass); @@ -1159,7 +1159,7 @@ class RestApi { // Powermeter mConfig->plugin.zeroExport.groups[group].pm_refresh = jsonIn[F("pm_refresh")]; mConfig->plugin.zeroExport.groups[group].pm_type = jsonIn[F("pm_type")]; - snprintf(mConfig->plugin.zeroExport.groups[group].pm_url, ZEROEXPORT_GROUP_MAX_LEN_PM_URL, "%s", jsonIn[F("pm_url")].as()); + snprintf(mConfig->plugin.zeroExport.groups[group].pm_src, ZEROEXPORT_GROUP_MAX_LEN_PM_SRC, "%s", jsonIn[F("pm_src")].as()); snprintf(mConfig->plugin.zeroExport.groups[group].pm_jsonPath, ZEROEXPORT_GROUP_MAX_LEN_PM_JSONPATH, "%s", jsonIn[F("pm_jsonPath")].as()); snprintf(mConfig->plugin.zeroExport.groups[group].pm_user, ZEROEXPORT_GROUP_MAX_LEN_PM_USER, "%s", jsonIn[F("pm_user")].as()); snprintf(mConfig->plugin.zeroExport.groups[group].pm_pass, ZEROEXPORT_GROUP_MAX_LEN_PM_PASS, "%s", jsonIn[F("pm_pass")].as()); diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 761e9f42..a2d89156 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -1389,12 +1389,11 @@ divRow("{#ZE_GROUP_TAB_POWERMETER_REFRESH}", ml("input", {name: "pm_refresh", class: "text", type: "number", min: "1", max: "30", step: "1", value: obj.pm_refresh}, null), ), -// TODO: URL -> IP divRow("{#ZE_GROUP_TAB_POWERMETER_TARGET}", ml("select", {name: "pm_target", class: "text", id: "pm_target"}, null), ), - divRow("{#ZE_GROUP_TAB_POWERMETER_IP}", [ - ml("input", {name: "pm_url", class: "text", type: "text", value: obj.pm_url, maxlength: "100"}, null), + divRow("{#ZE_GROUP_TAB_POWERMETER_SRC}", [ + ml("input", {name: "pm_src", class: "text", type: "text", value: obj.pm_src, maxlength: "100"}, null), ]), divRow("{#ZE_GROUP_TAB_POWERMETER_JSONPATH}", [ ml("input", {name: "pm_jsonPath", class: "text", type: "text", value: obj.pm_jsonPath}, null), @@ -1405,9 +1404,6 @@ divRow("{#ZE_GROUP_TAB_POWERMETER_PASS}", ml("input", {name: "pm_pass", class: "text", type: "password", value: "****"}, null), ), - divRow("{#ZE_GROUP_TAB_POWERMETER_TOPIC}", - ml("input", {id: 3, name: "pm_topic", class: "text", type: "text", value: ""}, null), - ), // TODO: Uebersetzen mit lang.json und auf die entsprechende Dokuseite verlinken divRow("Hinweis: ", ml("a", {href: "https://docs.ahoydtu.de/de/latest/zeroExport.html"}, "Bitte beachten Sie die Ausfüllhinweise in der Dokumentation."), @@ -1514,7 +1510,6 @@ // add addEventListener const selectElement = document.querySelector("#pm_type"); - //selectElement.addEventListener("change", (event) => { pm_type_dropdown() }); selectElement.addEventListener("change", (event) => { pm_type_dropdown() }); // run event one time @@ -1580,21 +1575,27 @@ // Formular for Powermeter-DropDown // show all DIVs and remove only what is not necessary + // 1 = pm_refresh, 2 = pm_target, 3 = pm_src, 4 = pm_jsonPath, 5 = pm_user, 6 = pm_pass for(var i = 0; i < divsToHide.childElementCount; i++) divsToHide.childNodes[i].style.display = ''; if(value == "---") for(var i = 1; i < divsToHide.childElementCount; i++) divsToHide.childNodes[i].style.display = 'none'; else if(value == "Shelly") { - divsToHide.childNodes[7].style.display = 'none'; + divsToHide.childNodes[5].style.display = 'none'; + divsToHide.childNodes[6].style.display = 'none'; } else if(value == "Mqtt") { - divsToHide.childNodes[3].style.display = 'none'; + divsToHide.childNodes[1].style.display = 'none'; + divsToHide.childNodes[2].style.display = 'none'; divsToHide.childNodes[4].style.display = 'none'; divsToHide.childNodes[5].style.display = 'none'; divsToHide.childNodes[6].style.display = 'none'; } else if(value == "Tibber") { divsToHide.childNodes[4].style.display = 'none'; - divsToHide.childNodes[7].style.display = 'none'; + } + else if(value == "Shrdzm") { + divsToHide.childNodes[1].style.display = 'none'; + divsToHide.childNodes[2].style.display = 'none'; } } @@ -1611,7 +1612,7 @@ o.pm_refresh = document.getElementsByName("pm_refresh")[0].value; var e = document.getElementsByName("pm_type")[0]; o.pm_type = e.options[e.selectedIndex].value; - o.pm_url = document.getElementsByName("pm_url")[0].value; + o.pm_src = document.getElementsByName("pm_src")[0].value; o.pm_jsonPath = document.getElementsByName("pm_jsonPath")[0].value; o.pm_user = document.getElementsByName("pm_user")[0].value; o.pm_pass = document.getElementsByName("pm_pass")[0].value; @@ -1678,7 +1679,7 @@ // Powermeter o.pm_refresh = 5; o.pm_type = 0; - o.pm_url = ""; + o.pm_src = ""; o.pm_jsonPath = ""; o.pm_user = ""; o.pm_pass = ""; diff --git a/src/web/lang.json b/src/web/lang.json index 4fa5b655..1172d670 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -894,9 +894,9 @@ "de": "Typ:" }, { - "token": "ZE_GROUP_TAB_POWERMETER_IP", - "en": "IP:", - "de": "IP:" + "token": "ZE_GROUP_TAB_POWERMETER_SRC", + "en": "IP / Topic:", + "de": "IP / Topic:" }, { "token": "ZE_GROUP_TAB_POWERMETER_JSONPATH", @@ -913,11 +913,6 @@ "en": "Password:", "de": "Passwort:" }, - { - "token": "ZE_GROUP_TAB_POWERMETER_TOPIC", - "en": "Topic:", - "de": "Topic:" - }, { "token": "ZE_GROUP_TAB_POWERMETER_TARGET", "en": "Target:", From 8f51dc29fc24b7478f325fde6fbd76ace3ba32fd Mon Sep 17 00:00:00 2001 From: DanielR92 Date: Tue, 14 May 2024 19:10:15 +0200 Subject: [PATCH 05/14] fix setup.html formular for tibber --- src/web/html/setup.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 506bda2e..60b00b3e 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -1590,9 +1590,9 @@ divsToHide.childNodes[5].style.display = 'none'; divsToHide.childNodes[6].style.display = 'none'; } - else if(value == "Tibber") { + /*else if(value == "Tibber") { divsToHide.childNodes[4].style.display = 'none'; - } + }*/ else if(value == "Shrdzm") { divsToHide.childNodes[1].style.display = 'none'; divsToHide.childNodes[2].style.display = 'none'; From c5056cbaeebbee744df87816e21361e07898b858 Mon Sep 17 00:00:00 2001 From: DanielR92 Date: Tue, 14 May 2024 19:11:16 +0200 Subject: [PATCH 06/14] fix tibber query and timer --- src/plugins/zeroExport/powermeter.h | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/plugins/zeroExport/powermeter.h b/src/plugins/zeroExport/powermeter.h index 20cbf4e1..0c68a4ae 100644 --- a/src/plugins/zeroExport/powermeter.h +++ b/src/plugins/zeroExport/powermeter.h @@ -103,8 +103,8 @@ class powermeter { 863.25 MHz - geht (ohne Tibber Probleme) => 3 & 4 Balken */ case zeroExportPowermeterType_t::Tibber: + if(mCfg->groups[group].pm_refresh < 3) mCfg->groups[group].pm_refresh = 3; result = getPowermeterWattsTibber(*mLog, group, &power); - mPreviousTsp += 2000; // Zusätzliche Pause break; #endif #if defined(ZEROEXPORT_POWERMETER_SHRDZM) @@ -114,15 +114,16 @@ class powermeter { #endif } - if (result) { + //if (mMqtt->isConnected()) mMqtt->publish(String("zero/state/groups/" + String(group) + "/result").c_str(), String(ret).c_str(), false); + + if (result) + { bufferWrite(power, group); // MQTT - Powermeter -// if (mCfg->debug) { - if (mMqtt->isConnected()) { - mMqtt->publish(String("zero/state/groups/" + String(group) + "/powermeter/P").c_str(), String(ah::round1(power)).c_str(), false); - } -// } + if (mMqtt->isConnected()) { + mMqtt->publish(String("zero/state/groups/" + String(group) + "/powermeter/P").c_str(), String(ah::round1(power)).c_str(), false); + } } } } @@ -181,7 +182,7 @@ class powermeter { } /** onMqttMessage - * + * This function is needed for all mqtt connections between ahoy and other devices. */ void onMqttMessage(JsonObject obj) { String topic = String(obj["topic"]); @@ -198,6 +199,7 @@ class powermeter { if (strcmp(mCfg->groups[group].pm_src, String(topic).c_str())) continue; float power = 0.0; + power = (uint16_t)obj["val"]; bufferWrite(power, group); @@ -479,20 +481,19 @@ class powermeter { {{0x01, 0x00, 0x02, 0x08, 0x00, 0xff}, &smlOBISWh, &_powerMeterExport}}; bool getPowermeterWattsTibber(JsonObject logObj, uint8_t group, float *power) { - mPreviousTsp = mPreviousTsp + 2000; // Zusätzliche Pause - bool result = false; logObj["mod"] = "getPowermeterWattsTibber"; String auth = mCfg->groups[group].pm_pass; - String url = String("http://") + mCfg->groups[group].pm_url + String("/") + String(mCfg->groups[group].pm_jsonPath); + String url = String("http://") + mCfg->groups[group].pm_src + String("/") + String(mCfg->groups[group].pm_jsonPath); setHeader(&http); http.begin(url); http.addHeader("Authorization", "Basic " + auth); - if (http.GET() == HTTP_CODE_OK && http.getSize() > 0) { + if (http.GET() == HTTP_CODE_OK && http.getSize() > 0) + { String myString = http.getString(); double readVal = 0; unsigned char c; From dd164f5236a211978fc0ea160493a5953f298eda Mon Sep 17 00:00:00 2001 From: DanielR92 Date: Tue, 14 May 2024 20:14:55 +0200 Subject: [PATCH 07/14] Shelly Topic MQTT checker - powermeter.h --- src/plugins/zeroExport/powermeter.h | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/plugins/zeroExport/powermeter.h b/src/plugins/zeroExport/powermeter.h index 20cbf4e1..b3736648 100644 --- a/src/plugins/zeroExport/powermeter.h +++ b/src/plugins/zeroExport/powermeter.h @@ -190,15 +190,28 @@ class powermeter { for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { if (!mCfg->groups[group].enabled) continue; - if (!mCfg->groups[group].pm_type == zeroExportPowermeterType_t::Mqtt) continue; - if (!strcmp(mCfg->groups[group].pm_src, "")) continue; - if (strcmp(mCfg->groups[group].pm_src, String(topic).c_str())) continue; float power = 0.0; - power = (uint16_t)obj["val"]; + + //TODO: datajson 100 enough? + // this if-statement need to check if value contains a json object. + // is it so, then deserialize it and get the values (Shelly GEN2) + DynamicJsonDocument datajson(100); + if (!deserializeJson(datajson, obj["val"])) + { + switch (mCfg->groups[group].pm_target) { + case 0: power = datajson["a_act_power"]; break; + case 1: power = datajson["b_act_power"]; break; + case 2: power = datajson["c_act_power"]; break; + case 3: power = datajson["total_act_power"]; break; + } + } else { + //TODO: check if parse is possible here? Is that right? + power = (uint16_t)obj["val"]; + } bufferWrite(power, group); From 52d9e6f9dbcbee544df953fe0ebe1b3a6c1af5a0 Mon Sep 17 00:00:00 2001 From: DanielR92 Date: Wed, 15 May 2024 21:17:23 +0200 Subject: [PATCH 08/14] extend JS for battery formular (dropdown) --- src/web/html/setup.html | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 60b00b3e..1b0a9f07 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -1509,8 +1509,8 @@ } // add addEventListener - const selectElement = document.querySelector("#pm_type"); - selectElement.addEventListener("change", (event) => { pm_type_dropdown() }); + const se_pm_type = document.querySelector("#pm_type"); + se_pm_type.addEventListener("change", (event) => { pm_type_dropdown() }); // run event one time pm_type_dropdown(); @@ -1566,6 +1566,31 @@ } } + // add addEventListener + const se_battCfg = document.querySelector("#battCfg"); + se_battCfg.addEventListener("change", (event) => { battCfg_dropdown() }); + + // run event one time + battCfg_dropdown(); + + function battCfg_dropdown() + { + var e = document.getElementsByName("battCfg")[0]; + var value = e.options[e.selectedIndex].text; + + var divsToHide = document.getElementById("divBattery"); + + // Formular for Powermeter-DropDown + // show all DIVs and remove only what is not necessary + // 1 = pm_refresh, 2 = pm_target, 3 = pm_src, 4 = pm_jsonPath, 5 = pm_user, 6 = pm_pass + for(var i = 0; i < divsToHide.childElementCount; i++) divsToHide.childNodes[i].style.display = ''; + + if(value == "---") for(var i = 1; i < divsToHide.childElementCount; i++) divsToHide.childNodes[i].style.display = 'none'; + else if(value == "Inverter U dc") { + divsToHide.childNodes[1].style.display = 'none'; + } + } + function pm_type_dropdown() { var e = document.getElementsByName("pm_type")[0]; @@ -1590,9 +1615,9 @@ divsToHide.childNodes[5].style.display = 'none'; divsToHide.childNodes[6].style.display = 'none'; } - /*else if(value == "Tibber") { + else if(value == "Tibber") { divsToHide.childNodes[4].style.display = 'none'; - }*/ + } else if(value == "Shrdzm") { divsToHide.childNodes[1].style.display = 'none'; divsToHide.childNodes[2].style.display = 'none'; From 3b061a070712550557be1850d6f56486a35ac0ba Mon Sep 17 00:00:00 2001 From: DanielR92 Date: Thu, 16 May 2024 15:56:10 +0200 Subject: [PATCH 09/14] combine two for-loops into one waste of time with two for-loops --- src/plugins/zeroExport/zeroExport.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/plugins/zeroExport/zeroExport.h b/src/plugins/zeroExport/zeroExport.h index 97353a6a..afd15205 100644 --- a/src/plugins/zeroExport/zeroExport.h +++ b/src/plugins/zeroExport/zeroExport.h @@ -106,18 +106,14 @@ class ZeroExport { return; } - // Calc Data->groupPower + uint16_t groupPower = 0; - for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { - groupPower += mCfg->groups[group].inverters[inv].power; - } - mLog["gP"] = groupPower; - - // Calc Data->groupLimit uint16_t groupLimit = 0; for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { - groupLimit += mCfg->groups[group].inverters[inv].limit; + groupPower += mCfg->groups[group].inverters[inv].power; // Calc Data->groupPower + groupLimit += mCfg->groups[group].inverters[inv].limit; // Calc Data->groupLimit } + mLog["gP"] = groupPower; mLog["gL"] = groupLimit; // Batteryprotection From 9dc7129ad749ee4342e9d3409dba0be3d53ae6a4 Mon Sep 17 00:00:00 2001 From: Patrick Amrhein Date: Mon, 20 May 2024 20:51:54 +0200 Subject: [PATCH 10/14] Bugfix: setLimit after iv reboot --- src/plugins/zeroExport/zeroExport.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/plugins/zeroExport/zeroExport.h b/src/plugins/zeroExport/zeroExport.h index 97353a6a..ae57b375 100644 --- a/src/plugins/zeroExport/zeroExport.h +++ b/src/plugins/zeroExport/zeroExport.h @@ -485,6 +485,17 @@ class ZeroExport { mLog["i"] = inv; mCfg->groups[group].inverters[inv].waitAck = 0; mLog["wA"] = mCfg->groups[group].inverters[inv].waitAck; + + mCfg->groups[group].inverters[inv].limit = mCfg->groups[group].inverters[inv].powerMin; + iv->powerLimit[0] = static_cast(mCfg->groups[group].inverters[inv].limit * 10.0); + iv->powerLimit[1] = AbsolutNonPersistent; + if (iv->setDevControlRequest(ActivePowerContr)) { + mApp->triggerTickSend(iv->id); + mCfg->groups[group].inverters[inv].waitAck = 60; + mCfg->groups[group].inverters[inv].action = zeroExportAction_t::doNone; + mCfg->groups[group].inverters[inv].actionTimer = 0; + mCfg->groups[group].inverters[inv].actionTimestamp = millis(); + } sendLog(); clearLog(); } From 119eeed539cb381507218a49ebd279996c1b53ac Mon Sep 17 00:00:00 2001 From: Patrick Amrhein Date: Mon, 20 May 2024 21:16:07 +0200 Subject: [PATCH 11/14] Powermeter add getDataMAX --- src/plugins/zeroExport/powermeter.h | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/plugins/zeroExport/powermeter.h b/src/plugins/zeroExport/powermeter.h index 0c68a4ae..955c6254 100644 --- a/src/plugins/zeroExport/powermeter.h +++ b/src/plugins/zeroExport/powermeter.h @@ -103,7 +103,7 @@ class powermeter { 863.25 MHz - geht (ohne Tibber Probleme) => 3 & 4 Balken */ case zeroExportPowermeterType_t::Tibber: - if(mCfg->groups[group].pm_refresh < 3) mCfg->groups[group].pm_refresh = 3; + if (mCfg->groups[group].pm_refresh < 3) mCfg->groups[group].pm_refresh = 3; result = getPowermeterWattsTibber(*mLog, group, &power); break; #endif @@ -114,10 +114,9 @@ class powermeter { #endif } - //if (mMqtt->isConnected()) mMqtt->publish(String("zero/state/groups/" + String(group) + "/result").c_str(), String(ret).c_str(), false); + // if (mMqtt->isConnected()) mMqtt->publish(String("zero/state/groups/" + String(group) + "/result").c_str(), String(ret).c_str(), false); - if (result) - { + if (result) { bufferWrite(power, group); // MQTT - Powermeter @@ -162,6 +161,24 @@ class powermeter { return min; } + /** getDataMAX + * Holt die Daten vom Powermeter + * @param group + * @returns value + */ + float getDataMAX(uint8_t group) { + float max = 0.0; + + for (int i = 0; i < 5; i++) { + if (i == 0) + max = mPowermeterBuffer[group][i]; + if (max < mPowermeterBuffer[group][i]) + max = mPowermeterBuffer[group][i]; + } + + return max; + } + /** onMqttConnect * */ @@ -492,8 +509,7 @@ class powermeter { http.begin(url); http.addHeader("Authorization", "Basic " + auth); - if (http.GET() == HTTP_CODE_OK && http.getSize() > 0) - { + if (http.GET() == HTTP_CODE_OK && http.getSize() > 0) { String myString = http.getString(); double readVal = 0; unsigned char c; From 6fbe9bd636404229a3988c1aaf3820b3b382d3f1 Mon Sep 17 00:00:00 2001 From: tictrick <117273857+tictrick@users.noreply.github.com> Date: Mon, 20 May 2024 21:24:23 +0200 Subject: [PATCH 12/14] Update powermeter.h --- src/plugins/zeroExport/powermeter.h | 33 ++++++++++++++++------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/plugins/zeroExport/powermeter.h b/src/plugins/zeroExport/powermeter.h index aed861fb..086a7f61 100644 --- a/src/plugins/zeroExport/powermeter.h +++ b/src/plugins/zeroExport/powermeter.h @@ -191,28 +191,31 @@ class powermeter { for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { if (!mCfg->groups[group].enabled) continue; + if (!mCfg->groups[group].pm_type == zeroExportPowermeterType_t::Mqtt) continue; + if (!strcmp(mCfg->groups[group].pm_src, "")) continue; + if (strcmp(mCfg->groups[group].pm_src, String(topic).c_str())) continue; float power = 0.0; - //TODO: datajson 100 enough? - // this if-statement need to check if value contains a json object. - // is it so, then deserialize it and get the values (Shelly GEN2) - DynamicJsonDocument datajson(100); - if (!deserializeJson(datajson, obj["val"])) - { - switch (mCfg->groups[group].pm_target) { - case 0: power = datajson["a_act_power"]; break; - case 1: power = datajson["b_act_power"]; break; - case 2: power = datajson["c_act_power"]; break; - case 3: power = datajson["total_act_power"]; break; - } - } else { - //TODO: check if parse is possible here? Is that right? +// //TODO: datajson 100 enough? +// // this if-statement need to check if value contains a json object. +// // is it so, then deserialize it and get the values (Shelly GEN2) +// DynamicJsonDocument datajson(100); +// if (!deserializeJson(datajson, obj["val"])) +// { +// switch (mCfg->groups[group].pm_target) { +// case 0: power = datajson["a_act_power"]; break; +// case 1: power = datajson["b_act_power"]; break; +// case 2: power = datajson["c_act_power"]; break; +// case 3: power = datajson["total_act_power"]; break; +// } +// } else { +// //TODO: check if parse is possible here? Is that right? power = (uint16_t)obj["val"]; - } +// } bufferWrite(power, group); From 13d59237c046e992abeafdcd847851123ffaba0d Mon Sep 17 00:00:00 2001 From: Patrick Amrhein Date: Mon, 20 May 2024 22:09:40 +0200 Subject: [PATCH 13/14] Powermeter modify getHeader --- src/plugins/zeroExport/powermeter.h | 9 ++++++--- src/plugins/zeroExport/zeroExport.h | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/plugins/zeroExport/powermeter.h b/src/plugins/zeroExport/powermeter.h index eca8ec59..eb0e6253 100644 --- a/src/plugins/zeroExport/powermeter.h +++ b/src/plugins/zeroExport/powermeter.h @@ -46,7 +46,8 @@ class powermeter { * @param *log * @returns void */ - bool setup(zeroExport_t *cfg, PubMqttType *mqtt, JsonObject *log) { + bool setup(IApp *app, zeroExport_t *cfg, PubMqttType *mqtt, JsonObject *log) { + mApp = app; mCfg = cfg; mMqtt = mqtt; mLog = log; @@ -277,6 +278,7 @@ class powermeter { zeroExport_t *mCfg; PubMqttType *mMqtt = nullptr; JsonObject *mLog; + IApp *mApp = nullptr; unsigned long mPreviousTsp = millis(); @@ -291,8 +293,9 @@ class powermeter { */ void setHeader(HTTPClient *h) { h->setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); - h->setUserAgent("Ahoy-Agent"); - // TODO: Ahoy-0.8.850024-zero +/// h->setUserAgent("Ahoy-Agent"); +/// // TODO: Ahoy-0.8.850024-zero + h->setUserAgent(mApp->getVersion()); h->setConnectTimeout(500); h->setTimeout(1000); h->addHeader("Content-Type", "application/json"); diff --git a/src/plugins/zeroExport/zeroExport.h b/src/plugins/zeroExport/zeroExport.h index 2b5aac9b..58541623 100644 --- a/src/plugins/zeroExport/zeroExport.h +++ b/src/plugins/zeroExport/zeroExport.h @@ -47,7 +47,7 @@ class ZeroExport { mApi = api; mMqtt = mqtt; - mIsInitialized = mPowermeter.setup(mCfg, mqtt, &mLog); + mIsInitialized = mPowermeter.setup(mApp, mCfg, mqtt, &mLog); } /** loop @@ -106,7 +106,7 @@ class ZeroExport { return; } - + uint16_t groupPower = 0; uint16_t groupLimit = 0; for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { From 23b0330ccabcebabe7ddf862884ff72b357a7287 Mon Sep 17 00:00:00 2001 From: Patrick Amrhein Date: Thu, 23 May 2024 23:21:20 +0200 Subject: [PATCH 14/14] 0.8.1030016 --- src/defines.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/defines.h b/src/defines.h index dcd61ab6..253b50b3 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 1030015 +#define VERSION_PATCH 1030016 //------------------------------------- typedef struct { uint8_t ch;