From 026df8a09bb1163d864e3813a204b0d4bdcc8ea5 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 11 Feb 2023 02:02:04 +0100 Subject: [PATCH] fix power-limit was not checked for max retransmits #667 fix blue LED lights up all the time #672 fix installing schedulers if NTP server isn't available improved zero values on triggers #671 hardcoded MQTT subtopics, because wildcard `#` leads to errors rephrased some messages on webif, thx to @Argafal #638 --- src/CHANGES.md | 8 ++++++++ src/app.cpp | 44 +++++++++++++++++++++++++---------------- src/app.h | 1 + src/defines.h | 2 +- src/hm/hmPayload.h | 41 +++++++++++++++++--------------------- src/hm/hmRadio.h | 5 ++--- src/publisher/pubMqtt.h | 11 ++++++++--- src/web/html/index.html | 6 +++--- src/web/html/setup.html | 11 ++++++----- src/web/html/style.css | 3 ++- 10 files changed, 76 insertions(+), 56 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 441d0a29e..6de9830a4 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -2,6 +2,14 @@ (starting from release version `0.5.66`) +## 0.5.85 +* fix power-limit was not checked for max retransmits #667 +* fix blue LED lights up all the time #672 +* fix installing schedulers if NTP server isn't available +* improved zero values on triggers #671 +* hardcoded MQTT subtopics, because wildcard `#` leads to errors +* rephrased some messages on webif, thx to @Argafal #638 + ## 0.5.84 * fix blue LED lights up all the time #672 * added an instant start communication (once NTP is synced) diff --git a/src/app.cpp b/src/app.cpp index cdaa7661a..5fcab6482 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -161,14 +161,16 @@ void app::tickNtpUpdate(void) { mMqtt.connect(); everySec(std::bind(&PubMqttType::tickerSecond, &mMqtt), "mqttS"); everyMin(std::bind(&PubMqttType::tickerMinute, &mMqtt), "mqttM"); - mMqttReconnect = false; } - if(mConfig->inst.rstValsNotAvail) - everyMin(std::bind(&app::tickMinute, this), "tMin"); - if(mConfig->inst.rstYieldMidNight) { - uint32_t midTrig = mTimestamp - ((mTimestamp - 1) % 86400) + 86400; // next midnight - onceAt(std::bind(&app::tickMidnight, this), midTrig, "midNi"); + // only install schedulers once even if NTP wasn't successful in first loop + if(mMqttReconnect) { // @TODO: mMqttReconnect is wrong name here + if(mConfig->inst.rstValsNotAvail) + everyMin(std::bind(&app::tickMinute, this), "tMin"); + if(mConfig->inst.rstYieldMidNight) { + uint32_t midTrig = mTimestamp - ((mTimestamp - 1) % 86400) + 86400; // next midnight + onceAt(std::bind(&app::tickMidnight, this), midTrig, "midNi"); + } } nxtTrig = isOK ? 43200 : 60; // depending on NTP update success check again in 12 h or in 1 min @@ -183,6 +185,8 @@ void app::tickNtpUpdate(void) { mSendFirst = false; once(std::bind(&app::tickSend, this), 2, "senOn"); } + + mMqttReconnect = false; } once(std::bind(&app::tickNtpUpdate, this), nxtTrig, "ntp"); } @@ -233,17 +237,8 @@ void app::tickSun(void) { //----------------------------------------------------------------------------- void app::tickComm(void) { - if(!mIVCommunicationOn && (mConfig->inst.rstValsCommStop)) { - Inverter<> *iv; - // set values to zero, except yields - for (uint8_t id = 0; id < mSys.getNumInverters(); id++) { - iv = mSys.getInverterByPos(id); - if (NULL == iv) - continue; // skip to next inverter - - mPayload.zeroInverterValues(iv); - } - } + if((!mIVCommunicationOn) && (mConfig->inst.rstValsCommStop)) + once(std::bind(&app::tickZeroValues, this), mConfig->nrf.sendInterval, "tZero"); if (mMqttEnabled) { if (!mMqtt.tickerComm(!mIVCommunicationOn)) @@ -251,6 +246,19 @@ void app::tickComm(void) { } } +//----------------------------------------------------------------------------- +void app::tickZeroValues(void) { + Inverter<> *iv; + // set values to zero, except yields + for (uint8_t id = 0; id < mSys.getNumInverters(); id++) { + iv = mSys.getInverterByPos(id); + if (NULL == iv) + continue; // skip to next inverter + + mPayload.zeroInverterValues(iv); + } +} + //----------------------------------------------------------------------------- void app::tickMinute(void) { // only triggered if 'reset values on no avail is enabled' @@ -273,6 +281,8 @@ void app::tickMidnight(void) { uint32_t nxtTrig = mTimestamp - ((mTimestamp - 1) % 86400) + 86400; // next midnight onceAt(std::bind(&app::tickMidnight, this), nxtTrig, "mid2"); + DPRINTLN(DBG_INFO, "tickMidnight " + String(nxtTrig)); + Inverter<> *iv; // set values to zero, except yield total for (uint8_t id = 0; id < mSys.getNumInverters(); id++) { diff --git a/src/app.h b/src/app.h index c0fefcf16..c3a7d0b34 100644 --- a/src/app.h +++ b/src/app.h @@ -223,6 +223,7 @@ class app : public IApp, public ah::Scheduler { void tickComm(void); void tickSend(void); void tickMinute(void); + void tickZeroValues(void); void tickMidnight(void); /*void tickSerial(void) { if(Serial.available() == 0) diff --git a/src/defines.h b/src/defines.h index 58ad16740..38cf3926a 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 5 -#define VERSION_PATCH 84 +#define VERSION_PATCH 85 //------------------------------------- typedef struct { diff --git a/src/hm/hmPayload.h b/src/hm/hmPayload.h index b0f256bc6..ab11ee665 100644 --- a/src/hm/hmPayload.h +++ b/src/hm/hmPayload.h @@ -71,36 +71,31 @@ class HmPayload { } void zeroYieldDay(Inverter<> *iv) { + DPRINTLN(DBG_INFO, "zeroYieldDay"); record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); - uint8_t pos = iv->getPosByChFld(CH0, FLD_YD, rec); - iv->setValue(pos, rec, 0.0f); + uint8_t pos; + for(uint8_t ch = 0; ch < iv->channels; ch++) { + pos = iv->getPosByChFld(CH0, FLD_YD, rec); + iv->setValue(pos, rec, 0.0f); + } } void zeroInverterValues(Inverter<> *iv) { + DPRINTLN(DBG_INFO, "zeroInverterValues"); record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); for(uint8_t ch = 0; ch <= iv->channels; ch++) { uint8_t pos = 0; - uint8_t fld = 0; - while(0xff != pos) { + for(uint8_t fld = 0; fld < FLD_EVT; fld++) { switch(fld) { case FLD_YD: case FLD_YT: - case FLD_FW_VERSION: - case FLD_FW_BUILD_YEAR: - case FLD_FW_BUILD_MONTH_DAY: - case FLD_FW_BUILD_HOUR_MINUTE: - case FLD_HW_ID: - case FLD_ACT_ACTIVE_PWR_LIMIT: - fld++; continue; } pos = iv->getPosByChFld(ch, fld, rec); iv->setValue(pos, rec, 0.0f); - fld++; } } - iv->doCalculations(); notify(RealTimeRunData_Debug); } @@ -217,16 +212,16 @@ class HmPayload { crcPass = build(iv->id, &pyldComplete); if (!crcPass && !pyldComplete) { // payload not complete if ((mPayload[iv->id].requested) && (retransmit)) { - if (iv->devControlCmd == Restart || iv->devControlCmd == CleanState_LockAndAlarm) { - // This is required to prevent retransmissions without answer. - DPRINTLN(DBG_INFO, F("Prevent retransmit on Restart / CleanState_LockAndAlarm...")); - mPayload[iv->id].retransmits = mMaxRetrans; - } else if(iv->devControlCmd == ActivePowerContr) { - DPRINTLN(DBG_INFO, F("retransmit power limit")); - mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); - } else { - if (mPayload[iv->id].retransmits < mMaxRetrans) { - mPayload[iv->id].retransmits++; + if (mPayload[iv->id].retransmits < mMaxRetrans) { + mPayload[iv->id].retransmits++; + if (iv->devControlCmd == Restart || iv->devControlCmd == CleanState_LockAndAlarm) { + // This is required to prevent retransmissions without answer. + DPRINTLN(DBG_INFO, F("Prevent retransmit on Restart / CleanState_LockAndAlarm...")); + mPayload[iv->id].retransmits = mMaxRetrans; + } else if(iv->devControlCmd == ActivePowerContr) { + DPRINTLN(DBG_INFO, F("retransmit power limit")); + mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); + } else { if(false == mPayload[iv->id].gotFragment) { /* DPRINTLN(DBG_WARN, F("nothing received: Request Complete Retransmit")); diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index 80738e48a..ef5e5e230 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -104,6 +104,7 @@ class HmRadio { mNrf24.setRetries(3, 15); // 3*250us + 250us and 15 loops -> 15ms mNrf24.setChannel(mRfChLst[mRxChIdx]); + mNrf24.startListening(); mNrf24.setDataRate(RF24_250KBPS); mNrf24.setAutoAck(true); mNrf24.enableDynamicPayloads(); @@ -118,8 +119,6 @@ class HmRadio { DPRINTLN(DBG_INFO, String(rf24AmpPowerNames[ampPwr])); mNrf24.setPALevel(ampPwr & 0x03); - mNrf24.startListening(); - if(mNrf24.isChipConnected()) { DPRINTLN(DBG_INFO, F("Radio Config:")); mNrf24.printPrettyDetails(); @@ -140,6 +139,7 @@ class HmRadio { // start listening on the default RX channel mRxChIdx = 0; mNrf24.setChannel(mRfChLst[mRxChIdx]); + mNrf24.startListening(); //uint32_t debug_ms = millis(); uint16_t cnt = 300; // that is 60 times 5 channels @@ -150,7 +150,6 @@ class HmRadio { mIrqRcvd = false; if (getReceived()) { // everything received //DBGPRINTLN("RX finished Cnt: " + String(300-cnt) + " time used: " + String(millis()-debug_ms)+ " ms"); - mNrf24.stopListening(); return true; } } diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index 94524faf2..251513125 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -72,7 +72,7 @@ class PubMqtt { #endif } - void connect() { + inline void connect() { mReconnectRequest = false; if(!mClient.connected()) mClient.connect(); @@ -136,6 +136,7 @@ class PubMqtt { } void payloadEventListener(uint8_t cmd) { + connect(); if(mClient.connected()) { // prevent overflow if MQTT broker is not reachable but set if((0 == mCfgMqtt->interval) || (RealTimeRunData_Debug != cmd)) // no interval or no live data mSendList.push(cmd); @@ -302,8 +303,12 @@ class PubMqtt { tickerMinute(); publish(mLwtTopic, mLwtOnline, true, false); - subscribe("ctrl/#"); - subscribe("setup/#"); + subscribe("ctrl/limit_persistent_relative"); + subscribe("ctrl/limit_persistent_absolute"); + subscribe("ctrl/limit_nonpersistent_relative"); + subscribe("ctrl/limit_nonpersistent_absolute"); + subscribe("setup/set_time"); + subscribe("setup/sync_ntp"); //subscribe("status/#"); } diff --git a/src/web/html/index.html b/src/web/html/index.html index cb16ddc9d..21bfb5f65 100644 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -145,12 +145,12 @@

Support this project:

if(obj["ts_sunrise"] > 0) { if(((obj["ts_sunrise"] - obj["ts_offset"]) < obj["ts_now"]) && ((obj["ts_sunset"] + obj["ts_offset"]) > obj["ts_now"])) { - commInfo = "Polling inverter(s), will stop at " + (new Date((obj["ts_sunset"] + obj["ts_offset"]) * 1000).toLocaleString('de-DE')); + commInfo = "Polling inverter(s), will stop at sunset " + (new Date((obj["ts_sunset"] + obj["ts_offset"]) * 1000).toLocaleString('de-DE')); } else if(obj["disNightComm"]) { - commInfo = "Night time, no Communication to Inverter, "; + commInfo = "Night time, inverter polling disabled, "; if(obj["ts_now"] > (obj["ts_sunrise"] - obj["ts_offset"])) { - commInfo += "stopped polling at " + (new Date((obj["ts_sunset"] + obj["ts_offset"]) * 1000).toLocaleString('de-DE')); + commInfo += "stopped at " + (new Date((obj["ts_sunset"] + obj["ts_offset"]) * 1000).toLocaleString('de-DE')); } else { commInfo += "will start polling at " + (new Date((obj["ts_sunrise"] - obj["ts_offset"]) * 1000).toLocaleString('de-DE')); diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 58c3153e1..723c6677d 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -96,11 +96,12 @@ - + +
- +
- +
@@ -125,7 +126,7 @@
Sunrise & Sunset

- Latitude and Longitude must be set to be stored! decimal separator: '.' (dot) + Use a decimal separator: '.' (dot) for Latitude and Longitude

@@ -134,7 +135,7 @@
- +
diff --git a/src/web/html/style.css b/src/web/html/style.css index 8f4b473bc..51f9a9b89 100644 --- a/src/web/html/style.css +++ b/src/web/html/style.css @@ -282,7 +282,8 @@ input.btn:hover { } input.cb { - margin-bottom: 20px; + margin-bottom: 15px; + margin-top: 10px; } label {