diff --git a/src/app.cpp b/src/app.cpp index daa13307..5359da30 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -32,11 +32,11 @@ void app::setup() { DBGPRINTLN(F("false")); if(mConfig->nrf.enabled) { - mNrfRadio.setup(&mConfig->serial.debug, &mConfig->serial.privacyLog, mConfig->nrf.pinIrq, mConfig->nrf.pinCe, mConfig->nrf.pinCs, mConfig->nrf.pinSclk, mConfig->nrf.pinMosi, mConfig->nrf.pinMiso); + mNrfRadio.setup(&mConfig->serial.debug, &mConfig->serial.privacyLog, &mConfig->serial.printWholeTrace, mConfig->nrf.pinIrq, mConfig->nrf.pinCe, mConfig->nrf.pinCs, mConfig->nrf.pinSclk, mConfig->nrf.pinMosi, mConfig->nrf.pinMiso); } #if defined(ESP32) if(mConfig->cmt.enabled) { - mCmtRadio.setup(&mConfig->serial.debug, &mConfig->serial.privacyLog, mConfig->cmt.pinSclk, mConfig->cmt.pinSdio, mConfig->cmt.pinCsb, mConfig->cmt.pinFcsb, false); + mCmtRadio.setup(&mConfig->serial.debug, &mConfig->serial.privacyLog, &mConfig->serial.printWholeTrace, mConfig->cmt.pinSclk, mConfig->cmt.pinSdio, mConfig->cmt.pinCsb, mConfig->cmt.pinFcsb, false); } #endif #ifdef ETHERNET @@ -55,7 +55,7 @@ void app::setup() { #endif #endif /* defined(ETHERNET) */ - mCommunication.setup(&mTimestamp, &mConfig->serial.debug, &mConfig->serial.privacyLog); + mCommunication.setup(&mTimestamp, &mConfig->serial.debug, &mConfig->serial.privacyLog, &mConfig->serial.printWholeTrace); mCommunication.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1, std::placeholders::_2)); mSys.setup(&mTimestamp, &mConfig->inst); for (uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { diff --git a/src/config/settings.h b/src/config/settings.h index 1fe7be00..46f0a565 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -30,7 +30,7 @@ * https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html#flash-layout * */ -#define CONFIG_VERSION 2 +#define CONFIG_VERSION 3 #define PROT_MASK_INDEX 0x0001 @@ -117,6 +117,7 @@ typedef struct { bool showIv; bool debug; bool privacyLog; + bool printWholeTrace; } cfgSerial_t; typedef struct { @@ -426,6 +427,7 @@ class settings { mCfg.serial.showIv = false; mCfg.serial.debug = false; mCfg.serial.privacyLog = true; + mCfg.serial.printWholeTrace = true; mCfg.mqtt.port = DEF_MQTT_PORT; snprintf(mCfg.mqtt.broker, MQTT_ADDR_LEN, "%s", DEF_MQTT_BROKER); @@ -476,6 +478,9 @@ class settings { mCfg.inst.iv[i].disNightCom = false; mCfg.inst.iv[i].add2Total = true; } + if(mCfg.configVersion < 3) { + mCfg.serial.printWholeTrace = true; + } } } @@ -620,10 +625,12 @@ class settings { obj[F("show")] = mCfg.serial.showIv; obj[F("debug")] = mCfg.serial.debug; obj[F("prv")] = (bool) mCfg.serial.privacyLog; + obj[F("trc")] = (bool) mCfg.serial.printWholeTrace; } else { getVal(obj, F("show"), &mCfg.serial.showIv); getVal(obj, F("debug"), &mCfg.serial.debug); getVal(obj, F("prv"), &mCfg.serial.privacyLog); + getVal(obj, F("trc"), &mCfg.serial.printWholeTrace); } } diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 91d10bed..f05d7986 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -11,21 +11,23 @@ #include "../utils/crc.h" #include "Heuristic.h" -#define MI_TIMEOUT 250 // timeout for MI type requests -#define FRSTMSG_TIMEOUT 150 // how long to wait for first msg to be received -#define DEFAULT_TIMEOUT 500 // timeout for regular requests -#define SINGLEFR_TIMEOUT 65 // timeout for single frame requests -#define MAX_BUFFER 250 +#define MI_TIMEOUT 250 // timeout for MI type requests +#define FRSTMSG_TIMEOUT 150 // how long to wait for first msg to be received +#define DEFAULT_TIMEOUT 500 // timeout for regular requests +#define SINGLEFR_TIMEOUT 65 // timeout for single frame requests +#define WAIT_GAP_TIMEOUT 200 // timeout after no complete payload +#define MAX_BUFFER 250 typedef std::function *)> payloadListenerType; typedef std::function *)> alarmListenerType; class Communication : public CommQueue<> { public: - void setup(uint32_t *timestamp, bool *serialDebug, bool *privacyMode) { + void setup(uint32_t *timestamp, bool *serialDebug, bool *privacyMode, bool *printWholeTrace) { mTimestamp = timestamp; mPrivacyMode = privacyMode; mSerialDebug = serialDebug; + mPrintWholeTrace = printWholeTrace; } void addImportant(Inverter<> *iv, uint8_t cmd, bool delOnPop = true) { @@ -47,7 +49,7 @@ class Communication : public CommQueue<> { return; // empty uint16_t timeout = (q->iv->ivGen == IV_MI) ? MI_TIMEOUT : ((q->iv->mGotFragment && q->iv->mGotLastMsg) || mIsResend) ? SINGLEFR_TIMEOUT : DEFAULT_TIMEOUT; - uint16_t timeout_min = (q->iv->ivGen == IV_MI) ? MI_TIMEOUT : ((q->iv->mGotFragment) ? SINGLEFR_TIMEOUT : FRSTMSG_TIMEOUT); + uint16_t timeout_min = (q->iv->ivGen == IV_MI) ? MI_TIMEOUT : ((q->iv->mGotFragment || mIsResend)) ? SINGLEFR_TIMEOUT : FRSTMSG_TIMEOUT; switch(mState) { case States::RESET: @@ -63,6 +65,7 @@ class Communication : public CommQueue<> { mHeu.getTxCh(q->iv); q->iv->mGotFragment = false; q->iv->mGotLastMsg = false; + mIsResend = false; if(NULL == q->iv->radio) cmdDone(true); // can't communicate while radio is not defined! mState = States::START; @@ -97,7 +100,9 @@ class Communication : public CommQueue<> { case States::WAIT: if(millis() > mWaitTimeout_min) { - if(q->iv->mGotFragment) { // nothing received yet? + if(mIsResend) { // we already have been through... + mWaitTimeout = mWaitTimeout_min; + } else if(q->iv->mGotFragment) { // nothing received yet? if(q->iv->mGotLastMsg) { //mState = States::CHECK_FRAMES; mWaitTimeout = mWaitTimeout_min; @@ -123,8 +128,7 @@ class Communication : public CommQueue<> { break; case States::CHECK_FRAMES: { - if((!q->iv->radio->get() && !mIsResend) || ((q->iv->mGotFragment) && (0 == q->attempts))) { // radio buffer empty - //cmdDone(); + if((!q->iv->radio->get() && !mIsResend) || (((q->iv->mGotFragment) || (mIsResend)) && (0 == q->attempts))) { // radio buffer empty or no more answers if(*mSerialDebug) { DPRINT_IVID(DBG_INFO, q->iv->id); DBGPRINT(F("request timeout: ")); @@ -153,21 +157,26 @@ class Communication : public CommQueue<> { if(p->millis < 100) DBGPRINT(F(" ")); DBGPRINT(String(p->millis)); - DBGPRINT(F("ms ")); + DBGPRINT(F("ms | ")); DBGPRINT(String(p->len)); if((IV_HM == q->iv->ivGen) || (IV_MI == q->iv->ivGen)) { DBGPRINT(F(" CH")); if(3 == p->ch) DBGPRINT(F("0")); DBGPRINT(String(p->ch)); + } else { + DBGPRINT(String(p->rssi)); + DBGPRINT(F("dBm | ")); + } + if(*mPrintWholeTrace) { + if(*mPrivacyMode) + ah::dumpBuf(p->packet, p->len, 1, 8); + else + ah::dumpBuf(p->packet, p->len); + } else { + DBGPRINT(F("frm ")); + DBGHEXLN(p->packet[9]); } - DBGPRINT(F(", ")); - DBGPRINT(String(p->rssi)); - DBGPRINT(F("dBm | ")); - if(*mPrivacyMode) - ah::dumpBuf(p->packet, p->len, 1, 8); - else - ah::dumpBuf(p->packet, p->len); if(checkIvSerial(&p->packet[1], q->iv)) { if(!mHeu.getTestModeEnabled()) @@ -178,7 +187,7 @@ class Communication : public CommQueue<> { nextState = States::CHECK_PACKAGE; } else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command parseDevCtrl(p, q); - cmdDone(true); // remove done request + closeRequest(q->iv, true); } else if(IV_MI == q->iv->ivGen) { parseMiFrame(p, q); } @@ -198,19 +207,20 @@ class Communication : public CommQueue<> { if(q->iv->ivGen != IV_MI) mState = nextState; else { - if( q->iv->miMultiParts > 5 && - ((q->cmd == 0x39) && (q->iv->type == INV_TYPE_4CH) || - (q->cmd == MI_REQ_CH2) && (q->iv->type == INV_TYPE_2CH) || - (q->cmd == MI_REQ_CH1) && (q->iv->type == INV_TYPE_1CH))) { + if(q->iv->miMultiParts < 6) { + nextState = States::WAIT; + } else { + if((q->cmd == 0x39) && (q->iv->type == INV_TYPE_4CH) || + (q->cmd == MI_REQ_CH2) && (q->iv->type == INV_TYPE_2CH) || + (q->cmd == MI_REQ_CH1) && (q->iv->type == INV_TYPE_1CH)) { miComplete(q->iv); //closeRequest(q->iv, q->iv->miMultiParts > 5); - } else if (q->iv->miMultiParts > 5) - closeRequest(q->iv, true); - else { - nextState = States::WAIT; } + closeRequest(q->iv, true); } + } + } } break; @@ -240,12 +250,14 @@ class Communication : public CommQueue<> { if(framnr) { setAttempt(); - DPRINT_IVID(DBG_WARN, q->iv->id); - DBGPRINT(F("frame ")); - DBGPRINT(String(framnr)); - DBGPRINT(F(" missing: request retransmit (")); - DBGPRINT(String(q->attempts)); - DBGPRINTLN(F(" attempts left)")); + if(*mSerialDebug) { + DPRINT_IVID(DBG_WARN, q->iv->id); + DBGPRINT(F("frame ")); + DBGPRINT(String(framnr)); + DBGPRINT(F(" missing: request retransmit (")); + DBGPRINT(String(q->attempts)); + DBGPRINTLN(F(" attempts left)")); + } sendRetransmit(q, framnr-1); mIsResend = true; mlastTO_min = timeout_min; @@ -448,7 +460,7 @@ class Communication : public CommQueue<> { private: void closeRequest(Inverter<> *iv, bool succeeded = true, bool delCmd = true) { - // ordering of lines is relevant for statistics + // ordering of lines is relevant for statistics if(succeeded) { mHeu.setGotAll(iv); if(!mHeu.getTestModeEnabled()) @@ -461,11 +473,13 @@ class Communication : public CommQueue<> { if(!mHeu.getTestModeEnabled()) iv->radioStatistics.rxFailNoAnser++; // got nothing mHeu.setGotNothing(iv); + mWaitTimeout = millis() + WAIT_GAP_TIMEOUT; } cmdDone(delCmd); iv->mGotFragment = false; iv->mGotLastMsg = false; iv->miMultiParts = 0; + mIsResend = false; mFirstTry = false; // for correct reset mState = States::RESET; } @@ -788,7 +802,7 @@ class Communication : public CommQueue<> { // update status state-machine, if (ac_pow) iv->isProducing(); - closeRequest(iv, iv->miMultiParts > 5); + //closeRequest(iv, iv->miMultiParts > 5); //mHeu.setGotAll(iv); //cmdDone(true); @@ -812,7 +826,7 @@ class Communication : public CommQueue<> { private: States mState = States::RESET; uint32_t *mTimestamp; - bool *mPrivacyMode, *mSerialDebug; + bool *mPrivacyMode, *mSerialDebug, *mPrintWholeTrace; uint32_t mWaitTimeout = 0; uint32_t mWaitTimeout_min = 0; std::array mLocalBuf; diff --git a/src/hm/Heuristic.h b/src/hm/Heuristic.h index 49f259e3..540d3326 100644 --- a/src/hm/Heuristic.h +++ b/src/hm/Heuristic.h @@ -12,6 +12,7 @@ #define RF_MAX_CHANNEL_ID 5 #define RF_MAX_QUALITY 4 #define RF_MIN_QUALTIY -6 +#define RF_NA -99 class Heuristic { public: @@ -19,25 +20,29 @@ class Heuristic { if((IV_HMS == iv->ivGen) || (IV_HMT == iv->ivGen)) return 0; // not used for these inverter types - mCycle++; // intended to overflow from time to time - if(mTestEn) { - iv->txRfChId = mCycle % RF_MAX_CHANNEL_ID; - DPRINTLN(DBG_INFO, F("heuristic test mode")); - return id2Ch(iv->txRfChId); - } - - uint8_t id = 0; + uint8_t bestId = 0; int8_t bestQuality = -6; for(uint8_t i = 0; i < RF_MAX_CHANNEL_ID; i++) { if(iv->txRfQuality[i] > bestQuality) { bestQuality = iv->txRfQuality[i]; - id = i; + bestId = i; } } - if(bestQuality == -6) - iv->txRfChId = (iv->txRfChId + 1) % RF_MAX_CHANNEL_ID; // next channel - else - iv->txRfChId = id; // best quality channel + + if(mTestEn) { + DPRINTLN(DBG_INFO, F("heuristic test mode")); + mTestIdx = (mTestIdx + 1) % RF_MAX_CHANNEL_ID; + + if (mTestIdx == bestId) + mTestIdx = (mTestIdx + 1) % RF_MAX_CHANNEL_ID; + + // test channel get's quality of best channel (maybe temporarily, see in 'setGotNothing') + mStoredIdx = iv->txRfQuality[mTestIdx]; + iv->txRfQuality[mTestIdx] = bestQuality; + + iv->txRfChId = mTestIdx; + } else + iv->txRfChId = bestId; return id2Ch(iv->txRfChId); } @@ -53,10 +58,15 @@ class Heuristic { } void setGotNothing(Inverter<> *iv) { + if(RF_NA != mStoredIdx) { + // if communication fails on first try with temporarily good level, revert it back to its original level + iv->txRfQuality[iv->txRfChId] = mStoredIdx; + mStoredIdx = RF_NA; + } + if(!mTestEn) { updateQuality(iv, -2); // BAD mTestEn = true; - iv->txRfChId = mCycle % RF_MAX_CHANNEL_ID; } } @@ -100,13 +110,14 @@ class Heuristic { case 3: return 61; case 4: return 75; } - return 0; // standard + return 3; // standard } private: uint8_t mChList[5] = {03, 23, 40, 61, 75}; bool mTestEn = false; - uint8_t mCycle = 0; + uint8_t mTestIdx = 0; + int8_t mStoredIdx = RF_NA; }; diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index a36935f8..18ae549e 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -34,12 +34,13 @@ class HmRadio : public Radio { } ~HmRadio() {} - void setup(bool *serialDebug, bool *privacyMode, uint8_t irq = IRQ_PIN, uint8_t ce = CE_PIN, uint8_t cs = CS_PIN, uint8_t sclk = SCLK_PIN, uint8_t mosi = MOSI_PIN, uint8_t miso = MISO_PIN) { + void setup(bool *serialDebug, bool *privacyMode, bool *printWholeTrace, uint8_t irq = IRQ_PIN, uint8_t ce = CE_PIN, uint8_t cs = CS_PIN, uint8_t sclk = SCLK_PIN, uint8_t mosi = MOSI_PIN, uint8_t miso = MISO_PIN) { DPRINTLN(DBG_VERBOSE, F("hmRadio.h:setup")); pinMode(irq, INPUT_PULLUP); mSerialDebug = serialDebug; mPrivacyMode = privacyMode; + mPrintWholeTrace = printWholeTrace; if(*mSerialDebug) { DPRINT(DBG_VERBOSE, F("hmRadio.h : HmRadio():mNrf24(CE_PIN: ")); @@ -293,10 +294,13 @@ class HmRadio : public Radio { DBGPRINT(" CH"); DBGPRINT(String(mTxChIdx)); DBGPRINT(F(" | ")); - if(*mPrivacyMode) - ah::dumpBuf(mTxBuf, len, 1, 4); - else - ah::dumpBuf(mTxBuf, len); + if(*mPrintWholeTrace) { + if(*mPrivacyMode) + ah::dumpBuf(mTxBuf, len, 1, 4); + else + ah::dumpBuf(mTxBuf, len); + } else + DBGHEXLN(mTxBuf[9]); } mNrf24.stopListening(); diff --git a/src/hm/radio.h b/src/hm/radio.h index c67186d7..4fd1fe29 100644 --- a/src/hm/radio.h +++ b/src/hm/radio.h @@ -111,8 +111,7 @@ class Radio { uint32_t mDtuSn; volatile bool mIrqRcvd; - bool *mSerialDebug; - bool *mPrivacyMode; + bool *mSerialDebug, *mPrivacyMode, *mPrintWholeTrace; uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE]; }; diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index 1f6044bb..e476bdf1 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -19,11 +19,12 @@ class CmtRadio : public Radio { mCmtAvail = false; } - void setup(bool *serialDebug, bool *privacyMode, uint8_t pinSclk, uint8_t pinSdio, uint8_t pinCsb, uint8_t pinFcsb, bool genDtuSn = true) { + void setup(bool *serialDebug, bool *privacyMode, bool *printWholeTrace, uint8_t pinSclk, uint8_t pinSdio, uint8_t pinCsb, uint8_t pinFcsb, bool genDtuSn = true) { mCmt.setup(pinSclk, pinSdio, pinCsb, pinFcsb); reset(genDtuSn); mPrivacyMode = privacyMode; mSerialDebug = serialDebug; + mPrintWholeTrace = printWholeTrace; } void setup(bool *serialDebug, bool *privacyMode, bool genDtuSn = true) { @@ -97,10 +98,13 @@ class CmtRadio : public Radio { DBGPRINT(F("TX ")); DBGPRINT(String(mCmt.getFreqKhz()/1000.0f)); DBGPRINT(F("Mhz | ")); - if(*mPrivacyMode) - ah::dumpBuf(mTxBuf, len, 1, 4); - else - ah::dumpBuf(mTxBuf, len); + if(*mPrintWholeTrace) { + if(*mPrivacyMode) + ah::dumpBuf(mTxBuf, len, 1, 4); + else + ah::dumpBuf(mTxBuf, len); + } else + DBGHEXLN(mTxBuf[9]); } uint8_t status = mCmt.tx(mTxBuf, len); diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 59a21ca5..7a59ac2b 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -563,6 +563,7 @@ class RestApi { obj[F("show_live_data")] = mConfig->serial.showIv; obj[F("debug")] = mConfig->serial.debug; obj[F("priv")] = mConfig->serial.privacyLog; + obj[F("wholeTrace")] = mConfig->serial.printWholeTrace; } void getStaticIp(JsonObject obj) { diff --git a/src/web/html/setup.html b/src/web/html/setup.html index b4d5749d..ec68f65a 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -52,6 +52,10 @@
Privacy Mode
+
+
Print whole traces in Log
+
+
@@ -937,7 +941,7 @@ /*ENDIF_ESP32*/ function parseSerial(obj) { - for(var i of [["serEn", "show_live_data"], ["serDbg", "debug"], ["priv", "priv"]]) + for(var i of [["serEn", "show_live_data"], ["serDbg", "debug"], ["priv", "priv"], ["wholeTrace", "wholeTrace"]]) document.getElementsByName(i[0])[0].checked = obj[i[1]]; } diff --git a/src/web/web.h b/src/web/web.h index 8c9be435..c88d829a 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -560,6 +560,7 @@ class Web { // serial console mConfig->serial.debug = (request->arg("serDbg") == "on"); mConfig->serial.privacyLog = (request->arg("priv") == "on"); + mConfig->serial.printWholeTrace = (request->arg("wholeTrace") == "on"); mConfig->serial.showIv = (request->arg("serEn") == "on"); // display