diff --git a/src/CHANGES.md b/src/CHANGES.md index 8d89f003..f2cc8785 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,6 +1,7 @@ # Development Changes -## 0.8.98 - 2024-03-23 +## 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 diff --git a/src/app.cpp b/src/app.cpp index f06e4a53..2dd8c49c 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -162,7 +162,6 @@ void app::loop(void) { //----------------------------------------------------------------------------- void app::onNetwork(bool gotIp) { - DPRINTLN(DBG_INFO, F("onNetwork")); mNetworkConnected = gotIp; ah::Scheduler::resetTicker(); regularTickers(); //reinstall regular tickers diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index 3c3489bd..59e000bd 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -173,7 +173,9 @@ class AhoyNetwork { enum class NetworkState : uint8_t { DISCONNECTED, CONNECTED, - GOT_IP + GOT_IP, + SCAN_READY, // ESP8266 + CONNECTING // ESP8266 }; protected: diff --git a/src/network/AhoyWifiEsp8266.h b/src/network/AhoyWifiEsp8266.h index 16a62b4b..2db24c21 100644 --- a/src/network/AhoyWifiEsp8266.h +++ b/src/network/AhoyWifiEsp8266.h @@ -8,6 +8,7 @@ #if defined(ESP8266) #include +#include #include #include "AhoyNetwork.h" #include "ESPAsyncWebServer.h" @@ -23,18 +24,15 @@ class AhoyWifi : public AhoyNetwork { }); WiFi.setHostname(mConfig->sys.deviceName); - #if !defined(AP_ONLY) - WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd); - - DBGPRINT(F("connect to network '")); Serial.flush(); - DBGPRINT(mConfig->sys.stationSsid); - #endif + mBSSIDList.clear(); } void tickNetworkLoop() override { if(mAp.isEnabled()) mAp.tickLoop(); + mCnt++; + switch(mStatus) { case NetworkState::DISCONNECTED: if(mConnected) { @@ -46,6 +44,45 @@ class AhoyWifi : public AhoyNetwork { if (WiFi.softAPgetStationNum() > 0) { DBGPRINTLN(F("AP client connected")); } + #if !defined(AP_ONLY) + else if (!mScanActive) { + DBGPRINT(F("scanning APs with SSID ")); + DBGPRINTLN(String(mConfig->sys.stationSsid)); + mScanCnt = 0; + mCnt = 0; + mScanActive = true; + WiFi.scanNetworks(true, true, 0U, ([this]() { + if (mConfig->sys.isHidden) + return (uint8_t*)NULL; + return (uint8_t*)(mConfig->sys.stationSsid); + })()); + } else if(getBSSIDs()) { + mStatus = NetworkState::SCAN_READY; + DBGPRINT(F("connect to network '")); Serial.flush(); + DBGPRINTLN(mConfig->sys.stationSsid); + } + #endif + break; + + case NetworkState::SCAN_READY: + mStatus = NetworkState::CONNECTING; + DBGPRINT(F("try to connect to BSSID:")); + uint8_t bssid[6]; + for (int j = 0; j < 6; j++) { + bssid[j] = mBSSIDList.front(); + mBSSIDList.pop_front(); + DBGPRINT(" " + String(bssid[j], HEX)); + } + DBGPRINTLN(""); + mGotDisconnect = false; + WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd, 0, &bssid[0]); + break; + + case NetworkState::CONNECTING: + if (isTimeout(TIMEOUT)) { + WiFi.disconnect(); + mStatus = mBSSIDList.empty() ? NetworkState::DISCONNECTED : NetworkState::SCAN_READY; + } break; case NetworkState::CONNECTED: @@ -104,8 +141,45 @@ class AhoyWifi : public AhoyNetwork { std::swap(sort[i], sort[j]); } + bool getBSSIDs() { + bool result = false; + int n = WiFi.scanComplete(); + if (n < 0) { + if (++mScanCnt < 20) + return false; + } + if(n > 0) { + mBSSIDList.clear(); + int sort[n]; + sortRSSI(&sort[0], n); + for (int i = 0; i < n; i++) { + DBGPRINT("BSSID " + String(i) + ":"); + uint8_t *bssid = WiFi.BSSID(sort[i]); + for (int j = 0; j < 6; j++){ + DBGPRINT(" " + String(bssid[j], HEX)); + mBSSIDList.push_back(bssid[j]); + } + DBGPRINTLN(""); + } + result = true; + } + mScanActive = false; + WiFi.scanDelete(); + return result; + } + + bool isTimeout(uint8_t timeout) { + return ((mCnt % timeout) == 0); + } + private: + uint8_t mCnt = 0; + uint8_t mScanCnt = 0; bool mScanActive = false; + bool mGotDisconnect = false; + std::list mBSSIDList; + static constexpr uint8_t TIMEOUT = 20; + static constexpr uint8_t SCAN_TIMEOUT = 10; }; #endif /*ESP8266*/