From 6a48b1a63d2e92991c1c70def2f207ea7d8573d5 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Mon, 12 Apr 2021 13:36:43 -0300 Subject: [PATCH] Webserver: Simplify Initial WiFi Configuration --- tasmota/xdrv_01_webserver.ino | 328 ++++++++++++++++++++++++++++------ 1 file changed, 270 insertions(+), 58 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index e61df582f..25f8fa68f 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -34,6 +34,19 @@ #define WIFI_SOFT_AP_CHANNEL 1 // Soft Access Point Channel number between 1 and 11 as used by WifiManager web GUI #endif +#ifndef MAX_WIFI_NETWORKS_TO_SHOW +#define MAX_WIFI_NETWORKS_TO_SHOW 3 // Maximum number of Wifi Networks to show in the Wifi Configuration Menu BEFORE clicking on Show More Networks. +#endif + +#ifndef RESTART_AFTER_INITIAL_WIFI_CONFIG +#define RESTART_AFTER_INITIAL_WIFI_CONFIG true // Restart Tasmota after initial Wifi Config of a blank device +#endif // If disabled, Tasmota will keep both the wifi AP and the wifi connection to the router + // but only until next restart. +#ifndef AFTER_INITIAL_WIFI_CONFIG_GO_TO_NEW_IP // If RESTART_AFTER_INITIAL_WIFI_CONFIG and AFTER_INITIAL_WIFI_CONFIG_GO_TO_NEW_IP are true, +#define AFTER_INITIAL_WIFI_CONFIG_GO_TO_NEW_IP true // the user will be redirected to the new IP of Tasmota (in the new Network). +#endif // If the first is true, but this is false, the device will restart but the user will see + // a window telling that the WiFi Configuration was Ok and that the window can be closed. + const uint16_t CHUNKED_BUFFER_SIZE = (MESSZ / 2) - 100; // Chunk buffer size (should be smaller than half mqtt_data size = MESSZ) const uint16_t HTTP_REFRESH_TIME = 2345; // milliseconds @@ -102,6 +115,17 @@ const char HTTP_SCRIPT_WIFI[] PROGMEM = "eb('p1').focus();" "}"; +const char HTTP_SCRIPT_HIDE[] PROGMEM = + "function hidBtns() {" + "eb('butmo').style.display = 'none';" + "eb('butmod').style.display = 'none';" + "eb('but0').style.display = 'block';" + "eb('but1').style.display = 'block';" + "eb('but13').style.display = 'block';" + "eb('but0d').style.display = 'block';" + "eb('but13d').style.display = 'block';" + "}"; + const char HTTP_SCRIPT_RELOAD_TIME[] PROGMEM = "setTimeout(function(){location.href='.';},%d);"; @@ -259,13 +283,19 @@ const char HTTP_FORM_MODULE[] PROGMEM = "

" D_MODULE_TYPE " (%s)

" "
"; +const char HTTP_FORM_WIFI_INITIAL[] PROGMEM = + "
 " D_WIFI_PARAMETERS " " + "
" + "

" D_AP1_SSID "

" // Need \" instead of ' to be able to use ' in text (#8489) + "


"; + const char HTTP_FORM_WIFI[] PROGMEM = "
 " D_WIFI_PARAMETERS " " "" - "

" D_AP1_SSID " (" STA_SSID1 ")

" // Need \" instead of ' to be able to use ' in text (#8489) - "


" - "

" D_AP2_SSID " (" STA_SSID2 ")

" - "


" + "

" D_AP1_SSID " (" STA_SSID1 ")

" // Need \" instead of ' to be able to use ' in text (#8489) + "


" + "

" D_AP2_SSID " (" STA_SSID2 ")

" + "


" "

" D_HOSTNAME " (%s)

" "

" D_CORS_DOMAIN "

"; @@ -366,6 +396,7 @@ const char kUploadErrors[] PROGMEM = const uint16_t DNS_PORT = 53; enum HttpOptions {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER, HTTP_MANAGER_RESET_ONLY}; +enum WifiTestOptions {WIFI_NOT_TESTING, WIFI_TESTING, WIFI_TEST_FINISHED_SUCCESSFUL, WIFI_TEST_FINISHED_BAD}; DNSServer *DnsServer; ESP8266WebServer *Webserver; @@ -380,6 +411,11 @@ struct WEB { uint8_t config_xor_on_set = CONFIG_FILE_XOR; bool upload_services_stopped = false; bool reset_web_log_flag = false; // Reset web console log + bool initial_config = false; + uint8_t wifiTest = WIFI_NOT_TESTING; + uint8_t wifi_test_counter = 0; + uint16_t save_data_counter = 0; + uint8_t old_wificonfig = WIFI_MANAGER; } Web; // Helper function to avoid code duplication (saves 4k Flash) @@ -497,8 +533,8 @@ void StartWebserver(int type, IPAddress ipweb) NetworkHostname(), (Mdns.begun) ? PSTR(".local") : "", (uint32_t)ipweb); #endif // LWIP_IPV6 = 1 TasmotaGlobal.rules_flag.http_init = 1; + Web.state = type; } - if (type) { Web.state = type; } } void StopWebserver(void) @@ -513,6 +549,7 @@ void StopWebserver(void) void WifiManagerBegin(bool reset_only) { // setup AP + if (!Web.initial_config) { AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_WCFG_2_WIFIMANAGER " " D_ACTIVE_FOR_3_MINUTES)); } if (!TasmotaGlobal.global_state.wifi_down) { // WiFi.mode(WIFI_AP_STA); WifiSetMode(WIFI_AP_STA); @@ -523,7 +560,7 @@ void WifiManagerBegin(bool reset_only) AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_WIFIMANAGER_SET_ACCESSPOINT)); } - StopWebserver(); + //StopWebserver(); DnsServer = new DNSServer(); @@ -717,7 +754,7 @@ void WSContentStart_P(const char* title) void WSContentSendStyle_P(const char* formatP, ...) { - if (WifiIsInManagerMode()) { + if ( WifiIsInManagerMode() && (!Web.initial_config) ) { if (WifiConfigCounter()) { WSContentSend_P(HTTP_SCRIPT_COUNTER); } @@ -753,8 +790,14 @@ void WSContentSendStyle_P(const char* formatP, ...) WebColor(COL_TEXT_WARNING), #endif WebColor(COL_TITLE), - ModuleName().c_str(), SettingsText(SET_DEVICENAME)); - if (Settings.flag3.gui_hostname_ip) { // SetOption53 - Show hostanme and IP address in GUI main menu + (Web.initial_config) ? "" : ModuleName().c_str(), SettingsText(SET_DEVICENAME)); + + // SetOption53 - Show hostname and IP address in GUI main menu +#if (RESTART_AFTER_INITIAL_WIFI_CONFIG) + if (Settings.flag3.gui_hostname_ip) { +#else + if ( Settings.flag3.gui_hostname_ip || ( (WiFi.getMode() == WIFI_AP_STA) && (!Web.initial_config) ) ) { +#endif bool lip = (static_cast(WiFi.localIP()) != 0); bool sip = (static_cast(WiFi.softAPIP()) != 0); WSContentSend_P(PSTR("

%s%s (%s%s%s)

"), // tasmota.local (192.168.2.12, 192.168.4.1) @@ -772,29 +815,33 @@ void WSContentSendStyle(void) WSContentSendStyle_P(nullptr); } -void WSContentButton(uint32_t title_index) +void WSContentButton(uint32_t title_index, bool show=true) { char action[4]; char title[100]; // Large to accomodate UTF-16 as used by Russian if (title_index <= BUTTON_RESET_CONFIGURATION) { char confirm[100]; - WSContentSend_P(PSTR("

"), + WSContentSend_P(PSTR("

"), + title_index, + show ? "block":"none", GetTextIndexed(action, sizeof(action), title_index, kButtonAction), GetTextIndexed(confirm, sizeof(confirm), title_index, kButtonConfirm), (!title_index) ? PSTR("rst") : PSTR("non"), GetTextIndexed(title, sizeof(title), title_index, kButtonTitle)); } else { - WSContentSend_P(PSTR("

"), + WSContentSend_P(PSTR("

"), + title_index, + show ? "block":"none", GetTextIndexed(action, sizeof(action), title_index, kButtonAction), GetTextIndexed(title, sizeof(title), title_index, kButtonTitle)); } } -void WSContentSpaceButton(uint32_t title_index) +void WSContentSpaceButton(uint32_t title_index, bool show=true) { - WSContentSend_P(PSTR("
")); // 5px padding - WSContentButton(title_index); + WSContentSend_P(PSTR("
"),title_index, show ? "block":"none"); // 5px padding + WSContentButton(title_index, show); } void WSContentSend_Temp(const char *types, float f_temperature) { @@ -821,7 +868,7 @@ void WSContentEnd(void) void WSContentStop(void) { - if (WifiIsInManagerMode()) { + if ( WifiIsInManagerMode() && (!Web.initial_config) ) { if (WifiConfigCounter()) { WSContentSend_P(HTTP_COUNTER); } @@ -836,31 +883,53 @@ void WebRestart(uint32_t type) { // type 0 = restart // type 1 = restart after config change - // type 2 = restart after config change with possible ip address change too - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_RESTART)); - + // type 2 = Checking WiFi Connection - no restart, only refresh page. + // type 3 = restart after WiFi Connection Test Successful bool reset_only = (HTTP_MANAGER_RESET_ONLY == Web.state); WSContentStart_P((type) ? PSTR(D_SAVE_CONFIGURATION) : PSTR(D_RESTART), !reset_only); - WSContentSend_P(HTTP_SCRIPT_RELOAD_TIME, HTTP_RESTART_RECONNECT_TIME); +#if ((RESTART_AFTER_INITIAL_WIFI_CONFIG) && (AFTER_INITIAL_WIFI_CONFIG_GO_TO_NEW_IP)) + // In case of type 3 (New network has been configured) go to the new device's IP in the new Network + if (3 == type) { + WSContentSend_P("setTimeout(function(){location.href='http://%_I';},%d);", + (uint32_t)WiFi.localIP(), + HTTP_RESTART_RECONNECT_TIME + ); + } else { + WSContentSend_P(HTTP_SCRIPT_RELOAD_TIME, HTTP_RESTART_RECONNECT_TIME); + } +#else + // In case of type 3 (New network has been configured) do not refresh the page. Just halt. + // The IP of the device while was in AP mode, won't be the new IP of the newly configured Network. + if (!(3 == type)) { WSContentSend_P(HTTP_SCRIPT_RELOAD_TIME, HTTP_RESTART_RECONNECT_TIME); } +#endif WSContentSendStyle(); if (type) { - WSContentSend_P(PSTR("
" D_CONFIGURATION_SAVED "
")); - if (2 == type) { - WSContentSend_P(PSTR("
" D_TRYING_TO_CONNECT "
")); + if (!(3 == type)) { + WSContentSend_P(PSTR("
%s

"), (type==2) ? PSTR(D_TRYING_TO_CONNECT) : PSTR(D_CONFIGURATION_SAVED) ); + } else { +#if (AFTER_INITIAL_WIFI_CONFIG_GO_TO_NEW_IP) + WSContentSend_P(PSTR("
" D_SUCCESSFUL_WIFI_CONNECTION "

" D_REDIRECTING_TO_NEW_IP "

"), WebColor(COL_TEXT_SUCCESS) ); +#else + WSContentSend_P(PSTR("
" D_SUCCESSFUL_WIFI_CONNECTION "

" D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "

"), WebColor(COL_TEXT_SUCCESS) ); +#endif } - WSContentSend_P(PSTR("
")); } - WSContentSend_P(HTTP_MSG_RSTRT); - if (HTTP_MANAGER == Web.state || reset_only) { - Web.state = HTTP_ADMIN; - } else { - WSContentSpaceButton(BUTTON_MAIN); + if (type<2) { + WSContentSend_P(HTTP_MSG_RSTRT); + if (HTTP_MANAGER == Web.state || reset_only) { + Web.state = HTTP_ADMIN; + } else { + WSContentSpaceButton(BUTTON_MAIN); + } } WSContentStop(); - ShowWebSource(SRC_WEBGUI); - TasmotaGlobal.restart_flag = 2; + if (!(2 == type)) { + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_RESTART)); + ShowWebSource(SRC_WEBGUI); + TasmotaGlobal.restart_flag = 2; + } } /*********************************************************************************************/ @@ -919,6 +988,10 @@ void HandleRoot(void) HandleWifiLogin(); } else { if (!strlen(SettingsText(SET_WEBPWD)) || (((Webserver->arg(F("USER1")) == WEB_USERNAME ) && (Webserver->arg(F("PASS1")) == SettingsText(SET_WEBPWD) )) || HTTP_MANAGER_RESET_ONLY == Web.state)) { + if (!Web.initial_config) { + Web.initial_config = !strlen(SettingsText(SET_STASSID1)); + if (Web.initial_config) { AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Blank Device - Initial Configuration")); } + } HandleWifiConfiguration(); } else { // wrong user and pass @@ -1648,26 +1721,77 @@ String HtmlEscape(const String unescaped) { const char kEncryptionType[] PROGMEM = "|||" D_WPA_PSK "||" D_WPA2_PSK "|" D_WEP "||" D_NONE "|" D_AUTO; void HandleWifiConfiguration(void) { + char tmp[TOPSZ]; // Max length is currently 150 + if (!HttpCheckPriviledgedAccess(!WifiIsInManagerMode())) { return; } AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_WIFI)); if (Webserver->hasArg(F("save")) && HTTP_MANAGER_RESET_ONLY != Web.state) { - WifiSaveSettings(); - WebRestart(2); + if ( WifiIsInManagerMode() ) { + // Test WIFI Connection to Router + // As Tasmota is in this case in AP mode, a STA connection can be established too at the same time + Web.wifi_test_counter = 9; // seconds to test user's proposed AP + Web.wifiTest = WIFI_TESTING; + + Web.save_data_counter = TasmotaGlobal.save_data_counter; + TasmotaGlobal.save_data_counter = 0; // Stop auto saving data - Updating Settings + Settings.save_data = 0; + + Web.old_wificonfig = TasmotaGlobal.wifi_state_flag; + Settings.sta_config = WIFI_MANAGER; + TasmotaGlobal.wifi_state_flag = Settings.sta_config; + + TasmotaGlobal.sleep = 0; // Disable sleep + TasmotaGlobal.restart_flag = 0; // No restart + TasmotaGlobal.ota_state_flag = 0; // No OTA +// TasmotaGlobal.blinks = 0; // Disable blinks initiated by WifiManager + + WebGetArg(PSTR("s1"), tmp, sizeof(tmp)); // SSID1 + SettingsUpdateText(SET_STASSID1, tmp); + WebGetArg(PSTR("p1"), tmp, sizeof(tmp)); // PASSWORD1 + SettingsUpdateText(SET_STAPWD1, tmp); + + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECTING_TO_AP " %s " D_AS " %s ..."), + SettingsText(SET_STASSID1), TasmotaGlobal.hostname); + + WiFi.begin(SettingsText(SET_STASSID1), SettingsText(SET_STAPWD1)); + + WebRestart(2); + } else { + // STATION MODE or MIXED + // Save the config and restart + WifiSaveSettings(); + WebRestart(1); + } return; } + if ( WIFI_TEST_FINISHED_SUCCESSFUL == Web.wifiTest ) { + Web.wifiTest = WIFI_NOT_TESTING; +#if (RESTART_AFTER_INITIAL_WIFI_CONFIG) + WebRestart(3); +#else + HandleRoot(); +#endif + } + WSContentStart_P(PSTR(D_CONFIGURE_WIFI), !WifiIsInManagerMode()); WSContentSend_P(HTTP_SCRIPT_WIFI); + if (WifiIsInManagerMode()) { WSContentSend_P(HTTP_SCRIPT_HIDE); } + if (WIFI_TESTING == Web.wifiTest) { WSContentSend_P(HTTP_SCRIPT_RELOAD_TIME, HTTP_RESTART_RECONNECT_TIME); } #ifdef USE_ENHANCED_GUI_WIFI_SCAN WSContentSendStyle_P(HTTP_HEAD_STYLE_SSI, WebColor(COL_TEXT)); #else WSContentSendStyle(); #endif // USE_ENHANCED_GUI_WIFI_SCAN + bool limitScannedNetworks = true; if (HTTP_MANAGER_RESET_ONLY != Web.state) { - if (Webserver->hasArg(F("scan"))) { + if (WIFI_TESTING == Web.wifiTest) { + limitScannedNetworks = false; + } else { + if (Webserver->hasArg(F("scan"))) { limitScannedNetworks = false; } #ifdef USE_EMULATION UdpDisconnect(); #endif // USE_EMULATION @@ -1677,7 +1801,7 @@ void HandleWifiConfiguration(void) { if (0 == n) { AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_NO_NETWORKS_FOUND)); WSContentSend_P(PSTR(D_NO_NETWORKS_FOUND)); - WSContentSend_P(PSTR(". " D_REFRESH_TO_SCAN_AGAIN ".")); + limitScannedNetworks = false; // in order to show D_SCAN_FOR_WIFI_NETWORKS } else { //sort networks int indices[n]; @@ -1685,7 +1809,6 @@ void HandleWifiConfiguration(void) { indices[i] = i; } - // RSSI SORT for (uint32_t i = 0; i < n; i++) { for (uint32_t j = i + 1; j < n; j++) { @@ -1695,9 +1818,16 @@ void HandleWifiConfiguration(void) { } } + uint32_t networksToShow = n; + if ((limitScannedNetworks) && (networksToShow > MAX_WIFI_NETWORKS_TO_SHOW)) { networksToShow = MAX_WIFI_NETWORKS_TO_SHOW; } + + if (WifiIsInManagerMode()) { WSContentSend_P(PSTR("
" D_SELECT_YOUR_WIFI_NETWORK "

"), WebColor(COL_TEXT)); } + #ifdef USE_ENHANCED_GUI_WIFI_SCAN //display networks in page - for (uint32_t i = 0; i < n; i++) { + bool skipduplicated; + int ssid_showed = 0; + for (uint32_t i = 0; i < networksToShow; i++) { if (indices[i] < n) { int32_t rssi = WiFi.RSSI(indices[i]); String ssid = WiFi.SSID(indices[i]); @@ -1705,29 +1835,47 @@ void HandleWifiConfiguration(void) { ssid.c_str(), WiFi.BSSIDstr(indices[i]).c_str(), WiFi.channel(indices[i]), rssi); // Print SSID - WSContentSend_P(PSTR("
%s
"), HtmlEscape(ssid).c_str()); + if (!limitScannedNetworks) { + WSContentSend_P(PSTR("
%s
"), HtmlEscape(ssid).c_str()); + } + skipduplicated = false; String nextSSID = ""; // Handle all APs with the same SSID for (uint32_t j = 0; j < n; j++) { if ((indices[j] < n) && ((nextSSID = WiFi.SSID(indices[j])) == ssid)) { - // Update RSSI / quality - rssi = WiFi.RSSI(indices[j]); - uint32_t rssi_as_quality = WifiGetRssiAsQuality(rssi); - uint32_t num_bars = changeUIntScale(rssi_as_quality, 0, 100, 0, 4); + if (!skipduplicated) { + // Update RSSI / quality + rssi = WiFi.RSSI(indices[j]); + uint32_t rssi_as_quality = WifiGetRssiAsQuality(rssi); + uint32_t num_bars = changeUIntScale(rssi_as_quality, 0, 100, 0, 4); - // Print item - WSContentSend_P(PSTR("
%s(%d)
"), - rssi, rssi_as_quality, - WiFi.BSSIDstr(indices[j]).c_str(), - WiFi.channel(indices[j]) - ); - // Print signal strength indicator - for (uint32_t k = 0; k < 4; ++k) { - WSContentSend_P(PSTR(""), k, (num_bars < k) ? PSTR(" o30") : PSTR("")); + if (limitScannedNetworks) { + // Print SSID and item + WSContentSend_P(PSTR("
%s
"), rssi, rssi_as_quality, HtmlEscape(ssid).c_str()); + // Print signal strength indicator + for (uint32_t k = 0; k < 4; ++k) { + WSContentSend_P(PSTR(""), k, (num_bars < k) ? PSTR(" o30") : PSTR("")); + } + WSContentSend_P(PSTR("
")); + ssid_showed++; + skipduplicated = true; // For the simplified page, just show 1 SSID if there are many Networks with the same + } else { + // Print item + WSContentSend_P(PSTR("
%s(%d)
"), + rssi, rssi_as_quality, + WiFi.BSSIDstr(indices[j]).c_str(), + WiFi.channel(indices[j]) + ); + // Print signal strength indicator + for (uint32_t k = 0; k < 4; ++k) { + WSContentSend_P(PSTR(""), k, (num_bars < k) ? PSTR(" o30") : PSTR("")); + } + WSContentSend_P(PSTR("
")); + } + } else { + if (ssid_showed <= networksToShow ) { networksToShow++; } } - WSContentSend_P(PSTR("
")); - indices[j] = n; } delay(0); @@ -1750,7 +1898,7 @@ void HandleWifiConfiguration(void) { } //display networks in page - for (uint32_t i = 0; i < n; i++) { + for (uint32_t i = 0; i < networksToShow; i++) { if (-1 == indices[i]) { continue; } // skip dups int32_t rssi = WiFi.RSSI(indices[i]); DEBUG_CORE_LOG(PSTR(D_LOG_WIFI D_SSID " %s, " D_BSSID " %s, " D_CHANNEL " %d, " D_RSSI " %d"), @@ -1778,21 +1926,44 @@ void HandleWifiConfiguration(void) { WSContentSend_P(PSTR("
")); } + } + + if (limitScannedNetworks) { + WSContentSend_P(PSTR("
")); } else { WSContentSend_P(PSTR("
")); } // As WIFI_HOSTNAME may contain %s-%04d it cannot be part of HTTP_FORM_WIFI where it will exception - WSContentSend_P(HTTP_FORM_WIFI, SettingsText(SET_STASSID1), SettingsText(SET_STASSID2), WIFI_HOSTNAME, WIFI_HOSTNAME, SettingsText(SET_HOSTNAME), SettingsText(SET_CORS)); + if (WifiIsInManagerMode()) { + WSContentSend_P(HTTP_FORM_WIFI_INITIAL, SettingsText(SET_STASSID1) ); + } else { + WSContentSend_P(HTTP_FORM_WIFI, SettingsText(SET_STASSID1), SettingsText(SET_STASSID2), WIFI_HOSTNAME, WIFI_HOSTNAME, SettingsText(SET_HOSTNAME), SettingsText(SET_CORS)); + } WSContentSend_P(HTTP_FORM_END); } if (WifiIsInManagerMode()) { #ifndef FIRMWARE_MINIMAL - WSContentSpaceButton(BUTTON_RESTORE); - WSContentButton(BUTTON_RESET_CONFIGURATION); + if (WIFI_TESTING == Web.wifiTest) { + WSContentSend_P(PSTR("

" D_TRYING_TO_CONNECT "
%s

"), + WebColor(COL_TEXT_WARNING), + SettingsText(SET_STASSID1) + ); + } else if (WIFI_TEST_FINISHED_BAD == Web.wifiTest) { + WSContentSend_P(PSTR("

" D_CONNECT_FAILED_TO " %s
" D_CHECK_CREDENTIALS "

"), + WebColor(COL_TEXT_WARNING), + SettingsText(SET_STASSID1) + ); + } + // More Options Button + WSContentSend_P(PSTR("

"), + (WIFI_TEST_FINISHED_BAD == Web.wifiTest) ? "none" : Web.initial_config ? "block" : "none", Web.initial_config ? "block" : "none" + ); + WSContentSpaceButton(BUTTON_RESTORE, !Web.initial_config); + WSContentButton(BUTTON_RESET_CONFIGURATION, !Web.initial_config); #endif // FIRMWARE_MINIMAL - WSContentSpaceButton(BUTTON_RESTART); + WSContentSpaceButton(BUTTON_RESTART, !Web.initial_config); } else { WSContentSpaceButton(BUTTON_CONFIGURATION); } @@ -3116,6 +3287,47 @@ bool Xdrv01(uint8_t function) if (Settings.flag2.emulation) { PollUdp(); } #endif // USE_EMULATION break; + case FUNC_EVERY_SECOND: + if (Web.initial_config) { + Wifi.config_counter = 200; // Do not restart the device if it has SSId Blank + } + if (Web.wifi_test_counter) { + Web.wifi_test_counter--; + AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_TRYING_TO_CONNECT " %s"), SettingsText(SET_STASSID1)); + if ( WifiCheck_hasIP(WiFi.localIP()) ) { // Got IP - Connection Established + Web.wifi_test_counter = 0; + Web.wifiTest = WIFI_TEST_FINISHED_SUCCESSFUL; + AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CMND_SSID "1 %s: " D_CONNECTED " - " D_IP_ADDRESS " %_I"), SettingsText(SET_STASSID1), (uint32_t)WiFi.localIP()); +// TasmotaGlobal.blinks = 255; // Signal wifi connection with blinks + Settings.sta_config = Web.old_wificonfig; + TasmotaGlobal.wifi_state_flag = Settings.sta_config; + TasmotaGlobal.save_data_counter = Web.save_data_counter; + Settings.save_data = Web.save_data_counter; + SettingsSaveAll(); +#if (!RESTART_AFTER_INITIAL_WIFI_CONFIG) + Web.initial_config = false; + Web.state = HTTP_ADMIN; +#endif + } else if (!Web.wifi_test_counter) { // Test TimeOut + Web.wifi_test_counter = 0; + Web.wifiTest = WIFI_TEST_FINISHED_BAD; + switch (WiFi.status()) { + case WL_CONNECTED: + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECT_FAILED_NO_IP_ADDRESS)); + break; + case WL_NO_SSID_AVAIL: + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECT_FAILED_AP_NOT_REACHED)); + break; + case WL_CONNECT_FAILED: + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECT_FAILED_WRONG_PASSWORD)); + break; + default: // WL_IDLE_STATUS and WL_DISCONNECTED + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECT_FAILED_AP_TIMEOUT)); + } + int n = WiFi.scanNetworks(); // restart scan + } + } + break; case FUNC_COMMAND: result = DecodeCommand(kWebCommands, WebCommand); break;