diff --git a/.gitignore b/.gitignore index 21ae2a574..b5c699ccd 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ src/web/html/tmp/* src/output.map /.venv +/scripts/__pycache__/htmlPreprocessorDefines.cpython-311.pyc diff --git a/src/.gitignore b/src/.gitignore index 89cc49cbd..30f1d1ca6 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -3,3 +3,5 @@ .vscode/c_cpp_properties.json .vscode/launch.json .vscode/ipch +scripts/__pycache__/* +*.pyc diff --git a/src/CHANGES.md b/src/CHANGES.md index 5cc43614b..1ba9edd1c 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -3,6 +3,9 @@ ## 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 diff --git a/src/app.cpp b/src/app.cpp index ae50ba49a..5166c0354 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -403,29 +403,7 @@ void app::tickSend(void) { for (uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { Inverter<> *iv = mSys.getInverterByPos(i); - if(NULL == iv) - continue; - - if(iv->config->enabled) { - if(!iv->commEnabled) { - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINTLN(F("no communication to the inverter (night time)")); - continue; - } - - if(!iv->radio->isChipConnected()) - continue; - - if(InverterStatus::OFF != iv->status) - notAvail = false; - - iv->tickSend([this, iv](uint8_t cmd, bool isDevControl) { - if(isDevControl) - mCommunication.addImportant(iv, cmd); - else - mCommunication.add(iv, cmd); - }); - } + sendIv(iv); } if(mAllIvNotAvail != notAvail) @@ -435,6 +413,37 @@ void app::tickSend(void) { updateLed(); } +//----------------------------------------------------------------------------- +bool app::sendIv(Inverter<> *iv) { + bool notAvail = true; + if(NULL == iv) + return notAvail; + + if(!iv->config->enabled) + return notAvail; + + if(!iv->commEnabled) { + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINTLN(F("no communication to the inverter (night time)")); + return notAvail; + } + + if(!iv->radio->isChipConnected()) + return notAvail; + + if(InverterStatus::OFF != iv->status) + notAvail = false; + + iv->tickSend([this, iv](uint8_t cmd, bool isDevControl) { + if(isDevControl) + mCommunication.addImportant(iv, cmd); + else + mCommunication.add(iv, cmd); + }); + + return notAvail; +} + //----------------------------------------------------------------------------- void app:: zeroIvValues(bool checkAvail, bool skipYieldDay) { Inverter<> *iv; diff --git a/src/app.h b/src/app.h index 300c1c25c..8fe9420dd 100644 --- a/src/app.h +++ b/src/app.h @@ -188,6 +188,10 @@ class app : public IApp, public ah::Scheduler { return mNetwork->getIp(); } + bool isApActive(void) override { + return mNetwork->isApActive(); + } + void setRebootFlag() override { once(std::bind(&app::tickReboot, this), 3, "rboot"); } @@ -386,8 +390,10 @@ class app : public IApp, public ah::Scheduler { bool mNtpReceived = false; void updateNtp(void); - void triggerTickSend() override { - once(std::bind(&app::tickSend, this), 0, "tSend"); + void triggerTickSend(uint8_t id) override { + once([this, id]() { + sendIv(mSys.getInverterByPos(id)); + }, 0, "devct"); } void tickCalcSunrise(void); @@ -396,6 +402,7 @@ class app : public IApp, public ah::Scheduler { void tickSunrise(void); void tickComm(void); void tickSend(void); + bool sendIv(Inverter<> *iv); void tickMinute(void); void tickZeroValues(void); void tickMidnight(void); diff --git a/src/appInterface.h b/src/appInterface.h index 49470e02f..a1f5cd0e8 100644 --- a/src/appInterface.h +++ b/src/appInterface.h @@ -31,6 +31,7 @@ class IApp { virtual bool getWasInCh12to14(void) const = 0; #endif /* defined(ETHERNET) */ virtual String getIp(void) = 0; + virtual bool isApActive(void) = 0; virtual uint32_t getUptime() = 0; virtual uint32_t getTimestamp() = 0; @@ -42,7 +43,7 @@ class IApp { virtual void getSchedulerInfo(uint8_t *max) = 0; virtual void getSchedulerNames() = 0; - virtual void triggerTickSend() = 0; + virtual void triggerTickSend(uint8_t id) = 0; virtual bool getRebootRequestState() = 0; virtual bool getSettingsValid() = 0; diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index c98d98667..55c5d1939 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -85,13 +85,18 @@ class AhoyNetwork { return false; } + bool isApActive() { + return mAp.isEnabled(); + } + #if !defined(ETHERNET) bool getAvailNetworks(JsonObject obj) { JsonArray nets = obj.createNestedArray(F("networks")); if(!mScanActive) { mScanActive = true; - WiFi.disconnect(); + if(NetworkState::GOT_IP != mStatus) + WiFi.disconnect(); WiFi.scanNetworks(true, true); return false; } diff --git a/src/network/AhoyWifiAp.h b/src/network/AhoyWifiAp.h index 56ff63d72..ce2bbd1b5 100644 --- a/src/network/AhoyWifiAp.h +++ b/src/network/AhoyWifiAp.h @@ -54,6 +54,9 @@ class AhoyWifiAp { if(!mEnabled) return; + if(WiFi.softAPgetStationNum() > 0) + return; + mDns.stop(); WiFi.softAPdisconnect(); #if defined(ETHERNET) diff --git a/src/network/AhoyWifiEsp32.h b/src/network/AhoyWifiEsp32.h index 58f5dc5df..41956dfc6 100644 --- a/src/network/AhoyWifiEsp32.h +++ b/src/network/AhoyWifiEsp32.h @@ -43,6 +43,7 @@ class AhoyWifi : public AhoyNetwork { mConnected = false; mOnNetworkCB(false); mAp.enable(); + MDNS.end(); } break; @@ -50,11 +51,14 @@ class AhoyWifi : public AhoyNetwork { break; case NetworkState::GOT_IP: - if(!mConnected) { + if(mAp.isEnabled()) mAp.disable(); + + if(!mConnected) { mConnected = true; ah::welcome(WiFi.localIP().toString(), F("Station")); MDNS.begin(mConfig->sys.deviceName); + MDNS.addServiceTxt("http", "tcp", "path", "/"); mOnNetworkCB(true); } break; diff --git a/src/network/AhoyWifiEsp8266.h b/src/network/AhoyWifiEsp8266.h index 93597f723..2497448be 100644 --- a/src/network/AhoyWifiEsp8266.h +++ b/src/network/AhoyWifiEsp8266.h @@ -39,6 +39,7 @@ class AhoyWifi : public AhoyNetwork { mConnected = false; mOnNetworkCB(false); mAp.enable(); + MDNS.end(); } if (WiFi.softAPgetStationNum() > 0) { @@ -93,6 +94,9 @@ class AhoyWifi : public AhoyNetwork { mConnected = true; ah::welcome(WiFi.localIP().toString(), F("Station")); MDNS.begin(mConfig->sys.deviceName); + MDNSResponder::hMDNSService hRes = MDNS.addService(NULL, "http", "tcp", 80); + MDNS.addServiceTxt(hRes, "path", "/"); + MDNS.announce(); mOnNetworkCB(true); } diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 0f256f254..a9756944f 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -1011,7 +1011,7 @@ class RestApi { accepted = iv->setDevControlRequest(ActivePowerContr); if(accepted) - mApp->triggerTickSend(); + mApp->triggerTickSend(iv->id); } else if(F("dev") == jsonIn[F("cmd")]) { DPRINTLN(DBG_INFO, F("dev cmd")); iv->setDevCommand(jsonIn[F("val")].as()); diff --git a/src/web/html/setup.html b/src/web/html/setup.html index fb1eff979..51d48f7c6 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -57,22 +57,9 @@
{#AP_PWD}
-
-
{#SEARCH_NETWORKS}
-
-
- -
-
{#AVAIL_NETWORKS}
-
- -
-
SSID
-
+
{#SSID_HIDDEN}
@@ -606,12 +593,6 @@ setTimeout(function() {getAjax('/api/index', apiCbNtp2)}, 2000) } - function scan() { - var obj = {cmd: "scan_wifi", token: "*"} - getAjax("/api/setup", apiCbWifi, "POST", JSON.stringify(obj)); - setTimeout(function() {getAjax('/api/setup/networks', listNetworks)}, 5000); - } - function syncTime() { var obj = {cmd: "sync_ntp", token: "*"} getAjax("/api/setup", apiCbNtp, "POST", JSON.stringify(obj)) @@ -1319,13 +1300,6 @@ s.appendChild(opt("-1", "{#NO_NETWORK_FOUND}")); } - function selNet() { - var s = document.getElementById("networks"); - var e = document.getElementsByName("ssid")[0]; - if(-1 != s.value) - e.value = s.value; - } - getAjax("/api/setup", parse); diff --git a/src/web/html/wizard.html b/src/web/html/wizard.html index d57562d10..1fc8503cb 100644 --- a/src/web/html/wizard.html +++ b/src/web/html/wizard.html @@ -218,7 +218,7 @@ sect("{#WIFI_MANUAL}", ml("input", {id: "man", type: "text"})), sect("{#WIFI_PASSWORD}", ml("input", {id: "pwd", type: "password"})), ml("div", {class: "row my-4"}, ml("div", {class: "col a-r"}, ml("input", {type: "button", class:"btn", value: "{#BTN_NEXT}", onclick: () => {saveWifi()}}, null))), - ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/"}, "{#STOP_WIZARD}"))) + ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/index"}, "{#STOP_WIZARD}"))) ]) } /*ENDIF_ETHERNET*/ @@ -229,9 +229,9 @@ ml("div", {class: "row"}, ml("div", {class: "col"}, ml("span", {class: "fs-5"}, "{#TEST_CONNECTION}"))), sect("{#TRY_TO_CONNECT}", ml("span", {id: "state"}, "{#CONNECTING}")), ml("div", {class: "row my-4"}, ml("div", {class: "col a-r"}, ml("input", {type: "button", class:"btn hide", id: "btn", value: "{#BTN_FINISH}", onclick: () => {redirect()}}, null))), - ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/"}, "{#STOP_WIZARD}"))) + ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/index"}, "{#STOP_WIZARD}"))) ) - v = setInterval(() => {getAjax('/api/setup/getip', printIp)}, 1000); + v = setInterval(() => {getAjax('/api/setup/getip', printIp)}, 300); } function redirect() { @@ -286,7 +286,8 @@ } c.append(step1()) - v = setInterval(() => {getAjax('/api/setup/networks', nets)}, 1000); + getAjax('/api/setup/networks', nets) + v = setInterval(() => {getAjax('/api/setup/networks', nets)}, 1000) /*ENDIF_ETHERNET*/ diff --git a/src/web/lang.json b/src/web/lang.json index ee9426083..57ded1dda 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -81,7 +81,7 @@ { "token": "BTN_NEXT", "en": "next >>", - "de": "prüfen >>" + "de": "prüfen >>" }, { "token": "BTN_REBOOT", @@ -91,7 +91,7 @@ { "token": "TEST_CONNECTION", "en": "Test Connection", - "de": "Verbindung wird überprüft" + "de": "Verbindung wird überprüft" }, { "token": "TRY_TO_CONNECT", @@ -259,19 +259,9 @@ "de": "Netzwerke suchen" }, { - "token": "BTN_SCAN", - "en": "scan", - "de": "Suche starten" - }, - { - "token": "AVAIL_NETWORKS", - "en": "Avail Networks", - "de": "Verfügbare Netzwerke" - }, - { - "token": "NETWORK_NOT_SCANNED", - "en": "not scanned", - "de": "nicht gesucht" + "token": "SCAN_WIFI", + "en": "scan for WiFi networks", + "de": "nach WiFi Netzwerken suchen" }, { "token": "SSID_HIDDEN", diff --git a/src/web/web.h b/src/web/web.h index 56ff577ef..4f93b9057 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -57,7 +57,8 @@ class Web { mConfig = config; DPRINTLN(DBG_VERBOSE, F("app::setup-on")); - mWeb.on("/", HTTP_GET, std::bind(&Web::onIndex, this, std::placeholders::_1)); + mWeb.on("/", HTTP_GET, std::bind(&Web::onIndex, this, std::placeholders::_1, true)); + mWeb.on("/index", HTTP_GET, std::bind(&Web::onIndex, this, std::placeholders::_1, false)); mWeb.on("/login", HTTP_ANY, std::bind(&Web::onLogin, this, std::placeholders::_1)); mWeb.on("/logout", HTTP_GET, std::bind(&Web::onLogout, this, std::placeholders::_1)); mWeb.on("/colors.css", HTTP_GET, std::bind(&Web::onColor, this, std::placeholders::_1)); @@ -319,7 +320,11 @@ class Web { client->send("hello!", NULL, millis(), 1000); } - void onIndex(AsyncWebServerRequest *request) { + void onIndex(AsyncWebServerRequest *request, bool checkAp = true) { + if(mApp->isApActive() && checkAp) { + onWizard(request); + return; + } getPage(request, PROT_MASK_INDEX, index_html, index_html_len); }