WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 50ec829

Browse files
authored
Merge pull request #5756 from esphome/bump-2025.12.0b1
2025.12.0b1
2 parents de726ec + 3ea41b6 commit 50ec829

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+2375
-144
lines changed

all_automations.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@
136136
"grove_tb6612fng.run",
137137
"grove_tb6612fng.standby",
138138
"grove_tb6612fng.stop",
139+
"hc8.calibrate",
139140
"homeassistant.action",
140141
"homeassistant.event",
141142
"homeassistant.service",

content/automations/all_actions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ title: ""
3131
- **fingerprint_grow:** `aura_led_control`, `cancel_enroll`, `delete`, `delete_all`, `enroll`, `led_control`
3232
- **globals:** `set`
3333
- **grove_tb6612fng:** `break`, `change_address`, `no_standby`, `run`, `standby`, `stop`
34+
- **hc8:** `calibrate`
3435
- **homeassistant:** `event`, `service`, `tag_scanned`
3536
- **http_request:** `get`, `post`, `send`
3637
- **htu21d:** `set_heater`, `set_heater_level`

content/changelog/2025.12.0.md

Lines changed: 358 additions & 0 deletions
Large diffs are not rendered by default.

content/changelog/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ description: "Changelog"
33
title: "Changelog"
44
---
55

6-
{{< redirect url="/changelog/2025.11.0.html" >}}
6+
{{< redirect url="/changelog/2025.12.0.html" >}}

content/components/_index.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ Create update entities simplifying management of OTA updates.
169169
"SPI Bus","components/spi","spi.svg",""
170170
"TinyUSB","components/tinyusb","usb.svg","dark-invert"
171171
"UART","components/uart","uart.svg",""
172+
"USB CDC-ACM","components/usb_cdc_acm","usb.svg","dark-invert"
172173
"USB Host","components/usb_host","usb.svg","dark-invert"
173174
"USB UART","components/usb_uart","usb.svg","dark-invert"
174175
{{< /imgtable >}}
@@ -240,6 +241,7 @@ Sensors are organized into categories; if a given sensor fits into more than one
240241
"GCJA5","components/sensor/gcja5","gcja5.svg","Particulate","",""
241242
"GP2Y1010AU0F","components/sensor/gp2y1010au0f","gp2y1010au0f.png","Particulate","",""
242243
"Grove Multichannel Gas V2","components/sensor/grove_gas_mc_v2","grove-gas-mc-v2.png","NO₂ & CO & Ethanol & Volatile organics","",""
244+
"HC8","components/sensor/hc8","hc8.png","CO₂","",""
243245
"HM3301","components/sensor/hm3301","hm3301.jpg","Particulate","",""
244246
"iAQ-Core","components/sensor/iaqcore","iaqcore.jpg","eCO₂ & Volatile organics","",""
245247
"MH-Z19","components/sensor/mhz19","mhz19.jpg","CO₂ & Temperature","",""
@@ -291,6 +293,7 @@ Sensors are organized into categories; if a given sensor fits into more than one
291293
"Mopeka Pro Check LP","components/sensor/mopeka_pro_check","mopeka_pro_check.jpg","Tank level"
292294
"Mopeka Standard Check LP","components/sensor/mopeka_std_check","mopeka_std_check.jpg","Tank level"
293295
"RuuviTag","components/sensor/ruuvitag","ruuvitag.jpg","Temperature & Humidity & Accelerometer"
296+
"ThermoPro BLE","components/sensor/thermopro_ble","thermopro_tp357.jpg","Temperature & Humidity"
294297
"Xiaomi BLE","components/sensor/xiaomi_ble","xiaomi_mijia_logo.jpg","Various"
295298
{{< /imgtable >}}
296299

@@ -335,6 +338,7 @@ Sensors are organized into categories; if a given sensor fits into more than one
335338
"Daly BMS","components/sensor/daly_bms","daly_bms.jpg","Voltage & Current & Power"
336339
"DSMR","components/sensor/dsmr","dsmr.svg","Electrical counter"
337340
"HLW8012","components/sensor/hlw8012","hlw8012.svg","Voltage & Current & Power"
341+
"HLW8032","components/sensor/hlw8032","hlw8032.png","Voltage & Current & Power"
338342
"INA219","components/sensor/ina219","ina219.jpg","DC Current"
339343
"INA226","components/sensor/ina226","ina226.jpg","DC Current & Power"
340344
"INA228","components/sensor/ina2xx","ina228.jpg","DC Voltage & Current & Power & Charge"
@@ -380,6 +384,7 @@ Sensors are organized into categories; if a given sensor fits into more than one
380384
"EMC2101","components/emc2101","emc2101.jpg","Temperature",""
381385
"ENS160","components/sensor/ens160","ens160.jpg","eCO₂ & Air Quality",""
382386
"ENS210","components/sensor/ens210","ens210.jpg","Temperature & Humidity",""
387+
"HC8","components/sensor/hc8","hc8.png","CO₂",""
383388
"HDC1080","components/sensor/hdc1080","hdc1080.jpg","Temperature & Humidity",""
384389
"HDC2010","components/sensor/hdc2010","hdc2010.png","Temperature & Humidity",""
385390
"HHCCJCY10 (MiFlora Pink)","components/sensor/xiaomi_hhccjcy10","xiaomi_hhccjcy10.jpg","Soil moisture & Temperature & Light",""
@@ -416,6 +421,7 @@ Sensors are organized into categories; if a given sensor fits into more than one
416421
"SHTCx","components/sensor/shtcx","shtc3.jpg","Temperature & Humidity",""
417422
"SMT100","components/sensor/smt100","smt100.jpg","Moisture & Temperature",""
418423
"STS3X","components/sensor/sts3x","sts3x.jpg","Temperature",""
424+
"STTS22H","components/sensor/stts22h","stts22h.jpg","Temperature",""
419425
"TC74","components/sensor/tc74","tc74.jpg","Temperature",""
420426
"TEE501","components/sensor/tee501","TEE501.png","Temperature",""
421427
"TE-M3200","components/sensor/tem3200","tem3200.jpg","Temperature & Pressure",""
@@ -999,6 +1005,7 @@ at the {{< docref "light/fastled" "FastLED Light" >}}.
9991005

10001006
{{< imgtable >}}
10011007
"Time Core","components/time/index","clock-outline.svg","dark-invert"
1008+
"BM8563 RTC","components/time/bm8563","bm8563.svg",""
10021009
"DS1307 RTC","components/time/ds1307","clock-outline.svg","dark-invert"
10031010
"RX8130 RTC","components/time/rx8130","clock-outline.svg","dark-invert"
10041011
"GPS Time","components/time/gps","crosshairs-gps.svg","dark-invert"
@@ -1037,6 +1044,7 @@ Used for creating infrared (IR) or radio frequency (RF) remote control transmitt
10371044
ESPHome to cellular networks. **Does not encompass Wi-Fi.**
10381045

10391046
{{< imgtable >}}
1047+
"CC1101","components/cc1101","cc1101.webp",""
10401048
"IR Remote Climate","components/climate/climate_ir","air-conditioner-ir.svg","dark-invert"
10411049
"Remote Receiver","components/remote_receiver","remote.svg","dark-invert"
10421050
"Remote Transmitter","components/remote_transmitter","remote.svg","dark-invert"

content/components/api.md

Lines changed: 179 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,12 @@ api:
5858
> The defaults are set to balance memory usage with allowing multiple simultaneous connections.
5959

6060
- **max_send_queue** (*Optional*, int): The maximum number of messages that can be queued for sending per connection before the connection is dropped. Must be between 1 and 64.
61-
Defaults to `5` for ESP8266/RP2040, `8` for ESP32/BK72xx/RTL87xx/LN882x, `16` for host platform. This prevents memory exhaustion when a client is slow or network-stalled.
61+
Defaults to:
62+
- `5` for ESP8266/RP2040,
63+
- `8` for ESP32/BK72xx/LN882x/nRF52/RTL87xx,
64+
- `16` for host platform.
65+
66+
This prevents memory exhaustion when a client is slow or network-stalled.
6267
Each queued message uses approximately 8-12 bytes of overhead plus the message size.
6368

6469
> [!NOTE]
@@ -385,25 +390,51 @@ api:
385390
- logger.log: "API client disconnected!"
386391
```
387392

393+
## Conditions
394+
388395
{{< anchor "api-connected_condition" >}}
389396

390-
## `api.connected` Condition
397+
### `api.connected` Condition
398+
399+
This [Condition](/automations/actions#all-conditions) checks if at least one client is connected to the ESPHome native API.
400+
401+
#### Configuration variables
402+
403+
- **state_subscription_only** (*Optional*, boolean): If enabled, only counts clients that have subscribed to entity state updates. This filters out logger-only connections (such as `esphome logs` command), which can cause false positives when waiting for Home Assistant. Defaults to `false`.
391404

392-
This [Condition](/automations/actions#all-conditions) checks if at least one client is connected to the ESPHome
393-
native API. Please note client not only includes Home Assistant, but also ESPHome's OTA log output
394-
if logs are shown remotely.
405+
**Check if any client is connected:**
395406

396407
```yaml
397408
on_...:
398409
if:
399410
condition:
400411
api.connected:
401412
then:
402-
- logger.log: API is connected!
413+
- logger.log: Client is connected to API!
403414
```
404415

405416
The lambda equivalent for this is `id(api_id).is_connected()`.
406417

418+
**Check if a client subscribed to entity states is connected (typically Home Assistant):**
419+
420+
```yaml
421+
on_boot:
422+
- wait_until:
423+
condition:
424+
api.connected:
425+
state_subscription_only: true
426+
- logger.log: Home Assistant is connected!
427+
- homeassistant.event:
428+
event: esphome.device_booted
429+
```
430+
431+
The lambda equivalent for this is `id(api_id).is_connected(true)`.
432+
433+
**Use Cases:**
434+
435+
- Use `state_subscription_only: false` (default) to detect any API connection
436+
- Use `state_subscription_only: true` when you need to ensure Home Assistant (or other connections that subscribe to states) is connected before sending events or calling services, preventing errors from logger-only connections
437+
407438
{{< anchor "api-device-actions" >}}
408439

409440
## User-defined Actions
@@ -412,6 +443,10 @@ It is also possible to get data from Home Assistant to ESPHome with user-defined
412443
When you declare actions in your ESPHome YAML file, they will automatically show up in
413444
Home Assistant and you can call them directly.
414445

446+
> [!NOTE]
447+
> User-defined actions can also send responses back to the calling client using the `api.respond` action.
448+
> See [Action Responses](#action-responses) for details.
449+
415450
```yaml
416451
# Example configuration entry
417452
api:
@@ -471,6 +506,144 @@ Each of these also exist in array form:
471506
- bool[]: An array of boolean values. C++ type: `std::vector<bool>`
472507
- ... - Same for other types.
473508

509+
### Action Responses
510+
511+
User-defined actions can send responses back to the calling client (such as Home Assistant). This enables
512+
bidirectional communication where actions can report success/error status or return structured JSON data.
513+
514+
#### Response Modes
515+
516+
The response behavior is controlled by the `supports_response` option, which can be set explicitly or
517+
auto-detected based on your action configuration:
518+
519+
- **none** (default): No response is sent. The action is "fire and forget".
520+
- **status**: Reports success/error status without data. Auto-detected when `api.respond` is used without `data:`.
521+
- **optional**: Returns JSON data when the client requests it. Auto-detected when `api.respond` is used with `data:`.
522+
- **only**: Always returns JSON data. Must be set explicitly. Use this for query-type actions.
523+
524+
#### Configuration variables
525+
526+
- **supports_response** (*Optional*, string): The response mode for this action. One of `none`, `status`,
527+
`optional`, or `only`. If not specified, the mode is auto-detected based on `api.respond` usage in the action.
528+
529+
#### Trigger variables
530+
531+
When `supports_response` is not `none`, the following variables are available in the action:
532+
533+
- **call_id** (`uint32_t`): A unique identifier for this action call. Used internally by `api.respond`.
534+
- **return_response** (`bool`): Only available in `optional` mode. Indicates whether the client requested
535+
a response. You don't typically need to check this - `api.respond` handles it automatically.
536+
537+
### `api.respond` Action
538+
539+
This action sends a response back to the client that called the user-defined action. It can report
540+
success/error status and optionally include JSON data.
541+
542+
#### Configuration variables
543+
544+
- **success** (*Optional*, boolean, [templatable](/automations/templates)): Whether the action succeeded.
545+
Defaults to `true`.
546+
- **error_message** (*Optional*, string, [templatable](/automations/templates)): An error message to include
547+
when `success` is `false`. Defaults to an empty string.
548+
- **data** (*Optional*, [lambda](/automations/templates#config-lambda)): A lambda that populates a JSON object
549+
with response data. The lambda receives a `root` variable of type [`JsonObject`](https://arduinojson.org/v7/api/jsonobject/)
550+
that you can populate with key-value pairs.
551+
552+
#### Status Response Example
553+
554+
Report success or error without returning data:
555+
556+
```yaml
557+
api:
558+
actions:
559+
- action: validate_input
560+
variables:
561+
value: int
562+
then:
563+
- if:
564+
condition:
565+
lambda: 'return value < 0;'
566+
then:
567+
- api.respond:
568+
success: false
569+
error_message: "Value must be positive"
570+
else:
571+
- api.respond:
572+
success: true
573+
```
574+
575+
#### Data Response Example
576+
577+
Return structured JSON data to the caller:
578+
579+
```yaml
580+
api:
581+
actions:
582+
- action: get_sensor_data
583+
variables:
584+
sensor_name: string
585+
then:
586+
- api.respond:
587+
data: !lambda |-
588+
root["sensor"] = sensor_name;
589+
root["value"] = id(my_sensor).state;
590+
root["unit"] = "°C";
591+
root["timestamp"] = id(homeassistant_time).now().timestamp;
592+
```
593+
594+
This action will be auto-detected as `optional` mode because it uses `api.respond` with `data:`.
595+
596+
#### Query Action Example
597+
598+
For actions that always return data (like queries), explicitly set `supports_response: only`:
599+
600+
```yaml
601+
api:
602+
actions:
603+
- action: get_device_info
604+
supports_response: only
605+
then:
606+
- api.respond:
607+
data: !lambda |-
608+
root["hostname"] = App.get_name();
609+
root["version"] = ESPHOME_VERSION;
610+
root["uptime"] = millis() / 1000;
611+
```
612+
613+
#### Nested JSON Data
614+
615+
You can create complex nested JSON structures:
616+
617+
```yaml
618+
api:
619+
actions:
620+
- action: get_full_status
621+
supports_response: only
622+
then:
623+
- api.respond:
624+
data: !lambda |-
625+
root["device"]["name"] = "living_room";
626+
root["device"]["version"] = 1;
627+
root["sensors"]["temperature"] = id(temp_sensor).state;
628+
root["sensors"]["humidity"] = id(humidity_sensor).state;
629+
```
630+
631+
#### Calling from Home Assistant
632+
633+
Actions with response support appear in Home Assistant with their response mode indicated. You can call
634+
them and receive the response data:
635+
636+
```yaml
637+
# Home Assistant automation example
638+
action: esphome.device_get_sensor_data
639+
data:
640+
sensor_name: "living_room"
641+
response_variable: sensor_response
642+
```
643+
644+
The response will be available in the `sensor_response` variable with the structure you defined in the
645+
`data:` lambda.
646+
474647
## Advantages over MQTT
475648

476649
The ESPHome native API has many advantages over using MQTT for communication with Home

content/components/canbus/esp32_can.md

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ params:
1010
{{< anchor "esp32-can" >}}
1111

1212
The ESP32 has an integrated CAN controller and therefore doesn't necessarily need an external controller.
13+
Some variants (ESP32-C5, ESP32-C6, ESP32-P4) have multiple CAN controllers - see [Multiple CAN Controllers](#multiple-can-controllers) below.
1314
You only need to specify the RX and TX pins. Any GPIO will work.
1415

1516
```yaml
@@ -39,28 +40,43 @@ canbus:
3940
4041
The following table lists the bit rates supported by the component for ESP32 variants:
4142
42-
| bit_rate | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
43-
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
44-
| 1KBPS | | x | x | x | x | x |
45-
| 5KBPS | | x | x | x | x | x |
46-
| 10KBPS | | x | x | x | x | x |
47-
| 12K5BPS | | x | x | x | x | x |
48-
| 16KBPS | | x | x | x | x | x |
49-
| 20KBPS | | x | x | x | x | x |
50-
| 25KBPS | x | x | x | x | x | x |
51-
| 31K25BPS | | | | | | |
52-
| 33KBPS | | | | | | |
53-
| 40KBPS | | | | | | |
54-
| 50KBPS | x | x | x | x | x | x |
55-
| 80KBPS | | | | | | |
56-
| 83K38BPS | | | | | | |
57-
| 95KBPS | | | | | | |
58-
| 100KBPS | x | x | x | x | x | x |
59-
| 125KBPS (Default) | x | x | x | x | x | x |
60-
| 250KBPS | x | x | x | x | x | x |
61-
| 500KBPS | x | x | x | x | x | x |
62-
| 800KBPS | x | x | x | x | x | x |
63-
| 1000KBPS | x | x | x | x | x | x |
43+
| bit_rate | ESP32 | Other variants* |
44+
| ----------------- | ----- | --------------- |
45+
| 1KBPS | | x |
46+
| 5KBPS | | x |
47+
| 10KBPS | | x |
48+
| 12K5BPS | | x |
49+
| 16KBPS | | x |
50+
| 20KBPS | | x |
51+
| 25KBPS | x | x |
52+
| 31K25BPS | | |
53+
| 33KBPS | | |
54+
| 40KBPS | | |
55+
| 50KBPS | x | x |
56+
| 80KBPS | | |
57+
| 83K3BPS | | |
58+
| 95KBPS | | |
59+
| 100KBPS | x | x |
60+
| 125KBPS (Default) | x | x |
61+
| 250KBPS | x | x |
62+
| 500KBPS | x | x |
63+
| 800KBPS | x | x |
64+
| 1000KBPS | x | x |
65+
66+
Other variants: ESP32-C3, ESP32-C5, ESP32-C6, ESP32-H2, ESP32-P4, ESP32-S2, ESP32-S3
67+
68+
> [!NOTE]
69+
> ESP32-C2 and ESP32-C61 do not have TWAI/CAN hardware and are not supported.
70+
71+
## Multiple CAN Controllers
72+
73+
Some ESP32 variants have multiple CAN (TWAI) controllers:
74+
75+
- **ESP32-C5**: 2 controllers
76+
- **ESP32-C6**: 2 controllers
77+
- **ESP32-P4**: 3 controllers
78+
79+
All other supported variants have a single controller. ESP32-C2 and ESP32-C61 do not have CAN hardware.
6480
6581
## Wiring options
6682

0 commit comments

Comments
 (0)