From f191c036bb633668576d69960ff55a4fee631b7c Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 16 Dec 2023 03:06:28 +0100 Subject: [PATCH 1/6] 0.8.24 * fix NRF communication for opendtufusion ethernet variant --- scripts/applyPatches.py | 1 - src/CHANGES.md | 3 +++ src/defines.h | 2 +- src/hm/CommQueue.h | 1 + src/hm/hmRadio.h | 20 +++++++++----------- src/hm/nrfHal.h | 2 +- src/hms/cmt2300a.h | 4 ++-- src/platformio.ini | 13 ++++++++++++- 8 files changed, 29 insertions(+), 17 deletions(-) diff --git a/scripts/applyPatches.py b/scripts/applyPatches.py index 131572fd..3ba30a5f 100644 --- a/scripts/applyPatches.py +++ b/scripts/applyPatches.py @@ -31,5 +31,4 @@ if env['PIOENV'][:22] != "opendtufusion-ethernet": if env['PIOENV'][:13] == "opendtufusion": applyPatch("GxEPD2", "../patches/GxEPD2_SW_SPI.patch") -if env['PIOENV'][:22] == "opendtufusion-ethernet": applyPatch("RF24", "../patches/RF24_Hal.patch") diff --git a/src/CHANGES.md b/src/CHANGES.md index 85e477e3..6364a7e7 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,8 @@ # Development Changes +## 0.8.24 - 2023-12-16 +* fix NRF communication for opendtufusion ethernet variant + ## 0.8.23 - 2023-12-14 * heuristics fix #1269 #1270 * moved `sendInterval` in settings, **important:** *will be reseted to 15s after update to this version* diff --git a/src/defines.h b/src/defines.h index c4559891..71bfc1fa 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 23 +#define VERSION_PATCH 24 //------------------------------------- typedef struct { diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index 5d6f9bd0..d1beedfc 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -31,6 +31,7 @@ class CommQueue { } uint8_t getFillState(void) { + DPRINTLN(DBG_INFO, "wr: " + String(mWrPtr) + ", rd: " + String(mRdPtr)); return abs(mRdPtr - mWrPtr); } diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index 14146830..d0387aa4 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -10,7 +10,7 @@ #include "SPI.h" #include "radio.h" #include "../config/config.h" -#if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(ETHERNET) +#if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(SPI_HAL) #include "nrfHal.h" #endif @@ -35,8 +35,8 @@ class HmRadio : public Radio { HmRadio() { mDtuSn = DTU_SN; mIrqRcvd = false; - #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(ETHERNET) - mNrf24.reset(new RF24()); + #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(SPI_HAL) + //mNrf24.reset(new RF24()); #else mNrf24.reset(new RF24(CE_PIN, CS_PIN, SPI_SPEED)); #endif @@ -56,8 +56,8 @@ class HmRadio : public Radio { DTU_RADIO_ID = ((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(ETHERNET) - mNrfHal.init(mosi, miso, sclk, cs, ce); + #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(SPI_HAL) + mNrfHal.init(mosi, miso, sclk, cs, ce, SPI_SPEED); mNrf24.reset(new RF24(&mNrfHal)); #else #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 @@ -73,7 +73,7 @@ class HmRadio : public Radio { mSpi->begin(); #endif - #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(ETHERNET) + #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(SPI_HAL) mNrf24->begin(); #else mNrf24->begin(mSpi.get(), ce, cs); @@ -133,14 +133,12 @@ class HmRadio : public Radio { yield(); } // switch to next RX channel - if(++mRxChIdx >= RF_CHANNELS) - mRxChIdx = 0; + mRxChIdx = (mRxChIdx + 1) % RF_CHANNELS; mNrf24->setChannel(mRfChLst[mRxChIdx]); startMicros = micros(); } // not finished but time is over - if(++mRxChIdx >= RF_CHANNELS) - mRxChIdx = 0; + mRxChIdx = (mRxChIdx + 1) % RF_CHANNELS; return; } @@ -344,7 +342,7 @@ class HmRadio : public Radio { std::unique_ptr mSpi; std::unique_ptr mNrf24; - #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(ETHERNET) + #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(SPI_HAL) nrfHal mNrfHal; #endif Inverter<> *mLastIv = NULL; diff --git a/src/hm/nrfHal.h b/src/hm/nrfHal.h index d4db9f92..c9fbcdc7 100644 --- a/src/hm/nrfHal.h +++ b/src/hm/nrfHal.h @@ -118,7 +118,7 @@ class nrfHal: public RF24_hal, public SpiPatcherHandle { uint8_t write(uint8_t cmd, const uint8_t* buf, uint8_t data_len, uint8_t blank_len) override { uint8_t data[NRF_MAX_TRANSFER_SZ]; data[0] = cmd; - memset(data, 0, NRF_MAX_TRANSFER_SZ); + memset(&data[1], 0, (NRF_MAX_TRANSFER_SZ-1)); std::copy(&buf[0], &buf[data_len], &data[1]); request_spi(); diff --git a/src/hms/cmt2300a.h b/src/hms/cmt2300a.h index bbbeefc7..1ff112e2 100644 --- a/src/hms/cmt2300a.h +++ b/src/hms/cmt2300a.h @@ -6,7 +6,7 @@ #ifndef __CMT2300A_H__ #define __CMT2300A_H__ -#if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(ETHERNET) +#if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(SPI_HAL) #include "cmtHal.h" #else #include "esp32_3wSpi.h" @@ -480,7 +480,7 @@ class Cmt2300a { return mSpi.readReg(CMT2300A_CUS_MODE_STA) & CMT2300A_MASK_CHIP_MODE_STA; } - #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(ETHERNET) + #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(SPI_HAL) cmtHal mSpi; #else esp32_3wSpi mSpi; diff --git a/src/platformio.ini b/src/platformio.ini index e7fb137e..43fd7ddd 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -162,6 +162,7 @@ lib_deps = upload_protocol = esp-builtin build_flags = ${env.build_flags} -DETHERNET + -DSPI_HAL -DUSE_HSPI_FOR_EPD -DDEF_ETH_CS_PIN=42 -DDEF_ETH_SCK_PIN=39 @@ -184,13 +185,22 @@ build_flags = ${env.build_flags} -DDEF_LED1=17 -DLED_ACTIVE_HIGH -DARDUINO_USB_MODE=1 - #-DARDUINO_USB_CDC_ON_BOOT=1 + -DARDUINO_USB_CDC_ON_BOOT=1 monitor_filters = esp32_exception_decoder, colorize [env:opendtufusion-dev] platform = espressif32@6.4.0 board = esp32-s3-devkitc-1 +lib_deps = + https://github.com/yubox-node-org/ESPAsyncWebServer + https://github.com/nrf24/RF24 @ ^1.4.8 + paulstoffregen/Time @ ^1.6.1 + https://github.com/bertmelis/espMqttClient#v1.5.0 + bblanchon/ArduinoJson @ ^6.21.3 + https://github.com/JChristensen/Timezone @ ^1.2.4 + olikraus/U8g2 @ ^2.35.7 + https://github.com/zinggjm/GxEPD2 @ ^1.5.2 upload_protocol = esp-builtin build_flags = ${env.build_flags} -DDEF_NRF_CS_PIN=37 @@ -209,5 +219,6 @@ build_flags = ${env.build_flags} -DLED_ACTIVE_HIGH -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=1 + -DSPI_HAL monitor_filters = esp32_exception_decoder, colorize From 78b603e37331b0ba6c8632fb9ce5d0f4ed6fd398 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 16 Dec 2023 03:13:01 +0100 Subject: [PATCH 2/6] 0.8.24 * remove debug flag for fusion eth --- src/platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platformio.ini b/src/platformio.ini index 43fd7ddd..54b63a22 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -185,7 +185,7 @@ build_flags = ${env.build_flags} -DDEF_LED1=17 -DLED_ACTIVE_HIGH -DARDUINO_USB_MODE=1 - -DARDUINO_USB_CDC_ON_BOOT=1 + #-DARDUINO_USB_CDC_ON_BOOT=1 monitor_filters = esp32_exception_decoder, colorize From d62b53019ae0629f58bbad531cba4a26a0fb7394 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 17 Dec 2023 01:01:20 +0100 Subject: [PATCH 3/6] 0.8.25 * RX channel ID starts with fixed value #1277 * fix static IP for Ethernet --- src/CHANGES.md | 4 ++++ src/app.cpp | 5 ----- src/eth/ahoyeth.cpp | 16 +++++++--------- src/hm/hmRadio.h | 2 +- src/platformio.ini | 2 +- 5 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 6364a7e7..a4805fd8 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,9 @@ # Development Changes +## 0.8.25 - 2023-12-17 +* RX channel ID starts with fixed value #1277 +* fix static IP for Ethernet + ## 0.8.24 - 2023-12-16 * fix NRF communication for opendtufusion ethernet variant diff --git a/src/app.cpp b/src/app.cpp index d670c696..05ca5563 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -40,11 +40,7 @@ void app::setup() { #endif #ifdef ETHERNET delay(1000); - DPRINT(DBG_INFO, F("mEth setup...")); - DSERIAL.flush(); mEth.setup(mConfig, &mTimestamp, [this](bool gotIp) { this->onNetwork(gotIp); }, [this](bool gotTime) { this->onNtpUpdate(gotTime); }); - DBGPRINTLN(F("done...")); - DSERIAL.flush(); #endif // ETHERNET #if !defined(ETHERNET) @@ -149,7 +145,6 @@ void app::regularTickers(void) { #if !defined(ETHERNET) //everySec([this]() { mImprov.tickSerial(); }, "impro"); #endif - // every([this]() { mPayload.simulation();}, 15, "simul"); } #if defined(ETHERNET) diff --git a/src/eth/ahoyeth.cpp b/src/eth/ahoyeth.cpp index be114cf1..2226fce6 100644 --- a/src/eth/ahoyeth.cpp +++ b/src/eth/ahoyeth.cpp @@ -26,12 +26,16 @@ void ahoyeth::setup(settings_t *config, uint32_t *utcTimestamp, OnNetworkCB onNe mOnNetworkCB = onNetworkCB; mOnTimeCB = onTimeCB; - DPRINTLN(DBG_INFO, F("[ETH]: Register for events...")); Serial.flush(); WiFi.onEvent([this](WiFiEvent_t event, arduino_event_info_t info) -> void { this->onEthernetEvent(event, info); }); - DPRINTLN(DBG_INFO, F("[ETH]: begin...")); Serial.flush(); + #if defined(CONFIG_IDF_TARGET_ESP32S3) + mEthSpi.begin(DEF_ETH_MISO_PIN, DEF_ETH_MOSI_PIN, DEF_ETH_SCK_PIN, DEF_ETH_CS_PIN, DEF_ETH_IRQ_PIN, DEF_ETH_RST_PIN); + #else + ETH.begin(DEF_ETH_MISO_PIN, DEF_ETH_MOSI_PIN, DEF_ETH_SCK_PIN, DEF_ETH_CS_PIN, DEF_ETH_IRQ_PIN, ETH_SPI_CLOCK_MHZ, ETH_SPI_HOST); + #endif + if(mConfig->sys.ip.ip[0] != 0) { IPAddress ip(mConfig->sys.ip.ip); IPAddress mask(mConfig->sys.ip.mask); @@ -41,11 +45,6 @@ void ahoyeth::setup(settings_t *config, uint32_t *utcTimestamp, OnNetworkCB onNe if(!ETH.config(ip, gateway, mask, dns1, dns2)) DPRINTLN(DBG_ERROR, F("failed to set static IP!")); } - #if defined(CONFIG_IDF_TARGET_ESP32S3) - mEthSpi.begin(DEF_ETH_MISO_PIN, DEF_ETH_MOSI_PIN, DEF_ETH_SCK_PIN, DEF_ETH_CS_PIN, DEF_ETH_IRQ_PIN, DEF_ETH_RST_PIN); - #else - ETH.begin(DEF_ETH_MISO_PIN, DEF_ETH_MOSI_PIN, DEF_ETH_SCK_PIN, DEF_ETH_CS_PIN, DEF_ETH_IRQ_PIN, ETH_SPI_CLOCK_MHZ, ETH_SPI_HOST); - #endif } @@ -130,8 +129,7 @@ void ahoyeth::welcome(String ip, String mode) { DBGPRINTLN(F("--------------------------------\n")); } -void ahoyeth::onEthernetEvent(WiFiEvent_t event, arduino_event_info_t info) -{ +void ahoyeth::onEthernetEvent(WiFiEvent_t event, arduino_event_info_t info) { AWS_LOG(F("[ETH]: Got event...")); switch (event) { #if ( ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) && ( ARDUINO_ESP32_GIT_VER != 0x46d5afb1 ) ) diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index d0387aa4..4fe3ea58 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -138,7 +138,7 @@ class HmRadio : public Radio { startMicros = micros(); } // not finished but time is over - mRxChIdx = (mRxChIdx + 1) % RF_CHANNELS; + mRxChIdx = 1; return; } diff --git a/src/platformio.ini b/src/platformio.ini index 54b63a22..43fd7ddd 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -185,7 +185,7 @@ build_flags = ${env.build_flags} -DDEF_LED1=17 -DLED_ACTIVE_HIGH -DARDUINO_USB_MODE=1 - #-DARDUINO_USB_CDC_ON_BOOT=1 + -DARDUINO_USB_CDC_ON_BOOT=1 monitor_filters = esp32_exception_decoder, colorize From d7f7cfb7ceb200156464be5352036f930e8dbc25 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 17 Dec 2023 01:01:53 +0100 Subject: [PATCH 4/6] 0.8.25 updated version number --- src/defines.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/defines.h b/src/defines.h index 71bfc1fa..b8bb8c64 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 24 +#define VERSION_PATCH 25 //------------------------------------- typedef struct { From 681c58e6a2214d3d6b093782db69a1d56c365d14 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 17 Dec 2023 01:30:39 +0100 Subject: [PATCH 5/6] 0.8.25 fix platformio.ini --- src/platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platformio.ini b/src/platformio.ini index 43fd7ddd..54b63a22 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -185,7 +185,7 @@ build_flags = ${env.build_flags} -DDEF_LED1=17 -DLED_ACTIVE_HIGH -DARDUINO_USB_MODE=1 - -DARDUINO_USB_CDC_ON_BOOT=1 + #-DARDUINO_USB_CDC_ON_BOOT=1 monitor_filters = esp32_exception_decoder, colorize From 16d0eb204842941a65e38e015a5f5c668a4037f4 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 17 Dec 2023 15:04:09 +0100 Subject: [PATCH 6/6] 0.8.26 * read grid profile as HEX (`live` -> click inverter name -> `show grid profile`) --- src/CHANGES.md | 3 +++ src/app.cpp | 2 +- src/config/settings.h | 12 ++++++++++-- src/defines.h | 2 +- src/hm/Communication.h | 8 +++++++- src/hm/hmInverter.h | 23 ++++++++++++++++++++++- src/web/RestApi.h | 14 ++++++++++++++ src/web/html/setup.html | 5 +++++ src/web/html/visualization.html | 10 +++++++++- src/web/web.h | 1 + 10 files changed, 73 insertions(+), 7 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index a4805fd8..d57c90d6 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,8 @@ # Development Changes +## 0.8.26 - 2023-12-17 +* read grid profile as HEX (`live` -> click inverter name -> `show grid profile`) + ## 0.8.25 - 2023-12-17 * RX channel ID starts with fixed value #1277 * fix static IP for Ethernet diff --git a/src/app.cpp b/src/app.cpp index 05ca5563..5a183cf4 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -336,7 +336,7 @@ void app::tickSend(void) { DBGPRINT(String(fill)); DBGPRINT(F(" of ")); DBGPRINT(String(max)); - DBGPRINTLN(F("entries used")); + DBGPRINTLN(F(" entries used")); } for (uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { diff --git a/src/config/settings.h b/src/config/settings.h index 31b5cab4..8acb0942 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -30,7 +30,7 @@ * https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html#flash-layout * */ -#define CONFIG_VERSION 5 +#define CONFIG_VERSION 6 #define PROT_MASK_INDEX 0x0001 @@ -157,6 +157,7 @@ typedef struct { bool startWithoutTime; float yieldEffiency; uint16_t gapMs; + bool readGrid; } cfgInst_t; typedef struct { @@ -440,6 +441,7 @@ class settings { mCfg.inst.rstMaxValsMidNight = false; mCfg.inst.yieldEffiency = 1.0f; mCfg.inst.gapMs = 2000; + mCfg.inst.readGrid = true; for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { mCfg.inst.iv[i].powerLevel = 0xff; // impossible high value @@ -481,12 +483,16 @@ class settings { mCfg.serial.printWholeTrace = false; } if(mCfg.configVersion < 4) { - mCfg.inst.gapMs = 2000; + mCfg.inst.gapMs = 500; } if(mCfg.configVersion < 5) { mCfg.inst.sendInterval = SEND_INTERVAL; mCfg.serial.printWholeTrace = false; } + if(mCfg.configVersion < 6) { + mCfg.inst.gapMs = 500; + mCfg.inst.readGrid = true; + } } } @@ -718,6 +724,7 @@ class settings { obj[F("rstMaxMidNight")] = (bool)mCfg.inst.rstMaxValsMidNight; obj[F("yldEff")] = mCfg.inst.yieldEffiency; obj[F("gap")] = mCfg.inst.gapMs; + obj[F("rdGrid")] = (bool)mCfg.inst.readGrid; } else { getVal(obj, F("intvl"), &mCfg.inst.sendInterval); @@ -729,6 +736,7 @@ class settings { getVal(obj, F("rstMaxMidNight"), &mCfg.inst.rstMaxValsMidNight); getVal(obj, F("yldEff"), &mCfg.inst.yieldEffiency); getVal(obj, F("gap"), &mCfg.inst.gapMs); + getVal(obj, F("rdGrid"), &mCfg.inst.readGrid); if(mCfg.inst.yieldEffiency < 0.5) mCfg.inst.yieldEffiency = 1.0f; diff --git a/src/defines.h b/src/defines.h index b8bb8c64..4d94bc95 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 25 +#define VERSION_PATCH 26 //------------------------------------- typedef struct { diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 51db6418..3e95b665 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -254,7 +254,7 @@ class Communication : public CommQueue<> { compilePayload(q); - if(NULL != mCbPayload) + if((NULL != mCbPayload) && (GridOnProFilePara != q->cmd)) (mCbPayload)(q->cmd, q->iv); closeRequest(q, true); @@ -440,9 +440,15 @@ class Communication : public CommQueue<> { } else DBGPRINTLN(F(")")); + if(GridOnProFilePara == q->cmd) { + q->iv->addGridProfile(mPayload, len); + return; + } + record_t<> *rec = q->iv->getRecordStruct(q->cmd); if(NULL == rec) { DPRINTLN(DBG_ERROR, F("record is NULL!")); + closeRequest(q, false); return; } if((rec->pyldLen != len) && (0 != rec->pyldLen)) { diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index 3e3e1c08..66496340 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -11,6 +11,8 @@ #define F(sl) (sl) #endif +#define MAX_GRID_LENGTH 150 + #include "hmDefines.h" #include "HeuristicInv.h" #include "../hms/hmsDefines.h" @@ -133,7 +135,7 @@ class Inverter { bool mGotLastMsg; // shows if inverter has already finished transmission cycle Radio *radio; // pointer to associated radio class statistics_t radioStatistics; // information about transmitted, failed, ... packets - HeuristicInv heuristics; + 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 @@ -183,6 +185,8 @@ class Inverter { else if(InitDataState != devControlCmd) { cb(devControlCmd, false); // custom command which was received by API devControlCmd = InitDataState; + } else if((0 == mGridLen) && generalConfig->readGrid) { // read grid profile + cb(GridOnProFilePara, false); } else cb(RealTimeRunData_Debug, false); // get live data } else { @@ -721,6 +725,21 @@ 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); + } + + String getGridProfile(void) { + char buf[MAX_GRID_LENGTH * 3]; + memset(buf, 0, MAX_GRID_LENGTH); + for(uint8_t i = 0; i < mGridLen; i++) { + snprintf(&buf[i*3], 4, "%02X ", mGridProfile[i]); + } + buf[mGridLen*3] = 0; + return String(buf); + } + private: inline void addAlarm(uint16_t code, uint32_t start, uint32_t end) { lastAlarm[alarmNxtWrPos] = alarm_t(code, start, end); @@ -741,6 +760,8 @@ class Inverter { private: float mOffYD[6], mLastYD[6]; bool mDevControlRequest; // true if change needed + uint8_t mGridLen = 0; + uint8_t mGridProfile[MAX_GRID_LENGTH]; }; template diff --git a/src/web/RestApi.h b/src/web/RestApi.h index a60d55b8..e98b00fe 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -109,6 +109,8 @@ class RestApi { getIvStatistis(root, request->url().substring(24).toInt()); else if(path.substring(0, 16) == "inverter/pwrack/") getIvPowerLimitAck(root, request->url().substring(21).toInt()); + else if(path.substring(0, 14) == "inverter/grid/") + getGridProfile(root, request->url().substring(19).toInt()); else getNotFound(root, F("http://") + request->host() + F("/api/")); } @@ -395,6 +397,7 @@ class RestApi { obj[F("rstNotAvail")] = (bool)mConfig->inst.rstValsNotAvail; obj[F("rstComStop")] = (bool)mConfig->inst.rstValsCommStop; obj[F("strtWthtTm")] = (bool)mConfig->inst.startWithoutTime; + obj[F("rdGrid")] = (bool)mConfig->inst.readGrid; obj[F("rstMaxMid")] = (bool)mConfig->inst.rstMaxValsMidNight; obj[F("yldEff")] = mConfig->inst.yieldEffiency; obj[F("gap")] = mConfig->inst.gapMs; @@ -452,6 +455,16 @@ class RestApi { } } + void getGridProfile(JsonObject obj, uint8_t id) { + Inverter<> *iv = mSys->getInverterByPos(id); + if(NULL == iv) { + return; + } + + obj[F("name")] = String(iv->config->name); + obj[F("grid")] = iv->getGridProfile(); + } + void getIvAlarms(JsonObject obj, uint8_t id) { Inverter<> *iv = mSys->getInverterByPos(id); if(NULL == iv) { @@ -484,6 +497,7 @@ class RestApi { record_t<> *rec = iv->getRecordStruct(InverterDevInform_Simple); + obj[F("id")] = id; obj[F("name")] = String(iv->config->name); obj[F("serial")] = String(iv->config->serial.u64, HEX); obj[F("generation")] = iv->ivGen; diff --git a/src/web/html/setup.html b/src/web/html/setup.html index fecebd81..a1e42a5c 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -172,6 +172,10 @@
Start without time sync (useful in AP-Only-Mode)
+
+
Read Grid Profile
+
+
Yield Efficiency (Standard 1.0)
@@ -580,6 +584,7 @@ for(var i of ["Mid", "ComStop", "NotAvail", "MaxMid"]) document.getElementsByName("invRst"+i)[0].checked = obj["rst" + i]; document.getElementsByName("strtWthtTm")[0].checked = obj["strtWthtTm"]; + document.getElementsByName("rdGrid")[0].checked = obj["rdGrid"]; } function parseSys(obj) { diff --git a/src/web/html/visualization.html b/src/web/html/visualization.html index bff8b4e3..faf76432 100644 --- a/src/web/html/visualization.html +++ b/src/web/html/visualization.html @@ -289,12 +289,20 @@ 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)) + tr("Bootloader Version", (obj.boot_ver/100).toFixed(2)), + tr("Grid Profile", ml("input", {type: "button", value: "show", class: "btn", onclick: function() { + modalClose(); + getAjax("/api/inverter/grid/" + obj.id, showGridProfile); + }}, null)) ]) ]); modal("Info for inverter " + obj.name, ml("div", {}, html)); } + function showGridProfile(obj) { + var html = ml("pre", {}, obj.grid); + modal("Grid Profile for inverter " + obj.name, ml("div", {}, html)); + } function parseIvRadioStats(obj) { diff --git a/src/web/web.h b/src/web/web.h index 9dc7ca8f..b104e9fd 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -501,6 +501,7 @@ class Web { mConfig->inst.rstValsCommStop = (request->arg("invRstComStop") == "on"); mConfig->inst.rstValsNotAvail = (request->arg("invRstNotAvail") == "on"); mConfig->inst.startWithoutTime = (request->arg("strtWthtTm") == "on"); + mConfig->inst.readGrid = (request->arg("rdGrid") == "on"); mConfig->inst.rstMaxValsMidNight = (request->arg("invRstMaxMid") == "on"); mConfig->inst.yieldEffiency = (request->arg("yldEff")).toFloat(); mConfig->inst.gapMs = (request->arg("invGap")).toInt();