mirror of https://github.com/lumapu/ahoy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
4.4 KiB
118 lines
4.4 KiB
//-----------------------------------------------------------------------------
|
|
// 2023 Ahoy, https://github.com/lumpapu/ahoy
|
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifndef __HEURISTIC_H__
|
|
#define __HEURISTIC_H__
|
|
|
|
#include "../utils/dbg.h"
|
|
#include "hmInverter.h"
|
|
#include "HeuristicInv.h"
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
if(iv->heuristics.testEn) {
|
|
DPRINTLN(DBG_INFO, F("heuristic test mode"));
|
|
iv->heuristics.testIdx = (iv->heuristics.testIdx + 1) % RF_MAX_CHANNEL_ID;
|
|
|
|
if (iv->heuristics.testIdx == bestId)
|
|
iv->heuristics.testIdx = (iv->heuristics.testIdx + 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;
|
|
|
|
iv->heuristics.txRfChId = iv->heuristics.testIdx;
|
|
} else
|
|
iv->heuristics.txRfChId = bestId;
|
|
|
|
return id2Ch(iv->heuristics.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;
|
|
}
|
|
|
|
if(!iv->heuristics.testEn) {
|
|
updateQuality(iv, -2); // BAD
|
|
iv->heuristics.testEn = true;
|
|
} else
|
|
iv->heuristics.testEn = false;
|
|
}
|
|
|
|
void printStatus(Inverter<> *iv) {
|
|
DPRINT_IVID(DBG_INFO, iv->id);
|
|
DBGPRINT(F("Radio infos:"));
|
|
for(uint8_t i = 0; i < RF_MAX_CHANNEL_ID; i++) {
|
|
DBGPRINT(F(" "));
|
|
DBGPRINT(String(iv->heuristics.txRfQuality[i]));
|
|
}
|
|
DBGPRINT(F(" | t: "));
|
|
DBGPRINT(String(iv->radioStatistics.txCnt));
|
|
DBGPRINT(F(", s: "));
|
|
DBGPRINT(String(iv->radioStatistics.rxSuccess));
|
|
DBGPRINT(F(", f: "));
|
|
DBGPRINT(String(iv->radioStatistics.rxFail));
|
|
DBGPRINT(F(", n: "));
|
|
DBGPRINT(String(iv->radioStatistics.rxFailNoAnser));
|
|
DBGPRINT(F(" | p: ")); // better debugging for helpers...
|
|
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;
|
|
}
|
|
|
|
inline uint8_t id2Ch(uint8_t id) {
|
|
switch(id) {
|
|
case 0: return 3;
|
|
case 1: return 23;
|
|
case 2: return 40;
|
|
case 3: return 61;
|
|
case 4: return 75;
|
|
}
|
|
return 3; // standard
|
|
}
|
|
|
|
private:
|
|
uint8_t mChList[5] = {03, 23, 40, 61, 75};
|
|
};
|
|
|
|
|
|
#endif /*__HEURISTIC_H__*/
|
|
|