mirror of
https://github.com/esphome/esphome.git
synced 2026-02-08 00:31:58 +00:00
[wifi] Use StaticVector for WiFi listeners with per-type compile-time sizing (#13197)
This commit is contained in:
@@ -624,7 +624,11 @@ async def wifi_disable_to_code(config, action_id, template_arg, args):
|
||||
|
||||
KEEP_SCAN_RESULTS_KEY = "wifi_keep_scan_results"
|
||||
RUNTIME_POWER_SAVE_KEY = "wifi_runtime_power_save"
|
||||
WIFI_LISTENERS_KEY = "wifi_listeners"
|
||||
# Keys for listener counts
|
||||
IP_STATE_LISTENERS_KEY = "wifi_ip_state_listeners"
|
||||
SCAN_RESULTS_LISTENERS_KEY = "wifi_scan_results_listeners"
|
||||
CONNECT_STATE_LISTENERS_KEY = "wifi_connect_state_listeners"
|
||||
POWER_SAVE_LISTENERS_KEY = "wifi_power_save_listeners"
|
||||
|
||||
|
||||
def request_wifi_scan_results():
|
||||
@@ -650,15 +654,28 @@ def enable_runtime_power_save_control():
|
||||
CORE.data[RUNTIME_POWER_SAVE_KEY] = True
|
||||
|
||||
|
||||
def request_wifi_listeners() -> None:
|
||||
"""Request that WiFi state listeners be compiled in.
|
||||
def request_wifi_ip_state_listener() -> None:
|
||||
"""Request an IP state listener slot."""
|
||||
CORE.data[IP_STATE_LISTENERS_KEY] = CORE.data.get(IP_STATE_LISTENERS_KEY, 0) + 1
|
||||
|
||||
Components that need to be notified about WiFi state changes (IP address changes,
|
||||
scan results, connection state) should call this function during their code generation.
|
||||
This enables the add_ip_state_listener(), add_scan_results_listener(),
|
||||
and add_connect_state_listener() APIs.
|
||||
"""
|
||||
CORE.data[WIFI_LISTENERS_KEY] = True
|
||||
|
||||
def request_wifi_scan_results_listener() -> None:
|
||||
"""Request a scan results listener slot."""
|
||||
CORE.data[SCAN_RESULTS_LISTENERS_KEY] = (
|
||||
CORE.data.get(SCAN_RESULTS_LISTENERS_KEY, 0) + 1
|
||||
)
|
||||
|
||||
|
||||
def request_wifi_connect_state_listener() -> None:
|
||||
"""Request a connect state listener slot."""
|
||||
CORE.data[CONNECT_STATE_LISTENERS_KEY] = (
|
||||
CORE.data.get(CONNECT_STATE_LISTENERS_KEY, 0) + 1
|
||||
)
|
||||
|
||||
|
||||
def request_wifi_power_save_listener() -> None:
|
||||
"""Request a power save listener slot."""
|
||||
CORE.data[POWER_SAVE_LISTENERS_KEY] = CORE.data.get(POWER_SAVE_LISTENERS_KEY, 0) + 1
|
||||
|
||||
|
||||
@coroutine_with_priority(CoroPriority.FINAL)
|
||||
@@ -670,8 +687,25 @@ async def final_step():
|
||||
)
|
||||
if CORE.data.get(RUNTIME_POWER_SAVE_KEY, False):
|
||||
cg.add_define("USE_WIFI_RUNTIME_POWER_SAVE")
|
||||
if CORE.data.get(WIFI_LISTENERS_KEY, False):
|
||||
cg.add_define("USE_WIFI_LISTENERS")
|
||||
|
||||
# Generate listener defines - each listener type has its own #ifdef
|
||||
ip_state_count = CORE.data.get(IP_STATE_LISTENERS_KEY, 0)
|
||||
scan_results_count = CORE.data.get(SCAN_RESULTS_LISTENERS_KEY, 0)
|
||||
connect_state_count = CORE.data.get(CONNECT_STATE_LISTENERS_KEY, 0)
|
||||
power_save_count = CORE.data.get(POWER_SAVE_LISTENERS_KEY, 0)
|
||||
|
||||
if ip_state_count:
|
||||
cg.add_define("USE_WIFI_IP_STATE_LISTENERS")
|
||||
cg.add_define("ESPHOME_WIFI_IP_STATE_LISTENERS", ip_state_count)
|
||||
if scan_results_count:
|
||||
cg.add_define("USE_WIFI_SCAN_RESULTS_LISTENERS")
|
||||
cg.add_define("ESPHOME_WIFI_SCAN_RESULTS_LISTENERS", scan_results_count)
|
||||
if connect_state_count:
|
||||
cg.add_define("USE_WIFI_CONNECT_STATE_LISTENERS")
|
||||
cg.add_define("ESPHOME_WIFI_CONNECT_STATE_LISTENERS", connect_state_count)
|
||||
if power_save_count:
|
||||
cg.add_define("USE_WIFI_POWER_SAVE_LISTENERS")
|
||||
cg.add_define("ESPHOME_WIFI_POWER_SAVE_LISTENERS", power_save_count)
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
|
||||
@@ -275,6 +275,9 @@ struct LTWiFiEvent;
|
||||
*
|
||||
* Components can implement this interface to receive IP address updates
|
||||
* without the overhead of std::function callbacks.
|
||||
*
|
||||
* @note Components must call wifi.request_wifi_ip_state_listener() in their
|
||||
* Python to_code() to register for this listener type.
|
||||
*/
|
||||
class WiFiIPStateListener {
|
||||
public:
|
||||
@@ -286,6 +289,9 @@ class WiFiIPStateListener {
|
||||
*
|
||||
* Components can implement this interface to receive scan results
|
||||
* without the overhead of std::function callbacks.
|
||||
*
|
||||
* @note Components must call wifi.request_wifi_scan_results_listener() in their
|
||||
* Python to_code() to register for this listener type.
|
||||
*/
|
||||
class WiFiScanResultsListener {
|
||||
public:
|
||||
@@ -296,6 +302,9 @@ class WiFiScanResultsListener {
|
||||
*
|
||||
* Components can implement this interface to receive connection updates
|
||||
* without the overhead of std::function callbacks.
|
||||
*
|
||||
* @note Components must call wifi.request_wifi_connect_state_listener() in their
|
||||
* Python to_code() to register for this listener type.
|
||||
*/
|
||||
class WiFiConnectStateListener {
|
||||
public:
|
||||
@@ -306,6 +315,9 @@ class WiFiConnectStateListener {
|
||||
*
|
||||
* Components can implement this interface to receive power save mode updates
|
||||
* without the overhead of std::function callbacks.
|
||||
*
|
||||
* @note Components must call wifi.request_wifi_power_save_listener() in their
|
||||
* Python to_code() to register for this listener type.
|
||||
*/
|
||||
class WiFiPowerSaveListener {
|
||||
public:
|
||||
@@ -444,26 +456,32 @@ class WiFiComponent : public Component {
|
||||
|
||||
int32_t get_wifi_channel();
|
||||
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_IP_STATE_LISTENERS
|
||||
/** Add a listener for IP state changes.
|
||||
* Listener receives: IP addresses, DNS address 1, DNS address 2
|
||||
*/
|
||||
void add_ip_state_listener(WiFiIPStateListener *listener) { this->ip_state_listeners_.push_back(listener); }
|
||||
#endif // USE_WIFI_IP_STATE_LISTENERS
|
||||
#ifdef USE_WIFI_SCAN_RESULTS_LISTENERS
|
||||
/// Add a listener for WiFi scan results
|
||||
void add_scan_results_listener(WiFiScanResultsListener *listener) {
|
||||
this->scan_results_listeners_.push_back(listener);
|
||||
}
|
||||
#endif // USE_WIFI_SCAN_RESULTS_LISTENERS
|
||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
/** Add a listener for WiFi connection state changes.
|
||||
* Listener receives: SSID, BSSID
|
||||
*/
|
||||
void add_connect_state_listener(WiFiConnectStateListener *listener) {
|
||||
this->connect_state_listeners_.push_back(listener);
|
||||
}
|
||||
#endif // USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
#ifdef USE_WIFI_POWER_SAVE_LISTENERS
|
||||
/** Add a listener for WiFi power save mode changes.
|
||||
* Listener receives: WiFiPowerSaveMode
|
||||
*/
|
||||
void add_power_save_listener(WiFiPowerSaveListener *listener) { this->power_save_listeners_.push_back(listener); }
|
||||
#endif // USE_WIFI_LISTENERS
|
||||
#endif // USE_WIFI_POWER_SAVE_LISTENERS
|
||||
|
||||
#ifdef USE_WIFI_RUNTIME_POWER_SAVE
|
||||
/** Request high-performance mode (no power saving) for improved WiFi latency.
|
||||
@@ -628,12 +646,18 @@ class WiFiComponent : public Component {
|
||||
WiFiAP ap_;
|
||||
#endif
|
||||
float output_power_{NAN};
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
std::vector<WiFiIPStateListener *> ip_state_listeners_;
|
||||
std::vector<WiFiScanResultsListener *> scan_results_listeners_;
|
||||
std::vector<WiFiConnectStateListener *> connect_state_listeners_;
|
||||
std::vector<WiFiPowerSaveListener *> power_save_listeners_;
|
||||
#endif // USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_IP_STATE_LISTENERS
|
||||
StaticVector<WiFiIPStateListener *, ESPHOME_WIFI_IP_STATE_LISTENERS> ip_state_listeners_;
|
||||
#endif
|
||||
#ifdef USE_WIFI_SCAN_RESULTS_LISTENERS
|
||||
StaticVector<WiFiScanResultsListener *, ESPHOME_WIFI_SCAN_RESULTS_LISTENERS> scan_results_listeners_;
|
||||
#endif
|
||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
StaticVector<WiFiConnectStateListener *, ESPHOME_WIFI_CONNECT_STATE_LISTENERS> connect_state_listeners_;
|
||||
#endif
|
||||
#ifdef USE_WIFI_POWER_SAVE_LISTENERS
|
||||
StaticVector<WiFiPowerSaveListener *, ESPHOME_WIFI_POWER_SAVE_LISTENERS> power_save_listeners_;
|
||||
#endif
|
||||
ESPPreferenceObject pref_;
|
||||
#ifdef USE_WIFI_FAST_CONNECT
|
||||
ESPPreferenceObject fast_connect_pref_;
|
||||
|
||||
@@ -105,7 +105,7 @@ bool WiFiComponent::wifi_apply_power_save_() {
|
||||
}
|
||||
wifi_fpm_auto_sleep_set_in_null_mode(1);
|
||||
bool success = wifi_set_sleep_type(power_save);
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_POWER_SAVE_LISTENERS
|
||||
if (success) {
|
||||
for (auto *listener : this->power_save_listeners_) {
|
||||
listener->on_wifi_power_save(this->power_save_);
|
||||
@@ -511,12 +511,13 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) {
|
||||
it.channel);
|
||||
#endif
|
||||
s_sta_connected = true;
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
for (auto *listener : global_wifi_component->connect_state_listeners_) {
|
||||
listener->on_wifi_connect_state(StringRef(it.ssid, it.ssid_len), it.bssid);
|
||||
}
|
||||
#endif
|
||||
// For static IP configurations, GOT_IP event may not fire, so notify IP listeners here
|
||||
#ifdef USE_WIFI_MANUAL_IP
|
||||
#if defined(USE_WIFI_IP_STATE_LISTENERS) && defined(USE_WIFI_MANUAL_IP)
|
||||
if (const WiFiAP *config = global_wifi_component->get_selected_sta_();
|
||||
config && config->get_manual_ip().has_value()) {
|
||||
for (auto *listener : global_wifi_component->ip_state_listeners_) {
|
||||
@@ -524,7 +525,6 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) {
|
||||
global_wifi_component->get_dns_address(0), global_wifi_component->get_dns_address(1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -547,7 +547,7 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) {
|
||||
// This ensures is_connected() returns false during listener callbacks,
|
||||
// which is critical for proper reconnection logic (e.g., roaming).
|
||||
global_wifi_component->error_from_callback_ = true;
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
// Notify listeners AFTER setting error flag so they see correct state
|
||||
static constexpr uint8_t EMPTY_BSSID[6] = {};
|
||||
for (auto *listener : global_wifi_component->connect_state_listeners_) {
|
||||
@@ -578,7 +578,7 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) {
|
||||
ESP_LOGV(TAG, "static_ip=%s gateway=%s netmask=%s", network::IPAddress(&it.ip).str_to(ip_buf),
|
||||
network::IPAddress(&it.gw).str_to(gw_buf), network::IPAddress(&it.mask).str_to(mask_buf));
|
||||
s_sta_got_ip = true;
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_IP_STATE_LISTENERS
|
||||
for (auto *listener : global_wifi_component->ip_state_listeners_) {
|
||||
listener->on_ip_state(global_wifi_component->wifi_sta_ip_addresses(), global_wifi_component->get_dns_address(0),
|
||||
global_wifi_component->get_dns_address(1));
|
||||
@@ -771,7 +771,7 @@ void WiFiComponent::wifi_scan_done_callback_(void *arg, STATUS status) {
|
||||
it->is_hidden != 0);
|
||||
}
|
||||
this->scan_done_ = true;
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_SCAN_RESULTS_LISTENERS
|
||||
for (auto *listener : global_wifi_component->scan_results_listeners_) {
|
||||
listener->on_wifi_scan_results(global_wifi_component->scan_result_);
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ bool WiFiComponent::wifi_apply_power_save_() {
|
||||
break;
|
||||
}
|
||||
bool success = esp_wifi_set_ps(power_save) == ESP_OK;
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_POWER_SAVE_LISTENERS
|
||||
if (success) {
|
||||
for (auto *listener : this->power_save_listeners_) {
|
||||
listener->on_wifi_power_save(this->power_save_);
|
||||
@@ -741,18 +741,18 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
|
||||
(const char *) it.ssid, bssid_buf, it.channel, get_auth_mode_str(it.authmode));
|
||||
#endif
|
||||
s_sta_connected = true;
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
for (auto *listener : this->connect_state_listeners_) {
|
||||
listener->on_wifi_connect_state(StringRef(it.ssid, it.ssid_len), it.bssid);
|
||||
}
|
||||
#endif
|
||||
// For static IP configurations, GOT_IP event may not fire, so notify IP listeners here
|
||||
#ifdef USE_WIFI_MANUAL_IP
|
||||
#if defined(USE_WIFI_IP_STATE_LISTENERS) && defined(USE_WIFI_MANUAL_IP)
|
||||
if (const WiFiAP *config = this->get_selected_sta_(); config && config->get_manual_ip().has_value()) {
|
||||
for (auto *listener : this->ip_state_listeners_) {
|
||||
listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
} else if (data->event_base == WIFI_EVENT && data->event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
@@ -774,7 +774,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
|
||||
s_sta_connected = false;
|
||||
s_sta_connecting = false;
|
||||
error_from_callback_ = true;
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
static constexpr uint8_t EMPTY_BSSID[6] = {};
|
||||
for (auto *listener : this->connect_state_listeners_) {
|
||||
listener->on_wifi_connect_state(StringRef(), EMPTY_BSSID);
|
||||
@@ -788,7 +788,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
|
||||
#endif /* USE_NETWORK_IPV6 */
|
||||
ESP_LOGV(TAG, "static_ip=" IPSTR " gateway=" IPSTR, IP2STR(&it.ip_info.ip), IP2STR(&it.ip_info.gw));
|
||||
this->got_ipv4_address_ = true;
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_IP_STATE_LISTENERS
|
||||
for (auto *listener : this->ip_state_listeners_) {
|
||||
listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
|
||||
}
|
||||
@@ -799,7 +799,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
|
||||
const auto &it = data->data.ip_got_ip6;
|
||||
ESP_LOGV(TAG, "IPv6 address=" IPV6STR, IPV62STR(it.ip6_info.ip));
|
||||
this->num_ipv6_addresses_++;
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_IP_STATE_LISTENERS
|
||||
for (auto *listener : this->ip_state_listeners_) {
|
||||
listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
|
||||
}
|
||||
@@ -843,7 +843,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
|
||||
scan_result_.emplace_back(bssid, ssid, record.primary, record.rssi, record.authmode != WIFI_AUTH_OPEN,
|
||||
ssid.empty());
|
||||
}
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_SCAN_RESULTS_LISTENERS
|
||||
for (auto *listener : this->scan_results_listeners_) {
|
||||
listener->on_wifi_scan_results(this->scan_result_);
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ bool WiFiComponent::wifi_sta_pre_setup_() {
|
||||
}
|
||||
bool WiFiComponent::wifi_apply_power_save_() {
|
||||
bool success = WiFi.setSleep(this->power_save_ != WIFI_POWER_SAVE_NONE);
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_POWER_SAVE_LISTENERS
|
||||
if (success) {
|
||||
for (auto *listener : this->power_save_listeners_) {
|
||||
listener->on_wifi_power_save(this->power_save_);
|
||||
@@ -455,19 +455,19 @@ void WiFiComponent::wifi_process_event_(LTWiFiEvent *event) {
|
||||
// Note: We don't set CONNECTED state here yet - wait for GOT_IP
|
||||
// This matches ESP32 IDF behavior where s_sta_connected is set but
|
||||
// wifi_sta_connect_status_() also checks got_ipv4_address_
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
for (auto *listener : this->connect_state_listeners_) {
|
||||
listener->on_wifi_connect_state(StringRef(it.ssid, it.ssid_len), it.bssid);
|
||||
}
|
||||
#endif
|
||||
// For static IP configurations, GOT_IP event may not fire, so notify IP listeners here
|
||||
#ifdef USE_WIFI_MANUAL_IP
|
||||
#if defined(USE_WIFI_IP_STATE_LISTENERS) && defined(USE_WIFI_MANUAL_IP)
|
||||
if (const WiFiAP *config = this->get_selected_sta_(); config && config->get_manual_ip().has_value()) {
|
||||
s_sta_state = LTWiFiSTAState::CONNECTED;
|
||||
for (auto *listener : this->ip_state_listeners_) {
|
||||
listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -521,7 +521,7 @@ void WiFiComponent::wifi_process_event_(LTWiFiEvent *event) {
|
||||
this->error_from_callback_ = true;
|
||||
}
|
||||
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
static constexpr uint8_t EMPTY_BSSID[6] = {};
|
||||
for (auto *listener : this->connect_state_listeners_) {
|
||||
listener->on_wifi_connect_state(StringRef(), EMPTY_BSSID);
|
||||
@@ -547,7 +547,7 @@ void WiFiComponent::wifi_process_event_(LTWiFiEvent *event) {
|
||||
ESP_LOGV(TAG, "static_ip=%s gateway=%s", network::IPAddress(WiFi.localIP()).str_to(ip_buf),
|
||||
network::IPAddress(WiFi.gatewayIP()).str_to(gw_buf));
|
||||
s_sta_state = LTWiFiSTAState::CONNECTED;
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_IP_STATE_LISTENERS
|
||||
for (auto *listener : this->ip_state_listeners_) {
|
||||
listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
|
||||
}
|
||||
@@ -556,7 +556,7 @@ void WiFiComponent::wifi_process_event_(LTWiFiEvent *event) {
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_GOT_IP6: {
|
||||
ESP_LOGV(TAG, "Got IPv6");
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_IP_STATE_LISTENERS
|
||||
for (auto *listener : this->ip_state_listeners_) {
|
||||
listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
|
||||
}
|
||||
@@ -677,7 +677,7 @@ void WiFiComponent::wifi_scan_done_callback_() {
|
||||
ssid.length() == 0);
|
||||
}
|
||||
WiFi.scanDelete();
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_SCAN_RESULTS_LISTENERS
|
||||
for (auto *listener : this->scan_results_listeners_) {
|
||||
listener->on_wifi_scan_results(this->scan_result_);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ bool WiFiComponent::wifi_apply_power_save_() {
|
||||
}
|
||||
int ret = cyw43_wifi_pm(&cyw43_state, pm);
|
||||
bool success = ret == 0;
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_POWER_SAVE_LISTENERS
|
||||
if (success) {
|
||||
for (auto *listener : this->power_save_listeners_) {
|
||||
listener->on_wifi_power_save(this->power_save_);
|
||||
@@ -245,7 +245,7 @@ void WiFiComponent::wifi_loop_() {
|
||||
if (this->state_ == WIFI_COMPONENT_STATE_STA_SCANNING && !cyw43_wifi_scan_active(&cyw43_state)) {
|
||||
this->scan_done_ = true;
|
||||
ESP_LOGV(TAG, "Scan done");
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_SCAN_RESULTS_LISTENERS
|
||||
for (auto *listener : this->scan_results_listeners_) {
|
||||
listener->on_wifi_scan_results(this->scan_result_);
|
||||
}
|
||||
@@ -263,28 +263,28 @@ void WiFiComponent::wifi_loop_() {
|
||||
// Just connected
|
||||
s_sta_was_connected = true;
|
||||
ESP_LOGV(TAG, "Connected");
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
String ssid = WiFi.SSID();
|
||||
bssid_t bssid = this->wifi_bssid();
|
||||
for (auto *listener : this->connect_state_listeners_) {
|
||||
listener->on_wifi_connect_state(StringRef(ssid.c_str(), ssid.length()), bssid);
|
||||
}
|
||||
#endif
|
||||
// For static IP configurations, notify IP listeners immediately as the IP is already configured
|
||||
#ifdef USE_WIFI_MANUAL_IP
|
||||
#if defined(USE_WIFI_IP_STATE_LISTENERS) && defined(USE_WIFI_MANUAL_IP)
|
||||
if (const WiFiAP *config = this->get_selected_sta_(); config && config->get_manual_ip().has_value()) {
|
||||
s_sta_had_ip = true;
|
||||
for (auto *listener : this->ip_state_listeners_) {
|
||||
listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
} else if (!is_connected && s_sta_was_connected) {
|
||||
// Just disconnected
|
||||
s_sta_was_connected = false;
|
||||
s_sta_had_ip = false;
|
||||
ESP_LOGV(TAG, "Disconnected");
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
static constexpr uint8_t EMPTY_BSSID[6] = {};
|
||||
for (auto *listener : this->connect_state_listeners_) {
|
||||
listener->on_wifi_connect_state(StringRef(), EMPTY_BSSID);
|
||||
@@ -305,7 +305,7 @@ void WiFiComponent::wifi_loop_() {
|
||||
// Just got IP address
|
||||
s_sta_had_ip = true;
|
||||
ESP_LOGV(TAG, "Got IP address");
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_IP_STATE_LISTENERS
|
||||
for (auto *listener : this->ip_state_listeners_) {
|
||||
listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
|
||||
}
|
||||
|
||||
@@ -69,16 +69,6 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
}
|
||||
)
|
||||
|
||||
# Keys that require WiFi listeners
|
||||
_NETWORK_INFO_KEYS = {
|
||||
CONF_SSID,
|
||||
CONF_BSSID,
|
||||
CONF_IP_ADDRESS,
|
||||
CONF_DNS_ADDRESS,
|
||||
CONF_SCAN_RESULTS,
|
||||
CONF_POWER_SAVE_MODE,
|
||||
}
|
||||
|
||||
|
||||
async def setup_conf(config, key):
|
||||
if key in config:
|
||||
@@ -88,16 +78,28 @@ async def setup_conf(config, key):
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
# Request WiFi listeners for any sensor that needs them
|
||||
if _NETWORK_INFO_KEYS.intersection(config):
|
||||
wifi.request_wifi_listeners()
|
||||
# Request specific WiFi listeners based on which sensors are configured
|
||||
# SSID and BSSID use WiFiConnectStateListener
|
||||
if CONF_SSID in config or CONF_BSSID in config:
|
||||
wifi.request_wifi_connect_state_listener()
|
||||
|
||||
# IP address and DNS use WiFiIPStateListener
|
||||
if CONF_IP_ADDRESS in config or CONF_DNS_ADDRESS in config:
|
||||
wifi.request_wifi_ip_state_listener()
|
||||
|
||||
# Scan results use WiFiScanResultsListener
|
||||
if CONF_SCAN_RESULTS in config:
|
||||
wifi.request_wifi_scan_results_listener()
|
||||
wifi.request_wifi_scan_results()
|
||||
|
||||
# Power save mode uses WiFiPowerSaveListener
|
||||
if CONF_POWER_SAVE_MODE in config:
|
||||
wifi.request_wifi_power_save_listener()
|
||||
|
||||
await setup_conf(config, CONF_SSID)
|
||||
await setup_conf(config, CONF_BSSID)
|
||||
await setup_conf(config, CONF_MAC_ADDRESS)
|
||||
if CONF_SCAN_RESULTS in config:
|
||||
await setup_conf(config, CONF_SCAN_RESULTS)
|
||||
wifi.request_wifi_scan_results()
|
||||
await setup_conf(config, CONF_SCAN_RESULTS)
|
||||
await setup_conf(config, CONF_DNS_ADDRESS)
|
||||
await setup_conf(config, CONF_POWER_SAVE_MODE)
|
||||
if conf := config.get(CONF_IP_ADDRESS):
|
||||
|
||||
@@ -10,9 +10,7 @@ namespace esphome::wifi_info {
|
||||
|
||||
static const char *const TAG = "wifi_info";
|
||||
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
|
||||
static constexpr size_t MAX_STATE_LENGTH = 255;
|
||||
#ifdef USE_WIFI_IP_STATE_LISTENERS
|
||||
|
||||
/********************
|
||||
* IPAddressWiFiInfo
|
||||
@@ -58,6 +56,10 @@ void DNSAddressWifiInfo::on_ip_state(const network::IPAddresses &ips, const netw
|
||||
this->publish_state(buf);
|
||||
}
|
||||
|
||||
#endif // USE_WIFI_IP_STATE_LISTENERS
|
||||
|
||||
#ifdef USE_WIFI_SCAN_RESULTS_LISTENERS
|
||||
|
||||
/**********************
|
||||
* ScanResultsWiFiInfo
|
||||
*********************/
|
||||
@@ -80,9 +82,9 @@ static char *format_scan_entry(char *buf, const char *ssid, size_t ssid_len, int
|
||||
}
|
||||
|
||||
void ScanResultsWiFiInfo::on_wifi_scan_results(const wifi::wifi_scan_vector_t<wifi::WiFiScanResult> &results) {
|
||||
char buf[MAX_STATE_LENGTH + 1];
|
||||
char buf[MAX_STATE_LEN + 1];
|
||||
char *ptr = buf;
|
||||
const char *end = buf + MAX_STATE_LENGTH;
|
||||
const char *end = buf + MAX_STATE_LEN;
|
||||
|
||||
for (const auto &scan : results) {
|
||||
if (scan.get_is_hidden())
|
||||
@@ -98,6 +100,10 @@ void ScanResultsWiFiInfo::on_wifi_scan_results(const wifi::wifi_scan_vector_t<wi
|
||||
this->publish_state(buf);
|
||||
}
|
||||
|
||||
#endif // USE_WIFI_SCAN_RESULTS_LISTENERS
|
||||
|
||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
|
||||
/***************
|
||||
* SSIDWiFiInfo
|
||||
**************/
|
||||
@@ -126,6 +132,10 @@ void BSSIDWiFiInfo::on_wifi_connect_state(StringRef ssid, std::span<const uint8_
|
||||
this->publish_state(buf);
|
||||
}
|
||||
|
||||
#endif // USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
|
||||
#ifdef USE_WIFI_POWER_SAVE_LISTENERS
|
||||
|
||||
/************************
|
||||
* PowerSaveModeWiFiInfo
|
||||
***********************/
|
||||
@@ -182,7 +192,7 @@ void PowerSaveModeWiFiInfo::on_wifi_power_save(wifi::WiFiPowerSaveMode mode) {
|
||||
this->publish_state(mode_str);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // USE_WIFI_POWER_SAVE_LISTENERS
|
||||
|
||||
/*********************
|
||||
* MacAddressWifiInfo
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace esphome::wifi_info {
|
||||
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_IP_STATE_LISTENERS
|
||||
class IPAddressWiFiInfo final : public Component, public text_sensor::TextSensor, public wifi::WiFiIPStateListener {
|
||||
public:
|
||||
void setup() override;
|
||||
@@ -35,7 +35,9 @@ class DNSAddressWifiInfo final : public Component, public text_sensor::TextSenso
|
||||
void on_ip_state(const network::IPAddresses &ips, const network::IPAddress &dns1,
|
||||
const network::IPAddress &dns2) override;
|
||||
};
|
||||
#endif // USE_WIFI_IP_STATE_LISTENERS
|
||||
|
||||
#ifdef USE_WIFI_SCAN_RESULTS_LISTENERS
|
||||
class ScanResultsWiFiInfo final : public Component,
|
||||
public text_sensor::TextSensor,
|
||||
public wifi::WiFiScanResultsListener {
|
||||
@@ -47,7 +49,9 @@ class ScanResultsWiFiInfo final : public Component,
|
||||
// WiFiScanResultsListener interface
|
||||
void on_wifi_scan_results(const wifi::wifi_scan_vector_t<wifi::WiFiScanResult> &results) override;
|
||||
};
|
||||
#endif // USE_WIFI_SCAN_RESULTS_LISTENERS
|
||||
|
||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
class SSIDWiFiInfo final : public Component, public text_sensor::TextSensor, public wifi::WiFiConnectStateListener {
|
||||
public:
|
||||
void setup() override;
|
||||
@@ -65,7 +69,9 @@ class BSSIDWiFiInfo final : public Component, public text_sensor::TextSensor, pu
|
||||
// WiFiConnectStateListener interface
|
||||
void on_wifi_connect_state(StringRef ssid, std::span<const uint8_t, 6> bssid) override;
|
||||
};
|
||||
#endif // USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
|
||||
#ifdef USE_WIFI_POWER_SAVE_LISTENERS
|
||||
class PowerSaveModeWiFiInfo final : public Component,
|
||||
public text_sensor::TextSensor,
|
||||
public wifi::WiFiPowerSaveListener {
|
||||
@@ -76,7 +82,7 @@ class PowerSaveModeWiFiInfo final : public Component,
|
||||
// WiFiPowerSaveListener interface
|
||||
void on_wifi_power_save(wifi::WiFiPowerSaveMode mode) override;
|
||||
};
|
||||
#endif
|
||||
#endif // USE_WIFI_POWER_SAVE_LISTENERS
|
||||
|
||||
class MacAddressWifiInfo final : public Component, public text_sensor::TextSensor {
|
||||
public:
|
||||
|
||||
@@ -25,6 +25,6 @@ CONFIG_SCHEMA = sensor.sensor_schema(
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
wifi.request_wifi_listeners()
|
||||
wifi.request_wifi_connect_state_listener()
|
||||
var = await sensor.new_sensor(config)
|
||||
await cg.register_component(var, config)
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
#include <span>
|
||||
namespace esphome::wifi_signal {
|
||||
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
class WiFiSignalSensor : public sensor::Sensor, public PollingComponent, public wifi::WiFiConnectStateListener {
|
||||
#else
|
||||
class WiFiSignalSensor : public sensor::Sensor, public PollingComponent {
|
||||
#endif
|
||||
public:
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
void setup() override { wifi::global_wifi_component->add_connect_state_listener(this); }
|
||||
#endif
|
||||
void update() override {
|
||||
@@ -28,7 +28,7 @@ class WiFiSignalSensor : public sensor::Sensor, public PollingComponent {
|
||||
|
||||
float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
|
||||
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
// WiFiConnectStateListener interface - update RSSI immediately on connect
|
||||
void on_wifi_connect_state(StringRef ssid, std::span<const uint8_t, 6> bssid) override { this->update(); }
|
||||
#endif
|
||||
|
||||
@@ -222,7 +222,14 @@
|
||||
#define USE_CAPTIVE_PORTAL_GZIP
|
||||
#define USE_WIFI_11KV_SUPPORT
|
||||
#define USE_WIFI_FAST_CONNECT
|
||||
#define USE_WIFI_LISTENERS
|
||||
#define USE_WIFI_IP_STATE_LISTENERS
|
||||
#define USE_WIFI_SCAN_RESULTS_LISTENERS
|
||||
#define USE_WIFI_CONNECT_STATE_LISTENERS
|
||||
#define USE_WIFI_POWER_SAVE_LISTENERS
|
||||
#define ESPHOME_WIFI_IP_STATE_LISTENERS 2
|
||||
#define ESPHOME_WIFI_SCAN_RESULTS_LISTENERS 2
|
||||
#define ESPHOME_WIFI_CONNECT_STATE_LISTENERS 2
|
||||
#define ESPHOME_WIFI_POWER_SAVE_LISTENERS 2
|
||||
#define USE_WIFI_RUNTIME_POWER_SAVE
|
||||
#define USB_HOST_MAX_REQUESTS 16
|
||||
|
||||
|
||||
Reference in New Issue
Block a user