From ef52ad1b0dc47a246d6e7e6b981b9cf8f9146592 Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 5 Aug 2024 19:54:20 +0200 Subject: [PATCH 01/40] changes for AsyncWebserver from mathieucarbou --- patches/AsyncWeb_Prometheus.patch | 34 +++++++++++++++---------------- scripts/applyPatches.py | 2 +- src/config/settings.h | 4 ++-- src/hm/hmInverter.h | 1 - src/platformio.ini | 4 +++- src/web/web.h | 28 ++++++++++++------------- 6 files changed, 37 insertions(+), 36 deletions(-) diff --git a/patches/AsyncWeb_Prometheus.patch b/patches/AsyncWeb_Prometheus.patch index 3c7deac4..f8e02c87 100644 --- a/patches/AsyncWeb_Prometheus.patch +++ b/patches/AsyncWeb_Prometheus.patch @@ -1,26 +1,26 @@ -diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp -index 6e88da9..09359c3 100644 +diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp +index 88d88ec..cb06fe0 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp -@@ -827,7 +827,7 @@ void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer) +@@ -745,7 +745,7 @@ void AsyncWebSocketClient::binary(const __FlashStringHelper* data, size_t len) { - IPAddress AsyncWebSocketClient::remoteIP() { - if(!_client) { -- return IPAddress((uint32_t)0); -+ return IPAddress(); - } - return _client->remoteIP(); + IPAddress AsyncWebSocketClient::remoteIP() const { + if (!_client) +- return IPAddress((uint32_t)0U); ++ return IPAddress(); + + return _client->remoteIP(); } diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp -index a22e991..babef18 100644 +index 86aa947..9d0ee00 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp -@@ -317,7 +317,7 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest *request, size_t len, u - free(buf); - return 0; +@@ -447,7 +447,7 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest* request, size_t len, u + free(buf); + return 0; } -- outLen = sprintf((char*)buf+headLen, "%x", readLen) + headLen; -+ outLen = sprintf((char*)buf+headLen, "%04x", readLen) + headLen; - while(outLen < headLen + 4) buf[outLen++] = ' '; +- outLen = sprintf_P((char*)buf + headLen, PSTR("%x"), readLen) + headLen; ++ outLen = sprintf_P((char*)buf + headLen, PSTR("%04x"), readLen) + headLen; + while (outLen < headLen + 4) + buf[outLen++] = ' '; buf[outLen++] = '\r'; - buf[outLen++] = '\n'; diff --git a/scripts/applyPatches.py b/scripts/applyPatches.py index 1672ab2f..b6d86be7 100644 --- a/scripts/applyPatches.py +++ b/scripts/applyPatches.py @@ -26,7 +26,7 @@ def applyPatch(libName, patchFile): # list of patches to apply (relative to /src) -applyPatch("ESPAsyncWebServer-esphome", "../patches/AsyncWeb_Prometheus.patch") +applyPatch("ESPAsyncWebServer", "../patches/AsyncWeb_Prometheus.patch") if (env['PIOENV'][:5] == "esp32") or (env['PIOENV'][:13] == "opendtufusion"): applyPatch("GxEPD2", "../patches/GxEPD2_HAL.patch") diff --git a/src/config/settings.h b/src/config/settings.h index 02beedce..41965998 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -412,8 +412,8 @@ class settings { memcpy(&mCfg.sys, &tmp, sizeof(cfgSys_t)); #if !defined(ETHERNET) else { - snprintf(mCfg.sys.stationSsid, SSID_LEN, FB_WIFI_SSID); - snprintf(mCfg.sys.stationPwd, PWD_LEN, FB_WIFI_PWD); + mCfg.sys.stationSsid[0] = '\0'; + mCfg.sys.stationPwd[0] = '\0'; mCfg.sys.isHidden = false; } #endif diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index ff3ff9c5..f09fbe1d 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -817,7 +817,6 @@ class Inverter { private: inline void addAlarm(uint16_t code, uint32_t start, uint32_t end) { - bool found = false; uint8_t i = 0; if(start > end) diff --git a/src/platformio.ini b/src/platformio.ini index ffdbd1f7..40bce86e 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -26,7 +26,8 @@ extra_scripts = post:../scripts/add_littlefs_binary.py lib_deps = - https://github.com/esphome/ESPAsyncWebServer @ ^3.2.2 + #https://github.com/esphome/ESPAsyncWebServer @ ^3.2.2 + https://github.com/mathieucarbou/ESPAsyncWebServer @ ^3.1.2 https://github.com/nRF24/RF24.git#v1.4.8 paulstoffregen/Time @ ^1.6.1 https://github.com/bertmelis/espMqttClient#v1.7.0 @@ -51,6 +52,7 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncUDP build_flags = ${env.build_flags} -DEMC_MIN_FREE_MEMORY=4096 + -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 ;-Wl,-Map,output.map monitor_filters = esp8266_exception_decoder diff --git a/src/web/web.h b/src/web/web.h index 2d017969..f44cc524 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -249,7 +249,7 @@ class Web { if (CHECK_MASK(mConfig->sys.protectionMask, mask)) checkProtection(request); - AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html; charset=UTF-8"), zippedHtml, len); + AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), zippedHtml, len); response->addHeader(F("Content-Encoding"), "gzip"); response->addHeader(F("content-type"), "text/html; charset=UTF-8"); if(request->hasParam("v")) @@ -339,7 +339,7 @@ class Web { } } - AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html; charset=UTF-8"), login_html, login_html_len); + AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), login_html, login_html_len); response->addHeader(F("Content-Encoding"), "gzip"); request->send(response); } @@ -350,7 +350,7 @@ class Web { checkProtection(request); mApp->lock(true); - AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html; charset=UTF-8"), system_html, system_html_len); + AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), system_html, system_html_len); response->addHeader(F("Content-Encoding"), "gzip"); request->send(response); } @@ -359,9 +359,9 @@ class Web { DPRINTLN(DBG_VERBOSE, F("onColor")); AsyncWebServerResponse *response; if (mConfig->sys.darkMode) - response = request->beginResponse_P(200, F("text/css"), colorDark_css, colorDark_css_len); + response = request->beginResponse(200, F("text/css"), colorDark_css, colorDark_css_len); else - response = request->beginResponse_P(200, F("text/css"), colorBright_css, colorBright_css_len); + response = request->beginResponse(200, F("text/css"), colorBright_css, colorBright_css_len); response->addHeader(F("Content-Encoding"), "gzip"); if(request->hasParam("v")) { response->addHeader(F("Cache-Control"), F("max-age=604800")); @@ -371,7 +371,7 @@ class Web { void onCss(AsyncWebServerRequest *request) { DPRINTLN(DBG_VERBOSE, F("onCss")); - AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/css"), style_css, style_css_len); + AsyncWebServerResponse *response = request->beginResponse(200, F("text/css"), style_css, style_css_len); response->addHeader(F("Content-Encoding"), "gzip"); if(request->hasParam("v")) { response->addHeader(F("Cache-Control"), F("max-age=604800")); @@ -382,7 +382,7 @@ class Web { void onApiJs(AsyncWebServerRequest *request) { DPRINTLN(DBG_VERBOSE, F("onApiJs")); - AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/javascript"), api_js, api_js_len); + AsyncWebServerResponse *response = request->beginResponse(200, F("text/javascript"), api_js, api_js_len); response->addHeader(F("Content-Encoding"), "gzip"); if(request->hasParam("v")) response->addHeader(F("Cache-Control"), F("max-age=604800")); @@ -392,7 +392,7 @@ class Web { void onGridInfoJson(AsyncWebServerRequest *request) { DPRINTLN(DBG_VERBOSE, F("onGridInfoJson")); - AsyncWebServerResponse *response = request->beginResponse_P(200, F("application/json; charset=utf-8"), grid_info_json, grid_info_json_len); + AsyncWebServerResponse *response = request->beginResponse(200, F("application/json; charset=utf-8"), grid_info_json, grid_info_json_len); response->addHeader(F("Content-Encoding"), "gzip"); if(request->hasParam("v")) response->addHeader(F("Cache-Control"), F("max-age=604800")); @@ -401,7 +401,7 @@ class Web { void onFavicon(AsyncWebServerRequest *request) { static const char favicon_type[] PROGMEM = "image/x-icon"; - AsyncWebServerResponse *response = request->beginResponse_P(200, favicon_type, favicon_ico, favicon_ico_len); + AsyncWebServerResponse *response = request->beginResponse(200, favicon_type, favicon_ico, favicon_ico_len); response->addHeader(F("Content-Encoding"), "gzip"); request->send(response); } @@ -414,7 +414,7 @@ class Web { void onReboot(AsyncWebServerRequest *request) { mApp->setRebootFlag(); - AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html; charset=UTF-8"), system_html, system_html_len); + AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), system_html, system_html_len); response->addHeader(F("Content-Encoding"), "gzip"); request->send(response); } @@ -422,7 +422,7 @@ class Web { void showHtml(AsyncWebServerRequest *request) { checkProtection(request); - AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html; charset=UTF-8"), system_html, system_html_len); + AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), system_html, system_html_len); response->addHeader(F("Content-Encoding"), "gzip"); request->send(response); } @@ -432,7 +432,7 @@ class Web { } void onWizard(AsyncWebServerRequest *request) { - AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html; charset=UTF-8"), wizard_html, wizard_html_len); + AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), wizard_html, wizard_html_len); response->addHeader(F("Content-Encoding"), "gzip"); response->addHeader(F("content-type"), "text/html; charset=UTF-8"); request->send(response); @@ -625,7 +625,7 @@ class Web { mApp->saveSettings((request->arg("reboot") == "on")); - AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html; charset=UTF-8"), save_html, save_html_len); + AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), save_html, save_html_len); response->addHeader(F("Content-Encoding"), "gzip"); request->send(response); } @@ -639,7 +639,7 @@ class Web { } void onAbout(AsyncWebServerRequest *request) { - AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html; charset=UTF-8"), about_html, about_html_len); + AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), about_html, about_html_len); response->addHeader(F("Content-Encoding"), "gzip"); response->addHeader(F("content-type"), "text/html; charset=UTF-8"); if(request->hasParam("v")) { From 9c895f9277830d73a24037561ed9b507791c1bef Mon Sep 17 00:00:00 2001 From: lumapu Date: Fri, 16 Aug 2024 22:12:03 +0200 Subject: [PATCH 02/40] 0.8.140 * released version --- src/CHANGES.md | 1569 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 1520 insertions(+), 49 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index cede20cb..a48295d1 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,54 +1,1525 @@ -Changelog v0.8.140 +# Development Changes -* added HMS-400-1T support (serial number 1125...) -* added further ESP8266 versions (-all, -minimal) because of small ressources on ESP8266 -* added some Gridprofiles -* added support for characters in serial number of inverter (A-F) -* added default coordinates on fresh install, needed for history graph on display and WebUI -* added option to reset values on communication start (sunrise) -* added max inverter temperature to WebUI -* added yield day to history graph +# RELEASE 0.8.140 - 2024-08-16 + +## 0.8.139 - 2024-08-15 +* fix reload after save for WiFi configurations (5s -> 20s) + +## 0.8.138 - 2024-08-15 +* fix ePaper not functional #1722 + +## 0.8.137 - 2024-08-13 +* fix storage of timezone and region #1723 + +## 0.8.136 - 2024-08-12 +* fix save settings for ESP32 devices #1720 + +## 0.8.135 - 2024-08-11 +* translated `/system` #1717 +* added default pin seetings for opendtufusion board +* fixed ethernet static IP +* fixed ethernet MAC address read back + +## 0.8.134 - 2024-08-10 +* combined Ethernet and WiFi variants - Ethernet is now always included, but needs to be enabled if needed +* improved statistic data in `/system` +* redesigned `/system` + +## 0.8.133 - 2024-08-10 +* Ethernet variants now support WiFi as fall back / configuration + +## 0.8.132 - 2024-08-09 +* fix boot loop once no ePaper is connected #1713, #1714 +* improved refresh routine of ePeper +* added default pin seetings for opendtufusion board + +## 0.8.131 - 2024-08-08 +* improved refresh routine of ePaper, full refresh each 12h #1107 #1706 + +## 0.8.130 - 2024-08-04 +* fix message `ERR_DUPLICATE_INVERTER` #1705, #1700 +* merge PR: Power limit command accelerated #1704 +* merge PR: reduce update cycle of ePaper from 5 to 10 seconds #1706 +* merge PR: small fixes in different files #1711 +* add timestamp to JSON output #1707 +* restart Ahoy using MqTT #1667 + +## 0.8.129 - 2024-07-11 +* sort alarms ascending #1471 +* fix alarm counter for first alarm +* prevent add inverter multiple times #1700 + +## 0.8.128 - 2024-07-10 +* add environments for 16MB flash size ESP32-S3 aka opendtufusion +* prevent duplicate alarms, update end time once it is received #1471 + +## 0.8.127 - 2024-06-21 +* add grid file #1677 +* merge PR: Bugfix Inv delete not working with password protection #1678 + +## 0.8.126 - 2024-06-12 +* merge PR: Update pubMqtt.h - Bugfix #1673 #1674 + +## 0.8.125 - 2024-06-09 +* fix ESP8266 compilation +* merge PR: active_PowerLimit #1663 + +## 0.8.124 - 2024-06-06 +* improved MqTT `OnMessage` (threadsafe) +* support of HERF inverters, serial number is converted in Javascript #1425 +* revert buffer size in `RestAPI` for ESP8266 #1650 + +## 0.8.123 - 2024-05-30 +* fix ESP8266, ESP32 static IP #1643 #1608 +* update MqTT library which enhances stability #1646 +* merge PR: MqTT JSON Payload pro Kanal und total, auswählbar #1541 +* add option to publish MqTT as json +* publish rssi not on ch0 any more, published on `topic/rssi` +* add total power to index page (if multiple inverters are configured) +* show device name in html title #1639 +* update AsyncWebserver library to `3.2.2` +* add environment name to filename of coredump + +## 0.8.122 - 2024-05-23 +* add button for donwloading coredump (ESP32 variants only) + +## 0.8.121 - 2024-05-20 +* fix ESP32 factory image generation +* fix plot of history graph #1635 + +## 0.8.120 - 2024-05-18 +* fix crash if invalid serial number was set -> inverter will be disabled automatically +* improved and fixed factory image generation +* fix HMT-1800-4T number of inputs #1628 + +## 0.8.119 - 2024-05-17 +* fix reset values at midnight if WiFi isn't available #1620 +* fix typo in English versions +* add yield day to history graph #1614 * added script and [instructions](../manual/factory_firmware.md) how to generate factory firmware which includes predefined settings -* added button for downloading coredump (ESP32 variants only) to `/system`. Once a crash happens the reason can be checked afterwards (even after a reboot) -* added support of HERF inverters, serial number is converted in Javascript -* added device name to HTML title -* added feature to restart Ahoy using MqTT -* added feature to publish MqTT messages as JSON as well (new setting) -* add timestamp to JSON output -* improved communication to inverter -* improved translation to German -* improved HTML pages, reduced in size by only including relevant contents depending by chip type -* improved history graph in WebUI -* improved network routines -* improved Wizard -* improved WebUI by disabling upload and import buttons when no file is selected +* merge PR: Fix MI overnight behaviour #1626 + +## 0.8.118 - 2024-05-10 +* possible fix reset max values #1609 +* slightly improved WiFi reconnect +* update AsyncWebserver to `3.2.0` + +## 0.8.117 - 2024-05-09 +* fix reboot issue #1607 #1606 +* fix max temperature tooltip if only one inverter is configured #1605 + +## 0.8.116 - 2024-05-05 +* calculation of max AC power +* fix counter overflow communication queue +* added max inverter temperature + +## 0.8.115 - 2024-05-03 +* fix inverter communication with manual time sync #1603 * improved queue, only add new object once they not exist in queue -* improved MqTT `OnMessage` (threadsafe) -* improved read of alarms, prevent duplicates, update alarm time if there is an update -* improved alarms are now sorted in ascending direction -* improved by prevent add inverter multiple times -* improved sending active power controll commands -* improved refresh routine of ePaper, full refresh each 12h -* redesigned WebUI on `/system` -* changed MqTT retained flags -* change MqTT return value of power limit acknowledge from `boolean` to `float`. The value returned is the same as it was set to confirm reception (not the read back value) +* added option to reset values on communication start (sunrise) +* fixed calculation of max AC power (API, MqTT) + +## 0.8.114 - 2024-04-29 +* fix ESP8266 compile +* fix history graph +* fix close button color of modal windows in dark mode #1598 +* fix only one total field in `/live` #1579 + +## 0.8.113 - 2024-04-25 +* code cleanup +* fix ESP32-C3 compile + +## 0.8.112 - 2024-04-24 +* improved wizard * converted ePaper and Ethernet to hal-SPI -* combined Ethernet and WiFi variants - Ethernet is now always included, but needs to be enabled if needed -* changed: Ethernet variants (W5500) now support WiFi as fall back / configuration -* switch AsyncWebserver library -* fixed autodiscovery for homeassistant -* fix reset values functionality -* fix read back of active power control value, now it has one decimal place -* fix NTP issues -* fixed MqTT discovery field `ALARM_MES_ID` -* fix close button color of modal windows in dark mode -* fixed calculation of max AC power -* fixed reset values at midnight if WiFi isn't available -* fixed HMT-1800-4T number of inputs -* fix crash if invalid serial number was set -> inverter will be disabled automatically -* fixed ESP8266, ESP32 static IP -* fixed ethernet MAC address read back -* update several libraries to more recent versions -* removed `yield efficiency` because the inverter already calculates correct +* improved network connection + +## 0.8.111 - 2024-04-17 +* fix MqTT discovery field `ALARM_MES_ID` #1591 +* fix Wifi reconnect for ESP32 #1589 #1575 +* open link from `index.html` in new tab #1588 #1587 +* merge PR: Disable upload and import buttons when no file is selected #1586 #1519 + +## 0.8.110 - 2024-04-11 +* revert CMT2300A changes #1553 +* merged PR: fix closing tag #1584 +* add disable retain flag #1582 +* fix German translation #1569 +* improved `Wizard` + +## 0.8.109 - 2024-04-09 +* fix hal patch + +## 0.8.108 - 2024-04-09 +* point to git SHA for `NRF24` library + +## 0.8.107 - 2024-04-08 +* fix boot loop on `reboot on midnight` feature #1542, #1599, #1566, #1571 +* fix German translation #1569 +* improved `Wizard` + +## 0.8.106 - 2024-04-05 +* fix bootloop with CMT and NRF on ESP32 #1566 #1562 +* possible fix of #1553 +* change MqTT return value of power limit acknowledge from `boolean` to `float`. The value returned is the same as it was set to confirm reception (not the read back value) + +## 0.8.105 - 2024-04-05 +* cleanup of `defines.h` +* fix compile of esp32-minimal + +## 0.8.104 - 2024-04-04 +* fix reboot on inverter save (ESP32) #1559 +* fix NRF and Ethernet #1506 + +## 0.8.103 - 2024-04-02 +* merge PR: fix: get refresh property from object #1552 +* merge PR: fix typos and spelling in Github Issue template #1550 +* merge PR: shorten last cmt waiting time #1549 +* fix cppcheck warnings +* changed MqTT retained flags of some topics + +## 0.8.102 - 2024-04-01 +* fix NTP for `opendtufusion` #1542 +* fix scan WiFi in AP mode +* fix MDNS #1538 +* improved Wizard +* improved MqTT on devcontrol e.g. set power limit + +## 0.8.101 - 2024-03-28 +* updated converter scripts to include all enabled features again (redundant scan of build flags) #1534 + +## 0.8.100 - 2024-03-27 +* fix captions in `/history #1532 +* fix get NTP time #1529 #1530 +* fix translation #1516 + +## 0.8.99 - 2024-03-27 +* fix compilation of all environments + +## 0.8.98 - 2024-03-24 +* new network routines + +## 0.8.97 - 2024-03-22 +* add support for newest generation of inverters with A-F in their serial number +* fix NTP and sunrise / sunset +* set default coordinates to the mid of Germany #1516 + +## 0.8.96 - 2024-03-21 +* fix precision of power limit in `/live` #1517 +* fix translation of `Werte ausgeben` in `settings` #1507 +* add grid profile #1518 + +## 0.8.95 - 2024-03-17 +* fix NTP issues #1440 #1497 #1499 + +## 0.8.94 - 2024-03-16 +* switched AsyncWebServer library +* Ethernet version now uses same AsyncWebServer library as Wifi version +* fix translation of `/history` +* fix RSSI on `/history` #1463 + +## 0.8.93 - 2024-03-14 +* improved history graph in WebUI #1491 +* merge PR: 1491 + +## 0.8.92 - 2024-03-10 +* fix read back of limit value, now with one decimal place +* added grid profile for Mexico #1493 +* added language to display on compile time #1484, #1255, #1479 +* added new environment `esp8266-all` which replace the original `esp8266`. The original now only have `MqTT` support but `Display` and `History` plugins are not included any more #1451 + +## 0.8.91 - 2024-03-05 +* fix javascript issues #1480 + +## 0.8.90 - 2024-03-05 +* added preprocessor defines to HTML (from platform.ini) to reduce the HTML in size if modules aren't enabled +* auto build minimal English versions of ESP8266 and ESP32 + +## 0.8.89 - 2024-03-02 +* merge PR: Collection of small fixes #1465 +* fix: show esp type on `/history` #1463 +* improved HMS-400-1T support (serial number 1125...) #1460 + +## 0.8.88 - 2024-02-28 +* fix MqTT statistic data overflow #1458 +* add HMS-400-1T support (serial number 1125...) #1460 +* removed `yield efficiency` because the inverter already calculates correct #1243 +* merge PR: Remove hint to INV_RESET_MIDNIGHT resp. INV_PAUSE_DURING_NIGHT #1431 + +## 0.8.87 - 2024-02-25 +* fix translations #1455 #1442 + +## 0.8.86 - 2024-02-23 +* RestAPI check for parent element to be JsonObject #1449 +* fix translation #1448 #1442 +* fix reset values when inverter status is 'not available' #1035 #1437 + +## 0.8.85 - 2024-02-22 +* possible fix of MqTT fix "total values are sent to often" #1421 +* fix translation #1442 +* availability check only related to live data #1035 #1437 + +## 0.8.84 - 2024-02-19 +* fix homeassistant autodiscovery #1432 +* merge PR: more gracefull handling of complete retransmits #1433 + +# RELEASE 0.8.83 - 2024-02-16 + +## 0.8.82 - 2024-02-15 +* fixed crash once firmware version was read and sent via MqTT #1428 +* possible fix: reset yield offset on midnight #1429 + +## 0.8.81 - 2024-02-13 +* fixed authentication with empty token #1415 +* added new setting for future function to send log via MqTT +* combined firmware and hardware version to JSON topics (MqTT) #1212 + +## 0.8.80 - 2024-02-12 +* optimize API authentication, Error-Codes #1415 +* breaking change: authentication API command changed #1415 +* breaking change: limit has to be send als `float`, `0.0 .. 100.0` #1415 +* updated documentation #1415 +* fix don't send control command twice #1426 + +## 0.8.79 - 2024-02-11 +* fix `opendtufusion` build (started only once USB-console was connected) +* code quality improvments + +## 0.8.78 - 2024-02-10 +* finalized API token access #1415 +* possible fix of MqTT fix "total values are sent to often" #1421 +* removed `switchCycle` from `hmsRadio.h` #1412 +* merge PR: Add hint to INV_RESET_MIDNIGHT resp. INV_PAUSE_DURING_NIGHT #1418 +* merge PR: simplify rxOffset logic #1417 +* code quality improvments + +## 0.8.77 - 2024-02-08 +* merge PR: BugFix: ACK #1414 +* fix suspicious if condition #1416 +* prepared API token for access, not functional #1415 + +## 0.8.76 - 2024-02-07 +* revert changes from yesterday regarding snprintf and its size #1410, #1411 +* reduced cppcheck linter warnings significantly +* try to improve ePaper (ghosting) #1107 + +## 0.8.75 - 2024-02-06 +* fix active power control value #1406, #1409 +* update Mqtt lib to version `1.6.0` +* take care of null terminator of chars #1410, #1411 + +## 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 + +## 0.8.72 - 2024-02-03 +* fixed translation #1403 +* fixed sending commands to inverters which are soft turned off #1397 +* reduce switchChannel command for HMS (only each 5th cycle it will be send now) + +## 0.8.71 - 2024-02-03 +* fix heuristics reset +* fix CMT missing frames problem +* removed inverter gap setting +* removed add to total (MqTT) inverter setting +* fixed sending commands to inverters which are soft turned off +* save settings before they are exported #1395 +* fix autologin bug if no password is set +* translated `/serial` +* removed "yield day" history + +## 0.8.70 - 2024-02-01 +* prevent sending commands to inverter which isn't active #1387 +* protect commands from popup in `/live` if password is set #1199 + +## 0.8.69 - 2024-01-31 +* merge PR: Dynamic retries, pendular first rx chan #1394 + +## 0.8.68 - 2024-01-29 +* fix HMS / HMT startup +* added `flush_rx` to NRF on TX +* start with heuristics set to `0` +* added warning for WiFi channel 12-14 (ESP8266 only) #1381 + +## 0.8.67 - 2024-01-29 +* fix HMS frequency +* fix display of inverter id in serial log (was displayed twice) + +## 0.8.66 - 2024-01-28 +* added support for other regions - untested #1271 +* fix generation of DTU-ID; was computed twice without reset if two radios are enabled + +## 0.8.65 - 2024-01-24 +* removed patch for NRF `PLOS` +* fix lang issues #1388 +* fix build on Windows of `opendtufusion` environments (git: trailing whitespaces) + +## 0.8.64 - 2024-01-22 +* add `ARC` to log (NRF24 Debug) +* merge PR: ETH NTP update bugfix #1385 + +## 0.8.63 - 2024-01-22 +* made code review +* fixed endless loop #1387 + +## 0.8.62 - 2024-01-21 +* updated version in footer #1381 +* repaired radio statistics #1382 + +## 0.8.61 - 2024-01-21 +* add favicon to header +* improved NRF communication +* merge PR: provide localized times to display mono classes #1376 +* merge PR: Bypass OOM-Crash on minimal version & history access #1378 +* merge PR: Add some REST Api Endpoints to avail_endpoints #1380 + +## 0.8.60 - 2024-01-20 +* merge PR: non blocking nRF loop #1371 +* merge PR: fixed millis in serial log #1373 +* merge PR: fix powergraph scale #1374 +* changed inverter gap to `1` as default (old settings will be overridden) + +## 0.8.59 - 2024-01-18 +* merge PR: solve display settings dependencies #1369 +* fix language typos #1346 +* full update of ePaper after booting #1107 +* fix MqTT yield day reset even if `pause inverter during nighttime` isn't active #1368 + +## 0.8.58 - 2024-01-17 +* fix missing refresh URL #1366 +* fix view of grid profile #1365 +* fix webUI translation #1346 +* fix protection mask #1352 +* merge PR: Add Watchdog for ESP32 #1367 +* merge PR: ETH support for CMT2300A - HMS/HMT #1356 +* full refresh of ePaper after booting #1107 +* add optional custom link #1199 +* pinout has an own subgroup in `/settings` +* grid profile will be displayed as hex in every case #1199 + +## 0.8.57 - 2024-01-15 +* merge PR: fix immediate clearing of display after sunset #1364 +* merge PR: MI-MQTT and last retransmit #1363 +* fixed DTU-ID, now built from the unique part of the MAC +* fix lang in `/system` #1346 +* added protection to prevent update to wrong firmware (environment check) + +## 0.8.56 - 2024-01-15 +* potential fix of update problems and random reboots #1359 #1354 + +## 0.8.55 - 2024-01-14 +* merge PR: fix reboot problem with deactivated power graph #1360 +* changed scope of variables and member functions inside display classes +* removed automatically "minimal" builds +* fix include of "settings.h" (was already done in #1360) +* merge PR: Enhancement: Add info about compiled modules to version string #1357 +* add info about installed binary to `/update` #1353 +* fix lang in `/system` #1346 + +## 0.8.54 - 2024-01-13 +* added minimal version (without: MqTT, Display, History), WebUI is not changed! +* added simulator (must be activated before compile, standard: off) +* changed communication attempts back to 5 + +## 0.8.53 - 2024-01-12 +* fix history graph +* fix MqTT yield day #1331 + +## 0.8.52 - 2024-01-11 +* possible fix of 'division by zero' #1345 +* fix lang #1348 #1346 +* fix timestamp `max AC power` #1324 +* fix stylesheet overlay `max AC power` #1324 +* fix download link #1340 +* fix history graph +* try to fix #1331 + +## 0.8.51 - 2024-01-10 +* fix translation #1346 +* further improve sending active power control command faster #1332 +* added history protection mask +* merge PR: display graph improvements #1347 + +## 0.8.50 - 2024-01-09 +* merge PR: added history charts to web #1336 +* merge PR: small display changes #1339 +* merge PR: MI - add "get loss logic" #1341 +* translated `/history` +* fix translations in title of documents +* added translations for error messages #1343 + +## 0.8.49 - 2024-01-08 +* fix send total values if inverter state is different from `OFF` #1331 +* fix german language issues #1335 + +## 0.8.48 - 2024-01-07 +* merge PR: pin selection for ESP-32 S2 #1334 +* merge PR: enhancement: power graph display option #1330 + +## 0.8.47 - 2024-01-06 +* reduce GxEPD2 lib to compile faster +* upgraded GxEPD2 lib to `1.5.3` +* updated espressif32 platform to `6.5.0` +* updated U8g2 to `2.35.9` +* started to convert deprecated functions of new ArduinoJson `7.0.0` +* started to have german translations of all variants (environments) #925 #1199 +* merge PR: add defines for retry attempts #1329 + +## 0.8.46 - 2024-01-06 +* improved communication + +## 0.8.45 - 2024-01-05 +* fix MqTT total values #1326 +* start implementing a wizard for initial (WiFi) configuration #1199 + +## 0.8.44 - 2024-01-05 +* fix MqTT transmission of data #1326 +* live data is read much earlier / faster and more often #1272 + +## 0.8.43 - 2024-01-04 +* fix display of sunrise in `/system` #1308 +* fix overflow of `getLossRate` calculation #1318 +* improved MqTT by marking sent data and improved `last_success` resends #1319 +* added timestamp for `max ac power` as tooltip #1324 #1123 #1199 +* repaired Power-limit acknowledge #1322 +* fix `max_power` in `/visualization` was set to `0` after sunset + +## 0.8.42 - 2024-01-02 +* add LED to display whether it's night time or not. Can be reused as output to control battery system #1308 +* merge PR: beautifiying typography, added spaces between value and unit for `/visualization` #1314 +* merge PR: Prometheus add `getLossRate` and bugfixing #1315 +* add loss rate to `/visualization` in the statistics window +* corrected `getLossRate` infos for MqTT and prometheus +* added information about working IRQ for NRF24 and CMT2300A to `/system` + +## 0.8.41 - 2024-01-02 +* fix display timeout (OLED) to 60s +* change offs to signed value + +## 0.8.40 - 2024-01-02 +* fix display of sunrise and sunset in `/system` #1308 +* fix MqTT set power limit #1313 + +## 0.8.39 - 2024-01-01 +* fix MqTT dis_night_comm in the morning #1309 #1286 +* separated offset for sunrise and sunset #1308 +* powerlimit (active power control) now has one decimal place (MqTT / API) #1199 +* merge Prometheus metrics fix #1310 +* merge MI grid profile request #1306 +* merge update documentation / readme #1305 +* add `getLossRate` to radio statistics and to MqTT #1199 + +## 0.8.38 - 2023-12-31 +* fix Grid-Profile JSON #1304 + +## 0.8.37 - 2023-12-30 +* added grid profiles +* format version of grid profile + +# RELEASE 0.8.36 - 2023-12-30 + +## 0.8.35 - 2023-12-30 +* added dim option for LEDS +* changed reload time for opendtufusion after update to 5s +* fix default interval and gap for communication +* fix serial number in exported json (was decimal, now correct as hexdecimal number) +* beautified factory reset +* added second stage for erase settings +* increased maximal number of inverters to 32 for opendtufusion board (ESP32-S3) +* fixed crash if CMT inverter is enabled, but CMT isn't configured + +# RELEASE 0.8.34 - 2023-12-29 + +## 0.8.33 - 2023-12-29 +* improved communication thx @rejoe2 + +## 0.8.32 - 2023-12-29 +* fix `start` / `stop` / `restart` commands #1287 +* added message, if profile was not read until now #1300 +* added developer option to use 'syslog-server' instead of 'web-serail' #1299 + +## 0.8.31 - 2023-12-29 +* added class to handle timeouts PR #1298 + +## 0.8.30 - 2023-12-28 +* added info if grid profile was not found +* merge PR #1293 +* merge PR #1295 fix ESP8266 pin settings +* merge PR #1297 fix layout for OLED displays + +## 0.8.29 - 2023-12-27 +* fix MqTT generic topic `comm_disabled` #1265 #1286 +* potential fix of #1285 (reset yield day) +* fix fraction of yield correction #1280 +* fix crash if `getLossRate` was read from inverter #1288 #1290 +* reduce reload time for opendtufusion ethernet variant to 5 seconds +* added basic grid parser +* added ESP32-C3 mini environment #1289 + +## 0.8.28 - 2023-12-23 +* fix bug heuristic +* add version information to clipboard once 'copy' was clicked +* add get loss rate @rejoe2 +* improve communication @rejoe2 + +## 0.8.27 - 2023-12-18 +* fix set power limit #1276 + +## 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 + +## 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* +* try to prevent access to radio classes if they are not activated +* fixed millis in serial log +* changed 'print whole trace' = `false` as default +* added communication loop duration in [ms] to serial console +* don't print Hex-Payload if 'print whole trace' == `false` + +## 0.8.22 - 2023-12-13 +* fix communication state-machine regarding zero export #1267 + +## 0.8.21 - 2023-12-12 +* fix ethernet save inverter parameters #886 +* fix ethernet OTA update #886 +* improved radio statistics, fixed heuristic output for HMS and HMT inverters + +## 0.8.20 - 2023-12-12 +* improved HM communication #1259 #1249 +* fix `loadDefaults` for ethernet builds #1263 +* don't loop through radios which aren't in use #1264 + +## 0.8.19 - 2023-12-11 +* added ms to serial log +* added (debug) option to configure gap between inverter requests + +## 0.8.18 - 2023-12-10 +* copied even more from the original heuristic code #1259 +* added mDNS support #1262 + +## 0.8.17 - 2023-12-10 +* possible fix of NRF with opendtufusion (without ETH) +* small fix in heuristics (if conditions made assignment not comparisson) + +## 0.8.16 - 2023-12-09 +* fix crash if NRF is not enabled +* updated heuristic #1080 #1259 +* fix compile opendtufusion fusion ethernet + +## 0.8.15 - 2023-12-09 +* added support for opendtufusion fusion ethernet shield #886 +* fixed range of HMS / HMT frequencies to 863 to 870 MHz #1238 +* changed `yield effiency` per default to `1.0` #1243 +* small heuristics improvements #1258 +* added class to combine inverter heuristics fields #1258 + +## 0.8.14 - 2023-12-07 +* fixed decimal points for temperature (WebUI) PR #1254 #1251 +* fixed inverter statemachine available state PR #1252 #1253 +* fixed NTP update and sunrise calculation #1240 #886 +* display improvments #1248 #1247 +* fixed overflow in `hmRadio.h` #1244 + +## 0.8.13 - 2023-11-28 +* merge PR #1239 symbolic layout for OLED 128x64 + motion senser functionality +* fix MqTT IP addr for ETH connections PR #1240 +* added ethernet build for fusion board, not tested so far + +## 0.8.12 - 2023-11-20 +* added button `copy to clipboard` to `/serial` + +## 0.8.11 - 2023-11-20 +* improved communication, thx @rejoe2 +* improved heuristics, thx @rejoe2, @Oberfritze +* added option to strip payload of frames to significant area + +## 0.8.10 - 2023-11-19 +* fix Mi and HM inverter communication #1235 +* added privacy mode option #1211 +* changed serial debug option to work without reboot + +## 0.8.9 - 2023-11-19 +* merged PR #1234 +* added new alarm codes +* removed serial interval, was not in use anymore + +## 0.8.8 - 2023-11-16 +* fix ESP8266 save inverter #1232 + +## 0.8.7 - 2023-11-13 +* fix ESP8266 inverter settings #1226 +* send radio statistics via MqTT #1227 +* made night communication inverter depended +* added option to prevent adding values of inverter to total values (MqTT only) #1199 + +## 0.8.6 - 2023-11-12 +* merged PR #1225 +* improved heuristics (prevent update of statitistic during testing) + +## 0.8.5 - 2023-11-12 +* fixed endless loop while switching CMT frequency +* removed obsolete "retries" field from settings #1224 +* fixed crash while defining new invertes #1224 +* fixed default frequency settings +* added default input power to `400` while adding new inverters +* fixed color of wifi RSSI icon #1224 + +## 0.8.4 - 2023-11-10 +* changed MqTT alarm topic, removed retained flag #1212 +* reduce last_success MQTT messages (#1124) +* introduced tabs in WebGUI (inverter settings) +* added inverter-wise power level and frequency + +## 0.8.3 - 2023-11-09 +* fix yield day reset during day #848 +* add total AC Max Power to WebUI +* fix opendtufusion build (GxEPD patch) +* fix null ptr PR #1222 + +## 0.8.2 - 2023-11-08 +* beautified inverter settings in `setup` (preperation for future, settings become more inverter dependent) + +## 0.8.1 - 2023-11-05 +* added tx channel heuristics (per inverter) +* fix statistics counter + +## 0.8.0 - 2023-10-?? +* switched to new communication scheme + +## 0.7.66 - 2023-10-04 +* prepared PA-Level for CMT +* removed settings for number of retransmits, its fixed to `5` now +* added parentheses to have a excactly defined behaviour + +## 0.7.65 - 2023-10-02 +* MI control command review #1197 + +## 0.7.64 - 2023-10-02 +* moved active power control to modal in `live` view (per inverter) by click on current APC state + +## 0.7.63 - 2023-10-01 +* fix NRF24 communication #1200 + +## 0.7.62 - 2023-10-01 +* fix communication to inverters #1198 +* add timeout before payload is tried to process (necessary for HMS/HMT) + +## 0.7.61 - 2023-10-01 +* merged `hmPayload` and `hmsPayload` into single class +* merged generic radio functions into new parent class `radio.h` +* moved radio statistics into the inverter - each inverter has now separate statistics which can be accessed by click on the footer in `/live` +* fix compiler warnings #1191 +* fix ePaper logo during night time #1151 + +## 0.7.60 - 2023-09-27 +* fixed typos in changelog #1172 +* fixed MqTT manual clientId storage #1174 +* fixed inverter name length in setup #1181 +* added inverter name to the header of alarm list #1181 +* improved code to avoid warning during compilation #1182 +* fix scheduler #1188, #1179 + +## 0.7.59 - 2023-09-20 +* re-add another HM-400 hardware serial number accidentally removed with `0.7.45` (#1169) +* merge PR #1170 +* reduce last_success MQTT messages (#1124) +* add re-request if inverter is known to be online and first try fails +* add alarm reporting to MI (might need review!) +* rebuild MI limiting code closer to DTUSimMI example +* round APC in `W` to an integer #1171 + +## 0.7.58 +* fix ESP8266 save settings issue #1166 + +## 0.7.57 - 2023-09-18 +* fix Alarms are always in queue (since 0.7.56) +* fix display active power control to long for small devices #1165 + +## 0.7.56 - 2023-09-17 +* only request alarms which were not received before #1113 +* added flag if alarm was requested but not received and re-request it #1105 +* merge PR #1163 + +## 0.7.55 - 2023-09-17 +* fix prometheus builds +* fix ESP32 default pinout #1159 +* added `opendtufusion-dev` because of annoying `-DARDUINO_USB_CDC_ON_BOOT=1` flag +* fix display of current power on `index` +* fix OTA, was damaged by version `0.7.51`, need to use webinstaller (from `0.7.51` to `0.7.54`) + +## 0.7.54 - 2023-09-16 +* added active power control in `W` to live view #201, #673 +* updated docu, active power control related #706 +* added current AC-Power to `index` page and removed version #763 +* improved statistic data, moved to entire struct +* removed `/api/statistics` endpoint from REST-API + +## 0.7.53 - 2023-09-16 +* fix ePaper / display night behaviour #1151 +* fix ESP8266 compile error + +## 0.7.52 - 2023-09-16 +* fix CMT configurable pins #1150, #1159 +* update MqTT lib to version `1.4.5` + +## 0.7.51 - 2023-09-16 +* fix CMT configurable pins #1150 +* fix default CMT pins for opendtufusion +* beautified `system` +* changed main loops, fix resets #1125, #1135 + +## 0.7.50 - 2023-09-12 +* moved MqTT info to `system` +* added CMT info for ESP32 devices +* improved CMT settings, now `SCLK` and `SDIO` are configurable #1046, #1150 +* changed `Power-Limit` in live-view to `Active Power Control` +* increase length of update file selector #1132 + +## 0.7.49 - 2023-09-11 +* merge PR: symbolic icons for mono displays, PR #1136 +* merge MI code restructuring PR #1145 +* merge Prometheus PR #1148 +* add option to strip webUI for ESP8266 (reduce code size, add ESP32 special features; `IF_ESP32` directives) +* started to get CMT info into `system` - not finished + +## 0.7.48 - 2023-09-10 +* fix SSD1309 2.42" display pinout +* improved setup page: save and delete of inverters + +## 0.7.47 - 2023-09-07 +* fix boot loop #1140 +* fix regex in `setup` page +* fix MI serial number display `max-module-power` in `setup` #1142 +* renamed `opendtufusionv1` to `opendtufusion` + +## 0.7.46 - 2023-09-04 +* removed `delay` from ePaper +* started improvements of `/system` +* fix LEDs to check all configured inverters +* send loop skip disabled inverters fix +* print generated DTU SN to console +* HW Versions for MI series PR #1133 +* 2.42" display (SSD1309) integration PR #1139 +* update user manual PR #1121 +* add / rename alarm codes PR #1118 +* revert default pin ESP32 for NRF23-CE #1132 +* luminance of display can be changed during runtime #1106 + +## 0.7.45 - 2023-08-29 +* change ePaper text to symbols PR #1131 +* added some invertes to dev info list #1111 + +## 0.7.44 - 2023-08-28 +* fix `last_success` transmitted to often #1124 + +## 0.7.43 - 2023-08-28 +* improved RSSI for NRF24, now it's read per package (and inverter) #1129 +* arranged `heap` related info together in `/system` +* fix display navi during save +* clean up binary output, separated to folders + +## 0.7.42 - 2023-08-27 +* fix ePaper for opendtufusion_v2.x boards (Software SPI) +* add signal strength for NRF24 - PR #1119 +* refactor wifi class to support ESP32 S2 PR #1127 +* update platform for ESP32 to 6.3.2 +* fix opendtufusion LED (were mixed) +* fix `last_success` transmitted to often #1124 +* added ESP32-S3-mini to github actions +* added old Changelog Entries, to have full log of changes + +## 0.7.41 - 2023-08-26 +* merge PR #1117 code spelling fixes #1112 +* alarms were not read after the first day + +## 0.7.40 - 2023-08-21 +* added default pins for opendtu-fusion-v1 board +* fixed hw version display in `live` +* removed development builds, renamed environments in `platform.ini` + +## 0.7.39 - 2023-08-21 +* fix background color of invalid inputs +* add hardware info (click in `live` on inverter name) + +## 0.7.38 - 2023-08-21 +* reset alarms at midnight (if inverter is not available) #1105, #1096 +* add option to reset 'max' values on midnight #1102 +* added default pins for CMT2300A (matching OpenDTU) + +## 0.7.37 - 2023-08-18 +* fix alarm time on WebGui #1099 +* added RSSI info for HMS and HMT inverters (MqTT + REST API) + +# RELEASE 0.7.36 - 2023-08-18 + +## 0.7.35 - 2023-08-17 +* fixed timestamp for alarms send over MqTT +* auto-patch of `AsyncWebServer` #834, #1036 +* Update documentation in Git regarding `ESP8266` default NRF24 pin assignments + +## 0.7.34 - 2023-08-16 +* fixed timezone offset of alarms +* added `AC` and `DC` to `/live` #1098 +* changed `ESP8266` default NRF24 pin assignments (`D3` = `CE` and `D4` = `IRQ`) +* fixed background of modal window for bright color +* fix MI crashes +* fix some lost debug messages +* merged PR #1095, MI fixes for 0.7.x versions +* fix scheduled reboot #1097 +* added vector graphic logo `/doc/logo.svg` +* merge PR #1093, improved Nokia5110 display layout + +## 0.7.33 - 2023-08-15 +* add alarms overview to WebGui #608 +* fix webGui total values #1084 + +## 0.7.32 - 2023-08-14 +* fix colors of live view #1091 + +## 0.7.31 - 2023-08-13 +* fixed docu #1085 +* changed active power limit MqTT messages to QOS2 #1072 +* improved alarm messages, added alarm-id to log #1089 +* trigger power limit read on next day (if inverter was offline meanwhile) +* disabled improv implementation to check if it is related to 'Schwuppdizitaet' +* changed live view to gray once inverter isn't available +* added inverter status to API +* changed sum of totals on WebGui depending on inverter status #1084 +* merge maximum power (AC and DC) from PR #1080 + +## 0.7.30 - 2023-08-10 +* attempt to improve speed / response times (Schwuppdizitaet) #1075 + +## 0.7.29 - 2023-08-09 +* MqTT alarm data was never sent, fixed +* REST API: added alarm data +* REST API: made get record obsolete +* REST API: added power limit acknowledge `/api/inverter/id/[0-x]` #1072 + +## 0.7.28 - 2023-08-08 +* fix MI inverter support #1078 + +## 0.7.27 - 2023-08-08 +* added compile option for ethernet #886 +* fix ePaper configuration, missing `Busy`-Pin #1075 + +# RELEASE 0.7.26 - 2023-08-06 + +* fix MqTT `last_success` + +# RELEASE 0.7.25 - 2023-08-06 + +## 0.7.24 - 2023-08-05 +* merge PR #1069 make MqTT client ID configurable +* fix #1016, general MqTT status depending on inverter state machine +* changed icon for fully available inverter to a filled check mark #1070 +* fixed `last_success` update with MqTT #1068 +* removed `improv` esp-web-installer script, because it is not fully functional at this time + +## 0.7.23 - 2023-08-04 +* merge PR #1056, visualization html +* update MqTT library to 1.4.4 +* update RF24 library to 1.4.7 +* update ArduinoJson library to 6.21.3 +* set minimum invervall for `/live` to 5 seconds + +## 0.7.22 - 2023-08-04 +* attempt to fix homeassistant auto discovery #1066 + +## 0.7.21 - 2023-07-30 +* fix MqTT YieldDay Total goes to 0 several times #1016 + +## 0.7.20 - 2023-07-28 +* merge PR #1048 version and hash in API, fixes #1045 +* fix: no yield day update if yield day reads `0` after inverter reboot (mostly on evening) #848 +* try to fix Wifi override #1047 +* added information after NTP sync to WebUI #1040 + +## 0.7.19 - 2023-07-27 +* next attempt to fix yield day for multiple inverters #1016 +* reduced threshold for inverter state machine from 60min to 15min to go from state `WAS_ON` to `OFF` + +## 0.7.18 - 2023-07-26 +* next attempt to fix yield day for multiple inverters #1016 + +## 0.7.17 - 2023-07-25 +* next attempt to fix yield day for multiple inverters #1016 +* added two more states for the inverter status (also docu) + +## 0.7.16 - 2023-07-24 +* next attempt to fix yield day for multiple inverters #1016 +* fix export settings date #1040 +* fix time on WebUI (timezone was not observed) #913 #1016 + +## 0.7.15 - 2023-07-23 +* add NTP sync interval #1019 +* adjusted range of contrast / luminance setting #1041 +* use only ISO time format in Web-UI #913 + +## 0.7.14 - 2023-07-23 +* fix Contrast for Nokia Display #1041 +* attempt to fix #1016 by improving inverter status +* added option to adjust efficiency for yield (day/total) #1028 + +## 0.7.13 - 2023-07-19 +* merged display PR #1027 +* add date, time and version to export json #1024 + +## 0.7.12 - 2023-07-09 +* added inverter status - state-machine #1016 + +## 0.7.11 - 2023-07-09 +* fix MqTT endless loop #1013 + +## 0.7.10 - 2023-07-08 +* fix MqTT endless loop #1013 + +## 0.7.9 - 2023-07-08 +* added 'improve' functions to set wifi password directly with ESP web tools #1014 +* fixed MqTT publish while applying power limit #1013 +* slightly improved HMT live view (Voltage & Current) + +## 0.7.8 - 2023-07-05 +* fix `YieldDay`, `YieldTotal` and `P_AC` in `TotalValues` #929 +* fix some serial debug prints +* merge PR #1005 which fixes issue #889 +* merge homeassistant PR #963 +* merge PR #890 which gives option for scheduled reboot at midnight (default off) + +## 0.7.7 - 2023-07-03 +* attempt to fix MqTT `YieldDay` in `TotalValues` #927 +* attempt to fix MqTT `YieldDay` and `YieldTotal` even if inverters are not completely available #929 +* fix wrong message 'NRF not connected' if it is disabled #1007 + +## 0.7.6 - 2023-06-17 +* fix display of hidden SSID checkbox +* changed yield correction data type to `double`, now decimal places are supported +* corrected name of 0.91" display in settings +* attempt to fix MqTT zero values only if setting is there #980, #957 +* made AP password configurable #951 +* added option to start without time-sync, eg. for AP-only-mode #951 + +## 0.7.5 - 2023-06-16 +* fix yield day reset on midnight #957 +* improved tickers in `app.cpp` + +## 0.7.4 - 2023-06-15 +* fix MqTT `P_AC` send if inverters are available #987 +* fix assignments for HMS 1CH and 2CH devices +* fixed uptime overflow #990 + +## 0.7.3 - 2023-06-09 +* fix hidden SSID scan #983 +* improved NRF24 missing message on home screen #981 +* fix MqTT publishing only updated values #982 + +## 0.7.2 - 2023-06-08 +* fix HMS-800 and HMS-1000 assignments #981 +* make nrf enabled all the time for ESP8266 +* fix menu item `active` highlight for 'API' and 'Doku' +* fix MqTT totals issue #927, #980 +* reduce maximum number of inverters to 4 for ESP8266, increase to 16 for ESP32 + +## 0.7.1 - 2023-06-05 +* enabled power limit control for HMS / HMT devices +* changed NRF24 lib version back to 1.4.5 because of compile problems for EPS8266 + +## 0.7.0 - 2023-06-04 +* HMS / HMT support for ESP32 devices + +## 0.6.15 - 2023-05-25 +* improved Prometheus Endpoint PR #958 +* fix turn off ePaper only if setting was set #956 +* improved reset values and update MqTT #957 + +## 0.6.14 - 2023-05-21 +* merge PR #902 Mono-Display + +## 0.6.13 - 2023-05-16 +* merge PR #934 (fix JSON API) and #944 (update manual) + +## 0.6.12 - 2023-04-28 +* improved MqTT +* fix menu active item + +## 0.6.11 - 2023-04-27 +* added MqTT class for publishing all values in Arduino `loop` + +## 0.6.10 - HMS +* Version available in `HMS` branch + +# RELEASE 0.6.9 - 2023-04-19 + +## 0.6.8 - 2023-04-19 +* fix #892 `zeroYieldDay` loop was not applied to all channels + +## 0.6.7 - 2023-04-13 +* merge PR #883, improved store of settings and javascript, thx @tastendruecker123 +* support `.` and `,` as floating point separator in setup #881 + +## 0.6.6 - 2023-04-12 +* increased distance for `import` button in mobile view #879 +* changed `led_high_active` to `bool` #879 + +## 0.6.5 - 2023-04-11 +* fix #845 MqTT subscription for `ctrl/power/[IV-ID]` was missing +* merge PR #876, check JSON settings during read for existence +* **NOTE:** incompatible change: renamed `led_high_active` to `act_high`, maybe setting must be changed after update +* merge PR #861 do not send channel metric if channel is disabled + +## 0.6.4 - 2023-04-06 +* merge PR #846, improved NRF24 communication and MI, thx @beegee3 & @rejoe2 +* merge PR #859, fix burger menu height, thx @ThomasPohl + +## 0.6.3 - 2023-04-04 +* fix login, password length was not checked #852 +* merge PR #854 optimize browser caching, thx @tastendruecker123 #828 +* fix WiFi reconnect not working #851 +* updated issue templates #822 + +## 0.6.2 - 2023-04-04 +* fix login from multiple clients #819 +* fix login screen on small displays + +## 0.6.1 - 2023-04-01 +* merge LED fix - LED1 shows MqTT state, LED configurable active high/low #839 +* only publish new inverter data #826 +* potential fix of WiFi hostname during boot up #752 + +# RELEASE 0.6.0 - 2023-03-27 + +## 0.5.110 +* MQTT fix reconnection by new lib version #780 +* add `about` page +* improved documentation regarding SPI pins #814 +* improved documentation (getting started) #815 #816 +* improved MI 4-ch inverter #820 + +## 0.5.109 +* reduced heap fragmentation by optimizing MqTT #768 +* ePaper: centered text thx @knickohr + +## 0.5.108 +* merge: PR SPI pins configurable (ESP32) #807, #806 (requires manual set of MISO=19, MOSI=23, SCLK=18 in GUI for existing installs) +* merge: PR MI serial outputs #809 +* fix: no MQTT `total` sensor for autodiscover if only one inverter was found #805 +* fix: MQTT `total` renamed to `device_name` + `_TOTOL` for better visibility #805 + +## 0.5.107 +* fix: show save message +* fix: removed serial newline for `enqueueCmd` +* Merged improved Prometheus #808 + +## 0.5.106 +* merged MI and debug message changes #804 +* fixed MQTT autodiscover #794, #632 + +## 0.5.105 +* merged MI, thx @rejoe2 #788 +* fixed reboot message #793 + +## 0.5.104 +* further improved save settings +* removed `#` character from ePaper +* fixed saving pinout for `Nokia-Display` +* removed `Reset` Pin for monochrome displays +* improved wifi connection #652 + +## 0.5.103 +* merged MI improvements, thx @rejoe2 #778 +* changed display inverter online message +* merged heap improvements #772 + +## 0.5.102 +* Warning: old exports are not compatible any more! +* fix JSON import #775 +* fix save settings, at least already stored settings are not lost #771 +* further save settings improvements (only store inverters which are existing) +* improved display of settings save return value +* made save settings asynchronous (more heap memory is free) + +## 0.5.101 +* fix SSD1306 +* update documentation +* Update miPayload.h +* Update README.md +* MI - remarks to user manual +* MI - fix AC calc +* MI - fix status msg. analysis + +## 0.5.100 +* fix add inverter `setup.html` #766 +* fix MQTT retained flag for total values #726 +* renamed buttons for import and export `setup.html` +* added serial message `settings saved` + +## 0.5.99 +* fix limit in [User_Manual.md](../User_Manual.md) +* changed `contrast` to `luminance` in `setup.html` +* try to fix SSD1306 display #759 +* only show necessary display pins depending on setting + +## 0.5.98 +* fix SH1106 rotation and turn off during night #756 +* removed MQTT subscription `sync_ntp`, `set_time` with a value of `0` does the same #696 +* simplified MQTT subscription for `limit`. Check [User_Manual.md](../User_Manual.md) for new syntax #696, #713 +* repaired inverter wise limit control +* fix upload settings #686 + +## 0.5.97 +* Attention: re-ordered display types, check your settings! #746 +* improved saving settings of display #747, #746 +* disabled contrast for Nokia display #746 +* added Prometheus as compile option #719, #615 +* update MQTT lib to v1.4.1 +* limit decimal places to 2 in `live` +* added `-DPIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48` to esp8266 debug build #657 +* a `max-module-power` of `0` disables channel in live view `setup` +* merge MI improvements, get firmware information #753 + +## 0.5.96 +* added Nokia display again for ESP8266 #764 +* changed `var` / `VAr` to SI unit `var` #732 +* fix MQTT retained flags for totals (P_AC, P_DC) #726, #721 + +## 0.5.95 +* merged #742 MI Improvements +* merged #736 remove obsolete JSON Endpoint + +## 0.5.94 +* added ePaper (for ESP32 only!), thx @dAjaY85 #735 +* improved `/live` margins #732 +* renamed `var` to `VAr` #732 + +## 0.5.93 +* improved web API for `live` +* added dark mode option +* converted all forms to reponsive design +* repaired menu with password protection #720, #716, #709 +* merged MI series fixes #729 + +## 0.5.92 +* fix mobile menu +* fix inverters in select `serial.html` #709 + +## 0.5.91 +* improved html and navi, navi is visible even when API dies #660 +* reduced maximum allowed JSON size for API to 6000Bytes #660 +* small fix: output command at `prepareDevInformCmd` #692 +* improved inverter handling #671 + +## 0.5.90 +* merged PR #684, #698, #705 +* webserial minor overflow fix #660 +* web `index.html` improve version information #701 +* fix MQTT sets power limit to zero (0) #692 +* changed `reset at midnight` with timezone #697 + +## 0.5.89 +* reduced heap fragmentation (removed `strtok` completely) #644, #645, #682 +* added part of mac address to MQTT client ID to separate multiple ESPs in same network +* added dictionary for MQTT to reduce heap-fragmentation +* removed `last Alarm` from Live view, because it showed always the same alarm - will change in future + +## 0.5.88 +* MQTT Yield Day zero, next try to fix #671, thx @beegee3 +* added Solenso inverter to supported devices +* improved reconnection of MQTT #650 + +## 0.5.87 +* fix yield total correction as module (inverter input) value #570 +* reneabled instant start communication (once NTP is synced) #674 + +## 0.5.86 +* prevent send devcontrol request during disabled night communication +* changed yield total correction as module (inverter input) value #570 +* MQTT Yield Day zero, next try to fix #671 + +## 0.5.85 +* fix power-limit was not checked for max retransmits #667 +* fix blue LED lights up all the time #672 +* fix installing schedulers if NTP server isn't available +* improved zero values on triggers #671 +* hardcoded MQTT subtopics, because wildcard `#` leads to errors +* rephrased some messages on webif, thx to @Argafal #638 +* fixed 'polling stop message' on `index.html` #639 + +## 0.5.84 +* fix blue LED lights up all the time #672 +* added an instant start communication (once NTP is synced) +* add MI 3rd generation inverters (10x2 serial numbers) +* first decodings of messages from MI 2nd generation inverters + +## 0.5.83 +* fix MQTT publishing, `callback` was set but reset by following `setup()` + +## 0.5.82 +* fixed communication error #652 +* reset values is no bound to MQTT any more, setting moved to `inverter` #649 +* fixed wording on `index.hmtl` #661 + +## 0.5.81 +* started implementation of MI inverters (setup.html, own processing `MiPayload.h`) + +## 0.5.80 +* fixed communication #656 + +## 0.5.79 +* fixed mixed reset flags #648 +* fixed `mCbAlarm` if MQTT is not used #653 +* fixed MQTT `autodiscover` #630 thanks to @antibill51 +* next changes from @beegee many thanks for your contribution! +* replaced `CircularBuffer` by `std::queue` +* reworked `hmRadio.h` completely (interrupts, packaging) +* fix exception while `reboot` +* cleanup MQTT coding + +## 0.5.78 +* further improvements regarding wifi #611, fix connection if only one AP with same SSID is there +* fix endless loop in `zerovalues` #564 +* fix auto discover again #565 +* added total values to autodiscover #630 +* improved zero at midnight #625 + +## 0.5.77 +* fix wrong filename for automatically created manifest (online installer) #620 +* added rotate display feature #619 +* improved Prometheus endpoint #615, thx to @fsck-block +* improved wifi to connect always to strongest RSSI, thx to @beegee3 #611 + +## 0.5.76 +* reduce MQTT retry interval from maximum speed to one second +* fixed homeassistant autodiscovery #565 +* implemented `getNTPTime` improvements #609 partially #611 +* added alarm messages to MQTT #177, #600, #608 + +## 0.5.75 +* fix wakeup issue, once wifi was lost during night the communication didn't start in the morning +* re-enabled FlashStringHelper because of lacking RAM +* complete rewrite of monochrome display class, thx to @dAjaY85 -> displays are now configurable in setup +* fix power limit not possible #607 + +## 0.5.74 +* improved payload handling (retransmit all fragments on CRC error) +* improved `isAvailable`, checks all record structs, inverter becomes available more early because version is check first +* fix tickers were not set if NTP is not available +* disabled annoying `FlashStringHelper` it gives randomly Exceptions during development, feels more stable since then +* moved erase button to the bottom in settings, not nice but more functional +* split `tx_count` to `tx_cnt` and `retransmits` in `system.html` +* fix mqtt retransmit IP address #602 +* added debug infos for `scheduler` (web -> `/debug` as trigger prints list of tickers to serial console) + +## 0.5.73 +* improved payload handling (request / retransmit) #464 +* included alarm ID parse to serial console (in development) + +## 0.5.72 +* repaired system, scheduler was not called any more #596 + +## 0.5.71 +* improved wifi handling and tickers, many thanks to @beegee3 #571 +* fixed YieldTotal correction calculation #589 +* fixed serial output of power limit acknowledge #569 +* reviewed `sendDiscoveryConfig` #565 +* merged PR `Monodisplay`, many thanks to @dAjaY85 #566, Note: (settings are introduced but not able to be modified, will be included in next version) + +## 0.5.70 +* corrected MQTT `comm_disabled` #529 +* fix Prometheus and JSON endpoints (`config_override.h`) #561 +* publish MQTT with fixed interval even if inverter is not available #542 +* added JSON settings upload. NOTE: settings JSON download changed, so only settings should be uploaded starting from version `0.5.70` #551 +* MQTT topic and inverter name have more allowed characters: `[A-Za-z0-9./#$%&=+_-]+`, thx: @Mo Demman +* improved potential issue with `checkTicker`, thx @cbscpe +* MQTT option for reset values on midnight / not avail / communication stop #539 +* small fix in `tickIVCommunication` #534 +* add `YieldTotal` correction, eg. to have the option to zero at year start #512 + +## 0.5.69 +* merged SH1106 1.3" Display, thx @dAjaY85 +* added SH1106 to automatic build +* added IP address to MQTT (version, device and IP are retained and only transmitted once after boot) #556 +* added `set_power_limit` acknowledge MQTT publish #553 +* changed: version, device name are only published via MQTT once after boot +* added `Login` to menu if admin password is set #554 +* added `development` to second changelog link in `index.html` #543 +* added interval for MQTT (as option). With this settings MQTT live data is published in a fixed timing (only if inverter is available) #542, #523 +* added MQTT `comm_disabled` #529 +* changed name of binaries, moved GIT-Sha to the front #538 + +## 0.5.68 +* repaired receive payload +* Powerlimit is transferred immediately to inverter + +## 0.5.67 +* changed calculation of start / stop communication to 1 min after last comm. stop #515 +* moved payload send to `payload.h`, function `ivSend` #515 +* payload: if last frame is missing, request all frames again + +# RELEASE 0.5.66 - 2022-12-30 + +## 0.5.65 +* wifi, code optimization #509 + +## 0.5.64 +* channel name can use any character, not limited any more +* added `/` to MQTT topic and Inverter name +* trigger for `calcSunrise` is now using local time #515 +* fix reconnect timeout for WiFi #509 +* start AP only after boot, not on WiFi connection loss +* improved /system `free_heap` value (measured before JSON-tree is built) + +## 0.5.63 +* fix Update button protection (prevent double click #527) +* optimized scheduler #515 (thx @beegee3) +* potential fix of #526 duplicates in API `/api/record/live` +* added update information to `index.html` + +## 0.5.62 +* fix MQTT `status` update +* removed MQTT `available_text` (can be deducted from `available`) +* enhanced MQTT documentation in `User_Manual.md` +* removed `tickSunset` and `tickSunrise` from MQTT. It's not needed any more because of minute wise check of status (`processIvStatus`) +* changed MQTT topic `status` to nummeric value, check documentation in `User_Manual.md` +* fix regular expression of `setup.html` for inverter name and channel name + +## 0.5.61 +* fix #521 no reconnect at beginning of day +* added immediate (each minute) report of inverter status MQTT #522 +* added protection mask to select which pages should be protected +* update of monochrome display, show values also if nothing changed + +## 0.5.60 +* added regex to inverter name and MQTT topic (setup.html) +* beautified serial.html +* added ticker for wifi loop #515 + +## 0.5.59 +* fix night communication enable +* improved different WiFi connection scenarios (STA WiFi not found, reconnect #509, redirect for AP to configuration) +* increased MQTT user, pwd and topic length to 64 characters + `\0`. (The string end `\0` reduces the available size by one) #516 + +## 0.5.58 +* improved stability +* improved WiFi initial connection - especially if station WiFi is not available +* removed new operators from web.h (reduce dynamic allocation) +* improved sun calculation #515, #505 +* fixed WiFi auto reconnect #509 +* added disable night communication flag to MQTT #505 +* changed MQTT publish of `available` and `available_text` to sunset #468 + +## 0.5.57 +* improved stability +* added icons to index.html, added WiFi-strength symbol on each page +* moved packet stats and sun to system.html +* refactored communication offset (adjustable in minutes now) + +## 0.5.56 +* factory reset formats entire little fs +* renamed sunrise / sunset on index.html to start / stop communication +* show system information only if called directly from menu +* beautified system.html + +## 0.5.55 +* fixed static IP save + +## 0.5.54 +* changed sunrise / sunset calculation, angle is now `-3.5` instead of original `-0.83` +* improved scheduler (removed -1 from `reload`) #483 +* improved reboot flag in `app.h` +* fixed #493 no MQTT payload once display is defined + +## 0.5.53 +* Mono-Display: show values in offline mode #498 +* improved WiFi class #483 +* added communication enable / disable (to test multiple DTUs with the same inverter) +* fix factory reset #495 + +## 0.5.52 +* improved ahoyWifi class +* added interface class for app +* refactored web and webApi -> RestApi +* fix calcSunrise was not called every day +* added MQTT RX counter to index.html +* all values are displayed on /live even if they are 0 +* added MQTT /status to show status over all inverters + +## 0.5.51 +* improved scheduler, @beegee3 #483 +* refactored get NTP time, @beegee3 #483 +* generate `bin.gz` only for 1M device ESP8285 +* fix calcSunrise was not called every day +* increased number of allowed characters for MQTT user, broker and password, @DanielR92 +* added NRF24 info to Systeminfo, @DanielR92 +* added timezone for monochrome displays, @gh-fx2 +* added support for second inverter for monochrome displays, @gh-fx2 + +## 0.5.50 +* fixed scheduler, uptime and timestamp counted too fast +* added / renamed automatically build outputs +* fixed MQTT ESP uptime on reconnect (not zero any more) +* changed uptime on index.html to count each second, synced with ESP each 10 seconds + +## 0.5.49 +* fixed AP mode on brand new ESP modules +* fixed `last_success` MQTT message +* fixed MQTT inverter available status at sunset +* reordered enqueue commands after boot up to prevent same payload length for successive commands +* added automatic build for Nokia5110 and SSD1306 displays (ESP8266) + +## 0.5.48 +* added MQTT message send at sunset +* added monochrome display support +* added `once` and `onceAt` to scheduler to make code cleaner +* improved sunrise / sunset calculation + +## 0.5.47 +* refactored ahoyWifi class: AP is opened on every boot, once station connection is successful the AP will be closed +* improved NTP sync after boot, faster sync +* fix NRF24 details only on valid SPI connection + +## 0.5.46 +* fix sunrise / sunset calculation +* improved setup.html: `reboot on save` is checked as default + +## 0.5.45 +* changed MQTT last will topic from `status` to `mqtt` +* fix sunrise / sunset calculation +* fix time of serial web console + +## 0.5.44 +* marked some MQTT messages as retained +* moved global functions to global location (no duplicates) +* changed index.html interval to static 10 seconds +* fix static IP +* fix NTP with static IP +* print MQTT info only if MQTT was configured + +## 0.5.43 +* updated REST API and MQTT (both of them use the same functionality) +* added ESP-heap information as MQTT message +* changed output name of automatic development build to fixed name (to have a static link from https://ahoydtu.de) +* updated user manual to latest MQTT and API changes + +## 0.5.42 +* fix web logout (auto logout) +* switched MQTT library + +# RELEASE 0.5.41 - 2022-11-22 + +# RELEASE 0.5.28 - 2022-10-30 + +# RELEASE 0.5.17 - 2022-09-06 + +# RELEASE 0.5.16 - 2022-09-04 -full version log: [Development Log](https://github.com/lumapu/ahoy/blob/development03/src/CHANGES.md) From d14d78392903fb8aa1c6ffacb13fd2f5c8dddbf1 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 17 Aug 2024 00:04:02 +0200 Subject: [PATCH 03/40] 0.8.141 * switch AsyncWebserver to https://github.com/mathieucarbou/ESPAsyncWebServer * fix missing translations to German #1717 * increased maximum number of alarms to 50 for ESP32 #1470 * fix German translation #1688 * fix display of delete and edit buttons in `/setup` #1372 --- src/CHANGES.md | 7 +++++++ src/defines.h | 2 +- src/hm/hmInverter.h | 17 ++++++++++++----- src/platformio.ini | 19 +++++++++++++++++-- src/web/RestApi.h | 6 +++--- src/web/html/index.html | 2 +- src/web/html/setup.html | 4 ++-- src/web/html/style.css | 1 + src/web/html/system.html | 10 +++++----- src/web/lang.json | 12 ++++++------ 10 files changed, 55 insertions(+), 25 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index a48295d1..0f1db603 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,12 @@ # Development Changes +## 0.8.141 - 2024-08-16 +* switch AsyncWebserver to https://github.com/mathieucarbou/ESPAsyncWebServer +* fix missing translations to German #1717 +* increased maximum number of alarms to 50 for ESP32 #1470 +* fix German translation #1688 +* fix display of delete and edit buttons in `/setup` #1372 + # RELEASE 0.8.140 - 2024-08-16 ## 0.8.139 - 2024-08-15 diff --git a/src/defines.h b/src/defines.h index 94674315..341ed04f 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 140 +#define VERSION_PATCH 141 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index 026bf6d8..ecf7bbfb 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -116,6 +116,13 @@ const calcFunc_t calcFunctions[] = { template class Inverter { + public: /*types*/ + #ifdef(ESP32) + constexpr static uint8_t MaxAlarmNum = 50; + #else + constexpr static uint8_t MaxAlarmNum = 10; + #endif + public: uint8_t ivGen = IV_UNKNOWN; // generation of inverter (HM / MI) uint8_t ivRadioType = INV_RADIO_TYPE_UNKNOWN; // refers to used radio (nRF24 / CMT) @@ -135,7 +142,7 @@ class Inverter { 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 + std::array lastAlarm; // holds last x alarms int8_t rssi = 0; // RSSI uint16_t alarmCnt = 0; // counts the total number of occurred alarms uint16_t alarmLastId = 0; // lastId which was received @@ -822,9 +829,9 @@ class Inverter { if(start > end) end = 0; - for(; i < 10; i++) { + for(; i < MaxAlarmNum; i++) { ++mAlarmNxtWrPos; - mAlarmNxtWrPos = mAlarmNxtWrPos % 10; + mAlarmNxtWrPos = mAlarmNxtWrPos % MaxAlarmNum; if(lastAlarm[mAlarmNxtWrPos].code == code && lastAlarm[mAlarmNxtWrPos].start == start) { // replace with same or update end time @@ -834,11 +841,11 @@ class Inverter { } } - if(alarmCnt < 10 && alarmCnt <= mAlarmNxtWrPos) + if(alarmCnt < MaxAlarmNum && alarmCnt <= mAlarmNxtWrPos) alarmCnt = mAlarmNxtWrPos + 1; lastAlarm[mAlarmNxtWrPos] = alarm_t(code, start, end); - if(++mAlarmNxtWrPos >= 10) // rolling buffer + if(++mAlarmNxtWrPos >= MaxAlarmNum) // rolling buffer mAlarmNxtWrPos = 0; } diff --git a/src/platformio.ini b/src/platformio.ini index 860699e5..17031213 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -26,8 +26,6 @@ extra_scripts = post:../scripts/add_littlefs_binary.py lib_deps = - #https://github.com/esphome/ESPAsyncWebServer @ ^3.2.2 - https://github.com/mathieucarbou/ESPAsyncWebServer @ ^3.1.3 https://github.com/nRF24/RF24.git#v1.4.8 paulstoffregen/Time @ ^1.6.1 https://github.com/bertmelis/espMqttClient#v1.7.0 @@ -49,6 +47,7 @@ board = esp12e board_build.f_cpu = 80000000L lib_deps = ${env.lib_deps} + https://github.com/esphome/ESPAsyncWebServer @ ^3.2.2 https://github.com/me-no-dev/ESPAsyncUDP build_flags = ${env.build_flags} -DEMC_MIN_FREE_MEMORY=4096 @@ -153,6 +152,9 @@ monitor_filters = [env:esp32-wroom32-minimal] platform = espressif32@6.7.0 board = lolin_d32 +lib_deps = + ${env.lib_deps} + https://github.com/mathieucarbou/ESPAsyncWebServer @ ^3.1.5 build_flags = ${env.build_flags} -DSPI_HAL monitor_filters = @@ -161,6 +163,7 @@ monitor_filters = [env:esp32-wroom32] platform = espressif32@6.7.0 board = lolin_d32 +lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:esp32-wroom32-minimal.build_flags} -DUSE_HSPI_FOR_EPD -DENABLE_MQTT @@ -190,6 +193,7 @@ monitor_filters = [env:esp32-wroom32-de] platform = espressif32@6.7.0 board = lolin_d32 +lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:esp32-wroom32.build_flags} -DLANG_DE monitor_filters = @@ -198,6 +202,7 @@ monitor_filters = [env:esp32-wroom32-prometheus] platform = espressif32@6.7.0 board = lolin_d32 +lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:esp32-wroom32.build_flags} -DENABLE_PROMETHEUS_EP monitor_filters = @@ -206,6 +211,7 @@ monitor_filters = [env:esp32-wroom32-prometheus-de] platform = espressif32@6.7.0 board = lolin_d32 +lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:esp32-wroom32-prometheus.build_flags} -DLANG_DE monitor_filters = @@ -214,6 +220,7 @@ monitor_filters = [env:esp32-s2-mini] platform = espressif32@6.7.0 board = lolin_s2_mini +lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env.build_flags} -DUSE_HSPI_FOR_EPD -DSPI_HAL @@ -237,6 +244,7 @@ monitor_filters = [env:esp32-s2-mini-de] platform = espressif32@6.7.0 board = lolin_s2_mini +lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:esp32-s2-mini.build_flags} -DLANG_DE monitor_filters = @@ -245,6 +253,7 @@ monitor_filters = [env:esp32-c3-mini] platform = espressif32@6.7.0 board = lolin_c3_mini +lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env.build_flags} -DUSE_HSPI_FOR_EPD -DSPI_HAL @@ -268,6 +277,7 @@ monitor_filters = [env:esp32-c3-mini-de] platform = espressif32@6.7.0 board = lolin_c3_mini +lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:esp32-c3-mini.build_flags} -DLANG_DE monitor_filters = @@ -277,6 +287,7 @@ monitor_filters = platform = espressif32@6.7.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin +lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env.build_flags} -DSPI_HAL -DDEF_NRF_CS_PIN=37 @@ -302,6 +313,7 @@ monitor_filters = platform = espressif32@6.7.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin +lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:opendtufusion-minimal.build_flags} -DETHERNET -DENABLE_MQTT @@ -320,6 +332,7 @@ monitor_filters = platform = espressif32@6.7.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin +lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:opendtufusion.build_flags} -DLANG_DE monitor_filters = @@ -331,6 +344,7 @@ board = esp32-s3-devkitc-1 board_upload.flash_size = 16MB board_build.partitions = default_16MB.csv upload_protocol = esp-builtin +lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:opendtufusion.build_flags} monitor_filters = esp32_exception_decoder, colorize @@ -339,6 +353,7 @@ monitor_filters = platform = espressif32@6.7.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin +lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:opendtufusion-16MB.build_flags} -DLANG_DE monitor_filters = diff --git a/src/web/RestApi.h b/src/web/RestApi.h index eac91cb9..b378b1da 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -674,15 +674,15 @@ class RestApi { // find oldest alarm uint8_t offset = 0; uint32_t oldestStart = 0xffffffff; - for(uint8_t i = 0; i < 10; i++) { + for(uint8_t i = 0; i < hmInverter::MaxAlarmNum; i++) { if((iv->lastAlarm[i].start != 0) && (iv->lastAlarm[i].start < oldestStart)) { offset = i; oldestStart = iv->lastAlarm[i].start; } } - for(uint8_t i = 0; i < 10; i++) { - uint8_t pos = (i + offset) % 10; + for(uint8_t i = 0; i < hmInverter::MaxAlarmNum; i++) { + uint8_t pos = (i + offset) % hmInverter::MaxAlarmNum; alarm[pos][F("code")] = iv->lastAlarm[pos].code; alarm[pos][F("str")] = iv->getAlarmStr(iv->lastAlarm[pos].code); alarm[pos][F("start")] = iv->lastAlarm[pos].start; diff --git a/src/web/html/index.html b/src/web/html/index.html index ee78ac8e..33887e86 100644 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -152,7 +152,7 @@ text = "{#INVERTER} #"; p.append( svg(icon, 30, 30, "icon " + cl), - span(text + i["id"] + ": " + i["name"] + " {#IS} " + avail), + span(text + i["id"] + ": " + i["name"] + " " + avail), br() ); diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 2b59146c..4d99331e 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -736,7 +736,7 @@ lines.push(ml("tr", {}, [ ml("th", {style: "width: 10%; text-align: center;"}, ""), ml("th", {}, "Name"), - ml("th", {}, "Serial"), + ml("th", {class: "d-none d-sm-cell"}, "Serial"), ml("th", {style: "width: 10%; text-align: center;"}, "{#INV_EDIT}"), ml("th", {style: "width: 10%; text-align: center;"}, "{#INV_DELETE}") ])); @@ -745,7 +745,7 @@ lines.push(ml("tr", {}, [ ml("td", {}, badge(obj.inverter[i].enabled, (obj.inverter[i].enabled) ? "{#ENABLED}" : "{#DISABLED}")), ml("td", {}, obj.inverter[i].name), - ml("td", {}, String(obj.inverter[i].serial)), + ml("td", {class: "d-none d-sm-cell"}, String(obj.inverter[i].serial)), ml("td", {style: "text-align: center;", onclick: function() {ivModal(obj.inverter[i]);}}, svg(iconGear, 25, 25, "icon icon-fg pointer")), ml("td", {style: "text-align: center; ", onclick: function() {ivDel(obj.inverter[i]);}}, svg(iconDel, 25, 25, "icon icon-fg pointer")) ])); diff --git a/src/web/html/style.css b/src/web/html/style.css index 6f05ea77..05c58168 100644 --- a/src/web/html/style.css +++ b/src/web/html/style.css @@ -339,6 +339,7 @@ p { .fs-sm-8 { font-size: 1rem; } .d-sm-block { display: block !important;} + .d-sm-cell { display: table-cell !important;} .d-sm-none { display: none !important; } } diff --git a/src/web/html/system.html b/src/web/html/system.html index 477b3a7e..c7e74ef3 100644 --- a/src/web/html/system.html +++ b/src/web/html/system.html @@ -62,8 +62,8 @@ function irqBadge(state) { switch(state) { case 0: return badge(false, "unknown", "warning"); break; - case 1: return badge(true, "true"); break; - default: return badge(false, "false"); break; + case 1: return badge(true, "{#TRUE}"); break; + default: return badge(false, "{#FALSE}"); break; } } @@ -125,13 +125,13 @@ function parseMqtt(obj) { if(obj.enabled) { lines = [ - tr("{#CONNECTED}", badge(obj.connected, ((obj.connected) ? "true" : "false"))), + tr("{#CONNECTED}", badge(obj.connected, ((obj.connected) ? "{#TRUE}" : "{#FALSE}"))), tr("#TX", obj.tx_cnt), tr("#RX", obj.rx_cnt) ] } else - lines = tr("enabled", badge(false, "false")); + lines = tr("{#ENABLED}", badge(false, "{#FALSE}")); document.getElementById("info").append( headline("MqTT"), @@ -161,7 +161,7 @@ function parseIndex(obj) { if(obj.ts_sunrise > 0) { document.getElementById("info").append( - headline("Sun"), + headline("{#SUN}"), ml("table", {class: "table"}, ml("tbody", {}, [ tr("{#SUNRISE}", new Date(obj.ts_sunrise * 1000).toLocaleString('de-DE')), diff --git a/src/web/lang.json b/src/web/lang.json index 179c3e4e..ee8835c2 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -1052,6 +1052,11 @@ "token": "COMMUNICATING", "en": "communicating", "de": "kommunizierend" + }, + { + "token": "SUN", + "en": "Sun", + "de": "Sonne" } ] }, @@ -1240,7 +1245,7 @@ }, { "token": "PRODUCING", - "en": "producing", + "en": "is producing", "de": "produziert" }, { @@ -1248,11 +1253,6 @@ "en": "Inverter", "de": "Wechselrichter" }, - { - "token": "IS", - "en": "is", - "de": "ist" - }, { "token": "LAST_SUCCESS", "en": "last successful transmission", From f90aacc3c97c28e99e6ea7a699c9de1940cc770d Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 17 Aug 2024 00:35:27 +0200 Subject: [PATCH 04/40] 0.8.141 * fix display IP in ePaper display (ETH or WiFi, static or DHCP) #1439 --- src/CHANGES.md | 1 + src/app.h | 4 ++++ src/appInterface.h | 1 + src/hm/hmInverter.h | 2 +- src/network/AhoyNetwork.h | 2 +- src/plugins/Display/Display.h | 2 +- src/plugins/Display/Display_ePaper.cpp | 16 +++++++++------- src/plugins/Display/Display_ePaper.h | 3 ++- src/plugins/plugin_lang.h | 6 +++--- src/web/RestApi.h | 6 +++--- 10 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 0f1db603..254256e7 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -6,6 +6,7 @@ * increased maximum number of alarms to 50 for ESP32 #1470 * fix German translation #1688 * fix display of delete and edit buttons in `/setup` #1372 +* fix display IP in ePaper display (ETH or WiFi, static or DHCP) #1439 # RELEASE 0.8.140 - 2024-08-16 diff --git a/src/app.h b/src/app.h index d23f307e..c03251e0 100644 --- a/src/app.h +++ b/src/app.h @@ -195,6 +195,10 @@ class app : public IApp, public ah::Scheduler { return mNetwork->isApActive(); } + bool isNetworkConnected() override { + return mNetwork->isConnected(); + } + void setRebootFlag() override { once(std::bind(&app::tickReboot, this), 3, "rboot"); } diff --git a/src/appInterface.h b/src/appInterface.h index d49f907e..ca0fc172 100644 --- a/src/appInterface.h +++ b/src/appInterface.h @@ -34,6 +34,7 @@ class IApp { virtual String getIp(void) = 0; virtual String getMac(void) = 0; virtual bool isApActive(void) = 0; + virtual bool isNetworkConnected() = 0; virtual uint32_t getUptime() = 0; virtual uint32_t getTimestamp() = 0; diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index ecf7bbfb..d74fdc6d 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -117,7 +117,7 @@ const calcFunc_t calcFunctions[] = { template class Inverter { public: /*types*/ - #ifdef(ESP32) + #if defined(ESP32) constexpr static uint8_t MaxAlarmNum = 50; #else constexpr static uint8_t MaxAlarmNum = 10; diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index e64a13b1..4d465758 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -52,7 +52,7 @@ class AhoyNetwork { } bool isConnected() const { - return (mStatus == NetworkState::CONNECTED); + return ((mStatus == NetworkState::CONNECTED) || (mStatus == NetworkState::GOT_IP)); } bool updateNtpTime(void) { diff --git a/src/plugins/Display/Display.h b/src/plugins/Display/Display.h index 4654a4f4..c2d96aae 100644 --- a/src/plugins/Display/Display.h +++ b/src/plugins/Display/Display.h @@ -195,7 +195,7 @@ class Display { } #if defined(ESP32) else if (DISP_TYPE_T10_EPAPER == mCfg->type) { - mEpaper.loop((totalPower), totalYieldDay, totalYieldTotal, nrprod); + mEpaper.loop((totalPower), totalYieldDay, totalYieldTotal, nrprod, mApp->getIp(), mApp->isNetworkConnected()); mRefreshCycle++; if (mRefreshCycle > 2880) { // 15 * 2280 = 44300s = 12h diff --git a/src/plugins/Display/Display_ePaper.cpp b/src/plugins/Display/Display_ePaper.cpp index 654627d2..d9f64796 100644 --- a/src/plugins/Display/Display_ePaper.cpp +++ b/src/plugins/Display/Display_ePaper.cpp @@ -1,7 +1,6 @@ #include "Display_ePaper.h" #if defined(ESP32) -#include #include "../../utils/helper.h" #include "imagedata.h" #include "defines.h" @@ -13,7 +12,9 @@ static const uint32_t spiClk = 4000000; // 4 MHz SPIClass hspi(HSPI); #endif -DisplayEPaper::DisplayEPaper() { +DisplayEPaper::DisplayEPaper() + : mNetworkConnected {false} +{ mDisplayRotation = 2; mHeadFootPadding = 16; memset(_fmtText, 0, EPAPER_MAX_TEXT_LEN); @@ -122,8 +123,8 @@ void DisplayEPaper::headlineIP() { _display->fillScreen(GxEPD_BLACK); do { - if ((WiFi.isConnected() == true) && (WiFi.localIP() > 0)) { - snprintf(_fmtText, EPAPER_MAX_TEXT_LEN, "%s", WiFi.localIP().toString().c_str()); + if (mNetworkConnected == true) { + snprintf(_fmtText, EPAPER_MAX_TEXT_LEN, "%s", _settedIP.c_str()); } else { snprintf(_fmtText, EPAPER_MAX_TEXT_LEN, STR_NO_WIFI); } @@ -289,14 +290,15 @@ void DisplayEPaper::actualPowerPaged(float totalPower, float totalYieldDay, floa } while (_display->nextPage()); } //*************************************************************************** -void DisplayEPaper::loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) { +void DisplayEPaper::loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod, String ip, bool networkConnected) { + mNetworkConnected = networkConnected; if(RefreshStatus::DONE != mRefreshState) return; // check if the IP has changed - if (_settedIP != WiFi.localIP().toString()) { + if (_settedIP != ip) { // save the new IP and call the Headline Function to adapt the Headline - _settedIP = WiFi.localIP().toString(); + _settedIP = ip; headlineIP(); } diff --git a/src/plugins/Display/Display_ePaper.h b/src/plugins/Display/Display_ePaper.h index 2106c492..e3ab2f41 100644 --- a/src/plugins/Display/Display_ePaper.h +++ b/src/plugins/Display/Display_ePaper.h @@ -33,7 +33,7 @@ class DisplayEPaper { void fullRefresh(); void init(uint8_t type, uint8_t _CS, uint8_t _DC, uint8_t _RST, uint8_t _BUSY, uint8_t _SCK, uint8_t _MOSI, uint32_t* utcTs, const char* version); void config(uint8_t rotation, bool enPowerSave); - void loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod); + void loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod, String ip, bool networkConnected); void refreshLoop(); void tickerSecond(); @@ -66,6 +66,7 @@ class DisplayEPaper { uint8_t mSecondCnt; bool mLogoDisplayed; + bool mNetworkConnected; #if defined(SPI_HAL) epdHal hal; #endif diff --git a/src/plugins/plugin_lang.h b/src/plugins/plugin_lang.h index 8d7a987f..e4f1db23 100644 --- a/src/plugins/plugin_lang.h +++ b/src/plugins/plugin_lang.h @@ -12,7 +12,7 @@ #define STR_OFFLINE "aus" #define STR_ONLINE "aktiv" #define STR_NO_INVERTER "kein inverter" - #define STR_NO_WIFI "WLAN nicht verbunden" + #define STR_NO_WIFI "Netzwerk nicht verbunden" #define STR_VERSION "Version" #define STR_ACTIVE_INVERTERS "aktive WR" #define STR_TODAY "heute" @@ -23,7 +23,7 @@ #define STR_OFFLINE "eteint" #define STR_ONLINE "online" #define STR_NO_INVERTER "pas d'onduleur" - #define STR_NO_WIFI "WiFi not connected" + #define STR_NO_WIFI "Network not connected" #define STR_VERSION "Version" #define STR_ACTIVE_INVERTERS "active Inv" #define STR_TODAY "today" @@ -34,7 +34,7 @@ #define STR_OFFLINE "offline" #define STR_ONLINE "online" #define STR_NO_INVERTER "no inverter" - #define STR_NO_WIFI "WiFi not connected" + #define STR_NO_WIFI "Network not connected" #define STR_VERSION "Version" #define STR_ACTIVE_INVERTERS "active Inv" #define STR_TODAY "today" diff --git a/src/web/RestApi.h b/src/web/RestApi.h index b378b1da..7e7971e4 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -674,15 +674,15 @@ class RestApi { // find oldest alarm uint8_t offset = 0; uint32_t oldestStart = 0xffffffff; - for(uint8_t i = 0; i < hmInverter::MaxAlarmNum; i++) { + for(uint8_t i = 0; i < Inverter<>::MaxAlarmNum; i++) { if((iv->lastAlarm[i].start != 0) && (iv->lastAlarm[i].start < oldestStart)) { offset = i; oldestStart = iv->lastAlarm[i].start; } } - for(uint8_t i = 0; i < hmInverter::MaxAlarmNum; i++) { - uint8_t pos = (i + offset) % hmInverter::MaxAlarmNum; + for(uint8_t i = 0; i < Inverter<>::MaxAlarmNum; i++) { + uint8_t pos = (i + offset) % Inverter<>::MaxAlarmNum; alarm[pos][F("code")] = iv->lastAlarm[pos].code; alarm[pos][F("str")] = iv->getAlarmStr(iv->lastAlarm[pos].code); alarm[pos][F("start")] = iv->lastAlarm[pos].start; From 85f854037acc5e8b8f4df317589e1adb33de3b3a Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 17 Aug 2024 00:51:45 +0200 Subject: [PATCH 05/40] 0.8.141 * fix compile --- src/web/web.h | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/web/web.h b/src/web/web.h index 64071e51..8ac18d9a 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -245,7 +245,7 @@ class Web { if (CHECK_MASK(mConfig->sys.protectionMask, mask)) checkProtection(request); - AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), zippedHtml, len); + AsyncWebServerResponse *response = beginResponse(request, 200, F("text/html; charset=UTF-8"), zippedHtml, len); response->addHeader(F("Content-Encoding"), "gzip"); response->addHeader(F("content-type"), "text/html; charset=UTF-8"); if(request->hasParam("v")) @@ -343,7 +343,7 @@ class Web { } } - AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), login_html, login_html_len); + AsyncWebServerResponse *response = beginResponse(request, 200, F("text/html; charset=UTF-8"), login_html, login_html_len); response->addHeader(F("Content-Encoding"), "gzip"); request->send(response); } @@ -354,7 +354,7 @@ class Web { checkProtection(request); mApp->lock(true); - AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), system_html, system_html_len); + AsyncWebServerResponse *response = beginResponse(request, 200, F("text/html; charset=UTF-8"), system_html, system_html_len); response->addHeader(F("Content-Encoding"), "gzip"); request->send(response); } @@ -363,9 +363,9 @@ class Web { DPRINTLN(DBG_VERBOSE, F("onColor")); AsyncWebServerResponse *response; if (mConfig->sys.darkMode) - response = request->beginResponse(200, F("text/css"), colorDark_css, colorDark_css_len); + response = beginResponse(request, 200, F("text/css"), colorDark_css, colorDark_css_len); else - response = request->beginResponse(200, F("text/css"), colorBright_css, colorBright_css_len); + response = beginResponse(request, 200, F("text/css"), colorBright_css, colorBright_css_len); response->addHeader(F("Content-Encoding"), "gzip"); if(request->hasParam("v")) { response->addHeader(F("Cache-Control"), F("max-age=604800")); @@ -375,7 +375,7 @@ class Web { void onCss(AsyncWebServerRequest *request) { DPRINTLN(DBG_VERBOSE, F("onCss")); - AsyncWebServerResponse *response = request->beginResponse(200, F("text/css"), style_css, style_css_len); + AsyncWebServerResponse *response = beginResponse(request, 200, F("text/css"), style_css, style_css_len); response->addHeader(F("Content-Encoding"), "gzip"); if(request->hasParam("v")) { response->addHeader(F("Cache-Control"), F("max-age=604800")); @@ -386,7 +386,7 @@ class Web { void onApiJs(AsyncWebServerRequest *request) { DPRINTLN(DBG_VERBOSE, F("onApiJs")); - AsyncWebServerResponse *response = request->beginResponse(200, F("text/javascript"), api_js, api_js_len); + AsyncWebServerResponse *response = beginResponse(request, 200, F("text/javascript"), api_js, api_js_len); response->addHeader(F("Content-Encoding"), "gzip"); if(request->hasParam("v")) response->addHeader(F("Cache-Control"), F("max-age=604800")); @@ -396,7 +396,7 @@ class Web { void onGridInfoJson(AsyncWebServerRequest *request) { DPRINTLN(DBG_VERBOSE, F("onGridInfoJson")); - AsyncWebServerResponse *response = request->beginResponse(200, F("application/json; charset=utf-8"), grid_info_json, grid_info_json_len); + AsyncWebServerResponse *response = beginResponse(request, 200, F("application/json; charset=utf-8"), grid_info_json, grid_info_json_len); response->addHeader(F("Content-Encoding"), "gzip"); if(request->hasParam("v")) response->addHeader(F("Cache-Control"), F("max-age=604800")); @@ -405,7 +405,7 @@ class Web { void onFavicon(AsyncWebServerRequest *request) { static const char favicon_type[] PROGMEM = "image/x-icon"; - AsyncWebServerResponse *response = request->beginResponse(200, favicon_type, favicon_ico, favicon_ico_len); + AsyncWebServerResponse *response = beginResponse(request, 200, favicon_type, favicon_ico, favicon_ico_len); response->addHeader(F("Content-Encoding"), "gzip"); request->send(response); } @@ -418,7 +418,7 @@ class Web { void onReboot(AsyncWebServerRequest *request) { mApp->setRebootFlag(); - AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), system_html, system_html_len); + AsyncWebServerResponse *response = beginResponse(request, 200, F("text/html; charset=UTF-8"), system_html, system_html_len); response->addHeader(F("Content-Encoding"), "gzip"); request->send(response); } @@ -426,7 +426,7 @@ class Web { void showHtml(AsyncWebServerRequest *request) { checkProtection(request); - AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), system_html, system_html_len); + AsyncWebServerResponse *response = beginResponse(request, 200, F("text/html; charset=UTF-8"), system_html, system_html_len); response->addHeader(F("Content-Encoding"), "gzip"); request->send(response); } @@ -443,7 +443,7 @@ class Web { } #endif - AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), wizard_html, wizard_html_len); + AsyncWebServerResponse *response = beginResponse(request, 200, F("text/html; charset=UTF-8"), wizard_html, wizard_html_len); response->addHeader(F("Content-Encoding"), "gzip"); response->addHeader(F("content-type"), "text/html; charset=UTF-8"); request->send(response); @@ -635,7 +635,7 @@ class Web { mApp->saveSettings((request->arg("reboot") == "on")); - AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), save_html, save_html_len); + AsyncWebServerResponse *response = beginResponse(request, 200, F("text/html; charset=UTF-8"), save_html, save_html_len); response->addHeader(F("Content-Encoding"), "gzip"); request->send(response); } @@ -649,7 +649,7 @@ class Web { } void onAbout(AsyncWebServerRequest *request) { - AsyncWebServerResponse *response = request->beginResponse(200, F("text/html; charset=UTF-8"), about_html, about_html_len); + AsyncWebServerResponse *response = beginResponse(request, 200, F("text/html; charset=UTF-8"), about_html, about_html_len); response->addHeader(F("Content-Encoding"), "gzip"); response->addHeader(F("content-type"), "text/html; charset=UTF-8"); if(request->hasParam("v")) { @@ -673,6 +673,14 @@ class Web { getPage(request, PROT_MASK_SYSTEM, system_html, system_html_len); } + AsyncWebServerResponse* beginResponse(AsyncWebServerRequest *request, int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback=nullptr) { + #if defined(ESP32) + return request->beginResponse(code, contentType, content, len); + #else + return request->beginResponse_P(code, contentType, content, len); + #endif + } + #ifdef ENABLE_PROMETHEUS_EP // Note From 7a3f4c125d2f5e09ae156f9254438ced144a9904 Mon Sep 17 00:00:00 2001 From: DanielR92 Date: Tue, 27 Aug 2024 17:04:08 +0200 Subject: [PATCH 06/40] add read_temp_c to system + mqtt --- src/publisher/pubMqtt.h | 3 ++- src/publisher/pubMqttDefs.h | 3 ++- src/utils/helper.cpp | 17 ++++++++++++++++- src/utils/helper.h | 2 ++ src/web/RestApi.h | 2 ++ src/web/html/system.html | 3 ++- 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index 6e021bed..f593e620 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -158,6 +158,7 @@ class PubMqtt { 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()); + publish(subtopics[MQTT_TEMP_SENS_C], String(ah::readTemperature()).c_str()); #ifndef ESP32 publish(subtopics[MQTT_HEAP_FRAG], String(ESP.getHeapFragmentation()).c_str()); #endif @@ -656,7 +657,7 @@ class PubMqtt { size_t index; size_t total; - message_s() + message_s() : topic { nullptr } , payload { nullptr } , len { 0 } diff --git a/src/publisher/pubMqttDefs.h b/src/publisher/pubMqttDefs.h index c97daa78..22239a0d 100644 --- a/src/publisher/pubMqttDefs.h +++ b/src/publisher/pubMqttDefs.h @@ -56,7 +56,8 @@ enum { MQTT_STATUS, MQTT_LWT_ONLINE, MQTT_LWT_OFFLINE, - MQTT_ACK_PWR_LMT + MQTT_ACK_PWR_LMT, + MQTT_TEMP_SENS_C }; const char* const subtopics[] PROGMEM = { diff --git a/src/utils/helper.cpp b/src/utils/helper.cpp index edb9b9b9..7fd025d8 100644 --- a/src/utils/helper.cpp +++ b/src/utils/helper.cpp @@ -2,7 +2,7 @@ // 2023 Ahoy, https://github.com/lumpapu/ahoy // Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ //----------------------------------------------------------------------------- - +#include #include "helper.h" #include "dbg.h" #include "../plugins/plugin_lang.h" @@ -142,4 +142,19 @@ namespace ah { } DBGPRINTLN(""); } + float readTemperature() { + /*// ADC1 channel 0 is GPIO36 + adc1_config_width(ADC_WIDTH_BIT_12); + adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_0); + int adc_reading = adc1_get_raw(ADC1_CHANNEL_0); + // Convert the raw ADC reading to a voltage in mV + esp_adc_cal_characteristics_t characteristics; + esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_0, ADC_WIDTH_BIT_12, 1100, &characteristics); + uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, &characteristics); + // Convert the voltage to a temperature in Celsius + // This formula is an approximation and might need to be calibrated for your specific use case. + float temperature = (voltage - 500) / 10.0;*/ + + return temperatureRead(); + } } diff --git a/src/utils/helper.h b/src/utils/helper.h index ff1a9aed..c09bfb9c 100644 --- a/src/utils/helper.h +++ b/src/utils/helper.h @@ -49,6 +49,8 @@ namespace ah { String getTimeStrMs(uint64_t t); uint64_t Serial2u64(const char *val); void dumpBuf(uint8_t buf[], uint8_t len, uint8_t firstRepl = 0, uint8_t lastRepl = 0); + + float readTemperature(); } #endif /*__HELPER_H__*/ diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 7e7971e4..b3d9df1f 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -822,6 +822,8 @@ class RestApi { void getChipInfo(JsonObject obj) { obj[F("cpu_freq")] = ESP.getCpuFreqMHz(); obj[F("sdk")] = ESP.getSdkVersion(); + obj[F("temp_sensor_c")] = ah::readTemperature(); + #if defined(ESP32) obj[F("revision")] = ESP.getChipRevision(); obj[F("model")] = ESP.getChipModel(); diff --git a/src/web/html/system.html b/src/web/html/system.html index c7e74ef3..daaa5e05 100644 --- a/src/web/html/system.html +++ b/src/web/html/system.html @@ -44,7 +44,8 @@ tr("{#ENVIRONMENT}", obj.generic.env + " ({#BUILD_OPTIONS}: " + obj.generic.modules + ")"), tr("Version", obj.generic.version + " - " + obj.generic.build), tr("Chip", "CPU: " + obj.chip.cpu_freq + "MHz, " + obj.chip.cores + " Core(s)"), - tr("Chip Model", obj.chip.model) + tr("Chip Model", obj.chip.model), + tr("Chip temp.", obj.chip.temp_sensor_c + "°C"), ] document.getElementById("info").append( From e64f22336cb36d32992a32362ae5227a3d88b9ff Mon Sep 17 00:00:00 2001 From: lumapu Date: Wed, 28 Aug 2024 22:36:16 +0200 Subject: [PATCH 07/40] 0.8.142 * merge PR: add read_temp_c to system + mqtt #1739 * improved sending limits of multiple inverters in very short timeframe #1726 * don't show '0 dBm' once no inverter is available, changed to '-- dBm' --- src/CHANGES.md | 5 +++++ src/defines.h | 2 +- src/hm/Communication.h | 8 +++++++- src/web/html/visualization.html | 5 ++++- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 254256e7..1c06a1e8 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,10 @@ # Development Changes +## 0.8.142 - 2024-08-28 +* merge PR: add read_temp_c to system + mqtt #1739 +* improved sending limits of multiple inverters in very short timeframe #1726 +* don't show '0 dBm' once no inverter is available, changed to '-- dBm' + ## 0.8.141 - 2024-08-16 * switch AsyncWebserver to https://github.com/mathieucarbou/ESPAsyncWebServer * fix missing translations to German #1717 diff --git a/src/defines.h b/src/defines.h index 341ed04f..2a0646be 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 141 +#define VERSION_PATCH 142 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 3192c513..e5a18858 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -29,7 +29,9 @@ class Communication : public CommQueue<> { } void addImportant(Inverter<> *iv, uint8_t cmd) { - mState = States::RESET; // cancel current operation + if(!mIsDevControl) // only reset communication once there is no other devcontrol command + mState = States::RESET; // cancel current operation + mIsDevControl = true; CommQueue::addImportant(iv, cmd); } @@ -77,6 +79,9 @@ class Communication : public CommQueue<> { mLocalBuf[i].len = 0; } + if(!q->isDevControl) + mIsDevControl = false; // reset devcontrol flag + if(*mSerialDebug) mHeu.printStatus(q->iv); mHeu.getTxCh(q->iv); @@ -1042,6 +1047,7 @@ class Communication : public CommQueue<> { Heuristic mHeu; uint32_t mLastEmptyQueueMillis = 0; bool mPrintSequenceDuration = false; + bool mIsDevControl = false; // holds if current command is devcontrol }; #endif /*__COMMUNICATION_H__*/ diff --git a/src/web/html/visualization.html b/src/web/html/visualization.html index 507a6f9f..c04425d9 100644 --- a/src/web/html/visualization.html +++ b/src/web/html/visualization.html @@ -208,8 +208,11 @@ if(obj.rssi > -127) { if(obj.generation < 2) ageInfo += " (RSSI: " + ((obj.rssi == -64) ? ">=" : "<") + " -64 dBm)"; - else + else { + if(obj.rssi == 0) + obj.rssi = "--"; ageInfo += " (RSSI: " + obj.rssi + " dBm)"; + } } return ml("div", {class: "mb-5"}, [ From 565a69e5c09a597f699c6dded43a44aada72bb98 Mon Sep 17 00:00:00 2001 From: lumapu Date: Wed, 28 Aug 2024 22:47:48 +0200 Subject: [PATCH 08/40] 0.8.142 * fix compile for ESP8266 --- src/publisher/pubMqtt.h | 3 ++- src/utils/helper.cpp | 5 +++++ src/web/RestApi.h | 2 +- src/web/html/system.html | 6 ++++-- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index f593e620..04494d7d 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -158,8 +158,9 @@ class PubMqtt { 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()); + #if defined(ESP32) publish(subtopics[MQTT_TEMP_SENS_C], String(ah::readTemperature()).c_str()); - #ifndef ESP32 + #else ESP32 publish(subtopics[MQTT_HEAP_FRAG], String(ESP.getHeapFragmentation()).c_str()); #endif } diff --git a/src/utils/helper.cpp b/src/utils/helper.cpp index 7fd025d8..7d0c2cfb 100644 --- a/src/utils/helper.cpp +++ b/src/utils/helper.cpp @@ -142,6 +142,7 @@ namespace ah { } DBGPRINTLN(""); } + float readTemperature() { /*// ADC1 channel 0 is GPIO36 adc1_config_width(ADC_WIDTH_BIT_12); @@ -155,6 +156,10 @@ namespace ah { // This formula is an approximation and might need to be calibrated for your specific use case. float temperature = (voltage - 500) / 10.0;*/ + #if defined(ESP_32) return temperatureRead(); + #else + return 0; + #endif } } diff --git a/src/web/RestApi.h b/src/web/RestApi.h index b3d9df1f..a868b31c 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -822,9 +822,9 @@ class RestApi { void getChipInfo(JsonObject obj) { obj[F("cpu_freq")] = ESP.getCpuFreqMHz(); obj[F("sdk")] = ESP.getSdkVersion(); - obj[F("temp_sensor_c")] = ah::readTemperature(); #if defined(ESP32) + obj[F("temp_sensor_c")] = ah::readTemperature(); obj[F("revision")] = ESP.getChipRevision(); obj[F("model")] = ESP.getChipModel(); obj[F("cores")] = ESP.getChipCores(); diff --git a/src/web/html/system.html b/src/web/html/system.html index daaa5e05..2e5d44a8 100644 --- a/src/web/html/system.html +++ b/src/web/html/system.html @@ -44,8 +44,10 @@ tr("{#ENVIRONMENT}", obj.generic.env + " ({#BUILD_OPTIONS}: " + obj.generic.modules + ")"), tr("Version", obj.generic.version + " - " + obj.generic.build), tr("Chip", "CPU: " + obj.chip.cpu_freq + "MHz, " + obj.chip.cores + " Core(s)"), - tr("Chip Model", obj.chip.model), - tr("Chip temp.", obj.chip.temp_sensor_c + "°C"), + tr("Chip Model", obj.chip.model) + /*IF_ESP32*/ + ,tr("Chip temp.", obj.chip.temp_sensor_c + "°C") + /*ENDIF_ESP32*/ ] document.getElementById("info").append( From 62ad9648b5c1bf8480b9c69ebb09a2a77db5cf41 Mon Sep 17 00:00:00 2001 From: lumapu Date: Thu, 29 Aug 2024 22:52:02 +0200 Subject: [PATCH 09/40] 0.8.143 * fixed crash #1743 --- src/CHANGES.md | 3 +++ src/defines.h | 2 +- src/publisher/pubMqtt.h | 5 +++-- src/publisher/pubMqttDefs.h | 3 ++- src/utils/helper.cpp | 2 +- src/web/html/system.html | 2 +- 6 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 1c06a1e8..6975fbf1 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,8 @@ # Development Changes +## 0.8.143 - 2024-08-29 +* fixed crash #1743 + ## 0.8.142 - 2024-08-28 * merge PR: add read_temp_c to system + mqtt #1739 * improved sending limits of multiple inverters in very short timeframe #1726 diff --git a/src/defines.h b/src/defines.h index 2a0646be..2f32e49e 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 142 +#define VERSION_PATCH 143 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index 04494d7d..49b209f5 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -159,8 +159,9 @@ class PubMqtt { publish(subtopics[MQTT_RSSI], String(WiFi.RSSI()).c_str()); publish(subtopics[MQTT_FREE_HEAP], String(ESP.getFreeHeap()).c_str()); #if defined(ESP32) - publish(subtopics[MQTT_TEMP_SENS_C], String(ah::readTemperature()).c_str()); - #else ESP32 + snprintf(mVal.data(), mVal.size(), "%.2f", ah::readTemperature()); + publish(subtopics[MQTT_TEMP_SENS_C], mVal.data()); + #else publish(subtopics[MQTT_HEAP_FRAG], String(ESP.getHeapFragmentation()).c_str()); #endif } diff --git a/src/publisher/pubMqttDefs.h b/src/publisher/pubMqttDefs.h index 22239a0d..691bb098 100644 --- a/src/publisher/pubMqttDefs.h +++ b/src/publisher/pubMqttDefs.h @@ -77,7 +77,8 @@ const char* const subtopics[] PROGMEM = { "status", "connected", "not_connected", - "ack_pwr_limit" + "ack_pwr_limit", + "cpu_temp" }; enum { diff --git a/src/utils/helper.cpp b/src/utils/helper.cpp index 7d0c2cfb..b30f58e0 100644 --- a/src/utils/helper.cpp +++ b/src/utils/helper.cpp @@ -156,7 +156,7 @@ namespace ah { // This formula is an approximation and might need to be calibrated for your specific use case. float temperature = (voltage - 500) / 10.0;*/ - #if defined(ESP_32) + #if defined(ESP32) return temperatureRead(); #else return 0; diff --git a/src/web/html/system.html b/src/web/html/system.html index 2e5d44a8..a6223455 100644 --- a/src/web/html/system.html +++ b/src/web/html/system.html @@ -46,7 +46,7 @@ tr("Chip", "CPU: " + obj.chip.cpu_freq + "MHz, " + obj.chip.cores + " Core(s)"), tr("Chip Model", obj.chip.model) /*IF_ESP32*/ - ,tr("Chip temp.", obj.chip.temp_sensor_c + "°C") + ,tr("Chip temp.", Math.round(obj.chip.temp_sensor_c * 10) / 10 + "°C") /*ENDIF_ESP32*/ ] From 84f21f441b0253346db5f9157b88a4345ed6ef4c Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 14 Sep 2024 12:06:20 +0200 Subject: [PATCH 10/40] fixed NTP and DNS --- src/app.cpp | 8 +++++-- src/network/AhoyNetwork.h | 50 ++++++++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index c6a689ee..35db3f31 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -153,10 +153,13 @@ void app::onNetwork(bool gotIp) { if(gotIp) { ah::Scheduler::resetTicker(); regularTickers(); //reinstall regular tickers - every(std::bind(&app::tickSend, this), mConfig->inst.sendInterval, "tSend"); + if(!mConfig->inst.startWithoutTime) // already set in regularTickers + every(std::bind(&app::tickSend, this), mConfig->inst.sendInterval, "tSend"); mTickerInstallOnce = true; mSunrise = 0; // needs to be set to 0, to reinstall sunrise and ivComm tickers! - once(std::bind(&app::tickNtpUpdate, this), 2, "ntp2"); + + uint32_t nextTrig = (mTimestamp < 0x1337) ? 0 : (mConfig->ntp.interval * 60); + once(std::bind(&app::tickNtpUpdate, this), nextTrig, "ntp"); } } @@ -237,6 +240,7 @@ void app::tickNtpUpdate(void) { nxtTrig = mConfig->ntp.interval * 60; // check again in configured interval mNtpReceived = false; } + yield(); updateNtp(); diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index e64a13b1..e60a8e68 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -11,9 +11,9 @@ #include "../utils/helper.h" #include "AhoyWifiAp.h" #include "AsyncJson.h" +#include #define NTP_PACKET_SIZE 48 - class AhoyNetwork { public: typedef std::function OnNetworkCB; @@ -26,6 +26,8 @@ class AhoyNetwork { mOnNetworkCB = onNetworkCB; mOnTimeCB = onTimeCB; + mNtpIp = IPAddress(0, 0, 0, 0); + if('\0' == mConfig->sys.deviceName[0]) snprintf(mConfig->sys.deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME); @@ -55,24 +57,41 @@ class AhoyNetwork { return (mStatus == NetworkState::CONNECTED); } - bool updateNtpTime(void) { - if(NetworkState::GOT_IP != mStatus) - return false; + static void dnsCallback(const char *name, const ip_addr_t *ipaddr, void *pClass) { + AhoyNetwork *obj = static_cast(pClass); + if (ipaddr) { + obj->mNtpIp = ipaddr->u_addr.ip4.addr; + } + } + + void updateNtpTime() { + if(mNtpIp != 0) { + startNtpUpdate(); + return; + } + + ip_addr_t ipaddr; + mNtpIp = WiFi.gatewayIP(); + err_t err = dns_gethostbyname(mConfig->ntp.addr, &ipaddr, dnsCallback, this); + if (err == ERR_OK) { + mNtpIp = ipaddr.u_addr.ip4.addr; + startNtpUpdate(); + } + } + + protected: + void startNtpUpdate() { + DPRINTLN(DBG_INFO, F("get time from: ") + mNtpIp.toString()); if (!mUdp.connected()) { - IPAddress timeServer; - if (!WiFi.hostByName(mConfig->ntp.addr, timeServer)) - return false; - if (!mUdp.connect(timeServer, mConfig->ntp.port)) - return false; + if (!mUdp.connect(mNtpIp, mConfig->ntp.port)) + return; } mUdp.onPacket([this](AsyncUDPPacket packet) { this->handleNTPPacket(packet); }); sendNTPpacket(); - - return true; } public: @@ -185,7 +204,7 @@ class AhoyNetwork { std::swap(sort[i], sort[j]); } - private: + protected: void sendNTPpacket(void) { uint8_t buf[NTP_PACKET_SIZE]; memset(buf, 0, NTP_PACKET_SIZE); @@ -194,11 +213,6 @@ class AhoyNetwork { buf[1] = 0; // Stratum buf[2] = 6; // Max Interval between messages in seconds buf[3] = 0xEC; // Clock Precision - // bytes 4 - 11 are for Root Delay and Dispersion and were set to 0 by memset - buf[12] = 49; // four-byte reference ID identifying - buf[13] = 0x4E; - buf[14] = 49; - buf[15] = 52; mUdp.write(buf, NTP_PACKET_SIZE); } @@ -245,6 +259,8 @@ class AhoyNetwork { AhoyWifiAp mAp; DNSServer mDns; + IPAddress mNtpIp; + AsyncUDP mUdp; // for time server #if defined(ESP8266) WiFiEventHandler wifiConnectHandler, wifiDisconnectHandler, wifiGotIPHandler; From 384ee6ea7f76de675a6d53cb975f3969dd935d7f Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 14 Sep 2024 12:10:40 +0200 Subject: [PATCH 11/40] added comments and cleanup --- src/network/AhoyNetwork.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index e60a8e68..af3c600f 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -72,6 +72,8 @@ class AhoyNetwork { ip_addr_t ipaddr; mNtpIp = WiFi.gatewayIP(); + // dns_gethostbyname runs asynchronous and sets the member mNtpIp which is then checked on + // next call of updateNtpTime err_t err = dns_gethostbyname(mConfig->ntp.addr, &ipaddr, dnsCallback, this); if (err == ERR_OK) { @@ -92,6 +94,9 @@ class AhoyNetwork { this->handleNTPPacket(packet); }); sendNTPpacket(); + + // reset to start with DNS lookup next time again + mNtpIp = IPAddress(0, 0, 0, 0); } public: From 9bc8385af18f8a85f324c675386d5717272c1dc4 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 14 Sep 2024 12:12:56 +0200 Subject: [PATCH 12/40] 0.8.144 * fix NTP lookup if internet connection is not there * added fallback for NTP to gateway IP --- src/CHANGES.md | 4 ++++ src/defines.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 6975fbf1..de2d149d 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,9 @@ # Development Changes +## 0.8.144 - 2024-09-14 +* fix NTP lookup if internet connection is not there +* added fallback for NTP to gateway IP + ## 0.8.143 - 2024-08-29 * fixed crash #1743 diff --git a/src/defines.h b/src/defines.h index 2f32e49e..6921c720 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 143 +#define VERSION_PATCH 144 //------------------------------------- typedef struct { uint8_t ch; From 97d978632a7a92b62227afa835ef0a9dbbcdbb32 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 14 Sep 2024 12:40:01 +0200 Subject: [PATCH 13/40] 0.8.144 fix ESP8266 compile --- src/network/AhoyNetwork.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index 5ecb6ef4..059d2603 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -26,7 +26,7 @@ class AhoyNetwork { mOnNetworkCB = onNetworkCB; mOnTimeCB = onTimeCB; - mNtpIp = IPAddress(0, 0, 0, 0); + mNtpIp = IPADDR_NONE; if('\0' == mConfig->sys.deviceName[0]) snprintf(mConfig->sys.deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME); @@ -60,12 +60,16 @@ class AhoyNetwork { static void dnsCallback(const char *name, const ip_addr_t *ipaddr, void *pClass) { AhoyNetwork *obj = static_cast(pClass); if (ipaddr) { + #if defined(ESP32) obj->mNtpIp = ipaddr->u_addr.ip4.addr; + #else + obj->mNtpIp = ipaddr->addr; + #endif } } void updateNtpTime() { - if(mNtpIp != 0) { + if(mNtpIp != IPADDR_NONE) { startNtpUpdate(); return; } @@ -77,7 +81,11 @@ class AhoyNetwork { err_t err = dns_gethostbyname(mConfig->ntp.addr, &ipaddr, dnsCallback, this); if (err == ERR_OK) { + #if defined(ESP32) mNtpIp = ipaddr.u_addr.ip4.addr; + #else + mNtpIp = ipaddr.addr; + #endif startNtpUpdate(); } } @@ -96,7 +104,7 @@ class AhoyNetwork { sendNTPpacket(); // reset to start with DNS lookup next time again - mNtpIp = IPAddress(0, 0, 0, 0); + mNtpIp = IPADDR_NONE; } public: From 2a990978d86356dcbe5a43450e98c32481d810c1 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 22 Sep 2024 01:03:12 +0200 Subject: [PATCH 14/40] 0.8.145 * fix NTP related issues #1748 #1752 * fix MqTT discovery total #1715 * upgrade webserver version for ESP32 devices --- src/CHANGES.md | 5 ++ src/app.cpp | 111 ++++++++++++++-------------------- src/app.h | 9 ++- src/defines.h | 2 +- src/network/AhoyNetwork.h | 36 ++++++++--- src/network/AhoyWifiEsp32.h | 1 + src/network/AhoyWifiEsp8266.h | 1 + src/platformio.ini | 2 +- src/publisher/pubMqtt.h | 24 +++++--- src/utils/scheduler.h | 19 +++--- 10 files changed, 112 insertions(+), 98 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index de2d149d..97c0c595 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,10 @@ # Development Changes +## 0.8.145 - 2024-09-22 +* fix NTP related issues #1748 #1752 +* fix MqTT discovery total #1715 +* upgrade webserver version for ESP32 devices + ## 0.8.144 - 2024-09-14 * fix NTP lookup if internet connection is not there * added fallback for NTP to gateway IP diff --git a/src/app.cpp b/src/app.cpp index 35db3f31..5a992f74 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -13,7 +13,15 @@ //----------------------------------------------------------------------------- -app::app() : ah::Scheduler {} { +app::app() + : ah::Scheduler {} + , mSunrise {0} + , mSunset {0} + , idTickMqttSecond {MAX_NUM_TICKER} + , idTickMqttMinute {MAX_NUM_TICKER} + , idTickMidnight {MAX_NUM_TICKER} + , idTickReboot {MAX_NUM_TICKER} +{ memset(mVersion, 0, sizeof(char) * 12); memset(mVersionModules, 0, sizeof(char) * 12); } @@ -51,7 +59,7 @@ void app::setup() { #else mNetwork = static_cast(new AhoyWifi()); #endif - mNetwork->setup(mConfig, &mTimestamp, [this](bool gotIp) { this->onNetwork(gotIp); }, [this](bool gotTime) { this->onNtpUpdate(gotTime); }); + mNetwork->setup(mConfig, [this](bool gotIp) { this->onNetwork(gotIp); }, [this](uint32_t gotTime) { this->onNtpUpdate(gotTime); }); mNetwork->begin(); esp_task_wdt_reset(); @@ -151,15 +159,19 @@ void app::loop(void) { void app::onNetwork(bool gotIp) { mNetworkConnected = gotIp; if(gotIp) { - ah::Scheduler::resetTicker(); - regularTickers(); //reinstall regular tickers + mNetwork->updateNtpTime(); if(!mConfig->inst.startWithoutTime) // already set in regularTickers every(std::bind(&app::tickSend, this), mConfig->inst.sendInterval, "tSend"); - mTickerInstallOnce = true; - mSunrise = 0; // needs to be set to 0, to reinstall sunrise and ivComm tickers! - uint32_t nextTrig = (mTimestamp < 0x1337) ? 0 : (mConfig->ntp.interval * 60); - once(std::bind(&app::tickNtpUpdate, this), nextTrig, "ntp"); + #if defined(ENABLE_MQTT) + if (mMqttEnabled) { + if(MAX_NUM_TICKER == idTickMqttSecond) + idTickMqttSecond = everySec(std::bind(&PubMqttType::tickerSecond, &mMqtt), "mqttS"); + + if(MAX_NUM_TICKER == idTickMqttMinute) + idTickMqttMinute = everyMin(std::bind(&PubMqttType::tickerMinute, &mMqtt), "mqttM"); + } + #endif /*ENABLE_MQTT*/ } } @@ -170,9 +182,15 @@ void app::regularTickers(void) { everySec([this]() { mProtection->tickSecond(); }, "prot"); everySec([this]() {mNetwork->tickNetworkLoop(); }, "net"); - if(mConfig->inst.startWithoutTime && !mNetworkConnected) + if(mConfig->inst.startWithoutTime) every(std::bind(&app::tickSend, this), mConfig->inst.sendInterval, "tSend"); + + every([this]() { mNetwork->updateNtpTime(); }, mConfig->ntp.interval * 60, "ntp"); + + if (mConfig->inst.rstValsNotAvail) + everyMin(std::bind(&app::tickMinute, this), "tMin"); + // Plugins #if defined(PLUGIN_DISPLAY) if (DISP_TYPE_T0_NONE != mConfig->plugin.display.type) @@ -191,62 +209,32 @@ void app::regularTickers(void) { } //----------------------------------------------------------------------------- -void app::onNtpUpdate(bool gotTime) { - mNtpReceived = true; - if ((0 == mSunrise) && (0.0 != mConfig->sun.lat) && (0.0 != mConfig->sun.lon)) { - mCalculatedTimezoneOffset = (int8_t)((mConfig->sun.lon >= 0 ? mConfig->sun.lon + 7.5 : mConfig->sun.lon - 7.5) / 15) * 3600; - tickCalcSunrise(); - } - - if (mTickerInstallOnce) { - mTickerInstallOnce = false; - #if defined(ENABLE_MQTT) - if (mMqttEnabled) { - mMqtt.tickerSecond(); - everySec(std::bind(&PubMqttType::tickerSecond, &mMqtt), "mqttS"); - everyMin(std::bind(&PubMqttType::tickerMinute, &mMqtt), "mqttM"); +void app::onNtpUpdate(uint32_t utcTimestamp) { + if(0 == utcTimestamp) { + // try again in 5s + once([this]() { mNetwork->updateNtpTime(); }, 5, "ntp"); + } else { + mTimestamp = utcTimestamp; + DPRINTLN(DBG_INFO, "[NTP]: " + ah::getDateTimeStr(mTimestamp) + " UTC"); + + uint32_t localTime = gTimezone.toLocal(mTimestamp); + uint32_t midTrig = gTimezone.toUTC(localTime - (localTime % 86400) + 86400); // next midnight local time + resetById(idTickMidnight); + idTickMidnight = onceAt(std::bind(&app::tickMidnight, this), midTrig, "midNi"); + + if (mConfig->sys.schedReboot) { + resetById(idTickReboot); + uint32_t rebootTrig = gTimezone.toUTC(localTime - (localTime % 86400) + 86410); // reboot 10 secs after midnght + idTickReboot = onceAt(std::bind(&app::tickReboot, this), rebootTrig, "midRe"); } - #endif /*ENABLE_MQTT*/ - - if (mConfig->inst.rstValsNotAvail) - everyMin(std::bind(&app::tickMinute, this), "tMin"); - if(mNtpReceived) { - uint32_t localTime = gTimezone.toLocal(mTimestamp); - uint32_t midTrig = gTimezone.toUTC(localTime - (localTime % 86400) + 86400); // next midnight local time - onceAt(std::bind(&app::tickMidnight, this), midTrig, "midNi"); - - if (mConfig->sys.schedReboot) { - uint32_t rebootTrig = gTimezone.toUTC(localTime - (localTime % 86400) + 86410); // reboot 10 secs after midnght - onceAt(std::bind(&app::tickReboot, this), rebootTrig, "midRe"); - } + if ((0 == mSunrise) && (0.0 != mConfig->sun.lat) && (0.0 != mConfig->sun.lon)) { + mCalculatedTimezoneOffset = (int8_t)((mConfig->sun.lon >= 0 ? mConfig->sun.lon + 7.5 : mConfig->sun.lon - 7.5) / 15) * 3600; + tickCalcSunrise(); } } } -//----------------------------------------------------------------------------- -void app::updateNtp(void) { - if(mNtpReceived) - onNtpUpdate(true); -} - -//----------------------------------------------------------------------------- -void app::tickNtpUpdate(void) { - uint32_t nxtTrig = 5; // default: check again in 5 sec - - if (!mNtpReceived) - mNetwork->updateNtpTime(); - else { - nxtTrig = mConfig->ntp.interval * 60; // check again in configured interval - mNtpReceived = false; - } - yield(); - - updateNtp(); - - once(std::bind(&app::tickNtpUpdate, this), nxtTrig, "ntp"); -} - //----------------------------------------------------------------------------- void app::tickCalcSunrise(void) { if (mSunrise == 0) // on boot/reboot calc sun values for current time @@ -528,9 +516,6 @@ void app::resetSystem(void) { mAllIvNotAvail = true; - mSunrise = 0; - mSunset = 0; - mMqttEnabled = false; mSendLastIvId = 0; @@ -539,8 +524,6 @@ void app::resetSystem(void) { mSaveReboot = false; mNetworkConnected = false; - mNtpReceived = false; - mTickerInstallOnce = false; } //----------------------------------------------------------------------------- diff --git a/src/app.h b/src/app.h index c03251e0..5e460bb5 100644 --- a/src/app.h +++ b/src/app.h @@ -407,10 +407,7 @@ class app : public IApp, public ah::Scheduler { setRebootFlag(); } - void tickNtpUpdate(void); - void onNtpUpdate(bool gotTime); - bool mNtpReceived = false; - void updateNtp(void); + void onNtpUpdate(uint32_t utcTimestamp); void triggerTickSend(uint8_t id) override { once([this, id]() { @@ -465,9 +462,11 @@ class app : public IApp, public ah::Scheduler { #if defined(ENABLE_MQTT) PubMqttType mMqtt; #endif - bool mTickerInstallOnce = false; bool mMqttEnabled = false; + uint8_t idTickMqttSecond, idTickMqttMinute; + uint8_t idTickMidnight, idTickReboot; + // sun int32_t mCalculatedTimezoneOffset = 0; uint32_t mSunrise = 0, mSunset = 0; diff --git a/src/defines.h b/src/defines.h index 6921c720..025f6e30 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 144 +#define VERSION_PATCH 145 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index 059d2603..1945fbb4 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -17,12 +17,11 @@ class AhoyNetwork { public: typedef std::function OnNetworkCB; - typedef std::function OnTimeCB; + typedef std::function OnTimeCB; public: - void setup(settings_t *config, uint32_t *utcTimestamp, OnNetworkCB onNetworkCB, OnTimeCB onTimeCB) { + void setup(settings_t *config, OnNetworkCB onNetworkCB, OnTimeCB onTimeCB) { mConfig = config; - mUtcTimestamp = utcTimestamp; mOnNetworkCB = onNetworkCB; mOnTimeCB = onTimeCB; @@ -53,6 +52,19 @@ class AhoyNetwork { #endif } + virtual void tickNetworkLoop() { + if(mDnsCallbackReady) { + mDnsCallbackReady = false; + startNtpUpdate(); + } + + if(mNtpTimeoutSec) { + mNtpTimeoutSec--; + if(!mNtpTimeoutSec) + mOnTimeCB(0); // timeout + } + } + bool isConnected() const { return ((mStatus == NetworkState::CONNECTED) || (mStatus == NetworkState::GOT_IP)); } @@ -66,6 +78,7 @@ class AhoyNetwork { obj->mNtpIp = ipaddr->addr; #endif } + obj->mDnsCallbackReady = true; } void updateNtpTime() { @@ -74,6 +87,8 @@ class AhoyNetwork { return; } + mNtpTimeoutSec = 30; + ip_addr_t ipaddr; mNtpIp = WiFi.gatewayIP(); // dns_gethostbyname runs asynchronous and sets the member mNtpIp which is then checked on @@ -94,8 +109,10 @@ class AhoyNetwork { void startNtpUpdate() { DPRINTLN(DBG_INFO, F("get time from: ") + mNtpIp.toString()); if (!mUdp.connected()) { - if (!mUdp.connect(mNtpIp, mConfig->ntp.port)) + if (!mUdp.connect(mNtpIp, mConfig->ntp.port)) { + mOnTimeCB(0); return; + } } mUdp.onPacket([this](AsyncUDPPacket packet) { @@ -109,7 +126,6 @@ class AhoyNetwork { public: virtual void begin() = 0; - virtual void tickNetworkLoop() = 0; virtual String getIp(void) = 0; virtual String getMac(void) = 0; @@ -242,10 +258,9 @@ class AhoyNetwork { // this is NTP time (seconds since Jan 1 1900): unsigned long secsSince1900 = highWord << 16 | lowWord; - *mUtcTimestamp = secsSince1900 - 2208988800UL; // UTC time - DPRINTLN(DBG_INFO, "[NTP]: " + ah::getDateTimeStr(*mUtcTimestamp) + " UTC"); - mOnTimeCB(true); mUdp.close(); + mNtpTimeoutSec = 0; // clear timeout + mOnTimeCB(secsSince1900 - 2208988800UL); } protected: @@ -257,12 +272,15 @@ class AhoyNetwork { CONNECTING // ESP8266 }; + public: + bool mDnsCallbackReady = false; + protected: settings_t *mConfig = nullptr; - uint32_t *mUtcTimestamp = nullptr; bool mConnected = false; bool mScanActive = false; bool mWifiConnecting = false; + uint8_t mNtpTimeoutSec = 0; OnNetworkCB mOnNetworkCB; OnTimeCB mOnTimeCB; diff --git a/src/network/AhoyWifiEsp32.h b/src/network/AhoyWifiEsp32.h index 70017518..70d8119c 100644 --- a/src/network/AhoyWifiEsp32.h +++ b/src/network/AhoyWifiEsp32.h @@ -37,6 +37,7 @@ class AhoyWifi : public AhoyNetwork { } void tickNetworkLoop() override { + AhoyNetwork::tickNetworkLoop(); if(mAp.isEnabled()) mAp.tickLoop(); } diff --git a/src/network/AhoyWifiEsp8266.h b/src/network/AhoyWifiEsp8266.h index c72f06b5..03cd54b1 100644 --- a/src/network/AhoyWifiEsp8266.h +++ b/src/network/AhoyWifiEsp8266.h @@ -23,6 +23,7 @@ class AhoyWifi : public AhoyNetwork { } void tickNetworkLoop() override { + AhoyNetwork::tickNetworkLoop(); if(mAp.isEnabled()) mAp.tickLoop(); diff --git a/src/platformio.ini b/src/platformio.ini index 17031213..e6811e0b 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -154,7 +154,7 @@ platform = espressif32@6.7.0 board = lolin_d32 lib_deps = ${env.lib_deps} - https://github.com/mathieucarbou/ESPAsyncWebServer @ ^3.1.5 + https://github.com/mathieucarbou/ESPAsyncWebServer @ ^3.3.1 build_flags = ${env.build_flags} -DSPI_HAL monitor_filters = diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index 49b209f5..227a1310 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -409,20 +409,19 @@ class PubMqtt { bool total = (mDiscovery.lastIvId == MAX_NUM_INVERTERS); Inverter<> *iv = mSys->getInverterByPos(mDiscovery.lastIvId); - record_t<> *rec = NULL; - if (NULL != iv) { + record_t<> *rec = nullptr; + if (nullptr != iv) { rec = iv->getRecordStruct(RealTimeRunData_Debug); if(0 == mDiscovery.sub) - mDiscovery.foundIvCnt++; + mDiscovery.foundIvCnt++; } - if ((NULL != iv) || total) { + if ((nullptr != iv) || total) { if (!total) { doc[F("name")] = iv->config->name; doc[F("ids")] = String(iv->config->serial.u64, HEX); doc[F("mdl")] = iv->config->name; - } - else { + } else { doc[F("name")] = node_id; doc[F("ids")] = node_id; doc[F("mdl")] = node_id; @@ -441,6 +440,7 @@ class PubMqtt { uniq_id.fill(0); buf.fill(0); const char *devCls, *stateCls; + if (!total) { if (rec->assign[mDiscovery.sub].ch == CH0) snprintf(name.data(), name.size(), "%s", iv->getFieldName(mDiscovery.sub, rec)); @@ -468,20 +468,26 @@ class PubMqtt { 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.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!? - if (devCls != NULL) + if (devCls != nullptr) doc2[F("dev_cla")] = String(devCls); - if (stateCls != NULL) + if (stateCls != nullptr) doc2[F("stat_cla")] = String(stateCls); if (!total) 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.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; serializeJson(doc2, buf.data(), size); - if(FLD_EVT != rec->assign[mDiscovery.sub].fieldId) + + if(nullptr != rec) { + if(FLD_EVT != rec->assign[mDiscovery.sub].fieldId) + publish(topic.data(), buf.data(), true, false); + } else if(total) publish(topic.data(), buf.data(), true, false); if(++mDiscovery.sub == ((!total) ? (rec->length) : 4)) { diff --git a/src/utils/scheduler.h b/src/utils/scheduler.h index 5ce43a36..1f5ef7d7 100644 --- a/src/utils/scheduler.h +++ b/src/utils/scheduler.h @@ -73,21 +73,22 @@ namespace ah { } - void once(scdCb c, uint32_t timeout, const char *name) { addTicker(c, timeout, 0, false, name); } - void onceAt(scdCb c, uint32_t timestamp, const char *name) { addTicker(c, timestamp, 0, true, name); } - uint8_t every(scdCb c, uint32_t interval, const char *name){ return addTicker(c, interval, interval, false, name); } + uint8_t once(scdCb c, uint32_t timeout, const char *name) { return addTicker(c, timeout, 0, false, name); } + uint8_t onceAt(scdCb c, uint32_t timestamp, const char *name) { return addTicker(c, timestamp, 0, true, name); } + uint8_t every(scdCb c, uint32_t interval, const char *name) { return addTicker(c, interval, interval, false, name); } - void everySec(scdCb c, const char *name) { every(c, SCD_SEC, name); } - void everyMin(scdCb c, const char *name) { every(c, SCD_MIN, name); } - void everyHour(scdCb c, const char *name) { every(c, SCD_HOUR, name); } - void every12h(scdCb c, const char *name) { every(c, SCD_12H, name); } - void everyDay(scdCb c, const char *name) { every(c, SCD_DAY, name); } + uint8_t everySec(scdCb c, const char *name) { return every(c, SCD_SEC, name); } + uint8_t everyMin(scdCb c, const char *name) { return every(c, SCD_MIN, name); } + uint8_t everyHour(scdCb c, const char *name) { return every(c, SCD_HOUR, name); } + uint8_t every12h(scdCb c, const char *name) { return every(c, SCD_12H, name); } + uint8_t everyDay(scdCb c, const char *name) { return every(c, SCD_DAY, name); } virtual void setTimestamp(uint32_t ts) { mTimestamp = ts; } - bool resetEveryById(uint8_t id) { + bool resetById(uint8_t id) { + id = (id % (MAX_NUM_TICKER - 1)); if (mTickerInUse[id] == false) return false; mTicker[id].timeout = mTicker[id].reload; From 8b1d7345871b1275711a08bb0bdd767bd3effb45 Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 23 Sep 2024 22:20:31 +0200 Subject: [PATCH 15/40] 0.8.146 * fix reset ticker #1754 * disable MqTT second and minute ticker on network loss * converted many `std::bind` to its lambda pendant --- src/CHANGES.md | 5 +++ src/app.cpp | 72 ++++++++++++++++++++++--------------------- src/app.h | 5 +-- src/defines.h | 2 +- src/utils/scheduler.h | 18 +++++++---- 5 files changed, 56 insertions(+), 46 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 97c0c595..776af866 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,10 @@ # Development Changes +## 0.8.146 - 2024-09-23 +* fix reset ticker #1754 +* disable MqTT second and minute ticker on network loss +* converted many `std::bind` to its lambda pendant + ## 0.8.145 - 2024-09-22 * fix NTP related issues #1748 #1752 * fix MqTT discovery total #1715 diff --git a/src/app.cpp b/src/app.cpp index 5a992f74..7c6a8aef 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -17,10 +17,6 @@ app::app() : ah::Scheduler {} , mSunrise {0} , mSunset {0} - , idTickMqttSecond {MAX_NUM_TICKER} - , idTickMqttMinute {MAX_NUM_TICKER} - , idTickMidnight {MAX_NUM_TICKER} - , idTickReboot {MAX_NUM_TICKER} { memset(mVersion, 0, sizeof(char) * 12); memset(mVersionModules, 0, sizeof(char) * 12); @@ -86,7 +82,7 @@ void app::setup() { mMqttEnabled = (mConfig->mqtt.broker[0] > 0); if (mMqttEnabled) { mMqtt.setup(this, &mConfig->mqtt, mConfig->sys.deviceName, mVersion, &mSys, &mTimestamp, &mUptime); - mMqtt.setSubscriptionCb(std::bind(&app::mqttSubRxCb, this, std::placeholders::_1)); + mMqtt.setSubscriptionCb([this](JsonObject obj) { mqttSubRxCb(obj); }); mCommunication.addAlarmListener([this](Inverter<> *iv) { mMqtt.alarmEvent(iv); }); } #endif @@ -156,20 +152,25 @@ void app::loop(void) { } //----------------------------------------------------------------------------- -void app::onNetwork(bool gotIp) { - mNetworkConnected = gotIp; - if(gotIp) { +void app::onNetwork(bool connected) { + mNetworkConnected = connected; + #if defined(ENABLE_MQTT) + if (mMqttEnabled) { + resetTickerByName("mqttS"); + resetTickerByName("mqttM"); + } + #endif + + if(connected) { mNetwork->updateNtpTime(); - if(!mConfig->inst.startWithoutTime) // already set in regularTickers - every(std::bind(&app::tickSend, this), mConfig->inst.sendInterval, "tSend"); + + resetTickerByName("tSend"); + every([this]() { tickSend(); }, mConfig->inst.sendInterval, "tSend"); #if defined(ENABLE_MQTT) if (mMqttEnabled) { - if(MAX_NUM_TICKER == idTickMqttSecond) - idTickMqttSecond = everySec(std::bind(&PubMqttType::tickerSecond, &mMqtt), "mqttS"); - - if(MAX_NUM_TICKER == idTickMqttMinute) - idTickMqttMinute = everyMin(std::bind(&PubMqttType::tickerMinute, &mMqtt), "mqttM"); + everySec([this]() { mMqtt.tickerSecond(); }, "mqttS"); + everyMin([this]() { mMqtt.tickerMinute(); }, "mqttM"); } #endif /*ENABLE_MQTT*/ } @@ -178,33 +179,33 @@ void app::onNetwork(bool gotIp) { //----------------------------------------------------------------------------- void app::regularTickers(void) { DPRINTLN(DBG_DEBUG, F("regularTickers")); - everySec(std::bind(&WebType::tickSecond, &mWeb), "webSc"); + everySec([this]() { mWeb.tickSecond(); }, "webSc"); everySec([this]() { mProtection->tickSecond(); }, "prot"); - everySec([this]() {mNetwork->tickNetworkLoop(); }, "net"); + everySec([this]() { mNetwork->tickNetworkLoop(); }, "net"); if(mConfig->inst.startWithoutTime) - every(std::bind(&app::tickSend, this), mConfig->inst.sendInterval, "tSend"); + every([this]() { tickSend(); }, mConfig->inst.sendInterval, "tSend"); every([this]() { mNetwork->updateNtpTime(); }, mConfig->ntp.interval * 60, "ntp"); if (mConfig->inst.rstValsNotAvail) - everyMin(std::bind(&app::tickMinute, this), "tMin"); + everyMin([this]() { tickMinute(); }, "tMin"); // Plugins #if defined(PLUGIN_DISPLAY) if (DISP_TYPE_T0_NONE != mConfig->plugin.display.type) - everySec(std::bind(&DisplayType::tickerSecond, &mDisplay), "disp"); + everySec([this]() { mDisplay.tickerSecond(); }, "disp"); #endif - every(std::bind(&PubSerialType::tick, &mPubSerial), 5, "uart"); + every([this]() { mPubSerial.tick(); }, 5, "uart"); //everySec([this]() { mImprov.tickSerial(); }, "impro"); #if defined(ENABLE_HISTORY) - everySec(std::bind(&HistoryType::tickerSecond, &mHistory), "hist"); + everySec([this]() { mHistory.tickerSecond(); }, "hist"); #endif /*ENABLE_HISTORY*/ #if defined(ENABLE_SIMULATOR) - every(std::bind(&SimulatorType::tick, &mSimulator), 5, "sim"); + every([this]() {mSimulator->tick(); }, 5, "sim"); #endif /*ENABLE_SIMULATOR*/ } @@ -219,13 +220,13 @@ void app::onNtpUpdate(uint32_t utcTimestamp) { uint32_t localTime = gTimezone.toLocal(mTimestamp); uint32_t midTrig = gTimezone.toUTC(localTime - (localTime % 86400) + 86400); // next midnight local time - resetById(idTickMidnight); - idTickMidnight = onceAt(std::bind(&app::tickMidnight, this), midTrig, "midNi"); + resetTickerByName("midNi"); + onceAt([this]() { tickMidnight(); }, midTrig, "midNi"); if (mConfig->sys.schedReboot) { - resetById(idTickReboot); uint32_t rebootTrig = gTimezone.toUTC(localTime - (localTime % 86400) + 86410); // reboot 10 secs after midnght - idTickReboot = onceAt(std::bind(&app::tickReboot, this), rebootTrig, "midRe"); + resetTickerByName("midRe"); + onceAt([this]() { tickReboot(); }, rebootTrig, "midRe"); } if ((0 == mSunrise) && (0.0 != mConfig->sun.lat) && (0.0 != mConfig->sun.lon)) { @@ -246,11 +247,11 @@ void app::tickCalcSunrise(void) { tickIVCommunication(); uint32_t nxtTrig = mSunset + mConfig->sun.offsetSecEvening + 60; // set next trigger to communication stop, +60 for safety that it is certain past communication stop - onceAt(std::bind(&app::tickCalcSunrise, this), nxtTrig, "Sunri"); + onceAt([this]() { tickCalcSunrise(); }, nxtTrig, "Sunri"); if (mMqttEnabled) { tickSun(); nxtTrig = mSunrise + mConfig->sun.offsetSecMorning + 1; // one second safety to trigger correctly - onceAt(std::bind(&app::tickSunrise, this), nxtTrig, "mqSr"); // trigger on sunrise to update 'dis_night_comm' + onceAt([this]() { tickSunrise(); }, nxtTrig, "mqSr"); // trigger on sunrise to update 'dis_night_comm' } } @@ -288,10 +289,10 @@ void app::tickIVCommunication(void) { } if(restartTick) // at least one inverter - onceAt(std::bind(&app::tickIVCommunication, this), nxtTrig, "ivCom"); + onceAt([this]() { tickIVCommunication(); }, nxtTrig, "ivCom"); if (zeroValues) // at least one inverter - once(std::bind(&app::tickZeroValues, this), mConfig->inst.sendInterval, "tZero"); + once([this]() { tickZeroValues(); }, mConfig->inst.sendInterval, "tZero"); } //----------------------------------------------------------------------------- @@ -299,7 +300,7 @@ void app::tickSun(void) { // only used and enabled by MQTT (see setup()) #if defined(ENABLE_MQTT) if (!mMqtt.tickerSun(mSunrise, mSunset, mConfig->sun.offsetSecMorning, mConfig->sun.offsetSecEvening)) - once(std::bind(&app::tickSun, this), 1, "mqSun"); // MQTT not connected, retry + once([this]() { tickSun(); }, 1, "mqSun"); // MQTT not connected, retry #endif } @@ -308,7 +309,7 @@ void app::tickSunrise(void) { // only used and enabled by MQTT (see setup()) #if defined(ENABLE_MQTT) if (!mMqtt.tickerSun(mSunrise, mSunset, mConfig->sun.offsetSecMorning, mConfig->sun.offsetSecEvening, true)) - once(std::bind(&app::tickSun, this), 1, "mqSun"); // MQTT not connected, retry + once([this]() { tickSun(); }, 1, "mqSun"); // MQTT not connected, retry #endif } @@ -336,7 +337,8 @@ void app::tickMinute(void) { void app::tickMidnight(void) { uint32_t localTime = gTimezone.toLocal(mTimestamp); uint32_t nxtTrig = gTimezone.toUTC(localTime - (localTime % 86400) + 86400); // next midnight local time - onceAt(std::bind(&app::tickMidnight, this), nxtTrig, "mid2"); + resetTickerByName("midNi"); + onceAt([this]() { tickMidnight(); }, nxtTrig, "midNi"); Inverter<> *iv; for (uint8_t id = 0; id < mSys.getNumInverters(); id++) { @@ -379,7 +381,7 @@ void app::tickSend(void) { } if(mAllIvNotAvail != notAvail) - once(std::bind(&app::notAvailChanged, this), 1, "avail"); + once([this]() { notAvailChanged(); }, 1, "avail"); mAllIvNotAvail = notAvail; updateLed(); diff --git a/src/app.h b/src/app.h index 5e460bb5..d954df35 100644 --- a/src/app.h +++ b/src/app.h @@ -89,7 +89,7 @@ class app : public IApp, public ah::Scheduler { void setup(void); void loop(void) override; - void onNetwork(bool gotIp); + void onNetwork(bool connected); void regularTickers(void); void handleIntr(void) { @@ -464,9 +464,6 @@ class app : public IApp, public ah::Scheduler { #endif bool mMqttEnabled = false; - uint8_t idTickMqttSecond, idTickMqttMinute; - uint8_t idTickMidnight, idTickReboot; - // sun int32_t mCalculatedTimezoneOffset = 0; uint32_t mSunrise = 0, mSunset = 0; diff --git a/src/defines.h b/src/defines.h index 025f6e30..3095b7a1 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 145 +#define VERSION_PATCH 146 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/utils/scheduler.h b/src/utils/scheduler.h index 1f5ef7d7..13208942 100644 --- a/src/utils/scheduler.h +++ b/src/utils/scheduler.h @@ -87,12 +87,18 @@ namespace ah { mTimestamp = ts; } - bool resetById(uint8_t id) { - id = (id % (MAX_NUM_TICKER - 1)); - if (mTickerInUse[id] == false) - return false; - mTicker[id].timeout = mTicker[id].reload; - return true; + bool resetTickerByName(const char* name) { + for (uint8_t id = 0; id < MAX_NUM_TICKER; id++) { + if (mTickerInUse[id]) { + if(strncmp(name, mTicker[id].name, strlen(name)) == 0) { + mTicker[id].timeout = mTicker[id].reload; + mTickerInUse[id] = false; + return true; + } + } + } + + return false; } uint32_t getUptime(void) { From 4c5c088607f509d40a7f53c337160de87e69caee Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 23 Sep 2024 22:28:48 +0200 Subject: [PATCH 16/40] 0.8.146 * fix redirect after login --- src/CHANGES.md | 1 + src/web/web.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 776af866..d3295e71 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -4,6 +4,7 @@ * fix reset ticker #1754 * disable MqTT second and minute ticker on network loss * converted many `std::bind` to its lambda pendant +* fix redirect after login ## 0.8.145 - 2024-09-22 * fix NTP related issues #1748 #1752 diff --git a/src/web/web.h b/src/web/web.h index 8ac18d9a..4a2544fd 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -339,7 +339,7 @@ class Web { if (request->args() > 0) { if (String(request->arg("pwd")) == String(mConfig->sys.adminPwd)) { mApp->unlock(request->client()->remoteIP().toString().c_str(), true); - request->redirect("/"); + request->redirect("/index"); } } From 2558b058c29a943b85b20c41e94ed7e1317ed4f9 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 29 Sep 2024 16:07:31 +0200 Subject: [PATCH 17/40] 0.8.147 * improved queue, added mutex --- src/CHANGES.md | 3 +++ src/defines.h | 2 +- src/hm/CommQueue.h | 34 +++++++++++++++++++++++++++++----- src/hm/Communication.h | 4 ++++ src/hms/CmtRadio.h | 3 ++- src/web/RestApi.h | 5 ----- src/web/web.h | 3 --- 7 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index d3295e71..ca5c40e8 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,8 @@ # Development Changes +## 0.8.147 - 2024-09-29 +* improved queue, added mutex + ## 0.8.146 - 2024-09-23 * fix reset ticker #1754 * disable MqTT second and minute ticker on network loss diff --git a/src/defines.h b/src/defines.h index 3095b7a1..f88e5682 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 146 +#define VERSION_PATCH 147 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index bf6f6861..bfb1e130 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -18,20 +18,35 @@ template class CommQueue { public: + CommQueue() { + mutex = xSemaphoreCreateBinaryStatic(&mutex_buffer); + xSemaphoreGive(mutex); + } + + ~CommQueue() { + vSemaphoreDelete(mutex); + } + void addImportant(Inverter<> *iv, uint8_t cmd) { queue_s q(iv, cmd, true); + xSemaphoreTake(mutex, portMAX_DELAY); if(!isIncluded(&q)) { dec(&mRdPtr); mQueue[mRdPtr] = q; - } + DPRINTLN(DBG_INFO, "addI, not incl.: " + String(iv->id)); + } else + DPRINTLN(DBG_INFO, "addI, incl.: " + String(iv->id)); + xSemaphoreGive(mutex); } void add(Inverter<> *iv, uint8_t cmd) { + xSemaphoreTake(mutex, portMAX_DELAY); queue_s q(iv, cmd, false); if(!isIncluded(&q)) { mQueue[mWrPtr] = q; inc(&mWrPtr); } + xSemaphoreGive(mutex); } void chgCmd(Inverter<> *iv, uint8_t cmd) { @@ -62,17 +77,21 @@ class CommQueue { protected: void add(queue_s q) { + xSemaphoreTake(mutex, portMAX_DELAY); mQueue[mWrPtr] = q; inc(&mWrPtr); + xSemaphoreGive(mutex); } void add(const queue_s *q, bool rstAttempts = false) { mQueue[mWrPtr] = *q; + xSemaphoreTake(mutex, portMAX_DELAY); if(rstAttempts) { mQueue[mWrPtr].attempts = DEFAULT_ATTEMPS; mQueue[mWrPtr].attemptsMax = DEFAULT_ATTEMPS; } inc(&mWrPtr); + xSemaphoreGive(mutex); } void chgCmd(uint8_t cmd) { @@ -81,20 +100,21 @@ class CommQueue { } void get(std::function cb) { - if(mRdPtr == mWrPtr) { + if(mRdPtr == mWrPtr) cb(false, &mQueue[mRdPtr]); // empty - return; - } - cb(true, &mQueue[mRdPtr]); + else + cb(true, &mQueue[mRdPtr]); } void cmdDone(bool keep = false) { + xSemaphoreTake(mutex, portMAX_DELAY); if(keep) { mQueue[mRdPtr].attempts = DEFAULT_ATTEMPS; mQueue[mRdPtr].attemptsMax = DEFAULT_ATTEMPS; add(mQueue[mRdPtr]); // add to the end again } inc(&mRdPtr); + xSemaphoreGive(mutex); } void setTs(const uint32_t *ts) { @@ -140,6 +160,10 @@ class CommQueue { std::array mQueue; uint8_t mWrPtr = 0; uint8_t mRdPtr = 0; + + private: + SemaphoreHandle_t mutex; + StaticSemaphore_t mutex_buffer; }; diff --git a/src/hm/Communication.h b/src/hm/Communication.h index e5a18858..90462b2c 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -21,6 +21,10 @@ typedef std::function *)> alarmListenerType; class Communication : public CommQueue<> { public: + Communication() : CommQueue() {} + + ~Communication() {} + void setup(uint32_t *timestamp, bool *serialDebug, bool *privacyMode, bool *printWholeTrace) { mTimestamp = timestamp; mPrivacyMode = privacyMode; diff --git a/src/hms/CmtRadio.h b/src/hms/CmtRadio.h index b6405329..fd49e8f8 100644 --- a/src/hms/CmtRadio.h +++ b/src/hms/CmtRadio.h @@ -53,7 +53,8 @@ class CmtRadio : public Radio { if(!mCfg->enabled) return; - DPRINT(DBG_INFO, F("sendControlPacket cmd: ")); + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F("sendControlPacket cmd: ")); DBGHEXLN(cmd); initPacket(iv->radioId.u64, TX_REQ_DEVCONTROL, SINGLE_FRAME); uint8_t cnt = 10; diff --git a/src/web/RestApi.h b/src/web/RestApi.h index a868b31c..099dc13b 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -7,11 +7,6 @@ #define __WEB_API_H__ #include "../utils/dbg.h" -#ifdef ESP32 -#include "AsyncTCP.h" -#else -#include "ESPAsyncTCP.h" -#endif #include "../appInterface.h" #include "../hm/hmSystem.h" #include "../utils/helper.h" diff --git a/src/web/web.h b/src/web/web.h index 4a2544fd..95ef7af1 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -8,10 +8,7 @@ #include "../utils/dbg.h" #ifdef ESP32 -#include "AsyncTCP.h" #include "Update.h" -#else -#include "ESPAsyncTCP.h" #endif #include "../appInterface.h" #include "../hm/hmSystem.h" From 6f04379cb142cae995e8b6793d4b642b20f17a7c Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 29 Sep 2024 17:32:42 +0200 Subject: [PATCH 18/40] further improved queue --- src/hm/CommQueue.h | 160 ++++++++++++++++++++++++---------------- src/hm/Communication.h | 54 +++++++------- src/web/html/about.html | 2 +- 3 files changed, 126 insertions(+), 90 deletions(-) diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index bfb1e130..b07010ea 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -18,44 +18,47 @@ template class CommQueue { public: - CommQueue() { - mutex = xSemaphoreCreateBinaryStatic(&mutex_buffer); - xSemaphoreGive(mutex); + CommQueue() + : wrPtr {0} + , rdPtr {0} + { + this->mutex = xSemaphoreCreateBinaryStatic(&this->mutex_buffer); + xSemaphoreGive(this->mutex); } ~CommQueue() { - vSemaphoreDelete(mutex); + vSemaphoreDelete(this->mutex); } void addImportant(Inverter<> *iv, uint8_t cmd) { queue_s q(iv, cmd, true); - xSemaphoreTake(mutex, portMAX_DELAY); + xSemaphoreTake(this->mutex, portMAX_DELAY); if(!isIncluded(&q)) { - dec(&mRdPtr); - mQueue[mRdPtr] = q; - DPRINTLN(DBG_INFO, "addI, not incl.: " + String(iv->id)); - } else - DPRINTLN(DBG_INFO, "addI, incl.: " + String(iv->id)); - xSemaphoreGive(mutex); + dec(&this->rdPtr); + mQueue[this->rdPtr] = q; + } + xSemaphoreGive(this->mutex); } void add(Inverter<> *iv, uint8_t cmd) { - xSemaphoreTake(mutex, portMAX_DELAY); + xSemaphoreTake(this->mutex, portMAX_DELAY); queue_s q(iv, cmd, false); if(!isIncluded(&q)) { - mQueue[mWrPtr] = q; - inc(&mWrPtr); + mQueue[this->wrPtr] = q; + inc(&this->wrPtr); } - xSemaphoreGive(mutex); + xSemaphoreGive(this->mutex); } void chgCmd(Inverter<> *iv, uint8_t cmd) { - mQueue[mWrPtr] = queue_s(iv, cmd, false); + xSemaphoreTake(this->mutex, portMAX_DELAY); + mQueue[this->wrPtr] = queue_s(iv, cmd, false); + xSemaphoreGive(this->mutex); } uint8_t getFillState(void) const { - //DPRINTLN(DBG_INFO, "wr: " + String(mWrPtr) + ", rd: " + String(mRdPtr)); - return abs(mRdPtr - mWrPtr); + //DPRINTLN(DBG_INFO, "wr: " + String(this->wrPtr) + ", rd: " + String(this->rdPtr)); + return abs(this->rdPtr - this->wrPtr); } uint8_t getMaxFill(void) const { @@ -70,68 +73,100 @@ class CommQueue { uint8_t attemptsMax; uint32_t ts; bool isDevControl; + queue_s() {} - queue_s(Inverter<> *i, uint8_t c, bool dev) : - iv(i), cmd(c), attempts(DEFAULT_ATTEMPS), attemptsMax(DEFAULT_ATTEMPS), ts(0), isDevControl(dev) {} + + queue_s(Inverter<> *i, uint8_t c, bool dev) + : iv {i} + , cmd {c} + , attempts {DEFAULT_ATTEMPS} + , attemptsMax {DEFAULT_ATTEMPS} + , ts {0} + , isDevControl {dev} + {} + + queue_s(const queue_s &other) // copy constructor + : iv {other.iv} + , cmd {other.cmd} + , attempts {other.attempts} + , attemptsMax {other.attemptsMax} + , ts {other.ts} + , isDevControl {other.isDevControl} + {} }; protected: void add(queue_s q) { - xSemaphoreTake(mutex, portMAX_DELAY); - mQueue[mWrPtr] = q; - inc(&mWrPtr); - xSemaphoreGive(mutex); + xSemaphoreTake(this->mutex, portMAX_DELAY); + mQueue[this->wrPtr] = q; + inc(&this->wrPtr); + xSemaphoreGive(this->mutex); } - void add(const queue_s *q, bool rstAttempts = false) { - mQueue[mWrPtr] = *q; - xSemaphoreTake(mutex, portMAX_DELAY); + void add(queue_s *q, bool rstAttempts = false) { + xSemaphoreTake(this->mutex, portMAX_DELAY); + mQueue[this->wrPtr] = *q; if(rstAttempts) { - mQueue[mWrPtr].attempts = DEFAULT_ATTEMPS; - mQueue[mWrPtr].attemptsMax = DEFAULT_ATTEMPS; + mQueue[this->wrPtr].attempts = DEFAULT_ATTEMPS; + mQueue[this->wrPtr].attemptsMax = DEFAULT_ATTEMPS; } - inc(&mWrPtr); - xSemaphoreGive(mutex); + inc(&this->wrPtr); + xSemaphoreGive(this->mutex); } - void chgCmd(uint8_t cmd) { - mQueue[mRdPtr].cmd = cmd; - mQueue[mRdPtr].isDevControl = false; + void chgCmd(queue_s *q, uint8_t cmd) { + xSemaphoreTake(this->mutex, portMAX_DELAY); + q->cmd = cmd; + q->isDevControl = false; + xSemaphoreGive(this->mutex); } - void get(std::function cb) { - if(mRdPtr == mWrPtr) - cb(false, &mQueue[mRdPtr]); // empty - else - cb(true, &mQueue[mRdPtr]); + void get(std::function cb) { + if(this->rdPtr == this->wrPtr) + cb(false, nullptr); // empty + else { + //xSemaphoreTake(this->mutex, portMAX_DELAY); + //uint8_t tmp = this->rdPtr; + //xSemaphoreGive(this->mutex); + cb(true, &mQueue[this->rdPtr]); + } } - void cmdDone(bool keep = false) { - xSemaphoreTake(mutex, portMAX_DELAY); + void cmdDone(queue_s *q, bool keep = false) { + xSemaphoreTake(this->mutex, portMAX_DELAY); if(keep) { - mQueue[mRdPtr].attempts = DEFAULT_ATTEMPS; - mQueue[mRdPtr].attemptsMax = DEFAULT_ATTEMPS; - add(mQueue[mRdPtr]); // add to the end again + q->attempts = DEFAULT_ATTEMPS; + q->attemptsMax = DEFAULT_ATTEMPS; + xSemaphoreGive(this->mutex); + add(q); // add to the end again + xSemaphoreTake(this->mutex, portMAX_DELAY); } - inc(&mRdPtr); - xSemaphoreGive(mutex); + inc(&this->rdPtr); + xSemaphoreGive(this->mutex); } - void setTs(const uint32_t *ts) { - mQueue[mRdPtr].ts = *ts; + void setTs(queue_s *q, const uint32_t *ts) { + xSemaphoreTake(this->mutex, portMAX_DELAY); + q->ts = *ts; + xSemaphoreGive(this->mutex); } - void setAttempt(void) { - if(mQueue[mRdPtr].attempts) - mQueue[mRdPtr].attempts--; + void setAttempt(queue_s *q) { + xSemaphoreTake(this->mutex, portMAX_DELAY); + if(q->attempts) + q->attempts--; + xSemaphoreGive(this->mutex); } - void incrAttempt(uint8_t attempts = 1) { - mQueue[mRdPtr].attempts += attempts; - if (mQueue[mRdPtr].attempts > mQueue[mRdPtr].attemptsMax) - mQueue[mRdPtr].attemptsMax = mQueue[mRdPtr].attempts; + void incrAttempt(queue_s *q, uint8_t attempts = 1) { + xSemaphoreTake(this->mutex, portMAX_DELAY); + q->attempts += attempts; + if (q->attempts > q->attemptsMax) + q->attemptsMax = q->attempts; + xSemaphoreGive(this->mutex); } + private: void inc(uint8_t *ptr) { if(++(*ptr) >= N) *ptr = 0; @@ -143,13 +178,14 @@ class CommQueue { --(*ptr); } - private: bool isIncluded(const queue_s *q) { - uint8_t ptr = mRdPtr; - while (ptr != mWrPtr) { + uint8_t ptr = this->rdPtr; + while (ptr != this->wrPtr) { if(mQueue[ptr].cmd == q->cmd) { - if(mQueue[ptr].iv->id == q->iv->id) - return true; + if(mQueue[ptr].iv->id == q->iv->id) { + if(mQueue[ptr].isDevControl == q->isDevControl) + return true; + } } inc(&ptr); } @@ -158,10 +194,10 @@ class CommQueue { protected: std::array mQueue; - uint8_t mWrPtr = 0; - uint8_t mRdPtr = 0; private: + uint8_t wrPtr; + uint8_t rdPtr; SemaphoreHandle_t mutex; StaticSemaphore_t mutex_buffer; }; diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 90462b2c..d60d0d38 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -52,7 +52,7 @@ class Communication : public CommQueue<> { } void loop() { - get([this](bool valid, const queue_s *q) { + get([this](bool valid, queue_s *q) { if(!valid) { if(mPrintSequenceDuration) { mPrintSequenceDuration = false; @@ -72,7 +72,7 @@ class Communication : public CommQueue<> { } private: - inline void innerLoop(const queue_s *q) { + inline void innerLoop(queue_s *q) { switch(mState) { case States::RESET: if (!mWaitTime.isTimeout()) @@ -95,20 +95,20 @@ class Communication : public CommQueue<> { q->iv->radioStatistics.txCnt++; mIsRetransmit = false; if(NULL == q->iv->radio) - cmdDone(false); // can't communicate while radio is not defined! + cmdDone(q, false); // can't communicate while radio is not defined! mFirstTry = (INV_RADIO_TYPE_NRF == q->iv->ivRadioType) && (q->iv->isAvailable()); q->iv->mCmd = q->cmd; q->iv->mIsSingleframeReq = false; mFramesExpected = getFramesExpected(q); // function to get expected frame count. mTimeout = DURATION_TXFRAME + mFramesExpected*DURATION_ONEFRAME + duration_reserve[q->iv->ivRadioType]; if((q->iv->ivGen == IV_MI) && ((q->cmd == MI_REQ_CH1) || (q->cmd == MI_REQ_4CH))) - incrAttempt(q->iv->channels); // 2 more attempts for 2ch, 4 more for 4ch + incrAttempt(q, q->iv->channels); // 2 more attempts for 2ch, 4 more for 4ch mState = States::START; break; case States::START: - setTs(mTimestamp); + setTs(q, mTimestamp); if(INV_RADIO_TYPE_CMT == q->iv->ivRadioType) { // frequency was changed during runtime if(q->iv->curCmtFreq != q->iv->config->frequency) { @@ -127,10 +127,10 @@ class Communication : public CommQueue<> { //q->iv->radioStatistics.txCnt++; q->iv->radio->mRadioWaitTime.startTimeMonitor(mTimeout); if((!mIsRetransmit && (q->cmd == AlarmData)) || (q->cmd == GridOnProFilePara)) - incrAttempt((q->cmd == AlarmData)? MORE_ATTEMPS_ALARMDATA : MORE_ATTEMPS_GRIDONPROFILEPARA); + incrAttempt(q, (q->cmd == AlarmData)? MORE_ATTEMPS_ALARMDATA : MORE_ATTEMPS_GRIDONPROFILEPARA); mIsRetransmit = false; - setAttempt(); + setAttempt(q); mState = States::WAIT; break; @@ -191,7 +191,7 @@ class Communication : public CommQueue<> { q->iv->mDtuRxCnt++; if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command - if(parseFrame(p)) { + if(parseFrame(q, p)) { q->iv->curFrmCnt++; if(!mIsRetransmit && ((p->packet[9] == 0x02) || (p->packet[9] == 0x82)) && (p->millis < LIMIT_FAST_IV)) mHeu.setIvRetriesGood(q->iv,p->millis < LIMIT_VERYFAST_IV); @@ -292,7 +292,7 @@ class Communication : public CommQueue<> { } } - setAttempt(); + setAttempt(q); if(*mSerialDebug) { DPRINT_IVID(DBG_WARN, q->iv->id); @@ -321,7 +321,7 @@ class Communication : public CommQueue<> { } } - inline void printRxInfo(const queue_s *q, packet_t *p) { + inline void printRxInfo(queue_s *q, packet_t *p) { DPRINT_IVID(DBG_INFO, q->iv->id); DBGPRINT(F("RX ")); if(p->millis < 100) @@ -355,7 +355,7 @@ class Communication : public CommQueue<> { } - inline uint8_t getFramesExpected(const queue_s *q) { + inline uint8_t getFramesExpected(queue_s *q) { if(q->isDevControl) return 1; @@ -419,7 +419,7 @@ class Communication : public CommQueue<> { return (ah::crc8(buf, len - 1) == buf[len-1]); } - inline bool parseFrame(packet_t *p) { + inline bool parseFrame(queue_s *q, packet_t *p) { uint8_t *frameId = &p->packet[9]; if(0x00 == *frameId) { DPRINTLN(DBG_WARN, F("invalid frameId 0x00")); @@ -438,7 +438,7 @@ class Communication : public CommQueue<> { if((*frameId & ALL_FRAMES) == ALL_FRAMES) { mMaxFrameId = (*frameId & 0x7f); if(mMaxFrameId > 8) // large payloads, e.g. AlarmData - incrAttempt(mMaxFrameId - 6); + incrAttempt(q, mMaxFrameId - 6); } frame_t *f = &mLocalBuf[(*frameId & 0x7f) - 1]; @@ -449,7 +449,7 @@ class Communication : public CommQueue<> { return true; } - inline void parseMiFrame(packet_t *p, const queue_s *q) { + inline void parseMiFrame(packet_t *p, 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) @@ -473,7 +473,7 @@ class Communication : public CommQueue<> { } } - inline bool parseDevCtrl(const packet_t *p, const queue_s *q) { + inline bool parseDevCtrl(const packet_t *p, queue_s *q) { switch(p->packet[12]) { case ActivePowerContr: if(p->packet[13] != 0x00) @@ -511,7 +511,7 @@ class Communication : public CommQueue<> { return accepted; } - inline bool compilePayload(const queue_s *q) { + inline bool compilePayload(queue_s *q) { uint16_t crc = 0xffff, crcRcv = 0x0000; for(uint8_t i = 0; i < mMaxFrameId; i++) { if(i == (mMaxFrameId - 1)) { @@ -611,7 +611,7 @@ class Communication : public CommQueue<> { return true; } - void sendRetransmit(const queue_s *q, uint8_t i) { + void sendRetransmit(queue_s *q, uint8_t i) { mFramesExpected = 1; q->iv->radio->setExpectedFrames(mFramesExpected); q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (SINGLE_FRAME + i), true); @@ -622,7 +622,7 @@ class Communication : public CommQueue<> { } private: - void closeRequest(const queue_s *q, bool crcPass) { + void closeRequest(queue_s *q, bool crcPass) { mHeu.evalTxChQuality(q->iv, crcPass, (q->attemptsMax - 1 - q->attempts), q->iv->curFrmCnt); if(crcPass) q->iv->radioStatistics.rxSuccess++; @@ -636,7 +636,7 @@ class Communication : public CommQueue<> { if(q->isDevControl) keep = !crcPass; - cmdDone(keep); + cmdDone(q, keep); q->iv->mGotFragment = false; q->iv->mGotLastMsg = false; q->iv->miMultiParts = 0; @@ -646,7 +646,7 @@ class Communication : public CommQueue<> { DBGPRINTLN(F("-----")); } - inline void miHwDecode(packet_t *p, const queue_s *q) { + inline void miHwDecode(packet_t *p, queue_s *q) { record_t<> *rec = q->iv->getRecordStruct(InverterDevInform_All); // choose the record structure rec->ts = q->ts; /* @@ -760,7 +760,7 @@ class Communication : public CommQueue<> { } } - inline void miGPFDecode(packet_t *p, const queue_s *q) { + inline void miGPFDecode(packet_t *p, queue_s *q) { record_t<> *rec = q->iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure rec->ts = q->ts; rec->mqttSentStatus = MqttSentStatus::NEW_DATA; @@ -786,7 +786,7 @@ class Communication : public CommQueue<> { q->iv->miMultiParts = 7; // indicate we are ready } - inline void miDataDecode(packet_t *p, const queue_s *q) { + inline void miDataDecode(packet_t *p, queue_s *q) { record_t<> *rec = q->iv->getRecordStruct(RealTimeRunData_Debug); // choose the parser rec->ts = q->ts; //mState = States::RESET; @@ -839,7 +839,7 @@ class Communication : public CommQueue<> { q->iv->miMultiParts += 6; // indicate we are ready } - void miNextRequest(uint8_t cmd, const queue_s *q) { + void miNextRequest(uint8_t cmd, queue_s *q) { mHeu.evalTxChQuality(q->iv, true, (q->attemptsMax - 1 - q->attempts), q->iv->curFrmCnt); mHeu.getTxCh(q->iv); q->iv->radioStatistics.ivSent++; @@ -859,12 +859,12 @@ class Communication : public CommQueue<> { DBGHEXLN(cmd); } mIsRetransmit = true; - chgCmd(cmd); + chgCmd(q, cmd); //mState = States::WAIT; } - void miRepeatRequest(const queue_s *q) { - setAttempt(); // if function is called, we got something, and we necessarily need more transmissions for MI types... + void miRepeatRequest(queue_s *q) { + setAttempt(q); // if function is called, we got something, and we necessarily need more transmissions for MI types... q->iv->radio->sendCmdPacket(q->iv, q->cmd, 0x00, true); q->iv->radioStatistics.retransmits++; q->iv->radio->mRadioWaitTime.startTimeMonitor(DURATION_TXFRAME + DURATION_ONEFRAME + duration_reserve[q->iv->ivRadioType]); @@ -878,7 +878,7 @@ class Communication : public CommQueue<> { //mIsRetransmit = false; } - void miStsConsolidate(const queue_s *q, uint8_t stschan, record_t<> *rec, uint8_t uState, uint8_t uEnum, uint8_t lState = 0, uint8_t lEnum = 0) { + void miStsConsolidate(queue_s *q, uint8_t stschan, record_t<> *rec, uint8_t uState, uint8_t uEnum, uint8_t lState = 0, uint8_t lEnum = 0) { //uint8_t status = (p->packet[11] << 8) + p->packet[12]; uint16_t statusMi = 3; // regular status for MI, change to 1 later? if ( uState == 2 ) { diff --git a/src/web/html/about.html b/src/web/html/about.html index 1b27ac9d..b03aff78 100644 --- a/src/web/html/about.html +++ b/src/web/html/about.html @@ -14,7 +14,7 @@
Used Libraries
- + From fe265d78a7743a882eb1f3fb885dd2640fd89c9b Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 29 Sep 2024 21:56:53 +0200 Subject: [PATCH 19/40] restructured communication queue and queue element --- src/hm/CommQueue.h | 112 +++++++++++++++++++---------------------- src/hm/Communication.h | 48 +++++++++--------- 2 files changed, 77 insertions(+), 83 deletions(-) diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index b07010ea..a73a3370 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -11,12 +11,13 @@ #include "hmInverter.h" #include "../utils/dbg.h" -#define DEFAULT_ATTEMPS 5 -#define MORE_ATTEMPS_ALARMDATA 3 // 8 -#define MORE_ATTEMPS_GRIDONPROFILEPARA 0 // 5 - template class CommQueue { + protected: /* types */ + static constexpr uint8_t DefaultAttempts = 5; + static constexpr uint8_t MoreAttemptsAlarmData = 3; + static constexpr uint8_t MoreAttemptsGridProfile = 0; + public: CommQueue() : wrPtr {0} @@ -31,7 +32,7 @@ class CommQueue { } void addImportant(Inverter<> *iv, uint8_t cmd) { - queue_s q(iv, cmd, true); + QueueElement q(iv, cmd, true); xSemaphoreTake(this->mutex, portMAX_DELAY); if(!isIncluded(&q)) { dec(&this->rdPtr); @@ -42,7 +43,7 @@ class CommQueue { void add(Inverter<> *iv, uint8_t cmd) { xSemaphoreTake(this->mutex, portMAX_DELAY); - queue_s q(iv, cmd, false); + QueueElement q(iv, cmd, false); if(!isIncluded(&q)) { mQueue[this->wrPtr] = q; inc(&this->wrPtr); @@ -50,12 +51,6 @@ class CommQueue { xSemaphoreGive(this->mutex); } - void chgCmd(Inverter<> *iv, uint8_t cmd) { - xSemaphoreTake(this->mutex, portMAX_DELAY); - mQueue[this->wrPtr] = queue_s(iv, cmd, false); - xSemaphoreGive(this->mutex); - } - uint8_t getFillState(void) const { //DPRINTLN(DBG_INFO, "wr: " + String(this->wrPtr) + ", rd: " + String(this->rdPtr)); return abs(this->rdPtr - this->wrPtr); @@ -66,7 +61,7 @@ class CommQueue { } protected: - struct queue_s { + struct QueueElement { Inverter<> *iv; uint8_t cmd; uint8_t attempts; @@ -74,18 +69,25 @@ class CommQueue { uint32_t ts; bool isDevControl; - queue_s() {} + QueueElement() + : iv {nullptr} + , cmd {0} + , attempts {0} + , attemptsMax {0} + , ts {0} + , isDevControl {false} + {} - queue_s(Inverter<> *i, uint8_t c, bool dev) - : iv {i} - , cmd {c} - , attempts {DEFAULT_ATTEMPS} - , attemptsMax {DEFAULT_ATTEMPS} + QueueElement(Inverter<> *iv, uint8_t cmd, bool devCtrl) + : iv {iv} + , cmd {cmd} + , attempts {DefaultAttempts} + , attemptsMax {DefaultAttempts} , ts {0} - , isDevControl {dev} + , isDevControl {devCtrl} {} - queue_s(const queue_s &other) // copy constructor + QueueElement(const QueueElement &other) // copy constructor : iv {other.iv} , cmd {other.cmd} , attempts {other.attempts} @@ -93,35 +95,48 @@ class CommQueue { , ts {other.ts} , isDevControl {other.isDevControl} {} + + void changeCmd(uint8_t cmd) { + this->cmd = cmd; + this->isDevControl = false; + } + + void setTs(const uint32_t ts) { + this->ts = ts; + } + + void setAttempt() { + if(this->attempts) + this->attempts--; + } + + void incrAttempt(uint8_t attempts = 1) { + this->attempts += attempts; + if (this->attempts > this->attemptsMax) + this->attemptsMax = this->attempts; + } }; protected: - void add(queue_s q) { + void add(QueueElement q) { xSemaphoreTake(this->mutex, portMAX_DELAY); mQueue[this->wrPtr] = q; inc(&this->wrPtr); xSemaphoreGive(this->mutex); } - void add(queue_s *q, bool rstAttempts = false) { + void add(QueueElement *q, bool rstAttempts = false) { xSemaphoreTake(this->mutex, portMAX_DELAY); mQueue[this->wrPtr] = *q; if(rstAttempts) { - mQueue[this->wrPtr].attempts = DEFAULT_ATTEMPS; - mQueue[this->wrPtr].attemptsMax = DEFAULT_ATTEMPS; + mQueue[this->wrPtr].attempts = DefaultAttempts; + mQueue[this->wrPtr].attemptsMax = DefaultAttempts; } inc(&this->wrPtr); xSemaphoreGive(this->mutex); } - void chgCmd(queue_s *q, uint8_t cmd) { - xSemaphoreTake(this->mutex, portMAX_DELAY); - q->cmd = cmd; - q->isDevControl = false; - xSemaphoreGive(this->mutex); - } - - void get(std::function cb) { + void get(std::function cb) { if(this->rdPtr == this->wrPtr) cb(false, nullptr); // empty else { @@ -132,11 +147,11 @@ class CommQueue { } } - void cmdDone(queue_s *q, bool keep = false) { + void cmdDone(QueueElement *q, bool keep = false) { xSemaphoreTake(this->mutex, portMAX_DELAY); if(keep) { - q->attempts = DEFAULT_ATTEMPS; - q->attemptsMax = DEFAULT_ATTEMPS; + q->attempts = DefaultAttempts; + q->attemptsMax = DefaultAttempts; xSemaphoreGive(this->mutex); add(q); // add to the end again xSemaphoreTake(this->mutex, portMAX_DELAY); @@ -145,27 +160,6 @@ class CommQueue { xSemaphoreGive(this->mutex); } - void setTs(queue_s *q, const uint32_t *ts) { - xSemaphoreTake(this->mutex, portMAX_DELAY); - q->ts = *ts; - xSemaphoreGive(this->mutex); - } - - void setAttempt(queue_s *q) { - xSemaphoreTake(this->mutex, portMAX_DELAY); - if(q->attempts) - q->attempts--; - xSemaphoreGive(this->mutex); - } - - void incrAttempt(queue_s *q, uint8_t attempts = 1) { - xSemaphoreTake(this->mutex, portMAX_DELAY); - q->attempts += attempts; - if (q->attempts > q->attemptsMax) - q->attemptsMax = q->attempts; - xSemaphoreGive(this->mutex); - } - private: void inc(uint8_t *ptr) { if(++(*ptr) >= N) @@ -178,7 +172,7 @@ class CommQueue { --(*ptr); } - bool isIncluded(const queue_s *q) { + bool isIncluded(const QueueElement *q) { uint8_t ptr = this->rdPtr; while (ptr != this->wrPtr) { if(mQueue[ptr].cmd == q->cmd) { @@ -193,7 +187,7 @@ class CommQueue { } protected: - std::array mQueue; + std::array mQueue; private: uint8_t wrPtr; diff --git a/src/hm/Communication.h b/src/hm/Communication.h index d60d0d38..1c7c83ae 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -52,7 +52,7 @@ class Communication : public CommQueue<> { } void loop() { - get([this](bool valid, queue_s *q) { + get([this](bool valid, QueueElement *q) { if(!valid) { if(mPrintSequenceDuration) { mPrintSequenceDuration = false; @@ -72,7 +72,7 @@ class Communication : public CommQueue<> { } private: - inline void innerLoop(queue_s *q) { + inline void innerLoop(QueueElement *q) { switch(mState) { case States::RESET: if (!mWaitTime.isTimeout()) @@ -102,13 +102,13 @@ class Communication : public CommQueue<> { mFramesExpected = getFramesExpected(q); // function to get expected frame count. mTimeout = DURATION_TXFRAME + mFramesExpected*DURATION_ONEFRAME + duration_reserve[q->iv->ivRadioType]; if((q->iv->ivGen == IV_MI) && ((q->cmd == MI_REQ_CH1) || (q->cmd == MI_REQ_4CH))) - incrAttempt(q, q->iv->channels); // 2 more attempts for 2ch, 4 more for 4ch + q->incrAttempt(q->iv->channels); // 2 more attempts for 2ch, 4 more for 4ch mState = States::START; break; case States::START: - setTs(q, mTimestamp); + q->setTs(*mTimestamp); if(INV_RADIO_TYPE_CMT == q->iv->ivRadioType) { // frequency was changed during runtime if(q->iv->curCmtFreq != q->iv->config->frequency) { @@ -127,10 +127,10 @@ class Communication : public CommQueue<> { //q->iv->radioStatistics.txCnt++; q->iv->radio->mRadioWaitTime.startTimeMonitor(mTimeout); if((!mIsRetransmit && (q->cmd == AlarmData)) || (q->cmd == GridOnProFilePara)) - incrAttempt(q, (q->cmd == AlarmData)? MORE_ATTEMPS_ALARMDATA : MORE_ATTEMPS_GRIDONPROFILEPARA); + q->incrAttempt((q->cmd == AlarmData)? CommQueue::MoreAttemptsAlarmData : CommQueue::MoreAttemptsGridProfile); mIsRetransmit = false; - setAttempt(q); + q->setAttempt(); mState = States::WAIT; break; @@ -292,7 +292,7 @@ class Communication : public CommQueue<> { } } - setAttempt(q); + q->setAttempt(); if(*mSerialDebug) { DPRINT_IVID(DBG_WARN, q->iv->id); @@ -321,7 +321,7 @@ class Communication : public CommQueue<> { } } - inline void printRxInfo(queue_s *q, packet_t *p) { + inline void printRxInfo(QueueElement *q, packet_t *p) { DPRINT_IVID(DBG_INFO, q->iv->id); DBGPRINT(F("RX ")); if(p->millis < 100) @@ -355,7 +355,7 @@ class Communication : public CommQueue<> { } - inline uint8_t getFramesExpected(queue_s *q) { + inline uint8_t getFramesExpected(QueueElement *q) { if(q->isDevControl) return 1; @@ -419,7 +419,7 @@ class Communication : public CommQueue<> { return (ah::crc8(buf, len - 1) == buf[len-1]); } - inline bool parseFrame(queue_s *q, packet_t *p) { + inline bool parseFrame(QueueElement *q, packet_t *p) { uint8_t *frameId = &p->packet[9]; if(0x00 == *frameId) { DPRINTLN(DBG_WARN, F("invalid frameId 0x00")); @@ -438,7 +438,7 @@ class Communication : public CommQueue<> { if((*frameId & ALL_FRAMES) == ALL_FRAMES) { mMaxFrameId = (*frameId & 0x7f); if(mMaxFrameId > 8) // large payloads, e.g. AlarmData - incrAttempt(q, mMaxFrameId - 6); + q->incrAttempt(mMaxFrameId - 6); } frame_t *f = &mLocalBuf[(*frameId & 0x7f) - 1]; @@ -449,7 +449,7 @@ class Communication : public CommQueue<> { return true; } - inline void parseMiFrame(packet_t *p, queue_s *q) { + inline void parseMiFrame(packet_t *p, QueueElement *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) @@ -473,7 +473,7 @@ class Communication : public CommQueue<> { } } - inline bool parseDevCtrl(const packet_t *p, queue_s *q) { + inline bool parseDevCtrl(const packet_t *p, QueueElement *q) { switch(p->packet[12]) { case ActivePowerContr: if(p->packet[13] != 0x00) @@ -511,7 +511,7 @@ class Communication : public CommQueue<> { return accepted; } - inline bool compilePayload(queue_s *q) { + inline bool compilePayload(QueueElement *q) { uint16_t crc = 0xffff, crcRcv = 0x0000; for(uint8_t i = 0; i < mMaxFrameId; i++) { if(i == (mMaxFrameId - 1)) { @@ -611,7 +611,7 @@ class Communication : public CommQueue<> { return true; } - void sendRetransmit(queue_s *q, uint8_t i) { + void sendRetransmit(QueueElement *q, uint8_t i) { mFramesExpected = 1; q->iv->radio->setExpectedFrames(mFramesExpected); q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (SINGLE_FRAME + i), true); @@ -622,7 +622,7 @@ class Communication : public CommQueue<> { } private: - void closeRequest(queue_s *q, bool crcPass) { + void closeRequest(QueueElement *q, bool crcPass) { mHeu.evalTxChQuality(q->iv, crcPass, (q->attemptsMax - 1 - q->attempts), q->iv->curFrmCnt); if(crcPass) q->iv->radioStatistics.rxSuccess++; @@ -646,7 +646,7 @@ class Communication : public CommQueue<> { DBGPRINTLN(F("-----")); } - inline void miHwDecode(packet_t *p, queue_s *q) { + inline void miHwDecode(packet_t *p, QueueElement *q) { record_t<> *rec = q->iv->getRecordStruct(InverterDevInform_All); // choose the record structure rec->ts = q->ts; /* @@ -760,7 +760,7 @@ class Communication : public CommQueue<> { } } - inline void miGPFDecode(packet_t *p, queue_s *q) { + inline void miGPFDecode(packet_t *p, QueueElement *q) { record_t<> *rec = q->iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure rec->ts = q->ts; rec->mqttSentStatus = MqttSentStatus::NEW_DATA; @@ -786,7 +786,7 @@ class Communication : public CommQueue<> { q->iv->miMultiParts = 7; // indicate we are ready } - inline void miDataDecode(packet_t *p, queue_s *q) { + inline void miDataDecode(packet_t *p, QueueElement *q) { record_t<> *rec = q->iv->getRecordStruct(RealTimeRunData_Debug); // choose the parser rec->ts = q->ts; //mState = States::RESET; @@ -839,7 +839,7 @@ class Communication : public CommQueue<> { q->iv->miMultiParts += 6; // indicate we are ready } - void miNextRequest(uint8_t cmd, queue_s *q) { + void miNextRequest(uint8_t cmd, QueueElement *q) { mHeu.evalTxChQuality(q->iv, true, (q->attemptsMax - 1 - q->attempts), q->iv->curFrmCnt); mHeu.getTxCh(q->iv); q->iv->radioStatistics.ivSent++; @@ -859,12 +859,12 @@ class Communication : public CommQueue<> { DBGHEXLN(cmd); } mIsRetransmit = true; - chgCmd(q, cmd); + q->changeCmd(cmd); //mState = States::WAIT; } - void miRepeatRequest(queue_s *q) { - setAttempt(q); // if function is called, we got something, and we necessarily need more transmissions for MI types... + void miRepeatRequest(QueueElement *q) { + q->setAttempt(); // if function is called, we got something, and we necessarily need more transmissions for MI types... q->iv->radio->sendCmdPacket(q->iv, q->cmd, 0x00, true); q->iv->radioStatistics.retransmits++; q->iv->radio->mRadioWaitTime.startTimeMonitor(DURATION_TXFRAME + DURATION_ONEFRAME + duration_reserve[q->iv->ivRadioType]); @@ -878,7 +878,7 @@ class Communication : public CommQueue<> { //mIsRetransmit = false; } - void miStsConsolidate(queue_s *q, uint8_t stschan, record_t<> *rec, uint8_t uState, uint8_t uEnum, uint8_t lState = 0, uint8_t lEnum = 0) { + void miStsConsolidate(QueueElement *q, uint8_t stschan, record_t<> *rec, uint8_t uState, uint8_t uEnum, uint8_t lState = 0, uint8_t lEnum = 0) { //uint8_t status = (p->packet[11] << 8) + p->packet[12]; uint16_t statusMi = 3; // regular status for MI, change to 1 later? if ( uState == 2 ) { From 08bc773cc2bde37797b7d7880a8930806c5cee65 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 29 Sep 2024 22:59:20 +0200 Subject: [PATCH 20/40] 0.8.147 * fixed send power limit #1757 --- src/CHANGES.md | 1 + src/hm/CommQueue.h | 17 +++++++---------- src/hm/Communication.h | 41 +++++++++++++++++++++++++---------------- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index ca5c40e8..e52d899c 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -2,6 +2,7 @@ ## 0.8.147 - 2024-09-29 * improved queue, added mutex +* fixed send power limit #1757 ## 0.8.146 - 2024-09-23 * fix reset ticker #1754 diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index a73a3370..bf2be217 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// 2023 Ahoy, https://github.com/lumpapu/ahoy +// 2024 Ahoy, https://github.com/lumpapu/ahoy // Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed //----------------------------------------------------------------------------- @@ -140,24 +140,21 @@ class CommQueue { if(this->rdPtr == this->wrPtr) cb(false, nullptr); // empty else { - //xSemaphoreTake(this->mutex, portMAX_DELAY); - //uint8_t tmp = this->rdPtr; - //xSemaphoreGive(this->mutex); - cb(true, &mQueue[this->rdPtr]); + xSemaphoreTake(this->mutex, portMAX_DELAY); + QueueElement el = mQueue[this->rdPtr]; + inc(&this->rdPtr); + xSemaphoreGive(this->mutex); + cb(true, &el); } } void cmdDone(QueueElement *q, bool keep = false) { - xSemaphoreTake(this->mutex, portMAX_DELAY); if(keep) { q->attempts = DefaultAttempts; q->attemptsMax = DefaultAttempts; - xSemaphoreGive(this->mutex); add(q); // add to the end again - xSemaphoreTake(this->mutex, portMAX_DELAY); } - inc(&this->rdPtr); - xSemaphoreGive(this->mutex); + //inc(&this->rdPtr); } private: diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 1c7c83ae..48e8840e 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -21,7 +21,9 @@ typedef std::function *)> alarmListenerType; class Communication : public CommQueue<> { public: - Communication() : CommQueue() {} + Communication() + : CommQueue() + {} ~Communication() {} @@ -52,23 +54,29 @@ class Communication : public CommQueue<> { } void loop() { - get([this](bool valid, QueueElement *q) { - if(!valid) { - if(mPrintSequenceDuration) { - mPrintSequenceDuration = false; - DPRINT(DBG_INFO, F("com loop duration: ")); - DBGPRINT(String(millis() - mLastEmptyQueueMillis)); - DBGPRINTLN(F("ms")); - DBGPRINTLN(F("-----")); + if(States::RESET == mState) { + get([this](bool valid, QueueElement *q) { + if(!valid) { + if(mPrintSequenceDuration) { + mPrintSequenceDuration = false; + DPRINT(DBG_INFO, F("com loop duration: ")); + DBGPRINT(String(millis() - mLastEmptyQueueMillis)); + DBGPRINTLN(F("ms")); + DBGPRINTLN(F("-----")); + el.iv = nullptr; + } + return; // empty } - return; // empty - } - if(!mPrintSequenceDuration) // entry was added to the queue - mLastEmptyQueueMillis = millis(); - mPrintSequenceDuration = true; - innerLoop(q); - }); + el = *q; + if(!mPrintSequenceDuration) // entry was added to the queue + mLastEmptyQueueMillis = millis(); + mPrintSequenceDuration = true; + }); + } + + if(nullptr != el.iv) + innerLoop(&el); } private: @@ -1035,6 +1043,7 @@ class Communication : public CommQueue<> { private: States mState = States::RESET; uint32_t *mTimestamp = nullptr; + QueueElement el; bool *mPrivacyMode = nullptr, *mSerialDebug = nullptr, *mPrintWholeTrace = nullptr; TimeMonitor mWaitTime = TimeMonitor(0, true); // start as expired (due to code in RESET state) std::array mLocalBuf; From b7e056653511e38c622f84c3f1429861255dc14f Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 29 Sep 2024 23:08:05 +0200 Subject: [PATCH 21/40] 0.8.147 code cleanup --- src/hm/CommQueue.h | 125 ++++++++++++++++++++--------------------- src/hm/Communication.h | 8 +-- 2 files changed, 65 insertions(+), 68 deletions(-) diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index bf2be217..c0676158 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -60,63 +60,6 @@ class CommQueue { return N; } - protected: - struct QueueElement { - Inverter<> *iv; - uint8_t cmd; - uint8_t attempts; - uint8_t attemptsMax; - uint32_t ts; - bool isDevControl; - - QueueElement() - : iv {nullptr} - , cmd {0} - , attempts {0} - , attemptsMax {0} - , ts {0} - , isDevControl {false} - {} - - QueueElement(Inverter<> *iv, uint8_t cmd, bool devCtrl) - : iv {iv} - , cmd {cmd} - , attempts {DefaultAttempts} - , attemptsMax {DefaultAttempts} - , ts {0} - , isDevControl {devCtrl} - {} - - QueueElement(const QueueElement &other) // copy constructor - : iv {other.iv} - , cmd {other.cmd} - , attempts {other.attempts} - , attemptsMax {other.attemptsMax} - , ts {other.ts} - , isDevControl {other.isDevControl} - {} - - void changeCmd(uint8_t cmd) { - this->cmd = cmd; - this->isDevControl = false; - } - - void setTs(const uint32_t ts) { - this->ts = ts; - } - - void setAttempt() { - if(this->attempts) - this->attempts--; - } - - void incrAttempt(uint8_t attempts = 1) { - this->attempts += attempts; - if (this->attempts > this->attemptsMax) - this->attemptsMax = this->attempts; - } - }; - protected: void add(QueueElement q) { xSemaphoreTake(this->mutex, portMAX_DELAY); @@ -148,13 +91,10 @@ class CommQueue { } } - void cmdDone(QueueElement *q, bool keep = false) { - if(keep) { - q->attempts = DefaultAttempts; - q->attemptsMax = DefaultAttempts; - add(q); // add to the end again - } - //inc(&this->rdPtr); + void cmdReset(QueueElement *q) { + q->attempts = DefaultAttempts; + q->attemptsMax = DefaultAttempts; + add(q); // add to the end again } private: @@ -183,6 +123,63 @@ class CommQueue { return false; } + protected: + struct QueueElement { + Inverter<> *iv; + uint8_t cmd; + uint8_t attempts; + uint8_t attemptsMax; + uint32_t ts; + bool isDevControl; + + QueueElement() + : iv {nullptr} + , cmd {0} + , attempts {0} + , attemptsMax {0} + , ts {0} + , isDevControl {false} + {} + + QueueElement(Inverter<> *iv, uint8_t cmd, bool devCtrl) + : iv {iv} + , cmd {cmd} + , attempts {DefaultAttempts} + , attemptsMax {DefaultAttempts} + , ts {0} + , isDevControl {devCtrl} + {} + + QueueElement(const QueueElement &other) // copy constructor + : iv {other.iv} + , cmd {other.cmd} + , attempts {other.attempts} + , attemptsMax {other.attemptsMax} + , ts {other.ts} + , isDevControl {other.isDevControl} + {} + + void changeCmd(uint8_t cmd) { + this->cmd = cmd; + this->isDevControl = false; + } + + void setTs(const uint32_t ts) { + this->ts = ts; + } + + void setAttempt() { + if(this->attempts) + this->attempts--; + } + + void incrAttempt(uint8_t attempts = 1) { + this->attempts += attempts; + if (this->attempts > this->attemptsMax) + this->attemptsMax = this->attempts; + } + }; + protected: std::array mQueue; diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 48e8840e..df406db5 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -102,8 +102,6 @@ class Communication : public CommQueue<> { q->iv->curFrmCnt = 0; q->iv->radioStatistics.txCnt++; mIsRetransmit = false; - if(NULL == q->iv->radio) - cmdDone(q, false); // can't communicate while radio is not defined! mFirstTry = (INV_RADIO_TYPE_NRF == q->iv->ivRadioType) && (q->iv->isAvailable()); q->iv->mCmd = q->cmd; q->iv->mIsSingleframeReq = false; @@ -112,7 +110,7 @@ class Communication : public CommQueue<> { if((q->iv->ivGen == IV_MI) && ((q->cmd == MI_REQ_CH1) || (q->cmd == MI_REQ_4CH))) q->incrAttempt(q->iv->channels); // 2 more attempts for 2ch, 4 more for 4ch - mState = States::START; + mState = (NULL == q->iv->radio) ? States::RESET : States::START; break; case States::START: @@ -644,7 +642,9 @@ class Communication : public CommQueue<> { if(q->isDevControl) keep = !crcPass; - cmdDone(q, keep); + if(keep) + cmdReset(q); + q->iv->mGotFragment = false; q->iv->mGotLastMsg = false; q->iv->miMultiParts = 0; From 27c77f4b0c656dd736f06891da66309b995312fe Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 29 Sep 2024 23:12:46 +0200 Subject: [PATCH 22/40] 0.8.147 fix compilation --- src/hm/CommQueue.h | 114 ++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index c0676158..48a13cd3 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -18,6 +18,63 @@ class CommQueue { static constexpr uint8_t MoreAttemptsAlarmData = 3; static constexpr uint8_t MoreAttemptsGridProfile = 0; + protected: + struct QueueElement { + Inverter<> *iv; + uint8_t cmd; + uint8_t attempts; + uint8_t attemptsMax; + uint32_t ts; + bool isDevControl; + + QueueElement() + : iv {nullptr} + , cmd {0} + , attempts {0} + , attemptsMax {0} + , ts {0} + , isDevControl {false} + {} + + QueueElement(Inverter<> *iv, uint8_t cmd, bool devCtrl) + : iv {iv} + , cmd {cmd} + , attempts {DefaultAttempts} + , attemptsMax {DefaultAttempts} + , ts {0} + , isDevControl {devCtrl} + {} + + QueueElement(const QueueElement &other) // copy constructor + : iv {other.iv} + , cmd {other.cmd} + , attempts {other.attempts} + , attemptsMax {other.attemptsMax} + , ts {other.ts} + , isDevControl {other.isDevControl} + {} + + void changeCmd(uint8_t cmd) { + this->cmd = cmd; + this->isDevControl = false; + } + + void setTs(const uint32_t ts) { + this->ts = ts; + } + + void setAttempt() { + if(this->attempts) + this->attempts--; + } + + void incrAttempt(uint8_t attempts = 1) { + this->attempts += attempts; + if (this->attempts > this->attemptsMax) + this->attemptsMax = this->attempts; + } + }; + public: CommQueue() : wrPtr {0} @@ -123,63 +180,6 @@ class CommQueue { return false; } - protected: - struct QueueElement { - Inverter<> *iv; - uint8_t cmd; - uint8_t attempts; - uint8_t attemptsMax; - uint32_t ts; - bool isDevControl; - - QueueElement() - : iv {nullptr} - , cmd {0} - , attempts {0} - , attemptsMax {0} - , ts {0} - , isDevControl {false} - {} - - QueueElement(Inverter<> *iv, uint8_t cmd, bool devCtrl) - : iv {iv} - , cmd {cmd} - , attempts {DefaultAttempts} - , attemptsMax {DefaultAttempts} - , ts {0} - , isDevControl {devCtrl} - {} - - QueueElement(const QueueElement &other) // copy constructor - : iv {other.iv} - , cmd {other.cmd} - , attempts {other.attempts} - , attemptsMax {other.attemptsMax} - , ts {other.ts} - , isDevControl {other.isDevControl} - {} - - void changeCmd(uint8_t cmd) { - this->cmd = cmd; - this->isDevControl = false; - } - - void setTs(const uint32_t ts) { - this->ts = ts; - } - - void setAttempt() { - if(this->attempts) - this->attempts--; - } - - void incrAttempt(uint8_t attempts = 1) { - this->attempts += attempts; - if (this->attempts > this->attemptsMax) - this->attemptsMax = this->attempts; - } - }; - protected: std::array mQueue; From 0b83e8bcb178d7699b42a3872cea647f3cc7f715 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 29 Sep 2024 23:48:42 +0200 Subject: [PATCH 23/40] 0.8.147 fix compilation --- src/hm/CommQueue.h | 12 ++++++++++++ src/platformio.ini | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index 48a13cd3..90e61071 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -11,6 +11,12 @@ #include "hmInverter.h" #include "../utils/dbg.h" +#if !defined(ESP32) + #define vSemaphoreDelete(a) + #define xSemaphoreTake(a, b) + #define xSemaphoreGive(a) +#endif + template class CommQueue { protected: /* types */ @@ -80,8 +86,10 @@ class CommQueue { : wrPtr {0} , rdPtr {0} { + #if defined(ESP32) this->mutex = xSemaphoreCreateBinaryStatic(&this->mutex_buffer); xSemaphoreGive(this->mutex); + #endif } ~CommQueue() { @@ -186,8 +194,12 @@ class CommQueue { private: uint8_t wrPtr; uint8_t rdPtr; + #if defined(ESP32) SemaphoreHandle_t mutex; StaticSemaphore_t mutex_buffer; + #else + bool mutex; + #endif }; diff --git a/src/platformio.ini b/src/platformio.ini index e6811e0b..bf789ed9 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -154,7 +154,7 @@ platform = espressif32@6.7.0 board = lolin_d32 lib_deps = ${env.lib_deps} - https://github.com/mathieucarbou/ESPAsyncWebServer @ ^3.3.1 + https://github.com/mathieucarbou/ESPAsyncWebServer#v3.3.1 build_flags = ${env.build_flags} -DSPI_HAL monitor_filters = From 4a32188bb262e4da0e3d48cdf85b71b3639f4118 Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 30 Sep 2024 23:30:30 +0200 Subject: [PATCH 24/40] 0.8.148 * fixed send power limit #1757 * fix redirect after login --- src/CHANGES.md | 4 ++++ src/defines.h | 2 +- src/hm/CommQueue.h | 50 +++++++++++++++++++++++++++--------------- src/hm/Communication.h | 29 ++++++++++++++---------- src/platformio.ini | 2 +- 5 files changed, 55 insertions(+), 32 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index e52d899c..c035bcba 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,9 @@ # Development Changes +## 0.8.148 - 2024-09-30 +* fixed send power limit #1757 +* fix redirect after login + ## 0.8.147 - 2024-09-29 * improved queue, added mutex * fixed send power limit #1757 diff --git a/src/defines.h b/src/defines.h index f88e5682..a8f1a345 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 147 +#define VERSION_PATCH 148 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index 90e61071..dd82e82e 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -51,14 +51,11 @@ class CommQueue { , isDevControl {devCtrl} {} - QueueElement(const QueueElement &other) // copy constructor - : iv {other.iv} - , cmd {other.cmd} - , attempts {other.attempts} - , attemptsMax {other.attemptsMax} - , ts {other.ts} - , isDevControl {other.isDevControl} - {} + QueueElement(const QueueElement&) = delete; + + QueueElement(QueueElement&& other) : QueueElement{} { + this->swap(other); + } void changeCmd(uint8_t cmd) { this->cmd = cmd; @@ -79,6 +76,22 @@ class CommQueue { if (this->attempts > this->attemptsMax) this->attemptsMax = this->attempts; } + + QueueElement& operator=(const QueueElement&) = delete; + + QueueElement& operator = (QueueElement&& other) { + this->swap(other); + return *this; + } + + void swap(QueueElement& other) { + std::swap(this->iv, other.iv); + std::swap(this->cmd, other.cmd); + std::swap(this->attempts, other.attempts); + std::swap(this->attemptsMax, other.attemptsMax); + std::swap(this->ts, other.ts); + std::swap(this->isDevControl, other.isDevControl); + } }; public: @@ -101,16 +114,16 @@ class CommQueue { xSemaphoreTake(this->mutex, portMAX_DELAY); if(!isIncluded(&q)) { dec(&this->rdPtr); - mQueue[this->rdPtr] = q; + mQueue[this->rdPtr] = std::move(q); } xSemaphoreGive(this->mutex); } void add(Inverter<> *iv, uint8_t cmd) { - xSemaphoreTake(this->mutex, portMAX_DELAY); QueueElement q(iv, cmd, false); + xSemaphoreTake(this->mutex, portMAX_DELAY); if(!isIncluded(&q)) { - mQueue[this->wrPtr] = q; + mQueue[this->wrPtr] = std::move(q); inc(&this->wrPtr); } xSemaphoreGive(this->mutex); @@ -135,21 +148,22 @@ class CommQueue { void add(QueueElement *q, bool rstAttempts = false) { xSemaphoreTake(this->mutex, portMAX_DELAY); - mQueue[this->wrPtr] = *q; if(rstAttempts) { - mQueue[this->wrPtr].attempts = DefaultAttempts; - mQueue[this->wrPtr].attemptsMax = DefaultAttempts; + q->attempts = DefaultAttempts; + q->attemptsMax = DefaultAttempts; } + mQueue[this->wrPtr] = std::move(*q); inc(&this->wrPtr); xSemaphoreGive(this->mutex); } void get(std::function cb) { - if(this->rdPtr == this->wrPtr) + xSemaphoreTake(this->mutex, portMAX_DELAY); + if(this->rdPtr == this->wrPtr) { + xSemaphoreGive(this->mutex); cb(false, nullptr); // empty - else { - xSemaphoreTake(this->mutex, portMAX_DELAY); - QueueElement el = mQueue[this->rdPtr]; + } else { + QueueElement el = std::move(mQueue[this->rdPtr]); inc(&this->rdPtr); xSemaphoreGive(this->mutex); cb(true, &el); diff --git a/src/hm/Communication.h b/src/hm/Communication.h index df406db5..1abaa9fd 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -36,7 +36,7 @@ class Communication : public CommQueue<> { void addImportant(Inverter<> *iv, uint8_t cmd) { if(!mIsDevControl) // only reset communication once there is no other devcontrol command - mState = States::RESET; // cancel current operation + mState = States::IDLE; // cancel current operation mIsDevControl = true; CommQueue::addImportant(iv, cmd); } @@ -54,7 +54,7 @@ class Communication : public CommQueue<> { } void loop() { - if(States::RESET == mState) { + if(States::IDLE == mState) { get([this](bool valid, QueueElement *q) { if(!valid) { if(mPrintSequenceDuration) { @@ -63,12 +63,12 @@ class Communication : public CommQueue<> { DBGPRINT(String(millis() - mLastEmptyQueueMillis)); DBGPRINTLN(F("ms")); DBGPRINTLN(F("-----")); - el.iv = nullptr; } return; // empty } - el = *q; + el = std::move(*q); + mState = States::INIT; if(!mPrintSequenceDuration) // entry was added to the queue mLastEmptyQueueMillis = millis(); mPrintSequenceDuration = true; @@ -82,7 +82,11 @@ class Communication : public CommQueue<> { private: inline void innerLoop(QueueElement *q) { switch(mState) { - case States::RESET: + default: + case States::IDLE: + break; + + case States::INIT: if (!mWaitTime.isTimeout()) return; @@ -110,7 +114,8 @@ class Communication : public CommQueue<> { if((q->iv->ivGen == IV_MI) && ((q->cmd == MI_REQ_CH1) || (q->cmd == MI_REQ_4CH))) q->incrAttempt(q->iv->channels); // 2 more attempts for 2ch, 4 more for 4ch - mState = (NULL == q->iv->radio) ? States::RESET : States::START; + if(NULL != q->iv->radio) + mState = States::START; break; case States::START: @@ -293,7 +298,7 @@ class Communication : public CommQueue<> { q->iv->radioStatistics.txCnt--; q->iv->radioStatistics.retransmits++; mCompleteRetry = true; - mState = States::RESET; + mState = States::IDLE; return; } } @@ -537,7 +542,7 @@ class Communication : public CommQueue<> { } else DBGPRINTLN(F("-> complete retransmit")); mCompleteRetry = true; - mState = States::RESET; + mState = States::IDLE; return false; } @@ -650,7 +655,7 @@ class Communication : public CommQueue<> { q->iv->miMultiParts = 0; mIsRetransmit = false; mCompleteRetry = false; - mState = States::RESET; + mState = States::IDLE; DBGPRINTLN(F("-----")); } @@ -797,7 +802,7 @@ class Communication : public CommQueue<> { inline void miDataDecode(packet_t *p, QueueElement *q) { record_t<> *rec = q->iv->getRecordStruct(RealTimeRunData_Debug); // choose the parser rec->ts = q->ts; - //mState = States::RESET; + //mState = States::IDLE; if(q->iv->miMultiParts < 6) q->iv->miMultiParts += 6; @@ -1031,7 +1036,7 @@ class Communication : public CommQueue<> { private: enum class States : uint8_t { - RESET, START, WAIT, CHECK_FRAMES, CHECK_PACKAGE + IDLE, INIT, START, WAIT, CHECK_FRAMES, CHECK_PACKAGE }; typedef struct { @@ -1041,7 +1046,7 @@ class Communication : public CommQueue<> { } frame_t; private: - States mState = States::RESET; + States mState = States::IDLE; uint32_t *mTimestamp = nullptr; QueueElement el; bool *mPrivacyMode = nullptr, *mSerialDebug = nullptr, *mPrintWholeTrace = nullptr; diff --git a/src/platformio.ini b/src/platformio.ini index bf789ed9..2c0af1d7 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -154,7 +154,7 @@ platform = espressif32@6.7.0 board = lolin_d32 lib_deps = ${env.lib_deps} - https://github.com/mathieucarbou/ESPAsyncWebServer#v3.3.1 + https://github.com/mathieucarbou/ESPAsyncWebServer#v3.2.4 build_flags = ${env.build_flags} -DSPI_HAL monitor_filters = From a31f1e753bd919deb6c374e44113e1ba660e376c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hendrik=20S=C3=B6bbing?= Date: Tue, 1 Oct 2024 10:41:01 +0200 Subject: [PATCH 25/40] Fix typos Fixed some German typos --- src/web/lang.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/web/lang.json b/src/web/lang.json index 179c3e4e..1e46a057 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -6,7 +6,7 @@ { "token": "NAV_WIZARD", "en": "Setup Wizard", - "de": "Einrichtungsassitent" + "de": "Einrichtungsassistent" }, { "token": "NAV_LIVE", @@ -236,7 +236,7 @@ { "token": "LOG_PRINT_TRACES", "en": "Print whole traces in Log", - "de": "alle Informationen in Log schreiben" + "de": "alle Informationen ins Log schreiben" }, { "token": "LOG_TO_MQTT", From 995c97f824fae2a5a7da07eccd4ae1329eca0a4e Mon Sep 17 00:00:00 2001 From: lumapu Date: Tue, 1 Oct 2024 22:44:29 +0200 Subject: [PATCH 26/40] 0.8.149 * fixed send power limit #1757 --- src/CHANGES.md | 3 +++ src/defines.h | 2 +- src/hm/Communication.h | 10 ++++++---- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index c035bcba..e7ebf545 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,8 @@ # Development Changes +## 0.8.149 - 2024-10-01 +* fixed send power limit #1757 + ## 0.8.148 - 2024-09-30 * fixed send power limit #1757 * fix redirect after login diff --git a/src/defines.h b/src/defines.h index a8f1a345..186e4d91 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 148 +#define VERSION_PATCH 149 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 1abaa9fd..1b2a6a7a 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -648,11 +648,13 @@ class Communication : public CommQueue<> { keep = !crcPass; if(keep) - cmdReset(q); + cmdReset(q); // q will be zero'ed after that command + else { + q->iv->mGotFragment = false; + q->iv->mGotLastMsg = false; + q->iv->miMultiParts = 0; + } - q->iv->mGotFragment = false; - q->iv->mGotLastMsg = false; - q->iv->miMultiParts = 0; mIsRetransmit = false; mCompleteRetry = false; mState = States::IDLE; From 6815b7da595a25989f61cbfd42a44fb07e39a26a Mon Sep 17 00:00:00 2001 From: lumapu Date: Tue, 1 Oct 2024 22:46:31 +0200 Subject: [PATCH 27/40] 0.8.149 * merged: Fix minor typos #1758 --- src/CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CHANGES.md b/src/CHANGES.md index e7ebf545..36a9ee62 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -2,6 +2,7 @@ ## 0.8.149 - 2024-10-01 * fixed send power limit #1757 +* merged: Fix minor typos #1758 ## 0.8.148 - 2024-09-30 * fixed send power limit #1757 From eb8924a6d83fcd29f51ed2618b05b3123e965519 Mon Sep 17 00:00:00 2001 From: lumapu Date: Tue, 1 Oct 2024 23:01:10 +0200 Subject: [PATCH 28/40] 0.8.149 * fix redirect after login with newest webserver version --- src/CHANGES.md | 1 + src/platformio.ini | 2 +- src/web/web.h | 44 +++++++++++++++++++++++++------------------- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 36a9ee62..aef37af8 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -3,6 +3,7 @@ ## 0.8.149 - 2024-10-01 * fixed send power limit #1757 * merged: Fix minor typos #1758 +* fix redirect after login with newest webserver version ## 0.8.148 - 2024-09-30 * fixed send power limit #1757 diff --git a/src/platformio.ini b/src/platformio.ini index 2c0af1d7..d67d6091 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -154,7 +154,7 @@ platform = espressif32@6.7.0 board = lolin_d32 lib_deps = ${env.lib_deps} - https://github.com/mathieucarbou/ESPAsyncWebServer#v3.2.4 + https://github.com/mathieucarbou/ESPAsyncWebServer#v3.3.7 build_flags = ${env.build_flags} -DSPI_HAL monitor_filters = diff --git a/src/web/web.h b/src/web/web.h index 95ef7af1..efabe587 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -216,31 +216,36 @@ class Web { } private: - inline void checkRedirect(AsyncWebServerRequest *request) { - if ((mConfig->sys.protectionMask & PROT_MASK_INDEX) != PROT_MASK_INDEX) - request->redirect(F("/index")); - else if ((mConfig->sys.protectionMask & PROT_MASK_LIVE) != PROT_MASK_LIVE) - request->redirect(F("/live")); - else if ((mConfig->sys.protectionMask & PROT_MASK_HISTORY) != PROT_MASK_HISTORY) - request->redirect(F("/history")); - else if ((mConfig->sys.protectionMask & PROT_MASK_SERIAL) != PROT_MASK_SERIAL) - request->redirect(F("/serial")); - else if ((mConfig->sys.protectionMask & PROT_MASK_SYSTEM) != PROT_MASK_SYSTEM) - request->redirect(F("/system")); - else - request->redirect(F("/login")); - } - - void checkProtection(AsyncWebServerRequest *request) { + bool checkProtection(AsyncWebServerRequest *request) { if(mApp->isProtected(request->client()->remoteIP().toString().c_str(), "", true)) { - checkRedirect(request); - return; + if ((mConfig->sys.protectionMask & PROT_MASK_INDEX) != PROT_MASK_INDEX) { + request->redirect(F("/index")); + return true; + } else if ((mConfig->sys.protectionMask & PROT_MASK_LIVE) != PROT_MASK_LIVE) { + request->redirect(F("/live")); + return true; + } else if ((mConfig->sys.protectionMask & PROT_MASK_HISTORY) != PROT_MASK_HISTORY) { + request->redirect(F("/history")); + return true; + } else if ((mConfig->sys.protectionMask & PROT_MASK_SERIAL) != PROT_MASK_SERIAL) { + request->redirect(F("/serial")); + return true; + } else if ((mConfig->sys.protectionMask & PROT_MASK_SYSTEM) != PROT_MASK_SYSTEM) { + request->redirect(F("/system")); + return true; + } else { + request->redirect(F("/login")); + return true; + } } + + return false; } void getPage(AsyncWebServerRequest *request, uint16_t mask, const uint8_t *zippedHtml, uint32_t len) { if (CHECK_MASK(mConfig->sys.protectionMask, mask)) - checkProtection(request); + if(checkProtection(request)) + return; AsyncWebServerResponse *response = beginResponse(request, 200, F("text/html; charset=UTF-8"), zippedHtml, len); response->addHeader(F("Content-Encoding"), "gzip"); @@ -337,6 +342,7 @@ class Web { if (String(request->arg("pwd")) == String(mConfig->sys.adminPwd)) { mApp->unlock(request->client()->remoteIP().toString().c_str(), true); request->redirect("/index"); + return; } } From 9efb3a99415a58282f95645b7e9aafe15d031f35 Mon Sep 17 00:00:00 2001 From: lumapu Date: Wed, 2 Oct 2024 22:53:51 +0200 Subject: [PATCH 29/40] 0.8.150 * fix nullptr exception * modified MqTT to not publish while not connected * removed patch for Webserver library - obsolete --- patches/AsyncWeb_Prometheus.patch | 26 -------------------------- scripts/applyPatches.py | 2 -- src/CHANGES.md | 5 +++++ src/defines.h | 2 +- src/hm/Communication.h | 2 +- src/platformio.ini | 2 ++ 6 files changed, 9 insertions(+), 30 deletions(-) delete mode 100644 patches/AsyncWeb_Prometheus.patch diff --git a/patches/AsyncWeb_Prometheus.patch b/patches/AsyncWeb_Prometheus.patch deleted file mode 100644 index f8e02c87..00000000 --- a/patches/AsyncWeb_Prometheus.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp -index 88d88ec..cb06fe0 100644 ---- a/src/AsyncWebSocket.cpp -+++ b/src/AsyncWebSocket.cpp -@@ -745,7 +745,7 @@ void AsyncWebSocketClient::binary(const __FlashStringHelper* data, size_t len) { - - IPAddress AsyncWebSocketClient::remoteIP() const { - if (!_client) -- return IPAddress((uint32_t)0U); -+ return IPAddress(); - - return _client->remoteIP(); - } -diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp -index 86aa947..9d0ee00 100644 ---- a/src/WebResponses.cpp -+++ b/src/WebResponses.cpp -@@ -447,7 +447,7 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest* request, size_t len, u - free(buf); - return 0; - } -- outLen = sprintf_P((char*)buf + headLen, PSTR("%x"), readLen) + headLen; -+ outLen = sprintf_P((char*)buf + headLen, PSTR("%04x"), readLen) + headLen; - while (outLen < headLen + 4) - buf[outLen++] = ' '; - buf[outLen++] = '\r'; diff --git a/scripts/applyPatches.py b/scripts/applyPatches.py index b6d86be7..1ef36963 100644 --- a/scripts/applyPatches.py +++ b/scripts/applyPatches.py @@ -26,8 +26,6 @@ def applyPatch(libName, patchFile): # list of patches to apply (relative to /src) -applyPatch("ESPAsyncWebServer", "../patches/AsyncWeb_Prometheus.patch") - if (env['PIOENV'][:5] == "esp32") or (env['PIOENV'][:13] == "opendtufusion"): applyPatch("GxEPD2", "../patches/GxEPD2_HAL.patch") diff --git a/src/CHANGES.md b/src/CHANGES.md index aef37af8..1b733050 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,10 @@ # Development Changes +## 0.8.150 - 2024-10-02 +* fix nullptr exception +* modified MqTT to not publish while not connected +* removed patch for Webserver library - obsolete + ## 0.8.149 - 2024-10-01 * fixed send power limit #1757 * merged: Fix minor typos #1758 diff --git a/src/defines.h b/src/defines.h index 186e4d91..19e4e6d2 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 149 +#define VERSION_PATCH 150 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 1b2a6a7a..4043f610 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -208,11 +208,11 @@ class Communication : public CommQueue<> { mHeu.setIvRetriesGood(q->iv,p->millis < LIMIT_VERYFAST_IV); } } else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command + q->iv->radio->mBufCtrl.pop(); if(parseDevCtrl(p, q)) closeRequest(q, true); else closeRequest(q, false); - q->iv->radio->mBufCtrl.pop(); return; // don't wait for empty buffer } else if(IV_MI == q->iv->ivGen) { parseMiFrame(p, q); diff --git a/src/platformio.ini b/src/platformio.ini index d67d6091..8553d824 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -37,6 +37,7 @@ lib_deps = build_flags = -std=c++17 -std=gnu++17 + -DEMC_ALLOW_NOT_CONNECTED_PUBLISH build_unflags = -std=gnu++11 @@ -51,6 +52,7 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncUDP build_flags = ${env.build_flags} -DEMC_MIN_FREE_MEMORY=4096 + -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 ;-Wl,-Map,output.map monitor_filters = From 677876a2c03319c868c1971f35042ee17825e5b2 Mon Sep 17 00:00:00 2001 From: lumapu Date: Wed, 2 Oct 2024 22:56:23 +0200 Subject: [PATCH 30/40] 0.8.150 fix communication --- src/hm/Communication.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 4043f610..31f2214a 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -647,13 +647,12 @@ class Communication : public CommQueue<> { if(q->isDevControl) keep = !crcPass; + q->iv->mGotFragment = false; + q->iv->mGotLastMsg = false; + q->iv->miMultiParts = 0; + if(keep) cmdReset(q); // q will be zero'ed after that command - else { - q->iv->mGotFragment = false; - q->iv->mGotLastMsg = false; - q->iv->miMultiParts = 0; - } mIsRetransmit = false; mCompleteRetry = false; From 28b303cac289789e2988863a665e4aaff06a922f Mon Sep 17 00:00:00 2001 From: lumapu Date: Thu, 3 Oct 2024 15:33:19 +0200 Subject: [PATCH 31/40] 0.8.151 * don't interrupt current command by setting a new limit #1757 --- src/CHANGES.md | 3 +++ src/defines.h | 2 +- src/hm/Communication.h | 11 ----------- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 1b733050..c3918c4d 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,8 @@ # Development Changes +## 0.8.151 - 2024-10-03 +* don't interrupt current command by setting a new limit #1757 + ## 0.8.150 - 2024-10-02 * fix nullptr exception * modified MqTT to not publish while not connected diff --git a/src/defines.h b/src/defines.h index 19e4e6d2..4b2828c8 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 150 +#define VERSION_PATCH 151 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 31f2214a..6290fc31 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -34,13 +34,6 @@ class Communication : public CommQueue<> { mPrintWholeTrace = printWholeTrace; } - void addImportant(Inverter<> *iv, uint8_t cmd) { - if(!mIsDevControl) // only reset communication once there is no other devcontrol command - mState = States::IDLE; // cancel current operation - mIsDevControl = true; - CommQueue::addImportant(iv, cmd); - } - void addPayloadListener(payloadListenerType cb) { mCbPayload = cb; } @@ -95,9 +88,6 @@ class Communication : public CommQueue<> { mLocalBuf[i].len = 0; } - if(!q->isDevControl) - mIsDevControl = false; // reset devcontrol flag - if(*mSerialDebug) mHeu.printStatus(q->iv); mHeu.getTxCh(q->iv); @@ -1066,7 +1056,6 @@ class Communication : public CommQueue<> { Heuristic mHeu; uint32_t mLastEmptyQueueMillis = 0; bool mPrintSequenceDuration = false; - bool mIsDevControl = false; // holds if current command is devcontrol }; #endif /*__COMMUNICATION_H__*/ From ac881090e582c07ef38968591466fc527e13c115 Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 3 Oct 2024 16:27:23 +0200 Subject: [PATCH 32/40] remove reference to pkg_resource which is deprecated in python 3.12 --- scripts/auto_firmware_version.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/scripts/auto_firmware_version.py b/scripts/auto_firmware_version.py index 75bf7379..1a69c8dc 100644 --- a/scripts/auto_firmware_version.py +++ b/scripts/auto_firmware_version.py @@ -2,16 +2,14 @@ # # Copyright (C) 2022 Thomas Basler and others # -import pkg_resources Import("env") -required_pkgs = {'dulwich'} -installed_pkgs = {pkg.key for pkg in pkg_resources.working_set} -missing_pkgs = required_pkgs - installed_pkgs - -if missing_pkgs: +try: + from dulwich import porcelain +except ModuleNotFoundError: env.Execute('"$PYTHONEXE" -m pip install dulwich') + from dulwich import porcelain from dulwich import porcelain From f06e56c14fbbda986424b79826b986889e96cab8 Mon Sep 17 00:00:00 2001 From: lumapu Date: Thu, 3 Oct 2024 17:06:12 +0200 Subject: [PATCH 33/40] 0.8.151 * add button for CMT inverters to catch them independend on which frequency they were before #1749 --- src/CHANGES.md | 1 + src/app.h | 23 +++++++++++++++++++++++ src/appInterface.h | 2 ++ src/hm/Radio.h | 1 + src/hms/CmtRadio.h | 37 +++++++++++++++++++++++++++++++------ src/hms/cmt2300a.h | 4 ++++ src/web/RestApi.h | 5 +++++ src/web/html/setup.html | 13 ++++++++++++- src/web/lang.json | 10 ++++++++++ 9 files changed, 89 insertions(+), 7 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index c3918c4d..c2e50d58 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -2,6 +2,7 @@ ## 0.8.151 - 2024-10-03 * don't interrupt current command by setting a new limit #1757 +* add button for CMT inverters to catch them independend on which frequency they were before #1749 ## 0.8.150 - 2024-10-02 * fix nullptr exception diff --git a/src/app.h b/src/app.h index d954df35..58101a59 100644 --- a/src/app.h +++ b/src/app.h @@ -291,6 +291,29 @@ class app : public IApp, public ah::Scheduler { return mConfig->cmt.enabled; } + bool cmtSearch(uint8_t id, uint8_t toCh) override { + #if defined(ESP32) + Inverter<> *iv; + + for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { + iv = mSys.getInverterByPos(i, true); + if(nullptr != iv) { + if(i == id) + break; + else + iv = nullptr; + } + } + + if(nullptr != iv) { + mCmtRadio.catchInverter(iv, toCh); + return true; + } + #endif + + return false; + } + uint8_t getNrfIrqPin(void) { return mConfig->nrf.pinIrq; } diff --git a/src/appInterface.h b/src/appInterface.h index ca0fc172..e03bc84f 100644 --- a/src/appInterface.h +++ b/src/appInterface.h @@ -56,6 +56,8 @@ class IApp { virtual bool getNrfEnabled() = 0; virtual bool getCmtEnabled() = 0; + virtual bool cmtSearch(uint8_t id, uint8_t toCh) = 0; + virtual uint32_t getMqttRxCnt() = 0; virtual uint32_t getMqttTxCnt() = 0; diff --git a/src/hm/Radio.h b/src/hm/Radio.h index 12e80850..f6a9b8d3 100644 --- a/src/hm/Radio.h +++ b/src/hm/Radio.h @@ -29,6 +29,7 @@ class Radio { virtual void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit) = 0; virtual bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) { return true; } virtual bool switchFrequencyCh(Inverter<> *iv, uint8_t fromCh, uint8_t toCh) { return true; } + virtual void catchInverter(Inverter<> *iv, uint8_t toCh) {} virtual bool isChipConnected(void) const { return false; } virtual uint16_t getBaseFreqMhz() { return 0; } virtual uint16_t getBootFreqMhz() { return 0; } diff --git a/src/hms/CmtRadio.h b/src/hms/CmtRadio.h index fd49e8f8..a5684a36 100644 --- a/src/hms/CmtRadio.h +++ b/src/hms/CmtRadio.h @@ -35,6 +35,11 @@ class CmtRadio : public Radio { return; mCmt.loop(); + if(nullptr != mCatchIv) { + if(mCmt.isTxReady()) + catchInverterLoop(); + } + if((!mIrqRcvd) && (!mRqstGetRx)) return; getRx(); @@ -93,6 +98,28 @@ class CmtRadio : public Radio { return true; } + void catchInverter(Inverter<> *iv, uint8_t toCh) override { + if(!isChipConnected()) + return; + + mCatchIv = iv; + mCatchIvCh = 1; + mCatchIvToCh = toCh; + + mCmt.switchChannel(0); + sendSwitchChCmd(iv, toCh); + } + + void catchInverterLoop() { + mCmt.switchChannel(mCatchIvCh); + sendSwitchChCmd(mCatchIv, mCatchIvToCh); + + if(++mCatchIvCh == 0x29) { + mCmt.switchChannel(mCatchIvToCh); + mCatchIv = nullptr; + } + } + uint16_t getBaseFreqMhz(void) override { return mCmt.getBaseFreqMhz(); } @@ -168,10 +195,6 @@ class CmtRadio : public Radio { } inline void sendSwitchChCmd(Inverter<> *iv, uint8_t ch) { - //if(CMT_SWITCH_CHANNEL_CYCLE > ++mSwitchCycle) - // return; - //mSwitchCycle = 0; - /** ch: * 0x00: 860.00 MHz * 0x01: 860.25 MHz @@ -194,7 +217,6 @@ class CmtRadio : public Radio { packet_t p; 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); } @@ -210,7 +232,10 @@ class CmtRadio : public Radio { bool mCmtAvail = false; bool mRqstGetRx = false; uint32_t mMillis = 0; - //uint8_t mSwitchCycle = 0; + + Inverter<> *mCatchIv = nullptr; + uint8_t mCatchIvCh = 0; + uint8_t mCatchIvToCh = 0; }; #endif /*__HMS_RADIO_H__*/ diff --git a/src/hms/cmt2300a.h b/src/hms/cmt2300a.h index ed3aab54..626d3e79 100644 --- a/src/hms/cmt2300a.h +++ b/src/hms/cmt2300a.h @@ -188,6 +188,10 @@ class Cmt2300a { } } + bool isTxReady() { + return !mTxPending; + } + CmtStatus goRx(void) { if(mTxPending) return CmtStatus::ERR_TX_PENDING; diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 099dc13b..c6859386 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -1131,6 +1131,11 @@ class RestApi { iv->setDevCommand(jsonIn[F("val")].as()); } else if(F("restart_ahoy") == jsonIn[F("cmd")]) { mApp->setRebootFlag(); + } else if(F("cmt_search") == jsonIn[F("cmd")]) { + if(!mApp->cmtSearch(jsonIn[F("id")], jsonIn[F("to_ch")])) { + jsonOut[F("error")] = F("ERR_INVERTER_NOT_FOUND"); + return false; + } } else { jsonOut[F("error")] = F("ERR_UNKNOWN_CMD"); return false; diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 4d99331e..ef9e06f5 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -817,7 +817,8 @@ ml("input", {type: "hidden", name: "isnrf"}, null), ml("div", {id: "setcmt"}, [ divRow("{#INV_FREQUENCY}", sel("freq", esp32cmtFreq, obj.freq)), - divRow("{#INV_POWER_LEVEL}", sel("cmtpa", esp32cmtPa, obj.pa)) + divRow("{#INV_POWER_LEVEL}", sel("cmtpa", esp32cmtPa, obj.pa)), + divRow("{#INV_SEARCH}", ml("input", {type: "button", value: "{#BTN_SEARCH}", class: "btn", onclick: function() { cmtSearch(); }}, null)) ]), ml("div", {id: "setnrf"}, divRow("{#INV_POWER_LEVEL}", sel("nrfpa", nrfPa, obj.pa)) @@ -902,6 +903,16 @@ getAjax("/api/setup", cb, "POST", JSON.stringify(o)); } + function cmtSearch() { + var o = {} + o.cmd = "cmt_search" + o.token = "*" + o.id = obj.id + o.to_ch = document.getElementsByName("freq")[0].value; + + getAjax("/api/ctrl", cb, "POST", JSON.stringify(o)); + } + function convHerf(sn) { let sn_int = 0n; const CHARS = "0123456789ABCDEFGHJKLMNPRSTUVWXY"; diff --git a/src/web/lang.json b/src/web/lang.json index 2cf9139d..a1f15451 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -698,6 +698,16 @@ "en": "Pause communication during night (lat. and lon. need to be set)", "de": "Kommunikation während der Nacht pausieren (Breiten- und Längengrad müssen gesetzt sein" }, + { + "token": "INV_SEARCH", + "en": "Catch Inverter", + "de": "Wechselrichter suchen" + }, + { + "token": "BTN_SEARCH", + "en": "start", + "de": "starten" + }, { "token": "BTN_SAVE", "en": "save", From d1fbb7d2596449c3b722164c2a8bad9c532ca098 Mon Sep 17 00:00:00 2001 From: lumapu Date: Thu, 3 Oct 2024 17:15:00 +0200 Subject: [PATCH 34/40] 0.8.151 fix ESP8266 compilation --- src/hm/CommQueue.h | 8 +++++--- src/publisher/pubMqtt.h | 7 +++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index dd82e82e..db00626a 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -12,9 +12,11 @@ #include "../utils/dbg.h" #if !defined(ESP32) - #define vSemaphoreDelete(a) - #define xSemaphoreTake(a, b) - #define xSemaphoreGive(a) + #if !defined(vSemaphoreDelete) + #define vSemaphoreDelete(a) + #define xSemaphoreTake(a, b) { while(a) { yield(); } a = true; } + #define xSemaphoreGive(a) { a = false; } + #endif #endif template diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index 227a1310..4f567dcf 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -11,8 +11,11 @@ #if defined(ENABLE_MQTT) #ifdef ESP8266 #include - #define xSemaphoreTake(a, b) { while(a) { yield(); } a = true; } - #define xSemaphoreGive(a) { a = false; } + #if !defined(vSemaphoreDelete) + #define vSemaphoreDelete(a) + #define xSemaphoreTake(a, b) { while(a) { yield(); } a = true; } + #define xSemaphoreGive(a) { a = false; } + #endif #elif defined(ESP32) #include #endif From e601bfe443342d1b7c85913b1852cac50c4c5475 Mon Sep 17 00:00:00 2001 From: lumapu Date: Thu, 3 Oct 2024 17:16:49 +0200 Subject: [PATCH 35/40] 0.8.151 * increased communication queue length from 100 to 200 for ESP32-S3 --- src/CHANGES.md | 1 + src/hm/CommQueue.h | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/CHANGES.md b/src/CHANGES.md index c2e50d58..050cbbf3 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -3,6 +3,7 @@ ## 0.8.151 - 2024-10-03 * don't interrupt current command by setting a new limit #1757 * add button for CMT inverters to catch them independend on which frequency they were before #1749 +* increased communication queue length from 100 to 200 for ESP32-S3 ## 0.8.150 - 2024-10-02 * fix nullptr exception diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index db00626a..8f11c31c 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -19,7 +19,11 @@ #endif #endif +#if defined(CONFIG_IDF_TARGET_ESP32S3) +template +#else template +#endif class CommQueue { protected: /* types */ static constexpr uint8_t DefaultAttempts = 5; From 2475b757856c3f443708cb3e2cc24aea2ab5bf65 Mon Sep 17 00:00:00 2001 From: geronet1 Date: Fri, 4 Oct 2024 12:07:24 +0200 Subject: [PATCH 36/40] HA discovery IP address fix, HA json output fix --- src/publisher/pubMqtt.h | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index 4f567dcf..721cc2ff 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -430,7 +430,7 @@ class PubMqtt { doc[F("mdl")] = node_id; } - doc[F("cu")] = F("http://") + String(WiFi.localIP().toString()); + doc[F("cu")] = F("http://") + mApp->getIp(); doc[F("mf")] = F("Hoymiles"); JsonObject deviceObj = doc.as(); // deviceObj is only pointer!? @@ -449,13 +449,15 @@ class PubMqtt { snprintf(name.data(), name.size(), "%s", iv->getFieldName(mDiscovery.sub, rec)); else 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)); + if (!mCfgMqtt->json) + snprintf(topic.data(), name.size(), "/ch%d/%s", rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec)); + else + snprintf(topic.data(), name.size(), "/ch%d", rec->assign[mDiscovery.sub].ch); 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.data(), name.size(), "Total %s", fields[fldTotal[mDiscovery.sub]]); snprintf(topic.data(), topic.size(), "/%s", fields[fldTotal[mDiscovery.sub]]); @@ -467,7 +469,20 @@ class PubMqtt { DynamicJsonDocument doc2(512); constexpr static const char* unitTotal[] = {"W", "kWh", "Wh", "W"}; doc2[F("name")] = String(name.data()); - doc2[F("stat_t")] = String(mCfgMqtt->topic) + "/" + ((!total) ? String(iv->config->name) : "total" ) + String(topic.data()); + + if (mCfgMqtt->json) { + if (total) { + doc2[F("val_tpl")] = String("{{ value_json.") + fields[fldTotal[mDiscovery.sub]] + String(" }}"); + doc2[F("stat_t")] = String(mCfgMqtt->topic) + "/" + "total"; + } + else { + doc2[F("val_tpl")] = String("{{ value_json.") + iv->getFieldName(mDiscovery.sub, rec) + String(" }}"); + doc2[F("stat_t")] = String(mCfgMqtt->topic) + "/" + String(iv->config->name) + String(topic.data()); + } + } + else { + 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.data(); doc2[F("dev")] = deviceObj; From 3afc16515718cd291471c7609601452d7c3afc1c Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 7 Oct 2024 22:42:47 +0200 Subject: [PATCH 37/40] 0.8.152 * patching MqTT library to prevent raise conditions while using semaphores * update ESP32 espressif platform to `0.6.9` * update ESPAsyncWebServer to `3.3.12` --- patches/espMqttClientSemaphore.patch | 88 ++++++++++++++++++++++++++++ scripts/applyPatches.py | 2 + src/CHANGES.md | 5 ++ src/defines.h | 2 +- src/platformio.ini | 30 +++++----- 5 files changed, 111 insertions(+), 16 deletions(-) create mode 100644 patches/espMqttClientSemaphore.patch diff --git a/patches/espMqttClientSemaphore.patch b/patches/espMqttClientSemaphore.patch new file mode 100644 index 00000000..99ad9249 --- /dev/null +++ b/patches/espMqttClientSemaphore.patch @@ -0,0 +1,88 @@ +diff --git a/src/MqttClient.cpp b/src/MqttClient.cpp +index dc21f74..d4b35c4 100644 +--- a/src/MqttClient.cpp ++++ b/src/MqttClient.cpp +@@ -1,7 +1,7 @@ + /* + Copyright (c) 2022 Bert Melis. All rights reserved. + +-This work is licensed under the terms of the MIT license. ++This work is licensed under the terms of the MIT license. + For a copy, see or + the LICENSE file. + */ +@@ -148,16 +148,19 @@ uint16_t MqttClient::publish(const char* topic, uint8_t qos, bool retain, const + #endif + return 0; + } +- EMC_SEMAPHORE_TAKE(); +- uint16_t packetId = (qos > 0) ? _getNextPacketId() : 1; +- if (!_addPacket(packetId, topic, payload, length, qos, retain)) { +- emc_log_e("Could not create PUBLISH packet"); ++ uint16_t packetId = 0; ++ if(pdTRUE == EMC_SEMAPHORE_TAKE()) { ++ packetId = (qos > 0) ? _getNextPacketId() : 1; ++ if (!_addPacket(packetId, topic, payload, length, qos, retain)) { ++ emc_log_e("Could not create PUBLISH packet"); ++ EMC_SEMAPHORE_GIVE(); ++ _onError(packetId, Error::OUT_OF_MEMORY); ++ if(pdTRUE == EMC_SEMAPHORE_TAKE()) ++ packetId = 0; ++ } + EMC_SEMAPHORE_GIVE(); +- _onError(packetId, Error::OUT_OF_MEMORY); +- EMC_SEMAPHORE_TAKE(); +- packetId = 0; ++ yield(); + } +- EMC_SEMAPHORE_GIVE(); + return packetId; + } + +@@ -174,16 +177,19 @@ uint16_t MqttClient::publish(const char* topic, uint8_t qos, bool retain, espMqt + #endif + return 0; + } +- EMC_SEMAPHORE_TAKE(); +- uint16_t packetId = (qos > 0) ? _getNextPacketId() : 1; +- if (!_addPacket(packetId, topic, callback, length, qos, retain)) { +- emc_log_e("Could not create PUBLISH packet"); ++ uint16_t packetId = 0; ++ if(pdTRUE == EMC_SEMAPHORE_TAKE()) { ++ packetId = (qos > 0) ? _getNextPacketId() : 1; ++ if (!_addPacket(packetId, topic, callback, length, qos, retain)) { ++ emc_log_e("Could not create PUBLISH packet"); ++ EMC_SEMAPHORE_GIVE(); ++ _onError(packetId, Error::OUT_OF_MEMORY); ++ if(pdTRUE == EMC_SEMAPHORE_TAKE()) ++ packetId = 0; ++ } + EMC_SEMAPHORE_GIVE(); +- _onError(packetId, Error::OUT_OF_MEMORY); +- EMC_SEMAPHORE_TAKE(); +- packetId = 0; ++ yield(); + } +- EMC_SEMAPHORE_GIVE(); + return packetId; + } + +@@ -237,11 +243,13 @@ void MqttClient::loop() { + case State::connectingMqtt: + #if EMC_WAIT_FOR_CONNACK + if (_transport->connected()) { +- EMC_SEMAPHORE_TAKE(); +- _sendPacket(); +- _checkIncoming(); +- _checkPing(); +- EMC_SEMAPHORE_GIVE(); ++ if(pdTRUE == EMC_SEMAPHORE_TAKE()) { ++ _sendPacket(); ++ _checkIncoming(); ++ _checkPing(); ++ EMC_SEMAPHORE_GIVE(); ++ yield(); ++ } + } else { + _setState(State::disconnectingTcp1); + _disconnectReason = DisconnectReason::TCP_DISCONNECTED; diff --git a/scripts/applyPatches.py b/scripts/applyPatches.py index 1ef36963..dcd3098f 100644 --- a/scripts/applyPatches.py +++ b/scripts/applyPatches.py @@ -25,6 +25,8 @@ def applyPatch(libName, patchFile): os.chdir(start) +applyPatch("espMqttClient", "../patches/espMqttClientSemaphore.patch") + # list of patches to apply (relative to /src) if (env['PIOENV'][:5] == "esp32") or (env['PIOENV'][:13] == "opendtufusion"): applyPatch("GxEPD2", "../patches/GxEPD2_HAL.patch") diff --git a/src/CHANGES.md b/src/CHANGES.md index 050cbbf3..d14bca3d 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,10 @@ # Development Changes +## 0.8.152 - 2024-10-07 +* patching MqTT library to prevent raise conditions while using semaphores +* update ESP32 espressif platform to `0.6.9` +* update ESPAsyncWebServer to `3.3.12` + ## 0.8.151 - 2024-10-03 * don't interrupt current command by setting a new limit #1757 * add button for CMT inverters to catch them independend on which frequency they were before #1749 diff --git a/src/defines.h b/src/defines.h index 4b2828c8..1f3d013c 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 151 +#define VERSION_PATCH 152 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/platformio.ini b/src/platformio.ini index 8553d824..f5c75a10 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -152,18 +152,18 @@ monitor_filters = esp8266_exception_decoder [env:esp32-wroom32-minimal] -platform = espressif32@6.7.0 +platform = espressif32@6.9.0 board = lolin_d32 lib_deps = ${env.lib_deps} - https://github.com/mathieucarbou/ESPAsyncWebServer#v3.3.7 + https://github.com/mathieucarbou/ESPAsyncWebServer#v3.3.12 build_flags = ${env.build_flags} -DSPI_HAL monitor_filters = esp32_exception_decoder [env:esp32-wroom32] -platform = espressif32@6.7.0 +platform = espressif32@6.9.0 board = lolin_d32 lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:esp32-wroom32-minimal.build_flags} @@ -193,7 +193,7 @@ monitor_filters = esp32_exception_decoder [env:esp32-wroom32-de] -platform = espressif32@6.7.0 +platform = espressif32@6.9.0 board = lolin_d32 lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:esp32-wroom32.build_flags} @@ -202,7 +202,7 @@ monitor_filters = esp32_exception_decoder [env:esp32-wroom32-prometheus] -platform = espressif32@6.7.0 +platform = espressif32@6.9.0 board = lolin_d32 lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:esp32-wroom32.build_flags} @@ -211,7 +211,7 @@ monitor_filters = esp32_exception_decoder [env:esp32-wroom32-prometheus-de] -platform = espressif32@6.7.0 +platform = espressif32@6.9.0 board = lolin_d32 lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:esp32-wroom32-prometheus.build_flags} @@ -220,7 +220,7 @@ monitor_filters = esp32_exception_decoder [env:esp32-s2-mini] -platform = espressif32@6.7.0 +platform = espressif32@6.9.0 board = lolin_s2_mini lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env.build_flags} @@ -244,7 +244,7 @@ monitor_filters = esp32_exception_decoder [env:esp32-s2-mini-de] -platform = espressif32@6.7.0 +platform = espressif32@6.9.0 board = lolin_s2_mini lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:esp32-s2-mini.build_flags} @@ -253,7 +253,7 @@ monitor_filters = esp32_exception_decoder [env:esp32-c3-mini] -platform = espressif32@6.7.0 +platform = espressif32@6.9.0 board = lolin_c3_mini lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env.build_flags} @@ -277,7 +277,7 @@ monitor_filters = esp32_exception_decoder [env:esp32-c3-mini-de] -platform = espressif32@6.7.0 +platform = espressif32@6.9.0 board = lolin_c3_mini lib_deps = ${env:esp32-wroom32-minimal.lib_deps} build_flags = ${env:esp32-c3-mini.build_flags} @@ -286,7 +286,7 @@ monitor_filters = esp32_exception_decoder [env:opendtufusion-minimal] -platform = espressif32@6.7.0 +platform = espressif32@6.9.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin lib_deps = ${env:esp32-wroom32-minimal.lib_deps} @@ -312,7 +312,7 @@ monitor_filters = esp32_exception_decoder, colorize [env:opendtufusion] -platform = espressif32@6.7.0 +platform = espressif32@6.9.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin lib_deps = ${env:esp32-wroom32-minimal.lib_deps} @@ -331,7 +331,7 @@ monitor_filters = esp32_exception_decoder, colorize [env:opendtufusion-de] -platform = espressif32@6.7.0 +platform = espressif32@6.9.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin lib_deps = ${env:esp32-wroom32-minimal.lib_deps} @@ -341,7 +341,7 @@ monitor_filters = esp32_exception_decoder, colorize [env:opendtufusion-16MB] -platform = espressif32@6.7.0 +platform = espressif32@6.9.0 board = esp32-s3-devkitc-1 board_upload.flash_size = 16MB board_build.partitions = default_16MB.csv @@ -352,7 +352,7 @@ monitor_filters = esp32_exception_decoder, colorize [env:opendtufusion-16MB-de] -platform = espressif32@6.7.0 +platform = espressif32@6.9.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin lib_deps = ${env:esp32-wroom32-minimal.lib_deps} From 76899a6498dad8cca35345c5b559768ce33c77a5 Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 7 Oct 2024 22:47:25 +0200 Subject: [PATCH 38/40] 0.8.152 * merge: avoid using pkg_resources because it's deprecated in python 3.12 #1759 * merge: HA discovery IP address fix, HA json output fix #1760 --- src/CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CHANGES.md b/src/CHANGES.md index d14bca3d..bc419068 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -4,6 +4,8 @@ * patching MqTT library to prevent raise conditions while using semaphores * update ESP32 espressif platform to `0.6.9` * update ESPAsyncWebServer to `3.3.12` +* merge: avoid using pkg_resources because it's deprecated in python 3.12 #1759 +* merge: HA discovery IP address fix, HA json output fix #1760 ## 0.8.151 - 2024-10-03 * don't interrupt current command by setting a new limit #1757 From 78cbd7749d1f81a5b71b0d2ea36c70c1d23b0a96 Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 7 Oct 2024 23:01:47 +0200 Subject: [PATCH 39/40] 0.8.152 fix ESP8266 compile --- patches/espMqttClientSemaphore.patch | 53 +++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/patches/espMqttClientSemaphore.patch b/patches/espMqttClientSemaphore.patch index 99ad9249..51376218 100644 --- a/patches/espMqttClientSemaphore.patch +++ b/patches/espMqttClientSemaphore.patch @@ -1,5 +1,38 @@ +diff --git a/src/Helpers.h b/src/Helpers.h +index 05ab136..50b4c2f 100644 +--- a/src/Helpers.h ++++ b/src/Helpers.h +@@ -1,7 +1,7 @@ + /* + Copyright (c) 2022 Bert Melis. All rights reserved. + +-This work is licensed under the terms of the MIT license. ++This work is licensed under the terms of the MIT license. + For a copy, see or + the LICENSE file. + */ +@@ -13,6 +13,7 @@ the LICENSE file. + #include "freertos/FreeRTOS.h" + #include "freertos/task.h" + #include "esp_task_wdt.h" ++ #define EMC_SEMAPHORE_TAKE_CHECK() if(pdTRUE == xSemaphoreTake(_xSemaphore, portMAX_DELAY)) + #define EMC_SEMAPHORE_TAKE() xSemaphoreTake(_xSemaphore, portMAX_DELAY) + #define EMC_SEMAPHORE_GIVE() xSemaphoreGive(_xSemaphore) + #define EMC_GET_FREE_MEMORY() std::max(ESP.getMaxAllocHeap(), ESP.getMaxAllocPsram()) +@@ -25,9 +26,11 @@ the LICENSE file. + // _xSemaphore defined as std::atomic + #define EMC_SEMAPHORE_TAKE() while (_xSemaphore) { /*ESP.wdtFeed();*/ } _xSemaphore = true + #define EMC_SEMAPHORE_GIVE() _xSemaphore = false ++ #define EMC_SEMAPHORE_TAKE_CHECK() EMC_SEMAPHORE_TAKE + #else + #define EMC_SEMAPHORE_TAKE() + #define EMC_SEMAPHORE_GIVE() ++ #define EMC_SEMAPHORE_TAKE_CHECK() + #endif + #define EMC_GET_FREE_MEMORY() ESP.getMaxFreeBlockSize() + // no need to yield for ESP8266, the Arduino framework does this internally diff --git a/src/MqttClient.cpp b/src/MqttClient.cpp -index dc21f74..d4b35c4 100644 +index dc21f74..d524e50 100644 --- a/src/MqttClient.cpp +++ b/src/MqttClient.cpp @@ -1,7 +1,7 @@ @@ -11,7 +44,7 @@ index dc21f74..d4b35c4 100644 For a copy, see or the LICENSE file. */ -@@ -148,16 +148,19 @@ uint16_t MqttClient::publish(const char* topic, uint8_t qos, bool retain, const +@@ -148,16 +148,20 @@ uint16_t MqttClient::publish(const char* topic, uint8_t qos, bool retain, const #endif return 0; } @@ -20,14 +53,15 @@ index dc21f74..d4b35c4 100644 - if (!_addPacket(packetId, topic, payload, length, qos, retain)) { - emc_log_e("Could not create PUBLISH packet"); + uint16_t packetId = 0; -+ if(pdTRUE == EMC_SEMAPHORE_TAKE()) { ++ EMC_SEMAPHORE_TAKE_CHECK() { + packetId = (qos > 0) ? _getNextPacketId() : 1; + if (!_addPacket(packetId, topic, payload, length, qos, retain)) { + emc_log_e("Could not create PUBLISH packet"); + EMC_SEMAPHORE_GIVE(); + _onError(packetId, Error::OUT_OF_MEMORY); -+ if(pdTRUE == EMC_SEMAPHORE_TAKE()) ++ EMC_SEMAPHORE_TAKE_CHECK() { + packetId = 0; ++ } + } EMC_SEMAPHORE_GIVE(); - _onError(packetId, Error::OUT_OF_MEMORY); @@ -39,7 +73,7 @@ index dc21f74..d4b35c4 100644 return packetId; } -@@ -174,16 +177,19 @@ uint16_t MqttClient::publish(const char* topic, uint8_t qos, bool retain, espMqt +@@ -174,16 +178,20 @@ uint16_t MqttClient::publish(const char* topic, uint8_t qos, bool retain, espMqt #endif return 0; } @@ -48,14 +82,15 @@ index dc21f74..d4b35c4 100644 - if (!_addPacket(packetId, topic, callback, length, qos, retain)) { - emc_log_e("Could not create PUBLISH packet"); + uint16_t packetId = 0; -+ if(pdTRUE == EMC_SEMAPHORE_TAKE()) { ++ EMC_SEMAPHORE_TAKE_CHECK() { + packetId = (qos > 0) ? _getNextPacketId() : 1; + if (!_addPacket(packetId, topic, callback, length, qos, retain)) { + emc_log_e("Could not create PUBLISH packet"); + EMC_SEMAPHORE_GIVE(); + _onError(packetId, Error::OUT_OF_MEMORY); -+ if(pdTRUE == EMC_SEMAPHORE_TAKE()) ++ EMC_SEMAPHORE_TAKE_CHECK() { + packetId = 0; ++ } + } EMC_SEMAPHORE_GIVE(); - _onError(packetId, Error::OUT_OF_MEMORY); @@ -67,7 +102,7 @@ index dc21f74..d4b35c4 100644 return packetId; } -@@ -237,11 +243,13 @@ void MqttClient::loop() { +@@ -237,11 +245,13 @@ void MqttClient::loop() { case State::connectingMqtt: #if EMC_WAIT_FOR_CONNACK if (_transport->connected()) { @@ -76,7 +111,7 @@ index dc21f74..d4b35c4 100644 - _checkIncoming(); - _checkPing(); - EMC_SEMAPHORE_GIVE(); -+ if(pdTRUE == EMC_SEMAPHORE_TAKE()) { ++ EMC_SEMAPHORE_TAKE_CHECK() { + _sendPacket(); + _checkIncoming(); + _checkPing(); From 5120aa473b48559cd700931edb0220ddfc8e86ba Mon Sep 17 00:00:00 2001 From: Lukas Pusch Date: Wed, 5 Mar 2025 12:29:29 +0100 Subject: [PATCH 40/40] 0.8.153 * added update warning once 0.9.x should be installed -> not possible using OTA because of changed partition layout * improved CMT communication --- src/CHANGES.md | 4 ++++ src/defines.h | 2 +- src/hms/cmt2300a.h | 29 +++++++++++++++++++++++------ src/web/html/update.html | 20 +++++++++++++++++--- src/web/lang.json | 5 +++++ 5 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index bc419068..11cd7393 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,9 @@ # Development Changes +## 0.8.153 - 2025-03-05 +* added update warning once 0.9.x should be installed -> not possible using OTA because of changed partition layout +* improved CMT communication + ## 0.8.152 - 2024-10-07 * patching MqTT library to prevent raise conditions while using semaphores * update ESP32 espressif platform to `0.6.9` diff --git a/src/defines.h b/src/defines.h index 1f3d013c..105220cf 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 152 +#define VERSION_PATCH 153 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/hms/cmt2300a.h b/src/hms/cmt2300a.h index 626d3e79..ece6fbc3 100644 --- a/src/hms/cmt2300a.h +++ b/src/hms/cmt2300a.h @@ -168,8 +168,13 @@ enum class CmtStatus : uint8_t { #define CMT2300A_MASK_PKT_OK_FLG 0x01 class Cmt2300a { + private: /*types*/ + static constexpr uint8_t CmtTimeoutMs = 40; + public: - Cmt2300a() {} + Cmt2300a() + : lastMillis {0} + {} void setup(uint8_t pinSclk, uint8_t pinSdio, uint8_t pinCsb, uint8_t pinFcsb) { mSpi.init(pinSdio, pinSclk, pinCsb, pinFcsb); @@ -182,6 +187,7 @@ class Cmt2300a { if(CMT2300A_MASK_TX_DONE_FLG == mSpi.readReg(CMT2300A_CUS_INT_CLR1)) { if(cmtSwitchStatus(CMT2300A_GO_STBY, CMT2300A_STA_STBY)) { mTxPending = false; + lastMillis = 0; goRx(); } } @@ -226,9 +232,6 @@ class Cmt2300a { } CmtStatus getRx(uint8_t buf[], uint8_t *rxLen, uint8_t maxlen, int8_t *rssi) { - if(mTxPending) - return CmtStatus::ERR_TX_PENDING; - if(0x1b != (mSpi.readReg(CMT2300A_CUS_INT_FLAG) & 0x1b)) return CmtStatus::FIFO_EMPTY; @@ -252,8 +255,19 @@ class Cmt2300a { } CmtStatus tx(uint8_t buf[], uint8_t len) { - if(mTxPending) - return CmtStatus::ERR_TX_PENDING; + if(mTxPending) { + if(CmtTimeoutMs < (millis() - lastMillis)) { + DPRINT(DBG_ERROR, "CMT, last TX timeout: "); + DBGPRINT(String(millis() - lastMillis)); + DBGPRINTLN("ms"); + } + + while(mTxPending && (CmtTimeoutMs > (millis() - lastMillis))) { + vTaskDelay(10); + } + mTxPending = false; + goRx(); + } if(mInRxMode) { mInRxMode = false; @@ -284,6 +298,7 @@ class Cmt2300a { if(!cmtSwitchStatus(CMT2300A_GO_TX, CMT2300A_STA_TX)) return CmtStatus::ERR_SWITCH_STATE; + lastMillis = millis(); // wait for tx done mTxPending = true; @@ -560,6 +575,8 @@ class Cmt2300a { uint8_t mCusIntFlag = 0; uint8_t mRqstCh = 0, mCurCh = 0; RegionCfg mRegionCfg = RegionCfg::EUROPE; + + uint32_t lastMillis; }; #endif /*__CMT2300A_H__*/ diff --git a/src/web/html/update.html b/src/web/html/update.html index 4b670d45..410fe452 100644 --- a/src/web/html/update.html +++ b/src/web/html/update.html @@ -50,7 +50,9 @@ } function hide() { - var bin = document.getElementsByName("update")[0].value.slice(-env.length-4, -4) + let fw = document.getElementsByName("update")[0].value + var bin = fw.slice(-env.length-4, -4) + let ver = fw.split("_")[2].split(".") if (bin !== env) { var html = ml("div", {class: "row"}, [ ml("div", {class: "row my-3"}, "{#WARN_DIFF_ENV}"), @@ -60,8 +62,20 @@ ]) ]) modal("{#UPDATE_MODAL}", html) - } else - start() + } else { + if(ver[1] != "9") + start() + else { + var html = ml("div", {class: "row"}, [ + ml("div", {class: "row my-3"}, "{#ERROR_UPGRADE_NOT_POSSIBLE}"), + ml("div", {class: "row"}, [ + ml("div", {class: "col-6"}, ml("input", {type: "button", class: "btn", value: "{#CANCEL}", onclick: function() { modalClose(); }}, null)) + ]) + ]) + modal("{#UPDATE_MODAL}", html) + } + } + } function start() { diff --git a/src/web/lang.json b/src/web/lang.json index a1f15451..96f60a54 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -1333,6 +1333,11 @@ "en": "your environment may not match the update file!", "de": "Die ausgewählte Firmware passt u.U. nicht zum Chipsatz!" }, + { + "token": "ERROR_UPGRADE_NOT_POSSIBLE", + "en": "OTA updade to version 0.9.x not possible, partition layout changed", + "de": "Aktualisierung auf Version 0.9.x nicht per Update möglich (Partition Layout geändert), bitte per Websinstaller neu installieren" + }, { "token": "CONTIUE", "en": "continue",