[wifi_info] Use callbacks instead of polling

This commit is contained in:
kbx81
2025-09-15 18:35:25 -05:00
parent 4859fe67eb
commit eae9335894
10 changed files with 288 additions and 199 deletions
+113
View File
@@ -0,0 +1,113 @@
#pragma once
#include "esphome/core/defines.h"
#ifdef USE_WIFI
#include "wifi_component.h"
namespace esphome {
namespace wifi {
template<typename... Ts> class WiFiConnectedCondition : public Condition<Ts...> {
public:
bool check(Ts... x) override { return global_wifi_component->is_connected(); }
};
template<typename... Ts> class WiFiEnabledCondition : public Condition<Ts...> {
public:
bool check(Ts... x) override { return !global_wifi_component->is_disabled(); }
};
template<typename... Ts> class WiFiEnableAction : public Action<Ts...> {
public:
void play(Ts... x) override { global_wifi_component->enable(); }
};
template<typename... Ts> class WiFiDisableAction : public Action<Ts...> {
public:
void play(Ts... x) override { global_wifi_component->disable(); }
};
template<typename... Ts> class WiFiConfigureAction : public Action<Ts...>, public Component {
public:
TEMPLATABLE_VALUE(std::string, ssid)
TEMPLATABLE_VALUE(std::string, password)
TEMPLATABLE_VALUE(bool, save)
TEMPLATABLE_VALUE(uint32_t, connection_timeout)
void play(Ts... x) override {
auto ssid = this->ssid_.value(x...);
auto password = this->password_.value(x...);
// Avoid multiple calls
if (this->connecting_)
return;
// If already connected to the same AP, do nothing
if (global_wifi_component->wifi_ssid() == ssid) {
// Callback to notify the user that the connection was successful
this->connect_trigger_->trigger();
return;
}
// Create a new WiFiAP object with the new SSID and password
this->new_sta_.set_ssid(ssid);
this->new_sta_.set_password(password);
// Save the current STA
this->old_sta_ = global_wifi_component->get_sta();
// Disable WiFi
global_wifi_component->disable();
// Set the state to connecting
this->connecting_ = true;
// Store the new STA so once the WiFi is enabled, it will connect to it
// This is necessary because the WiFiComponent will raise an error and fallback to the saved STA
// if trying to connect to a new STA while already connected to another one
if (this->save_.value(x...)) {
global_wifi_component->save_wifi_sta(new_sta_.get_ssid(), new_sta_.get_password());
} else {
global_wifi_component->set_sta(new_sta_);
}
// Enable WiFi
global_wifi_component->enable();
// Set timeout for the connection
this->set_timeout("wifi-connect-timeout", this->connection_timeout_.value(x...), [this, x...]() {
// If the timeout is reached, stop connecting and revert to the old AP
global_wifi_component->disable();
global_wifi_component->save_wifi_sta(old_sta_.get_ssid(), old_sta_.get_password());
global_wifi_component->enable();
// Start a timeout for the fallback if the connection to the old AP fails
this->set_timeout("wifi-fallback-timeout", this->connection_timeout_.value(x...), [this]() {
this->connecting_ = false;
this->error_trigger_->trigger();
});
});
}
Trigger<> *get_connect_trigger() const { return this->connect_trigger_; }
Trigger<> *get_error_trigger() const { return this->error_trigger_; }
void loop() override {
if (!this->connecting_)
return;
if (global_wifi_component->is_connected()) {
// The WiFi is connected, stop the timeout and reset the connecting flag
this->cancel_timeout("wifi-connect-timeout");
this->cancel_timeout("wifi-fallback-timeout");
this->connecting_ = false;
if (global_wifi_component->wifi_ssid() == this->new_sta_.get_ssid()) {
// Callback to notify the user that the connection was successful
this->connect_trigger_->trigger();
} else {
// Callback to notify the user that the connection failed
this->error_trigger_->trigger();
}
}
}
protected:
bool connecting_{false};
WiFiAP new_sta_;
WiFiAP old_sta_;
Trigger<> *connect_trigger_{new Trigger<>()};
Trigger<> *error_trigger_{new Trigger<>()};
};
} // namespace wifi
} // namespace esphome
#endif
+22 -101
View File
@@ -322,6 +322,25 @@ class WiFiComponent : public Component {
int32_t get_wifi_channel();
/// Add a callback that will be called on configuration changes (IP change, SSID change, etc.)
/// @param callback The callback to be called; template arguments are:
/// - IP addresses
/// - DNS address 1
/// - DNS address 2
void add_on_ip_state_callback(
std::function<void(network::IPAddresses, network::IPAddress, network::IPAddress)> &&callback) {
this->ip_state_callback_.add(std::move(callback));
}
/// - Wi-Fi scan results
void add_on_wifi_scan_state_callback(std::function<void(std::vector<wifi::WiFiScanResult>)> &&callback) {
this->wifi_scan_state_callback_.add(std::move(callback));
}
/// - Wi-Fi SSID
/// - Wi-Fi BSSID
void add_on_wifi_connect_state_callback(std::function<void(std::string, wifi::bssid_t)> &&callback) {
this->wifi_connect_state_callback_.add(std::move(callback));
}
protected:
#ifdef USE_WIFI_AP
void setup_ap_config_();
@@ -389,6 +408,9 @@ class WiFiComponent : public Component {
WiFiAP selected_ap_;
WiFiAP ap_;
optional<float> output_power_;
CallbackManager<void(network::IPAddresses, network::IPAddress, network::IPAddress)> ip_state_callback_;
CallbackManager<void(std::vector<wifi::WiFiScanResult>)> wifi_scan_state_callback_;
CallbackManager<void(std::string, wifi::bssid_t)> wifi_connect_state_callback_;
ESPPreferenceObject pref_;
ESPPreferenceObject fast_connect_pref_;
@@ -432,107 +454,6 @@ class WiFiComponent : public Component {
extern WiFiComponent *global_wifi_component; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
template<typename... Ts> class WiFiConnectedCondition : public Condition<Ts...> {
public:
bool check(Ts... x) override { return global_wifi_component->is_connected(); }
};
template<typename... Ts> class WiFiEnabledCondition : public Condition<Ts...> {
public:
bool check(Ts... x) override { return !global_wifi_component->is_disabled(); }
};
template<typename... Ts> class WiFiEnableAction : public Action<Ts...> {
public:
void play(Ts... x) override { global_wifi_component->enable(); }
};
template<typename... Ts> class WiFiDisableAction : public Action<Ts...> {
public:
void play(Ts... x) override { global_wifi_component->disable(); }
};
template<typename... Ts> class WiFiConfigureAction : public Action<Ts...>, public Component {
public:
TEMPLATABLE_VALUE(std::string, ssid)
TEMPLATABLE_VALUE(std::string, password)
TEMPLATABLE_VALUE(bool, save)
TEMPLATABLE_VALUE(uint32_t, connection_timeout)
void play(Ts... x) override {
auto ssid = this->ssid_.value(x...);
auto password = this->password_.value(x...);
// Avoid multiple calls
if (this->connecting_)
return;
// If already connected to the same AP, do nothing
if (global_wifi_component->wifi_ssid() == ssid) {
// Callback to notify the user that the connection was successful
this->connect_trigger_->trigger();
return;
}
// Create a new WiFiAP object with the new SSID and password
this->new_sta_.set_ssid(ssid);
this->new_sta_.set_password(password);
// Save the current STA
this->old_sta_ = global_wifi_component->get_sta();
// Disable WiFi
global_wifi_component->disable();
// Set the state to connecting
this->connecting_ = true;
// Store the new STA so once the WiFi is enabled, it will connect to it
// This is necessary because the WiFiComponent will raise an error and fallback to the saved STA
// if trying to connect to a new STA while already connected to another one
if (this->save_.value(x...)) {
global_wifi_component->save_wifi_sta(new_sta_.get_ssid(), new_sta_.get_password());
} else {
global_wifi_component->set_sta(new_sta_);
}
// Enable WiFi
global_wifi_component->enable();
// Set timeout for the connection
this->set_timeout("wifi-connect-timeout", this->connection_timeout_.value(x...), [this, x...]() {
// If the timeout is reached, stop connecting and revert to the old AP
global_wifi_component->disable();
global_wifi_component->save_wifi_sta(old_sta_.get_ssid(), old_sta_.get_password());
global_wifi_component->enable();
// Start a timeout for the fallback if the connection to the old AP fails
this->set_timeout("wifi-fallback-timeout", this->connection_timeout_.value(x...), [this]() {
this->connecting_ = false;
this->error_trigger_->trigger();
});
});
}
Trigger<> *get_connect_trigger() const { return this->connect_trigger_; }
Trigger<> *get_error_trigger() const { return this->error_trigger_; }
void loop() override {
if (!this->connecting_)
return;
if (global_wifi_component->is_connected()) {
// The WiFi is connected, stop the timeout and reset the connecting flag
this->cancel_timeout("wifi-connect-timeout");
this->cancel_timeout("wifi-fallback-timeout");
this->connecting_ = false;
if (global_wifi_component->wifi_ssid() == this->new_sta_.get_ssid()) {
// Callback to notify the user that the connection was successful
this->connect_trigger_->trigger();
} else {
// Callback to notify the user that the connection failed
this->error_trigger_->trigger();
}
}
}
protected:
bool connecting_{false};
WiFiAP new_sta_;
WiFiAP old_sta_;
Trigger<> *connect_trigger_{new Trigger<>()};
Trigger<> *error_trigger_{new Trigger<>()};
};
} // namespace wifi
} // namespace esphome
#endif
@@ -559,7 +559,7 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
#if USE_NETWORK_IPV6
this->set_timeout(100, [] { WiFi.enableIPv6(); });
#endif /* USE_NETWORK_IPV6 */
this->wifi_connect_state_callback_.call(this->wifi_ssid(), this->wifi_bssid());
break;
}
case ESPHOME_EVENT_ID_WIFI_STA_DISCONNECTED: {
@@ -586,6 +586,7 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
}
s_sta_connecting = false;
this->wifi_connect_state_callback_.call("", bssid_t({0, 0, 0, 0, 0, 0}));
break;
}
case ESPHOME_EVENT_ID_WIFI_STA_AUTHMODE_CHANGE: {
@@ -614,6 +615,7 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
#else
s_sta_connecting = false;
#endif /* USE_NETWORK_IPV6 */
this->ip_state_callback_.call(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
break;
}
#if USE_NETWORK_IPV6
@@ -622,6 +624,7 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
ESP_LOGV(TAG, "IPv6 address=" IPV6STR, IPV62STR(it.ip));
this->num_ipv6_addresses_++;
s_sta_connecting = !(this->got_ipv4_address_ & (this->num_ipv6_addresses_ >= USE_NETWORK_MIN_IPV6_ADDR_COUNT));
this->ip_state_callback_.call(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
break;
}
#endif /* USE_NETWORK_IPV6 */
@@ -715,6 +718,7 @@ void WiFiComponent::wifi_scan_done_callback_() {
}
WiFi.scanDelete();
this->scan_done_ = true;
this->wifi_scan_state_callback_.call(this->scan_result_);
}
#ifdef USE_WIFI_AP
@@ -499,6 +499,8 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) {
ESP_LOGV(TAG, "Connected ssid='%s' bssid=%s channel=%u", buf, format_mac_address_pretty(it.bssid).c_str(),
it.channel);
s_sta_connected = true;
global_wifi_component->wifi_connect_state_callback_.call(global_wifi_component->wifi_ssid(),
global_wifi_component->wifi_bssid());
break;
}
case EVENT_STAMODE_DISCONNECTED: {
@@ -516,6 +518,7 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) {
}
s_sta_connected = false;
s_sta_connecting = false;
global_wifi_component->wifi_connect_state_callback_.call("", bssid_t({0, 0, 0, 0, 0, 0}));
break;
}
case EVENT_STAMODE_AUTHMODE_CHANGE: {
@@ -538,6 +541,9 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) {
ESP_LOGV(TAG, "static_ip=%s gateway=%s netmask=%s", format_ip_addr(it.ip).c_str(), format_ip_addr(it.gw).c_str(),
format_ip_addr(it.mask).c_str());
s_sta_got_ip = true;
global_wifi_component->ip_state_callback_.call(global_wifi_component->wifi_sta_ip_addresses(),
global_wifi_component->get_dns_address(0),
global_wifi_component->get_dns_address(1));
break;
}
case EVENT_STAMODE_DHCP_TIMEOUT: {
@@ -704,6 +710,7 @@ void WiFiComponent::wifi_scan_done_callback_(void *arg, STATUS status) {
this->scan_result_.push_back(res);
}
this->scan_done_ = true;
global_wifi_component->wifi_scan_state_callback_.call(global_wifi_component->scan_result_);
}
#ifdef USE_WIFI_AP
@@ -713,6 +713,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
ESP_LOGV(TAG, "Connected ssid='%s' bssid=" LOG_SECRET("%s") " channel=%u, authmode=%s", buf,
format_mac_address_pretty(it.bssid).c_str(), it.channel, get_auth_mode_str(it.authmode));
s_sta_connected = true;
this->wifi_connect_state_callback_.call(this->wifi_ssid(), this->wifi_bssid());
} else if (data->event_base == WIFI_EVENT && data->event_id == WIFI_EVENT_STA_DISCONNECTED) {
const auto &it = data->data.sta_disconnected;
@@ -734,6 +735,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
s_sta_connected = false;
s_sta_connecting = false;
error_from_callback_ = true;
this->wifi_connect_state_callback_.call("", bssid_t({0, 0, 0, 0, 0, 0}));
} else if (data->event_base == IP_EVENT && data->event_id == IP_EVENT_STA_GOT_IP) {
const auto &it = data->data.ip_got_ip;
@@ -743,12 +745,14 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
ESP_LOGV(TAG, "static_ip=%s gateway=%s", format_ip4_addr(it.ip_info.ip).c_str(),
format_ip4_addr(it.ip_info.gw).c_str());
this->got_ipv4_address_ = true;
this->ip_state_callback_.call(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
#if USE_NETWORK_IPV6
} else if (data->event_base == IP_EVENT && data->event_id == IP_EVENT_GOT_IP6) {
const auto &it = data->data.ip_got_ip6;
ESP_LOGV(TAG, "IPv6 address=%s", format_ip6_addr(it.ip6_info.ip).c_str());
this->num_ipv6_addresses_++;
this->ip_state_callback_.call(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
#endif /* USE_NETWORK_IPV6 */
} else if (data->event_base == IP_EVENT && data->event_id == IP_EVENT_STA_LOST_IP) {
@@ -789,6 +793,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
WiFiScanResult result(bssid, ssid, record.primary, record.rssi, record.authmode != WIFI_AUTH_OPEN, ssid.empty());
scan_result_.push_back(result);
}
this->wifi_scan_state_callback_.call(this->scan_result_);
} else if (data->event_base == WIFI_EVENT && data->event_id == WIFI_EVENT_AP_START) {
ESP_LOGV(TAG, "AP start");
@@ -282,7 +282,7 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
buf[it.ssid_len] = '\0';
ESP_LOGV(TAG, "Connected ssid='%s' bssid=" LOG_SECRET("%s") " channel=%u, authmode=%s", buf,
format_mac_address_pretty(it.bssid).c_str(), it.channel, get_auth_mode_str(it.authmode));
this->wifi_connect_state_callback_.call(this->wifi_ssid(), this->wifi_bssid());
break;
}
case ESPHOME_EVENT_ID_WIFI_STA_DISCONNECTED: {
@@ -306,6 +306,7 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
}
s_sta_connecting = false;
this->wifi_connect_state_callback_.call("", bssid_t({0, 0, 0, 0, 0, 0}));
break;
}
case ESPHOME_EVENT_ID_WIFI_STA_AUTHMODE_CHANGE: {
@@ -327,11 +328,13 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
ESP_LOGV(TAG, "static_ip=%s gateway=%s", format_ip4_addr(WiFi.localIP()).c_str(),
format_ip4_addr(WiFi.gatewayIP()).c_str());
s_sta_connecting = false;
this->ip_state_callback_.call(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
break;
}
case ESPHOME_EVENT_ID_WIFI_STA_GOT_IP6: {
// auto it = info.got_ip.ip_info;
ESP_LOGV(TAG, "Got IPv6");
this->ip_state_callback_.call(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
break;
}
case ESPHOME_EVENT_ID_WIFI_STA_LOST_IP: {
@@ -425,6 +428,7 @@ void WiFiComponent::wifi_scan_done_callback_() {
}
WiFi.scanDelete();
this->scan_done_ = true;
this->wifi_scan_state_callback_.call(this->scan_result_);
}
#ifdef USE_WIFI_AP
@@ -51,7 +51,7 @@ bool WiFiComponent::wifi_apply_power_save_() {
return ret == 0;
}
// TODO: The driver doesnt seem to have an API for this
// TODO: The driver doesn't seem to have an API for this
bool WiFiComponent::wifi_apply_output_power_(float output_power) { return true; }
bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) {
@@ -210,6 +210,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");
this->wifi_scan_state_callback_.call(this->scan_result_);
}
}
+10 -14
View File
@@ -15,31 +15,27 @@ DEPENDENCIES = ["wifi"]
wifi_info_ns = cg.esphome_ns.namespace("wifi_info")
IPAddressWiFiInfo = wifi_info_ns.class_(
"IPAddressWiFiInfo", text_sensor.TextSensor, cg.PollingComponent
"IPAddressWiFiInfo", text_sensor.TextSensor, cg.Component
)
ScanResultsWiFiInfo = wifi_info_ns.class_(
"ScanResultsWiFiInfo", text_sensor.TextSensor, cg.PollingComponent
)
SSIDWiFiInfo = wifi_info_ns.class_(
"SSIDWiFiInfo", text_sensor.TextSensor, cg.PollingComponent
"ScanResultsWiFiInfo", text_sensor.TextSensor, cg.Component
)
SSIDWiFiInfo = wifi_info_ns.class_("SSIDWiFiInfo", text_sensor.TextSensor, cg.Component)
BSSIDWiFiInfo = wifi_info_ns.class_(
"BSSIDWiFiInfo", text_sensor.TextSensor, cg.PollingComponent
"BSSIDWiFiInfo", text_sensor.TextSensor, cg.Component
)
MacAddressWifiInfo = wifi_info_ns.class_(
"MacAddressWifiInfo", text_sensor.TextSensor, cg.Component
)
DNSAddressWifiInfo = wifi_info_ns.class_(
"DNSAddressWifiInfo", text_sensor.TextSensor, cg.PollingComponent
"DNSAddressWifiInfo", text_sensor.TextSensor, cg.Component
)
CONFIG_SCHEMA = cv.Schema(
{
cv.Optional(CONF_IP_ADDRESS): text_sensor.text_sensor_schema(
IPAddressWiFiInfo, entity_category=ENTITY_CATEGORY_DIAGNOSTIC
)
.extend(cv.polling_component_schema("1s"))
.extend(
).extend(
{
cv.Optional(f"address_{x}"): text_sensor.text_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
@@ -49,19 +45,19 @@ CONFIG_SCHEMA = cv.Schema(
),
cv.Optional(CONF_SCAN_RESULTS): text_sensor.text_sensor_schema(
ScanResultsWiFiInfo, entity_category=ENTITY_CATEGORY_DIAGNOSTIC
).extend(cv.polling_component_schema("60s")),
),
cv.Optional(CONF_SSID): text_sensor.text_sensor_schema(
SSIDWiFiInfo, entity_category=ENTITY_CATEGORY_DIAGNOSTIC
).extend(cv.polling_component_schema("1s")),
),
cv.Optional(CONF_BSSID): text_sensor.text_sensor_schema(
BSSIDWiFiInfo, entity_category=ENTITY_CATEGORY_DIAGNOSTIC
).extend(cv.polling_component_schema("1s")),
),
cv.Optional(CONF_MAC_ADDRESS): text_sensor.text_sensor_schema(
MacAddressWifiInfo, entity_category=ENTITY_CATEGORY_DIAGNOSTIC
),
cv.Optional(CONF_DNS_ADDRESS): text_sensor.text_sensor_schema(
DNSAddressWifiInfo, entity_category=ENTITY_CATEGORY_DIAGNOSTIC
).extend(cv.polling_component_schema("1s")),
),
}
)
@@ -7,13 +7,113 @@ namespace wifi_info {
static const char *const TAG = "wifi_info";
/********************
* IPAddressWiFiInfo
*******************/
void IPAddressWiFiInfo::setup() {
wifi::global_wifi_component->add_on_ip_state_callback(
[this](network::IPAddresses ips, network::IPAddress dns1_ip, network::IPAddress dns2_ip) {
this->state_callback_(ips);
});
}
void IPAddressWiFiInfo::dump_config() { LOG_TEXT_SENSOR("", "IP Address", this); }
void ScanResultsWiFiInfo::dump_config() { LOG_TEXT_SENSOR("", "Scan Results", this); }
void SSIDWiFiInfo::dump_config() { LOG_TEXT_SENSOR("", "SSID", this); }
void BSSIDWiFiInfo::dump_config() { LOG_TEXT_SENSOR("", "BSSID", this); }
void MacAddressWifiInfo::dump_config() { LOG_TEXT_SENSOR("", "MAC Address", this); }
void IPAddressWiFiInfo::state_callback_(network::IPAddresses ips) {
this->publish_state(ips[0].str());
uint8_t sensor = 0;
for (auto &ip : ips) {
if (ip.is_set()) {
if (this->ip_sensors_[sensor] != nullptr) {
this->ip_sensors_[sensor]->publish_state(ip.str());
}
sensor++;
}
}
}
/*********************
* DNSAddressWifiInfo
********************/
void DNSAddressWifiInfo::setup() {
wifi::global_wifi_component->add_on_ip_state_callback(
[this](network::IPAddresses ips, network::IPAddress dns1_ip, network::IPAddress dns2_ip) {
this->state_callback_(dns1_ip, dns2_ip);
});
}
void DNSAddressWifiInfo::dump_config() { LOG_TEXT_SENSOR("", "DNS Address", this); }
void DNSAddressWifiInfo::state_callback_(network::IPAddress dns1_ip, network::IPAddress dns2_ip) {
std::string dns_results = dns1_ip.str() + " " + dns2_ip.str();
this->publish_state(dns_results);
}
/**********************
* ScanResultsWiFiInfo
*********************/
void ScanResultsWiFiInfo::setup() {
wifi::global_wifi_component->add_on_wifi_scan_state_callback(
[this](const std::vector<wifi::WiFiScanResult> &results) { this->state_callback_(results); });
}
void ScanResultsWiFiInfo::dump_config() { LOG_TEXT_SENSOR("", "Scan Results", this); }
void ScanResultsWiFiInfo::state_callback_(const std::vector<wifi::WiFiScanResult> &results) {
std::string scan_results;
for (auto scan : results) {
if (scan.get_is_hidden())
continue;
scan_results += scan.get_ssid();
scan_results += ": ";
scan_results += esphome::to_string(scan.get_rssi());
scan_results += "dB\n";
}
// There's a limit of 255 characters per state; longer states just don't get sent so we truncate it
this->publish_state(scan_results.substr(0, 255));
}
/***************
* SSIDWiFiInfo
**************/
void SSIDWiFiInfo::setup() {
wifi::global_wifi_component->add_on_wifi_connect_state_callback(
[this](std::string ssid, wifi::bssid_t bssid) { this->state_callback_(ssid); });
}
void SSIDWiFiInfo::dump_config() { LOG_TEXT_SENSOR("", "SSID", this); }
void SSIDWiFiInfo::state_callback_(std::string &ssid) { this->publish_state(ssid); }
/****************
* BSSIDWiFiInfo
***************/
void BSSIDWiFiInfo::setup() {
wifi::global_wifi_component->add_on_wifi_connect_state_callback(
[this](std::string ssid, wifi::bssid_t bssid) { this->state_callback_(bssid); });
}
void BSSIDWiFiInfo::dump_config() { LOG_TEXT_SENSOR("", "BSSID", this); }
void BSSIDWiFiInfo::state_callback_(wifi::bssid_t bssid) {
char buf[18] = "unknown";
if (mac_address_is_valid(bssid.data())) {
format_mac_addr_upper(bssid.data(), buf);
}
this->publish_state(buf);
}
/*********************
* MacAddressWifiInfo
********************/
void MacAddressWifiInfo::dump_config() { LOG_TEXT_SENSOR("", "MAC Address", this); }
} // namespace wifi_info
} // namespace esphome
#endif
@@ -10,113 +10,51 @@
namespace esphome {
namespace wifi_info {
class IPAddressWiFiInfo : public PollingComponent, public text_sensor::TextSensor {
class IPAddressWiFiInfo : public Component, public text_sensor::TextSensor {
public:
void update() override {
auto ips = wifi::global_wifi_component->wifi_sta_ip_addresses();
if (ips != this->last_ips_) {
this->last_ips_ = ips;
this->publish_state(ips[0].str());
uint8_t sensor = 0;
for (auto &ip : ips) {
if (ip.is_set()) {
if (this->ip_sensors_[sensor] != nullptr) {
this->ip_sensors_[sensor]->publish_state(ip.str());
}
sensor++;
}
}
}
}
float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
void setup() override;
void dump_config() override;
void add_ip_sensors(uint8_t index, text_sensor::TextSensor *s) { this->ip_sensors_[index] = s; }
protected:
network::IPAddresses last_ips_;
void state_callback_(network::IPAddresses ips);
std::array<text_sensor::TextSensor *, 5> ip_sensors_;
};
class DNSAddressWifiInfo : public PollingComponent, public text_sensor::TextSensor {
class DNSAddressWifiInfo : public Component, public text_sensor::TextSensor {
public:
void update() override {
auto dns_one = wifi::global_wifi_component->get_dns_address(0);
auto dns_two = wifi::global_wifi_component->get_dns_address(1);
std::string dns_results = dns_one.str() + " " + dns_two.str();
if (dns_results != this->last_results_) {
this->last_results_ = dns_results;
this->publish_state(dns_results);
}
}
float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
void setup() override;
void dump_config() override;
protected:
std::string last_results_;
void state_callback_(network::IPAddress dns1_ip, network::IPAddress dns2_ip);
};
class ScanResultsWiFiInfo : public PollingComponent, public text_sensor::TextSensor {
class ScanResultsWiFiInfo : public Component, public text_sensor::TextSensor {
public:
void update() override {
std::string scan_results;
for (auto &scan : wifi::global_wifi_component->get_scan_result()) {
if (scan.get_is_hidden())
continue;
scan_results += scan.get_ssid();
scan_results += ": ";
scan_results += esphome::to_string(scan.get_rssi());
scan_results += "dB\n";
}
if (this->last_scan_results_ != scan_results) {
this->last_scan_results_ = scan_results;
// There's a limit of 255 characters per state.
// Longer states just don't get sent so we truncate it.
this->publish_state(scan_results.substr(0, 255));
}
}
float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
void setup() override;
void dump_config() override;
protected:
std::string last_scan_results_;
void state_callback_(const std::vector<wifi::WiFiScanResult> &results);
};
class SSIDWiFiInfo : public PollingComponent, public text_sensor::TextSensor {
class SSIDWiFiInfo : public Component, public text_sensor::TextSensor {
public:
void update() override {
std::string ssid = wifi::global_wifi_component->wifi_ssid();
if (this->last_ssid_ != ssid) {
this->last_ssid_ = ssid;
this->publish_state(this->last_ssid_);
}
}
float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
void setup() override;
void dump_config() override;
protected:
std::string last_ssid_;
void state_callback_(std::string &ssid);
};
class BSSIDWiFiInfo : public PollingComponent, public text_sensor::TextSensor {
class BSSIDWiFiInfo : public Component, public text_sensor::TextSensor {
public:
void update() override {
wifi::bssid_t bssid = wifi::global_wifi_component->wifi_bssid();
if (memcmp(bssid.data(), last_bssid_.data(), 6) != 0) {
std::copy(bssid.begin(), bssid.end(), last_bssid_.begin());
char buf[18];
format_mac_addr_upper(bssid.data(), buf);
this->publish_state(buf);
}
}
float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
void setup() override;
void dump_config() override;
protected:
wifi::bssid_t last_bssid_;
void state_callback_(wifi::bssid_t bssid);
};
class MacAddressWifiInfo : public Component, public text_sensor::TextSensor {