diff --git a/src/app.cpp b/src/app.cpp index d3fba12a..7d9f75ba 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -51,6 +51,7 @@ void app::setup() { mMiPayload.setup(this, &mSys, &mStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); mMiPayload.enableSerialDebug(mConfig->serial.debug); + mMiPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1)); // DBGPRINTLN("--- after payload"); // DBGPRINTLN(String(ESP.getFreeHeap())); @@ -67,6 +68,7 @@ void app::setup() { mMqtt.setup(&mConfig->mqtt, mConfig->sys.deviceName, mVersion, &mSys, &mTimestamp); mMqtt.setSubscriptionCb(std::bind(&app::mqttSubRxCb, this, std::placeholders::_1)); mPayload.addAlarmListener(std::bind(&PubMqttType::alarmEventListener, &mMqtt, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + mMiPayload.addAlarmListener(std::bind(&PubMqttType::alarmEventListener, &mMqtt, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); } #endif setupLed(); diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index 3917df8e..8a4f602e 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -101,19 +101,20 @@ class HmRadio { // change the byte order of the DTU serial number and append the required 0x01 at the end DTU_RADIO_ID = ((uint64_t)(((dtuSn >> 24) & 0xFF) | ((dtuSn >> 8) & 0xFF00) | ((dtuSn << 8) & 0xFF0000) | ((dtuSn << 24) & 0xFF000000)) << 8) | 0x01; + SPIClass* spi; #ifdef ESP32 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 - mSpi = new SPIClass(FSPI); + spi = new SPIClass(FSPI); #else - mSpi = new SPIClass(VSPI); + spi = new SPIClass(VSPI); #endif - mSpi->begin(sclk, miso, mosi, cs); + spi->begin(sclk, miso, mosi, cs); #else //the old ESP82xx cannot freely place their SPI pins - mSpi = new SPIClass(); - mSpi->begin(); + spi = new SPIClass(); + spi->begin(); #endif - mNrf24.begin(mSpi, ce, cs); + mNrf24.begin(spi, ce, cs); mNrf24.setRetries(3, 15); // 3*250us + 250us and 15 loops -> 15ms mNrf24.setChannel(mRfChLst[mRxChIdx]); @@ -123,7 +124,7 @@ class HmRadio { mNrf24.enableDynamicPayloads(); mNrf24.setCRCLength(RF24_CRC_16); mNrf24.setAddressWidth(5); - mNrf24.openReadingPipe(1, DTU_RADIO_ID); + mNrf24.openReadingPipe(1, reinterpret_cast(&DTU_RADIO_ID)); // enable all receiving interrupts mNrf24.maskIRQ(false, false, false); @@ -147,32 +148,31 @@ class HmRadio { bool tx_ok, tx_fail, rx_ready; mNrf24.whatHappened(tx_ok, tx_fail, rx_ready); // resets the IRQ pin to HIGH mNrf24.flush_tx(); // empty TX FIFO - //DBGPRINTLN("TX whatHappened Ch" + String(mRfChLst[mTxChIdx]) + " " + String(tx_ok) + String(tx_fail) + String(rx_ready)); - // start listening on the default RX channel - mRxChIdx = 0; + // start listening mNrf24.setChannel(mRfChLst[mRxChIdx]); mNrf24.startListening(); - //uint32_t debug_ms = millis(); - uint16_t cnt = 300; // that is 60 times 5 channels - while (0 < cnt--) { - uint32_t startMillis = millis(); - while (millis()-startMillis < 4) { // listen 4ms to each channel + uint32_t startMicros = micros(); + uint32_t loopMillis = millis(); + while (millis()-loopMillis < 410) { + while (micros()-startMicros < 5110) { // listen 5110us to each channel if (mIrqRcvd) { mIrqRcvd = false; if (getReceived()) { // everything received - //DBGPRINTLN("RX finished Cnt: " + String(300-cnt) + " time used: " + String(millis()-debug_ms)+ " ms"); return true; } } yield(); } - switchRxCh(); // switch to next RX channel + // switch to next RX channel + startMicros = micros(); + if(++mRxChIdx >= RF_CHANNELS) + mRxChIdx = 0; + mNrf24.setChannel(mRfChLst[mRxChIdx]); yield(); } // not finished but time is over - //DBGPRINTLN("RX not finished: 300 time used: " + String(millis()-debug_ms)+ " ms"); return true; } @@ -240,9 +240,9 @@ class HmRadio { sendPacket(invId, 24, isRetransmit, true); } - void sendCmdPacket(uint64_t invId, uint8_t mid, uint8_t pid, bool isRetransmit, bool isMI=false) { + void sendCmdPacket(uint64_t invId, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) { initPacket(invId, mid, pid); - sendPacket(invId, 10, isRetransmit, isMI); + sendPacket(invId, 10, isRetransmit, appendCrc16); } void dumpBuf(uint8_t buf[], uint8_t len) { @@ -275,7 +275,6 @@ class HmRadio { bool getReceived(void) { bool tx_ok, tx_fail, rx_ready; mNrf24.whatHappened(tx_ok, tx_fail, rx_ready); // resets the IRQ pin to HIGH - //DBGPRINTLN("RX whatHappened Ch" + String(mRfChLst[mRxChIdx]) + " " + String(tx_ok) + String(tx_fail) + String(rx_ready)); bool isLastPackage = false; while(mNrf24.available()) { @@ -286,29 +285,21 @@ class HmRadio { p.ch = mRfChLst[mRxChIdx]; p.len = len; mNrf24.read(p.packet, len); - mBufCtrl.push(p); - if (p.packet[0] == (TX_REQ_INFO + ALL_FRAMES)) // response from get information command - isLastPackage = (p.packet[9] > 0x81); // > 0x81 indicates last packet received - else if (p.packet[0] == ( 0x0f + ALL_FRAMES) ) // response from MI get information command - isLastPackage = (p.packet[9] > 0x11); // > 0x11 indicates last packet received - else if (p.packet[0] != 0x00 && p.packet[0] != 0x88 && p.packet[0] != 0x92) - // ignore fragment number zero and MI status messages - isLastPackage = true; // response from dev control command - yield(); + if (p.packet[0] != 0x00) { + mBufCtrl.push(p); + if (p.packet[0] == (TX_REQ_INFO + ALL_FRAMES)) // response from get information command + isLastPackage = (p.packet[9] > ALL_FRAMES); // > ALL_FRAMES indicates last packet received + else if (p.packet[0] == ( 0x0f + ALL_FRAMES) ) // response from MI get information command + isLastPackage = (p.packet[9] > 0x10); // > 0x10 indicates last packet received + else if ((p.packet[0] != 0x88) && (p.packet[0] != 0x92)) // ignore fragment number zero and MI status messages //#0 was p.packet[0] != 0x00 && + isLastPackage = true; // response from dev control command + } } + yield(); } return isLastPackage; } - void switchRxCh() { - mNrf24.stopListening(); - // get next channel index - if(++mRxChIdx >= RF_CHANNELS) - mRxChIdx = 0; - mNrf24.setChannel(mRfChLst[mRxChIdx]); - mNrf24.startListening(); - } - void initPacket(uint64_t invId, uint8_t mid, uint8_t pid) { DPRINTLN(DBG_VERBOSE, F("initPacket, mid: ") + String(mid, HEX) + F(" pid: ") + String(pid, HEX)); memset(mTxBuf, 0, MAX_RF_PAYLOAD_SIZE); @@ -318,12 +309,12 @@ class HmRadio { mTxBuf[9] = pid; } - void sendPacket(uint64_t invId, uint8_t len, bool isRetransmit, bool appendCrc16=false) { + void sendPacket(uint64_t invId, uint8_t len, bool isRetransmit, bool appendCrc16=true) { //DPRINTLN(DBG_VERBOSE, F("hmRadio.h:sendPacket")); //DPRINTLN(DBG_VERBOSE, "sent packet: #" + String(mSendCnt)); // append crc's - if (appendCrc16 && len > 10) { + if (appendCrc16 && (len > 10)) { // crc control data uint16_t crc = ah::crc16(&mTxBuf[10], len - 10); mTxBuf[len++] = (crc >> 8) & 0xff; @@ -333,6 +324,10 @@ class HmRadio { mTxBuf[len] = ah::crc8(mTxBuf, len); len++; + // set TX and RX channels + mTxChIdx = (mTxChIdx + 1) % RF_CHANNELS; + mRxChIdx = (mTxChIdx + 2) % RF_CHANNELS; + if(mSerialDebug) { DPRINT(DBG_INFO, F("TX ")); DBGPRINT(String(len)); @@ -347,10 +342,6 @@ class HmRadio { mNrf24.openWritingPipe(reinterpret_cast(&invId)); mNrf24.startWrite(mTxBuf, len, false); // false = request ACK response - // switch TX channel for next packet - if(++mTxChIdx >= RF_CHANNELS) - mTxChIdx = 0; - if(isRetransmit) mRetransmits++; else @@ -364,7 +355,6 @@ class HmRadio { uint8_t mTxChIdx; uint8_t mRxChIdx; - SPIClass* mSpi; RF24 mNrf24; uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE]; }; diff --git a/src/hm/miPayload.h b/src/hm/miPayload.h index d9f0b338..92020b51 100644 --- a/src/hm/miPayload.h +++ b/src/hm/miPayload.h @@ -149,7 +149,7 @@ class MiPayload { if (cmd == 0x01 || cmd == SystemConfigPara ) { //0x1 and 0x05 for HM-types cmd = 0x0f; // for MI, these seem to make part of the Polling the device software and hardware version number command cmd2 = cmd == SystemConfigPara ? 0x01 : 0x00; //perhaps we can only try to get second frame? - mSys->Radio.sendCmdPacket(iv->radioId.u64, cmd, cmd2, false, true); + mSys->Radio.sendCmdPacket(iv->radioId.u64, cmd, cmd2, false, false); } else { mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd2, mPayload[iv->id].ts, iv->alarmMesIndex, false, cmd); }; @@ -442,7 +442,7 @@ const byteAssign_t InfoAssignment[] = { mPayload[iv->id].retransmits = mMaxRetrans; } else if ( cmd == 0x0f ) { //hard/firmware request - mSys->Radio.sendCmdPacket(iv->radioId.u64, 0x0f, 0x00, true, true); + mSys->Radio.sendCmdPacket(iv->radioId.u64, 0x0f, 0x00, true, false); //iv->setQueuedCmdFinished(); //cmd = iv->getQueuedCmd(); } else { diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index b008d8d2..f75c4068 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -49,6 +49,8 @@ class PubMqtt { mTxCnt = 0; mSubscriptionCb = NULL; memset(mLastIvState, MQTT_STATUS_NOT_AVAIL_NOT_PROD, MAX_NUM_INVERTERS); + memset(mIvLastRTRpub, 0, MAX_NUM_INVERTERS * 4); + mLastAnyAvail = false; } @@ -522,7 +524,13 @@ class PubMqtt { void sendData(Inverter<> *iv, uint8_t curInfoCmd) { record_t<> *rec = iv->getRecordStruct(curInfoCmd); - if (iv->getLastTs(rec) > 0) { + uint32_t lastTs = iv->getLastTs(rec); + bool pubData = (lastTs > 0); + if (curInfoCmd == RealTimeRunData_Debug) + pubData &= (lastTs != mIvLastRTRpub[iv->id]); + + if (pubData) { + mIvLastRTRpub[iv->id] = lastTs; for (uint8_t i = 0; i < rec->length; i++) { bool retained = false; if (curInfoCmd == RealTimeRunData_Debug) { @@ -653,6 +661,7 @@ class PubMqtt { subscriptionCb mSubscriptionCb; bool mLastAnyAvail; uint8_t mLastIvState[MAX_NUM_INVERTERS]; + uint32_t mIvLastRTRpub[MAX_NUM_INVERTERS]; uint16_t mIntervalTimeout; // last will topic and payload must be available trough lifetime of 'espMqttClient'