diff --git a/patches/RF24.patch b/patches/RF24.patch deleted file mode 100644 index 63db8823..00000000 --- a/patches/RF24.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/RF24.cpp b/RF24.cpp -index 9e5b4a8..a4de63c 100644 ---- a/RF24.cpp -+++ b/RF24.cpp -@@ -1871,6 +1871,11 @@ uint8_t RF24::getARC(void) - return read_register(OBSERVE_TX) & 0x0F; - } - -+uint8_t RF24::getPLOS(void) -+{ -+ return read_register(OBSERVE_TX) & 0x0F; -+} -+ - /****************************************************************************/ - - bool RF24::setDataRate(rf24_datarate_e speed) -diff --git a/RF24.h b/RF24.h -index dbd32ae..a3d6b52 100644 ---- a/RF24.h -+++ b/RF24.h -@@ -1644,6 +1644,7 @@ public: - * @return Returns values from 0 to 15. - */ - uint8_t getARC(void); -+ uint8_t getPLOS(void); - - /** - * Set the transmission @ref Datarate -@@ -2415,4 +2416,4 @@ private: - * Use `ctrl+c` to quit at any time. - */ - --#endif // __RF24_H__ -\ No newline at end of file -+#endif // __RF24_H__ diff --git a/scripts/applyPatches.py b/scripts/applyPatches.py index 3289badb..147fb0f3 100644 --- a/scripts/applyPatches.py +++ b/scripts/applyPatches.py @@ -12,11 +12,11 @@ def applyPatch(libName, patchFile): os.chdir('.pio/libdeps/' + env['PIOENV'] + '/' + libName) - process = subprocess.run(['git', 'apply', '--reverse', '--check', '../../../../' + patchFile], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + process = subprocess.run(['git', 'apply', '--ignore-whitespace', '--reverse', '--check', '../../../../' + patchFile], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) if (process.returncode == 0): print('\'' + patchFile + '\' already applied') else: - process = subprocess.run(['git', 'apply', '../../../../' + patchFile]) + process = subprocess.run(['git', 'apply', '--ignore-whitespace', '../../../../' + patchFile]) if (process.returncode == 0): print('\'' + patchFile + '\' applied') else: @@ -32,5 +32,3 @@ if env['PIOENV'][:22] != "opendtufusion-ethernet": if env['PIOENV'][:13] == "opendtufusion": applyPatch("GxEPD2", "../patches/GxEPD2_SW_SPI.patch") applyPatch("RF24", "../patches/RF24_Hal.patch") -else: - applyPatch("RF24", "../patches/RF24.patch") diff --git a/src/CHANGES.md b/src/CHANGES.md index a4942d55..f690b192 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,24 @@ # Development Changes +## 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 @@ -160,7 +179,7 @@ ## 0.8.37 - 2023-12-30 * added grid profiles -* format version of grid profile +* format version of grid profile # RELEASE 0.8.36 - 2023-12-30 diff --git a/src/app.cpp b/src/app.cpp index 9f569259..a14a8811 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -47,7 +47,7 @@ void app::setup() { } #if defined(ESP32) if(mConfig->cmt.enabled) { - mCmtRadio.setup(&mConfig->serial.debug, &mConfig->serial.privacyLog, &mConfig->serial.printWholeTrace, mConfig->cmt.pinSclk, mConfig->cmt.pinSdio, mConfig->cmt.pinCsb, mConfig->cmt.pinFcsb); + mCmtRadio.setup(&mConfig->serial.debug, &mConfig->serial.privacyLog, &mConfig->serial.printWholeTrace, mConfig->cmt.pinSclk, mConfig->cmt.pinSdio, mConfig->cmt.pinCsb, mConfig->cmt.pinFcsb, mConfig->sys.region); } #endif #ifdef ETHERNET diff --git a/src/app.h b/src/app.h index 851ad3c8..ccf46297 100644 --- a/src/app.h +++ b/src/app.h @@ -182,6 +182,10 @@ class app : public IApp, public ah::Scheduler { return mWifi.getStationIp(); } + bool getWasInCh12to14(void) const { + return mWifi.getWasInCh12to14(); + } + #endif /* !defined(ETHERNET) */ void setRebootFlag() { diff --git a/src/appInterface.h b/src/appInterface.h index ad38f756..f98fb0cb 100644 --- a/src/appInterface.h +++ b/src/appInterface.h @@ -35,6 +35,7 @@ class IApp { virtual void setupStation(void) = 0; virtual void setStopApAllowedMode(bool allowed) = 0; virtual String getStationIp(void) = 0; + virtual bool getWasInCh12to14(void) const = 0; #endif /* defined(ETHERNET) */ virtual uint32_t getUptime() = 0; diff --git a/src/config/settings.h b/src/config/settings.h index d8c93b10..e074d5b1 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -30,7 +30,7 @@ * https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html#flash-layout * */ -#define CONFIG_VERSION 9 +#define CONFIG_VERSION 10 #define PROT_MASK_INDEX 0x0001 @@ -68,6 +68,8 @@ typedef struct { uint16_t protectionMask; bool darkMode; bool schedReboot; + uint8_t region; + int8_t timezone; #if !defined(ETHERNET) // wifi @@ -395,6 +397,8 @@ class settings { #endif /* !defined(ETHERNET) */ snprintf(mCfg.sys.deviceName, DEVNAME_LEN, DEF_DEVICE_NAME); + mCfg.sys.region = 0; // Europe + mCfg.sys.timezone = 1; mCfg.nrf.pinCs = DEF_NRF_CS_PIN; mCfg.nrf.pinCe = DEF_NRF_CE_PIN; @@ -512,6 +516,10 @@ class settings { if(mCfg.configVersion < 9) { mCfg.inst.gapMs = 1; } + if(mCfg.configVersion < 10) { + mCfg.sys.region = 0; // Europe + mCfg.sys.timezone = 1; + } } } @@ -537,6 +545,8 @@ class settings { obj[F("prot_mask")] = mCfg.sys.protectionMask; obj[F("dark")] = mCfg.sys.darkMode; obj[F("reb")] = (bool) mCfg.sys.schedReboot; + obj[F("region")] = mCfg.sys.region; + obj[F("timezone")] = mCfg.sys.timezone; ah::ip2Char(mCfg.sys.ip.ip, buf); obj[F("ip")] = String(buf); ah::ip2Char(mCfg.sys.ip.mask, buf); obj[F("mask")] = String(buf); ah::ip2Char(mCfg.sys.ip.dns1, buf); obj[F("dns1")] = String(buf); @@ -554,6 +564,8 @@ class settings { getVal(obj, F("prot_mask"), &mCfg.sys.protectionMask); getVal(obj, F("dark"), &mCfg.sys.darkMode); getVal(obj, F("reb"), &mCfg.sys.schedReboot); + getVal(obj, F("region"), &mCfg.sys.region); + getVal(obj, F("timezone"), &mCfg.sys.timezone); if(obj.containsKey(F("ip"))) ah::ip2Arr(mCfg.sys.ip.ip, obj[F("ip")].as()); if(obj.containsKey(F("mask"))) ah::ip2Arr(mCfg.sys.ip.mask, obj[F("mask")].as()); if(obj.containsKey(F("dns1"))) ah::ip2Arr(mCfg.sys.ip.dns1, obj[F("dns1")].as()); diff --git a/src/defines.h b/src/defines.h index b8ddace9..442008ff 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 64 +#define VERSION_PATCH 68 //------------------------------------- typedef struct { diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 8887a4a2..5725f2ec 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -136,7 +136,8 @@ class Communication : public CommQueue<> { DBGPRINT(F("request timeout: ")); DBGPRINT(String(q->iv->radio->mRadioWaitTime.getRunTime())); DBGPRINTLN(F("ms")); - } + } + if(!q->iv->mGotFragment) { if(INV_RADIO_TYPE_CMT == q->iv->ivRadioType) { #if defined(ESP32) diff --git a/src/hm/HeuristicInv.h b/src/hm/HeuristicInv.h index 505562e3..89099ca8 100644 --- a/src/hm/HeuristicInv.h +++ b/src/hm/HeuristicInv.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 //----------------------------------------------------------------------------- diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index a88e43c6..d1dd42d5 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -77,7 +77,7 @@ class HmRadio : public Radio { #else mNrf24->begin(mSpi.get(), ce, cs); #endif - mNrf24->setRetries(3, 15); // wait 3*250 = 750us, 16 * 250us -> 4000us = 4ms + mNrf24->setRetries(3, 9); // wait 3*250 = 750us, 16 * 250us -> 4000us = 4ms mNrf24->setDataRate(RF24_250KBPS); //mNrf24->setAutoAck(true); // enabled by default @@ -176,6 +176,7 @@ class HmRadio : public Radio { rx_ready = false; mRadioWaitTime.startTimeMonitor(DURATION_PAUSE_LASTFR); // let the inverter first end his transmissions mNrf24->stopListening(); + return false; } else { innerLoopTimeout = DURATION_LISTEN_MIN; mTimeslotStart = millis(); @@ -187,6 +188,7 @@ class HmRadio : public Radio { } else mRxChIdx = tempRxChIdx; } + return true; } rx_ready = false; // reset return mNRFisInRX; diff --git a/src/hm/radio.h b/src/hm/radio.h index 9702c304..7bbb42bc 100644 --- a/src/hm/radio.h +++ b/src/hm/radio.h @@ -127,7 +127,8 @@ class Radio { mDtuSn |= (t << i); } mDtuSn |= 0x80000000; // the first digit is an 8 for DTU production year 2022, the rest is filled with the ESP chipID in decimal - } + } + uint32_t mDtuSn; diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index 07afd4b8..ae9fd369 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -76,7 +76,7 @@ class CmtRadio : public Radio { return true; } -uint16_t getBaseFreqMhz(void) override { + uint16_t getBaseFreqMhz(void) override { return mCmt.getBaseFreqMhz(); } diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 98e0afd2..ccdc8747 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -268,6 +268,8 @@ class RestApi { obj[F("menu_protEn")] = (bool) (strlen(mConfig->sys.adminPwd) > 0); obj[F("cst_lnk")] = String(mConfig->plugin.customLink); obj[F("cst_lnk_txt")] = String(mConfig->plugin.customLinkText); + obj[F("region")] = mConfig->sys.region; + obj[F("timezone")] = mConfig->sys.timezone; #if defined(ESP32) obj[F("esp_type")] = F("ESP32"); @@ -651,6 +653,9 @@ class RestApi { obj[F("fcsb")] = mConfig->cmt.pinFcsb; obj[F("gpio3")] = mConfig->cmt.pinIrq; obj[F("en")] = (bool) mConfig->cmt.enabled; + std::pair range = mRadioCmt->getFreqRangeMhz(); + obj[F("freq_min")] = range.first; + obj[F("freq_max")] = range.second; } void getRadioCmtInfo(JsonObject obj) { @@ -749,6 +754,12 @@ class RestApi { warn.add(F(REBOOT_ESP_APPLY_CHANGES)); if(0 == mApp->getTimestamp()) warn.add(F(TIME_NOT_SET)); + #if !defined(ETHERNET) + #if !defined(ESP32) + if(mApp->getWasInCh12to14()) + warn.add(F(WAS_IN_CH_12_TO_14)); + #endif + #endif } void getSetup(AsyncWebServerRequest *request, JsonObject obj) { diff --git a/src/web/html/setup.html b/src/web/html/setup.html index b4c72069..d4f245ef 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -26,6 +26,14 @@
{#DARK_MODE_NOTE}
+
+
{#REGION}
+
+
+
+
{#TIMEZONE}
+
+
{#CUSTOM_LINK}
@@ -499,9 +507,6 @@ for(var i = 0; i < 31; i++) { esp32cmtPa.push([i, String(i-10) + " dBm"]); } - for(var i = 12; i < 41; i++) { - esp32cmtFreq.push([i, freqFmt.format(860 + i*0.25) + " MHz"]); - } /*ENDIF_ESP32*/ var led_high_active = [ [0, "{#PIN_LOW_ACTIVE}"], @@ -650,6 +655,14 @@ el.push(mlCb("protMask" + i, a[i], chk)) } d.append(...el); + + var tz = [] + for(i = 0; i < 24; i += 0.5) + tz.push([i, ((i-12 > 0) ? "+" : "") + String(i-12)]); + document.getElementById("timezone").append(sel("timezone", tz, obj.timezone + 12)) + var region = [[0, "Europe (860 - 870 MHz)"], [1, "USA, Indonesia (905 - 925 MHz)"], [2, "Brazil (915 - 928 MHz)"]] + document.getElementById("region").append(sel("region", region, obj.region)) + } function parseGeneric(obj) { @@ -1019,6 +1032,12 @@ ]) ); } + + var i = 0 + while(obj.freq_max >= (obj.freq_min + i * 0.25)) { + esp32cmtFreq.push([i, freqFmt.format(obj.freq_min + i * 0.25) + " MHz"]) + i++ + } } /*ENDIF_ESP32*/ diff --git a/src/web/lang.h b/src/web/lang.h index 546399aa..e55493eb 100644 --- a/src/web/lang.h +++ b/src/web/lang.h @@ -18,6 +18,12 @@ #define TIME_NOT_SET "time not set. No communication to inverter possible" #endif +#ifdef LANG_DE + #define WAS_IN_CH_12_TO_14 "Der ESP war in WLAN Kanal 12 bis 14, was uU. zu Abstürzen führt" +#else /*LANG_EN*/ + #define WAS_IN_CH_12_TO_14 "Your ESP was in wifi channel 12 to 14. It may cause reboots of your AhoyDTU" +#endif + #ifdef LANG_DE #define INV_INDEX_INVALID "Wechselrichterindex ungültig; " #else /*LANG_EN*/ diff --git a/src/web/lang.json b/src/web/lang.json index 1eece937..d083ddff 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -148,6 +148,16 @@ "en": "(empty browser cache or use CTRL + F5 after reboot to apply this setting)", "de": "(der Browser-Cache muss geleert oder STRG + F5 gedrückt werden, um diese Einstellung zu aktivieren)" }, + { + "token": "REGION", + "en": "Region", + "de": "Region" + }, + { + "token": "TIMEZONE", + "en": "Timezone", + "de": "Zeitzone" + }, { "token": "CUSTOM_LINK", "en": "Custom link (leave empty to hide element in navigation)", @@ -670,7 +680,7 @@ }, { "token": "INV_DELETE_SURE", - "en": "do you realy want to delete inverter?", + "en": "do you really want to delete inverter?", "de": "Willst du den Wechselrichter wirklich löschen?" }, { @@ -1070,7 +1080,7 @@ }, { "token": "WARN_DIFF_ENV", - "en": "your environment does not match the update file!", + "en": "your environment may not match the update file!", "de": "Die ausgewählte Firmware passt u.U. nicht zum Chipsatz!" }, { diff --git a/src/web/web.h b/src/web/web.h index ba4540b1..6de9c877 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -481,7 +481,8 @@ class Web { request->arg("device").toCharArray(mConfig->sys.deviceName, DEVNAME_LEN); mConfig->sys.darkMode = (request->arg("darkMode") == "on"); mConfig->sys.schedReboot = (request->arg("schedReboot") == "on"); - + mConfig->sys.region = (request->arg("region")).toInt(); + mConfig->sys.timezone = (request->arg("timezone")).toInt() - 12; if (request->arg("cstLnk") != "") { request->arg("cstLnk").toCharArray(mConfig->plugin.customLink, MAX_CUSTOM_LINK_LEN); diff --git a/src/wifi/ahoywifi.cpp b/src/wifi/ahoywifi.cpp index defca5bc..9bcbdadc 100644 --- a/src/wifi/ahoywifi.cpp +++ b/src/wifi/ahoywifi.cpp @@ -92,6 +92,8 @@ void ahoywifi::tickWifiLoop() { } #if !defined(ESP32) MDNS.update(); + if(WiFi.channel() > 11) + mWasInCh12to14 = true; #endif return; case IN_AP_MODE: diff --git a/src/wifi/ahoywifi.h b/src/wifi/ahoywifi.h index 7fb62a20..709c08c4 100644 --- a/src/wifi/ahoywifi.h +++ b/src/wifi/ahoywifi.h @@ -37,6 +37,10 @@ class ahoywifi { } void setupStation(void); + bool getWasInCh12to14() const { + return mWasInCh12to14; + } + private: typedef enum WiFiStatus { DISCONNECTED = 0, @@ -86,6 +90,7 @@ class ahoywifi { bool mGotDisconnect; std::list mBSSIDList; bool mStopApAllowed; + bool mWasInCh12to14 = false; }; #endif /*__AHOYWIFI_H__*/