Browse Source

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)
pull/1626/head
lumapu 9 months ago
parent
commit
84ac10531a
  1. 5
      src/CHANGES.md
  2. 5
      src/app.cpp
  3. 4
      src/app.h
  4. 16
      src/config/settings.h
  5. 27
      src/hm/CommQueue.h
  6. 4
      src/plugins/history.h
  7. 1
      src/web/RestApi.h
  8. 8
      src/web/html/setup.html
  9. 7
      src/web/lang.json
  10. 1
      src/web/web.h

5
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

5
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;
}

4
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 {

16
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<bool>(obj, F("rstMidNight"), &mCfg.inst.rstYieldMidNight);
getVal<bool>(obj, F("rstNotAvail"), &mCfg.inst.rstValsNotAvail);
getVal<bool>(obj, F("rstComStop"), &mCfg.inst.rstValsCommStop);
getVal<bool>(obj, F("rstComStart"), &mCfg.inst.rstValsCommStart);
getVal<bool>(obj, F("strtWthtTime"), &mCfg.inst.startWithoutTime);
getVal<bool>(obj, F("rstMaxMidNight"), &mCfg.inst.rstMaxValsMidNight);
getVal<bool>(obj, F("rdGrid"), &mCfg.inst.readGrid);

27
src/hm/CommQueue.h

@ -19,13 +19,19 @@ template <uint8_t N=100>
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<queue_s, N> mQueue;
uint8_t mWrPtr = 0;

4
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) {

1
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;

8
src/web/html/setup.html

@ -130,7 +130,11 @@
<div class="col-4"><input type="checkbox" name="invRstMid"/></div>
</div>
<div class="row mb-3">
<div class="col-8 mb-2">{#INV_PAUSE_SUNSET}</div>
<div class="col-8 mb-2">{#INV_RESET_SUNRISE}</div>
<div class="col-4"><input type="checkbox" name="invRstComStart"/></div>
</div>
<div class="row mb-3">
<div class="col-8 mb-2">{#INV_RESET_SUNSET}</div>
<div class="col-4"><input type="checkbox" name="invRstComStop"/></div>
</div>
<div class="row mb-3">
@ -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"];

7
src/web/lang.json

@ -324,10 +324,15 @@
"de": "Werte und Gesamtertrag um Mitternacht zur&uuml;cksetzen"
},
{
"token": "INV_PAUSE_SUNSET",
"token": "INV_RESET_SUNSET",
"en": "Reset values at sunset",
"de": "Werte bei Sonnenuntergang zur&uuml;cksetzen"
},
{
"token": "INV_RESET_SUNRISE",
"en": "Reset values at sunrise",
"de": "Werte bei Sonnenaufgang zur&uuml;cksetzen"
},
{
"token": "INV_RESET_NOT_AVAIL",
"en": "Reset values when inverter status is 'not available'",

1
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");

Loading…
Cancel
Save