diff --git a/.github/workflows/compile_development.yml b/.github/workflows/compile_development.yml index 49d9d713..aa5789c6 100644 --- a/.github/workflows/compile_development.yml +++ b/.github/workflows/compile_development.yml @@ -47,7 +47,7 @@ jobs: run: python convert.py - name: Run PlatformIO - run: pio run -d src --environment esp8266 --environment esp8266-prometheus --environment esp8285 --environment esp32-wroom32 --environment esp32-wroom32-prometheus --environment esp32-wroom32-ethernet --environment opendtufusionv1 + run: pio run -d src --environment esp8266 --environment esp8266-prometheus --environment esp8285 --environment esp32-wroom32 --environment esp32-wroom32-prometheus --environment esp32-wroom32-ethernet --environment esp32-s2-mini --environment opendtufusionv1 - name: Copy boot_app0.bin run: cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin src/.pio/build/opendtufusionv1/ota.bin diff --git a/.github/workflows/compile_release.yml b/.github/workflows/compile_release.yml index 5d7078e2..ce75358e 100644 --- a/.github/workflows/compile_release.yml +++ b/.github/workflows/compile_release.yml @@ -51,7 +51,7 @@ jobs: run: python convert.py - name: Run PlatformIO - run: pio run -d src --environment esp8266 --environment esp8266-prometheus --environment esp8285 --environment esp32-wroom32 --environment esp32-wroom32-prometheus --environment esp32-wroom32-ethernet --environment opendtufusionv1 + run: pio run -d src --environment esp8266 --environment esp8266-prometheus --environment esp8285 --environment esp32-wroom32 --environment esp32-wroom32-prometheus --environment esp32-wroom32-ethernet --environment esp32-s2-mini --environment opendtufusionv1 - name: Copy boot_app0.bin run: cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin src/.pio/build/opendtufusionv1/ota.bin diff --git a/patches/GxEPD2_SW_SPI.patch b/patches/GxEPD2_SW_SPI.patch new file mode 100644 index 00000000..3eb6a32c --- /dev/null +++ b/patches/GxEPD2_SW_SPI.patch @@ -0,0 +1,361 @@ +diff --git a/src/GxEPD2_EPD.cpp b/src/GxEPD2_EPD.cpp +index 1588444..592869b 100644 +--- a/src/GxEPD2_EPD.cpp ++++ b/src/GxEPD2_EPD.cpp +@@ -19,9 +19,9 @@ + + GxEPD2_EPD::GxEPD2_EPD(int16_t cs, int16_t dc, int16_t rst, int16_t busy, int16_t busy_level, uint32_t busy_timeout, + uint16_t w, uint16_t h, GxEPD2::Panel p, bool c, bool pu, bool fpu) : +- WIDTH(w), HEIGHT(h), panel(p), hasColor(c), hasPartialUpdate(pu), hasFastPartialUpdate(fpu), ++ WIDTH(w), HEIGHT(h), panel(p), hasColor(c), hasPartialUpdate(pu), hasFastPartialUpdate(fpu), _sck(-1), _mosi(-1), + _cs(cs), _dc(dc), _rst(rst), _busy(busy), _busy_level(busy_level), _busy_timeout(busy_timeout), _diag_enabled(false), +- _pSPIx(&SPI), _spi_settings(4000000, MSBFIRST, SPI_MODE0) ++ _spi_settings(4000000, MSBFIRST, SPI_MODE0) + { + _initial_write = true; + _initial_refresh = true; +@@ -67,27 +67,30 @@ void GxEPD2_EPD::init(uint32_t serial_diag_bitrate, bool initial, uint16_t reset + { + pinMode(_busy, INPUT); + } +- _pSPIx->begin(); +- if (_busy == MISO) // may be overridden +- { +- pinMode(_busy, INPUT); +- } +- if (_dc == MISO) // may be overridden, TTGO T5 V2.66 +- { +- pinMode(_dc, OUTPUT); +- } +- if (_cs == MISO) // may be overridden ++ if (_sck < 0) SPI.begin(); ++} ++ ++void GxEPD2_EPD::init(int16_t sck, int16_t mosi, uint32_t serial_diag_bitrate, bool initial, uint16_t reset_duration, bool pulldown_rst_mode) ++{ ++ if ((sck >= 0) && (mosi >= 0)) + { +- pinMode(_cs, INPUT); +- } ++ _sck = sck; ++ _mosi = mosi; ++ digitalWrite(_sck, LOW); ++ digitalWrite(_mosi, LOW); ++ pinMode(_sck, OUTPUT); ++ pinMode(_mosi, OUTPUT); ++ } else _sck = -1; ++ init(serial_diag_bitrate, initial, reset_duration, pulldown_rst_mode); + } + + void GxEPD2_EPD::end() + { +- _pSPIx->end(); + if (_cs >= 0) pinMode(_cs, INPUT); + if (_dc >= 0) pinMode(_dc, INPUT); + if (_rst >= 0) pinMode(_rst, INPUT); ++ if (_sck >= 0) pinMode(_sck, INPUT); ++ if (_mosi >= 0) pinMode(_mosi, INPUT); + } + + void GxEPD2_EPD::setBusyCallback(void (*busyCallback)(const void*), const void* busy_callback_parameter) +@@ -96,12 +99,6 @@ void GxEPD2_EPD::setBusyCallback(void (*busyCallback)(const void*), const void* + _busy_callback_parameter = busy_callback_parameter; + } + +-void GxEPD2_EPD::selectSPI(SPIClass& spi, SPISettings spi_settings) +-{ +- _pSPIx = &spi; +- _spi_settings = spi_settings; +-} +- + void GxEPD2_EPD::_reset() + { + if (_rst >= 0) +@@ -168,115 +165,201 @@ void GxEPD2_EPD::_waitWhileBusy(const char* comment, uint16_t busy_time) + + void GxEPD2_EPD::_writeCommand(uint8_t c) + { +- _pSPIx->beginTransaction(_spi_settings); ++ _beginTransaction(_spi_settings); + if (_dc >= 0) digitalWrite(_dc, LOW); + if (_cs >= 0) digitalWrite(_cs, LOW); +- _pSPIx->transfer(c); ++ _spi_write(c); + if (_cs >= 0) digitalWrite(_cs, HIGH); + if (_dc >= 0) digitalWrite(_dc, HIGH); +- _pSPIx->endTransaction(); ++ _endTransaction(); + } + + void GxEPD2_EPD::_writeData(uint8_t d) + { +- _pSPIx->beginTransaction(_spi_settings); ++ _beginTransaction(_spi_settings); + if (_cs >= 0) digitalWrite(_cs, LOW); +- _pSPIx->transfer(d); ++ _spi_write(d); + if (_cs >= 0) digitalWrite(_cs, HIGH); +- _pSPIx->endTransaction(); ++ _endTransaction(); + } + + void GxEPD2_EPD::_writeData(const uint8_t* data, uint16_t n) + { +- _pSPIx->beginTransaction(_spi_settings); ++ _beginTransaction(_spi_settings); + if (_cs >= 0) digitalWrite(_cs, LOW); +- for (uint16_t i = 0; i < n; i++) ++ for (uint8_t i = 0; i < n; i++) + { +- _pSPIx->transfer(*data++); ++ _spi_write(*data++); + } + if (_cs >= 0) digitalWrite(_cs, HIGH); +- _pSPIx->endTransaction(); ++ _endTransaction(); + } + + void GxEPD2_EPD::_writeDataPGM(const uint8_t* data, uint16_t n, int16_t fill_with_zeroes) + { +- _pSPIx->beginTransaction(_spi_settings); ++ _beginTransaction(_spi_settings); + if (_cs >= 0) digitalWrite(_cs, LOW); +- for (uint16_t i = 0; i < n; i++) ++ for (uint8_t i = 0; i < n; i++) + { +- _pSPIx->transfer(pgm_read_byte(&*data++)); ++ _spi_write(pgm_read_byte(&*data++)); + } + while (fill_with_zeroes > 0) + { +- _pSPIx->transfer(0x00); ++ _spi_write(0x00); + fill_with_zeroes--; + } + if (_cs >= 0) digitalWrite(_cs, HIGH); +- _pSPIx->endTransaction(); ++ _endTransaction(); + } + + void GxEPD2_EPD::_writeDataPGM_sCS(const uint8_t* data, uint16_t n, int16_t fill_with_zeroes) + { +- _pSPIx->beginTransaction(_spi_settings); ++ _beginTransaction(_spi_settings); + for (uint8_t i = 0; i < n; i++) + { + if (_cs >= 0) digitalWrite(_cs, LOW); +- _pSPIx->transfer(pgm_read_byte(&*data++)); ++ _spi_write(pgm_read_byte(&*data++)); + if (_cs >= 0) digitalWrite(_cs, HIGH); + } + while (fill_with_zeroes > 0) + { + if (_cs >= 0) digitalWrite(_cs, LOW); +- _pSPIx->transfer(0x00); ++ _spi_write(0x00); + fill_with_zeroes--; + if (_cs >= 0) digitalWrite(_cs, HIGH); + } +- _pSPIx->endTransaction(); ++ _endTransaction(); + } + + void GxEPD2_EPD::_writeCommandData(const uint8_t* pCommandData, uint8_t datalen) + { +- _pSPIx->beginTransaction(_spi_settings); ++ _beginTransaction(_spi_settings); + if (_dc >= 0) digitalWrite(_dc, LOW); + if (_cs >= 0) digitalWrite(_cs, LOW); +- _pSPIx->transfer(*pCommandData++); ++ _spi_write(*pCommandData++); + if (_dc >= 0) digitalWrite(_dc, HIGH); + for (uint8_t i = 0; i < datalen - 1; i++) // sub the command + { +- _pSPIx->transfer(*pCommandData++); ++ _spi_write(*pCommandData++); + } + if (_cs >= 0) digitalWrite(_cs, HIGH); +- _pSPIx->endTransaction(); ++ _endTransaction(); + } + + void GxEPD2_EPD::_writeCommandDataPGM(const uint8_t* pCommandData, uint8_t datalen) + { +- _pSPIx->beginTransaction(_spi_settings); ++ _beginTransaction(_spi_settings); + if (_dc >= 0) digitalWrite(_dc, LOW); + if (_cs >= 0) digitalWrite(_cs, LOW); +- _pSPIx->transfer(pgm_read_byte(&*pCommandData++)); ++ _spi_write(pgm_read_byte(&*pCommandData++)); + if (_dc >= 0) digitalWrite(_dc, HIGH); + for (uint8_t i = 0; i < datalen - 1; i++) // sub the command + { +- _pSPIx->transfer(pgm_read_byte(&*pCommandData++)); ++ _spi_write(pgm_read_byte(&*pCommandData++)); + } + if (_cs >= 0) digitalWrite(_cs, HIGH); +- _pSPIx->endTransaction(); ++ _endTransaction(); + } + + void GxEPD2_EPD::_startTransfer() + { +- _pSPIx->beginTransaction(_spi_settings); ++ _beginTransaction(_spi_settings); + if (_cs >= 0) digitalWrite(_cs, LOW); + } + + void GxEPD2_EPD::_transfer(uint8_t value) + { +- _pSPIx->transfer(value); ++ _spi_write(value); + } + + void GxEPD2_EPD::_endTransfer() + { + if (_cs >= 0) digitalWrite(_cs, HIGH); +- _pSPIx->endTransaction(); ++ _endTransaction(); ++} ++ ++void GxEPD2_EPD::_beginTransaction(const SPISettings& settings) ++{ ++ if (_sck < 0) SPI.beginTransaction(settings); ++} ++ ++void GxEPD2_EPD::_spi_write(uint8_t data) ++{ ++ if (_sck < 0) SPI.transfer(data); ++ else ++ { ++#if defined (ESP8266) ++ yield(); ++#endif ++ for (int i = 0; i < 8; i++) ++ { ++ digitalWrite(_mosi, (data & 0x80) ? HIGH : LOW); ++ data <<= 1; ++ digitalWrite(_sck, HIGH); ++ digitalWrite(_sck, LOW); ++ } ++ } ++} ++ ++void GxEPD2_EPD::_endTransaction() ++{ ++ if (_sck < 0) SPI.endTransaction(); ++} ++ ++uint8_t GxEPD2_EPD::_readData() ++{ ++ uint8_t data = 0; ++ _beginTransaction(_spi_settings); ++ if (_cs >= 0) digitalWrite(_cs, LOW); ++ if (_sck < 0) ++ { ++ data = SPI.transfer(0); ++ } ++ else ++ { ++ pinMode(_mosi, INPUT); ++ for (int i = 0; i < 8; i++) ++ { ++ data <<= 1; ++ digitalWrite(_sck, HIGH); ++ data |= digitalRead(_mosi); ++ digitalWrite(_sck, LOW); ++ } ++ pinMode(_mosi, OUTPUT); ++ } ++ if (_cs >= 0) digitalWrite(_cs, HIGH); ++ _endTransaction(); ++ return data; ++} ++ ++void GxEPD2_EPD::_readData(uint8_t* data, uint16_t n) ++{ ++ _beginTransaction(_spi_settings); ++ if (_cs >= 0) digitalWrite(_cs, LOW); ++ if (_sck < 0) ++ { ++ for (uint8_t i = 0; i < n; i++) ++ { ++ *data++ = SPI.transfer(0); ++ } ++ } ++ else ++ { ++ pinMode(_mosi, INPUT); ++ for (uint8_t i = 0; i < n; i++) ++ { ++ *data = 0; ++ for (int i = 0; i < 8; i++) ++ { ++ *data <<= 1; ++ digitalWrite(_sck, HIGH); ++ *data |= digitalRead(_mosi); ++ digitalWrite(_sck, LOW); ++ } ++ data++; ++ } ++ pinMode(_mosi, OUTPUT); ++ } ++ if (_cs >= 0) digitalWrite(_cs, HIGH); ++ _endTransaction(); + } +diff --git a/src/GxEPD2_EPD.h b/src/GxEPD2_EPD.h +index ef2318f..50aa961 100644 +--- a/src/GxEPD2_EPD.h ++++ b/src/GxEPD2_EPD.h +@@ -8,6 +8,10 @@ + // Version: see library.properties + // + // Library: https://github.com/ZinggJM/GxEPD2 ++// To use SW SPI with GxEPD2: ++// add the special call to the added init method BEFORE the normal init method: ++// display.epd2.init(SW_SCK, SW_MOSI, 115200, true, 20, false); // define or replace SW_SCK, SW_MOSI ++// display.init(115200); // needed to init upper level + + #ifndef _GxEPD2_EPD_H_ + #define _GxEPD2_EPD_H_ +@@ -35,6 +39,7 @@ class GxEPD2_EPD + uint16_t w, uint16_t h, GxEPD2::Panel p, bool c, bool pu, bool fpu); + virtual void init(uint32_t serial_diag_bitrate = 0); // serial_diag_bitrate = 0 : disabled + virtual void init(uint32_t serial_diag_bitrate, bool initial, uint16_t reset_duration = 10, bool pulldown_rst_mode = false); ++ virtual void init(int16_t sck, int16_t mosi, uint32_t serial_diag_bitrate, bool initial, uint16_t reset_duration = 20, bool pulldown_rst_mode = false); + virtual void end(); // release SPI and control pins + // Support for Bitmaps (Sprites) to Controller Buffer and to Screen + virtual void clearScreen(uint8_t value) = 0; // init controller memory and screen (default white) +@@ -97,7 +102,6 @@ class GxEPD2_EPD + { + return (a > b ? a : b); + }; +- void selectSPI(SPIClass& spi, SPISettings spi_settings); + protected: + void _reset(); + void _waitWhileBusy(const char* comment = 0, uint16_t busy_time = 5000); +@@ -111,16 +115,21 @@ class GxEPD2_EPD + void _startTransfer(); + void _transfer(uint8_t value); + void _endTransfer(); ++ void _beginTransaction(const SPISettings& settings); ++ void _spi_write(uint8_t data); ++ void _endTransaction(); ++ public: ++ uint8_t _readData(); ++ void _readData(uint8_t* data, uint16_t n); + protected: +- int16_t _cs, _dc, _rst, _busy, _busy_level; ++ int16_t _cs, _dc, _rst, _busy, _busy_level, _sck, _mosi;; + uint32_t _busy_timeout; + bool _diag_enabled, _pulldown_rst_mode; +- SPIClass* _pSPIx; + SPISettings _spi_settings; + bool _initial_write, _initial_refresh; + bool _power_is_on, _using_partial_mode, _hibernating; + uint16_t _reset_duration; +- void (*_busy_callback)(const void*); ++ void (*_busy_callback)(const void*); + const void* _busy_callback_parameter; + }; + diff --git a/scripts/applyPatches.py b/scripts/applyPatches.py index 7250f5cb..51fbaa40 100644 --- a/scripts/applyPatches.py +++ b/scripts/applyPatches.py @@ -3,7 +3,11 @@ import subprocess Import("env") def applyPatch(libName, patchFile): + # save current wd + start = os.getcwd() + if os.path.exists('.pio/libdeps/' + env['PIOENV'] + '/' + libName) == False: + print("path '" + '.pio/libdeps/' + env['PIOENV'] + '/' + libName + "' does not exist") return os.chdir('.pio/libdeps/' + env['PIOENV'] + '/' + libName) @@ -18,6 +22,11 @@ def applyPatch(libName, patchFile): else: print('applying \'' + patchFile + '\' failed') + os.chdir(start) + # list of patches to apply (relative to /src) applyPatch("ESP Async WebServer", "../patches/AsyncWeb_Prometheus.patch") + +if env['PIOENV'] == "opendtufusionv1": + applyPatch("GxEPD2", "../patches/GxEPD2_SW_SPI.patch") diff --git a/scripts/getVersion.py b/scripts/getVersion.py index 9e6c90b7..f0000758 100644 --- a/scripts/getVersion.py +++ b/scripts/getVersion.py @@ -84,6 +84,11 @@ def readVersion(path, infile): dst = path + "firmware/" + versionout os.rename(src, dst) + versionout = version[:-1] + "_" + sha + "_esp32s2-mini.bin" + src = path + ".pio/build/esp32-s2-mini/firmware.bin" + dst = path + "firmware/" + versionout + os.rename(src, dst) + versionout = version[:-1] + "_" + sha + "_esp32s3.bin" src = path + ".pio/build/opendtufusionv1/firmware.bin" dst = path + "firmware/s3/" + versionout diff --git a/src/CHANGES.md b/src/CHANGES.md index a4a234ee..d611f052 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,15 @@ # Development Changes +## 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 Changlog 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 @@ -22,5 +32,665 @@ * fix alarm time on WebGui #1099 * added RSSI info for HMS and HMT inverters (MqTT + REST API) -## 0.7.36 -* last Release +# 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 chrashes +* 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 / repsonse 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 serveral 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 effiency 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 appling 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 completly 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 seperator 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 existance +* **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 configureable 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 configureable (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 Improvments +* 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 seperate 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 +* reenabled 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`, checkes 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 Expeptions 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 transfered 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` +* remvoed `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 mutliple 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 +* incresed 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 inverval 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 + diff --git a/src/app.cpp b/src/app.cpp index 4fd1a6a6..13b44fe4 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -225,8 +225,8 @@ void app::onNetwork(bool gotIp) { #if !defined(ETHERNET) if (WIFI_AP == WiFi.getMode()) { mMqttEnabled = false; - everySec(std::bind(&ahoywifi::tickWifiLoop, &mWifi), "wifiL"); } + everySec(std::bind(&ahoywifi::tickWifiLoop, &mWifi), "wifiL"); #endif /* !defined(ETHERNET) */ mInnerLoopCb = [this]() { this->loopStandard(); }; } else { diff --git a/src/defines.h b/src/defines.h index a5df274b..25779f7b 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 7 -#define VERSION_PATCH 41 +#define VERSION_PATCH 42 //------------------------------------- typedef struct { diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index 789b80d5..cd9018b8 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -239,6 +239,16 @@ class HmRadio { return mNrf24.isPVariant(); } + /* Test whether a signal (carrier or otherwise) greater than or equal to -64dBm is present on the channel. + Valid only on nRF24L01P (+) hardware. On nRF24L01, use testCarrier(). + Useful to check for interference on the current channel and channel hopping strategies. + bool goodSignal = radio.testRPD();*/ + bool goodSignal(void) { + bool goodSignal = mNrf24.testRPD(); + mNrf24.read(0,0); + return goodSignal; + } + std::queue mBufCtrl; uint32_t mSendCnt; diff --git a/src/platformio.ini b/src/platformio.ini index 50be00c4..1e61dda1 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -31,7 +31,7 @@ lib_deps = bblanchon/ArduinoJson @ ^6.21.3 https://github.com/JChristensen/Timezone @ ^1.2.4 olikraus/U8g2 @ ^2.34.17 - zinggjm/GxEPD2 @ ^1.5.2 + https://github.com/zinggjm/GxEPD2 @ ^1.5.2 build_flags = -std=c++17 -std=gnu++17 @@ -71,16 +71,18 @@ monitor_filters = esp8266_exception_decoder [env:esp32-wroom32] -platform = espressif32@6.1.0 +platform = espressif32@6.3.2 board = lolin_d32 build_flags = ${env.build_flags} + -DUSE_HSPI_FOR_EPD monitor_filters = esp32_exception_decoder [env:esp32-wroom32-prometheus] -platform = espressif32@6.1.0 +platform = espressif32@6.3.2 board = lolin_d32 build_flags = ${env.build_flags} + -DUSE_HSPI_FOR_EPD -DENABLE_PROMETHEUS_EP monitor_filters = esp32_exception_decoder @@ -101,13 +103,28 @@ lib_deps = build_flags = ${env.build_flags} -D ETHERNET -DRELEASE + -DUSE_HSPI_FOR_EPD -DLOG_LOCAL_LEVEL=ESP_LOG_INFO -DDEBUG_LEVEL=DBG_INFO monitor_filters = esp32_exception_decoder +[env:esp32-s2-mini] +platform = espressif32@6.3.2 +board = lolin_s2_mini +build_flags = ${env.build_flags} + -DUSE_HSPI_FOR_EPD + -DDEF_NRF_CS_PIN=12 + -DDEF_NRF_CE_PIN=3 + -DDEF_NRF_IRQ_PIN=5 + -DDEF_NRF_MISO_PIN=9 + -DDEF_NRF_MOSI_PIN=11 + -DDEF_NRF_SCLK_PIN=7 +monitor_filters = + esp32_exception_decoder + [env:opendtufusionv1] -platform = espressif32@6.1.0 +platform = espressif32@6.3.2 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin debug_tool = esp-builtin @@ -122,8 +139,8 @@ build_flags = ${env.build_flags} -DDEF_CMT_CSB=4 -DDEF_CMT_FCSB=21 -DDEF_CMT_IRQ=8 - -DDEF_LED0=17 - -DDEF_LED1=18 + -DDEF_LED0=18 + -DDEF_LED1=17 -DLED_ACTIVE_HIGH monitor_filters = esp32_exception_decoder diff --git a/src/plugins/Display/Display_ePaper.cpp b/src/plugins/Display/Display_ePaper.cpp index f4b16ff7..8a72a485 100644 --- a/src/plugins/Display/Display_ePaper.cpp +++ b/src/plugins/Display/Display_ePaper.cpp @@ -29,12 +29,14 @@ void DisplayEPaper::init(uint8_t type, uint8_t _CS, uint8_t _DC, uint8_t _RST, u if (type == 10) { Serial.begin(115200); _display = new GxEPD2_BW(GxEPD2_150_BN(_CS, _DC, _RST, _BUSY)); - hspi.begin(_SCK, _BUSY, _MOSI, _CS); #if defined(ESP32) && defined(USE_HSPI_FOR_EPD) + hspi.begin(_SCK, _BUSY, _MOSI, _CS); _display->epd2.selectSPI(hspi, SPISettings(spiClk, MSBFIRST, SPI_MODE0)); +#elif defined(ESP32) + _display->epd2.init(_SCK, _MOSI, 115200, true, 20, false); #endif - _display->init(115200, true, 2, false); + _display->init(115200, true, 20, false); _display->setRotation(mDisplayRotation); _display->setFullWindow(); diff --git a/src/plugins/Display/Display_ePaper.h b/src/plugins/Display/Display_ePaper.h index ad422b26..d9b24e34 100644 --- a/src/plugins/Display/Display_ePaper.h +++ b/src/plugins/Display/Display_ePaper.h @@ -3,9 +3,6 @@ #if defined(ESP32) -// uncomment next line to use HSPI for EPD (and VSPI for SD), e.g. with Waveshare ESP32 Driver Board -#define USE_HSPI_FOR_EPD - /// uncomment next line to use class GFX of library GFX_Root instead of Adafruit_GFX, to use less code and ram // #include // base class GxEPD2_GFX can be used to pass references or pointers to the display instance as parameter, uses ~1.2k more code diff --git a/src/publisher/pubMqttIvData.h b/src/publisher/pubMqttIvData.h index 22a2626d..9393733e 100644 --- a/src/publisher/pubMqttIvData.h +++ b/src/publisher/pubMqttIvData.h @@ -102,14 +102,16 @@ class PubMqttIvData { mPos = 0; if(found) { record_t<> *rec = mIv->getRecordStruct(mCmd); - snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/last_success", mIv->config->name); - snprintf(mVal, 40, "%d", mIv->getLastTs(rec)); - mPublish(mSubTopic, mVal, true, QOS_0); - - if((mIv->ivGen == IV_HMS) || (mIv->ivGen == IV_HMT)) { - snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/ch0/rssi", mIv->config->name); - snprintf(mVal, 40, "%d", mIv->rssi); - mPublish(mSubTopic, mVal, false, QOS_0); + if(mIv->getLastTs(rec) != mIvLastRTRpub[mIv->id]) { + snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/last_success", mIv->config->name); + snprintf(mVal, 40, "%d", mIv->getLastTs(rec)); + mPublish(mSubTopic, mVal, true, QOS_0); + + if((mIv->ivGen == IV_HMS) || (mIv->ivGen == IV_HMT)) { + snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/ch0/rssi", mIv->config->name); + snprintf(mVal, 40, "%d", mIv->rssi); + mPublish(mSubTopic, mVal, false, QOS_0); + } } mIv->isProducing(); // recalculate status diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 270cb372..cb147a07 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -502,6 +502,7 @@ class RestApi { obj[F("isconnected")] = mRadio->isChipConnected(); obj[F("DataRate")] = mRadio->getDataRate(); obj[F("isPVariant")] = mRadio->isPVariant(); + obj[F("goodSignal")] = mRadio->goodSignal(); obj[F("en")] = (bool) mConfig->nrf.enabled; } @@ -570,6 +571,8 @@ class RestApi { warn.add(F("reboot your ESP to apply all your configuration changes")); if(0 == mApp->getTimestamp()) warn.add(F("time not set. No communication to inverter possible")); + + /*if(0 == mSys->getNumInverters()) warn.add(F("no inverter configured"));*/ diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 94c3d461..3f8a6c64 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -778,10 +778,10 @@ ml("div", {class: "col-12 col-sm-3 my-2"}, "Power Level"), ml("div", {class: "col-12 col-sm-9"}, sel("rf24Power", [ - [0, "MIN"], + [0, "MIN (recommended)"], [1, "LOW"], [2, "HIGH"], - [3, "MAX"] + [3, "MAX (experimental)"] ], obj["power_level"]) ) ]) diff --git a/src/web/html/system.html b/src/web/html/system.html index 0f1df319..295f0a55 100644 --- a/src/web/html/system.html +++ b/src/web/html/system.html @@ -50,7 +50,7 @@ } function parseRadio(obj, stat) { - const pa = ["MIN", "LOW", "HIGH", "MAX"]; + const pa = ["MIN (recommended)", "LOW", "HIGH", "MAX"]; const datarate = ["1 MBps", "2 MBps", "250 kbps"]; var main = document.getElementById("radio"); @@ -60,7 +60,10 @@ h.appendChild(r); main.appendChild(h); - main.appendChild(genTabRow("nrf24l01" + (obj["isPVariant"] ? "+ " : ""), (obj["isconnected"] ? "is connected " : "is not connected "))); + main.append( + genTabRow("nrf24l01" + (obj["isPVariant"] ? "+ " : ""), (obj["isconnected"] ? "is connected " : "is not connected ")), + genTabRow("NRF Signal: ", (obj["goodSignal"] ? "Strong signal > 64dBm" : "Weak signal < 64dBm")) + ); if(obj["isconnected"]) { main.appendChild(genTabRow("Datarate", datarate[obj["DataRate"]])); diff --git a/src/wifi/ahoywifi.cpp b/src/wifi/ahoywifi.cpp index 863ca88f..8632de49 100644 --- a/src/wifi/ahoywifi.cpp +++ b/src/wifi/ahoywifi.cpp @@ -29,7 +29,8 @@ void ahoywifi::setup(settings_t *config, uint32_t *utcTimestamp, appWifiCb cb) { mUtcTimestamp = utcTimestamp; mAppWifiCb = cb; - mStaConn = DISCONNECTED; + mGotDisconnect = false; + mStaConn = DISCONNECTED; mCnt = 0; mScanActive = false; mScanCnt = 0; @@ -69,12 +70,33 @@ void ahoywifi::setupWifi(bool startAP = false) { } -//----------------------------------------------------------------------------- void ahoywifi::tickWifiLoop() { + static const uint8_t TIMEOUT = 20; + static const uint8_t SCAN_TIMEOUT = 10; #if !defined(AP_ONLY) - if(mStaConn != GOT_IP) { - if (WiFi.softAPgetStationNum() > 0) { // do not reconnect if any AP connection exists - if(mStaConn != IN_AP_MODE) { + + mCnt++; + + switch (mStaConn) { + case IN_STA_MODE: + // Nothing to do + if (mGotDisconnect) { + mStaConn = RESET; + } + return; + case IN_AP_MODE: + if (WiFi.softAPgetStationNum() == 0) { + mCnt = 0; + mDns.stop(); + WiFi.mode(WIFI_AP_STA); + mStaConn = DISCONNECTED; + } else { + mDns.processNextRequest(); + return; + } + break; + case DISCONNECTED: + if (WiFi.softAPgetStationNum() > 0) { mStaConn = IN_AP_MODE; // first time switch to AP Mode if (mScanActive) { @@ -86,56 +108,45 @@ void ahoywifi::tickWifiLoop() { WiFi.mode(WIFI_AP); mDns.start(53, "*", mApIp); mAppWifiCb(true); + mDns.processNextRequest(); + return; + } else if (!mScanActive) { + DBGPRINT(F("scanning APs with SSID ")); + DBGPRINTLN(String(mConfig->sys.stationSsid)); + mScanCnt = 0; + mCnt = 0; + mScanActive = true; +#if defined(ESP8266) + WiFi.scanNetworks(true, true, 0U, ([this]() { + if (mConfig->sys.isHidden) + return (uint8_t*)NULL; + return (uint8_t*)(mConfig->sys.stationSsid); + })()); +#else + WiFi.scanNetworks(true, true, false, 300U, 0U, ([this]() { + if (mConfig->sys.isHidden) + return (char*)NULL; + return (mConfig->sys.stationSsid); + })()); +#endif + return; + } else if(getBSSIDs()) { + // Scan ready + mStaConn = SCAN_READY; + } else { + // In case of a timeout, what do we do? + // For now we start scanning again as the original code did. + // Would be better to into PA mode + + if (isTimeout(SCAN_TIMEOUT)) { + WiFi.scanDelete(); + mScanActive = false; + } } - mDns.processNextRequest(); - return; - } - else if(mStaConn == IN_AP_MODE) { - mCnt = 0; - mDns.stop(); - WiFi.mode(WIFI_AP_STA); - mStaConn = DISCONNECTED; - } - mCnt++; - - uint8_t timeout = (mStaConn == DISCONNECTED) ? 10 : 20; // seconds - if (mStaConn == CONNECTED) // connected but no ip - timeout = 20; - - if(!mScanActive && mBSSIDList.empty() && (mStaConn == DISCONNECTED)) { // start scanning APs with the given SSID - DBGPRINT(F("scanning APs with SSID ")); - DBGPRINTLN(String(mConfig->sys.stationSsid)); - mScanCnt = 0; - mScanActive = true; - #if defined(ESP8266) - WiFi.scanNetworks(true, true, 0U, ([this] () { - if(mConfig->sys.isHidden) - return (uint8_t *)NULL; - return (uint8_t *)(mConfig->sys.stationSsid); - })()); - #else - WiFi.scanNetworks(true, true, false, 300U, 0U, ([this] () { - if(mConfig->sys.isHidden) - return (char*)NULL; - return (mConfig->sys.stationSsid); - })()); - #endif - return; - } - DBGPRINT(F("reconnect in ")); - DBGPRINT(String(timeout-mCnt)); - DBGPRINTLN(F(" seconds")); - if(mScanActive) { - getBSSIDs(); - if((!mScanActive) && (!mBSSIDList.empty())) // scan completed - if ((mCnt % timeout) < timeout - 2) - mCnt = timeout - 2; - } - if((mCnt % timeout) == 0) { // try to reconnect after x sec without connection - mStaConn = CONNECTING; - WiFi.disconnect(); - - if(mBSSIDList.size() > 0) { // get first BSSID in list + break; + case SCAN_READY: + mStaConn = CONNECTING; + mCnt = 0; DBGPRINT(F("try to connect to AP with BSSID:")); uint8_t bssid[6]; for (int j = 0; j < 6; j++) { @@ -144,17 +155,47 @@ void ahoywifi::tickWifiLoop() { DBGPRINT(" " + String(bssid[j], HEX)); } DBGPRINTLN(""); + mGotDisconnect = false; WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd, 0, &bssid[0]); - } - else - mStaConn = DISCONNECTED; - mCnt = 0; - } + break; + case CONNECTING: + if (isTimeout(TIMEOUT)) { + WiFi.disconnect(); + mStaConn = mBSSIDList.empty() ? DISCONNECTED : SCAN_READY; + } + break; + case CONNECTED: + // Connection but no IP yet + if (isTimeout(TIMEOUT) || mGotDisconnect) { + mStaConn = RESET; + } + break; + case GOT_IP: + welcome(WiFi.localIP().toString(), F(" (Station)")); + WiFi.softAPdisconnect(); + WiFi.mode(WIFI_STA); + DBGPRINTLN(F("[WiFi] AP disabled")); + delay(100); + mAppWifiCb(true); + mGotDisconnect = false; + mStaConn = IN_STA_MODE; + break; + case RESET: + mGotDisconnect = false; + mStaConn = DISCONNECTED; + mCnt = 5; // try to reconnect in 5 sec + setupWifi(); // reconnect with AP / Station setup + mAppWifiCb(false); + DPRINTLN(DBG_INFO, "[WiFi] Connection Lost"); + break; + default: + DBGPRINTLN(F("Unhandled status")); + break; } - #endif -} +#endif +} //----------------------------------------------------------------------------- void ahoywifi::setupAp(void) { @@ -213,7 +254,7 @@ void ahoywifi::setupStation(void) { //----------------------------------------------------------------------------- bool ahoywifi::getNtpTime(void) { - if(GOT_IP != mStaConn) + if(IN_STA_MODE != mStaConn) return false; IPAddress timeServer; @@ -314,11 +355,12 @@ bool ahoywifi::getAvailNetworks(JsonObject obj) { } //----------------------------------------------------------------------------- -void ahoywifi::getBSSIDs() { +bool ahoywifi::getBSSIDs() { + bool result = false; int n = WiFi.scanComplete(); if (n < 0) { if (++mScanCnt < 20) - return; + return false; } if(n > 0) { mBSSIDList.clear(); @@ -333,9 +375,11 @@ void ahoywifi::getBSSIDs() { } DBGPRINTLN(""); } + result = true; } mScanActive = false; WiFi.scanDelete(); + return result; } //----------------------------------------------------------------------------- @@ -346,32 +390,17 @@ void ahoywifi::connectionEvent(WiFiStatus_t status) { case CONNECTED: if(mStaConn != CONNECTED) { mStaConn = CONNECTED; + mGotDisconnect = false; DBGPRINTLN(F("\n[WiFi] Connected")); } break; case GOT_IP: mStaConn = GOT_IP; - if (mScanActive) { // maybe another scan has started - WiFi.scanDelete(); - mScanActive = false; - } - welcome(WiFi.localIP().toString(), F(" (Station)")); - WiFi.softAPdisconnect(); - WiFi.mode(WIFI_STA); - DBGPRINTLN(F("[WiFi] AP disabled")); - delay(100); - mAppWifiCb(true); break; case DISCONNECTED: - if(mStaConn != CONNECTING) { - mStaConn = DISCONNECTED; - mCnt = 5; // try to reconnect in 5 sec - setupWifi(); // reconnect with AP / Station setup - mAppWifiCb(false); - DPRINTLN(DBG_INFO, "[WiFi] Connection Lost"); - } + mGotDisconnect = true; break; default: diff --git a/src/wifi/ahoywifi.h b/src/wifi/ahoywifi.h index ef4f2b71..e44d6858 100644 --- a/src/wifi/ahoywifi.h +++ b/src/wifi/ahoywifi.h @@ -32,10 +32,13 @@ class ahoywifi { private: typedef enum WiFiStatus { DISCONNECTED = 0, + SCAN_READY, CONNECTING, CONNECTED, IN_AP_MODE, - GOT_IP + GOT_IP, + IN_STA_MODE, + RESET } WiFiStatus_t; void setupWifi(bool startAP); @@ -43,9 +46,11 @@ class ahoywifi { void setupStation(void); void sendNTPpacket(IPAddress& address); void sortRSSI(int *sort, int n); - void getBSSIDs(void); + bool getBSSIDs(void); void connectionEvent(WiFiStatus_t status); - #if defined(ESP8266) + bool isTimeout(uint8_t timeout) { return (mCnt % timeout) == 0; } + +#if defined(ESP8266) void onConnect(const WiFiEventStationModeConnected& event); void onGotIP(const WiFiEventStationModeGotIP& event); void onDisconnect(const WiFiEventStationModeDisconnected& event); @@ -71,6 +76,7 @@ class ahoywifi { uint8_t mScanCnt; bool mScanActive; + bool mGotDisconnect; std::list mBSSIDList; };