Browse Source

0.6.12

added inverter status - state-machine #1016
pull/1048/head
lumapu 2 years ago
parent
commit
be9c505407
  1. 4
      src/CHANGES.md
  2. 5
      src/app.cpp
  3. 2
      src/defines.h
  4. 59
      src/hm/hmInverter.h
  5. 3
      src/hm/hmSystem.h
  6. 2
      src/platformio.ini
  7. 2
      src/plugins/Display/Display.h
  8. 6
      src/publisher/pubMqtt.h
  9. 38
      src/publisher/pubMqttIvData.h
  10. 2
      src/publisher/pubSerial.h
  11. 4
      src/web/RestApi.h

4
src/CHANGES.md

@ -1,5 +1,9 @@
# Development Changes # Development Changes
## 0.7.12 - 2023-07-09
* added inverter status - state-machine #1016
## 0.7.11 - 2023-07-09 ## 0.7.11 - 2023-07-09
* fix MqTT endless loop #1013 * fix MqTT endless loop #1013

5
src/app.cpp

@ -51,6 +51,7 @@ void app::setup() {
everySec(std::bind(&ahoywifi::tickWifiLoop, &mWifi), "wifiL"); everySec(std::bind(&ahoywifi::tickWifiLoop, &mWifi), "wifiL");
#endif #endif
mSys.setup(&mTimestamp);
mSys.addInverters(&mConfig->inst); mSys.addInverters(&mConfig->inst);
if(mConfig->nrf.enabled) { if(mConfig->nrf.enabled) {
mPayload.setup(this, &mSys, &mNrfRadio, &mStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); mPayload.setup(this, &mSys, &mNrfRadio, &mStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp);
@ -413,7 +414,7 @@ void app:: zeroIvValues(bool checkAvail, bool skipYieldDay) {
continue; // skip to next inverter continue; // skip to next inverter
if (checkAvail) { if (checkAvail) {
if (!iv->isAvailable(mTimestamp)) if (!iv->isAvailable())
continue; continue;
} }
@ -496,7 +497,7 @@ void app::updateLed(void) {
if (mConfig->led.led0 != 0xff) { if (mConfig->led.led0 != 0xff) {
Inverter<> *iv = mSys.getInverterByPos(0); Inverter<> *iv = mSys.getInverterByPos(0);
if (NULL != iv) { if (NULL != iv) {
if (iv->isProducing(mTimestamp)) if (iv->isProducing())
digitalWrite(mConfig->led.led0, led_on); digitalWrite(mConfig->led.led0, led_on);
else else
digitalWrite(mConfig->led.led0, led_off); digitalWrite(mConfig->led.led0, led_off);

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 11 #define VERSION_PATCH 12
//------------------------------------- //-------------------------------------
typedef struct { typedef struct {

59
src/hm/hmInverter.h

@ -102,6 +102,13 @@ const calcFunc_t<T> calcFunctions[] = {
{ CALC_IRR_CH, &calcIrradiation } { CALC_IRR_CH, &calcIrradiation }
}; };
enum class InverterStatus : uint8_t {
OFF,
STARTING,
PRODUCING,
WAS_PRODUCING,
WAS_ON
};
template <class REC_TYP> template <class REC_TYP>
class Inverter { class Inverter {
@ -123,6 +130,9 @@ class Inverter {
//String lastAlarmMsg; //String lastAlarmMsg;
bool initialized; // needed to check if the inverter was correctly added (ESP32 specific - union types are never null) bool initialized; // needed to check if the inverter was correctly added (ESP32 specific - union types are never null)
bool isConnected; // shows if inverter was successfully identified (fw version and hardware info) bool isConnected; // shows if inverter was successfully identified (fw version and hardware info)
InverterStatus status; // indicates the current inverter status
static uint32_t *timestamp; // system timestamp
Inverter() { Inverter() {
ivGen = IV_HM; ivGen = IV_HM;
@ -135,6 +145,7 @@ class Inverter {
//lastAlarmMsg = "nothing"; //lastAlarmMsg = "nothing";
alarmMesIndex = 0; alarmMesIndex = 0;
isConnected = false; isConnected = false;
status = InverterStatus::OFF;
} }
~Inverter() { ~Inverter() {
@ -319,6 +330,9 @@ class Inverter {
} }
else else
DPRINTLN(DBG_ERROR, F("addValue: assignment not found with cmd 0x")); DPRINTLN(DBG_ERROR, F("addValue: assignment not found with cmd 0x"));
// update status state-machine
isProducing();
} }
/*inline REC_TYP getPowerLimit(void) { /*inline REC_TYP getPowerLimit(void) {
@ -372,25 +386,39 @@ class Inverter {
} }
} }
bool isAvailable(uint32_t timestamp) { bool isAvailable() {
if((timestamp - recordMeas.ts) < INACT_THRES_SEC) bool val = false;
return true; if((*timestamp - recordMeas.ts) < INACT_THRES_SEC)
if((timestamp - recordInfo.ts) < INACT_THRES_SEC) val = true;
return true; if((*timestamp - recordInfo.ts) < INACT_THRES_SEC)
if((timestamp - recordConfig.ts) < INACT_THRES_SEC) val = true;
return true; if((*timestamp - recordConfig.ts) < INACT_THRES_SEC)
if((timestamp - recordAlarm.ts) < INACT_THRES_SEC) val = true;
return true; if((*timestamp - recordAlarm.ts) < INACT_THRES_SEC)
return false; val = true;
if(val) {
if((InverterStatus::OFF == status) || (InverterStatus::WAS_ON == status))
status = InverterStatus::STARTING;
} else
status = InverterStatus::WAS_ON;
return val;
} }
bool isProducing(uint32_t timestamp) { bool isProducing() {
bool val = false;
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:isProducing")); DPRINTLN(DBG_VERBOSE, F("hmInverter.h:isProducing"));
if(isAvailable(timestamp)) { if(isAvailable()) {
uint8_t pos = getPosByChFld(CH0, FLD_PAC, &recordMeas); uint8_t pos = getPosByChFld(CH0, FLD_PAC, &recordMeas);
return (getValue(pos, &recordMeas) > INACT_PWR_THRESH); val = (getValue(pos, &recordMeas) > INACT_PWR_THRESH);
if(val)
status = InverterStatus::PRODUCING;
else if(InverterStatus::PRODUCING == status)
status = InverterStatus::WAS_PRODUCING;
} }
return false; return val;
} }
uint16_t getFwVersion() { uint16_t getFwVersion() {
@ -605,6 +633,9 @@ class Inverter {
bool mDevControlRequest; // true if change needed bool mDevControlRequest; // true if change needed
}; };
template <class REC_TYP>
uint32_t *Inverter<REC_TYP>::timestamp {0};
/** /**
* To calculate values which are not transmitted by the unit there is a generic * To calculate values which are not transmitted by the unit there is a generic

3
src/hm/hmSystem.h

@ -13,7 +13,8 @@ class HmSystem {
public: public:
HmSystem() {} HmSystem() {}
void setup() { void setup(uint32_t *timestamp) {
mInverter[0].timestamp = timestamp;
mNumInv = 0; mNumInv = 0;
} }

2
src/platformio.ini

@ -26,7 +26,7 @@ lib_deps =
https://github.com/yubox-node-org/ESPAsyncWebServer https://github.com/yubox-node-org/ESPAsyncWebServer
nrf24/RF24 @ 1.4.5 nrf24/RF24 @ 1.4.5
paulstoffregen/Time @ ^1.6.1 paulstoffregen/Time @ ^1.6.1
https://github.com/bertmelis/espMqttClient#v1.4.2 https://github.com/bertmelis/espMqttClient#v1.4.4
bblanchon/ArduinoJson @ ^6.21.2 bblanchon/ArduinoJson @ ^6.21.2
https://github.com/JChristensen/Timezone @ ^1.2.4 https://github.com/JChristensen/Timezone @ ^1.2.4
olikraus/U8g2 @ ^2.34.17 olikraus/U8g2 @ ^2.34.17

2
src/plugins/Display/Display.h

@ -89,7 +89,7 @@ class Display {
if (iv == NULL) if (iv == NULL)
continue; continue;
if (iv->isProducing(*mUtcTs)) if (iv->isProducing())
isprod++; isprod++;
totalPower += iv->getChannelFieldValue(CH0, FLD_PAC, rec); totalPower += iv->getChannelFieldValue(CH0, FLD_PAC, rec);

6
src/publisher/pubMqtt.h

@ -489,9 +489,9 @@ class PubMqtt {
// inverter status // inverter status
uint8_t status = MQTT_STATUS_NOT_AVAIL_NOT_PROD; uint8_t status = MQTT_STATUS_NOT_AVAIL_NOT_PROD;
if (iv->isAvailable(*mUtcTimestamp)) { if (iv->isAvailable()) {
anyAvail = true; anyAvail = true;
status = (iv->isProducing(*mUtcTimestamp)) ? MQTT_STATUS_AVAIL_PROD : MQTT_STATUS_AVAIL_NOT_PROD; status = (iv->isProducing()) ? MQTT_STATUS_AVAIL_PROD : MQTT_STATUS_AVAIL_NOT_PROD;
} }
else // inverter is enabled but not available else // inverter is enabled but not available
allAvail = false; allAvail = false;
@ -551,7 +551,7 @@ class PubMqtt {
switch (rec->assign[i].fieldId) { switch (rec->assign[i].fieldId) {
case FLD_YT: case FLD_YT:
case FLD_YD: case FLD_YD:
if ((rec->assign[i].ch == CH0) && (!iv->isProducing(*mUtcTimestamp))) // avoids returns to 0 on restart if ((rec->assign[i].ch == CH0) && (!iv->isProducing())) // avoids returns to 0 on restart
continue; continue;
retained = true; retained = true;
break; break;

38
src/publisher/pubMqttIvData.h

@ -67,6 +67,7 @@ class PubMqttIvData {
void stateStart() { void stateStart() {
mLastIvId = 0; mLastIvId = 0;
mTotalFound = false;
if(!mSendList->empty()) { if(!mSendList->empty()) {
mCmd = mSendList->front().cmd; mCmd = mSendList->front().cmd;
mIvSend = mSendList->front().iv; mIvSend = mSendList->front().iv;
@ -99,7 +100,7 @@ class PubMqttIvData {
mPos = 0; mPos = 0;
if(found) if(found)
mState = SEND_DATA; mState = SEND_DATA;
else if(mSendTotals) else if(mSendTotals && mTotalFound)
mState = SEND_TOTALS; mState = SEND_TOTALS;
else { else {
mSendList->pop(); mSendList->pop();
@ -122,32 +123,33 @@ class PubMqttIvData {
if(FLD_YT == rec->assign[mPos].fieldId) if(FLD_YT == rec->assign[mPos].fieldId)
retained = true; retained = true;
else if(FLD_YD == rec->assign[mPos].fieldId) { else if(FLD_YD == rec->assign[mPos].fieldId) {
/*if(!mZeroValues) { if(!mZeroValues) {
if ((rec->assign[mPos].ch == CH0) && (!mIv->isProducing(*mUtcTimestamp))) { // avoids returns to 0 on restart if ((rec->assign[mPos].ch == CH0) && (!mIv->isProducing())) { // avoids returns to 0 on restart
mPos++; mPos++;
return; return;
} }
}*/ }
retained = true; retained = true;
} }
// calculate total values for RealTimeRunData_Debug // calculate total values for RealTimeRunData_Debug
if (CH0 == rec->assign[mPos].ch) { if (CH0 == rec->assign[mPos].ch) {
switch (rec->assign[mPos].fieldId) { if(mIv->status > InverterStatus::STARTING) {
case FLD_PAC: mTotalFound = true;
if(mIv->isAvailable(*mUtcTimestamp)) switch (rec->assign[mPos].fieldId) {
case FLD_PAC:
mTotal[0] += mIv->getValue(mPos, rec); mTotal[0] += mIv->getValue(mPos, rec);
break; break;
case FLD_YT: case FLD_YT:
mTotal[1] += mIv->getValue(mPos, rec); mTotal[1] += mIv->getValue(mPos, rec);
break; break;
case FLD_YD: case FLD_YD:
mTotal[2] += mIv->getValue(mPos, rec); mTotal[2] += mIv->getValue(mPos, rec);
break; break;
case FLD_PDC: case FLD_PDC:
if(mIv->isAvailable(*mUtcTimestamp))
mTotal[3] += mIv->getValue(mPos, rec); mTotal[3] += mIv->getValue(mPos, rec);
break; break;
}
} }
} }
} else } else
@ -207,7 +209,7 @@ class PubMqttIvData {
uint8_t mCmd; uint8_t mCmd;
uint8_t mLastIvId; uint8_t mLastIvId;
bool mSendTotals; bool mSendTotals, mTotalFound;
float mTotal[4]; float mTotal[4];
Inverter<> *mIv, *mIvSend; Inverter<> *mIv, *mIvSend;

2
src/publisher/pubSerial.h

@ -28,7 +28,7 @@ class PubSerial {
Inverter<> *iv = mSys->getInverterByPos(id); Inverter<> *iv = mSys->getInverterByPos(id);
if (NULL != iv) { if (NULL != iv) {
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
if (iv->isAvailable(*mUtcTimestamp)) { if (iv->isAvailable()) {
DPRINTLN(DBG_INFO, "Iv: " + String(id)); DPRINTLN(DBG_INFO, "Iv: " + String(id));
for (uint8_t i = 0; i < rec->length; i++) { for (uint8_t i = 0; i < rec->length; i++) {
if (0.0f != iv->getValue(i, rec)) { if (0.0f != iv->getValue(i, rec)) {

4
src/web/RestApi.h

@ -472,8 +472,8 @@ class RestApi {
invObj[F("id")] = i; invObj[F("id")] = i;
invObj[F("name")] = String(iv->config->name); invObj[F("name")] = String(iv->config->name);
invObj[F("version")] = String(iv->getFwVersion()); invObj[F("version")] = String(iv->getFwVersion());
invObj[F("is_avail")] = iv->isAvailable(mApp->getTimestamp()); invObj[F("is_avail")] = iv->isAvailable();
invObj[F("is_producing")] = iv->isProducing(mApp->getTimestamp()); invObj[F("is_producing")] = iv->isProducing();
invObj[F("ts_last_success")] = iv->getLastTs(rec); invObj[F("ts_last_success")] = iv->getLastTs(rec);
} }
} }

Loading…
Cancel
Save