From 9d1147b3716f98856f4129f19bfeecb6bbd14c9a Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Tue, 13 Feb 2024 12:13:53 +0100 Subject: [PATCH] more gracefull handling of complete retransmits - Heuristics is less strict with complete retransmits - fix MI typo - new logic for MI alarms (not working correctly!) --- src/hm/Communication.h | 86 +++++++++++++++++++++++------------------- src/hm/Heuristic.h | 8 +++- src/hm/hmRadio.h | 4 +- 3 files changed, 56 insertions(+), 42 deletions(-) diff --git a/src/hm/Communication.h b/src/hm/Communication.h index a37bcdb2..8c7fbe6d 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -276,7 +276,7 @@ class Communication : public CommQueue<> { DBGPRINT(F(" frames missing ")); DBGPRINTLN(F("-> complete retransmit")); } - mHeu.evalTxChQuality(q->iv, false, (q->attemptsMax - 1 - q->attempts), q->iv->curFrmCnt); + mHeu.evalTxChQuality(q->iv, false, (q->attemptsMax - 1 - q->attempts), q->iv->curFrmCnt, true); q->iv->radioStatistics.txCnt--; q->iv->radioStatistics.retransmits++; mCompleteRetry = true; @@ -893,50 +893,60 @@ class Communication : public CommQueue<> { uint16_t prntsts = (statusMi == 3) ? 1 : statusMi; bool stsok = true; - if ( prntsts != rec->record[q->iv->getPosByChFld(0, FLD_EVT, rec)] ) { //sth.'s changed? - q->iv->alarmCnt = 1; // minimum... + bool changedStatus = false; //if true, raise alarms and send via mqtt (might affect single channel only) + uint8_t oldState = rec->record[q->iv->getPosByChFld(0, FLD_EVT, rec)]; + if ( prntsts != oldState ) { // sth.'s changed? stsok = false; - //sth is or was wrong? - if ((q->iv->type != INV_TYPE_1CH) - && ((statusMi != 3) - || ((q->iv->lastAlarm[stschan].code) && (q->iv->lastAlarm[stschan].code != 1))) - ) { - q->iv->lastAlarm[stschan+q->iv->type==INV_TYPE_2CH ? 2: 4] = alarm_t(q->iv->lastAlarm[stschan].code, q->iv->lastAlarm[stschan].start,q->ts); - q->iv->lastAlarm[stschan] = alarm_t(prntsts, q->ts,0); - q->iv->alarmCnt = q->iv->type == INV_TYPE_2CH ? 3 : 5; - } else if ((q->iv->type == INV_TYPE_1CH) - && ( (statusMi != 3) - || ((q->iv->lastAlarm[stschan].code) && (q->iv->lastAlarm[stschan].code != 1))) - ) { - q->iv->lastAlarm[stschan] = alarm_t(q->iv->lastAlarm[0].code, q->iv->lastAlarm[0].start,q->ts); - } else if (q->iv->type == INV_TYPE_1CH) - stsok = true; - - q->iv->alarmLastId = prntsts; //iv->alarmMesIndex; - - if (q->iv->alarmCnt > 1) { //more than one channel - for (uint8_t ch = 0; ch < (q->iv->alarmCnt); ++ch) { //start with 1 - if (q->iv->lastAlarm[ch].code == 1) { - stsok = true; - break; + if(!oldState) { // initial zero value? => just write this channel to main state and raise changed flags + changedStatus = true; + q->iv->alarmCnt = 1; // minimum... + } else { + //sth is or was wrong? + if (q->iv->type == INV_TYPE_1CH) { + changedStatus = true; + if(q->iv->alarmCnt == 2) // we had sth. other than "producing" in the past + q->iv->lastAlarm[1].end = q->ts; + else { // copy old state and mark as ended + q->iv->lastAlarm[1] = alarm_t(q->iv->lastAlarm[0].code, q->iv->lastAlarm[0].start,q->ts); + q->iv->alarmCnt = 2; + } + } else if((prntsts != 1) || (q->iv->alarmCnt > 1) ) { // we had sth. other than "producing" in the past in at least one channel (2 and 4 ch types) + if (q->iv->alarmCnt == 1) + q->iv->alarmCnt = (q->iv->type == INV_TYPE_2CH) ? 5 : 9; + if(q->iv->lastAlarm[stschan].code != prntsts) { // changed? + changedStatus = true; + if(q->iv->lastAlarm[stschan].code) // copy old data and mark as ended (if any) + q->iv->lastAlarm[(stschan + (q->iv->type==INV_TYPE_2CH ? 2 : 4))] = alarm_t(q->iv->lastAlarm[stschan].code, q->iv->lastAlarm[stschan].start,q->ts); + q->iv->lastAlarm[stschan] = alarm_t(prntsts, q->ts,0); + } + if(changedStatus) { + for (uint8_t i = 1; i <= q->iv->channels; i++) { //start with 1 + if (q->iv->lastAlarm[i].code == 1) { + stsok = true; + break; + } + } } } } - if(*mSerialDebug) { - DPRINT(DBG_WARN, F("New state on CH")); - DBGPRINT(String(stschan)); DBGPRINT(F(" (")); - DBGPRINT(String(prntsts)); DBGPRINT(F("): ")); - DBGPRINTLN(q->iv->getAlarmStr(prntsts)); - } - if(!q->iv->miMultiParts) - q->iv->miMultiParts = 1; // indicate we got status info (1+2 ch types) } if (!stsok) { q->iv->setValue(q->iv->getPosByChFld(0, FLD_EVT, rec), rec, prntsts); q->iv->lastAlarm[0] = alarm_t(prntsts, q->ts, 0); + } + if (changedStatus || !stsok) { rec->ts = q->ts; rec->mqttSentStatus = MqttSentStatus::NEW_DATA; + q->iv->alarmLastId = prntsts; //iv->alarmMesIndex; + if (NULL != mCbAlarm) + (mCbAlarm)(q->iv); + if(*mSerialDebug) { + DPRINT(DBG_WARN, F("New state on CH")); + DBGPRINT(String(stschan)); DBGPRINT(F(" (")); + DBGPRINT(String(prntsts)); DBGPRINT(F("): ")); + DBGPRINTLN(q->iv->getAlarmStr(prntsts)); + } } if (q->iv->alarmMesIndex < rec->record[q->iv->getPosByChFld(0, FLD_EVT, rec)]) { @@ -947,6 +957,8 @@ class Communication : public CommQueue<> { DBGPRINTLN(String(q->iv->alarmMesIndex)); } } + if(!q->iv->miMultiParts) + q->iv->miMultiParts = 1; // indicate we got status info (1+2 ch types) } @@ -986,10 +998,8 @@ class Communication : public CommQueue<> { ac_pow += iv->getValue(iv->getPosByChFld(1, FLD_PDC, rec), rec); } else { for(uint8_t i = 1; i <= iv->channels; i++) { - if ((!iv->lastAlarm[i].code) || (iv->lastAlarm[i].code == 1)) { - uint8_t pos = iv->getPosByChFld(i, FLD_PDC, rec); - ac_pow += iv->getValue(pos, rec); - } + if ((!iv->lastAlarm[i].code) || (iv->lastAlarm[i].code == 1)) + ac_pow += iv->getValue(iv->getPosByChFld(i, FLD_PDC, rec), rec); } } ac_pow = (int) (ac_pow*9.5); diff --git a/src/hm/Heuristic.h b/src/hm/Heuristic.h index ecf82aa7..cc42df4f 100644 --- a/src/hm/Heuristic.h +++ b/src/hm/Heuristic.h @@ -38,6 +38,8 @@ class Heuristic { ih->txRfChId = curId; curId = (curId + 1) % RF_MAX_CHANNEL_ID; } + if(ih->txRfQuality[ih->txRfChId] == RF_MIN_QUALTIY) // all channels are bad, reset... + ih->clear(); if(ih->testPeriodSendCnt < 0xff) ih->testPeriodSendCnt++; @@ -71,7 +73,7 @@ class Heuristic { return id2Ch(ih->txRfChId); } - void evalTxChQuality(Inverter<> *iv, bool crcPass, uint8_t retransmits, uint8_t rxFragments) { + void evalTxChQuality(Inverter<> *iv, bool crcPass, uint8_t retransmits, uint8_t rxFragments, bool quotaMissed = false) { HeuristicInv *ih = &iv->heuristics; #if (DBG_DEBUG == DEBUG_LEVEL) @@ -84,8 +86,10 @@ class Heuristic { DBGPRINT(", "); DBGPRINTLN(String(ih->lastRxFragments)); #endif + if(quotaMissed) // we got not enough frames on this attempt, but iv was answering + updateQuality(ih, (rxFragments > 3 ? RF_TX_CHAN_QUALITY_GOOD : (rxFragments > 1 ? RF_TX_CHAN_QUALITY_OK : RF_TX_CHAN_QUALITY_LOW))); - if(ih->lastRxFragments == rxFragments) { + else if(ih->lastRxFragments == rxFragments) { if(crcPass) updateQuality(ih, RF_TX_CHAN_QUALITY_GOOD); else if(!retransmits || isNewTxCh(ih)) { // nothing received: send probably lost diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index d1d24364..eb44dd8c 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -77,7 +77,7 @@ class HmRadio : public Radio { #else mNrf24->begin(mSpi.get(), ce, cs); #endif - mNrf24->setRetries(3, 9); // wait 3*250 = 750us, 16 * 250us -> 4000us = 4ms + mNrf24->setRetries(3, 15); // wait 3*250 = 750us, 16 * 250us -> 4000us = 4ms mNrf24->setDataRate(RF24_250KBPS); //mNrf24->setAutoAck(true); // enabled by default @@ -159,7 +159,7 @@ class HmRadio : public Radio { mTimeslotStart = millis(); tempRxChIdx = mRxChIdx; // might be better to start off with one channel less? mRxPendular = false; - mNRFloopChannels = (mLastIv->mCmd == MI_REQ_CH1); + mNRFloopChannels = (mLastIv->mCmd == MI_REQ_CH1 || mLastIv->mCmd == MI_REQ_CH2); innerLoopTimeout = DURATION_LISTEN_MIN; }