From 0f02c75f66bb56318edae341830c3c71819f6b6f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 10 Nov 2025 20:03:50 -0600 Subject: [PATCH 1/4] [wifi] Change priority type from float to int8_t --- esphome/components/wifi/__init__.py | 2 +- esphome/components/wifi/wifi_component.cpp | 42 ++++++++++++++++++---- esphome/components/wifi/wifi_component.h | 24 +++++++------ 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/esphome/components/wifi/__init__.py b/esphome/components/wifi/__init__.py index 5f4190a933..358f920c2c 100644 --- a/esphome/components/wifi/__init__.py +++ b/esphome/components/wifi/__init__.py @@ -174,7 +174,7 @@ WIFI_NETWORK_STA = WIFI_NETWORK_BASE.extend( { cv.Optional(CONF_BSSID): cv.mac_address, cv.Optional(CONF_HIDDEN): cv.boolean, - cv.Optional(CONF_PRIORITY, default=0.0): cv.float_, + cv.Optional(CONF_PRIORITY, default=0): cv.int_range(min=-128, max=127), cv.Optional(CONF_EAP): EAP_AUTH_SCHEMA, } ) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 7279e0c783..1196902117 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -675,7 +675,7 @@ void WiFiComponent::start_connecting(const WiFiAP &ap, bool two) { } ESP_LOGI(TAG, - "Connecting to " LOG_SECRET("'%s'") " " LOG_SECRET("(%s)") " (priority %.1f, attempt %u/%u in phase %s)...", + "Connecting to " LOG_SECRET("'%s'") " " LOG_SECRET("(%s)") " (priority %d, attempt %u/%u in phase %s)...", ap.get_ssid().c_str(), ap.get_bssid().has_value() ? bssid_formatted.c_str() : LOG_STR_LITERAL("any"), priority, this->num_retried_ + 1, get_max_retries_for_phase(this->retry_phase_), LOG_STR_ARG(retry_phase_to_log_string(this->retry_phase_))); @@ -812,7 +812,7 @@ void WiFiComponent::print_connect_params_() { wifi_gateway_ip_().str().c_str(), wifi_dns_ip_(0).str().c_str(), wifi_dns_ip_(1).str().c_str()); #ifdef ESPHOME_LOG_HAS_VERBOSE if (const WiFiAP *config = this->get_selected_sta_(); config && config->get_bssid().has_value()) { - ESP_LOGV(TAG, " Priority: %.1f", this->get_sta_priority(*config->get_bssid())); + ESP_LOGV(TAG, " Priority: %d", this->get_sta_priority(*config->get_bssid())); } #endif #ifdef USE_WIFI_11KV_SUPPORT @@ -933,8 +933,7 @@ __attribute__((noinline)) static void log_scan_result(const WiFiScanResult &res) ESP_LOGI(TAG, "- '%s' %s" LOG_SECRET("(%s) ") "%s", res.get_ssid().c_str(), res.get_is_hidden() ? LOG_STR_LITERAL("(HIDDEN) ") : LOG_STR_LITERAL(""), bssid_s, LOG_STR_ARG(get_signal_bars(res.get_rssi()))); - ESP_LOGD(TAG, " Channel: %2u, RSSI: %3d dB, Priority: %4.1f", res.get_channel(), res.get_rssi(), - res.get_priority()); + ESP_LOGD(TAG, " Channel: %2u, RSSI: %3d dB, Priority: %4d", res.get_channel(), res.get_rssi(), res.get_priority()); } else { ESP_LOGD(TAG, "- " LOG_SECRET("'%s'") " " LOG_SECRET("(%s) ") "%s", res.get_ssid().c_str(), bssid_s, LOG_STR_ARG(get_signal_bars(res.get_rssi()))); @@ -1063,6 +1062,9 @@ void WiFiComponent::check_connecting_finished() { this->state_ = WIFI_COMPONENT_STATE_STA_CONNECTED; this->num_retried_ = 0; + // Reset all priorities if they're all the same (can't differentiate) + this->reset_priorities_if_all_same_(); + #ifdef USE_WIFI_FAST_CONNECT this->save_fast_connect_settings_(); #endif @@ -1291,6 +1293,27 @@ bool WiFiComponent::transition_to_phase_(WiFiRetryPhase new_phase) { return false; // Did not start scan, can proceed with connection } +/// Reset all BSSID priorities to 0 if they're all identical (can't differentiate) +/// Called when starting a fresh connection attempt or after successful connection +void WiFiComponent::reset_priorities_if_all_same_() { + if (this->sta_priorities_.empty()) { + return; + } + + int8_t first_priority = this->sta_priorities_[0].priority; + for (const auto &pri : this->sta_priorities_) { + if (pri.priority != first_priority) { + return; // Not all same, nothing to do + } + } + + // All priorities are identical, reset to 0 + ESP_LOGD(TAG, "Resetting all BSSID priorities (all identical)"); + for (auto &pri : this->sta_priorities_) { + pri.priority = 0; + } +} + /// Log failed connection attempt and decrease BSSID priority to avoid repeated failures /// This function identifies which BSSID was attempted (from scan results or config), /// decreases its priority by 1.0 to discourage future attempts, and logs the change. @@ -1321,8 +1344,9 @@ void WiFiComponent::log_and_adjust_priority_for_failed_connect_() { } // Decrease priority to avoid repeatedly trying the same failed BSSID - float old_priority = this->get_sta_priority(failed_bssid.value()); - float new_priority = old_priority - 1.0f; + int8_t old_priority = this->get_sta_priority(failed_bssid.value()); + int8_t new_priority = + (old_priority > std::numeric_limits::min()) ? (old_priority - 1) : std::numeric_limits::min(); this->set_sta_priority(failed_bssid.value(), new_priority); // Get SSID for logging @@ -1333,8 +1357,12 @@ void WiFiComponent::log_and_adjust_priority_for_failed_connect_() { ssid = config->get_ssid(); } - ESP_LOGD(TAG, "Failed " LOG_SECRET("'%s'") " " LOG_SECRET("(%s)") ", priority %.1f → %.1f", ssid.c_str(), + ESP_LOGD(TAG, "Failed " LOG_SECRET("'%s'") " " LOG_SECRET("(%s)") ", priority %d → %d", ssid.c_str(), format_mac_address_pretty(failed_bssid.value().data()).c_str(), old_priority, new_priority); + + // After adjusting priority, check if all priorities are now identical + // If so, reset them all to 0 to start fresh + this->reset_priorities_if_all_same_(); } /// Handle target advancement or retry counter increment when staying in the same phase diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index ed049544cf..c0616c2076 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -157,7 +157,7 @@ class WiFiAP { void set_eap(optional eap_auth); #endif // USE_WIFI_WPA2_EAP void set_channel(optional channel); - void set_priority(float priority) { priority_ = priority; } + void set_priority(int8_t priority) { priority_ = priority; } void set_manual_ip(optional manual_ip); void set_hidden(bool hidden); const std::string &get_ssid() const; @@ -167,7 +167,7 @@ class WiFiAP { const optional &get_eap() const; #endif // USE_WIFI_WPA2_EAP const optional &get_channel() const; - float get_priority() const { return priority_; } + int8_t get_priority() const { return priority_; } const optional &get_manual_ip() const; bool get_hidden() const; @@ -179,8 +179,8 @@ class WiFiAP { optional eap_; #endif // USE_WIFI_WPA2_EAP optional manual_ip_; - float priority_{0}; optional channel_; + int8_t priority_{0}; bool hidden_{false}; }; @@ -198,17 +198,17 @@ class WiFiScanResult { int8_t get_rssi() const; bool get_with_auth() const; bool get_is_hidden() const; - float get_priority() const { return priority_; } - void set_priority(float priority) { priority_ = priority; } + int8_t get_priority() const { return priority_; } + void set_priority(int8_t priority) { priority_ = priority; } bool operator==(const WiFiScanResult &rhs) const; protected: bssid_t bssid_; - std::string ssid_; - float priority_{0.0f}; uint8_t channel_; int8_t rssi_; + std::string ssid_; + int8_t priority_{0}; bool matches_{false}; bool with_auth_; bool is_hidden_; @@ -216,7 +216,7 @@ class WiFiScanResult { struct WiFiSTAPriority { bssid_t bssid; - float priority; + int8_t priority; }; enum WiFiPowerSaveMode : uint8_t { @@ -317,14 +317,14 @@ class WiFiComponent : public Component { } return false; } - float get_sta_priority(const bssid_t bssid) { + int8_t get_sta_priority(const bssid_t bssid) { for (auto &it : this->sta_priorities_) { if (it.bssid == bssid) return it.priority; } - return 0.0f; + return 0; } - void set_sta_priority(const bssid_t bssid, float priority) { + void set_sta_priority(const bssid_t bssid, int8_t priority) { for (auto &it : this->sta_priorities_) { if (it.bssid == bssid) { it.priority = priority; @@ -383,6 +383,8 @@ class WiFiComponent : public Component { int8_t find_next_hidden_sta_(int8_t start_index, bool include_explicit_hidden = true); /// Log failed connection and decrease BSSID priority to avoid repeated attempts void log_and_adjust_priority_for_failed_connect_(); + /// Reset all BSSID priorities to 0 if they're all identical (can't differentiate) + void reset_priorities_if_all_same_(); /// Advance to next target (AP/SSID) within current phase, or increment retry counter /// Called when staying in the same phase after a failed connection attempt void advance_to_next_target_or_increment_retry_(); From 130a8b853dfca25b34ffe93f3f8c7a15e4a46329 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 10 Nov 2025 20:14:40 -0600 Subject: [PATCH 2/4] missed one --- esphome/components/wifi/wifi_component.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 1196902117..8c9deee552 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -667,7 +667,7 @@ void WiFiComponent::save_wifi_sta(const std::string &ssid, const std::string &pa void WiFiComponent::start_connecting(const WiFiAP &ap, bool two) { // Log connection attempt at INFO level with priority std::string bssid_formatted; - float priority = 0.0f; + int8_t priority = 0; if (ap.get_bssid().has_value()) { bssid_formatted = format_mac_address_pretty(ap.get_bssid().value().data()); @@ -1575,9 +1575,9 @@ bool WiFiAP::get_hidden() const { return this->hidden_; } WiFiScanResult::WiFiScanResult(const bssid_t &bssid, std::string ssid, uint8_t channel, int8_t rssi, bool with_auth, bool is_hidden) : bssid_(bssid), - ssid_(std::move(ssid)), channel_(channel), rssi_(rssi), + ssid_(std::move(ssid)), with_auth_(with_auth), is_hidden_(is_hidden) {} bool WiFiScanResult::matches(const WiFiAP &config) const { From b80b0eb864281158112990eac22800bb0fe0a0d4 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 10 Nov 2025 20:17:03 -0600 Subject: [PATCH 3/4] save more --- esphome/components/wifi/wifi_component.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 8c9deee552..629d8c1238 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -1293,7 +1293,7 @@ bool WiFiComponent::transition_to_phase_(WiFiRetryPhase new_phase) { return false; // Did not start scan, can proceed with connection } -/// Reset all BSSID priorities to 0 if they're all identical (can't differentiate) +/// Reset all BSSID priorities if they're all identical (can't differentiate) /// Called when starting a fresh connection attempt or after successful connection void WiFiComponent::reset_priorities_if_all_same_() { if (this->sta_priorities_.empty()) { @@ -1307,11 +1307,10 @@ void WiFiComponent::reset_priorities_if_all_same_() { } } - // All priorities are identical, reset to 0 - ESP_LOGD(TAG, "Resetting all BSSID priorities (all identical)"); - for (auto &pri : this->sta_priorities_) { - pri.priority = 0; - } + // All priorities are identical - clear the vector to save memory + ESP_LOGD(TAG, "Clearing BSSID priorities (all identical)"); + this->sta_priorities_.clear(); + this->sta_priorities_.shrink_to_fit(); } /// Log failed connection attempt and decrease BSSID priority to avoid repeated failures From 6631e2ffb278ef3c66f2967c35fdd942e150510c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 10 Nov 2025 20:22:24 -0600 Subject: [PATCH 4/4] tweaks --- esphome/components/wifi/wifi_component.cpp | 12 ++++++------ esphome/components/wifi/wifi_component.h | 4 ++-- tests/components/wifi/common.yaml | 5 +++++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 629d8c1238..b7cac68cd7 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -1062,8 +1062,8 @@ void WiFiComponent::check_connecting_finished() { this->state_ = WIFI_COMPONENT_STATE_STA_CONNECTED; this->num_retried_ = 0; - // Reset all priorities if they're all the same (can't differentiate) - this->reset_priorities_if_all_same_(); + // Clear priority tracking if all priorities are identical + this->clear_priorities_if_all_same_(); #ifdef USE_WIFI_FAST_CONNECT this->save_fast_connect_settings_(); @@ -1293,9 +1293,9 @@ bool WiFiComponent::transition_to_phase_(WiFiRetryPhase new_phase) { return false; // Did not start scan, can proceed with connection } -/// Reset all BSSID priorities if they're all identical (can't differentiate) +/// Clear BSSID priority tracking if all priorities are identical (can't differentiate, saves memory) /// Called when starting a fresh connection attempt or after successful connection -void WiFiComponent::reset_priorities_if_all_same_() { +void WiFiComponent::clear_priorities_if_all_same_() { if (this->sta_priorities_.empty()) { return; } @@ -1360,8 +1360,8 @@ void WiFiComponent::log_and_adjust_priority_for_failed_connect_() { format_mac_address_pretty(failed_bssid.value().data()).c_str(), old_priority, new_priority); // After adjusting priority, check if all priorities are now identical - // If so, reset them all to 0 to start fresh - this->reset_priorities_if_all_same_(); + // If so, clear the vector to save memory + this->clear_priorities_if_all_same_(); } /// Handle target advancement or retry counter increment when staying in the same phase diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index c0616c2076..84dfa57ab1 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -383,8 +383,8 @@ class WiFiComponent : public Component { int8_t find_next_hidden_sta_(int8_t start_index, bool include_explicit_hidden = true); /// Log failed connection and decrease BSSID priority to avoid repeated attempts void log_and_adjust_priority_for_failed_connect_(); - /// Reset all BSSID priorities to 0 if they're all identical (can't differentiate) - void reset_priorities_if_all_same_(); + /// Clear BSSID priority tracking if all priorities are identical (saves memory) + void clear_priorities_if_all_same_(); /// Advance to next target (AP/SSID) within current phase, or increment retry counter /// Called when staying in the same phase after a failed connection attempt void advance_to_next_target_or_increment_retry_(); diff --git a/tests/components/wifi/common.yaml b/tests/components/wifi/common.yaml index af27f85092..5d9973cbc8 100644 --- a/tests/components/wifi/common.yaml +++ b/tests/components/wifi/common.yaml @@ -15,5 +15,10 @@ wifi: networks: - ssid: MySSID password: password1 + priority: 10 - ssid: MySSID2 password: password2 + priority: 5 + - ssid: MySSID3 + password: password3 + priority: 0