diff --git a/src/CHANGES.md b/src/CHANGES.md index 813f1708e..f0491335f 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,8 @@ # Development Changes +## 0.8.74 - 2024-02-05 +* reduced cppcheck linter warnings significantly + ## 0.8.73 - 2024-02-03 * fix nullpointer during communication #1401 * added `max_power` to MqTT total values #1375 diff --git a/src/app.cpp b/src/app.cpp index 4f49d93b2..d9b0f9332 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -13,7 +13,10 @@ //----------------------------------------------------------------------------- -app::app() : ah::Scheduler {} {} +app::app() : ah::Scheduler {} { + memset(mVersion, 0, sizeof(char) * 12); + memset(mVersionModules, 0, sizeof(char) * 12); +} //----------------------------------------------------------------------------- @@ -228,7 +231,6 @@ void app::updateNtp(void) { onceAt(std::bind(&app::tickMidnight, this), midTrig, "midNi"); if (mConfig->sys.schedReboot) { - uint32_t localTime = gTimezone.toLocal(mTimestamp); uint32_t rebootTrig = gTimezone.toUTC(localTime - (localTime % 86400) + 86410); // reboot 10 secs after midnght if (rebootTrig <= mTimestamp) { //necessary for times other than midnight to prevent reboot loop rebootTrig += 86400; @@ -301,9 +303,8 @@ void app::tickIVCommunication(void) { bool zeroValues = false; uint32_t nxtTrig = 0; - Inverter<> *iv; for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { - iv = mSys.getInverterByPos(i); + Inverter<> *iv = mSys.getInverterByPos(i); if(NULL == iv) continue; @@ -390,10 +391,9 @@ void app::tickMidnight(void) { // clear max values if(mConfig->inst.rstMaxValsMidNight) { - uint8_t pos; record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); for(uint8_t i = 0; i <= iv->channels; i++) { - pos = iv->getPosByChFld(i, FLD_MP, rec); + uint8_t pos = iv->getPosByChFld(i, FLD_MP, rec); iv->setValue(pos, rec, 0.0f); } } @@ -592,9 +592,8 @@ void app::updateLed(void) { uint8_t led_on = (mConfig->led.high_active) ? (mConfig->led.luminance) : (255-mConfig->led.luminance); if (mConfig->led.led[0] != DEF_PIN_OFF) { - Inverter<> *iv; for (uint8_t id = 0; id < mSys.getNumInverters(); id++) { - iv = mSys.getInverterByPos(id); + Inverter<> *iv = mSys.getInverterByPos(id); if (NULL != iv) { if (iv->isProducing()) { // turn on when at least one inverter is producing diff --git a/src/app.h b/src/app.h index b44d3781e..60be4d1d0 100644 --- a/src/app.h +++ b/src/app.h @@ -90,7 +90,7 @@ class app : public IApp, public ah::Scheduler { void handleIntr(void) { mNrfRadio.handleIntr(); } - void* getRadioObj(bool nrf) { + void* getRadioObj(bool nrf) override { if(nrf) return (void*)&mNrfRadio; else { @@ -108,19 +108,19 @@ class app : public IApp, public ah::Scheduler { } #endif - uint32_t getUptime() { + uint32_t getUptime() override { return Scheduler::getUptime(); } - uint32_t getTimestamp() { + uint32_t getTimestamp() override { return Scheduler::mTimestamp; } - uint64_t getTimestampMs() { + uint64_t getTimestampMs() override { return ((uint64_t)Scheduler::mTimestamp * 1000) + ((uint64_t)millis() - (uint64_t)Scheduler::mTsMillis) % 1000; } - bool saveSettings(bool reboot) { + bool saveSettings(bool reboot) override { mShowRebootRequest = true; // only message on index, no reboot mSavePending = true; mSaveReboot = reboot; @@ -131,7 +131,7 @@ class app : public IApp, public ah::Scheduler { return true; } - void initInverter(uint8_t id) { + void initInverter(uint8_t id) override { mSys.addInverter(id, [this](Inverter<> *iv) { if((IV_MI == iv->ivGen) || (IV_HM == iv->ivGen)) iv->radio = &mNrfRadio; @@ -142,7 +142,7 @@ class app : public IApp, public ah::Scheduler { }); } - bool readSettings(const char *path) { + bool readSettings(const char *path) override { return mSettings.readSettings(path); } @@ -150,80 +150,80 @@ class app : public IApp, public ah::Scheduler { return mSettings.eraseSettings(eraseWifi); } - bool getSavePending() { + bool getSavePending() override { return mSavePending; } - bool getLastSaveSucceed() { + bool getLastSaveSucceed() override { return mSettings.getLastSaveSucceed(); } - bool getShouldReboot() { + bool getShouldReboot() override { return mSaveReboot; } #if !defined(ETHERNET) - void scanAvailNetworks() { + void scanAvailNetworks() override { mWifi.scanAvailNetworks(); } - bool getAvailNetworks(JsonObject obj) { + bool getAvailNetworks(JsonObject obj) override { return mWifi.getAvailNetworks(obj); } - void setupStation(void) { + void setupStation(void) override { mWifi.setupStation(); } - void setStopApAllowedMode(bool allowed) { + void setStopApAllowedMode(bool allowed) override { mWifi.setStopApAllowedMode(allowed); } - String getStationIp(void) { + String getStationIp(void) override { return mWifi.getStationIp(); } - bool getWasInCh12to14(void) const { + bool getWasInCh12to14(void) const override { return mWifi.getWasInCh12to14(); } #endif /* !defined(ETHERNET) */ - void setRebootFlag() { + void setRebootFlag() override { once(std::bind(&app::tickReboot, this), 3, "rboot"); } - const char *getVersion() { + const char *getVersion() override { return mVersion; } - const char *getVersionModules() { + const char *getVersionModules() override { return mVersionModules; } - uint32_t getSunrise() { + uint32_t getSunrise() override { return mSunrise; } - uint32_t getSunset() { + uint32_t getSunset() override { return mSunset; } - bool getSettingsValid() { + bool getSettingsValid() override { return mSettings.getValid(); } - bool getRebootRequestState() { + bool getRebootRequestState() override { return mShowRebootRequest; } - void setMqttDiscoveryFlag() { + void setMqttDiscoveryFlag() override { #if defined(ENABLE_MQTT) once(std::bind(&PubMqttType::sendDiscoveryConfig, &mMqtt), 1, "disCf"); #endif } - bool getMqttIsConnected() { + bool getMqttIsConnected() override { #if defined(ENABLE_MQTT) return mMqtt.isConnected(); #else @@ -231,7 +231,7 @@ class app : public IApp, public ah::Scheduler { #endif } - uint32_t getMqttTxCnt() { + uint32_t getMqttTxCnt() override { #if defined(ENABLE_MQTT) return mMqtt.getTxCnt(); #else @@ -239,7 +239,7 @@ class app : public IApp, public ah::Scheduler { #endif } - uint32_t getMqttRxCnt() { + uint32_t getMqttRxCnt() override { #if defined(ENABLE_MQTT) return mMqtt.getRxCnt(); #else @@ -267,11 +267,11 @@ class app : public IApp, public ah::Scheduler { return mProtection->isProtected(clientIp); } - bool getNrfEnabled(void) { + bool getNrfEnabled(void) override { return mConfig->nrf.enabled; } - bool getCmtEnabled(void) { + bool getCmtEnabled(void) override { return mConfig->cmt.enabled; } @@ -283,19 +283,19 @@ class app : public IApp, public ah::Scheduler { return mConfig->cmt.pinIrq; } - uint32_t getTimezoneOffset() { + uint32_t getTimezoneOffset() override { return mApi.getTimezoneOffset(); } - void getSchedulerInfo(uint8_t *max) { + void getSchedulerInfo(uint8_t *max) override { getStat(max); } - void getSchedulerNames(void) { + void getSchedulerNames(void) override { printSchedulers(); } - void setTimestamp(uint32_t newTime) { + void setTimestamp(uint32_t newTime) override { DPRINT(DBG_DEBUG, F("setTimestamp: ")); DBGPRINTLN(String(newTime)); if(0 == newTime) @@ -310,7 +310,7 @@ class app : public IApp, public ah::Scheduler { Scheduler::setTimestamp(newTime); } - uint16_t getHistoryValue(uint8_t type, uint16_t i) { + uint16_t getHistoryValue(uint8_t type, uint16_t i) override { #if defined(ENABLE_HISTORY) return mHistory.valueAt((HistoryStorageType)type, i); #else @@ -318,7 +318,7 @@ class app : public IApp, public ah::Scheduler { #endif } - uint16_t getHistoryMaxDay() { + uint16_t getHistoryMaxDay() override { #if defined(ENABLE_HISTORY) return mHistory.getMaximumDay(); #else @@ -372,11 +372,11 @@ class app : public IApp, public ah::Scheduler { void tickNtpUpdate(void); #if defined(ETHERNET) void onNtpUpdate(bool gotTime); - bool mNtpReceived; + bool mNtpReceived = false; #endif /* defined(ETHERNET) */ void updateNtp(void); - void triggerTickSend() { + void triggerTickSend() override { once(std::bind(&app::tickSend, this), 0, "tSend"); } @@ -395,7 +395,7 @@ class app : public IApp, public ah::Scheduler { HmRadio<> mNrfRadio; Communication mCommunication; - bool mShowRebootRequest; + bool mShowRebootRequest = false; #if defined(ETHERNET) ahoyeth mEth; @@ -404,7 +404,7 @@ class app : public IApp, public ah::Scheduler { #endif /* defined(ETHERNET) */ WebType mWeb; RestApiType mApi; - Protection *mProtection; + Protection *mProtection = nullptr; #ifdef ENABLE_SYSLOG DbgSyslog mDbgSyslog; #endif @@ -421,26 +421,26 @@ class app : public IApp, public ah::Scheduler { char mVersion[12]; char mVersionModules[12]; settings mSettings; - settings_t *mConfig; - bool mSavePending; - bool mSaveReboot; + settings_t *mConfig = nullptr; + bool mSavePending = false; + bool mSaveReboot = false; - uint8_t mSendLastIvId; - bool mSendFirst; - bool mAllIvNotAvail; + uint8_t mSendLastIvId = 0; + bool mSendFirst = false; + bool mAllIvNotAvail = false; - bool mNetworkConnected; + bool mNetworkConnected = false; // mqtt #if defined(ENABLE_MQTT) PubMqttType mMqtt; #endif /*ENABLE_MQTT*/ - bool mMqttReconnect; - bool mMqttEnabled; + bool mMqttReconnect = false; + bool mMqttEnabled = false; // sun - int32_t mCalculatedTimezoneOffset; - uint32_t mSunrise, mSunset; + int32_t mCalculatedTimezoneOffset = 0; + uint32_t mSunrise = 0, mSunset = 0; // plugins #if defined(PLUGIN_DISPLAY) diff --git a/src/config/settings.h b/src/config/settings.h index ec9712ea1..0cb9ed4ee 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -13,6 +13,7 @@ #include #include +#include #include #include "../defines.h" @@ -206,7 +207,7 @@ typedef struct { class settings { public: settings() { - mLastSaveSucceed = false; + std::fill(reinterpret_cast(&mCfg), reinterpret_cast(&mCfg) + sizeof(mCfg), 0); } void setup() { @@ -377,7 +378,7 @@ class settings { memcpy(&tmp, &mCfg.sys, sizeof(cfgSys_t)); } // erase all settings and reset to default - memset(&mCfg, 0, sizeof(settings_t)); + std::fill(reinterpret_cast(&mCfg), reinterpret_cast(&mCfg) + sizeof(mCfg), 0); mCfg.sys.protectionMask = DEF_PROT_INDEX | DEF_PROT_LIVE | DEF_PROT_SERIAL | DEF_PROT_SETUP | DEF_PROT_UPDATE | DEF_PROT_SYSTEM | DEF_PROT_API | DEF_PROT_MQTT | DEF_PROT_HISTORY; mCfg.sys.darkMode = false; @@ -847,7 +848,7 @@ class settings { #endif settings_t mCfg; - bool mLastSaveSucceed; + bool mLastSaveSucceed = 0; }; #endif /*__SETTINGS_H__*/ diff --git a/src/defines.h b/src/defines.h index b71a1d253..bc9d24529 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 73 +#define VERSION_PATCH 74 //------------------------------------- typedef struct { diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index acbe9a358..328309acd 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -91,7 +91,7 @@ class CommQueue { inc(&mRdPtr); } - void setTs(uint32_t *ts) { + void setTs(const uint32_t *ts) { mQueue[mRdPtr].ts = *ts; } diff --git a/src/hm/Communication.h b/src/hm/Communication.h index d1521f81b..326fb57ed 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -6,6 +6,7 @@ #ifndef __COMMUNICATION_H__ #define __COMMUNICATION_H__ +#include #include "CommQueue.h" #include #include "../utils/crc.h" @@ -194,8 +195,8 @@ class Communication : public CommQueue<> { q->iv->radio->mBufCtrl.pop(); return; // don't wait for empty buffer } else if(IV_MI == q->iv->ivGen) { - if(parseMiFrame(p, q)) - q->iv->curFrmCnt++; + parseMiFrame(p, q); + q->iv->curFrmCnt++; } } //else -> serial does not match @@ -385,7 +386,7 @@ class Communication : public CommQueue<> { } } - inline bool validateIvSerial(uint8_t buf[], Inverter<> *iv) { + inline bool validateIvSerial(const uint8_t buf[], Inverter<> *iv) { uint8_t tmp[4]; CP_U32_BigEndian(tmp, iv->radioId.u64 >> 8); for(uint8_t i = 0; i < 4; i++) { @@ -435,7 +436,7 @@ class Communication : public CommQueue<> { return true; } - inline bool parseMiFrame(packet_t *p, const queue_s *q) { + inline void parseMiFrame(packet_t *p, const queue_s *q) { if((!mIsRetransmit && p->packet[9] == 0x00) && (p->millis < LIMIT_FAST_IV_MI)) //first frame is fast? mHeu.setIvRetriesGood(q->iv,p->millis < LIMIT_VERYFAST_IV_MI); if ((p->packet[0] == MI_REQ_CH1 + ALL_FRAMES) @@ -458,11 +459,9 @@ class Communication : public CommQueue<> { rec->ts = q->ts; miStsConsolidate(q, ((p->packet[0] == 0x88) ? 1 : 2), rec, p->packet[10], p->packet[12], p->packet[9], p->packet[11]); } - - return true; } - inline bool parseDevCtrl(packet_t *p, const queue_s *q) { + inline bool parseDevCtrl(const packet_t *p, const queue_s *q) { switch(p->packet[12]) { case ActivePowerContr: if(p->packet[13] != 0x00) @@ -524,7 +523,7 @@ class Communication : public CommQueue<> { return false; } - memset(mPayload, 0, MAX_BUFFER); + mPayload.fill(0); int8_t rssi = -127; uint8_t len = 0; @@ -547,19 +546,19 @@ class Communication : public CommQueue<> { DBGPRINT(String(len)); if(*mPrintWholeTrace) { DBGPRINT(F("): ")); - ah::dumpBuf(mPayload, len); + ah::dumpBuf(mPayload.data(), len); } else DBGPRINTLN(F(")")); if(GridOnProFilePara == q->cmd) { - q->iv->addGridProfile(mPayload, len); + q->iv->addGridProfile(mPayload.data(), len); return true; } record_t<> *rec = q->iv->getRecordStruct(q->cmd); if(NULL == rec) { if(GetLossRate == q->cmd) { - q->iv->parseGetLossRate(mPayload, len); + q->iv->parseGetLossRate(mPayload.data(), len); return true; } else DPRINTLN(DBG_ERROR, F("record is NULL!")); @@ -578,7 +577,7 @@ class Communication : public CommQueue<> { rec->ts = q->ts; for (uint8_t i = 0; i < rec->length; i++) { - q->iv->addValue(i, mPayload, rec); + q->iv->addValue(i, mPayload.data(), rec); } rec->mqttSentStatus = MqttSentStatus::NEW_DATA; @@ -588,7 +587,7 @@ class Communication : public CommQueue<> { if(AlarmData == q->cmd) { uint8_t i = 0; while(1) { - if(0 == q->iv->parseAlarmLog(i++, mPayload, len)) + if(0 == q->iv->parseAlarmLog(i++, mPayload.data(), len)) break; if (NULL != mCbAlarm) (mCbAlarm)(q->iv); @@ -670,7 +669,7 @@ class Communication : public CommQueue<> { }; */ - if ( p->packet[9] == 0x00 ) {//first frame + if ( p->packet[9] == 0x00 ) { //first frame //FLD_FW_VERSION for (uint8_t i = 0; i < 5; i++) { q->iv->setValue(i, rec, (float) ((p->packet[(12+2*i)] << 8) + p->packet[(13+2*i)])/1); @@ -680,7 +679,7 @@ class Communication : public CommQueue<> { DBGPRINT(F("HW_VER is ")); DBGPRINTLN(String((p->packet[24] << 8) + p->packet[25])); } - record_t<> *rec = q->iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure + rec = q->iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure rec->ts = q->ts; q->iv->setValue(1, rec, (uint32_t) ((p->packet[24] << 8) + p->packet[25])/1); q->iv->miMultiParts +=4; @@ -894,7 +893,7 @@ class Communication : public CommQueue<> { statusMi = 8310; //trick? } - uint16_t prntsts = statusMi == 3 ? 1 : statusMi; + uint16_t prntsts = (statusMi == 3) ? 1 : statusMi; bool stsok = true; if ( prntsts != rec->record[q->iv->getPosByChFld(0, FLD_EVT, rec)] ) { //sth.'s changed? q->iv->alarmCnt = 1; // minimum... @@ -1017,17 +1016,17 @@ class Communication : public CommQueue<> { private: States mState = States::RESET; - uint32_t *mTimestamp; - bool *mPrivacyMode, *mSerialDebug, *mPrintWholeTrace; + uint32_t *mTimestamp = nullptr; + bool *mPrivacyMode = nullptr, *mSerialDebug = nullptr, *mPrintWholeTrace = nullptr; TimeMonitor mWaitTime = TimeMonitor(0, true); // start as expired (due to code in RESET state) std::array mLocalBuf; bool mFirstTry = false; // see, if we should do a second try bool mCompleteRetry = false; // remember if we did request a complete retransmission bool mIsRetransmit = false; // we already had waited one complete cycle - uint8_t mMaxFrameId; + uint8_t mMaxFrameId = 0; uint8_t mFramesExpected = 12; // 0x8c was highest last frame for alarm data uint16_t mTimeout = 0; // calculating that once should be ok - uint8_t mPayload[MAX_BUFFER]; + std::array mPayload; payloadListenerType mCbPayload = NULL; powerLimitAckListenerType mCbPwrAck = NULL; alarmListenerType mCbAlarm = NULL; diff --git a/src/hm/Heuristic.h b/src/hm/Heuristic.h index fa4512b50..2a36bc78b 100644 --- a/src/hm/Heuristic.h +++ b/src/hm/Heuristic.h @@ -157,7 +157,7 @@ class Heuristic { DBGPRINTLN(String(iv->config->powerLevel)); } - uint8_t getIvRetries(Inverter<> *iv) { + uint8_t getIvRetries(const Inverter<> *iv) const { if(iv->heuristics.rxSpeeds[0]) return RETRIES_VERYFAST_IV; if(iv->heuristics.rxSpeeds[1]) @@ -200,7 +200,7 @@ class Heuristic { } private: - bool isNewTxCh(HeuristicInv *ih) { + bool isNewTxCh(const HeuristicInv *ih) const { return ih->txRfChId != ih->lastBestTxChId; } @@ -222,9 +222,6 @@ class Heuristic { } return 3; // standard } - - private: - uint8_t mChList[5] = {03, 23, 40, 61, 75}; }; diff --git a/src/hm/hmDefines.h b/src/hm/hmDefines.h index 0b42aeae9..8fc4f71f1 100644 --- a/src/hm/hmDefines.h +++ b/src/hm/hmDefines.h @@ -76,7 +76,7 @@ enum {CMD_CALC = 0xffff}; enum {CH0 = 0, CH1, CH2, CH3, CH4, CH5, CH6}; enum {INV_TYPE_1CH = 0, INV_TYPE_2CH, INV_TYPE_4CH, INV_TYPE_6CH}; -enum {INV_RADIO_TYPE_NRF = 0, INV_RADIO_TYPE_CMT}; +enum {INV_RADIO_TYPE_UNKNOWN = 0, INV_RADIO_TYPE_NRF, INV_RADIO_TYPE_CMT}; #define DURATION_ONEFRAME 50 // timeout parameter for each expected frame (ms) diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index b62e985ae..275fce2ca 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -81,12 +81,12 @@ enum class InverterStatus : uint8_t { template struct record_t { - byteAssign_t* assign; // assignment of bytes in payload - uint8_t length; // length of the assignment list - T *record; // data pointer - uint32_t ts; // timestamp of last received payload - uint8_t pyldLen; // expected payload length for plausibility check - MqttSentStatus mqttSentStatus; // indicates the current MqTT sent status + byteAssign_t* assign = nullptr; // assignment of bytes in payload + uint8_t length = 0; // length of the assignment list + T *record = nullptr; // data pointer + uint32_t ts = 0; // timestamp of last received payload + uint8_t pyldLen = 0; // expected payload length for plausibility check + MqttSentStatus mqttSentStatus = MqttSentStatus:: NEW_DATA; // indicates the current MqTT sent status }; struct alarm_t { @@ -113,42 +113,42 @@ const calcFunc_t calcFunctions[] = { template class Inverter { public: - uint8_t ivGen; // generation of inverter (HM / MI) - uint8_t ivRadioType; // refers to used radio (nRF24 / CMT) - cfgIv_t *config; // stored settings - uint8_t id; // unique id - uint8_t type; // integer which refers to inverter type - uint16_t alarmMesIndex; // Last recorded Alarm Message Index - uint16_t powerLimit[2]; // limit power output (multiplied by 10) - float actPowerLimit; // actual power limit - bool powerLimitAck; // acknowledged power limit (default: false) - uint8_t devControlCmd; // carries the requested cmd - serial_u radioId; // id converted to modbus - 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 recordConfig; // structure for system config values - record_t recordAlarm; // structure for alarm values - InverterStatus status; // indicates the current inverter status - std::array lastAlarm; // holds last 10 alarms - uint8_t rxOffset; // holds the default channel offset between tx and rx channel (nRF only) - int8_t rssi; // RSSI - uint16_t alarmCnt; // counts the total number of occurred alarms - uint16_t alarmLastId; // lastId which was received - uint8_t mCmd; // holds the command to send - bool mGotFragment; // shows if inverter has sent at least one fragment - uint8_t miMultiParts; // helper info for MI multiframe msgs - uint8_t outstandingFrames; // helper info to count difference between expected and received frames - uint8_t curFrmCnt; // count received frames in current loop - bool mGotLastMsg; // shows if inverter has already finished transmission cycle - bool mIsSingleframeReq; // indicates this is a missing single frame request - Radio *radio; // pointer to associated radio class - statistics_t radioStatistics; // information about transmitted, failed, ... packets - HeuristicInv heuristics; // heuristic information / logic - uint8_t curCmtFreq; // current used CMT frequency, used to check if freq. was changed during runtime - bool commEnabled; // 'pause night communication' sets this field to false - uint32_t tsMaxAcPower; // holds the timestamp when the MaxAC power was seen + uint8_t ivGen = IV_UNKNOWN; // generation of inverter (HM / MI) + uint8_t ivRadioType = INV_RADIO_TYPE_UNKNOWN; // refers to used radio (nRF24 / CMT) + cfgIv_t *config = nullptr; // stored settings + uint8_t id = 0; // unique id + uint8_t type = INV_TYPE_1CH; // integer which refers to inverter type + uint16_t alarmMesIndex = 0; // Last recorded Alarm Message Index + uint16_t powerLimit[2] = {0xffff, AbsolutNonPersistent}; // limit power output (multiplied by 10) + float actPowerLimit = -1; // actual power limit + bool powerLimitAck = false; // acknowledged power limit + uint8_t devControlCmd = InitDataState; // carries the requested cmd + serial_u radioId; // id converted to modbus + uint8_t channels = 1; // 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 recordConfig; // structure for system config values + record_t recordAlarm; // structure for alarm values + InverterStatus status = InverterStatus::OFF; // indicates the current inverter status + std::array lastAlarm; // holds last 10 alarms + uint8_t rxOffset = 0; // holds the default channel offset between tx and rx channel (nRF only) + int8_t rssi = 0; // RSSI + uint16_t alarmCnt = 0; // counts the total number of occurred alarms + uint16_t alarmLastId = 0; // lastId which was received + uint8_t mCmd = InitDataState; // holds the command to send + bool mGotFragment = false; // shows if inverter has sent at least one fragment + uint8_t miMultiParts = 0; // helper info for MI multiframe msgs + uint8_t outstandingFrames = 0; // helper info to count difference between expected and received frames + uint8_t curFrmCnt = 0; // count received frames in current loop + bool mGotLastMsg = false; // shows if inverter has already finished transmission cycle + bool mIsSingleframeReq = false; // indicates this is a missing single frame request + Radio *radio = nullptr; // pointer to associated radio class + statistics_t radioStatistics; // information about transmitted, failed, ... packets + HeuristicInv heuristics; // heuristic information / logic + uint8_t curCmtFreq = 0; // current used CMT frequency, used to check if freq. was changed during runtime + uint32_t tsMaxAcPower = 0; // holds the timestamp when the MaxAC power was seen + bool commEnabled = true; // 'pause night communication' sets this field to false static uint32_t *timestamp; // system timestamp static cfgInst_t *generalConfig; // general inverter configuration from setup @@ -156,29 +156,10 @@ class Inverter { public: Inverter() { - ivGen = IV_HM; - powerLimit[0] = 0xffff; // 6553.5 W Limit -> unlimited - powerLimit[1] = AbsolutNonPersistent; // default power limit setting - powerLimitAck = false; - actPowerLimit = 0xffff; // init feedback from inverter to -1 - mDevControlRequest = false; - devControlCmd = InitDataState; - alarmMesIndex = 0; - status = InverterStatus::OFF; - alarmCnt = 0; - alarmLastId = 0; - rssi = -127; - miMultiParts = 0; - mGotLastMsg = false; - mCmd = InitDataState; - mIsSingleframeReq = false; - radio = NULL; - commEnabled = true; - tsMaxAcPower = 0; - memset(&radioStatistics, 0, sizeof(statistics_t)); memset(mOffYD, 0, sizeof(float) * 6); memset(mLastYD, 0, sizeof(float) * 6); + mGridProfile.fill(0); } void tickSend(std::function cb) { @@ -255,8 +236,8 @@ class Inverter { uint8_t getPosByChFld(uint8_t channel, uint8_t fieldId, record_t<> *rec) { DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getPosByChFld")); - uint8_t pos = 0; if(NULL != rec) { + uint8_t pos = 0; for(; pos < rec->length; pos++) { if((rec->assign[pos].ch == channel) && (rec->assign[pos].fieldId == fieldId)) break; @@ -303,7 +284,7 @@ class Inverter { return (InverterStatus::OFF != status); } - void addValue(uint8_t pos, uint8_t buf[], record_t<> *rec) { + void addValue(uint8_t pos, const uint8_t buf[], record_t<> *rec) { DPRINTLN(DBG_VERBOSE, F("hmInverter.h:addValue")); if(NULL != rec) { uint8_t ptr = rec->assign[pos].start; @@ -387,8 +368,8 @@ class Inverter { } REC_TYP getChannelFieldValue(uint8_t channel, uint8_t fieldId, record_t<> *rec) { - uint8_t pos = 0; if(NULL != rec) { + uint8_t pos = 0; for(; pos < rec->length; pos++) { if((rec->assign[pos].ch == channel) && (rec->assign[pos].fieldId == fieldId)) break; @@ -529,11 +510,11 @@ class Inverter { if (INV_TYPE_1CH == type) { if((IV_HM == ivGen) || (IV_MI == ivGen)) { rec->length = (uint8_t)(HM1CH_LIST_LEN); - rec->assign = (byteAssign_t *)hm1chAssignment; + rec->assign = reinterpret_cast(const_cast(hm1chAssignment)); rec->pyldLen = HM1CH_PAYLOAD_LEN; } else if(IV_HMS == ivGen) { rec->length = (uint8_t)(HMS1CH_LIST_LEN); - rec->assign = (byteAssign_t *)hms1chAssignment; + rec->assign = reinterpret_cast(const_cast(hms1chAssignment)); rec->pyldLen = HMS1CH_PAYLOAD_LEN; } channels = 1; @@ -541,11 +522,11 @@ class Inverter { else if (INV_TYPE_2CH == type) { if((IV_HM == ivGen) || (IV_MI == ivGen)) { rec->length = (uint8_t)(HM2CH_LIST_LEN); - rec->assign = (byteAssign_t *)hm2chAssignment; + rec->assign = reinterpret_cast(const_cast(hm2chAssignment)); rec->pyldLen = HM2CH_PAYLOAD_LEN; } else if(IV_HMS == ivGen) { rec->length = (uint8_t)(HMS2CH_LIST_LEN); - rec->assign = (byteAssign_t *)hms2chAssignment; + rec->assign = reinterpret_cast(const_cast(hms2chAssignment)); rec->pyldLen = HMS2CH_PAYLOAD_LEN; } channels = 2; @@ -553,18 +534,18 @@ class Inverter { else if (INV_TYPE_4CH == type) { if((IV_HM == ivGen) || (IV_MI == ivGen)) { rec->length = (uint8_t)(HM4CH_LIST_LEN); - rec->assign = (byteAssign_t *)hm4chAssignment; + rec->assign = reinterpret_cast(const_cast(hm4chAssignment)); rec->pyldLen = HM4CH_PAYLOAD_LEN; } else if(IV_HMS == ivGen) { rec->length = (uint8_t)(HMS4CH_LIST_LEN); - rec->assign = (byteAssign_t *)hms4chAssignment; + rec->assign = reinterpret_cast(const_cast(hms4chAssignment)); rec->pyldLen = HMS4CH_PAYLOAD_LEN; } channels = 4; } else if (INV_TYPE_6CH == type) { rec->length = (uint8_t)(HMT6CH_LIST_LEN); - rec->assign = (byteAssign_t *)hmt6chAssignment; + rec->assign = reinterpret_cast(const_cast(hmt6chAssignment)); rec->pyldLen = HMT6CH_PAYLOAD_LEN; channels = 6; } @@ -577,22 +558,22 @@ class Inverter { break; case InverterDevInform_All: rec->length = (uint8_t)(HMINFO_LIST_LEN); - rec->assign = (byteAssign_t *)InfoAssignment; + rec->assign = reinterpret_cast(const_cast(InfoAssignment)); rec->pyldLen = HMINFO_PAYLOAD_LEN; break; case InverterDevInform_Simple: rec->length = (uint8_t)(HMSIMPLE_INFO_LIST_LEN); - rec->assign = (byteAssign_t *)SimpleInfoAssignment; + rec->assign = reinterpret_cast(const_cast(SimpleInfoAssignment)); rec->pyldLen = HMSIMPLE_INFO_PAYLOAD_LEN; break; case SystemConfigPara: rec->length = (uint8_t)(HMSYSTEM_LIST_LEN); - rec->assign = (byteAssign_t *)SystemConfigParaAssignment; + rec->assign = reinterpret_cast(const_cast(SystemConfigParaAssignment)); rec->pyldLen = HMSYSTEM_PAYLOAD_LEN; break; case AlarmData: rec->length = (uint8_t)(HMALARMDATA_LIST_LEN); - rec->assign = (byteAssign_t *)AlarmDataAssignment; + rec->assign = reinterpret_cast(const_cast(AlarmDataAssignment)); rec->pyldLen = HMALARMDATA_PAYLOAD_LEN; break; default: @@ -616,7 +597,7 @@ class Inverter { memset(mLastYD, 0, sizeof(float) * 6); } - bool parseGetLossRate(uint8_t pyld[], uint8_t len) { + bool parseGetLossRate(const uint8_t pyld[], uint8_t len) { if (len == HMGETLOSSRATE_PAYLOAD_LEN) { uint16_t rxCnt = (pyld[0] << 8) + pyld[1]; uint16_t txCnt = (pyld[2] << 8) + pyld[3]; @@ -815,7 +796,7 @@ class Inverter { void addGridProfile(uint8_t buf[], uint8_t length) { mGridLen = (length > MAX_GRID_LENGTH) ? MAX_GRID_LENGTH : length; - std::copy(buf, &buf[mGridLen], mGridProfile); + std::copy(buf, &buf[mGridLen], mGridProfile.data()); } String getGridProfile(void) { @@ -847,9 +828,9 @@ class Inverter { private: float mOffYD[6], mLastYD[6]; - bool mDevControlRequest; // true if change needed + bool mDevControlRequest = false; // true if change needed uint8_t mGridLen = 0; - uint8_t mGridProfile[MAX_GRID_LENGTH]; + std::array mGridProfile; uint8_t mAlarmNxtWrPos = 0; // indicates the position in array (rolling buffer) public: diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index ca96a3330..aef4f49d1 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -52,7 +52,7 @@ class HmRadio : public Radio { mPrintWholeTrace = printWholeTrace; generateDtuSn(); - DTU_RADIO_ID = ((uint64_t)(((mDtuSn >> 24) & 0xFF) | ((mDtuSn >> 8) & 0xFF00) | ((mDtuSn << 8) & 0xFF0000) | ((mDtuSn << 24) & 0xFF000000)) << 8) | 0x01; + mDtuRadioId = ((uint64_t)(((mDtuSn >> 24) & 0xFF) | ((mDtuSn >> 8) & 0xFF00) | ((mDtuSn << 8) & 0xFF0000) | ((mDtuSn << 24) & 0xFF000000)) << 8) | 0x01; #ifdef ESP32 #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(SPI_HAL) @@ -85,7 +85,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(&mDtuRadioId)); mNrf24->maskIRQ(false, false, false); // enable all receiving interrupts mNrf24->setPALevel(1); // low is default @@ -99,7 +99,7 @@ class HmRadio : public Radio { } // returns true if communication is active - bool loop(void) { + bool loop(void) override { if (!mIrqRcvd && !mNRFisInRX) return false; // first quick check => nothing to do at all here @@ -198,11 +198,11 @@ class HmRadio : public Radio { return false; } - bool isChipConnected(void) const { + bool isChipConnected(void) const override { return mNrf24->isChipConnected(); } - void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit) { + void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit) override { DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("sendControlPacket cmd: ")); DBGHEXLN(cmd); @@ -423,15 +423,15 @@ class HmRadio : public Radio { mNRFisInRX = false; } - uint64_t getIvId(Inverter<> *iv) const { + uint64_t getIvId(Inverter<> *iv) const override { return iv->radioId.u64; } - uint8_t getIvGen(Inverter<> *iv) const { + uint8_t getIvGen(Inverter<> *iv) const override { return iv->ivGen; } - inline bool checkIvSerial(uint8_t buf[], Inverter<> *iv) { + inline bool checkIvSerial(const uint8_t buf[], Inverter<> *iv) { for(uint8_t i = 1; i < 5; i++) { if(buf[i] != iv->radioId.b[i]) return false; @@ -439,14 +439,14 @@ class HmRadio : public Radio { return true; } - uint64_t DTU_RADIO_ID; - uint8_t mRfChLst[RF_CHANNELS] = {03, 23, 40, 61, 75}; // channel List:2403, 2423, 2440, 2461, 2475MHz + uint64_t mDtuRadioId = 0ULL; + const uint8_t mRfChLst[RF_CHANNELS] = {03, 23, 40, 61, 75}; // channel List:2403, 2423, 2440, 2461, 2475MHz uint8_t mTxChIdx = 0; uint8_t mRxChIdx = 0; - uint8_t tempRxChIdx = mRxChIdx; + uint8_t tempRxChIdx = 0; bool mGotLastMsg = false; - uint32_t mMillis; - bool tx_ok, tx_fail, rx_ready = false; + uint32_t mMillis = 0; + bool tx_ok = false, tx_fail = false, rx_ready = false; unsigned long mTimeslotStart = 0; unsigned long mLastIrqTime = 0; bool mNRFloopChannels = false; @@ -454,7 +454,6 @@ class HmRadio : public Radio { bool isRxInit = true; bool mRxPendular = false; uint32_t innerLoopTimeout = DURATION_LISTEN_MIN; - //uint8_t mTxSetupTime = 0; uint8_t mTxRetries = 15; // memorize last setting for mNrf24->setRetries(3, 15); std::unique_ptr mSpi; diff --git a/src/hm/hmSystem.h b/src/hm/hmSystem.h index aa2910e54..0266a9485 100644 --- a/src/hm/hmSystem.h +++ b/src/hm/hmSystem.h @@ -98,35 +98,33 @@ class HmSystem { #ifdef DYNAMIC_OFFSET iv->rxOffset = (iv->ivGen == IV_HM) ? 13 : 12; // effective 3 (or 2), but can easily be recognized as default setting #else - iv->rxOffset = ((iv->ivGen == IV_HM) && (iv->type == INV_TYPE_4CH)) ? 3 : 2; + //iv->rxOffset = ((iv->ivGen == IV_HM) && (iv->type == INV_TYPE_4CH)) ? 3 : 2; iv->rxOffset = (iv->ivGen == IV_HM) ? 3 : 2; #endif cb(iv); } - INVERTERTYPE *findInverter(uint8_t buf[]) { - DPRINTLN(DBG_VERBOSE, F("hmSystem.h:findInverter")); - INVERTERTYPE *p; + INVERTERTYPE *findInverter(const uint8_t buf[]) { for(uint8_t i = 0; i < MAX_INVERTER; i++) { - p = &mInverter[i]; + INVERTERTYPE *p = &mInverter[i]; if((p->config->serial.b[3] == buf[0]) && (p->config->serial.b[2] == buf[1]) && (p->config->serial.b[1] == buf[2]) && (p->config->serial.b[0] == buf[3])) return p; } - return NULL; + return nullptr; } INVERTERTYPE *getInverterByPos(uint8_t pos, bool check = true) { DPRINTLN(DBG_VERBOSE, F("hmSystem.h:getInverterByPos")); if(pos >= MAX_INVERTER) - return NULL; + return nullptr; else if((mInverter[pos].config->serial.u64 != 0ULL) || (false == check)) return &mInverter[pos]; else - return NULL; + return nullptr; } uint8_t getNumInverters(void) { diff --git a/src/hm/nrfHal.h b/src/hm/nrfHal.h index 0532a5240..b9265626c 100644 --- a/src/hm/nrfHal.h +++ b/src/hm/nrfHal.h @@ -142,7 +142,7 @@ class nrfHal: public RF24_hal, public SpiPatcherHandle { } uint8_t read(uint8_t cmd, uint8_t* buf, uint8_t len) override { - uint8_t data[NRF_MAX_TRANSFER_SZ]; + uint8_t data[NRF_MAX_TRANSFER_SZ + 1]; data[0] = cmd; if(len > NRF_MAX_TRANSFER_SZ) len = NRF_MAX_TRANSFER_SZ; diff --git a/src/hm/radio.h b/src/hm/radio.h index 7bbb42bc8..db694b545 100644 --- a/src/hm/radio.h +++ b/src/hm/radio.h @@ -11,6 +11,7 @@ #define ALL_FRAMES 0x80 #define SINGLE_FRAME 0x81 +#include #include "../utils/dbg.h" #include "../utils/crc.h" #include "../utils/timemonitor.h" @@ -119,9 +120,8 @@ class Radio { #endif mDtuSn = 0; - uint8_t t; for(int i = 0; i < (7 << 2); i += 4) { - t = (chipID >> i) & 0x0f; + uint8_t t = (chipID >> i) & 0x0f; if(t > 0x09) t -= 6; mDtuSn |= (t << i); @@ -132,8 +132,8 @@ class Radio { uint32_t mDtuSn; - volatile bool mIrqRcvd; - bool *mSerialDebug, *mPrivacyMode, *mPrintWholeTrace; + std::atomic mIrqRcvd; + bool *mSerialDebug = nullptr, *mPrivacyMode = nullptr, *mPrintWholeTrace = nullptr; uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE]; }; diff --git a/src/hms/cmt2300a.h b/src/hms/cmt2300a.h index e6456f5bf..23911b157 100644 --- a/src/hms/cmt2300a.h +++ b/src/hms/cmt2300a.h @@ -529,7 +529,8 @@ class Cmt2300a { return false; } - inline bool switchDtuFreq(const uint32_t freqKhz) { + // maybe used in future + /*inline bool switchDtuFreq(const uint32_t freqKhz) { uint8_t toCh = freq2Chan(freqKhz); if(0xff == toCh) return false; @@ -537,7 +538,7 @@ class Cmt2300a { switchChannel(toCh); return true; - } + }*/ inline uint8_t getChipStatus(void) { return mSpi.readReg(CMT2300A_CUS_MODE_STA) & CMT2300A_MASK_CHIP_MODE_STA; @@ -549,11 +550,11 @@ class Cmt2300a { #else esp32_3wSpi mSpi; #endif - uint8_t mCnt; - bool mTxPending; - bool mInRxMode; - uint8_t mCusIntFlag; - uint8_t mRqstCh, mCurCh; + uint8_t mCnt = 0; + bool mTxPending = false; + bool mInRxMode = false; + uint8_t mCusIntFlag = 0; + uint8_t mRqstCh = 0, mCurCh = 0; RegionCfg mRegionCfg = RegionCfg::EUROPE; }; diff --git a/src/hms/cmtHal.h b/src/hms/cmtHal.h index 768b8da5a..a4bec5870 100644 --- a/src/hms/cmtHal.h +++ b/src/hms/cmtHal.h @@ -89,7 +89,7 @@ class cmtHal : public SpiPatcherHandle { } uint8_t readReg(uint8_t addr) { - uint8_t data; + uint8_t data = 0; request_spi(); diff --git a/src/hms/esp32_3wSpi.h b/src/hms/esp32_3wSpi.h index c562671a9..a0366b238 100644 --- a/src/hms/esp32_3wSpi.h +++ b/src/hms/esp32_3wSpi.h @@ -10,6 +10,7 @@ #if defined(ESP32) #include "driver/spi_master.h" #include "esp_rom_gpio.h" // for esp_rom_gpio_connect_out_signal +#include "../config/config.h" #define SPI_CLK 1 * 1000 * 1000 // 1MHz @@ -104,7 +105,7 @@ class esp32_3wSpi { if(!mInitialized) return 0; - uint8_t rx_data; + uint8_t rx_data = 0; spi_transaction_t t = { .cmd = 0, .addr = (uint64_t)(~addr), @@ -121,7 +122,7 @@ class esp32_3wSpi { return rx_data; } - void writeFifo(uint8_t buf[], uint8_t len) { + void writeFifo(const uint8_t buf[], uint8_t len) { if(!mInitialized) return; uint8_t tx_data; @@ -144,7 +145,7 @@ class esp32_3wSpi { void readFifo(uint8_t buf[], uint8_t *len, uint8_t maxlen) { if(!mInitialized) return; - uint8_t rx_data; + uint8_t rx_data = 0; spi_transaction_t t = { .length = 8, diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index 0fa1b6ab1..66e312d7b 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -15,10 +15,6 @@ template class CmtRadio : public Radio { typedef Cmt2300a CmtType; public: - CmtRadio() { - mDtuSn = DTU_SN; - } - void setup(bool *serialDebug, bool *privacyMode, bool *printWholeTrace, uint8_t pinSclk, uint8_t pinSdio, uint8_t pinCsb, uint8_t pinFcsb, uint8_t region = 0, bool genDtuSn = true) { mCmt.setup(pinSclk, pinSdio, pinCsb, pinFcsb); reset(genDtuSn, static_cast(region)); @@ -27,7 +23,7 @@ class CmtRadio : public Radio { mPrintWholeTrace = printWholeTrace; } - bool loop() { + bool loop() override { mCmt.loop(); if((!mIrqRcvd) && (!mRqstGetRx)) return false; @@ -39,11 +35,11 @@ class CmtRadio : public Radio { return false; } - bool isChipConnected(void) const { + bool isChipConnected(void) const override { return mCmtAvail; } - void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit) { + void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit) override { DPRINT(DBG_INFO, F("sendControlPacket cmd: ")); DBGHEXLN(cmd); initPacket(iv->radioId.u64, TX_REQ_DEVCONTROL, SINGLE_FRAME); @@ -61,14 +57,14 @@ class CmtRadio : public Radio { sendPacket(iv, cnt, isRetransmit); } - bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) { + bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) override { uint8_t fromCh = mCmt.freq2Chan(fromkHz); uint8_t toCh = mCmt.freq2Chan(tokHz); return switchFrequencyCh(iv, fromCh, toCh); } - bool switchFrequencyCh(Inverter<> *iv, uint8_t fromCh, uint8_t toCh) { + bool switchFrequencyCh(Inverter<> *iv, uint8_t fromCh, uint8_t toCh) override { if((0xff == fromCh) || (0xff == toCh)) return false; @@ -92,7 +88,7 @@ class CmtRadio : public Radio { private: - void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) { + void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) override { // inverters have maybe different settings regarding frequency if(mCmt.getCurrentChannel() != iv->config->frequency) mCmt.switchChannel(iv->config->frequency); @@ -129,11 +125,11 @@ class CmtRadio : public Radio { iv->mDtuTxCnt++; } - uint64_t getIvId(Inverter<> *iv) const { + uint64_t getIvId(Inverter<> *iv) const override { return iv->radioId.u64; } - uint8_t getIvGen(Inverter<> *iv) const { + uint8_t getIvGen(Inverter<> *iv) const override { return iv->ivGen; } @@ -180,6 +176,7 @@ class CmtRadio : public Radio { p.millis = millis() - mMillis; if(CmtStatus::SUCCESS == mCmt.getRx(p.packet, &p.len, 28, &p.rssi)) { mSwitchCycle = 0; + p.ch = 0; // not used for CMT inverters mBufCtrl.push(p); } @@ -187,14 +184,12 @@ class CmtRadio : public Radio { setExpectedFrames(p.packet[9] - ALL_FRAMES); mRadioWaitTime.startTimeMonitor(DURATION_PAUSE_LASTFR); // let the inverter first get back to rx mode? } - // optionally instead: - // mRadioWaitTime.stopTimeMonitor(); // we got everything we expected and can exit rx mode... } CmtType mCmt; bool mCmtAvail = false; bool mRqstGetRx = false; - uint32_t mMillis; + uint32_t mMillis = 0; uint8_t mSwitchCycle = 0; }; diff --git a/src/plugins/Display/Display.h b/src/plugins/Display/Display.h index 862e452b4..c59a56b62 100644 --- a/src/plugins/Display/Display.h +++ b/src/plugins/Display/Display.h @@ -192,15 +192,14 @@ class Display { if ((mCfg->screenSaver == 2) && (mCfg->pirPin != DEF_PIN_OFF)) { #if defined(ESP8266) if (mCfg->pirPin == A0) - return((analogRead(A0) >= 512)); + return (analogRead(A0) >= 512); else - return(digitalRead(mCfg->pirPin)); + return digitalRead(mCfg->pirPin); #elif defined(ESP32) - return(digitalRead(mCfg->pirPin)); + return digitalRead(mCfg->pirPin); #endif - } - else - return(false); + } else + return false; } // approximate RSSI in dB by invQuality levels from heuristic function (very unscientific but better than nothing :-) ) diff --git a/src/plugins/Display/Display_Mono.h b/src/plugins/Display/Display_Mono.h index 2c1fc9354..e855eeb9a 100644 --- a/src/plugins/Display/Display_Mono.h +++ b/src/plugins/Display/Display_Mono.h @@ -24,8 +24,6 @@ class DisplayMono { public: - DisplayMono() {}; - virtual void init(DisplayData *displayData) = 0; virtual void config(display_t *cfg) = 0; virtual void disp(void) = 0; @@ -289,11 +287,11 @@ class DisplayMono { DispSwitchState mDispSwitchState = DispSwitchState::TEXT; uint16_t mDispWidth; - uint8_t mExtra; + uint8_t mExtra = 0; int8_t mPixelshift=0; char mFmtText[DISP_FMT_TEXT_LEN]; - uint8_t mLineXOffsets[5] = {}; - uint8_t mLineYOffsets[5] = {}; + uint8_t mLineXOffsets[5] = {0, 0, 0, 0, 0}; + uint8_t mLineYOffsets[5] = {0, 0, 0, 0, 0}; uint8_t mPgWidth = 0; @@ -308,8 +306,8 @@ class DisplayMono { uint32_t mPgLastTime = 0; PowerGraphState mPgState = PowerGraphState::NO_TIME_SYNC; - uint16_t mDispHeight; - uint8_t mLuminance; + uint16_t mDispHeight = 0; + uint8_t mLuminance = 0; TimeMonitor mDisplayTime = TimeMonitor(1000 * DISP_DEFAULT_TIMEOUT, true); TimeMonitor mDispSwitchTime = TimeMonitor(); diff --git a/src/plugins/history.h b/src/plugins/history.h index 7a9382847..7e4156758 100644 --- a/src/plugins/history.h +++ b/src/plugins/history.h @@ -24,23 +24,15 @@ template class HistoryData { private: struct storage_t { - uint16_t refreshCycle; - uint16_t loopCnt; - uint16_t listIdx; // index for next Element to write into WattArr - uint16_t dispIdx; // index for 1st Element to display from WattArr - bool wrapped; + uint16_t refreshCycle = 0; + uint16_t loopCnt = 0; + uint16_t listIdx = 0; // index for next Element to write into WattArr + uint16_t dispIdx = 0; // index for 1st Element to display from WattArr + bool wrapped = false; // ring buffer for watt history std::array data; - void reset() { - loopCnt = 0; - listIdx = 0; - dispIdx = 0; - wrapped = false; - for(uint16_t i = 0; i < (HISTORY_DATA_ARR_LENGTH + 1); i++) { - data[i] = 0; - } - } + storage_t() { data.fill(0); } }; public: @@ -50,9 +42,7 @@ class HistoryData { mConfig = config; mTs = ts; - mCurPwr.reset(); mCurPwr.refreshCycle = mConfig->inst.sendInterval; - //mYieldDay.reset(); //mYieldDay.refreshCycle = 60; } @@ -113,14 +103,13 @@ class HistoryData { } private: - IApp *mApp; - HMSYSTEM *mSys; - settings *mSettings; - settings_t *mConfig; - uint32_t *mTs; + IApp *mApp = nullptr; + HMSYSTEM *mSys = nullptr; + settings *mSettings = nullptr; + settings_t *mConfig = nullptr; + uint32_t *mTs = nullptr; storage_t mCurPwr; - //storage_t mYieldDay; bool mDayStored = false; uint16_t mMaximumDay = 0; }; diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index 865c76b5a..7799b6d27 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -15,6 +15,7 @@ #include #endif +#include #include "../utils/dbg.h" #include "../config/config.h" #include @@ -38,12 +39,15 @@ template class PubMqtt { public: PubMqtt() { - mRxCnt = 0; - mTxCnt = 0; - mSubscriptionCb = NULL; - memset(mLastIvState, (uint8_t)InverterStatus::OFF, MAX_NUM_INVERTERS); - memset(mIvLastRTRpub, 0, MAX_NUM_INVERTERS * 4); - mLastAnyAvail = false; + mLastIvState.fill(InverterStatus::OFF); + mIvLastRTRpub.fill(0); + + mVal.fill(0); + mTopic.fill(0); + mSubTopic.fill(0); + mClientId.fill(0); + mLwtTopic.fill(0); + mSendAlarm.fill(false); } ~PubMqtt() { } @@ -63,16 +67,16 @@ class PubMqtt { }); mDiscovery.running = false; - snprintf(mLwtTopic, MQTT_TOPIC_LEN + 5, "%s/mqtt", mCfgMqtt->topic); + snprintf(mLwtTopic.data(), mLwtTopic.size(), "%s/mqtt", mCfgMqtt->topic); if((strlen(mCfgMqtt->user) > 0) && (strlen(mCfgMqtt->pwd) > 0)) mClient.setCredentials(mCfgMqtt->user, mCfgMqtt->pwd); if(strlen(mCfgMqtt->clientId) > 0) - snprintf(mClientId, 23, "%s", mCfgMqtt->clientId); + snprintf(mClientId.data(), mClientId.size(), "%s", mCfgMqtt->clientId); else { - snprintf(mClientId, 23, "%s-", mDevName); - uint8_t pos = strlen(mClientId); + snprintf(mClientId.data(), mClientId.size(), "%s-", mDevName); + uint8_t pos = strlen(mClientId.data()); mClientId[pos++] = WiFi.macAddress().substring( 9, 10).c_str()[0]; mClientId[pos++] = WiFi.macAddress().substring(10, 11).c_str()[0]; mClientId[pos++] = WiFi.macAddress().substring(12, 13).c_str()[0]; @@ -82,9 +86,9 @@ class PubMqtt { mClientId[pos++] = '\0'; } - mClient.setClientId(mClientId); + mClient.setClientId(mClientId.data()); mClient.setServer(mCfgMqtt->broker, mCfgMqtt->port); - mClient.setWill(mLwtTopic, QOS_0, true, mqttStr[MQTT_STR_LWT_NOT_CONN]); + mClient.setWill(mLwtTopic.data(), QOS_0, true, mqttStr[MQTT_STR_LWT_NOT_CONN]); mClient.onConnect(std::bind(&PubMqtt::onConnect, this, std::placeholders::_1)); mClient.onDisconnect(std::bind(&PubMqtt::onDisconnect, this, std::placeholders::_1)); mClient.onMessage(std::bind(&PubMqtt::onMessage, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6)); @@ -125,8 +129,8 @@ class PubMqtt { } void tickerMinute() { - snprintf(mVal, 40, "%d", (*mUptime)); - publish(subtopics[MQTT_UPTIME], mVal); + snprintf(mVal.data(), mVal.size(), "%u", (*mUptime)); + publish(subtopics[MQTT_UPTIME], mVal.data()); publish(subtopics[MQTT_RSSI], String(WiFi.RSSI()).c_str()); publish(subtopics[MQTT_FREE_HEAP], String(ESP.getFreeHeap()).c_str()); #ifndef ESP32 @@ -143,18 +147,17 @@ class PubMqtt { publish(subtopics[MQTT_COMM_START], String(sunrise + offsM).c_str(), true); publish(subtopics[MQTT_COMM_STOP], String(sunset + offsE).c_str(), true); - Inverter<> *iv; for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { - iv = mSys->getInverterByPos(i); + Inverter<> *iv = mSys->getInverterByPos(i); if(NULL == iv) continue; - snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/dis_night_comm", iv->config->name); - publish(mSubTopic, ((iv->commEnabled) ? dict[STR_TRUE] : dict[STR_FALSE]), true); + snprintf(mSubTopic.data(), mSubTopic.size(), "%s/dis_night_comm", iv->config->name); + publish(mSubTopic.data(), ((iv->commEnabled) ? dict[STR_TRUE] : dict[STR_FALSE]), true); } - snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "comm_disabled"); - publish(mSubTopic, (((*mUtcTimestamp > (sunset + offsE)) || (*mUtcTimestamp < (sunrise + offsM))) ? dict[STR_TRUE] : dict[STR_FALSE]), true); + snprintf(mSubTopic.data(), mSubTopic.size(), "comm_disabled"); + publish(mSubTopic.data(), (((*mUtcTimestamp > (sunset + offsE)) || (*mUtcTimestamp < (sunrise + offsM))) ? dict[STR_TRUE] : dict[STR_FALSE]), true); return true; } @@ -176,9 +179,9 @@ class PubMqtt { void tickerMidnight() { // set Total YieldDay to zero - snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "total/%s", fields[FLD_YD]); - snprintf(mVal, 2, "0"); - publish(mSubTopic, mVal, true); + snprintf(mSubTopic.data(), mSubTopic.size(), "total/%s", fields[FLD_YD]); + snprintf(mVal.data(), mVal.size(), "0"); + publish(mSubTopic.data(), mVal.data(), true); } void payloadEventListener(uint8_t cmd, Inverter<> *iv) { @@ -197,11 +200,11 @@ class PubMqtt { return; if(addTopic) - snprintf(mTopic, MQTT_TOPIC_LEN + 32 + MAX_NAME_LENGTH + 1, "%s/%s", mCfgMqtt->topic, subTopic); + snprintf(mTopic.data(), mTopic.size(), "%s/%s", mCfgMqtt->topic, subTopic); else - snprintf(mTopic, MQTT_TOPIC_LEN + 32 + MAX_NAME_LENGTH + 1, "%s", subTopic); + snprintf(mTopic.data(), mTopic.size(), "%s", subTopic); - mClient.publish(mTopic, qos, retained, payload); + mClient.publish(mTopic.data(), qos, retained, payload); yield(); mTxCnt++; } @@ -238,8 +241,8 @@ class PubMqtt { void setPowerLimitAck(Inverter<> *iv) { if (NULL != iv) { - snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/%s", iv->config->name, subtopics[MQTT_ACK_PWR_LMT]); - publish(mSubTopic, "true", true, true, QOS_2); + snprintf(mSubTopic.data(), mSubTopic.size(), "%s/%s", iv->config->name, subtopics[MQTT_ACK_PWR_LMT]); + publish(mSubTopic.data(), "true", true, true, QOS_2); } } @@ -255,15 +258,15 @@ class PubMqtt { publish(subtopics[MQTT_IP_ADDR], WiFi.localIP().toString().c_str(), true); #endif tickerMinute(); - publish(mLwtTopic, mqttStr[MQTT_STR_LWT_CONN], true, false); + publish(mLwtTopic.data(), mqttStr[MQTT_STR_LWT_CONN], true, false); for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { - snprintf(mVal, 20, "ctrl/limit/%d", i); - subscribe(mVal, QOS_2); - snprintf(mVal, 20, "ctrl/restart/%d", i); - subscribe(mVal); - snprintf(mVal, 20, "ctrl/power/%d", i); - subscribe(mVal); + snprintf(mVal.data(), mVal.size(), "ctrl/limit/%d", i); + subscribe(mVal.data(), QOS_2); + snprintf(mVal.data(), mVal.size(), "ctrl/restart/%d", i); + subscribe(mVal.data()); + snprintf(mVal.data(), mVal.size(), "ctrl/power/%d", i); + subscribe(mVal.data()); } subscribe(subscr[MQTT_SUBS_SET_TIME]); } @@ -359,11 +362,9 @@ class PubMqtt { } void discoveryConfigLoop(void) { - char topic[64], name[32], uniq_id[32], buf[350]; DynamicJsonDocument doc(256); - uint8_t fldTotal[4] = {FLD_PAC, FLD_YT, FLD_YD, FLD_PDC}; - const char* unitTotal[4] = {"W", "kWh", "Wh", "W"}; + constexpr static uint8_t fldTotal[] = {FLD_PAC, FLD_YT, FLD_YD, FLD_PDC}; String node_id = String(mDevName) + "_TOTAL"; bool total = (mDiscovery.lastIvId == MAX_NUM_INVERTERS); @@ -392,32 +393,37 @@ class PubMqtt { doc[F("mf")] = F("Hoymiles"); JsonObject deviceObj = doc.as(); // deviceObj is only pointer!? + std::array topic; + std::array name; + std::array uniq_id; + std::array buf; const char *devCls, *stateCls; if (!total) { if (rec->assign[mDiscovery.sub].ch == CH0) - snprintf(name, 32, "%s", iv->getFieldName(mDiscovery.sub, rec)); + snprintf(name.data(), name.size(), "%s", iv->getFieldName(mDiscovery.sub, rec)); else - snprintf(name, 32, "CH%d_%s", rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec)); - snprintf(topic, 64, "/ch%d/%s", rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec)); - snprintf(uniq_id, 32, "ch%d_%s", rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec)); + snprintf(name.data(), name.size(), "CH%d_%s", rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec)); + snprintf(topic.data(), name.size(), "/ch%d/%s", rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec)); + snprintf(uniq_id.data(), uniq_id.size(), "ch%d_%s", rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec)); devCls = getFieldDeviceClass(rec->assign[mDiscovery.sub].fieldId); stateCls = getFieldStateClass(rec->assign[mDiscovery.sub].fieldId); } else { // total values - snprintf(name, 32, "Total %s", fields[fldTotal[mDiscovery.sub]]); - snprintf(topic, 64, "/%s", fields[fldTotal[mDiscovery.sub]]); - snprintf(uniq_id, 32, "total_%s", fields[fldTotal[mDiscovery.sub]]); + snprintf(name.data(), name.size(), "Total %s", fields[fldTotal[mDiscovery.sub]]); + snprintf(topic.data(), topic.size(), "/%s", fields[fldTotal[mDiscovery.sub]]); + snprintf(uniq_id.data(), uniq_id.size(), "total_%s", fields[fldTotal[mDiscovery.sub]]); devCls = getFieldDeviceClass(fldTotal[mDiscovery.sub]); stateCls = getFieldStateClass(fldTotal[mDiscovery.sub]); } DynamicJsonDocument doc2(512); + constexpr static char* unitTotal[] = {"W", "kWh", "Wh", "W"}; doc2[F("name")] = name; - doc2[F("stat_t")] = String(mCfgMqtt->topic) + "/" + ((!total) ? String(iv->config->name) : "total" ) + String(topic); + doc2[F("stat_t")] = String(mCfgMqtt->topic) + "/" + ((!total) ? String(iv->config->name) : "total" ) + String(topic.data()); doc2[F("unit_of_meas")] = ((!total) ? (iv->getUnit(mDiscovery.sub, rec)) : (unitTotal[mDiscovery.sub])); - doc2[F("uniq_id")] = ((!total) ? (String(iv->config->serial.u64, HEX)) : (node_id)) + "_" + uniq_id; + doc2[F("uniq_id")] = ((!total) ? (String(iv->config->serial.u64, HEX)) : (node_id)) + "_" + uniq_id.data(); doc2[F("dev")] = deviceObj; if (!(String(stateCls) == String("total_increasing"))) doc2[F("exp_aft")] = MQTT_INTERVAL + 5; // add 5 sec if connection is bad or ESP too slow @TODO: stimmt das wirklich als expire!? @@ -427,13 +433,13 @@ class PubMqtt { doc2[F("stat_cla")] = String(stateCls); if (!total) - snprintf(topic, 64, "%s/sensor/%s/ch%d_%s/config", MQTT_DISCOVERY_PREFIX, iv->config->name, rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec)); + snprintf(topic.data(), topic.size(), "%s/sensor/%s/ch%d_%s/config", MQTT_DISCOVERY_PREFIX, iv->config->name, rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec)); else // total values - snprintf(topic, 64, "%s/sensor/%s/total_%s/config", MQTT_DISCOVERY_PREFIX, node_id.c_str(), fields[fldTotal[mDiscovery.sub]]); + snprintf(topic.data(), topic.size(), "%s/sensor/%s/total_%s/config", MQTT_DISCOVERY_PREFIX, node_id.c_str(), fields[fldTotal[mDiscovery.sub]]); size_t size = measureJson(doc2) + 1; - memset(buf, 0, size); - serializeJson(doc2, buf, size); - publish(topic, buf, true, false); + buf.fill(0); + serializeJson(doc2, buf.data(), size); + publish(topic.data(), buf.data(), true, false); if(++mDiscovery.sub == ((!total) ? (rec->length) : 4)) { mDiscovery.sub = 0; @@ -503,15 +509,15 @@ class PubMqtt { mLastIvState[id] = status; changed = true; - snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/available", iv->config->name); - snprintf(mVal, 40, "%d", (uint8_t)status); - publish(mSubTopic, mVal, true); + snprintf(mSubTopic.data(), mSubTopic.size(), "%s/available", iv->config->name); + snprintf(mVal.data(), mVal.size(), "%d", (uint8_t)status); + publish(mSubTopic.data(), mVal.data(), true); } } if(changed) { - snprintf(mVal, 32, "%d", ((allAvail) ? MQTT_STATUS_ONLINE : ((anyAvail) ? MQTT_STATUS_PARTIAL : MQTT_STATUS_OFFLINE))); - publish("status", mVal, true); + snprintf(mVal.data(), mVal.size(), "%d", ((allAvail) ? MQTT_STATUS_ONLINE : ((anyAvail) ? MQTT_STATUS_PARTIAL : MQTT_STATUS_OFFLINE))); + publish("status", mVal.data(), true); } return anyAvail; @@ -533,19 +539,19 @@ class PubMqtt { mSendAlarm[i] = false; - snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/alarm/cnt", iv->config->name); - snprintf(mVal, 40, "%d", iv->alarmCnt); - publish(mSubTopic, mVal, false); + snprintf(mSubTopic.data(), mSubTopic.size(), "%s/alarm/cnt", iv->config->name); + snprintf(mVal.data(), mVal.size(), "%d", iv->alarmCnt); + publish(mSubTopic.data(), mVal.data(), false); for(uint8_t j = 0; j < 10; j++) { if(0 != iv->lastAlarm[j].code) { - snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/alarm/%d", iv->config->name, j); - snprintf(mVal, 100, "{\"code\":%d,\"str\":\"%s\",\"start\":%d,\"end\":%d}", + snprintf(mSubTopic.data(), mSubTopic.size(), "%s/alarm/%d", iv->config->name, j); + snprintf(mVal.data(), mVal.size(), "{\"code\":%d,\"str\":\"%s\",\"start\":%d,\"end\":%d}", iv->lastAlarm[j].code, iv->getAlarmStr(iv->lastAlarm[j].code).c_str(), iv->lastAlarm[j].start + lastMidnight, iv->lastAlarm[j].end + lastMidnight); - publish(mSubTopic, mVal, false); + publish(mSubTopic.data(), mVal.data(), false); yield(); } } @@ -575,9 +581,9 @@ class PubMqtt { } } - snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/ch%d/%s", iv->config->name, rec->assign[i].ch, fields[rec->assign[i].fieldId]); - snprintf(mVal, 40, "%g", ah::round3(iv->getValue(i, rec))); - publish(mSubTopic, mVal, retained); + snprintf(mSubTopic.data(), mSubTopic.size(), "%s/ch%d/%s", iv->config->name, rec->assign[i].ch, fields[rec->assign[i].fieldId]); + snprintf(mVal.data(), mVal.size(), "%g", ah::round3(iv->getValue(i, rec))); + publish(mSubTopic.data(), mVal.data(), retained); yield(); } @@ -597,33 +603,33 @@ class PubMqtt { } espMqttClient mClient; - cfgMqtt_t *mCfgMqtt; + cfgMqtt_t *mCfgMqtt = nullptr; #if defined(ESP8266) WiFiEventHandler mHWifiCon, mHWifiDiscon; #endif - HMSYSTEM *mSys; + HMSYSTEM *mSys = nullptr; PubMqttIvData mSendIvData; - uint32_t *mUtcTimestamp, *mUptime; - uint32_t mRxCnt, mTxCnt; + uint32_t *mUtcTimestamp = nullptr, *mUptime = nullptr; + uint32_t mRxCnt = 0, mTxCnt = 0; std::queue mSendList; - std::array mSendAlarm{}; - subscriptionCb mSubscriptionCb; - bool mLastAnyAvail; - InverterStatus mLastIvState[MAX_NUM_INVERTERS]; - uint32_t mIvLastRTRpub[MAX_NUM_INVERTERS]; - uint16_t mIntervalTimeout; + std::array mSendAlarm; + subscriptionCb mSubscriptionCb = nullptr; + bool mLastAnyAvail = false; + std::array mLastIvState; + std::array mIvLastRTRpub; + uint16_t mIntervalTimeout = 0; // last will topic and payload must be available through lifetime of 'espMqttClient' - char mLwtTopic[MQTT_TOPIC_LEN+5]; - const char *mDevName, *mVersion; - char mClientId[24]; // number of chars is limited to 23 up to v3.1 of MQTT + std::array mLwtTopic; + const char *mDevName = nullptr, *mVersion = nullptr; + std::array mClientId; // number of chars is limited to 23 up to v3.1 of MQTT // global buffer for mqtt topic. Used when publishing mqtt messages. - char mTopic[MQTT_TOPIC_LEN + 32 + MAX_NAME_LENGTH + 1]; - char mSubTopic[32 + MAX_NAME_LENGTH + 1]; - char mVal[100]; - discovery_t mDiscovery; + std::array mTopic; + std::array mSubTopic; + std::array mVal; + discovery_t mDiscovery = {true, 0, 0, 0}; }; #endif /*ENABLE_MQTT*/ diff --git a/src/publisher/pubMqttIvData.h b/src/publisher/pubMqttIvData.h index cfed38b92..4405d037c 100644 --- a/src/publisher/pubMqttIvData.h +++ b/src/publisher/pubMqttIvData.h @@ -205,9 +205,9 @@ class PubMqttIvData { } void stateSendTotals() { - uint8_t fieldId; mRTRDataHasBeenSent = true; if(mPos < 5) { + uint8_t fieldId; bool retained = true; switch (mPos) { default: diff --git a/src/publisher/pubSerial.h b/src/publisher/pubSerial.h index 34dc64f26..9ac245931 100644 --- a/src/publisher/pubSerial.h +++ b/src/publisher/pubSerial.h @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- -// 2022 Ahoy, https://ahoydtu.de -// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ +// 2024 Ahoy, https://github.com/lumpapu/ahoy +// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed //----------------------------------------------------------------------------- #ifndef __PUB_SERIAL_H__ @@ -13,8 +13,6 @@ template class PubSerial { public: - PubSerial() {} - void setup(settings_t *cfg, HMSYSTEM *sys, uint32_t *utcTs) { mCfg = cfg; mSys = sys; @@ -46,9 +44,9 @@ class PubSerial { } private: - settings_t *mCfg; - HMSYSTEM *mSys; - uint32_t *mUtcTimestamp; + settings_t *mCfg = nullptr; + HMSYSTEM *mSys = nullptr; + uint32_t *mUtcTimestamp = nullptr; }; diff --git a/src/utils/improv.h b/src/utils/improv.h index d5a9ae743..32bc403c1 100644 --- a/src/utils/improv.h +++ b/src/utils/improv.h @@ -10,6 +10,7 @@ #include #include "dbg.h" #include "AsyncJson.h" +#include "../appInterface.h" // https://www.improv-wifi.com/serial/ // https://github.com/jnthas/improv-wifi-demo/blob/main/src/esp32-wifiimprov/esp32-wifiimprov.ino @@ -78,7 +79,7 @@ class Improv { DBGPRINTLN(""); } - inline uint8_t buildChecksum(uint8_t buf[], uint8_t len) { + inline uint8_t buildChecksum(const uint8_t buf[], uint8_t len) { uint8_t calc = 0; for(uint8_t i = 0; i < len; i++) { calc += buf[i]; @@ -86,7 +87,7 @@ class Improv { return calc; } - inline bool checkChecksum(uint8_t buf[], uint8_t len) { + inline bool checkChecksum(const uint8_t buf[], uint8_t len) { /*DHEX(buf[len], false); DBGPRINT(F(" == "), false); DBGHEXLN(buildChecksum(buf, len), false);*/ @@ -97,7 +98,7 @@ class Improv { if(len < 11) return false; - if(0 != strncmp((char*)buf, "IMPROV", 6)) + if(0 != strncmp(reinterpret_cast(buf), "IMPROV", 6)) return false; // version check (only version 1 is supported!) @@ -199,7 +200,7 @@ class Improv { dumpBuf(buf, len); } - void parsePayload(uint8_t type, uint8_t buf[], uint8_t len) { + void parsePayload(uint8_t type, const uint8_t buf[], uint8_t len) { if(TYPE_RPC == type) { if(GET_CURRENT_STATE == buf[0]) { setDebugEn(false); @@ -212,9 +213,10 @@ class Improv { } } - IApp *mApp; - const char *mDevName, *mVersion; - bool mScanRunning; + IApp *mApp = nullptr; + const char *mDevName = nullptr; + const char *mVersion = nullptr; + bool mScanRunning = false; }; #endif diff --git a/src/utils/scheduler.h b/src/utils/scheduler.h index 751550df8..160097787 100644 --- a/src/utils/scheduler.h +++ b/src/utils/scheduler.h @@ -7,6 +7,7 @@ #define __SCHEDULER_H__ #include +#include #include "dbg.h" namespace ah { @@ -28,8 +29,6 @@ namespace ah { class Scheduler { public: - Scheduler() {} - void setup(bool directStart) { mUptime = 0; mTimestamp = (directStart) ? 1 : 0; @@ -93,8 +92,7 @@ namespace ah { } inline void resetTicker(void) { - for (uint8_t i = 0; i < MAX_NUM_TICKER; i++) - mTickerInUse[i] = false; + mTickerInUse.fill(false); } void getStat(uint8_t *max) { @@ -159,11 +157,11 @@ namespace ah { } } - sP mTicker[MAX_NUM_TICKER]; - bool mTickerInUse[MAX_NUM_TICKER]; - uint32_t mMillis, mPrevMillis, mDiff; - uint8_t mDiffSeconds; - uint8_t mMax; + std::array mTicker; + std::array mTickerInUse; + uint32_t mMillis = 0, mPrevMillis = 0, mDiff = 0; + uint8_t mDiffSeconds = 0; + uint8_t mMax = 0; }; } diff --git a/src/utils/spiPatcher.h b/src/utils/spiPatcher.h index 2f8ce616f..210b2a094 100644 --- a/src/utils/spiPatcher.h +++ b/src/utils/spiPatcher.h @@ -16,7 +16,7 @@ class SpiPatcher { protected: - SpiPatcher(spi_host_device_t dev) : + explicit SpiPatcher(spi_host_device_t dev) : mHostDevice(dev), mCurHandle(nullptr) { // Use binary semaphore instead of mutex for performance reasons mutex = xSemaphoreCreateBinaryStatic(&mutex_buffer); diff --git a/src/utils/timemonitor.h b/src/utils/timemonitor.h index 9f99cc92f..18ab51d96 100644 --- a/src/utils/timemonitor.h +++ b/src/utils/timemonitor.h @@ -22,14 +22,14 @@ class TimeMonitor { /** * A constructor for creating a TimeMonitor object */ - TimeMonitor(void) {} + TimeMonitor() {} /** * A constructor for initializing a TimeMonitor object * @param timeout timeout in ms * @param start (optional) if true, start TimeMonitor immediately */ - TimeMonitor(uint32_t timeout, bool start = false) { + explicit TimeMonitor(uint32_t timeout, bool start = false) { if (start) startTimeMonitor(timeout); else @@ -80,7 +80,7 @@ class TimeMonitor { * true: TimeMonitor already timed out * false: TimeMonitor still in time or TimeMonitor was stopped */ - bool isTimeout(void) { + bool isTimeout(void) const { if ((mStarted) && ((millis() - mStartTime) >= mTimeout)) return true; else diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 564d6c622..acd085f3c 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -141,7 +141,7 @@ class RestApi { #endif } - void onApiPostBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) { + void onApiPostBody(AsyncWebServerRequest *request, const uint8_t *data, size_t len, size_t index, size_t total) { DPRINTLN(DBG_VERBOSE, "onApiPostBody"); if(0 == index) { @@ -158,7 +158,7 @@ class RestApi { DynamicJsonDocument json(1000); - DeserializationError err = deserializeJson(json, (const char *)mTmpBuf, mTmpSize); + DeserializationError err = deserializeJson(json, reinterpret_cast(mTmpBuf), mTmpSize); JsonObject obj = json.as(); AsyncJsonResponse* response = new AsyncJsonResponse(false, 200); @@ -930,20 +930,20 @@ class RestApi { return true; } - IApp *mApp; - HMSYSTEM *mSys; - HmRadio<> *mRadioNrf; + IApp *mApp = nullptr; + HMSYSTEM *mSys = nullptr; + HmRadio<> *mRadioNrf = nullptr; #if defined(ESP32) - CmtRadio<> *mRadioCmt; + CmtRadio<> *mRadioCmt = nullptr; #endif - AsyncWebServer *mSrv; - settings_t *mConfig; + AsyncWebServer *mSrv = nullptr; + settings_t *mConfig = nullptr; - uint32_t mTimezoneOffset; - uint32_t mHeapFree, mHeapFreeBlk; - uint8_t mHeapFrag; + uint32_t mTimezoneOffset = 0; + uint32_t mHeapFree = 0, mHeapFreeBlk = 0; + uint8_t mHeapFrag = 0; uint8_t *mTmpBuf = NULL; - uint32_t mTmpSize; + uint32_t mTmpSize = 0; }; #endif /*__WEB_API_H__*/ diff --git a/src/web/web.h b/src/web/web.h index 0ffd0594e..a166377f6 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -48,9 +48,6 @@ class Web { public: Web(void) : mWeb(80), mEvts("/events") { memset(mSerialBuf, 0, WEB_SERIAL_BUF_SIZE); - mSerialBufFill = 0; - mSerialAddTime = true; - mSerialClientConnnected = false; } void setup(IApp *app, HMSYSTEM *sys, settings_t *config) { @@ -490,9 +487,8 @@ class Web { // pinout - uint8_t pin; for (uint8_t i = 0; i < 16; i++) { - pin = request->arg(String(pinArgNames[i])).toInt(); + uint8_t pin = request->arg(String(pinArgNames[i])).toInt(); switch(i) { case 0: mConfig->nrf.pinCs = ((pin != 0xff) ? pin : DEF_NRF_CS_PIN); break; case 1: mConfig->nrf.pinCe = ((pin != 0xff) ? pin : DEF_NRF_CE_PIN); break; @@ -633,8 +629,8 @@ class Web { // NOTE: Grouping for fields with channels and totals is currently not working // TODO: Handle grouping and sorting for independant from channel number // NOTE: Check packetsize for MAX_NUM_INVERTERS. Successfully Tested with 4 Inverters (each with 4 channels) - const char * metricConstPrefix = "ahoy_solar_"; - const char * metricConstInverterFormat = " {inverter=\"%s\"} %d\n"; + const char* metricConstPrefix = "ahoy_solar_"; + const char* metricConstInverterFormat = " {inverter=\"%s\"} %d\n"; typedef enum { metricsStateInverterInfo=0, metricsStateInverterEnabled=1, metricsStateInverterAvailable=2, metricsStateInverterProducing=3, metricsStateInverterPowerLimitRead=4, metricsStateInverterPowerLimitAck=5, @@ -648,7 +644,7 @@ class Web { metricsStateStart, metricsStateEnd } MetricStep_t; - MetricStep_t metricsStep; + MetricStep_t metricsStep = metricsStateInverterInfo; typedef struct { const char *topic; const char *type; @@ -674,9 +670,6 @@ class Web { { "radio_dtu_loss_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.dtuLoss;} }, { "radio_dtu_sent_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.dtuSent;} } }; - int metricsInverterId; - uint8_t metricsFieldId; - bool metricDeclared, metricTotalDeclard; void showMetrics(AsyncWebServerRequest *request) { DPRINTLN(DBG_VERBOSE, F("web::showMetrics")); @@ -715,7 +708,7 @@ class Web { snprintf(topic,sizeof(topic),"%swifi_rssi_db{devicename=\"%s\"} %d\n",metricConstPrefix, mConfig->sys.deviceName, WiFi.RSSI()); metrics += String(type) + String(topic); - len = snprintf((char *)buffer,maxLen,"%s",metrics.c_str()); + len = snprintf(reinterpret_cast(buffer), maxLen,"%s",metrics.c_str()); // Next is Inverter information metricsStep = metricsStateInverterInfo; break; @@ -743,7 +736,7 @@ class Web { (String("ahoy_solar_inverter_") + inverterMetrics[metricsStep].topic + inverterMetrics[metricsStep].format).c_str(), inverterMetrics[metricsStep].valueFunc); - len = snprintf((char *)buffer,maxLen,"%s",metrics.c_str()); + len = snprintf(reinterpret_cast(buffer), maxLen, "%s", metrics.c_str()); // ugly hack to increment the enum metricsStep = static_cast( static_cast(metricsStep) + 1); // Prepare Realtime Field loop, which may be startet next @@ -763,7 +756,7 @@ class Web { metrics = "# Info: all realtime fields processed\n"; metricsStep = metricsStateAlarmData; } - len = snprintf((char *)buffer,maxLen,"%s",metrics.c_str()); + len = snprintf(reinterpret_cast(buffer), maxLen, "%s", metrics.c_str()); break; case metricStateRealtimeInverterId: // Iterate over all inverters for this field @@ -837,7 +830,7 @@ class Web { metricsFieldId++; // Process next field Id metricsStep = metricStateRealtimeFieldId; } - len = snprintf((char *)buffer,maxLen,"%s",metrics.c_str()); + len = snprintf(reinterpret_cast(buffer), maxLen, "%s", metrics.c_str()); break; case metricsStateAlarmData: // Alarm Info loop : fit to one packet @@ -861,7 +854,7 @@ class Web { } } } - len = snprintf((char*)buffer,maxLen,"%s",metrics.c_str()); + len = snprintf(reinterpret_cast(buffer), maxLen, "%s", metrics.c_str()); metricsStep = metricsStateEnd; break; @@ -880,10 +873,9 @@ class Web { // Traverse all inverters and collect the metric via valueFunc String inverterMetric(char *buffer, size_t len, const char *format, std::function *iv)> valueFunc) { - Inverter<> *iv; String metric = ""; for (int metricsInverterId = 0; metricsInverterId < mSys->getNumInverters();metricsInverterId++) { - iv = mSys->getInverterByPos(metricsInverterId); + Inverter<> *iv = mSys->getInverterByPos(metricsInverterId); if (NULL != iv) { snprintf(buffer,len,format,iv->config->name, valueFunc(iv)); metric += String(buffer); @@ -904,21 +896,27 @@ class Web { if(shortUnit == "Hz") return {"_hertz", "gauge"}; return {"", "gauge"}; } + + private: + int metricsInverterId = 0; + uint8_t metricsFieldId = 0; + bool metricDeclared = false, metricTotalDeclard = false; #endif + private: AsyncWebServer mWeb; AsyncEventSource mEvts; - IApp *mApp; - HMSYSTEM *mSys; + IApp *mApp = nullptr; + HMSYSTEM *mSys = nullptr; - settings_t *mConfig; + settings_t *mConfig = nullptr; - bool mSerialAddTime; + bool mSerialAddTime = true; char mSerialBuf[WEB_SERIAL_BUF_SIZE]; - uint16_t mSerialBufFill; - bool mSerialClientConnnected; + uint16_t mSerialBufFill = 0; + bool mSerialClientConnnected = false; File mUploadFp; - bool mUploadFail; + bool mUploadFail = false; }; #endif /*__WEB_H__*/ diff --git a/src/wifi/ahoywifi.h b/src/wifi/ahoywifi.h index 709c08c43..d38701aa6 100644 --- a/src/wifi/ahoywifi.h +++ b/src/wifi/ahoywifi.h @@ -71,7 +71,7 @@ class ahoywifi { void welcome(String ip, String mode); - settings_t *mConfig = NULL; + settings_t *mConfig = nullptr; appWifiCb mAppWifiCb; DNSServer mDns; @@ -81,15 +81,15 @@ class ahoywifi { WiFiEventHandler wifiConnectHandler, wifiDisconnectHandler, wifiGotIPHandler; #endif - WiFiStatus_t mStaConn; - uint8_t mCnt; - uint32_t *mUtcTimestamp; + WiFiStatus_t mStaConn = DISCONNECTED; + uint8_t mCnt = 0; + uint32_t *mUtcTimestamp = nullptr; - uint8_t mScanCnt; - bool mScanActive; - bool mGotDisconnect; + uint8_t mScanCnt = 0; + bool mScanActive = false; + bool mGotDisconnect = false; std::list mBSSIDList; - bool mStopApAllowed; + bool mStopApAllowed = false; bool mWasInCh12to14 = false; };