From d203defb2ef0e300c809e5215ad04e983371f5d4 Mon Sep 17 00:00:00 2001 From: Patrick Amrhein Date: Thu, 14 Mar 2024 20:25:19 +0100 Subject: [PATCH] 0.8.910009-zero --- src/config/settings.h | 24 ++++++++++ src/defines.h | 2 +- src/plugins/zeroExport/zeroExport.h | 69 ++++++++++++++++++++++------- src/web/RestApi.h | 6 +++ src/web/html/setup.html | 9 ++++ src/web/lang.json | 15 +++++++ 6 files changed, 107 insertions(+), 18 deletions(-) diff --git a/src/config/settings.h b/src/config/settings.h index 75753076..4e86f5df 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -299,6 +299,18 @@ typedef struct { unsigned long lastRefresh; // bool waitForAck; + float eSum; + float eSum1; + float eSum2; + float eSum3; + float eOld; + float eOld1; + float eOld2; + float eOld3; + float Kp; + float Ki; + float Kd; + float pmPower; float pmPowerL1; float pmPowerL2; @@ -682,6 +694,9 @@ class settings { mCfg.plugin.zeroExport.groups[group].refresh = 10; mCfg.plugin.zeroExport.groups[group].powerTolerance = 10; mCfg.plugin.zeroExport.groups[group].powerMax = 600; + mCfg.plugin.zeroExport.groups[group].Kp = -1; + mCfg.plugin.zeroExport.groups[group].Ki = 0; + mCfg.plugin.zeroExport.groups[group].Kd = 0; // mCfg.plugin.zeroExport.groups[group].state = zeroExportState::INIT; mCfg.plugin.zeroExport.groups[group].lastRun = 0; @@ -1004,6 +1019,9 @@ class settings { obj[F("refresh")] = mCfg.plugin.zeroExport.groups[group].refresh; obj[F("powerTolerance")] = mCfg.plugin.zeroExport.groups[group].powerTolerance; obj[F("powerMax")] = mCfg.plugin.zeroExport.groups[group].powerMax; + obj[F("Kp")] = mCfg.plugin.zeroExport.groups[group].Kp; + obj[F("Ki")] = mCfg.plugin.zeroExport.groups[group].Ki; + obj[F("Kd")] = mCfg.plugin.zeroExport.groups[group].Kd; } else { // General if (obj.containsKey(F("enabled"))) @@ -1043,6 +1061,12 @@ class settings { getVal(obj, F("powerTolerance"), &mCfg.plugin.zeroExport.groups[group].powerTolerance); if (obj.containsKey(F("powerMax"))) getVal(obj, F("powerMax"), &mCfg.plugin.zeroExport.groups[group].powerMax); + if (obj.containsKey(F("Kp"))) + getVal(obj, F("Kp"), &mCfg.plugin.zeroExport.groups[group].Kp); + if (obj.containsKey(F("Ki"))) + getVal(obj, F("Ki"), &mCfg.plugin.zeroExport.groups[group].Ki); + if (obj.containsKey(F("Kd"))) + getVal(obj, F("Kd"), &mCfg.plugin.zeroExport.groups[group].Kd); } } diff --git a/src/defines.h b/src/defines.h index 67d5d10e..4eaa1675 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 910008 +#define VERSION_PATCH 910009 //------------------------------------- typedef struct { diff --git a/src/plugins/zeroExport/zeroExport.h b/src/plugins/zeroExport/zeroExport.h index 730a1c57..2887da90 100644 --- a/src/plugins/zeroExport/zeroExport.h +++ b/src/plugins/zeroExport/zeroExport.h @@ -46,9 +46,9 @@ class ZeroExport { mApi = api; mMqtt = mqtt; -// mIsInitialized = true; + mIsInitialized = true; // TODO: Sicherheitsreturn weil noch Sicherheitsfunktionen fehlen. - mIsInitialized = false; +// mIsInitialized = false; } /** loop @@ -393,6 +393,12 @@ mCfg->groups[group].lastRefresh = millis();; } } + if (wait) { + if (mCfg->groups[group].lastRun > (millis() - 30000UL)) { + wait = false; + } + } + mLog["wait"] = wait; // Next @@ -660,28 +666,57 @@ mCfg->groups[group].lastRefresh = millis();; // Regler // TODO: Regelparameter unter Advanced konfigurierbar? Aber erst wenn Regler komplett ingegriert. - const float Kp = -1; - const float Ki = -1; - const float Kd = -1; + float Kp = mCfg->groups[group].Kp; + float Ki = mCfg->groups[group].Ki; + float Kd = mCfg->groups[group].Kd; + unsigned long Ta = bTsp - mCfg->groups[group].lastRefresh; + mLog["Kp"] = Kp; + mLog["Ki"] = Ki; + mLog["Kd"] = Kd; + mLog["Ta"] = Ta; // - P-Anteil float yP = Kp * e; float yP1 = Kp * e1; float yP2 = Kp * e2; float yP3 = Kp * e3; + mLog["yP"] = yP; + mLog["yP1"] = yP1; + mLog["yP2"] = yP2; + mLog["yP3"] = yP3; // - I-Anteil -// float esum = esum + e; -// float yI = Ki * Ta * esum; - float yI = 0; - float yI1 = 0; - float yI2 = 0; - float yI3 = 0; + mCfg->groups[group].eSum += e; + mCfg->groups[group].eSum1 += e1; + mCfg->groups[group].eSum2 += e2; + mCfg->groups[group].eSum3 += e3; + mLog["esum"] = mCfg->groups[group].eSum; + mLog["esum1"] = mCfg->groups[group].eSum1; + mLog["esum2"] = mCfg->groups[group].eSum2; + mLog["esum3"] = mCfg->groups[group].eSum3; + float yI = Ki * Ta * mCfg->groups[group].eSum; + float yI1 = Ki * Ta * mCfg->groups[group].eSum1; + float yI2 = Ki * Ta * mCfg->groups[group].eSum2; + float yI3 = Ki * Ta * mCfg->groups[group].eSum3; + mLog["yI"] = yI; + mLog["yI1"] = yI1; + mLog["yI2"] = yI2; + mLog["yI3"] = yI3; // - D-Anteil -// float yD = Kd * (e -ealt) / Ta; -// float ealt = e; - float yD = 0; - float yD1 = 0; - float yD2 = 0; - float yD3 = 0; + mLog["ealt"] = mCfg->groups[group].eOld; + mLog["ealt1"] = mCfg->groups[group].eOld1; + mLog["ealt2"] = mCfg->groups[group].eOld2; + mLog["ealt3"] = mCfg->groups[group].eOld3; + float yD = Kd * (e - mCfg->groups[group].eOld) / Ta; + float yD1 = Kd * (e1 - mCfg->groups[group].eOld1) / Ta; + float yD2 = Kd * (e2 - mCfg->groups[group].eOld2) / Ta; + float yD3 = Kd * (e3 - mCfg->groups[group].eOld3) / Ta; + mLog["yD"] = yD; + mLog["yD1"] = yD1; + mLog["yD2"] = yD2; + mLog["yD3"] = yD3; + mCfg->groups[group].eOld = e; + mCfg->groups[group].eOld1 = e1; + mCfg->groups[group].eOld2 = e2; + mCfg->groups[group].eOld3 = e3; // - PID-Anteil float yPID = yP + yI + yD; float yPID1 = yP1 + yI1 + yD1; diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 2377e5fa..d111a252 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -755,6 +755,9 @@ class RestApi { objGroup[F("refresh")] = (uint8_t)mConfig->plugin.zeroExport.groups[group].refresh; objGroup[F("powerTolerance")] = (uint8_t)mConfig->plugin.zeroExport.groups[group].powerTolerance; objGroup[F("powerMax")] = (uint16_t)mConfig->plugin.zeroExport.groups[group].powerMax; + objGroup[F("Kp")] = ah::round3((float)mConfig->plugin.zeroExport.groups[group].Kp); + objGroup[F("Ki")] = ah::round3((float)mConfig->plugin.zeroExport.groups[group].Ki); + objGroup[F("Kd")] = ah::round3((float)mConfig->plugin.zeroExport.groups[group].Kd); } } #endif @@ -1017,6 +1020,9 @@ class RestApi { mConfig->plugin.zeroExport.groups[group].refresh = jsonIn[F("refresh")]; mConfig->plugin.zeroExport.groups[group].powerTolerance = jsonIn[F("powerTolerance")]; mConfig->plugin.zeroExport.groups[group].powerMax = jsonIn[F("powerMax")]; + mConfig->plugin.zeroExport.groups[group].Kp = jsonIn[F("Kp")]; + mConfig->plugin.zeroExport.groups[group].Ki = jsonIn[F("Ki")]; + mConfig->plugin.zeroExport.groups[group].Kd = jsonIn[F("Kd")]; // Global mApp->saveSettings(false); // without reboot } diff --git a/src/web/html/setup.html b/src/web/html/setup.html index ac1c969b..7b967ff6 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -1379,6 +1379,9 @@ divRow("{#ZE_GROUP_TAB_ADVANCED_REFRESH}", ml("input", {name: "refresh", class: "text", type: "number", min: "0", max: "255", value: obj.refresh}, null)), divRow("{#ZE_GROUP_TAB_ADVANCED_POWERTOLERANCE}", ml("input", {name: "powerTolerance", class: "text", type: "number", min: "0", max: "255", value: obj.powerTolerance}, null)), divRow("{#ZE_GROUP_TAB_ADVANCED_POWERMAX}", ml("input", {name: "powerMax", class: "text", type: "number", min: "0", max: "65535", value: obj.powerMax}, null)), + divRow("{#ZE_GROUP_TAB_ADVANCED_KP}", ml("input", {name: "Kp", class: "text", type: "number", min: "-5", max: "0", step: "0.01", value: obj.Kp}, null)), + divRow("{#ZE_GROUP_TAB_ADVANCED_KI}", ml("input", {name: "Ki", class: "text", type: "number", min: "-5", max: "0", step: "0.01", value: obj.Ki}, null)), + divRow("{#ZE_GROUP_TAB_ADVANCED_KD}", ml("input", {name: "Kd", class: "text", type: "number", min: "-5", max: "0", step: "0.01", value: obj.Kd}, null)), ]), // Global ml("div", {class: "row mt-5"}, [ @@ -1495,6 +1498,9 @@ o.refresh = document.getElementsByName("refresh")[0].value; o.powerTolerance = document.getElementsByName("powerTolerance")[0].value; o.powerMax = document.getElementsByName("powerMax")[0].value; + o.Kp = document.getElementsByName("Kp")[0].value; + o.Ki = document.getElementsByName("Ki")[0].value; + o.Kd = document.getElementsByName("Kd")[0].value; // Global getAjax("/api/setup", cb, "POST", JSON.stringify(o)); } @@ -1555,6 +1561,9 @@ o.refresh = 10; o.powerTolerance = 10; o.powerMax = 600; + o.Kp = -1; + o.Ki = 0; + o.Kd = 0; // Global getAjax("/api/setup", cb, "POST", JSON.stringify(o)); } diff --git a/src/web/lang.json b/src/web/lang.json index 035b2b8f..9147f8df 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -948,6 +948,21 @@ "en": "Group Power max (Watt):", "de": "Gruppe Leistung Max (Watt):" }, + { + "token": "ZE_GROUP_TAB_ADVANCED_KP", + "en": "Kp:", + "de": "Kp:" + }, + { + "token": "ZE_GROUP_TAB_ADVANCED_KI", + "en": "Ki:", + "de": "Ki:" + }, + { + "token": "ZE_GROUP_TAB_ADVANCED_KD", + "en": "Kd:", + "de": "Kd:" + }, { "token": "ZE_GROUP_EDIT_BTN_SAVE", "en": "save",