Skip to content

Commit

Permalink
0.8.16
Browse files Browse the repository at this point in the history
* updated heuristic #1080 #1259
* fix compile opendtufusion fusion ethernet
  • Loading branch information
lumapu committed Dec 9, 2023
1 parent 4afd631 commit 240be8c
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 66 deletions.
2 changes: 2 additions & 0 deletions src/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## 0.8.16 - 2023-12-09
* fix crash if NRF is not enabled
* updated heuristic #1080 #1259
* fix compile opendtufusion fusion ethernet

## 0.8.15 - 2023-12-09
* added support for opendtufusion fusion ethernet shield #886
Expand Down
34 changes: 12 additions & 22 deletions src/hm/Communication.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ class Communication : public CommQueue<> {
} else
q->iv->radio->prepareDevInformCmd(q->iv, q->cmd, q->ts, q->iv->alarmLastId, false);

if(!mHeu.getTestModeEnabled(q->iv))
q->iv->radioStatistics.txCnt++;
q->iv->radioStatistics.txCnt++;
mWaitTimeout = millis() + timeout;
mWaitTimeout_min = millis() + timeout_min;
mIsResend = false;
Expand All @@ -115,8 +114,7 @@ class Communication : public CommQueue<> {
}
mFirstTry = false;
mlastTO_min = timeout_min;
if(!mHeu.getTestModeEnabled(q->iv))
q->iv->radioStatistics.retransmits++; // got nothing
q->iv->radioStatistics.retransmits++; // got nothing
mState = States::START;
break;
}
Expand Down Expand Up @@ -166,6 +164,7 @@ class Communication : public CommQueue<> {
DBGPRINT(String(p->ch));
DBGPRINT(F(" "));
} else {
DBGPRINT(F(" "));
DBGPRINT(String(p->rssi));
DBGPRINT(F("dBm | "));
}
Expand All @@ -180,8 +179,7 @@ class Communication : public CommQueue<> {
}

if(checkIvSerial(&p->packet[1], q->iv)) {
if(!mHeu.getTestModeEnabled(q->iv))
q->iv->radioStatistics.frmCnt++;
q->iv->radioStatistics.frmCnt++;

if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command
parseFrame(p);
Expand All @@ -193,8 +191,7 @@ class Communication : public CommQueue<> {
parseMiFrame(p, q);
}
} else {
if(!mHeu.getTestModeEnabled(q->iv))
q->iv->radioStatistics.rxFail++; // got no complete payload
q->iv->radioStatistics.rxFail++; // got no complete payload
DPRINTLN(DBG_WARN, F("Inverter serial does not match"));
mWaitTimeout = millis() + timeout;
}
Expand Down Expand Up @@ -370,8 +367,7 @@ class Communication : public CommQueue<> {
DBGPRINT(F("CRC Error "));
if(q->attempts == 0) {
DBGPRINTLN(F("-> Fail"));
/*if(!mHeu.getTestModeEnabled())
q->iv->radioStatistics.rxFail++; // got fragments but not complete response
/*q->iv->radioStatistics.rxFail++; // got fragments but not complete response
cmdDone();*/
closeRequest(q->iv, false, false);

Expand Down Expand Up @@ -420,8 +416,7 @@ class Communication : public CommQueue<> {
DBGPRINT(String(rec->pyldLen));
DBGPRINTLN(F(" bytes"));
}
/*if(!mHeu.getTestModeEnabled())
q->iv->radioStatistics.rxFail++;*/
/*q->iv->radioStatistics.rxFail++;*/
closeRequest(q->iv, false, false);

return;
Expand Down Expand Up @@ -464,15 +459,12 @@ class Communication : public CommQueue<> {
// ordering of lines is relevant for statistics
if(succeeded) {
mHeu.setGotAll(iv);
if(!mHeu.getTestModeEnabled(iv))
iv->radioStatistics.rxSuccess++;
iv->radioStatistics.rxSuccess++;
} else if(iv->mGotFragment) {
mHeu.setGotFragment(iv);
if(!mHeu.getTestModeEnabled(iv))
iv->radioStatistics.rxFail++; // got no complete payload
iv->radioStatistics.rxFail++; // got no complete payload
} else {
if(!mHeu.getTestModeEnabled(iv))
iv->radioStatistics.rxFailNoAnser++; // got nothing
iv->radioStatistics.rxFailNoAnser++; // got nothing
mHeu.setGotNothing(iv);
mWaitTimeout = millis() + WAIT_GAP_TIMEOUT;
}
Expand Down Expand Up @@ -682,12 +674,10 @@ class Communication : public CommQueue<> {

if(q->iv->miMultiParts == 7) {
mHeu.setGotAll(q->iv);
if(!mHeu.getTestModeEnabled(q->iv))
q->iv->radioStatistics.rxSuccess++;
q->iv->radioStatistics.rxSuccess++;
} else
mHeu.setGotFragment(q->iv);
/*if(!mHeu.getTestModeEnabled())
iv->radioStatistics.rxFail++; // got no complete payload*/
/*iv->radioStatistics.rxFail++; // got no complete payload*/
//q->iv->radioStatistics.retransmits++;
q->iv->radio->sendCmdPacket(q->iv, cmd, 0x00, true);

Expand Down
94 changes: 55 additions & 39 deletions src/hm/Heuristic.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,61 +10,79 @@
#include "hmInverter.h"
#include "HeuristicInv.h"

#define RF_TEST_PERIOD_MAX_SEND_CNT 50
#define RF_TEST_PERIOD_MAX_FAIL_CNT 5

#define RF_TX_TEST_CHAN_1ST_USE 0xff

class Heuristic {
public:
uint8_t getTxCh(Inverter<> *iv) {
if((IV_HMS == iv->ivGen) || (IV_HMT == iv->ivGen))
return 0; // not used for these inverter types

uint8_t bestId = 0;
int8_t bestQuality = -6;
for(uint8_t i = 0; i < RF_MAX_CHANNEL_ID; i++) {
if(iv->heuristics.txRfQuality[i] > bestQuality) {
bestQuality = iv->heuristics.txRfQuality[i];
bestId = i;
}
HeuristicInv *ih = &iv->heuristics;

// start with the next index: round robbin in case of same 'best' quality
uint8_t curId = (ih->txRfChId + 1) % RF_MAX_CHANNEL_ID;
uint8_t lastBestId = ih->txRfChId;
ih->txRfChId = curId;
curId = (curId + 1) % RF_MAX_CHANNEL_ID;
for(uint8_t i = 1; i < RF_MAX_CHANNEL_ID; i++) {
if(ih->txRfQuality[curId] > ih->txRfQuality[ih->txRfChId])
ih->txRfChId = curId;
curId = (curId + 1) % RF_MAX_CHANNEL_ID;
}

if(iv->heuristics.testEn) {
DPRINTLN(DBG_INFO, F("heuristic test mode"));
iv->heuristics.testIdx = (iv->heuristics.testIdx + 1) % RF_MAX_CHANNEL_ID;
if(ih->testPeriodSendCnt < 0xff)
ih->testPeriodSendCnt++;

if (iv->heuristics.testIdx == bestId)
iv->heuristics.testIdx = (iv->heuristics.testIdx + 1) % RF_MAX_CHANNEL_ID;
if((ih->txRfChId == lastBestId) && (ih->testPeriodSendCnt >= RF_TEST_PERIOD_MAX_SEND_CNT)) {
if(ih->testPeriodFailCnt > RF_TEST_PERIOD_MAX_FAIL_CNT) {
// try round robbin another chan and see if it works even better
ih->testChId = (ih->testChId + 1) % RF_MAX_CHANNEL_ID;
if(ih->testChId = ih->txRfChId)
ih->testChId = (ih->testChId + 1) % RF_MAX_CHANNEL_ID;

// test channel get's quality of best channel (maybe temporarily, see in 'setGotNothing')
iv->heuristics.storedIdx = iv->heuristics.txRfQuality[iv->heuristics.testIdx];
iv->heuristics.txRfQuality[iv->heuristics.testIdx] = bestQuality;
// give it a fair chance but remember old status in case of immediate fail
ih->txRfChId = ih->testChId;
ih->testChId = RF_TX_TEST_CHAN_1ST_USE; // mark the chan as a test and as 1st use during new test period
DPRINTLN(DBG_INFO, "Test CH " + String(id2Ch(ih->txRfChId)));
}

iv->heuristics.txRfChId = iv->heuristics.testIdx;
} else
iv->heuristics.txRfChId = bestId;
// start new test period
ih->testPeriodSendCnt = 0;
ih->testPeriodFailCnt = 0;
} else if(ih->txRfChId != lastBestId) {
// start new test period
ih->testPeriodSendCnt = 0;
ih->testPeriodFailCnt = 0;
}

return id2Ch(iv->heuristics.txRfChId);
return id2Ch(ih->txRfChId);
}

void setGotAll(Inverter<> *iv) {
updateQuality(iv, 2); // GOOD
iv->heuristics.testEn = false;
}

void setGotFragment(Inverter<> *iv) {
updateQuality(iv, 1); // OK
iv->heuristics.testEn = false;
}

void setGotNothing(Inverter<> *iv) {
if(RF_NA != iv->heuristics.storedIdx) {
// if communication fails on first try with temporarily good level, revert it back to its original level
iv->heuristics.txRfQuality[iv->heuristics.txRfChId] = iv->heuristics.storedIdx;
iv->heuristics.storedIdx = RF_NA;
HeuristicInv *ih = &iv->heuristics;

if(RF_TX_TEST_CHAN_1ST_USE == ih->testChId) {
// immediate fail
ih->testChId = ih->txRfChId; // reset to best
return;
}

if(!iv->heuristics.testEn) {
updateQuality(iv, -2); // BAD
iv->heuristics.testEn = true;
} else
iv->heuristics.testEn = false;
if(ih->testPeriodFailCnt < 0xff)
ih->testPeriodFailCnt++;

updateQuality(iv, -2); // BAD
}

void printStatus(Inverter<> *iv) {
Expand All @@ -86,17 +104,15 @@ class Heuristic {
DBGPRINTLN(String(iv->config->powerLevel));
}

bool getTestModeEnabled(Inverter<> *iv) {
return iv->heuristics.testEn;
}

private:
void updateQuality(Inverter<> *iv, uint8_t quality) {
iv->heuristics.txRfQuality[iv->heuristics.txRfChId] += quality;
if(iv->heuristics.txRfQuality[iv->heuristics.txRfChId] > RF_MAX_QUALITY)
iv->heuristics.txRfQuality[iv->heuristics.txRfChId] = RF_MAX_QUALITY;
else if(iv->heuristics.txRfQuality[iv->heuristics.txRfChId] < RF_MIN_QUALTIY)
iv->heuristics.txRfQuality[iv->heuristics.txRfChId] = RF_MIN_QUALTIY;
HeuristicInv *ih = &iv->heuristics;

ih->txRfQuality[ih->txRfChId] += quality;
if(ih->txRfQuality[ih->txRfChId] > RF_MAX_QUALITY)
ih->txRfQuality[ih->txRfChId] = RF_MAX_QUALITY;
else if(ih->txRfQuality[ih->txRfChId] < RF_MIN_QUALTIY)
ih->txRfQuality[ih->txRfChId] = RF_MIN_QUALTIY;
}

inline uint8_t id2Ch(uint8_t id) {
Expand Down
15 changes: 10 additions & 5 deletions src/hm/HeuristicInv.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,17 @@

class HeuristicInv {
public:
int8_t txRfQuality[5]; // heuristics tx quality (check 'Heuristics.h')
uint8_t txRfChId; // RF TX channel id
HeuristicInv() {
memset(txRfQuality, -6, RF_MAX_CHANNEL_ID);
}

bool testEn = false;
uint8_t testIdx = 0;
int8_t storedIdx = RF_NA;
public:
int8_t txRfQuality[RF_MAX_CHANNEL_ID]; // heuristics tx quality (check 'Heuristics.h')
uint8_t txRfChId = 0; // RF TX channel id

uint8_t testPeriodSendCnt = 0;
uint8_t testPeriodFailCnt = 0;
uint8_t testChId = 0;
};

#endif /*__HEURISTIC_INV_H__*/
4 changes: 4 additions & 0 deletions src/hm/hmRadio.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ class HmRadio : public Radio {
HmRadio() {
mDtuSn = DTU_SN;
mIrqRcvd = false;
#if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(ETHERNET)
mNrf24.reset(new RF24());
#else
mNrf24.reset(new RF24(CE_PIN, CS_PIN, SPI_SPEED));
#endif
}
~HmRadio() {}

Expand Down

0 comments on commit 240be8c

Please sign in to comment.