1010#include " hmInverter.h"
1111#include " HeuristicInv.h"
1212
13+ #define RF_TEST_PERIOD_MAX_SEND_CNT 50
14+ #define RF_TEST_PERIOD_MAX_FAIL_CNT 5
15+
16+ #define RF_TX_TEST_CHAN_1ST_USE 0xff
17+
1318class Heuristic {
1419 public:
1520 uint8_t getTxCh (Inverter<> *iv) {
1621 if ((IV_HMS == iv->ivGen ) || (IV_HMT == iv->ivGen ))
1722 return 0 ; // not used for these inverter types
1823
19- uint8_t bestId = 0 ;
20- int8_t bestQuality = -6 ;
21- for (uint8_t i = 0 ; i < RF_MAX_CHANNEL_ID; i++) {
22- if (iv->heuristics .txRfQuality [i] > bestQuality) {
23- bestQuality = iv->heuristics .txRfQuality [i];
24- bestId = i;
25- }
24+ HeuristicInv *ih = &iv->heuristics ;
25+
26+ // start with the next index: round robbin in case of same 'best' quality
27+ uint8_t curId = (ih->txRfChId + 1 ) % RF_MAX_CHANNEL_ID;
28+ uint8_t lastBestId = ih->txRfChId ;
29+ ih->txRfChId = curId;
30+ curId = (curId + 1 ) % RF_MAX_CHANNEL_ID;
31+ for (uint8_t i = 1 ; i < RF_MAX_CHANNEL_ID; i++) {
32+ if (ih->txRfQuality [curId] > ih->txRfQuality [ih->txRfChId ])
33+ ih->txRfChId = curId;
34+ curId = (curId + 1 ) % RF_MAX_CHANNEL_ID;
2635 }
2736
28- if (iv->heuristics .testEn ) {
29- DPRINTLN (DBG_INFO, F (" heuristic test mode" ));
30- iv->heuristics .testIdx = (iv->heuristics .testIdx + 1 ) % RF_MAX_CHANNEL_ID;
37+ if (ih->testPeriodSendCnt < 0xff )
38+ ih->testPeriodSendCnt ++;
3139
32- if (iv->heuristics .testIdx == bestId)
33- iv->heuristics .testIdx = (iv->heuristics .testIdx + 1 ) % RF_MAX_CHANNEL_ID;
40+ if ((ih->txRfChId == lastBestId) && (ih->testPeriodSendCnt >= RF_TEST_PERIOD_MAX_SEND_CNT)) {
41+ if (ih->testPeriodFailCnt > RF_TEST_PERIOD_MAX_FAIL_CNT) {
42+ // try round robbin another chan and see if it works even better
43+ ih->testChId = (ih->testChId + 1 ) % RF_MAX_CHANNEL_ID;
44+ if (ih->testChId = ih->txRfChId )
45+ ih->testChId = (ih->testChId + 1 ) % RF_MAX_CHANNEL_ID;
3446
35- // test channel get's quality of best channel (maybe temporarily, see in 'setGotNothing')
36- iv->heuristics .storedIdx = iv->heuristics .txRfQuality [iv->heuristics .testIdx ];
37- iv->heuristics .txRfQuality [iv->heuristics .testIdx ] = bestQuality;
47+ // give it a fair chance but remember old status in case of immediate fail
48+ ih->txRfChId = ih->testChId ;
49+ ih->testChId = RF_TX_TEST_CHAN_1ST_USE; // mark the chan as a test and as 1st use during new test period
50+ DPRINTLN (DBG_INFO, " Test CH " + String (id2Ch (ih->txRfChId )));
51+ }
3852
39- iv->heuristics .txRfChId = iv->heuristics .testIdx ;
40- } else
41- iv->heuristics .txRfChId = bestId;
53+ // start new test period
54+ ih->testPeriodSendCnt = 0 ;
55+ ih->testPeriodFailCnt = 0 ;
56+ } else if (ih->txRfChId != lastBestId) {
57+ // start new test period
58+ ih->testPeriodSendCnt = 0 ;
59+ ih->testPeriodFailCnt = 0 ;
60+ }
4261
43- return id2Ch (iv-> heuristics . txRfChId );
62+ return id2Ch (ih-> txRfChId );
4463 }
4564
4665 void setGotAll (Inverter<> *iv) {
4766 updateQuality (iv, 2 ); // GOOD
48- iv->heuristics .testEn = false ;
4967 }
5068
5169 void setGotFragment (Inverter<> *iv) {
5270 updateQuality (iv, 1 ); // OK
53- iv->heuristics .testEn = false ;
5471 }
5572
5673 void setGotNothing (Inverter<> *iv) {
57- if (RF_NA != iv->heuristics .storedIdx ) {
58- // if communication fails on first try with temporarily good level, revert it back to its original level
59- iv->heuristics .txRfQuality [iv->heuristics .txRfChId ] = iv->heuristics .storedIdx ;
60- iv->heuristics .storedIdx = RF_NA;
74+ HeuristicInv *ih = &iv->heuristics ;
75+
76+ if (RF_TX_TEST_CHAN_1ST_USE == ih->testChId ) {
77+ // immediate fail
78+ ih->testChId = ih->txRfChId ; // reset to best
79+ return ;
6180 }
6281
63- if (!iv->heuristics .testEn ) {
64- updateQuality (iv, -2 ); // BAD
65- iv->heuristics .testEn = true ;
66- } else
67- iv->heuristics .testEn = false ;
82+ if (ih->testPeriodFailCnt < 0xff )
83+ ih->testPeriodFailCnt ++;
84+
85+ updateQuality (iv, -2 ); // BAD
6886 }
6987
7088 void printStatus (Inverter<> *iv) {
@@ -86,17 +104,15 @@ class Heuristic {
86104 DBGPRINTLN (String (iv->config ->powerLevel ));
87105 }
88106
89- bool getTestModeEnabled (Inverter<> *iv) {
90- return iv->heuristics .testEn ;
91- }
92-
93107 private:
94108 void updateQuality (Inverter<> *iv, uint8_t quality) {
95- iv->heuristics .txRfQuality [iv->heuristics .txRfChId ] += quality;
96- if (iv->heuristics .txRfQuality [iv->heuristics .txRfChId ] > RF_MAX_QUALITY)
97- iv->heuristics .txRfQuality [iv->heuristics .txRfChId ] = RF_MAX_QUALITY;
98- else if (iv->heuristics .txRfQuality [iv->heuristics .txRfChId ] < RF_MIN_QUALTIY)
99- iv->heuristics .txRfQuality [iv->heuristics .txRfChId ] = RF_MIN_QUALTIY;
109+ HeuristicInv *ih = &iv->heuristics ;
110+
111+ ih->txRfQuality [ih->txRfChId ] += quality;
112+ if (ih->txRfQuality [ih->txRfChId ] > RF_MAX_QUALITY)
113+ ih->txRfQuality [ih->txRfChId ] = RF_MAX_QUALITY;
114+ else if (ih->txRfQuality [ih->txRfChId ] < RF_MIN_QUALTIY)
115+ ih->txRfQuality [ih->txRfChId ] = RF_MIN_QUALTIY;
100116 }
101117
102118 inline uint8_t id2Ch (uint8_t id) {
0 commit comments