Optimise wifi scan

- prioritize strongest signal
- prune removed networks
- fill present networks
This commit is contained in:
Blaz Kristan 2024-01-23 20:44:43 +01:00
parent bfb217c203
commit 1bebf3d3d6
5 changed files with 67 additions and 12 deletions

View File

@ -52,8 +52,9 @@
}
scanLoops = 0;
let cs = d.querySelectorAll("#wifi_entries input[type=text]#CS0");
let cs = d.querySelectorAll("#wifi_entries input[type=text]");
for (let input of (cs||[])) {
let found = false;
let select = cE("select");
select.id = input.id;
select.name = input.name;
@ -72,6 +73,7 @@
if (networks[i].ssid === input.value) {
option.setAttribute("selected", "selected");
found = true;
}
select.appendChild(option);
@ -82,7 +84,8 @@
option.textContent = "Other network...";
select.appendChild(option);
input.replaceWith(select);
if (input.value === "" || found) input.replaceWith(select);
else select.remove();
}
button.disabled = false;

View File

@ -81,6 +81,7 @@ input:disabled {
}
input[type="text"],
input[type="number"],
input[type="password"],
select {
font-size: medium;
margin: 2px;

View File

@ -19,8 +19,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
//WIFI SETTINGS
if (subPage == SUBPAGE_WIFI)
{
char oldSSID[33];
strlcpy(oldSSID, multiWiFi[0].clientSSID, 33);
unsigned cnt = 0;
for (size_t n = 0; n < WLED_MAX_WIFI_COUNT; n++) {
char cs[4] = "CS"; cs[2] = 48+n; cs[3] = 0; //client SSID
char pw[4] = "PW"; pw[2] = 48+n; pw[3] = 0; //client password
@ -28,10 +27,11 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
char gw[5] = "GW"; gw[2] = 48+n; gw[4] = 0; //GW address
char sn[5] = "SN"; sn[2] = 48+n; sn[4] = 0; //subnet mask
if (request->hasArg(cs)) {
if (n >= multiWiFi.size()) multiWiFi.push_back(WiFiConfig());
if (n >= multiWiFi.size()) multiWiFi.push_back(WiFiConfig()); // expand vector by one
char oldSSID[33]; strcpy(oldSSID, multiWiFi[n].clientSSID);
char oldPass[65]; strcpy(oldPass, multiWiFi[n].clientPass);
if (!strncmp(request->arg(cs).c_str(), oldSSID, 32)) {
if (strlen(oldSSID) == 0 || !strncmp(request->arg(cs).c_str(), oldSSID, 32)) {
strlcpy(multiWiFi[n].clientSSID, request->arg(cs).c_str(), 33);
forceReconnect = true;
}
@ -47,18 +47,24 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
multiWiFi[n].staticGW[i] = request->arg(gw).toInt();
multiWiFi[n].staticSN[i] = request->arg(sn).toInt();
}
cnt++;
}
}
// remove unused
if (cnt < multiWiFi.size()) {
cnt = multiWiFi.size() - cnt;
while (cnt--) multiWiFi.pop_back();
multiWiFi.shrink_to_fit(); // release memory
}
if (request->hasArg(F("D0"))) {
dnsAddress = IPAddress(request->arg(F("D0")).toInt(),request->arg(F("D1")).toInt(),request->arg(F("D2")).toInt(),request->arg(F("D3")).toInt());
DEBUG_PRINTLN(dnsAddress);
}
strlcpy(cmDNS, request->arg(F("CM")).c_str(), 33);
apBehavior = request->arg(F("AB")).toInt();
strcpy(oldSSID, apSSID);
char oldSSID[33]; strcpy(oldSSID, apSSID);
strlcpy(apSSID, request->arg(F("AS")).c_str(), 33);
if (!strcmp(oldSSID, apSSID) && apActive) forceReconnect = true;
apHide = request->hasArg(F("AH"));

View File

@ -453,6 +453,8 @@ void WLED::setup()
WiFi.onEvent(WiFiEvent);
#endif
findWiFi(true); // start scanning for available WiFi-s
#ifdef WLED_ENABLE_ADALIGHT
//Serial RX (Adalight, Improv, Serial JSON) only possible if GPIO3 unused
//Serial TX (Debug, Improv, Serial JSON) only possible if GPIO1 unused
@ -698,7 +700,48 @@ bool WLED::initEthernet()
#else
return false; // Ethernet not enabled for build
#endif
}
// performs asynchronous scan for available networks (which may take couple of seconds to finish)
// returns true if only one wifi is configured or scan completed
bool WLED::findWiFi(bool doScan) {
if (multiWiFi.size() <= 1) {
DEBUG_PRINTLN(F("Defaulf WiFi used."));
selectedWiFi = 0;
return true;
}
if (doScan) WiFi.scanDelete(); // restart scan
int status = WiFi.scanComplete();
if (status == WIFI_SCAN_FAILED) {
DEBUG_PRINTLN(F("WiFi scan started."));
WiFi.scanNetworks(true); // start scanning in asynchronous mode
return false;
}
if (status > 0) { // status contains number of found networks
DEBUG_PRINT(F("WiFi scan completed: ")); DEBUG_PRINTLN(status);
int rssi = -9999;
for (int o = 0; o < status; o++) {
DEBUG_PRINT(F(" WiFi available: ")); DEBUG_PRINT(WiFi.SSID(o));
DEBUG_PRINT(F(" RSSI: ")); DEBUG_PRINT(WiFi.RSSI(o)); DEBUG_PRINTLN(F("dB"));
for (unsigned n = 0; n < multiWiFi.size(); n++)
if (!strcmp(WiFi.SSID(o).c_str(), multiWiFi[n].clientSSID)) {
// find the WiFi with the strongest signal (but keep priority of entry if signal difference is not big)
if ((n < selectedWiFi && WiFi.RSSI(o) > rssi-10) || WiFi.RSSI(o) > rssi) {
rssi = WiFi.RSSI(o);
selectedWiFi = n;
}
break;
}
}
DEBUG_PRINT(F("Selected: ")); DEBUG_PRINT(multiWiFi[selectedWiFi].clientSSID);
DEBUG_PRINT(F(" RSSI: ")); DEBUG_PRINT(rssi); DEBUG_PRINTLN(F("dB"));
return true;
}
//DEBUG_PRINT(F("WiFi scan running."));
return false; // scan is still running or there was an error
}
void WLED::initConnection()
@ -715,7 +758,7 @@ void WLED::initConnection()
}
#endif
WiFi.disconnect(true); // close old connections
if (findWiFi()) WiFi.disconnect(true); // close old connections (only if scan completed and found networks)
#ifdef ESP8266
WiFi.setPhyMode(force802_3g ? WIFI_PHY_MODE_11G : WIFI_PHY_MODE_11N);
#endif
@ -752,7 +795,7 @@ void WLED::initConnection()
// convert the "serverDescription" into a valid DNS hostname (alphanumeric)
char hostname[25];
prepareHostname(hostname);
WiFi.begin(multiWiFi[selectedWiFi].clientSSID, multiWiFi[selectedWiFi].clientPass);
WiFi.begin(multiWiFi[selectedWiFi].clientSSID, multiWiFi[selectedWiFi].clientPass); // no harm if called multiple times
#ifdef ARDUINO_ARCH_ESP32
#if defined(LOLIN_WIFI_FIX) && (defined(ARDUINO_ARCH_ESP32C3) || defined(ARDUINO_ARCH_ESP32S2) || defined(ARDUINO_ARCH_ESP32S3))
WiFi.setTxPower(WIFI_POWER_8_5dBm);
@ -907,6 +950,7 @@ void WLED::handleConnection()
if (interfacesInited) {
DEBUG_PRINTLN(F("Disconnected!"));
initConnection();
findWiFi(true); // reinit scan
interfacesInited = false;
}
//send improv failed 6 seconds after second init attempt (24 sec. after provisioning)
@ -917,15 +961,15 @@ void WLED::handleConnection()
if (now - lastReconnectAttempt > ((stac) ? 300000 : 18000) && WLED_WIFI_CONFIGURED) {
if (improvActive == 2) improvActive = 3;
DEBUG_PRINTLN(F("Last reconnect too old."));
if (++selectedWiFi >= multiWiFi.size()) selectedWiFi = 0;
initConnection();
findWiFi(true); // reinit scan
}
if (!apActive && now - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) {
DEBUG_PRINTLN(F("Not connected AP."));
initAP();
}
} else if (!interfacesInited) { //newly connected
DEBUG_PRINTLN("");
DEBUG_PRINTLN();
DEBUG_PRINT(F("Connected! IP address: "));
DEBUG_PRINTLN(Network.localIP());
if (improvActive) {

View File

@ -881,6 +881,7 @@ public:
void initAP(bool resetAP = false);
void initConnection();
void initInterfaces();
bool findWiFi(bool doScan = false);
#if defined(STATUSLED)
void handleStatusLED();
#endif