ESPHome  2022.9.3
wifi_component.h
Go to the documentation of this file.
1 #pragma once
2 
4 #include "esphome/core/defines.h"
6 #include "esphome/core/helpers.h"
8 #include <string>
9 
10 #ifdef USE_ESP32_FRAMEWORK_ARDUINO
11 #include <esp_wifi.h>
12 #include <WiFiType.h>
13 #include <WiFi.h>
14 #endif
15 
16 #ifdef USE_ESP8266
17 #include <ESP8266WiFi.h>
18 #include <ESP8266WiFiType.h>
19 
20 #if defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE < VERSION_CODE(2, 4, 0)
21 extern "C" {
22 #include <user_interface.h>
23 };
24 #endif
25 #endif
26 
27 namespace esphome {
28 namespace wifi {
29 
31  char ssid[33];
32  char password[65];
33 } PACKED; // NOLINT
34 
54 };
55 
56 enum class WiFiSTAConnectStatus : int {
57  IDLE,
58  CONNECTING,
59  CONNECTED,
62 };
63 
65 struct ManualIP {
71 };
72 
73 #ifdef USE_WIFI_WPA2_EAP
74 struct EAPAuth {
75  std::string identity; // required for all auth types
76  std::string username;
77  std::string password;
78  const char *ca_cert; // optionally verify authentication server
79  // used for EAP-TLS
80  const char *client_cert;
81  const char *client_key;
82 };
83 #endif // USE_WIFI_WPA2_EAP
84 
85 using bssid_t = std::array<uint8_t, 6>;
86 
87 class WiFiAP {
88  public:
89  void set_ssid(const std::string &ssid);
90  void set_bssid(bssid_t bssid);
91  void set_bssid(optional<bssid_t> bssid);
92  void set_password(const std::string &password);
93 #ifdef USE_WIFI_WPA2_EAP
94  void set_eap(optional<EAPAuth> eap_auth);
95 #endif // USE_WIFI_WPA2_EAP
96  void set_channel(optional<uint8_t> channel);
97  void set_priority(float priority) { priority_ = priority; }
98  void set_manual_ip(optional<ManualIP> manual_ip);
99  void set_hidden(bool hidden);
100  const std::string &get_ssid() const;
101  const optional<bssid_t> &get_bssid() const;
102  const std::string &get_password() const;
103 #ifdef USE_WIFI_WPA2_EAP
104  const optional<EAPAuth> &get_eap() const;
105 #endif // USE_WIFI_WPA2_EAP
106  const optional<uint8_t> &get_channel() const;
107  float get_priority() const { return priority_; }
108  const optional<ManualIP> &get_manual_ip() const;
109  bool get_hidden() const;
110 
111  protected:
112  std::string ssid_;
114  std::string password_;
115 #ifdef USE_WIFI_WPA2_EAP
117 #endif // USE_WIFI_WPA2_EAP
119  float priority_{0};
121  bool hidden_{false};
122 };
123 
125  public:
126  WiFiScanResult(const bssid_t &bssid, std::string ssid, uint8_t channel, int8_t rssi, bool with_auth, bool is_hidden);
127 
128  bool matches(const WiFiAP &config);
129 
130  bool get_matches() const;
131  void set_matches(bool matches);
132  const bssid_t &get_bssid() const;
133  const std::string &get_ssid() const;
134  uint8_t get_channel() const;
135  int8_t get_rssi() const;
136  bool get_with_auth() const;
137  bool get_is_hidden() const;
138  float get_priority() const { return priority_; }
139  void set_priority(float priority) { priority_ = priority; }
140 
141  protected:
142  bool matches_{false};
144  std::string ssid_;
145  uint8_t channel_;
146  int8_t rssi_;
149  float priority_{0.0f};
150 };
151 
154  float priority;
155 };
156 
161 };
162 
163 #ifdef USE_ESP_IDF
164 struct IDFWiFiEvent;
165 #endif
166 
168 class WiFiComponent : public Component {
169  public:
171  WiFiComponent();
172 
173  void set_sta(const WiFiAP &ap);
174  void add_sta(const WiFiAP &ap);
175  void clear_sta();
176 
184  void set_ap(const WiFiAP &ap);
185  WiFiAP get_ap() { return this->ap_; }
186 
187  void start_scanning();
188  void check_scanning_finished();
189  void start_connecting(const WiFiAP &ap, bool two);
190  void set_fast_connect(bool fast_connect);
191  void set_ap_timeout(uint32_t ap_timeout) { ap_timeout_ = ap_timeout; }
192 
193  void check_connecting_finished();
194 
195  void retry_connect();
196 
197  bool can_proceed() override;
198 
199  void set_reboot_timeout(uint32_t reboot_timeout);
200 
201  bool is_connected();
202 
203  void set_power_save_mode(WiFiPowerSaveMode power_save);
204  void set_output_power(float output_power) { output_power_ = output_power; }
205 
206  void save_wifi_sta(const std::string &ssid, const std::string &password);
207  // ========== INTERNAL METHODS ==========
208  // (In most use cases you won't need these)
210  void setup() override;
211  void dump_config() override;
213  float get_setup_priority() const override;
214  float get_loop_priority() const override;
215 
217  void loop() override;
218 
219  bool has_sta() const;
220  bool has_ap() const;
221 
222 #ifdef USE_WIFI_11KV_SUPPORT
223  void set_btm(bool btm);
224  void set_rrm(bool rrm);
225 #endif
226 
228  std::string get_use_address() const;
229  void set_use_address(const std::string &use_address);
230 
231  const std::vector<WiFiScanResult> &get_scan_result() const { return scan_result_; }
232 
233  network::IPAddress wifi_soft_ap_ip();
234 
235  bool has_sta_priority(const bssid_t &bssid) {
236  for (auto &it : this->sta_priorities_) {
237  if (it.bssid == bssid)
238  return true;
239  }
240  return false;
241  }
242  float get_sta_priority(const bssid_t bssid) {
243  for (auto &it : this->sta_priorities_) {
244  if (it.bssid == bssid)
245  return it.priority;
246  }
247  return 0.0f;
248  }
249  void set_sta_priority(const bssid_t bssid, float priority) {
250  for (auto &it : this->sta_priorities_) {
251  if (it.bssid == bssid) {
252  it.priority = priority;
253  return;
254  }
255  }
256  this->sta_priorities_.push_back(WiFiSTAPriority{
257  .bssid = bssid,
258  .priority = priority,
259  });
260  }
261 
262  network::IPAddress wifi_sta_ip();
263  std::string wifi_ssid();
264  bssid_t wifi_bssid();
265 
266  int8_t wifi_rssi();
267 
268  protected:
269  static std::string format_mac_addr(const uint8_t mac[6]);
270  void setup_ap_config_();
271  void print_connect_params_();
272 
273  void wifi_loop_();
274  bool wifi_mode_(optional<bool> sta, optional<bool> ap);
275  bool wifi_sta_pre_setup_();
276  bool wifi_apply_output_power_(float output_power);
277  bool wifi_apply_power_save_();
278  bool wifi_sta_ip_config_(optional<ManualIP> manual_ip);
279  bool wifi_apply_hostname_();
280  bool wifi_sta_connect_(const WiFiAP &ap);
281  void wifi_pre_setup_();
282  WiFiSTAConnectStatus wifi_sta_connect_status_();
283  bool wifi_scan_start_();
284  bool wifi_ap_ip_config_(optional<ManualIP> manual_ip);
285  bool wifi_start_ap_(const WiFiAP &ap);
286  bool wifi_disconnect_();
287  int32_t wifi_channel_();
288  network::IPAddress wifi_subnet_mask_();
289  network::IPAddress wifi_gateway_ip_();
290  network::IPAddress wifi_dns_ip_(int num);
291 
292  bool is_captive_portal_active_();
293  bool is_esp32_improv_active_();
294 
295 #ifdef USE_ESP8266
296  static void wifi_event_callback(System_Event_t *event);
297  void wifi_scan_done_callback_(void *arg, STATUS status);
298  static void s_wifi_scan_done_callback(void *arg, STATUS status);
299 #endif
300 
301 #ifdef USE_ESP32_FRAMEWORK_ARDUINO
302 #if ESP_IDF_VERSION_MAJOR >= 4
303  void wifi_event_callback_(arduino_event_id_t event, arduino_event_info_t info);
304 #else
305  void wifi_event_callback_(system_event_id_t event, system_event_info_t info);
306 #endif
307  void wifi_scan_done_callback_();
308 #endif
309 #ifdef USE_ESP_IDF
310  void wifi_process_event_(IDFWiFiEvent *data);
311 #endif
312 
313  std::string use_address_;
314  std::vector<WiFiAP> sta_;
315  std::vector<WiFiSTAPriority> sta_priorities_;
317  bool fast_connect_{false};
318 
319  bool has_ap_{false};
322  uint32_t action_started_;
323  uint8_t num_retried_{0};
324  uint32_t last_connected_{0};
325  uint32_t reboot_timeout_{};
326  uint32_t ap_timeout_{};
328  bool error_from_callback_{false};
329  std::vector<WiFiScanResult> scan_result_;
330  bool scan_done_{false};
331  bool ap_setup_{false};
334  bool has_saved_wifi_settings_{false};
335 #ifdef USE_WIFI_11KV_SUPPORT
336  bool btm_{false};
337  bool rrm_{false};
338 #endif
339 };
340 
341 extern WiFiComponent *global_wifi_component; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
342 
343 template<typename... Ts> class WiFiConnectedCondition : public Condition<Ts...> {
344  public:
345  bool check(Ts... x) override;
346 };
347 
348 template<typename... Ts> bool WiFiConnectedCondition<Ts...>::check(Ts... x) {
349  return global_wifi_component->is_connected();
350 }
351 
352 } // namespace wifi
353 } // namespace esphome
void setup()
Nothing has been initialized yet.
void loop()
This component is responsible for managing the ESP WiFi interface.
void set_priority(float priority)
std::array< uint8_t, 6 > bssid_t
std::string get_use_address()
Get the active network hostname.
Definition: util.cpp:41
float get_priority() const
void set_output_power(float output_power)
const std::vector< WiFiScanResult > & get_scan_result() const
void set_sta_priority(const bssid_t bssid, float priority)
optional< ManualIP > manual_ip_
struct esphome::wifi::SavedWifiSettings PACKED
WiFi is in STA(+AP) mode and currently connecting to an AP a second time.
WiFi is in STA(+AP) mode and successfully connected.
void set_priority(float priority)
network::IPAddress static_ip
bool is_connected()
Return whether the node is connected to the network (through wifi, eth, ...)
Definition: util.cpp:15
network::IPAddress gateway
void set_ap_timeout(uint32_t ap_timeout)
std::vector< WiFiScanResult > scan_result_
WiFi is in STA-only mode and currently scanning for APs.
Struct for setting static IPs in WiFiComponent.
network::IPAddress dns1
The first DNS server. 0.0.0.0 for default.
Base class for all automation conditions.
Definition: automation.h:74
WiFi is in STA(+AP) mode and currently connecting to an AP.
bool has_sta_priority(const bssid_t &bssid)
WiFi is in cooldown mode because something went wrong, scanning will begin after a short period of ti...
optional< bssid_t > bssid_
WiFiComponent * global_wifi_component
optional< uint8_t > channel_
uint8_t priority
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
std::vector< WiFiSTAPriority > sta_priorities_
std::vector< WiFiAP > sta_
optional< float > output_power_
network::IPAddress subnet
Definition: a4988.cpp:4
float get_sta_priority(const bssid_t bssid)
optional< EAPAuth > eap_
WiFi is in AP-only mode and internal AP is already enabled.
network::IPAddress get_ip_address()
Definition: util.cpp:29