1
0
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:
J. Nick Koston
2026-01-13 16:20:39 -10:00
committed by GitHub
parent 2793e33baf
commit 47ee2f4ad9
12 changed files with 161 additions and 78 deletions

View File

@@ -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(

View File

@@ -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_;

View File

@@ -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_);
}

View File

@@ -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_);
}

View File

@@ -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_);
}

View File

@@ -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));
}

View File

@@ -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):

View File

@@ -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

View File

@@ -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:

View File

@@ -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)

View File

@@ -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

View File

@@ -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