mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Merge branch 'wifi_sort' into integration
This commit is contained in:
		| @@ -35,7 +35,7 @@ void Syslog::log_(const int level, const char *tag, const char *message, size_t | |||||||
|     severity = LOG_LEVEL_TO_SYSLOG_SEVERITY[level]; |     severity = LOG_LEVEL_TO_SYSLOG_SEVERITY[level]; | ||||||
|   } |   } | ||||||
|   int pri = this->facility_ * 8 + severity; |   int pri = this->facility_ * 8 + severity; | ||||||
|   auto timestamp = this->time_->now().strftime("%b %d %H:%M:%S"); |   auto timestamp = this->time_->now().strftime("%b %e %H:%M:%S"); | ||||||
|   size_t len = message_len; |   size_t len = message_len; | ||||||
|   // remove color formatting |   // remove color formatting | ||||||
|   if (this->strip_ && message[0] == 0x1B && len > 11) { |   if (this->strip_ && message[0] == 0x1B && len > 11) { | ||||||
|   | |||||||
| @@ -505,6 +505,54 @@ void WiFiComponent::start_scanning() { | |||||||
|   this->state_ = WIFI_COMPONENT_STATE_STA_SCANNING; |   this->state_ = WIFI_COMPONENT_STATE_STA_SCANNING; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Helper function for WiFi scan result comparison | ||||||
|  | // Returns true if 'a' should be placed before 'b' in the sorted order | ||||||
|  | static bool wifi_scan_result_is_better(const WiFiScanResult &a, const WiFiScanResult &b) { | ||||||
|  |   // Matching networks always come before non-matching | ||||||
|  |   if (a.get_matches() && !b.get_matches()) | ||||||
|  |     return true; | ||||||
|  |   if (!a.get_matches() && b.get_matches()) | ||||||
|  |     return false; | ||||||
|  |  | ||||||
|  |   if (a.get_matches() && b.get_matches()) { | ||||||
|  |     // For APs with the same SSID, always prefer stronger signal | ||||||
|  |     // This helps with mesh networks and multiple APs | ||||||
|  |     if (a.get_ssid() == b.get_ssid()) { | ||||||
|  |       return a.get_rssi() > b.get_rssi(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // For different SSIDs, check priority first | ||||||
|  |     if (a.get_priority() != b.get_priority()) | ||||||
|  |       return a.get_priority() > b.get_priority(); | ||||||
|  |     // If priorities are equal, prefer stronger signal | ||||||
|  |     return a.get_rssi() > b.get_rssi(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Both don't match - sort by signal strength | ||||||
|  |   return a.get_rssi() > b.get_rssi(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Helper function for insertion sort of WiFi scan results | ||||||
|  | // Using insertion sort instead of std::stable_sort saves flash memory | ||||||
|  | // by avoiding template instantiations (std::rotate, std::stable_sort, lambdas) | ||||||
|  | // IMPORTANT: This sort is stable (preserves relative order of equal elements) | ||||||
|  | static void insertion_sort_scan_results(std::vector<WiFiScanResult> &results) { | ||||||
|  |   const size_t size = results.size(); | ||||||
|  |   for (size_t i = 1; i < size; i++) { | ||||||
|  |     // Make a copy to avoid issues with move semantics during comparison | ||||||
|  |     WiFiScanResult key = results[i]; | ||||||
|  |     int32_t j = i - 1; | ||||||
|  |  | ||||||
|  |     // Move elements that are worse than key to the right | ||||||
|  |     // For stability, we only move if key is strictly better than results[j] | ||||||
|  |     while (j >= 0 && wifi_scan_result_is_better(key, results[j])) { | ||||||
|  |       results[j + 1] = results[j]; | ||||||
|  |       j--; | ||||||
|  |     } | ||||||
|  |     results[j + 1] = key; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| void WiFiComponent::check_scanning_finished() { | void WiFiComponent::check_scanning_finished() { | ||||||
|   if (!this->scan_done_) { |   if (!this->scan_done_) { | ||||||
|     if (millis() - this->action_started_ > 30000) { |     if (millis() - this->action_started_ > 30000) { | ||||||
| @@ -535,30 +583,8 @@ void WiFiComponent::check_scanning_finished() { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   std::stable_sort(this->scan_result_.begin(), this->scan_result_.end(), |   // Sort scan results using insertion sort for better memory efficiency | ||||||
|                    [](const WiFiScanResult &a, const WiFiScanResult &b) { |   insertion_sort_scan_results(this->scan_result_); | ||||||
|                      // return true if a is better than b |  | ||||||
|                      if (a.get_matches() && !b.get_matches()) |  | ||||||
|                        return true; |  | ||||||
|                      if (!a.get_matches() && b.get_matches()) |  | ||||||
|                        return false; |  | ||||||
|  |  | ||||||
|                      if (a.get_matches() && b.get_matches()) { |  | ||||||
|                        // For APs with the same SSID, always prefer stronger signal |  | ||||||
|                        // This helps with mesh networks and multiple APs |  | ||||||
|                        if (a.get_ssid() == b.get_ssid()) { |  | ||||||
|                          return a.get_rssi() > b.get_rssi(); |  | ||||||
|                        } |  | ||||||
|  |  | ||||||
|                        // For different SSIDs, check priority first |  | ||||||
|                        if (a.get_priority() != b.get_priority()) |  | ||||||
|                          return a.get_priority() > b.get_priority(); |  | ||||||
|                        // If priorities are equal, prefer stronger signal |  | ||||||
|                        return a.get_rssi() > b.get_rssi(); |  | ||||||
|                      } |  | ||||||
|  |  | ||||||
|                      return a.get_rssi() > b.get_rssi(); |  | ||||||
|                    }); |  | ||||||
|  |  | ||||||
|   for (auto &res : this->scan_result_) { |   for (auto &res : this->scan_result_) { | ||||||
|     char bssid_s[18]; |     char bssid_s[18]; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user