From 84ac10531a308b82477b1602a6c76ef9575a346e Mon Sep 17 00:00:00 2001 From: lumapu Date: Fri, 3 May 2024 23:54:06 +0200 Subject: [PATCH] 0.8.115 * fix inverter communication with manual time sync #1603 * improved queue, only add new object once they not exist * added option to reset values on communication start (sunrise) --- src/CHANGES.md | 5 +++++ src/app.cpp | 5 +++++ src/app.h | 4 +++- src/config/settings.h | 16 ++++++++++------ src/hm/CommQueue.h | 27 +++++++++++++++++++++++---- src/plugins/history.h | 4 ---- src/web/RestApi.h | 1 + src/web/html/setup.html | 8 ++++++-- src/web/lang.json | 7 ++++++- src/web/web.h | 1 + 10 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index a023fbe5..4586fc86 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,10 @@ # Development Changes +## 0.8.115 - 2024-05-03 +* fix inverter communication with manual time sync #1603 +* improved queue, only add new object once they not exist +* added option to reset values on communication start (sunrise) + ## 0.8.114 - 2024-04-29 * fix ESP8266 compile * fix history graph diff --git a/src/app.cpp b/src/app.cpp index 30942fec..b362057a 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -162,6 +162,9 @@ void app::regularTickers(void) { everySec([this]() { mProtection->tickSecond(); }, "prot"); everySec([this]() {mNetwork->tickNetworkLoop(); }, "net"); + if(mConfig->inst.startWithoutTime && !mNetworkConnected) + every(std::bind(&app::tickSend, this), mConfig->inst.sendInterval, "tSend"); + // Plugins #if defined(PLUGIN_DISPLAY) if (DISP_TYPE_T0_NONE != mConfig->plugin.display.type) @@ -275,6 +278,8 @@ void app::tickIVCommunication(void) { if (mTimestamp >= (mSunset + mConfig->sun.offsetSecEvening)) { // current time is past communication stop, nothing to do. Next update will be done at midnight by tickCalcSunrise nxtTrig = 0; } else { // current time lies within communication start/stop time, set next trigger to communication stop + if((!iv->commEnabled) && mConfig->inst.rstValsCommStart) + zeroValues = true; iv->commEnabled = true; nxtTrig = mSunset + mConfig->sun.offsetSecEvening; } diff --git a/src/app.h b/src/app.h index 4f07adc6..a3692d20 100644 --- a/src/app.h +++ b/src/app.h @@ -303,8 +303,10 @@ class app : public IApp, public ah::Scheduler { DBGPRINTLN(String(newTime)); if(0 == newTime) mNetwork->updateNtpTime(); - else + else { Scheduler::setTimestamp(newTime); + onNtpUpdate(false); + } } uint16_t getHistoryValue(uint8_t type, uint16_t i) override { diff --git a/src/config/settings.h b/src/config/settings.h index 19579359..9459b80b 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -188,6 +188,7 @@ typedef struct { bool rstYieldMidNight; bool rstValsNotAvail; bool rstValsCommStop; + bool rstValsCommStart; bool rstMaxValsMidNight; bool startWithoutTime; bool readGrid; @@ -486,13 +487,14 @@ class settings { mCfg.mqtt.interval = 0; // off mCfg.mqtt.enableRetain = true; - mCfg.inst.sendInterval = SEND_INTERVAL; - mCfg.inst.rstYieldMidNight = false; - mCfg.inst.rstValsNotAvail = false; - mCfg.inst.rstValsCommStop = false; - mCfg.inst.startWithoutTime = false; + mCfg.inst.sendInterval = SEND_INTERVAL; + mCfg.inst.rstYieldMidNight = false; + mCfg.inst.rstValsNotAvail = false; + mCfg.inst.rstValsCommStop = false; + mCfg.inst.rstValsCommStart = false; + mCfg.inst.startWithoutTime = false; mCfg.inst.rstMaxValsMidNight = false; - mCfg.inst.readGrid = true; + mCfg.inst.readGrid = true; for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { mCfg.inst.iv[i].powerLevel = 0xff; // impossible high value @@ -822,6 +824,7 @@ class settings { obj[F("rstMidNight")] = (bool)mCfg.inst.rstYieldMidNight; obj[F("rstNotAvail")] = (bool)mCfg.inst.rstValsNotAvail; obj[F("rstComStop")] = (bool)mCfg.inst.rstValsCommStop; + obj[F("rstComStart")] = (bool)mCfg.inst.rstValsCommStart; obj[F("strtWthtTime")] = (bool)mCfg.inst.startWithoutTime; obj[F("rstMaxMidNight")] = (bool)mCfg.inst.rstMaxValsMidNight; obj[F("rdGrid")] = (bool)mCfg.inst.readGrid; @@ -832,6 +835,7 @@ class settings { getVal(obj, F("rstMidNight"), &mCfg.inst.rstYieldMidNight); getVal(obj, F("rstNotAvail"), &mCfg.inst.rstValsNotAvail); getVal(obj, F("rstComStop"), &mCfg.inst.rstValsCommStop); + getVal(obj, F("rstComStart"), &mCfg.inst.rstValsCommStart); getVal(obj, F("strtWthtTime"), &mCfg.inst.startWithoutTime); getVal(obj, F("rstMaxMidNight"), &mCfg.inst.rstMaxValsMidNight); getVal(obj, F("rdGrid"), &mCfg.inst.readGrid); diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index 328309ac..7164d773 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -19,13 +19,19 @@ template class CommQueue { public: void addImportant(Inverter<> *iv, uint8_t cmd) { - dec(&mRdPtr); - mQueue[mRdPtr] = queue_s(iv, cmd, true); + queue_s q(iv, cmd, true); + if(!isIncluded(&q)) { + dec(&mRdPtr); + mQueue[mRdPtr] = q; + } } void add(Inverter<> *iv, uint8_t cmd) { - mQueue[mWrPtr] = queue_s(iv, cmd, false); - inc(&mWrPtr); + queue_s q(iv, cmd, false); + if(!isIncluded(&q)) { + mQueue[mWrPtr] = q; + inc(&mWrPtr); + } } void chgCmd(Inverter<> *iv, uint8_t cmd) { @@ -117,6 +123,19 @@ class CommQueue { --(*ptr); } + private: + bool isIncluded(const queue_s *q) { + uint8_t ptr = mRdPtr; + while (ptr != mWrPtr) { + if(mQueue[ptr].cmd == q->cmd) { + if(mQueue[ptr].iv->id == q->iv->id) + return true; + } + ptr++; + } + return false; + } + protected: std::array mQueue; uint8_t mWrPtr = 0; diff --git a/src/plugins/history.h b/src/plugins/history.h index 7d7be57c..8531b463 100644 --- a/src/plugins/history.h +++ b/src/plugins/history.h @@ -57,7 +57,6 @@ class HistoryData { void tickerSecond() { float curPwr = 0; - //float maxPwr = 0; float yldDay = -0.1; uint32_t ts = 0; @@ -67,7 +66,6 @@ class HistoryData { if (iv == NULL) continue; curPwr += iv->getChannelFieldValue(CH0, FLD_PAC, rec); - //maxPwr += iv->getChannelFieldValue(CH0, FLD_MP, rec); yldDay += iv->getChannelFieldValue(CH0, FLD_YD, rec); if (rec->ts > ts) ts = rec->ts; @@ -81,8 +79,6 @@ class HistoryData { if (curPwr > mMaximumDay) mMaximumDay = roundf(curPwr); } - //if (maxPwr > 0) - // mMaximumDay = roundf(maxPwr); } if ((++mCurPwrDay.loopCnt % mCurPwrDay.refreshCycle) == 0) { diff --git a/src/web/RestApi.h b/src/web/RestApi.h index ed1aac75..b7e33984 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -577,6 +577,7 @@ class RestApi { obj[F("rstMid")] = (bool)mConfig->inst.rstYieldMidNight; obj[F("rstNotAvail")] = (bool)mConfig->inst.rstValsNotAvail; obj[F("rstComStop")] = (bool)mConfig->inst.rstValsCommStop; + obj[F("rstComStart")] = (bool)mConfig->inst.rstValsCommStart; obj[F("strtWthtTm")] = (bool)mConfig->inst.startWithoutTime; obj[F("rdGrid")] = (bool)mConfig->inst.readGrid; obj[F("rstMaxMid")] = (bool)mConfig->inst.rstMaxValsMidNight; diff --git a/src/web/html/setup.html b/src/web/html/setup.html index adb9477a..dbe88663 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -130,7 +130,11 @@
-
{#INV_PAUSE_SUNSET}
+
{#INV_RESET_SUNRISE}
+
+
+
+
{#INV_RESET_SUNSET}
@@ -670,7 +674,7 @@ function ivGlob(obj) { for(var i of [["invInterval", "interval"]]) document.getElementsByName(i[0])[0].value = obj[i[1]]; - for(var i of ["Mid", "ComStop", "NotAvail", "MaxMid"]) + for(var i of ["Mid", "ComStop", "ComStart", "NotAvail", "MaxMid"]) document.getElementsByName("invRst"+i)[0].checked = obj["rst" + i]; document.getElementsByName("strtWthtTm")[0].checked = obj["strtWthtTm"]; document.getElementsByName("rdGrid")[0].checked = obj["rdGrid"]; diff --git a/src/web/lang.json b/src/web/lang.json index 34b10a25..0093cea9 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -324,10 +324,15 @@ "de": "Werte und Gesamtertrag um Mitternacht zurücksetzen" }, { - "token": "INV_PAUSE_SUNSET", + "token": "INV_RESET_SUNSET", "en": "Reset values at sunset", "de": "Werte bei Sonnenuntergang zurücksetzen" }, + { + "token": "INV_RESET_SUNRISE", + "en": "Reset values at sunrise", + "de": "Werte bei Sonnenaufgang zurücksetzen" + }, { "token": "INV_RESET_NOT_AVAIL", "en": "Reset values when inverter status is 'not available'", diff --git a/src/web/web.h b/src/web/web.h index 7b73fe9f..5d75199b 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -500,6 +500,7 @@ class Web { mConfig->inst.sendInterval = request->arg("invInterval").toInt(); mConfig->inst.rstYieldMidNight = (request->arg("invRstMid") == "on"); mConfig->inst.rstValsCommStop = (request->arg("invRstComStop") == "on"); + mConfig->inst.rstValsCommStart = (request->arg("invRstComStart") == "on"); mConfig->inst.rstValsNotAvail = (request->arg("invRstNotAvail") == "on"); mConfig->inst.startWithoutTime = (request->arg("strtWthtTm") == "on"); mConfig->inst.readGrid = (request->arg("rdGrid") == "on");