diff --git a/src/defines.h b/src/defines.h index cffc0278..3a85392f 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 2708 +#define VERSION_PATCH 2716 //------------------------------------- typedef struct { diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 48e92ce9..b5b1aa66 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -176,6 +176,7 @@ class Communication : public CommQueue<> { if(validateIvSerial(&p->packet[1], q->iv)) { q->iv->radioStatistics.frmCnt++; + q->iv->mDtuRxCnt++; //q->iv->mRxChanIdx = mRxChanIdx; if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command @@ -486,8 +487,13 @@ class Communication : public CommQueue<> { record_t<> *rec = q->iv->getRecordStruct(q->cmd); if(NULL == rec) { - DPRINTLN(DBG_ERROR, F("record is NULL!")); - closeRequest(q, false); + if(GetLossRate == q->cmd) { + q->iv->parseGetLossRate(q->iv->id, mPayload, len); + closeRequest(q, true); + } else { + DPRINTLN(DBG_ERROR, F("record is NULL!")); + closeRequest(q, false); + } return; } if((rec->pyldLen != len) && (0 != rec->pyldLen)) { diff --git a/src/hm/hmDefines.h b/src/hm/hmDefines.h index c00f4940..55259289 100644 --- a/src/hm/hmDefines.h +++ b/src/hm/hmDefines.h @@ -139,6 +139,8 @@ const byteAssign_t AlarmDataAssignment[] = { #define HMALARMDATA_PAYLOAD_LEN 0 // 0: means check is off #define ALARM_LOG_ENTRY_SIZE 12 +#define HMGETLOSSRATE_PAYLOAD_LEN 4 +#define AHOY_GET_LOSS_INTERVAL 10 //------------------------------------- // HM300, HM350, HM400 diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index 7c987fb2..0a369802 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -135,6 +135,7 @@ class Inverter { bool mGotLastMsg; // shows if inverter has already finished transmission cycle uint8_t mCmd; // holds the command to send uint8_t mRxChanIdx; // holds the index of the last used rx channel + bool mRxChanSync; // indicates if last rx channel ist synced bool mIsSingleframeReq; // indicates this is a missing single frame request Radio *radio; // pointer to associated radio class statistics_t radioStatistics; // information about transmitted, failed, ... packets @@ -142,6 +143,12 @@ class Inverter { uint8_t curCmtFreq; // current used CMT frequency, used to check if freq. was changed during runtime bool commEnabled; // 'pause night communication' sets this field to false + uint16_t mIvRxCnt; // last iv rx frames (from GetLossRate) + uint16_t mIvTxCnt; // last iv tx frames (from GetLossRate) + uint16_t mDtuRxCnt; // cur dtu rx frames (since last GetLossRate) + uint16_t mDtuTxCnt; // cur dtu tx frames (since last getLoassRate) + uint8_t mGetLossInterval; // request iv every AHOY_GET_LOSS_INTERVAL RealTimeRunData_Debug + static uint32_t *timestamp; // system timestamp static cfgInst_t *generalConfig; // general inverter configuration from setup @@ -164,6 +171,7 @@ class Inverter { mGotLastMsg = false; mCmd = InitDataState; mRxChanIdx = 1; + mRxChanSync = false; mIsSingleframeReq = false; radio = NULL; commEnabled = true; @@ -180,6 +188,8 @@ class Inverter { cb(devControlCmd, true); mDevControlRequest = false; } else if (IV_MI != ivGen) { + mGetLossInterval++; + if((alarmLastId != alarmMesIndex) && (alarmMesIndex != 0)) cb(AlarmData, false); // get last alarms else if(0 == getFwVersion()) @@ -191,9 +201,18 @@ class Inverter { else if(InitDataState != devControlCmd) { cb(devControlCmd, false); // custom command which was received by API devControlCmd = InitDataState; - } else if((0 == mGridLen) && generalConfig->readGrid) { // read grid profile + mGetLossInterval = 1; + } + else if((0 == mGridLen) && generalConfig->readGrid) { // read grid profile cb(GridOnProFilePara, false); - } else + } + else if (mGetLossInterval > AHOY_GET_LOSS_INTERVAL) { + mGetLossInterval = 1; + //DPRINTLN(DBG_INFO, F("enqueue GetLossRate")); + cb(GetLossRate, false); + } + + else cb(RealTimeRunData_Debug, false); // get live data } else { if(0 == getFwVersion()) @@ -202,8 +221,10 @@ class Inverter { record_t<> *rec = getRecordStruct(InverterDevInform_Simple); if (getChannelFieldValue(CH0, FLD_PART_NUM, rec) == 0) cb(0x0f, false); // hard- and firmware version for missing HW part nr, delivered by frame 1 - else + else { + mGetLossInterval++; cb(((type == INV_TYPE_4CH) ? MI_REQ_4CH : MI_REQ_CH1), false); + } } } } @@ -580,6 +601,27 @@ class Inverter { memset(mLastYD, 0, sizeof(float) * 6); } + bool parseGetLossRate(uint8_t id, uint8_t pyld[], uint8_t len) { + if (len == HMGETLOSSRATE_PAYLOAD_LEN) { + uint16_t rxCnt = (pyld[0] << 8) + pyld[1]; + uint16_t txCnt = (pyld[2] << 8) + pyld[3]; + + if (mIvRxCnt || mIvTxCnt) { // there was successful GetLossRate in the past + DPRINT_IVID(DBG_INFO, id); + DBGPRINTLN("Inv loss: " + String (mDtuTxCnt - (rxCnt - mIvRxCnt)) + " of " + + String (mDtuTxCnt) + ", DTU loss: " + + String (txCnt - mIvTxCnt - mDtuRxCnt) + " of " + + String (txCnt - mIvTxCnt)); + } + mIvRxCnt = rxCnt; + mIvTxCnt = txCnt; + mDtuRxCnt = 0; // start new interval + mDtuTxCnt = 0; // start new interval + return true; + } + return false; + } + uint16_t parseAlarmLog(uint8_t id, uint8_t pyld[], uint8_t len) { uint8_t startOff = 2 + id * ALARM_LOG_ENTRY_SIZE; if((startOff + ALARM_LOG_ENTRY_SIZE) > len) diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index a18fa5ec..f8a1257d 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -129,19 +129,23 @@ class HmRadio : public Radio { //(mLastIv->mRxChanIdx + RF_MAX_CHANNEL_ID -1) % RF_MAX_CHANNEL_ID; // make sure, we start with last successfull channel (result will be increased in loop) //mRxChannels - 1; // //(mTxChIdx + mRxChannels) % RF_MAX_CHANNEL_ID; // start with a fixed offset + bool switchch = true; while ((millis() - loopMillis) < mRxTmoOuterLoop) { while ((micros() - startMicros) < mRxTmoInnerLoop) { // listen (4088us or?) 5110us to each channel if (mIrqRcvd) { mIrqRcvd = false; if (getReceived()) { // everything received - mLastIv->mRxChanIdx = mRxChIdx; return; } } yield(); } // switch to next RX channel + /*if (mLastIv->mRxChanSync) { + switchch = !switchch; + mRxChIdx = mLastIv->mRxChanIdx - switchch; + }*/ if(++mRxChIdx >= RF_CHANNELS) mRxChIdx = 0; @@ -161,6 +165,7 @@ class HmRadio : public Radio { //if(!mLastIv->mGotFragment) mLastIv->mRxChanIdx = mLastIv->mRxChanIdx +1; // + 2; //mLastIv->mRxChanIdx = ++mRxChIdx; + mLastIv->mRxChanSync = false; return; } @@ -326,6 +331,9 @@ class HmRadio : public Radio { return false; } mLastIv->mGotFragment = true; + mLastIv->mRxChanIdx = mRxChIdx; + mLastIv->mRxChanSync = true; + mBufCtrl.push(p); if (p.packet[0] == (TX_REQ_INFO + ALL_FRAMES)) // response from get information command isLastPackage = (p.packet[9] > ALL_FRAMES); // > ALL_FRAMES indicates last packet received @@ -378,6 +386,7 @@ class HmRadio : public Radio { mMillis = millis(); mLastIv = iv; + iv->mDtuTxCnt++; } uint64_t getIvId(Inverter<> *iv) { diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index d57a590b..4aea6a41 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -111,6 +111,7 @@ class CmtRadio : public Radio { if(CMT_ERR_RX_IN_FIFO == status) mIrqRcvd = true; } + iv->mDtuTxCnt++; } uint64_t getIvId(Inverter<> *iv) { diff --git a/src/publisher/pubMqttIvData.h b/src/publisher/pubMqttIvData.h index 0ac6d306..3600e22c 100644 --- a/src/publisher/pubMqttIvData.h +++ b/src/publisher/pubMqttIvData.h @@ -127,6 +127,11 @@ class PubMqttIvData { void stateSend() { record_t<> *rec = mIv->getRecordStruct(mCmd); + if(rec == NULL) { + if (mCmd != GetLossRate) + DPRINT(DBG_WARN, "unknown record to publish!"); + return; + } uint32_t lastTs = mIv->getLastTs(rec); bool pubData = (lastTs > 0); if (mCmd == RealTimeRunData_Debug)