跳转到内容

ESPHome 2026.4.0 - 2026 年 4 月

ESPHome 2026.4.0 为所有平台带来了重大的性能和可靠性提升。ESP32 设备默认启用最高 CPU 频率(API 操作快 33%),解锁额外 40 KB IRAM,支持签名 OTA 验证和自定义分区表。ESP8266 获得与 ESP32/RP2040 对等的崩溃处理程序,全新的客户端状态日志架构通过将日志格式化从设备端移出,实现了最快 46 倍的传感器发布加速。蓝牙代理广播转发(恒定热点路径)在 ESP32-C3 上降至仅占主循环时间约 1.8%。31 个 PR 为 ESP-IDF 6.0 做好了代码库准备,CodSpeed 基准测试基础设施现在能在回归上线前捕获它们。替换系统进行了重新设计,配置加载快 18 倍,支持动态 !include 路径;以太网支持在 ESP32 和 RP2040 上扩展了 5 种新芯片类型;GPIO 扩展器获得中断驱动操作,闲置 I2C 流量降低 99.7%。本版还新增了 LVGL v9.5.0、原生三菱 CN105 气候控制、4 个新传感器组件,以及一个 esphome bundle CLI 命令以辅助远程编译。

  • 如果您使用带有在显示组件上配置 rotation 的 LVGL,请将 rotation 设置移至 lvgl: 块,并移除触摸屏 transform:。
  • 如果您使用 i2s_audio 媒体播放器,请迁移到 speaker 媒体播放器组件(i2s_audio 媒体播放器已被移除)
  • 如果您在 i2s_audio 配置中使用 use_legacy,请将其移除(旧的 I2S 驱动程序已被移除)
  • 如果您有电池供电的 ESP32/S2/S3/C5 设备,请在配置中添加 cpu_frequency: 160MHZ(默认值现在为 240MHz)
  • 如果您有两个 YAML 键解析为相同的替换名称,请注意后来的键现在优先(“后写入者胜”)
  • 如果您在 sen5x 中使用 voc_baseline,请将其移除(它是从未起作用的死代码;改用 store_baseline: true)
  • 如果您在 rp2040_pio_led_strip 中使用 chipset: CUSTOM,请改用显式的 bit0_high/bit0_low/bit1_high/bit1_low 时序参数
  • 如果您在 lambda 中使用 Nextion get_wave_chan_id(),请切换到 get_wave_channel_id()(旧方法已弃用,将在 2026.10.0 移除)
  • 如果您在 lambda 中使用 sensor.raw_state,请迁移到使用过滤后状态或 on_raw_value 触发器(.raw_state 已弃用)
  • 如果您维护调用 TEMPLATABLE_VALUE 宏生成设置器(带原始 C++ 常量)的外部组件,请在 Python codegen 中通过 cg.templatable() 路由值
  • 如果您维护使用 ButtonPressTrigger、SensorStateTrigger 或类似触发器类的外部组件,请迁移到 build_callback_automation()
  • 如果您维护使用 FlushResult 的外部组件,请重命名为 UARTFlushResult(使用 UART_FLUSH_RESULT_ 前缀)

几项 ESP32 平台更改提升了性能、安全性和灵活性。

默认 CPU 频率提升至最高(#15143):

ESP32、ESP32-S2、ESP32-S3 和 ESP32-C5 现在默认使用 240MHz 而非 160MHz。这恢复了 2025 年 5 月之前 Arduino 用户所拥有的性能水平,并使 CPU 密集型操作快约 34%:

  • API 加密握手:90ms 降至 64ms(快 29%)
  • Protobuf 编码(BLE 代理):快 34%
  • Noise 加密:在所有有效载荷大小下快 33-34%

使用电池或存在热约束的用户可以通过 cpu_frequency: 160MHZ 覆盖此设置。这是一项破坏性变更,因为它会增加受影响变体的功耗。

ESP32 崩溃处理程序改进:现有崩溃处理程序现在在双核 ESP32 变体上捕获两个核心的回溯(#15559),并在 OTA 回滚重启时保留崩溃数据(#15578)。

原版 ESP32 额外 40KB IRAM(#14874):一个新选项将以前保留的 40KB SRAM1 回收为 IRAM,扩展了闪存缓存窗口并减少了 WiFi、BLE 和 API 操作的缓存未命中,对堆栈无任何成本。ESPHome 将在启动时自动检测引导程序版本,并仅在安全时建议启用此选项。在引导程序检查确认安全之前不要启用此选项;与 v5.1 之前的引导程序一起启用它将导致设备变砖(需要 USB 重新烧录恢复)。详情请参见 ESP32 文档。

签名 OTA 验证(#15357):新的 signed_ota_verification 选项在 OTA 更新期间启用固件签名验证,无需硬件 Secure Boot(eFuse 烧录)。支持两种工作流:

  • 私钥模式(signing_key)—— 固件在构建期间自动签名。最简单的设置。
  • 公钥模式(verification_key)—— 仅嵌入公钥;二进制文件在外部签名(例如在 CI/CD 中使用安全保险库中的私钥)。
esp32:
framework:
type: esp-idf
advanced:
signed_ota_verification:
signing_key: secure_boot_signing_key.pem
signing_scheme: rsa3072

自定义分区表(#7682):组件和 YAML 配置现在可以定义自定义数据/应用分区,追加到闪存布局中。分区表生成在 Arduino 和 IDF 之间已统一,NVS 已移至闪存末尾并增大尺寸(Arduino 上从 20KB 到 384KB)。详情请参见 ESP32 文档。

ESP-IDF 5.5.4 和 Arduino 3.3.8(#15666、#15705):平台升至 pioarduino 55.03.38-1,搭配 ESP-IDF 5.5.4 和 Arduino 3.3.8。PlatformIO 现在以子进程运行,以将其 virtualenv 与 ESPHome 隔离,防止构建后出现导入错误。

ADC 崩溃修复(#15717):ADC 一次性控制函数现在置于 IRAM 中以供缓存安全。此前,当后台 NVS 写入(由 WiFi、BLE、Zigbee、Thread 或电源管理引起)禁用闪存缓存时,ADC 读取可能会崩溃。

Web 服务器 OTA 变砖风险修复(#15720):修复了受控门户和 Web 服务器 OTA 流程中长期存在的变砖风险,即中断的上传后重试可能会将拼接的固件写入闪存,产生无效镜像,使设备软变砖并需要串口闪存恢复。OTA 后端现在在每次新上传时重置。

mDNS 崩溃修复(#15670):将 espressif/mdns 升级至 1.11.0,修复了处理持续 mDNS 浏览流量时的堆损坏,此前会导致确定性的 LoadProhibited 崩溃,以及 mdns_parse_packet 中的空指针异常。

ESP8266 崩溃处理程序,无需串口线缆

Section titled “ESP8266 崩溃处理程序,无需串口线缆”

在 2026.3.0 中开始的平台覆盖工作(为 ESP32 和 RP2040 添加了崩溃处理程序)现已完成,ESP8266 设备现在拥有相同的死后崩溃诊断功能(#15465)。当设备崩溃时,异常详情和最多 16 个栈扫描回溯地址会保存到 RTC 内存,并在下次启动时通过 API 报告。无需 USB 线缆;崩溃数据出现在 esphome logs 中(通过 addr2line 自动将地址解码为源代码位置)和 Home Assistant 日志查看器中,完全通过 WiFi。

[E][esp8266]: *** CRASH DETECTED ON PREVIOUS BOOT ***
[E][esp8266]: Reason: Exception - StoreProhibit (exccause=29)
[E][esp8266]: PC: 0x40212EC5
[E][esp8266]: EXCVADDR: 0x00000000
[E][esp8266]: BT0: 0x40212F5A
[E][esp8266]: BT1: 0x40203B10

PC 是崩溃发生的程序计数器,EXCVADDR 是引起故障的内存地址,BT0/BT1 等是显示导致崩溃调用链的栈回溯。使用 esphome logs 时,这些地址会通过 addr2line 自动解码为源文件和行号,因此您看到的是实际函数名而非原始十六进制。

无需配置;它会自动为所有 ESP8266 设备启用。资源成本微乎其微:0 字节 RAM、119 字节 IRAM、约 1KB 闪存。

状态变更日志已从根本上重新设计,以消除每台 ESPHome 设备上最大的 CPU 瓶颈(#15155)。

每个实体状态变更('CO2' >> 420 ppm、'Light' - Setting ON)以前都在设备上运行 vsnprintf 来格式化日志字符串并通过 UART 发送,即使没有人正在查看串口控制台(99.9% 的设备)。CodSpeed 基准测试显示这消耗了传感器发布时间的 95% 以上。

状态变更日志现在在客户端上重建,而非在设备上。当 esphome logs 或仪表盘连接时,它会订阅紧凑的 protobuf 状态消息并在本地格式化。protobuf 消息的大小仅为格式化字符串的一小部分,且格式化发生在您的计算机上而非微控制器上。这在发布路径中实现了最快 46 倍加速,闪存节省 1.4KB(ESP32-C3)到 2.2KB(ESP8266)。状态变更仍然作为明亮的青色 [S] 行出现在日志中:

[18:03:14.677][S][sensor]: 'CO2' >> 420 ppm
[18:03:14.677][S][sensor]: 'Temperature' >> 35.63 °C
[18:03:51.747][S][light]: 'Light' >> ON

新的 --no-states 标志(#15160)允许用户首次完全抑制状态变更行,在日志被传感器读数淹没时进行调试非常有用。需要旧版设备端状态日志的用户可以通过设置 logger: level: VERBOSE 选择重新启用。

本次发布包含 31 个拉取请求,为 ESP-IDF 6.0 做准备,它带来了 GCC 15、picolibc 以及 Espressif 的重大 API 变更。由 @swoboda1337 主导,这项工作触及了整个代码库中的加密、驱动程序和工具链兼容性。虽然 ESP-IDF 6.0 还不是默认框架版本,但这些更改确保 ESPHome 在其发布时已做好准备。所有相关 PR 均标记为 idf-6 标签。

PSA Crypto API 迁移:

IDF 6.0 弃用了旧版 mbedTLS 加密 API。所有 ESPHome 加密操作均已迁移到新的 PSA Crypto API:

  • SHA-256 哈希(#14809)
  • HMAC-SHA256(#14814)
  • BLE 跟踪器 PSA Crypto(#14811)
  • BTHome/Xiaomi BLE CCM 解密(#14816)
  • DLMS 电表 GCM 解密(#14817)

20 多个组件的驱动程序和 API 兼容性修复:

  • WiFi、ADC、LEDC、RMT(LED 灯带、远程发射器/接收器)、MIPI DSI、PSRAM、I2S 音频、I2C、深度睡眠、MQTT、USB 主机、OpenTherm 定时器、以太网、调试和相机组件均已为 IDF 6.0 API 变更更新

工具链兼容性:

  • PicoLibC std::isnan 冲突已解决(#14768)
  • picolibc 的 vfprintf printf 存根已修复(#15172)
  • GCC 15 的隐式 int 到 gpio_num_t 转换已修复(#14830)
  • 准备 IDF 6.0 时移除了旧的 I2S 驱动程序,该驱动程序在 IDF 6.0 中已不存在(#14932)

由 @jpeletier 主导,YAML 配置系统获得了两项重大改进,使复杂的多文件配置更加强大且加载更快。

!include 路径中的替换(#12213):现在可以直接在 !include 文件名中使用替换变量和 Jinja 表达式,实现动态文件选择:

substitutions:
eth_model: LAN8720
packages:
- !include network/${eth_model}/config.yaml

这也适用于命令行替换,使相同的 YAML 可以针对不同的硬件配置,而无需复制文件。

配置加载快 18 倍(#14918):替换引擎经过重新设计,在单次线性遍历中执行所有变量替换,而非以前的多遍方法。对于带有大量包和包含的大型项目,这实现了最快 18 倍的配置加载时间。此次重写还修复了几个交叉文件变量引用(${A * B} 混合本地和根变量)不可靠的边缘情况。请注意,重复替换键的 merge_config 参数顺序已更改为“后写入者胜”。

在 RP2040/RP2350 于 2026.3.0 中获得一等平台支持的基础上,本次发布大幅扩展了跨平台的以太网支持,添加了 5 种新芯片类型,并首次将 SPI 以太网引入 RP2040 平台。像 WIZnet EVB-Pico 系列这样的 RP2040 板卡现在可以在没有 WiFi 的情况下作为有线 IoT 控制器使用。

新的 RP2040 以太网支持:

  • W5500(#14820)—— 100Mbps SPI 以太网,在 WIZnet W5500-EVB-Pico 上以 344 次成功的 API 连接通过压力测试
  • W5100/W5100S(#15131)—— 10/100Mbps SPI 以太网,适用于 W5100S-EVB-Pico 等板卡
  • W6100 和 W6300(#15543)—— 支持 IPv6 的下一代 WIZnet 控制器,适用于 W6300-EVB-Pico2 等板卡

跨平台新增:

  • ENC28J60(#14945)—— Microchip 广泛供应的 10BASE-T 控制器现在在 ESP32(IDF)和 RP2040 上均受支持

ESP32 改进:

  • SPI 接口选择(#10285)—— 新的 interface 配置变量允许 ESP32 用户选择 spi2 或 spi3 主机,解决了 M5Stack CoreS3 等板卡上与显示组件的冲突

PCF8574、PCA9554、MCP23008/MCP23017、MCP23S08/MCP23S17、PI4IOE5V6408、MCP23016、PCA6416A 和 TCA9555 GPIO 扩展器组件现在支持可选的 interrupt_pin,完全消除 I2C/SPI 轮询(#15444、#15445、#15616、#15614、#15613)。

受支持的扩展器:

  • PCF8574、PCA9554、PCA6416A、TCA9555 —— I2C GPIO 扩展器
  • MCP23008、MCP23017、MCP23S08、MCP23S17、MCP23016 —— I2C 和 SPI GPIO 扩展器系列
  • PI4IOE5V6408 —— I2C GPIO 扩展器

实测影响(ESP32-IDF、PCF8574 + 3 个二进制传感器):

指标轮询中断改进
I2C 读取/分钟(闲置)4100ms12ms减少 99.7%
每个门控周期的循环迭代次数747716少 468 倍
二进制传感器读取时间~0.6ms(I2C)~0.002ms(缓存)快 300 倍

配置后,二进制传感器在中断之间从缓存返回(无总线读取),主循环在引脚变化发生前完全禁用。MCP23x17 自动启用 MIRROR 位,因此单根中断线即可捕获全部 16 个引脚的变化。

pcf8574:
id: my_pcf8574
interrupt_pin: GPIO16

本次发布引入了使用 CodSpeed 的全面 C++ 基准测试基础设施,实现持续性能跟踪和回归预防。虽然最初是为了保护 2026.3.0 的改进而添加的,但基准测试很快暴露了剩余的瓶颈,并在整个发布周期中推动了一系列针对性优化。

新增基准测试:

  • Protobuf 编码/解码(API 消息、BLE 广播、ListEntities)
  • Noise 加密握手和有效载荷加密
  • 传感器、二进制传感器、灯、遮阳帘、气候、风扇、数值、选择、开关、文本传感器和按钮发布/调用路径
  • 调度器间隔和超时操作
  • 明文和加密 API 帧写入

API 层优化(原生 API 是 ESPHome 设备与 Home Assistant 之间的主要通信路径)。目标是让蓝牙代理足够轻量,每台 ESP32-C3 都可以运行而不必担心性能影响,本版实现了这一点:结合 2026.3.0 的更改,API 和 BLE 代理广播转发(恒定热点路径)现在在 ESP32-C3 上仅消耗约 1.8% 的主循环运行时间,低于 2026.3.0 的约 3.3%,而一年前的比例更是微不足道:

  • Protobuf 编码:通过寄存器优化的写入路径快 17-20%(#15290)
  • 预计算标签字节:在编译时计算 Varint 和长度限定字段标签(#15067)
  • 帧写入热点路径:展开第一次写入迭代、内联套接字写入、零间隙批处理编码。单个传感器状态写入快 72%,批处理写入快 21%,栈帧从 352 降至 48 字节(-86%)(#15063)
  • Varint 编码优化:明文 varint 编码和 write_protobuf_packet 去虚拟化(#14758)
  • 命令分派去虚拟化:消除每个传入 API 消息的虚拟调用开销(#15044)
  • Protobuf 解码非虚拟:ProtoDecodableMessage::decode() 去虚拟化(#15076)
  • 定长 varint codegen:max_value proto 选项消除了有界字段的变长编码(#15424)
  • 实体名称/object_id 优化:已知有界字符串字段的 max_data_length proto 选项(#15426)
  • Fixed32 解码:在小端平台上使用 memcpy 而非字节移位(#15292)
  • 原始标签+值写入:强制 fixed32 键字段发出原始字节(#15051)
  • 浮点零检查:使用整数比较而非浮点(#15490)
  • 代码大小缩减:缓冲区和非延迟优化(#14797)
  • 溢出缓冲区提取:简化帧辅助缓冲区管理(#14871)
  • Noise 加密加速:继 2026.3.0 的 ChaCha20-Poly1305 优化(实现了 8-32% 的加密加速)之后,本版为 libsodium 启用了 HAVE_WEAK_SYMBOLS 和 HAVE_INLINE_ASM,用字级 memset() 替换了逐字节的 sodium_memzero() 回退。小消息(传感器更新和服务调用的常见情况)获得最大收益:在 ESP32 上快 24%,ESP8266 上快 11%,RP2040 上快 10%(#15038)
  • Noise 握手:拆分 state_action_ 以降低栈压力(#15464)
  • PSK 更新:在超时 lambda 中避免堆分配(#14921)
  • 批处理编码:简化 encode_to_buffer 为单次 resize 调用,内联 DeferredBatch::add_item(#15355、#15353)
  • 枚举自动派生:在 protobuf codegen 中为枚举字段自动派生 max_value(#15469)
  • 子消息内联:新的 (inline_encode) proto 选项将小子消息直接内联到父编码器中,消除函数指针间接。应用于 BluetoothLERawAdvertisement(每批 BLE 最多编码 12 次):BLE 广播编码快 40-55%(#15599)
  • speed_optimized 热点路径:新的 proto 选项在特定编码路径上发出 __attribute__((optimize("O2"))),即使固件默认使用 -Os 标志也能保持内联。应用于 SensorStateResponse、BluetoothLERawAdvertisementsResponse 和 SubscribeLogsResponse:BLE 广播 calculate_size 额外快 41%,传感器状态和日志编码获得类似收益(#15691、#15698)

核心框架优化:

  • 调度器:间隔偏移量计算使用整数运算,直接将已触发的间隔重新调度到堆栈,提前退出的取消路径,以及内联的快速路径检查(#14755、#15516、#14902、#14905)
  • 主循环内联:Application::loop() 和 calculate_looping_components_ 内联以消除栈帧(#15041、#14944)
  • std::bind 消除:在 20 多个组件中用 lambda 替换,以适配小缓冲区优化(#14961 和相关 PR)
  • 自动化调用链折叠:Trigger::trigger() → Automation::trigger() → ActionList::play() 转发链强制内联,将 3 个栈帧折叠为 1 个。结合 ControllerRegistry 分派内联和 call_loop_ 移除,一个按钮→lambda 自动化从16 个栈帧降至 10 个,显著降低了具有深度自动化链的设备上的栈溢出风险(#15042、#15173、#14931)
  • IfAction 编译时优化:HasElse 参数在编译时无 else 块时消除 else 分支检查(#15134)
  • Logger:通过内联热点路径辅助函数减少每条消息的开销(#14851)
  • errno 缓存:避免在 API、async_tcp、captive_portal 和 web_server_idf 中重复调用 __errno()(#14751)
  • 循环消除:许多组件之前每个主循环迭代都会运行其 loop() 仅仅是为了检查条件或时间戳。这些已转换为仅在需要时运行的事件驱动模式:
    • web_server:没有 SSE 客户端连接时完全禁用循环;大多数设备在 99% 以上的时间内没有浏览器客户端(#15428)
    • total_daily_energy:用午夜触发的单个超时替换了 loop()(#15432)
    • CronTrigger:用 set_interval 替换了 loop()(#15433)
    • preferences:当 flash_write_interval 非零时完全编译掉 loop(#14943)
    • GPIO 扩展器(PCF8574、PCA9554、MCP23xxx、PI4IOE5V6408):所有引脚都是输出时禁用循环(#15455、#15460)
    • sx127x、cc1101、sx126x:使用 GPIO 中断唤醒循环而非轮询,包模式不活动时完全禁用循环(#15627、#15606)
    • hbridge 灯:仅当冷白和暖白通道都活跃且需要复用循环时循环才运行;单通道或关闭状态下禁用(#15615)
  • 蓝牙代理:BLE 事件处理程序分派去虚拟化,消除每个 BLE 广播和 GATT 事件的虚拟调用开销(#15310)。BLE is_active/is_running 内联并移除 STL 膨胀(#14875)。广播刷新用 set_interval(100ms) 替换了 loop()(此前每个 60 秒约运行 7,400 次仅为检查时间戳),因此刷新逻辑仅在需要时运行(每个 60 秒约 600 次),每分钟消除约 6,800 次浪费的迭代(#15347)
  • 去虚拟化:Preferences 后端、PollingComponent::set_update_interval(#14825、#14938)
  • 灯:normalize_color 中的倒数乘法,传递 LightTraits 以避免冗余虚拟调用(#15401、#15403)

CodSpeed 在每次 PR 和推送到 dev 时运行,提供持续基线,在回归上线前捕获它们。正是 CodSpeed 的基准可视化揭示了 vsnprintf 消耗了 95% 以上的传感器发布时间,这促成了客户端状态日志的变更,在传感器发布路径上实现了46 倍加速。访问 codspeed.io/esphome/esphome 探索基准测试结果。感谢 CodSpeed 为开源项目免费提供其服务。

在基准测试和内存分析工具的推动之下,本版在框架中实现了大量的 RAM 和闪存节省。

组件分配从堆栈移至 BSS(#15079):这是一项重大架构变更;所有组件实例(new_Pvariable)现在通过 placement new 分配到静态大小的 BSS 存储中,而非单独的堆栈分配。此前,每个组件、传感器、自动化和过滤器都是单独的 new 调用,随着时间推移碎片化堆栈。现在这些分配被打包到一个连续的 BSS 区域中,为真正需要动态分配的 WiFi、BLE 和网络缓冲区释放堆栈空间。这消除了每台设备数百个小的堆栈分配,并显著减少了长期运行设备上的堆栈碎片。

ESPHome 的 CI 会在每次 PR 时自动运行自研的内存影响分析,在合并前向贡献者展示他们更改的确切闪存和 RAM 影响。此前,组件内存对此类工具不可见,因为它都是在运行时分配在堆栈上的。一旦 BSS 变更落地,每个组件的内存就变成了一个 CI 可以测量和归因的静态可见符号。analyze-memory 工具已扩展以将 placement new 存储符号归因回其拥有组件(#15092),使得轻松发现哪些组件仍有改进空间。这种可见性推动了下面一系列有针对性的优化。

核心框架节省:

  • 组件基类:每个实例从 12 字节缩小到 8 字节,在典型配置中节省约 200-400 字节(#15103)
  • CallbackManager:在所有回调注册中用轻量级 Callback(8 字节)替换 std::function(16 字节)。像 [this] 这样的小型 lambda 现在内联存储在函数指针上下文中,零堆栈分配,覆盖了 96% 的回调注册。在具有 MQTT + web_server + 许多实体的 ESP8266 配置上,实测**+488 字节空闲堆栈**(#14853)。后续将 std::vector 替换为平凡复制容器,消除了每签名的向量重新分配机制的模板实例化,在 ESP8266 上节省了 996 字节闪存,每个 CallbackManager 实例节省 4 字节 RAM(#15272)
  • 23 个组件中消除触发器跳板:此前,每个 on_press、on_value、on_state 等自动化都会实例化一个单独的 Trigger 对象以转发回调,这是一个 4+ 字节的堆栈分配对象,仅用于保存一个指针。新的 build_callback_automation() 模式将触发器折叠为一个指针大小的转发器结构体,内联存储在回调管理器中,完全消除了单独的分配。初始 PR(#15174)迁移了核心实体类型(button、sensor、binary_sensor、switch、text_sensor、number、event),节省 88-208 字节 RAM,随后 22 个后续 PR 迁移了 alarm_control_panel、lock、media_player、ld2450、rtttl、online_image、rotary_encoder、dfplayer、hlk_fm22x、pn532、pn7150/pn7160、sim800l、fingerprint_grow、ltr_als_ps、ltr501、nextion、ezo、haier、modbus_controller、rf_bridge、factory_reset、sml 和 safe_mode
  • TemplatableValue → TemplatableFn:函数指针模式首先在 LightControlAction 上得到验证,每个实例从 128 字节缩小到 72 字节(减少 44%,在具有 11 个操作的 ESP8266 灯配置上节省 616 字节 RAM)(#15132)。随后在全代码库中推广:约 340 个 TEMPLATABLE_VALUE 字段通过存储函数指针而非标签联合,自动从每个 8 字节降至 4 字节(#15545)
  • ActionList:移除 actions_end_ 指针以节省每个自动化的 RAM(#15283)

实体和组件节省:

  • 二进制传感器:移除冗余的 optional<bool> 状态,每个实例节省 8 字节(#15095)
  • 文本传感器:raw_callback_ 由 USE_TEXT_SENSOR_FILTER 门控,未使用时每个实例节省 4 字节(#15097)
  • 灯:重新排列 LightState 字段以消除填充(#15112)
  • GPIO 二进制传感器:打包字段并移除冗余的 last_state_(#15113)
  • GPIO 开关:未使用时编译掉互锁字段(#15111)
  • 气候/风扇:自定义模式向量直接存储在实体上,消除堆栈分配(#15206、#15209)
  • WebServerBase:减少 4 字节(#15251)
  • 运行时统计:内联存储在 Component 上,消除 std::map 查找(#15345)

堆栈分配消除:

  • 传感器过滤器:OrFilter、CalibrateLinearFilter、CalibratePolynomialFilter、ValueList、FilterOut、ThrottleWithPriority 迁移到 std::array(#15262、#15263、#15264、#15265)
  • 文本传感器过滤器:SubstituteFilter 和 MapFilter 迁移到 std::array(#15266、#15269)
  • 自动化条件:And、Or、Xor 条件迁移到 std::array(#15282)
  • PID:用 FixedRingBuffer 替换 std::deque(#14733)
  • 传感器滑动窗口:替换为 FixedRingBuffer(#14736)

ESP8266 RAM 节省:

  • API dump 字符串:移至 PROGMEM(#14982)
  • Logger:日志级别查找表和任务日志缓冲区移至 PROGMEM/BSS(#15003、#15153)

新的 esphome bundle CLI 命令将 YAML 配置及其所有本地依赖项(字体、图像、证书、本地 external_components、密钥)打包为一个自包含的 .esphomebundle.tar.gz 存档(#13791)。这是远程编译支持的基础,使像 Home Assistant Green 这样的设备能够将编译卸载到远程构建服务器。

关键特性:

  • 自动依赖项发现 —— 查找所有引用的文件(YAML 包含、字体、图像、动画、证书、C++ 包含、Web 资源)
  • 密钥过滤 —— 仅包含捆绑的 YAML 文件实际引用的密钥
  • 确定性存档 —— 排序条目和归零时间戳以实现可重现性
  • 增量构建 —— 在重新提取之间保留 PlatformIO 构建缓存
Terminal window
esphome bundle my_device.yaml # 创建包
esphome bundle my_device.yaml --list-only # 预览文件
esphome compile my_device.esphomebundle.tar.gz # 从包编译

由 @clydebarrow 通过 27 个 PR 主导,ESPHome 的 LVGL 集成已从 v8 升级至 LVGL v9.5.0(#12312)。这是一次重大的库迁移,带来了新的渲染管道、改进的性能和新的组件功能。现有配置应该能够编译和运行,尽管某些属性已弃用。

关键变更:

  • 原生旋转及硬件加速 —— 旋转现在直接由 LVGL 处理,而非显示驱动程序,通过 lvgl.display.set_rotation 进行运行时旋转更改,并在可用时自动使用硬件旋转。 在 ESP32-P4 上,旋转使用 PPA(像素处理加速器)实现零 CPU 成本变换(#14955、#15453)。
  • 自动触摸屏旋转 —— 触摸输入自动旋转到与显示方向匹配,在大多数情况下消除了手动坐标变换的需求。 用户需要将 rotation 配置从显示组件移至 lvgl: 块,并在触摸屏组件中移除或调整 transform: 块。
  • 内置暗色主题 —— 在 theme: 下使用单个 dark_mode: true 即可启用 LVGL 的原生暗色默认主题,取代了手动复制暗色主题属性的繁琐过程(#15389)
  • 所有 LVGL 9 事件 —— 将 LVGL 9 事件完全映射到 ESPHome 自动化触发器(#15362)
  • 投影支持 —— 新的 bitmap_mask_src 样式属性和 A8 图像格式用于投影效果(#15334)

本次发布添加了对多种新传感器和硬件平台的支持:

  • SPA06-003 由 @danielkent-net 贡献 —— 具有 I2C 和 SPI 接口的 Goermicro 数字压力和温度传感器,可在 Adafruit 和 Seeed Grove 获取(#14521、#14522、#14523)
  • HDC2080 由 @G-Pereira 贡献 —— 德州仪器温度和湿度传感器(#9331)
  • emonTx 由 @FredM67 贡献 —— 通过 UART 串行桥接的 OpenEnergyMonitor emonTx/emonPi 能量监测,具有 JSON 触发器和命令操作(#9027)
  • BMP581 SPI 支持 由 @danielkent-net 贡献 —— BMP581 压力传感器现在支持 I2C 之外的 SPI(#13124)
  • BMP585 支持 由 @nytaros 贡献 —— 为 BMP581 组件添加较新的 BMP585 ASIC ID(#15277)
  • ESP32-C61 PSRAM —— 在 40MHz 和 80MHz 下的 Quad 模式 PSRAM 支持(#14795)
  • nRF52 Zephyr 内部温度 由 @Ardumine 贡献(#15297)和 LN882H 由 @Bl00d-B0b 贡献(#15370)
  • 数值到传感器和文本到文本传感器桥接 —— 用于自动化和显示中的 number/text 组件的新只读传感器/文本传感器视图(#15125、#15090)
  • ESP32 托管 SPI 传输 —— 用于 esp32_hosted WiFi 卸载组件的 SPI 传输和 1 位 SDIO 总线宽度支持(#15551)
  • Nextion 自定义协议触发器 —— 用于无需实体的事件驱动 Nextion 工作流的 on_custom_switch、on_custom_sensor、on_custom_text_sensor、on_custom_binary_sensor 触发器(#13248)
  • MQTT 报警面板 JSON 负载 —— 报警控制面板命令主题现在接受带 PIN 码的 JSON 负载,例如 {"state": "DISARM", "code": "1234"}(#14731)
  • 媒体播放器入队操作 —— 用于从自动化中排队媒体 URL 的新 media_player.enqueue 操作(#14775)
  • MIPI RGB 可选同步引脚 —— hsync_pin/vsync_pin 现在对 BigTreeTech PandaTouch 等显示器为可选(#14870)
  • Brennenstuhl 远程开关 —— 用于 Brennenstuhl comfort-line 开关的新 433MHz 滚动码协议(#9407)
  • DSMR 热 MBUS ID —— 用于 Warmtelink 热计量表的新 thermal_mbus_id 选项(#7519)
  • VBus DeltaSol CS4 —— 支持 Citrin Solar 1.3 控制器(#12477)
  • TM1637 缓冲区操作 —— 用于原始段写入和自定义字形的新 set_buffer 方法(#13686)
  • HUB75 扫描接线 —— 新的 SCAN_1_8_32PX_FULL 接线选项(#15130)
  • */N cron 语法 —— 基于时间的自动化现在支持 */5 风格的步进表达式(#15434)
  • microFLAC 音频解码 由 @kahrendt 贡献 —— 新的 FLAC 解码器在 ESP32-S3 上快 9% 且重新启用了 CRC 验证,加上真正的流式支持以消除不必要的内存复制(#15372)

由 @crnjan 通过 5 个 PR 构建,新的 mitsubishi_cn105 组件为通过 CN105 连接器控制三菱空调单元提供了原生支持,这是 ESPHome 中需求最迫切的气候集成之一。该组件实现了与流行的 SwiCago HeatPump 项目相同的 CN105 协议,确保与相同设备范围的兼容性(#15315、#15358、#15437、#15462、#15483)。

关键特性:

  • 完整的气候控制 —— 电源、模式、目标温度和风扇速度可以直接从 Home Assistant 控制
  • 非阻塞协议驱动程序 —— 专为性能和可靠性设计的自定义 UART 解析器
  • 智能温度轮询 —— current_temperature_min_interval 选项对室内温度读取进行速率限制,以防止在测量边界附近的快速振荡,同时保持快速的 update_interval 以实现响应式控制
  • 广泛的平台支持 —— 适用于 ESP32、ESP32 IDF、ESP8266 和 RP2040/RP2350
climate:
- platform: mitsubishi_cn105
name: "Air Condition"
uart_id: ac_uart
update_interval: 1s
current_temperature_min_interval: 60s

继 2026.3.0 开始的正确性扫尾之后,@swoboda1337 在本版中又贡献了 99 个错误修复和验证 PR,解决了传感器模式上缺失的 state_class 和 device_class、不正确的配置验证(类型错误、缺少范围检查、ensure_list 用法损坏)、死代码移除、格式说明符警告,以及 100 多个组件中的 codegen 类型不匹配。这种持续的努力显著提高了 ESPHome 代码库的可靠性和正确性。

本次发布包含来自 40 多位贡献者的 507 个拉取请求。衷心感谢所有让 2026.4.0 成为可能的人:

  • @swoboda1337 - 121 个 PR,包括跨 100+ 组件的正确性扫尾、几十个组件的 ESP-IDF 6.0 兼容性,以及 ESP32 CPU 频率默认值变更
  • @clydebarrow - 27 个 PR,包括 LVGL v9.5.0 迁移、原生旋转支持,以及显示组件改进
  • @edwardtfn - 14 个 PR,包括 Nextion 自定义协议触发器、性能优化,以及 Nextion 组件的代码质量改进
  • @jpeletier - 10 个 PR,包括将替换系统重新设计为 18 倍配置加载速度,以及 !include 路径替换支持
  • @kbx81 - 10 个 PR,包括无需硬件安全启动的签名 OTA 验证、IR 接收器频率元数据,以及传感器代码清理
  • @kahrendt - 7 个 PR,包括媒体播放器入队操作、microFLAC 解码,以及音频管线改进
  • @danielkent-net - 5 个 PR,包括新的 SPA06-003 压力/温度传感器(I2C 和 SPI)和 BMP581 SPI 支持
  • @crnjan - 5 个 PR,从框架到完整读写控制,构建了新的三菱 CN105 气候组件
  • @exciton - 4 个 PR,包括 modbus 辅助重构和集成测试
  • @jesserockz - 4 个 PR,包括 CI 改进和无界百分比验证器
  • @diorcety - 4 个 PR,包括 git 子路径支持和编译器兼容性修复
  • @FredM67 - 2 个 PR,包括新的 emonTx 能量监测组件
  • @tomaszduda23 - 2 个 PR,包括调试外设状态和 Zigbee 日志改进
  • @P4uLT - 2 个 PR,包括 PID FixedRingBuffer 优化
  • @Kamilcuk - 2 个 PR,包括 Pvariable 的 placement new 分配
  • @luar123 - 自定义 ESP32 分区表和分区表重构
  • @G-Pereira - 新的 HDC2080 温度和湿度传感器

同时感谢 @bdraco、@thomwiggers、@aanban、@rtyle、@Szewcson、@Pernotto、@mike1703、@tuct、@CFlix、@heythisisnate、@warthog618、@FWeinb、@droscy、@intcreator、@szupi-ipuzs、@fblaese、@glmnet、@nytaros、@Ardumine、@rguca、@Bl00d-B0b、@RAR、@Passific 和 @Tomer27cz 的贡献,以及所有报告问题、测试预发布版本并在社区中帮助的人。

  • ESP32 CPU 频率:默认 CPU 频率更改为每个变体支持的最大值(ESP32/S2/S3/C5:从 160MHz 到 240MHz)。这使性能提升约 33%,但增加了功耗。电池供电设备应在配置中添加 cpu_frequency: 160MHZ。#15143

  • ESP32 分区表:Arduino 和 IDF 框架的分区布局均已更改。NVS 移至闪存末尾,尺寸增大(Arduino 上从 20KB 到 384KB)。现有设备将在下次 OTA 更新时获得新的分区表。由于库通过名称而非位置查找 NVS 数据,NVS 数据将得到保留。#7682

  • ESP8266 RTC 偏好设置:RTC 偏好设置容量从 96 降至 78 个词,以适应新的崩溃处理程序。溢出写入闪存。对真实配置的影响极小。#15465

  • LVGL 旋转:rotation 选项现在必须在 lvgl: 下配置,而非在显示组件下。LVGL 现在直接为显示和触摸屏处理旋转,支持通过 lvgl.display.set_rotation 进行运行时旋转更改。用户必须将 rotation 设置从显示配置移至 lvgl: 块。#14955,并在有触摸屏配置的情况下移除或调整 transform: 块。

  • I2S 音频:旧的 I2S 驱动程序(use_legacy 选项)已移除。始终使用新 I2S 驱动程序。i2s_audio 媒体播放器子组件已完全移除;用户应迁移到speaker 媒体播放器组件。#14932

  • 二进制传感器 multi_click:on_multi_click 时序序列现在限制为 255 个条目(以前无限制)。没有真实配置会接近此限制。#15267

  • 二进制传感器 autorepeat:自动重复时序列表现在限制为 254 个条目(以前无限制)。没有真实配置会接近此限制。#15268

  • 替换:当同一个字典中的两个 YAML 键解析为相同的替换名称时,后出现的键值现在优先(“后写入者胜”)。此前,在字典合并时现有解析值优先。这仅影响重复替换键的边缘情况。#14918

本版中若干内部 C++ API 已发生变更。虽然这些不属于公共 API,但它们可能影响编写 lambda 或维护外部组件的用户。

  • Component:set_component_source(const LogString *) 已移除,由受保护的 set_component_source_(uint8_t) 替换。warn_if_blocking_over_ 字段从 uint16_t(毫秒)变为 uint8_t(百分秒)。组件基类从 12 字节缩小到 8 字节。#15103

  • Preferences:ESPPreferenceBackend 和 ESPPreferences 抽象基类已移除。它们现在是对具体平台特定 final 类的类型别名。所有使用 global_preferences 或 ESPPreferenceObject 的现有代码继续正常工作。#14825

  • 触发器类移除:ButtonPressTrigger、SensorStateTrigger、SensorRawStateTrigger、PressTrigger、ReleaseTrigger、StateTrigger、StateChangeTrigger、SwitchStateTrigger、SwitchTurnOnTrigger、SwitchTurnOffTrigger、TextSensorStateTrigger、TextSensorStateRawTrigger、NumberStateTrigger 和 EventTrigger 不再被实例化。使用 trigger_id 访问这些对象的 lambda 将会出错。请使用 Script 进行动作控制。Automation::trigger_ 受保护字段也已移除。#15174
  • 非字符串类型的 TemplatableValue:不再接受有状态 lambda(带捕获的 lambda)。未发现外部使用情况。如果您需要一个有状态的函数对象,请直接使用 std::function<T(X...)>。TEMPLATABLE_VALUE 宏现在对平凡可复制类型使用 TemplatableFn(4 字节)。#15545
  • Nextion:get_wave_chan_id() 弃用,改为使用 get_wave_channel_id()(将在 2026.10.0 移除)。Getter 方法现在通过 const 引用返回,而非通过值。get_queue_type_string() 返回 const char * 而非 std::string。波形相关方法现在由 USE_NEXTION_WAVEFORM 门控,如果未配置波形传感器,可能不可用。#15204、#15273

  • ATM90E32:get_phase_angle_() 返回类型从 uint16_t 更改为 float(修复精度损失)。last_periodic_millis 成员已移除(从未使用)。#15238

  • AS5600:死 angle_sensor_、raw_angle_sensor_、position_sensor_ 成员及其设置器已移除(从未连接到配置模式)。#15254

  • SEN5x:voc_baseline 配置选项已移除(从未连接到 C++)。改用 store_baseline: true。#15391

  • Graph:legend 配置不再接受列表(以前仅使用第一个元素)。单值配置继续工作。#15522

  • Haier:control_method 配置不再接受列表。单值配置继续工作。#15523

  • RP2040 PIO LED 灯带:chipset 枚举中移除 CUSTOM(在编译时崩溃)。改用显式时序参数(bit0_high、bit0_low、bit1_high、bit1_low)。#15537

  • CallbackManager:用轻量级 Callback 类型替换 std::function。现有代码继续工作,但外部组件应将其回调注册方法从 std::function 参数迁移到模板以获得最佳性能(非模板方法回退到堆栈分配路径)。#14853
  • PollingComponent:set_update_interval() 现在为非虚拟。重写此方法的子类应使用替代模式。#14938
  • UART FlushResult:FlushResult 重命名为 UARTFlushResult,枚举值使用 UART_FLUSH_RESULT_ 前缀。#15101
  • 传感器 raw_state:.raw_state 已弃用。raw_callback_ 现在由 USE_SENSOR_FILTER 门控,当未配置过滤器时为每个传感器实例节省 RAM。#15094
  • 触发器跳板消除:常见实体自动化(button、sensor、binary_sensor、switch、text_sensor、number、event)的触发器对象不再被实例化。build_automation() 和 Trigger 子类仍然可用。#15174
  • TemplatableFn:TEMPLATABLE_VALUE 宏现在对平凡可复制类型使用 4 字节的 TemplatableFn。使用原始 C++ 常量而非通过 cg.templatable() 调用宏生成设置器的外部组件将无法编译。#15545
  • 气候/风扇自定义模式:自定义模式/预设向量现在存储在实体上,而非在堆栈上分配。气候和风扇特性的构造函数已更改。#15206、#15209
  • 触发器迁移到回调自动化:alarm_control_panel、lock 和 media_player 触发器现在使用回调自动化模式。#15198、#15199、#15200
  • BLE 事件分派:BLE 事件处理程序分派已去虚拟化。#15310
  • wake_loop:从套接字组件移至核心。#15446
  • Preferences 去虚拟化:ESPPreferenceBackend 和 ESPPreferences 现在是对具体平台特定类的类型别名(无虚拟基类)。#14825
  • Component 从 12 字节缩小到 8 字节:set_component_source(const LogString *) 已移除,由 set_component_source_(uint8_t)(受保护)替换。#15103
  • AS5600:死角度/原始角度/位置传感器代码已移除。#15254
  • Modbus 辅助:跨 modbus 组件重构共享辅助函数。#15291、#14172

详细迁移指南和 API 文档,请参阅 ESPHome 开发者文档。

(完整变更列表请参见原文)

(完整变更列表请参见原文)

(完整变更列表请参见原文)

(完整变更列表请参见原文)

(完整变更列表请参见原文)