Browse Source

0.7.38

* reset alarms at midnight (if inverter is not available) #1105, #1096
* add option to reset 'max' values on midnight #1102
* added default pins for CMT2300A (matching OpenDTU)
pull/1116/head
lumapu 1 year ago
parent
commit
b01fbe205e
  1. 5
      src/CHANGES.md
  2. 28
      src/app.cpp
  3. 4
      src/config/config.h
  4. 10
      src/config/settings.h
  5. 2
      src/defines.h
  6. 6
      src/hm/hmInverter.h
  7. 3
      src/web/RestApi.h
  8. 8
      src/web/html/setup.html
  9. 1
      src/web/web.h

5
src/CHANGES.md

@ -1,5 +1,10 @@
# Development Changes # Development Changes
## 0.7.38 - 2023-08-21
* reset alarms at midnight (if inverter is not available) #1105, #1096
* add option to reset 'max' values on midnight #1102
* added default pins for CMT2300A (matching OpenDTU)
## 0.7.37 - 2023-08-18 ## 0.7.37 - 2023-08-18
* fix alarm time on WebGui #1099 * fix alarm time on WebGui #1099
* added RSSI info for HMS and HMT inverters (MqTT + REST API) * added RSSI info for HMS and HMT inverters (MqTT + REST API)

28
src/app.cpp

@ -276,11 +276,11 @@ void app::updateNtp(void) {
if (mMqttReconnect) { // @TODO: mMqttReconnect is variable which scope has changed if (mMqttReconnect) { // @TODO: mMqttReconnect is variable which scope has changed
if (mConfig->inst.rstValsNotAvail) if (mConfig->inst.rstValsNotAvail)
everyMin(std::bind(&app::tickMinute, this), "tMin"); everyMin(std::bind(&app::tickMinute, this), "tMin");
if (mConfig->inst.rstYieldMidNight) {
uint32_t localTime = gTimezone.toLocal(mTimestamp); uint32_t localTime = gTimezone.toLocal(mTimestamp);
uint32_t midTrig = gTimezone.toUTC(localTime - (localTime % 86400) + 86400); // next midnight local time uint32_t midTrig = gTimezone.toUTC(localTime - (localTime % 86400) + 86400); // next midnight local time
onceAt(std::bind(&app::tickMidnight, this), midTrig, "midNi"); onceAt(std::bind(&app::tickMidnight, this), midTrig, "midNi");
}
if (mConfig->sys.schedReboot) { if (mConfig->sys.schedReboot) {
uint32_t localTime = gTimezone.toLocal(mTimestamp); uint32_t localTime = gTimezone.toLocal(mTimestamp);
uint32_t rebootTrig = gTimezone.toUTC(localTime - (localTime % 86400) + 86410); // reboot 10 secs after midnght uint32_t rebootTrig = gTimezone.toUTC(localTime - (localTime % 86400) + 86410); // reboot 10 secs after midnght
@ -392,15 +392,37 @@ void app::tickMinute(void) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void app::tickMidnight(void) { void app::tickMidnight(void) {
// only triggered if 'reset values at midnight is enabled'
uint32_t localTime = gTimezone.toLocal(mTimestamp); uint32_t localTime = gTimezone.toLocal(mTimestamp);
uint32_t nxtTrig = gTimezone.toUTC(localTime - (localTime % 86400) + 86400); // next midnight local time uint32_t nxtTrig = gTimezone.toUTC(localTime - (localTime % 86400) + 86400); // next midnight local time
onceAt(std::bind(&app::tickMidnight, this), nxtTrig, "mid2"); onceAt(std::bind(&app::tickMidnight, this), nxtTrig, "mid2");
Inverter<> *iv;
for (uint8_t id = 0; id < mSys.getNumInverters(); id++) {
iv = mSys.getInverterByPos(id);
if (NULL == iv)
continue; // skip to next inverter
// reset alarms
if(InverterStatus::OFF == iv->status)
iv->resetAlarms();
// clear max values
if(mConfig->inst.rstMaxValsMidNight) {
uint8_t pos;
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
for(uint8_t i = 0; i <= iv->channels; i++) {
pos = iv->getPosByChFld(i, FLD_MP, rec);
iv->setValue(pos, rec, 0.0f);
}
}
}
if (mConfig->inst.rstYieldMidNight) {
zeroIvValues(!CHECK_AVAIL, !SKIP_YIELD_DAY); zeroIvValues(!CHECK_AVAIL, !SKIP_YIELD_DAY);
if (mMqttEnabled) if (mMqttEnabled)
mMqtt.tickerMidnight(); mMqtt.tickerMidnight();
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

4
src/config/config.h

@ -66,6 +66,10 @@
#define DEF_MISO_PIN 19 #define DEF_MISO_PIN 19
#define DEF_MOSI_PIN 23 #define DEF_MOSI_PIN 23
#define DEF_SCLK_PIN 18 #define DEF_SCLK_PIN 18
#define DEF_CMT_CSB 27
#define DEF_CMT_FCSB 26
#define DEF_CMT_IRQ 34
#else #else
#define DEF_CS_PIN 15 #define DEF_CS_PIN 15
#define DEF_CE_PIN 0 #define DEF_CE_PIN 0

10
src/config/settings.h

@ -151,6 +151,7 @@ typedef struct {
bool rstYieldMidNight; bool rstYieldMidNight;
bool rstValsNotAvail; bool rstValsNotAvail;
bool rstValsCommStop; bool rstValsCommStop;
bool rstMaxValsMidNight;
bool startWithoutTime; bool startWithoutTime;
float yieldEffiency; float yieldEffiency;
} cfgInst_t; } cfgInst_t;
@ -394,9 +395,9 @@ class settings {
mCfg.nrf.amplifierPower = DEF_AMPLIFIERPOWER & 0x03; mCfg.nrf.amplifierPower = DEF_AMPLIFIERPOWER & 0x03;
mCfg.nrf.enabled = true; mCfg.nrf.enabled = true;
mCfg.cmt.pinCsb = DEF_PIN_OFF; mCfg.cmt.pinCsb = DEF_CMT_CSB;
mCfg.cmt.pinFcsb = DEF_PIN_OFF; mCfg.cmt.pinFcsb = DEF_CMT_FCSB;
mCfg.cmt.pinIrq = DEF_PIN_OFF; mCfg.cmt.pinIrq = DEF_CMT_IRQ;
mCfg.cmt.enabled = false; mCfg.cmt.enabled = false;
snprintf(mCfg.ntp.addr, NTP_ADDR_LEN, "%s", DEF_NTP_SERVER_NAME); snprintf(mCfg.ntp.addr, NTP_ADDR_LEN, "%s", DEF_NTP_SERVER_NAME);
@ -423,6 +424,7 @@ class settings {
mCfg.inst.rstValsNotAvail = false; mCfg.inst.rstValsNotAvail = false;
mCfg.inst.rstValsCommStop = false; mCfg.inst.rstValsCommStop = false;
mCfg.inst.startWithoutTime = false; mCfg.inst.startWithoutTime = false;
mCfg.inst.rstMaxValsMidNight = false;
mCfg.inst.yieldEffiency = 0.955f; mCfg.inst.yieldEffiency = 0.955f;
mCfg.led.led0 = DEF_PIN_OFF; mCfg.led.led0 = DEF_PIN_OFF;
@ -651,6 +653,7 @@ class settings {
obj[F("rstNotAvail")] = (bool)mCfg.inst.rstValsNotAvail; obj[F("rstNotAvail")] = (bool)mCfg.inst.rstValsNotAvail;
obj[F("rstComStop")] = (bool)mCfg.inst.rstValsCommStop; obj[F("rstComStop")] = (bool)mCfg.inst.rstValsCommStop;
obj[F("strtWthtTime")] = (bool)mCfg.inst.startWithoutTime; obj[F("strtWthtTime")] = (bool)mCfg.inst.startWithoutTime;
obj[F("rstMaxMidNight")] = (bool)mCfg.inst.rstMaxValsMidNight;
obj[F("yldEff")] = mCfg.inst.yieldEffiency; obj[F("yldEff")] = mCfg.inst.yieldEffiency;
} }
else { else {
@ -659,6 +662,7 @@ class settings {
getVal<bool>(obj, F("rstNotAvail"), &mCfg.inst.rstValsNotAvail); getVal<bool>(obj, F("rstNotAvail"), &mCfg.inst.rstValsNotAvail);
getVal<bool>(obj, F("rstComStop"), &mCfg.inst.rstValsCommStop); getVal<bool>(obj, F("rstComStop"), &mCfg.inst.rstValsCommStop);
getVal<bool>(obj, F("strtWthtTime"), &mCfg.inst.startWithoutTime); getVal<bool>(obj, F("strtWthtTime"), &mCfg.inst.startWithoutTime);
getVal<bool>(obj, F("rstMaxMidNight"), &mCfg.inst.rstMaxValsMidNight);
getVal<float>(obj, F("yldEff"), &mCfg.inst.yieldEffiency); getVal<float>(obj, F("yldEff"), &mCfg.inst.yieldEffiency);
if(mCfg.inst.yieldEffiency < 0.5) if(mCfg.inst.yieldEffiency < 0.5)

2
src/defines.h

@ -13,7 +13,7 @@
//------------------------------------- //-------------------------------------
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 7 #define VERSION_MINOR 7
#define VERSION_PATCH 37 #define VERSION_PATCH 38
//------------------------------------- //-------------------------------------
typedef struct { typedef struct {

6
src/hm/hmInverter.h

@ -556,6 +556,12 @@ class Inverter {
} }
} }
void resetAlarms() {
lastAlarm.fill({0, 0, 0});
alarmNxtWrPos = 0;
alarmCnt = 0;
}
uint16_t parseAlarmLog(uint8_t id, uint8_t pyld[], uint8_t len) { uint16_t parseAlarmLog(uint8_t id, uint8_t pyld[], uint8_t len) {
uint8_t startOff = 2 + id * ALARM_LOG_ENTRY_SIZE; uint8_t startOff = 2 + id * ALARM_LOG_ENTRY_SIZE;
if((startOff + ALARM_LOG_ENTRY_SIZE) > len) if((startOff + ALARM_LOG_ENTRY_SIZE) > len)

3
src/web/RestApi.h

@ -342,9 +342,10 @@ class RestApi {
obj[F("retries")] = String(mConfig->nrf.maxRetransPerPyld); obj[F("retries")] = String(mConfig->nrf.maxRetransPerPyld);
obj[F("max_num_inverters")] = MAX_NUM_INVERTERS; obj[F("max_num_inverters")] = MAX_NUM_INVERTERS;
obj[F("rstMid")] = (bool)mConfig->inst.rstYieldMidNight; obj[F("rstMid")] = (bool)mConfig->inst.rstYieldMidNight;
obj[F("rstNAvail")] = (bool)mConfig->inst.rstValsNotAvail; obj[F("rstNotAvail")] = (bool)mConfig->inst.rstValsNotAvail;
obj[F("rstComStop")] = (bool)mConfig->inst.rstValsCommStop; obj[F("rstComStop")] = (bool)mConfig->inst.rstValsCommStop;
obj[F("strtWthtTm")] = (bool)mConfig->inst.startWithoutTime; obj[F("strtWthtTm")] = (bool)mConfig->inst.startWithoutTime;
obj[F("rstMaxMid")] = (bool)mConfig->inst.rstMaxValsMidNight;
obj[F("yldEff")] = mConfig->inst.yieldEffiency; obj[F("yldEff")] = mConfig->inst.yieldEffiency;
} }

8
src/web/html/setup.html

@ -172,6 +172,10 @@
<div class="col-8 col-sm-3">Reset values when inverter status is 'not available'</div> <div class="col-8 col-sm-3">Reset values when inverter status is 'not available'</div>
<div class="col-4 col-sm-9"><input type="checkbox" name="invRstNotAvail"/></div> <div class="col-4 col-sm-9"><input type="checkbox" name="invRstNotAvail"/></div>
</div> </div>
<div class="row mb-3">
<div class="col-8 col-sm-3">Reset 'max' values at midnight</div>
<div class="col-4 col-sm-9"><input type="checkbox" name="invRstMaxMid"/></div>
</div>
<div class="row mb-3"> <div class="row mb-3">
<div class="col-8 col-sm-3">Start without time sync (useful in AP-Only-Mode)</div> <div class="col-8 col-sm-3">Start without time sync (useful in AP-Only-Mode)</div>
<div class="col-4 col-sm-9"><input type="checkbox" name="strtWthtTm"/></div> <div class="col-4 col-sm-9"><input type="checkbox" name="strtWthtTm"/></div>
@ -653,8 +657,8 @@
function ivGlob(obj) { function ivGlob(obj) {
for(var i of [["invInterval", "interval"], ["invRetry", "retries"], ["yldEff", "yldEff"]]) for(var i of [["invInterval", "interval"], ["invRetry", "retries"], ["yldEff", "yldEff"]])
document.getElementsByName(i[0])[0].value = obj[i[1]]; document.getElementsByName(i[0])[0].value = obj[i[1]];
for(var i of [["Mid", "rstMid"], ["ComStop", "rstComStop"], ["NotAvail", "rstNAvail"]]) for(var i of ["Mid", "ComStop", "NotAvail", "MaxMid"])
document.getElementsByName("invRst"+i[0])[0].checked = obj[i[1]]; document.getElementsByName("invRst"+i)[0].checked = obj["rst" + i];
document.getElementsByName("strtWthtTm")[0].checked = obj["strtWthtTm"]; document.getElementsByName("strtWthtTm")[0].checked = obj["strtWthtTm"];
} }

1
src/web/web.h

@ -537,6 +537,7 @@ class Web {
mConfig->inst.rstValsCommStop = (request->arg("invRstComStop") == "on"); mConfig->inst.rstValsCommStop = (request->arg("invRstComStop") == "on");
mConfig->inst.rstValsNotAvail = (request->arg("invRstNotAvail") == "on"); mConfig->inst.rstValsNotAvail = (request->arg("invRstNotAvail") == "on");
mConfig->inst.startWithoutTime = (request->arg("strtWthtTm") == "on"); mConfig->inst.startWithoutTime = (request->arg("strtWthtTm") == "on");
mConfig->inst.rstMaxValsMidNight = (request->arg("invRstMaxMid") == "on");
mConfig->inst.yieldEffiency = (request->arg("yldEff")).toFloat(); mConfig->inst.yieldEffiency = (request->arg("yldEff")).toFloat();

Loading…
Cancel
Save