From 09896fbe6be78e645c9bb76e88203adc3492bdd3 Mon Sep 17 00:00:00 2001 From: lumapu Date: Fri, 29 Sep 2023 23:54:29 +0200 Subject: [PATCH 01/18] first comparison, compiles fine --- src/hm/hmPayload.h | 3 +- src/hms/hmsPayload.h | 233 ++++++++++++++++++++++++++++--------------- src/hms/hmsRadio.h | 5 + 3 files changed, 158 insertions(+), 83 deletions(-) diff --git a/src/hm/hmPayload.h b/src/hm/hmPayload.h index 8693cb00..a07c57eb 100644 --- a/src/hm/hmPayload.h +++ b/src/hm/hmPayload.h @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // 2023 Ahoy, https://ahoydtu.de -// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ +// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed //----------------------------------------------------------------------------- #ifndef __HM_PAYLOAD_H__ @@ -15,7 +15,6 @@ typedef struct { uint8_t txCmd; uint8_t txId; - uint8_t invId; uint32_t ts; uint8_t data[MAX_PAYLOAD_ENTRIES][MAX_RF_PAYLOAD_SIZE]; int8_t rssi[MAX_PAYLOAD_ENTRIES]; diff --git a/src/hms/hmsPayload.h b/src/hms/hmsPayload.h index e082f059..489fe044 100644 --- a/src/hms/hmsPayload.h +++ b/src/hms/hmsPayload.h @@ -16,7 +16,6 @@ typedef struct { uint8_t txCmd; uint8_t txId; - //uint8_t invId; uint32_t ts; uint8_t data[MAX_PAYLOAD_ENTRIES][MAX_RF_PAYLOAD_SIZE]; int8_t rssi[MAX_PAYLOAD_ENTRIES]; @@ -27,6 +26,7 @@ typedef struct { uint8_t retransmits; bool requested; bool gotFragment; + bool rxTmo; } hmsPayload_t; @@ -50,11 +50,10 @@ class HmsPayload { reset(i); mIvCmd56Cnt[i] = 0; } - mSerialDebug = false; - mHighPrioIv = NULL; - mCbAlarm = NULL; - mCbPayload = NULL; - //mLastRx = 0; + mSerialDebug = false; + mHighPrioIv = NULL; + mCbAlarm = NULL; + mCbPayload = NULL; } void enableSerialDebug(bool enable) { @@ -70,12 +69,35 @@ class HmsPayload { } void loop() { - if(NULL != mHighPrioIv) { + if (NULL != mHighPrioIv) { ivSend(mHighPrioIv, true); mHighPrioIv = NULL; } } + /*void simulation() { + uint8_t pay[] = { + 0x00, 0x01, 0x01, 0x24, 0x02, 0x28, 0x02, 0x33, + 0x06, 0x49, 0x06, 0x6a, 0x00, 0x05, 0x5f, 0x1b, + 0x00, 0x06, 0x66, 0x9a, 0x03, 0xfd, 0x04, 0x0b, + 0x01, 0x23, 0x02, 0x28, 0x02, 0x28, 0x06, 0x41, + 0x06, 0x43, 0x00, 0x05, 0xdc, 0x2c, 0x00, 0x06, + 0x2e, 0x3f, 0x04, 0x01, 0x03, 0xfb, 0x09, 0x78, + 0x13, 0x86, 0x18, 0x15, 0x00, 0xcf, 0x00, 0xfe, + 0x03, 0xe7, 0x01, 0x42, 0x00, 0x03 + }; + + Inverter<> *iv = mSys->getInverterByPos(0); + record_t<> *rec = iv->getRecordStruct(0x0b); + rec->ts = *mTimestamp; + for (uint8_t i = 0; i < rec->length; i++) { + iv->addValue(i, pay, rec); + yield(); + } + iv->doCalculations(); + notify(0x0b, iv); + }*/ + void ivSendHighPrio(Inverter<> *iv) { mHighPrioIv = iv; } @@ -90,26 +112,26 @@ class HmsPayload { process(false); // no retransmit if (!mPayload[iv->id].complete) { - if (MAX_PAYLOAD_ENTRIES == mPayload[iv->id].maxPackId) + if (mSerialDebug) + DPRINT_IVID(DBG_INFO, iv->id); + if (MAX_PAYLOAD_ENTRIES == mPayload[iv->id].maxPackId) { mStat->rxFailNoAnser++; // got nothing - else + if (mSerialDebug) + DBGPRINTLN(F("enqueued cmd failed/timeout")); + } else { mStat->rxFail++; // got fragments but not complete response - + if (mSerialDebug) { + DBGPRINT(F("no complete Payload received! (retransmits: ")); + DBGPRINT(String(mPayload[iv->id].retransmits)); + DBGPRINTLN(F(")")); + } + } iv->setQueuedCmdFinished(); // command failed - if (mSerialDebug) - DPRINTLN(DBG_INFO, F("enqueued cmd failed/timeout")); - /*if (mSerialDebug) { - DPRINT(DBG_INFO, F("(#")); - DBGPRINT(String(iv->id)); - DBGPRINT(F(") no Payload received! (retransmits: ")); - DBGPRINT(String(mPayload[iv->id].retransmits)); - DBGPRINTLN(F(")")); - }*/ } } } - reset(iv->id); + reset(iv->id, !iv->isAvailable()); mPayload[iv->id].requested = true; yield(); @@ -140,9 +162,11 @@ class HmsPayload { if(++mIvCmd56Cnt[iv->id] == 10) mIvCmd56Cnt[iv->id] = 0; uint8_t cmd = iv->getQueuedCmd(); - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINT(F("prepareDevInformCmd 0x")); - DBGHEXLN(cmd); + if (mSerialDebug) { + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F("prepareDevInformCmd 0x")); + DBGHEXLN(cmd); + } mRadio->prepareDevInformCmd(&iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); mPayload[iv->id].txCmd = cmd; } @@ -154,7 +178,7 @@ class HmsPayload { DPRINTLN(DBG_DEBUG, F("Response from info request received")); uint8_t *pid = &p->data[10]; if (*pid == 0x00) { - DPRINT(DBG_DEBUG, F("fragment number zero received and ignored")); + DPRINTLN(DBG_DEBUG, F("fragment number zero received and ignored")); } else { DPRINTLN(DBG_DEBUG, "PID: 0x" + String(*pid, HEX)); if ((*pid & 0x7F) < MAX_PAYLOAD_ENTRIES) { @@ -186,13 +210,16 @@ class HmsPayload { iv->powerLimitAck = true; } else ok = false; - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINT(F(" has ")); - if(!ok) DBGPRINT(F("not ")); - DBGPRINT(F("accepted power limit set point ")); - DBGPRINT(String(iv->powerLimit[0])); - DBGPRINT(F(" with PowerLimitControl ")); - DBGPRINTLN(String(iv->powerLimit[1])); + + if (mSerialDebug) { + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F(" has ")); + if(!ok) DBGPRINT(F("not ")); + DBGPRINT(F("accepted power limit set point ")); + DBGPRINT(String(iv->powerLimit[0])); + DBGPRINT(F(" with PowerLimitControl ")); + DBGPRINTLN(String(iv->powerLimit[1])); + } iv->clearCmdQueue(); iv->enqueCommand(SystemConfigPara); // read back power limit @@ -219,8 +246,9 @@ class HmsPayload { } if (!mPayload[iv->id].complete) { - bool crcPass, pyldComplete; - crcPass = build(iv->id, &pyldComplete); + bool crcPass, pyldComplete, fastNext; + + crcPass = build(iv, &pyldComplete, &fastNext); if (!crcPass && !pyldComplete) { // payload not complete if ((mPayload[iv->id].requested) && (retransmit)) { if (mPayload[iv->id].retransmits < mMaxRetrans) { @@ -230,26 +258,31 @@ class HmsPayload { DPRINTLN(DBG_INFO, F("Prevent retransmit on Restart / CleanState_LockAndAlarm...")); mPayload[iv->id].retransmits = mMaxRetrans; } else if(iv->devControlCmd == ActivePowerContr) { + DPRINT_IVID(DBG_INFO, iv->id); DPRINTLN(DBG_INFO, F("retransmit power limit")); mRadio->sendControlPacket(&iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); } else { if(false == mPayload[iv->id].gotFragment) { - - //DPRINTLN(DBG_WARN, F("nothing received: Request Complete Retransmit")); - //mPayload[iv->id].txCmd = iv->getQueuedCmd(); - //DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX)); - //mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmLastId, true); - - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINTLN(F("nothing received")); - mPayload[iv->id].retransmits = mMaxRetrans; + DPRINT_IVID(DBG_WARN, iv->id); + if (mPayload[iv->id].rxTmo) { + DBGPRINTLN(F("nothing received")); + mPayload[iv->id].retransmits = mMaxRetrans; + } else { + DBGPRINTLN(F("nothing received: complete retransmit")); + mPayload[iv->id].txCmd = iv->getQueuedCmd(); + DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX)); + mRadio->prepareDevInformCmd(&iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); + } } else { for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) { if (mPayload[iv->id].len[i] == 0) { - DPRINT(DBG_WARN, F("Frame ")); - DBGPRINT(String(i + 1)); - DBGPRINTLN(F(" missing: Request Retransmit")); - //mRadio->sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true); + if (mSerialDebug) { + DPRINT_IVID(DBG_WARN, iv->id); + DBGPRINT(F("Frame ")); + DBGPRINT(String(i + 1)); + DBGPRINTLN(F(" missing: Request Retransmit")); + } + mRadio->sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true); break; // only request retransmit one frame per loop } yield(); @@ -257,26 +290,36 @@ class HmsPayload { } } } + } else if (false == mPayload[iv->id].gotFragment) { + // only if there is no sign of life + mPayload[iv->id].rxTmo = true; // inv might be down, no complete retransmit anymore } - } /*else if(!crcPass && pyldComplete) { // crc error on complete Payload + } else if(!crcPass && pyldComplete) { // crc error on complete Payload if (mPayload[iv->id].retransmits < mMaxRetrans) { mPayload[iv->id].retransmits++; - DPRINTLN(DBG_WARN, F("CRC Error: Request Complete Retransmit")); mPayload[iv->id].txCmd = iv->getQueuedCmd(); - DPRINT(DBG_INFO, F("(#")); - DBGPRINT(String(iv->id)); - DBGPRINT(F(") prepareDevInformCmd 0x")); - DBGPRINTLN(String(mPayload[iv->id].txCmd, HEX)); - mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmLastId, true); + if (mSerialDebug) { + DPRINTLN(DBG_WARN, F("CRC Error: Request Complete Retransmit")); + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F("prepareDevInformCmd 0x")); + DBGHEXLN(mPayload[iv->id].txCmd); + } + mRadio->prepareDevInformCmd(&iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmLastId, true); + } + } else { // payload complete + if (mSerialDebug) { + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F("procPyld: cmd: 0x")); + DBGHEXLN(mPayload[iv->id].txCmd); + //DPRINT(DBG_DEBUG, F("procPyld: txid: 0x")); + //DBGHEXLN(mPayload[iv->id].txId); + DPRINT(DBG_DEBUG, F("procPyld: max: ")); + DPRINTLN(DBG_DEBUG, String(mPayload[iv->id].maxPackId)); } - }*/ else { // payload complete - DPRINT(DBG_INFO, F("procPyld: cmd: 0x")); - DBGPRINTLN(String(mPayload[iv->id].txCmd, HEX)); - //DPRINT(DBG_DEBUG, F("procPyld: txid: 0x")); - //DBGPRINTLN(String(mPayload[iv->id].txId, HEX)); - DPRINTLN(DBG_DEBUG, F("procPyld: max: ") + String(mPayload[iv->id].maxPackId)); record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser mPayload[iv->id].complete = true; + mPayload[iv->id].requested = false; + mPayload[iv->id].rxTmo = false; uint8_t payload[150]; uint8_t payloadLen = 0; @@ -324,7 +367,6 @@ class HmsPayload { if(AlarmData == mPayload[iv->id].txCmd) { uint8_t i = 0; - uint32_t start, end; while(1) { if(0 == iv->parseAlarmLog(i++, payload, payloadLen)) break; @@ -333,10 +375,28 @@ class HmsPayload { yield(); } } + if (fastNext && (mHighPrioIv == NULL)) { + /*iv->setQueuedCmdFinished(); + uint8_t cmd = iv->getQueuedCmd(); + if (mSerialDebug) { + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F("fast mode ")); + DBGPRINT(F("prepareDevInformCmd 0x")); + DBGHEXLN(cmd); + } + mStat->rxSuccess++; + mRadio->prepareDevInformCmd(&iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); + mPayload[iv->id].txCmd = cmd; + */ + mHighPrioIv = iv; + } + } else { - DPRINT(DBG_ERROR, F("plausibility check failed, expected ")); - DBGPRINT(String(rec->pyldLen)); - DBGPRINTLN(F(" bytes")); + if (mSerialDebug) { + DPRINT(DBG_ERROR, F("plausibility check failed, expected ")); + DBGPRINT(String(rec->pyldLen)); + DBGPRINTLN(F(" bytes")); + } mStat->rxFail++; } @@ -353,47 +413,59 @@ class HmsPayload { (mCbPayload)(val, iv); } - bool build(uint8_t id, bool *complete) { + bool build(Inverter<> *iv, bool *complete, bool *fastNext ) { DPRINTLN(DBG_VERBOSE, F("build")); uint16_t crc = 0xffff, crcRcv = 0x0000; - if (mPayload[id].maxPackId > MAX_PAYLOAD_ENTRIES) - mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES; + if (mPayload[iv->id].maxPackId > MAX_PAYLOAD_ENTRIES) + mPayload[iv->id].maxPackId = MAX_PAYLOAD_ENTRIES; // check if all fragments are there *complete = true; - for (uint8_t i = 0; i < mPayload[id].maxPackId; i++) { - if(mPayload[id].len[i] == 0) + *fastNext = false; + for (uint8_t i = 0; i < mPayload[iv->id].maxPackId; i++) { + if(mPayload[iv->id].len[i] == 0) { *complete = false; + } } if(!*complete) return false; - for (uint8_t i = 0; i < mPayload[id].maxPackId; i++) { - if (mPayload[id].len[i] > 0) { - if (i == (mPayload[id].maxPackId - 1)) { - crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i] - 1, crc); - crcRcv = (mPayload[id].data[i][mPayload[id].len[i] - 2] << 8) | (mPayload[id].data[i][mPayload[id].len[i] - 1]); + for (uint8_t i = 0; i < mPayload[iv->id].maxPackId; i++) { + if (mPayload[iv->id].len[i] > 0) { + if (i == (mPayload[iv->id].maxPackId - 1)) { + crc = ah::crc16(mPayload[iv->id].data[i], mPayload[iv->id].len[i] - 1, crc); + crcRcv = (mPayload[iv->id].data[i][mPayload[iv->id].len[i] - 2] << 8) | (mPayload[iv->id].data[i][mPayload[iv->id].len[i] - 1]); } else - crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i], crc); + crc = ah::crc16(mPayload[iv->id].data[i], mPayload[iv->id].len[i], crc); } yield(); } - return (crc == crcRcv) ? true : false; + //return (crc == crcRcv) ? true : false; + if (crc != crcRcv) + return false; + + //requests to cause the next request to be executed immediately + if (mPayload[iv->id].gotFragment && ((mPayload[iv->id].txCmd < 11) || (mPayload[iv->id].txCmd > 18))) { + *fastNext = true; + } + + return true; } - void reset(uint8_t id) { - //DPRINT(DBG_INFO, "resetPayload: id: "); - //DBGPRINTLN(String(id)); - memset(&mPayload[id], 0, sizeof(hmsPayload_t)); + void reset(uint8_t id, bool setTxTmo = true) { + //DPRINT_IVID(DBG_INFO, id); + //DBGPRINTLN(F("resetPayload")); + memset(mPayload[id].len, 0, MAX_PAYLOAD_ENTRIES); mPayload[id].txCmd = 0; mPayload[id].gotFragment = false; - //mPayload[id].retransmits = 0; + mPayload[id].retransmits = 0; mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES; mPayload[id].lastFound = false; mPayload[id].complete = false; mPayload[id].requested = false; mPayload[id].ts = *mTimestamp; + mPayload[id].rxTmo = setTxTmo; // design: don't start with complete retransmit } IApp *mApp; @@ -402,7 +474,6 @@ class HmsPayload { statistics_t *mStat; uint8_t mMaxRetrans; uint32_t *mTimestamp; - //uint32_t mLastRx; hmsPayload_t mPayload[MAX_NUM_INVERTERS]; uint8_t mIvCmd56Cnt[MAX_NUM_INVERTERS]; bool mSerialDebug; diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index e579deda..4cc88d03 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -111,6 +111,11 @@ class CmtRadio { sendPacket(24, isRetransmit); } + void sendCmdPacket(uint64_t ivId, uint8_t mid, uint8_t pid, bool isRetransmit) { + initPacket(&ivId, mid, pid); + sendPacket(10, isRetransmit); + } + void sendPacket(uint8_t len, bool isRetransmit) { if (len > 14) { uint16_t crc = ah::crc16(&mTxBuf[10], len - 10); From d8feaf02acf4eb41a8f3ea4b748be1944fb62c56 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 30 Sep 2023 00:10:49 +0200 Subject: [PATCH 02/18] changed to generic packet_t --- src/app.cpp | 8 ++++---- src/hm/hmPayload.h | 6 +++--- src/hms/cmt2300a.h | 4 ++-- src/hms/esp32_3wSpi.h | 9 ++++++--- src/hms/hmsPayload.h | 23 ++++++++++++----------- src/hms/hmsRadio.h | 11 +++-------- 6 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index ffc7c871..c7a20391 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -151,18 +151,18 @@ void app::loop(void) { #if defined(ESP32) if (mCmtRadio.loop() && mConfig->cmt.enabled) { while (!mCmtRadio.mBufCtrl.empty()) { - hmsPacket_t *p = &mCmtRadio.mBufCtrl.front(); + packet_t *p = &mCmtRadio.mBufCtrl.front(); if (mConfig->serial.debug) { DPRINT(DBG_INFO, F("RX ")); - DBGPRINT(String(p->data[0])); + DBGPRINT(String(p->len)); DBGPRINT(F(", ")); DBGPRINT(String(p->rssi)); DBGPRINT(F("dBm | ")); - ah::dumpBuf(&p->data[1], p->data[0]); + ah::dumpBuf(p->packet, p->len); } mCmtStat.frmCnt++; - Inverter<> *iv = mSys.findInverter(&p->data[2]); + Inverter<> *iv = mSys.findInverter(&p->packet[1]); if(NULL != iv) { if((iv->ivGen == IV_HMS) || (iv->ivGen == IV_HMT)) mHmsPayload.add(iv, p); diff --git a/src/hm/hmPayload.h b/src/hm/hmPayload.h index a07c57eb..aa8fdfe6 100644 --- a/src/hm/hmPayload.h +++ b/src/hm/hmPayload.h @@ -33,12 +33,12 @@ typedef std::function *)> payloadListenerType; typedef std::function *)> alarmListenerType; -template +template class HmPayload { public: HmPayload() {} - void setup(IApp *app, HMSYSTEM *sys, HMRADIO *radio, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) { + void setup(IApp *app, HMSYSTEM *sys, RADIO *radio, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) { mApp = app; mSys = sys; mRadio = radio; @@ -460,7 +460,7 @@ class HmPayload { IApp *mApp; HMSYSTEM *mSys; - HMRADIO *mRadio; + RADIO *mRadio; statistics_t *mStat; uint8_t mMaxRetrans; uint32_t *mTimestamp; diff --git a/src/hms/cmt2300a.h b/src/hms/cmt2300a.h index d99875b9..a4308519 100644 --- a/src/hms/cmt2300a.h +++ b/src/hms/cmt2300a.h @@ -239,7 +239,7 @@ class Cmt2300a { return CMT_SUCCESS; } - uint8_t getRx(uint8_t buf[], uint8_t len, int8_t *rssi) { + uint8_t getRx(uint8_t buf[], uint8_t *rxLen, uint8_t maxlen, int8_t *rssi) { if(mTxPending) return CMT_ERR_TX_PENDING; @@ -250,7 +250,7 @@ class Cmt2300a { if(!cmtSwitchStatus(CMT2300A_GO_STBY, CMT2300A_STA_STBY)) return CMT_ERR_SWITCH_STATE; - mSpi.readFifo(buf, len); + mSpi.readFifo(buf, rxLen, maxlen); *rssi = mSpi.readReg(CMT2300A_CUS_RSSI_DBM) - 128; if(!cmtSwitchStatus(CMT2300A_GO_SLEEP, CMT2300A_STA_SLEEP)) diff --git a/src/hms/esp32_3wSpi.h b/src/hms/esp32_3wSpi.h index 4fe47497..e1c4114b 100644 --- a/src/hms/esp32_3wSpi.h +++ b/src/hms/esp32_3wSpi.h @@ -141,7 +141,7 @@ class esp32_3wSpi { SPI_PARAM_UNLOCK(); } - void readFifo(uint8_t buf[], uint8_t len) { + void readFifo(uint8_t buf[], uint8_t *len, uint8_t maxlen) { if(!mInitialized) return; uint8_t rx_data; @@ -154,10 +154,13 @@ class esp32_3wSpi { }; SPI_PARAM_LOCK(); - for(uint8_t i = 0; i < len; i++) { + for(uint8_t i = 0; i < maxlen; i++) { ESP_ERROR_CHECK(spi_device_polling_transmit(spi_fifo, &t)); delayMicroseconds(4); // > 4 us - buf[i] = rx_data; + if(0 == i) + *len = rx_data; + else + buf[i-1] = rx_data; } SPI_PARAM_UNLOCK(); } diff --git a/src/hms/hmsPayload.h b/src/hms/hmsPayload.h index 489fe044..893dfee2 100644 --- a/src/hms/hmsPayload.h +++ b/src/hms/hmsPayload.h @@ -172,18 +172,19 @@ class HmsPayload { } } - void add(Inverter<> *iv, hmsPacket_t *p) { - if (p->data[1] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command - mPayload[iv->id].txId = p->data[1]; + void add(Inverter<> *iv, packet_t *p) { + if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command + mPayload[iv->id].txId = p->packet[0]; DPRINTLN(DBG_DEBUG, F("Response from info request received")); - uint8_t *pid = &p->data[10]; + uint8_t *pid = &p->packet[9]; if (*pid == 0x00) { DPRINTLN(DBG_DEBUG, F("fragment number zero received and ignored")); } else { - DPRINTLN(DBG_DEBUG, "PID: 0x" + String(*pid, HEX)); + DPRINT(DBG_DEBUG, F("PID: 0x")); + DPRINTLN(DBG_DEBUG, String(*pid, HEX)); if ((*pid & 0x7F) < MAX_PAYLOAD_ENTRIES) { - memcpy(mPayload[iv->id].data[(*pid & 0x7F) - 1], &p->data[11], p->data[0] - 11); - mPayload[iv->id].len[(*pid & 0x7F) - 1] = p->data[0] -11; + memcpy(mPayload[iv->id].data[(*pid & 0x7F) - 1], &p->packet[10], p->len - 11); + mPayload[iv->id].len[(*pid & 0x7F) - 1] = p->len - 11; mPayload[iv->id].gotFragment = true; mPayload[iv->id].rssi[(*pid & 0x7F) - 1] = p->rssi; } @@ -197,15 +198,15 @@ class HmsPayload { } } } - } else if (p->data[1] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command + } else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command DPRINTLN(DBG_DEBUG, F("Response from devcontrol request received")); - mPayload[iv->id].txId = p->data[1]; + mPayload[iv->id].txId = p->packet[0]; iv->clearDevControlRequest(); - if ((p->data[13] == ActivePowerContr) && (p->data[14] == 0x00)) { + if ((p->packet[12] == ActivePowerContr) && (p->packet[13] == 0x00)) { bool ok = true; - if((p->data[11] == 0x00) && (p->data[12] == 0x00)) { + if((p->packet[10] == 0x00) && (p->packet[11] == 0x00)) { mApp->setMqttPowerLimitAck(iv); iv->powerLimitAck = true; } else diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index 4cc88d03..ff19e217 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -9,11 +9,6 @@ #include "../utils/dbg.h" #include "cmt2300a.h" -typedef struct { - int8_t rssi; - uint8_t data[28]; -} hmsPacket_t; - #define U32_B3(val) ((uint8_t)((val >> 24) & 0xff)) #define U32_B2(val) ((uint8_t)((val >> 16) & 0xff)) #define U32_B1(val) ((uint8_t)((val >> 8) & 0xff)) @@ -146,7 +141,7 @@ class CmtRadio { mStat->txCnt++; } - std::queue mBufCtrl; + std::queue mBufCtrl; private: inline void reset(bool genDtuSn) { @@ -206,8 +201,8 @@ class CmtRadio { } inline void getRx(void) { - hmsPacket_t p; - uint8_t status = mCmt.getRx(p.data, 28, &p.rssi); + packet_t p; + uint8_t status = mCmt.getRx(p.packet, &p.len, 28, &p.rssi); if(CMT_SUCCESS == status) mBufCtrl.push(p); } From 09c43974911de2a024cd49538db621fe60c444e7 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 30 Sep 2023 00:24:02 +0200 Subject: [PATCH 03/18] aligned radios --- src/hms/hmsPayload.h | 16 ++++++++-------- src/hms/hmsRadio.h | 14 +++++++------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/hms/hmsPayload.h b/src/hms/hmsPayload.h index 893dfee2..f63f38e4 100644 --- a/src/hms/hmsPayload.h +++ b/src/hms/hmsPayload.h @@ -151,12 +151,12 @@ class HmsPayload { DBGPRINTLN(String(iv->powerLimit[0])); } iv->powerLimitAck = false; - mRadio->sendControlPacket(&iv->radioId.u64, iv->devControlCmd, iv->powerLimit, false); + mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, false); mPayload[iv->id].txCmd = iv->devControlCmd; //iv->clearCmdQueue(); //iv->enqueCommand(SystemConfigPara); // read back power limit } else if(((rec->ts + HMS_TIMEOUT_SEC) < *mTimestamp) && (mIvCmd56Cnt[iv->id] < 3)) { - mRadio->switchFrequency(&iv->radioId.u64, HOY_BOOT_FREQ_KHZ, WORK_FREQ_KHZ); + mRadio->switchFrequency(iv->radioId.u64, HOY_BOOT_FREQ_KHZ, WORK_FREQ_KHZ); mIvCmd56Cnt[iv->id]++; } else { if(++mIvCmd56Cnt[iv->id] == 10) @@ -167,7 +167,7 @@ class HmsPayload { DBGPRINT(F("prepareDevInformCmd 0x")); DBGHEXLN(cmd); } - mRadio->prepareDevInformCmd(&iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); + mRadio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); mPayload[iv->id].txCmd = cmd; } } @@ -261,7 +261,7 @@ class HmsPayload { } else if(iv->devControlCmd == ActivePowerContr) { DPRINT_IVID(DBG_INFO, iv->id); DPRINTLN(DBG_INFO, F("retransmit power limit")); - mRadio->sendControlPacket(&iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); + mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); } else { if(false == mPayload[iv->id].gotFragment) { DPRINT_IVID(DBG_WARN, iv->id); @@ -272,7 +272,7 @@ class HmsPayload { DBGPRINTLN(F("nothing received: complete retransmit")); mPayload[iv->id].txCmd = iv->getQueuedCmd(); DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX)); - mRadio->prepareDevInformCmd(&iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); + mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); } } else { for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) { @@ -305,7 +305,7 @@ class HmsPayload { DBGPRINT(F("prepareDevInformCmd 0x")); DBGHEXLN(mPayload[iv->id].txCmd); } - mRadio->prepareDevInformCmd(&iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmLastId, true); + mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmLastId, true); } } else { // payload complete if (mSerialDebug) { @@ -386,7 +386,7 @@ class HmsPayload { DBGHEXLN(cmd); } mStat->rxSuccess++; - mRadio->prepareDevInformCmd(&iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); + mRadio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); mPayload[iv->id].txCmd = cmd; */ mHighPrioIv = iv; @@ -434,7 +434,7 @@ class HmsPayload { for (uint8_t i = 0; i < mPayload[iv->id].maxPackId; i++) { if (mPayload[iv->id].len[i] > 0) { if (i == (mPayload[iv->id].maxPackId - 1)) { - crc = ah::crc16(mPayload[iv->id].data[i], mPayload[iv->id].len[i] - 1, crc); + crc = ah::crc16(mPayload[iv->id].data[i], mPayload[iv->id].len[i] - 2, crc); crcRcv = (mPayload[iv->id].data[i][mPayload[iv->id].len[i] - 2] << 8) | (mPayload[iv->id].data[i][mPayload[iv->id].len[i] - 1]); } else crc = ah::crc16(mPayload[iv->id].data[i], mPayload[iv->id].len[i], crc); diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index ff19e217..29f23236 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -64,7 +64,7 @@ class CmtRadio { return mCmtAvail; } - void sendControlPacket(const uint64_t *ivId, uint8_t cmd, uint16_t *data, bool isRetransmit) { + void sendControlPacket(uint64_t ivId, uint8_t cmd, uint16_t *data, bool isRetransmit) { DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x")); DBGHEXLN(cmd); initPacket(ivId, TX_REQ_DEVCONTROL, SINGLE_FRAME); @@ -82,7 +82,7 @@ class CmtRadio { sendPacket(cnt, isRetransmit); } - bool switchFrequency(const uint64_t *ivId, uint32_t fromkHz, uint32_t tokHz) { + bool switchFrequency(uint64_t ivId, uint32_t fromkHz, uint32_t tokHz) { uint8_t fromCh = mCmt.freq2Chan(fromkHz); uint8_t toCh = mCmt.freq2Chan(tokHz); @@ -95,7 +95,7 @@ class CmtRadio { return true; } - void prepareDevInformCmd(const uint64_t *ivId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) { // might not be necessary to add additional arg. + void prepareDevInformCmd(uint64_t ivId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) { // might not be necessary to add additional arg. initPacket(ivId, reqfld, ALL_FRAMES); mTxBuf[10] = cmd; CP_U32_LittleEndian(&mTxBuf[12], ts); @@ -107,7 +107,7 @@ class CmtRadio { } void sendCmdPacket(uint64_t ivId, uint8_t mid, uint8_t pid, bool isRetransmit) { - initPacket(&ivId, mid, pid); + initPacket(ivId, mid, pid); sendPacket(10, isRetransmit); } @@ -160,7 +160,7 @@ class CmtRadio { mRqstGetRx = false; } - inline void sendSwitchChCmd(const uint64_t *ivId, uint8_t ch) { + inline void sendSwitchChCmd(uint64_t ivId, uint8_t ch) { /** ch: * 0x00: 860.00 MHz * 0x01: 860.25 MHz @@ -179,9 +179,9 @@ class CmtRadio { mRqstGetRx = true; } - void initPacket(const uint64_t *ivId, uint8_t mid, uint8_t pid) { + void initPacket(uint64_t ivId, uint8_t mid, uint8_t pid) { mTxBuf[0] = mid; - CP_U32_BigEndian(&mTxBuf[1], (*ivId) >> 8); + CP_U32_BigEndian(&mTxBuf[1], ivId >> 8); CP_U32_LittleEndian(&mTxBuf[5], mDtuSn); mTxBuf[9] = pid; memset(&mTxBuf[10], 0x00, 17); From 1d28387d1dc35980baa096309f13d2c484e5ac6a Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 30 Sep 2023 00:47:02 +0200 Subject: [PATCH 04/18] add radio interface radio.h --- src/hm/hmPayload.h | 2 ++ src/hm/hmRadio.h | 14 +++++--------- src/hm/radio.h | 22 ++++++++++++++++++++++ src/hms/hmsPayload.h | 8 +------- src/hms/hmsRadio.h | 12 ++++-------- 5 files changed, 34 insertions(+), 24 deletions(-) create mode 100644 src/hm/radio.h diff --git a/src/hm/hmPayload.h b/src/hm/hmPayload.h index aa8fdfe6..14f8da75 100644 --- a/src/hm/hmPayload.h +++ b/src/hm/hmPayload.h @@ -12,6 +12,8 @@ #include "hmRadio.h" #include +#define HMS_TIMEOUT_SEC 30 + typedef struct { uint8_t txCmd; uint8_t txId; diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index 870ef457..cde5cba0 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -3,24 +3,20 @@ // Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed //----------------------------------------------------------------------------- -#ifndef __RADIO_H__ -#define __RADIO_H__ +#ifndef __HM_RADIO_H__ +#define __HM_RADIO_H__ #include "../utils/dbg.h" #include #include "../utils/crc.h" #include "../config/config.h" #include "SPI.h" +#include "radio.h" #define SPI_SPEED 1000000 #define RF_CHANNELS 5 -#define TX_REQ_INFO 0x15 -#define TX_REQ_DEVCONTROL 0x51 -#define ALL_FRAMES 0x80 -#define SINGLE_FRAME 0x81 - const char* const rf24AmpPowerNames[] = {"MIN", "LOW", "HIGH", "MAX"}; @@ -28,7 +24,7 @@ const char* const rf24AmpPowerNames[] = {"MIN", "LOW", "HIGH", "MAX"}; // HM Radio class //----------------------------------------------------------------------------- template -class HmRadio { +class HmRadio : public Radio { public: HmRadio() : mNrf24(CE_PIN, CS_PIN, SPI_SPEED) { if(mSerialDebug) { @@ -349,4 +345,4 @@ class HmRadio { statistics_t *mStat; }; -#endif /*__RADIO_H__*/ +#endif /*__HM_RADIO_H__*/ diff --git a/src/hm/radio.h b/src/hm/radio.h new file mode 100644 index 00000000..0eb2df5f --- /dev/null +++ b/src/hm/radio.h @@ -0,0 +1,22 @@ +//----------------------------------------------------------------------------- +// 2023 Ahoy, https://github.com/lumpapu/ahoy +// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed +//----------------------------------------------------------------------------- + +#ifndef __RADIO_H__ +#define __RADIO_H__ + +#define TX_REQ_INFO 0x15 +#define TX_REQ_DEVCONTROL 0x51 +#define ALL_FRAMES 0x80 +#define SINGLE_FRAME 0x81 + +// abstract radio interface +class Radio { + public: + virtual void sendControlPacket(uint64_t invId, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) = 0; + virtual void prepareDevInformCmd(uint64_t invId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) = 0; + virtual void sendCmdPacket(uint64_t invId, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) = 0; +}; + +#endif /*__RADIO_H__*/ diff --git a/src/hms/hmsPayload.h b/src/hms/hmsPayload.h index f63f38e4..d6f1232e 100644 --- a/src/hms/hmsPayload.h +++ b/src/hms/hmsPayload.h @@ -11,7 +11,7 @@ #include "../config/config.h" #include -#define HMS_TIMEOUT_SEC 30 // 30s * 1000 +#define HMS_TIMEOUT_SEC 30 typedef struct { uint8_t txCmd; @@ -103,9 +103,6 @@ class HmsPayload { } void ivSend(Inverter<> *iv, bool highPrio = false) { - if ((IV_HMS != iv->ivGen) && (IV_HMT != iv->ivGen)) // only process HMS inverters - return; - if(!highPrio) { if (mPayload[iv->id].requested) { if (!mPayload[iv->id].complete) @@ -237,9 +234,6 @@ class HmsPayload { if (NULL == iv) continue; // skip to next inverter - if ((IV_HMS != iv->ivGen) && (IV_HMT != iv->ivGen)) // only process HMS inverters - continue; // skip to next inverter - if ((mPayload[iv->id].txId != (TX_REQ_INFO + ALL_FRAMES)) && (0 != mPayload[iv->id].txId)) { // no processing needed if txId is not 0x95 mPayload[iv->id].complete = true; diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index 29f23236..c8cf480c 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -8,14 +8,10 @@ #include "../utils/dbg.h" #include "cmt2300a.h" - -#define U32_B3(val) ((uint8_t)((val >> 24) & 0xff)) -#define U32_B2(val) ((uint8_t)((val >> 16) & 0xff)) -#define U32_B1(val) ((uint8_t)((val >> 8) & 0xff)) -#define U32_B0(val) ((uint8_t)((val ) & 0xff)) +#include "../hm/radio.h" template -class CmtRadio { +class CmtRadio : public Radio { typedef SPI SpiType; typedef Cmt2300a CmtType; public: @@ -64,7 +60,7 @@ class CmtRadio { return mCmtAvail; } - void sendControlPacket(uint64_t ivId, uint8_t cmd, uint16_t *data, bool isRetransmit) { + void sendControlPacket(uint64_t ivId, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) { DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x")); DBGHEXLN(cmd); initPacket(ivId, TX_REQ_DEVCONTROL, SINGLE_FRAME); @@ -106,7 +102,7 @@ class CmtRadio { sendPacket(24, isRetransmit); } - void sendCmdPacket(uint64_t ivId, uint8_t mid, uint8_t pid, bool isRetransmit) { + void sendCmdPacket(uint64_t ivId, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) { initPacket(ivId, mid, pid); sendPacket(10, isRetransmit); } From 9b22b1017afd7bf30e9f4095dc1f7c560c5cf374 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 30 Sep 2023 01:05:34 +0200 Subject: [PATCH 05/18] improved hmSystem --- src/app.cpp | 7 +++- src/hm/hmInverter.h | 4 +- src/hm/hmSystem.h | 99 +++++++++++++++++++++------------------------ 3 files changed, 53 insertions(+), 57 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index c7a20391..06a1c264 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -59,8 +59,11 @@ void app::setup() { #endif #endif /* defined(ETHERNET) */ - mSys.setup(&mTimestamp); - mSys.addInverters(&mConfig->inst); + mSys.setup(&mTimestamp, &mConfig->inst); + Inverter<> *iv; + for (uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { + mSys.addInverter(i); + } if (mConfig->nrf.enabled) { mPayload.setup(this, &mSys, &mNrfRadio, &mNrfStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); mPayload.enableSerialDebug(mConfig->serial.debug); diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index 54355da5..8cef4f2f 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -17,6 +17,7 @@ #include #include "../config/settings.h" +#include "radio.h" /** * For values which are of interest and not transmitted by the inverter can be * calculated automatically. @@ -152,7 +153,8 @@ class Inverter { uint8_t alarmNxtWrPos; // indicates the position in array (rolling buffer) uint16_t alarmCnt; // counts the total number of occurred alarms uint16_t alarmLastId; // lastId which was received - int8_t rssi; // HMS and HMT inverters only + int8_t rssi; // RSSI + Radio *radio; // pointer to associated radio class static uint32_t *timestamp; // system timestamp diff --git a/src/hm/hmSystem.h b/src/hm/hmSystem.h index 25d6dd11..6a4666a3 100644 --- a/src/hm/hmSystem.h +++ b/src/hm/hmSystem.h @@ -7,70 +7,45 @@ #define __HM_SYSTEM_H__ #include "hmInverter.h" +#include template > class HmSystem { public: HmSystem() {} - void setup(uint32_t *timestamp) { + void setup(uint32_t *timestamp, cfgInst_t *config) { mInverter[0].timestamp = timestamp; - mNumInv = 0; - } - - void addInverters(cfgInst_t *config) { mInverter[0].generalConfig = config; - Inverter<> *iv; - for (uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { - iv = addInverter(&config->iv[i]); - if (0ULL != config->iv[i].serial.u64) { - if (NULL != iv) { - DPRINT(DBG_INFO, "added inverter "); - if(iv->config->serial.b[5] == 0x11) { - if((iv->config->serial.b[4] & 0x0f) == 0x04) - DBGPRINT("HMS"); - else - DBGPRINT("HM"); - } else if(iv->config->serial.b[5] == 0x13) - DBGPRINT("HMT"); - else - DBGPRINT(((iv->config->serial.b[4] & 0x03) == 0x01) ? " (2nd Gen) " : " (3rd Gen) "); - - 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!!!")); - } - } - } + mNumInv = 0; } - INVERTERTYPE *addInverter(cfgIv_t *config) { + void addInverter(uint8_t id) { DPRINTLN(DBG_VERBOSE, F("hmSystem.h:addInverter")); if(MAX_INVERTER <= mNumInv) { DPRINT(DBG_WARN, F("max number of inverters reached!")); - return NULL; + return; } - INVERTERTYPE *p = &mInverter[mNumInv]; - p->id = mNumInv; - p->config = config; - DPRINT(DBG_VERBOSE, "SERIAL: " + String(p->config->serial.b[5], HEX)); - DPRINTLN(DBG_VERBOSE, " " + String(p->config->serial.b[4], HEX)); - if((p->config->serial.b[5] == 0x11) || (p->config->serial.b[5] == 0x10)) { - switch(p->config->serial.b[4]) { + INVERTERTYPE *iv = &mInverter[mNumInv]; + iv->id = mNumInv; + iv->config = &mInverter[0].generalConfig->iv[id]; + DPRINT(DBG_VERBOSE, "SERIAL: " + String(iv->config->serial.b[5], HEX)); + DPRINTLN(DBG_VERBOSE, " " + String(iv->config->serial.b[4], HEX)); + if((iv->config->serial.b[5] == 0x11) || (iv->config->serial.b[5] == 0x10)) { + switch(iv->config->serial.b[4]) { case 0x24: // HMS-500 case 0x22: - case 0x21: p->type = INV_TYPE_1CH; + case 0x21: iv->type = INV_TYPE_1CH; break; case 0x44: // HMS-1000 case 0x42: - case 0x41: p->type = INV_TYPE_2CH; + case 0x41: iv->type = INV_TYPE_2CH; break; case 0x64: // HMS-2000 case 0x62: - case 0x61: p->type = INV_TYPE_4CH; + case 0x61: iv->type = INV_TYPE_4CH; break; default: @@ -78,26 +53,42 @@ class HmSystem { break; } - if(p->config->serial.b[5] == 0x11) { - if((p->config->serial.b[4] & 0x0f) == 0x04) - p->ivGen = IV_HMS; + if(iv->config->serial.b[5] == 0x11) { + if((iv->config->serial.b[4] & 0x0f) == 0x04) + iv->ivGen = IV_HMS; else - p->ivGen = IV_HM; + iv->ivGen = IV_HM; } - else if((p->config->serial.b[4] & 0x03) == 0x02) // MI 3rd Gen -> same as HM - p->ivGen = IV_HM; + else if((iv->config->serial.b[4] & 0x03) == 0x02) // MI 3rd Gen -> same as HM + iv->ivGen = IV_HM; else // MI 2nd Gen - p->ivGen = IV_MI; - } else if(p->config->serial.b[5] == 0x13) { - p->ivGen = IV_HMT; - p->type = INV_TYPE_6CH; - } else if(p->config->serial.u64 != 0ULL) + iv->ivGen = IV_MI; + } else if(iv->config->serial.b[5] == 0x13) { + iv->ivGen = IV_HMT; + iv->type = INV_TYPE_6CH; + } else if(iv->config->serial.u64 != 0ULL) { DPRINTLN(DBG_ERROR, F("inverter type can't be detected!")); + return; + } - p->init(); - + iv->init(); mNumInv ++; - return p; + + DPRINT(DBG_INFO, "added inverter "); + if(iv->config->serial.b[5] == 0x11) { + if((iv->config->serial.b[4] & 0x0f) == 0x04) + DBGPRINT("HMS"); + else + DBGPRINT("HM"); + } else if(iv->config->serial.b[5] == 0x13) + DBGPRINT("HMT"); + else + DBGPRINT(((iv->config->serial.b[4] & 0x03) == 0x01) ? " (2nd Gen) " : " (3rd Gen) "); + + 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!!!")); } INVERTERTYPE *findInverter(uint8_t buf[]) { From dcd5d5a72b68dfbc56b6f9690865d534dc643d94 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 30 Sep 2023 01:11:20 +0200 Subject: [PATCH 06/18] set radio pointer to inverter --- src/app.cpp | 8 ++++++-- src/hm/hmSystem.h | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index 06a1c264..a7a12ae8 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -60,9 +60,13 @@ void app::setup() { #endif /* defined(ETHERNET) */ mSys.setup(&mTimestamp, &mConfig->inst); - Inverter<> *iv; for (uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { - mSys.addInverter(i); + mSys.addInverter(i, [this](Inverter<> *iv) { + if((IV_MI == iv->ivGen) || (IV_HM == iv->ivGen)) + iv->radio = &mNrfRadio; + else if((IV_HMS == iv->ivGen) || (IV_HMT == iv->ivGen)) + iv->radio = &mCmtRadio; + }); } if (mConfig->nrf.enabled) { mPayload.setup(this, &mSys, &mNrfRadio, &mNrfStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); diff --git a/src/hm/hmSystem.h b/src/hm/hmSystem.h index 6a4666a3..6c6faef6 100644 --- a/src/hm/hmSystem.h +++ b/src/hm/hmSystem.h @@ -20,7 +20,7 @@ class HmSystem { mNumInv = 0; } - void addInverter(uint8_t id) { + void addInverter(uint8_t id, std::function *iv)> cb) { DPRINTLN(DBG_VERBOSE, F("hmSystem.h:addInverter")); if(MAX_INVERTER <= mNumInv) { DPRINT(DBG_WARN, F("max number of inverters reached!")); @@ -89,6 +89,8 @@ class HmSystem { 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!!!")); + + cb(iv); } INVERTERTYPE *findInverter(uint8_t buf[]) { From a6953563139b2f939710442c978dc646e1af4f1c Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 30 Sep 2023 01:33:09 +0200 Subject: [PATCH 07/18] removed / replaced hmsPayload completely --- src/app.cpp | 30 +-- src/app.h | 15 +- src/hm/hmPayload.h | 39 ++-- src/hm/radio.h | 1 + src/hms/hmsPayload.h | 481 ------------------------------------------- 5 files changed, 36 insertions(+), 530 deletions(-) delete mode 100644 src/hms/hmsPayload.h diff --git a/src/app.cpp b/src/app.cpp index a7a12ae8..7ba18a8c 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -69,7 +69,7 @@ void app::setup() { }); } if (mConfig->nrf.enabled) { - mPayload.setup(this, &mSys, &mNrfRadio, &mNrfStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); + mPayload.setup(this, &mSys, &mNrfStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); mPayload.enableSerialDebug(mConfig->serial.debug); mPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1, std::placeholders::_2)); @@ -78,12 +78,6 @@ void app::setup() { mMiPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1, std::placeholders::_2)); } - #if defined(ESP32) - mHmsPayload.setup(this, &mSys, &mCmtRadio, &mCmtStat, 5, &mTimestamp); - mHmsPayload.enableSerialDebug(mConfig->serial.debug); - mHmsPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1, std::placeholders::_2)); - #endif - if(mConfig->nrf.enabled) { if (!mNrfRadio.isChipConnected()) DPRINTLN(DBG_WARN, F("WARNING! your NRF24 module can't be reached, check the wiring")); @@ -97,9 +91,6 @@ void app::setup() { mMqtt.setSubscriptionCb(std::bind(&app::mqttSubRxCb, this, std::placeholders::_1)); mPayload.addAlarmListener([this](Inverter<> *iv) { mMqtt.alarmEvent(iv); }); mMiPayload.addAlarmListener([this](Inverter<> *iv) { mMqtt.alarmEvent(iv); }); - #if defined(ESP32) - mHmsPayload.addAlarmListener([this](Inverter<> *iv) { mMqtt.alarmEvent(iv); }); - #endif } #endif setupLed(); @@ -172,19 +163,16 @@ void app::loop(void) { Inverter<> *iv = mSys.findInverter(&p->packet[1]); if(NULL != iv) { if((iv->ivGen == IV_HMS) || (iv->ivGen == IV_HMT)) - mHmsPayload.add(iv, p); + mPayload.add(iv, p); } mCmtRadio.mBufCtrl.pop(); yield(); } - mHmsPayload.process(false); //true + mPayload.process(false); //true } #endif mPayload.loop(); mMiPayload.loop(); - #if defined(ESP32) - mHmsPayload.loop(); - #endif if (mMqttEnabled && mNetworkConnected) mMqtt.loop(); @@ -438,17 +426,11 @@ void app::tickSend(void) { if (NULL != iv) { if (iv->config->enabled) { if(mConfig->nrf.enabled) { - if (iv->ivGen == IV_HM) - mPayload.ivSend(iv); - else if(iv->ivGen == IV_MI) + if(iv->ivGen == IV_MI) mMiPayload.ivSend(iv); + else + mPayload.ivSend(iv); } - #if defined(ESP32) - if(mConfig->cmt.enabled) { - if((iv->ivGen == IV_HMS) || (iv->ivGen == IV_HMT)) - mHmsPayload.ivSend(iv); - } - #endif } } } else { diff --git a/src/app.h b/src/app.h index 3399869e..d383157a 100644 --- a/src/app.h +++ b/src/app.h @@ -16,7 +16,6 @@ #include "hm/hmSystem.h" #include "hm/hmRadio.h" #include "hms/hmsRadio.h" -#include "hms/hmsPayload.h" #include "hm/hmPayload.h" #include "hm/miPayload.h" #include "publisher/pubMqtt.h" @@ -42,11 +41,10 @@ #define ACOS(x) (degrees(acos(x))) typedef HmSystem HmSystemType; -typedef HmPayload> PayloadType; +typedef HmPayload PayloadType; typedef MiPayload> MiPayloadType; #ifdef ESP32 typedef CmtRadio CmtRadioType; -typedef HmsPayload HmsPayloadType; #endif typedef Web WebType; typedef RestApi RestApiType; @@ -180,14 +178,10 @@ class app : public IApp, public ah::Scheduler { void ivSendHighPrio(Inverter<> *iv) { if(mIVCommunicationOn) { // only send commands if communication is enabled - if (iv->ivGen == IV_HM) - mPayload.ivSendHighPrio(iv); - else if (iv->ivGen == IV_MI) + if (iv->ivGen == IV_MI) mMiPayload.ivSendHighPrio(iv); - #if defined(ESP32) - else if((iv->ivGen == IV_HMS) || (iv->ivGen == IV_HMT)) - mHmsPayload.ivSendHighPrio(iv); - #endif + else + mPayload.ivSendHighPrio(iv); } } @@ -334,7 +328,6 @@ class app : public IApp, public ah::Scheduler { #endif #ifdef ESP32 CmtRadioType mCmtRadio; - HmsPayloadType mHmsPayload; #endif char mVersion[12]; diff --git a/src/hm/hmPayload.h b/src/hm/hmPayload.h index 14f8da75..2f08886a 100644 --- a/src/hm/hmPayload.h +++ b/src/hm/hmPayload.h @@ -10,6 +10,9 @@ #include "../utils/crc.h" #include "../config/config.h" #include "hmRadio.h" +#if defined(ESP32) +#include "../hms/cmt2300a.h" +#endif #include #define HMS_TIMEOUT_SEC 30 @@ -35,20 +38,20 @@ typedef std::function *)> payloadListenerType; typedef std::function *)> alarmListenerType; -template +template class HmPayload { public: HmPayload() {} - void setup(IApp *app, HMSYSTEM *sys, RADIO *radio, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) { + void setup(IApp *app, HMSYSTEM *sys, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) { mApp = app; mSys = sys; - mRadio = radio; mStat = stat; mMaxRetrans = maxRetransmits; mTimestamp = timestamp; for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { reset(i); + mIvCmd56Cnt[i] = 0; } mSerialDebug = false; mHighPrioIv = NULL; @@ -147,18 +150,29 @@ class HmPayload { DBGPRINTLN(String(iv->powerLimit[0])); } iv->powerLimitAck = false; - mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, false); + iv->radio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, false); mPayload[iv->id].txCmd = iv->devControlCmd; //iv->clearCmdQueue(); //iv->enqueCommand(SystemConfigPara); // read back power limit } else { + #if defined(ESP32) + if((IV_HMS == iv->ivGen) || (IV_HMT == iv->ivGen)) { + record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); + if(((rec->ts + HMS_TIMEOUT_SEC) < *mTimestamp) && (mIvCmd56Cnt[iv->id] < 3)) { + iv->radio->switchFrequency(iv->radioId.u64, HOY_BOOT_FREQ_KHZ, WORK_FREQ_KHZ); + mIvCmd56Cnt[iv->id]++; + return; + } else if(++mIvCmd56Cnt[iv->id] == 10) + mIvCmd56Cnt[iv->id] = 0; + } + #endif uint8_t cmd = iv->getQueuedCmd(); if (mSerialDebug) { DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("prepareDevInformCmd 0x")); DBGHEXLN(cmd); } - mRadio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); + iv->radio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); mPayload[iv->id].txCmd = cmd; } } @@ -228,9 +242,6 @@ class HmPayload { if (NULL == iv) continue; // skip to next inverter - if (IV_HM != iv->ivGen) // only process HM inverters - continue; // skip to next inverter - if ((mPayload[iv->id].txId != (TX_REQ_INFO + ALL_FRAMES)) && (0 != mPayload[iv->id].txId)) { // no processing needed if txId is not 0x95 mPayload[iv->id].complete = true; @@ -252,7 +263,7 @@ class HmPayload { } else if(iv->devControlCmd == ActivePowerContr) { DPRINT_IVID(DBG_INFO, iv->id); DPRINTLN(DBG_INFO, F("retransmit power limit")); - mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); + iv->radio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); } else { if(false == mPayload[iv->id].gotFragment) { DPRINT_IVID(DBG_WARN, iv->id); @@ -263,7 +274,7 @@ class HmPayload { DBGPRINTLN(F("nothing received: complete retransmit")); mPayload[iv->id].txCmd = iv->getQueuedCmd(); DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX)); - mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); + iv->radio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); } } else { for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) { @@ -274,7 +285,7 @@ class HmPayload { DBGPRINT(String(i + 1)); DBGPRINTLN(F(" missing: Request Retransmit")); } - mRadio->sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true); + iv->radio->sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true); break; // only request retransmit one frame per loop } yield(); @@ -296,7 +307,7 @@ class HmPayload { DBGPRINT(F("prepareDevInformCmd 0x")); DBGHEXLN(mPayload[iv->id].txCmd); } - mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmLastId, true); + iv->radio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmLastId, true); } } else { // payload complete if (mSerialDebug) { @@ -377,7 +388,7 @@ class HmPayload { DBGHEXLN(cmd); } mStat->rxSuccess++; - mRadio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); + iv->radio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); mPayload[iv->id].txCmd = cmd; */ mHighPrioIv = iv; @@ -462,11 +473,11 @@ class HmPayload { IApp *mApp; HMSYSTEM *mSys; - RADIO *mRadio; statistics_t *mStat; uint8_t mMaxRetrans; uint32_t *mTimestamp; invPayload_t mPayload[MAX_NUM_INVERTERS]; + uint8_t mIvCmd56Cnt[MAX_NUM_INVERTERS]; bool mSerialDebug; Inverter<> *mHighPrioIv; diff --git a/src/hm/radio.h b/src/hm/radio.h index 0eb2df5f..9f026add 100644 --- a/src/hm/radio.h +++ b/src/hm/radio.h @@ -17,6 +17,7 @@ class Radio { virtual void sendControlPacket(uint64_t invId, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) = 0; virtual void prepareDevInformCmd(uint64_t invId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) = 0; virtual void sendCmdPacket(uint64_t invId, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) = 0; + virtual bool switchFrequency(uint64_t ivId, uint32_t fromkHz, uint32_t tokHz) { return true; } }; #endif /*__RADIO_H__*/ diff --git a/src/hms/hmsPayload.h b/src/hms/hmsPayload.h deleted file mode 100644 index d6f1232e..00000000 --- a/src/hms/hmsPayload.h +++ /dev/null @@ -1,481 +0,0 @@ -//----------------------------------------------------------------------------- -// 2023 Ahoy, https://ahoydtu.de -// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed -//----------------------------------------------------------------------------- - -#ifndef __HMS_PAYLOAD_H__ -#define __HMS_PAYLOAD_H__ - -#include "../utils/dbg.h" -#include "../utils/crc.h" -#include "../config/config.h" -#include - -#define HMS_TIMEOUT_SEC 30 - -typedef struct { - uint8_t txCmd; - uint8_t txId; - uint32_t ts; - uint8_t data[MAX_PAYLOAD_ENTRIES][MAX_RF_PAYLOAD_SIZE]; - int8_t rssi[MAX_PAYLOAD_ENTRIES]; - uint8_t len[MAX_PAYLOAD_ENTRIES]; - bool complete; - uint8_t maxPackId; - bool lastFound; - uint8_t retransmits; - bool requested; - bool gotFragment; - bool rxTmo; -} hmsPayload_t; - - -typedef std::function *)> payloadListenerType; -typedef std::function *)> alarmListenerType; - - -template -class HmsPayload { - public: - HmsPayload() {} - - void setup(IApp *app, HMSYSTEM *sys, RADIO *radio, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) { - mApp = app; - mSys = sys; - mRadio = radio; - mStat = stat; - mMaxRetrans = maxRetransmits; - mTimestamp = timestamp; - for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { - reset(i); - mIvCmd56Cnt[i] = 0; - } - mSerialDebug = false; - mHighPrioIv = NULL; - mCbAlarm = NULL; - mCbPayload = NULL; - } - - void enableSerialDebug(bool enable) { - mSerialDebug = enable; - } - - void addPayloadListener(payloadListenerType cb) { - mCbPayload = cb; - } - - void addAlarmListener(alarmListenerType cb) { - mCbAlarm = cb; - } - - void loop() { - if (NULL != mHighPrioIv) { - ivSend(mHighPrioIv, true); - mHighPrioIv = NULL; - } - } - - /*void simulation() { - uint8_t pay[] = { - 0x00, 0x01, 0x01, 0x24, 0x02, 0x28, 0x02, 0x33, - 0x06, 0x49, 0x06, 0x6a, 0x00, 0x05, 0x5f, 0x1b, - 0x00, 0x06, 0x66, 0x9a, 0x03, 0xfd, 0x04, 0x0b, - 0x01, 0x23, 0x02, 0x28, 0x02, 0x28, 0x06, 0x41, - 0x06, 0x43, 0x00, 0x05, 0xdc, 0x2c, 0x00, 0x06, - 0x2e, 0x3f, 0x04, 0x01, 0x03, 0xfb, 0x09, 0x78, - 0x13, 0x86, 0x18, 0x15, 0x00, 0xcf, 0x00, 0xfe, - 0x03, 0xe7, 0x01, 0x42, 0x00, 0x03 - }; - - Inverter<> *iv = mSys->getInverterByPos(0); - record_t<> *rec = iv->getRecordStruct(0x0b); - rec->ts = *mTimestamp; - for (uint8_t i = 0; i < rec->length; i++) { - iv->addValue(i, pay, rec); - yield(); - } - iv->doCalculations(); - notify(0x0b, iv); - }*/ - - void ivSendHighPrio(Inverter<> *iv) { - mHighPrioIv = iv; - } - - void ivSend(Inverter<> *iv, bool highPrio = false) { - if(!highPrio) { - if (mPayload[iv->id].requested) { - if (!mPayload[iv->id].complete) - process(false); // no retransmit - - if (!mPayload[iv->id].complete) { - if (mSerialDebug) - DPRINT_IVID(DBG_INFO, iv->id); - if (MAX_PAYLOAD_ENTRIES == mPayload[iv->id].maxPackId) { - mStat->rxFailNoAnser++; // got nothing - if (mSerialDebug) - DBGPRINTLN(F("enqueued cmd failed/timeout")); - } else { - mStat->rxFail++; // got fragments but not complete response - if (mSerialDebug) { - DBGPRINT(F("no complete Payload received! (retransmits: ")); - DBGPRINT(String(mPayload[iv->id].retransmits)); - DBGPRINTLN(F(")")); - } - } - iv->setQueuedCmdFinished(); // command failed - } - } - } - - reset(iv->id, !iv->isAvailable()); - mPayload[iv->id].requested = true; - - yield(); - if (mSerialDebug) { - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINT(F("Requesting Inv SN ")); - DBGPRINTLN(String(iv->config->serial.u64, HEX)); - } - - record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); - if (iv->getDevControlRequest()) { - if (mSerialDebug) { - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINT(F("Devcontrol request 0x")); - DBGPRINT(String(iv->devControlCmd, HEX)); - DBGPRINT(F(" power limit ")); - DBGPRINTLN(String(iv->powerLimit[0])); - } - iv->powerLimitAck = false; - mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, false); - mPayload[iv->id].txCmd = iv->devControlCmd; - //iv->clearCmdQueue(); - //iv->enqueCommand(SystemConfigPara); // read back power limit - } else if(((rec->ts + HMS_TIMEOUT_SEC) < *mTimestamp) && (mIvCmd56Cnt[iv->id] < 3)) { - mRadio->switchFrequency(iv->radioId.u64, HOY_BOOT_FREQ_KHZ, WORK_FREQ_KHZ); - mIvCmd56Cnt[iv->id]++; - } else { - if(++mIvCmd56Cnt[iv->id] == 10) - mIvCmd56Cnt[iv->id] = 0; - uint8_t cmd = iv->getQueuedCmd(); - if (mSerialDebug) { - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINT(F("prepareDevInformCmd 0x")); - DBGHEXLN(cmd); - } - mRadio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); - mPayload[iv->id].txCmd = cmd; - } - } - - void add(Inverter<> *iv, packet_t *p) { - if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command - mPayload[iv->id].txId = p->packet[0]; - DPRINTLN(DBG_DEBUG, F("Response from info request received")); - uint8_t *pid = &p->packet[9]; - if (*pid == 0x00) { - DPRINTLN(DBG_DEBUG, F("fragment number zero received and ignored")); - } else { - DPRINT(DBG_DEBUG, F("PID: 0x")); - DPRINTLN(DBG_DEBUG, String(*pid, HEX)); - if ((*pid & 0x7F) < MAX_PAYLOAD_ENTRIES) { - memcpy(mPayload[iv->id].data[(*pid & 0x7F) - 1], &p->packet[10], p->len - 11); - mPayload[iv->id].len[(*pid & 0x7F) - 1] = p->len - 11; - mPayload[iv->id].gotFragment = true; - mPayload[iv->id].rssi[(*pid & 0x7F) - 1] = p->rssi; - } - - if ((*pid & ALL_FRAMES) == ALL_FRAMES) { - // Last packet - if (((*pid & 0x7f) > mPayload[iv->id].maxPackId) || (MAX_PAYLOAD_ENTRIES == mPayload[iv->id].maxPackId)) { - mPayload[iv->id].maxPackId = (*pid & 0x7f); - if (*pid > 0x81) - mPayload[iv->id].lastFound = true; - } - } - } - } else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command - DPRINTLN(DBG_DEBUG, F("Response from devcontrol request received")); - - mPayload[iv->id].txId = p->packet[0]; - iv->clearDevControlRequest(); - - if ((p->packet[12] == ActivePowerContr) && (p->packet[13] == 0x00)) { - bool ok = true; - if((p->packet[10] == 0x00) && (p->packet[11] == 0x00)) { - mApp->setMqttPowerLimitAck(iv); - iv->powerLimitAck = true; - } else - ok = false; - - if (mSerialDebug) { - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINT(F(" has ")); - if(!ok) DBGPRINT(F("not ")); - DBGPRINT(F("accepted power limit set point ")); - DBGPRINT(String(iv->powerLimit[0])); - DBGPRINT(F(" with PowerLimitControl ")); - DBGPRINTLN(String(iv->powerLimit[1])); - } - - iv->clearCmdQueue(); - iv->enqueCommand(SystemConfigPara); // read back power limit - if(mHighPrioIv == NULL) // do it immediately if possible - mHighPrioIv = iv; - } - iv->devControlCmd = Init; - } - } - - void process(bool retransmit) { - for (uint8_t id = 0; id < mSys->getNumInverters(); id++) { - Inverter<> *iv = mSys->getInverterByPos(id); - if (NULL == iv) - continue; // skip to next inverter - - if ((mPayload[iv->id].txId != (TX_REQ_INFO + ALL_FRAMES)) && (0 != mPayload[iv->id].txId)) { - // no processing needed if txId is not 0x95 - mPayload[iv->id].complete = true; - continue; // skip to next inverter - } - - if (!mPayload[iv->id].complete) { - bool crcPass, pyldComplete, fastNext; - - crcPass = build(iv, &pyldComplete, &fastNext); - if (!crcPass && !pyldComplete) { // payload not complete - if ((mPayload[iv->id].requested) && (retransmit)) { - if (mPayload[iv->id].retransmits < mMaxRetrans) { - mPayload[iv->id].retransmits++; - if (iv->devControlCmd == Restart || iv->devControlCmd == CleanState_LockAndAlarm) { - // This is required to prevent retransmissions without answer. - DPRINTLN(DBG_INFO, F("Prevent retransmit on Restart / CleanState_LockAndAlarm...")); - mPayload[iv->id].retransmits = mMaxRetrans; - } else if(iv->devControlCmd == ActivePowerContr) { - DPRINT_IVID(DBG_INFO, iv->id); - DPRINTLN(DBG_INFO, F("retransmit power limit")); - mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); - } else { - if(false == mPayload[iv->id].gotFragment) { - DPRINT_IVID(DBG_WARN, iv->id); - if (mPayload[iv->id].rxTmo) { - DBGPRINTLN(F("nothing received")); - mPayload[iv->id].retransmits = mMaxRetrans; - } else { - DBGPRINTLN(F("nothing received: complete retransmit")); - mPayload[iv->id].txCmd = iv->getQueuedCmd(); - DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX)); - mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); - } - } else { - for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) { - if (mPayload[iv->id].len[i] == 0) { - if (mSerialDebug) { - DPRINT_IVID(DBG_WARN, iv->id); - DBGPRINT(F("Frame ")); - DBGPRINT(String(i + 1)); - DBGPRINTLN(F(" missing: Request Retransmit")); - } - mRadio->sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true); - break; // only request retransmit one frame per loop - } - yield(); - } - } - } - } - } else if (false == mPayload[iv->id].gotFragment) { - // only if there is no sign of life - mPayload[iv->id].rxTmo = true; // inv might be down, no complete retransmit anymore - } - } else if(!crcPass && pyldComplete) { // crc error on complete Payload - if (mPayload[iv->id].retransmits < mMaxRetrans) { - mPayload[iv->id].retransmits++; - mPayload[iv->id].txCmd = iv->getQueuedCmd(); - if (mSerialDebug) { - DPRINTLN(DBG_WARN, F("CRC Error: Request Complete Retransmit")); - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINT(F("prepareDevInformCmd 0x")); - DBGHEXLN(mPayload[iv->id].txCmd); - } - mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmLastId, true); - } - } else { // payload complete - if (mSerialDebug) { - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINT(F("procPyld: cmd: 0x")); - DBGHEXLN(mPayload[iv->id].txCmd); - //DPRINT(DBG_DEBUG, F("procPyld: txid: 0x")); - //DBGHEXLN(mPayload[iv->id].txId); - DPRINT(DBG_DEBUG, F("procPyld: max: ")); - DPRINTLN(DBG_DEBUG, String(mPayload[iv->id].maxPackId)); - } - record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser - mPayload[iv->id].complete = true; - mPayload[iv->id].requested = false; - mPayload[iv->id].rxTmo = false; - - uint8_t payload[150]; - uint8_t payloadLen = 0; - - memset(payload, 0, 150); - - int8_t rssi = -127; - - for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId); i++) { - if((mPayload[iv->id].len[i] + payloadLen) > 150) { - DPRINTLN(DBG_ERROR, F("payload buffer to small!")); - break; - } - memcpy(&payload[payloadLen], mPayload[iv->id].data[i], (mPayload[iv->id].len[i])); - payloadLen += (mPayload[iv->id].len[i]); - // get worst RSSI - if(mPayload[iv->id].rssi[i] > rssi) - rssi = mPayload[iv->id].rssi[i]; - yield(); - } - payloadLen -= 2; - - if (mSerialDebug) { - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINT(F("Payload (")); - DBGPRINT(String(payloadLen)); - DBGPRINT(F("): ")); - ah::dumpBuf(payload, payloadLen); - } - - if (NULL == rec) { - DPRINTLN(DBG_ERROR, F("record is NULL!")); - } else if ((rec->pyldLen == payloadLen) || (0 == rec->pyldLen)) { - if (mPayload[iv->id].txId == (TX_REQ_INFO + ALL_FRAMES)) - mStat->rxSuccess++; - - rec->ts = mPayload[iv->id].ts; - for (uint8_t i = 0; i < rec->length; i++) { - iv->addValue(i, payload, rec); - yield(); - } - iv->rssi = rssi; - iv->doCalculations(); - notify(mPayload[iv->id].txCmd, iv); - - if(AlarmData == mPayload[iv->id].txCmd) { - uint8_t i = 0; - while(1) { - if(0 == iv->parseAlarmLog(i++, payload, payloadLen)) - break; - if (NULL != mCbAlarm) - (mCbAlarm)(iv); - yield(); - } - } - if (fastNext && (mHighPrioIv == NULL)) { - /*iv->setQueuedCmdFinished(); - uint8_t cmd = iv->getQueuedCmd(); - if (mSerialDebug) { - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINT(F("fast mode ")); - DBGPRINT(F("prepareDevInformCmd 0x")); - DBGHEXLN(cmd); - } - mStat->rxSuccess++; - mRadio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); - mPayload[iv->id].txCmd = cmd; - */ - mHighPrioIv = iv; - } - - } else { - if (mSerialDebug) { - DPRINT(DBG_ERROR, F("plausibility check failed, expected ")); - DBGPRINT(String(rec->pyldLen)); - DBGPRINTLN(F(" bytes")); - } - mStat->rxFail++; - } - - iv->setQueuedCmdFinished(); - } - } - yield(); - } - } - - private: - void notify(uint8_t val, Inverter<> *iv) { - if(NULL != mCbPayload) - (mCbPayload)(val, iv); - } - - bool build(Inverter<> *iv, bool *complete, bool *fastNext ) { - DPRINTLN(DBG_VERBOSE, F("build")); - uint16_t crc = 0xffff, crcRcv = 0x0000; - if (mPayload[iv->id].maxPackId > MAX_PAYLOAD_ENTRIES) - mPayload[iv->id].maxPackId = MAX_PAYLOAD_ENTRIES; - - // check if all fragments are there - *complete = true; - *fastNext = false; - for (uint8_t i = 0; i < mPayload[iv->id].maxPackId; i++) { - if(mPayload[iv->id].len[i] == 0) { - *complete = false; - } - } - if(!*complete) - return false; - - for (uint8_t i = 0; i < mPayload[iv->id].maxPackId; i++) { - if (mPayload[iv->id].len[i] > 0) { - if (i == (mPayload[iv->id].maxPackId - 1)) { - crc = ah::crc16(mPayload[iv->id].data[i], mPayload[iv->id].len[i] - 2, crc); - crcRcv = (mPayload[iv->id].data[i][mPayload[iv->id].len[i] - 2] << 8) | (mPayload[iv->id].data[i][mPayload[iv->id].len[i] - 1]); - } else - crc = ah::crc16(mPayload[iv->id].data[i], mPayload[iv->id].len[i], crc); - } - yield(); - } - - //return (crc == crcRcv) ? true : false; - if (crc != crcRcv) - return false; - - //requests to cause the next request to be executed immediately - if (mPayload[iv->id].gotFragment && ((mPayload[iv->id].txCmd < 11) || (mPayload[iv->id].txCmd > 18))) { - *fastNext = true; - } - - return true; - } - - void reset(uint8_t id, bool setTxTmo = true) { - //DPRINT_IVID(DBG_INFO, id); - //DBGPRINTLN(F("resetPayload")); - memset(mPayload[id].len, 0, MAX_PAYLOAD_ENTRIES); - mPayload[id].txCmd = 0; - mPayload[id].gotFragment = false; - mPayload[id].retransmits = 0; - mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES; - mPayload[id].lastFound = false; - mPayload[id].complete = false; - mPayload[id].requested = false; - mPayload[id].ts = *mTimestamp; - mPayload[id].rxTmo = setTxTmo; // design: don't start with complete retransmit - } - - IApp *mApp; - HMSYSTEM *mSys; - RADIO *mRadio; - statistics_t *mStat; - uint8_t mMaxRetrans; - uint32_t *mTimestamp; - hmsPayload_t mPayload[MAX_NUM_INVERTERS]; - uint8_t mIvCmd56Cnt[MAX_NUM_INVERTERS]; - bool mSerialDebug; - Inverter<> *mHighPrioIv; - - alarmListenerType mCbAlarm; - payloadListenerType mCbPayload; -}; - -#endif /*__HMS_PAYLOAD_H__*/ From ded734fa8be2c1aaabfef4603cc52b3966f2d27f Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 30 Sep 2023 02:02:19 +0200 Subject: [PATCH 08/18] fix some errors --- src/app.cpp | 7 +++---- src/defines.h | 2 +- src/hm/hmSystem.h | 5 ++++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index 7ba18a8c..2454e9ea 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -120,7 +120,6 @@ void app::loop(void) { if (mNrfRadio.loop() && mConfig->nrf.enabled) { while (!mNrfRadio.mBufCtrl.empty()) { packet_t *p = &mNrfRadio.mBufCtrl.front(); - if (mConfig->serial.debug) { DPRINT(DBG_INFO, F("RX ")); DBGPRINT(String(p->len)); @@ -135,10 +134,10 @@ void app::loop(void) { Inverter<> *iv = mSys.findInverter(&p->packet[1]); if (NULL != iv) { - if (IV_HM == iv->ivGen) - mPayload.add(iv, p); - else + if (IV_MI == iv->ivGen) mMiPayload.add(iv, p); + else + mPayload.add(iv, p); } mNrfRadio.mBufCtrl.pop(); yield(); diff --git a/src/defines.h b/src/defines.h index 71766802..b7b53887 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 7 -#define VERSION_PATCH 60 +#define VERSION_PATCH 61 //------------------------------------- typedef struct { diff --git a/src/hm/hmSystem.h b/src/hm/hmSystem.h index 6c6faef6..a8ca2371 100644 --- a/src/hm/hmSystem.h +++ b/src/hm/hmSystem.h @@ -69,10 +69,13 @@ class HmSystem { } else if(iv->config->serial.u64 != 0ULL) { DPRINTLN(DBG_ERROR, F("inverter type can't be detected!")); return; - } + } else + iv->ivGen = IV_UNKNOWN; iv->init(); mNumInv ++; + if(IV_UNKNOWN == iv->ivGen) + return; // serial is 0 DPRINT(DBG_INFO, "added inverter "); if(iv->config->serial.b[5] == 0x11) { From 124cbf6ba289d88940714df34bd866d7c78c19fe Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 30 Sep 2023 02:14:35 +0200 Subject: [PATCH 09/18] bug fix esp8266 --- src/app.cpp | 11 +++++++++-- src/hm/hmInverter.h | 10 +++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index 2454e9ea..c1b9b1d0 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -64,8 +64,10 @@ void app::setup() { mSys.addInverter(i, [this](Inverter<> *iv) { if((IV_MI == iv->ivGen) || (IV_HM == iv->ivGen)) iv->radio = &mNrfRadio; + #if defined(ESP32) else if((IV_HMS == iv->ivGen) || (IV_HMT == iv->ivGen)) iv->radio = &mCmtRadio; + #endif }); } if (mConfig->nrf.enabled) { @@ -116,6 +118,7 @@ void app::setup() { //----------------------------------------------------------------------------- void app::loop(void) { ah::Scheduler::loop(); + bool processPayload = false; if (mNrfRadio.loop() && mConfig->nrf.enabled) { while (!mNrfRadio.mBufCtrl.empty()) { @@ -142,7 +145,7 @@ void app::loop(void) { mNrfRadio.mBufCtrl.pop(); yield(); } - mPayload.process(true); + processPayload = true; mMiPayload.process(true); } #if defined(ESP32) @@ -167,9 +170,13 @@ void app::loop(void) { mCmtRadio.mBufCtrl.pop(); yield(); } - mPayload.process(false); //true + processPayload = true; } #endif + + if(processPayload) + mPayload.process(true); + mPayload.loop(); mMiPayload.loop(); diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index 8cef4f2f..56c348b6 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -143,7 +143,7 @@ class Inverter { uint8_t channels; // number of PV channels (1-4) record_t recordMeas; // structure for measured values record_t recordInfo; // structure for info values - record_t recordHwInfo; // structure for simple (hardware) info values + record_t recordHwInfo; // structure for simple (hardware) info values record_t recordConfig; // structure for system config values record_t recordAlarm; // structure for alarm values bool initialized; // needed to check if the inverter was correctly added (ESP32 specific - union types are never null) @@ -169,7 +169,6 @@ class Inverter { mDevControlRequest = false; devControlCmd = InitDataState; initialized = false; - //lastAlarmMsg = "nothing"; alarmMesIndex = 0; isConnected = false; status = InverterStatus::OFF; @@ -364,9 +363,6 @@ class Inverter { } else if (rec->assign == AlarmDataAssignment) { DPRINTLN(DBG_DEBUG, "add alarm"); - //if (getPosByChFld(0, FLD_LAST_ALARM_CODE, rec) == pos){ - // lastAlarmMsg = getAlarmStr(rec->record[pos]); - //} } else DPRINTLN(DBG_WARN, F("add with unknown assignment")); @@ -499,8 +495,8 @@ class Inverter { record_t<> *getRecordStruct(uint8_t cmd) { switch (cmd) { case RealTimeRunData_Debug: return &recordMeas; // 11 = 0x0b - case InverterDevInform_Simple: return &recordHwInfo; // 0 = 0x00 - case InverterDevInform_All: return &recordInfo; // 1 = 0x01 + case InverterDevInform_Simple: return &recordHwInfo; // 0 = 0x00 + case InverterDevInform_All: return &recordInfo; // 1 = 0x01 case SystemConfigPara: return &recordConfig; // 5 = 0x05 case AlarmData: return &recordAlarm; // 17 = 0x11 default: break; From 28868a6ca61bbd3afbb3aea6771c13c0ff41fff2 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 30 Sep 2023 18:17:39 +0200 Subject: [PATCH 10/18] fix HMS only installation --- src/app.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index c1b9b1d0..56a0133b 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -70,11 +70,11 @@ void app::setup() { #endif }); } - if (mConfig->nrf.enabled) { - mPayload.setup(this, &mSys, &mNrfStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); - mPayload.enableSerialDebug(mConfig->serial.debug); - mPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1, std::placeholders::_2)); + mPayload.setup(this, &mSys, &mNrfStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); + mPayload.enableSerialDebug(mConfig->serial.debug); + mPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1, std::placeholders::_2)); + if (mConfig->nrf.enabled) { mMiPayload.setup(this, &mSys, &mNrfRadio, &mNrfStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); mMiPayload.enableSerialDebug(mConfig->serial.debug); mMiPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1, std::placeholders::_2)); @@ -431,12 +431,10 @@ void app::tickSend(void) { if (NULL != iv) { if (iv->config->enabled) { - if(mConfig->nrf.enabled) { - if(iv->ivGen == IV_MI) - mMiPayload.ivSend(iv); - else - mPayload.ivSend(iv); - } + if((iv->ivGen == IV_MI) && mConfig->nrf.enabled) + mMiPayload.ivSend(iv); + else + mPayload.ivSend(iv); } } } else { From ac0a4976d82efa5931ead5d71f1d7b8b28f08e43 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 30 Sep 2023 23:23:11 +0200 Subject: [PATCH 11/18] moved radio-statistic to inverter (not global per radio module any more) --- src/app.cpp | 8 ++++---- src/app.h | 2 +- src/hm/hmInverter.h | 5 +---- src/hm/hmPayload.h | 30 ++++++++++++++---------------- src/hm/hmRadio.h | 32 +++++++++++++++----------------- src/hm/miPayload.h | 42 ++++++++++++++++++------------------------ src/hm/radio.h | 12 ++++++++---- src/hms/hmsRadio.h | 38 ++++++++++++++++++-------------------- 8 files changed, 79 insertions(+), 90 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index 56a0133b..5666e2d7 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -34,12 +34,12 @@ void app::setup() { DBGPRINTLN(F("false")); if(mConfig->nrf.enabled) { - mNrfRadio.setup(&mNrfStat, mConfig->nrf.amplifierPower, mConfig->nrf.pinIrq, mConfig->nrf.pinCe, mConfig->nrf.pinCs, mConfig->nrf.pinSclk, mConfig->nrf.pinMosi, mConfig->nrf.pinMiso); + mNrfRadio.setup(mConfig->nrf.amplifierPower, mConfig->nrf.pinIrq, mConfig->nrf.pinCe, mConfig->nrf.pinCs, mConfig->nrf.pinSclk, mConfig->nrf.pinMosi, mConfig->nrf.pinMiso); mNrfRadio.enableDebug(); } #if defined(ESP32) if(mConfig->cmt.enabled) { - mCmtRadio.setup(&mCmtStat, mConfig->cmt.pinSclk, mConfig->cmt.pinSdio, mConfig->cmt.pinCsb, mConfig->cmt.pinFcsb, false); + mCmtRadio.setup(mConfig->cmt.pinSclk, mConfig->cmt.pinSdio, mConfig->cmt.pinCsb, mConfig->cmt.pinFcsb, false); mCmtRadio.enableDebug(); } #endif @@ -71,11 +71,11 @@ void app::setup() { }); } - mPayload.setup(this, &mSys, &mNrfStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); + mPayload.setup(this, &mSys, mConfig->nrf.maxRetransPerPyld, &mTimestamp); mPayload.enableSerialDebug(mConfig->serial.debug); mPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1, std::placeholders::_2)); if (mConfig->nrf.enabled) { - mMiPayload.setup(this, &mSys, &mNrfRadio, &mNrfStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); + mMiPayload.setup(this, &mSys, mConfig->nrf.maxRetransPerPyld, &mTimestamp); mMiPayload.enableSerialDebug(mConfig->serial.debug); mMiPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1, std::placeholders::_2)); } diff --git a/src/app.h b/src/app.h index d383157a..942848da 100644 --- a/src/app.h +++ b/src/app.h @@ -42,7 +42,7 @@ typedef HmSystem HmSystemType; typedef HmPayload PayloadType; -typedef MiPayload> MiPayloadType; +typedef MiPayload MiPayloadType; #ifdef ESP32 typedef CmtRadio CmtRadioType; #endif diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index 56c348b6..54165d81 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -25,10 +25,6 @@ * automatically. Their result does not differ from original read values. */ -// forward declaration of class -template -class Inverter; - // prototypes template @@ -155,6 +151,7 @@ class Inverter { uint16_t alarmLastId; // lastId which was received int8_t rssi; // RSSI Radio *radio; // pointer to associated radio class + statistics_t radioStatistics; // information about transmitted, failed, ... packets static uint32_t *timestamp; // system timestamp diff --git a/src/hm/hmPayload.h b/src/hm/hmPayload.h index 2f08886a..c4a63212 100644 --- a/src/hm/hmPayload.h +++ b/src/hm/hmPayload.h @@ -43,10 +43,9 @@ class HmPayload { public: HmPayload() {} - void setup(IApp *app, HMSYSTEM *sys, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) { + void setup(IApp *app, HMSYSTEM *sys, uint8_t maxRetransmits, uint32_t *timestamp) { mApp = app; mSys = sys; - mStat = stat; mMaxRetrans = maxRetransmits; mTimestamp = timestamp; for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { @@ -115,11 +114,11 @@ class HmPayload { if (mSerialDebug) DPRINT_IVID(DBG_INFO, iv->id); if (MAX_PAYLOAD_ENTRIES == mPayload[iv->id].maxPackId) { - mStat->rxFailNoAnser++; // got nothing + iv->radioStatistics.rxFailNoAnser++; // got nothing if (mSerialDebug) DBGPRINTLN(F("enqueued cmd failed/timeout")); } else { - mStat->rxFail++; // got fragments but not complete response + iv->radioStatistics.rxFail++; // got fragments but not complete response if (mSerialDebug) { DBGPRINT(F("no complete Payload received! (retransmits: ")); DBGPRINT(String(mPayload[iv->id].retransmits)); @@ -150,7 +149,7 @@ class HmPayload { DBGPRINTLN(String(iv->powerLimit[0])); } iv->powerLimitAck = false; - iv->radio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, false); + iv->radio->sendControlPacket(iv, iv->devControlCmd, iv->powerLimit, false); mPayload[iv->id].txCmd = iv->devControlCmd; //iv->clearCmdQueue(); //iv->enqueCommand(SystemConfigPara); // read back power limit @@ -159,7 +158,7 @@ class HmPayload { if((IV_HMS == iv->ivGen) || (IV_HMT == iv->ivGen)) { record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); if(((rec->ts + HMS_TIMEOUT_SEC) < *mTimestamp) && (mIvCmd56Cnt[iv->id] < 3)) { - iv->radio->switchFrequency(iv->radioId.u64, HOY_BOOT_FREQ_KHZ, WORK_FREQ_KHZ); + iv->radio->switchFrequency(iv, HOY_BOOT_FREQ_KHZ, WORK_FREQ_KHZ); mIvCmd56Cnt[iv->id]++; return; } else if(++mIvCmd56Cnt[iv->id] == 10) @@ -172,7 +171,7 @@ class HmPayload { DBGPRINT(F("prepareDevInformCmd 0x")); DBGHEXLN(cmd); } - iv->radio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); + iv->radio->prepareDevInformCmd(iv, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); mPayload[iv->id].txCmd = cmd; } } @@ -263,7 +262,7 @@ class HmPayload { } else if(iv->devControlCmd == ActivePowerContr) { DPRINT_IVID(DBG_INFO, iv->id); DPRINTLN(DBG_INFO, F("retransmit power limit")); - iv->radio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); + iv->radio->sendControlPacket(iv, iv->devControlCmd, iv->powerLimit, true); } else { if(false == mPayload[iv->id].gotFragment) { DPRINT_IVID(DBG_WARN, iv->id); @@ -274,7 +273,7 @@ class HmPayload { DBGPRINTLN(F("nothing received: complete retransmit")); mPayload[iv->id].txCmd = iv->getQueuedCmd(); DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX)); - iv->radio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); + iv->radio->prepareDevInformCmd(iv, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); } } else { for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) { @@ -285,7 +284,7 @@ class HmPayload { DBGPRINT(String(i + 1)); DBGPRINTLN(F(" missing: Request Retransmit")); } - iv->radio->sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true); + iv->radio->sendCmdPacket(iv, TX_REQ_INFO, (SINGLE_FRAME + i), true); break; // only request retransmit one frame per loop } yield(); @@ -307,7 +306,7 @@ class HmPayload { DBGPRINT(F("prepareDevInformCmd 0x")); DBGHEXLN(mPayload[iv->id].txCmd); } - iv->radio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmLastId, true); + iv->radio->prepareDevInformCmd(iv, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmLastId, true); } } else { // payload complete if (mSerialDebug) { @@ -357,7 +356,7 @@ class HmPayload { DPRINTLN(DBG_ERROR, F("record is NULL!")); } else if ((rec->pyldLen == payloadLen) || (0 == rec->pyldLen)) { if (mPayload[iv->id].txId == (TX_REQ_INFO + ALL_FRAMES)) - mStat->rxSuccess++; + iv->radioStatistics.rxSuccess++; rec->ts = mPayload[iv->id].ts; for (uint8_t i = 0; i < rec->length; i++) { @@ -387,8 +386,8 @@ class HmPayload { DBGPRINT(F("prepareDevInformCmd 0x")); DBGHEXLN(cmd); } - mStat->rxSuccess++; - iv->radio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); + iv->radioStatistics.rxSuccess++; + iv->radio->prepareDevInformCmd(iv, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); mPayload[iv->id].txCmd = cmd; */ mHighPrioIv = iv; @@ -400,7 +399,7 @@ class HmPayload { DBGPRINT(String(rec->pyldLen)); DBGPRINTLN(F(" bytes")); } - mStat->rxFail++; + iv->radioStatistics.rxFail++; } iv->setQueuedCmdFinished(); @@ -473,7 +472,6 @@ class HmPayload { IApp *mApp; HMSYSTEM *mSys; - statistics_t *mStat; uint8_t mMaxRetrans; uint32_t *mTimestamp; invPayload_t mPayload[MAX_NUM_INVERTERS]; diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index cde5cba0..3c2e6ba1 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -54,10 +54,9 @@ class HmRadio : public Radio { } ~HmRadio() {} - void setup(statistics_t *stat, uint8_t ampPwr = RF24_PA_LOW, 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(uint8_t ampPwr = RF24_PA_LOW, 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); - mStat = stat; uint32_t dtuSn = 0x87654321; uint32_t chipID = 0; // will be filled with last 3 bytes of MAC @@ -165,10 +164,10 @@ class HmRadio : public Radio { mSerialDebug = true; } - void sendControlPacket(uint64_t invId, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) { + void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) { DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x")); DBGHEXLN(cmd); - initPacket(invId, TX_REQ_DEVCONTROL, SINGLE_FRAME); + initPacket(iv->radioId.u64, TX_REQ_DEVCONTROL, SINGLE_FRAME); uint8_t cnt = 10; if (isNoMI) { mTxBuf[cnt++] = cmd; // cmd -> 0 on, 1 off, 2 restart, 11 active power, 12 reactive power, 13 power factor @@ -212,15 +211,15 @@ class HmRadio : public Radio { } cnt++; } - sendPacket(invId, cnt, isRetransmit, isNoMI); + sendPacket(iv, cnt, isRetransmit, isNoMI); } - void prepareDevInformCmd(uint64_t invId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) { // might not be necessary to add additional arg. + void prepareDevInformCmd(Inverter<> *iv, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) { // might not be necessary to add additional arg. if(mSerialDebug) { DPRINT(DBG_DEBUG, F("prepareDevInformCmd 0x")); DPRINTLN(DBG_DEBUG,String(cmd, HEX)); } - initPacket(invId, reqfld, ALL_FRAMES); + initPacket(iv->radioId.u64, reqfld, ALL_FRAMES); mTxBuf[10] = cmd; // cid mTxBuf[11] = 0x00; CP_U32_LittleEndian(&mTxBuf[12], ts); @@ -228,12 +227,12 @@ class HmRadio : public Radio { mTxBuf[18] = (alarmMesId >> 8) & 0xff; mTxBuf[19] = (alarmMesId ) & 0xff; } - sendPacket(invId, 24, isRetransmit); + sendPacket(iv, 24, isRetransmit); } - void sendCmdPacket(uint64_t invId, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) { - initPacket(invId, mid, pid); - sendPacket(invId, 10, isRetransmit, appendCrc16); + void sendCmdPacket(Inverter<> *iv, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) { + initPacket(iv->radioId.u64, mid, pid); + sendPacket(iv, 10, isRetransmit, appendCrc16); } uint8_t getDataRate(void) { @@ -293,9 +292,9 @@ class HmRadio : public Radio { mTxBuf[9] = pid; } - void sendPacket(uint64_t invId, uint8_t len, bool isRetransmit, bool appendCrc16=true) { + void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) { //DPRINTLN(DBG_VERBOSE, F("hmRadio.h:sendPacket")); - //DPRINTLN(DBG_VERBOSE, "sent packet: #" + String(mStat->txCnt)); + //DPRINTLN(DBG_VERBOSE, "sent packet: #" + String(iv->radioStatistics.txCnt)); // append crc's if (appendCrc16 && (len > 10)) { @@ -323,13 +322,13 @@ class HmRadio : public Radio { mNrf24.stopListening(); mNrf24.setChannel(mRfChLst[mTxChIdx]); - mNrf24.openWritingPipe(reinterpret_cast(&invId)); + mNrf24.openWritingPipe(reinterpret_cast(&iv->radioId.u64)); mNrf24.startWrite(mTxBuf, len, false); // false = request ACK response if(isRetransmit) - mStat->retransmits++; + iv->radioStatistics.retransmits++; else - mStat->txCnt++; + iv->radioStatistics.txCnt++; } volatile bool mIrqRcvd; @@ -342,7 +341,6 @@ class HmRadio : public Radio { SPIClass* mSpi; RF24 mNrf24; uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE]; - statistics_t *mStat; }; #endif /*__HM_RADIO_H__*/ diff --git a/src/hm/miPayload.h b/src/hm/miPayload.h index 716ea019..7288be45 100644 --- a/src/hm/miPayload.h +++ b/src/hm/miPayload.h @@ -5,8 +5,6 @@ #ifndef __MI_PAYLOAD_H__ #define __MI_PAYLOAD_H__ - -//#include "hmInverter.h" #include "../utils/dbg.h" #include "../utils/crc.h" #include "../config/config.h" @@ -35,16 +33,14 @@ typedef struct { typedef std::function *)> miPayloadListenerType; -template +template class MiPayload { public: MiPayload() {} - void setup(IApp *app, HMSYSTEM *sys, HMRADIO *radio, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) { + void setup(IApp *app, HMSYSTEM *sys, uint8_t maxRetransmits, uint32_t *timestamp) { mApp = app; mSys = sys; - mRadio = radio; - mStat = stat; mMaxRetrans = maxRetransmits; mTimestamp = timestamp; for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { @@ -89,11 +85,11 @@ class MiPayload { if (mSerialDebug) DPRINT_IVID(DBG_INFO, iv->id); if (!mPayload[iv->id].gotFragment) { - mStat->rxFailNoAnser++; // got nothing + iv->radioStatistics.rxFailNoAnser++; // got nothing if (mSerialDebug) DBGPRINTLN(F("enqueued cmd failed/timeout")); } else { - mStat->rxFail++; // got "fragments" (part of the required messages) + iv->radioStatistics.rxFail++; // got "fragments" (part of the required messages) // but no complete set of responses if (mSerialDebug) { DBGPRINT(F("no complete Payload received! (retransmits: ")); @@ -127,7 +123,7 @@ class MiPayload { DBGPRINTLN(String(iv->powerLimit[0])); } iv->powerLimitAck = false; - mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, false, false, iv->type == INV_TYPE_4CH); + iv->radio->sendControlPacket(iv, iv->devControlCmd, iv->powerLimit, false, false, iv->type == INV_TYPE_4CH); mPayload[iv->id].txCmd = iv->devControlCmd; mPayload[iv->id].limitrequested = true; @@ -153,7 +149,7 @@ class MiPayload { DBGPRINT(F("prepareDevInformCmd 0x")); DBGHEXLN(cmd); } - mRadio->sendCmdPacket(iv->radioId.u64, cmd, cmd2, false, false); + iv->radio->sendCmdPacket(iv, cmd, cmd2, false, false); mPayload[iv->id].txCmd = cmd; if (iv->type == INV_TYPE_1CH || iv->type == INV_TYPE_2CH) { @@ -262,7 +258,7 @@ class MiPayload { DPRINTLN(DBG_ERROR, F("record is NULL!")); } else if ((rec->pyldLen == payloadLen) || (0 == rec->pyldLen)) { if (mPayload[iv->id].txId == (TX_REQ_INFO + ALL_FRAMES)) - mStat->rxSuccess++; + iv->radioStatistics.rxSuccess++; rec->ts = mPayload[iv->id].ts; for (uint8_t i = 0; i < rec->length; i++) { @@ -284,7 +280,7 @@ class MiPayload { } } else { DPRINTLN(DBG_ERROR, F("plausibility check failed, expected ") + String(rec->pyldLen) + F(" bytes")); - mStat->rxFail++; + iv->radioStatistics.rxFail++; } iv->setQueuedCmdFinished(); @@ -330,7 +326,7 @@ class MiPayload { } else if(iv->devControlCmd == ActivePowerContr) { DPRINT_IVID(DBG_INFO, iv->id); DBGPRINTLN(F("retransmit power limit")); - mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true, false); + iv->radio->sendControlPacket(iv, iv->devControlCmd, iv->powerLimit, true, false); } else { uint8_t cmd = mPayload[iv->id].txCmd; if (mPayload[iv->id].retransmits < mMaxRetrans) { @@ -343,10 +339,10 @@ class MiPayload { DPRINT_IVID(DBG_INFO, iv->id); DBGPRINTLN(F("retransmit on failed first request")); mPayload[iv->id].rxTmo = true; - mRadio->sendCmdPacket(iv->radioId.u64, cmd, cmd, true, false); + iv->radio->sendCmdPacket(iv, cmd, cmd, true, false); } else if ( cmd == 0x0f ) { //hard/firmware request - mRadio->sendCmdPacket(iv->radioId.u64, 0x0f, 0x00, true, false); + iv->radio->sendCmdPacket(iv, 0x0f, 0x00, true, false); mPayload[id].multi_parts = 0; } else { bool change = false; @@ -384,7 +380,7 @@ class MiPayload { DBGPRINT(F(" 0x")); DBGHEXLN(cmd); mPayload[id].multi_parts = 0; - mRadio->sendCmdPacket(iv->radioId.u64, cmd, cmd, true, false); + iv->radio->sendCmdPacket(iv, cmd, cmd, true, false); yield(); } } else { @@ -404,7 +400,7 @@ class MiPayload { DBGPRINT(F("prepareDevInformCmd 0x")); DBGHEXLN(mPayload[iv->id].txCmd); } - mRadio->sendCmdPacket(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].txCmd, false, false); + iv->radio->sendCmdPacket(iv, mPayload[iv->id].txCmd, mPayload[iv->id].txCmd, false, false); } else { mPayload[iv->id].rxTmo = true; } @@ -420,9 +416,9 @@ class MiPayload { DBGPRINT(F("prepareDevInformCmd 0x")); DBGHEXLN(cmd); } - mStat->rxSuccess++; - //mRadio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false); - mRadio->prepareDevInformCmd(iv->radioId.u64, iv->getType(), + iv->radioStatistics.rxSuccess++; + //iv->radio->prepareDevInformCmd(iv, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false); + iv->radio->prepareDevInformCmd(iv, iv->getType(), iv->getNextTxChanIndex(), cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false); mPayload[iv->id].txCmd = cmd; */ if (mHighPrioIv == NULL) @@ -600,7 +596,7 @@ class MiPayload { iv->isProducing(); iv->setQueuedCmdFinished(); - mStat->rxSuccess++; + iv->radioStatistics.rxSuccess++; yield(); notify(RealTimeRunData_Debug, iv); } @@ -756,7 +752,7 @@ const byteAssign_t InfoAssignment[] = { mPayload[iv->id].complete = true; mPayload[iv->id].rxTmo = true; mPayload[iv->id].requested= false; - mStat->rxSuccess++; + iv->radioStatistics.rxSuccess++; } } @@ -789,8 +785,6 @@ const byteAssign_t InfoAssignment[] = { IApp *mApp; HMSYSTEM *mSys; - HMRADIO *mRadio; - statistics_t *mStat; uint8_t mMaxRetrans; uint32_t *mTimestamp; miPayload_t mPayload[MAX_NUM_INVERTERS]; diff --git a/src/hm/radio.h b/src/hm/radio.h index 9f026add..1cefa176 100644 --- a/src/hm/radio.h +++ b/src/hm/radio.h @@ -11,13 +11,17 @@ #define ALL_FRAMES 0x80 #define SINGLE_FRAME 0x81 +// forward declaration of class +template +class Inverter; + // abstract radio interface class Radio { public: - virtual void sendControlPacket(uint64_t invId, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) = 0; - virtual void prepareDevInformCmd(uint64_t invId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) = 0; - virtual void sendCmdPacket(uint64_t invId, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) = 0; - virtual bool switchFrequency(uint64_t ivId, uint32_t fromkHz, uint32_t tokHz) { return true; } + virtual void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) = 0; + virtual void prepareDevInformCmd(Inverter<> *iv, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) = 0; + virtual void sendCmdPacket(Inverter<> *iv, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) = 0; + virtual bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) { return true; } }; #endif /*__RADIO_H__*/ diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index c8cf480c..b26552c8 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -20,9 +20,8 @@ class CmtRadio : public Radio { mCmtAvail = false; } - void setup(statistics_t *stat, uint8_t pinSclk, uint8_t pinSdio, uint8_t pinCsb, uint8_t pinFcsb, bool genDtuSn = true) { + void setup(uint8_t pinSclk, uint8_t pinSdio, uint8_t pinCsb, uint8_t pinFcsb, bool genDtuSn = true) { mCmt.setup(pinSclk, pinSdio, pinCsb, pinFcsb); - mStat = stat; reset(genDtuSn); } @@ -60,10 +59,10 @@ class CmtRadio : public Radio { return mCmtAvail; } - void sendControlPacket(uint64_t ivId, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) { + void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) { DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x")); DBGHEXLN(cmd); - initPacket(ivId, TX_REQ_DEVCONTROL, SINGLE_FRAME); + initPacket(iv->radioId.u64, TX_REQ_DEVCONTROL, SINGLE_FRAME); uint8_t cnt = 10; mTxBuf[cnt++] = cmd; // cmd -> 0 on, 1 off, 2 restart, 11 active power, 12 reactive power, 13 power factor @@ -75,10 +74,10 @@ class CmtRadio : public Radio { mTxBuf[cnt++] = ((data[1] ) ) & 0xff; // setting for persistens handling } - sendPacket(cnt, isRetransmit); + sendPacket(iv, cnt, isRetransmit); } - bool switchFrequency(uint64_t ivId, uint32_t fromkHz, uint32_t tokHz) { + bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) { uint8_t fromCh = mCmt.freq2Chan(fromkHz); uint8_t toCh = mCmt.freq2Chan(tokHz); @@ -86,28 +85,28 @@ class CmtRadio : public Radio { return false; mCmt.switchChannel(fromCh); - sendSwitchChCmd(ivId, toCh); + sendSwitchChCmd(iv, toCh); mCmt.switchChannel(toCh); return true; } - void prepareDevInformCmd(uint64_t ivId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) { // might not be necessary to add additional arg. - initPacket(ivId, reqfld, ALL_FRAMES); + void prepareDevInformCmd(Inverter<> *iv, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) { // might not be necessary to add additional arg. + initPacket(iv->radioId.u64, reqfld, ALL_FRAMES); mTxBuf[10] = cmd; CP_U32_LittleEndian(&mTxBuf[12], ts); if (cmd == AlarmData ) { //cmd == RealTimeRunData_Debug || mTxBuf[18] = (alarmMesId >> 8) & 0xff; mTxBuf[19] = (alarmMesId ) & 0xff; } - sendPacket(24, isRetransmit); + sendPacket(iv, 24, isRetransmit); } - void sendCmdPacket(uint64_t ivId, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) { - initPacket(ivId, mid, pid); - sendPacket(10, isRetransmit); + void sendCmdPacket(Inverter<> *iv, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) { + initPacket(iv->radioId.u64, mid, pid); + sendPacket(iv, 10, isRetransmit); } - void sendPacket(uint8_t len, bool isRetransmit) { + void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit) { if (len > 14) { uint16_t crc = ah::crc16(&mTxBuf[10], len - 10); mTxBuf[len++] = (crc >> 8) & 0xff; @@ -132,9 +131,9 @@ class CmtRadio : public Radio { } if(isRetransmit) - mStat->retransmits++; + iv->radioStatistics.retransmits++; else - mStat->txCnt++; + iv->radioStatistics.txCnt++; } std::queue mBufCtrl; @@ -156,7 +155,7 @@ class CmtRadio : public Radio { mRqstGetRx = false; } - inline void sendSwitchChCmd(uint64_t ivId, uint8_t ch) { + inline void sendSwitchChCmd(Inverter<> *iv, uint8_t ch) { /** ch: * 0x00: 860.00 MHz * 0x01: 860.25 MHz @@ -166,12 +165,12 @@ class CmtRadio : public Radio { * ... * 0x28: 870.00 MHz * */ - initPacket(ivId, 0x56, 0x02); + initPacket(iv->radioId.u64, 0x56, 0x02); mTxBuf[10] = 0x15; mTxBuf[11] = 0x21; mTxBuf[12] = ch; mTxBuf[13] = 0x14; - sendPacket(14, false); + sendPacket(iv, 14, false); mRqstGetRx = true; } @@ -210,7 +209,6 @@ class CmtRadio : public Radio { bool mIrqRcvd; bool mRqstGetRx; bool mCmtAvail; - statistics_t *mStat; }; #endif /*__HMS_RADIO_H__*/ From c3162fd2eda970d363fdeae05d9d2a386d004316 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 30 Sep 2023 23:40:31 +0200 Subject: [PATCH 12/18] update web, moved radio statistics to live view (footer of inverter) as modal --- src/web/RestApi.h | 30 ++++++++++------------- src/web/html/api.js | 9 +++++++ src/web/html/system.html | 22 ----------------- src/web/html/visualization.html | 43 +++++++++++++++++---------------- 4 files changed, 44 insertions(+), 60 deletions(-) diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 871c9ca7..acfddbb2 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -107,6 +107,8 @@ class RestApi { getIvAlarms(root, request->url().substring(20).toInt()); else if(path.substring(0, 17) == "inverter/version/") getIvVersion(root, request->url().substring(22).toInt()); + else if(path.substring(0, 17) == "inverter/radiostat/") + getIvStatistis(root, request->url().substring(24).toInt()); else getNotFound(root, F("http://") + request->host() + F("/api/")); } @@ -245,7 +247,6 @@ class RestApi { getRadioCmtInfo(obj.createNestedObject(F("radioCmt"))); #endif getMqttInfo(obj.createNestedObject(F("mqtt"))); - getStatistics(obj.createNestedArray(F("statistics"))); #if defined(ESP32) obj[F("chip_revision")] = ESP.getChipRevision(); @@ -310,23 +311,18 @@ class RestApi { obj[F("html")] = F("reboot. Autoreload after 10 seconds"); } - void getStatistics(JsonArray arr) { - statistics_t *stat; - #if defined(ESP32) - for(uint8_t i = 0; i < 2; i++) { - stat = (0 == i) ? mApp->getNrfStatistics() : mApp->getCmtStatistics(); - #else - { - stat = mApp->getNrfStatistics(); - #endif - JsonObject obj = arr.createNestedObject(); - obj[F("rx_success")] = stat->rxSuccess; - obj[F("rx_fail")] = stat->rxFail; - obj[F("rx_fail_answer")] = stat->rxFailNoAnser; - obj[F("frame_cnt")] = stat->frmCnt; - obj[F("tx_cnt")] = stat->txCnt; - obj[F("retransmits")] = stat->retransmits; + void getIvStatistis(JsonObject obj, uint8_t id) { + Inverter<> *iv = mSys->getInverterByPos(id); + if(NULL == iv) { + obj[F("error")] = F("inverter not found!"); + return; } + obj[F("rx_success")] = iv->radioStatistics.rxSuccess; + obj[F("rx_fail")] = iv->radioStatistics.rxFail; + obj[F("rx_fail_answer")] = iv->radioStatistics.rxFailNoAnser; + obj[F("frame_cnt")] = iv->radioStatistics.frmCnt; + obj[F("tx_cnt")] = iv->radioStatistics.txCnt; + obj[F("retransmits")] = iv->radioStatistics.retransmits; } void getInverterList(JsonObject obj) { diff --git a/src/web/html/api.js b/src/web/html/api.js index 82405a71..c9590d89 100644 --- a/src/web/html/api.js +++ b/src/web/html/api.js @@ -172,6 +172,15 @@ function getAjax(url, ptr, method="GET", json=null) { * CREATE DOM FUNCTIONS */ +function tr(val1, val2) { + if(typeof val2 == "number") + val2 = String(val2); + return ml("tr", {}, [ + ml("th", {style: "width: 50%"}, val1), + ml("td", {}, val2) + ]); +} + function des(val) { e = document.createElement('p'); e.classList.add("subdes"); diff --git a/src/web/html/system.html b/src/web/html/system.html index 071ddb1d..27ad1801 100644 --- a/src/web/html/system.html +++ b/src/web/html/system.html @@ -48,26 +48,6 @@ return ml("div", {class: "head p-2 mt-3"}, ml("div", {class: "row"}, ml("div", {class: "col a-c"}, text))) } - function tr(val1, val2) { - if(typeof val2 == "number") - val2 = String(val2); - return ml("tr", {}, [ - ml("th", {style: "width: 50%"}, val1), - ml("td", {}, val2) - ]); - } - - function parseStat(stat) { - return [ - tr("TX count", stat.tx_cnt), - tr("RX success", stat.rx_success), - tr("RX fail", stat.rx_fail), - tr("RX no answer", stat.rx_fail_answer), - tr("RX fragments", stat.frame_cnt), - tr("TX retransmits", stat.retransmits) - ]; - } - function parseRadio(obj) { const pa = ["MIN (recommended)", "LOW", "HIGH", "MAX"]; const dr = ["1 M", "2 M", "250 k"] @@ -78,7 +58,6 @@ tr("NRF24 Power Level", pa[obj.radioNrf.power_level]), tr("NRF24 Data Rate", dr[obj.radioNrf.dataRate] + "bps") ]; - Array.prototype.push.apply(lines, parseStat(obj.statistics[0])); } else lines = [tr("NRF24L01", badge(false, "not enabled"))]; @@ -92,7 +71,6 @@ /*IF_ESP32*/ if(obj.radioCmt.en) { cmt = [tr("CMT2300A", badge(obj.radioCmt.isconnected, ((obj.radioCmt.isconnected) ? "" : "not ") + "connected"))]; - Array.prototype.push.apply(cmt, parseStat(obj.statistics[1])); } else cmt = [tr("CMT2300A", badge(false, "not enabled"))]; diff --git a/src/web/html/visualization.html b/src/web/html/visualization.html index b4119450..48d34211 100644 --- a/src/web/html/visualization.html +++ b/src/web/html/visualization.html @@ -198,7 +198,9 @@ ml("div", {class: "col"}, "") ), ml("div", {class: "row p-2 ts-bg mx-2"}, - ml("div", {class: "col mx-2"}, ageInfo) + ml("div", { class: "pointer col mx-2", onclick: function() { + getAjax("/api/inverter/radiostat/" + obj.id, parseIvRadioStats); + }}, ageInfo) ) ]); } @@ -279,26 +281,25 @@ var html = ml("table", {class: "table"}, [ ml("tbody", {}, [ - ml("tr", {}, [ - ml("th", {}, "Model"), - ml("td", {}, model) - ]), - ml("tr", {}, [ - ml("th", {}, "Firmware Version / Build"), - ml("td", {}, String(obj.fw_ver) + " (build: " + String(obj.fw_date) + " " + String(obj.fw_time) + ")") - ]), - ml("tr", {}, [ - ml("th", {}, "Hardware Version / Build"), - ml("td", {}, (obj.hw_ver/100).toFixed(2) + " (build: " + String(obj.prod_cw) + "/" + String(obj.prod_year) + ")") - ]), - ml("tr", {}, [ - ml("th", {}, "Hardware Number"), - ml("td", {}, obj.part_num.toString(16)) - ]), - ml("tr", {}, [ - ml("th", {}, "Bootloader Version"), - ml("td", {}, (obj.boot_ver/100).toFixed(2)) - ]) + tr("Model", model), + tr("Firmware Version / Build", String(obj.fw_ver) + " (build: " + String(obj.fw_date) + " " + String(obj.fw_time) + ")"), + tr("Hardware Version / Build", (obj.hw_ver/100).toFixed(2) + " (build: " + String(obj.prod_cw) + "/" + String(obj.prod_year) + ")"), + tr("Hardware Number", obj.part_num.toString(16)), + tr("Bootloader Version", (obj.boot_ver/100).toFixed(2)) + ]) + ]); + modal("Info for inverter " + obj.name, ml("div", {}, html)); + } + + function parseIvRadioStats(obj) { + var html = ml("table", {class: "table"}, [ + ml("tbody", {}, [ + tr("TX count", obj.tx_cnt), + tr("RX success", obj.rx_success), + tr("RX fail", obj.rx_fail), + tr("RX no answer", obj.rx_fail_answer), + tr("RX fragments", obj.frame_cnt), + tr("TX retransmits", obj.retransmits) ]) ]); modal("Info for inverter " + obj.name, ml("div", {}, html)); From 097dd3c39cee9a5285bcd21bd4518bc08cf0d04a Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 30 Sep 2023 23:58:38 +0200 Subject: [PATCH 13/18] fix web --- src/hm/hmPayload.h | 7 ++++--- src/hm/miPayload.h | 23 ++++++++++------------- src/web/RestApi.h | 3 ++- src/web/html/visualization.html | 18 +++++++++--------- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/hm/hmPayload.h b/src/hm/hmPayload.h index c4a63212..1f6e0468 100644 --- a/src/hm/hmPayload.h +++ b/src/hm/hmPayload.h @@ -72,7 +72,7 @@ class HmPayload { void loop() { if (NULL != mHighPrioIv) { - ivSend(mHighPrioIv, true); + ivSend(mHighPrioIv, true); // for e.g. devcontrol commands mHighPrioIv = NULL; } } @@ -144,7 +144,7 @@ class HmPayload { if (mSerialDebug) { DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("Devcontrol request 0x")); - DBGPRINT(String(iv->devControlCmd, HEX)); + DHEX(iv->devControlCmd); DBGPRINT(F(" power limit ")); DBGPRINTLN(String(iv->powerLimit[0])); } @@ -301,7 +301,8 @@ class HmPayload { mPayload[iv->id].retransmits++; mPayload[iv->id].txCmd = iv->getQueuedCmd(); if (mSerialDebug) { - DPRINTLN(DBG_WARN, F("CRC Error: Request Complete Retransmit")); + DPRINT_IVID(DBG_WARN, iv->id); + DBGPRINTLN(F("CRC Error: Request Complete Retransmit")); DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("prepareDevInformCmd 0x")); DBGHEXLN(mPayload[iv->id].txCmd); diff --git a/src/hm/miPayload.h b/src/hm/miPayload.h index 7288be45..6273d571 100644 --- a/src/hm/miPayload.h +++ b/src/hm/miPayload.h @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // 2023 Ahoy, https://ahoydtu.de -// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ +// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed //----------------------------------------------------------------------------- #ifndef __MI_PAYLOAD_H__ @@ -49,7 +49,7 @@ class MiPayload { } mSerialDebug = false; mHighPrioIv = NULL; - mCbMiPayload = NULL; + mCbPayload = NULL; } void enableSerialDebug(bool enable) { @@ -57,7 +57,7 @@ class MiPayload { } void addPayloadListener(miPayloadListenerType cb) { - mCbMiPayload = cb; + mCbPayload = cb; } void addAlarmListener(alarmListenerType cb) { @@ -108,7 +108,7 @@ class MiPayload { mPayload[iv->id].requested = true; yield(); - if (mSerialDebug){ + if (mSerialDebug) { DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("Requesting Inv SN ")); DBGPRINTLN(String(iv->config->serial.u64, HEX)); @@ -434,8 +434,8 @@ class MiPayload { private: void notify(uint8_t val, Inverter<> *iv) { - if(NULL != mCbMiPayload) - (mCbMiPayload)(val, iv); + if(NULL != mCbPayload) + (mCbPayload)(val, iv); } void miStsDecode(Inverter<> *iv, packet_t *p, uint8_t stschan = CH1) { @@ -506,14 +506,11 @@ class MiPayload { } /*if(AlarmData == mPayload[iv->id].txCmd) { uint8_t i = 0; - uint16_t code; - uint32_t start, end; while(1) { - code = iv->parseAlarmLog(i++, payload, payloadLen, &start, &end); - if(0 == code) + if(0 == iv->parseAlarmLog(i++, payload, payloadLen)) break; if (NULL != mCbAlarm) - (mCbAlarm)(code, start, end); + (mCbAlarm)(iv); yield(); } }*/ @@ -789,10 +786,10 @@ const byteAssign_t InfoAssignment[] = { uint32_t *mTimestamp; miPayload_t mPayload[MAX_NUM_INVERTERS]; bool mSerialDebug; - Inverter<> *mHighPrioIv; + alarmListenerType mCbAlarm; - payloadListenerType mCbMiPayload; + payloadListenerType mCbPayload; }; #endif /*__MI_PAYLOAD_H__*/ diff --git a/src/web/RestApi.h b/src/web/RestApi.h index acfddbb2..a8843306 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -107,7 +107,7 @@ class RestApi { getIvAlarms(root, request->url().substring(20).toInt()); else if(path.substring(0, 17) == "inverter/version/") getIvVersion(root, request->url().substring(22).toInt()); - else if(path.substring(0, 17) == "inverter/radiostat/") + else if(path.substring(0, 19) == "inverter/radiostat/") getIvStatistis(root, request->url().substring(24).toInt()); else getNotFound(root, F("http://") + request->host() + F("/api/")); @@ -317,6 +317,7 @@ class RestApi { obj[F("error")] = F("inverter not found!"); return; } + obj[F("name")] = String(iv->config->name); obj[F("rx_success")] = iv->radioStatistics.rxSuccess; obj[F("rx_fail")] = iv->radioStatistics.rxFail; obj[F("rx_fail_answer")] = iv->radioStatistics.rxFailNoAnser; diff --git a/src/web/html/visualization.html b/src/web/html/visualization.html index 48d34211..d790147c 100644 --- a/src/web/html/visualization.html +++ b/src/web/html/visualization.html @@ -177,20 +177,20 @@ ]); } - function tsInfo(ts, gen, rssi) { + function tsInfo(obj) { var ageInfo = "Last received data requested at: "; - if(ts > 0) { - var date = new Date(ts * 1000); + if(obj.ts_last_success > 0) { + var date = new Date(obj.ts_last_success * 1000); ageInfo += toIsoDateStr(date); } else ageInfo += "nothing received"; - if(rssi > -127) { - if(gen < 2) - ageInfo += " (RSSI: " + ((rssi == -64) ? ">=" : "<") + " -64dBm)"; + if(obj.rssi > -127) { + if(obj.generation < 2) + ageInfo += " (RSSI: " + ((obj.rssi == -64) ? ">=" : "<") + " -64dBm)"; else - ageInfo += " (RSSI: " + rssi + "dBm)"; + ageInfo += " (RSSI: " + obj.rssi + "dBm)"; } return ml("div", {class: "mb-5"}, [ @@ -220,7 +220,7 @@ ml("div", {}, [ ivHead(obj), ml("div", {class: "row mb-2"}, chn), - tsInfo(obj.ts_last_success, obj.generation, obj.rssi) + tsInfo(obj) ]) ); @@ -302,7 +302,7 @@ tr("TX retransmits", obj.retransmits) ]) ]); - modal("Info for inverter " + obj.name, ml("div", {}, html)); + modal("Radio statistics for inverter " + obj.name, ml("div", {}, html)); } function parse(obj) { From 01f113cd2b98473aa99427d9155c8819243f78c5 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 1 Oct 2023 00:15:50 +0200 Subject: [PATCH 14/18] moved some generic functions to parent radio class --- src/hm/hmRadio.h | 41 +++++------------------------------------ src/hm/radio.h | 28 ++++++++++++++++++++++++++++ src/hms/hmsRadio.h | 23 ----------------------- 3 files changed, 33 insertions(+), 59 deletions(-) diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index 3c2e6ba1..96e38fac 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -23,7 +23,7 @@ const char* const rf24AmpPowerNames[] = {"MIN", "LOW", "HIGH", "MAX"}; //----------------------------------------------------------------------------- // HM Radio class //----------------------------------------------------------------------------- -template +template class HmRadio : public Radio { public: HmRadio() : mNrf24(CE_PIN, CS_PIN, SPI_SPEED) { @@ -36,6 +36,7 @@ class HmRadio : public Radio { DBGPRINT(String(SPI_SPEED)); DBGPRINTLN(F(")")); } + mDtuSn = DTU_SN; // Depending on the program, the module can work on 2403, 2423, 2440, 2461 or 2475MHz. // Channel List 2403, 2423, 2440, 2461, 2475MHz @@ -58,23 +59,7 @@ class HmRadio : public Radio { DPRINTLN(DBG_VERBOSE, F("hmRadio.h:setup")); pinMode(irq, INPUT_PULLUP); - uint32_t dtuSn = 0x87654321; - uint32_t chipID = 0; // will be filled with last 3 bytes of MAC - #ifdef ESP32 - uint64_t MAC = ESP.getEfuseMac(); - chipID = ((MAC >> 8) & 0xFF0000) | ((MAC >> 24) & 0xFF00) | ((MAC >> 40) & 0xFF); - #else - chipID = ESP.getChipId(); - #endif - if(chipID) { - dtuSn = 0x80000000; // the first digit is an 8 for DTU production year 2022, the rest is filled with the ESP chipID in decimal - for(int i = 0; i < 7; i++) { - dtuSn |= (chipID % 10) << (i * 4); - chipID /= 10; - } - } - // 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; + generateDtuSn(); #ifdef ESP32 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 @@ -99,7 +84,7 @@ class HmRadio : public Radio { mNrf24.enableDynamicPayloads(); mNrf24.setCRCLength(RF24_CRC_16); mNrf24.setAddressWidth(5); - mNrf24.openReadingPipe(1, reinterpret_cast(&DTU_RADIO_ID)); + mNrf24.openReadingPipe(1, reinterpret_cast(&mDtuSn)); // enable all receiving interrupts mNrf24.maskIRQ(false, false, false); @@ -112,7 +97,7 @@ class HmRadio : public Radio { DPRINTLN(DBG_INFO, F("Radio Config:")); mNrf24.printPrettyDetails(); DPRINT(DBG_INFO, F("DTU_SN: 0x")); - DBGPRINTLN(String(DTU_RADIO_ID, HEX)); + DBGPRINTLN(String(mDtuSn, HEX)); } else DPRINTLN(DBG_WARN, F("WARNING! your NRF24 module can't be reached, check the wiring")); } @@ -278,20 +263,6 @@ class HmRadio : public Radio { return isLastPackage; } - void initPacket(uint64_t invId, uint8_t mid, uint8_t pid) { - if(mSerialDebug) { - DPRINT(DBG_VERBOSE, F("initPacket, mid: ")); - DPRINT(DBG_VERBOSE, String(mid, HEX)); - DPRINT(DBG_VERBOSE,F(" pid: ")); - DPRINTLN(DBG_VERBOSE,String(pid, HEX)); - } - memset(mTxBuf, 0, MAX_RF_PAYLOAD_SIZE); - mTxBuf[0] = mid; // message id - CP_U32_BigEndian(&mTxBuf[1], (invId >> 8)); - CP_U32_BigEndian(&mTxBuf[5], (DTU_RADIO_ID >> 8)); - mTxBuf[9] = pid; - } - void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) { //DPRINTLN(DBG_VERBOSE, F("hmRadio.h:sendPacket")); //DPRINTLN(DBG_VERBOSE, "sent packet: #" + String(iv->radioStatistics.txCnt)); @@ -332,7 +303,6 @@ class HmRadio : public Radio { } volatile bool mIrqRcvd; - uint64_t DTU_RADIO_ID; uint8_t mRfChLst[RF_CHANNELS]; uint8_t mTxChIdx; @@ -340,7 +310,6 @@ class HmRadio : public Radio { SPIClass* mSpi; RF24 mNrf24; - uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE]; }; #endif /*__HM_RADIO_H__*/ diff --git a/src/hm/radio.h b/src/hm/radio.h index 1cefa176..4247fa72 100644 --- a/src/hm/radio.h +++ b/src/hm/radio.h @@ -22,6 +22,34 @@ class Radio { virtual void prepareDevInformCmd(Inverter<> *iv, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) = 0; virtual void sendCmdPacket(Inverter<> *iv, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) = 0; virtual bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) { return true; } + + protected: + void initPacket(uint64_t ivId, uint8_t mid, uint8_t pid) { + mTxBuf[0] = mid; + CP_U32_BigEndian(&mTxBuf[1], ivId >> 8); + CP_U32_LittleEndian(&mTxBuf[5], mDtuSn); + mTxBuf[9] = pid; + memset(&mTxBuf[10], 0x00, (MAX_RF_PAYLOAD_SIZE-10)); + } + + void generateDtuSn(void) { + uint32_t chipID = 0; + #ifdef ESP32 + uint64_t MAC = ESP.getEfuseMac(); + chipID = ((MAC >> 8) & 0xFF0000) | ((MAC >> 24) & 0xFF00) | ((MAC >> 40) & 0xFF); + #else + chipID = ESP.getChipId(); + #endif + mDtuSn = 0x80000000; // the first digit is an 8 for DTU production year 2022, the rest is filled with the ESP chipID in decimal + for(int i = 0; i < 7; i++) { + mDtuSn |= (chipID % 10) << (i * 4); + chipID /= 10; + } + } + + uint32_t mDtuSn; + uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE]; + }; #endif /*__RADIO_H__*/ diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index b26552c8..1c26cb91 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -174,27 +174,6 @@ class CmtRadio : public Radio { mRqstGetRx = true; } - void initPacket(uint64_t ivId, uint8_t mid, uint8_t pid) { - mTxBuf[0] = mid; - CP_U32_BigEndian(&mTxBuf[1], ivId >> 8); - CP_U32_LittleEndian(&mTxBuf[5], mDtuSn); - mTxBuf[9] = pid; - memset(&mTxBuf[10], 0x00, 17); - } - - inline void generateDtuSn(void) { - uint32_t chipID = 0; - #ifdef ESP32 - uint64_t MAC = ESP.getEfuseMac(); - chipID = ((MAC >> 8) & 0xFF0000) | ((MAC >> 24) & 0xFF00) | ((MAC >> 40) & 0xFF); - #endif - mDtuSn = 0x80000000; // the first digit is an 8 for DTU production year 2022, the rest is filled with the ESP chipID in decimal - for(int i = 0; i < 7; i++) { - mDtuSn |= (chipID % 10) << (i * 4); - chipID /= 10; - } - } - inline void getRx(void) { packet_t p; uint8_t status = mCmt.getRx(p.packet, &p.len, 28, &p.rssi); @@ -203,8 +182,6 @@ class CmtRadio : public Radio { } CmtType mCmt; - uint32_t mDtuSn; - uint8_t mTxBuf[27]; bool mSerialDebug; bool mIrqRcvd; bool mRqstGetRx; From 86822eb7b84cf34060abf4437f1d90b1b579f42f Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 1 Oct 2023 00:39:22 +0200 Subject: [PATCH 15/18] further improvements to generic functions --- src/app.cpp | 4 ---- src/hm/hmRadio.h | 50 ++++----------------------------------------- src/hm/radio.h | 51 ++++++++++++++++++++++++++++++++++++++++++++-- src/hms/hmsRadio.h | 46 +++++++---------------------------------- 4 files changed, 60 insertions(+), 91 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index 5666e2d7..a58ae877 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -191,10 +191,6 @@ void app::onNetwork(bool gotIp) { ah::Scheduler::resetTicker(); regularTickers(); //reinstall regular tickers every(std::bind(&app::tickSend, this), mConfig->nrf.sendInterval, "tSend"); - #if defined(ESP32) - if(mConfig->cmt.enabled) - everySec(std::bind(&CmtRadioType::tickSecond, &mCmtRadio), "tsCmt"); - #endif mMqttReconnect = true; mSunrise = 0; // needs to be set to 0, to reinstall sunrise and ivComm tickers! //once(std::bind(&app::tickNtpUpdate, this), 2, "ntp2"); diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index 96e38fac..a808bd88 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -6,10 +6,7 @@ #ifndef __HM_RADIO_H__ #define __HM_RADIO_H__ -#include "../utils/dbg.h" #include -#include "../utils/crc.h" -#include "../config/config.h" #include "SPI.h" #include "radio.h" @@ -137,17 +134,10 @@ class HmRadio : public Radio { return true; } - void handleIntr(void) { - mIrqRcvd = true; - } - bool isChipConnected(void) { //DPRINTLN(DBG_VERBOSE, F("hmRadio.h:isChipConnected")); return mNrf24.isChipConnected(); } - void enableDebug() { - mSerialDebug = true; - } void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) { DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x")); @@ -199,27 +189,6 @@ class HmRadio : public Radio { sendPacket(iv, cnt, isRetransmit, isNoMI); } - void prepareDevInformCmd(Inverter<> *iv, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) { // might not be necessary to add additional arg. - if(mSerialDebug) { - DPRINT(DBG_DEBUG, F("prepareDevInformCmd 0x")); - DPRINTLN(DBG_DEBUG,String(cmd, HEX)); - } - initPacket(iv->radioId.u64, reqfld, ALL_FRAMES); - mTxBuf[10] = cmd; // cid - mTxBuf[11] = 0x00; - CP_U32_LittleEndian(&mTxBuf[12], ts); - if (cmd == AlarmData ) { //cmd == RealTimeRunData_Debug || - mTxBuf[18] = (alarmMesId >> 8) & 0xff; - mTxBuf[19] = (alarmMesId ) & 0xff; - } - sendPacket(iv, 24, isRetransmit); - } - - void sendCmdPacket(Inverter<> *iv, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) { - initPacket(iv->radioId.u64, mid, pid); - sendPacket(iv, 10, isRetransmit, appendCrc16); - } - uint8_t getDataRate(void) { if(!mNrf24.isChipConnected()) return 3; // unknown @@ -231,7 +200,6 @@ class HmRadio : public Radio { } std::queue mBufCtrl; - bool mSerialDebug; private: bool getReceived(void) { @@ -264,19 +232,7 @@ class HmRadio : public Radio { } void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) { - //DPRINTLN(DBG_VERBOSE, F("hmRadio.h:sendPacket")); - //DPRINTLN(DBG_VERBOSE, "sent packet: #" + String(iv->radioStatistics.txCnt)); - - // append crc's - if (appendCrc16 && (len > 10)) { - // crc control data - uint16_t crc = ah::crc16(&mTxBuf[10], len - 10); - mTxBuf[len++] = (crc >> 8) & 0xff; - mTxBuf[len++] = (crc ) & 0xff; - } - // crc over all - mTxBuf[len] = ah::crc8(mTxBuf, len); - len++; + updateCrcs(len, appendCrc16); // set TX and RX channels mTxChIdx = (mTxChIdx + 1) % RF_CHANNELS; @@ -302,7 +258,9 @@ class HmRadio : public Radio { iv->radioStatistics.txCnt++; } - volatile bool mIrqRcvd; + uint64_t getIvId(Inverter<> *iv) { + return iv->radioId.u64; + } uint8_t mRfChLst[RF_CHANNELS]; uint8_t mTxChIdx; diff --git a/src/hm/radio.h b/src/hm/radio.h index 4247fa72..e9b1e47b 100644 --- a/src/hm/radio.h +++ b/src/hm/radio.h @@ -11,6 +11,9 @@ #define ALL_FRAMES 0x80 #define SINGLE_FRAME 0x81 +#include "../utils/dbg.h" +#include "../utils/crc.h" + // forward declaration of class template class Inverter; @@ -19,11 +22,40 @@ class Inverter; class Radio { public: virtual void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) = 0; - virtual void prepareDevInformCmd(Inverter<> *iv, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) = 0; - virtual void sendCmdPacket(Inverter<> *iv, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) = 0; virtual bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) { return true; } + void handleIntr(void) { + mIrqRcvd = true; + } + + void enableDebug() { + mSerialDebug = true; + } + + void sendCmdPacket(Inverter<> *iv, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) { + initPacket(getIvId(iv), mid, pid); + sendPacket(iv, 10, isRetransmit, appendCrc16); + } + + void prepareDevInformCmd(Inverter<> *iv, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) { // might not be necessary to add additional arg. + if(mSerialDebug) { + DPRINT(DBG_DEBUG, F("prepareDevInformCmd 0x")); + DPRINTLN(DBG_DEBUG,String(cmd, HEX)); + } + initPacket(getIvId(iv), reqfld, ALL_FRAMES); + mTxBuf[10] = cmd; + CP_U32_LittleEndian(&mTxBuf[12], ts); + if (cmd == AlarmData ) { //cmd == RealTimeRunData_Debug || + mTxBuf[18] = (alarmMesId >> 8) & 0xff; + mTxBuf[19] = (alarmMesId ) & 0xff; + } + sendPacket(iv, 24, isRetransmit); + } + protected: + virtual void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) = 0; + virtual uint64_t getIvId(Inverter<> *iv) = 0; + void initPacket(uint64_t ivId, uint8_t mid, uint8_t pid) { mTxBuf[0] = mid; CP_U32_BigEndian(&mTxBuf[1], ivId >> 8); @@ -32,6 +64,19 @@ class Radio { memset(&mTxBuf[10], 0x00, (MAX_RF_PAYLOAD_SIZE-10)); } + void updateCrcs(uint8_t len, bool appendCrc16=true) { + // append crc's + if (appendCrc16 && (len > 10)) { + // crc control data + uint16_t crc = ah::crc16(&mTxBuf[10], len - 10); + mTxBuf[len++] = (crc >> 8) & 0xff; + mTxBuf[len++] = (crc ) & 0xff; + } + // crc over all + mTxBuf[len] = ah::crc8(mTxBuf, len); + len++; + } + void generateDtuSn(void) { uint32_t chipID = 0; #ifdef ESP32 @@ -48,6 +93,8 @@ class Radio { } uint32_t mDtuSn; + volatile bool mIrqRcvd; + bool mSerialDebug; uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE]; }; diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index 1c26cb91..b6b6bb48 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -6,7 +6,6 @@ #ifndef __HMS_RADIO_H__ #define __HMS_RADIO_H__ -#include "../utils/dbg.h" #include "cmt2300a.h" #include "../hm/radio.h" @@ -44,17 +43,6 @@ class CmtRadio : public Radio { return false; } - void tickSecond() { - } - - void handleIntr(void) { - mIrqRcvd = true; - } - - void enableDebug() { - mSerialDebug = true; - } - bool isConnected() { return mCmtAvail; } @@ -90,30 +78,11 @@ class CmtRadio : public Radio { return true; } - void prepareDevInformCmd(Inverter<> *iv, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) { // might not be necessary to add additional arg. - initPacket(iv->radioId.u64, reqfld, ALL_FRAMES); - mTxBuf[10] = cmd; - CP_U32_LittleEndian(&mTxBuf[12], ts); - if (cmd == AlarmData ) { //cmd == RealTimeRunData_Debug || - mTxBuf[18] = (alarmMesId >> 8) & 0xff; - mTxBuf[19] = (alarmMesId ) & 0xff; - } - sendPacket(iv, 24, isRetransmit); - } - - void sendCmdPacket(Inverter<> *iv, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) { - initPacket(iv->radioId.u64, mid, pid); - sendPacket(iv, 10, isRetransmit); - } + std::queue mBufCtrl; - void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit) { - if (len > 14) { - uint16_t crc = ah::crc16(&mTxBuf[10], len - 10); - mTxBuf[len++] = (crc >> 8) & 0xff; - mTxBuf[len++] = (crc ) & 0xff; - } - mTxBuf[len] = ah::crc8(mTxBuf, len); - len++; + private: + void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) { + updateCrcs(len, appendCrc16); if(mSerialDebug) { DPRINT(DBG_INFO, F("TX ")); @@ -136,9 +105,10 @@ class CmtRadio : public Radio { iv->radioStatistics.txCnt++; } - std::queue mBufCtrl; + uint64_t getIvId(Inverter<> *iv) { + return iv->radioId.u64; + } - private: inline void reset(bool genDtuSn) { if(genDtuSn) generateDtuSn(); @@ -182,8 +152,6 @@ class CmtRadio : public Radio { } CmtType mCmt; - bool mSerialDebug; - bool mIrqRcvd; bool mRqstGetRx; bool mCmtAvail; }; From bd20eba709757f7a6a36c530ae206f74d69741f4 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 1 Oct 2023 00:45:47 +0200 Subject: [PATCH 16/18] 0.7.61 * merged `hmPayload` and `hmsPayload` into single class * merged generic radio functions into new parent class `radio.h` * moved radio statistics into the inverter - each inverter has now seperate statistics which can be accessed by click on the footer in `/live` --- src/CHANGES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/CHANGES.md b/src/CHANGES.md index aad3b75a..67368f8d 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,10 @@ # Development Changes +## 0.7.61 - 2023-10-01 +* merged `hmPayload` and `hmsPayload` into single class +* merged generic radio functions into new parent class `radio.h` +* moved radio statistics into the inverter - each inverter has now seperate statistics which can be accessed by click on the footer in `/live` + ## 0.7.60 - 2023-09-27 * fixed typos in changelog #1172 * fixed MqTT manual clientId storage #1174 From c1cb62685da3e031f8793a28b4a3d28df858e5ca Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 1 Oct 2023 00:48:51 +0200 Subject: [PATCH 17/18] 0.7.61 --- src/hm/hmInverter.h | 2 +- src/utils/dbg.h | 12 ++++++------ src/utils/helper.h | 8 ++++---- src/web/web.h | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index 54165d81..17ad6cc5 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -85,7 +85,7 @@ class CommandAbstract { }; virtual ~CommandAbstract() {}; - const uint8_t getCmd() { + uint8_t getCmd() const { return _Cmd; } diff --git a/src/utils/dbg.h b/src/utils/dbg.h index 6c861329..9e754ba6 100644 --- a/src/utils/dbg.h +++ b/src/utils/dbg.h @@ -148,7 +148,7 @@ #define PVERBLN(str) #endif -#define DPRINT(level, str) ({\ +#define DPRINT(level, str) do {\ switch(level) {\ case DBG_ERROR: PERR(str); break; \ case DBG_WARN: PWARN(str); break; \ @@ -156,13 +156,13 @@ case DBG_DEBUG: PDBG(str); break; \ default: PVERB(str); break; \ }\ -}) +} while (0) -#define DPRINT_IVID(level, id) ({\ +#define DPRINT_IVID(level, id) do {\ DPRINT(level, F("(#")); DBGPRINT(String(id)); DBGPRINT(F(") "));\ -}) +} while (0) -#define DPRINTLN(level, str) ({\ +#define DPRINTLN(level, str) do {\ switch(level) {\ case DBG_ERROR: PERRLN(str); break; \ case DBG_WARN: PWARNLN(str); break; \ @@ -170,7 +170,7 @@ case DBG_DEBUG: PDBGLN(str); break; \ default: PVERBLN(str); break; \ }\ -}) +} while (0) /*class ahoyLog { diff --git a/src/utils/helper.h b/src/utils/helper.h index e1702877..252ca9fe 100644 --- a/src/utils/helper.h +++ b/src/utils/helper.h @@ -20,21 +20,21 @@ static Timezone gTimezone(CEST, CET); #define CHECK_MASK(a,b) ((a & b) == b) -#define CP_U32_LittleEndian(buf, v) ({ \ +#define CP_U32_LittleEndian(buf, v) do { \ uint8_t *b = buf; \ b[0] = ((v >> 24) & 0xff); \ b[1] = ((v >> 16) & 0xff); \ b[2] = ((v >> 8) & 0xff); \ b[3] = ((v ) & 0xff); \ -}) +} while (0) -#define CP_U32_BigEndian(buf, v) ({ \ +#define CP_U32_BigEndian(buf, v) do { \ uint8_t *b = buf; \ b[3] = ((v >> 24) & 0xff); \ b[2] = ((v >> 16) & 0xff); \ b[1] = ((v >> 8) & 0xff); \ b[0] = ((v ) & 0xff); \ -}) +} while (0) namespace ah { void ip2Arr(uint8_t ip[], const char *ipStr); diff --git a/src/web/web.h b/src/web/web.h index 59f853b1..20883c97 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -183,8 +183,8 @@ class Web { mUploadFp.write(data, len); if (final) { mUploadFp.close(); - char pwd[PWD_LEN]; #if !defined(ETHERNET) + char pwd[PWD_LEN]; strncpy(pwd, mConfig->sys.stationPwd, PWD_LEN); // backup WiFi PWD #endif if (!mApp->readSettings("/tmp.json")) { From 5a01cc86e661fdfe8dc1c63a0be519967d67fd2b Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 1 Oct 2023 01:13:42 +0200 Subject: [PATCH 18/18] 0.7.61 * fix compiler warnings #1191 * fix ePaper logo during night time #1151 --- src/CHANGES.md | 2 ++ src/plugins/Display/Display.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 67368f8d..89f334cc 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -4,6 +4,8 @@ * merged `hmPayload` and `hmsPayload` into single class * merged generic radio functions into new parent class `radio.h` * moved radio statistics into the inverter - each inverter has now seperate statistics which can be accessed by click on the footer in `/live` +* fix compiler warnings #1191 +* fix ePaper logo during night time #1151 ## 0.7.60 - 2023-09-27 * fixed typos in changelog #1172 diff --git a/src/plugins/Display/Display.h b/src/plugins/Display/Display.h index 8152f372..c4853bab 100644 --- a/src/plugins/Display/Display.h +++ b/src/plugins/Display/Display.h @@ -135,7 +135,7 @@ class Display { } #if defined(ESP32) else if (mCfg->type == 10) { - mEpaper.loop(totalPower, totalYieldDay, totalYieldTotal, nrprod); + mEpaper.loop(((allOff) ? 0.0 : totalPower), totalYieldDay, totalYieldTotal, nrprod); mRefreshCycle++; }