Browse Source

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
pull/698/head
lumapu 2 years ago
parent
commit
026df8a09b
  1. 8
      src/CHANGES.md
  2. 44
      src/app.cpp
  3. 1
      src/app.h
  4. 2
      src/defines.h
  5. 41
      src/hm/hmPayload.h
  6. 5
      src/hm/hmRadio.h
  7. 11
      src/publisher/pubMqtt.h
  8. 6
      src/web/html/index.html
  9. 11
      src/web/html/setup.html
  10. 3
      src/web/html/style.css

8
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)

44
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++) {

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

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

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

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

11
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/#");
}

6
src/web/html/index.html

@ -145,12 +145,12 @@
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'));

11
src/web/html/setup.html

@ -96,11 +96,12 @@
<label for="invRetry">Max retries per Payload</label>
<input type="text" class="text" name="invRetry"/>
<label for="invRstMid">Reset Values and YieldDay at Midnight</label>
<label for="invRstMid">Reset values and YieldDay at midnight</label>
<input type="checkbox" class="cb" name="invRstMid"/><br/>
<label for="invRstComStop">Reset Values at Communication stop</label>
<label for="invRstComStop">Reset values when inverter polling stops at sunset</label>
<input type="checkbox" class="cb" name="invRstComStop"/><br/>
<label for="invRstNotAvail">Reset Values on 'not available'</label>
<label for="invRstNotAvail">Reset values when inverter status is 'not available'</label>
<input type="checkbox" class="cb" name="invRstNotAvail"/><br/>
</fieldset>
</div>
@ -125,7 +126,7 @@
<fieldset>
<legend class="des">Sunrise & Sunset</legend>
<p>
Latitude and Longitude must be set to be stored! decimal separator: '.' (dot)
Use a decimal separator: '.' (dot) for Latitude and Longitude
</p>
<label for="sunLat">Latitude (decimal)</label>
<input type="text" class="text" name="sunLat"/>
@ -134,7 +135,7 @@
<label for="sunOffs">Offset (pre sunrise, post sunset)</label>
<select name="sunOffs"></select>
<br>
<label for="sunDisNightCom">disable night communication</label>
<label for="sunDisNightCom">Stop polling inverters during night</label>
<input type="checkbox" class="cb" name="sunDisNightCom"/><br/>
</fieldset>
</div>

3
src/web/html/style.css

@ -282,7 +282,8 @@ input.btn:hover {
}
input.cb {
margin-bottom: 20px;
margin-bottom: 15px;
margin-top: 10px;
}
label {

Loading…
Cancel
Save