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
## 0.7.12 - 2023-07-09
* added inverter status - state-machine #1016
## 0.7.11 - 2023-07-09
* fix MqTT endless loop #1013

5
src/app.cpp

@ -51,6 +51,7 @@ void app::setup() {
everySec(std::bind(&ahoywifi::tickWifiLoop, &mWifi), "wifiL");
#endif
mSys.setup(&mTimestamp);
mSys.addInverters(&mConfig->inst);
if(mConfig->nrf.enabled) {
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
if (checkAvail) {
if (!iv->isAvailable(mTimestamp))
if (!iv->isAvailable())
continue;
}
@ -496,7 +497,7 @@ void app::updateLed(void) {
if (mConfig->led.led0 != 0xff) {
Inverter<> *iv = mSys.getInverterByPos(0);
if (NULL != iv) {
if (iv->isProducing(mTimestamp))
if (iv->isProducing())
digitalWrite(mConfig->led.led0, led_on);
else
digitalWrite(mConfig->led.led0, led_off);

2
src/defines.h

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

59
src/hm/hmInverter.h

@ -102,6 +102,13 @@ const calcFunc_t<T> calcFunctions[] = {
{ CALC_IRR_CH, &calcIrradiation }
};
enum class InverterStatus : uint8_t {
OFF,
STARTING,
PRODUCING,
WAS_PRODUCING,
WAS_ON
};
template <class REC_TYP>
class Inverter {
@ -123,6 +130,9 @@ class Inverter {
//String lastAlarmMsg;
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)
InverterStatus status; // indicates the current inverter status
static uint32_t *timestamp; // system timestamp
Inverter() {
ivGen = IV_HM;
@ -135,6 +145,7 @@ class Inverter {
//lastAlarmMsg = "nothing";
alarmMesIndex = 0;
isConnected = false;
status = InverterStatus::OFF;
}
~Inverter() {
@ -319,6 +330,9 @@ class Inverter {
}
else
DPRINTLN(DBG_ERROR, F("addValue: assignment not found with cmd 0x"));
// update status state-machine
isProducing();
}
/*inline REC_TYP getPowerLimit(void) {
@ -372,25 +386,39 @@ class Inverter {
}
}
bool isAvailable(uint32_t timestamp) {
if((timestamp - recordMeas.ts) < INACT_THRES_SEC)
return true;
if((timestamp - recordInfo.ts) < INACT_THRES_SEC)
return true;
if((timestamp - recordConfig.ts) < INACT_THRES_SEC)
return true;
if((timestamp - recordAlarm.ts) < INACT_THRES_SEC)
return true;
return false;
bool isAvailable() {
bool val = false;
if((*timestamp - recordMeas.ts) < INACT_THRES_SEC)
val = true;
if((*timestamp - recordInfo.ts) < INACT_THRES_SEC)
val = true;
if((*timestamp - recordConfig.ts) < INACT_THRES_SEC)
val = true;
if((*timestamp - recordAlarm.ts) < INACT_THRES_SEC)
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"));
if(isAvailable(timestamp)) {
if(isAvailable()) {
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() {
@ -605,6 +633,9 @@ class Inverter {
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

3
src/hm/hmSystem.h

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

2
src/platformio.ini

@ -26,7 +26,7 @@ lib_deps =
https://github.com/yubox-node-org/ESPAsyncWebServer
nrf24/RF24 @ 1.4.5
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
https://github.com/JChristensen/Timezone @ ^1.2.4
olikraus/U8g2 @ ^2.34.17

2
src/plugins/Display/Display.h

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

6
src/publisher/pubMqtt.h

@ -489,9 +489,9 @@ class PubMqtt {
// inverter status
uint8_t status = MQTT_STATUS_NOT_AVAIL_NOT_PROD;
if (iv->isAvailable(*mUtcTimestamp)) {
if (iv->isAvailable()) {
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
allAvail = false;
@ -551,7 +551,7 @@ class PubMqtt {
switch (rec->assign[i].fieldId) {
case FLD_YT:
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;
retained = true;
break;

38
src/publisher/pubMqttIvData.h

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

2
src/publisher/pubSerial.h

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

4
src/web/RestApi.h

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

Loading…
Cancel
Save