ESPHome  2023.3.1
wifi_component.cpp
Go to the documentation of this file.
1 #include "wifi_component.h"
2 
3 #if defined(USE_ESP32) || defined(USE_ESP_IDF)
4 #include <esp_wifi.h>
5 #endif
6 #ifdef USE_ESP8266
7 #include <user_interface.h>
8 #endif
9 
10 #include <utility>
11 #include <algorithm>
12 #include "lwip/err.h"
13 #include "lwip/dns.h"
14 
15 #include "esphome/core/helpers.h"
16 #include "esphome/core/log.h"
17 #include "esphome/core/hal.h"
18 #include "esphome/core/util.h"
20 
21 #ifdef USE_CAPTIVE_PORTAL
23 #endif
24 
25 #ifdef USE_IMPROV
27 #endif
28 
29 namespace esphome {
30 namespace wifi {
31 
32 static const char *const TAG = "wifi";
33 
35 
37  ESP_LOGCONFIG(TAG, "Setting up WiFi...");
38  ESP_LOGCONFIG(TAG, " Local MAC: %s", get_mac_address_pretty().c_str());
39  this->last_connected_ = millis();
40  this->wifi_pre_setup_();
41 
42  uint32_t hash = this->has_sta() ? fnv1_hash(App.get_compilation_time()) : 88491487UL;
43 
45 
46  SavedWifiSettings save{};
47  if (this->pref_.load(&save)) {
48  ESP_LOGD(TAG, "Loaded saved wifi settings: %s", save.ssid);
49 
50  WiFiAP sta{};
51  sta.set_ssid(save.ssid);
52  sta.set_password(save.password);
53  this->set_sta(sta);
54  }
55 
56  if (this->has_sta()) {
57  this->wifi_sta_pre_setup_();
58  if (this->output_power_.has_value() && !this->wifi_apply_output_power_(*this->output_power_)) {
59  ESP_LOGV(TAG, "Setting Output Power Option failed!");
60  }
61 
62  if (!this->wifi_apply_power_save_()) {
63  ESP_LOGV(TAG, "Setting Power Save Option failed!");
64  }
65 
66  if (this->fast_connect_) {
67  this->selected_ap_ = this->sta_[0];
68  this->start_connecting(this->selected_ap_, false);
69  } else {
70  this->start_scanning();
71  }
72  } else if (this->has_ap()) {
73  this->setup_ap_config_();
74  if (this->output_power_.has_value() && !this->wifi_apply_output_power_(*this->output_power_)) {
75  ESP_LOGV(TAG, "Setting Output Power Option failed!");
76  }
77 #ifdef USE_CAPTIVE_PORTAL
79  this->wifi_sta_pre_setup_();
80  this->start_scanning();
82  }
83 #endif
84  }
85 #ifdef USE_IMPROV
87  if (this->wifi_mode_(true, {}))
89  }
90 #endif
91  this->wifi_apply_hostname_();
92 }
93 
95  this->wifi_loop_();
96  const uint32_t now = millis();
97 
98  if (this->has_sta()) {
99  switch (this->state_) {
101  this->status_set_warning();
102  if (millis() - this->action_started_ > 5000) {
103  if (this->fast_connect_) {
104  this->start_connecting(this->sta_[0], false);
105  } else {
106  this->start_scanning();
107  }
108  }
109  break;
110  }
112  this->status_set_warning();
113  this->check_scanning_finished();
114  break;
115  }
118  this->status_set_warning();
120  break;
121  }
122 
124  if (!this->is_connected()) {
125  ESP_LOGW(TAG, "WiFi Connection lost... Reconnecting...");
127  this->retry_connect();
128  } else {
129  this->status_clear_warning();
130  this->last_connected_ = now;
131  }
132  break;
133  }
136  break;
137  }
138 
139  if (this->has_ap() && !this->ap_setup_) {
140  if (now - this->last_connected_ > this->ap_timeout_) {
141  ESP_LOGI(TAG, "Starting fallback AP!");
142  this->setup_ap_config_();
143 #ifdef USE_CAPTIVE_PORTAL
146 #endif
147  }
148  }
149 
150 #ifdef USE_IMPROV
151  if (esp32_improv::global_improv_component != nullptr) {
152  if (!this->is_connected()) {
153  if (this->wifi_mode_(true, {}))
155  }
156  }
157 
158 #endif
159 
160  if (!this->has_ap() && this->reboot_timeout_ != 0) {
161  if (now - this->last_connected_ > this->reboot_timeout_) {
162  ESP_LOGE(TAG, "Can't connect to WiFi, rebooting...");
163  App.reboot();
164  }
165  }
166  }
167 }
168 
170 
171 bool WiFiComponent::has_ap() const { return this->has_ap_; }
172 bool WiFiComponent::has_sta() const { return !this->sta_.empty(); }
173 void WiFiComponent::set_fast_connect(bool fast_connect) { this->fast_connect_ = fast_connect; }
174 #ifdef USE_WIFI_11KV_SUPPORT
175 void WiFiComponent::set_btm(bool btm) { this->btm_ = btm; }
176 void WiFiComponent::set_rrm(bool rrm) { this->rrm_ = rrm; }
177 #endif
179  if (this->has_sta())
180  return this->wifi_sta_ip();
181  if (this->has_ap())
182  return this->wifi_soft_ap_ip();
183  return {};
184 }
185 std::string WiFiComponent::get_use_address() const {
186  if (this->use_address_.empty()) {
187  return App.get_name() + ".local";
188  }
189  return this->use_address_;
190 }
191 void WiFiComponent::set_use_address(const std::string &use_address) { this->use_address_ = use_address; }
193  this->wifi_mode_({}, true);
194 
195  if (this->ap_setup_)
196  return;
197 
198  if (this->ap_.get_ssid().empty()) {
199  std::string name = App.get_name();
200  if (name.length() > 32) {
202  name.erase(name.begin() + 25, name.end() - 7); // Remove characters between 25 and the mac address
203  } else {
204  name = name.substr(0, 32);
205  }
206  }
207  this->ap_.set_ssid(name);
208  }
209 
210  ESP_LOGCONFIG(TAG, "Setting up AP...");
211 
212  ESP_LOGCONFIG(TAG, " AP SSID: '%s'", this->ap_.get_ssid().c_str());
213  ESP_LOGCONFIG(TAG, " AP Password: '%s'", this->ap_.get_password().c_str());
214  if (this->ap_.get_manual_ip().has_value()) {
215  auto manual = *this->ap_.get_manual_ip();
216  ESP_LOGCONFIG(TAG, " AP Static IP: '%s'", manual.static_ip.str().c_str());
217  ESP_LOGCONFIG(TAG, " AP Gateway: '%s'", manual.gateway.str().c_str());
218  ESP_LOGCONFIG(TAG, " AP Subnet: '%s'", manual.subnet.str().c_str());
219  }
220 
221  this->ap_setup_ = this->wifi_start_ap_(this->ap_);
222  ESP_LOGCONFIG(TAG, " IP Address: %s", this->wifi_soft_ap_ip().str().c_str());
223 
224  if (!this->has_sta()) {
226  }
227 }
228 
230  return 10.0f; // before other loop components
231 }
232 void WiFiComponent::set_ap(const WiFiAP &ap) {
233  this->ap_ = ap;
234  this->has_ap_ = true;
235 }
236 void WiFiComponent::add_sta(const WiFiAP &ap) { this->sta_.push_back(ap); }
238  this->clear_sta();
239  this->add_sta(ap);
240 }
241 void WiFiComponent::clear_sta() { this->sta_.clear(); }
242 void WiFiComponent::save_wifi_sta(const std::string &ssid, const std::string &password) {
243  SavedWifiSettings save{};
244  strncpy(save.ssid, ssid.c_str(), sizeof(save.ssid));
245  strncpy(save.password, password.c_str(), sizeof(save.password));
246  this->pref_.save(&save);
247  // ensure it's written immediately
249 
250  WiFiAP sta{};
251  sta.set_ssid(ssid);
252  sta.set_password(password);
253  this->set_sta(sta);
254 }
255 
256 void WiFiComponent::start_connecting(const WiFiAP &ap, bool two) {
257  ESP_LOGI(TAG, "WiFi Connecting to '%s'...", ap.get_ssid().c_str());
258 #ifdef ESPHOME_LOG_HAS_VERBOSE
259  ESP_LOGV(TAG, "Connection Params:");
260  ESP_LOGV(TAG, " SSID: '%s'", ap.get_ssid().c_str());
261  if (ap.get_bssid().has_value()) {
262  bssid_t b = *ap.get_bssid();
263  ESP_LOGV(TAG, " BSSID: %02X:%02X:%02X:%02X:%02X:%02X", b[0], b[1], b[2], b[3], b[4], b[5]);
264  } else {
265  ESP_LOGV(TAG, " BSSID: Not Set");
266  }
267 
268 #ifdef USE_WIFI_WPA2_EAP
269  if (ap.get_eap().has_value()) {
270  ESP_LOGV(TAG, " WPA2 Enterprise authentication configured:");
271  EAPAuth eap_config = ap.get_eap().value();
272  ESP_LOGV(TAG, " Identity: " LOG_SECRET("'%s'"), eap_config.identity.c_str());
273  ESP_LOGV(TAG, " Username: " LOG_SECRET("'%s'"), eap_config.username.c_str());
274  ESP_LOGV(TAG, " Password: " LOG_SECRET("'%s'"), eap_config.password.c_str());
275  bool ca_cert_present = eap_config.ca_cert != nullptr && strlen(eap_config.ca_cert);
276  bool client_cert_present = eap_config.client_cert != nullptr && strlen(eap_config.client_cert);
277  bool client_key_present = eap_config.client_key != nullptr && strlen(eap_config.client_key);
278  ESP_LOGV(TAG, " CA Cert: %s", ca_cert_present ? "present" : "not present");
279  ESP_LOGV(TAG, " Client Cert: %s", client_cert_present ? "present" : "not present");
280  ESP_LOGV(TAG, " Client Key: %s", client_key_present ? "present" : "not present");
281  } else {
282 #endif
283  ESP_LOGV(TAG, " Password: " LOG_SECRET("'%s'"), ap.get_password().c_str());
284 #ifdef USE_WIFI_WPA2_EAP
285  }
286 #endif
287  if (ap.get_channel().has_value()) {
288  ESP_LOGV(TAG, " Channel: %u", *ap.get_channel());
289  } else {
290  ESP_LOGV(TAG, " Channel: Not Set");
291  }
292  if (ap.get_manual_ip().has_value()) {
293  ManualIP m = *ap.get_manual_ip();
294  ESP_LOGV(TAG, " Manual IP: Static IP=%s Gateway=%s Subnet=%s DNS1=%s DNS2=%s", m.static_ip.str().c_str(),
295  m.gateway.str().c_str(), m.subnet.str().c_str(), m.dns1.str().c_str(), m.dns2.str().c_str());
296  } else {
297  ESP_LOGV(TAG, " Using DHCP IP");
298  }
299  ESP_LOGV(TAG, " Hidden: %s", YESNO(ap.get_hidden()));
300 #endif
301 
302  if (!this->wifi_sta_connect_(ap)) {
303  ESP_LOGE(TAG, "wifi_sta_connect_ failed!");
304  this->retry_connect();
305  return;
306  }
307 
308  if (!two) {
310  } else {
312  }
313  this->action_started_ = millis();
314 }
315 
316 const LogString *get_signal_bars(int8_t rssi) {
317  // LOWER ONE QUARTER BLOCK
318  // Unicode: U+2582, UTF-8: E2 96 82
319  // LOWER HALF BLOCK
320  // Unicode: U+2584, UTF-8: E2 96 84
321  // LOWER THREE QUARTERS BLOCK
322  // Unicode: U+2586, UTF-8: E2 96 86
323  // FULL BLOCK
324  // Unicode: U+2588, UTF-8: E2 96 88
325  if (rssi >= -50) {
326  return LOG_STR("\033[0;32m" // green
327  "\xe2\x96\x82"
328  "\xe2\x96\x84"
329  "\xe2\x96\x86"
330  "\xe2\x96\x88"
331  "\033[0m");
332  } else if (rssi >= -65) {
333  return LOG_STR("\033[0;33m" // yellow
334  "\xe2\x96\x82"
335  "\xe2\x96\x84"
336  "\xe2\x96\x86"
337  "\033[0;37m"
338  "\xe2\x96\x88"
339  "\033[0m");
340  } else if (rssi >= -85) {
341  return LOG_STR("\033[0;33m" // yellow
342  "\xe2\x96\x82"
343  "\xe2\x96\x84"
344  "\033[0;37m"
345  "\xe2\x96\x86"
346  "\xe2\x96\x88"
347  "\033[0m");
348  } else {
349  return LOG_STR("\033[0;31m" // red
350  "\xe2\x96\x82"
351  "\033[0;37m"
352  "\xe2\x96\x84"
353  "\xe2\x96\x86"
354  "\xe2\x96\x88"
355  "\033[0m");
356  }
357 }
358 
360  bssid_t bssid = wifi_bssid();
361 
362  ESP_LOGCONFIG(TAG, " Local MAC: %s", get_mac_address_pretty().c_str());
363  ESP_LOGCONFIG(TAG, " SSID: " LOG_SECRET("'%s'"), wifi_ssid().c_str());
364  ESP_LOGCONFIG(TAG, " IP Address: %s", wifi_sta_ip().str().c_str());
365  ESP_LOGCONFIG(TAG, " BSSID: " LOG_SECRET("%02X:%02X:%02X:%02X:%02X:%02X"), bssid[0], bssid[1], bssid[2], bssid[3],
366  bssid[4], bssid[5]);
367  ESP_LOGCONFIG(TAG, " Hostname: '%s'", App.get_name().c_str());
368  int8_t rssi = wifi_rssi();
369  ESP_LOGCONFIG(TAG, " Signal strength: %d dB %s", rssi, LOG_STR_ARG(get_signal_bars(rssi)));
370  if (this->selected_ap_.get_bssid().has_value()) {
371  ESP_LOGV(TAG, " Priority: %.1f", this->get_sta_priority(*this->selected_ap_.get_bssid()));
372  }
373  ESP_LOGCONFIG(TAG, " Channel: %d", wifi_channel_());
374  ESP_LOGCONFIG(TAG, " Subnet: %s", wifi_subnet_mask_().str().c_str());
375  ESP_LOGCONFIG(TAG, " Gateway: %s", wifi_gateway_ip_().str().c_str());
376  ESP_LOGCONFIG(TAG, " DNS1: %s", wifi_dns_ip_(0).str().c_str());
377  ESP_LOGCONFIG(TAG, " DNS2: %s", wifi_dns_ip_(1).str().c_str());
378 #ifdef USE_WIFI_11KV_SUPPORT
379  ESP_LOGCONFIG(TAG, " BTM: %s", this->btm_ ? "enabled" : "disabled");
380  ESP_LOGCONFIG(TAG, " RRM: %s", this->rrm_ ? "enabled" : "disabled");
381 #endif
382 }
383 
385  this->action_started_ = millis();
386  ESP_LOGD(TAG, "Starting scan...");
387  this->wifi_scan_start_();
389 }
390 
392  if (!this->scan_done_) {
393  if (millis() - this->action_started_ > 30000) {
394  ESP_LOGE(TAG, "Scan timeout!");
395  this->retry_connect();
396  }
397  return;
398  }
399  this->scan_done_ = false;
400 
401  ESP_LOGD(TAG, "Found networks:");
402  if (this->scan_result_.empty()) {
403  ESP_LOGD(TAG, " No network found!");
404  this->retry_connect();
405  return;
406  }
407 
408  for (auto &res : this->scan_result_) {
409  for (auto &ap : this->sta_) {
410  if (res.matches(ap)) {
411  res.set_matches(true);
412  if (!this->has_sta_priority(res.get_bssid())) {
413  this->set_sta_priority(res.get_bssid(), ap.get_priority());
414  }
415  res.set_priority(this->get_sta_priority(res.get_bssid()));
416  break;
417  }
418  }
419  }
420 
421  std::stable_sort(this->scan_result_.begin(), this->scan_result_.end(),
422  [](const WiFiScanResult &a, const WiFiScanResult &b) {
423  // return true if a is better than b
424  if (a.get_matches() && !b.get_matches())
425  return true;
426  if (!a.get_matches() && b.get_matches())
427  return false;
428 
429  if (a.get_matches() && b.get_matches()) {
430  // if both match, check priority
431  if (a.get_priority() != b.get_priority())
432  return a.get_priority() > b.get_priority();
433  }
434 
435  return a.get_rssi() > b.get_rssi();
436  });
437 
438  for (auto &res : this->scan_result_) {
439  char bssid_s[18];
440  auto bssid = res.get_bssid();
441  sprintf(bssid_s, "%02X:%02X:%02X:%02X:%02X:%02X", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
442 
443  if (res.get_matches()) {
444  ESP_LOGI(TAG, "- '%s' %s" LOG_SECRET("(%s) ") "%s", res.get_ssid().c_str(),
445  res.get_is_hidden() ? "(HIDDEN) " : "", bssid_s, LOG_STR_ARG(get_signal_bars(res.get_rssi())));
446  ESP_LOGD(TAG, " Channel: %u", res.get_channel());
447  ESP_LOGD(TAG, " RSSI: %d dB", res.get_rssi());
448  } else {
449  ESP_LOGD(TAG, "- " LOG_SECRET("'%s'") " " LOG_SECRET("(%s) ") "%s", res.get_ssid().c_str(), bssid_s,
450  LOG_STR_ARG(get_signal_bars(res.get_rssi())));
451  }
452  }
453 
454  if (!this->scan_result_[0].get_matches()) {
455  ESP_LOGW(TAG, "No matching network found!");
456  this->retry_connect();
457  return;
458  }
459 
460  WiFiAP connect_params;
461  WiFiScanResult scan_res = this->scan_result_[0];
462  for (auto &config : this->sta_) {
463  // search for matching STA config, at least one will match (from checks before)
464  if (!scan_res.matches(config)) {
465  continue;
466  }
467 
468  if (config.get_hidden()) {
469  // selected network is hidden, we use the data from the config
470  connect_params.set_hidden(true);
471  connect_params.set_ssid(config.get_ssid());
472  // don't set BSSID and channel, there might be multiple hidden networks
473  // but we can't know which one is the correct one. Rely on probe-req with just SSID.
474  } else {
475  // selected network is visible, we use the data from the scan
476  // limit the connect params to only connect to exactly this network
477  // (network selection is done during scan phase).
478  connect_params.set_hidden(false);
479  connect_params.set_ssid(scan_res.get_ssid());
480  connect_params.set_channel(scan_res.get_channel());
481  connect_params.set_bssid(scan_res.get_bssid());
482  }
483  // copy manual IP (if set)
484  connect_params.set_manual_ip(config.get_manual_ip());
485 
486 #ifdef USE_WIFI_WPA2_EAP
487  // copy EAP parameters (if set)
488  connect_params.set_eap(config.get_eap());
489 #endif
490 
491  // copy password (if set)
492  connect_params.set_password(config.get_password());
493 
494  break;
495  }
496 
497  yield();
498 
499  this->selected_ap_ = connect_params;
500  this->start_connecting(connect_params, false);
501 }
502 
504  ESP_LOGCONFIG(TAG, "WiFi:");
505  this->print_connect_params_();
506 }
507 
509  auto status = this->wifi_sta_connect_status_();
510 
512  if (wifi_ssid().empty()) {
513  ESP_LOGW(TAG, "Incomplete connection.");
514  this->retry_connect();
515  return;
516  }
517 
518  ESP_LOGI(TAG, "WiFi Connected!");
519  this->print_connect_params_();
520 
521  if (this->has_ap()) {
522 #ifdef USE_CAPTIVE_PORTAL
523  if (this->is_captive_portal_active_()) {
525  }
526 #endif
527  ESP_LOGD(TAG, "Disabling AP...");
528  this->wifi_mode_({}, false);
529  }
530 #ifdef USE_IMPROV
531  if (this->is_esp32_improv_active_()) {
533  }
534 #endif
535 
537  this->num_retried_ = 0;
538  return;
539  }
540 
541  uint32_t now = millis();
542  if (now - this->action_started_ > 30000) {
543  ESP_LOGW(TAG, "Timeout while connecting to WiFi.");
544  this->retry_connect();
545  return;
546  }
547 
548  if (this->error_from_callback_) {
549  ESP_LOGW(TAG, "Error while connecting to network.");
550  this->retry_connect();
551  return;
552  }
553 
555  return;
556  }
557 
559  ESP_LOGW(TAG, "WiFi network can not be found anymore.");
560  this->retry_connect();
561  return;
562  }
563 
565  ESP_LOGW(TAG, "Connecting to WiFi network failed. Are the credentials wrong?");
566  this->retry_connect();
567  return;
568  }
569 
570  ESP_LOGW(TAG, "WiFi Unknown connection status %d", (int) status);
571  this->retry_connect();
572 }
573 
575  if (this->selected_ap_.get_bssid()) {
576  auto bssid = *this->selected_ap_.get_bssid();
577  float priority = this->get_sta_priority(bssid);
578  this->set_sta_priority(bssid, priority - 1.0f);
579  }
580 
581  delay(10);
582  if (!this->is_captive_portal_active_() && !this->is_esp32_improv_active_() &&
583  (this->num_retried_ > 5 || this->error_from_callback_)) {
584  // If retry failed for more than 5 times, let's restart STA
585  ESP_LOGW(TAG, "Restarting WiFi adapter...");
586  this->wifi_mode_(false, {});
587  delay(100); // NOLINT
588  this->num_retried_ = 0;
589  } else {
590  this->num_retried_++;
591  }
592  this->error_from_callback_ = false;
594  yield();
596  this->start_connecting(this->selected_ap_, true);
597  return;
598  }
599 
601  this->action_started_ = millis();
602 }
603 
605  if (!this->has_sta()) {
606  return true;
607  }
608  return this->is_connected();
609 }
610 void WiFiComponent::set_reboot_timeout(uint32_t reboot_timeout) { this->reboot_timeout_ = reboot_timeout; }
612  return this->state_ == WIFI_COMPONENT_STATE_STA_CONNECTED &&
614 }
615 void WiFiComponent::set_power_save_mode(WiFiPowerSaveMode power_save) { this->power_save_ = power_save; }
616 
617 std::string WiFiComponent::format_mac_addr(const uint8_t *mac) {
618  char buf[20];
619  sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
620  return buf;
621 }
623 #ifdef USE_CAPTIVE_PORTAL
625 #else
626  return false;
627 #endif
628 }
630 #ifdef USE_IMPROV
632 #else
633  return false;
634 #endif
635 }
636 
637 void WiFiAP::set_ssid(const std::string &ssid) { this->ssid_ = ssid; }
638 void WiFiAP::set_bssid(bssid_t bssid) { this->bssid_ = bssid; }
639 void WiFiAP::set_bssid(optional<bssid_t> bssid) { this->bssid_ = bssid; }
640 void WiFiAP::set_password(const std::string &password) { this->password_ = password; }
641 #ifdef USE_WIFI_WPA2_EAP
642 void WiFiAP::set_eap(optional<EAPAuth> eap_auth) { this->eap_ = std::move(eap_auth); }
643 #endif
644 void WiFiAP::set_channel(optional<uint8_t> channel) { this->channel_ = channel; }
645 void WiFiAP::set_manual_ip(optional<ManualIP> manual_ip) { this->manual_ip_ = manual_ip; }
646 void WiFiAP::set_hidden(bool hidden) { this->hidden_ = hidden; }
647 const std::string &WiFiAP::get_ssid() const { return this->ssid_; }
648 const optional<bssid_t> &WiFiAP::get_bssid() const { return this->bssid_; }
649 const std::string &WiFiAP::get_password() const { return this->password_; }
650 #ifdef USE_WIFI_WPA2_EAP
651 const optional<EAPAuth> &WiFiAP::get_eap() const { return this->eap_; }
652 #endif
653 const optional<uint8_t> &WiFiAP::get_channel() const { return this->channel_; }
654 const optional<ManualIP> &WiFiAP::get_manual_ip() const { return this->manual_ip_; }
655 bool WiFiAP::get_hidden() const { return this->hidden_; }
656 
657 WiFiScanResult::WiFiScanResult(const bssid_t &bssid, std::string ssid, uint8_t channel, int8_t rssi, bool with_auth,
658  bool is_hidden)
659  : bssid_(bssid),
660  ssid_(std::move(ssid)),
661  channel_(channel),
662  rssi_(rssi),
663  with_auth_(with_auth),
664  is_hidden_(is_hidden) {}
665 bool WiFiScanResult::matches(const WiFiAP &config) {
666  if (config.get_hidden()) {
667  // User configured a hidden network, only match actually hidden networks
668  // don't match SSID
669  if (!this->is_hidden_)
670  return false;
671  } else if (!config.get_ssid().empty()) {
672  // check if SSID matches
673  if (config.get_ssid() != this->ssid_)
674  return false;
675  } else {
676  // network is configured without SSID - match other settings
677  }
678  // If BSSID configured, only match for correct BSSIDs
679  if (config.get_bssid().has_value() && *config.get_bssid() != this->bssid_)
680  return false;
681 
682 #ifdef USE_WIFI_WPA2_EAP
683  // BSSID requires auth but no PSK or EAP credentials given
684  if (this->with_auth_ && (config.get_password().empty() && !config.get_eap().has_value()))
685  return false;
686 
687  // BSSID does not require auth, but PSK or EAP credentials given
688  if (!this->with_auth_ && (!config.get_password().empty() || config.get_eap().has_value()))
689  return false;
690 #else
691  // If PSK given, only match for networks with auth (and vice versa)
692  if (config.get_password().empty() == this->with_auth_)
693  return false;
694 #endif
695 
696  // If channel configured, only match networks on that channel.
697  if (config.get_channel().has_value() && *config.get_channel() != this->channel_) {
698  return false;
699  }
700  return true;
701 }
702 bool WiFiScanResult::get_matches() const { return this->matches_; }
704 const bssid_t &WiFiScanResult::get_bssid() const { return this->bssid_; }
705 const std::string &WiFiScanResult::get_ssid() const { return this->ssid_; }
706 uint8_t WiFiScanResult::get_channel() const { return this->channel_; }
707 int8_t WiFiScanResult::get_rssi() const { return this->rssi_; }
708 bool WiFiScanResult::get_with_auth() const { return this->with_auth_; }
709 bool WiFiScanResult::get_is_hidden() const { return this->is_hidden_; }
710 
711 bool WiFiScanResult::operator==(const WiFiScanResult &rhs) const { return this->bssid_ == rhs.bssid_; }
712 
713 WiFiComponent *global_wifi_component; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
714 
715 } // namespace wifi
716 } // namespace esphome
Nothing has been initialized yet.
const char * name
Definition: stm32flash.h:78
This component is responsible for managing the ESP WiFi interface.
const std::string & get_ssid() const
std::array< uint8_t, 6 > bssid_t
const optional< EAPAuth > & get_eap() const
static std::string format_mac_addr(const uint8_t mac[6])
const std::string & get_password() const
WiFiPowerSaveMode power_save_
void save_wifi_sta(const std::string &ssid, const std::string &password)
network::IPAddress wifi_dns_ip_(int num)
void set_sta_priority(const bssid_t bssid, float priority)
bool wifi_mode_(optional< bool > sta, optional< bool > ap)
const optional< bssid_t > & get_bssid() const
std::string str() const
Definition: ip_address.h:28
bool wifi_apply_output_power_(float output_power)
void add_sta(const WiFiAP &ap)
WiFi is in STA(+AP) mode and currently connecting to an AP a second time.
STL namespace.
WiFi is in STA(+AP) mode and successfully connected.
bool has_value() const
Definition: optional.h:87
network::IPAddress static_ip
void set_ap(const WiFiAP &ap)
Setup an Access Point that should be created if no connection to a station can be made...
network::IPAddress get_ip_address()
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:26
const bssid_t & get_bssid() const
void set_channel(optional< uint8_t > channel)
bool save(const T *src)
Definition: preferences.h:21
network::IPAddress gateway
void start_connecting(const WiFiAP &ap, bool two)
WiFiComponent()
Construct a WiFiComponent.
CaptivePortal * global_captive_portal
std::vector< WiFiScanResult > scan_result_
WiFi is in STA-only mode and currently scanning for APs.
uint8_t m
Definition: bl0939.h:20
Struct for setting static IPs in WiFiComponent.
void set_power_save_mode(WiFiPowerSaveMode power_save)
network::IPAddress dns1
The first DNS server. 0.0.0.0 for default.
WiFi is in STA(+AP) mode and currently connecting to an AP.
bool has_sta_priority(const bssid_t &bssid)
const optional< ManualIP > & get_manual_ip() const
ESPPreferences * global_preferences
const optional< uint8_t > & get_channel() const
void status_clear_warning()
Definition: component.cpp:153
WiFi is in cooldown mode because something went wrong, scanning will begin after a short period of ti...
void set_ssid(const std::string &ssid)
Application App
Global storage of Application pointer - only one Application can exist.
bool matches(const WiFiAP &config)
WiFiComponent * global_wifi_component
const std::string & get_name() const
Get the name of this Application set by pre_setup().
Definition: application.h:143
void status_set_warning()
Definition: component.cpp:145
void set_reboot_timeout(uint32_t reboot_timeout)
bool is_name_add_mac_suffix_enabled() const
Definition: application.h:150
ESP32ImprovComponent * global_improv_component
const std::string & get_compilation_time() const
Definition: application.h:152
void loop() override
Reconnect WiFi if required.
uint8_t priority
bool operator==(const WiFiScanResult &rhs) const
uint8_t status
Definition: bl0942.h:23
ESPPreferenceObject pref_
network::IPAddress dns2
The second DNS server. 0.0.0.0 for default.
const char * client_cert
void IRAM_ATTR HOT yield()
Definition: core.cpp:25
void set_fast_connect(bool fast_connect)
void set_manual_ip(optional< ManualIP > manual_ip)
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)=0
uint32_t fnv1_hash(const std::string &str)
Calculate a FNV-1 hash of str.
Definition: helpers.cpp:86
std::vector< WiFiAP > sta_
optional< float > output_power_
network::IPAddress subnet
void set_sta(const WiFiAP &ap)
Definition: a4988.cpp:4
void set_bssid(bssid_t bssid)
const std::string & get_ssid() const
void set_eap(optional< EAPAuth > eap_auth)
void set_hidden(bool hidden)
float get_loop_priority() const override
void set_use_address(const std::string &use_address)
WiFiScanResult(const bssid_t &bssid, std::string ssid, uint8_t channel, int8_t rssi, bool with_auth, bool is_hidden)
std::string get_mac_address_pretty()
Get the device MAC address as a string, in colon-separated uppercase hex notation.
Definition: helpers.cpp:459
virtual bool sync()=0
Commit pending writes to flash.
std::string get_use_address() const
float get_sta_priority(const bssid_t bssid)
void set_password(const std::string &password)
void setup() override
Setup WiFi interface.
float get_setup_priority() const override
WIFI setup_priority.
WiFi is in AP-only mode and internal AP is already enabled.
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:27
const LogString * get_signal_bars(int8_t rssi)