diff --git a/src/CHANGES.md b/src/CHANGES.md index b1e93d32..8a41bd80 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,12 @@ # Development Changes +## 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 diff --git a/src/app.h b/src/app.h index 70a1fde2..a7be0a55 100644 --- a/src/app.h +++ b/src/app.h @@ -168,7 +168,7 @@ class app : public IApp, public ah::Scheduler { #if !defined(ETHERNET) bool getAvailNetworks(JsonObject obj) override { - return mNetwork->getAvailNetworks(obj); + return mNetwork->getAvailNetworks(obj, this); } void setupStation(void) override { @@ -204,6 +204,10 @@ class app : public IApp, public ah::Scheduler { return mVersionModules; } + void addOnce(ah::scdCb c, uint32_t timeout, const char *name) override { + once(c, timeout, name); + } + uint32_t getSunrise() override { return mSunrise; } diff --git a/src/appInterface.h b/src/appInterface.h index a1f5cd0e..a5f4d081 100644 --- a/src/appInterface.h +++ b/src/appInterface.h @@ -8,6 +8,7 @@ #include "defines.h" #include "ESPAsyncWebServer.h" +#include "utils/scheduler.h" // abstract interface to App. Make members of App accessible from child class // like web or API without forward declaration @@ -25,6 +26,8 @@ class IApp { virtual const char *getVersion() = 0; virtual const char *getVersionModules() = 0; + virtual void addOnce(ah::scdCb c, uint32_t timeout, const char *name) = 0; + #if !defined(ETHERNET) virtual bool getAvailNetworks(JsonObject obj) = 0; virtual void setupStation(void) = 0; diff --git a/src/config/settings.h b/src/config/settings.h index d73ba810..c608dabb 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -166,6 +166,7 @@ typedef struct { char topic[MQTT_TOPIC_LEN]; bool json; uint16_t interval; + bool enableRetain; } cfgMqtt_t; typedef struct { @@ -492,6 +493,7 @@ class settings { snprintf(mCfg.mqtt.topic, MQTT_TOPIC_LEN, "%s", DEF_MQTT_TOPIC); mCfg.mqtt.interval = 0; // off mCfg.mqtt.json = 0; // off + mCfg.mqtt.enableRetain = true; mCfg.inst.sendInterval = SEND_INTERVAL; mCfg.inst.rstYieldMidNight = false; @@ -749,6 +751,7 @@ class settings { obj[F("topic")] = mCfg.mqtt.topic; obj[F("json")] = mCfg.mqtt.json; obj[F("intvl")] = mCfg.mqtt.interval; + obj[F("retain")] = mCfg.mqtt.enableRetain; } else { getVal(obj, F("port"), &mCfg.mqtt.port); @@ -759,6 +762,7 @@ class settings { getChar(obj, F("clientId"), mCfg.mqtt.clientId, MQTT_CLIENTID_LEN); getChar(obj, F("pwd"), mCfg.mqtt.pwd, MQTT_PWD_LEN); getChar(obj, F("topic"), mCfg.mqtt.topic, MQTT_TOPIC_LEN); + getVal(obj, F("retain"), &mCfg.mqtt.enableRetain); } } diff --git a/src/defines.h b/src/defines.h index 7e050bb4..e7eecc00 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 108 +#define VERSION_PATCH 110 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/hms/cmt2300a.h b/src/hms/cmt2300a.h index 61b26894..ed3aab54 100644 --- a/src/hms/cmt2300a.h +++ b/src/hms/cmt2300a.h @@ -248,12 +248,14 @@ class Cmt2300a { } CmtStatus tx(uint8_t buf[], uint8_t len) { + if(mTxPending) + return CmtStatus::ERR_TX_PENDING; + if(mInRxMode) { mInRxMode = false; if(!cmtSwitchStatus(CMT2300A_GO_STBY, CMT2300A_STA_STBY)) return CmtStatus::ERR_SWITCH_STATE; } - mTxPending = false; // safety mSpi.writeReg(CMT2300A_CUS_INT1_CTL, CMT2300A_INT_SEL_TX_DONE); diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index b5778f7d..889fde8e 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -90,12 +90,9 @@ class AhoyNetwork { } #if !defined(ETHERNET) - bool getAvailNetworks(JsonObject obj) { + bool getAvailNetworks(JsonObject obj, IApp *app) { if(!mScanActive) { - mScanActive = true; - if(NetworkState::GOT_IP != mStatus) - WiFi.disconnect(); - WiFi.scanNetworks(true, true); + app->addOnce([this]() {scan();}, 1, "scan"); return false; } @@ -117,6 +114,13 @@ class AhoyNetwork { return true; } + + void scan(void) { + mScanActive = true; + if(NetworkState::GOT_IP != mStatus) + WiFi.disconnect(); + WiFi.scanNetworks(true, true); + } #endif protected: diff --git a/src/network/AhoyWifiAp.h b/src/network/AhoyWifiAp.h index 994af3de..669e8ec8 100644 --- a/src/network/AhoyWifiAp.h +++ b/src/network/AhoyWifiAp.h @@ -63,6 +63,7 @@ class AhoyWifiAp { #if defined(ETHERNET) WiFi.mode(WIFI_OFF); #else + WiFi.scanDelete(); WiFi.mode(WIFI_STA); #endif diff --git a/src/network/AhoyWifiEsp32.h b/src/network/AhoyWifiEsp32.h index 6ccb077a..98b7053c 100644 --- a/src/network/AhoyWifiEsp32.h +++ b/src/network/AhoyWifiEsp32.h @@ -30,6 +30,7 @@ class AhoyWifi : public AhoyNetwork { DBGPRINT(F("connect to network '")); DBGPRINT(mConfig->sys.stationSsid); + DBGPRINTLN(F("'")); #endif } diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index 15b43052..ce3f9b19 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -205,6 +205,9 @@ class PubMqtt { else snprintf(mTopic.data(), mTopic.size(), "%s", subTopic); + if(!mCfgMqtt->enableRetain) + retained = false; + mClient.publish(mTopic.data(), qos, retained, payload); yield(); mTxCnt++; diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 108c7afe..9a633e91 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -489,7 +489,9 @@ class RestApi { void getHtmlFactory(AsyncWebServerRequest *request, JsonObject obj) { getGeneric(request, obj.createNestedObject(F("generic"))); - obj[F("html")] = F("Factory reset? yes no"); + char tmp[200]; + snprintf(tmp, 200, "%s %s %s", FACTORY_RESET, BTN_YES, BTN_NO); + obj[F("html")] = tmp; } void getHtmlFactoryTrue(AsyncWebServerRequest *request, JsonObject obj) { @@ -712,6 +714,7 @@ class RestApi { obj[F("topic")] = String(mConfig->mqtt.topic); obj[F("json")] = (bool) mConfig->mqtt.json; obj[F("interval")] = String(mConfig->mqtt.interval); + obj[F("retain")] = (bool)mConfig->mqtt.enableRetain; } void getNtp(JsonObject obj) { diff --git a/src/web/html/setup.html b/src/web/html/setup.html index d83476ad..bba90f0a 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -250,6 +250,10 @@ +
+
{#RETAIN}
+
+
@@ -286,7 +290,7 @@
{#DISP_LUMINANCE}
-
+

{#DISP_PINOUT}

@@ -295,7 +299,7 @@

{#GRAPH_OPTIONS}

{#GRAPH_SHOW_RATIO}
-
+
@@ -927,6 +931,7 @@ for(var i of [["Addr", "broker"], ["Port", "port"], ["ClientId", "clientId"], ["User", "user"], ["Pwd", "pwd"], ["Topic", "topic"], ["Interval", "interval"]]) document.getElementsByName("mqtt"+i[0])[0].value = obj[i[1]]; document.getElementsByName("mqttJson")[0].checked = obj["json"]; + document.getElementsByName("retain")[0].checked = obj.retain } function parseNtp(obj) { diff --git a/src/web/html/update.html b/src/web/html/update.html index 52ace5f1..ebdbb7ab 100644 --- a/src/web/html/update.html +++ b/src/web/html/update.html @@ -17,7 +17,7 @@ diff --git a/src/web/lang.h b/src/web/lang.h index fb5506ee..54ade94e 100644 --- a/src/web/lang.h +++ b/src/web/lang.h @@ -72,4 +72,22 @@ #define BTN_REBOOT "Reboot" #endif +#ifdef LANG_DE + #define BTN_REBOOT "Ahoy neustarten" +#else /*LANG_EN*/ + #define BTN_REBOOT "Reboot" +#endif + +#ifdef LANG_DE + #define BTN_YES "ja" +#else /*LANG_EN*/ + #define BTN_YES "yes" +#endif + +#ifdef LANG_DE + #define BTN_NO "nein" +#else /*LANG_EN*/ + #define BTN_NO "no" +#endif + #endif /*__LANG_H__*/ diff --git a/src/web/lang.json b/src/web/lang.json index 09d7d424..ce696152 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -106,7 +106,7 @@ { "token": "NETWORK_SUCCESS", "en": "success, got following IP in your network: ", - "de": "Verindung erfolgreich. AhoyDTU hat die folgende IP bekommen: " + "de": "Verbindung erfolgreich. AhoyDTU hat die folgende IP bekommen: " }, { "token": "BTN_FINISH", @@ -418,6 +418,11 @@ "en": "Send Inverter data in a fixed interval, even if there is no change. A value of '0' disables the fixed interval. The data is published once it was successfully received from inverter. (default: 0)", "de": "Wechselrichterdaten in fixem Intervall schicken, auch wenn es keine Änderung gab. Ein Wert von '0' deaktiviert das fixe Intervall, die Wechselrichterdaten werden übertragen, sobald neue zur Verfügung stehen. (Standard: 0)" }, + { + "token": "RETAIN", + "en": "enable retain flag", + "de": "'Retain Flag' aktivieren" + }, { "token": "DISPLAY_CONFIG", "en": "Display Config", diff --git a/src/web/web.h b/src/web/web.h index 0719755c..b75aae5b 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -584,6 +584,7 @@ class Web { mConfig->mqtt.json = (request->arg("mqttJson") == "on"); mConfig->mqtt.port = request->arg("mqttPort").toInt(); mConfig->mqtt.interval = request->arg("mqttInterval").toInt(); + mConfig->mqtt.enableRetain = (request->arg("retain") == "on"); // serial console mConfig->serial.debug = (request->arg("serDbg") == "on");