Skip to content
Closed
24 changes: 16 additions & 8 deletions content/changelog/2025.11.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,12 @@ Users who access component members directly in YAML lambdas may need updates:
- **Fan**: Change `id(my_fan).preset_mode` to `id(my_fan).get_preset_mode()`. [#11632](https://github.com/esphome/esphome/pull/11632)

- **Event**: Change `id(my_event).last_event_type` to `id(my_event).get_last_event_type()`. [#11767](https://github.com/esphome/esphome/pull/11767)

- **Climate**: Custom mode members are now private. Change direct access to public accessor methods:
- Check if active: `id(my_climate).custom_fan_mode.has_value()` → `id(my_climate).has_custom_fan_mode()`, `id(my_climate).custom_preset.has_value()` → `id(my_climate).has_custom_preset()`
- Get value: `id(my_climate).custom_fan_mode.value()` → `id(my_climate).get_custom_fan_mode()`, `id(my_climate).custom_preset.value()` → `id(my_climate).get_custom_preset()`

[#11621](https://github.com/esphome/esphome/pull/11621)
<!-- BREAKING_CHANGES_USERS_END -->

### Breaking Changes for Developers
Expand All @@ -429,7 +435,7 @@ The following changes affect external component developers. Standard YAML config

## Core Framework Changes

- **Action/Trigger Framework**: All action/trigger/condition method signatures changed to use const references (`const Ts&... x`) instead of pass-by-value (`Ts... x`). See the [Action Framework Performance Optimization](https://developers.esphome.io/blog/2025/11/action-framework-performance-optimization.html) blog post for migration details. [#11704](https://github.com/esphome/esphome/pull/11704)
- **Action/Trigger Framework**: All action/trigger/condition method signatures changed to use const references (`const Ts&... x`) instead of pass-by-value (`Ts... x`). See the [Action Framework Performance Optimization](https://developers.esphome.io/blog/2025/11/06/action-framework-performance-optimization/) blog post for migration details. [#11704](https://github.com/esphome/esphome/pull/11704)

- **Controller API**: Controllers now use global registry pattern. Method signatures changed to remove unused state parameters (e.g., `on_sensor_update(sensor::Sensor *obj)` instead of `on_sensor_update(sensor::Sensor *obj, float state)`). External controller implementations extremely rare. [#11772](https://github.com/esphome/esphome/pull/11772)

Expand All @@ -443,17 +449,17 @@ The following changes affect external component developers. Standard YAML config

### Climate

See the [Climate Entity Class: FiniteSetMask and Flash Storage Optimizations](https://developers.esphome.io/blog/2025/11/climate-entity-class-memory-optimizations.html) blog post for migration details.
See the [Climate Entity Class: FiniteSetMask and Flash Storage Optimizations](https://developers.esphome.io/blog/2025/11/07/climate-entity-class-finitesetmask-and-flash-storage-optimizations/) blog post for migration details.

- **Custom modes storage**: Changed from `std::set<std::string>` to `FiniteSetMask` for supported modes, and from `std::vector<std::string>` to `std::vector<const char *>` for custom fan modes and presets. [#11466](https://github.com/esphome/esphome/pull/11466), [#11621](https://github.com/esphome/esphome/pull/11621)

- **Member access**: Climate device members (`custom_fan_mode_`, `custom_preset_`) are now private. Use protected setter methods (`set_custom_fan_mode_()`, `set_custom_preset_()`) in derived classes. [#11621](https://github.com/esphome/esphome/pull/11621)
- **Member access**: Climate device members (`custom_fan_mode_`, `custom_preset_`) are now private. Use protected setter methods (`set_custom_fan_mode_()`, `set_custom_preset_()`) in derived classes. Use public accessor methods to read values: `has_custom_fan_mode()`, `get_custom_fan_mode()`, `has_custom_preset()`, `get_custom_preset()`. [#11621](https://github.com/esphome/esphome/pull/11621)

- **Deprecated methods**: Removed methods deprecated in 1.20 (July 2021). [#11388](https://github.com/esphome/esphome/pull/11388)

### Light

See the [Light Entity Class: Memory Optimizations](https://developers.esphome.io/blog/2025/11/light-entity-class-memory-optimizations.html) blog post for migration details.
See the [Light Entity Class: Memory Optimizations](https://developers.esphome.io/blog/2025/11/07/light-entity-class-memory-optimizations/) blog post for migration details.

- **Color modes**: Replaced `std::set<ColorMode>` with `ColorModeMask` bitmask class. [#11348](https://github.com/esphome/esphome/pull/11348)

Expand All @@ -463,15 +469,15 @@ See the [Light Entity Class: Memory Optimizations](https://developers.esphome.io

### Fan

See the [Fan Entity Class: Preset Mode Flash Storage and Order Preservation](https://developers.esphome.io/blog/2025/11/fan-entity-class-memory-optimizations.html) blog post for migration details.
See the [Fan Entity Class: Preset Mode Flash Storage and Order Preservation](https://developers.esphome.io/blog/2025/11/07/fan-entity-class-preset-mode-flash-storage-and-order-preservation/) blog post for migration details.

- **Preset modes**: Changed from `std::set<std::string>` to `std::vector<const char *>`. The `.preset_mode` public member has been removed - use `get_preset_mode()` for reading and `set_preset_mode_()` for writing in derived classes. [#11483](https://github.com/esphome/esphome/pull/11483), [#11632](https://github.com/esphome/esphome/pull/11632)

- **Deprecated code**: Removed code deprecated in 2022.2. [#11392](https://github.com/esphome/esphome/pull/11392)

### Select

See the [Select Entity Class: Index-Based Operations and Flash Storage](https://developers.esphome.io/blog/2025/11/select-entity-class-memory-optimizations.html) blog post for migration details.
See the [Select Entity Class: Index-Based Operations and Flash Storage](https://developers.esphome.io/blog/2025/11/07/select-entity-class-index-based-operations-and-flash-storage/) blog post for migration details.

- **Options storage**: Changed from `std::vector<std::string>` to `FixedVector<const char *>`. [#11514](https://github.com/esphome/esphome/pull/11514)

Expand All @@ -481,15 +487,17 @@ See the [Select Entity Class: Index-Based Operations and Flash Storage](https://

### Event

See the [Event Entity Class: Memory Optimizations](https://developers.esphome.io/blog/2025/11/event-entity-class-memory-optimizations.html) blog post for migration details.
See the [Event Entity Class: Memory Optimizations](https://developers.esphome.io/blog/2025/11/07/event-entity-class-memory-optimizations/) blog post for migration details.

- **Event types storage**: Changed from `FixedVector<std::string>` to `FixedVector<const char *>`. The `last_event_type` field is now private - use `get_last_event_type()` getter instead. [#11463](https://github.com/esphome/esphome/pull/11463), [#11767](https://github.com/esphome/esphome/pull/11767)

### Network Components

See the [Network get_use_address() Optimization](https://developers.esphome.io/blog/2025/11/20/network-use-address-optimization/) blog post for migration details.

- **WiFi scan results**: External components that access WiFi scan results after connection must call `wifi.request_wifi_scan_results()` in their `to_code()` function to prevent cleanup. [#11205](https://github.com/esphome/esphome/pull/11205)

- **use_address**: Changed from `const std::string &` to `const char *` in WiFi, Ethernet, and OpenThread components. Update external components calling `get_use_address()` or `set_use_address()`. [#11707](https://github.com/esphome/esphome/pull/11707)
- **use_address**: Changed from `const std::string &` to `const char *` in WiFi, Ethernet, and OpenThread components. Remove `.c_str()` calls when using `get_use_address()`. [#11707](https://github.com/esphome/esphome/pull/11707)

### Other Components

Expand Down
32 changes: 28 additions & 4 deletions content/components/climate/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,18 +234,42 @@ advanced stuff.
id(my_climate).target_humidity
// Fan mode, type: FanMode (enum)
id(my_climate).fan_mode
// Custom Fan mode, type: string
id(my_climate).custom_fan_mode
// Swing mode, type: SwingMode (enum)
id(my_climate).swing_mode
// Current action (currentl on idle, cooling, heating, etc.), ClimateAction (enum)
id(my_climate).action
// Preset, type: Preset (enum)
id(my_climate).preset
// Custom Preset, type: string
id(my_climate).custom_preset
```

- Custom mode accessor methods:

```cpp
// Check if custom fan mode is active, type: bool
id(my_climate).has_custom_fan_mode()
// Get custom fan mode (read-only), type: const char*
id(my_climate).get_custom_fan_mode()
// Check if custom preset is active, type: bool
id(my_climate).has_custom_preset()
// Get custom preset (read-only), type: const char*
id(my_climate).get_custom_preset()
```

> [!WARNING]
> Always check if a custom mode is active before accessing it. Calling `get_custom_fan_mode()` or `get_custom_preset()` when no custom mode is set will return `nullptr`, which can cause crashes if dereferenced.
>
> ```cpp
> // Correct - check before accessing
> if (id(my_climate).has_custom_fan_mode()) {
> const char* mode = id(my_climate).get_custom_fan_mode();
> // Now safe to use mode
> }
>
> // Wrong - may crash if no custom mode is set
> const char* mode = id(my_climate).get_custom_fan_mode();
> ESP_LOGD("tag", "Mode: %s", mode); // Crashes if mode is nullptr
> ```

- `.make_call` : Control the climate device

```cpp
Expand Down
1 change: 1 addition & 0 deletions content/components/display/mipi_dsi.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ specified, or a custom init sequence can be provided.
| Model | Manufacturer | Product Description |
| ---------------------- | ------------ | ----------------------------------------------------------------------------- |
| JC1060P470 | Guition | <https://aliexpress.com/item/1005008328088576.html> |
| JC4880P443 | Guition | <https://aliexpress.com/item/1005009618259341.html> |
| M5STACK-TAB5 | M5Stack | <https://shop.m5stack.com/products/m5stack-tab5-iot-development-kit-esp32-p4> |
| WAVESHARE-P4-NANO-10.1 | Waveshare | <https://www.waveshare.com/esp32-p4-nano.htm?sku=29031> |
| WAVESHARE-P4-86-PANEL | Waveshare | <https://www.waveshare.com/esp32-p4-wifi6-touch-lcd-4b.htm?sku=31570> |
Expand Down
8 changes: 5 additions & 3 deletions content/components/display/mipi_rgb.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,11 @@ Displays needing a custom init sequence require an SPI bus to be configured, plu
`16bit` (default) or `18bit`.
- **invert_colors** (*Optional*): Inverts the display colors, (white becomes black.) Defaults to false.
- **color_order** (*Optional*): Should be one of `bgr` (default) or `rgb`.
- **transform** (*Optional*): Transform the display presentation using hardware. All defaults are `false`.
This option should not be used with `rotation`. For the `CUSTOM` model, use `transform: disabled`
if the display does not support it, which will prevent a `rotation` being translated to a hardware transform.
- **transform** (*Optional*): Transform the display presentation using hardware.
This is typically used only to correct for displays that have x or y drivers wired backwards. To rotate the
display the `rotation` option is preferred - it will automatically use hardware transform if possible.
The default values for the `mirror_x` and `mirror_y` options are model dependent.
For the `CUSTOM` model, use of `transform: disabled` will prevent a `rotation` being translated to a hardware transform.

- **mirror_x** (*Optional*, boolean): If true, mirror the x-axis.
- **mirror_y** (*Optional*, boolean): If true, mirror the y-axis.
Expand Down
2 changes: 1 addition & 1 deletion content/components/esp32.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ esp32:
This must match the hardware in use, or it will fail to flash.

- **board** (*Optional*, string): The PlatformIO board ID that should be used. Choose the appropriate board from
[this list](https://registry.platformio.org/platforms/platformio/espressif32/boards?version=5.3.0) (the icon next
[this list](https://registry.platformio.org/platforms/platformio/espressif32/boards) (the icon next
to the name can be used to copy the board ID). *This only affects pin aliases and some internal settings*;
This setting is no longer recommended, `variant` should be used instead.

Expand Down
7 changes: 5 additions & 2 deletions content/components/espnow.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ params:
image: esp-now.svg
---

This component allows ESPHome to communicate with esp32 devices in a simple and unrestricted way.
The ESPNow component allows ESPHome to communicate with esp32 devices in a simple and unrestricted way.
It enables the option to interact with other esp32 devices over the Espressif's ESP-NOW protocol, see
[documentation](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/network/esp_now.html)
[documentation](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/network/esp_now.html).
It can be used with the [Packet Transport Component](/components/packet_transport) to broadcast
sensor data, see [ESP-NOW Packet Transport Platform](/components/packet_transport/espnow).

> [!NOTE]
> Broadcasting data is not recommended, this will also reach devices not controlled by you that use the esp-now protocol.
Expand Down Expand Up @@ -213,3 +215,4 @@ automatically add any peer that data is sent to.
## See Also

- {{< apiref "espnow/espnow.h" "espnow/espnow.h" >}}
- {{< docref "/components/packet_transport/espnow" >}}
2 changes: 1 addition & 1 deletion content/components/lvgl/widgets.md
Original file line number Diff line number Diff line change
Expand Up @@ -1253,7 +1253,7 @@ The meter widget can visualize data in very flexible ways. It can use arcs, need
- Style options from [Style properties](/components/lvgl#lvgl-styling) for the tick *lines* and *labels* using the [`line`](#lvgl-widget-line) and [`label`](#lvgl-widget-label) text style properties.
- Style options from [Style properties](/components/lvgl#lvgl-styling) for the background of the meter, using the typical background properties.
- **ticks** (*Optional*, dict): Styling options for the ticks *part*, which will be applied to the tick lines and labels using standard *line* and *label* styles.
- **indicator** (*Optional*, dict): Styling options for the indicator *part*, which will be applied to the needle line or image using standard *line* and *image* styles.
- **indicator** (*Optional*, dict): Styling options for the indicator *part*, which will be applied to the needle line or image using standard *line* and *image* styles. Background properties applied here will style the pivot (the dot in the middle of the meter) for example to hide the pivot use `bg_opa: transp` in the `indicator` style.
- **items** (*Optional*, dict): Settings for the items *part*, which will be applied to arcs.

> [!NOTE]
Expand Down
39 changes: 23 additions & 16 deletions content/components/packet_transport/espnow.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,17 @@ params:

{{< anchor "espnow-packet-transport" >}}

The [Packet Transport Component](#packet-transport) platform allows ESPHome nodes to directly communicate with each over a communication channel. The ESP-NOW implementation of the platform uses ESP-NOW as a communication medium. See the [Packet Transport Component](#packet-transport) and {{< docref "/components/espnow" >}} for more information.
The [Packet Transport Component](#packet-transport) platform allows ESPHome nodes to directly communicate with each
over a communication channel. The ESP-NOW implementation of the platform uses ESP-NOW as a communication medium.
See the [Packet Transport Component](#packet-transport) and {{< docref "/components/espnow" >}} for more information.

ESP-NOW provides low-latency, low-power wireless communication between ESP32 devices without requiring a Wi-Fi connection. This makes it ideal for battery-powered sensors or applications where Wi-Fi overhead would impact performance.
ESP-NOW provides low-latency, low-power wireless communication between ESP32 devices without requiring a Wi-Fi
connection. This makes it ideal for battery-powered sensors or applications where Wi-Fi overhead would impact
performance.

> **Note:**
> ESP-NOW communication occurs independently of Wi-Fi. Devices can communicate via ESP-NOW even when Wi-Fi is disabled, making it suitable for power-sensitive applications.
> ESP-NOW communication occurs independently of Wi-Fi. Devices can communicate via ESP-NOW even when Wi-Fi is
> disabled, making it suitable for power-sensitive applications.

## Example Configuration

Expand Down Expand Up @@ -44,7 +49,7 @@ sensor:
- **espnow_id** (**Required**, [ID](#config-id)): The esp-now ID to use for transport.
- **peer_address** (*Optional*, MAC Address): MAC address to send packets to. This can be either a specific
peer address for point-to-point communication, or the broadcast address. Default FF:FF:FF:FF:FF:FF
- All other options from the [Packet Transport Component](#packet-transport)
- All other options from the [Packet Transport Component](/components/packet_transport)

> **Note:**
> Peers must be registered with the {{< docref "/components/espnow" >}} component before
Expand All @@ -64,10 +69,12 @@ packet_transport:
- sensor_id
```

All devices with the broadcast address (`FF:FF:FF:FF:FF:FF`) registered as a peer will receive the packets. This is useful for hub-and-spoke topologies where multiple devices monitor a single sensor source.
All devices with the broadcast address (`FF:FF:FF:FF:FF:FF`) registered as a peer will receive the packets.
This is useful for hub-and-spoke topologies where multiple devices monitor a single sensor source.

> **Warning:**
> Using broadcast mode increases ESP-NOW traffic on the radio channel, which may impact performance of other ESP-NOW devices in range. Use specific peer addresses whenever possible to minimize interference.
> Using broadcast mode increases ESP-NOW traffic on the radio channel, which may impact performance of other
> ESP-NOW devices in range. Use specific peer addresses whenever possible to minimize interference.

### Unicast Mode

Expand All @@ -79,7 +86,8 @@ packet_transport:
- sensor_id
```

Only the specified peer receives the packets. This is more efficient for point-to-point communication and reduces radio channel congestion for neighboring ESP-NOW devices.
Only the specified peer receives the packets. This is more efficient for point-to-point communication and reduces
radio channel congestion for neighboring ESP-NOW devices.

## Simple Example

Expand All @@ -90,11 +98,11 @@ This example shows two devices exchanging sensor data over ESP-NOW with encrypti
```yaml
espnow:
peers:
- mac_address: "AA:BB:CC:DD:EE:01" # Device 2
- "AA:BB:CC:DD:EE:01" # Consumer mac address

packet_transport:
- platform: espnow
peer_address: "AA:BB:CC:DD:EE:01" # Send to Device 2
peer_address: "AA:BB:CC:DD:EE:01" # Consumer mac address
encryption: "MySecretKey123"
sensors:
- outdoor_temp
Expand All @@ -111,13 +119,13 @@ sensor:
```yaml
espnow:
peers:
- mac_address: "AA:BB:CC:DD:EE:00" # Device 1
- "AA:BB:CC:DD:EE:00" # Provider mac address

packet_transport:
- platform: espnow
encryption: "MySecretKey123"
providers:
- name: temp-sensor
- name: temp-sensor # Provider device name

sensor:
- platform: packet_transport
Expand All @@ -136,7 +144,9 @@ This example shows a central hub receiving sensor data from multiple remote devi
```yaml
espnow:
peers:
- mac_address: "FF:FF:FF:FF:FF:FF"
- "AA:BB:CC:DD:EE:01" # room-sensor-1 mac address
- "AA:BB:CC:DD:EE:02" # room-sensor-2 mac address
- "AA:BB:CC:DD:EE:03" # outdoor-sensor mac address

packet_transport:
- platform: espnow
Expand Down Expand Up @@ -167,12 +177,9 @@ sensor:

```yaml
espnow:
peers:
- mac_address: "FF:FF:FF:FF:FF:FF"

packet_transport:
- platform: espnow
peer_address: "FF:FF:FF:FF:FF:FF"
encryption: "HubSecret123"
sensors:
- temperature
Expand All @@ -185,7 +192,7 @@ sensor:

## See Also

- [Packet Transport Component](#packet-transport)
- [Packet Transport Component](/components/packet_transport)
- {{< docref "/components/espnow" >}}
- {{< docref "/components/binary_sensor/packet_transport" >}}
- {{< docref "/components/sensor/packet_transport" >}}
Expand Down
Loading