diff --git a/src/config/settings.h b/src/config/settings.h index cc5f1ddf..bcc34c5a 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -283,6 +283,8 @@ typedef struct { bool sleep; char name[ZEROEXPORT_GROUP_MAX_LEN_NAME]; // Powermeter + uint8_t pm_refresh; + unsigned long pm_peviousTsp; uint8_t pm_type; char pm_url[ZEROEXPORT_GROUP_MAX_LEN_PM_URL]; char pm_jsonPath[ZEROEXPORT_GROUP_MAX_LEN_PM_JSONPATH]; @@ -670,6 +672,8 @@ class settings { mCfg.plugin.zeroExport.groups[group].sleep = false; snprintf(mCfg.plugin.zeroExport.groups[group].name, ZEROEXPORT_GROUP_MAX_LEN_NAME, "%s", DEF_ZEXPORT); // Powermeter + 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_jsonPath, ZEROEXPORT_GROUP_MAX_LEN_PM_JSONPATH, "%s", DEF_ZEXPORT); @@ -1031,6 +1035,7 @@ class settings { obj[F("enabled")] = mCfg.plugin.zeroExport.groups[group].enabled; obj[F("name")] = mCfg.plugin.zeroExport.groups[group].name; // 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_jsonPath")] = mCfg.plugin.zeroExport.groups[group].pm_jsonPath; @@ -1061,6 +1066,8 @@ class settings { if (obj.containsKey(F("name"))) getChar(obj, F("name"), mCfg.plugin.zeroExport.groups[group].name, ZEXPORT_ADDR_LEN); // Powermeter + if (obj.containsKey(F("pm_refresh"))) + 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"))) diff --git a/src/plugins/zeroExport/powermeter.h b/src/plugins/zeroExport/powermeter.h index 2e32675b..ff6c273d 100644 --- a/src/plugins/zeroExport/powermeter.h +++ b/src/plugins/zeroExport/powermeter.h @@ -75,6 +75,9 @@ class powermeter { 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; + mCfg->groups[group].pm_peviousTsp = millis(); + switch (mCfg->groups[group].pm_type) { #if defined(ZEROEXPORT_POWERMETER_SHELLY) case zeroExportPowermeterType_t::Shelly: @@ -88,8 +91,8 @@ class powermeter { #endif #if defined(ZEROEXPORT_POWERMETER_MQTT) case zeroExportPowermeterType_t::Mqtt: -/// power = getPowermeterWattsMqtt(*mLog, group); -continue; + /// power = getPowermeterWattsMqtt(*mLog, group); + continue; break; #endif #if defined(ZEROEXPORT_POWERMETER_HICHI) @@ -158,7 +161,6 @@ continue; * */ void onMqttConnect(void) { - #if defined(ZEROEXPORT_POWERMETER_MQTT) for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { @@ -167,13 +169,11 @@ 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); } } #endif /*defined(ZEROEXPORT_POWERMETER_MQTT)*/ - } /** @@ -183,14 +183,42 @@ continue; String topic = String(obj["topic"]); #if defined(ZEROEXPORT_POWERMETER_MQTT) - // topic for powermeter? -// for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { -// if (mCfg->groups[group].pm_type == zeroExportPowermeterType_t::Mqtt) { -// // mLog["mqttDevice"] = "topicInverter"; -// if (!topic.equals(mCfg->groups[group].pm_jsonPath)) return; -// mCfg->groups[group].pm_P = (int32_t)obj["val"]; -// } -// } + + 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_jsonPath, "")) continue; + + if (strcmp(mCfg->groups[group].pm_jsonPath, String(topic).c_str())) continue; + + PowermeterBuffer_t power; + power.P = (uint16_t)obj["val"]; + power.P1 = power.P2 = power.P3 = (uint16_t)obj["val"] / 3; + + if ((power.P == 0) and (power.P1 == 0) && (power.P2 == 0) && (power.P3 == 0)) return; + + bufferWrite(power, group); + + // MQTT - Powermeter + if (mCfg->debug) { + if (mMqtt->isConnected()) { + // P + mqttObj["Sum"] = ah::round1(power.P); + 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) + } + } + + return; + } + #endif /*defined(ZEROEXPORT_POWERMETER_MQTT)*/ } @@ -202,7 +230,7 @@ continue; * @returns void */ void mqttSubscribe(String gr, String payload) { -// mqttPublish(gr, payload); + // mqttPublish(gr, payload); mMqtt->subscribe(gr.c_str(), QOS_2); } @@ -435,26 +463,26 @@ continue; } #endif -///#if defined(ZEROEXPORT_POWERMETER_MQTT) -/// /** getPowermeterWattsMqtt -/// * ... -/// * @param logObj -/// * @param group -/// * @returns true/false -/// */ -/// PowermeterBuffer_t getPowermeterWattsMqtt(JsonObject logObj, uint8_t group) { -/// PowermeterBuffer_t result; -/// result.P = result.P1 = result.P2 = result.P3 = 0; -/// -/// logObj["mod"] = "getPowermeterWattsMqtt"; -/// -/// // topic for powermeter? -/// result.P = mCfg->groups[group].pm_P; -/// result.P1 = result.P2 = result.P3 = mCfg->groups[group].pm_P / 3; -/// -/// return result; -/// } -///#endif + /// #if defined(ZEROEXPORT_POWERMETER_MQTT) + /// /** getPowermeterWattsMqtt + /// * ... + /// * @param logObj + /// * @param group + /// * @returns true/false + /// */ + /// PowermeterBuffer_t getPowermeterWattsMqtt(JsonObject logObj, uint8_t group) { + /// PowermeterBuffer_t result; + /// result.P = result.P1 = result.P2 = result.P3 = 0; + /// + /// logObj["mod"] = "getPowermeterWattsMqtt"; + /// + /// // topic for powermeter? + /// result.P = mCfg->groups[group].pm_P; + /// result.P1 = result.P2 = result.P3 = mCfg->groups[group].pm_P / 3; + /// + /// return result; + /// } + /// #endif #if defined(ZEROEXPORT_POWERMETER_HICHI) /** getPowermeterWattsHichi diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 5b34f1dd..e7a6244c 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -242,7 +242,7 @@ class RestApi { if((len + index) != total) return; // not last frame - nothing to do - DynamicJsonDocument json(1000); + DynamicJsonDocument json(2000); AsyncJsonResponse* response = new AsyncJsonResponse(false, 200); JsonObject root = response->getRoot(); @@ -837,6 +837,7 @@ class RestApi { objGroup[F("enabled")] = (bool)mConfig->plugin.zeroExport.groups[group].enabled; objGroup[F("name")] = String(mConfig->plugin.zeroExport.groups[group].name); // 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_jsonPath")] = String(mConfig->plugin.zeroExport.groups[group].pm_jsonPath); @@ -1156,6 +1157,7 @@ class RestApi { mConfig->plugin.zeroExport.groups[group].enabled = jsonIn[F("enabled")]; snprintf(mConfig->plugin.zeroExport.groups[group].name, ZEROEXPORT_GROUP_MAX_LEN_NAME, "%s", jsonIn[F("name")].as()); // 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_jsonPath, ZEROEXPORT_GROUP_MAX_LEN_PM_JSONPATH, "%s", jsonIn[F("pm_jsonPath")].as()); diff --git a/src/web/html/setup.html b/src/web/html/setup.html index dd96a53a..5cedc4e4 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -1390,10 +1390,9 @@ ]), // Powermeter ml("div", {id: "div{#ZE_GROUP_TAB_POWERMETER}", class: "tab-content hide"}, [ -// TODO: add -//divRow("{#ZE_GROUP_TAB_POWERMETER_REFRESH}", -//ml("select", {name: "pm_refresh", class: "text", type: "text", value: obj.pm_refresh}, null), -//), + 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), + ), divRow("{#ZE_GROUP_TAB_POWERMETER_TYPE}", ml("select", {name: "pm_type", class: "text", id: "pm_type"}, null), ), @@ -1556,7 +1555,7 @@ o.enabled = document.getElementsByName("enabled")[0].checked; o.name = document.getElementsByName("name")[0].value; // Powermeter - //o.pm_type = document.getElementsByName("pm_type")[0].selectedIndex; + 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; @@ -1623,6 +1622,7 @@ o.enabled = false; o.name = ""; // Powermeter + o.pm_refresh = 5; o.pm_type = 0; o.pm_url = ""; o.pm_jsonPath = ""; @@ -1640,6 +1640,7 @@ q.target = -1; q.powerMin = 0; q.powerMax = 0; + q.turnOff = false; o.inverters.push(q); } // Battery diff --git a/src/web/lang.json b/src/web/lang.json index ab4efa39..dcfa99c0 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -883,6 +883,11 @@ "en": "Powermeter", "de": "Leistungsmessung" }, + { + "token": "ZE_GROUP_TAB_POWERMETER_REFRESH", + "en": "Refresh (s):", + "de": "Zykluszeit (s):" + }, { "token": "ZE_GROUP_TAB_POWERMETER_TYPE", "en": "Type:",