From ac0c93cb408521899e4c6c406c8136b9eb720d98 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Sat, 20 Jan 2024 10:03:57 +0100 Subject: [PATCH] non blocking - first review - discord 0.8.5902 - stay longer on expected rx channel to wait for first frame - stick to looping over 5 channels for MI (after first frame or timeout) --- src/app.cpp | 21 +++++++++++++++++++-- src/app.h | 4 +++- src/hm/CommQueue.h | 4 ++-- src/hm/Communication.h | 27 +++++++++++---------------- src/hm/hmDefines.h | 7 ++++--- src/hm/hmInverter.h | 1 + src/hm/hmRadio.h | 36 +++++++++++++++++++++--------------- src/hm/hmSystem.h | 16 +++++++++++----- 8 files changed, 72 insertions(+), 44 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index 97abc790..c53efa3b 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -106,7 +106,7 @@ void app::setup() { #endif // Plugins #if defined(PLUGIN_DISPLAY) - if (mConfig->plugin.display.type != 0) + if (DISP_TYPE_T0_NONE != mConfig->plugin.display.type) #if defined(ESP32) mDisplay.setup(this, &mConfig->plugin.display, &mSys, &mNrfRadio, &mCmtRadio, &mTimestamp); #else @@ -184,7 +184,7 @@ void app::regularTickers(void) { everySec(std::bind(&WebType::tickSecond, &mWeb), "webSc"); // Plugins #if defined(PLUGIN_DISPLAY) - if (mConfig->plugin.display.type != 0) + if (DISP_TYPE_T0_NONE != mConfig->plugin.display.type) everySec(std::bind(&DisplayType::tickerSecond, &mDisplay), "disp"); #endif every(std::bind(&PubSerialType::tick, &mPubSerial), 5, "uart"); @@ -350,6 +350,14 @@ void app::tickSunrise(void) { #endif } +//----------------------------------------------------------------------------- +void app::notAvailChanged(void) { + #if defined(ENABLE_MQTT) + if (mMqttEnabled) + mMqtt.notAvailChanged(mAllIvNotAvail); + #endif +} + //----------------------------------------------------------------------------- void app::tickZeroValues(void) { zeroIvValues(!CHECK_AVAIL, SKIP_YIELD_DAY); @@ -401,6 +409,7 @@ void app::tickMidnight(void) { //----------------------------------------------------------------------------- void app::tickSend(void) { + bool notAvail = true; uint8_t fill = mCommunication.getFillState(); uint8_t max = mCommunication.getMaxFill(); if((max-MAX_NUM_INVERTERS) <= fill) { @@ -426,6 +435,9 @@ void app::tickSend(void) { if(!iv->radio->isChipConnected()) continue; + if(InverterStatus::OFF != iv->status) + notAvail = false; + iv->tickSend([this, iv](uint8_t cmd, bool isDevControl) { if(isDevControl) mCommunication.addImportant(iv, cmd); @@ -435,6 +447,10 @@ void app::tickSend(void) { } } + if(mAllIvNotAvail != notAvail) + once(std::bind(&app::notAvailChanged, this), 1, "avail"); + mAllIvNotAvail = notAvail; + updateLed(); } @@ -533,6 +549,7 @@ void app::resetSystem(void) { #endif mSendFirst = true; + mAllIvNotAvail = true; mSunrise = 0; mSunset = 0; diff --git a/src/app.h b/src/app.h index a5438777..4d9aae79 100644 --- a/src/app.h +++ b/src/app.h @@ -320,7 +320,7 @@ class app : public IApp, public ah::Scheduler { #endif /*ENABLE_MQTT*/ #endif #if defined(PLUGIN_DISPLAY) - if(mConfig->plugin.display.type != 0) + if(DISP_TYPE_T0_NONE != mConfig->plugin.display.type) mDisplay.payloadEventListener(cmd); #endif updateLed(); @@ -367,6 +367,7 @@ class app : public IApp, public ah::Scheduler { void tickMinute(void); void tickZeroValues(void); void tickMidnight(void); + void notAvailChanged(void); HmSystemType mSys; HmRadio<> mNrfRadio; @@ -403,6 +404,7 @@ class app : public IApp, public ah::Scheduler { uint8_t mSendLastIvId; bool mSendFirst; + bool mAllIvNotAvail; bool mNetworkConnected; diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index 13decc01..d3fe1c69 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -12,8 +12,8 @@ #include "../utils/dbg.h" #define DEFAULT_ATTEMPS 5 -#define MORE_ATTEMPS_ALARMDATA 15 -#define MORE_ATTEMPS_GRIDONPROFILEPARA 15 +#define MORE_ATTEMPS_ALARMDATA 8 +#define MORE_ATTEMPS_GRIDONPROFILEPARA 5 template class CommQueue { diff --git a/src/hm/Communication.h b/src/hm/Communication.h index efcb69f8..8874a87a 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -89,14 +89,14 @@ class Communication : public CommQueue<> { q->iv->mCmd = q->cmd; q->iv->mIsSingleframeReq = false; mFramesExpected = getFramesExpected(q); // function to get expected frame count. - mTimeout = DURATION_TXFRAME + mFramesExpected*DURATION_ONEFRAME + DURATION_RESERVE; + mTimeout = DURATION_TXFRAME + mFramesExpected*DURATION_ONEFRAME + duration_reserve[q->iv->ivRadioType]; mState = States::START; break; case States::START: setTs(mTimestamp); - if((IV_HMS == q->iv->ivGen) || (IV_HMT == q->iv->ivGen)) { + if(q->iv->ivRadioType == INV_RADIO_TYPE_CMT) { // frequency was changed during runtime if(q->iv->curCmtFreq != q->iv->config->frequency) { if(q->iv->radio->switchFrequencyCh(q->iv, q->iv->curCmtFreq, q->iv->config->frequency)) @@ -136,7 +136,7 @@ class Communication : public CommQueue<> { DBGPRINTLN(F("ms")); } if(!q->iv->mGotFragment) { - if((IV_HMS == q->iv->ivGen) || (IV_HMT == q->iv->ivGen)) { + if(q->iv->ivRadioType == INV_RADIO_TYPE_CMT) { q->iv->radio->switchFrequency(q->iv, HOY_BOOT_FREQ_KHZ, (q->iv->config->frequency*FREQ_STEP_KHZ + HOY_BASE_FREQ_KHZ)); mWaitTime.startTimeMonitor(1000); } else { @@ -284,7 +284,7 @@ class Communication : public CommQueue<> { DBGPRINT(String(p->millis)); DBGPRINT(F("ms | ")); DBGPRINT(String(p->len)); - if((IV_HM == q->iv->ivGen) || (IV_MI == q->iv->ivGen)) { + if(q->iv->ivRadioType == INV_RADIO_TYPE_NRF) { DBGPRINT(F(" CH")); if(3 == p->ch) DBGPRINT(F("0")); @@ -316,13 +316,8 @@ class Communication : public CommQueue<> { if(q->iv->ivGen != IV_MI) { if (q->cmd == RealTimeRunData_Debug) { - switch (q->iv->type) { // breaks are intentionally missing! - case INV_TYPE_1CH: return 2; - case INV_TYPE_2CH: return 3; - case INV_TYPE_4CH: return 4; - case INV_TYPE_6CH: return 7; - default: return 7; - } + uint8_t framecnt[4] = {2, 3, 4, 7}; + return framecnt[q->iv->type]; } switch (q->cmd) { @@ -350,8 +345,8 @@ class Communication : public CommQueue<> { } else { //MI switch (q->cmd) { - case 0x09: - case 0x11: + case MI_REQ_CH1: + case MI_REQ_CH2: return 2; case 0x0f: return 3; default: return 1; @@ -582,7 +577,7 @@ class Communication : public CommQueue<> { q->iv->radio->setExpectedFrames(mFramesExpected); q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (SINGLE_FRAME + i), true); q->iv->radioStatistics.retransmits++; - q->iv->radio->mRadioWaitTime.startTimeMonitor(DURATION_TXFRAME + DURATION_ONEFRAME + DURATION_RESERVE); + q->iv->radio->mRadioWaitTime.startTimeMonitor(DURATION_TXFRAME + DURATION_ONEFRAME + duration_reserve[q->iv->ivRadioType]); mState = States::WAIT; } @@ -827,7 +822,7 @@ class Communication : public CommQueue<> { q->iv->radio->setExpectedFrames(mFramesExpected); q->iv->radio->sendCmdPacket(q->iv, cmd, 0x00, true); - q->iv->radio->mRadioWaitTime.startTimeMonitor(DURATION_TXFRAME + DURATION_ONEFRAME + DURATION_RESERVE); + q->iv->radio->mRadioWaitTime.startTimeMonitor(DURATION_TXFRAME + DURATION_ONEFRAME + duration_reserve[q->iv->ivRadioType]); q->iv->miMultiParts = 0; q->iv->mGotFragment = 0; mIsRetransmit = true; @@ -847,7 +842,7 @@ class Communication : public CommQueue<> { q->iv->radio->sendCmdPacket(q->iv, q->cmd, 0x00, true); - q->iv->radio->mRadioWaitTime.startTimeMonitor(DURATION_TXFRAME + DURATION_ONEFRAME + DURATION_RESERVE); + q->iv->radio->mRadioWaitTime.startTimeMonitor(DURATION_TXFRAME + DURATION_ONEFRAME + duration_reserve[q->iv->ivRadioType]); mIsRetransmit = false; } diff --git a/src/hm/hmDefines.h b/src/hm/hmDefines.h index bee67bb8..969e4e1b 100644 --- a/src/hm/hmDefines.h +++ b/src/hm/hmDefines.h @@ -76,6 +76,7 @@ enum {CMD_CALC = 0xffff}; enum {CH0 = 0, CH1, CH2, CH3, CH4, CH5, CH6}; enum {INV_TYPE_1CH = 0, INV_TYPE_2CH, INV_TYPE_4CH, INV_TYPE_6CH}; +enum {INV_RADIO_TYPE_NRF = 0, INV_RADIO_TYPE_CMT}; #define WORK_FREQ_KHZ 865000 // desired work frequency between DTU and // inverter in kHz @@ -87,11 +88,11 @@ enum {INV_TYPE_1CH = 0, INV_TYPE_2CH, INV_TYPE_4CH, INV_TYPE_6CH}; #define FREQ_WARN_MAX_KHZ 870000 // for EU 863 - 870 MHz is allowed #define DURATION_ONEFRAME 50 // timeout parameter for each expected frame (ms) -#define DURATION_RESERVE 90 // timeout parameter to still wait after last expected frame (ms) -#define DURATION_TXFRAME 60 // timeout parameter for first transmission and first expected frame (time to first channel switch from tx start!) (ms) +//#define DURATION_RESERVE {90,120} // timeout parameter to still wait after last expected frame (ms) +#define DURATION_TXFRAME 85 // timeout parameter for first transmission and first expected frame (time to first channel switch from tx start!) (ms) #define DURATION_LISTEN_MIN 5 // time to stay at least on a listening channel (ms) #define DURATION_PAUSE_LASTFR 45 // how long to pause after last frame (ms) - +const uint8_t duration_reserve[2] = {115,115}; typedef struct { uint8_t fieldId; // field id diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index ff3343fb..2c1c6362 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -114,6 +114,7 @@ template class Inverter { public: uint8_t ivGen; // generation of inverter (HM / MI) + uint8_t ivRadioType; // refers to used radio (nRF24 / CMT) cfgIv_t *config; // stored settings uint8_t id; // unique id uint8_t type; // integer which refers to inverter type diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index 0ef24477..54dc0121 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -125,11 +125,16 @@ class HmRadio : public Radio { // otherwise switch to next RX channel mTimeslotStart = millis(); + if(!mNRFloopChannels && (mTimeslotStart - mLastIrqTime > (DURATION_TXFRAME+DURATION_ONEFRAME))) + mNRFloopChannels = true; + rxPendular = !rxPendular; //innerLoopTimeout = (rxPendular ? 1 : 2)*DURATION_LISTEN_MIN; innerLoopTimeout = DURATION_LISTEN_MIN; - tempRxChIdx = (mRxChIdx + rxPendular*chOffset2) % RF_CHANNELS; + tempRxChIdx = mNRFloopChannels ? + (tempRxChIdx + 4) % RF_CHANNELS : + (mRxChIdx + rxPendular*4) % RF_CHANNELS; mNrf24->setChannel(mRfChLst[tempRxChIdx]); isRxInit = false; @@ -140,6 +145,7 @@ class HmRadio : public Radio { mNrf24->whatHappened(tx_ok, tx_fail, rx_ready); // resets the IRQ pin to HIGH mIrqRcvd = false; + mLastIrqTime = millis(); if(tx_ok || tx_fail) { // tx related interrupt, basically we should start listening mNrf24->flush_tx(); // empty TX FIFO @@ -154,13 +160,13 @@ class HmRadio : public Radio { mLastIv->mAckCount++; // start listening - mRxChIdx = (mTxChIdx + chOffset) % RF_CHANNELS; + mRxChIdx = (mTxChIdx + 2 ) % RF_CHANNELS; mNrf24->setChannel(mRfChLst[mRxChIdx]); mNrf24->startListening(); mTimeslotStart = millis(); tempRxChIdx = mRxChIdx; - chOffset2 = mLastIv->ivGen == IV_HM ? 4 : (mLastIv->mCmd == MI_REQ_CH1 || mLastIv->mCmd == MI_REQ_CH2) ? 1 :4; // reversed channel order for everything apart from 1/2ch MI Data requests rxPendular = false; + mNRFloopChannels = mLastIv->ivGen == IV_MI; innerLoopTimeout = DURATION_TXFRAME; } @@ -172,17 +178,18 @@ class HmRadio : public Radio { mRadioWaitTime.startTimeMonitor(DURATION_PAUSE_LASTFR); // let the inverter first end his transmissions // add stop listening? } else { - //rxPendular = true; // stay longer on the next rx channel - - if (isRxInit) { - isRxInit = false; - tempRxChIdx = (mRxChIdx + chOffset2) % RF_CHANNELS; - mNrf24->setChannel(mRfChLst[tempRxChIdx]); - } else { - mRxChIdx = tempRxChIdx; - } innerLoopTimeout = DURATION_LISTEN_MIN; mTimeslotStart = millis(); + if (!mNRFloopChannels) { + //rxPendular = true; // stay longer on the next rx channel + if (isRxInit) { + isRxInit = false; + tempRxChIdx = (mRxChIdx + 4) % RF_CHANNELS; + mNrf24->setChannel(mRfChLst[tempRxChIdx]); + } else + mRxChIdx = tempRxChIdx; + + } } return; } @@ -396,14 +403,13 @@ class HmRadio : public Radio { bool mGotLastMsg = false; uint32_t mMillis; bool tx_ok, tx_fail, rx_ready = false; - uint8_t chOffset = 2; - uint8_t chOffset2 = 4; unsigned long mTimeslotStart = 0; + unsigned long mLastIrqTime = 0; + bool mNRFloopChannels = false; bool mNRFisInRX = false; bool isRxInit = true; bool rxPendular = false; uint32_t innerLoopTimeout = DURATION_LISTEN_MIN; - //uint32_t outerLoopTimeout = 400; std::unique_ptr mSpi; std::unique_ptr mNrf24; diff --git a/src/hm/hmSystem.h b/src/hm/hmSystem.h index 8f997104..8229378e 100644 --- a/src/hm/hmSystem.h +++ b/src/hm/hmSystem.h @@ -51,15 +51,21 @@ class HmSystem { } if(iv->config->serial.b[5] == 0x11) { - if((iv->config->serial.b[4] & 0x0f) == 0x04) + if((iv->config->serial.b[4] & 0x0f) == 0x04) { iv->ivGen = IV_HMS; - else + iv->ivRadioType = INV_RADIO_TYPE_CMT; + } else { iv->ivGen = IV_HM; + iv->ivRadioType = INV_RADIO_TYPE_NRF; + } } - else if((iv->config->serial.b[4] & 0x03) == 0x02) // MI 3rd Gen -> same as HM + else if((iv->config->serial.b[4] & 0x03) == 0x02) { // MI 3rd Gen -> same as HM iv->ivGen = IV_HM; - else // MI 2nd Gen + iv->ivRadioType = INV_RADIO_TYPE_NRF; + } else { // MI 2nd Gen iv->ivGen = IV_MI; + iv->ivRadioType = INV_RADIO_TYPE_NRF; + } } else if(iv->config->serial.b[5] == 0x13) { iv->ivGen = IV_HMT; iv->type = INV_TYPE_6CH; @@ -87,7 +93,7 @@ class HmSystem { DBGPRINTLN(String(iv->config->serial.u64, HEX)); if((iv->config->serial.b[5] == 0x10) && ((iv->config->serial.b[4] & 0x03) == 0x01)) - DPRINTLN(DBG_WARN, F("MI Inverter are not fully supported now!!!")); + DPRINTLN(DBG_WARN, F("MI Inverter, has some restrictions!")); cb(iv); }