From 0b60fd0c8c6b9ff704b25e6730b1de6521b1d918 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Jan 2026 21:49:14 -1000 Subject: [PATCH 1/9] [core] Avoid heap allocation in str_equals_case_insensitive with string literals (#13312) --- esphome/core/helpers.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 6c06757d8c..ed5c4911ad 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -572,6 +572,10 @@ template constexpr T convert_little_endian(T val) { bool str_equals_case_insensitive(const std::string &a, const std::string &b); /// Compare StringRefs for equality in case-insensitive manner. bool str_equals_case_insensitive(StringRef a, StringRef b); +/// Compare C strings for equality in case-insensitive manner (no heap allocation). +inline bool str_equals_case_insensitive(const char *a, const char *b) { return strcasecmp(a, b) == 0; } +inline bool str_equals_case_insensitive(const std::string &a, const char *b) { return strcasecmp(a.c_str(), b) == 0; } +inline bool str_equals_case_insensitive(const char *a, const std::string &b) { return strcasecmp(a, b.c_str()) == 0; } /// Check whether a string starts with a value. bool str_startswith(const std::string &str, const std::string &start); From 37eaf10f751ccb4f04d34c94953309b0e9ae84b4 Mon Sep 17 00:00:00 2001 From: Kevin Ahrendt Date: Wed, 21 Jan 2026 12:40:41 +0000 Subject: [PATCH 2/9] [audio] Bump esp-audio-libs to 2.0.3 (#13346) --- .clang-tidy.hash | 2 +- esphome/components/audio/__init__.py | 6 +++++- esphome/components/audio/audio_decoder.cpp | 2 +- esphome/idf_component.yml | 2 ++ platformio.ini | 2 -- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.clang-tidy.hash b/.clang-tidy.hash index b448915e27..75f0fc9c98 100644 --- a/.clang-tidy.hash +++ b/.clang-tidy.hash @@ -1 +1 @@ -d15ae81646ac0ee76b2586716fe697f187281523ee6db566aed26542a9f98d1a +a34e66dce18eaf9d2d094fedf6b9799bbd9ec1e734f76a29544e3f6d61786c3e diff --git a/esphome/components/audio/__init__.py b/esphome/components/audio/__init__.py index 7b03e4b6a7..6c721652e1 100644 --- a/esphome/components/audio/__init__.py +++ b/esphome/components/audio/__init__.py @@ -1,4 +1,5 @@ import esphome.codegen as cg +from esphome.components.esp32 import add_idf_component import esphome.config_validation as cv from esphome.const import CONF_BITS_PER_SAMPLE, CONF_NUM_CHANNELS, CONF_SAMPLE_RATE import esphome.final_validate as fv @@ -165,4 +166,7 @@ def final_validate_audio_schema( async def to_code(config): - cg.add_library("esphome/esp-audio-libs", "2.0.1") + add_idf_component( + name="esphome/esp-audio-libs", + ref="2.0.3", + ) diff --git a/esphome/components/audio/audio_decoder.cpp b/esphome/components/audio/audio_decoder.cpp index d1ad571a52..8f514468c4 100644 --- a/esphome/components/audio/audio_decoder.cpp +++ b/esphome/components/audio/audio_decoder.cpp @@ -300,7 +300,7 @@ FileDecoderState AudioDecoder::decode_mp3_() { // Advance read pointer to match the offset for the syncword this->input_transfer_buffer_->decrease_buffer_length(offset); - uint8_t *buffer_start = this->input_transfer_buffer_->get_buffer_start(); + const uint8_t *buffer_start = this->input_transfer_buffer_->get_buffer_start(); buffer_length = (int) this->input_transfer_buffer_->available(); int err = esp_audio_libs::helix_decoder::MP3Decode(this->mp3_decoder_, &buffer_start, &buffer_length, diff --git a/esphome/idf_component.yml b/esphome/idf_component.yml index e19c1a1c87..9be787d0cd 100644 --- a/esphome/idf_component.yml +++ b/esphome/idf_component.yml @@ -1,6 +1,8 @@ dependencies: bblanchon/arduinojson: version: "7.4.2" + esphome/esp-audio-libs: + version: 2.0.3 espressif/esp-tflite-micro: version: 1.3.3~1 espressif/esp32-camera: diff --git a/platformio.ini b/platformio.ini index a54aa0964c..62de5aa0d7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -154,7 +154,6 @@ lib_deps = makuna/NeoPixelBus@2.8.0 ; neopixelbus esphome/ESP32-audioI2S@2.3.0 ; i2s_audio droscy/esp_wireguard@0.4.2 ; wireguard - esphome/esp-audio-libs@2.0.1 ; audio kahrendt/ESPMicroSpeechFeatures@1.1.0 ; micro_wake_word build_flags = @@ -178,7 +177,6 @@ lib_deps = ${common:idf.lib_deps} droscy/esp_wireguard@0.4.2 ; wireguard kahrendt/ESPMicroSpeechFeatures@1.1.0 ; micro_wake_word - esphome/esp-audio-libs@2.0.1 ; audio build_flags = ${common:idf.build_flags} -Wno-nonnull-compare From 29555c0ddc3a6d637789f89cd4120667e945412c Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 12:32:55 -0500 Subject: [PATCH 3/9] =?UTF-8?q?[lvgl]=20Validate=20LVGL=20dropdown=20symbo?= =?UTF-8?q?ls=20require=20Unicode=20codepoint=20=E2=89=A5=200x100=20(#1339?= =?UTF-8?q?4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: clydebarrow <2366188+clydebarrow@users.noreply.github.com> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- esphome/components/lvgl/widgets/dropdown.py | 33 +++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/esphome/components/lvgl/widgets/dropdown.py b/esphome/components/lvgl/widgets/dropdown.py index 9ff183f3dd..ca89bb625b 100644 --- a/esphome/components/lvgl/widgets/dropdown.py +++ b/esphome/components/lvgl/widgets/dropdown.py @@ -1,3 +1,4 @@ +from esphome import codegen as cg import esphome.config_validation as cv from esphome.const import CONF_OPTIONS @@ -24,6 +25,34 @@ from .label import CONF_LABEL CONF_DROPDOWN = "dropdown" CONF_DROPDOWN_LIST = "dropdown_list" +# Example valid dropdown symbol (left arrow) for error messages +EXAMPLE_DROPDOWN_SYMBOL = "\U00002190" # ← + + +def dropdown_symbol_validator(value): + """ + Validate that the dropdown symbol is a single Unicode character + with a codepoint of 0x100 (256) or greater. + This is required because LVGL uses codepoints below 0x100 for internal symbols. + """ + value = cv.string(value) + # len(value) counts Unicode code points, not grapheme clusters or bytes + if len(value) != 1: + raise cv.Invalid( + f"Dropdown symbol must be a single character, got '{value}' with length {len(value)}" + ) + codepoint = ord(value) + if codepoint < 0x100: + # Format the example symbol as a Unicode escape for the error message + example_escape = f"\\U{ord(EXAMPLE_DROPDOWN_SYMBOL):08X}" + raise cv.Invalid( + f"Dropdown symbol must have a Unicode codepoint of 0x100 (256) or greater. " + f"'{value}' has codepoint {codepoint} (0x{codepoint:X}). " + f"Use a character like '{example_escape}' ({EXAMPLE_DROPDOWN_SYMBOL}) or other Unicode symbols with codepoint >= 0x100." + ) + return value + + lv_dropdown_t = LvSelect("LvDropdownType", parents=(LvCompound,)) lv_dropdown_list_t = LvType("lv_dropdown_list_t") @@ -33,7 +62,7 @@ dropdown_list_spec = WidgetType( DROPDOWN_BASE_SCHEMA = cv.Schema( { - cv.Optional(CONF_SYMBOL): lv_text, + cv.Optional(CONF_SYMBOL): dropdown_symbol_validator, cv.Exclusive(CONF_SELECTED_INDEX, CONF_SELECTED_TEXT): lv_int, cv.Exclusive(CONF_SELECTED_TEXT, CONF_SELECTED_TEXT): lv_text, cv.Optional(CONF_DROPDOWN_LIST): part_schema(dropdown_list_spec.parts), @@ -70,7 +99,7 @@ class DropdownType(WidgetType): if options := config.get(CONF_OPTIONS): lv_add(w.var.set_options(options)) if symbol := config.get(CONF_SYMBOL): - lv.dropdown_set_symbol(w.var.obj, await lv_text.process(symbol)) + lv.dropdown_set_symbol(w.var.obj, cg.safe_exp(symbol)) if (selected := config.get(CONF_SELECTED_INDEX)) is not None: value = await lv_int.process(selected) lv_add(w.var.set_selected_index(value, literal("LV_ANIM_OFF"))) From 5f2394ef80105bd911c80398624e454afc07a594 Mon Sep 17 00:00:00 2001 From: maikeljkwak Date: Wed, 21 Jan 2026 18:34:52 +0100 Subject: [PATCH 4/9] [hc8, mhz19] Moving constant CONF_WARMUP_TIME to const.py (#13392) Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- esphome/components/hc8/sensor.py | 3 +-- esphome/components/mhz19/sensor.py | 2 +- esphome/const.py | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/hc8/sensor.py b/esphome/components/hc8/sensor.py index 90698b2661..2f39b47f3c 100644 --- a/esphome/components/hc8/sensor.py +++ b/esphome/components/hc8/sensor.py @@ -6,6 +6,7 @@ from esphome.const import ( CONF_BASELINE, CONF_CO2, CONF_ID, + CONF_WARMUP_TIME, DEVICE_CLASS_CARBON_DIOXIDE, ICON_MOLECULE_CO2, STATE_CLASS_MEASUREMENT, @@ -14,8 +15,6 @@ from esphome.const import ( DEPENDENCIES = ["uart"] -CONF_WARMUP_TIME = "warmup_time" - hc8_ns = cg.esphome_ns.namespace("hc8") HC8Component = hc8_ns.class_("HC8Component", cg.PollingComponent, uart.UARTDevice) HC8CalibrateAction = hc8_ns.class_("HC8CalibrateAction", automation.Action) diff --git a/esphome/components/mhz19/sensor.py b/esphome/components/mhz19/sensor.py index 1f698be404..2841afde7a 100644 --- a/esphome/components/mhz19/sensor.py +++ b/esphome/components/mhz19/sensor.py @@ -7,6 +7,7 @@ from esphome.const import ( CONF_CO2, CONF_ID, CONF_TEMPERATURE, + CONF_WARMUP_TIME, DEVICE_CLASS_CARBON_DIOXIDE, DEVICE_CLASS_TEMPERATURE, ICON_MOLECULE_CO2, @@ -18,7 +19,6 @@ from esphome.const import ( DEPENDENCIES = ["uart"] CONF_AUTOMATIC_BASELINE_CALIBRATION = "automatic_baseline_calibration" -CONF_WARMUP_TIME = "warmup_time" CONF_DETECTION_RANGE = "detection_range" mhz19_ns = cg.esphome_ns.namespace("mhz19") diff --git a/esphome/const.py b/esphome/const.py index d955387f7f..4243b2e25d 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1086,6 +1086,7 @@ CONF_WAKEUP_PIN = "wakeup_pin" CONF_WAND_ID = "wand_id" CONF_WARM_WHITE = "warm_white" CONF_WARM_WHITE_COLOR_TEMPERATURE = "warm_white_color_temperature" +CONF_WARMUP_TIME = "warmup_time" CONF_WATCHDOG_THRESHOLD = "watchdog_threshold" CONF_WATCHDOG_TIMEOUT = "watchdog_timeout" CONF_WATER_HEATER = "water_heater" From 6014bba3d1a5a26f164b8eaf49263d66778acc4e Mon Sep 17 00:00:00 2001 From: Dawid Date: Wed, 21 Jan 2026 18:37:10 +0100 Subject: [PATCH 5/9] [zephyr] Small build fixes for the logger/gpio subsystems (#13242) Co-authored-by: dawret --- esphome/components/zephyr/gpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/zephyr/gpio.h b/esphome/components/zephyr/gpio.h index c9540f4f01..94f25f02ac 100644 --- a/esphome/components/zephyr/gpio.h +++ b/esphome/components/zephyr/gpio.h @@ -2,7 +2,7 @@ #ifdef USE_ZEPHYR #include "esphome/core/hal.h" -struct device; +#include namespace esphome { namespace zephyr { From 333ace25c9f324a1bccd3edcefed0d7e4ea53a82 Mon Sep 17 00:00:00 2001 From: tomaszduda23 Date: Wed, 21 Jan 2026 18:41:56 +0100 Subject: [PATCH 6/9] [adc] Fix indent (#11933) --- esphome/components/adc/sensor.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/esphome/components/adc/sensor.py b/esphome/components/adc/sensor.py index 607609bbc7..64dd22b0c3 100644 --- a/esphome/components/adc/sensor.py +++ b/esphome/components/adc/sensor.py @@ -160,21 +160,21 @@ async def to_code(config): zephyr_add_user("io-channels", f"<&adc {channel_id}>") zephyr_add_overlay( f""" -&adc {{ - #address-cells = <1>; - #size-cells = <0>; + &adc {{ + #address-cells = <1>; + #size-cells = <0>; - channel@{channel_id} {{ - reg = <{channel_id}>; - zephyr,gain = "{gain}"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,input-positive = ; - zephyr,resolution = <14>; - zephyr,oversampling = <8>; - }}; -}}; -""" + channel@{channel_id} {{ + reg = <{channel_id}>; + zephyr,gain = "{gain}"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,input-positive = ; + zephyr,resolution = <14>; + zephyr,oversampling = <8>; + }}; + }}; + """ ) From 5345c96ff38c4e9b988679c9f133078d4c817440 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Wed, 21 Jan 2026 13:18:37 -0500 Subject: [PATCH 7/9] [http_request] Fix verify_ssl: false not working on ESP32 (#13422) Co-authored-by: Claude Opus 4.5 --- esphome/components/http_request/__init__.py | 1 + esphome/components/http_request/http_request_idf.cpp | 2 +- esphome/components/http_request/http_request_idf.h | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/esphome/components/http_request/__init__.py b/esphome/components/http_request/__init__.py index b133aa69b2..9f74fb1023 100644 --- a/esphome/components/http_request/__init__.py +++ b/esphome/components/http_request/__init__.py @@ -157,6 +157,7 @@ async def to_code(config): if CORE.is_esp32: cg.add(var.set_buffer_size_rx(config[CONF_BUFFER_SIZE_RX])) cg.add(var.set_buffer_size_tx(config[CONF_BUFFER_SIZE_TX])) + cg.add(var.set_verify_ssl(config[CONF_VERIFY_SSL])) if config.get(CONF_VERIFY_SSL): esp32.add_idf_sdkconfig_option("CONFIG_MBEDTLS_CERTIFICATE_BUNDLE", True) diff --git a/esphome/components/http_request/http_request_idf.cpp b/esphome/components/http_request/http_request_idf.cpp index 1de947ba5b..eedd321d80 100644 --- a/esphome/components/http_request/http_request_idf.cpp +++ b/esphome/components/http_request/http_request_idf.cpp @@ -89,7 +89,7 @@ std::shared_ptr HttpRequestIDF::perform(const std::string &url, c config.max_redirection_count = this->redirect_limit_; config.auth_type = HTTP_AUTH_TYPE_BASIC; #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE - if (secure) { + if (secure && this->verify_ssl_) { config.crt_bundle_attach = esp_crt_bundle_attach; } #endif diff --git a/esphome/components/http_request/http_request_idf.h b/esphome/components/http_request/http_request_idf.h index 4dc4736423..0fae67f5bc 100644 --- a/esphome/components/http_request/http_request_idf.h +++ b/esphome/components/http_request/http_request_idf.h @@ -34,6 +34,7 @@ class HttpRequestIDF : public HttpRequestComponent { void set_buffer_size_rx(uint16_t buffer_size_rx) { this->buffer_size_rx_ = buffer_size_rx; } void set_buffer_size_tx(uint16_t buffer_size_tx) { this->buffer_size_tx_ = buffer_size_tx; } + void set_verify_ssl(bool verify_ssl) { this->verify_ssl_ = verify_ssl; } protected: std::shared_ptr perform(const std::string &url, const std::string &method, const std::string &body, @@ -42,6 +43,7 @@ class HttpRequestIDF : public HttpRequestComponent { // if zero ESP-IDF will use DEFAULT_HTTP_BUF_SIZE uint16_t buffer_size_rx_{}; uint16_t buffer_size_tx_{}; + bool verify_ssl_{true}; /// @brief Monitors the http client events to gather response headers static esp_err_t http_event_handler(esp_http_client_event_t *evt); From e62368e058a15f35c69298af830de62ec85e688d Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Wed, 21 Jan 2026 13:19:36 -0500 Subject: [PATCH 8/9] [heatpumpir] Add ESP-IDF support, bump to 1.0.40 (#13042) --- .clang-tidy.hash | 2 +- esphome/components/heatpumpir/climate.py | 4 ++-- esphome/components/heatpumpir/heatpumpir.cpp | 2 +- esphome/components/heatpumpir/heatpumpir.h | 2 +- esphome/components/heatpumpir/ir_sender_esphome.cpp | 2 +- esphome/components/heatpumpir/ir_sender_esphome.h | 2 +- platformio.ini | 3 ++- tests/components/heatpumpir/test.esp32-idf.yaml | 4 ++++ 8 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 tests/components/heatpumpir/test.esp32-idf.yaml diff --git a/.clang-tidy.hash b/.clang-tidy.hash index 75f0fc9c98..0204b50264 100644 --- a/.clang-tidy.hash +++ b/.clang-tidy.hash @@ -1 +1 @@ -a34e66dce18eaf9d2d094fedf6b9799bbd9ec1e734f76a29544e3f6d61786c3e +c0335c9688ce9defb4a7d4446b93460547e22df055668bacd7d963c770f0c65f diff --git a/esphome/components/heatpumpir/climate.py b/esphome/components/heatpumpir/climate.py index ec6eac670f..0d760938d0 100644 --- a/esphome/components/heatpumpir/climate.py +++ b/esphome/components/heatpumpir/climate.py @@ -107,7 +107,7 @@ CONFIG_SCHEMA = cv.All( cv.Required(CONF_MAX_TEMPERATURE): cv.temperature, } ), - cv.only_with_arduino, + cv.Any(cv.only_with_arduino, cv.only_on_esp32), ) @@ -126,6 +126,6 @@ async def to_code(config): cg.add(var.set_max_temperature(config[CONF_MAX_TEMPERATURE])) cg.add(var.set_min_temperature(config[CONF_MIN_TEMPERATURE])) - cg.add_library("tonia/HeatpumpIR", "1.0.37") + cg.add_library("tonia/HeatpumpIR", "1.0.40") if CORE.is_libretiny or CORE.is_esp32: CORE.add_platformio_option("lib_ignore", ["IRremoteESP8266"]) diff --git a/esphome/components/heatpumpir/heatpumpir.cpp b/esphome/components/heatpumpir/heatpumpir.cpp index 67447a3123..1f1362f8d8 100644 --- a/esphome/components/heatpumpir/heatpumpir.cpp +++ b/esphome/components/heatpumpir/heatpumpir.cpp @@ -1,6 +1,6 @@ #include "heatpumpir.h" -#ifdef USE_ARDUINO +#if defined(USE_ARDUINO) || defined(USE_ESP32) #include #include "ir_sender_esphome.h" diff --git a/esphome/components/heatpumpir/heatpumpir.h b/esphome/components/heatpumpir/heatpumpir.h index ed43ffdc83..6270dd1e5a 100644 --- a/esphome/components/heatpumpir/heatpumpir.h +++ b/esphome/components/heatpumpir/heatpumpir.h @@ -1,6 +1,6 @@ #pragma once -#ifdef USE_ARDUINO +#if defined(USE_ARDUINO) || defined(USE_ESP32) #include "esphome/components/climate_ir/climate_ir.h" diff --git a/esphome/components/heatpumpir/ir_sender_esphome.cpp b/esphome/components/heatpumpir/ir_sender_esphome.cpp index 173d595119..f010c72dac 100644 --- a/esphome/components/heatpumpir/ir_sender_esphome.cpp +++ b/esphome/components/heatpumpir/ir_sender_esphome.cpp @@ -1,6 +1,6 @@ #include "ir_sender_esphome.h" -#ifdef USE_ARDUINO +#if defined(USE_ARDUINO) || defined(USE_ESP32) namespace esphome { namespace heatpumpir { diff --git a/esphome/components/heatpumpir/ir_sender_esphome.h b/esphome/components/heatpumpir/ir_sender_esphome.h index 944d0e859c..c4209145ba 100644 --- a/esphome/components/heatpumpir/ir_sender_esphome.h +++ b/esphome/components/heatpumpir/ir_sender_esphome.h @@ -1,6 +1,6 @@ #pragma once -#ifdef USE_ARDUINO +#if defined(USE_ARDUINO) || defined(USE_ESP32) #include "esphome/components/remote_base/remote_base.h" #include // arduino-heatpump library diff --git a/platformio.ini b/platformio.ini index 62de5aa0d7..b109284933 100644 --- a/platformio.ini +++ b/platformio.ini @@ -84,7 +84,7 @@ lib_deps = fastled/FastLED@3.9.16 ; fastled_base freekode/TM1651@1.0.1 ; tm1651 dudanov/MideaUART@1.1.9 ; midea - tonia/HeatpumpIR@1.0.37 ; heatpumpir + tonia/HeatpumpIR@1.0.40 ; heatpumpir build_flags = ${common.build_flags} -DUSE_ARDUINO @@ -177,6 +177,7 @@ lib_deps = ${common:idf.lib_deps} droscy/esp_wireguard@0.4.2 ; wireguard kahrendt/ESPMicroSpeechFeatures@1.1.0 ; micro_wake_word + tonia/HeatpumpIR@1.0.40 ; heatpumpir build_flags = ${common:idf.build_flags} -Wno-nonnull-compare diff --git a/tests/components/heatpumpir/test.esp32-idf.yaml b/tests/components/heatpumpir/test.esp32-idf.yaml new file mode 100644 index 0000000000..e891f9dc85 --- /dev/null +++ b/tests/components/heatpumpir/test.esp32-idf.yaml @@ -0,0 +1,4 @@ +packages: + remote_transmitter: !include ../../test_build_components/common/remote_transmitter/esp32-idf.yaml + +<<: !include common.yaml From bbe1b8caa3420f3bcb3ecf446b1162b93c5c73fc Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 21 Jan 2026 08:26:15 -1000 Subject: [PATCH 9/9] [wifi] Fix LibreTiny manual_ip preventing API connection --- esphome/components/wifi/wifi_component_libretiny.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/wifi/wifi_component_libretiny.cpp b/esphome/components/wifi/wifi_component_libretiny.cpp index 162ed4e835..cc9f4ec193 100644 --- a/esphome/components/wifi/wifi_component_libretiny.cpp +++ b/esphome/components/wifi/wifi_component_libretiny.cpp @@ -460,13 +460,15 @@ void WiFiComponent::wifi_process_event_(LTWiFiEvent *event) { 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 -#if defined(USE_WIFI_IP_STATE_LISTENERS) && defined(USE_WIFI_MANUAL_IP) + // For static IP configurations, GOT_IP event may not fire, so set connected state here +#ifdef USE_WIFI_MANUAL_IP if (const WiFiAP *config = this->get_selected_sta_(); config && config->get_manual_ip().has_value()) { s_sta_state = LTWiFiSTAState::CONNECTED; +#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)); } +#endif } #endif break;