diff --git a/esphome/components/debug/debug_component.cpp b/esphome/components/debug/debug_component.cpp index 790635e6c7..f54bf82eae 100644 --- a/esphome/components/debug/debug_component.cpp +++ b/esphome/components/debug/debug_component.cpp @@ -18,7 +18,6 @@ void DebugComponent::dump_config() { ESP_LOGCONFIG(TAG, "Debug component:"); #ifdef USE_TEXT_SENSOR LOG_TEXT_SENSOR(" ", "Device info", this->device_info_); - LOG_TEXT_SENSOR(" ", "WiFi Power Save Mode", this->wifi_power_save_); #endif // USE_TEXT_SENSOR #ifdef USE_SENSOR LOG_SENSOR(" ", "Free space on heap", this->free_sensor_); diff --git a/esphome/components/debug/debug_component.h b/esphome/components/debug/debug_component.h index 86217e9ae4..c997ad7bd7 100644 --- a/esphome/components/debug/debug_component.h +++ b/esphome/components/debug/debug_component.h @@ -10,9 +10,6 @@ #endif #ifdef USE_TEXT_SENSOR #include "esphome/components/text_sensor/text_sensor.h" -#if defined(USE_WIFI) && defined(USE_ESP32) -#include -#endif #endif // USE_TEXT_SENSOR namespace esphome { @@ -28,7 +25,6 @@ class DebugComponent : public PollingComponent { #ifdef USE_TEXT_SENSOR void set_device_info_sensor(text_sensor::TextSensor *device_info) { device_info_ = device_info; } void set_reset_reason_sensor(text_sensor::TextSensor *reset_reason) { reset_reason_ = reset_reason; } - void set_wifi_power_save_sensor(text_sensor::TextSensor *wifi_power_save) { wifi_power_save_ = wifi_power_save; } #endif // USE_TEXT_SENSOR #ifdef USE_SENSOR void set_free_sensor(sensor::Sensor *free_sensor) { free_sensor_ = free_sensor; } @@ -83,10 +79,6 @@ class DebugComponent : public PollingComponent { #ifdef USE_TEXT_SENSOR text_sensor::TextSensor *device_info_{nullptr}; text_sensor::TextSensor *reset_reason_{nullptr}; - text_sensor::TextSensor *wifi_power_save_{nullptr}; -#if defined(USE_WIFI) && defined(USE_ESP32) - wifi_ps_type_t last_wifi_ps_mode_{}; -#endif #endif // USE_TEXT_SENSOR std::string get_reset_reason_(); diff --git a/esphome/components/debug/debug_esp32.cpp b/esphome/components/debug/debug_esp32.cpp index 3d84b3a235..1c3dc3699b 100644 --- a/esphome/components/debug/debug_esp32.cpp +++ b/esphome/components/debug/debug_esp32.cpp @@ -11,10 +11,6 @@ #include #include -#ifdef USE_WIFI -#include -#endif - #ifdef USE_ARDUINO #include #endif @@ -48,29 +44,6 @@ static const char *const RESET_REASONS[] = { static const char *const REBOOT_KEY = "reboot_source"; static const size_t REBOOT_MAX_LEN = 24; -#if defined(USE_TEXT_SENSOR) && defined(USE_WIFI) -/// @brief Helper function to convert ESP32 WiFi power save mode to string -/// @param ps_mode WiFi power save mode from esp_wifi_get_ps() -/// @return const char pointer to the readable power save mode -/// -/// Maps ESP32 WiFi power save modes to user-friendly strings: -/// - WIFI_PS_NONE (no power saving) -> "NONE" -/// - WIFI_PS_MIN_MODEM (minimal modem sleep) -> "LIGHT" -/// - WIFI_PS_MAX_MODEM (maximum modem sleep) -> "HIGH" -static const char *wifi_ps_mode_to_string(wifi_ps_type_t ps_mode) { - switch (ps_mode) { - case WIFI_PS_NONE: - return "NONE"; - case WIFI_PS_MIN_MODEM: - return "LIGHT"; - case WIFI_PS_MAX_MODEM: - return "HIGH"; - default: - return "UNKNOWN"; - } -} -#endif // USE_TEXT_SENSOR && USE_WIFI - // on shutdown, store the source of the reboot request void DebugComponent::on_shutdown() { auto *component = App.get_current_component(); @@ -261,19 +234,6 @@ void DebugComponent::update_platform_() { this->psram_sensor_->publish_state(heap_caps_get_free_size(MALLOC_CAP_SPIRAM)); } #endif - -#if defined(USE_TEXT_SENSOR) && defined(USE_WIFI) - if (this->wifi_power_save_ != nullptr) { - wifi_ps_type_t power_save_mode; - if (esp_wifi_get_ps(&power_save_mode) == ESP_OK) { - // Publish if the state has changed or if this is the first read - if (this->last_wifi_ps_mode_ != power_save_mode || !this->wifi_power_save_->has_state()) { - this->wifi_power_save_->publish_state(wifi_ps_mode_to_string(power_save_mode)); - this->last_wifi_ps_mode_ = power_save_mode; - } - } - } -#endif } } // namespace debug diff --git a/esphome/components/debug/text_sensor.py b/esphome/components/debug/text_sensor.py index 74027a694d..96ef231850 100644 --- a/esphome/components/debug/text_sensor.py +++ b/esphome/components/debug/text_sensor.py @@ -3,11 +3,9 @@ from esphome.components import text_sensor import esphome.config_validation as cv from esphome.const import ( CONF_DEVICE, - CONF_POWER_SAVE_MODE, ENTITY_CATEGORY_DIAGNOSTIC, ICON_CHIP, ICON_RESTART, - ICON_WIFI, ) from . import CONF_DEBUG_ID, DebugComponent @@ -27,14 +25,6 @@ CONFIG_SCHEMA = cv.Schema( icon=ICON_RESTART, entity_category=ENTITY_CATEGORY_DIAGNOSTIC, ), - cv.Optional(CONF_POWER_SAVE_MODE): cv.All( - text_sensor.text_sensor_schema( - icon=ICON_WIFI, - entity_category=ENTITY_CATEGORY_DIAGNOSTIC, - ), - cv.only_on(["esp32"]), - cv.requires_component("wifi"), - ), } ) @@ -48,6 +38,3 @@ async def to_code(config): if CONF_RESET_REASON in config: sens = await text_sensor.new_text_sensor(config[CONF_RESET_REASON]) cg.add(debug_component.set_reset_reason_sensor(sens)) - if CONF_POWER_SAVE_MODE in config: - sens = await text_sensor.new_text_sensor(config[CONF_POWER_SAVE_MODE]) - cg.add(debug_component.set_wifi_power_save_sensor(sens)) diff --git a/esphome/components/wifi_info/text_sensor.py b/esphome/components/wifi_info/text_sensor.py index bc0c038f80..8cc0c4e66f 100644 --- a/esphome/components/wifi_info/text_sensor.py +++ b/esphome/components/wifi_info/text_sensor.py @@ -6,9 +6,11 @@ from esphome.const import ( CONF_DNS_ADDRESS, CONF_IP_ADDRESS, CONF_MAC_ADDRESS, + CONF_POWER_SAVE_MODE, CONF_SCAN_RESULTS, CONF_SSID, ENTITY_CATEGORY_DIAGNOSTIC, + ICON_WIFI, ) DEPENDENCIES = ["wifi"] @@ -30,6 +32,9 @@ MacAddressWifiInfo = wifi_info_ns.class_( DNSAddressWifiInfo = wifi_info_ns.class_( "DNSAddressWifiInfo", text_sensor.TextSensor, cg.Component ) +PowerSaveModeWiFiInfo = wifi_info_ns.class_( + "PowerSaveModeWiFiInfo", text_sensor.TextSensor, cg.PollingComponent +) CONFIG_SCHEMA = cv.Schema( { @@ -57,6 +62,14 @@ CONFIG_SCHEMA = cv.Schema( ), cv.Optional(CONF_DNS_ADDRESS): text_sensor.text_sensor_schema( DNSAddressWifiInfo, entity_category=ENTITY_CATEGORY_DIAGNOSTIC + ).extend(cv.polling_component_schema("1s")), + cv.Optional(CONF_POWER_SAVE_MODE): cv.All( + text_sensor.text_sensor_schema( + PowerSaveModeWiFiInfo, + icon=ICON_WIFI, + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, + ).extend(cv.polling_component_schema("1s")), + cv.only_on(["esp32"]), ), } ) @@ -90,6 +103,7 @@ async def to_code(config): await setup_conf(config, CONF_SCAN_RESULTS) wifi.request_wifi_scan_results() await setup_conf(config, CONF_DNS_ADDRESS) + await setup_conf(config, CONF_POWER_SAVE_MODE) if conf := config.get(CONF_IP_ADDRESS): wifi_info = await text_sensor.new_text_sensor(config[CONF_IP_ADDRESS]) await cg.register_component(wifi_info, config[CONF_IP_ADDRESS]) diff --git a/esphome/components/wifi_info/wifi_info_text_sensor.cpp b/esphome/components/wifi_info/wifi_info_text_sensor.cpp index 6c9d0c00e5..360cd979ea 100644 --- a/esphome/components/wifi_info/wifi_info_text_sensor.cpp +++ b/esphome/components/wifi_info/wifi_info_text_sensor.cpp @@ -6,6 +6,29 @@ namespace esphome::wifi_info { static const char *const TAG = "wifi_info"; +#ifdef USE_ESP32 +/// @brief Helper function to convert ESP32 WiFi power save mode to string +/// @param ps_mode WiFi power save mode from esp_wifi_get_ps() +/// @return const char pointer to the readable power save mode +/// +/// Maps ESP32 WiFi power save modes to user-friendly strings: +/// - WIFI_PS_NONE (no power saving) -> "NONE" +/// - WIFI_PS_MIN_MODEM (minimal modem sleep) -> "LIGHT" +/// - WIFI_PS_MAX_MODEM (maximum modem sleep) -> "HIGH" +static const char *wifi_ps_mode_to_string(wifi_ps_type_t ps_mode) { + switch (ps_mode) { + case WIFI_PS_NONE: + return "NONE"; + case WIFI_PS_MIN_MODEM: + return "LIGHT"; + case WIFI_PS_MAX_MODEM: + return "HIGH"; + default: + return "UNKNOWN"; + } +} +#endif // USE_ESP32 + #ifdef USE_WIFI_LISTENERS static constexpr size_t MAX_STATE_LENGTH = 255; @@ -108,5 +131,20 @@ void BSSIDWiFiInfo::on_wifi_connect_state(const std::string &ssid, const wifi::b void MacAddressWifiInfo::dump_config() { LOG_TEXT_SENSOR("", "MAC Address", this); } +#ifdef USE_ESP32 +void PowerSaveModeWiFiInfo::dump_config() { LOG_TEXT_SENSOR("", "WiFi Power Save Mode", this); } + +void PowerSaveModeWiFiInfo::update() { + wifi_ps_type_t power_save_mode; + if (esp_wifi_get_ps(&power_save_mode) == ESP_OK) { + // Publish if the state has changed or if this is the first read + if (this->last_power_save_mode_ != power_save_mode || !this->has_state()) { + this->publish_state(wifi_ps_mode_to_string(power_save_mode)); + this->last_power_save_mode_ = power_save_mode; + } + } +} +#endif // USE_ESP32 + } // namespace esphome::wifi_info #endif diff --git a/esphome/components/wifi_info/wifi_info_text_sensor.h b/esphome/components/wifi_info/wifi_info_text_sensor.h index f1f85c114f..78afcad43f 100644 --- a/esphome/components/wifi_info/wifi_info_text_sensor.h +++ b/esphome/components/wifi_info/wifi_info_text_sensor.h @@ -6,6 +6,9 @@ #include "esphome/components/wifi/wifi_component.h" #ifdef USE_WIFI #include +#ifdef USE_ESP32 +#include +#endif // USE_ESP32 namespace esphome::wifi_info { @@ -74,5 +77,17 @@ class MacAddressWifiInfo final : public Component, public text_sensor::TextSenso void dump_config() override; }; +#ifdef USE_ESP32 +class PowerSaveModeWiFiInfo : public PollingComponent, public text_sensor::TextSensor { + public: + void update() override; + float get_setup_priority() const override { return setup_priority::AFTER_WIFI; } + void dump_config() override; + + protected: + wifi_ps_type_t last_power_save_mode_{}; +}; +#endif // USE_ESP32 + } // namespace esphome::wifi_info #endif diff --git a/tests/components/debug/test.esp32-ard.yaml b/tests/components/debug/test.esp32-ard.yaml index ff6e34a845..8e19a4d627 100644 --- a/tests/components/debug/test.esp32-ard.yaml +++ b/tests/components/debug/test.esp32-ard.yaml @@ -1,13 +1,4 @@ <<: !include common.yaml -wifi: - ssid: "WIFI SSID" - password: "WIFI PASSWORD" - -text_sensor: - - platform: debug - power_save_mode: - name: "WiFi Power Save Mode" - esp32: cpu_frequency: 240MHz diff --git a/tests/components/debug/test.esp32-idf.yaml b/tests/components/debug/test.esp32-idf.yaml index 96e1611392..f7483a54b3 100644 --- a/tests/components/debug/test.esp32-idf.yaml +++ b/tests/components/debug/test.esp32-idf.yaml @@ -3,15 +3,6 @@ esp32: cpu_frequency: 240MHz -wifi: - ssid: "WIFI SSID" - password: "WIFI PASSWORD" - -text_sensor: - - platform: debug - power_save_mode: - name: "WiFi Power Save Mode" - sensor: - platform: debug free: diff --git a/tests/components/debug/test.esp32-s2-idf.yaml b/tests/components/debug/test.esp32-s2-idf.yaml index b1b6cebd7c..dade44d145 100644 --- a/tests/components/debug/test.esp32-s2-idf.yaml +++ b/tests/components/debug/test.esp32-s2-idf.yaml @@ -1,10 +1 @@ <<: !include common.yaml - -wifi: - ssid: "WIFI SSID" - password: "WIFI PASSWORD" - -text_sensor: - - platform: debug - power_save_mode: - name: "WiFi Power Save Mode" diff --git a/tests/components/wifi_info/test.esp32-ard.yaml b/tests/components/wifi_info/test.esp32-ard.yaml new file mode 100644 index 0000000000..3393e33898 --- /dev/null +++ b/tests/components/wifi_info/test.esp32-ard.yaml @@ -0,0 +1,9 @@ +packages: + i2c: !include ../../test_build_components/common/i2c/esp32-ard.yaml + +<<: !include common.yaml + +text_sensor: + - platform: wifi_info + power_save_mode: + name: "WiFi Power Save Mode" diff --git a/tests/components/wifi_info/test.esp32-idf.yaml b/tests/components/wifi_info/test.esp32-idf.yaml index b47e39c389..648bdf47c9 100644 --- a/tests/components/wifi_info/test.esp32-idf.yaml +++ b/tests/components/wifi_info/test.esp32-idf.yaml @@ -2,3 +2,8 @@ packages: i2c: !include ../../test_build_components/common/i2c/esp32-idf.yaml <<: !include common.yaml + +text_sensor: + - platform: wifi_info + power_save_mode: + name: "WiFi Power Save Mode"