From 02aa43238416a966ecd1c00ab8065e7bc1e93758 Mon Sep 17 00:00:00 2001
From: Adrian Scillato
Date: Tue, 2 Aug 2022 22:25:20 -0700
Subject: [PATCH 1/6] Move Wifi Struct definition to a header file
Move Wifi Struct definition to a header file in order to be accessible from functions outside support_wifi.ino file
---
tasmota/include/tasmota_globals.h | 34 +++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/tasmota/include/tasmota_globals.h b/tasmota/include/tasmota_globals.h
index abdb5deb2..deaebd316 100644
--- a/tasmota/include/tasmota_globals.h
+++ b/tasmota/include/tasmota_globals.h
@@ -593,4 +593,38 @@ bool first_device_group_is_local = true;
/*********************************************************************************************/
+
+enum WifiTestOptions { WIFI_NOT_TESTING, WIFI_TESTING, WIFI_TEST_FINISHED, WIFI_TEST_FINISHED_BAD };
+
+struct WIFI {
+ uint32_t last_event = 0; // Last wifi connection event
+ uint32_t downtime = 0; // Wifi down duration
+ uint16_t link_count = 0; // Number of wifi re-connect
+ uint8_t counter;
+ uint8_t retry_init;
+ uint8_t retry;
+ uint8_t max_retry;
+ uint8_t status;
+ uint8_t config_type = 0;
+ uint8_t config_counter = 0;
+ uint8_t scan_state;
+ uint8_t bssid[6];
+ int8_t best_network_db;
+ uint8_t wifiTest = WIFI_NOT_TESTING;
+ uint8_t wifi_test_counter = 0;
+ uint16_t save_data_counter = 0;
+ uint8_t old_wificonfig = MAX_WIFI_OPTION; // means "nothing yet saved here"
+ bool wifi_test_AP_TIMEOUT = false;
+ bool wifi_Test_Restart = false;
+ bool wifi_Test_Save_SSID2 = false;
+} Wifi;
+
+// Reference. WiFi.encryptionType =
+// 2 : ENC_TYPE_TKIP - WPA / PSK
+// 4 : ENC_TYPE_CCMP - WPA2 / PSK
+// 5 : ENC_TYPE_WEP - WEP
+// 7 : ENC_TYPE_NONE - open network
+// 8 : ENC_TYPE_AUTO - WPA / WPA2 / PSK
+const char kWifiEncryptionTypes[] PROGMEM = "0" "|" "1" "|" "WPA/PSK" "|" "3" "|" "WPA2/PSK" "|" "WEP" "|" "6" "|" "OPEN" "|" "WPA/WPA2/PSK";
+
#endif // _TASMOTA_GLOBALS_H_
From de84f6781f11723bd44ffd6cf6fa8f41b8f14c3d Mon Sep 17 00:00:00 2001
From: Adrian Scillato
Date: Tue, 2 Aug 2022 22:28:59 -0700
Subject: [PATCH 2/6] Add new commands definitions (WifiScan, WifiTest)
---
tasmota/include/i18n.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h
index 3a8a7382c..bb8e27f3d 100644
--- a/tasmota/include/i18n.h
+++ b/tasmota/include/i18n.h
@@ -207,6 +207,11 @@
#define D_JSON_WEIGHT "Weight"
#define D_JSON_WIFI "Wifi"
#define D_JSON_WIFI_MODE "Mode"
+#define D_JSON_NOT_STARTED "Not Started"
+#define D_JSON_SCANNING "Scanning"
+#define D_JSON_TESTING "Testing"
+#define D_JSON_BUSY "Busy"
+#define D_JSON_ENCRYPTION "Encryption"
#define D_JSON_WRONG "Wrong"
#define D_JSON_WRONG_PARAMETERS "Wrong parameters"
#define D_JSON_YESTERDAY "Yesterday"
@@ -309,6 +314,8 @@
#define D_CMND_PASSWORD "Password"
#define D_CMND_HOSTNAME "Hostname"
#define D_CMND_WIFI "Wifi"
+#define D_CMND_WIFISCAN "WiFiScan"
+#define D_CMND_WIFITEST "WiFiTest"
#define D_CMND_ETHERNET "Ethernet"
#define D_CMND_WIFICONFIG "WifiConfig"
#define D_WCFG_0_RESTART "Restart"
From ca2bc5ae70dd4f034fe2bb92f123046e5d65f8ed Mon Sep 17 00:00:00 2001
From: Adrian Scillato
Date: Tue, 2 Aug 2022 22:31:29 -0700
Subject: [PATCH 3/6] Add new logic for wifiscan command
---
tasmota/tasmota_support/support_wifi.ino | 92 ++++++++++++++++++------
1 file changed, 71 insertions(+), 21 deletions(-)
diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino
index 7215e4682..e715b0429 100644
--- a/tasmota/tasmota_support/support_wifi.ino
+++ b/tasmota/tasmota_support/support_wifi.ino
@@ -45,22 +45,6 @@ const uint8_t WIFI_RETRY_OFFSET_SEC = WIFI_RETRY_SECONDS; // seconds
#include // IPv6 DualStack
#endif // LWIP_IPV6=1
-struct WIFI {
- uint32_t last_event = 0; // Last wifi connection event
- uint32_t downtime = 0; // Wifi down duration
- uint16_t link_count = 0; // Number of wifi re-connect
- uint8_t counter;
- uint8_t retry_init;
- uint8_t retry;
- uint8_t max_retry;
- uint8_t status;
- uint8_t config_type = 0;
- uint8_t config_counter = 0;
- uint8_t scan_state;
- uint8_t bssid[6];
- int8_t best_network_db;
-} Wifi;
-
int WifiGetRssiAsQuality(int rssi)
{
int quality = 0;
@@ -351,6 +335,75 @@ void WifiBeginAfterScan(void)
}
}
}
+
+ // Init scan for wifiscan command
+ if (6 == Wifi.scan_state) {
+ if (wifi_scan_result != WIFI_SCAN_RUNNING) {
+ WiFi.scanNetworks(true); // Start wifi scan async
+ Wifi.scan_state++;
+ AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI "Network scan started..."));
+ return;
+ }
+ }
+ // Check scan done
+ if (7 == Wifi.scan_state) {
+ if (wifi_scan_result != WIFI_SCAN_RUNNING) {
+ AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI "Network scan finished..."));
+ Wifi.scan_state++;
+ return;
+ }
+ }
+ // Scan done. Show SSId's scan result by MQTT and in console
+ if (7 < Wifi.scan_state) {
+ Wifi.scan_state++;
+
+ ResponseClear();
+
+ uint32_t initial_item = (Wifi.scan_state - 9)*10;
+
+ if ( wifi_scan_result > initial_item ) {
+ // Sort networks by RSSI
+ uint32_t indexes[wifi_scan_result];
+ for (uint32_t i = 0; i < wifi_scan_result; i++) {
+ indexes[i] = i;
+ }
+ for (uint32_t i = 0; i < wifi_scan_result; i++) {
+ for (uint32_t j = i + 1; j < wifi_scan_result; j++) {
+ if (WiFi.RSSI(indexes[j]) > WiFi.RSSI(indexes[i])) {
+ std::swap(indexes[i], indexes[j]);
+ }
+ }
+ }
+ delay(0);
+
+ // Publish the list
+ char stemp1[20];
+ uint32_t end_item = ( wifi_scan_result > initial_item + 10 ) ? initial_item + 10 : wifi_scan_result;
+ for (uint32_t i = initial_item; i < end_item; i++) {
+ Response_P(PSTR("{\"" D_CMND_WIFISCAN "\":{\"" D_STATUS5_NETWORK "%d\":{\"" D_SSID "\":\"%s\", \"" D_BSSID "\":\"%s\", \"" D_CHANNEL
+ "\":\"%d\", \"" D_JSON_SIGNAL "\":\"%d\", \"" D_RSSI "\":\"%d\", \"" D_JSON_ENCRYPTION "\":\"%s\"}}}"),
+ i+1,
+ WiFi.SSID(indexes[i]).c_str(),
+ WiFi.BSSIDstr(indexes[i]).c_str(),
+ WiFi.channel(indexes[i]),
+ WiFi.RSSI(indexes[i]),
+ WifiGetRssiAsQuality(WiFi.RSSI(indexes[i])),
+ GetTextIndexed(stemp1, sizeof(stemp1), WiFi.encryptionType(indexes[i]), kWifiEncryptionTypes));
+ MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_CMND_WIFISCAN));
+ }
+ } else if (9 == Wifi.scan_state) {
+ Response_P(PSTR("{\"" D_CMND_WIFISCAN "\":\"" D_NO_NETWORKS_FOUND "\"}"));
+ MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_CMND_WIFISCAN));
+ }
+ delay(0);
+ }
+ // Wait 1 minute before cleaning the results so the user can ask for the them using wifiscan command (HTTP use-case)
+ if (69 == Wifi.scan_state) {
+ //AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI "Network scan results deleted..."));
+ Wifi.scan_state = 0;
+ WiFi.scanDelete(); // Clean up Ram
+ }
+
}
uint16_t WifiLinkCount(void)
@@ -523,8 +576,6 @@ void WifiCheck(uint8_t param)
TasmotaGlobal.restart_flag = 2;
}
} else {
- if (Wifi.scan_state) { WifiBeginAfterScan(); }
-
if (Wifi.counter <= 0) {
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_WIFI D_CHECKING_CONNECTION));
Wifi.counter = WIFI_CHECK_SEC;
@@ -534,7 +585,7 @@ void WifiCheck(uint8_t param)
WifiSetState(1);
if (Settings->flag3.use_wifi_rescan) { // SetOption57 - Scan wifi network every 44 minutes for configured AP's
if (!(TasmotaGlobal.uptime % (60 * WIFI_RESCAN_MINUTES))) {
- Wifi.scan_state = 2;
+ if (!Wifi.scan_state) { Wifi.scan_state = 2; } // If wifi scan routine is free, use it. Otherwise, wait for next RESCAN TIME
}
}
} else {
@@ -542,6 +593,7 @@ void WifiCheck(uint8_t param)
Mdns.begun = 0;
}
}
+ if (Wifi.scan_state) { WifiBeginAfterScan(); }
}
}
@@ -881,5 +933,3 @@ uint32_t WifiGetNtp(void) {
ntp_server_id++; // Next server next time
return 0;
}
-
-
From 922ece0959f4a4f8aa25927b7f6a02616afc7df5 Mon Sep 17 00:00:00 2001
From: Adrian Scillato
Date: Tue, 2 Aug 2022 22:32:55 -0700
Subject: [PATCH 4/6] Add WifiScan and WifiTest commands
---
tasmota/tasmota_support/support_command.ino | 152 +++++++++++++++++++-
1 file changed, 150 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino
index a41560e12..5750e279b 100644
--- a/tasmota/tasmota_support/support_command.ino
+++ b/tasmota/tasmota_support/support_command.ino
@@ -33,7 +33,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix
D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|" D_CMND_WIFI "|" D_CMND_DNSTIMEOUT "|"
D_CMND_DEVICENAME "|" D_CMND_FN "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|"
D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_LEDPWM_ON "|" D_CMND_LEDPWM_OFF "|" D_CMND_LEDPWM_MODE "|"
- D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM"|" D_CMND_GLOBAL_PRESS "|" D_CMND_SWITCHTEXT "|"
+ D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM"|" D_CMND_GLOBAL_PRESS "|" D_CMND_SWITCHTEXT "|" D_CMND_WIFISCAN "|" D_CMND_WIFITEST "|"
#ifdef USE_I2C
D_CMND_I2CSCAN "|" D_CMND_I2CDRIVER "|"
#endif
@@ -68,7 +68,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = {
&CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig, &CmndWifi, &CmndDnsTimeout,
&CmndDevicename, &CmndFriendlyname, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd,
&CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndLedPwmOn, &CmndLedPwmOff, &CmndLedPwmMode,
- &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndGlobalPress, &CmndSwitchText,
+ &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndGlobalPress, &CmndSwitchText, &CmndWifiScan, &CmndWifiTest,
#ifdef USE_I2C
&CmndI2cScan, &CmndI2cDriver,
#endif
@@ -91,6 +91,154 @@ const char kWifiConfig[] PROGMEM =
/********************************************************************************************/
+#ifndef FIRMWARE_MINIMAL_ONLY
+void CmndWifiScan(void)
+{
+ if (XdrvMailbox.data_len > 0) {
+ if ( !Wifi.scan_state || Wifi.scan_state > 7 ) {
+ ResponseCmndChar(D_JSON_SCANNING);
+ Wifi.scan_state = 6;
+ } else {
+ ResponseCmndChar(D_JSON_BUSY);
+ }
+ } else {
+ if ( !Wifi.scan_state ) {
+ ResponseCmndChar(D_JSON_NOT_STARTED);
+ } else if ( Wifi.scan_state >= 1 && Wifi.scan_state <= 5 ) {
+ ResponseCmndChar(D_JSON_BUSY);
+ } else if ( Wifi.scan_state >= 6 && Wifi.scan_state <= 7 ) {
+ ResponseCmndChar(D_JSON_SCANNING);
+ } else { //show scan result
+ Response_P(PSTR("{\"" D_CMND_WIFISCAN "\":"));
+
+ if (WiFi.scanComplete() > 0) {
+ // Sort networks by RSSI
+ uint32_t indexes[WiFi.scanComplete()];
+ for (uint32_t i = 0; i < WiFi.scanComplete(); i++) {
+ indexes[i] = i;
+ }
+ for (uint32_t i = 0; i < WiFi.scanComplete(); i++) {
+ for (uint32_t j = i + 1; j < WiFi.scanComplete(); j++) {
+ if (WiFi.RSSI(indexes[j]) > WiFi.RSSI(indexes[i])) {
+ std::swap(indexes[i], indexes[j]);
+ }
+ }
+ }
+ delay(0);
+
+ char stemp1[20];
+ for (uint32_t i = 0; i < WiFi.scanComplete(); i++) {
+ ResponseAppend_P(PSTR("{\"" D_STATUS5_NETWORK "%d\":{\"" D_SSID "\":\"%s\", \"" D_BSSID "\":\"%s\", \"" D_CHANNEL
+ "\":\"%d\", \"" D_JSON_SIGNAL "\":\"%d\", \"" D_RSSI "\":\"%d\", \"" D_JSON_ENCRYPTION "\":\"%s\"}"),
+ i+1,
+ WiFi.SSID(indexes[i]).c_str(),
+ WiFi.BSSIDstr(indexes[i]).c_str(),
+ WiFi.channel(indexes[i]),
+ WiFi.RSSI(indexes[i]),
+ WifiGetRssiAsQuality(WiFi.RSSI(indexes[i])),
+ GetTextIndexed(stemp1, sizeof(stemp1), WiFi.encryptionType(indexes[i]), kWifiEncryptionTypes));
+ if ( ResponseSize() < ResponseLength() + 300 ) { break; }
+ if ( i < WiFi.scanComplete() -1 ) { ResponseAppend_P(PSTR(", ")); }
+ //AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI "MAX SIZE: %d, SIZE: %d"),ResponseSize(),ResponseLength());
+ }
+ ResponseJsonEnd();
+ } else {
+ ResponseAppend_P(PSTR("\"" D_NO_NETWORKS_FOUND "\""));
+ }
+ ResponseJsonEnd();
+ MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_CMND_WIFISCAN));
+ }
+ }
+}
+
+void CmndWifiTest(void)
+{
+ // Test WIFI Connection to Router if Tasmota is in AP mode since in AP mode, a STA connection can be established
+ // at the same time for testing the connection.
+
+#ifdef USE_WEBSERVER
+ if (!WifiIsInManagerMode()) { ResponseCmndError(); return; }
+
+ if ( (XdrvMailbox.data_len > 0) ) {
+
+ if (Wifi.wifiTest != WIFI_TESTING) { // Start Test
+ char* pos = strchr(XdrvMailbox.data, '+');
+ if (pos != nullptr) {
+ char ssid_test[XdrvMailbox.data_len];
+ char pswd_test[XdrvMailbox.data_len];
+ subStr(ssid_test, XdrvMailbox.data, "+", 1);
+ subStr(pswd_test, XdrvMailbox.data, "+", 2);
+ ResponseCmndIdxChar(D_JSON_TESTING);
+ //Response_P(PSTR("{\"%s%d\":{\"Network\":\"%s,\"PASS\":\"%s\"}}"), XdrvMailbox.command, XdrvMailbox.index, ssid_test, pswd_test);
+
+ if (WIFI_NOT_TESTING == Wifi.wifiTest) {
+ if (MAX_WIFI_OPTION == Wifi.old_wificonfig) { Wifi.old_wificonfig = Settings->sta_config; }
+ TasmotaGlobal.wifi_state_flag = Settings->sta_config = WIFI_MANAGER;
+ Wifi.save_data_counter = TasmotaGlobal.save_data_counter;
+ }
+
+ Wifi.wifi_test_counter = 9; // seconds to test user's proposed AP
+ Wifi.wifiTest = WIFI_TESTING;
+ TasmotaGlobal.save_data_counter = 0; // Stop auto saving data - Updating Settings
+ Settings->save_data = 0;
+ TasmotaGlobal.sleep = 0; // Disable sleep
+ TasmotaGlobal.restart_flag = 0; // No restart
+ TasmotaGlobal.ota_state_flag = 0; // No OTA
+
+ Wifi.wifi_Test_Restart = false;
+ Wifi.wifi_Test_Save_SSID2 = false;
+ if (0 == XdrvMailbox.index) { Wifi.wifi_Test_Restart = true; } // If WifiTest is successful, save data on SSID1 and restart
+ if (2 == XdrvMailbox.index) { Wifi.wifi_Test_Save_SSID2 = true; } // If WifiTest is successful, save data on SSID2
+
+ SettingsUpdateText(Wifi.wifi_Test_Save_SSID2 ? SET_STASSID2 : SET_STASSID1, ssid_test);
+ SettingsUpdateText(Wifi.wifi_Test_Save_SSID2 ? SET_STAPWD2 : SET_STAPWD1, pswd_test);
+
+ AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECTING_TO_AP " %s " D_AS " %s ..."),
+ SettingsText(Wifi.wifi_Test_Save_SSID2 ? SET_STASSID2 : SET_STASSID1), TasmotaGlobal.hostname);
+
+ WiFi.begin(SettingsText(Wifi.wifi_Test_Save_SSID2 ? SET_STASSID2 : SET_STASSID1), SettingsText(Wifi.wifi_Test_Save_SSID2 ? SET_STAPWD2 : SET_STAPWD1));
+ }
+ } else {
+ ResponseCmndChar(D_JSON_BUSY);
+ }
+
+ } else {
+ switch (Wifi.wifiTest) {
+ case WIFI_TESTING:
+ ResponseCmndChar(D_JSON_TESTING);
+ break;
+ case WIFI_NOT_TESTING:
+ ResponseCmndChar(D_JSON_NOT_STARTED);
+ break;
+ case WIFI_TEST_FINISHED:
+ ResponseCmndChar(Wifi.wifi_test_AP_TIMEOUT ? D_CONNECT_FAILED_AP_TIMEOUT : D_JSON_SUCCESSFUL);
+ break;
+ case WIFI_TEST_FINISHED_BAD:
+
+ switch (WiFi.status()) {
+ case WL_CONNECTED:
+ ResponseCmndChar(D_CONNECT_FAILED_NO_IP_ADDRESS);
+ break;
+ case WL_NO_SSID_AVAIL:
+ ResponseCmndChar(D_CONNECT_FAILED_AP_NOT_REACHED);
+ break;
+ case WL_CONNECT_FAILED:
+ ResponseCmndChar(D_CONNECT_FAILED_WRONG_PASSWORD);
+ break;
+ default: // WL_IDLE_STATUS and WL_DISCONNECTED - SSId in range but no answer from the router
+ ResponseCmndChar(D_CONNECT_FAILED_AP_TIMEOUT);
+ }
+
+ break;
+ }
+ }
+#else
+ ResponseCmndError();
+#endif //USE_WEBSERVER
+}
+
+#endif // not defined FIRMWARE_MINIMAL_ONLY
+
void ResponseCmndNumber(int value) {
Response_P(S_JSON_COMMAND_NVALUE, XdrvMailbox.command, value);
}
From f514d1702d288729db53be31ddc38ff78e0e3f01 Mon Sep 17 00:00:00 2001
From: Adrian Scillato
Date: Tue, 2 Aug 2022 22:35:16 -0700
Subject: [PATCH 5/6] Move ScanNetwork variables to wifi struct
---
.../xdrv_01_9_webserver.ino | 99 +++++++++----------
1 file changed, 48 insertions(+), 51 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
index f6e81f76b..b169af2a4 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
@@ -426,14 +426,12 @@ const char kUploadErrors[] PROGMEM =
D_UPLOAD_ERR_1 "|" D_UPLOAD_ERR_2 "|" D_UPLOAD_ERR_3 "|" D_UPLOAD_ERR_4 "| |" D_UPLOAD_ERR_6 "|" D_UPLOAD_ERR_7 "|" D_UPLOAD_ERR_8 "|" D_UPLOAD_ERR_9;
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, WIFI_TEST_FINISHED_BAD};
-
+enum HttpOptions { HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER, HTTP_MANAGER_RESET_ONLY };
enum WebCmndStatus { WEBCMND_DONE=0, WEBCMND_WRONG_PARAMETERS, WEBCMND_CONNECT_FAILED, WEBCMND_HOST_NOT_FOUND, WEBCMND_MEMORY_ERROR
#ifdef USE_WEBGETCONFIG
, WEBCMND_FILE_NOT_FOUND, WEBCMND_OTHER_HTTP_ERROR, WEBCMND_CONNECTION_LOST, WEBCMND_INVALID_FILE
#endif // USE_WEBGETCONFIG
-};
+ };
DNSServer *DnsServer;
ESP8266WebServer *Webserver;
@@ -448,11 +446,6 @@ struct WEB {
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 = MAX_WIFI_OPTION; // means "nothing yet saved here"
- bool wifi_test_AP_TIMEOUT = false;
} Web;
// Helper function to avoid code duplication (saves 4k Flash)
@@ -607,6 +600,11 @@ void StartWebserver(int type, IPAddress ipweb)
XdrvCall(FUNC_WEB_ADD_HANDLER);
XsnsCall(FUNC_WEB_ADD_HANDLER);
#endif // Not FIRMWARE_MINIMAL
+
+ if (!Web.initial_config) {
+ Web.initial_config = !strlen(SettingsText(SET_STASSID1)) || !strlen(SettingsText(SET_STASSID2));
+ if (Web.initial_config) { AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Blank Device - Initial Configuration")); }
+ }
}
Web.reset_web_log_flag = false;
@@ -1135,10 +1133,6 @@ 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
@@ -1864,14 +1858,14 @@ void HandleWifiConfiguration(void) {
// 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
- if (WIFI_NOT_TESTING == Web.wifiTest) {
- if (MAX_WIFI_OPTION == Web.old_wificonfig) { Web.old_wificonfig = Settings->sta_config; }
+ if (WIFI_NOT_TESTING == Wifi.wifiTest) {
+ if (MAX_WIFI_OPTION == Wifi.old_wificonfig) { Wifi.old_wificonfig = Settings->sta_config; }
TasmotaGlobal.wifi_state_flag = Settings->sta_config = WIFI_MANAGER;
- Web.save_data_counter = TasmotaGlobal.save_data_counter;
+ Wifi.save_data_counter = TasmotaGlobal.save_data_counter;
}
- Web.wifi_test_counter = 9; // seconds to test user's proposed AP
- Web.wifiTest = WIFI_TESTING;
+ Wifi.wifi_test_counter = 9; // seconds to test user's proposed AP
+ Wifi.wifiTest = WIFI_TESTING;
TasmotaGlobal.save_data_counter = 0; // Stop auto saving data - Updating Settings
Settings->save_data = 0;
TasmotaGlobal.sleep = 0; // Disable sleep
@@ -1899,9 +1893,9 @@ void HandleWifiConfiguration(void) {
return;
}
- if ( WIFI_TEST_FINISHED == Web.wifiTest ) {
- Web.wifiTest = WIFI_NOT_TESTING;
- if (Web.wifi_test_AP_TIMEOUT) {
+ if ( WIFI_TEST_FINISHED == Wifi.wifiTest ) {
+ Wifi.wifiTest = WIFI_NOT_TESTING;
+ if (Wifi.wifi_test_AP_TIMEOUT) {
WebRestart(1); // Save credentials and Force Restart in STA only mode (11n-only routers)
} else {
#if (RESTART_AFTER_INITIAL_WIFI_CONFIG)
@@ -1915,7 +1909,7 @@ void HandleWifiConfiguration(void) {
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); }
+ if (WIFI_TESTING == Wifi.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
@@ -1924,7 +1918,7 @@ void HandleWifiConfiguration(void) {
bool limitScannedNetworks = true;
if (HTTP_MANAGER_RESET_ONLY != Web.state) {
- if (WIFI_TESTING == Web.wifiTest) {
+ if (WIFI_TESTING == Wifi.wifiTest) {
limitScannedNetworks = false;
} else {
if (Webserver->hasArg(F("scan"))) { limitScannedNetworks = false; }
@@ -2078,14 +2072,14 @@ void HandleWifiConfiguration(void) {
WSContentTextCenterStart(WebColor(COL_TEXT_WARNING));
WSContentSend_P(PSTR(""));
- if (WIFI_TESTING == Web.wifiTest) {
+ if (WIFI_TESTING == Wifi.wifiTest) {
WSContentSend_P(PSTR(D_TRYING_TO_CONNECT "
%s
"), SettingsText(SET_STASSID1));
- } else if (WIFI_TEST_FINISHED_BAD == Web.wifiTest) {
+ } else if (WIFI_TEST_FINISHED_BAD == Wifi.wifiTest) {
WSContentSend_P(PSTR(D_CONNECT_FAILED_TO " %s
" D_CHECK_CREDENTIALS ""), 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"
+ (WIFI_TEST_FINISHED_BAD == Wifi.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);
@@ -3711,44 +3705,47 @@ bool Xdrv01(uint8_t function)
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--;
+ if (Wifi.wifi_test_counter) {
+ Wifi.wifi_test_counter--;
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_TRYING_TO_CONNECT " %s"), SettingsText(SET_STASSID1));
if (WifiHasIP()) { // Got IP - Connection Established
- Web.wifi_test_AP_TIMEOUT = false;
- Web.wifi_test_counter = 0;
- Web.wifiTest = WIFI_TEST_FINISHED;
- AddLog(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());
+ Wifi.wifi_test_AP_TIMEOUT = false;
+ Wifi.wifi_test_counter = 0;
+ Wifi.wifiTest = WIFI_TEST_FINISHED;
+ AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CMND_SSID " %s: " D_CONNECTED " - " D_IP_ADDRESS " %_I"), SettingsText(Wifi.wifi_Test_Save_SSID2 ? SET_STASSID2 : SET_STASSID1), (uint32_t)WiFi.localIP());
// TasmotaGlobal.blinks = 255; // Signal wifi connection with blinks
- if (MAX_WIFI_OPTION != Web.old_wificonfig) {
- TasmotaGlobal.wifi_state_flag = Settings->sta_config = Web.old_wificonfig;
+ if (MAX_WIFI_OPTION != Wifi.old_wificonfig) {
+ TasmotaGlobal.wifi_state_flag = Settings->sta_config = Wifi.old_wificonfig;
}
- TasmotaGlobal.save_data_counter = Web.save_data_counter;
- Settings->save_data = Web.save_data_counter;
+ TasmotaGlobal.save_data_counter = Wifi.save_data_counter;
+ Settings->save_data = Wifi.save_data_counter;
SettingsSaveAll();
+
+ if ( Wifi.wifi_Test_Restart ) { TasmotaGlobal.restart_flag = 2; }
+
#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;
+ } else if (!Wifi.wifi_test_counter) { // Test TimeOut
+ Wifi.wifi_test_counter = 0;
+ Wifi.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));
- Web.wifi_test_AP_TIMEOUT = false;
+ Wifi.wifi_test_AP_TIMEOUT = false;
break;
case WL_NO_SSID_AVAIL:
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECT_FAILED_AP_NOT_REACHED));
- Web.wifi_test_AP_TIMEOUT = false;
+ Wifi.wifi_test_AP_TIMEOUT = false;
break;
case WL_CONNECT_FAILED:
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECT_FAILED_WRONG_PASSWORD));
- Web.wifi_test_AP_TIMEOUT = false;
+ Wifi.wifi_test_AP_TIMEOUT = false;
break;
default: // WL_IDLE_STATUS and WL_DISCONNECTED - SSId in range but no answer from the router
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECT_FAILED_AP_TIMEOUT));
- // If this error occurs twice, Tasmota will connect directly to the router without testing crendentials.
+ // If this error occurs twice, Tasmota will connect directly to the router without testing credentials.
// ESP8266 in AP+STA mode can manage only 11b and 11g, so routers that are 11n-ONLY won't respond.
// For this case, the user will see in the UI a message to check credentials. After that, if the user hits
// save and connect again, and the CONNECT_FAILED_AP_TIMEOUT is shown again, Credentials will be saved and
@@ -3756,17 +3753,17 @@ bool Xdrv01(uint8_t function)
//
// If it fails again, depending on the WIFICONFIG settings, the user will need to wait or will need to
// push 6 times the button to enable Tasmota AP mode again.
- if (Web.wifi_test_AP_TIMEOUT) {
- Web.wifiTest = WIFI_TEST_FINISHED;
- AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CMND_SSID "1 %s: " D_ATTEMPTING_CONNECTION), SettingsText(SET_STASSID1) );
- if (MAX_WIFI_OPTION != Web.old_wificonfig) {
- TasmotaGlobal.wifi_state_flag = Settings->sta_config = Web.old_wificonfig;
+ if (Wifi.wifi_test_AP_TIMEOUT) {
+ Wifi.wifiTest = WIFI_TEST_FINISHED;
+ AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CMND_SSID " %s: " D_ATTEMPTING_CONNECTION), SettingsText(Wifi.wifi_Test_Save_SSID2 ? SET_STASSID2 : SET_STASSID1) );
+ if (MAX_WIFI_OPTION != Wifi.old_wificonfig) {
+ TasmotaGlobal.wifi_state_flag = Settings->sta_config = Wifi.old_wificonfig;
}
- TasmotaGlobal.save_data_counter = Web.save_data_counter;
- Settings->save_data = Web.save_data_counter;
+ TasmotaGlobal.save_data_counter = Wifi.save_data_counter;
+ Settings->save_data = Wifi.save_data_counter;
SettingsSaveAll();
}
- Web.wifi_test_AP_TIMEOUT = true;
+ Wifi.wifi_test_AP_TIMEOUT = true;
}
WiFi.scanNetworks(); // restart scan
}
From 058f9ecea9c5b3d99e08846695fa66efb1f7ca15 Mon Sep 17 00:00:00 2001
From: Adrian Scillato
Date: Wed, 3 Aug 2022 02:39:51 -0700
Subject: [PATCH 6/6] Fix WifiScan JSON Response
---
tasmota/tasmota_support/support_command.ino | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino
index 5750e279b..026073422 100644
--- a/tasmota/tasmota_support/support_command.ino
+++ b/tasmota/tasmota_support/support_command.ino
@@ -127,8 +127,9 @@ void CmndWifiScan(void)
delay(0);
char stemp1[20];
+ ResponseAppend_P(PSTR("{"));
for (uint32_t i = 0; i < WiFi.scanComplete(); i++) {
- ResponseAppend_P(PSTR("{\"" D_STATUS5_NETWORK "%d\":{\"" D_SSID "\":\"%s\", \"" D_BSSID "\":\"%s\", \"" D_CHANNEL
+ ResponseAppend_P(PSTR("\"" D_STATUS5_NETWORK "%d\":{\"" D_SSID "\":\"%s\", \"" D_BSSID "\":\"%s\", \"" D_CHANNEL
"\":\"%d\", \"" D_JSON_SIGNAL "\":\"%d\", \"" D_RSSI "\":\"%d\", \"" D_JSON_ENCRYPTION "\":\"%s\"}"),
i+1,
WiFi.SSID(indexes[i]).c_str(),