diff --git a/esphome/components/cse7766/cse7766.cpp b/esphome/components/cse7766/cse7766.cpp index 4432195365..c36e57c929 100644 --- a/esphome/components/cse7766/cse7766.cpp +++ b/esphome/components/cse7766/cse7766.cpp @@ -152,6 +152,10 @@ void CSE7766Component::parse_data_() { if (this->power_sensor_ != nullptr) { this->power_sensor_->publish_state(power); } + } else if (this->power_sensor_ != nullptr) { + // No valid power measurement from chip - publish 0W to avoid stale readings + // This typically happens when current is below the measurable threshold (~50mA) + this->power_sensor_->publish_state(0.0f); } float current = 0.0f; diff --git a/esphome/components/mipi_dsi/models/waveshare.py b/esphome/components/mipi_dsi/models/waveshare.py index c3d080f8b2..f83cacc5a3 100644 --- a/esphome/components/mipi_dsi/models/waveshare.py +++ b/esphome/components/mipi_dsi/models/waveshare.py @@ -94,3 +94,29 @@ DriverChip( (0x29, 0x00), ], ) + +DriverChip( + "WAVESHARE-ESP32-P4-WIFI6-TOUCH-LCD-7B", + height=600, + width=1024, + hsync_back_porch=160, + hsync_pulse_width=10, + hsync_front_porch=160, + vsync_back_porch=23, + vsync_pulse_width=1, + vsync_front_porch=12, + pclk_frequency="52MHz", + lane_bit_rate="900Mbps", + no_transform=True, + color_order="RGB", + initsequence=[ + (0x80, 0x8B), + (0x81, 0x78), + (0x82, 0x84), + (0x83, 0x88), + (0x84, 0xA8), + (0x85, 0xE3), + (0x86, 0x88), + (0xB2, 0x10), + ], +) diff --git a/esphome/components/opentherm/__init__.py b/esphome/components/opentherm/__init__.py index 8cbee1eed2..dddb9dc891 100644 --- a/esphome/components/opentherm/__init__.py +++ b/esphome/components/opentherm/__init__.py @@ -4,8 +4,10 @@ from typing import Any from esphome import automation, pins import esphome.codegen as cg from esphome.components import sensor +from esphome.components.esp32 import include_builtin_idf_component import esphome.config_validation as cv from esphome.const import CONF_ID, CONF_TRIGGER_ID, PLATFORM_ESP32, PLATFORM_ESP8266 +from esphome.core import CORE from . import const, generate, schema, validate @@ -83,6 +85,12 @@ CONFIG_SCHEMA = cv.All( async def to_code(config: dict[str, Any]) -> None: + if CORE.is_esp32: + # Re-enable ESP-IDF's legacy driver component (excluded by default to save compile time) + # Provides driver/timer.h header for hardware timer API + # TODO: Remove this once opentherm migrates to GPTimer API (driver/gptimer.h) + include_builtin_idf_component("driver") + var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) diff --git a/esphome/components/opentherm/opentherm.cpp b/esphome/components/opentherm/opentherm.cpp index 2bf438a52f..cdf89207bc 100644 --- a/esphome/components/opentherm/opentherm.cpp +++ b/esphome/components/opentherm/opentherm.cpp @@ -8,6 +8,8 @@ #include "opentherm.h" #include "esphome/core/helpers.h" #include +// TODO: Migrate from legacy timer API (driver/timer.h) to GPTimer API (driver/gptimer.h) +// The legacy timer API is deprecated in ESP-IDF 5.x. See opentherm.h for details. #ifdef USE_ESP32 #include "driver/timer.h" #include "esp_err.h" diff --git a/esphome/components/opentherm/opentherm.h b/esphome/components/opentherm/opentherm.h index 3996481760..a2c347d0d8 100644 --- a/esphome/components/opentherm/opentherm.h +++ b/esphome/components/opentherm/opentherm.h @@ -12,6 +12,10 @@ #include "esphome/core/helpers.h" #include "esphome/core/log.h" +// TODO: Migrate from legacy timer API (driver/timer.h) to GPTimer API (driver/gptimer.h) +// The legacy timer API is deprecated in ESP-IDF 5.x. Migration would allow removing the +// "driver" IDF component dependency. See: +// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/migration-guides/release-5.x/5.0/peripherals.html#id4 #ifdef USE_ESP32 #include "driver/timer.h" #endif diff --git a/esphome/components/speaker/media_player/__init__.py b/esphome/components/speaker/media_player/__init__.py index 370b4576a7..034312236c 100644 --- a/esphome/components/speaker/media_player/__init__.py +++ b/esphome/components/speaker/media_player/__init__.py @@ -157,8 +157,14 @@ def _read_audio_file_and_type(file_config): import puremagic - file_type: str = puremagic.from_string(data) - file_type = file_type.removeprefix(".") + try: + file_type: str = puremagic.from_string(data) + file_type = file_type.removeprefix(".") + except puremagic.PureError as e: + raise cv.Invalid( + f"Unable to determine audio file type of '{path}'. " + f"Try re-encoding the file into a supported format. Details: {e}" + ) media_file_type = audio.AUDIO_FILE_TYPE_ENUM["NONE"] if file_type in ("wav"):