From 479ac5d3439112e548a5e164989be012f3a224d1 Mon Sep 17 00:00:00 2001 From: Northern Man <19808920+NorthernMan54@users.noreply.github.com> Date: Wed, 12 Apr 2023 14:29:03 -0400 Subject: [PATCH] [WebUI] Completion of WiFi and MQTT Configuration (#1603) * Configure WiFi - 1/2 working * WiFi and MQTT Configuration * Refactor MQTTtoSYS * Firmware Upgrade is Wired --- main/ZwebUI.ino | 412 +++++++++++++++++++++++++++++++++++---- main/config_WebContent.h | 12 +- main/config_WebUI.h | 2 +- main/main.ino | 33 ++-- 4 files changed, 399 insertions(+), 60 deletions(-) diff --git a/main/ZwebUI.ino b/main/ZwebUI.ino index 3bd8535..32f6658 100644 --- a/main/ZwebUI.ino +++ b/main/ZwebUI.ino @@ -179,6 +179,68 @@ size_t strchrspn(const char* str1, int character) { return ret; } +int WifiGetRssiAsQuality(int rssi) { + int quality = 0; + + if (rssi <= -100) { + quality = 0; + } else if (rssi >= -50) { + quality = 100; + } else { + quality = 2 * (rssi + 100); + } + return quality; +} + +char* GetTextIndexed(char* destination, size_t destination_size, uint32_t index, const char* haystack) { + // Returns empty string if not found + // Returns text of found + char* write = destination; + const char* read = haystack; + + index++; + while (index--) { + size_t size = destination_size - 1; + write = destination; + char ch = '.'; + while ((ch != '\0') && (ch != '|')) { + ch = pgm_read_byte(read++); + if (size && (ch != '|')) { + *write++ = ch; + size--; + } + } + if (0 == ch) { + if (index) { + write = destination; + } + break; + } + } + *write = '\0'; + return destination; +} + +const char kUnescapeCode[] = "&><\"\'\\"; +const char kEscapeCode[] PROGMEM = "&|>|<|"|'|\"; + +String HtmlEscape(const String unescaped) { + char escaped[10]; + size_t ulen = unescaped.length(); + String result; + result.reserve(ulen); // pre-reserve the required space to avoid mutiple reallocations + for (size_t i = 0; i < ulen; i++) { + char c = unescaped[i]; + char* p = strchr(kUnescapeCode, c); + if (p != nullptr) { + result += GetTextIndexed(escaped, sizeof(escaped), p - kUnescapeCode, kEscapeCode); + } else { + result += c; + } + } + return result; +} + # endif // ESP32 void AddLogData(uint32_t loglevel, const char* log_data, const char* log_data_payload = nullptr, const char* log_data_retained = nullptr) { @@ -439,14 +501,142 @@ void handleCN() { /** * @brief /WI - Configure WiFi Page - * + * T: handleWI: uri: /wi, args: 4, method: 1 + * T: handleWI Arg: 0, s1=SSID + * T: handleWI Arg: 1, p1=xxxxxx + * T: handleWI Arg: 3, save= */ void handleWI() { WEBUI_TRACE_LOG(F("handleWI: uri: %s, args: %d, method: %d" CR), server.uri(), server.args(), server.method()); + String WiFiScan = ""; if (server.args()) { for (uint8_t i = 0; i < server.args(); i++) { WEBUI_TRACE_LOG(F("handleWI Arg: %d, %s=%s" CR), i, server.argName(i).c_str(), server.arg(i).c_str()); } + if (server.hasArg("scan")) { + bool limitScannedNetworks = true; + int n = WiFi.scanNetworks(); + + WEBUI_TRACE_LOG(F("handleWI scan: found %d" CR), n); + if (0 == n) { + // WSContentSend_P(PSTR(D_NO_NETWORKS_FOUND)); + // limitScannedNetworks = false; // in order to show D_SCAN_FOR_WIFI_NETWORKS + } else { + //sort networks + int indices[n]; + for (uint32_t i = 0; i < n; i++) { + indices[i] = i; + } + + // RSSI SORT + for (uint32_t i = 0; i < n; i++) { + for (uint32_t j = i + 1; j < n; j++) { + if (WiFi.RSSI(indices[j]) > WiFi.RSSI(indices[i])) { + std::swap(indices[i], indices[j]); + } + } + } + + uint32_t networksToShow = n; + if ((limitScannedNetworks) && (networksToShow > MAX_WIFI_NETWORKS_TO_SHOW)) { + networksToShow = MAX_WIFI_NETWORKS_TO_SHOW; + } + + for (uint32_t i = 0; i < n; i++) { + if (-1 == indices[i]) { + continue; + } + String cssid = WiFi.SSID(indices[i]); + uint32_t cschn = WiFi.channel(indices[i]); + for (uint32_t j = i + 1; j < n; j++) { + if ((cssid == WiFi.SSID(indices[j])) && (cschn == WiFi.channel(indices[j]))) { + WEBUI_TRACE_LOG(F("handleWI scan: duplicate %s" CR), WiFi.SSID(indices[j]).c_str()); + indices[j] = -1; // set dup aps to index -1 + } + } + } + + //display networks in page + for (uint32_t i = 0; i < networksToShow; i++) { + if (-1 == indices[i]) { + continue; + } // skip dups + int32_t rssi = WiFi.RSSI(indices[i]); + WEBUI_TRACE_LOG(F("D_LOG_WIFI D_SSID %s, D_BSSID %s, D_CHANNEL %d, D_RSSI %d" CR), + WiFi.SSID(indices[i]).c_str(), WiFi.BSSIDstr(indices[i]).c_str(), WiFi.channel(indices[i]), rssi); + int quality = WifiGetRssiAsQuality(rssi); + String ssid_copy = WiFi.SSID(indices[i]); + if (!ssid_copy.length()) { + ssid_copy = F("no_name"); + } + + WiFiScan += "
| %s |
|---|