mirror of
https://github.com/esphome/esphome.git
synced 2025-08-01 07:57:47 +00:00
[wifi] Allow fast_connect with multiple networks (#9947)
This commit is contained in:
parent
88d8cfe6a2
commit
fb379bbb88
@ -265,8 +265,6 @@ def _validate(config):
|
||||
networks = config.get(CONF_NETWORKS, [])
|
||||
if not networks:
|
||||
raise cv.Invalid("At least one network required for fast_connect!")
|
||||
if len(networks) != 1:
|
||||
raise cv.Invalid("Fast connect can only be used with one network!")
|
||||
|
||||
if CONF_USE_ADDRESS not in config:
|
||||
use_address = CORE.name + config[CONF_DOMAIN]
|
||||
|
@ -91,8 +91,11 @@ void WiFiComponent::start() {
|
||||
}
|
||||
|
||||
if (this->fast_connect_) {
|
||||
this->selected_ap_ = this->sta_[0];
|
||||
this->load_fast_connect_settings_();
|
||||
this->trying_loaded_ap_ = this->load_fast_connect_settings_();
|
||||
if (!this->trying_loaded_ap_) {
|
||||
this->ap_index_ = 0;
|
||||
this->selected_ap_ = this->sta_[this->ap_index_];
|
||||
}
|
||||
this->start_connecting(this->selected_ap_, false);
|
||||
} else {
|
||||
this->start_scanning();
|
||||
@ -121,6 +124,14 @@ void WiFiComponent::start() {
|
||||
this->wifi_apply_hostname_();
|
||||
}
|
||||
|
||||
void WiFiComponent::restart_adapter() {
|
||||
ESP_LOGW(TAG, "Restarting adapter");
|
||||
this->wifi_mode_(false, {});
|
||||
delay(100); // NOLINT
|
||||
this->num_retried_ = 0;
|
||||
this->retry_hidden_ = false;
|
||||
}
|
||||
|
||||
void WiFiComponent::loop() {
|
||||
this->wifi_loop_();
|
||||
const uint32_t now = App.get_loop_component_start_time();
|
||||
@ -140,7 +151,7 @@ void WiFiComponent::loop() {
|
||||
this->status_set_warning("waiting to reconnect");
|
||||
if (millis() - this->action_started_ > 5000) {
|
||||
if (this->fast_connect_ || this->retry_hidden_) {
|
||||
this->start_connecting(this->sta_[0], false);
|
||||
this->start_connecting(this->selected_ap_, false);
|
||||
} else {
|
||||
this->start_scanning();
|
||||
}
|
||||
@ -703,18 +714,30 @@ void WiFiComponent::retry_connect() {
|
||||
delay(10);
|
||||
if (!this->is_captive_portal_active_() && !this->is_esp32_improv_active_() &&
|
||||
(this->num_retried_ > 3 || this->error_from_callback_)) {
|
||||
if (this->num_retried_ > 5) {
|
||||
// If retry failed for more than 5 times, let's restart STA
|
||||
ESP_LOGW(TAG, "Restarting adapter");
|
||||
this->wifi_mode_(false, {});
|
||||
delay(100); // NOLINT
|
||||
if (this->fast_connect_) {
|
||||
if (this->trying_loaded_ap_) {
|
||||
this->trying_loaded_ap_ = false;
|
||||
this->ap_index_ = 0; // Retry from the first configured AP
|
||||
} else if (this->ap_index_ >= this->sta_.size() - 1) {
|
||||
ESP_LOGW(TAG, "No more APs to try");
|
||||
this->ap_index_ = 0;
|
||||
this->restart_adapter();
|
||||
} else {
|
||||
// Try next AP
|
||||
this->ap_index_++;
|
||||
}
|
||||
this->num_retried_ = 0;
|
||||
this->retry_hidden_ = false;
|
||||
this->selected_ap_ = this->sta_[this->ap_index_];
|
||||
} else {
|
||||
// Try hidden networks after 3 failed retries
|
||||
ESP_LOGD(TAG, "Retrying with hidden networks");
|
||||
this->retry_hidden_ = true;
|
||||
this->num_retried_++;
|
||||
if (this->num_retried_ > 5) {
|
||||
// If retry failed for more than 5 times, let's restart STA
|
||||
this->restart_adapter();
|
||||
} else {
|
||||
// Try hidden networks after 3 failed retries
|
||||
ESP_LOGD(TAG, "Retrying with hidden networks");
|
||||
this->retry_hidden_ = true;
|
||||
this->num_retried_++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this->num_retried_++;
|
||||
@ -761,17 +784,22 @@ bool WiFiComponent::is_esp32_improv_active_() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void WiFiComponent::load_fast_connect_settings_() {
|
||||
bool WiFiComponent::load_fast_connect_settings_() {
|
||||
SavedWifiFastConnectSettings fast_connect_save{};
|
||||
|
||||
if (this->fast_connect_pref_.load(&fast_connect_save)) {
|
||||
bssid_t bssid{};
|
||||
std::copy(fast_connect_save.bssid, fast_connect_save.bssid + 6, bssid.begin());
|
||||
this->ap_index_ = fast_connect_save.ap_index;
|
||||
this->selected_ap_ = this->sta_[this->ap_index_];
|
||||
this->selected_ap_.set_bssid(bssid);
|
||||
this->selected_ap_.set_channel(fast_connect_save.channel);
|
||||
|
||||
ESP_LOGD(TAG, "Loaded fast_connect settings");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void WiFiComponent::save_fast_connect_settings_() {
|
||||
@ -783,6 +811,7 @@ void WiFiComponent::save_fast_connect_settings_() {
|
||||
|
||||
memcpy(fast_connect_save.bssid, bssid.data(), 6);
|
||||
fast_connect_save.channel = channel;
|
||||
fast_connect_save.ap_index = this->ap_index_;
|
||||
|
||||
this->fast_connect_pref_.save(&fast_connect_save);
|
||||
|
||||
|
@ -60,6 +60,7 @@ struct SavedWifiSettings {
|
||||
struct SavedWifiFastConnectSettings {
|
||||
uint8_t bssid[6];
|
||||
uint8_t channel;
|
||||
int8_t ap_index;
|
||||
} PACKED; // NOLINT
|
||||
|
||||
enum WiFiComponentState : uint8_t {
|
||||
@ -256,6 +257,7 @@ class WiFiComponent : public Component {
|
||||
void setup() override;
|
||||
void start();
|
||||
void dump_config() override;
|
||||
void restart_adapter();
|
||||
/// WIFI setup_priority.
|
||||
float get_setup_priority() const override;
|
||||
float get_loop_priority() const override;
|
||||
@ -353,7 +355,7 @@ class WiFiComponent : public Component {
|
||||
bool is_captive_portal_active_();
|
||||
bool is_esp32_improv_active_();
|
||||
|
||||
void load_fast_connect_settings_();
|
||||
bool load_fast_connect_settings_();
|
||||
void save_fast_connect_settings_();
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
@ -400,12 +402,14 @@ class WiFiComponent : public Component {
|
||||
WiFiComponentState state_{WIFI_COMPONENT_STATE_OFF};
|
||||
WiFiPowerSaveMode power_save_{WIFI_POWER_SAVE_NONE};
|
||||
uint8_t num_retried_{0};
|
||||
uint8_t ap_index_{0};
|
||||
#if USE_NETWORK_IPV6
|
||||
uint8_t num_ipv6_addresses_{0};
|
||||
#endif /* USE_NETWORK_IPV6 */
|
||||
|
||||
// Group all boolean values together
|
||||
bool fast_connect_{false};
|
||||
bool trying_loaded_ap_{false};
|
||||
bool retry_hidden_{false};
|
||||
bool has_ap_{false};
|
||||
bool handled_connected_state_{false};
|
||||
|
Loading…
x
Reference in New Issue
Block a user