diff --git a/src/config/settings.h b/src/config/settings.h index bcc34c5a..d412094e 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -210,7 +210,7 @@ typedef struct { #define ZEROEXPORT_GROUP_MAX_LEN_PM_JSONPATH 100 #define ZEROEXPORT_GROUP_MAX_LEN_PM_USER 25 #define ZEROEXPORT_GROUP_MAX_LEN_PM_PASS 25 -#define ZEROEXPORT_GROUP_MAX_LEN_BATTERY_SOC 100 +#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 @@ -242,6 +242,13 @@ typedef enum { L3Sum = 6, } zeroExportInverterTarget_t; +typedef enum { + none = 0, + invUdc, + mqttU, + mqttSoC +} zeroExportBatteryCfg; + typedef enum { doNone = 0, doRestart, @@ -293,10 +300,11 @@ typedef struct { // Inverters zeroExportGroupInverter_t inverters[ZEROEXPORT_GROUP_MAX_INVERTERS]; // Battery - bool battEnabled; - float battVoltageOn; - float battVoltageOff; - char battSoC[ZEROEXPORT_GROUP_MAX_LEN_BATTERY_SOC]; + uint8_t battCfg; + char battTopic[ZEROEXPORT_GROUP_MAX_LEN_BATT_TOPIC]; + float battValue; + float battLimitOn; + float battLimitOff; // Advanced int16_t setPoint; bool minimum; @@ -696,10 +704,10 @@ class settings { mCfg.plugin.zeroExport.groups[group].inverters[inv].limitNew = 0; } // Battery - mCfg.plugin.zeroExport.groups[group].battEnabled = false; - mCfg.plugin.zeroExport.groups[group].battVoltageOn = 0; - mCfg.plugin.zeroExport.groups[group].battVoltageOff = 0; - snprintf(mCfg.plugin.zeroExport.groups[group].battSoC, ZEROEXPORT_GROUP_MAX_LEN_BATTERY_SOC, "%s", DEF_ZEXPORT); + mCfg.plugin.zeroExport.groups[group].battCfg = zeroExportBatteryCfg::none; + snprintf(mCfg.plugin.zeroExport.groups[group].battTopic, ZEROEXPORT_GROUP_MAX_LEN_BATT_TOPIC, "%s", DEF_ZEXPORT); + mCfg.plugin.zeroExport.groups[group].battLimitOn = 0; + mCfg.plugin.zeroExport.groups[group].battLimitOff = 0; // Advanced mCfg.plugin.zeroExport.groups[group].setPoint = 0; mCfg.plugin.zeroExport.groups[group].minimum = true; @@ -1047,10 +1055,10 @@ class settings { jsonZeroExportGroupInverter(invArr.createNestedObject(), group, inv, set); } // Battery - obj[F("battEnabled")] = mCfg.plugin.zeroExport.groups[group].battEnabled; - obj[F("battVoltageOn")] = mCfg.plugin.zeroExport.groups[group].battVoltageOn; - obj[F("battVoltageOff")] = mCfg.plugin.zeroExport.groups[group].battVoltageOff; - obj[F("battSoC")] = mCfg.plugin.zeroExport.groups[group].battSoC; + obj[F("battCfg")] = mCfg.plugin.zeroExport.groups[group].battCfg; + obj[F("battTopic")] = mCfg.plugin.zeroExport.groups[group].battTopic; + obj[F("battLimitOn")] = mCfg.plugin.zeroExport.groups[group].battLimitOn; + obj[F("battLimitOff")] = mCfg.plugin.zeroExport.groups[group].battLimitOff; // Advanced obj[F("setPoint")] = mCfg.plugin.zeroExport.groups[group].setPoint; obj[F("minimum")] = mCfg.plugin.zeroExport.groups[group].minimum; @@ -1085,14 +1093,14 @@ class settings { } } // Battery - if (obj.containsKey(F("battEnabled"))) - getVal(obj, F("battEnabled"), &mCfg.plugin.zeroExport.groups[group].battEnabled); - if (obj.containsKey(F("battVoltageOn"))) - getVal(obj, F("battVoltageOn"), &mCfg.plugin.zeroExport.groups[group].battVoltageOn); - if (obj.containsKey(F("battVoltageOff"))) - getVal(obj, F("battVoltageOff"), &mCfg.plugin.zeroExport.groups[group].battVoltageOff); - if (obj.containsKey(F("battSoC"))) - getChar(obj, F("battSoC"), mCfg.plugin.zeroExport.groups[group].battSoC, ZEROEXPORT_GROUP_MAX_LEN_BATTERY_SOC); + if (obj.containsKey(F("battCfg"))) + getVal(obj, F("battCfg"), &mCfg.plugin.zeroExport.groups[group].battCfg); + if (obj.containsKey(F("battTopic"))) + getChar(obj, F("battTopic"), mCfg.plugin.zeroExport.groups[group].battTopic, ZEROEXPORT_GROUP_MAX_LEN_BATT_TOPIC); + if (obj.containsKey(F("battLimitOn"))) + getVal(obj, F("battLimitOn"), &mCfg.plugin.zeroExport.groups[group].battLimitOn); + if (obj.containsKey(F("battLimitOff"))) + getVal(obj, F("battLimitOff"), &mCfg.plugin.zeroExport.groups[group].battLimitOff); // Advanced if (obj.containsKey(F("setPoint"))) getVal(obj, F("setPoint"), &mCfg.plugin.zeroExport.groups[group].setPoint); diff --git a/src/defines.h b/src/defines.h index 0ea72c56..f5fa2832 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 1030010 +#define VERSION_PATCH 1030011 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/plugins/zeroExport/zeroExport.h b/src/plugins/zeroExport/zeroExport.h index d70f5e3f..a5720a74 100644 --- a/src/plugins/zeroExport/zeroExport.h +++ b/src/plugins/zeroExport/zeroExport.h @@ -121,29 +121,40 @@ class ZeroExport { mLog["gL"] = groupLimit; // Batteryprotection - mLog["bEn"] = CfgGroup->battEnabled; - if (CfgGroup->battEnabled) { - if (CfgGroup->battSwitch != true) { - if (CfgGroupInv->dcVoltage > CfgGroup->battVoltageOn) { + mLog["bEn"] = (uint8_t)CfgGroup->battCfg; + switch (CfgGroup->battCfg) { + case zeroExportBatteryCfg::none: + if (CfgGroup->battSwitch != true) { CfgGroup->battSwitch = true; mLog["bA"] = "turn on"; } - if ((CfgGroupInv->dcVoltage > CfgGroup->battVoltageOff) && (CfgGroupInv->power > 0)) { - CfgGroup->battSwitch = true; - mLog["bA"] = "turn on"; + break; + case zeroExportBatteryCfg::invUdc: + case zeroExportBatteryCfg::mqttU: + case zeroExportBatteryCfg::mqttSoC: + if (CfgGroup->battSwitch != true) { + if (CfgGroup->battValue > CfgGroup->battLimitOn) { + CfgGroup->battSwitch = true; + mLog["bA"] = "turn on"; + } + if ((CfgGroup->battValue > CfgGroup->battLimitOff) && (CfgGroupInv->power > 0)) { + CfgGroup->battSwitch = true; + mLog["bA"] = "turn on"; + } + } else { + if (CfgGroup->battValue < CfgGroup->battLimitOff) { + CfgGroup->battSwitch = false; + mLog["bA"] = "turn off"; + } } - } else { - if (CfgGroupInv->dcVoltage < CfgGroup->battVoltageOff) { + mLog["bU"] = ah::round1(CfgGroup->battValue); + break; + default: + if (CfgGroup->battSwitch == true) { CfgGroup->battSwitch = false; mLog["bA"] = "turn off"; } - } - mLog["bU"] = ah::round1(CfgGroupInv->dcVoltage); - } else { - if (CfgGroup->battSwitch != true) { - CfgGroup->battSwitch = true; - mLog["bA"] = "turn on"; - } + break; } mLog["bSw"] = CfgGroup->battSwitch; @@ -309,8 +320,8 @@ class ZeroExport { } } -// CfgGroupInv->actionTimer = 0; -// TODO: Timer stoppen wenn Limit gesetzt wird. + // CfgGroupInv->actionTimer = 0; + // TODO: Timer stoppen wenn Limit gesetzt wird. mLog["lN"] = CfgGroupInv->limitNew; CfgGroupInv->limit = CfgGroupInv->limitNew; @@ -553,27 +564,37 @@ class ZeroExport { CfgGroupInv->dcVoltage = iv->getChannelFieldValue(CH1, FLD_UDC, rec); mLog["bU"] = ah::round1(CfgGroupInv->dcVoltage); -// Fallschirm 2: Für nicht übernommene Limits bzw. nicht regelnde Inverter -// Bisher ist nicht geklärt ob der Inverter das Limit bestätigt hat -// Erstmalig aufgetreten bei @knickohr am 28.04.2024 ... l=300 pM=300, p=9 -if (CfgGroupInv->MaxPower > 0) { -uint16_t limitPercent = 100 / CfgGroupInv->MaxPower * CfgGroupInv->limit; -uint16_t powerPercent = 100 / CfgGroupInv->MaxPower * CfgGroupInv->power; -uint16_t delta = abs(limitPercent - powerPercent); -if ((delta > 10) && (CfgGroupInv->power > 0)) { - mLog["delta"] = delta; - unsigned long delay = iv->getLastTs(rec) - CfgGroupInv->actionTimestamp; - mLog["delay"] = delay; - if (delay > 30000) { - CfgGroupInv->action = zeroExportAction_t::doActivePowerContr; - mLog["do"] = "doActivePowerContr"; - } - if (delay > 60000) { - CfgGroupInv->action = zeroExportAction_t::doRestart; - mLog["do"] = "doRestart"; - } -} -} + // Batterieüberwachung - Überwachung über die DC-Spannung am PV-Eingang 1 des Inverters + if (CfgGroup->battCfg == zeroExportBatteryCfg::invUdc) { + if ((CfgGroup->battSwitch == false) && (CfgGroup->battValue < CfgGroupInv->dcVoltage)) { + CfgGroup->battValue = CfgGroupInv->dcVoltage; + } + if ((CfgGroup->battSwitch == true) && (CfgGroup->battValue > CfgGroupInv->dcVoltage)) { + CfgGroup->battValue = CfgGroupInv->dcVoltage; + } + } + + // Fallschirm 2: Für nicht übernommene Limits bzw. nicht regelnde Inverter + // Bisher ist nicht geklärt ob der Inverter das Limit bestätigt hat + // Erstmalig aufgetreten bei @knickohr am 28.04.2024 ... l=300 pM=300, p=9 + if (CfgGroupInv->MaxPower > 0) { + uint16_t limitPercent = 100 / CfgGroupInv->MaxPower * CfgGroupInv->limit; + uint16_t powerPercent = 100 / CfgGroupInv->MaxPower * CfgGroupInv->power; + uint16_t delta = abs(limitPercent - powerPercent); + if ((delta > 10) && (CfgGroupInv->power > 0)) { + mLog["delta"] = delta; + unsigned long delay = iv->getLastTs(rec) - CfgGroupInv->actionTimestamp; + mLog["delay"] = delay; + if (delay > 30000) { + CfgGroupInv->action = zeroExportAction_t::doActivePowerContr; + mLog["do"] = "doActivePowerContr"; + } + if (delay > 60000) { + CfgGroupInv->action = zeroExportAction_t::doRestart; + mLog["do"] = "doRestart"; + } + } + } } zeroExportQueue_t Entry; @@ -600,12 +621,15 @@ if ((delta > 10) && (CfgGroupInv->power > 0)) { mPowermeter.onMqttConnect(); + // "topic":"userdefined battSoCTopic" for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { - if (!mCfg->groups [group].enabled) continue; + if (!mCfg->groups[group].enabled) continue; + + if ((!mCfg->groups[group].battCfg == zeroExportBatteryCfg::mqttU) && (!mCfg->groups[group].battCfg == zeroExportBatteryCfg::mqttSoC)) continue; - if(!strcmp(mCfg->groups[group].battSoC, "")) continue; + if (!strcmp(mCfg->groups[group].battTopic, "")) continue; - mMqtt->subscribeExtern(String(mCfg->groups[group].battSoC).c_str(), QOS_2); + mMqtt->subscribeExtern(String(mCfg->groups[group].battTopic).c_str(), QOS_2); } } @@ -621,13 +645,22 @@ if ((delta > 10) && (CfgGroupInv->power > 0)) { String topic = String(obj["topic"]); -/// TODO: Receive Message für SoC -// if ((topicGroup >= 0) && (topicGroup < ZEROEXPORT_MAX_GROUPS)) { -// if (topic.indexOf("xxx") != -1) { + // "topic":"userdefined battSoCTopic" + for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { + if (!mCfg->groups[group].enabled) continue; + + if ((!mCfg->groups[group].battCfg == zeroExportBatteryCfg::mqttU) && (!mCfg->groups[group].battCfg == zeroExportBatteryCfg::mqttSoC)) continue; -// } -// } + if (!strcmp(mCfg->groups[group].battTopic, "")) continue; + + if (strcmp(mCfg->groups[group].battTopic, String(topic).c_str())) { + mCfg->groups[group].battValue = (bool)obj["val"]; + mLog["k"] = mCfg->groups[group].battTopic; + mLog["v"] = mCfg->groups[group].battValue; + } + } + // "topic":"ctrl/zero" if (topic.indexOf("ctrl/zero") == -1) return; if (mCfg->debug) mLog["d"] = obj; @@ -669,27 +702,27 @@ if ((delta > 10) && (CfgGroupInv->power > 0)) { mLog["v"] = mCfg->groups[topicGroup].sleep; } -// Auf Eis gelegt, dafür 2 Gruppen mehr -// 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()); -/// 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()); -// mLog["k"] = "ctrl/zero/groups/" + String(topicGroup) + "/pm_ip"; -// mLog["v"] = mCfg->groups[topicGroup].pm_url; -// } -// -// // "topic":"ctrl/zero/groups/+/pm_jsonPath" -// if (topic.indexOf("ctrl/zero/groups/" + String(topicGroup) + "/pm_jsonPath") != -1) { -/// TODO: -// snprintf(mCfg->groups[topicGroup].pm_jsonPath, ZEROEXPORT_GROUP_MAX_LEN_PM_JSONPATH, "%s", obj[F("val")].as()); -// mLog["k"] = "ctrl/zero/groups/" + String(topicGroup) + "/pm_jsonPath"; -// mLog["v"] = mCfg->groups[topicGroup].pm_jsonPath; -// } + // Auf Eis gelegt, dafür 2 Gruppen mehr + // 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()); + /// 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()); + // mLog["k"] = "ctrl/zero/groups/" + String(topicGroup) + "/pm_ip"; + // mLog["v"] = mCfg->groups[topicGroup].pm_url; + // } + // + // // "topic":"ctrl/zero/groups/+/pm_jsonPath" + // if (topic.indexOf("ctrl/zero/groups/" + String(topicGroup) + "/pm_jsonPath") != -1) { + /// TODO: + // snprintf(mCfg->groups[topicGroup].pm_jsonPath, ZEROEXPORT_GROUP_MAX_LEN_PM_JSONPATH, "%s", obj[F("val")].as()); + // mLog["k"] = "ctrl/zero/groups/" + String(topicGroup) + "/pm_jsonPath"; + // mLog["v"] = mCfg->groups[topicGroup].pm_jsonPath; + // } // "topic":"ctrl/zero/groups/+/battery/switch" if (topic.indexOf("ctrl/zero/groups/" + String(topicGroup) + "/battery/switch") != -1) { diff --git a/src/web/RestApi.h b/src/web/RestApi.h index e7a6244c..86b27003 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -856,10 +856,10 @@ class RestApi { objGroupInv[F("turnOff")] = (uint16_t)mConfig->plugin.zeroExport.groups[group].inverters[inv].turnOff; } // Battery - objGroup[F("battEnabled")] = (bool)mConfig->plugin.zeroExport.groups[group].battEnabled; - objGroup[F("battVoltageOn")] = ah::round1((float)mConfig->plugin.zeroExport.groups[group].battVoltageOn); - objGroup[F("battVoltageOff")] = ah::round1((float)mConfig->plugin.zeroExport.groups[group].battVoltageOff); - objGroup[F("battSoC")] = String(mConfig->plugin.zeroExport.groups[group].battSoC); + objGroup[F("battCfg")] = (uint8_t)mConfig->plugin.zeroExport.groups[group].battCfg; + objGroup[F("battTopic")] = String(mConfig->plugin.zeroExport.groups[group].battTopic); + objGroup[F("battLimitOn")] = ah::round1((float)mConfig->plugin.zeroExport.groups[group].battLimitOn); + objGroup[F("battLimitOff")] = ah::round1((float)mConfig->plugin.zeroExport.groups[group].battLimitOff); // Advanced objGroup[F("setPoint")] = (int16_t)mConfig->plugin.zeroExport.groups[group].setPoint; objGroup[F("minimum")] = (bool)mConfig->plugin.zeroExport.groups[group].minimum; @@ -1173,10 +1173,10 @@ class RestApi { mConfig->plugin.zeroExport.groups[group].inverters[inv].turnOff = jsonIn[F("inverters")][inv][F("turnOff")]; } // Battery - mConfig->plugin.zeroExport.groups[group].battEnabled = jsonIn[F("battEnabled")]; - mConfig->plugin.zeroExport.groups[group].battVoltageOn = jsonIn[F("battVoltageOn")]; - mConfig->plugin.zeroExport.groups[group].battVoltageOff = jsonIn[F("battVoltageOff")]; - snprintf(mConfig->plugin.zeroExport.groups[group].battSoC, ZEROEXPORT_GROUP_MAX_LEN_BATTERY_SOC, "%s", jsonIn[F("battSoC")].as()); + mConfig->plugin.zeroExport.groups[group].battCfg = jsonIn[F("battCfg")]; + snprintf(mConfig->plugin.zeroExport.groups[group].battTopic, ZEROEXPORT_GROUP_MAX_LEN_BATT_TOPIC, "%s", jsonIn[F("battTopic")].as()); + mConfig->plugin.zeroExport.groups[group].battLimitOn = jsonIn[F("battLimitOn")]; + mConfig->plugin.zeroExport.groups[group].battLimitOff = jsonIn[F("battLimitOff")]; // Advanced mConfig->plugin.zeroExport.groups[group].setPoint = jsonIn[F("setPoint")]; mConfig->plugin.zeroExport.groups[group].minimum = jsonIn[F("minimum")]; diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 5cedc4e4..35b0ca5b 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -1364,8 +1364,6 @@ } // Tab_Battery - var cb_battEnabled = ml("input", {name: "battEnabled", type: "checkbox"}, null); - cb_battEnabled.checked = (obj.battEnabled); // Tab_Advanced var cb_minimum = ml("input", {name: "minimum", type: "checkbox"}, null); @@ -1432,10 +1430,18 @@ ]), // Battery ml("div", {id: "div{#ZE_GROUP_TAB_BATTERY}", class: "tab-content hide"}, [ - divRow("{#ZE_GROUP_TAB_BATTERY_ENABLED}", cb_battEnabled), - divRow("{#ZE_GROUP_TAB_BATTERY_VOLTAGEON}", ml("input", {name: "battVoltageOn", class: "text", type: "number", min: "0", max: "100", step: "0.1", value: obj.battVoltageOn}, null)), - divRow("{#ZE_GROUP_TAB_BATTERY_VOLTAGEOFF}", ml("input", {name: "battVoltageOff", class: "text", type: "number", min: "0", max: "100", step: "0.1", value: obj.battVoltageOff}, null)), - divRow("{#ZE_GROUP_TAB_BATTERY_SOC}", ml("input", {name: "battSoC", class: "text", type: "text", value: obj.battSoC}, null)), + divRow("{#ZE_GROUP_TAB_BATTERY_CFG}", + ml("select", {name: "battCfg", class: "text", id: "battCfg"}, null), + ), + divRow("{#ZE_GROUP_TAB_BATTERY_TOPIC}", + ml("input", {name: "battTopic", class: "text", type: "text", value: obj.battTopic}, null), + ), + divRow("{#ZE_GROUP_TAB_BATTERY_LIMITON}", + ml("input", {name: "battLimitOn", class: "text", type: "number", min: "0", max: "100", step: "0.1", value: obj.battLimitOn}, null), + ), + divRow("{#ZE_GROUP_TAB_BATTERY_LIMITOFF}", + ml("input", {name: "battLimitOff", class: "text", type: "number", min: "0", max: "100", step: "0.1", value: obj.battLimitOff}, null), + ), divRow("{#ZE_GROUP_TAB_BATTERY_ONOFF}", ml("input", {name: "battSwitch", id: "battSwitch", class: "btn", type: "button", value: "{#BTN_ONOFF}", onclick: battOnOff()}, null)), // TODO: Uebersetzen mit lang.json und auf die entsprechende Dokuseite verlinken divRow("Hinweis: ", @@ -1546,6 +1552,21 @@ e.checked = (obj.inverters[inv].turnOff); } + // Tab_Battery + // battCfg + var e = document.getElementById("battCfg"); + selDelAllOpt(e); +// TODO: uebersetzen? + e.appendChild(opt("0", "---")); + e.appendChild(opt("1", "Inverter U dc")); + e.appendChild(opt("2", "MQTT U")); + e.appendChild(opt("3", "MQTT Soc")); + for (var i = 0; i < e.options.length; i++) { + if (e.options[i].value == obj.battCfg) { + e.selectedIndex = i; + } + } + function save() { var o = new Object(); o.cmd = "ze_save_group" @@ -1578,10 +1599,11 @@ o.inverters.push(q); } // Battery - o.battEnabled = document.getElementsByName("battEnabled")[0].checked; - o.battVoltageOn = document.getElementsByName("battVoltageOn")[0].value; - o.battVoltageOff = document.getElementsByName("battVoltageOff")[0].value; - o.battSoC = document.getElementsByName("battSoC")[0].value; + var e = document.getElementsByName("battCfg")[0]; + o.battCfg = e.options[e.selectedIndex].value; + o.battTopic = document.getElementsByName("battTopic")[0].value; + o.battLimitOn = document.getElementsByName("battLimitOn")[0].value; + o.battLimitOff = document.getElementsByName("battLimitOff")[0].value; // Advanced o.setPoint = document.getElementsByName("setPoint")[0].value; o.minimum = document.getElementsByName("minimum")[0].checked; @@ -1644,10 +1666,10 @@ o.inverters.push(q); } // Battery - o.battEnabled = false; - o.battVoltageOn = 0; - o.battVoltageOff = 0; - o.battSoC = ""; + o.battCfg = 0; + o.battTopic = ""; + o.battLimitOn = 0; + o.battLimitOff = 0; // Advanced o.setPoint = 0; o.minimum = true; diff --git a/src/web/lang.json b/src/web/lang.json index dcfa99c0..8c3a7a4b 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -954,24 +954,24 @@ "de": "Batterie" }, { - "token": "ZE_GROUP_TAB_BATTERY_ENABLED", - "en": "Enabled:", - "de": "Aktiviert:" + "token": "ZE_GROUP_TAB_BATTERY_CFG", + "en": "Mode:", + "de": "Modus:" }, { - "token": "ZE_GROUP_TAB_BATTERY_VOLTAGEON", - "en": "Voltage on (Volt):", - "de": "Spannung Ein (Volt):" + "token": "ZE_GROUP_TAB_BATTERY_TOPIC", + "en": "Topic:", + "de": "Topic:" }, { - "token": "ZE_GROUP_TAB_BATTERY_VOLTAGEOFF", - "en": "Voltage off (Volt):", - "de": "Spannung Aus (Volt):" + "token": "ZE_GROUP_TAB_BATTERY_LIMITON", + "en": "Limit On:", + "de": "Limit Ein:" }, { - "token": "ZE_GROUP_TAB_BATTERY_SOC", - "en": "SoC % (MQTT Topic):", - "de": "SoC (MQTT Topic):" + "token": "ZE_GROUP_TAB_BATTERY_LIMITOFF", + "en": "Limit Off:", + "de": "Limit Aus:" }, { "token": "ZE_GROUP_TAB_BATTERY_ONOFF",