From 75687a78db3c5e58529bda4519029be118f2f4c8 Mon Sep 17 00:00:00 2001 From: Patrick Amrhein Date: Fri, 10 May 2024 18:47:30 +0200 Subject: [PATCH] 0.8.1030012 --- src/config/settings.h | 29 +-- src/defines.h | 2 +- src/plugins/zeroExport/powermeter.h | 314 +++++++++++----------------- src/plugins/zeroExport/zeroExport.h | 43 +--- src/web/RestApi.h | 4 +- src/web/html/setup.html | 49 ++--- src/web/lang.json | 10 +- 7 files changed, 160 insertions(+), 291 deletions(-) diff --git a/src/config/settings.h b/src/config/settings.h index d412094e..bdcd25e0 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -213,7 +213,6 @@ typedef struct { #define ZEROEXPORT_GROUP_MAX_LEN_BATT_TOPIC 100 #define ZEROEXPORT_GROUP_MAX_INVERTERS 3 #define ZEROEXPORT_POWERMETER_MAX_ERRORS 5 -#define ZEROEXPORT_DEF_INV_WAITINGTIME_MS 10000 #define ZEROEXPORT_GROUP_WR_LIMIT_MIN_DIFF 2 #define ZEROEXPORT_POWERMETER_SHELLY //#define ZEROEXPORT_POWERMETER_TASMOTA @@ -237,10 +236,7 @@ typedef enum { L1 = 1, L2 = 2, L3 = 3, - L1Sum = 4, - L2Sum = 5, - L3Sum = 6, -} zeroExportInverterTarget_t; +} zeroExportPowermeterTarget; typedef enum { none = 0, @@ -266,7 +262,6 @@ typedef struct { typedef struct { bool enabled; int8_t id; - int8_t target; uint16_t powerMin; uint16_t powerMax; bool turnOff; @@ -297,6 +292,7 @@ typedef struct { 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]; + uint8_t pm_target; // Inverters zeroExportGroupInverter_t inverters[ZEROEXPORT_GROUP_MAX_INVERTERS]; // Battery @@ -317,11 +313,6 @@ typedef struct { unsigned long lastRefresh; uint16_t wait; - int32_t pm_P; - int32_t pm_P1; - int32_t pm_P2; - int32_t pm_P3; - bool battSwitch; // PID controller @@ -687,11 +678,11 @@ class settings { 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); + mCfg.plugin.zeroExport.groups[group].pm_target = zeroExportPowermeterTarget::Sum; // Inverters for(uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { mCfg.plugin.zeroExport.groups[group].inverters[inv].enabled = false; mCfg.plugin.zeroExport.groups[group].inverters[inv].id = -1; - mCfg.plugin.zeroExport.groups[group].inverters[inv].target = -1; mCfg.plugin.zeroExport.groups[group].inverters[inv].powerMin = 10; mCfg.plugin.zeroExport.groups[group].inverters[inv].powerMax = 600; mCfg.plugin.zeroExport.groups[group].inverters[inv].turnOff = false; @@ -720,10 +711,10 @@ class settings { mCfg.plugin.zeroExport.groups[group].lastRun = 0; mCfg.plugin.zeroExport.groups[group].lastRefresh = 0; mCfg.plugin.zeroExport.groups[group].wait = 60000; - mCfg.plugin.zeroExport.groups[group].pm_P = 0; - mCfg.plugin.zeroExport.groups[group].pm_P1 = 0; - mCfg.plugin.zeroExport.groups[group].pm_P2 = 0; - mCfg.plugin.zeroExport.groups[group].pm_P3 = 0; +// mCfg.plugin.zeroExport.groups[group].pm_P = 0; +// mCfg.plugin.zeroExport.groups[group].pm_P1 = 0; +// mCfg.plugin.zeroExport.groups[group].pm_P2 = 0; +// mCfg.plugin.zeroExport.groups[group].pm_P3 = 0; mCfg.plugin.zeroExport.groups[group].battSwitch = false; mCfg.plugin.zeroExport.groups[group].power = 0; @@ -1017,7 +1008,6 @@ class settings { if(set) { obj[F("enabled")] = mCfg.plugin.zeroExport.groups[group].inverters[inv].enabled; obj[F("id")] = mCfg.plugin.zeroExport.groups[group].inverters[inv].id; - obj[F("target")] = mCfg.plugin.zeroExport.groups[group].inverters[inv].target; obj[F("powerMin")] = mCfg.plugin.zeroExport.groups[group].inverters[inv].powerMin; obj[F("powerMax")] = mCfg.plugin.zeroExport.groups[group].inverters[inv].powerMax; obj[F("turnOff")] = mCfg.plugin.zeroExport.groups[group].inverters[inv].turnOff; @@ -1026,8 +1016,6 @@ class settings { getVal(obj, F("enabled"), &mCfg.plugin.zeroExport.groups[group].inverters[inv].enabled); if (obj.containsKey(F("id"))) getVal(obj, F("id"), &mCfg.plugin.zeroExport.groups[group].inverters[inv].id); - if (obj.containsKey(F("target"))) - getVal(obj, F("target"), &mCfg.plugin.zeroExport.groups[group].inverters[inv].target); if (obj.containsKey(F("powerMin"))) getVal(obj, F("powerMin"), &mCfg.plugin.zeroExport.groups[group].inverters[inv].powerMin); if (obj.containsKey(F("powerMax"))) @@ -1049,6 +1037,7 @@ class settings { 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; + obj[F("pm_target")] = mCfg.plugin.zeroExport.groups[group].pm_target; // Inverters JsonArray invArr = obj.createNestedArray(F("inverters")); for(uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { @@ -1086,6 +1075,8 @@ class settings { getChar(obj, F("pm_user"), mCfg.plugin.zeroExport.groups[group].pm_user, ZEROEXPORT_GROUP_MAX_LEN_PM_USER); if (obj.containsKey(F("pm_pass"))) getChar(obj, F("pm_pass"), mCfg.plugin.zeroExport.groups[group].pm_pass, ZEROEXPORT_GROUP_MAX_LEN_PM_PASS); + if (obj.containsKey(F("pm_target"))) + getVal(obj, F("pm_target"), &mCfg.plugin.zeroExport.groups[group].pm_target); // Inverters if (obj.containsKey(F("inverters"))) { for(uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { diff --git a/src/defines.h b/src/defines.h index f5fa2832..e3798cc1 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 1030011 +#define VERSION_PATCH 1030012 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/plugins/zeroExport/powermeter.h b/src/plugins/zeroExport/powermeter.h index ff6c273d..43c31956 100644 --- a/src/plugins/zeroExport/powermeter.h +++ b/src/plugins/zeroExport/powermeter.h @@ -26,13 +26,6 @@ typedef struct { } OBISHandler; #endif -typedef struct { - float P; - float P1; - float P2; - float P3; -} PowermeterBuffer_t; - class powermeter { public: /** powermeter @@ -70,7 +63,8 @@ class powermeter { if (millis() - mPreviousTsp <= 1000) return; // skip when it is to fast mPreviousTsp = millis(); - PowermeterBuffer_t power; + 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; @@ -81,54 +75,48 @@ class powermeter { switch (mCfg->groups[group].pm_type) { #if defined(ZEROEXPORT_POWERMETER_SHELLY) case zeroExportPowermeterType_t::Shelly: - power = getPowermeterWattsShelly(*mLog, group); + result = getPowermeterWattsShelly(*mLog, group, &power); break; #endif #if defined(ZEROEXPORT_POWERMETER_TASMOTA) case zeroExportPowermeterType_t::Tasmota: - power = getPowermeterWattsTasmota(*mLog, group); - break; -#endif -#if defined(ZEROEXPORT_POWERMETER_MQTT) - case zeroExportPowermeterType_t::Mqtt: - /// power = getPowermeterWattsMqtt(*mLog, group); - continue; + result = getPowermeterWattsTasmota(*mLog, group, &power); break; #endif #if defined(ZEROEXPORT_POWERMETER_HICHI) case zeroExportPowermeterType_t::Hichi: - power = getPowermeterWattsHichi(*mLog, group); + result = getPowermeterWattsHichi(*mLog, group, &power); break; #endif #if defined(ZEROEXPORT_POWERMETER_TIBBER) case zeroExportPowermeterType_t::Tibber: - power = getPowermeterWattsTibber(*mLog, group); + result = getPowermeterWattsTibber(*mLog, group, &power); mPreviousTsp += 2000; // Zusätzliche Pause break; #endif #if defined(ZEROEXPORT_POWERMETER_SHRDZM) case zeroExportPowermeterType_t::Shrdzm: - power = getPowermeterWattsShrdzm(*mLog, group); + result = getPowermeterWattsShrdzm(*mLog, group, &power); break; #endif } - 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) + if (result) { + bufferWrite(power, group); + + // 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) + } } } } @@ -139,24 +127,33 @@ class powermeter { * @param group * @returns true/false */ - PowermeterBuffer_t getDataAVG(uint8_t group) { - PowermeterBuffer_t avg; - avg.P = avg.P1 = avg.P2 = avg.P2 = avg.P3 = 0; + float getDataAVG(uint8_t group) { + float avg = 0.0; for (int i = 0; i < 5; i++) { - avg.P += mPowermeterBuffer[group][i].P; - avg.P1 += mPowermeterBuffer[group][i].P1; - avg.P2 += mPowermeterBuffer[group][i].P2; - avg.P3 += mPowermeterBuffer[group][i].P3; + avg += mPowermeterBuffer[group][i]; } - avg.P = avg.P / 5; - avg.P1 = avg.P1 / 5; - avg.P2 = avg.P2 / 5; - avg.P3 = avg.P3 / 5; + avg = avg / 5.0; return avg; } + /** groupGetPowermeter + * Holt die Daten vom Powermeter + * @param group + * @returns true/false + */ + float getDataMIN(uint8_t group) { + 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]; + } + + return min; + } + /** * */ @@ -193,11 +190,8 @@ class powermeter { 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; + float power = 0.0; + power = (uint16_t)obj["val"]; bufferWrite(power, group); @@ -205,10 +199,10 @@ class 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); + 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(); @@ -253,7 +247,7 @@ class powermeter { unsigned long mPreviousTsp = 0; - PowermeterBuffer_t mPowermeterBuffer[ZEROEXPORT_MAX_GROUPS][5] = {0}; + float mPowermeterBuffer[ZEROEXPORT_MAX_GROUPS][5] = {0}; short mPowermeterBufferPos[ZEROEXPORT_MAX_GROUPS] = {0}; StaticJsonDocument<512> mqttDoc; // DynamicJsonDocument mqttDoc(512); @@ -279,10 +273,7 @@ class powermeter { * @param group * @returns true/false */ - PowermeterBuffer_t getPowermeterWattsShelly(JsonObject logObj, uint8_t group) { - PowermeterBuffer_t result; - result.P = result.P1 = result.P2 = result.P3 = 0; - + bool getPowermeterWattsShelly(JsonObject logObj, uint8_t group, float *power) { logObj["mod"] = "getPowermeterWattsShelly"; setHeader(&http); @@ -294,97 +285,69 @@ class powermeter { if (http.GET() == HTTP_CODE_OK) { // Parsing + // http.getSize()); + // TODO: Umstellen auf dynamische Größe DynamicJsonDocument doc(2048); DeserializationError error = deserializeJson(doc, http.getString()); if (error) { logObj["err"] = "deserializeJson: " + String(error.c_str()); - return result; + return false; } else { - if (doc.containsKey(F("total_power"))) { - // Shelly 3EM - result.P = doc["total_power"]; - } else if (doc.containsKey(F("em:0"))) { - // Shelly pro 3EM - result.P = doc["em:0"]["total_act_power"]; - } else if (doc.containsKey(F("total_act_power"))) { - // Shelly pro 3EM - result.P = doc["total_act_power"]; - } else { - // Keine Daten - result.P = 0; - } - - if (doc.containsKey(F("emeters"))) { - // Shelly 3EM - result.P1 = doc["emeters"][0]["power"]; - } else if (doc.containsKey(F("em:0"))) { - // Shelly pro 3EM - result.P1 = doc["em:0"]["a_act_power"]; - } else if (doc.containsKey(F("a_act_power"))) { - // Shelly pro 3EM - result.P1 = doc["a_act_power"]; - } else if (doc.containsKey(F("switch:0"))) { - // Shelly plus1pm plus2pm - result.P1 = doc["switch:0"]["apower"]; - result.P += result.P1; - } else if (doc.containsKey(F("apower"))) { - // Shelly Alternative - result.P1 = doc["apower"]; - result.P += result.P1; - } else { - // Keine Daten - result.P1 = 0; - } - - if (doc.containsKey(F("emeters"))) { - // Shelly 3EM - result.P2 = doc["emeters"][1]["power"]; - } else if (doc.containsKey(F("em:0"))) { - // Shelly pro 3EM - result.P2 = doc["em:0"]["b_act_power"]; - } else if (doc.containsKey(F("b_act_power"))) { - // Shelly pro 3EM - result.P2 = doc["b_act_power"]; - } else if (doc.containsKey(F("switch:1"))) { - // Shelly plus1pm plus2pm - result.P2 = doc["switch.1"]["apower"]; - result.P += result.P2; - //} else if (doc.containsKey(F("apower"))) { - // Shelly Alternative - // mCfg->groups[group].pmPowerL2 = doc["apower"]; - // mCfg->groups[group].pmPower += mCfg->groups[group].pmPowerL2; - // ret = true; - } else { - // Keine Daten - result.P2 = 0; - } - - if (doc.containsKey(F("emeters"))) { - // Shelly 3EM - result.P3 = doc["emeters"][2]["power"]; - } else if (doc.containsKey(F("em:0"))) { - // Shelly pro 3EM - result.P3 = doc["em:0"]["c_act_power"]; - } else if (doc.containsKey(F("c_act_power"))) { - // Shelly pro 3EM - result.P3 = doc["c_act_power"]; - } else if (doc.containsKey(F("switch:2"))) { - // Shelly plus1pm plus2pm - result.P3 = doc["switch:2"]["apower"]; - result.P += result.P3; - //} else if (doc.containsKey(F("apower"))) { - // Shelly Alternative - // mCfg->groups[group].pmPowerL3 = doc["apower"]; - // mCfg->groups[group].pmPower += mCfg->groups[group].pmPowerL3; - // result = true; - } else { - // Keine Daten - result.P3 = 0; + switch (mCfg->groups[group].pm_target) { + case zeroExportPowermeterTarget::L1: + if (doc.containsKey(F("emeters"))) { + // Shelly 3EM + *power = doc["emeters"][0]["power"]; + } else if (doc.containsKey(F("em:0"))) { + // Shelly pro 3EM + *power = doc["em:0"]["a_act_power"]; + } else if (doc.containsKey(F("a_act_power"))) { + // Shelly pro 3EM + *power = doc["a_act_power"]; + } + break; + case zeroExportPowermeterTarget::L2: + if (doc.containsKey(F("emeters"))) { + // Shelly 3EM + *power = doc["emeters"][1]["power"]; + } else if (doc.containsKey(F("em:0"))) { + // Shelly pro 3EM + *power = doc["em:0"]["b_act_power"]; + } else if (doc.containsKey(F("b_act_power"))) { + // Shelly pro 3EM + *power = doc["b_act_power"]; + } + break; + case zeroExportPowermeterTarget::L3: + if (doc.containsKey(F("emeters"))) { + // Shelly 3EM + *power = doc["emeters"][2]["power"]; + } else if (doc.containsKey(F("em:0"))) { + // Shelly pro 3EM + *power = doc["em:0"]["c_act_power"]; + } else if (doc.containsKey(F("c_act_power"))) { + // Shelly pro 3EM + *power = doc["c_act_power"]; + } + break; + case zeroExportPowermeterTarget::Sum: + default: + if (doc.containsKey(F("total_power"))) { + // Shelly 3EM + *power = doc["total_power"]; + } else if (doc.containsKey(F("em:0"))) { + // Shelly pro 3EM + *power = doc["em:0"]["total_act_power"]; + } else if (doc.containsKey(F("total_act_power"))) { + // Shelly pro 3EM + *power = doc["total_act_power"]; + } + break; } } } http.end(); - return result; + return true; } #endif @@ -395,10 +358,7 @@ class powermeter { * @param group * @returns true/false */ - PowermeterBuffer_t getPowermeterWattsTasmota(JsonObject logObj, uint8_t group) { - PowermeterBuffer_t result; - result.P = result.P1 = result.P2 = result.P3 = 0; - + bool getPowermeterWattsTasmota(JsonObject logObj, uint8_t group, float *power) { logObj["mod"] = "getPowermeterWattsTasmota"; /* // TODO: nicht komplett @@ -459,31 +419,10 @@ class powermeter { } http.end(); */ - return result; + return false; } #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 * ... @@ -491,10 +430,7 @@ class powermeter { * @param group * @returns true/false */ - PowermeterBuffer_t getPowermeterWattsHichi(JsonObject logObj, uint8_t group) { - PowermeterBuffer_t result; - result.P = result.P1 = result.P2 = result.P3 = 0; - + bool getPowermeterWattsHichi(JsonObject logObj, uint8_t group, float *power) { logObj["mod"] = "getPowermeterWattsHichi"; // Hier neuer Code - Anfang @@ -503,7 +439,7 @@ class powermeter { // Hier neuer Code - Ende - return result; + return false; } #endif @@ -545,11 +481,10 @@ class powermeter { {{0x01, 0x00, 0x01, 0x08, 0x00, 0xff}, &smlOBISWh, &_powerMeterImport}, {{0x01, 0x00, 0x02, 0x08, 0x00, 0xff}, &smlOBISWh, &_powerMeterExport}}; - PowermeterBuffer_t getPowermeterWattsTibber(JsonObject logObj, uint8_t group) { + bool getPowermeterWattsTibber(JsonObject logObj, uint8_t group, float *power) { mPreviousTsp = mPreviousTsp + 2000; // Zusätzliche Pause - PowermeterBuffer_t result; - result.P = result.P1 = result.P2 = result.P3 = 0; + bool result = false; logObj["mod"] = "getPowermeterWattsTibber"; @@ -580,14 +515,8 @@ class powermeter { switch (smlCurrentState) { case SML_FINAL: - result.P = _powerMeterTotal; - result.P1 = _powerMeter1Power; - result.P2 = _powerMeter2Power; - result.P3 = _powerMeter3Power; - - if (!(_powerMeter1Power && _powerMeter2Power && _powerMeter3Power)) { - result.P1 = result.P2 = result.P3 = _powerMeterTotal / 3; - } + *power = _powerMeterTotal; + result = true; break; case SML_LISTEND: // check handlers on last received list @@ -616,10 +545,7 @@ class powermeter { * @TODO: Username & Passwort wird mittels base64 verschlüsselt. Dies wird für die Authentizierung benötigt. Wichtig diese im WebUI unkenntlich zu machen und base64 im eeprom zu speichern, statt klartext. * @TODO: Abfrage Interval einbauen. Info: Datei-Size kann auch mal 0-bytes sein? */ - PowermeterBuffer_t getPowermeterWattsShrdzm(JsonObject logObj, uint8_t group) { - PowermeterBuffer_t result; - result.P = result.P1 = result.P2 = result.P3 = 0; - + bool getPowermeterWattsShrdzm(JsonObject logObj, uint8_t group, float *power) { logObj["mod"] = "getPowermeterWattsShrdzm"; setHeader(&http); @@ -636,27 +562,23 @@ class powermeter { DeserializationError error = deserializeJson(doc, http.getString()); if (error) { logObj["err"] = "deserializeJson: " + String(error.c_str()); - return result; + return false; } else { if (doc.containsKey(F("16.7.0"))) { - result.P = doc["16.7.0"]; - } - - if (!(result.P1 && result.P2 && result.P3)) { - result.P1 = result.P2 = result.P3 = result.P / 3; + *power = doc["16.7.0"]; } } } http.end(); - return result; + return true; } #endif /** * */ - void bufferWrite(PowermeterBuffer_t raw, short group) { + void bufferWrite(float raw, short group) { mPowermeterBuffer[group][mPowermeterBufferPos[group]] = raw; mPowermeterBufferPos[group]++; if (mPowermeterBufferPos[group] >= 5) mPowermeterBufferPos[group] = 0; diff --git a/src/plugins/zeroExport/zeroExport.h b/src/plugins/zeroExport/zeroExport.h index a5720a74..644f1535 100644 --- a/src/plugins/zeroExport/zeroExport.h +++ b/src/plugins/zeroExport/zeroExport.h @@ -166,45 +166,10 @@ class ZeroExport { // Regelgröße x in Watt int16_t x = 0.0; - int16_t xSum = 0.0; - switch (CfgGroupInv->target) { - case zeroExportInverterTarget_t::Sum: - x = mPowermeter.getDataAVG(group).P; - break; - case zeroExportInverterTarget_t::L1: - x = mPowermeter.getDataAVG(group).P1; - break; - case zeroExportInverterTarget_t::L2: - x = mPowermeter.getDataAVG(group).P2; - break; - case zeroExportInverterTarget_t::L3: - x = mPowermeter.getDataAVG(group).P3; - break; - case zeroExportInverterTarget_t::L1Sum: - x = mPowermeter.getDataAVG(group).P1; - xSum = mPowermeter.getDataAVG(group).P; - xSum -= mPowermeter.getDataAVG(group).P2; - xSum -= mPowermeter.getDataAVG(group).P3; - if (xSum > x) x = xSum; - break; - case zeroExportInverterTarget_t::L2Sum: - x = mPowermeter.getDataAVG(group).P2; - xSum = mPowermeter.getDataAVG(group).P; - xSum -= mPowermeter.getDataAVG(group).P1; - xSum -= mPowermeter.getDataAVG(group).P3; - if (xSum > x) x = xSum; - break; - case zeroExportInverterTarget_t::L3Sum: - x = mPowermeter.getDataAVG(group).P3; - xSum = mPowermeter.getDataAVG(group).P; - xSum -= mPowermeter.getDataAVG(group).P1; - xSum -= mPowermeter.getDataAVG(group).P2; - if (xSum > x) x = xSum; - break; - default: - x = w; - // TODO: ErrorLog - break; + if (CfgGroup->minimum) { + x = mPowermeter.getDataMIN(group); + } else { + x = mPowermeter.getDataAVG(group); } mLog["x"] = x; diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 86b27003..21123be6 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -843,6 +843,7 @@ class RestApi { 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); + objGroup[F("pm_target")] = (uint8_t)mConfig->plugin.zeroExport.groups[group].pm_target; // Inverters objGroup[F("max_inverters")] = ZEROEXPORT_GROUP_MAX_INVERTERS; JsonArray arrInv = objGroup.createNestedArray(F("inverters")); @@ -850,7 +851,6 @@ class RestApi { JsonObject objGroupInv = arrInv.createNestedObject(); objGroupInv[F("enabled")] = (bool)mConfig->plugin.zeroExport.groups[group].inverters[inv].enabled; objGroupInv[F("id")] = (int8_t)mConfig->plugin.zeroExport.groups[group].inverters[inv].id; - objGroupInv[F("target")] = (int8_t)mConfig->plugin.zeroExport.groups[group].inverters[inv].target; objGroupInv[F("powerMin")] = (uint16_t)mConfig->plugin.zeroExport.groups[group].inverters[inv].powerMin; objGroupInv[F("powerMax")] = (uint16_t)mConfig->plugin.zeroExport.groups[group].inverters[inv].powerMax; objGroupInv[F("turnOff")] = (uint16_t)mConfig->plugin.zeroExport.groups[group].inverters[inv].turnOff; @@ -1163,11 +1163,11 @@ class RestApi { 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()); + mConfig->plugin.zeroExport.groups[group].pm_target = jsonIn[F("pm_target")]; // Inverters for(uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { mConfig->plugin.zeroExport.groups[group].inverters[inv].enabled = jsonIn[F("inverters")][inv][F("enabled")]; mConfig->plugin.zeroExport.groups[group].inverters[inv].id = jsonIn[F("inverters")][inv][F("id")]; - mConfig->plugin.zeroExport.groups[group].inverters[inv].target = jsonIn[F("inverters")][inv][F("target")]; mConfig->plugin.zeroExport.groups[group].inverters[inv].powerMin = jsonIn[F("inverters")][inv][F("powerMin")]; mConfig->plugin.zeroExport.groups[group].inverters[inv].powerMax = jsonIn[F("inverters")][inv][F("powerMax")]; mConfig->plugin.zeroExport.groups[group].inverters[inv].turnOff = jsonIn[F("inverters")][inv][F("turnOff")]; diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 35b0ca5b..0cf9817e 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -1321,7 +1321,6 @@ ml("th", {style: "width: 10%;"}, ml("input", {name: "invMax", id: "invMax", type: "hidden", value: maxInv}, null)), ml("th", {style: "width: 10%;"}, "{#ZE_GROUP_TAB_INVERTER_ENABLED}"), ml("th", {}, "{#ZE_GROUP_TAB_INVERTER_NAME}"), - ml("th", {}, "{#ZE_GROUP_TAB_INVERTER_SUM}"), ml("th", {style: "width: 15%;"}, "{#ZE_GROUP_TAB_INVERTER_POWERMIN}"), ml("th", {style: "width: 15%;"}, "{#ZE_GROUP_TAB_INVERTER_POWERMAX}"), ml("th", {style: "width: 5%;"}, "{#ZE_GROUP_TAB_INVERTER_TURNOFF}"), @@ -1340,11 +1339,6 @@ ml("select", {name: "invId"+inv, class: "text", id: "invId"+inv}, null), ]), ), - ml("td", {}, - ml("div", {}, [ - ml("select", {name: "invTarget"+inv, class: "text", id: "invTarget"+inv}, null), - ]), - ), ml("td", {}, ml("div", {}, [ ml("input", {name: "invPowerMin"+inv, class: "text", id: "invPowerMin"+inv, type: "number", min: "0", max: "65535"}, null) @@ -1407,6 +1401,9 @@ divRow("{#ZE_GROUP_TAB_POWERMETER_PASS}", ml("input", {name: "pm_pass", class: "text", type: "password", value: "****"}, null), ), + divRow("{#ZE_GROUP_TAB_POWERMETER_TARGET}", + ml("select", {name: "pm_target", class: "text", id: "pm_target"}, 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."), @@ -1480,6 +1477,8 @@ modal("{#ZE_GROUP_EDIT_MODAL}: " + obj.id, html); // ser.dispatchEvent(new Event('change')); + // Tab_Powermeter + // - pm_type // Inhalt fuer pm_type aus config laden und in eine Funktion ausgliedern var e = document.getElementById("pm_type"); selDelAllOpt(e); @@ -1496,6 +1495,18 @@ e.selectedIndex = i; } } + // - pm_target + var e = document.getElementById("pm_target"); + selDelAllOpt(e); + e.appendChild(opt("0", "Sum")); + e.appendChild(opt("1", "L1")); + e.appendChild(opt("2", "L2")); + e.appendChild(opt("3", "L3")); + for (var i = 0; i < e.options.length; i++) { + if (e.options[i].value == obj.pm_target) { + e.selectedIndex = i; + } + } // Tab_Inverters // - Enabled @@ -1517,25 +1528,6 @@ } } } - // - Target - for (var inv = 0; inv < maxInv; inv++) { - var e = document.getElementById("invTarget"+inv); - selDelAllOpt(e); -// TODO: ?bersetzen? - e.appendChild(opt("-1", "---")); - e.appendChild(opt("0", "Sum")); - e.appendChild(opt("1", "L1")); - e.appendChild(opt("2", "L2")); - e.appendChild(opt("3", "L3")); - e.appendChild(opt("4", "L1 + Sum")); - e.appendChild(opt("5", "L2 + Sum")); - e.appendChild(opt("6", "L3 + Sum")); - for (var i = 0; i < e.options.length; i++) { - if (e.options[i].value == obj.inverters[inv].target) { - e.selectedIndex = i; - } - } - } // - powerMin for (var inv = 0; inv < maxInv; inv++) { var e = document.getElementById("invPowerMin"+inv); @@ -1583,6 +1575,8 @@ 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; + var e = document.getElementsByName("pm_target")[0]; + o.pm_target = e.options[e.selectedIndex].value; // Inverters o.invMax = document.getElementById("invMax").value; o.inverters = []; @@ -1591,8 +1585,6 @@ q.enabled = document.getElementById("invEnabled"+inv).checked; var e = document.getElementById("invId"+inv); q.id = e.options[e.selectedIndex].value; - var e = document.getElementById("invTarget"+inv); - q.target = e.options[e.selectedIndex].value; q.powerMin = document.getElementById("invPowerMin"+inv).value; q.powerMax = document.getElementById("invPowerMax"+inv).value; q.turnOff = document.getElementById("invTurnOff"+inv).checked; @@ -1650,6 +1642,7 @@ o.pm_jsonPath = ""; o.pm_user = ""; o.pm_pass = ""; + o.pm_target = 0; // Inverters o.invMax = obj.inverters.length; o.inverters = []; @@ -1658,8 +1651,6 @@ q.enabled = false; var e = document.getElementById("invId"+inv); q.id = -1; - var e = document.getElementById("invTarget"+inv); - q.target = -1; q.powerMin = 0; q.powerMax = 0; q.turnOff = false; diff --git a/src/web/lang.json b/src/web/lang.json index 8c3a7a4b..87b2459a 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -913,6 +913,11 @@ "en": "Password:", "de": "Passwort:" }, + { + "token": "ZE_GROUP_TAB_POWERMETER_TARGET", + "en": "Target:", + "de": "Ziel:" + }, { "token": "ZE_GROUP_TAB_INVERTER", "en": "Inverter", @@ -928,11 +933,6 @@ "en": "Name", "de": "Name" }, - { - "token": "ZE_GROUP_TAB_INVERTER_SUM", - "en": "Sum", - "de": "Gesamt" - }, { "token": "ZE_GROUP_TAB_INVERTER_POWERMIN", "en": "Power (Min)",