Browse Source

0.8.16

* updated heuristic #1080 #1259
* fix compile opendtufusion fusion ethernet
pull/1262/head
lumapu 1 year ago
parent
commit
240be8cd98
  1. 2
      src/CHANGES.md
  2. 34
      src/hm/Communication.h
  3. 94
      src/hm/Heuristic.h
  4. 15
      src/hm/HeuristicInv.h
  5. 4
      src/hm/hmRadio.h

2
src/CHANGES.md

@ -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

34
src/hm/Communication.h

@ -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;
@ -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;
}
@ -166,6 +164,7 @@ class Communication : public CommQueue<> {
DBGPRINT(String(p->ch));
DBGPRINT(F(" "));
} else {
DBGPRINT(F(" "));
DBGPRINT(String(p->rssi));
DBGPRINT(F("dBm | "));
}
@ -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);
@ -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;
}
@ -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);
@ -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;
@ -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;
}
@ -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);

94
src/hm/Heuristic.h

@ -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) {
@ -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) {

15
src/hm/HeuristicInv.h

@ -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
src/hm/hmRadio.h

@ -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() {}

Loading…
Cancel
Save