Compare commits

...

3111 Commits

Author SHA1 Message Date
J. Nick Koston
52c34441b1 Merge branch 'libretiny_regen_fixes' into integration 2026-01-13 09:50:52 -10:00
J. Nick Koston
ae2575b33f fix 2026-01-13 09:34:43 -10:00
J. Nick Koston
3d51413706 lets not miss it 2026-01-13 09:33:46 -10:00
J. Nick Koston
6fd6b46ef8 [libretiny] Regenerate boards, enable Cortex-M4 atomics, and consolidate platform code 2026-01-13 09:31:05 -10:00
J. Nick Koston
ec38ffc310 [libretiny] Regenerate boards, enable Cortex-M4 atomics, and consolidate platform code 2026-01-13 09:09:49 -10:00
J. Nick Koston
a45cbc6595 [libretiny] Regenerate boards, enable Cortex-M4 atomics, and consolidate platform code 2026-01-13 09:07:04 -10:00
J. Nick Koston
62bce73b7e Merge branch 'fix_callback_order_wifi_8266' into integration 2026-01-13 08:39:42 -10:00
J. Nick Koston
39f77a3315 [wifi] Fix ESP8266 disconnect callback order to set error flag before notifying listeners 2026-01-13 08:14:46 -10:00
J. Nick Koston
714188cfd8 [wifi] Fix ESP8266 disconnect callback order to set error flag before notifying listeners 2026-01-13 08:13:37 -10:00
J. Nick Koston
3d40979c96 [mqtt] Avoid intermediate string allocations in publish calls (#13174) 2026-01-13 08:05:04 -10:00
J. Nick Koston
7fed9144a6 [api] Use stack buffer for VERY_VERBOSE proto message dumps (#13176) 2026-01-13 08:04:48 -10:00
J. Nick Koston
7abb374f2a [improv_serial] Use stack buffers for webserver URL formatting (#13175) 2026-01-13 08:04:33 -10:00
Jonathan Swoboda
5d90f170e5 Merge branch 'release' into dev 2026-01-13 11:55:58 -05:00
Jonathan Swoboda
6e01c4f86e Merge pull request #13188 from esphome/bump-2025.12.6
2025.12.6
2026-01-13 11:55:44 -05:00
Jonathan Swoboda
f4c17e15ea Bump version to 2025.12.6 2026-01-13 11:01:21 -05:00
J. Nick Koston
d6507ce329 [esphome] Fix OTA backend abort not being called on error (#13182) 2026-01-13 11:01:21 -05:00
Jonathan Swoboda
9504e92458 [remote_transmitter] Fix ESP8266 timing by using busy loop (#13172)
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-13 11:01:21 -05:00
Jonathan Swoboda
3911991de2 [packet_transport] Fix packet size check to account for round4 padding (#13165)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 11:01:21 -05:00
Jonathan Swoboda
dede47477b [ltr_als_ps] Remove incorrect device_class from count sensors (#13167)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 11:01:21 -05:00
Jonathan Swoboda
dca8def0f2 [seeed_mr24hpc1] Add ifdef guards for conditional entity types (#13147)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 11:01:21 -05:00
Samuel Sieb
a1727a8901 [espnow] fix channel validation (#13057) 2026-01-13 11:01:20 -05:00
J. Nick Koston
d49f176f31 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-12 22:33:50 -10:00
Samuel Sieb
48f5296d24 [ld24xx] add id to support extending (#13183)
Co-authored-by: Samuel Sieb <samuel@sieb.net>
2026-01-12 22:32:20 -10:00
Samuel Sieb
1327776d5b [bme68x_bsec2] use EntityBase instead of Component for the id (#13185)
Co-authored-by: Samuel Sieb <samuel@sieb.net>
2026-01-12 22:32:11 -10:00
J. Nick Koston
d378b40235 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-12 21:54:44 -10:00
J. Nick Koston
df4a3e8915 [socket] Call lwip_read/lwip_write directly on ESP32 to reduce network I/O latency (#13179) 2026-01-13 01:47:11 -06:00
Keith Burzinski
6823e17b3b [ir_rf_proxy] New component (#12985)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-01-13 07:44:24 +00:00
J. Nick Koston
eb4d6ce29f Merge remote-tracking branch 'upstream/dev' into integration 2026-01-12 20:56:10 -10:00
J. Nick Koston
675103bed0 [esphome] Fix OTA backend abort not being called on error (#13182) 2026-01-12 20:55:40 -10:00
J. Nick Koston
6c043be4d3 [ci] Add format_hex_pretty to heap-allocating helper lint check (#13178) 2026-01-12 20:55:23 -10:00
J. Nick Koston
a95f2fb002 Merge remote-tracking branch 'origin/ota_fix_abort' into integration 2026-01-12 20:18:30 -10:00
J. Nick Koston
1a30851b0a [esphome] Fix OTA backend abort not being called on error 2026-01-12 20:17:38 -10:00
J. Nick Koston
a74cba61df Merge branch 'lwip_read_write' into integration 2026-01-12 20:04:18 -10:00
J. Nick Koston
47f32d60b5 [socket] Call lwip_read/lwip_write directly on ESP32 to reduce network I/O latency 2026-01-12 20:03:45 -10:00
J. Nick Koston
e5e977c054 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-12 17:41:28 -10:00
Rodrigo Martín
e9469cbe48 [mqtt] templatable state and command topics (#12441)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-01-12 17:40:27 -10:00
J. Nick Koston
5046ca164a fix packed buffer 2026-01-12 17:23:09 -10:00
J. Nick Koston
3a7cf3ac95 Merge branch 'improv_serial_webserver' into integration 2026-01-12 17:17:09 -10:00
J. Nick Koston
6e82606419 cleanup 2026-01-12 17:10:21 -10:00
J. Nick Koston
26ed3d24c1 Merge branch 'api_debug_logging' into integration 2026-01-12 17:07:10 -10:00
J. Nick Koston
b24a1a9e25 cleanup 2026-01-12 17:06:49 -10:00
J. Nick Koston
5e911e20bc tweaks 2026-01-12 17:00:26 -10:00
J. Nick Koston
3206c5664f Merge branch 'api_debug_logging' into integration 2026-01-12 16:55:03 -10:00
J. Nick Koston
b5f6a6e24d [api] Use stack buffer for VERY_VERBOSE proto message dumps 2026-01-12 16:51:52 -10:00
dependabot[bot]
5890cdf69a Bump github/codeql-action from 4.31.9 to 4.31.10 (#13173)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-12 16:31:51 -10:00
J. Nick Koston
e1a0398160 [improv_serial] Use stack buffers for webserver URL formatting 2026-01-12 16:27:38 -10:00
J. Nick Koston
9876788e65 Merge branch 'more_heap_cleanup' into integration 2026-01-12 15:52:46 -10:00
J. Nick Koston
4a03ff898f Merge remote-tracking branch 'upstream/dev' into integration 2026-01-12 15:52:36 -10:00
J. Nick Koston
410507d476 [mqtt] Avoid intermediate string allocations in publish calls 2026-01-12 15:46:16 -10:00
lullius
297f05d600 [tuya] add color_type_lowercase option (#13101)
Co-authored-by: lullius <>
2026-01-12 18:08:33 -05:00
Jonathan Swoboda
54fc10714d [remote_transmitter] Fix ESP8266 timing by using busy loop (#13172)
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-12 18:06:41 -05:00
J. Nick Koston
889886909b [core] Soft deprecate heap-allocating string helpers to prevent fragmentation patterns (#13156) 2026-01-12 12:48:54 -10:00
J. Nick Koston
655e2b43cb [infrared] Use set_data() for vector timings in control() (#13171) 2026-01-12 15:27:42 -06:00
J. Nick Koston
81e639a6ba [core] Migrate callers and soft deprecate get_mac_address()/get_mac_address_pretty() (#13157) 2026-01-12 19:35:49 +00:00
Jonathan Swoboda
f9ffd134df [packet_transport] Fix packet size check to account for round4 padding (#13165)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 14:10:15 -05:00
Jonathan Swoboda
c50bf45496 [ltr_als_ps] Remove incorrect device_class from count sensors (#13167)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 14:09:54 -05:00
J. Nick Koston
9f9341a700 [web_server] Fix select compilation error in v1 (#13169) 2026-01-12 18:42:10 +00:00
tomaszduda23
71d532a349 [nrf52,sdk] Add framework version support (#12489) 2026-01-12 13:31:09 -05:00
Jasper van der Neut - Stulen
61a89a97d7 [deep_sleep] Fix GPIO wakeup on ESP32-C3/C6 (#12803) 2026-01-12 13:03:13 -05:00
Jasper van der Neut - Stulen
0c3433d056 [deep_sleep] Fix GPIO wakeup comment (#12815) 2026-01-12 12:57:58 -05:00
mikaabra
7e1cda8f9f [esp32_can] Add listen-only mode to esp32_can component (#13084)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 12:50:59 -05:00
J. Nick Koston
7f0e4eaa84 [nfc] Use stack-based hex formatting in pn7150/pn7160 components (#13163) 2026-01-12 07:38:39 -10:00
J. Nick Koston
8cccfa5369 [mqtt][prometheus][graph] Migrate value_accuracy_to_string() to stack-based alternative (#13159)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-12 07:38:20 -10:00
J. Nick Koston
7ea6bcef88 [api] Use stack buffer for bytes field dumping in proto message logs (#13162) 2026-01-12 07:37:58 -10:00
tomaszduda23
353daa97d0 [nrf52,zigbee] Warning if spaces in description (#13114)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-01-12 14:45:15 +00:00
Jas Strong
6c68ebe86e [rd03d] Filter targets with sentinel speed values (#13146)
Co-authored-by: jas <jas@asspa.in>
2026-01-12 09:25:43 -05:00
J. Nick Koston
62565304e4 Merge branch 'nfc_hex' into integration 2026-01-12 00:33:54 -10:00
J. Nick Koston
51dfb3af5e [nfc] Use stack-based hex formatting in pn7150/pn7160 components 2026-01-12 00:23:09 -10:00
J. Nick Koston
40b278f485 [nfc] Use stack-based hex formatting in pn7150/pn7160 components 2026-01-12 00:21:40 -10:00
J. Nick Koston
ed34a98f48 Merge branch 'api_format_hex_pretty_to' into integration 2026-01-12 00:04:50 -10:00
J. Nick Koston
d7e7e7849f [api] Use stack buffer for bytes field dumping in proto message logs 2026-01-11 19:59:05 -10:00
dependabot[bot]
29cef3bc5d Bump aioesphomeapi from 43.12.0 to 43.13.0 (#13160)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-11 19:26:40 -10:00
Keith Burzinski
83eebdf15d [infrared] Implement experimental API/Core/component for new component/entity type (#13129)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-01-12 05:01:23 +00:00
J. Nick Koston
595217786c [tuya][rc522][remote_base] Migrate format_hex_pretty() to stack-based alternatives (#13158) 2026-01-12 04:47:57 +00:00
J. Nick Koston
f22e42addc Merge branch 'dep_heap_fragmenting_helpers' into integration 2026-01-11 18:28:51 -10:00
J. Nick Koston
f70cb78d52 fix 2026-01-11 18:28:37 -10:00
J. Nick Koston
25e9e84ca5 Merge branch 'dep_heap_fragmenting_helpers' into integration 2026-01-11 18:27:29 -10:00
J. Nick Koston
d807f93c66 cleanup 2026-01-11 18:27:05 -10:00
J. Nick Koston
7a33793304 Merge branch 'format_hex_to_more' into integration 2026-01-11 18:24:55 -10:00
J. Nick Koston
f4437c9eaa Merge branch 'value_accuracy_to_string_to' into integration 2026-01-11 18:24:50 -10:00
J. Nick Koston
d52ea47552 [mqtt][prometheus][graph] Migrate value_accuracy_to_string() to stack-based alternative 2026-01-11 17:54:48 -10:00
J. Nick Koston
912f94d1e8 [api] Use StringRef for HomeassistantServiceMap.value to eliminate heap allocations (#13154)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-11 17:54:06 -10:00
J. Nick Koston
ea8ae2ae60 [climate] Return StringRef from get_custom_fan_mode() and get_custom_preset() (#13103) 2026-01-11 17:53:06 -10:00
J. Nick Koston
e1aac7601d [event] Return StringRef from get_last_event_type() (#13104) 2026-01-11 17:52:54 -10:00
J. Nick Koston
f1b11b1855 [light] Return StringRef from LightEffect::get_name() and LightState::get_effect_name() (#13105) 2026-01-11 17:52:39 -10:00
J. Nick Koston
6e6d545963 [tuya][rc522][remote_base] Migrate format_hex_pretty() to stack-based alternatives 2026-01-11 17:44:43 -10:00
J. Nick Koston
23f9f70b71 [select] Return StringRef from current_option() (#13095) 2026-01-11 17:40:43 -10:00
J. Nick Koston
eeeae53f76 [fan] Return StringRef from get_preset_mode() for safety and modern API (#13092) 2026-01-11 17:40:09 -10:00
J. Nick Koston
a29ad99661 Merge branch 'mac_address_stack' into integration 2026-01-11 17:35:18 -10:00
J. Nick Koston
c8fabf214e Merge branch 'dep_heap_fragmenting_helpers' into integration 2026-01-11 17:35:09 -10:00
J. Nick Koston
291db7c5a9 [core] Migrate callers and deprecate get_mac_address()/get_mac_address_pretty() 2026-01-11 17:34:03 -10:00
J. Nick Koston
cea8c9b212 [core] Deprecate heap-allocating string helpers to prevent fragmentation patterns 2026-01-11 17:26:42 -10:00
J. Nick Koston
45c0796e40 [ci] Add RP2040 to memory impact analysis (#13134) 2026-01-11 17:19:00 -10:00
J. Nick Koston
38e2e4a56d [runtime_stats] Fix log output formatting alignment (#13155) 2026-01-11 17:18:49 -10:00
J. Nick Koston
52132ea3bc [ch422g][lc709203f][qmc5883l] Avoid heap allocation in status_set_warning calls (#13152) 2026-01-11 17:18:37 -10:00
J. Nick Koston
ace3ff2170 [safe_mode] Conditionally compile callback when on_safe_mode is configured (#13136) 2026-01-11 17:18:24 -10:00
J. Nick Koston
26e90b4ca6 [light] Move LightColorValues::lerp() out of header to reduce code duplication (#13138) 2026-01-11 17:18:13 -10:00
J. Nick Koston
684790c2ab [web_server_idf] Reduce heap usage in DefaultHeaders and auth (#13141) 2026-01-11 17:17:57 -10:00
J. Nick Koston
6a3737bac3 [improv_serial] Use int8_to_str to avoid heap allocation for RSSI formatting (#13149) 2026-01-11 17:17:44 -10:00
J. Nick Koston
723ca57617 [uptime] Format text sensor output on stack to avoid heap allocations (#13150)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-11 17:17:32 -10:00
J. Nick Koston
909bd1074a [wifi] Fix captive portal/improv only attempting last configured network (#13086)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-11 17:17:18 -10:00
J. Nick Koston
68064dc974 [web_server] Fix v1 compilation on ESP-IDF by adding missing write method (#13153) 2026-01-11 17:17:07 -10:00
Jonathan Swoboda
742d724e65 [seeed_mr24hpc1] Add ifdef guards for conditional entity types (#13147)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 22:16:55 -05:00
J. Nick Koston
69dd056516 Merge branch 'complete_removal_no_zero_copy' into integration 2026-01-11 16:12:57 -10:00
J. Nick Koston
024097b635 cleanup 2026-01-11 16:05:33 -10:00
J. Nick Koston
0d30c2cdfd drop no zero copy 2026-01-11 16:03:26 -10:00
J. Nick Koston
2c0954c03c [api] Use StringRef for HomeassistantServiceMap.value to eliminate heap allocations 2026-01-11 16:00:44 -10:00
J. Nick Koston
f6eebe9b27 Merge branch 'web_server_1' into integration 2026-01-11 15:40:15 -10:00
J. Nick Koston
78edba8db5 [web_server] Fix v1 compilation on ESP-IDF by adding missing write method 2026-01-11 15:39:09 -10:00
J. Nick Koston
1cf3a2bc47 [web_server] Fix v1 compilation on ESP-IDF by adding missing write method 2026-01-11 15:37:22 -10:00
J. Nick Koston
3bd5dc7a8e Merge branch 'status_set_warning_str_print' into integration 2026-01-11 15:10:12 -10:00
J. Nick Koston
3e2f12d5d6 [ch422g][lc709203f][qmc5883l] Avoid heap allocation in status_set_warning calls 2026-01-11 15:09:30 -10:00
J. Nick Koston
ce79556cbd Merge remote-tracking branch 'origin/uptime_sensor_text' into integration 2026-01-11 14:52:53 -10:00
J. Nick Koston
a36b3fc81b Merge remote-tracking branch 'origin/improv_serial_format' into integration 2026-01-11 14:52:48 -10:00
J. Nick Koston
cdd09bdb94 preen 2026-01-11 14:46:14 -10:00
J. Nick Koston
c19e129821 another pass at reducing the logic 2026-01-11 14:40:50 -10:00
J. Nick Koston
f14d1edcc9 [uptime] Format text sensor output on stack to avoid heap allocations 2026-01-11 14:33:31 -10:00
J. Nick Koston
cda750e6b7 [improv_serial] Use int8_to_str to avoid heap allocation for RSSI formatting 2026-01-11 14:04:48 -10:00
dependabot[bot]
5ae46a4369 Bump aioesphomeapi from 43.11.0 to 43.12.0 (#13139)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-11 09:49:17 -10:00
J. Nick Koston
7666644ad8 Merge branch 'web_server_idf_cleanup_strings' into integration 2026-01-11 09:01:16 -10:00
J. Nick Koston
d7dd6a5cb8 static, less heap 2026-01-11 09:00:20 -10:00
J. Nick Koston
1fa86a7505 tweak comment 2026-01-11 08:46:02 -10:00
J. Nick Koston
c6bb62cc36 tweak comment 2026-01-11 08:45:54 -10:00
J. Nick Koston
0e6a798b2f Merge branch 'web_server_idf_cleanup_strings' into integration 2026-01-11 08:42:02 -10:00
J. Nick Koston
cd37e3c1f6 [web_server_idf] Reduce string allocations in HTTP header storage and auth 2026-01-11 08:39:11 -10:00
J. Nick Koston
5ca7b885e8 Merge branch 'light_color_values' into integration 2026-01-11 01:18:54 -10:00
J. Nick Koston
bc91fbec83 [light] Move LightColorValues::lerp() out of header to reduce code duplication 2026-01-11 01:03:08 -10:00
J. Nick Koston
31c63ef2b4 Merge branch 'safe_mode_ifdef' into integration 2026-01-10 21:06:01 -10:00
J. Nick Koston
ce336b7745 [safe_mode] Conditionally compile callback when on_safe_mode is configured 2026-01-10 20:35:11 -10:00
J. Nick Koston
a30d12fb89 [safe_mode] Conditionally compile callback when on_safe_mode is configured 2026-01-10 20:34:05 -10:00
J. Nick Koston
b480b8f572 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-10 17:09:03 -10:00
J. Nick Koston
a1395af763 [helpers] Add format_hex_prefixed_to for "0x" prefixed hex formatting (#13115) 2026-01-10 17:07:21 -10:00
J. Nick Koston
6222fae907 [libretiny] Disable BLE stack on BK7231N to save ~21KB RAM (#13131) 2026-01-10 16:43:15 -10:00
J. Nick Koston
e34532f283 [sensor] Use C++17 nested namespace syntax (#13116) 2026-01-10 21:42:35 -05:00
Keith Burzinski
f2eb61a767 [api] Proto code generator changes for #12985 (#13100)
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-01-10 15:43:27 -10:00
dependabot[bot]
5725a4840e Bump aioesphomeapi from 43.10.1 to 43.11.0 (#13132)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-11 01:09:25 +00:00
J. Nick Koston
de82f96ccb [core] Rename FixedVector::shrink_to_fit() to release() for clarity (#13130) 2026-01-11 00:43:31 +00:00
J. Nick Koston
a295a552f9 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-10 13:06:24 -10:00
Jonathan Swoboda
6c981d8b71 [esp32_hosted] Bump component versions (#13118)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 10:26:42 -10:00
Jas Strong
c03faf2d9a [aqi] Fix precision loss for low PM concentration values (#13120)
Co-authored-by: jas <jas@asspa.in>
2026-01-10 09:40:14 -10:00
J. Nick Koston
dff01ab8f3 Merge branch 'sensor_ns' into integration 2026-01-09 23:14:36 -10:00
J. Nick Koston
3392216b0b [sensor] Use C++17 nested namespace syntax 2026-01-09 23:12:27 -10:00
J. Nick Koston
523e27e103 Merge branch 'fan_get_preset_mode_safer' into integration 2026-01-09 22:01:43 -10:00
J. Nick Koston
4289ba23f2 Merge branch 'light_std_string' into integration 2026-01-09 22:01:32 -10:00
J. Nick Koston
90e6ff2922 Merge branch 'select_current_option' into integration 2026-01-09 22:01:17 -10:00
J. Nick Koston
c20d20bf73 Merge branch 'climate_string_view' into integration 2026-01-09 22:01:10 -10:00
J. Nick Koston
6a280f8e2b Merge branch 'event_string_view' into integration 2026-01-09 22:01:04 -10:00
J. Nick Koston
3fd31581d6 cleanup 2026-01-09 21:59:19 -10:00
J. Nick Koston
3178ae32dd missed some 2026-01-09 21:56:14 -10:00
J. Nick Koston
3b5b9445fe Merge remote-tracking branch 'origin/integration' into integration 2026-01-09 17:05:11 -10:00
J. Nick Koston
db7bba744d Merge remote-tracking branch 'upstream/dev' into integration 2026-01-09 17:05:03 -10:00
J. Nick Koston
54668648df fix 2026-01-09 16:56:02 -10:00
J. Nick Koston
54d3ea4098 fix: use simple .c_str() for ESP8266 compatibility 2026-01-09 16:54:21 -10:00
J. Nick Koston
08bd49c038 fix 2026-01-09 16:50:42 -10:00
J. Nick Koston
a3a4c12f3e try 2026-01-09 16:47:40 -10:00
J. Nick Koston
2eb98c19f7 strinferf 2026-01-09 16:43:28 -10:00
J. Nick Koston
fef7b6093d Merge branch 'dev' into event_string_view 2026-01-09 16:40:12 -10:00
J. Nick Koston
74f2619097 Merge branch 'dev' into select_current_option 2026-01-09 16:39:43 -10:00
J. Nick Koston
1593b6f10d Merge branch 'dev' into climate_string_view 2026-01-09 16:39:08 -10:00
J. Nick Koston
0aab72a462 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-09 16:38:32 -10:00
esphomebot
da7680f7d9 Update webserver local assets to 20260110-013228 (#13113)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2026-01-09 16:38:01 -10:00
J. Nick Koston
2034e7d39c Merge remote-tracking branch 'origin/climate_string_view' into climate_string_view 2026-01-09 16:36:59 -10:00
J. Nick Koston
f01aeded4d tests update 2026-01-09 16:36:17 -10:00
J. Nick Koston
cacbb017c0 fix 2026-01-09 16:35:04 -10:00
J. Nick Koston
682b2104f2 tweak comments 2026-01-09 16:31:01 -10:00
J. Nick Koston
7bc970809a tweak comments 2026-01-09 16:29:38 -10:00
J. Nick Koston
3dbca6692e stringref 2026-01-09 16:28:21 -10:00
J. Nick Koston
48906aaa51 Merge remote-tracking branch 'origin/dev' into integration 2026-01-09 16:21:50 -10:00
J. Nick Koston
7a64d834d1 Merge remote-tracking branch 'origin/light_std_string' into light_std_string 2026-01-09 16:19:56 -10:00
J. Nick Koston
dc49f4c180 fix 2026-01-09 16:19:43 -10:00
J. Nick Koston
15734c63a1 back to print 2026-01-09 16:18:35 -10:00
J. Nick Koston
33d2140f1c stringref 2026-01-09 16:13:17 -10:00
J. Nick Koston
606ce9cfd2 stringref 2026-01-09 16:12:12 -10:00
J. Nick Koston
aa760446af Merge branch 'dev' into select_current_option 2026-01-09 16:07:32 -10:00
J. Nick Koston
60a06a5aac Merge branch 'dev' into light_std_string 2026-01-09 16:01:07 -10:00
J. Nick Koston
c8f86f0a94 stringref 2026-01-09 15:57:20 -10:00
J. Nick Koston
ca31c975be stringref 2026-01-09 15:57:06 -10:00
J. Nick Koston
ec03a0155b stringref 2026-01-09 15:52:11 -10:00
J. Nick Koston
5f6cfb4feb Merge remote-tracking branch 'origin/fan_get_preset_mode_safer' into fan_get_preset_mode_safer 2026-01-09 15:40:31 -10:00
J. Nick Koston
1fdacd9d22 use stringref 2026-01-09 15:40:18 -10:00
J. Nick Koston
ab3ab6f521 Merge remote-tracking branch 'upstream/dev' into fan_get_preset_mode_safer 2026-01-09 15:36:04 -10:00
J. Nick Koston
9ef492e95a Merge branch 'dev' into fan_get_preset_mode_safer 2026-01-09 15:35:19 -10:00
Douwe
cea2878b55 [water_heater] (3/4) Implement web_server for new water_heater component (#12511)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-01-09 15:25:42 -10:00
J. Nick Koston
a5b906516d Merge branch 'dev' into light_std_string 2026-01-09 14:03:26 -10:00
J. Nick Koston
2e6b22aa62 Merge remote-tracking branch 'origin/light_std_string' into light_std_string 2026-01-09 14:02:57 -10:00
J. Nick Koston
66d978ade1 comment 2026-01-09 14:02:37 -10:00
Jonathan Swoboda
e0ff7fdaa1 [esp32_hosted] Add HTTP-based coprocessor firmware update support (#13090)
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-09 17:36:56 -05:00
tomaszduda23
3c9b300c46 [CI] skip endpoint check due to test grouping (#13111) 2026-01-09 22:13:37 +00:00
J. Nick Koston
9bcdcedd94 Merge branch 'dev' into light_std_string 2026-01-09 09:48:20 -10:00
J. Nick Koston
ed07c7c7ee cleanups 2026-01-09 09:47:43 -10:00
J. Nick Koston
32f90b2855 [mdns] Remove deprecated api password from test configuration (#13107) 2026-01-09 09:40:24 -10:00
J. Nick Koston
2fb7c0d453 [mapping] Fix test SPI data rate for RP2040 (#13108) 2026-01-09 09:39:53 -10:00
dependabot[bot]
7935fba4b1 Bump esphome-dashboard from 20251013.0 to 20260110.0 (#13109)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-09 14:37:53 -05:00
Stuart Parmenter
ab32b93928 [hub75] Fix gamma_correct to use enum value instead of key string (#13102)
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-09 13:34:04 -06:00
J. Nick Koston
999d2d7f7e [light] Return std::string_view from LightEffect::get_name() and LightState::get_effect_name() 2026-01-09 09:11:58 -10:00
J. Nick Koston
a693e631bb [light] Return std::string_view from LightEffect::get_name() and LightState::get_effect_name() 2026-01-09 08:38:08 -10:00
J. Nick Koston
775c6a077d [light] Return std::string_view from LightEffect::get_name() and LightState::get_effect_name() 2026-01-09 08:35:37 -10:00
J. Nick Koston
8a3e26e6e9 [event] Return std::string_view from get_last_event_type() 2026-01-09 08:07:57 -10:00
J. Nick Koston
56ced4a403 [climate] Return std::string_view from get_custom_fan_mode() and get_custom_preset() 2026-01-09 07:47:42 -10:00
J. Nick Koston
265bc55c28 [climate] Return std::string_view from get_custom_fan_mode() and get_custom_preset() 2026-01-09 07:43:52 -10:00
J. Nick Koston
6dcbc24864 [climate] Return std::string_view from get_custom_fan_mode() and get_custom_preset() 2026-01-09 07:43:01 -10:00
J. Nick Koston
3d54ccac65 Revert "[wifi] Disable SoftAP support on Arduino ESP32 when ap: not configured" (#13099) 2026-01-09 09:35:19 -05:00
Keith Burzinski
c40f44f4bd [remote_base] Add zero-copy packed sint32 decoder for #12985 (#13093) 2026-01-09 04:06:03 -06:00
Keith Burzinski
62cb08c3dc [api] Add methods supporting efficient packed repeated sint32 field encoding for #12985 (#13094) 2026-01-09 04:05:47 -06:00
J. Nick Koston
26671cb1ee [select] Return std::string_view from current_option() 2026-01-08 23:05:30 -10:00
J. Nick Koston
6596186240 actually commit thte tests 2026-01-08 23:00:34 -10:00
J. Nick Koston
e8465bfcda [select] Return std::string_view from current_option() 2026-01-08 22:58:49 -10:00
J. Nick Koston
b9b3adae0d Merge branch 'dev' into fan_get_preset_mode_safer 2026-01-08 22:26:49 -10:00
J. Nick Koston
872b2ec7db address copilot review comments 2026-01-08 22:25:16 -10:00
J. Nick Koston
a3553dab1c address copilot review comments 2026-01-08 22:24:38 -10:00
J. Nick Koston
cd76747b25 tests 2026-01-08 22:19:52 -10:00
J. Nick Koston
0ebe99ccf5 tests 2026-01-08 22:00:04 -10:00
J. Nick Koston
04eba0563a tests 2026-01-08 21:58:20 -10:00
Stuart Parmenter
7576e032f8 [hub75] Fix depth and gamma mode defines (#13091) 2026-01-09 01:56:51 -06:00
J. Nick Koston
1e30f54dff cleanup 2026-01-08 21:49:59 -10:00
J. Nick Koston
6c502d879b cleanup 2026-01-08 21:49:15 -10:00
J. Nick Koston
04ffa74643 if we are going ot break it, string view 2026-01-08 21:44:40 -10:00
J. Nick Koston
ff0b1a24c7 [fan] Make get_preset_mode() return empty string instead of nullptr for safety 2026-01-08 21:35:18 -10:00
J. Nick Koston
b24dbf77e4 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-08 21:01:17 -10:00
J. Nick Koston
cd43b4114e [api] Fire on_client_disconnected trigger after removing client from list (#13088) 2026-01-08 20:36:24 -10:00
J. Nick Koston
2c165e4817 [web_server] Use centralized length constants for buffer sizing (#13073) 2026-01-08 20:36:08 -10:00
J. Nick Koston
5afe4b7b12 [wifi] Warn when AP is configured without captive_portal or web_server (#13087) 2026-01-08 16:41:34 -10:00
Anton Viktorov
dcb8c994cc [ac_dimmer] Added support for ESP-IDF (5+) (#7072)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-08 15:24:01 -10:00
J. Nick Koston
7f5887581d Merge branch 'ap_misconfigured_warn' into integration 2026-01-08 14:55:32 -10:00
J. Nick Koston
12be08f85e [wifi] Warn when AP is configured without captive_portal or web_server 2026-01-08 14:54:41 -10:00
J. Nick Koston
8c6a3f8d62 Merge branch 'blind_retry' into integration 2026-01-08 14:27:48 -10:00
J. Nick Koston
23eec55ed3 [wifi] Fix captive portal/improv only attempting last configured network 2026-01-08 14:26:24 -10:00
J. Nick Koston
cb383c8049 [wifi] Fix captive portal/improv only attempting last configured network 2026-01-08 14:23:44 -10:00
J. Nick Koston
ca45c0de66 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-08 12:16:22 -10:00
Rodrigo Martín
012a1e2afd [mqtt] Include session_present and reason parameters in connection callbacks (#12413)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-01-08 22:05:53 +00:00
J. Nick Koston
d4969f581a [wifi] Limit ignored disconnect events on LibreTiny to speed up AP failover (#13070) 2026-01-08 11:42:30 -10:00
J. Nick Koston
40f108116b [mqtt] Reduce heap allocations in topic string building (#13072) 2026-01-08 11:42:18 -10:00
J. Nick Koston
52459d1bc7 [wifi] Fix infinite roaming when best-signal AP is crashed/broken (#13071) 2026-01-08 11:42:06 -10:00
dependabot[bot]
325c938074 Bump ruff from 0.14.10 to 0.14.11 (#13082)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-01-08 20:57:30 +00:00
J. Nick Koston
423a617b15 [core] Improve minimum_chip_revision warning for PSRAM users (#13074) 2026-01-08 10:52:27 -10:00
J. Nick Koston
eb5c4f34e2 [wifi] Disable SoftAP support on Arduino ESP32 when ap: not configured (#13076) 2026-01-08 10:51:58 -10:00
J. Nick Koston
c9ab4ca018 [libretiny] Bump to 1.9.2 (#13077) 2026-01-08 10:51:35 -10:00
J. Nick Koston
da0b01f4d0 [logger] Enable loop disable optimization for LibreTiny task log buffer (#13078) 2026-01-08 10:51:18 -10:00
J. Nick Koston
7ff590e1da Merge branch 'disable_loop_when_buffer_empty_' into integration 2026-01-07 23:35:13 -10:00
J. Nick Koston
d402b0c391 [logger] Enable loop disable optimization for LibreTiny task log buffer 2026-01-07 23:34:39 -10:00
J. Nick Koston
ebd484495e Merge branch 'bump_libretiny_192' into integration 2026-01-07 23:07:52 -10:00
J. Nick Koston
36e748609e [libretiny] Bump to 1.9.2 2026-01-07 23:01:00 -10:00
J. Nick Koston
57152edf23 Merge branch 'wifi_ard_esp32' into integration 2026-01-07 22:50:06 -10:00
J. Nick Koston
1c3f421746 [wifi] Disable SoftAP support on Arduino ESP32 when ap: not configured 2026-01-07 22:42:49 -10:00
J. Nick Koston
182063d5c6 Merge remote-tracking branch 'origin/reuse_constexpr_web_server' into integration 2026-01-07 22:06:54 -10:00
J. Nick Koston
f8f6ad942b Merge branch 'min_chip_psram' into integration 2026-01-07 22:06:40 -10:00
J. Nick Koston
fd1ad89a33 [core] Improve minimum_chip_revision warning for PSRAM users 2026-01-07 22:05:40 -10:00
J. Nick Koston
735aca89ee [web_server] Use centralized length constants for buffer sizing 2026-01-07 20:03:18 -10:00
J. Nick Koston
aa3bed7089 [web_server] Use centralized length constants for buffer sizing 2026-01-07 20:01:54 -10:00
J. Nick Koston
40cd6aa18b [web_server] Use centralized length constants for buffer sizing 2026-01-07 20:01:23 -10:00
J. Nick Koston
b8da3b3265 [web_server] Use centralized length constants for buffer sizing 2026-01-07 20:00:40 -10:00
J. Nick Koston
9a3d1f5acc [web_server] Use centralized length constants for buffer sizing 2026-01-07 19:59:45 -10:00
J. Nick Koston
ec5290ef80 [web_server] Use centralized length constants for buffer sizing 2026-01-07 19:58:30 -10:00
J. Nick Koston
197cf6f445 [web_server] Use centralized length constants for buffer sizing 2026-01-07 19:56:16 -10:00
J. Nick Koston
8b46610281 tweaks 2026-01-07 19:39:11 -10:00
J. Nick Koston
3234f44660 Address Copilot review comments 2026-01-07 19:32:30 -10:00
J. Nick Koston
b5b78a674e [mqtt] Reduce heap allocations in topic string building 2026-01-07 18:42:58 -10:00
Keith Burzinski
e301b8d0e0 [thermostat] Allow heat_cool_mode without an automation (#13069)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2026-01-07 21:44:10 -06:00
J. Nick Koston
3a2f2aa6a8 Merge branch 'wifi_roaming_prevent_ping_pong_broken_ap' into integration 2026-01-07 16:37:48 -10:00
J. Nick Koston
d46b0c4abb tweak 2026-01-07 16:37:09 -10:00
J. Nick Koston
329e800684 more logging 2026-01-07 16:36:45 -10:00
J. Nick Koston
8aa77f7888 Merge branch 'wifi_roaming_prevent_ping_pong_broken_ap' into integration 2026-01-07 16:30:34 -10:00
J. Nick Koston
79c1680b80 show attempts remaining in logging 2026-01-07 16:30:25 -10:00
J. Nick Koston
d2347e1302 Merge branch 'wifi_roaming_prevent_ping_pong_broken_ap' into integration 2026-01-07 16:28:35 -10:00
J. Nick Koston
de1c213537 handle scan error 2026-01-07 16:27:27 -10:00
J. Nick Koston
1fb2eaa905 fixes 2026-01-07 16:24:55 -10:00
J. Nick Koston
b919cc584c fixes 2026-01-07 16:24:46 -10:00
J. Nick Koston
142b1640b6 Merge branch 'wifi_roaming_prevent_ping_pong_broken_ap' into integration 2026-01-07 16:18:21 -10:00
J. Nick Koston
fb4d50150a [wifi] Fix infinite roaming when best-signal AP is crashed/broken 2026-01-07 16:16:47 -10:00
J. Nick Koston
d0843d504e [wifi] Fix infinite roaming when best-signal AP is crashed/broken 2026-01-07 16:15:38 -10:00
J. Nick Koston
77077b470a Merge branch 'libretiny_limit_wifi_retries' into integration 2026-01-07 15:40:11 -10:00
J. Nick Koston
22af0b9eec [wifi] Limit ignored disconnect events on LibreTiny to speed up AP failover 2026-01-07 15:38:54 -10:00
Clyde Stubbs
738678e87b [image] Add define and core data (#13058) 2026-01-08 11:20:37 +11:00
J. Nick Koston
761aa2eecf Merge remote-tracking branch 'upstream/dev' into integration 2026-01-07 13:44:27 -10:00
J. Nick Koston
0ce3ac438b [logger] Add thread-safe logging support for LibreTiny platform (#13062) 2026-01-07 13:40:15 -10:00
marcbodea
afa4fe9820 [esp32_touch] Disable hardware timeout to prevent continuous interrupts (#13059)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-01-07 18:37:47 -05:00
J. Nick Koston
cc08d17f85 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-07 11:52:17 -10:00
esphomebot
a66df9ab0f Update webserver local assets to 20260107-214817 (#13064)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-01-07 11:52:02 -10:00
J. Nick Koston
4ad721f632 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-07 11:51:46 -10:00
J. Nick Koston
1339f3e77e [web_server][captive_portal] Add Brotli compression (saves ~11KB flash when using local) (#12959) 2026-01-07 11:49:23 -10:00
J. Nick Koston
fb03947d28 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-07 11:39:50 -10:00
J. Nick Koston
e29523e248 [abbwelcome] Use stack-based formatting to eliminate heap allocations (#12799) 2026-01-07 10:31:19 -10:00
J. Nick Koston
44eac36e05 [debug] Use stack buffers with buf_append helper instead of std::string (#13020) 2026-01-07 10:19:10 -10:00
J. Nick Koston
050e9b0d4a [wifi] Add basic post-connect roaming support for stationary devices (#12809) 2026-01-07 08:30:23 -10:00
J. Nick Koston
25ac89e9b5 [logger] Add thread-safe logging for host platform (#13010) 2026-01-07 08:29:50 -10:00
J. Nick Koston
d86d1f9f52 [modbus_controller] Replace format_hex_pretty with stack-based format_hex_pretty_to (#12781) 2026-01-07 08:29:28 -10:00
J. Nick Koston
fd19280df9 [es8388] Use index-based select publish_state to avoid heap allocations (#13053) 2026-01-07 08:29:00 -10:00
J. Nick Koston
b7dbda497a [core] Improve log timestamp accuracy by batching serial reads (#12750) 2026-01-07 08:28:31 -10:00
J. Nick Koston
815543b77e [tuya] Avoid heap allocation in text sensor enum publish (#13056) 2026-01-07 08:28:14 -10:00
J. Nick Koston
0948e0359f [core] Add integer overload for fnv1a_hash_extend (#13054) 2026-01-07 08:27:58 -10:00
J. Nick Koston
2830c7dab8 [ld2410/ld2412/ld2450] Use index-based select publish_state to avoid heap allocations (#13051) 2026-01-07 08:27:39 -10:00
J. Nick Koston
a03c13f304 [esp32_hosted] Add SHA256 alignment for hardware DMA compatibility (#13050) 2026-01-07 08:26:49 -10:00
J. Nick Koston
ef64226ed0 [mqtt] Use ESPHOME_F() for JSON strings to reduce ESP8266 RAM usage (#13049) 2026-01-07 08:26:21 -10:00
J. Nick Koston
ed39a130a8 [http_request] Store JSON keys in flash for ESP8266 (#13048) 2026-01-07 08:26:04 -10:00
J. Nick Koston
21687a1f58 [sun_gtil2] Eliminate heap allocations in text sensor publishing (#13047)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-07 08:25:33 -10:00
J. Nick Koston
bf75f77eee [preferences] Fix preferences not syncing in safe mode due to component registration order (#13041) 2026-01-07 08:25:08 -10:00
J. Nick Koston
39526e5360 [analyze-memory] Add RAM symbol analysis by component (#13040) 2026-01-07 08:24:44 -10:00
J. Nick Koston
8e40a55d5d [ble_client] Eliminate heap allocations in text sensor (#13038) 2026-01-07 08:24:22 -10:00
J. Nick Koston
20927674da [sun] Eliminate heap allocation in text sensor (#13037) 2026-01-07 08:24:09 -10:00
J. Nick Koston
8464307a43 [api] Coalesce log packets to reduce buffer pressure and prevent dropped state updates (#13026) 2026-01-07 08:23:50 -10:00
J. Nick Koston
546cdbde0d [api] Simplify string handling by removing bifurcated client/server storage (#12822) 2026-01-07 08:23:28 -10:00
tomaszduda23
ada4e6d5e9 [nrf52, zigbee] Add sensor (#12187)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-01-07 08:20:01 -10:00
Keith Burzinski
d6554702d8 [zwave_proxy] Make send_frame safer, make set_home_id protected (#13055) 2026-01-07 08:54:08 +00:00
Samuel Sieb
b083c33857 [espnow] fix channel validation (#13057) 2026-01-07 00:41:24 -08:00
J. Nick Koston
30cf47f737 Merge branch 'fnv_extend' into integration 2026-01-06 22:19:21 -10:00
J. Nick Koston
d2fb4b1af7 [core] Add integer overloads for fnv1_hash_extend and fnv1a_hash_extend 2026-01-06 22:17:44 -10:00
J. Nick Koston
062bb66943 Merge branch 'es8388' into integration 2026-01-06 21:45:02 -10:00
J. Nick Koston
7a300b04f0 [es8388] Use index-based select publish_state to avoid heap allocations 2026-01-06 21:44:21 -10:00
Keith Burzinski
f8309b007c [zwave_proxy] Add logging if client sends zero-length message (#13052) 2026-01-07 01:41:33 -06:00
J. Nick Koston
112cf35960 Merge branch 'ld24xx_select_heap' into integration 2026-01-06 21:36:13 -10:00
J. Nick Koston
899f40a024 fix up 2026-01-06 21:31:08 -10:00
J. Nick Koston
b128f1fb76 Merge branch 'ld24xx_select_heap' into integration 2026-01-06 21:22:10 -10:00
J. Nick Koston
255aa14aff [ld2410/ld2412/ld2450] Use index-based select publish_state to avoid heap allocations 2026-01-06 21:20:48 -10:00
Clyde Stubbs
ac672e4b8f [esp32] Don't warn about no ota rollback if no ota at all (#13045) 2026-01-07 18:19:46 +11:00
J. Nick Koston
7c0562b134 Merge branch 'esp_hosted_dma' into integration 2026-01-06 20:57:52 -10:00
J. Nick Koston
cf2beb40af [esp32_hosted] Add SHA256 alignment for hardware DMA compatibility 2026-01-06 20:56:20 -10:00
J. Nick Koston
631089b852 Merge branch 'debug_cleanup' into integration 2026-01-06 20:38:28 -10:00
J. Nick Koston
d02830307f missed one 2026-01-06 20:36:57 -10:00
J. Nick Koston
cd3b9fa268 Merge branch 'update_esp8266' into integration 2026-01-06 20:20:30 -10:00
J. Nick Koston
99171afd01 Merge branch 'mqtt_json_flash' into integration 2026-01-06 20:20:25 -10:00
J. Nick Koston
8c549d1ef3 [mqtt] Use ESPHOME_F() for JSON strings to reduce ESP8266 RAM usage 2026-01-06 20:19:48 -10:00
J. Nick Koston
e4a92989b3 [http_request] Store JSON keys in flash for ESP8266 2026-01-06 20:13:54 -10:00
J. Nick Koston
813099ace6 Merge branch 'debug_cleanup' into integration 2026-01-06 19:48:06 -10:00
J. Nick Koston
18b0f0965f Merge branch 'no_heap_no_change_text' into integration 2026-01-06 19:47:57 -10:00
J. Nick Koston
d7f832c1cd Merge branch 'sun_gtil2_heap' into integration 2026-01-06 19:47:52 -10:00
J. Nick Koston
f512882a38 Merge branch 'dev' into debug_cleanup 2026-01-06 19:31:49 -10:00
J. Nick Koston
499dbd9e91 [sun_gtil2] Eliminate heap allocations in text sensor publishing 2026-01-06 19:29:00 -10:00
J. Nick Koston
c387c03944 [text_sensor][text] Avoid heap allocation when state unchanged (#13044) 2026-01-06 19:22:04 -10:00
J. Nick Koston
0acd78612f [text_sensor][text] Avoid heap allocation when state unchanged 2026-01-06 18:06:08 -10:00
J. Nick Koston
22dea00d1b Merge remote-tracking branch 'upstream/dev' into integration 2026-01-06 17:57:17 -10:00
J. Nick Koston
906fb3213f Merge branch 'sun_heap_churn' into integration 2026-01-06 17:57:02 -10:00
J. Nick Koston
fb47bfe92a [dsmr] Eliminate heap allocation when publishing telegram (#13032) 2026-01-06 17:54:20 -10:00
J. Nick Koston
5b9be7c169 [ci] Add lint check to prevent usage of deprecated CORE.using_esp_idf (#13029) 2026-01-06 17:54:04 -10:00
J. Nick Koston
6d1f6a1084 [wifi_info] Eliminate heap churn in text sensors (#13031) 2026-01-06 17:53:54 -10:00
J. Nick Koston
f9ed2aa17f [pylontech] Eliminate heap allocations in text sensors (#13033) 2026-01-06 17:53:42 -10:00
J. Nick Koston
35118da606 [ethernet_info] Eliminate heap allocations in text sensors (#13034) 2026-01-06 17:53:29 -10:00
J. Nick Koston
498477c5a2 [homeassistant] Eliminate heap allocation in text sensor state updates (#13035) 2026-01-06 17:53:14 -10:00
J. Nick Koston
3a84e4a0b4 [openthread_info] Eliminate heap allocations in text sensors (#13036) 2026-01-06 17:53:00 -10:00
J. Nick Koston
bb1dcca39d lower case - clang-tidy 2026-01-06 17:52:38 -10:00
J. Nick Koston
4391457a96 [sml] Eliminate heap allocations in text sensor (#13039) 2026-01-06 17:51:26 -10:00
Kyrill
68b4bc9d9e Map HEAT_COOL to MODE_AUTO in HeatpumpIR component (#12058)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-06 21:28:41 -06:00
J. Nick Koston
b052c9f562 [esp32_camera][uart] Add missing wake_loop_threadsafe() preprocessor guards (#13043) 2026-01-07 03:22:10 +00:00
J. Nick Koston
c73d88ce33 enforce buffer size safety at compile time 2026-01-06 16:36:36 -10:00
J. Nick Koston
04057a59c6 tests 2026-01-06 16:35:05 -10:00
J. Nick Koston
c9f4a0e010 enforce buffer size safety at compile time 2026-01-06 16:27:12 -10:00
J. Nick Koston
2a89488cb6 enforce buffer size safety at compile time 2026-01-06 16:24:55 -10:00
J. Nick Koston
58375a3f36 Merge branch 'dev' into sun_heap_churn 2026-01-06 16:18:47 -10:00
J. Nick Koston
a19597626b [text_sensor][text] Add const char* overloads to publish_state to eliminate heap churn (#13030) 2026-01-06 16:16:37 -10:00
J. Nick Koston
609cb8f0fe Merge branch 'flash_write_after_ota_broken_libretiny' into integration 2026-01-06 16:12:56 -10:00
J. Nick Koston
46a85203e0 fix 2026-01-06 16:09:26 -10:00
J. Nick Koston
bf8caeb0a8 Merge branch 'flash_write_after_ota_broken_libretiny' into integration 2026-01-06 14:53:54 -10:00
J. Nick Koston
f54505243c [safe_mode] Fix devices getting stuck in safe mode on LibreTiny 2026-01-06 14:49:06 -10:00
J. Nick Koston
3aa396ceb6 Merge remote-tracking branch 'origin/ram_symbols' into integration 2026-01-06 14:37:01 -10:00
J. Nick Koston
b341374a5d Merge branch 'sml_fix_heap_churn' into integration 2026-01-06 14:36:46 -10:00
J. Nick Koston
34819881c6 Merge branch 'ble_client_heap_churn' into integration 2026-01-06 14:36:40 -10:00
J. Nick Koston
d9c9d21750 [analyze-memory] Add RAM symbol analysis by component 2026-01-06 14:35:35 -10:00
J. Nick Koston
aba4645d81 remove useless 2026-01-06 14:27:07 -10:00
J. Nick Koston
04d498eb41 [sml] Eliminate heap allocations in text sensor 2026-01-06 14:25:33 -10:00
J. Nick Koston
b6058e837b Merge branch 'ble_client_heap_churn' into integration 2026-01-06 14:18:02 -10:00
J. Nick Koston
6b088eac16 [ble_client] Eliminate heap allocations in text sensor 2026-01-06 14:16:19 -10:00
J. Nick Koston
7ec6f6ba76 Merge branch 'sun_heap_churn' into integration 2026-01-06 14:10:35 -10:00
J. Nick Koston
34de46ecec [sun] Eliminate heap allocation in text sensor 2026-01-06 14:08:58 -10:00
J. Nick Koston
a51c1ec9f8 Merge branch 'openthread_heap_churn' into integration 2026-01-06 13:03:15 -10:00
J. Nick Koston
97591a8743 [openthread_info] Eliminate heap allocations in text sensors 2026-01-06 13:02:24 -10:00
J. Nick Koston
6fe0f29bac Merge branch 'homeassistant_text_churn' into integration 2026-01-06 12:51:17 -10:00
J. Nick Koston
6b1a36b416 [homeassistant] Eliminate heap allocation in text sensor state updates 2026-01-06 12:49:56 -10:00
J. Nick Koston
d85c0ff4d5 Merge branch 'ethernet_text_churn' into integration 2026-01-06 12:45:31 -10:00
J. Nick Koston
319be3498a [ethernet_info] Eliminate heap allocations in text sensors 2026-01-06 12:44:47 -10:00
J. Nick Koston
5c482f0809 Merge branch 'pylontech_no_heap' into integration 2026-01-06 12:41:12 -10:00
J. Nick Koston
bdbd275dcc Merge branch 'dsmr_no_heap' into integration 2026-01-06 12:41:07 -10:00
J. Nick Koston
776b6a6cac [pylontech] Eliminate heap allocations in text sensors 2026-01-06 12:40:10 -10:00
J. Nick Koston
559f534f13 [dsmr] Eliminate heap allocation when publishing telegram 2026-01-06 12:37:25 -10:00
J. Nick Koston
be77f57fc3 Merge branch 'text_no_string' into integration 2026-01-06 12:33:33 -10:00
J. Nick Koston
45b195aba5 [wifi_info] Eliminate heap churn in text sensors 2026-01-06 12:32:41 -10:00
J. Nick Koston
d07772671e Merge branch 'fix_text_heap_churn' into integration 2026-01-06 12:19:41 -10:00
J. Nick Koston
9ee5c1bb27 wip 2026-01-06 12:19:32 -10:00
J. Nick Koston
3d1589a278 Merge branch 'fix_text_heap_churn' into integration 2026-01-06 12:17:32 -10:00
J. Nick Koston
227787ab95 [text_sensor][text] Add const char* overloads to publish_state to eliminate heap churn 2026-01-06 12:16:49 -10:00
J. Nick Koston
7bd77eec31 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-06 11:52:26 -10:00
J. Nick Koston
2147ddf8c7 [api] Eliminate std::string from ClientInfo struct (#12566)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2026-01-06 21:32:23 +00:00
Jas Strong
412ab5dbbf [aqi] Implement a sensor that computes AQI (#12958)
Co-authored-by: jas <jas@asspa.in>
2026-01-06 16:31:50 -05:00
David Woodhouse
4419bf02b1 [async_tcp] Fix build conflicts and use IDF component for ESP32 (#13025)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-01-06 20:26:27 +00:00
J. Nick Koston
8eb28a7724 [neopixelbus] Fix ESP8266 compilation by enabling Serial/Serial1 for NeoPixelBus library (#13027) 2026-01-06 18:38:39 +00:00
J. Nick Koston
cf1444742b Merge branch 'log_coalesce' into integration 2026-01-06 08:30:57 -10:00
J. Nick Koston
195b606259 explain 2026-01-06 08:30:13 -10:00
J. Nick Koston
d6c2dd3c26 [wifi] Eliminate heap allocations in IP address logging (#13017) 2026-01-06 08:21:16 -10:00
J. Nick Koston
c4d3a56cc9 [api] Coalesce log packets to reduce buffer pressure and prevent dropped state updates 2026-01-06 08:13:35 -10:00
J. Nick Koston
ac42102320 [core] Auto-replace / in entity names with Unicode fraction slash during deprecation period (#13016) 2026-01-06 07:36:01 -10:00
J. Nick Koston
2c6584baf5 [xiaomi_ble] Simplify set_bindkey using parse_hex and const char* (#13014) 2026-01-06 07:35:40 -10:00
J. Nick Koston
c1ad39a072 [wifi] Clean up duplicate and empty logging output (#13018) 2026-01-06 07:35:16 -10:00
J. Nick Koston
d3e193cd71 [ota] Fix ESP32-S3 OTA crash with hardware SHA acceleration on IDF 5.5.x (#13021) 2026-01-06 07:34:58 -10:00
J. Nick Koston
11aed601b8 [ble_scanner] Use stack-based string formatting to reduce heap allocations (#13013) 2026-01-06 07:34:38 -10:00
J. Nick Koston
e0981323bd [mqtt] Move Home Assistant discovery keys to PROGMEM on ESP8266 (#13011) 2026-01-06 07:33:56 -10:00
J. Nick Koston
1e56325b33 [improv_base] Optimize next_url to avoid STL string operations (#13015) 2026-01-06 07:33:32 -10:00
J. Nick Koston
a8a26f4ea8 [opentherm][nau7802] Use direct format specifiers instead of to_string().c_str() (#13019) 2026-01-06 07:32:43 -10:00
Jonathan Swoboda
a94eef3a60 Merge branch 'release' into dev 2026-01-06 10:23:02 -05:00
Jonathan Swoboda
b6f3a5d8b7 Merge pull request #13024 from esphome/bump-2025.12.5
2025.12.5
2026-01-06 10:22:48 -05:00
Jonathan Swoboda
3322b04e00 Bump version to 2025.12.5 2026-01-06 09:35:38 -05:00
Jonathan Swoboda
47d0d3cfeb [cc1101] Add PLL lock verification and retry support (#13006) 2026-01-06 09:35:37 -05:00
Clyde Stubbs
8255c02d5d [esp32_ble] Remove requirement for configured network (#12891) 2026-01-06 09:35:37 -05:00
Conrad Juhl Andersen
8b4ba8dfe6 [wts01] Fix negative values for WTS01 sensor (#12835) 2026-01-06 09:35:37 -05:00
Artur
178a61b6fd [sn74hc595]: fix 'Attempted read from write-only channel' when using esp-idf framework (#12801) 2026-01-06 09:35:37 -05:00
Clyde Stubbs
b5df4cdf1d [lvgl] Fix arc background angles (#12773) 2026-01-06 09:35:37 -05:00
Jonathan Swoboda
484f4b3aad [cc1101] Add PLL lock verification and retry support (#13006) 2026-01-06 09:34:28 -05:00
J. Nick Koston
249d89cc5d Merge branch 'sha256_ota_fix' into integration 2026-01-06 00:51:09 -10:00
J. Nick Koston
ffb15b592c cleanup 2026-01-06 00:50:43 -10:00
J. Nick Koston
b40de61224 cleanup 2026-01-06 00:48:40 -10:00
J. Nick Koston
3e6d777439 fix 2026-01-06 00:46:15 -10:00
J. Nick Koston
f5ae09056c cleanup 2026-01-06 00:34:36 -10:00
J. Nick Koston
72892b8913 fix 2026-01-06 00:31:40 -10:00
J. Nick Koston
84e382387d [ota] Fix ESP32-S3 OTA crash with hardware SHA acceleration on IDF 5.5.x 2026-01-06 00:09:14 -10:00
J. Nick Koston
4e80a89f61 tidy 2026-01-05 23:44:22 -10:00
J. Nick Koston
b19918cdbf [debug] Use stack buffers with buf_append helper instead of std::string 2026-01-05 23:38:06 -10:00
J. Nick Koston
2288f8eb5e [debug] Use stack buffers with buf_append helper instead of std::string 2026-01-05 23:35:24 -10:00
J. Nick Koston
9420ae7795 [debug] Use stack buffers with buf_append helper instead of std::string 2026-01-05 23:32:36 -10:00
J. Nick Koston
5e573ee116 [debug] Use stack buffers with buf_append helper instead of std::string 2026-01-05 23:28:17 -10:00
J. Nick Koston
8046dc5ea5 Merge branch 'drop_to_string' into integration 2026-01-05 22:51:25 -10:00
J. Nick Koston
efbd14c15c [opentherm][nau7802] Use direct format specifiers instead of to_string().c_str() 2026-01-05 22:50:51 -10:00
J. Nick Koston
d51ee3d004 Merge branch 'wifi_logging_cleanup' into integration 2026-01-05 22:35:53 -10:00
J. Nick Koston
570ecd1842 tweak 2026-01-05 22:35:40 -10:00
J. Nick Koston
3502ac7bee tweak 2026-01-05 22:33:14 -10:00
J. Nick Koston
04cc713b0c Merge branch 'wifi_logging_cleanup' into integration 2026-01-05 22:29:04 -10:00
J. Nick Koston
63713cac57 [wifi] Clean up duplicate and empty logging output 2026-01-05 22:26:36 -10:00
J. Nick Koston
44ecdeb3b6 Merge branch 'wifi_fix_more_alloc' into integration 2026-01-05 19:35:52 -10:00
J. Nick Koston
913609d985 simplify code 2026-01-05 19:32:47 -10:00
J. Nick Koston
a7b4ae13a3 simplify code 2026-01-05 19:32:11 -10:00
J. Nick Koston
a02583028e Merge branch 'wifi_fix_more_alloc' into integration 2026-01-05 19:24:19 -10:00
J. Nick Koston
43e0f1fb35 [wifi] Eliminate heap allocations in IP address logging 2026-01-05 19:23:46 -10:00
J. Nick Koston
b8faecfd4e Merge branch 'slash_workaround' into integration 2026-01-05 18:49:34 -10:00
J. Nick Koston
4b4c1c1191 [core] Auto-replace / in entity names with Unicode fraction slash during deprecation period 2026-01-05 18:46:54 -10:00
J. Nick Koston
4a499054b7 Merge branch 'bind_key_simplify' into integration 2026-01-05 18:25:01 -10:00
J. Nick Koston
2d65717e43 Merge remote-tracking branch 'origin/improv_next_url' into integration 2026-01-05 18:24:55 -10:00
J. Nick Koston
d8731d376d fixes 2026-01-05 18:23:43 -10:00
J. Nick Koston
d42567c5b0 [improv_base] Optimize next_url to avoid STL string operations 2026-01-05 18:20:23 -10:00
J. Nick Koston
b5ea8a4627 [xiaomi_ble] Simplify set_bindkey using parse_hex and const char* 2026-01-05 18:17:58 -10:00
J. Nick Koston
bc54c5aff3 Merge branch 'ble_scanner_reduce_realloc' into integration 2026-01-05 18:02:40 -10:00
J. Nick Koston
442cd60341 [ble_scanner] Use stack-based string formatting to reduce heap allocations 2026-01-05 17:55:41 -10:00
J. Nick Koston
0a9287df33 Merge remote-tracking branch 'upstream/dev' into integration
# Conflicts:
#	esphome/components/bedjet/bedjet_hub.cpp
#	esphome/components/esp8266/preferences.cpp
#	esphome/components/radon_eye_ble/radon_eye_listener.cpp
#	esphome/components/radon_eye_rd200/radon_eye_rd200.cpp
2026-01-05 17:48:09 -10:00
J. Nick Koston
22cb0da903 [radon_eye_rd200, radon_eye_ble] Use stack-based string formatting in logging (#12991) 2026-01-05 17:45:51 -10:00
Jas Strong
28cf3b7a9b [rd03d] Add Ai-Thinker RD-03D mmWave radar component (#12764)
Co-authored-by: jas <jas@asspa.in>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-01-05 22:35:32 -05:00
J. Nick Koston
84dd17187d [pvvx_mithermometer] Reduce heap allocations with stack-based string formatting (#12994) 2026-01-05 17:35:22 -10:00
J. Nick Koston
110c892c3c [esp8266] Avoid heap allocation in preferences save/load (#12465)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-05 17:35:04 -10:00
J. Nick Koston
8518424a88 [esp8266] Add enable_serial/enable_serial1 helpers to exclude unused Serial objects (#12736) 2026-01-05 17:26:49 -10:00
J. Nick Koston
7ba4dc0f1a [airthings_wave_base, airthings_ble] Use stack-based string formatting in logging (#12989) 2026-01-05 17:22:27 -10:00
J. Nick Koston
95573bc106 [mopeka] Reduce heap allocations with stack-based string formatting (#12990) 2026-01-05 17:21:54 -10:00
J. Nick Koston
a6adc29b14 [xiaomi_ble] Reduce heap allocations with stack-based string formatting (#12992) 2026-01-05 17:20:51 -10:00
J. Nick Koston
8251513556 [bedjet] Use stack-based UUID formatting in logging (#12993) 2026-01-05 17:19:34 -10:00
J. Nick Koston
e6e0be3345 [bthome_mithermometer] Reduce heap allocations with stack-based string formatting (#12995) 2026-01-05 17:18:58 -10:00
J. Nick Koston
64da6d46e9 [ruuvi_ble] Reduce heap allocation with stack-based string formatting (#12997) 2026-01-05 17:18:06 -10:00
J. Nick Koston
9b9a341db0 [b_parasite] Reduce heap allocation with stack-based string formatting (#12998) 2026-01-05 17:17:37 -10:00
J. Nick Koston
18217fbe10 [atc_mithermometer] Reduce heap allocations with stack-based string formatting (#12996) 2026-01-05 17:16:47 -10:00
J. Nick Koston
c3e6a4178c [thermopro_ble] Reduce heap allocation with stack-based string formatting (#12999) 2026-01-05 17:16:14 -10:00
J. Nick Koston
2d4cd4ce7e [midea] Reduce heap allocations with stack-based string formatting (#13000) 2026-01-05 17:15:50 -10:00
J. Nick Koston
0290ed5d23 [voice_assistant] Reduce heap allocation with stack-based timer formatting (#13001) 2026-01-05 17:14:33 -10:00
Evaldas Auryla
b402e403a0 [radon_eye_rd200] update Radon Eye RD200 with v2/v3 support (#7962)
Co-authored-by: Artem Butusov <art.sormy@gmail.com>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-01-05 16:34:23 -10:00
J. Nick Koston
b34260d5c8 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-05 16:21:07 -10:00
J. Nick Koston
4a97bd4859 Merge branch 'host_logger_thread_safe' into integration 2026-01-05 15:26:26 -10:00
J. Nick Koston
0453c74133 Address Copilot review: fix pthread_setname_np for Linux, simplify loop() condition 2026-01-05 15:14:24 -10:00
J. Nick Koston
a6a7b41b2e Merge remote-tracking branch 'origin/host_logger_thread_safe' into host_logger_thread_safe 2026-01-05 15:11:27 -10:00
J. Nick Koston
327458169c bot nits 2026-01-05 15:11:01 -10:00
Jonathan Swoboda
b2c22a02b1 [cc1101] Add freq_offset to on_packet trigger (#13008) 2026-01-05 20:08:07 -05:00
J. Nick Koston
f237d96121 Merge branch 'dev' into host_logger_thread_safe 2026-01-05 14:59:34 -10:00
J. Nick Koston
21b0955d4f [logger] Add thread-safe logging for host platform 2026-01-05 14:58:29 -10:00
J. Nick Koston
d3a128803c add diagram 2026-01-05 14:55:48 -10:00
J. Nick Koston
813012a65d remove dead code 2026-01-05 14:53:42 -10:00
J. Nick Koston
993070156a host has plenty of ram, do not give a knob, its not needed 2026-01-05 14:50:55 -10:00
J. Nick Koston
4a3e3a3b37 host has plenty of ram, do not give a knob, its not needed 2026-01-05 14:50:46 -10:00
J. Nick Koston
602bde0e5d reduce ram 2026-01-05 14:49:24 -10:00
J. Nick Koston
4c0e45ea5d wip 2026-01-05 14:43:48 -10:00
J. Nick Koston
707337d27a tweak 2026-01-05 14:33:40 -10:00
J. Nick Koston
6ea3dd8975 tweak 2026-01-05 14:33:00 -10:00
J. Nick Koston
c64514acdc tweak 2026-01-05 14:31:38 -10:00
J. Nick Koston
0d2c48a55a tweak 2026-01-05 14:29:52 -10:00
J. Nick Koston
b2f1f0faad tweak 2026-01-05 14:26:55 -10:00
J. Nick Koston
f0775d7ae0 host logger thread safe 2026-01-05 14:21:36 -10:00
PolarGoose
7ed4922d28 [dsmr] Remove dependency on Arduino framework. Various bug fixes. Add missing sensors. (#11036)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-01-06 00:18:54 +00:00
Clyde Stubbs
21aa245cff [image] Replace use of cairosvg with resvg-py (#12863)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-06 10:56:59 +11:00
David Woodhouse
94bedd83be async_tcp: Add AsyncClient for ESP-IDF and host (#12337)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-05 23:37:38 +00:00
guillempages
c8f5a97cef [esphome OTA] Allow compilation on host platform (#11655)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-01-05 23:33:06 +00:00
J. Nick Koston
90597a1255 Merge branch 'esp8266_prefs_avoid_heap' into integration 2026-01-05 09:34:27 -10:00
J. Nick Koston
3fed238f79 Merge branch 'voice_assistant_format_stack' into integration 2026-01-05 09:28:10 -10:00
J. Nick Koston
cc8bd2d29d dry 2026-01-05 09:26:41 -10:00
J. Nick Koston
7a0d7c5ca1 [voice_assistant] Reduce heap allocation with stack-based timer formatting 2026-01-05 09:24:33 -10:00
J. Nick Koston
bc7b2d317c Merge branch 'midea_stack_format' into integration 2026-01-05 09:21:12 -10:00
J. Nick Koston
334b7168bd [midea] Reduce heap allocations with stack-based string formatting 2026-01-05 09:20:45 -10:00
J. Nick Koston
8aaa51e5c7 Merge branch 'thermopro_ble' into integration 2026-01-05 09:16:35 -10:00
J. Nick Koston
d9568251dc [thermopro_ble] Reduce heap allocation with stack-based string formatting 2026-01-05 09:16:04 -10:00
J. Nick Koston
652660ca57 Merge branch 'b_parasite' into integration 2026-01-05 09:14:55 -10:00
J. Nick Koston
6b9f105b0b [b_parasite] Reduce heap allocation with stack-based string formatting 2026-01-05 09:14:26 -10:00
J. Nick Koston
8751e00077 Merge branch 'ruuvi_ble' into integration 2026-01-05 09:13:04 -10:00
J. Nick Koston
647c727708 [ruuvi_ble] Reduce heap allocation with stack-based string formatting 2026-01-05 09:12:36 -10:00
J. Nick Koston
b376b78625 Merge branch 'atc_mithermometer' into integration 2026-01-05 09:10:41 -10:00
J. Nick Koston
fdb4d411ce [atc_mithermometer] Reduce heap allocations with stack-based string formatting 2026-01-05 09:09:11 -10:00
J. Nick Koston
a762590b35 Merge branch 'bthome_mithermometer_logging' into integration 2026-01-05 09:06:33 -10:00
J. Nick Koston
6f1185011f [bthome_mithermometer] Reduce heap allocations with stack-based string formatting 2026-01-05 09:04:12 -10:00
J. Nick Koston
8092215de1 [bthome_mithermometer] Reduce heap allocations with stack-based string formatting 2026-01-05 09:02:46 -10:00
J. Nick Koston
b4a1421c71 Merge branch 'pvvx_mithermometer_format' into integration 2026-01-05 08:58:43 -10:00
J. Nick Koston
fc9b0cd56c [pvvx_mithermometer] Reduce heap allocations with stack-based string formatting 2026-01-05 08:58:08 -10:00
J. Nick Koston
16c61afb15 Merge branch 'bedjet_logging' into integration 2026-01-05 08:55:52 -10:00
J. Nick Koston
754a34357d [bedjet] Use stack-based UUID formatting in logging 2026-01-05 08:55:14 -10:00
J. Nick Koston
dc7aeec9ee Merge branch 'xiaomi_heap_logging' into integration 2026-01-05 08:53:13 -10:00
J. Nick Koston
cc3e05dece Merge branch 'mopeka_stack_format' into integration 2026-01-05 08:53:08 -10:00
J. Nick Koston
92399e58fc Merge branch 'radon_eye_stack' into integration 2026-01-05 08:53:04 -10:00
J. Nick Koston
70792ac9c5 fix bug 2026-01-05 08:52:20 -10:00
J. Nick Koston
152a146946 reduce 2026-01-05 08:50:24 -10:00
J. Nick Koston
0184636cde [xiaomi_ble] Reduce heap allocations with stack-based string formatting 2026-01-05 08:48:29 -10:00
J. Nick Koston
215fa497d8 Merge branch 'radon_eye_stack' into integration 2026-01-05 08:38:11 -10:00
J. Nick Koston
6dbcb28012 [radon_eye_rd200, radon_eye_ble] Use stack-based string formatting in logging 2026-01-05 08:28:04 -10:00
J. Nick Koston
204a15d53f Merge branch 'airthings_stack_format_logs' into integration 2026-01-05 08:26:03 -10:00
J. Nick Koston
de060e3209 Merge branch 'mopeka_stack_format' into integration 2026-01-05 08:25:55 -10:00
J. Nick Koston
879c6b87bb [mopeka] Reduce heap allocations with stack-based string formatting 2026-01-05 08:25:16 -10:00
J. Nick Koston
bed16ee76a [airthings_wave_base, airthings_ble] Use stack-based string formatting in logging 2026-01-05 08:21:31 -10:00
J. Nick Koston
1be3cab71d Merge branch 'logger_esp8266' into integration 2026-01-05 08:15:34 -10:00
J. Nick Koston
4a31fd6a9c escape hatch 2026-01-05 08:10:13 -10:00
J. Nick Koston
6974e8b767 keep error log 2026-01-05 07:44:21 -10:00
J. Nick Koston
fc7e55bfdc [api] Avoid heap string copies in Home Assistant state subscription callbacks (#12506) 2026-01-05 07:42:18 -10:00
J. Nick Koston
54c9f0db42 Merge branch 'dev' into esp8266_prefs_avoid_heap 2026-01-05 07:41:25 -10:00
J. Nick Koston
6aaaae5d0e [ci] Add LibreTiny (BK72XX) to memory impact analysis (#12983)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-05 07:40:49 -10:00
J. Nick Koston
e87a3b3916 [light] Use zero-copy set_effect overload in JSON schema parsing (#12979) 2026-01-05 07:40:24 -10:00
J. Nick Koston
3fb5b28930 [captive_portal] Avoid defer overhead on ESP8266 when saving WiFi credentials (#12981) 2026-01-05 07:40:04 -10:00
J. Nick Koston
1bb4be435c [esp32_ble_tracker, ble_client] Reduce heap allocations with stack-based string formatting (#12982) 2026-01-05 07:39:37 -10:00
J. Nick Koston
0990a9c2b0 [esp32_ble] Avoid heap allocation in ESPBTUUID::from_raw for string literals (#12980) 2026-01-05 07:39:24 -10:00
Samuel Schultze
086eb4b930 [whirlpool] support for 14 byte whirlpool IR receiver messages (#12774)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-01-05 11:45:32 -05:00
J. Nick Koston
ed03b09b61 Merge remote-tracking branch 'upstream/avoid_heap_address_str' into integration 2026-01-04 19:30:02 -10:00
J. Nick Koston
f7109c6ced more 2026-01-04 19:28:10 -10:00
J. Nick Koston
d4e3396ce1 Merge remote-tracking branch 'upstream/avoid_heap_address_str' into integration 2026-01-04 19:20:31 -10:00
J. Nick Koston
dbfef45fbb [esp32_ble_tracker, ble_client] Reduce heap allocations with stack-based string formatting 2026-01-04 19:19:23 -10:00
J. Nick Koston
dc7b5a5498 Merge branch 'no_defer_cap_port_8266' into integration 2026-01-04 18:52:01 -10:00
J. Nick Koston
d46982a6af [captive_portal] Avoid defer overhead on ESP8266 when saving WiFi credentials 2026-01-04 18:51:13 -10:00
J. Nick Koston
454471d923 Merge remote-tracking branch 'origin/esp_btuid_from_raw_no_heap_alloc' into integration 2026-01-04 18:33:01 -10:00
J. Nick Koston
6dc8e8ce64 Revert "constexpr"
This reverts commit 5ed2043037.
2026-01-04 18:27:53 -10:00
J. Nick Koston
5ed2043037 constexpr 2026-01-04 18:21:06 -10:00
J. Nick Koston
bd8f9d5984 [esp32_ble] Avoid heap allocation in ESPBTUUID::from_raw for string literals 2026-01-04 18:14:55 -10:00
J. Nick Koston
851f3733db Merge branch 'avoid_forced_heap_alloc_light_json_schema' into integration 2026-01-04 18:06:14 -10:00
J. Nick Koston
690cf1aec9 [light] Use zero-copy set_effect overload in JSON schema parsing 2026-01-04 18:05:48 -10:00
J. Nick Koston
d107b37d3b [st7735] Combine log statements to reduce loop blocking (#12977) 2026-01-04 17:51:02 -10:00
J. Nick Koston
0aa8cfcff5 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-04 17:03:54 -10:00
J. Nick Koston
80ab9485e0 [spi_led_strip] Combine log statements to reduce loop blocking (#12968) 2026-01-04 17:00:59 -10:00
J. Nick Koston
28d30fdddb [ssd1306_i2c] Combine log statements to reduce loop blocking (#12969) 2026-01-04 17:00:40 -10:00
J. Nick Koston
0bd8a7e1a0 [ssd1306_spi] Combine log statements to reduce loop blocking (#12970) 2026-01-04 17:00:21 -10:00
J. Nick Koston
2381ea7ff5 [ssd1322_spi] Combine log statements to reduce loop blocking (#12971) 2026-01-04 17:00:09 -10:00
J. Nick Koston
06101c54a5 [ssd1327_spi] Combine log statements to reduce loop blocking (#12973) 2026-01-04 16:59:52 -10:00
J. Nick Koston
ed332a034b [ssd1351_spi] Combine log statements to reduce loop blocking (#12974) 2026-01-04 16:59:36 -10:00
J. Nick Koston
a2bb9468ff [sm2235] Combine log statements to reduce loop blocking (#12964)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-01-05 02:57:43 +00:00
J. Nick Koston
d8387799d9 [sm2335] Combine log statements to reduce loop blocking (#12965) 2026-01-04 16:56:30 -10:00
J. Nick Koston
ae3cdeda99 [ssd1325_spi] Combine log statements to reduce loop blocking (#12972) 2026-01-04 16:55:55 -10:00
J. Nick Koston
9cd003034c [spi_device] Combine log statements to reduce loop blocking (#12967) 2026-01-04 16:55:31 -10:00
J. Nick Koston
f67a8d0d1f [sonoff_d1] Combine log statements to reduce loop blocking (#12966) 2026-01-04 16:55:11 -10:00
J. Nick Koston
47223965b6 [sm2135] Combine log statements to reduce loop blocking (#12963) 2026-01-04 16:54:17 -10:00
J. Nick Koston
9128fc3120 [sm16716] Combine log statements to reduce loop blocking (#12962) 2026-01-04 16:54:03 -10:00
J. Nick Koston
c742db48b8 [sim800l] Combine log statements to reduce loop blocking (#12961) 2026-01-04 16:52:57 -10:00
J. Nick Koston
4bc1a02fc2 [shtcx] Combine log statements to reduce loop blocking (#12960) 2026-01-04 16:52:03 -10:00
J. Nick Koston
1d0f36ba35 [st7789v] Combine log statements to reduce loop blocking (#12978) 2026-01-04 16:51:37 -10:00
J. Nick Koston
405b26426c [st7567_spi] Combine log statements to reduce loop blocking (#12976) 2026-01-04 16:51:24 -10:00
J. Nick Koston
2295f57dec [st7567_i2c] Combine log statements to reduce loop blocking (#12975) 2026-01-04 16:51:11 -10:00
J. Nick Koston
81a230284f Merge branch 'web_server_br' into integration 2026-01-04 16:28:36 -10:00
J. Nick Koston
a011d5ea96 [sht3xd] Combine log statements to reduce loop blocking (#12957) 2026-01-05 02:14:57 +00:00
tomaszduda23
12027569d3 [nrf52,zigbee] add support for binary_input (#11535)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-01-04 21:11:14 -05:00
J. Nick Koston
ab0e15e4bb [runtime_stats] Combine log statements to reduce loop blocking (#12954) 2026-01-04 16:10:51 -10:00
J. Nick Koston
9f7925c1d5 [safe_mode] Combine log statements to reduce loop blocking (#12955) 2026-01-04 16:10:19 -10:00
J. Nick Koston
7449421cea [shelly_dimmer] Combine log statements to reduce loop blocking (#12956) 2026-01-04 16:10:06 -10:00
J. Nick Koston
4f20c1ceb1 [rp2040_pwm] Combine log statements to reduce loop blocking (#12952) 2026-01-04 16:09:51 -10:00
J. Nick Koston
452fcd56dd [remote_receiver] Combine log statements to reduce loop blocking (#12951) 2026-01-04 16:08:45 -10:00
J. Nick Koston
44fc156ef6 [remote_base] Combine log statements to reduce loop blocking (#12950) 2026-01-04 16:07:50 -10:00
J. Nick Koston
3ec05a5a13 [radon_eye_rd200] Combine log statements to reduce loop blocking (#12949) 2026-01-04 16:06:55 -10:00
J. Nick Koston
e6a630ae64 [qmp6988] Combine log statements to reduce loop blocking (#12947) 2026-01-04 16:06:34 -10:00
J. Nick Koston
3c8fd5c5c0 [pulse_counter] Combine log statements to reduce loop blocking (#12946) 2026-01-04 16:05:05 -10:00
J. Nick Koston
a635c82830 [pid] Combine log statements to reduce loop blocking (#12942) 2026-01-04 16:04:50 -10:00
J. Nick Koston
b550e2f4f9 [web_server][captive_portal] Add Brotli compression (saves ~11KB flash) 2026-01-04 15:40:25 -10:00
J. Nick Koston
676517fff3 [web_server][captive_portal] Add Brotli compression (saves ~11KB flash) 2026-01-04 15:40:19 -10:00
J. Nick Koston
a16746d30a [web_server][captive_portal] Add Brotli compression (saves ~11KB flash) 2026-01-04 15:38:15 -10:00
J. Nick Koston
0b9fcf9ed3 [pn532] Combine log statements to reduce loop blocking (#12943) 2026-01-04 14:46:21 -10:00
J. Nick Koston
2d8abbb2ac [pn7150] Combine log statements to reduce loop blocking (#12944) 2026-01-04 14:46:09 -10:00
J. Nick Koston
6d8142c539 [rpi_dpi_rgb] Combine log statements to reduce loop blocking (#12953) 2026-01-04 14:45:52 -10:00
J. Nick Koston
50f27cdd77 [pn7160] Combine log statements to reduce loop blocking (#12945) 2026-01-04 14:45:38 -10:00
J. Nick Koston
6c809583d3 [qspi_dbi] Combine log statements to reduce loop blocking (#12948)
Co-authored-by: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-04 14:45:22 -10:00
J. Nick Koston
4e94d1ba58 Merge branch 'get_peername_stack_save_ram' into integration 2026-01-04 14:07:08 -10:00
J. Nick Koston
cd3f0e9fc4 Merge remote-tracking branch 'upstream/dev' into get_peername_stack_save_ram 2026-01-04 14:06:41 -10:00
J. Nick Koston
f41f0506c1 [pcf8574] Combine log statements to reduce loop blocking (#12941) 2026-01-04 14:05:17 -10:00
J. Nick Koston
850f189225 [api] Fix message batch size mismatch and improve naming consistency (#12940) 2026-01-04 23:44:49 +00:00
J. Nick Koston
a37d4b17eb [wifi] Combine log statements to reduce loop blocking (#12939) 2026-01-04 23:11:48 +00:00
J. Nick Koston
7309a65167 [tlc5971] Combine log statements to reduce loop blocking (#12922) 2026-01-04 13:11:08 -10:00
J. Nick Koston
6e391bb083 Merge branch 'get_peername_stack_save_ram' into integration 2026-01-04 13:07:32 -10:00
J. Nick Koston
8862fcac45 Merge remote-tracking branch 'upstream/dev' into get_peername_stack_save_ram
# Conflicts:
#	esphome/components/voice_assistant/voice_assistant.cpp
2026-01-04 13:05:42 -10:00
J. Nick Koston
7fde110ac5 [voice_assistant] Combine log statements to reduce loop blocking (#12930) 2026-01-04 13:04:22 -10:00
J. Nick Koston
9ed107bc33 [xgzp68xx] Combine log statements to reduce loop blocking (#12935) 2026-01-04 13:04:08 -10:00
J. Nick Koston
b291f359ae [x9c] Combine log statements to reduce loop blocking (#12934) 2026-01-04 13:03:56 -10:00
J. Nick Koston
161545584d [wl_134] Combine log statements to reduce loop blocking (#12933) 2026-01-04 13:03:42 -10:00
J. Nick Koston
3ea11d4e59 [xpt2046] Combine log statements to reduce loop blocking (#12937) 2026-01-04 13:03:22 -10:00
J. Nick Koston
5713d69efe [ufire_ec] Combine log statements to reduce loop blocking (#12925) 2026-01-04 13:03:06 -10:00
J. Nick Koston
9d9f9c3c84 [xiaomi_xmwsdj04mmc] Combine log statements to reduce loop blocking (#12936) 2026-01-04 13:02:52 -10:00
J. Nick Koston
29d332af92 [wireguard] Combine log statements to reduce loop blocking (#12932) 2026-01-04 13:02:02 -10:00
J. Nick Koston
c44d095f8a [usb_host] Combine log statements to reduce loop blocking (#12927) 2026-01-04 13:01:49 -10:00
J. Nick Koston
0b996616b8 [waveshare_epaper] Combine log statements to reduce loop blocking (#12931) 2026-01-04 13:01:33 -10:00
J. Nick Koston
557b6a9ef0 [sun] Combine log statements to reduce loop blocking (#12919) 2026-01-04 13:00:59 -10:00
J. Nick Koston
6e633f7f3b [usb_uart] Combine log statements to reduce loop blocking (#12928) 2026-01-04 13:00:03 -10:00
J. Nick Koston
c59455e445 [mqtt] Combine log statements to reduce loop blocking (#12938) 2026-01-04 12:59:47 -10:00
J. Nick Koston
32b3d27c7c [uln2003] Combine log statements to reduce loop blocking (#12926) 2026-01-04 12:58:42 -10:00
J. Nick Koston
88cb5d9671 [tmp1075] Combine log statements to reduce loop blocking (#12923) 2026-01-04 12:58:20 -10:00
J. Nick Koston
56d1d928f9 [tlc5947] Combine log statements to reduce loop blocking (#12921) 2026-01-04 12:57:10 -10:00
J. Nick Koston
e9cab96cb7 [sx1509] Combine log statements to reduce loop blocking (#12920) 2026-01-04 12:56:50 -10:00
J. Nick Koston
022c42f9ca [tuya] Combine log statements to reduce loop blocking (#12924) 2026-01-04 12:53:58 -10:00
J. Nick Koston
25ef9aff04 [vl53l0x] Combine log statements to reduce loop blocking (#12929) 2026-01-04 12:53:46 -10:00
J. Nick Koston
f4d2fa8da5 Merge branch 'align_max_messages' into integration 2026-01-04 12:47:06 -10:00
J. Nick Koston
1ef6c6a416 move const 2026-01-04 12:46:35 -10:00
J. Nick Koston
a1aaaedf3c Merge branch 'align_max_messages' into integration 2026-01-04 12:43:56 -10:00
J. Nick Koston
9297850afe [api] Fix message batch size mismatch and improve naming consistency 2026-01-04 12:41:01 -10:00
Clyde Stubbs
71940acc49 [esp32_ble] Remove requirement for configured network (#12891) 2026-01-04 22:37:44 +00:00
J. Nick Koston
4bffe5bd4a Merge remote-tracking branch 'upstream/dev' into integration 2026-01-04 11:56:33 -10:00
J. Nick Koston
05695affff [m5stack_8angle] Combine log statements to reduce loop blocking (#12908) 2026-01-04 11:55:31 -10:00
J. Nick Koston
f2308c77c6 [libretiny_pwm] Combine log statements to reduce loop blocking (#12907) 2026-01-04 11:55:18 -10:00
J. Nick Koston
a5368d1d95 [modbus] Combine log statements to reduce loop blocking (#12910) 2026-01-04 11:54:47 -10:00
J. Nick Koston
b8d93f2150 [mopeka_std_check] Combine log statements to reduce loop blocking (#12911) 2026-01-04 11:54:31 -10:00
J. Nick Koston
ca574a1550 [ledc] Combine log statements to reduce loop blocking (#12906) 2026-01-04 11:54:14 -10:00
J. Nick Koston
b0855b4a0e [lc709203f] Combine log statements to reduce loop blocking (#12905) 2026-01-04 11:53:50 -10:00
J. Nick Koston
1fccddf67f [ina2xx_base] Combine log statements to reduce loop blocking (#12904) 2026-01-04 11:52:56 -10:00
J. Nick Koston
548600b47a [ina260] Combine log statements to reduce loop blocking (#12903) 2026-01-04 11:52:34 -10:00
J. Nick Koston
9bbfad4a08 [honeywellabp] Combine log statements to reduce loop blocking (#12902) 2026-01-04 11:52:08 -10:00
J. Nick Koston
8ae1f26b6a [hlw8012] Combine log statements to reduce loop blocking (#12901) 2026-01-04 11:51:45 -10:00
J. Nick Koston
9b2a36a313 [hc8] Combine log statements to reduce loop blocking (#12900) 2026-01-04 11:51:33 -10:00
J. Nick Koston
aa4b274b3c [mcp3204] Combine log statements to reduce loop blocking (#12912) 2026-01-04 11:51:18 -10:00
J. Nick Koston
d1d5c942ec [mcp9600] Combine log statements to reduce loop blocking (#12913) 2026-01-04 11:51:01 -10:00
J. Nick Koston
a336cba035 Merge branch 'get_peername_stack_save_ram' into integration 2026-01-04 11:47:52 -10:00
J. Nick Koston
aa30a1d008 all 3 2026-01-04 11:47:34 -10:00
J. Nick Koston
591b5fa25b all 3 2026-01-04 11:45:27 -10:00
J. Nick Koston
96b59af983 all 3 2026-01-04 11:42:07 -10:00
J. Nick Koston
17250c7244 Merge remote-tracking branch 'upstream/get_peername_stack_save_ram' into integration 2026-01-04 11:28:41 -10:00
J. Nick Koston
ccc9d95c9d [mqtt] Combine log statements to reduce loop blocking (#12914) 2026-01-04 11:28:14 -10:00
J. Nick Koston
6d9d593e12 [my9231] Combine log statements to reduce loop blocking (#12915) 2026-01-04 11:27:14 -10:00
J. Nick Koston
fc9683f024 [opentherm] Combine log statements to reduce loop blocking (#12916) 2026-01-04 11:26:13 -10:00
J. Nick Koston
61ecfb5f2b [openthread] Combine log statements to reduce loop blocking (#12917) 2026-01-04 11:25:52 -10:00
J. Nick Koston
7e75826064 [wifi] Fix LibreTiny thread safety with queue-based event handling (#12833) 2026-01-04 11:25:24 -10:00
J. Nick Koston
8287484a36 [gl_r01_i2c] Combine log statements to reduce loop blocking (#12899) 2026-01-04 11:24:51 -10:00
J. Nick Koston
dd8259b2ce [gcja5] Combine log statements to reduce loop blocking (#12898) 2026-01-04 11:24:36 -10:00
J. Nick Koston
520f8eb9ef simplify 2026-01-04 11:18:44 -10:00
J. Nick Koston
2d0dd93ae8 Merge remote-tracking branch 'upstream/dev' into get_peername_stack_save_ram 2026-01-04 11:16:44 -10:00
J. Nick Koston
cb4a974144 simplify 2026-01-04 11:13:58 -10:00
J. Nick Koston
5143ef4f2d Merge remote-tracking branch 'upstream/dev' into integration 2026-01-04 10:56:13 -10:00
Stuart Parmenter
449e478bec [hub75] Bump esp-hub75 version to 0.2.2 (#12674) 2026-01-04 10:50:10 -10:00
Jonathan Swoboda
9ae19d53dc [ultrasonic] Fix timeout issues and deprecate timeout option (#12897)
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-04 13:39:56 -05:00
J. Nick Koston
77b3ffee00 [factory_reset] Combine log statements to reduce loop blocking (#12866) 2026-01-04 08:34:16 -10:00
J. Nick Koston
dff8dc0ed1 [cc1101] Combine log statements to reduce loop blocking (#12869) 2026-01-04 08:34:07 -10:00
J. Nick Koston
5a8b0f59b8 [cd74hc4067] Combine log statements to reduce loop blocking (#12870) 2026-01-04 08:33:58 -10:00
J. Nick Koston
25a325da61 [current_based] Combine log statements to reduce loop blocking (#12873) 2026-01-04 08:33:49 -10:00
J. Nick Koston
a6db5a2ed8 [dfrobot_sen0395] Combine log statements to reduce loop blocking (#12876) 2026-01-04 08:33:38 -10:00
J. Nick Koston
9e5dbb073a [emmeti] Combine log statements to reduce loop blocking (#12878) 2026-01-04 08:31:14 -10:00
J. Nick Koston
cf513975f3 [ens160_base] Combine log statements to reduce loop blocking (#12880) 2026-01-04 08:30:45 -10:00
J. Nick Koston
1e70091a27 [esp32_hosted] Combine log statements to reduce loop blocking (#12884) 2026-01-04 08:28:17 -10:00
J. Nick Koston
766826cc9c [esp32][libretiny] Reuse preference buffer to avoid heap churn (#12890) 2026-01-04 08:28:01 -10:00
J. Nick Koston
8a4ee19c0b [es8388] Combine log statements to reduce loop blocking (#12882) 2026-01-04 08:26:19 -10:00
J. Nick Koston
b1f9c08f51 [esp32_ble_tracker] Make start_scan action idempotent (#12864) 2026-01-04 08:11:36 -10:00
J. Nick Koston
d328ccd1da Merge branch 'get_peername_stack_save_ram' into integration 2026-01-03 22:11:28 -10:00
J. Nick Koston
d7006a839b Merge remote-tracking branch 'upstream/get_peername_stack_save_ram' into get_peername_stack_save_ram 2026-01-03 22:01:59 -10:00
J. Nick Koston
156ef8df64 reduce 2026-01-03 22:01:25 -10:00
J. Nick Koston
cd5c04bc1e Merge branch 'dev' into get_peername_stack_save_ram 2026-01-03 21:55:03 -10:00
J. Nick Koston
a4accc14c4 Merge branch 'prefs_no_churn_reuse' into integration 2026-01-03 21:21:03 -10:00
J. Nick Koston
9c37443757 guard 2026-01-03 21:20:16 -10:00
J. Nick Koston
8ac16bac7d Merge branch 'prefs_no_churn_reuse' into integration 2026-01-03 21:17:02 -10:00
J. Nick Koston
0f6b9818e4 [esp32][libretiny] Reuse preference buffer to avoid heap churn 2026-01-03 21:16:25 -10:00
J. Nick Koston
facf4777a4 [ezo_pmp] Combine log statements to reduce loop blocking (#12888) 2026-01-03 18:04:00 -10:00
J. Nick Koston
096de869b6 [esp32_ble_client] Combine log statements to reduce loop blocking (#12883) 2026-01-03 18:01:55 -10:00
J. Nick Koston
c59314ec09 [debug] Combine log statements to reduce loop blocking (#12875) 2026-01-03 18:01:28 -10:00
J. Nick Koston
e94158a12f [fan] Combine log statements to reduce loop blocking (#12889) 2026-01-03 18:00:52 -10:00
J. Nick Koston
cb598c43e8 [endstop] Combine log statements to reduce loop blocking (#12879) 2026-01-03 18:00:31 -10:00
J. Nick Koston
6e8817cbc4 [esp8266_pwm] Combine log statements to reduce loop blocking (#12885) 2026-01-03 18:00:11 -10:00
J. Nick Koston
9f06f046d6 [espnow] Combine log statements to reduce loop blocking (#12887) 2026-01-03 17:59:53 -10:00
J. Nick Koston
44fa6bae95 [dht] Combine log statements to reduce loop blocking (#12877) 2026-01-03 17:57:53 -10:00
J. Nick Koston
bc9093127e [cap1188] Combine log statements to reduce loop blocking (#12868) 2026-01-03 17:00:14 -10:00
J. Nick Koston
cf93b66306 [chsc6x] Combine log statements to reduce loop blocking (#12871) 2026-01-03 16:59:55 -10:00
J. Nick Koston
16ada4d477 [epaper_spi] Combine log statements to reduce loop blocking (#12881) 2026-01-04 02:48:39 +00:00
J. Nick Koston
c96d0015a0 [esp_ldo] Combine log statements to reduce loop blocking (#12886) 2026-01-04 02:48:04 +00:00
J. Nick Koston
12c6f5749e [cst816] Combine log statements to reduce loop blocking (#12872) 2026-01-04 02:46:29 +00:00
Douwe
5f1eacf4ec [water_heater] (4/4) Implement tests for new water_heater component (#12517)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-01-03 16:43:31 -10:00
J. Nick Koston
5d384c77c5 [esp32] Move heap functions to flash, saving ~6KB (#12862) 2026-01-03 16:00:50 -10:00
dependabot[bot]
32562ca991 Bump aioesphomeapi from 43.10.0 to 43.10.1 (#12865)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-04 01:59:03 +00:00
J. Nick Koston
6b4b1272db [binary_sensor] Combine log statements to reduce loop blocking (#12849) 2026-01-04 01:56:52 +00:00
J. Nick Koston
7b74f94360 [wifi] Combine log statements to reduce loop blocking (#12856)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-01-04 01:54:56 +00:00
J. Nick Koston
79de1bc609 Merge branch 'esp32_ble_automations' into integration 2026-01-03 15:54:36 -10:00
J. Nick Koston
93adab389e [esp32_ble_tracker] Make start_scan action idempotent 2026-01-03 15:54:15 -10:00
J. Nick Koston
997ab553c1 [ac_dimmer] Combine log statements to reduce loop blocking (#12840)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-01-04 01:36:08 +00:00
Frederic Meeuwissen
8b80fe9c6b [esp32_rmt_led_strip] Support inverted logic (#12825)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-03 20:32:27 -05:00
J. Nick Koston
ee65f2f0cd [adc] Combine log statements to reduce loop blocking (#12841) 2026-01-03 15:24:41 -10:00
J. Nick Koston
c2c7d4e89d Merge branch 'heap-in-iram-flash' into integration 2026-01-03 15:22:29 -10:00
J. Nick Koston
ba1bbaf67d [esp32] Move heap functions to flash, saving ~6KB
This is the culmination of months of work to reduce heap churn
throughout the ESPHome codebase. By systematically eliminating
unnecessary dynamic allocations (StaticVector, FixedVector, const
char* instead of std::string, pre-allocated buffers, etc.), heap
functions are now called so infrequently that they can safely be
moved from IRAM to flash.

Enable CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH by default, which moves
malloc/free/realloc from IRAM to flash. This is safe because:
- Heap functions should never be called from ISRs
- CONFIG_SPI_MASTER_ISR_IN_IRAM is not enabled
- Audio/video use pre-allocated ring buffers, not dynamic allocation

Measured results: +6,124 bytes of heap freed.

Add heap_in_iram advanced option as an escape hatch for users who
need heap functions in IRAM for specific use cases.
2026-01-03 15:10:32 -10:00
J. Nick Koston
723ccd7547 [ade7880] Combine log statements to reduce loop blocking (#12842) 2026-01-03 15:05:41 -10:00
J. Nick Koston
102862e99d [ads1115] Combine log statements to reduce loop blocking (#12843) 2026-01-03 15:05:29 -10:00
J. Nick Koston
9cb265347c [ads1118] Combine log statements to reduce loop blocking (#12844) 2026-01-03 15:05:15 -10:00
J. Nick Koston
d84562f878 [anova] Combine log statements to reduce loop blocking (#12845) 2026-01-03 15:04:57 -10:00
J. Nick Koston
6bbee3cfc6 [as3935] Combine log statements to reduce loop blocking (#12846) 2026-01-03 15:04:38 -10:00
J. Nick Koston
41e7ecb29f [bedjet] Combine log statements to reduce loop blocking (#12848) 2026-01-03 15:04:21 -10:00
J. Nick Koston
0196d6ee55 [ble_nus] Combine log statements to reduce loop blocking (#12850) 2026-01-03 15:03:44 -10:00
J. Nick Koston
ea848db683 [bp1658cj] Combine log statements to reduce loop blocking (#12851) 2026-01-03 15:03:20 -10:00
J. Nick Koston
41a188ac35 [ac_dimmer] Fix ESP8266 build by requiring waveform support (#12852) 2026-01-03 15:03:01 -10:00
J. Nick Koston
8ddfeb2d38 [captive_portal] Combine log statements to reduce loop blocking (#12853) 2026-01-03 15:02:26 -10:00
J. Nick Koston
d364432e3a [uart] Combine log statements to reduce loop blocking (#12855) 2026-01-03 15:02:12 -10:00
J. Nick Koston
2a6b192af8 [ethernet] Combine log statements to reduce loop blocking (#12854) 2026-01-03 15:01:35 -10:00
J. Nick Koston
07a581e13a [update] Combine log statements to reduce loop blocking (#12857) 2026-01-03 15:01:24 -10:00
J. Nick Koston
5f5edf90e9 [water_heater] Combine log statements to reduce loop blocking (#12858) 2026-01-03 15:01:12 -10:00
J. Nick Koston
5e24469ce3 [http_request] Combine log statements to reduce loop blocking (#12859) 2026-01-03 15:01:01 -10:00
J. Nick Koston
d7a1ac83ca [esp32_ble_tracker] Combine log statements to reduce loop blocking (#12860) 2026-01-03 15:00:51 -10:00
Douwe
f11abc7dbf [water_heater] (2/4) Implement template for new water_heater component (#12516)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-01-03 14:45:49 -10:00
J. Nick Koston
f98cc96a6f Merge branch 'combine-logs-captive_portal' into integration 2026-01-03 14:35:05 -10:00
J. Nick Koston
dff89193dd Merge branch 'combine-logs-uart' into integration 2026-01-03 14:35:01 -10:00
J. Nick Koston
b868d0f254 Merge branch 'combine-logs-ethernet' into integration 2026-01-03 14:34:54 -10:00
tomaszduda23
ec05692f0d [nrf52] add printk doc (#12839) 2026-01-04 00:12:31 +00:00
J. Nick Koston
2e2e54811a [absolute_humidity] Combine log statements to reduce loop blocking (#12838) 2026-01-03 17:52:23 -06:00
J. Nick Koston
6d7949c686 [uart] Combine log statements to reduce loop blocking 2026-01-03 13:26:17 -10:00
J. Nick Koston
f78cf6d6b3 [ethernet] Combine log statements to reduce loop blocking 2026-01-03 13:25:58 -10:00
J. Nick Koston
8f77e0712e [captive_portal] Combine log statements to reduce loop blocking 2026-01-03 13:25:38 -10:00
Clyde Stubbs
c29aa61e2a [image] Use alternative version of CairoSVG on Windows (#12811) 2026-01-04 10:08:47 +11:00
J. Nick Koston
cb3edfc654 [wifi] Use stack-based MAC formatting in ESP8266 and IDF event handlers (#12834) 2026-01-03 12:32:22 -10:00
J. Nick Koston
6685fa1da9 [core] Fix startup delay from setup timing logs when console connected (#12832) 2026-01-03 12:32:10 -10:00
J. Nick Koston
d505f0316b [wifi] Combine scan result log lines to reduce loop blocking with many matching APs (#12830) 2026-01-03 12:31:58 -10:00
J. Nick Koston
9781073f2a [espnow] Use stack-based MAC formatting and remove dead code (#12836) 2026-01-03 12:31:38 -10:00
John Hollowell
0a0501c140 Fix comment typos (#12828) 2026-01-03 17:11:48 -05:00
Jasper van der Neut - Stulen
a6e9aa7876 [mhz19] Refactor Actions to Parented (#12837) 2026-01-03 17:11:02 -05:00
Conrad Juhl Andersen
ede7391582 [wts01] Fix negative values for WTS01 sensor (#12835) 2026-01-03 17:06:33 -05:00
J. Nick Koston
1a86f7c67c Merge branch 'espnow_mac_format' into integration 2026-01-03 11:05:42 -10:00
J. Nick Koston
8a59e13bbc [espnow] Use stack-based MAC formatting and remove dead code 2026-01-03 11:05:20 -10:00
J. Nick Koston
7e31e9823b Merge branch 'wifi_esp8266_idf_format_mac_address_pretty' into integration 2026-01-03 10:59:49 -10:00
J. Nick Koston
becab116c7 [wifi] Use stack-based MAC formatting in ESP8266 and IDF event handlers 2026-01-03 10:59:27 -10:00
J. Nick Koston
28bad19900 Merge branch 'libretiny_thread_safe_wifi' into integration 2026-01-03 10:52:10 -10:00
J. Nick Koston
eada23d587 optimize away 2026-01-03 10:51:56 -10:00
Jasper van der Neut - Stulen
5cfcf8d104 [mhz19] Make detection range configurable (#12677)
Co-authored-by: Fabio Pugliese Ornellas <fabio.ornellas@gmail.com>
2026-01-03 15:51:48 -05:00
J. Nick Koston
a1e5d59161 Merge branch 'libretiny_thread_safe_wifi' into integration 2026-01-03 10:48:33 -10:00
J. Nick Koston
2074447120 tune 2026-01-03 10:48:24 -10:00
J. Nick Koston
f267eac729 Merge branch 'libretiny_thread_safe_wifi' into integration 2026-01-03 10:42:23 -10:00
J. Nick Koston
9187bf52e6 tweak 2026-01-03 10:42:06 -10:00
J. Nick Koston
a95dcad380 Merge branch 'libretiny_thread_safe_wifi' into integration 2026-01-03 10:23:37 -10:00
J. Nick Koston
f0a496b08d [wifi] Fix LibreTiny thread safety with queue-based event handling 2026-01-03 10:22:08 -10:00
J. Nick Koston
cc56702e79 Merge branch 'no_delay_startup_many_entities' into integration 2026-01-03 09:34:22 -10:00
J. Nick Koston
a8e8c9d8b5 [core] Fix startup delay from setup timing logs when console connected 2026-01-03 09:33:43 -10:00
J. Nick Koston
846d46cd72 Merge branch 'wifi_roam' into integration 2026-01-03 09:27:51 -10:00
J. Nick Koston
6dbd0de0b5 tweak 2026-01-03 09:19:31 -10:00
J. Nick Koston
c34665f650 [api] Fix KeyError when running logs after password removal (#12831) 2026-01-03 19:13:07 +00:00
J. Nick Koston
fcab160049 Merge branch 'wifi_roam' into integration 2026-01-03 09:11:26 -10:00
J. Nick Koston
c809f86507 fix refactoring error 2026-01-03 09:11:18 -10:00
J. Nick Koston
a184b00051 Merge branch 'wifi_roam' into integration 2026-01-03 09:08:32 -10:00
J. Nick Koston
f7d9ebcf01 reduce 2026-01-03 09:08:23 -10:00
Mariusz Kryński
69867bf818 [nrf52, zephyr] move nrf52-specific code to nrf52 component (#12582)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-01-03 18:58:56 +00:00
J. Nick Koston
16f3605399 Merge branch 'dev' into get_peername_stack_save_ram 2026-01-03 08:02:34 -10:00
J. Nick Koston
c95b00e7fc Merge branch 'get_rid_of_complex_bifurcated_client_server_api_strings' into integration 2026-01-03 08:01:08 -10:00
J. Nick Koston
8cbb2eef84 merge 2026-01-03 08:00:56 -10:00
J. Nick Koston
21556e714b Merge remote-tracking branch 'upstream/dev' into get_rid_of_complex_bifurcated_client_server_api_strings 2026-01-03 08:00:17 -10:00
J. Nick Koston
dd9804aff4 Merge branch 'missing_password_removal' into integration 2026-01-03 07:56:51 -10:00
J. Nick Koston
b93817e872 [api] Fix KeyError when running logs after password removal 2026-01-03 07:42:46 -10:00
J. Nick Koston
af69ca58c6 Merge branch 'many_mesh_still_blocked_loop' into integration 2026-01-03 07:26:03 -10:00
J. Nick Koston
64261d9b04 [wifi] Combine scan result log lines to reduce loop blocking with many APs 2026-01-03 07:24:21 -10:00
J. Nick Koston
1d323c2d71 [api] Remove deprecated password authentication (#12819) 2026-01-03 07:14:48 -10:00
J. Nick Koston
e8de6627d8 document, document, document 2026-01-03 00:44:37 -10:00
J. Nick Koston
6029f24369 Merge branch 'wifi_roam' into integration 2026-01-03 00:42:31 -10:00
J. Nick Koston
b4f24f6a7f Merge remote-tracking branch 'origin/wifi_roam' into wifi_roam 2026-01-03 00:42:21 -10:00
J. Nick Koston
356e6a3c97 document roam fail path 2026-01-03 00:42:06 -10:00
J. Nick Koston
c4820fcc36 Merge branch 'logger_esp8266' into integration 2026-01-03 00:20:27 -10:00
J. Nick Koston
36d1ef9584 fixes 2026-01-03 00:20:02 -10:00
J. Nick Koston
a5269efd48 fixes 2026-01-03 00:16:07 -10:00
J. Nick Koston
46d9cdfe93 Merge branch 'dev' into logger_esp8266 2026-01-03 00:06:49 -10:00
J. Nick Koston
da34fca20c Merge branch 'dev' into wifi_roam 2026-01-02 23:57:41 -10:00
J. Nick Koston
dc159737ec Merge branch 'wifi_roam' into integration 2026-01-02 23:52:08 -10:00
J. Nick Koston
0ba1fe8457 -49 is the boundray for excellent 2026-01-02 23:51:02 -10:00
tomaszduda23
95a7356ea0 [uart] make sure that all variables are initialized (#12823) 2026-01-03 03:43:17 -06:00
J. Nick Koston
a46a51e885 tweak 2026-01-02 23:43:03 -10:00
J. Nick Koston
bb414f1745 Merge branch 'wifi_roam' into integration 2026-01-02 23:34:54 -10:00
J. Nick Koston
9d79a98c0d log cleanup 2026-01-02 23:34:45 -10:00
J. Nick Koston
cc7e075857 Merge branch 'wifi_roam' into integration 2026-01-02 23:24:41 -10:00
J. Nick Koston
b8c0dc7b04 stale comments 2026-01-02 23:24:22 -10:00
J. Nick Koston
7e313de1c1 Merge remote-tracking branch 'upstream/dev' into wifi_roam 2026-01-02 23:22:45 -10:00
J. Nick Koston
68ad5e457a fix stale comment 2026-01-02 23:22:10 -10:00
J. Nick Koston
a020a3421c Merge branch 'wifi_roam' into integration 2026-01-02 23:17:30 -10:00
J. Nick Koston
8fff7f6b85 len 1 2026-01-02 23:16:01 -10:00
J. Nick Koston
27ae2881de Merge branch 'wifi_roam' into integration 2026-01-02 23:11:42 -10:00
J. Nick Koston
2ab27a6ae2 avoid inlining expensive vector ops 2026-01-02 23:11:30 -10:00
J. Nick Koston
22ad0f2f2d handle race 2026-01-02 23:09:45 -10:00
J. Nick Koston
d99fd22f53 Merge branch 'wifi_roam' into integration 2026-01-02 23:06:01 -10:00
J. Nick Koston
f32c190905 optimize 2026-01-02 23:05:39 -10:00
J. Nick Koston
996bd12871 optimize 2026-01-02 23:03:52 -10:00
J. Nick Koston
516c074b8f optimize 2026-01-02 22:58:18 -10:00
J. Nick Koston
1c9e0f6b22 optimize 2026-01-02 22:56:48 -10:00
J. Nick Koston
828a27b1b6 reduce some code size 2026-01-02 22:53:42 -10:00
J. Nick Koston
039ae65ed8 Update esphome/components/wifi/wifi_component.cpp 2026-01-02 22:52:01 -10:00
J. Nick Koston
2275f638fb Merge remote-tracking branch 'origin/wifi_roam' into wifi_roam 2026-01-02 22:51:29 -10:00
J. Nick Koston
369f32b496 reduce some code size 2026-01-02 22:50:38 -10:00
J. Nick Koston
c6774d81cb Merge branch 'wifi_roam' into integration 2026-01-02 22:29:30 -10:00
J. Nick Koston
828e91a61b Merge remote-tracking branch 'origin/get_rid_of_complex_bifurcated_client_server_api_strings' into get_rid_of_complex_bifurcated_client_server_api_strings 2026-01-02 22:19:12 -10:00
J. Nick Koston
fb255d7e7c fixes 2026-01-02 22:19:01 -10:00
J. Nick Koston
c7e9eda5aa Merge branch 'dev' into get_rid_of_complex_bifurcated_client_server_api_strings 2026-01-02 22:11:24 -10:00
J. Nick Koston
979b96f7d4 cleanup 2026-01-02 21:56:38 -10:00
J. Nick Koston
af8c453f7c [api] Simplify string handling by removing bifurcated client/server storage 2026-01-02 21:52:20 -10:00
Keith Burzinski
5db4574cb8 Merge branch 'dev' into get_peername_stack_save_ram 2026-01-03 01:01:07 -06:00
J. Nick Koston
89b550b74a [tests] Remove reserved / character from entity names in component tests (#12820) 2026-01-03 01:00:46 -06:00
dependabot[bot]
538c6544a0 Bump ruamel-yaml from 0.18.17 to 0.19.1 (#12768)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-02 20:51:56 -10:00
dependabot[bot]
98e3695c89 Bump aioesphomeapi from 43.9.1 to 43.10.0 (#12821)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-03 06:45:17 +00:00
J. Nick Koston
ae1082e3e6 Merge branch 'get_peername_stack_save_ram' into integration 2026-01-02 20:31:10 -10:00
J. Nick Koston
a63ed0d616 fix merge conflict 2026-01-02 20:29:45 -10:00
J. Nick Koston
c2ffd4e49a fix merge conflict 2026-01-02 20:28:37 -10:00
J. Nick Koston
c2c513fd75 Merge branch 'dev' into get_peername_stack_save_ram 2026-01-02 20:26:30 -10:00
J. Nick Koston
2ed5015089 Merge branch 'api_avoid_copies' into integration 2026-01-02 20:21:47 -10:00
J. Nick Koston
48760ef927 match it to upstream change 2026-01-02 20:21:06 -10:00
J. Nick Koston
40b09e8cd4 match it to upstream change 2026-01-02 20:20:02 -10:00
J. Nick Koston
61692894e1 Merge branch 'dev' into api_avoid_copies 2026-01-02 20:19:11 -10:00
J. Nick Koston
00fd4f2fdd [esp8266] Exclude unused waveform code to save ~596 bytes RAM (#12690) 2026-01-02 19:51:07 -10:00
J. Nick Koston
2a5be725c8 [api] Enable zero-copy bytes SOURCE_BOTH messages (#12816) 2026-01-02 19:50:30 -10:00
Robert Klep
c4d339a4c9 [core] Add CONF_ON_START (#12439) (#12440) 2026-01-02 23:42:18 -05:00
J. Nick Koston
c25b732d39 Merge remote-tracking branch 'upstream/source_both_zero_copy' into integration 2026-01-02 17:02:10 -10:00
J. Nick Koston
3148cb2bdd Merge branch 'api_avoid_copies' into integration 2026-01-02 17:01:56 -10:00
J. Nick Koston
114624acbd fix conflicts 2026-01-02 16:57:41 -10:00
J. Nick Koston
c82ae34ccf Merge remote-tracking branch 'upstream/dev' into get_peername_stack_save_ram
# Conflicts:
#	esphome/components/api/api_connection.cpp
#	esphome/components/api/api_frame_helper.cpp
#	esphome/components/api/api_frame_helper_noise.cpp
#	esphome/components/api/api_frame_helper_plaintext.cpp
2026-01-02 16:52:04 -10:00
J. Nick Koston
cf46f71933 Merge branch 'dev' into source_both_zero_copy 2026-01-02 16:45:45 -10:00
J. Nick Koston
9fc78d424c Merge remote-tracking branch 'upstream/dev' into api_avoid_copies
# Conflicts:
#	esphome/components/api/api_connection.cpp
2026-01-02 16:44:53 -10:00
J. Nick Koston
6409970f6e [uponor_smatrix] Use stack-based hex formatting in verbose logging (#12797)
Co-authored-by: Stefan Rado <628587+kroimon@users.noreply.github.com>
2026-01-02 16:41:02 -10:00
J. Nick Koston
bc1af007b4 [vbus] Use stack-based hex formatting in verbose logging (#12796) 2026-01-02 16:40:47 -10:00
Thomas Rupprecht
c3ffc1635d [gps] add icon for HDOP and use correct state_class for longitude and… (#12718) 2026-01-02 21:40:28 -05:00
J. Nick Koston
016eeef04a [tee501] Use stack-based hex formatting in verbose logging (#12795) 2026-01-02 16:40:06 -10:00
J. Nick Koston
ace48464a8 [addressable_light] Use StringRef to avoid allocation when saving effect name (#12759) 2026-01-02 16:39:44 -10:00
J. Nick Koston
64ba376330 [hte501] Use stack-based hex formatting in verbose logging (#12794) 2026-01-02 16:37:38 -10:00
J. Nick Koston
d946ddabfd [xiaomi_ble] Use stack-based hex formatting in verbose logging (#12793) 2026-01-02 16:37:16 -10:00
J. Nick Koston
a57011b50b [kuntze] Use stack buffer for hex formatting in verbose logging (#12775) 2026-01-02 16:36:57 -10:00
J. Nick Koston
1240e7907e [api] Use stack-based format_hex_pretty_to for packet logging macros (#12788) 2026-01-02 16:35:44 -10:00
J. Nick Koston
d70b3091c9 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-02 16:35:18 -10:00
J. Nick Koston
f0391f0213 [api] Remove object_id from API protocol - clients compute it from name #12698 (#12818) 2026-01-02 16:32:46 -10:00
J. Nick Koston
3cc6810be5 [core] Remove object_id RAM storage - no longer in hot path after #12627 (#12631) 2026-01-02 15:46:01 -10:00
J. Nick Koston
916370a943 [gpio] Avoid heap allocation in dump_summary (#12760) 2026-01-02 15:42:56 -10:00
J. Nick Koston
3d6c64b657 Merge branch 'dev' into wifi_roam 2026-01-02 14:28:59 -10:00
J. Nick Koston
e2f45c590e [esp32_improv] Use stack buffer for hex formatting in verbose logging (#12737) 2026-01-02 14:28:38 -10:00
J. Nick Koston
7d21411ca4 [epaper_spi] Use stack buffer for hex formatting in command logging (#12734) 2026-01-02 14:27:00 -10:00
J. Nick Koston
56ed5af27d [nextion] Use stack buffers for hex formatting in upload logging (#12733) 2026-01-02 14:26:14 -10:00
J. Nick Koston
c8241b0122 [sonoff_d1] Use stack buffer for hex formatting in logging (#12730) 2026-01-02 14:25:02 -10:00
J. Nick Koston
30efd7fb07 [jsn_sr04t] Use stack buffer for hex formatting in error logging (#12729) 2026-01-02 14:24:47 -10:00
J. Nick Koston
1703343694 [a02yyuw] Use stack buffer for hex formatting in error logging (#12728) 2026-01-02 14:24:30 -10:00
J. Nick Koston
7fa04b6c25 [a01nyub] Use stack buffer for hex formatting in error logging (#12727) 2026-01-02 14:23:33 -10:00
J. Nick Koston
61b6476de4 [opentherm] Replace heap-allocating format calls with printf format specifiers in debug_error (#12726) 2026-01-02 14:23:18 -10:00
J. Nick Koston
b4e5e0bc9b [rc522] Use stack buffers for hex formatting in tag logging (#12725) 2026-01-02 14:22:58 -10:00
J. Nick Koston
f9b4e0e489 [remote_base] Use stack buffer for hex formatting in haier protocol logging (#12723) 2026-01-02 14:22:26 -10:00
J. Nick Koston
9ccb100cca [remote_base] Use stack buffer for hex formatting in mirage protocol logging (#12722) 2026-01-02 14:21:42 -10:00
J. Nick Koston
20b66cba23 [shelly_dimmer] Use stack buffer for hex formatting in command logging (#12721) 2026-01-02 14:21:23 -10:00
J. Nick Koston
b711172b33 [wifi] Use precision format specifier for SSID logging to avoid stack copy (#12704) 2026-01-02 14:21:09 -10:00
J. Nick Koston
0c4184b129 [cse7766] Use stack buffer for hex formatting in debug logging (#12732) 2026-01-02 14:20:17 -10:00
J. Nick Koston
0e108c2178 [esp32] Add minimum_chip_revision setting and log chip revision at startup (#12696) 2026-01-02 14:14:52 -10:00
J. Nick Koston
2230e56347 [wifi] Use stack buffers for IP address logging to avoid heap allocations (#12680) 2026-01-02 14:14:24 -10:00
J. Nick Koston
2ff9535f5f [esp32_improv] Use stack buffer for URL formatting to avoid heap allocation (#12682) 2026-01-02 14:14:12 -10:00
J. Nick Koston
ddb6c6cfd4 [captive_portal] Use stack buffer for IP address logging in DNS server (#12679) 2026-01-02 14:13:59 -10:00
J. Nick Koston
00ab64a3c7 [wifi] Use wifi_ssid_to() to avoid heap allocations in automation and connection checks (#12678) 2026-01-02 14:13:43 -10:00
J. Nick Koston
e732f8469e [udp] Avoid heap allocations when joining multicast groups (#12685) 2026-01-02 14:13:26 -10:00
J. Nick Koston
023be88a87 [tuya] Use stack buffers for hex logging to avoid heap allocations (#12689) 2026-01-02 14:13:08 -10:00
J. Nick Koston
25e60d62cf [mqtt] Avoid heap allocations when logging IP addresses (#12686) 2026-01-02 14:12:04 -10:00
J. Nick Koston
167a42aa27 [api] Use StringRef in send_action_response and send_execute_service_response (#12658) 2026-01-02 14:11:45 -10:00
J. Nick Koston
0ef49a8b73 [ld2410][ld2412][ld2450] Use stack buffers for hex logging (#12688) 2026-01-02 14:11:31 -10:00
J. Nick Koston
e3fe738966 Merge branch 'dev' into source_both_zero_copy 2026-01-02 14:10:27 -10:00
J. Nick Koston
51259888bf [voice_assistant] Use zero-copy buffer access for audio data (#12656) 2026-01-02 14:10:21 -10:00
J. Nick Koston
0b7ff09657 [api] Use pointer to FixedVector for siren tones field (#12657) 2026-01-02 14:09:40 -10:00
J. Nick Koston
8a5e06b6d2 merge 2026-01-02 14:08:09 -10:00
J. Nick Koston
560966ad98 Merge remote-tracking branch 'upstream/dev' into source_both_zero_copy
# Conflicts:
#	script/api_protobuf/api_protobuf.py
2026-01-02 14:07:55 -10:00
J. Nick Koston
f394cf3f4d [packet_transport] Use stack-based format_hex_pretty_to for logging (#12791) 2026-01-02 14:06:03 -10:00
J. Nick Koston
4cb066bcbf [api] Use StringRef in handle_action_response to avoid temporary string (#12655) 2026-01-02 14:05:50 -10:00
J. Nick Koston
e7001c5eea [api] Auto-generate zero-copy pointer access for incoming API bytes fields (#12654) 2026-01-02 14:05:37 -10:00
esphomebot
5bb9ffa0cb Update webserver local assets to 20260102-230255 (#12817) 2026-01-02 23:14:11 +00:00
J. Nick Koston
7438034411 Merge remote-tracking branch 'upstream/dev' into integration 2026-01-02 13:09:46 -10:00
J. Nick Koston
c6713eaccb [web_server] Fix URL collisions with UTF-8 names and sub-devices (#12627) 2026-01-02 13:07:11 -10:00
J. Nick Koston
5b4bd555dd cleanup per bot 2026-01-02 12:36:44 -10:00
J. Nick Koston
9b02daae2b cleanup per bot 2026-01-02 12:35:05 -10:00
J. Nick Koston
d77fc596a9 its going to drop anyways 2026-01-02 11:37:56 -10:00
Jonathan Swoboda
087f521b19 [ultrasonic] Use interrupt-based measurement for reliability (#12617)
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-02 15:58:53 -05:00
J. Nick Koston
9906724828 [api] Enable zero-copy bytes for VoiceAssistantAudio and other SOURCE_BOTH messages 2026-01-02 10:56:17 -10:00
Jonathan Swoboda
763515d3a1 [core] Remove unused USE_ESP32_FRAMEWORK_ARDUINO ifdefs (#12813)
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-02 14:47:14 -05:00
J. Nick Koston
5c890fcfc4 add roam diagram 2026-01-02 09:29:59 -10:00
J. Nick Koston
5d8346cfb6 Merge branch 'dev' into bytes_zero_copy_default_api 2026-01-02 08:17:33 -10:00
J. Nick Koston
6d4f4d8d23 [api] Auto-generate StringRef for incoming API string fields (#12648) 2026-01-02 08:17:05 -10:00
J. Nick Koston
0a98f7877c tweak 2026-01-01 22:49:21 -10:00
Tobias Stanzel
d7fd85e610 [spi] Allow any achievable data rate (#12753)
Co-authored-by: clydebarrow <2366188+clydebarrow@users.noreply.github.com>
2026-01-02 18:10:30 +11:00
J. Nick Koston
8acaa16987 [usb_cdc_acm] Use stack-based hex formatting in verbose logging (#12792) 2026-01-02 01:04:11 -06:00
J. Nick Koston
4e8c02b396 [xiaomi_*] Use stack-based hex formatting for bindkey logging (#12798) 2026-01-01 20:25:12 -10:00
J. Nick Koston
a828abf53d [ota] Remove MD5 authentication support (#12707) 2026-01-01 20:24:31 -10:00
J. Nick Koston
ebfa0149cc [light] Use StringRef to avoid allocation in JSON effect name serialization (#12758) 2026-01-01 20:23:37 -10:00
J. Nick Koston
3a4cca0027 [ble_client] Use stack buffer for hex formatting in very verbose logging (#12744) 2026-01-01 20:22:48 -10:00
J. Nick Koston
7702a9ae85 [ethernet] Use stack buffer for hex formatting in very verbose logging (#12742) 2026-01-01 20:22:19 -10:00
J. Nick Koston
2e8baa0493 [esp32_ble_tracker] Use stack buffer for hex formatting in very verbose logging (#12741) 2026-01-01 20:21:33 -10:00
J. Nick Koston
69ec311d21 [hlk_fm22x] Use stack buffer for hex formatting in verbose logging (#12740) 2026-01-01 20:20:58 -10:00
J. Nick Koston
1cc18055ef [i2c] Use stack buffer for hex formatting in verbose logging (#12739) 2026-01-01 20:20:24 -10:00
J. Nick Koston
bcc6bbbf5f [espnow] Use stack buffer for hex formatting in verbose logging (#12738) 2026-01-01 20:19:49 -10:00
J. Nick Koston
71c3d4ca27 [mopeka_std_check] Use stack-based format_hex_pretty_to for very verbose logging (#12790) 2026-01-01 20:19:20 -10:00
J. Nick Koston
c6f3860f90 [ee895] Use stack-based format_hex_to for verbose logging (#12789) 2026-01-01 20:18:23 -10:00
J. Nick Koston
0049c8ad38 [zwave_proxy] Use stack-based format_hex_pretty_to for very verbose logging (#12786) 2026-01-01 20:17:51 -10:00
J. Nick Koston
e1788bba45 [seeed_mr60fda2] Use stack-based format_hex_pretty_to for verbose logging (#12785) 2026-01-01 20:17:22 -10:00
J. Nick Koston
4fcd263ea8 [seeed_mr60bha2] Replace format_hex_pretty with stack-based format_hex_pretty_to (#12784) 2026-01-01 20:16:40 -10:00
J. Nick Koston
c81ce243cc [qspi_dbi] Replace format_hex_pretty with stack-based format_hex_pretty_to (#12783) 2026-01-01 20:13:10 -10:00
J. Nick Koston
7df41124b2 [pn532_spi] Replace format_hex_pretty with stack-based format_hex_pretty_to (#12782) 2026-01-01 20:11:53 -10:00
J. Nick Koston
b5188731f8 [modbus] Use stack buffer for hex formatting in verbose logging (#12780) 2026-01-01 20:10:45 -10:00
J. Nick Koston
0924281545 [mitsubishi] Use stack buffer for hex formatting in verbose logging (#12779) 2026-01-01 20:10:08 -10:00
J. Nick Koston
14e97642f7 [mipi_rgb] Use stack buffer for hex formatting in init sequence logging (#12777) 2026-01-01 20:09:37 -10:00
J. Nick Koston
544aaeaa66 [mipi_dsi] Use stack buffer for hex formatting in very verbose logging (#12776) 2026-01-01 20:08:57 -10:00
Stuart Parmenter
7483bbd6ea [display] Ensure drivers respect clipping during fill() (#12808) 2026-01-02 16:34:39 +11:00
Artur
2841b5fe44 [sn74hc595]: fix 'Attempted read from write-only channel' when using esp-idf framework (#12801) 2026-01-01 23:28:10 -05:00
J. Nick Koston
dd6ed4aea6 [wifi] Add basic post-connect roaming support for stationary devices 2026-01-01 17:48:20 -10:00
J. Nick Koston
ab17775c3e tweaks 2026-01-01 17:45:05 -10:00
J. Nick Koston
dc07926a91 tweaks 2026-01-01 17:44:39 -10:00
J. Nick Koston
291722c50e tweak 2026-01-01 17:18:21 -10:00
J. Nick Koston
8b7bb4ecef wip 2026-01-01 14:59:19 -10:00
J. Nick Koston
1def4df146 wip 2026-01-01 14:57:28 -10:00
J. Nick Koston
ff33e362cf wifi roam 2026-01-01 14:55:16 -10:00
J. Nick Koston
ed435241b1 [mipi_spi] Use stack buffer for hex formatting in verbose logging (#12778) 2026-01-01 11:48:37 -10:00
H. Árkosi Róbert
9847e51fbc [bthome_mithermometer] Add BTHome parsing for Xiaomi Mijia BLE Sensors (#12635) 2026-01-02 08:40:18 +11:00
dependabot[bot]
dc320f455a Bump bleak from 2.1.0 to 2.1.1 (#12804)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-01 09:16:01 -10:00
Clyde Stubbs
1945e85ddc [core] Make LockFreeQueue more widely available (#12766) 2026-01-01 22:07:35 +11:00
J. Nick Koston
84e764fa87 Merge branch 'abbwelcome_format' into integration 2025-12-31 23:12:36 -10:00
J. Nick Koston
54a5c9d4af tweak 2025-12-31 23:09:51 -10:00
J. Nick Koston
1303dfa960 tweak 2025-12-31 23:09:39 -10:00
J. Nick Koston
7ce30b693e Merge branch 'abbwelcome_format' into integration 2025-12-31 23:07:18 -10:00
J. Nick Koston
5caa9b8140 snprintf 2025-12-31 23:03:55 -10:00
J. Nick Koston
42746b4b6f tweak 2025-12-31 22:59:44 -10:00
J. Nick Koston
47603de7ce handle truncate 2025-12-31 22:51:42 -10:00
J. Nick Koston
acb54ebb38 Merge branch 'abbwelcome_format' into integration 2025-12-31 22:46:16 -10:00
J. Nick Koston
819bc0a0f2 [abbwelcome] Use stack-based formatting to eliminate heap allocations 2025-12-31 22:45:45 -10:00
J. Nick Koston
b28385da40 Merge branch 'xiaomi_cgd1' into integration 2025-12-31 22:34:22 -10:00
J. Nick Koston
c6a612f580 fix seperator 2025-12-31 22:30:16 -10:00
J. Nick Koston
ad7f48f16d Merge branch 'xiaomi_cgd1' into integration 2025-12-31 22:25:00 -10:00
J. Nick Koston
22502983df [xiaomi_*] Use stack-based hex formatting for bindkey logging 2025-12-31 22:24:29 -10:00
J. Nick Koston
160e649d86 Merge branch 'xiaomi_ble' into integration 2025-12-31 22:16:46 -10:00
J. Nick Koston
259ca86ed7 fix 2025-12-31 22:09:32 -10:00
J. Nick Koston
4ee1358a9f Merge branch 'uponor_smatrix' into integration 2025-12-31 22:07:02 -10:00
J. Nick Koston
8e4913d78c [uponor_smatrix] Use stack-based hex formatting in verbose logging 2025-12-31 22:06:26 -10:00
J. Nick Koston
b6e05a0570 Merge branch 'vbus_hex' into integration 2025-12-31 22:04:11 -10:00
J. Nick Koston
d4e2d808d7 [vbus] Use stack-based hex formatting in verbose logging 2025-12-31 22:03:40 -10:00
J. Nick Koston
fd65ea1d05 Merge branch 'tee501' into integration 2025-12-31 22:00:13 -10:00
J. Nick Koston
91e9c8b63b [tee501] Use stack-based hex formatting in verbose logging 2025-12-31 21:58:37 -10:00
J. Nick Koston
22d2087563 Merge branch 'hte501' into integration 2025-12-31 21:56:43 -10:00
J. Nick Koston
7588f3b120 [hte501] Use stack-based hex formatting in verbose logging 2025-12-31 21:56:06 -10:00
J. Nick Koston
9e1c14dde5 Merge branch 'xiaomi_ble' into integration 2025-12-31 21:54:31 -10:00
J. Nick Koston
2a262babd3 Merge branch 'usb_cdc_acm_hex' into integration 2025-12-31 21:54:26 -10:00
J. Nick Koston
4ba89d9430 Merge branch 'packet_transport_hex' into integration 2025-12-31 21:54:21 -10:00
J. Nick Koston
22fff2b147 Merge branch 'seeed_mr60fda2' into integration 2025-12-31 21:54:14 -10:00
J. Nick Koston
9928e29f52 Merge branch 'zwave_proxy_hex' into integration 2025-12-31 21:54:09 -10:00
J. Nick Koston
59419a63bd Merge branch 'mopeka_std_check' into integration 2025-12-31 21:54:05 -10:00
J. Nick Koston
9501431908 [xiaomi_ble] Use stack-based hex formatting in verbose logging 2025-12-31 21:52:02 -10:00
J. Nick Koston
7c47c1e3b2 [usb_cdc_acm] Use stack-based hex formatting in verbose logging 2025-12-31 21:48:07 -10:00
J. Nick Koston
d93ed1982e [packet_transport] Use stack-based format_hex_pretty_to for logging 2025-12-31 21:42:13 -10:00
J. Nick Koston
df4ce52deb reduce 2025-12-31 21:37:05 -10:00
J. Nick Koston
fa5aa619ad reduce 2025-12-31 21:34:42 -10:00
J. Nick Koston
ecf6e62b86 [mopeka_std_check] Use stack-based format_hex_pretty_to for very verbose logging 2025-12-31 21:30:17 -10:00
Clyde Stubbs
4313130f2e [lvgl] Fix arc background angles (#12773) 2026-01-01 14:44:21 +11:00
J. Nick Koston
252e35c516 Merge branch 'ee895' into integration 2025-12-31 17:40:59 -10:00
J. Nick Koston
45124c05ad [ee895] Use stack-based format_hex_to for verbose logging 2025-12-31 17:40:25 -10:00
J. Nick Koston
77a95a5fd4 adjust 2025-12-31 17:30:44 -10:00
J. Nick Koston
8dd958fcd1 [api] Use stack-based format_hex_pretty_to for packet logging macros 2025-12-31 17:28:01 -10:00
J. Nick Koston
2a87a70963 Merge branch 'espnow' into integration 2025-12-31 17:25:34 -10:00
J. Nick Koston
5bfb020c1f Merge branch 'epaper_spi' into integration 2025-12-31 17:25:15 -10:00
J. Nick Koston
d2afa9a120 Merge branch 'zwave_proxy_hex' into integration 2025-12-31 17:16:17 -10:00
J. Nick Koston
aade54e3c9 [zwave_proxy] Use stack-based format_hex_pretty_to for very verbose logging 2025-12-31 17:10:52 -10:00
J. Nick Koston
4439d30d27 Merge branch 'seeed_mr60fda2' into integration 2025-12-31 17:04:14 -10:00
J. Nick Koston
38381a0d24 Merge branch 'seeed_mr60bha2' into integration 2025-12-31 17:04:10 -10:00
J. Nick Koston
eddb386277 [seeed_mr60fda2] Use stack-based format_hex_pretty_to for verbose logging 2025-12-31 17:03:32 -10:00
J. Nick Koston
dde20e82f7 [seeed_mr60bha2] Replace format_hex_pretty with stack-based format_hex_pretty_to 2025-12-31 16:58:19 -10:00
J. Nick Koston
8f856fab1b Merge branch 'qspi_dbi' into integration 2025-12-31 16:55:25 -10:00
J. Nick Koston
3e1f7a9cd8 Merge branch 'pn532_spi' into integration 2025-12-31 16:55:21 -10:00
J. Nick Koston
f8e56a8565 Merge branch 'modbus_controller' into integration 2025-12-31 16:55:16 -10:00
J. Nick Koston
a952d843e7 Merge branch 'modbus' into integration 2025-12-31 16:55:12 -10:00
J. Nick Koston
278fdae770 Merge branch 'mitsubishi' into integration 2025-12-31 16:55:08 -10:00
J. Nick Koston
6fc9c63f2d Merge branch 'mipi_spi' into integration 2025-12-31 16:55:03 -10:00
J. Nick Koston
be6ec974e1 Merge branch 'mipi_rgb_hex' into integration 2025-12-31 16:54:58 -10:00
J. Nick Koston
9de52fb9f5 Merge branch 'mipi_dsi' into integration 2025-12-31 16:54:54 -10:00
J. Nick Koston
7993ff7602 Merge branch 'hlk_fm22x_format' into integration 2025-12-31 16:54:49 -10:00
J. Nick Koston
253ce861ab [qspi_dbi] Replace format_hex_pretty with stack-based format_hex_pretty_to 2025-12-31 16:54:13 -10:00
J. Nick Koston
1fff2f503f [pn532_spi] Replace format_hex_pretty with stack-based format_hex_pretty_to 2025-12-31 16:52:24 -10:00
J. Nick Koston
6925ab3bf1 tweak 2025-12-31 16:46:57 -10:00
J. Nick Koston
d8a84e6f2b wip 2025-12-31 16:42:45 -10:00
J. Nick Koston
73b19bc5d1 [modbus_controller] Replace format_hex_pretty with stack-based format_hex_pretty_to 2025-12-31 16:38:58 -10:00
J. Nick Koston
528b374b3f [modbus] Use stack buffer for hex formatting in verbose logging 2025-12-31 16:34:36 -10:00
J. Nick Koston
b7d9e3e847 [mitsubishi] Use stack buffer for hex formatting in verbose logging 2025-12-31 16:31:18 -10:00
J. Nick Koston
afd4562062 [mipi_spi] Use stack buffer for hex formatting in verbose logging 2025-12-31 16:28:51 -10:00
J. Nick Koston
724829f5bd [mipi_rgb] Use stack buffer for hex formatting in init sequence logging 2025-12-31 16:25:08 -10:00
J. Nick Koston
4f1b1d7a1e [mipi_dsi] Use stack buffer for hex formatting in very verbose logging 2025-12-31 16:22:04 -10:00
J. Nick Koston
b1ebdabaa9 Merge branch 'kuntze' into integration 2025-12-31 16:18:12 -10:00
J. Nick Koston
b1e359750c [kuntze] Use stack buffer for hex formatting in verbose logging 2025-12-31 16:17:13 -10:00
Jonathan Swoboda
3c9ed126a6 Merge branch 'release' into dev 2025-12-31 17:42:51 -05:00
Jonathan Swoboda
d8c23d4fc9 Merge pull request #12772 from esphome/bump-2025.12.4
2025.12.4
2025-12-31 17:42:39 -05:00
Konstantin Tretyakov
1d96de986e [sdist] Include yaml files in components in source distribution package
Co-authored-by: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com>
2026-01-01 08:49:43 +11:00
Jonathan Swoboda
e9e0712959 Bump version to 2025.12.4 2025-12-31 16:07:00 -05:00
J. Nick Koston
062840dd7b [docker] Add build-essential to fix ruamel.yaml 0.19.0 compilation (#12769)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-31 16:07:00 -05:00
J. Nick Koston
f0f01c081a [wifi] Fix ESP-IDF reporting connected before DHCP completes on reconnect (#12755) 2025-12-31 16:07:00 -05:00
Stuart Parmenter
dd855985be [hub75] Add clipping check (#12762) 2025-12-31 16:06:59 -05:00
J. Nick Koston
4633803d5d [docker] Add build-essential to fix ruamel.yaml 0.19.0 compilation (#12769)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-31 16:05:58 -05:00
J. Nick Koston
476d00d0e5 [wifi] Fix ESP-IDF reporting connected before DHCP completes on reconnect (#12755) 2025-12-31 15:59:28 -05:00
Stuart Parmenter
98cdef2568 [hub75] Add clipping check (#12762) 2025-12-31 15:58:37 -05:00
J. Nick Koston
4bfc14fa0e Merge branch 'dump_summary' into integration 2025-12-30 13:46:48 -10:00
J. Nick Koston
71d9dff3fc fix 2025-12-30 13:46:36 -10:00
J. Nick Koston
6728a28e1d Merge branch 'dump_summary' into integration 2025-12-30 13:43:20 -10:00
J. Nick Koston
c716983d5c tweak 2025-12-30 13:41:29 -10:00
J. Nick Koston
2c0c5a1b09 Merge branch 'dump_summary' into integration 2025-12-30 13:29:31 -10:00
J. Nick Koston
c13bbd300d tweaks 2025-12-30 13:24:32 -10:00
J. Nick Koston
ac515d6d2e tweaks 2025-12-30 13:23:21 -10:00
J. Nick Koston
e7e83305e8 Merge branch 'dump_summary' into integration 2025-12-30 13:13:40 -10:00
J. Nick Koston
580498e06c missing ; 2025-12-30 13:13:31 -10:00
J. Nick Koston
2d4be9c96f Merge branch 'dump_summary' into integration 2025-12-30 13:10:03 -10:00
J. Nick Koston
52eda13ecd reduce 2025-12-30 13:09:35 -10:00
J. Nick Koston
8ab37379e8 reduce 2025-12-30 13:08:16 -10:00
J. Nick Koston
fcd49fd32d reduce 2025-12-30 13:08:05 -10:00
J. Nick Koston
22b01ad440 Merge branch 'dump_summary' into integration 2025-12-30 13:04:36 -10:00
J. Nick Koston
53aa3f539b copilot suggestion is overkill and breaks things 2025-12-30 13:04:26 -10:00
J. Nick Koston
f42af572b8 Merge branch 'dump_summary' into integration 2025-12-30 13:04:02 -10:00
J. Nick Koston
61b377140f copilot suggestion is overkill and breaks things 2025-12-30 13:03:48 -10:00
J. Nick Koston
957b4d532c Merge branch 'dump_summary' into integration 2025-12-30 12:06:56 -10:00
J. Nick Koston
354ca54a11 adjust 2025-12-30 12:05:36 -10:00
J. Nick Koston
f0be51a49f Merge branch 'dev' into hlk_fm22x_format 2025-12-30 12:02:58 -10:00
J. Nick Koston
9ca590a125 Merge branch 'dump_summary' into integration 2025-12-30 11:53:16 -10:00
J. Nick Koston
ebf5c2851b [gpio] Avoid heap allocation in dump_summary 2025-12-30 11:52:39 -10:00
J. Nick Koston
bd3ecad3a1 [core] Add format_hex_pretty_to buffer helper and reduce code duplication (#12687) 2025-12-30 11:51:51 -10:00
J. Nick Koston
0e725a35c9 Merge branch 'light_effect_ref' into integration 2025-12-30 11:20:08 -10:00
J. Nick Koston
c2865d040f Merge branch 'addressable_light_effect_ref' into integration 2025-12-30 11:19:55 -10:00
J. Nick Koston
5a4a58fd14 Merge branch 'api_avoid_copies' into integration 2025-12-30 11:19:51 -10:00
J. Nick Koston
00f4449cc0 fix ambiguous 2025-12-30 11:17:21 -10:00
J. Nick Koston
89e0797657 simple 2025-12-30 11:14:41 -10:00
J. Nick Koston
cc79334da7 [addressable_light] Use StringRef to avoid allocation when saving effect name 2025-12-30 11:11:53 -10:00
J. Nick Koston
8d61d83425 [light] Use StringRef to avoid allocation in JSON effect name serialization 2025-12-30 11:07:59 -10:00
J. Nick Koston
ac673852bd Merge branch 'api_avoid_copies' into integration 2025-12-30 10:50:32 -10:00
J. Nick Koston
a42820dc26 should never happen but ok 2025-12-30 10:49:02 -10:00
J. Nick Koston
80e03e3951 Merge branch 'api_avoid_copies' into integration 2025-12-30 10:44:37 -10:00
J. Nick Koston
f615409032 len known 2025-12-30 10:44:30 -10:00
J. Nick Koston
d357a62fec Merge branch 'api_avoid_copies' into integration 2025-12-30 10:42:26 -10:00
J. Nick Koston
089e21b15a tweaks 2025-12-30 10:37:03 -10:00
J. Nick Koston
3e8857b358 tweaks 2025-12-30 10:32:06 -10:00
J. Nick Koston
03c9107826 Merge remote-tracking branch 'upstream/dev' into api_avoid_copies 2025-12-30 10:28:51 -10:00
J. Nick Koston
dae7ba604a [ethernet_info] Eliminate heap allocations in DNS text sensor (#12756) 2025-12-30 10:25:51 -10:00
J. Nick Koston
201ae5801a Merge branch 'ethernet_info_no_heap' into integration 2025-12-30 09:59:49 -10:00
J. Nick Koston
a346b983a7 [ethernet_info] Eliminate heap allocations in DNS text sensor 2025-12-30 09:59:20 -10:00
J. Nick Koston
880cc841f4 Merge branch 'wifi_reconnect_esp_idf' into integration 2025-12-30 09:13:26 -10:00
J. Nick Koston
eea2037627 [wifi] Fix ESP-IDF reporting connected before DHCP completes on reconnect 2025-12-30 08:51:00 -10:00
Jonathan Swoboda
96c47f3b4d Merge branch 'release' into dev 2025-12-30 09:31:44 -05:00
Jonathan Swoboda
5b5cede5f9 Merge pull request #12752 from esphome/bump-2025.12.3
2025.12.3
2025-12-30 09:31:31 -05:00
Jonathan Swoboda
c737033cc4 Bump version to 2025.12.3 2025-12-30 09:22:03 -05:00
J. Nick Koston
0194bfd9ea [core] Fix incremental build failures when adding components on ESP32-Arduino (#12745) 2025-12-30 09:22:03 -05:00
J. Nick Koston
339399eb70 [lvgl] Fix lambdas in canvas actions called from outside LVGL context (#12671) 2025-12-30 09:22:03 -05:00
Samuel Sieb
a615b28ecf [bme68x_bsec2] add id: to allow extending (#12649) 2025-12-29 23:22:36 -08:00
J. Nick Koston
065d0541d1 Merge branch 'buffering' into integration 2025-12-29 21:16:25 -10:00
J. Nick Koston
25a4d7ffab tweak 2025-12-29 21:16:11 -10:00
J. Nick Koston
10b0308bc0 tests 2025-12-29 21:11:39 -10:00
J. Nick Koston
21bd6c5b18 [core] Improve log timestamp accuracy by batching serial reads 2025-12-29 20:59:03 -10:00
bakroistvan
468bd7b04f [dallas_temp] higher precision for logged temperature (#12695) 2025-12-29 22:53:28 -08:00
J. Nick Koston
fe7fa02a4e Merge remote-tracking branch 'upstream/dev' into integration 2025-12-29 17:43:52 -10:00
Jonathan Swoboda
4c16afeacb [esp32] Add IDF framework source for Arduino builds (#12731)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-12-29 22:25:26 -05:00
J. Nick Koston
d86c05bfe6 [esp32] Breaking Change: Change default framework to ESP-IDF (#12746)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-30 03:23:41 +00:00
J. Nick Koston
63464a13c3 [core] Fix incremental build failures when adding components on ESP32-Arduino (#12745) 2025-12-29 16:57:22 -10:00
J. Nick Koston
f2b1c51372 Merge remote-tracking branch 'upstream/esp32_default_framework_idf' into integration 2025-12-29 16:54:05 -10:00
J. Nick Koston
3903594bd3 Update esphome/components/esp32/__init__.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-29 16:53:51 -10:00
J. Nick Koston
c4d73a07b2 Merge branch 'storage_should_update_cmake_cache_arudino_fix' into integration 2025-12-29 16:49:26 -10:00
J. Nick Koston
148dbee6cb Merge branch 'esp32_default_framework_idf' into integration 2025-12-29 16:49:22 -10:00
J. Nick Koston
436b4c4217 [esp32] Change default framework to ESP-IDF 2025-12-29 16:38:11 -10:00
J. Nick Koston
2297d240be cleanup 2025-12-29 16:28:14 -10:00
J. Nick Koston
1d1f2a9877 cover 2025-12-29 16:25:17 -10:00
J. Nick Koston
1472914527 cover 2025-12-29 16:24:10 -10:00
J. Nick Koston
c9c0bdb1c6 Merge branch 'dev' into storage_should_update_cmake_cache_arudino_fix 2025-12-29 16:23:39 -10:00
J. Nick Koston
1e5739fb93 [core] Fix incremental build failures when adding components on ESP32-Arduino 2025-12-29 16:22:04 -10:00
Clyde Stubbs
20e43398fa [cli] Report program path on host (#12743) 2025-12-30 13:21:30 +11:00
J. Nick Koston
3053687273 Merge branch 'ble_client' into integration 2025-12-29 15:52:12 -10:00
J. Nick Koston
5e7d89f302 [ble_client] Use stack buffer for hex formatting in very verbose logging 2025-12-29 15:51:35 -10:00
J. Nick Koston
005dd1ea73 [ble_client] Use stack buffer for hex formatting in very verbose logging 2025-12-29 15:49:48 -10:00
J. Nick Koston
8477dfc6c2 Merge branch 'ethernet_format_hex' into integration 2025-12-29 14:55:28 -10:00
J. Nick Koston
7b274d3347 [ethernet] Use stack buffer for hex formatting in very verbose logging 2025-12-29 14:54:53 -10:00
J. Nick Koston
e844d5403e Merge branch 'esp32_ble_tracker' into integration 2025-12-29 14:37:45 -10:00
J. Nick Koston
d16b790243 [esp32_ble_tracker] Use stack buffer for hex formatting in very verbose logging 2025-12-29 14:34:08 -10:00
J. Nick Koston
2bcdee5a09 Merge branch 'hlk_fm22x_format' into integration 2025-12-29 14:25:27 -10:00
J. Nick Koston
c413b968f3 [hlk_fm22x] Use stack buffer for hex formatting in verbose logging 2025-12-29 14:23:39 -10:00
J. Nick Koston
f98ba2827c Merge branch 'i2c' into integration 2025-12-29 14:11:23 -10:00
J. Nick Koston
8f42b3d101 [i2c] Use stack buffer for hex formatting in verbose logging 2025-12-29 14:10:34 -10:00
J. Nick Koston
b7e27087b4 [espnow] Use stack buffer for hex formatting in verbose logging 2025-12-29 14:04:36 -10:00
J. Nick Koston
4230d39262 Merge branch 'esp32_improv' into integration 2025-12-29 13:58:27 -10:00
J. Nick Koston
fe9de00f54 [esp32_improv] Use stack buffer for hex formatting in verbose logging 2025-12-29 13:56:43 -10:00
J. Nick Koston
0aa275f475 Merge branch 'dev' into logger_esp8266 2025-12-29 13:08:24 -10:00
J. Nick Koston
c94f0e16ad Merge branch 'logger_esp8266' into integration 2025-12-29 13:07:19 -10:00
J. Nick Koston
c09f555e18 [logger] Exclude unused Arduino Serial objects on ESP8266 2025-12-29 13:06:33 -10:00
hsand
2e7cdad532 [pvvx_mithermometer] fix displaying negative numbers (#12735) 2025-12-29 13:58:38 -08:00
J. Nick Koston
70bd83f4f5 Merge remote-tracking branch 'swoboda1337/esp32-arduino-idf-source' into integration 2025-12-29 10:52:11 -10:00
J. Nick Koston
2e5403c743 [epaper_spi] Use stack buffer for hex formatting in command logging 2025-12-29 10:41:39 -10:00
J. Nick Koston
eafa86e227 Merge branch 'nextion' into integration 2025-12-29 10:30:49 -10:00
J. Nick Koston
4e93fdd37a [nextion] Use stack buffers for hex formatting in upload logging 2025-12-29 10:29:57 -10:00
J. Nick Koston
05761ba972 Merge branch 'tuya_format_hex' into integration 2025-12-29 10:25:22 -10:00
J. Nick Koston
6ca9220e5b Merge branch 'cse7766' into integration 2025-12-29 10:25:17 -10:00
J. Nick Koston
98f49fa970 [cse7766] Use stack buffer for hex formatting in debug logging 2025-12-29 10:24:32 -10:00
J. Nick Koston
22656095b6 missed one 2025-12-29 10:21:11 -10:00
J. Nick Koston
ede4511b12 Merge branch 'fix_opentherm_heap_alloc_logging' into integration 2025-12-29 10:15:47 -10:00
J. Nick Koston
33fafa2427 Merge branch 'shelly_dimmer' into integration 2025-12-29 10:15:37 -10:00
J. Nick Koston
5cd4df2de9 Merge branch 'mirage_protocol' into integration 2025-12-29 10:15:34 -10:00
J. Nick Koston
37b656323c Merge branch 'rc522' into integration 2025-12-29 10:15:31 -10:00
J. Nick Koston
b19f0b092a Merge branch 'haier_protocol' into integration 2025-12-29 10:15:27 -10:00
J. Nick Koston
f70b56bb04 Merge branch 'jsn_sr04t' into integration 2025-12-29 10:15:16 -10:00
J. Nick Koston
42333473c5 Merge branch 'a02yyuw' into integration 2025-12-29 10:15:11 -10:00
J. Nick Koston
159f9afcc0 Merge branch 'a01nyub' into integration 2025-12-29 10:15:08 -10:00
J. Nick Koston
9f0644cc02 Merge branch 'sonoff_d1' into integration 2025-12-29 10:14:52 -10:00
J. Nick Koston
b2b18b26c3 [sonoff_d1] Use stack buffer for hex formatting in logging 2025-12-29 10:14:17 -10:00
Jonathan Swoboda
c5be39f499 [esp32] Add IDF framework source for Arduino builds
Add ARDUINO_IDF_VERSION_LOOKUP table mapping Arduino framework versions
to their underlying ESP-IDF versions. When building with Arduino framework,
explicitly add the corresponding IDF framework source to platform_packages
to ensure consistent IDF versions are used.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 15:12:55 -05:00
J. Nick Koston
e1ce6b151d [jsn_sr04t] Use stack buffer for hex formatting in error logging 2025-12-29 10:09:27 -10:00
J. Nick Koston
0bc35f5086 [a02yyuw] Use stack buffer for hex formatting in error logging 2025-12-29 10:05:46 -10:00
J. Nick Koston
6ead7f82db [a01nyub] Use stack buffer for hex formatting in error logging 2025-12-29 10:03:25 -10:00
J. Nick Koston
1f832064d1 [opentherm] Replace heap-allocating format calls with printf format specifiers in debug_error 2025-12-29 09:58:13 -10:00
dependabot[bot]
636cccc6a3 Bump aioesphomeapi from 43.9.0 to 43.9.1 (#12724)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-29 09:55:26 -10:00
J. Nick Koston
b47462d64a [rc522] Use stack buffers for hex formatting in tag logging 2025-12-29 09:53:03 -10:00
J. Nick Koston
fdefbeb3dc [remote_base] Use stack buffer for hex formatting in haier protocol logging` 2025-12-29 09:44:08 -10:00
J. Nick Koston
3bd1a6fcf8 [remote_base] Use stack buffer for hex formatting in mirage protocol logging 2025-12-29 09:39:27 -10:00
J. Nick Koston
80551969f1 fix 2025-12-29 09:34:43 -10:00
J. Nick Koston
29a64b9113 [shelly_dimmer] Use stack buffer for hex formatting in command logging 2025-12-29 09:31:17 -10:00
Thomas Rupprecht
93e2a1bd1a [tests] improve mipi_spi variable naming (#12716) 2025-12-29 14:21:07 -05:00
Thomas Rupprecht
dd3beb5841 [tests] fix typo mipi tests (#12715) 2025-12-29 14:20:38 -05:00
Thomas Rupprecht
97af01c5ed [usb_host] sort esp32 variants (#12720) 2025-12-29 14:19:36 -05:00
J. Nick Koston
f1f0f9d7bf Merge remote-tracking branch 'upstream/ota_drop_md5' into integration 2025-12-29 08:45:46 -10:00
J. Nick Koston
8110d36f1c Merge branch 'dev' into ota_drop_md5 2025-12-29 08:45:00 -10:00
J. Nick Koston
7e362cdafc [ota] Use precision format specifier for auth logging (#12706)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-29 08:43:54 -10:00
Jonathan Swoboda
890d531cea [esp32] Bump to ESP-IDF 5.5.2, Arduino 3.3.5, platform 55.3.35 (#12681)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-12-29 11:35:54 -05:00
Swaptor
6a6c6b648f [internal_temperature] Add ESP32-C5 support (#12713)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-12-29 11:32:32 -05:00
J. Nick Koston
2f5e3193c7 Merge branch 'ota_drop_md5' into integration 2025-12-28 22:35:01 -10:00
J. Nick Koston
5f387e5d6c tweaks 2025-12-28 22:34:49 -10:00
J. Nick Koston
dbb87f53e1 Merge branch 'ota_drop_md5' into integration 2025-12-28 22:28:26 -10:00
J. Nick Koston
fe8f9c160d Merge branch 'ota_logging_cleanups' into integration 2025-12-28 22:27:29 -10:00
J. Nick Koston
d2217a2534 [ota] Remove MD5 authentication support 2025-12-28 22:26:04 -10:00
J. Nick Koston
8dd803a05e Update esphome/components/esphome/ota/ota_esphome.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-28 22:08:27 -10:00
J. Nick Koston
3ef0a7527f Merge branch 'ota_logging_cleanups' into integration 2025-12-28 22:03:11 -10:00
J. Nick Koston
bf1d3c534d [ota] Use precision format specifier for auth logging 2025-12-28 22:02:46 -10:00
J. Nick Koston
600c2453f4 Merge branch 'stack_copy_not_needed_wifi' into integration 2025-12-28 21:54:25 -10:00
J. Nick Koston
ab332b588f [wifi] Use precision format specifier for SSID logging to avoid stack copy 2025-12-28 21:53:53 -10:00
J. Nick Koston
495b128af9 Merge branch 'no_send_object_id' into integration 2025-12-28 21:41:59 -10:00
dependabot[bot]
d0673122a8 Bump aioesphomeapi from 43.8.0 to 43.9.0 (#12702) 2025-12-28 18:15:06 -10:00
J. Nick Koston
70038ea0a8 tweak 2025-12-28 17:42:31 -10:00
J. Nick Koston
463a5b6af9 tweak 2025-12-28 17:37:25 -10:00
J. Nick Koston
2756a027f7 Merge branch 'object_id_no_ram' into no_send_object_id 2025-12-28 17:17:05 -10:00
J. Nick Koston
64b61809a4 Merge branch 'dev' into object_id_no_ram 2025-12-28 17:16:35 -10:00
dependabot[bot]
5cbef3ef95 Bump aioesphomeapi from 43.7.0 to 43.8.0 (#12701) 2025-12-29 03:15:40 +00:00
dependabot[bot]
a1e0121330 Bump bleak from 2.0.0 to 2.1.0 (#12700)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-28 16:48:20 -10:00
dependabot[bot]
eb050ff13e Bump aioesphomeapi from 43.6.0 to 43.7.0 (#12699)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-28 16:48:08 -10:00
J. Nick Koston
d65284e760 Merge branch 'no_send_object_id' into integration 2025-12-28 15:34:55 -10:00
J. Nick Koston
7a091c0ac6 [api] Remove object_id from API protocol - clients compute it from name 2025-12-28 15:23:32 -10:00
J. Nick Koston
c81aec9e58 Merge branch 'dev' into object_id_no_ram 2025-12-28 14:51:14 -10:00
J. Nick Koston
550c8c40d3 Merge branch 'min_chip_revision' into integration 2025-12-28 13:43:22 -10:00
J. Nick Koston
cd3dadb3c9 reduce 2025-12-28 13:43:04 -10:00
J. Nick Koston
c6857cb5fe Merge branch 'min_chip_revision' into integration 2025-12-28 13:31:52 -10:00
J. Nick Koston
16315d72b6 define 2025-12-28 13:30:45 -10:00
J. Nick Koston
56a0fe0a1a Merge branch 'min_chip_revision' into integration 2025-12-28 13:26:08 -10:00
J. Nick Koston
90af7e3088 [esp32] Add minimum_chip_revision setting and log chip revision at startup 2025-12-28 13:20:06 -10:00
J. Nick Koston
07e844453d Merge branch 'esp8266_waveform' into integration 2025-12-27 22:02:28 -10:00
J. Nick Koston
080e461184 tweaks 2025-12-27 21:59:44 -10:00
J. Nick Koston
05f19ea644 tweaks 2025-12-27 21:56:02 -10:00
J. Nick Koston
8751c1d32c Merge branch 'esp8266_waveform' into integration 2025-12-27 21:38:58 -10:00
J. Nick Koston
ebe43228e3 tweaks 2025-12-27 21:33:08 -10:00
J. Nick Koston
0f8bef5543 fixes 2025-12-27 21:29:00 -10:00
J. Nick Koston
53fa89d0e3 tweaks 2025-12-27 21:27:34 -10:00
J. Nick Koston
ca3b9a0e55 [esp8266] Exclude unused waveform code to save ~596 bytes RAM 2025-12-27 21:24:24 -10:00
J. Nick Koston
f0894ab958 Merge branch 'get_peername_stack_save_ram' into integration 2025-12-27 19:06:25 -10:00
J. Nick Koston
c410171a63 remove old way 2025-12-27 19:06:09 -10:00
J. Nick Koston
5f7863af21 Merge branch 'get_peername_stack_save_ram' into integration 2025-12-27 18:58:47 -10:00
J. Nick Koston
95ae7caf24 mark final 2025-12-27 18:58:35 -10:00
J. Nick Koston
4d6bc262da Merge branch 'get_peername_stack_save_ram' into integration 2025-12-27 18:54:31 -10:00
J. Nick Koston
e698a88380 fix 2025-12-27 18:54:11 -10:00
J. Nick Koston
ee94ee7e59 Merge branch 'get_peername_stack_save_ram' into integration 2025-12-27 18:51:00 -10:00
J. Nick Koston
30b169a4cf fix 2025-12-27 18:50:34 -10:00
J. Nick Koston
47c475a03c wip 2025-12-27 18:40:14 -10:00
J. Nick Koston
a522447bed Merge branch 'get_peername_stack_save_ram' into integration 2025-12-27 18:36:10 -10:00
J. Nick Koston
e15bac46cb missed one 2025-12-27 18:35:57 -10:00
J. Nick Koston
6f5900713c wip 2025-12-27 18:32:14 -10:00
J. Nick Koston
dafe9da1eb Merge branch 'get_peername_stack_save_ram' into integration 2025-12-27 18:24:15 -10:00
J. Nick Koston
b8d246b706 fix 2025-12-27 18:24:01 -10:00
J. Nick Koston
23d88933fd Merge branch 'get_peername_stack_save_ram' into integration 2025-12-27 18:20:47 -10:00
J. Nick Koston
274b1e26ce tweak 2025-12-27 18:20:29 -10:00
J. Nick Koston
dc51abbd82 Merge branch 'get_peername_stack_save_ram' into integration 2025-12-27 18:18:55 -10:00
J. Nick Koston
0217c130dd tweak 2025-12-27 18:15:11 -10:00
J. Nick Koston
1290929684 tweak 2025-12-27 18:14:11 -10:00
J. Nick Koston
96b2888505 tweak 2025-12-27 18:06:57 -10:00
J. Nick Koston
d2bab26e67 tweak 2025-12-27 18:05:26 -10:00
J. Nick Koston
d404e37449 reduce 2025-12-27 17:49:25 -10:00
J. Nick Koston
f9659fc693 reduce 2025-12-27 17:49:04 -10:00
J. Nick Koston
ce71e7bccd Merge branch 'get_peername_stack_save_ram' into integration 2025-12-27 17:10:50 -10:00
J. Nick Koston
f4cb379d6b tweaks 2025-12-27 17:01:10 -10:00
J. Nick Koston
49e0e66aee Merge branch 'dev' into get_peername_stack_save_ram 2025-12-27 16:51:46 -10:00
J. Nick Koston
3d82118bd5 Merge branch 'dev' into api_avoid_copies 2025-12-27 16:45:43 -10:00
J. Nick Koston
92f44da2cf Merge branch 'tuya_format_hex' into integration 2025-12-27 16:34:37 -10:00
J. Nick Koston
db82a3f5f8 [tuya] Use stack buffers for hex logging to avoid heap allocations 2025-12-27 16:10:38 -10:00
J. Nick Koston
e6891d4027 Merge branch 'ldxxxx_no_heap' into integration 2025-12-27 15:54:01 -10:00
J. Nick Koston
60c6d94083 remove tests 2025-12-27 15:48:43 -10:00
J. Nick Koston
e1a5830d9f Merge branch 'zwave_no_alloc_hex' of https://github.com/esphome/esphome into zwave_no_alloc_hex 2025-12-27 15:46:23 -10:00
J. Nick Koston
783604b8b4 [ld2410][ld2412][ld2450] Use stack buffers for hex logging 2025-12-27 15:45:17 -10:00
J. Nick Koston
53ad49086d fixes 2025-12-27 15:40:32 -10:00
J. Nick Koston
a2d25b532a Merge branch 'zwave_no_alloc_hex' into integration 2025-12-27 15:23:43 -10:00
J. Nick Koston
05c51b6ced Add isolated tests for hex formatting functions 2025-12-27 15:18:47 -10:00
J. Nick Koston
89f326be30 reduce 2025-12-27 15:12:30 -10:00
J. Nick Koston
38850a9ab3 more dry 2025-12-27 15:08:44 -10:00
J. Nick Koston
4d4498e81f fix max 2025-12-27 14:57:42 -10:00
J. Nick Koston
d1707ac4d6 Merge branch 'zwave_no_alloc_hex' into integration 2025-12-27 14:39:36 -10:00
J. Nick Koston
61970bd1de [core] Add format_hex_pretty_to buffer helper and reduce code duplication 2025-12-27 14:34:33 -10:00
J. Nick Koston
09f03dcf0c Merge branch 'mqtt_ip_no_alloc' into integration 2025-12-27 14:08:18 -10:00
J. Nick Koston
adaebd4b4e [mqtt] Avoid heap allocations when logging IP addresses 2025-12-27 14:07:07 -10:00
J. Nick Koston
9f2d34bacb Merge remote-tracking branch 'origin/no_heap_alloc_start_dnsserver' into integration 2025-12-27 14:03:44 -10:00
J. Nick Koston
6f780a63ab Merge branch 'udp_multicast_avoid_heap' into integration 2025-12-27 14:02:12 -10:00
J. Nick Koston
9b2488cd8d [udp] Avoid heap allocations when joining multicast groups 2025-12-27 14:00:38 -10:00
J. Nick Koston
e76bc6b357 Merge remote-tracking branch 'origin/integration' into integration 2025-12-27 12:35:36 -10:00
J. Nick Koston
0867e96585 Merge branch 'esp-idf-5.5.2' into integration 2025-12-27 12:35:24 -10:00
J. Nick Koston
1618c69923 Merge remote-tracking branch 'upstream/dev' into esp-idf-5.5.2 2025-12-27 12:02:07 -10:00
Jonathan Swoboda
45e61f100c [core] Replace USE_ESP_IDF with USE_ESP32 across components (#12673)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-12-27 11:59:55 -10:00
J. Nick Koston
6dd1175fe7 Merge branch 'improv_stack_format' into integration 2025-12-27 11:30:02 -10:00
J. Nick Koston
fe651f1b8d Merge branch 'wifi_no_heap_logging_cap_portal' into integration 2025-12-27 11:29:53 -10:00
J. Nick Koston
3768a269ad nolint 2025-12-27 11:29:29 -10:00
J. Nick Koston
b9d80a5ef3 [esp32_improv] Use stack buffer for URL formatting to avoid heap allocation 2025-12-27 11:27:28 -10:00
J. Nick Koston
1aebe90ad5 [esp32_improv] Use stack buffer for URL formatting to avoid heap allocation 2025-12-27 11:26:24 -10:00
J. Nick Koston
06c4325525 lint 2025-12-27 11:21:44 -10:00
Jonathan Swoboda
343316ac2d [esp32] Bump to ESP-IDF 5.5.2, Arduino 3.3.5, platform 55.3.35
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-27 14:33:32 -05:00
J. Nick Koston
cc0b63a277 fix 2025-12-27 09:32:22 -10:00
J. Nick Koston
4271a64ce4 fix 2025-12-27 09:31:06 -10:00
J. Nick Koston
52c692c99b [wifi] Use stack buffers for IP address logging to avoid heap allocations 2025-12-27 09:26:44 -10:00
J. Nick Koston
a8fb40c946 [wifi] Use stack buffers for IP address logging to avoid heap allocations 2025-12-27 09:24:17 -10:00
J. Nick Koston
0b621bb0a3 [captive_portal] Use stack buffer for IP address logging in DNS server 2025-12-27 09:07:44 -10:00
J. Nick Koston
7bc7089fbe Merge branch 'wifi_alloc_during_connect' into integration 2025-12-27 08:58:11 -10:00
J. Nick Koston
32880e3d5a [wifi] Use wifi_ssid_to() to avoid heap allocations in automation and connection checks 2025-12-27 08:57:39 -10:00
J. Nick Koston
206793d4ab Merge remote-tracking branch 'upstream/dev' into integration 2025-12-27 08:52:13 -10:00
J. Nick Koston
5e99dd14ae [ethernet] Eliminate heap allocations in dump_config logging (#12665) 2025-12-27 08:36:35 -10:00
J. Nick Koston
a6097f4a0f [wifi] Eliminate heap allocations in dump_config logging (#12664)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-27 08:36:19 -10:00
J. Nick Koston
f243e609a5 [wifi] Use StringRef and std::span in WiFiConnectStateListener to avoid allocations (#12672) 2025-12-27 08:35:58 -10:00
J. Nick Koston
be0bf1e5b9 [lvgl] Fix lambdas in canvas actions called from outside LVGL context (#12671) 2025-12-27 08:35:36 -10:00
J. Nick Koston
a275f37135 [udp] Use stack buffer for listen address logging in dump_config (#12667) 2025-12-27 08:35:16 -10:00
J. Nick Koston
e9f2d75aab [core] Add format_hex_to helper for zero-allocation hex formatting (#12670) 2025-12-27 08:34:45 -10:00
J. Nick Koston
34067f8b15 [esp8266] Native OTA backend to reduce Arduino dependencies (#12675)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-27 08:29:15 -10:00
J. Nick Koston
47ae027026 Merge branch 'esp8266_native_framework_update' into integration 2025-12-26 23:04:31 -10:00
J. Nick Koston
cfe9e6204b preen 2025-12-26 23:01:18 -10:00
J. Nick Koston
547aa59c18 Merge branch 'esp8266_native_framework_update' into integration 2025-12-26 22:37:59 -10:00
J. Nick Koston
5b9c7d1322 Update esphome/components/ota/ota_backend_esp8266.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-26 22:36:12 -10:00
J. Nick Koston
d0ba608ffa add comment 2025-12-26 22:35:27 -10:00
J. Nick Koston
c91f56171b Update esphome/components/ota/ota_backend_esp8266.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-26 22:34:22 -10:00
J. Nick Koston
15ad89f66d Update esphome/components/ota/ota_backend_esp8266.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-26 22:33:38 -10:00
J. Nick Koston
8f0de69e9f Merge branch 'esp8266_native_framework_update' into integration 2025-12-26 22:23:40 -10:00
J. Nick Koston
37de782e3e guard 2025-12-26 22:13:10 -10:00
J. Nick Koston
a5574bbabe dry 2025-12-26 21:59:47 -10:00
J. Nick Koston
1bea4df45e guard 2025-12-26 21:51:09 -10:00
J. Nick Koston
57829ddd76 fixes 2025-12-26 20:23:13 -10:00
J. Nick Koston
99722fb04f fixes 2025-12-26 20:22:16 -10:00
J. Nick Koston
faa4cf7483 fixes 2025-12-26 20:19:25 -10:00
J. Nick Koston
16e96dfbc0 fixes 2025-12-26 20:18:25 -10:00
J. Nick Koston
062195be95 native framework updater PoC 2025-12-26 20:12:27 -10:00
J. Nick Koston
b2133c75f1 native framework updater PoC 2025-12-26 20:07:20 -10:00
J. Nick Koston
655a746e0d Merge branch 'wifi_listeners' into integration 2025-12-26 14:57:39 -10:00
J. Nick Koston
a2ea545e10 make the bot happy 2025-12-26 14:57:26 -10:00
J. Nick Koston
6fe5d14b3f Merge branch 'wifi_listeners' into integration 2025-12-26 14:44:41 -10:00
J. Nick Koston
f446860166 might as well make it span 2025-12-26 14:43:01 -10:00
J. Nick Koston
02e8603051 Merge branch 'wifi_listeners' into integration 2025-12-26 14:35:32 -10:00
J. Nick Koston
3fe4e18dc4 [wifi] Use StringRef for WiFiConnectStateListener to avoid heap allocation 2025-12-26 14:34:06 -10:00
J. Nick Koston
b221673ba7 Merge branch 'ethernet_logging_less_alloc' into integration 2025-12-26 13:44:44 -10:00
J. Nick Koston
e711cd0e41 dry it up 2025-12-26 13:39:57 -10:00
J. Nick Koston
307489cd59 missed one 2025-12-26 13:33:01 -10:00
J. Nick Koston
e7c0d13500 Merge branch 'dev' into ethernet_logging_less_alloc 2025-12-26 12:56:06 -10:00
J. Nick Koston
bdc087148a [wifi_info] Reduce heap allocations in text sensor formatting (#12660) 2025-12-26 12:52:41 -10:00
J. Nick Koston
5a2e0612a8 [web_server] Use C++17 nested namespace syntax (#12663) 2025-12-26 08:44:34 -10:00
J. Nick Koston
f1fecd22e3 [web_server] Move HTTP header strings to flash on ESP8266 (#12668) 2025-12-26 08:44:17 -10:00
J. Nick Koston
0919017d49 [wifi] Avoid unnecessary string copy in failed connection logging (#12659) 2025-12-26 08:44:03 -10:00
J. Nick Koston
963f594c9e [text_sensor] Return state by const reference to avoid copies (#12661) 2025-12-26 07:58:46 -10:00
J. Nick Koston
4f70663658 [alarm_control_panel] Use C++17 nested namespace and remove unused include (#12662) 2025-12-26 07:57:33 -10:00
J. Nick Koston
3f20a54240 Merge branch 'web_server_more_strings_ram' into integration 2025-12-25 23:07:17 -10:00
J. Nick Koston
e9e301c835 cleanup 2025-12-25 23:05:29 -10:00
J. Nick Koston
8c90477387 more 2025-12-25 23:02:22 -10:00
J. Nick Koston
a394fe8ad2 Merge branch 'web_server_more_strings_ram' into integration 2025-12-25 22:52:46 -10:00
J. Nick Koston
d642e9d85e [web_server] Move HTTP header strings to flash on ESP8266 2025-12-25 22:52:01 -10:00
J. Nick Koston
fa05018b2c Merge branch 'object_id_no_ram' into integration 2025-12-25 22:26:56 -10:00
J. Nick Koston
63d7ab0d40 Merge branch 'udp_listen_logging_alloc' into integration 2025-12-25 22:03:04 -10:00
J. Nick Koston
51f95c7f9a [udp] Use stack buffer for listen address logging in dump_config 2025-12-25 22:01:57 -10:00
J. Nick Koston
2ac67b59e8 Merge branch 'ethernet_logging_less_alloc' into integration 2025-12-25 21:51:39 -10:00
J. Nick Koston
0767df02d9 [ethernet] Eliminate heap allocations in dump_config logging 2025-12-25 21:50:54 -10:00
J. Nick Koston
984822388d Merge branch 'web_server_namespace' into integration 2025-12-25 21:25:32 -10:00
J. Nick Koston
cc49ec82bf [web_server] Use C++17 nested namespace syntax 2025-12-25 21:24:47 -10:00
J. Nick Koston
cc18092e7a Merge branch 'alarm_control_panel_cleanup' into integration 2025-12-25 21:17:59 -10:00
J. Nick Koston
825d12553e [alarm_control_panel] Use C++17 nested namespace and remove unused include 2025-12-25 21:17:13 -10:00
J. Nick Koston
0bd82b19b3 Merge branch 'text_sensor_avoid_copies' into integration 2025-12-25 21:10:41 -10:00
J. Nick Koston
460792e180 [text_sensor] Return state by const reference to avoid copies 2025-12-25 21:09:49 -10:00
J. Nick Koston
5411008c49 Merge branch 'wifi_info_less_alloc' into integration 2025-12-25 20:47:01 -10:00
J. Nick Koston
9e13f6ac4c copilot is wrong, add comment 2025-12-25 20:46:20 -10:00
J. Nick Koston
b8cb6fedb3 address copilot review comments 2025-12-25 20:38:50 -10:00
J. Nick Koston
68f36ae736 address copilot review comments 2025-12-25 20:38:38 -10:00
J. Nick Koston
6cbe3e306b Merge branch 'wifi_info_less_alloc' into integration 2025-12-25 16:03:31 -10:00
J. Nick Koston
cae7163741 fixes 2025-12-25 16:03:12 -10:00
J. Nick Koston
10aee92762 Merge branch 'wifi_avoid_copy_logging' into integration 2025-12-25 16:01:04 -10:00
J. Nick Koston
736a1bb019 Merge branch 'wifi_info_less_alloc' into integration 2025-12-25 16:00:58 -10:00
J. Nick Koston
ca652b2065 [wifi_info] Reduce heap allocations in text sensor formatting 2025-12-25 15:58:17 -10:00
J. Nick Koston
7608b8ee84 [wifi] Avoid unnecessary string copy in failed connection logging 2025-12-25 15:06:36 -10:00
J. Nick Koston
d490594609 Merge remote-tracking branch 'upstream/response_api' into integration 2025-12-25 14:51:28 -10:00
J. Nick Koston
8715a60b7a [api] Use StringRef in send_action_response and send_execute_service_response 2025-12-25 14:48:19 -10:00
J. Nick Koston
dd99c565ca Merge remote-tracking branch 'upstream/siren_zero_copy' into integration 2025-12-25 14:37:45 -10:00
J. Nick Koston
20df6a7f9a [api] Use pointer to FixedVector for siren tones field 2025-12-25 14:36:06 -10:00
J. Nick Koston
3e4631baa9 Merge remote-tracking branch 'upstream/bytes_zero_copy_default_api' into integration 2025-12-25 14:20:31 -10:00
J. Nick Koston
6af34f1e2a Merge remote-tracking branch 'upstream/handle_action_response_opt' into integration 2025-12-25 14:20:28 -10:00
J. Nick Koston
0ba15b51c6 Merge remote-tracking branch 'upstream/voice_assist_zero_copy' into integration 2025-12-25 14:20:22 -10:00
J. Nick Koston
8004602ef2 [voice_assistant] Use zero-copy buffer access for audio data` 2025-12-25 14:14:06 -10:00
J. Nick Koston
a3ec57eaf4 [api] Use StringRef in handle_action_response to avoid temporary string 2025-12-25 14:01:40 -10:00
J. Nick Koston
98460ac828 [api] Auto-generate zero-copy pointer access for incoming API bytes fields 2025-12-25 13:56:08 -10:00
J. Nick Koston
7c739592a8 Merge branch 'dev' into get_peername_stack_save_ram 2025-12-25 09:02:44 -10:00
J. Nick Koston
2b10408e28 Merge remote-tracking branch 'upstream/string_ref_for_all_incoming_api_strings' into integration 2025-12-25 09:02:03 -10:00
J. Nick Koston
33d1efe27c tidy 2025-12-24 22:21:00 -10:00
J. Nick Koston
0e9aaf1a8b fixes 2025-12-24 22:07:48 -10:00
J. Nick Koston
7f4fad74c2 fixes 2025-12-24 22:07:35 -10:00
J. Nick Koston
8b72c3c0ef [api] Auto-generate StringRef for incoming API string fields 2025-12-24 22:05:19 -10:00
dependabot[bot]
958a35e262 Bump aioesphomeapi from 43.5.0 to 43.6.0 (#12644)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-24 14:17:52 -10:00
J. Nick Koston
da1955fefc dry up tests 2025-12-23 07:54:52 -10:00
J. Nick Koston
8505a4dfaf dry up tests 2025-12-23 07:52:33 -10:00
J. Nick Koston
071e42d4e7 Merge remote-tracking branch 'origin/object_id_no_ram' into object_id_no_ram 2025-12-23 07:46:07 -10:00
J. Nick Koston
38beb613c2 simplify 2025-12-23 07:45:46 -10:00
J. Nick Koston
058c637b59 Merge branch 'dev' into object_id_no_ram 2025-12-23 06:59:16 -10:00
J. Nick Koston
0c566c6f00 [core] Deprecate get_object_id() and migrate remaining usages to get_object_id_to() (#12629) 2025-12-23 06:59:07 -10:00
Jonathan Swoboda
ba73289b28 Merge branch 'release' into dev 2025-12-23 11:17:15 -05:00
Jonathan Swoboda
99f7e9aeb7 Merge pull request #12632 from esphome/bump-2025.12.2
2025.12.2
2025-12-23 11:17:01 -05:00
Jonathan Swoboda
ebb6babb3d Fix hash 2025-12-23 09:26:38 -05:00
Jonathan Swoboda
0922f240e0 Bump version to 2025.12.2 2025-12-23 09:23:04 -05:00
Jonathan Swoboda
c8fb694dcb [cc1101] Fix packet mode RSSI/LQI (#12630)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-23 09:23:04 -05:00
J. Nick Koston
6054685dae [esp32_camera] Throttle frame logging to reduce overhead and improve throughput (#12586) 2025-12-23 09:23:04 -05:00
Anna Oake
61ec3508ed [cc1101] Fix option defaults and move them to YAML (#12608) 2025-12-23 09:23:04 -05:00
Leo Bergolth
086ec770ea send NIL ("-") as timestamp if time source is not valid (#12588) 2025-12-23 09:23:04 -05:00
Stuart Parmenter
b055f5b4bf [hub75] Bump esp-hub75 version to 0.1.7 (#12564) 2025-12-23 09:23:00 -05:00
Eduard Llull
726db746c8 [display_menu_base] Call on_value_ after updating the select (#12584) 2025-12-23 09:21:54 -05:00
Keith Burzinski
1922455fa7 [wifi] Fix for wifi_info when static IP is configured (#12576) 2025-12-23 09:21:54 -05:00
Thomas Rupprecht
dc943d7e7a [pca9685,sx126x,sx127x] Use frequency/float_range check (#12490)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-23 09:21:54 -05:00
Jonathan Swoboda
ffefa8929e [cc1101] Fix packet mode RSSI/LQI (#12630)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-23 09:05:48 -05:00
J. Nick Koston
89ef523990 tweak 2025-12-23 01:01:20 -10:00
J. Nick Koston
0ec741c425 one more case 2025-12-23 00:48:25 -10:00
J. Nick Koston
c265436b07 cover 2025-12-23 00:45:25 -10:00
J. Nick Koston
04a75cf200 cover 2025-12-23 00:24:45 -10:00
J. Nick Koston
83598d6798 cover 2025-12-23 00:21:20 -10:00
J. Nick Koston
fa39b6bebd fixes 2025-12-23 00:16:53 -10:00
J. Nick Koston
1beec0ecf1 bug for bug compat 2025-12-23 00:05:12 -10:00
J. Nick Koston
3ef4e0bc47 fixes 2025-12-23 00:00:03 -10:00
J. Nick Koston
bda2db9184 Merge branch 'migrate_remain_get_object_id' into object_id_no_ram 2025-12-22 23:19:25 -10:00
J. Nick Koston
3009da14f1 tweaks 2025-12-22 23:17:15 -10:00
J. Nick Koston
d334d0d458 tweaks 2025-12-22 23:16:28 -10:00
J. Nick Koston
25b340cbbf Merge branch 'migrate_remain_get_object_id' into object_id_no_ram 2025-12-22 23:13:47 -10:00
J. Nick Koston
fa2bc21d3d tweaks 2025-12-22 23:13:28 -10:00
J. Nick Koston
83d65cff5d Merge branch 'migrate_remain_get_object_id' into object_id_no_ram 2025-12-22 23:12:09 -10:00
J. Nick Koston
9205cb3d67 tweaks 2025-12-22 23:11:42 -10:00
J. Nick Koston
f9a4a8a82e tweaks 2025-12-22 23:11:12 -10:00
J. Nick Koston
2d6b9b3888 more cover 2025-12-22 22:06:48 -10:00
J. Nick Koston
da8e23f968 more cover 2025-12-22 21:58:58 -10:00
J. Nick Koston
4bec2dc75c tweak 2025-12-22 21:51:57 -10:00
J. Nick Koston
6d5ab00385 tweak 2025-12-22 21:42:50 -10:00
J. Nick Koston
3e1db740ea cover 2025-12-22 21:40:10 -10:00
J. Nick Koston
e13f48b348 preen 2025-12-22 20:10:36 -10:00
J. Nick Koston
9f2d2eed8c preen 2025-12-22 20:08:38 -10:00
J. Nick Koston
b6b871cb73 preen 2025-12-22 20:07:02 -10:00
J. Nick Koston
452246e1c5 [core] Remove object_id RAM storage - no longer in hot path after #12627 2025-12-22 20:01:57 -10:00
J. Nick Koston
7d5342bca5 [logger] Host: Use fwrite() with explicit length and remove platform branching (#12628) 2025-12-22 16:45:22 -10:00
J. Nick Koston
7944fe6993 [core] Deprecate get_object_id() and migrate remaining usages to get_object_id_to() 2025-12-22 15:13:59 -10:00
J. Nick Koston
b4c92dd8cb [logger] Zephyr: Use k_str_out() with known length instead of printk() (#12619) 2025-12-22 14:29:47 -10:00
eoasmxd
1b31253287 Add Event Component to UART (#11765)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-12-22 12:19:48 -10:00
J. Nick Koston
6ae3d9c769 Merge remote-tracking branch 'upstream/dev' into integration 2025-12-22 12:09:02 -10:00
J. Nick Koston
af0d4d2c2c [web_server] Use stack buffers for value formatting to reduce flash usage (#12575) 2025-12-22 21:56:07 +00:00
J. Nick Koston
f238f93312 [core] Move comment to PROGMEM on ESP8266 (#12554) 2025-12-22 21:37:51 +00:00
J. Nick Koston
bdbe72b7f1 [web_server] Make internal JSON helper methods private (#12624) 2025-12-22 11:14:11 -10:00
J. Nick Koston
c8b531ac06 [safe_mode] Defer preference sync in clean_rtc to avoid blocking event loop (#12625) 2025-12-22 11:13:51 -10:00
J. Nick Koston
689e1d6ca0 Merge branch 'web_server_stack_format' into integration 2025-12-22 11:11:56 -10:00
J. Nick Koston
7b82b3b584 reduce churn 2025-12-22 11:11:16 -10:00
J. Nick Koston
36c0553cf7 Merge branch 'web_server_stack_format' into integration 2025-12-22 11:09:56 -10:00
J. Nick Koston
d3b3358527 inline it 2025-12-22 11:09:38 -10:00
J. Nick Koston
b950d65a7b Merge branch 'move_comment_build_info' into integration 2025-12-22 10:56:34 -10:00
J. Nick Koston
b2a6e6e078 undeprecate get_comment 2025-12-22 10:53:11 -10:00
J. Nick Koston
972cf01763 Merge remote-tracking branch 'origin/safe_mode_blocking_on_success' into integration 2025-12-22 10:49:24 -10:00
J. Nick Koston
029df4ff3d [safe_mode] Remove unnecessary blocking sync from successful boot reset 2025-12-22 10:48:10 -10:00
J. Nick Koston
21ba0e5a2b Merge remote-tracking branch 'origin/safe_mode_blocking_on_success' into integration 2025-12-22 10:46:10 -10:00
J. Nick Koston
8bb57f90de Merge branch 'web_server_json_priv' into integration 2025-12-22 10:45:59 -10:00
J. Nick Koston
145d09c8dd [safe_mode] Remove unnecessary blocking sync from successful boot reset 2025-12-22 10:41:47 -10:00
Jonathan Swoboda
918bc4b74f [esp32] Remove remaining using_esp_idf checks (#12623)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-22 15:41:14 -05:00
J. Nick Koston
5373393714 [safe_mode] Remove unnecessary blocking sync from successful boot reset 2025-12-22 10:39:30 -10:00
J. Nick Koston
21f6fefd98 [web_server] Make internal JSON helper methods private 2025-12-22 10:31:24 -10:00
J. Nick Koston
efc30ed198 Merge remote-tracking branch 'upstream/dev' into integration 2025-12-22 10:13:57 -10:00
J. Nick Koston
63005eaa06 Merge remote-tracking branch 'swoboda1337/deprecate-using-esp-idf' into integration 2025-12-22 09:20:05 -10:00
Keith Burzinski
08c0f65f30 [sprinkler] Remove internal latching valve support (#12603) 2025-12-22 14:13:18 -05:00
Keith Burzinski
cd45fe0c3a [thermostat] Optimizations to reduce binary size (#12621) 2025-12-22 14:13:03 -05:00
Jonathan Swoboda
676fbf6161 Fix 2025-12-22 14:08:27 -05:00
Jonathan Swoboda
fb009f47f1 Deprecate again 2025-12-22 14:08:04 -05:00
Jonathan Swoboda
84b5d9b21c [core] Remove deprecated config options from before 2025 (#12622)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-22 14:00:12 -05:00
J. Nick Koston
b272966d19 Merge branch 'deprecate-using-esp-idf' into integration 2025-12-22 08:48:51 -10:00
J. Nick Koston
b0c99ec1ce Merge branch 'cleanup-old-deprecations' into integration 2025-12-22 08:48:47 -10:00
J. Nick Koston
218c8e4d75 Merge remote-tracking branch 'upstream/dev' into integration 2025-12-22 08:48:37 -10:00
J. Nick Koston
2a53a89cee Merge branch 'dev' into esp8266_prefs_avoid_heap 2025-12-22 07:58:00 -10:00
J. Nick Koston
b191461929 Merge branch 'dev' into move_comment_build_info 2025-12-22 07:57:34 -10:00
J. Nick Koston
6383fe4598 [core] Add zero-allocation object_id methods (#12578) 2025-12-22 07:56:33 -10:00
J. Nick Koston
265ad9d264 [esp32_camera] Reduce loop overhead and improve frame latency with wake_loop_threadsafe (#12601) 2025-12-22 07:55:28 -10:00
J. Nick Koston
1bdbc4cb85 [esp32_ble] Avoid string allocation when setting BLE device name (#12579) 2025-12-22 07:54:55 -10:00
J. Nick Koston
1756fc31b0 [api] Use union for iterators to reduce APIConnection size by ~16 bytes (#12563) 2025-12-22 07:54:17 -10:00
Jonathan Swoboda
03db8e4f54 Fix 2025-12-22 12:22:04 -05:00
J. Nick Koston
74b075d3cf [codegen] Add static storage class to global variables for size optimization (#12616) 2025-12-22 07:03:17 -10:00
Jonathan Swoboda
ce86f01cba Change 2025-12-22 12:02:26 -05:00
Jonathan Swoboda
bee5847464 Fix 2025-12-22 11:34:49 -05:00
Jonathan Swoboda
4ffbdd9a3a Fix 2025-12-22 11:23:43 -05:00
Jonathan Swoboda
c5ac62676c Fix 2025-12-22 11:19:56 -05:00
Jonathan Swoboda
63b8fa004c [core] Fix mdns and network for using_esp_idf deprecation
- mdns: Remove ESPmDNS Arduino library for ESP32, use IDF component for both frameworks
- network: Use using_arduino for IPv6 to maintain Arduino behavior (always True)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-22 11:09:37 -05:00
Jonathan Swoboda
66b46ea81e [core] Deprecate using_esp_idf, replace with is_esp32
Arduino on ESP32 now builds ESP-IDF as a component, so add_idf_sdkconfig_option()
and add_idf_component() work with both Arduino and ESP-IDF frameworks.

The using_esp_idf property is deprecated and now emits a warning. All internal
usages have been replaced with is_esp32.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-22 11:00:27 -05:00
Jonathan Swoboda
fc019bf3e3 [core] Remove deprecated config options from before 2025
Remove old deprecated configuration options that have been showing
error messages for years:

- bedjet/climate: ble_client_id, time_id, receive_timeout (2022)
- bh1750: resolution, measurement_duration (2022)
- ethernet: enable_mdns (2021)
- wifi: enable_mdns (2021)
- i2c: multiplexer (2021)
- uart: invert (2021)
- tca9548a: scan (2021)
- tuya/light: rgb_datapoint, hsv_datapoint (2023)
- remote_base: receiver_id in triggers/dumpers, coolix data (2020-2023)
- sensor: last_reset_type (2021)
- template/switch: restore_state (2023)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-22 10:46:53 -05:00
J. Nick Koston
da872dcbf3 Merge branch 'web_server_stack_format' into integration 2025-12-21 22:26:12 -10:00
J. Nick Koston
a015cbedfe Merge branch 'dev' into api_avoid_copies 2025-12-21 22:03:47 -10:00
J. Nick Koston
c7006f8c33 Merge remote-tracking branch 'upstream/dev' into web_server_stack_format 2025-12-21 22:01:29 -10:00
Clint Armstrong
52eb08f48f [thermostat] Enhance timer behavior for immediate response to duration changes (#12610) 2025-12-21 23:52:17 -06:00
J. Nick Koston
fe84aba2ee Merge branch 'storage_class_optimize' into integration 2025-12-21 19:30:10 -10:00
J. Nick Koston
0d993691d4 [logger] RP2040: Use write() with known length instead of println() (#12615) 2025-12-21 17:59:30 -10:00
J. Nick Koston
f17a0000aa lvgl has a special case 2025-12-21 17:41:48 -10:00
J. Nick Koston
8db6ff4039 Merge branch 'storage_class_optimize' into integration 2025-12-21 17:33:16 -10:00
J. Nick Koston
ff808618da better to be a kw 2025-12-21 17:27:49 -10:00
J. Nick Koston
57baf7ac7b [codegen] Add static storage class to global variables for size optimization 2025-12-21 17:20:01 -10:00
J. Nick Koston
da8c4cd654 Merge remote-tracking branch 'upstream/dev' into integration 2025-12-21 12:13:04 -10:00
Douwe
39926909af [water_heater] (1/4) Implement API/Core/component for new water_heater component (#12498)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-12-21 11:36:34 -10:00
J. Nick Koston
637e032528 [esp32_camera] Throttle frame logging to reduce overhead and improve throughput (#12586) 2025-12-21 09:04:43 -10:00
Anna Oake
d89eaf5bf6 [cc1101] Fix option defaults and move them to YAML (#12608) 2025-12-21 13:04:17 -05:00
J. Nick Koston
9aff4a15a3 Merge branch 'esp32_camera_latancy_reduce' into integration 2025-12-21 07:53:18 -10:00
J. Nick Koston
dbf494fd98 Merge branch 'fix_slow_esp32_camera_at_high_fps' into esp32_camera_latancy_reduce 2025-12-21 07:53:07 -10:00
J. Nick Koston
219cf26d98 tweak logging 2025-12-21 07:36:25 -10:00
J. Nick Koston
bf617c3279 [web_server] Replace str_sprintf with stack buffers (#12592) 2025-12-21 07:32:05 -10:00
J. Nick Koston
c70eab931e [api] Add zero-copy support for Home Assistant state response messages (#12585) 2025-12-21 07:31:54 -10:00
J. Nick Koston
a799ac6488 [syslog] Eliminate heap allocations in log path (#12589) 2025-12-21 07:10:27 -10:00
polyfloyd
5a36cea5ec Add nix files to gitignore (#12604) 2025-12-21 09:26:03 -05:00
J. Nick Koston
60756db06d [syslog] Use C++17 nested namespace syntax (#12594) 2025-12-21 02:47:37 -06:00
Keith Burzinski
2113858f89 [sprinkler] Squash a few bugs + minor optimization (#12436) 2025-12-21 02:45:24 -06:00
J. Nick Koston
14ea235939 Merge branch 'esp32_camera_latancy_reduce' into integration 2025-12-20 21:59:01 -10:00
J. Nick Koston
26f1be40dc pro 2025-12-20 21:58:24 -10:00
J. Nick Koston
0467fdbb61 Merge branch 'esp32_camera_latancy_reduce' into integration 2025-12-20 21:31:46 -10:00
J. Nick Koston
c1463a569c reorder 2025-12-20 21:31:30 -10:00
J. Nick Koston
6dd41a14c4 try send right away 2025-12-20 21:17:19 -10:00
J. Nick Koston
9855d86616 try send right away 2025-12-20 21:10:22 -10:00
J. Nick Koston
ffe459e666 [esp32_camera] Reduce loop overhead and improve frame latency with wake_loop_threadsafe 2025-12-20 15:30:24 -10:00
J. Nick Koston
1f15023d30 Merge remote-tracking branch 'upstream/dev' into integration 2025-12-20 14:49:34 -10:00
dependabot[bot]
e89fe9b945 Bump aioesphomeapi from 43.4.0 to 43.5.0 (#12599)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-20 23:59:48 +00:00
dependabot[bot]
f1362cd9fe Bump aioesphomeapi from 43.3.0 to 43.4.0 (#12597)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-20 22:37:10 +00:00
Frédéric Metrich
bf554a58ef [const] Add CONF_ON_DATA and consolidate definitions (#12595)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 12:17:09 -10:00
J. Nick Koston
9d01357e8a Merge branch 'ha_state_only_copy_state' into integration 2025-12-20 11:46:04 -10:00
J. Nick Koston
d6cf80f95a Merge remote-tracking branch 'origin/syslog_no_heap' into integration 2025-12-20 11:26:06 -10:00
J. Nick Koston
8d14c1ceb1 Merge remote-tracking branch 'origin/no_alloc_object_id' into integration 2025-12-20 11:25:54 -10:00
J. Nick Koston
9ca2b0adb7 Merge remote-tracking branch 'origin/syslog_ns' into integration 2025-12-20 11:25:40 -10:00
J. Nick Koston
945d5890b5 Revert "[improv_serial] Use stack buffer for RSSI formatting"
This reverts commit c0ab783ba2.
2025-12-20 11:25:22 -10:00
J. Nick Koston
2b53976b0f [syslog] Use C++17 nested namespace syntax 2025-12-20 11:23:21 -10:00
J. Nick Koston
589942f52c simplify logic 2025-12-20 11:11:54 -10:00
J. Nick Koston
a9c294bc03 copilot edge cases 2025-12-20 11:09:52 -10:00
J. Nick Koston
a0d1a10d17 Update tests/integration/test_syslog.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-20 11:00:31 -10:00
J. Nick Koston
496c09b333 bounds fixes 2025-12-20 11:00:03 -10:00
J. Nick Koston
1dfb808590 Merge branch 'improv_serial_stack_format' into integration 2025-12-20 10:58:24 -10:00
J. Nick Koston
c0ab783ba2 [improv_serial] Use stack buffer for RSSI formatting 2025-12-20 10:55:16 -10:00
J. Nick Koston
6b7115f40e Merge branch 'web_server_no_heap_churn_prints' into integration 2025-12-20 10:49:46 -10:00
J. Nick Koston
42610d5a6f 8266 2025-12-20 10:48:52 -10:00
J. Nick Koston
ad17c8524c Merge branch 'web_server_no_heap_churn_prints' into integration 2025-12-20 10:41:15 -10:00
J. Nick Koston
1a60ce8cc6 Merge branch 'dev' into no_alloc_object_id 2025-12-20 10:40:52 -10:00
J. Nick Koston
644e806afd [zwave_proxy] Add missing USE_API guards for clang-tidy (#12590) 2025-12-20 10:40:43 -10:00
J. Nick Koston
de3e72af04 [web_server] Replace str_sprintf with stack buffers 2025-12-20 10:39:19 -10:00
J. Nick Koston
43046b2c55 Merge remote-tracking branch 'origin/syslog_no_heap' into integration 2025-12-20 10:31:48 -10:00
J. Nick Koston
808f1ac078 Merge branch 'no_alloc_object_id' into integration 2025-12-20 10:31:40 -10:00
J. Nick Koston
c22eff24d8 [syslog] Eliminate heap allocations in log path 2025-12-20 10:24:46 -10:00
J. Nick Koston
f470cf5c87 add missing USE_API guard 2025-12-20 10:05:50 -10:00
Leo Bergolth
6c2d255230 send NIL ("-") as timestamp if time source is not valid (#12588) 2025-12-20 10:04:59 -10:00
J. Nick Koston
832d232814 Merge branch 'fix_slow_esp32_camera_at_high_fps' into integration 2025-12-20 09:13:13 -10:00
J. Nick Koston
6efb167b65 edge case 2025-12-20 09:12:55 -10:00
J. Nick Koston
4d99632a61 [esp32_camera] Throttle frame logging to reduce overhead and improve throughput 2025-12-20 09:02:39 -10:00
J. Nick Koston
6cb66559bc fix test 2025-12-20 08:42:52 -10:00
Stuart Parmenter
6f3bfc2060 [hub75] Bump esp-hub75 version to 0.1.7 (#12564) 2025-12-20 13:18:20 -05:00
J. Nick Koston
e812d8683a tests 2025-12-20 07:23:55 -10:00
J. Nick Koston
cc9f42cc9a [api] Add zero-copy support for Home Assistant state response messages 2025-12-20 07:22:36 -10:00
J. Nick Koston
89012f80a9 Merge branch 'dev' into api_avoid_copies 2025-12-20 06:48:24 -10:00
J. Nick Koston
9a54cc12ba Merge branch 'dev' into no_alloc_object_id 2025-12-20 06:47:49 -10:00
J. Nick Koston
40eb898814 [api] Add zero-copy support for noise encryption key requests (#12405) 2025-12-20 06:47:30 -10:00
J. Nick Koston
64269334ce [text_sensor] Avoid string copies in callbacks by passing const ref (#12503)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-20 06:46:13 -10:00
Eduard Llull
121375ff39 [display_menu_base] Call on_value_ after updating the select (#12584) 2025-12-20 10:59:14 -05:00
J. Nick Koston
48cdf9e036 [tests] Fix race condition in alarm control panel state transitions test (#12581) 2025-12-20 10:47:29 -05:00
J. Nick Koston
bed779b1c9 Merge branch 'alarm_control_flakey' into integration 2025-12-19 21:18:08 -10:00
J. Nick Koston
a31bef5390 [tests] Fix race condition in alarm control panel state transitions test 2025-12-19 21:01:31 -10:00
J. Nick Koston
2d792ddf40 Merge branch 'noise_api_zero_copy' into integration 2025-12-19 20:12:58 -10:00
J. Nick Koston
7365885464 Merge branch 'dev' into noise_api_zero_copy 2025-12-19 20:12:47 -10:00
J. Nick Koston
df5193ff73 fix merge 2025-12-19 20:11:21 -10:00
J. Nick Koston
2d6103f0d0 Merge branch 'text_sensor_avoid_copies_const_ref' into integration 2025-12-19 20:07:35 -10:00
J. Nick Koston
4036671583 Update esphome/components/sensor/sensor.cpp 2025-12-19 20:06:22 -10:00
J. Nick Koston
4a1db67566 Update esphome/components/sensor/sensor.cpp 2025-12-19 20:06:10 -10:00
J. Nick Koston
0814419d61 Update esphome/components/text_sensor/text_sensor.h 2025-12-19 20:05:30 -10:00
J. Nick Koston
c799ce05f7 Update esphome/components/text_sensor/text_sensor.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-19 20:05:11 -10:00
J. Nick Koston
8088f09902 Update esphome/components/text_sensor/text_sensor.h 2025-12-19 20:05:05 -10:00
J. Nick Koston
0cff5326bc Update esphome/components/text_sensor/text_sensor.cpp 2025-12-19 20:04:36 -10:00
J. Nick Koston
60d66365ad Update esphome/components/sensor/sensor.cpp 2025-12-19 20:04:17 -10:00
J. Nick Koston
f727edab58 Update esphome/components/text_sensor/text_sensor.cpp 2025-12-19 20:03:43 -10:00
J. Nick Koston
a0647cbe71 Update esphome/components/text_sensor/text_sensor.cpp 2025-12-19 20:03:14 -10:00
J. Nick Koston
0543d65969 Update esphome/components/text_sensor/text_sensor.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-19 20:02:54 -10:00
J. Nick Koston
4bfe09768c Update esphome/components/sensor/sensor.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-19 20:02:31 -10:00
J. Nick Koston
4d0a54d9f0 Update esphome/components/sensor/sensor.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-19 20:02:24 -10:00
J. Nick Koston
4739e9cabe Merge branch 'dev' into text_sensor_avoid_copies_const_ref 2025-12-19 19:13:33 -10:00
J. Nick Koston
4c4c6fb257 Merge branch 'parition_callbacks' into text_sensor_avoid_copies_const_ref 2025-12-19 19:12:10 -10:00
J. Nick Koston
3e313014e1 [core] Migrate entities to use lazy callbacks (#12580) 2025-12-19 19:04:21 -10:00
J. Nick Koston
68b7fbdecf Merge branch 'lazy_allocate_entity_callbacks' - add LazyCallbackManager for other entities 2025-12-19 17:19:39 -10:00
J. Nick Koston
e7ea17fcba [core] Migrate entities to use lazy callbacks 2025-12-19 17:13:27 -10:00
Martin Ebner
be6c1e4ec0 [sen5x][sgp4x] Move configuration keys from SEN5x and SGP4x to const.py (#12567)
Co-authored-by: Martin Ebner <martinebner@me.com>
2025-12-19 21:29:02 -05:00
Keith Burzinski
730bf206de [wifi] Fix for wifi_info when static IP is configured (#12576) 2025-12-19 21:25:16 -05:00
J. Nick Koston
4eea8082cd Merge branch 'name_with_suffix_ble' into integration 2025-12-19 16:01:24 -10:00
J. Nick Koston
78899831cf dry 2025-12-19 15:55:20 -10:00
J. Nick Koston
6cac302c01 Merge branch 'name_with_suffix_ble' into integration 2025-12-19 15:52:45 -10:00
J. Nick Koston
a76461cf5f [esp32_ble] Avoid string allocation when setting BLE device name 2025-12-19 15:50:25 -10:00
J. Nick Koston
6a9a6554e1 Merge branch 'no_alloc_object_id' into integration 2025-12-19 15:25:38 -10:00
J. Nick Koston
6904f0f3c4 fix 2025-12-19 15:25:25 -10:00
J. Nick Koston
7eca8905ea refactor 2025-12-19 15:13:16 -10:00
J. Nick Koston
01224f25f7 tweak 2025-12-19 15:08:02 -10:00
J. Nick Koston
cd6240541b [core] Add zero-allocation get_object_id_to() method 2025-12-19 15:03:27 -10:00
J. Nick Koston
94fcd18306 Merge remote-tracking branch 'upstream/dev' into integration
# Conflicts:
#	esphome/components/fan/fan_traits.h
#	esphome/components/http_request/ota/ota_http_request.cpp
#	tests/integration/test_alarm_control_panel_state_transitions.py
2025-12-19 14:22:19 -10:00
J. Nick Koston
da472f3f79 Merge branch 'dev' into noise_api_zero_copy 2025-12-19 12:46:07 -10:00
J. Nick Koston
c9fccdff25 [fan] Add zero-copy support for API preset mode commands (#12404)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-19 22:05:52 +00:00
J. Nick Koston
ada6c42f3f [alarm_control_panel] Remove redundant per-state callbacks (#12171)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-19 11:48:14 -10:00
J. Nick Koston
988b888c63 [ota] Replace std::function callbacks with listener interface (#12167) 2025-12-19 11:19:07 -10:00
J. Nick Koston
940afdbb12 [climate] Add zero-copy support for API custom fan mode and preset commands (#12402) 2025-12-19 11:18:50 -10:00
J. Nick Koston
81e91c2a8f [esp32_ble] Add stack-based UUID formatting to avoid heap allocations (#12510) 2025-12-19 11:18:32 -10:00
J. Nick Koston
ebc3d28ade [wifi] Replace optional with sentinel values to reduce RAM and clarify API (#12446) 2025-12-19 11:18:15 -10:00
J. Nick Koston
3fff2f2f0a Merge branch 'web_server_stack_format' into integration 2025-12-19 10:50:16 -10:00
J. Nick Koston
04eb64f361 safer 2025-12-19 10:49:19 -10:00
J. Nick Koston
4464e464b6 safer 2025-12-19 10:48:52 -10:00
Rene Guca
25cebedcfc [dht] Fix "Falling edge for bit 39 failed!" for Sonoff THS01 (#9225)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-19 15:42:39 -05:00
J. Nick Koston
20a12ca02a Merge branch 'web_server_stack_format' into integration 2025-12-19 10:20:38 -10:00
J. Nick Koston
b2a43a3a69 [web_server] Use stack buffers for value formatting to reduce flash usage 2025-12-19 10:18:58 -10:00
dependabot[bot]
98ed679b19 Bump ruff from 0.14.9 to 0.14.10 (#12572)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-12-19 19:22:56 +00:00
J. Nick Koston
097617cb4e Merge remote-tracking branch 'upstream/dev' into integration 2025-12-19 09:22:29 -10:00
dependabot[bot]
59b38d79b4 Bump docker/setup-buildx-action from 3.11.1 to 3.12.0 in the docker-actions group (#12574)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-19 09:18:52 -10:00
dependabot[bot]
26c16f4ca2 Bump voluptuous from 0.15.2 to 0.16.0 (#12573)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-19 09:18:33 -10:00
Jas Strong
940e619481 [aqi, hm3301, pmsx003] Air Quality Index improvements (#12203)
Co-authored-by: jas <jas@asspa.in>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-12-19 13:42:11 -05:00
J. Nick Koston
043204baa6 Merge branch 'get_peername_stack_save_ram' into integration 2025-12-19 06:34:49 -10:00
J. Nick Koston
92157c89bc cleanup 2025-12-19 06:29:57 -10:00
J. Nick Koston
25f83384a4 cleanup 2025-12-19 06:29:36 -10:00
Jonathan Swoboda
eaca81c3ab Merge branch 'release' into dev 2025-12-19 10:53:18 -05:00
Jonathan Swoboda
93e38f2608 Merge pull request #12569 from esphome/bump-2025.12.1
2025.12.1
2025-12-19 10:53:05 -05:00
Jonathan Swoboda
3a888326d8 Bump version to 2025.12.1 2025-12-19 10:13:35 -05:00
Keith Burzinski
f0d0ea60a7 [esp32_ble, esp32_ble_tracker] Fix crash, error messages when ble.disable called during boot (#12560) 2025-12-19 10:13:35 -05:00
Jonathan Swoboda
7ca11764ab [template.alarm_control_panel] Fix compile without binary_sensor (#12548)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-19 10:13:35 -05:00
Jonathan Swoboda
3e38a5e630 [esp32_camera] Fix I2C driver conflict with other components (#12533)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-12-19 10:13:35 -05:00
Jonathan Swoboda
636be92c97 [bme68x_bsec2_i2c] Add MULTI_CONF support for multiple sensors (#12535)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-19 10:13:35 -05:00
Jack Wilsdon
195b1c6323 [pm1006] Fix "never" update interval detection (#12529) 2025-12-19 10:13:35 -05:00
Anna Oake
7e08092012 [cc1101] Fix default frequencies (#12539) 2025-12-19 10:13:35 -05:00
J. Nick Koston
86119c3439 Merge branch 'get_peername_stack_save_ram' into integration 2025-12-18 22:18:00 -10:00
J. Nick Koston
cf404c34d0 [api] Use stack buffers for peername logging to reduce per-connection memory 2025-12-18 22:13:27 -10:00
pixelgrb
f962497db1 [mmc5603] enable AUTO_SR_en to compensate for temperature drift (#12556)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-18 23:13:36 -05:00
J. Nick Koston
ce1c6721b1 Merge branch 'union_iter' into integration 2025-12-18 16:55:06 -10:00
J. Nick Koston
a7f82f5201 state machine 2025-12-18 16:50:41 -10:00
J. Nick Koston
38afc5149a [api] Use union for iterators to reduce APIConnection size by ~16 bytes 2025-12-18 16:18:45 -10:00
Keith Burzinski
7ae3a11d6b [esp32_ble, esp32_ble_tracker] Fix crash, error messages when ble.disable called during boot (#12560) 2025-12-18 19:42:47 -06:00
J. Nick Koston
7a5a768c04 Merge remote-tracking branch 'kbx81/20251218-ble-disable-fixes' into integration 2025-12-18 15:21:57 -10:00
kbx81
37e2a114db [esp32_ble, esp32_ble_tracker] Fix crash, error messages when ble.disable called during boot 2025-12-18 18:58:26 -06:00
J. Nick Koston
b5950d41b5 Merge remote-tracking branch 'upstream/move_comment_build_info' into integration 2025-12-18 11:19:51 -10:00
dependabot[bot]
1c50c2b672 Bump ruamel-yaml from 0.18.16 to 0.18.17 (#12555)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-18 11:19:19 -10:00
J. Nick Koston
3a69cb9c13 tidy 2025-12-18 07:53:48 -10:00
J. Nick Koston
5547f9f5d6 span 2025-12-18 06:58:32 -10:00
J. Nick Koston
12d8e2ada2 tweaks 2025-12-18 06:56:12 -10:00
J. Nick Koston
455091a03f tweaks 2025-12-18 06:55:02 -10:00
J. Nick Koston
23ee8bdcaf [core] Move comment to PROGMEM on ESP8266 2025-12-18 06:48:23 -10:00
Jonathan Swoboda
41fd1762e9 [core] Deprecate custom_components folder (#12552)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-18 11:46:16 -05:00
J. Nick Koston
cd93468225 [core] Move comment to PROGMEM on ESP8266 2025-12-18 06:41:23 -10:00
J. Nick Koston
2cf6ed2af7 [socket] Refactor socket implementations for memory efficiency and code quality (#12550) 2025-12-18 09:07:35 -07:00
J. Nick Koston
b47b7d43fd [api] Remove unused force parameter from encode_message (#12551) 2025-12-18 09:06:16 -07:00
Jonathan Swoboda
663a4304e0 [libretiny] Fix millis() ambiguity on BK72XX (#12534)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-18 07:50:31 -05:00
J. Nick Koston
bef017fd3e Merge branch 'encode_message_dead_code' into integration 2025-12-17 20:05:59 -10:00
J. Nick Koston
6707ac6a0f [api] Remove unused force parameter from encode_message 2025-12-17 20:03:40 -10:00
J. Nick Koston
ec55dcbe41 Merge branch 'socket_reorg_cleanup' into integration 2025-12-17 19:28:20 -10:00
J. Nick Koston
655f493eaa [socket] Refactor socket implementations for memory efficiency and code quality 2025-12-17 19:20:35 -10:00
J. Nick Koston
50f0f7595b Merge remote-tracking branch 'upstream/dev' into integration 2025-12-17 18:50:37 -10:00
Jonathan Swoboda
ca47bad90a [template.alarm_control_panel] Fix compile without binary_sensor (#12548)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-17 23:34:04 -05:00
J. Nick Koston
4f821a6d76 [wifi] Reduce scan logging to prevent blocking loop during connection (#12544) 2025-12-17 18:21:46 -10:00
J. Nick Koston
426305836d [esp32][libretiny] Avoid duplicate snprintf when syncing preferences (#12542) 2025-12-17 18:16:14 -10:00
J. Nick Koston
c6b33586c1 Merge remote-tracking branch 'upstream/dev' into integration 2025-12-17 15:54:10 -10:00
dependabot[bot]
1b5af7d21d Bump github/codeql-action from 4.31.8 to 4.31.9 (#12524)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-17 15:22:19 -10:00
J. Nick Koston
a97f637cb9 Merge branch 'wifi_connect_blocked_loop_logging' into integration 2025-12-17 14:14:11 -10:00
J. Nick Koston
0185541000 [wifi] Reduce scan logging to prevent blocking loop during connection 2025-12-17 14:13:37 -10:00
David Woodhouse
9de7df7b5b Add build info to image (#12425)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-18 00:06:52 +00:00
J. Nick Koston
ce18b4c3ca Merge branch 'prefs_snprintf_once' into integration 2025-12-17 14:01:12 -10:00
J. Nick Koston
60b266e73d [esp32][libretiny] Avoid duplicate snprintf when syncing preferences 2025-12-17 14:00:19 -10:00
J. Nick Koston
4c8a2fe3d4 Merge branch 'fan_zero_copy' into noise_api_zero_copy 2025-12-17 16:41:26 -07:00
J. Nick Koston
190ebecd7b Merge branch 'climate_zero_copy' into fan_zero_copy 2025-12-17 16:41:18 -07:00
J. Nick Koston
71b6fc4baa Merge branch 'dev' into climate_zero_copy 2025-12-17 16:41:06 -07:00
J. Nick Koston
bec60c4da8 Merge branch 'dev' into api_avoid_copies 2025-12-17 16:40:39 -07:00
J. Nick Koston
df2936f686 Merge branch 'dev' into parition_callbacks 2025-12-17 16:40:30 -07:00
J. Nick Koston
1fb89e5223 Merge branch 'buildinfo' into integration 2025-12-17 13:27:58 -10:00
J. Nick Koston
8c185254ef give 6 months of get_compilation_time for back compat 2025-12-17 13:04:46 -10:00
David Woodhouse
14ecb906a1 Merge branch 'dev' into buildinfo 2025-12-17 22:59:57 +00:00
Jonathan Swoboda
2b337aa306 [esp32_camera] Fix I2C driver conflict with other components (#12533)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-12-17 17:37:59 -05:00
Jonathan Swoboda
4ddaff4027 [esp32] Dynamically embed managed component server certificates (#12509)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-12-17 17:26:56 -05:00
J. Nick Koston
91c504061b [select] Eliminate string allocation in state callbacks (#12505)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-17 12:19:26 -10:00
Jonathan Swoboda
dc8f7abce2 [bme68x_bsec2_i2c] Add MULTI_CONF support for multiple sensors (#12535)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-17 17:07:42 -05:00
Jonathan Swoboda
3d673ac55e [ci] Check changed headers in clang-tidy when using --changed (#12540)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-17 11:13:18 -10:00
Jack Wilsdon
b02696edc0 [pm1006] Fix "never" update interval detection (#12529) 2025-12-18 07:40:31 +11:00
David Woodhouse
0688abdbd8 Merge branch 'dev' into buildinfo 2025-12-17 20:35:06 +00:00
Anna Oake
f9720026d0 [cc1101] Fix default frequencies (#12539) 2025-12-17 14:19:18 -05:00
David Woodhouse
745f5b8dd2 Merge branch 'dev' into buildinfo 2025-12-17 19:15:48 +00:00
Jonathan Swoboda
d7b04a3d18 [nextion] Fix clang-tidy error on Zephyr for HTTPClient (#12538)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-17 13:59:49 -05:00
David Woodhouse
01d8775005 Merge branch 'dev' into buildinfo 2025-12-17 18:04:45 +00:00
Jonathan Swoboda
0e71fa97a7 [spi] Add SPIInterface stub for clang-tidy on unsupported platforms (#12532)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-17 12:18:25 -05:00
J. Nick Koston
7701371bb4 Merge branch 'fix-bk72xx-millis-ambiguity' into integration 2025-12-17 07:18:19 -10:00
J. Nick Koston
42e061c9ae [text] Avoid string copies in callbacks by passing const ref (#12504) 2025-12-17 12:00:19 -05:00
J. Nick Koston
94763ebdab [libretiny] Store preference keys as uint32_t, convert to string only at FlashDB boundary (#12500) 2025-12-17 11:59:40 -05:00
J. Nick Koston
f32bb618ac [esp32] Store preference keys as uint32_t, convert to string only at NVS boundary (#12494) 2025-12-17 11:59:35 -05:00
Edward Firmo
0707f383a6 [nextion] Use ESP-IDF for ESP32 Arduino (#9429)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-17 11:45:17 -05:00
Piotr Szulc
e91c6a79ea [deep_sleep] Deep sleep for BK72xx (#12267)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-17 11:45:05 -05:00
J. Nick Koston
63fc8b4e5a [core] Refactor str_snake_case and str_sanitize to use constexpr helpers (#12454) 2025-12-17 11:30:12 -05:00
J. Nick Koston
ab73ed76b8 [esphome] Improve OTA field alignment to save 4 bytes on 32-bit (#12461) 2025-12-17 11:29:58 -05:00
J. Nick Koston
bf6a03d1cf [factory_reset] Optimize memory by storing interval as uint16_t seconds (#12462) 2025-12-17 11:29:51 -05:00
J. Nick Koston
9928ab09cf [time] Convert to C++17 nested namespace syntax (#12463) 2025-12-17 11:29:43 -05:00
Jonathan Swoboda
eb2392b33a [libretiny] Fix millis() ambiguity on BK72XX
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-17 11:25:21 -05:00
David Woodhouse
7e36112687 Merge branch 'dev' into buildinfo 2025-12-17 09:32:40 +00:00
Thomas Rupprecht
56c1691d72 [pca9685,sx126x,sx127x] Use frequency/float_range check (#12490)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-16 22:52:28 -05:00
Roger Fachini
a065990ab9 [update] Add check action to trigger update checks (#12415) 2025-12-16 22:20:12 -05:00
Stuart Parmenter
084f517a20 [hub75] Add set_brightness action (#12521) 2025-12-16 22:12:33 -05:00
David Woodhouse
77d914e67f Merge branch 'dev' into buildinfo 2025-12-17 01:52:36 +00:00
Jonathan Swoboda
1122ec354f [esp32] Add OTA rollback support (#12460)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-16 20:07:57 -05:00
Jonathan Swoboda
431183eebc [ledc,mqtt,resampler] Remove unnecessary ESP-IDF framework restrictions (#12442)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-16 20:07:09 -05:00
Jonathan Swoboda
08beaf8750 [esp32] Remove Arduino-specific code from core.cpp (#12501)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-16 20:06:12 -05:00
David Woodhouse
f2f30337a0 Merge branch 'dev' into buildinfo 2025-12-17 00:44:15 +00:00
Jonathan Swoboda
18814f12dc [http_request] Use ESP-IDF for ESP32 Arduino (#12428)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-16 19:44:14 -05:00
Jonathan Swoboda
9cd888cef6 [spi] Use ESP-IDF driver for ESP32 Arduino (#12420)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-16 19:44:01 -05:00
Thomas Rupprecht
9727c7135c [openthread] channel range, fix typo, use C++17 nested namespace syntax (#12422) 2025-12-16 19:43:18 -05:00
Thomas Rupprecht
93621d85b0 [climate] Improve temperature unit regex (#12032) 2025-12-16 19:43:10 -05:00
Thomas Rupprecht
046ea922e8 [esp32] improve types and variable naming (#12423) 2025-12-16 19:42:52 -05:00
David Woodhouse
71f2331bc8 Fix clang-format: use lowercase buf_size variable name 2025-12-17 00:42:46 +00:00
Jeff Zigler
fab4efb469 [esp32] Fix serial logging on h2, c2 & c61 (#12522)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-16 19:42:12 -05:00
Jonathan Swoboda
efc5672567 Merge branch 'release' into dev 2025-12-16 18:57:37 -05:00
Jonathan Swoboda
0ea5f2fd81 Merge pull request #12525 from esphome/bump-2025.12.0
2025.12.0
2025-12-16 18:57:20 -05:00
David Woodhouse
8358ef0096 Use ESPHOME_strncpy_P in get_build_time_string()
Replace platform-specific ifdef with cross-platform ESPHOME_strncpy_P
macro for consistency.
2025-12-16 23:06:31 +00:00
David Woodhouse
f8c9cf8fd9 Use PROGMEM for version text sensor strings on ESP8266
Build version string incrementally from PROGMEM literals using
ESPHOME_strncpy_P and ESPHOME_strncat_P. Write hash and build time
directly into buffer without temporary variables. Calculate buffer
size based on actual components needed.

Add ESPHOME_strncat_P macro to progmem.h for cross-platform PROGMEM
string concatenation.
2025-12-16 23:05:07 +00:00
Jonathan Swoboda
fa3d998c3d Bump version to 2025.12.0 2025-12-16 17:15:50 -05:00
David Woodhouse
8429684fce Fix clang-format: use uppercase PREFIX constant name 2025-12-16 19:46:04 +00:00
David Woodhouse
a30052e7c0 Use PROGMEM for version text sensor strings on ESP8266
Build version string incrementally from PROGMEM literal prefix, avoiding
format strings in RAM. Copy from PROGMEM on ESP8266, use directly on
other platforms.
2025-12-16 19:22:42 +00:00
David Woodhouse
175250deb0 Use PROGMEM for MQTT version format string on ESP8266
Store format string in PROGMEM and copy to RAM buffer on ESP8266 before
use. On other platforms, use the format string directly. This saves RAM
on ESP8266 while maintaining the same functionality.
2025-12-16 19:20:50 +00:00
David Woodhouse
12734ba258 Revert "Use PROGMEM format strings to reduce RAM usage on ESP8266"
This reverts commit da67c47a76.
2025-12-16 19:03:13 +00:00
David Woodhouse
da67c47a76 Use PROGMEM format strings to reduce RAM usage on ESP8266
Replace str_sprintf() with snprintf_P() and PSTR() to keep format
strings in flash instead of RAM. Also removes 'config hash 0x' prefix
to save additional bytes.
2025-12-16 18:13:35 +00:00
David Woodhouse
38167c268f Add get_config_version_hash() and make hash functions constexpr
Add Application::get_config_version_hash() as a constexpr that returns
fnv1a_hash_extend(config_hash, ESPHOME_VERSION).

Make get_config_hash(), get_build_time(), fnv1a_hash(), and
fnv1a_hash_extend() constexpr inline functions.

Replace open-coded fnv1a_hash_extend(config_hash, ESPHOME_VERSION)
calls with get_config_version_hash() in sensor and wifi components.

Remove now-unnecessary version.h includes from component files.
2025-12-16 17:15:19 +00:00
David Woodhouse
7298db0a7e Add tests for source file removal detection in copy_src_tree
Add tests covering the logic that detects when source files are removed:
- test_copy_src_tree_detects_removed_source_file: Verifies that removing
  a regular source file triggers sources_changed flag
- test_copy_src_tree_ignores_removed_generated_file: Verifies that removing
  a generated file (like build_info_data.h) does not trigger sources_changed
2025-12-16 16:45:28 +00:00
J. Nick Koston
6eb8095480 Merge branch 'dev' into buildinfo 2025-12-16 10:29:51 -06:00
Jonathan Swoboda
5e630e9255 Merge branch 'beta' into dev 2025-12-16 11:26:08 -05:00
Jonathan Swoboda
864aaeec01 Merge pull request #12520 from esphome/bump-2025.12.0b5
2025.12.0b5
2025-12-16 11:25:57 -05:00
David Woodhouse
3679a81220 Merge branch 'dev' into buildinfo 2025-12-16 15:55:36 +00:00
Jonathan Swoboda
9c88e44300 Bump version to 2025.12.0b5 2025-12-16 10:35:31 -05:00
Jonathan Swoboda
4d6a93f92d [uart] Fix UART on default UART0 pins for ESP-IDF (#12519)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-16 10:35:31 -05:00
J. Nick Koston
7216120bfd [socket] Fix getpeername() returning local address instead of remote in LWIP raw TCP (#12475) 2025-12-16 10:35:31 -05:00
Jonathan Swoboda
1897551b28 [uart] Fix UART on default UART0 pins for ESP-IDF (#12519)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-16 10:17:17 -05:00
David Woodhouse
dfae9e5750 Merge branch 'dev' into buildinfo 2025-12-16 10:21:02 +00:00
J. Nick Koston
ead60bc5c4 [socket] Fix getpeername() returning local address instead of remote in LWIP raw TCP (#12475) 2025-12-16 00:48:30 -06:00
David Woodhouse
87f88b8a9a Add version.h includes to sensor components
Add missing version.h includes to sen5x, sgp30, and sgp4x components
for ESPHOME_VERSION definition.
2025-12-16 00:32:30 +00:00
David Woodhouse
ba79a8e6c8 Merge branch 'dev' into buildinfo 2025-12-16 00:19:29 +00:00
David Woodhouse
e8a3a8380d Remove stray debug 2025-12-16 00:18:56 +00:00
David Woodhouse
305a58cb84 Use config_hash in MQTT and version sensor
Change MQTT sw_version and version text sensor to display config_hash
instead of build_time_str. Format: "(config hash 0xXXXXXXXX)"

Version sensor with hide_timestamp=false also includes build time:
"(config hash 0xXXXXXXXX, built: YYYY-MM-DD HH:MM:SS +ZZZZ)"
2025-12-16 00:09:28 +00:00
David Woodhouse
f231fc856b Use fnv1a_hash_extend with config_hash and version for wifi preferences
Change wifi component to use fnv1a_hash_extend(config_hash, ESPHOME_VERSION)
instead of fnv1_hash(compilation_time) for the preferences hash.

This ensures wifi settings are invalidated on config or version changes,
not just on recompilation.
2025-12-16 00:05:43 +00:00
Jonathan Swoboda
7fe8e53f82 Merge branch 'beta' into dev 2025-12-15 19:01:12 -05:00
Jonathan Swoboda
8cf0ee38a3 Merge pull request #12513 from esphome/bump-2025.12.0b4
2025.12.0b4
2025-12-15 19:01:02 -05:00
David Woodhouse
69fa5020d2 Re-remove compilation_time_ from the app 2025-12-15 23:23:46 +00:00
David Woodhouse
f5592595bc Use fnv1a_hash_extend with config_hash and version for sensor baselines
Change sen5x, sgp30, and sgp4x components to use fnv1a_hash_extend()
starting with config_hash and ESPHOME_VERSION, then extending with the
sensor serial number. This replaces the previous use of fnv1_hash with
compilation_time.

This ensures baseline storage is invalidated on config or version
changes, not just on recompilation.
2025-12-15 23:22:23 +00:00
David Woodhouse
4a58ab6310 Restore switch to build_time_str in mqtt sw_version and version sensor 2025-12-15 23:14:25 +00:00
David Woodhouse
a5ff374540 Merge branch 'dev' of github.com:esphome/esphome into buildinfo 2025-12-15 23:12:40 +00:00
David Woodhouse
ffbbf37fc2 Revert "Revert API compilation_time to old locale-dependent format"
This reverts commit d2b5398fad.
2025-12-15 23:12:21 +00:00
Jonathan Swoboda
4c926cca60 Bump version to 2025.12.0b4 2025-12-15 18:09:42 -05:00
Pascal Vizeli
57634b612a [http_request] Fix infinite loop when server doesn't send Content-Length header (#12480)
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-15 18:09:42 -05:00
Jonathan Swoboda
8dff7ee746 [esp32] Support all IDF component version operators in shorthand syntax (#12499)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-15 18:09:42 -05:00
Jonathan Swoboda
803bb742c9 [remote_base] Fix crash when ABBWelcome action has no data field (#12493)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-15 18:09:42 -05:00
J. Nick Koston
682acf81b2 Merge remote-tracking branch 'upstream/dev' into integration 2025-12-15 15:35:46 -06:00
David Woodhouse
d2b5398fad Revert API compilation_time to old locale-dependent format
Keep the API DeviceInfo compilation_time field using the old
get_compilation_time_ref() format for backward compatibility.

The text sensor build_time_str continues to use the new ISO 8601 format.
2025-12-15 21:01:15 +00:00
David Woodhouse
839139df36 Add FNV-1a hash functions (#12502) 2025-12-15 20:23:54 +00:00
dependabot[bot]
24d7e9dd23 Bump tornado from 6.5.3 to 6.5.4 (#12508)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-15 20:08:16 +00:00
dependabot[bot]
1214bb6bad Bump aioesphomeapi from 43.2.1 to 43.3.0 (#12507)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-15 20:07:20 +00:00
J. Nick Koston
3ebbc1e769 overloads 2025-12-15 13:28:59 -06:00
J. Nick Koston
9578a02fe3 overloads 2025-12-15 13:27:51 -06:00
J. Nick Koston
68edb5c9a0 Merge branch 'noise_api_zero_copy' into integration 2025-12-15 13:19:52 -06:00
David Woodhouse
d911ae94fe Fix BUILD_TIME_STR_SIZE for ISO 8601 format
Increase buffer from 24 to 26 bytes to accommodate the ISO 8601 format
with timezone: "YYYY-MM-DD HH:MM:SS +ZZZZ" (25 chars + null terminator).

The old format "Dec 15 2025, 18:14:59" was 20 chars, but the new format
needs 25 chars. The 24-byte buffer was truncating the timezone to "+00"
instead of "+0000".
2025-12-15 18:53:56 +00:00
J. Nick Koston
487b66d92a Merge branch 'api_avoid_copies' into integration 2025-12-15 12:46:14 -06:00
J. Nick Koston
fc4869e2f9 Merge branch 'select_avoid_copies' into integration 2025-12-15 12:46:10 -06:00
J. Nick Koston
109e6c9719 Merge branch 'text_avoid_copies_const_ref' into integration 2025-12-15 12:46:06 -06:00
J. Nick Koston
3c42e534b3 Merge branch 'text_sensor_avoid_copies_const_ref' into integration 2025-12-15 12:46:02 -06:00
J. Nick Koston
b956c7798b [api] Avoid string copies in Home Assistant state subscription callbacks 2025-12-15 12:45:15 -06:00
J. Nick Koston
f8c0cd9ff6 [select] Eliminate string allocation in state callbacks 2025-12-15 12:39:52 -06:00
J. Nick Koston
e27c693051 [text] Avoid string copies in callbacks by passing const ref 2025-12-15 12:29:15 -06:00
J. Nick Koston
f6f1961e0e [text_sensor] Avoid string copies in callbacks by passing const ref 2025-12-15 12:24:34 -06:00
J. Nick Koston
ab0ca3006a Merge branch 'dev' into parition_callbacks 2025-12-15 12:20:54 -06:00
David Woodhouse
af1e0e6489 Merge branch 'dev' into buildinfo 2025-12-15 18:10:50 +00:00
Pascal Vizeli
260ffba2a5 [http_request] Fix infinite loop when server doesn't send Content-Length header (#12480)
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-15 12:54:12 -05:00
J. Nick Koston
dab6b54e97 Merge branch 'fix-http-request-content-length' into integration 2025-12-15 11:48:06 -06:00
David Woodhouse
fd32139d89 Use new ISO format for compilation_time in API DeviceInfo
Change the API's DeviceInfo response to use the new ISO 8601 format
with timezone for compilation_time field by calling get_build_time_string()
instead of get_compilation_time_ref().

Update the placeholder build_info_data.h to match the new format.

Update integration test to expect the new format for compilation_time.
2025-12-15 17:44:35 +00:00
J. Nick Koston
245e7682c1 Merge remote-tracking branch 'swoboda1337/esp32-remove-arduino-core' into integration 2025-12-15 11:32:08 -06:00
Jonathan Swoboda
2e899dd010 [esp32] Support all IDF component version operators in shorthand syntax (#12499)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-15 12:07:02 -05:00
David Woodhouse
93bf1c8452 Merge branch 'dev' into buildinfo 2025-12-15 17:00:31 +00:00
David Woodhouse
0a63c50e1e Add test for build_info regeneration behaviour
Test verifies that:
- When source files change, build_info is regenerated with new timestamp
- When no files change, build_info is preserved with same timestamp

The test runs copy_src_tree() three times in the same environment:
1. Initial run creates build_info
2. Second run with no changes preserves the timestamp
3. Third run with changed source file regenerates with new timestamp
2025-12-15 16:59:51 +00:00
David Woodhouse
61cbd07e1d Add hmac-sha256 support (#12437)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-12-15 10:55:03 -06:00
David Woodhouse
87a125f303 Add test coverage for build_info.json change detection
Add tests to cover:
- Detection of config_hash changes in existing build_info.json
- Detection of esphome_version changes in existing build_info.json
- Handling of invalid/corrupted build_info.json files

These tests cover the exception handling and change detection logic
in copy_src_tree() that checks the existing build_info.json.
2025-12-15 16:45:15 +00:00
Jonathan Swoboda
e57e1f5094 Fix 2025-12-15 11:44:14 -05:00
David Woodhouse
09e9b58eb6 Change build_time_str format to ISO 8601 with timezone
Use YYYY-MM-DD HH:MM:SS +ZZZZ format instead of the locale-dependent
'%b %d %Y, %H:%M:%S' format. This provides:
- Unambiguous date format (YYYY-MM-DD)
- Timezone information
- Locale-independent formatting
- Better sortability and parseability

Example: "2025-12-15 16:30:27 +0000" instead of "Dec 15 2025, 16:30:27"

Tests validate the format using strptime with '%Y-%m-%d %H:%M:%S %z'.
2025-12-15 16:38:44 +00:00
David Woodhouse
c451fbd697 Postpone breaking changes for another PR
I think we need to put a little more thought into whether we really
want the build time in each of these, or whether it should be just
the config_hash (perhaps extended with version, and in some cases
the component's own serial number or other identifier).

So put the old compilation_time_ and its access methods back, so
this PR only adds the *new* fields. We can migrate users over and
then remove the compilation_time_ separately.
2025-12-15 16:26:15 +00:00
Jonathan Swoboda
853372a814 Fix 2025-12-15 10:48:48 -05:00
Jonathan Swoboda
db91ac9c75 Fix 2025-12-15 10:45:59 -05:00
David Woodhouse
d83fd263b0 Don't rebuild build_time_str
It's already in the JSON now
2025-12-15 15:44:12 +00:00
Jonathan Swoboda
415a1dd75a Merge branch 'dev' into esp32-remove-arduino-core 2025-12-15 10:43:14 -05:00
J. Nick Koston
ed4f90db8f Merge remote-tracking branch 'upstream/libretiny_prefs' into integration 2025-12-15 09:21:51 -06:00
J. Nick Koston
9dc06f04b1 Merge branch 'dev' into libretiny_prefs 2025-12-15 09:21:36 -06:00
Jonathan Swoboda
fe315a4cf8 Clean 2025-12-15 10:20:52 -05:00
Jonathan Swoboda
b9d59f5a00 [esp32] Remove Arduino-specific code from core.cpp, use initArduino
- Remove all USE_ARDUINO conditionals from core.cpp
- Add weak initArduino() stub that gets overridden when Arduino is present
- Call initArduino() in app_main() to initialize Arduino framework
- Remove CONFIG_AUTOSTART_ARDUINO (no longer needed)
- Fix deprecated hal/cpu_hal.h include, use esp_cpu.h instead
- Remove old ESP-IDF version conditionals (now IDF 5.x+ only)
- Clean up and sort includes alphabetically

This unifies the ESP32 startup code path - Arduino initialization is now
handled by calling initArduino() rather than using CONFIG_AUTOSTART_ARDUINO
which would start Arduino's own main loop.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-15 10:19:20 -05:00
J. Nick Koston
efc53ddd77 Merge remote-tracking branch 'upstream/esp32_prefs_uint32_str' into integration 2025-12-15 09:11:16 -06:00
J. Nick Koston
0bc81633bf at boundry 2025-12-15 09:06:33 -06:00
J. Nick Koston
cf20e0d772 libretiny prefs 2025-12-15 09:03:42 -06:00
David Woodhouse
bc5444cbe1 Merge branch 'dev' into buildinfo 2025-12-15 14:40:52 +00:00
Jonathan Swoboda
450962850a [remote_base] Fix crash when ABBWelcome action has no data field (#12493)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-15 09:29:51 -05:00
Pascal Vizeli
2dbaedbda2 Simplify condition check - remove redundant bufsize > 0 check
The bufsize > 0 check is redundant because the previous if statement
already handles all cases where bufsize <= 0, ensuring that by the time
we reach this condition, bufsize is always positive.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-15 12:17:47 +00:00
David Woodhouse
5eab42441e Fix dummy_main.cpp to match new pre_setup signature
Remove compilation timestamp argument as build time is now handled
through build_info_data.h instead of being passed to pre_setup().
2025-12-15 09:06:49 +00:00
David Woodhouse
0f22b23d9a clang-tidy CI fix
...but this is weird. Why are we copying into a local buffer
at all instead of just using the original string?
2025-12-15 17:11:04 +09:00
David Woodhouse
b27229d9b9 Merge branch 'dev' into buildinfo 2025-12-15 08:11:00 +00:00
J. Nick Koston
6a5dc6e7f5 Merge branch 'esp32_prefs_uint32_str' into integration 2025-12-14 22:29:28 -06:00
J. Nick Koston
ee5a3088b9 tweak 2025-12-14 22:17:45 -06:00
J. Nick Koston
6c166c904c [esp32] Replace std::string with char[12] for NVS preference keys 2025-12-14 22:06:42 -06:00
J. Nick Koston
995cf8be9c Merge remote-tracking branch 'upstream/dev' into integration 2025-12-14 21:34:22 -06:00
Jonathan Swoboda
6b088caf5d Merge branch 'beta' into dev 2025-12-14 19:18:10 -05:00
Jonathan Swoboda
3e6a65e7dc Merge pull request #12488 from esphome/bump-2025.12.0b3
2025.12.0b3
2025-12-14 19:17:58 -05:00
Jonathan Swoboda
3a101d8886 Bump version to 2025.12.0b3 2025-12-14 18:17:00 -05:00
J. Nick Koston
fa0f07bfe9 [wifi] Fix WiFi recovery after failed connection attempts (#12483) 2025-12-14 18:17:00 -05:00
mbohdal
fffa16e4d8 [ethernet] fix used pins validation in configuration of RMII pins (#12486) 2025-12-14 18:17:00 -05:00
guillempages
734710d22a [core] Use Arduino string macros only on ESP8266 (#12471) 2025-12-14 18:17:00 -05:00
J. Nick Koston
3a1be6822e [ota] Match client timeout to device timeout to prevent premature failures (#12484) 2025-12-14 18:17:00 -05:00
J. Nick Koston
c85b1b8609 [web_server_idf] Always enable LRU purge to prevent socket exhaustion (#12481) 2025-12-14 18:17:00 -05:00
J. Nick Koston
2e9ddd967c [wifi_signal] Skip publishing disconnected RSSI value (#12482) 2025-12-14 18:17:00 -05:00
J. Nick Koston
078afe9656 [dashboard] Add ESPHOME_TRUSTED_DOMAINS support to events WebSocket (#12479) 2025-12-14 18:17:00 -05:00
Jonathan Swoboda
46574fcbec [cc1101] Add packet mode support (#12474)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-14 18:17:00 -05:00
Jonathan Swoboda
359f45400f [core] Fix polling_component_schema and type consistency (#12478)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-14 18:16:59 -05:00
Clyde Stubbs
4da95ccd7e [packet_transport] Ensure retransmission at update intervals (#12472)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-14 18:16:59 -05:00
J. Nick Koston
c69d58273a [core] Fix CORE.raw_config not updated after package merge (#12456) 2025-12-14 18:16:59 -05:00
J. Nick Koston
ffce80f96c [wifi] Fix WiFi recovery after failed connection attempts (#12483) 2025-12-14 16:26:34 -06:00
mbohdal
fa5b14fad4 [ethernet] fix used pins validation in configuration of RMII pins (#12486) 2025-12-14 16:40:08 -05:00
J. Nick Koston
45f413de0e Merge branch 'wifi_timeout' into integration 2025-12-14 15:30:58 -06:00
J. Nick Koston
24e490ef26 Merge branch 'wifi_fail_too_quickly_fix' into wifi_timeout 2025-12-14 15:17:05 -06:00
J. Nick Koston
d9296a907d Revert "recovery"
This reverts commit 712da5c2ae.
2025-12-14 15:13:22 -06:00
J. Nick Koston
0a979cf26a Merge branch 'wifi_fail_too_quickly_fix' into wifi_timeout 2025-12-14 15:07:48 -06:00
J. Nick Koston
712da5c2ae recovery 2025-12-14 15:07:22 -06:00
J. Nick Koston
09573b5e5f Merge branch 'wifi_fail_too_quickly_fix' into wifi_timeout 2025-12-14 14:40:38 -06:00
J. Nick Koston
11c9e974ac tweak 2025-12-14 14:38:02 -06:00
J. Nick Koston
3786c84bbe Merge branch 'wifi_fail_too_quickly_fix' into wifi_timeout 2025-12-14 14:32:02 -06:00
J. Nick Koston
c8b48df8f2 tweak 2025-12-14 14:31:41 -06:00
J. Nick Koston
1de743d85e Merge branch 'wifi_fail_too_quickly_fix' into wifi_timeout 2025-12-14 14:25:41 -06:00
J. Nick Koston
f22396a097 fixes 2025-12-14 14:25:23 -06:00
J. Nick Koston
8cdee86334 Merge branch 'wifi_fail_too_quickly_fix' into wifi_timeout 2025-12-14 14:20:19 -06:00
J. Nick Koston
7801420eca one more failure more 2025-12-14 14:18:59 -06:00
guillempages
cee532a1e3 [core] Use Arduino string macros only on ESP8266 (#12471) 2025-12-15 07:15:19 +11:00
J. Nick Koston
8524b894d6 [ota] Match client timeout to device timeout to prevent premature failures (#12484) 2025-12-14 13:47:11 -06:00
J. Nick Koston
4928862622 esp32 has same bug 2025-12-14 13:42:59 -06:00
J. Nick Koston
6939b67e47 esp32 has same bug 2025-12-14 13:42:10 -06:00
J. Nick Koston
0b32add874 Merge branch 'wifi_fail_too_quickly_fix' into wifi_timeout 2025-12-14 13:38:05 -06:00
J. Nick Koston
616dae5bf9 fix missing s_sta_connecting = false; 2025-12-14 13:37:48 -06:00
J. Nick Koston
3a5e708c13 [web_server_idf] Always enable LRU purge to prevent socket exhaustion (#12481) 2025-12-14 13:31:19 -06:00
J. Nick Koston
96e418a8ca [wifi_signal] Skip publishing disconnected RSSI value (#12482) 2025-12-14 13:31:07 -06:00
J. Nick Koston
780a407b10 [dashboard] Add ESPHOME_TRUSTED_DOMAINS support to events WebSocket (#12479) 2025-12-14 13:30:55 -06:00
J. Nick Koston
bd539fa34f Merge branch 'wifi_fail_too_quickly_fix' into wifi_timeout 2025-12-14 13:27:09 -06:00
J. Nick Koston
8ce2cc564f make sure we are disconnected on timeout 2025-12-14 13:26:54 -06:00
J. Nick Koston
2696297428 Merge branch 'ota_timeout_fix' into wifi_timeout 2025-12-14 12:45:57 -06:00
J. Nick Koston
7eff3217aa [ota] Match client timeout to device timeout to prevent premature failures 2025-12-14 12:34:54 -06:00
Jonathan Swoboda
cfc0d8bdfc [cc1101] Add packet mode support (#12474)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-14 13:22:55 -05:00
J. Nick Koston
af04eaaba0 [wifi] Fix premature connection timeout on LibreTiny/Beken 2025-12-14 12:19:58 -06:00
Jonathan Swoboda
786d7266f5 [core] Fix polling_component_schema and type consistency (#12478)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-14 12:47:52 -05:00
Clyde Stubbs
ede64a9f47 [packet_transport] Ensure retransmission at update intervals (#12472)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-14 12:47:15 -05:00
Pascal Vizeli
c4d9ed7b70 [http_request] Fix infinite loop on read error in update component
The update component had the same infinite loop issue as the OTA component
when network read errors occurred. If container->read() returned an error
(negative value), it would be added to read_index and the loop would continue
indefinitely since get_bytes_read() would never reach content_length.

This fix breaks out of the read loop on any read error (read_bytes <= 0),
preventing watchdog resets and infinite loops during manifest downloads.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-14 17:06:53 +00:00
Pascal Vizeli
f20f3e0525 [http_request] Fix infinite loop when server doesn't send Content-Length header
This commit fixes an issue where the http_request component would enter
an infinite loop when an HTTP server doesn't send a Content-Length header
or closes the connection prematurely.

The read loop was assuming read operations would always return data, but:
1. When the stream pointer becomes invalid (connection closed), read() returns -1
2. When no more data is available, read() returns 0

Without these checks, the loop would continue indefinitely, causing:
- "Stream pointer vanished!" errors (Arduino platform)
- CPU spinning on zero-byte reads
- Watchdog timeouts

The fix adds validation checks to break out of read loops when
read() returns <= 0 (covering both error and end-of-stream conditions).

This is applied to:
- Response capture loops (http_request.h)
- OTA firmware download loop (ota_http_request.cpp)
- MD5 verification download loop (ota_http_request.cpp)

This allows graceful handling of non-compliant HTTP servers while
maintaining compatibility with properly formatted responses.

Fixes esphome/issues#6682

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-14 16:18:37 +00:00
J. Nick Koston
2bfa1aacd8 Merge branch 'skip_wifi_rssi_publish_when_discoed' into integration 2025-12-14 09:55:42 -06:00
J. Nick Koston
1b551b0897 [wifi_signal] Skip publishing disconnected RSSI value 2025-12-14 09:55:09 -06:00
J. Nick Koston
7e1bd289b3 Merge branch 'fix-polling-component-schema' into integration 2025-12-14 09:38:15 -06:00
J. Nick Koston
cf373edd81 Merge branch 'lwip_raw_tcp_impl_getpeername' into integration 2025-12-14 09:38:07 -06:00
J. Nick Koston
0d7fbb79b3 Merge branch 'events_trusted_domains' into integration 2025-12-14 09:38:01 -06:00
J. Nick Koston
c87771184e Merge branch 'fix-epaper-spi-update-interval-never' into integration 2025-12-14 09:37:56 -06:00
J. Nick Koston
1185abadc1 Merge branch 'always_lru_enable_idf_web_server' into integration 2025-12-14 09:37:49 -06:00
J. Nick Koston
6f6c65509d [web_server_idf] Always enable LRU purge to prevent socket exhaustion 2025-12-14 09:37:11 -06:00
J. Nick Koston
f50ffb2b92 cover 2025-12-14 09:09:24 -06:00
J. Nick Koston
4892bfb6e4 [dashboard] Add ESPHOME_TRUSTED_DOMAINS support to events WebSocket 2025-12-14 09:00:27 -06:00
Jonathan Swoboda
586e82bfa5 [core] Fix polling_component_schema and use SCHEDULER_DONT_RUN constant
- Fix polling_component_schema to use update_interval validator when
  default_update_interval is None (was using None as validator)
- Replace hardcoded 4294967295 with SCHEDULER_DONT_RUN constant in
  update_interval function

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-14 09:41:56 -05:00
J. Nick Koston
512a7df007 [socket] Fix getpeername() returning local address instead of remote in LWIP raw TCP 2025-12-13 22:49:05 -06:00
J. Nick Koston
0e60aefdec Merge remote-tracking branch 'upstream/dev' into integration 2025-12-13 22:15:41 -06:00
David Woodhouse
1ebfd5b4eb Update test for new get_build_info behaviour
get_build_info() now always returns current time instead of preserving
the existing build_time. The timestamp preservation logic is now handled
in copy_src_tree() based on sources_changed flag.
2025-12-14 09:07:44 +09:00
David Woodhouse
4bde4dbdc8 Fix KeyError when build_info_data.h not in source_files_copy
Use pop(t, None) instead of pop(t) to handle case where
build_info_data.h might not be in the component resources.
2025-12-14 08:55:25 +09:00
David Woodhouse
841d9664d3 Fix build system to relink when source files change
- Make copy_file_if_changed() return bool indicating if file was copied
- Track sources_changed in copy_src_tree() to detect when source files change
- Only update build_info timestamp when sources/config/version change
- Exclude generated files (build_info_data.h) from sources_changed tracking
- Add build_info_data.h to ignore_targets to prevent copying from resources
- Track changes to generated headers (defines.h, esphome.h, version.h)
- Check for config_hash or version changes to trigger rebuild
- Pretty-print build_info.json with indentation and trailing newline
- Update mock_copy_file_if_changed to return True by default

This fixes the issue where changing a source file would recompile the .o
file but not relink the final program executable.
2025-12-14 08:51:59 +09:00
J. Nick Koston
16107ad788 bot comments 2025-12-13 10:34:09 -06:00
J. Nick Koston
8299656375 Update esphome/components/sgp4x/sgp4x.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 10:32:39 -06:00
J. Nick Koston
184ac0c1e7 Update esphome/components/sgp30/sgp30.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 10:32:33 -06:00
J. Nick Koston
6198618044 Update esphome/components/sen5x/sen5x.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 10:32:25 -06:00
J. Nick Koston
ba0f559856 better cover 2025-12-13 10:10:24 -06:00
J. Nick Koston
0539c5d4d2 cover 2025-12-13 10:02:54 -06:00
J. Nick Koston
bb35ed5f53 tidy 2025-12-13 09:54:07 -06:00
J. Nick Koston
de500450d9 coverage for hash order change 2025-12-13 09:45:17 -06:00
J. Nick Koston
b4a54f2df1 sort so config hash does not change 2025-12-13 09:40:26 -06:00
J. Nick Koston
cf8708b888 writer coverage 2025-12-13 09:28:52 -06:00
J. Nick Koston
15494c0d28 Merge branch 'buildinfo' of https://github.com/dwmw2/esphome into buildinfo 2025-12-13 09:25:32 -06:00
J. Nick Koston
4bf810fcd1 a bit of future proofing to avoid many dumps if it gets reused 2025-12-13 09:25:21 -06:00
J. Nick Koston
959a2e8ddd Merge branch 'dev' into buildinfo 2025-12-13 09:22:09 -06:00
J. Nick Koston
4b937b5228 some coverage 2025-12-13 09:21:53 -06:00
J. Nick Koston
0c7c1d3c57 check version as well 2025-12-13 09:13:28 -06:00
J. Nick Koston
d31be6ed9d check version as well 2025-12-13 09:10:40 -06:00
J. Nick Koston
dce5face4e simplify more 2025-12-13 09:01:39 -06:00
J. Nick Koston
6d91f1cd77 tests 2025-12-13 08:56:12 -06:00
J. Nick Koston
67937aeda4 tests 2025-12-13 08:55:26 -06:00
J. Nick Koston
1543f56f70 simplify approach 2025-12-13 08:53:51 -06:00
J. Nick Koston
e0ce66e011 [core] Fix CORE.raw_config not updated after package merge (#12456) 2025-12-13 07:38:31 -06:00
J. Nick Koston
2fc3ef61ea adjust 2025-12-12 21:42:07 -06:00
J. Nick Koston
145475e461 tidy 2025-12-12 21:31:43 -06:00
J. Nick Koston
b1fb705864 [esp8266] Avoid heap allocation in preferences save/load 2025-12-12 21:28:21 -06:00
David Woodhouse
15d2d3ff96 Update esphome/core/buildinfo.cpp
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-12-13 12:13:01 +09:00
David Woodhouse
d016302e36 Convert buildinfo.h to C++17 nested namespace syntax 2025-12-13 12:05:05 +09:00
David Woodhouse
fe798dff81 Update esphome/writer.py
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-12-13 12:03:43 +09:00
J. Nick Koston
75b8279361 Merge remote-tracking branch 'upstream/dev' into integration 2025-12-12 21:03:28 -06:00
David Woodhouse
17db6bee3c Update esphome/__main__.py
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-12-13 12:03:12 +09:00
David Woodhouse
e7c8892d6d Merge branch 'dev' into buildinfo 2025-12-13 12:00:08 +09:00
David Woodhouse
12e0d6bdcc Create and use buildinfo.json instead of parsing linker script
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-12-13 11:57:04 +09:00
David Woodhouse
d8c52297ab Add type hints to _encode_string_symbols function 2025-12-13 11:54:24 +09:00
David Woodhouse
6fce0a6104 Add host platform support to MD5 component (#12458) 2025-12-13 02:50:34 +00:00
David Woodhouse
eda0a391ca Extract duplicate string encoding logic into helper function 2025-12-13 11:26:37 +09:00
David Woodhouse
94fefb1405 Limit OSError exception catch to file open operation only 2025-12-13 11:26:37 +09:00
David Woodhouse
da96ffb923 Convert buildinfo to C++17 nested namespace syntax 2025-12-13 11:26:37 +09:00
David Woodhouse
d7451257a5 Merge branch 'dev' into buildinfo 2025-12-13 11:20:39 +09:00
J. Nick Koston
b10a87c1b0 Merge branch 'factory_reset_waste' into integration 2025-12-12 20:14:42 -06:00
J. Nick Koston
f2505ce453 tidy 2025-12-12 20:14:31 -06:00
David Woodhouse
32797fbe00 Generate buildinfo.ld directly, use fnv1a_32bit_hash()
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-12-13 11:11:59 +09:00
J. Nick Koston
ec7143d835 Merge branch 'factory_reset_waste' into integration 2025-12-12 20:09:19 -06:00
J. Nick Koston
d77f9c96b9 [factory_reset] Optimize memory by storing interval as uint16_t seconds 2025-12-12 20:08:00 -06:00
J. Nick Koston
4329794924 Merge branch 'ota_align_password' into integration 2025-12-12 19:39:06 -06:00
J. Nick Koston
99b0b974ad [esphome] Improve OTA field alignment to save 4 bytes on 32-bit 2025-12-12 19:38:44 -06:00
J. Nick Koston
9dafafa07c Merge branch 'memory_api' into integration 2025-12-12 19:25:14 -06:00
J. Nick Koston
200cd8cace Merge branch 'str_helpers' into integration 2025-12-12 19:25:09 -06:00
J. Nick Koston
ce717e2276 Merge branch 'integration' into memory_api 2025-12-12 19:24:21 -06:00
J. Nick Koston
20b6d28c90 Merge remote-tracking branch 'upstream/dev' into integration 2025-12-12 19:24:14 -06:00
David Woodhouse
ff7651875e Add HMAC-MD5 component tests (#12459) 2025-12-12 19:19:31 -06:00
David Woodhouse
1a43a06dd4 Add USE_SHA256 define to sha256 component to enable tests (#12457) 2025-12-12 19:15:50 -06:00
Jonathan Swoboda
b8c00e6452 Merge branch 'dev' into fix-epaper-spi-update-interval-never 2025-12-12 17:25:02 -05:00
Jonathan Swoboda
1d081fd510 [epaper_spi] Fix update_interval: never validation error
- Add full_display_schema() function to display component to allow
  configurable default update_interval
- Fix epaper_spi to use 60s default update_interval instead of 1s
- Fix minimum update_interval validation to allow "never" value
- Keep FULL_DISPLAY_SCHEMA constant for backward compatibility

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-12 16:59:50 -05:00
David Woodhouse
a86095d865 Merge branch 'dev' into buildinfo 2025-12-13 06:24:20 +09:00
David Woodhouse
e728e8ed0c Apply clang-format suggestions to buildinfo.cpp
- Use <cstdint> instead of <stdint.h>
- Rename config_hash_struct to ConfigHashStruct for naming consistency
2025-12-13 06:17:28 +09:00
dependabot[bot]
51b187954a Bump ruff from 0.14.8 to 0.14.9 (#12448)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-12-12 19:20:06 +00:00
dependabot[bot]
9126b32c35 Bump actions/cache from 4.3.0 to 5.0.1 in /.github/actions/restore-python (#12453)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-12 13:17:08 -06:00
dependabot[bot]
4993bb2f49 Bump github/codeql-action from 4.31.7 to 4.31.8 (#12451)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-12 13:16:41 -06:00
dependabot[bot]
2b40af3459 Bump actions/cache from 4.3.0 to 5.0.1 (#12450)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-12 13:16:29 -06:00
dependabot[bot]
b3e967a233 Bump actions/download-artifact from 6.0.0 to 7.0.0 (#12449)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-12 13:15:41 -06:00
dependabot[bot]
26a08e3ae3 Bump actions/upload-artifact from 5.0.0 to 6.0.0 (#12452)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-12 13:15:28 -06:00
J. Nick Koston
80fda97c60 [core] Refactor str_snake_case and str_sanitize to use constexpr helpers 2025-12-12 13:13:07 -06:00
J. Nick Koston
b2a1448fe4 Merge branch 'integration' into memory_api 2025-12-12 12:37:42 -06:00
J. Nick Koston
e05e5bc82c Merge branch 'wifi_cleanups' into integration 2025-12-12 12:37:36 -06:00
J. Nick Koston
eeefc0e6c4 [wifi] Replace optional with sentinel values to reduce RAM and clarify API 2025-12-12 12:35:30 -06:00
J. Nick Koston
d54088d1fb Merge branch 'integration' into memory_api 2025-12-12 11:39:41 -06:00
J. Nick Koston
16a532f565 Merge remote-tracking branch 'upstream/dev' into integration 2025-12-12 11:39:31 -06:00
Jonathan Swoboda
64d650c65c Merge branch 'beta' into dev 2025-12-12 12:15:52 -05:00
Jonathan Swoboda
375e53105f Merge pull request #12444 from esphome/bump-2025.12.0b2
2025.12.0b2
2025-12-12 12:15:41 -05:00
David Woodhouse
7d3afe5de0 Merge branch 'dev' into buildinfo 2025-12-13 01:45:43 +09:00
David Woodhouse
b5703523f9 nolint for the macros that have to be macros 2025-12-13 01:44:25 +09:00
David Woodhouse
07d784b0bf Pass config hash and build date in as strings via linker symbols
This saves the RAM we were using to build it at runtime.
2025-12-13 01:39:29 +09:00
Jonathan Swoboda
c9506b056d Bump version to 2025.12.0b2 2025-12-12 11:12:58 -05:00
Jonathan Swoboda
2c77668a05 [http_request] Skip update check when network not connected (#12418)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-12 11:12:58 -05:00
J. Nick Koston
5567d96dd9 [esp8266] Eliminate up to 16ms socket latency (#12397) 2025-12-12 11:12:58 -05:00
J. Nick Koston
78b76045ce [api] Fix potential buffer overflow in noise PSK base64 decode (#12395) 2025-12-12 11:12:58 -05:00
J. Nick Koston
1d13d18a16 [light] Add zero-copy support for API effect commands (#12384) 2025-12-12 11:12:58 -05:00
Jonathan Swoboda
d30d8156c1 [http_request] Skip update check when network not connected (#12418)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-12 10:31:17 -05:00
David Woodhouse
25805da008 Merge branch 'dev' into buildinfo 2025-12-12 09:54:47 +09:00
dependabot[bot]
8d1e68c4c1 Bump tornado from 6.5.2 to 6.5.3 (#12430)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-11 17:53:12 -06:00
David Woodhouse
ccebe613e2 Optimize buildinfo RAM usage on 32-bit platforms
Use direct symbol access on 32-bit platforms to avoid 8 bytes of RAM
overhead. Keep indirection workaround only on 64-bit platforms where
PC-relative relocations cause linking issues.
2025-12-12 01:51:12 +09:00
David Woodhouse
295b317809 Optimize get_build_time_string to avoid repeated formatting
Apply same concurrency fix as get_config_hash to prevent race
conditions when multiple threads access the function.
2025-12-11 22:54:19 +09:00
David Woodhouse
58fddeb74f Optimize get_config_hash to avoid repeated snprintf calls
Check if hash string is already formatted before calling snprintf,
since static variables in BSS are zero-initialized.
2025-12-11 22:53:03 +09:00
David Woodhouse
54ed6154eb Expand non-const comment 2025-12-11 22:49:32 +09:00
David Woodhouse
0b1ea8f2ca Add nolint for non-const buildinfo variables
Variables must remain non-const to prevent compiler optimization
that would bypass the indirection workaround for PC-relative
relocation issues.
2025-12-11 22:48:02 +09:00
David Woodhouse
478f12f75e Remove const from buildinfo static variables
The const qualifier allows compiler optimization that bypasses our
indirection workaround, causing PC-relative relocations that fail
on some platforms. Keep variables non-const to force data section
relocations.
2025-12-11 22:46:09 +09:00
David Woodhouse
cfdb5a82e2 Replace __DATE__/__TIME__ with buildinfo functions
- Add get_build_time_string() function to format build time consistently
- Replace __DATE__ ", " __TIME__ in App.pre_setup() with buildinfo call
- Eliminates dependency on compiler-provided date/time macros
- Ensures consistent build time across all build information displays
2025-12-11 22:24:30 +09:00
David Woodhouse
edc320fef8 Add buildinfo system with config hash and build time
To allow for more selective managed updates, allow the config hash and
build time to be built into the image itself.

To avoid triggering unneeded rebuilds, do this through a linker script
so that the new config hash and timestamp are included only if the
firmware is actually relinked.

Add a _check_and_emit_buildinfo() step after building, which prints
the information after the firmware was rebuilt. A subsequent commit
will emit a manifest here, or at least the HMAC-MD5 for signing OTA
updates using the hmac_key configured in this image.
2025-12-11 22:24:30 +09:00
J. Nick Koston
74218bc742 [api] Release prologue memory after noise handshake completes (#12412) 2025-12-10 19:33:22 -06:00
J. Nick Koston
369cc70fdf [climate] Save 48 bytes per entity by conditionally compiling visual overrides (#12406) 2025-12-10 19:10:42 -06:00
dependabot[bot]
1f0a27b181 Bump codecov/codecov-action from 5.5.1 to 5.5.2 (#12408)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-10 22:34:24 +01:00
J. Nick Koston
d7cb3d8e35 Merge branch 'integration' into memory_api 2025-12-10 22:32:19 +01:00
J. Nick Koston
6519b90829 Merge branch 'noise_prologue_not_released' into integration 2025-12-10 22:31:59 +01:00
J. Nick Koston
5c39ff7b5c [api] Release prologue memory after noise handshake completes 2025-12-10 22:31:09 +01:00
dependabot[bot]
22918d3bd5 Bump peter-evans/create-pull-request from 7.0.11 to 8.0.0 (#12409)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-10 22:21:29 +01:00
J. Nick Koston
7a9fce90cb [text] Add integration tests for text command API (#12401) 2025-12-10 12:13:40 -05:00
J. Nick Koston
4f9c00382e Merge branch 'integration' into memory_api 2025-12-10 13:50:46 +01:00
J. Nick Koston
afd9fc6c96 Merge branch 'visual_overrides_rarely_used' into integration 2025-12-10 13:50:33 +01:00
J. Nick Koston
a3017ca3be [climate] Save 48 bytes per entity by conditionally compiling visual overrides 2025-12-10 13:46:50 +01:00
dependabot[bot]
d1d376ebc8 Bump actions/create-github-app-token from 2.2.0 to 2.2.1 (#12370)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-10 13:05:01 +01:00
J. Nick Koston
2d3ccab0b3 [api] Add zero-copy support for noise encryption key requests 2025-12-10 12:48:04 +01:00
J. Nick Koston
fdd560b165 [fan] Add zero-copy support for API preset mode commands 2025-12-10 12:40:35 +01:00
J. Nick Koston
6b810b340a fix 2025-12-10 12:38:04 +01:00
J. Nick Koston
3cd14fa39d [climate] Add zero-copy support for API custom fan mode and preset commands 2025-12-10 10:45:07 +01:00
J. Nick Koston
c124d72ea9 [esp8266] Eliminate up to 16ms socket latency (#12397) 2025-12-10 03:45:27 +00:00
J. Nick Koston
5b83e9e81b Merge branch 'integration' into memory_api 2025-12-10 04:34:28 +01:00
J. Nick Koston
e85aa1e24b Merge remote-tracking branch 'upstream/dev' into integration 2025-12-10 04:34:16 +01:00
J. Nick Koston
567e82cfec [api] Fix potential buffer overflow in noise PSK base64 decode (#12395) 2025-12-10 04:20:23 +01:00
J. Nick Koston
b1f9100b02 [core] Add constexpr parse_hex_char helper and simplify parse_hex (#12394) 2025-12-10 04:20:08 +01:00
J. Nick Koston
d0fbc82f47 [esp32_ble_client] Use stack-based MAC formatting in auth logging (#12393)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-10 04:19:52 +01:00
J. Nick Koston
03c391bd43 [light] Add zero-copy support for API effect commands (#12384) 2025-12-10 04:19:29 +01:00
J. Nick Koston
95609480b7 Merge branch 'integration' into memory_api 2025-12-10 04:01:12 +01:00
J. Nick Koston
7dca3c9eee Merge branch 'esp8266_wake' into integration 2025-12-10 04:01:07 +01:00
J. Nick Koston
cbbb3bbabc wake flag 2025-12-10 04:00:54 +01:00
J. Nick Koston
3aaca9e668 Merge branch 'integration' into memory_api 2025-12-10 03:57:59 +01:00
J. Nick Koston
33bba52a79 Merge branch 'esp8266_wake' into integration 2025-12-10 03:57:54 +01:00
J. Nick Koston
e160fcce0e fixes 2025-12-10 03:51:20 +01:00
Jonathan Swoboda
5601a2b686 Merge branch 'beta' into dev 2025-12-09 21:34:12 -05:00
Jonathan Swoboda
a3a2a6d965 Merge pull request #12396 from esphome/bump-2025.12.0b1
2025.12.0b1
2025-12-09 21:33:58 -05:00
J. Nick Koston
fa58cf7f9f Merge branch 'integration' into memory_api 2025-12-10 03:25:47 +01:00
J. Nick Koston
5b9053c678 Merge branch 'esp8266_wake' into integration 2025-12-10 03:25:41 +01:00
J. Nick Koston
a9a3103a0d more legacy code that clang-tidy is complaining about 2025-12-10 03:25:31 +01:00
J. Nick Koston
ccd0df87ac Merge branch 'integration' into memory_api 2025-12-10 03:21:03 +01:00
J. Nick Koston
79b6f2a288 Merge branch 'esp8266_wake' into integration 2025-12-10 03:20:58 +01:00
J. Nick Koston
795ace5eaa make clang-tidy happy 2025-12-10 03:17:17 +01:00
J. Nick Koston
0a5e8af69f Merge branch 'integration' into memory_api 2025-12-10 03:10:49 +01:00
J. Nick Koston
a84de27831 Merge branch 'esp8266_wake' into integration 2025-12-10 03:10:37 +01:00
J. Nick Koston
a4e81dc176 [socket] Wake loop immediately on socket data for ESP8266 2025-12-10 03:09:47 +01:00
J. Nick Koston
882838c389 Merge branch 'integration' into memory_api 2025-12-10 02:35:03 +01:00
J. Nick Koston
564bc7caf1 Merge branch 'noise_eliminate_temp_std_vector' into integration 2025-12-10 02:34:58 +01:00
J. Nick Koston
f10a2ed6bc fix buffer overflow 2025-12-10 02:26:49 +01:00
J. Nick Koston
d442095d9a fix buffer overflow 2025-12-10 02:26:12 +01:00
J. Nick Koston
d52981fe01 Merge branch 'integration' into memory_api 2025-12-10 02:22:38 +01:00
J. Nick Koston
29f2b358d1 Merge branch 'noise_eliminate_temp_std_vector' into integration 2025-12-10 02:22:30 +01:00
J. Nick Koston
9fd952c18b [core] Eliminate temporary vector in base64_decode buffer overload 2025-12-10 02:18:23 +01:00
Jonathan Swoboda
84d5348bd8 Bump version to 2026.1.0-dev 2025-12-09 20:08:35 -05:00
Jonathan Swoboda
26770e09dc Bump version to 2025.12.0b1 2025-12-09 20:08:35 -05:00
J. Nick Koston
45e843779c Merge branch 'integration' into memory_api 2025-12-10 02:04:37 +01:00
J. Nick Koston
a56c8e4d37 Merge branch 'parse_hex_constexpr' into integration 2025-12-10 02:04:23 +01:00
J. Nick Koston
0ece36ecc5 [core] Add constexpr parse_hex_char helper and simplify parse_hex 2025-12-10 02:02:53 +01:00
J. Nick Koston
231199defe Merge branch 'integration' into memory_api 2025-12-10 01:50:33 +01:00
J. Nick Koston
eb2781e418 Merge branch 'ble_mac_address_formatting_cleanup' into integration 2025-12-10 01:50:27 +01:00
J. Nick Koston
7bdee7261d Update esphome/components/esp32_ble_client/ble_client_base.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-10 01:50:06 +01:00
J. Nick Koston
efbd202518 Merge branch 'integration' into memory_api 2025-12-10 01:47:10 +01:00
J. Nick Koston
f50feca026 Merge branch 'ble_mac_address_formatting_cleanup' into integration 2025-12-10 01:46:56 +01:00
J. Nick Koston
602f25ba89 [esp32_ble_client] Use stack-based MAC formatting in auth logging 2025-12-10 01:46:28 +01:00
J. Nick Koston
56f699e897 Merge branch 'integration' into memory_api 2025-12-10 01:36:18 +01:00
J. Nick Koston
efbdbc63d0 Merge remote-tracking branch 'upstream/dev' into integration 2025-12-10 01:36:11 +01:00
Javier Peletier
9f2693ead5 [core] Packages refactor and conditional package inclusion (package refactor part 1) (#11605)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-12-10 00:59:58 +01:00
J. Nick Koston
3642399460 [tests] Fix clang-tidy warnings in custom_api_device_component fixture (#12390) 2025-12-10 00:50:26 +01:00
J. Nick Koston
3a6edbc2c7 [micronova] Fix test UART package key to match directory name (#12391) 2025-12-10 00:49:44 +01:00
J. Nick Koston
608f834eaa [ci] Isolate usb_cdc_acm in component tests due to tinyusb/usb_host conflict (#12392) 2025-12-10 00:49:29 +01:00
J. Nick Koston
5919355d18 [ci] Allow memory impact target branch build to fail without blocking CI (#12381) 2025-12-10 00:26:24 +01:00
J. Nick Koston
e0147aab16 Merge branch 'light_effects_call_zero_copy' into integration 2025-12-09 23:52:12 +01:00
J. Nick Koston
724fb222dc Merge remote-tracking branch 'upstream/dev' into integration
# Conflicts:
#	esphome/components/api/api_connection.cpp
#	esphome/components/api/api_server.cpp
#	esphome/components/api/api_server.h
#	esphome/components/wifi_signal/wifi_signal_sensor.h
#	esphome/core/string_ref.h
2025-12-09 23:51:44 +01:00
dependabot[bot]
1e23b10eed Bump aioesphomeapi from 43.1.0 to 43.2.1 (#12385)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-09 22:02:42 +00:00
Clyde Stubbs
ad0218fd40 [mipi_rgb] Add Waveshare 3.16 (#12309) 2025-12-10 08:17:59 +11:00
J. Nick Koston
8525f24a3b [light] Add zero-copy support for API effect commands 2025-12-09 21:53:03 +01:00
Clyde Stubbs
87142efbb4 [epaper_spi] Set reasonable default update interval (#12331) 2025-12-10 06:42:11 +11:00
Robert Resch
329b38fa29 [micronova] Require memory location and address for custom entities (#12371) 2025-12-09 14:30:55 -05:00
Jonathan Swoboda
4b44c7384b Merge branch 'release' into dev 2025-12-09 12:54:45 -05:00
Jonathan Swoboda
a593965372 Merge pull request #12380 from esphome/bump-2025.11.5
2025.11.5
2025-12-09 12:54:30 -05:00
Jonathan Swoboda
4743e5592a Bump version to 2025.11.5 2025-12-09 12:02:53 -05:00
Jonathan Swoboda
464607011c [mqtt] Fix logger method case sensitivity error (#12379)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-09 12:02:53 -05:00
J. Nick Koston
16fe8f9e9e [libretiny] Fix WiFi scan timeout loop when scan fails (#12356) 2025-12-09 12:02:46 -05:00
J. Nick Koston
436d2c44e8 [wifi] Fix scan timeout loop when scan returns zero networks (#12354) 2025-12-09 12:01:51 -05:00
J. Nick Koston
b213555dd2 [scheduler] Fix missing lock when recycling items in defer queue processing (#12343) 2025-12-09 12:01:51 -05:00
Clyde Stubbs
b6336f9e63 [lvgl] Number saves value on interactive change (#12315) 2025-12-09 12:01:51 -05:00
Clyde Stubbs
fb7800a22f [binary_sensor] Fix reporting of 'unknown' (#12296)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-12-09 12:01:51 -05:00
J. Nick Koston
2c0f4d8f80 [api] Reduce heap usage for Home Assistant service call string storage (#12151) 2025-12-09 16:35:14 +01:00
J. Nick Koston
e96c37965c [wifi] Fix LibreTiny spurious disconnect events aborting connections (#12357) 2025-12-09 16:26:27 +01:00
J. Nick Koston
72c74bc0b3 [api] Store Home Assistant state subscriptions in flash instead of heap (#12008) 2025-12-09 16:26:11 +01:00
J. Nick Koston
443f9c3f57 [api] Use StringRef for ActionResponse error message to avoid copy (#12240) 2025-12-09 16:10:43 +01:00
Javier Peletier
88a2e75989 [packages] Add more information and deprecation deadline for "single package" includes (#12280) 2025-12-09 16:04:10 +01:00
J. Nick Koston
e1afd65fae [api] Store device info strings in flash on ESP8266 (#12173) 2025-12-09 15:59:27 +01:00
Jonathan Swoboda
27e031c257 [mqtt] Fix logger method case sensitivity error (#12379)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-09 09:43:47 -05:00
Jonathan Swoboda
74f509c754 [core] Add PR template instruction to AI instructions (#12375)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-09 15:42:06 +01:00
J. Nick Koston
f9aa48295c [mdns] Reduce RAM usage by eliminating MAC address heap allocation (#12073) 2025-12-09 09:33:23 -05:00
J. Nick Koston
861ed8dd41 [scheduler] Avoid std::string allocation in RetryArgs (#12311) 2025-12-09 09:27:12 -05:00
Clyde Stubbs
750f4ea797 [pio] Rationalise library definitions in platformio.ini (#12374) 2025-12-09 08:40:58 -05:00
Clyde Stubbs
6945b44af5 [psram] Fix boot failure with 120MHz Octal flash (#12377) 2025-12-09 08:38:16 -05:00
Mirko Vogt
fcae13836c [sx1509] Change setup priority from HARDWARE to IO (#12373)
Co-authored-by: Your Name <you@example.com>
2025-12-08 22:50:07 -05:00
Robert Resch
3eaa9f164b [micronova] Remove MicroNovaFunctions (#12363)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-08 14:38:13 -05:00
smarthome-10
4c31961ae9 Update URLs (#12369)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-12-08 14:37:45 -05:00
Sébastien Blanchet
7a20c85eec [i2c] Fix port logic with ESP-IDF (#12063)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-12-08 14:12:15 -05:00
Robert Resch
9f60aed9b0 [micronova] Make stove switch entity independent (#12355)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-08 11:18:44 -05:00
J. Nick Koston
801d1135ab [select] Add zero-copy support for API select commands (#12329) 2025-12-08 10:37:51 -05:00
J. Nick Koston
d635892ecf [core] Use StringRef for get_comment and get_compilation_time to avoid allocations (#12219)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-08 10:36:13 -05:00
Johannes Nau
7e486b1c25 [pca9685] Allow to disable the phase balancer for PCA9685 (#9792) 2025-12-08 10:34:26 -05:00
Keith Burzinski
eda743ee48 [usb_cdc_acm] New component (#11687)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-12-08 09:50:23 -05:00
Sébastien Blanchet
5144154f91 [hub75] fix id conflict (#12365) 2025-12-08 14:31:05 +00:00
J. Nick Koston
4466c4c69f [libretiny] Fix WiFi scan timeout loop when scan fails (#12356) 2025-12-08 09:09:04 -05:00
Richard Kubíček
c7382fc494 [hlw8032] Single-phase metering IC (#7241)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-08 09:07:10 -05:00
Robert Resch
95efb37045 [micronova] Set the write bit automatically (#12318)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-08 08:39:43 -05:00
Berik Visschers
2515f1c080 Add seeed_xiao_esp32c6 board definition (#12307)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-08 08:37:59 -05:00
J. Nick Koston
53ddd1a1cd [wifi_signal] Add ifdef guards for clang-tidy compatibility (#12362) 2025-12-08 07:43:48 -05:00
J. Nick Koston
b953c0322c Merge branch 'integration' into memory_api 2025-12-07 22:13:53 -06:00
J. Nick Koston
ed8b21aec3 Merge branch 'libretiny_wifi' into integration 2025-12-07 22:13:42 -06:00
J. Nick Koston
93a85d7979 [wifi_signal] Update signal strength immediately on WiFi connect/disconnect (#12347) 2025-12-07 22:08:46 -06:00
J. Nick Koston
159194587b [core] Move Color::gradient to cpp to avoid duplicate code (#12348) 2025-12-07 22:08:21 -06:00
J. Nick Koston
590f9ca488 Merge branch 'dev' into libretiny_wifi 2025-12-07 22:00:15 -06:00
J. Nick Koston
ffb3e2eb0a [wifi] Fix scan timeout loop when scan returns zero networks (#12354) 2025-12-07 22:00:04 -06:00
J. Nick Koston
da4bd321f0 [libretiny] Fix WiFi scan timeout loop when scan fails 2025-12-07 21:54:09 -06:00
Robert Resch
c5cc91f6f0 [micronova] Add FINAL_VALIDATE_SCHEMA to validate uart (#12350)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-07 21:02:05 -05:00
J. Nick Koston
26475cd7d3 Merge branch 'integration' into memory_api 2025-12-07 18:51:22 -06:00
J. Nick Koston
50ce7b361a Merge branch 'wifi_scan_failure_recover' into integration 2025-12-07 18:51:16 -06:00
J. Nick Koston
02acfeac2c [wifi] Fix scan timeout loop when scan returns zero networks 2025-12-07 18:50:43 -06:00
Robert Resch
e36e6fbc3f [micronova] Move STOVE_STATES to text sensor file as it's used only there (#12349) 2025-12-07 19:08:41 -05:00
Robert Resch
1134251c32 [micronova] Set update_interval on entities instead on hub (#12226)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-12-07 23:55:36 +00:00
J. Nick Koston
68a7634228 [text] Store pattern as const char* to reduce memory usage (#12335) 2025-12-07 15:33:15 -06:00
J. Nick Koston
dd65488f91 Merge branch 'integration' into memory_api 2025-12-07 15:27:09 -06:00
J. Nick Koston
659f257703 Merge branch 'stale_wifi_signal_on_connect' into integration 2025-12-07 15:27:01 -06:00
J. Nick Koston
9c28bbcfa8 [wifi_signal] Update signal strength immediately on WiFi connect/disconnect 2025-12-07 15:25:04 -06:00
J. Nick Koston
3d5d89ff00 [template] Use C++17 nested namespace syntax (#12346) 2025-12-07 15:09:25 -06:00
Joakim Plate
f015130f2e [esp8266] Allow use of recvfrom for esphome sockets (#12342) 2025-12-07 14:59:59 -06:00
J. Nick Koston
acda5bcd5a [text] Add component tests with pattern coverage (#12345) 2025-12-07 14:34:12 -06:00
Edward Firmo
4b5435fd93 [nextion] Use 16-bit id for pics (#12330)
Co-authored-by: Szczepan <szczepan.staszak@gmail.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-12-07 15:16:49 -05:00
J. Nick Koston
05826d5ead [scheduler] Fix missing lock when recycling items in defer queue processing (#12343) 2025-12-07 13:30:22 -06:00
J. Nick Koston
e7a3cccb4d [text_sensor] Reduce filter memory usage using const char* (#12334) 2025-12-07 13:30:06 -06:00
J. Nick Koston
dbbb5f25e3 Merge branch 'integration' into memory_api 2025-12-07 13:22:04 -06:00
J. Nick Koston
40f865e185 Merge branch 'text_pattern' into integration 2025-12-07 13:21:55 -06:00
J. Nick Koston
6b0128b683 Merge branch 'text_sensor_filters_no_alloc' into integration 2025-12-07 13:21:47 -06:00
J. Nick Koston
475ce1f3fa tweaks 2025-12-07 12:43:02 -06:00
J. Nick Koston
d881e6055e tweak 2025-12-07 10:31:33 -06:00
J. Nick Koston
188148546e [text] Store pattern as const char* to reduce memory usage 2025-12-06 23:55:38 -06:00
J. Nick Koston
e63673f5ef [text] Store pattern as const char* to reduce memory usage 2025-12-06 23:55:15 -06:00
J. Nick Koston
789faca7c4 [text] Store pattern as const char* to reduce memory usage 2025-12-06 23:50:48 -06:00
J. Nick Koston
0610b3a60a [text] Store pattern as const char* to reduce memory usage 2025-12-06 23:49:09 -06:00
J. Nick Koston
36036014cc reduce 2025-12-06 23:30:15 -06:00
J. Nick Koston
5264584202 reduce 2025-12-06 23:29:26 -06:00
J. Nick Koston
716a868da6 reduce 2025-12-06 23:29:10 -06:00
J. Nick Koston
02fcd83461 Merge branch 'text_sensor_filters_no_alloc' into integration 2025-12-06 22:55:54 -06:00
J. Nick Koston
f3a039e70f cover 2025-12-06 22:55:28 -06:00
J. Nick Koston
81f4add324 [text_sensor] Use StringRef for filter static data to avoid heap allocation 2025-12-06 22:31:21 -06:00
J. Nick Koston
8fd7c00613 [text_sensor] Use StringRef for filter static data to avoid heap allocation 2025-12-06 22:29:24 -06:00
J. Nick Koston
49e7ccd937 [text_sensor] Use StringRef for filter static data to avoid heap allocation 2025-12-06 22:25:00 -06:00
J. Nick Koston
c90e91eef8 Merge remote-tracking branch 'upstream/dev' into integration 2025-12-06 21:53:51 -06:00
J. Nick Koston
a100caff9f Merge branch 'zero_copy_select' into integration 2025-12-06 21:33:32 -06:00
dependabot[bot]
1f271e7c10 Bump pytest from 9.0.1 to 9.0.2 (#12332)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-06 21:32:08 -06:00
dependabot[bot]
aeedfdcaf3 Bump aioesphomeapi from 43.0.0 to 43.1.0 (#12333)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-06 21:31:56 -06:00
J. Nick Koston
96108a1277 [select] Add zero-copy support for API select commands 2025-12-06 14:35:43 -06:00
J. Nick Koston
f23428fbaf Merge remote-tracking branch 'upstream/dev' into integration 2025-12-06 14:10:44 -06:00
Jesse Hills
f20aaf3981 [api] Device defined action responses (#12136)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-12-06 09:47:57 -06:00
Clyde Stubbs
75c41b11d1 [lvgl] Number saves value on interactive change (#12315) 2025-12-06 08:49:15 -06:00
Clyde Stubbs
3c7d6b7fc6 [ci-custom] Fix after switch from string to path (#12314) 2025-12-06 07:49:23 -06:00
Clyde Stubbs
7eae0a4972 [image] Add USE_IMAGE in defines.h (#12317) 2025-12-06 07:46:39 -06:00
Jonathan Swoboda
6220427524 [cc1101] Use Hz and cv.frequency instead of kHz (#12313) 2025-12-05 22:32:20 -05:00
J. Nick Koston
aba883a7a7 Merge branch 'retry_no_double_copy' into integration 2025-12-05 20:52:07 -06:00
J. Nick Koston
554ce30fca add missing overloads 2025-12-05 20:46:26 -06:00
J. Nick Koston
05dd1e4602 [scheduler] Avoid std::string allocation in RetryArgs 2025-12-05 20:38:57 -06:00
Clyde Stubbs
6716194e47 [binary_sensor] Fix reporting of 'unknown' (#12296)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-12-05 16:59:29 -06:00
J. Nick Koston
d89aeca65a Merge remote-tracking branch 'upstream/dev' into integration 2025-12-05 15:58:18 -06:00
Jonathan Swoboda
a517e0ec80 [esp32] Add missing variant support (#12305)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-05 16:28:24 -05:00
dependabot[bot]
10b54df771 Bump github/codeql-action from 4.31.6 to 4.31.7 (#12304)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-05 15:17:10 -06:00
dependabot[bot]
bbb71b5359 Bump peter-evans/create-pull-request from 7.0.9 to 7.0.11 (#12303)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-05 15:16:55 -06:00
Ludovic BOUÉ
1fa7adbe8d [mipi_spi] Add M5CORE2 model (#12301) 2025-12-06 07:24:57 +11:00
Stuart Parmenter
7421f31160 [hub75] HUB75 display component (#11153)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-12-05 18:51:32 +00:00
c0mputerguru
78bef42473 [sps30] Add idle mode functionality (#12255)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-12-05 13:33:00 -05:00
J. Nick Koston
7f7c913a85 [light] Fix schedule_show not enabling loop for idle addressable lights (#12302) 2025-12-05 11:47:54 -06:00
Jonathan Swoboda
1a308583b3 [esp32] Add support for ESP32-C61 variant (#12285)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-12-05 12:16:19 -05:00
J. Nick Koston
27fcff2092 [api] Simplify MessageCreator to trivially copyable type (#12295)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-05 10:27:41 -06:00
Jonathan Swoboda
f4d1c9df71 [remote_receiver] Fix Zephyr clang tidy (#12299)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-05 09:56:11 -06:00
Jesse Hills
7fd79fdded [esp32] Change imports to use esp32 only, not .const (#12243) 2025-12-05 09:53:08 -05:00
Jesse Hills
19fa768730 Update readme logo (#12294)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-05 08:48:04 -05:00
J. Nick Koston
948a6f2134 Merge branch 'batch_cleanup' into integration 2025-12-04 22:50:56 -06:00
J. Nick Koston
5cb2128cd5 [api] Simplify MessageCreator to trivially copyable type 2025-12-04 22:50:20 -06:00
Jonathan Swoboda
ca1d17562a Merge branch 'release' into dev 2025-12-04 22:55:08 -05:00
Jonathan Swoboda
42811edeb4 Merge pull request #12293 from esphome/bump-2025.11.4
2025.11.4
2025-12-04 22:54:55 -05:00
Citizen07
22481d9c0e [remote_receiver] buffer usage fix and idle optimizations (#9999)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-04 22:50:23 -05:00
J. Nick Koston
202b580e71 Merge remote-tracking branch 'upstream/dev' into integration 2025-12-04 21:43:05 -06:00
Jonathan Swoboda
8f20abebf6 Bump version to 2025.11.4 2025-12-04 21:52:48 -05:00
J. Nick Koston
7077488dc7 [scheduler] Fix use-after-free when cancelling timeouts from non-main-loop threads (#12288) 2025-12-04 21:52:48 -05:00
Jesse Hills
ef34239064 [CI] Trigger generic version notifier job on release (#12292) 2025-12-04 21:52:48 -05:00
Jonathan Swoboda
44148c0c6b [esp32_hosted] Fix build and bump IDF component version to 2.7.0 (#12282)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-04 21:52:48 -05:00
Jonathan Swoboda
1b53fcf634 [es8311] Remove MIN and MAX from mic_gain enum options (#12281)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-04 21:52:48 -05:00
Clyde Stubbs
b18e3d943a [config] Provide path for has_at_most_one_of messages (#12277) 2025-12-04 21:52:48 -05:00
Jonathan Swoboda
f0673f6304 [ld2420] Add missing USE_SELECT ifdefs (#12275)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-04 21:52:48 -05:00
Clyde Stubbs
320ba30d50 [esp32] Add build flag to suppress noexecstack message (#12272) 2025-12-04 21:52:48 -05:00
J. Nick Koston
637cb3f04a [api] Use loop-based reboot timeout check to avoid scheduler heap churn (#12291)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-04 19:14:35 -06:00
J. Nick Koston
80e881655f [scheduler] Fix use-after-free when cancelling timeouts from non-main-loop threads (#12288) 2025-12-04 19:14:22 -06:00
Jesse Hills
78b2ae8a35 [CI] Trigger generic version notifier job on release (#12292) 2025-12-05 14:00:08 +13:00
Jesse Hills
8caaf53ef0 [CI] Update renamed action repo (#12290) 2025-12-05 12:53:13 +13:00
J. Nick Koston
ad688a88b0 Merge branch 'back_to_loop_check_for_api_reboot' into integration 2025-12-04 17:50:45 -06:00
J. Nick Koston
501a5f8df4 Update esphome/components/api/api_server.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-04 17:49:49 -06:00
J. Nick Koston
2134e4eaea Merge branch 'back_to_loop_check_for_api_reboot' into integration 2025-12-04 17:08:03 -06:00
J. Nick Koston
5f2afe4b82 tweak 2025-12-04 17:04:44 -06:00
J. Nick Koston
d950d3868d fix 2025-12-04 17:01:38 -06:00
J. Nick Koston
2b54f96d67 [api] Use loop-based reboot timeout check to avoid scheduler heap churn 2025-12-04 16:58:09 -06:00
J. Nick Koston
62da4b7057 Merge branch 'scheduler_recycle_safety' into integration 2025-12-04 16:34:36 -06:00
dependabot[bot]
4db7748815 Bump ruff from 0.14.7 to 0.14.8 (#12286)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-12-04 21:53:36 +00:00
Jonathan Swoboda
0da157ab98 [tests] Bump esp32_hosted in the test code (#12289)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-04 21:14:30 +00:00
J. Nick Koston
3e96a86869 [scheduler] Fix use-after-free when cancelling timeouts from non-main-loop threads 2025-12-04 19:58:07 +00:00
Jonathan Swoboda
cafa275579 [esp32_hosted] Fix build and bump IDF component version to 2.7.0 (#12282)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-04 14:47:21 -05:00
Jonathan Swoboda
a31fb223f3 [es8311] Remove MIN and MAX from mic_gain enum options (#12281)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-04 10:00:45 -05:00
J. Nick Koston
f819b740dd Merge remote-tracking branch 'upstream/dev' into integration 2025-12-04 09:36:20 +00:00
Javier Peletier
37019231de [lvgl] refactor hello world to yaml file (#12274) 2025-12-04 20:18:27 +11:00
Clyde Stubbs
2af66bd6fc [config] Provide path for has_at_most_one_of messages (#12277) 2025-12-04 21:20:55 +13:00
Jonathan Swoboda
951c5377c5 [ld2420] Add missing USE_SELECT ifdefs (#12275)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-04 20:25:13 +13:00
Thomas Rupprecht
22803ef54b [esp32] Sort variants in situ (#10410)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-03 20:48:11 -05:00
Clyde Stubbs
20f82a3820 [esp32] Add build flag to suppress noexecstack message (#12272) 2025-12-03 23:49:57 +00:00
dependabot[bot]
fb331e1c5a Bump actions/stale from 10.1.0 to 10.1.1 (#12270)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-03 21:04:09 +00:00
Kevin Ahrendt
a8518d3cea [wifi, wifi_info] Add a WiFi power mode text sensor (#11480)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-12-04 09:18:59 +13:00
jsmarion
03aaa66f8e [cst816] Fix CST826 & CST836 (#12260)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-03 14:35:14 -05:00
J. Nick Koston
a24ba26068 [core] Improve CORE.data documentation with dataclass pattern (#12170)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-04 07:33:57 +13:00
Javier Peletier
623cdac689 [tests] Add testing of command line substitutions (#12210)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-03 12:36:35 -05:00
Jonathan Swoboda
1fbd91dc71 Merge branch 'release' into dev 2025-12-03 11:37:13 -05:00
Jonathan Swoboda
cfd88376b9 Merge pull request #12266 from esphome/bump-2025.11.3
2025.11.3
2025-12-03 11:36:57 -05:00
J. Nick Koston
b3812b5811 [text_sensor] Fix spurious raw_state deprecation warnings (#12262) 2025-12-03 16:22:06 +00:00
Jonathan Swoboda
577a6b2941 Bump version to 2025.11.3 2025-12-03 10:50:28 -05:00
Jonathan Swoboda
de68b56c4a [rtl87xx] Fix FreeRTOS version for RTL8720C boards (#12261)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-03 10:50:28 -05:00
Jonathan Swoboda
ccd23e692b [analog_threshold] Fix oscillation when using invert filter (#12251)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-03 10:50:28 -05:00
Jonathan Swoboda
1f5a44be3d [rtl87xx] Fix AsyncTCP compilation by upgrading FreeRTOS to 8.2.3 (#12230)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-03 10:50:28 -05:00
Jonathan Swoboda
1d1e47c757 [core] Fix clean all windows (#12217)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-12-03 10:50:28 -05:00
3fbed1fa79 [ade7953] Apply voltage_gain setting to both channels (#12180) 2025-12-03 10:50:28 -05:00
Jonathan Swoboda
5c71520635 [mopeka_pro_check] Fix negative temperatures (#12198)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-03 10:50:28 -05:00
J. Nick Koston
9d6c81ec23 [hlk_fm22x] Fix Action::play method signatures (#12192) 2025-12-03 10:50:28 -05:00
Clyde Stubbs
73fa9230e6 [helpers] Add conversion from FixedVector to std::vector (#12179) 2025-12-03 10:50:28 -05:00
J. Nick Koston
48caff13c9 [espnow] Initialize LwIP stack when running without WiFi component (#12169) 2025-12-03 10:50:28 -05:00
J. Nick Koston
71bb94524e [usb_uart] Wake main loop immediately when USB data arrives (#12148) 2025-12-03 10:50:28 -05:00
Clyde Stubbs
a3199792c6 [build] Don't clear pio cache unless requested (#11966) 2025-12-03 10:50:28 -05:00
lygris
87ac4baf3a [cc1101] Add new cc1101 component (#11849)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-03 10:42:04 -05:00
J. Nick Koston
84d4ca61a3 Merge branch 'debug-wifi-power-mode-sensor' into integration 2025-12-03 15:33:02 +00:00
Jonathan Swoboda
669bcad458 [rtl87xx] Fix FreeRTOS version for RTL8720C boards (#12261)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-03 15:31:12 +00:00
H. Árkosi Róbert
6f91c75f86 [gree] turbo, light, health, xfan switches (#12160)
Co-authored-by: clydebarrow <2366188+clydebarrow@users.noreply.github.com>
2025-12-03 09:20:17 +00:00
J. Nick Koston
29c260858f Merge branch 'parition_callbacks' into integration 2025-12-02 22:42:13 -06:00
Kevin Ahrendt
d85d8745f6 use progmem to store strings on ESP8266s 2025-12-02 17:48:05 -05:00
Kevin Ahrendt
224866dfbb fix typo in test 2025-12-02 17:47:25 -05:00
Javier Peletier
ab60ae092d [tests] Allow substitution tests to run independently for debugging (#12224)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-12-02 16:17:24 -06:00
J. Nick Koston
4634eb3ce4 Merge upstream/dev into parition_callbacks
Resolved conflicts in text_sensor.cpp by preserving the PartitionedCallbackManager
implementation while adding back pragma directives for deprecation warnings.
2025-12-02 15:25:25 -06:00
Kevin Ahrendt
7c532ba812 remove unusued include 2025-12-02 15:12:40 -05:00
Kevin Ahrendt
2821f3041c move ifdef guard to outside if statement 2025-12-02 15:08:43 -05:00
Kevin Ahrendt
2a27a3a95a add a power save mode listener and use it for the text sensor 2025-12-02 15:01:39 -05:00
dependabot[bot]
708496c101 Bump actions/checkout from 6.0.0 to 6.0.1 (#12259)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-02 13:45:38 -06:00
Kevin Ahrendt
85d8a26d51 remove icon 2025-12-02 14:27:20 -05:00
Kevin Ahrendt
70fa4dc3b2 fix codegen and increase update interval 2025-12-02 14:26:24 -05:00
Kevin Ahrendt
7dfd20fb4f remove arduino test 2025-12-02 14:11:57 -05:00
Kevin Ahrendt
8ffdfc2aad move sensor to wifi_info 2025-12-02 14:06:24 -05:00
Kevin Ahrendt
3934c1563c Fix bad rebase 2025-12-02 14:03:39 -05:00
Kevin Ahrendt
8c6917fe8b only implement for esp32 2025-12-02 14:03:39 -05:00
Kevin Ahrendt
5115aeeb2b remove untested support for rp2040 and libretiny platforms 2025-12-02 14:03:38 -05:00
Kevin Ahrendt
a3677daee1 ln882x doesn't support it, so remove it 2025-12-02 14:03:38 -05:00
Kevin Ahrendt
4a84221641 Add a WiFi power mode debug text sensor 2025-12-02 14:03:38 -05:00
Jonathan Swoboda
2f75962b19 [analog_threshold] Fix oscillation when using invert filter (#12251)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 13:40:46 -05:00
J. Nick Koston
a6a6f482e6 [core] Add PROGMEM macros and move web_server JSON keys to flash (#12214) 2025-12-02 16:51:05 +00:00
dependabot[bot]
638c59e162 Bump pylint from 4.0.3 to 4.0.4 (#12239)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-02 10:13:20 -06:00
Flo
8f97f3b81f [wifi] Fix ap_active condition (#12227) 2025-12-02 10:12:27 -06:00
J. Nick Koston
6ce2a45691 [text_sensor] Add deprecation warning for raw_state member access (#12246) 2025-12-02 10:03:58 -06:00
J. Nick Koston
77477bd330 [web_server_idf] Fix SSE multi-line message formatting (#12247) 2025-12-02 10:03:29 -06:00
J. Nick Koston
3f08cacf71 [valve] Store valve state strings in flash on ESP8266 (#12202) 2025-12-02 10:02:51 -06:00
J. Nick Koston
d1583456e9 [web_server] Store update state strings in flash on ESP8266 (#12204) 2025-12-02 10:02:29 -06:00
J. Nick Koston
101103c666 [core] Add RAM strings and symbols analysis to analyze-memory command (#12161) 2025-12-02 10:02:09 -06:00
J. Nick Koston
5142ff372b [light] Use listener pattern for state callbacks with lazy allocation (#12166) 2025-12-02 10:01:54 -06:00
J. Nick Koston
f9ad832e7b [esp32_camera] Replace std::function callbacks with CameraListener interface (#12165)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-02 09:59:32 -06:00
J. Nick Koston
deda7a1bf3 [lock] Store lock state strings in flash on ESP8266 (#12163) 2025-12-02 09:59:05 -06:00
Jonathan Swoboda
29be1423f5 [core] Filter noisy platformio log messages (#12218)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-12-02 08:59:50 -05:00
J. Nick Koston
347dcdc018 Merge branch 'give_six_months_for_text_sensor_raw_state' into integration 2025-12-01 23:37:09 -06:00
J. Nick Koston
754f320382 Merge branch 'web_server_idf_fix_sse_line_breaks' into integration 2025-12-01 23:35:57 -06:00
J. Nick Koston
4b83401835 Merge remote-tracking branch 'upstream/dev' into integration 2025-12-01 23:35:45 -06:00
J. Nick Koston
7ad63849f0 [web_server_idf] Fix SSE multi-line message formatting 2025-12-01 23:31:13 -06:00
J. Nick Koston
9f5e04c3d3 [text_sensor] Add deprecation warning for raw_state member access 2025-12-01 22:36:03 -06:00
J. Nick Koston
10ddebc737 [text_sensor] Avoid duplicate string storage when no filters configured (#12205) 2025-12-01 22:17:31 -06:00
dependabot[bot]
9a0731437a Bump aioesphomeapi from 42.9.0 to 42.10.0 (#12245)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 22:11:33 -06:00
J. Nick Koston
82a06c697e [esp32] Place ring buffer functions in flash by default (prep for IDF 6.0) (#12184) 2025-12-02 03:57:41 +00:00
dependabot[bot]
c45cd44bb8 Bump github/codeql-action from 4.31.5 to 4.31.6 (#12234)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 21:49:25 -06:00
Jonathan Swoboda
2903a4aa92 [ota] Use ESP-IDF OTA backend for all ESP32 builds (#12244)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-12-02 03:41:34 +00:00
J. Nick Koston
6943803176 [cover] Store cover state strings in flash on ESP8266 (#12196) 2025-12-01 21:26:13 -06:00
J. Nick Koston
6dafc5137e [esp32] Place FreeRTOS functions in flash by default (prep for IDF 6.0) (#12182) 2025-12-01 21:24:08 -06:00
J. Nick Koston
f34e464ccb Merge remote-tracking branch 'swoboda1337/ota-use-idf-backend-for-all-esp32' into integration 2025-12-01 21:05:48 -06:00
J. Nick Koston
e19529cccc Merge branch 'dev' into ota-use-idf-backend-for-all-esp32 2025-12-01 21:05:33 -06:00
J. Nick Koston
db70f8117d Merge remote-tracking branch 'upstream/dev' into integration 2025-12-01 20:58:37 -06:00
Jonathan Swoboda
9bdff288d1 [ota] Use ESP-IDF OTA backend for all ESP32 builds
Remove the Arduino-specific ESP32 OTA backend and use the ESP-IDF
backend for both Arduino and ESP-IDF framework builds on ESP32.

Since Arduino-ESP32 is built on top of ESP-IDF, the ESP-IDF OTA APIs
(esp_ota_begin, esp_ota_write, esp_ota_end, etc.) are available
regardless of which framework is used.

This simplifies the codebase by removing ~100 lines of duplicate code
and ensures consistent OTA behavior across all ESP32 builds.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 20:45:46 -05:00
Djordje Mandic
df58e832e5 [esp8266] Allow IN&OUT pin config for ESP8266 (#12238) 2025-12-01 15:44:33 -08:00
Peter Popovec
e42cf9a4f4 [mqtt] Enable support for the RTL87XX platform (#7697)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-12-01 23:06:47 +00:00
J. Nick Koston
96f28f0ab4 [button] Convert to C++17 nested namespace style (#12233)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-12-01 17:50:29 -05:00
J. Nick Koston
d332edfaca [datetime] Convert to C++17 nested namespace style (#12235) 2025-12-01 17:50:03 -05:00
J. Nick Koston
0e8e0ca9a8 Merge branch 'action_response_error_ref' into integration 2025-12-01 16:29:34 -06:00
J. Nick Koston
73f3cf9703 [api] Use StringRef for ActionResponse error message to avoid copy 2025-12-01 16:25:06 -06:00
Keith Burzinski
d4bd282bb4 [helpers] Fix unit tests following #12135 (#12237) 2025-12-01 22:08:49 +00:00
J. Nick Koston
a3a6b77cd0 Merge branch 'button_cpp17' into integration 2025-12-01 15:16:17 -06:00
J. Nick Koston
e1f9f68421 Merge branch 'datetime_cpp17' into integration 2025-12-01 15:16:08 -06:00
J. Nick Koston
76d540d6a6 [datetime] Convert to C++17 nested namespace style 2025-12-01 15:09:52 -06:00
J. Nick Koston
0fd878d3c4 [button] Convert to C++17 nested namespace style 2025-12-01 15:06:43 -06:00
Jonathan Swoboda
78df884bb5 [rtl87xx] Fix AsyncTCP compilation by upgrading FreeRTOS to 8.2.3 (#12230)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 16:03:00 -05:00
J. Nick Koston
a09481a352 Merge remote-tracking branch 'upstream/dev' into integration 2025-12-01 14:52:51 -06:00
Keith Burzinski
52fe3de78f [zwave_proxy] Use new socket wake infrastructure to reduce latency, convert to C++17 namespace style (#12135)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-12-01 14:27:20 -06:00
Keith Burzinski
6a79ce8eff [uart] Automatically enable the socket wake infrastructure when RX wake requested (#12221) 2025-12-01 14:16:39 -06:00
Jonathan Swoboda
2b7695ba3f [core] Fix clean all windows (#12217)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-12-01 12:40:56 -05:00
Juri Berlanda
6d336676a2 [remote_transmitter, remote_receiver] Add RP2040 support (#12048)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-12-01 12:09:58 -05:00
Robert Resch
b322622ef1 [micronova] Convert to C++17 namespace style (#12229) 2025-12-01 10:47:00 -05:00
J. Nick Koston
065c1bfc6a [core] Fix status_momentary API misuse and optimize parameter type (#12216) 2025-12-01 08:34:07 -06:00
Keith Burzinski
664881bc13 [uart] Convert to C++17 namespace style (#12220) 2025-12-01 07:57:18 -05:00
Keith Burzinski
dbc16ce468 [wifi_info] Fix compilation error when using only mac_address sensor, add tests (#12222) 2025-12-01 02:48:47 -06:00
Keith Burzinski
161a18b326 [uart] Add wake_loop_on_rx flag for low latency processing (#12172)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-12-01 00:33:23 -06:00
J. Nick Koston
8e8b2f3a9c Merge branch 'comment_comp_time' into integration 2025-12-01 00:26:04 -06:00
J. Nick Koston
ae6c123784 cleaner 2025-11-30 23:40:25 -06:00
J. Nick Koston
8c828884c0 Merge branch 'comment_comp_time' into integration 2025-11-30 22:51:39 -06:00
J. Nick Koston
edf19b8dd4 [core] Use StringRef for get_comment and get_compilation_time to avoid allocations 2025-11-30 22:49:23 -06:00
J. Nick Koston
b5a3c0be21 [core] Use StringRef for get_comment and get_compilation_time to avoid allocations 2025-11-30 22:47:40 -06:00
J. Nick Koston
de6b20d495 [core] Use StringRef for get_comment and get_compilation_time to avoid allocations 2025-11-30 22:44:30 -06:00
J. Nick Koston
4dbe0dab51 [core] Use StringRef for get_comment and get_compilation_time to avoid allocations 2025-11-30 22:42:20 -06:00
Jonathan Swoboda
4335fcdb72 [psram] Add C5 support (#12215)
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-30 23:27:10 -05:00
J. Nick Koston
5996ae4dc5 Merge branch 'moment_api_misuse_fix' into integration 2025-11-30 22:02:10 -06:00
J. Nick Koston
d9a8bb9774 [core] Fix status_momentary API misuse and optimize parameter type 2025-11-30 21:56:22 -06:00
bf4ef36c3a [ade7953] Apply voltage_gain setting to both channels (#12180) 2025-11-30 19:17:50 -05:00
J. Nick Koston
cbc03fc342 Merge branch 'web_server_keys_progmem' into integration 2025-11-30 17:53:43 -06:00
J. Nick Koston
675b5d4501 merge 2025-11-30 17:51:23 -06:00
J. Nick Koston
1e38d0445e Merge branch 'web_server_keys_progmem' into integration
# Conflicts:
#	esphome/components/web_server/web_server.cpp
2025-11-30 17:47:55 -06:00
J. Nick Koston
2ac9f44377 store web_server keys in progmem 2025-11-30 17:39:37 -06:00
J. Nick Koston
2ca118f371 [web_server] Replace routing table with if-else chain to save 116 bytes RAM (#12139) 2025-12-01 12:25:46 +13:00
J. Nick Koston
7b541e3d80 Merge branch 'integration' into memory_api 2025-11-30 17:19:49 -06:00
J. Nick Koston
eebfa6584c Merge branch 'text_sensor_dupe_storage' into integration 2025-11-30 17:19:43 -06:00
J. Nick Koston
e8f6f86a02 cover 2025-11-30 17:17:15 -06:00
J. Nick Koston
c23e5c5c03 Merge branch 'integration' into memory_api 2025-11-30 17:10:36 -06:00
J. Nick Koston
fbf2ee9d39 Merge remote-tracking branch 'upstream/dev' into integration 2025-11-30 17:10:30 -06:00
J. Nick Koston
82e1238330 [lock] Refactor trigger classes to template and add integration tests (#12193) 2025-11-30 17:09:02 -06:00
Jimmy Hedman
8308bc2911 [mdns] Bump mDNS component to 1.9.1 (#12207) 2025-11-30 08:06:06 -05:00
Jonathan Swoboda
47c767fa5e [openthread] Add C5 support (#12200) 2025-11-30 08:04:45 -05:00
Jonathan Swoboda
e95ceafc17 [mopeka_pro_check] Fix negative temperatures (#12198)
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-30 08:04:33 -05:00
Jonathan Swoboda
7317bf4a5d [esp32_can] Add P4 support (#12201) 2025-11-30 08:04:19 -05:00
J. Nick Koston
4762f9a52a Merge branch 'integration' into memory_api 2025-11-29 23:38:36 -06:00
J. Nick Koston
858b0c0957 Merge branch 'text_sensor_dupe_storage' into integration 2025-11-29 23:38:05 -06:00
J. Nick Koston
4b16a4bca2 merge 2025-11-29 23:35:05 -06:00
J. Nick Koston
3cc9411d5a Merge branch 'text_sensor_dupe_storage' into integration 2025-11-29 23:32:51 -06:00
J. Nick Koston
b4e6c38d65 [text_sensor] Avoid duplicate string storage when no filters configured 2025-11-29 23:30:01 -06:00
J. Nick Koston
62d144932b Merge branch 'integration' into memory_api 2025-11-29 23:06:14 -06:00
J. Nick Koston
159580d56a Merge branch 'update_state_strings_flash' into integration 2025-11-29 23:05:51 -06:00
J. Nick Koston
7699928339 Merge branch 'valve_state_strings_flash' into integration 2025-11-29 23:05:47 -06:00
J. Nick Koston
0219125397 Merge branch 'integration' of https://github.com/esphome/esphome into integration 2025-11-29 23:05:41 -06:00
J. Nick Koston
278f3e2914 [web_server] Store update state strings in flash on ESP8266 2025-11-29 23:04:57 -06:00
J. Nick Koston
87ab10b8dc [valve] Store valve state strings in flash on ESP8266 2025-11-29 22:44:01 -06:00
J. Nick Koston
042a08887f [climate] Use C++17 nested namespace syntax (#12194) 2025-11-30 00:54:49 +00:00
J. Nick Koston
8f8828d5b8 Merge branch 'integration' into memory_api 2025-11-29 18:36:33 -06:00
J. Nick Koston
d5139ff0e7 Merge remote-tracking branch 'origin/cover_state_strings_flash' into integration 2025-11-29 18:36:21 -06:00
J. Nick Koston
77f5f2326f [hlk_fm22x] Fix Action::play method signatures (#12192) 2025-11-29 19:36:12 -05:00
J. Nick Koston
b14a1b3fd4 Merge branch 'climate_nested_namespace' into integration 2025-11-29 18:35:55 -06:00
J. Nick Koston
a54a0e54b2 [cover] Store cover state strings in flash on ESP8266 2025-11-29 18:34:50 -06:00
J. Nick Koston
24f34cf782 [climate] Use C++17 nested namespace syntax 2025-11-29 18:29:46 -06:00
J. Nick Koston
415c56e324 Merge branch 'integration' into memory_api 2025-11-29 18:21:24 -06:00
J. Nick Koston
428ee718a9 Merge remote-tracking branch 'origin/hlk_fm22x_signatures' into integration 2025-11-29 18:21:18 -06:00
J. Nick Koston
ffdc391c7b Merge branch 'lock_cleanups' into integration 2025-11-29 18:21:00 -06:00
J. Nick Koston
a80435af0f [lock] Refactor trigger classes to template and add integration tests 2025-11-29 18:20:18 -06:00
J. Nick Koston
0dc6c6f563 [hlk_fm22x] Fix Action::play method signatures 2025-11-29 18:19:00 -06:00
d82a92b406 [ade7953_base] Add missing CODEOWNERS (#12181) 2025-11-29 18:41:47 -05:00
J. Nick Koston
7d7e0f98f6 Merge branch 'integration' into memory_api 2025-11-29 17:09:57 -06:00
J. Nick Koston
544a70253f Merge remote-tracking branch 'upstream/dev' into integration 2025-11-29 17:09:52 -06:00
dependabot[bot]
ec88bf0cb1 Bump ruff from 0.14.5 to 0.14.7 (#12190)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-11-29 22:56:26 +00:00
dependabot[bot]
46567c4716 Bump aioesphomeapi from 42.8.0 to 42.9.0 (#12189)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-29 22:55:27 +00:00
Jakub Čermák
1f47797007 Add MEASUREMENT_ANGLE to SensorStateClass (#12085) 2025-11-29 16:26:25 -06:00
J. Nick Koston
9ec2733b09 Merge branch 'integration' into memory_api 2025-11-29 03:26:08 -06:00
J. Nick Koston
e24407344e Merge branch 'prepare_idf_6_rtos_ring_buf_flash' into integration 2025-11-29 03:26:02 -06:00
J. Nick Koston
b44abfce57 [esp32] Place ring buffer functions in flash by default (prep for IDF 6.0) 2025-11-29 03:18:39 -06:00
J. Nick Koston
22de35b202 [esp32] Place ring buffer functions in flash by default (prep for IDF 6.0) 2025-11-29 03:17:08 -06:00
J. Nick Koston
75b72a08f2 Merge branch 'integration' into memory_api 2025-11-29 02:46:18 -06:00
J. Nick Koston
5938d85cb0 Merge branch 'prepare_idf_6_rtos_funcs_flash' into integration 2025-11-29 02:46:11 -06:00
J. Nick Koston
e7c54598cd tweak 2025-11-29 02:44:27 -06:00
Javier Peletier
cf444fc3b8 [mipi_spi] add guition JC4827W543 C/R (#12034) 2025-11-29 19:40:13 +11:00
Clyde Stubbs
c40e8e7f5c [helpers] Add conversion from FixedVector to std::vector (#12179) 2025-11-29 19:38:29 +11:00
J. Nick Koston
64281631a1 [esp32] Place FreeRTOS functions in flash by default (prep for IDF 6.0) 2025-11-29 02:32:40 -06:00
J. Nick Koston
b71d8010d2 [light] Store log_percent parameter strings in flash on ESP8266 (#12174) 2025-11-28 22:59:31 -05:00
J. Nick Koston
2174795b27 [number] Reduce NumberCall size by 4 bytes on 32-bit platforms (#12178)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-28 22:57:36 -05:00
J. Nick Koston
5fa4ff754c [ble_client] Convert to C++17 namespace style (#12176) 2025-11-28 22:57:01 -05:00
J. Nick Koston
29334b3584 Merge branch 'integration' into memory_api 2025-11-28 21:23:41 -06:00
J. Nick Koston
584902fa94 Merge branch 'number_reorder_reduce' into integration 2025-11-28 21:23:34 -06:00
J. Nick Koston
e851493080 Update esphome/components/number/number_call.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-28 21:20:42 -06:00
J. Nick Koston
3dce0587cf Merge branch 'integration' into memory_api 2025-11-28 21:20:07 -06:00
J. Nick Koston
835f7198e4 Merge branch 'speed_count_255' into integration 2025-11-28 21:19:58 -06:00
J. Nick Koston
a30786b055 clamp 2025-11-28 21:19:47 -06:00
J. Nick Koston
76a596d3b5 Merge branch 'integration' into memory_api 2025-11-28 21:15:46 -06:00
J. Nick Koston
260e8bdd75 Merge branch 'number_reorder_reduce' into integration 2025-11-28 21:15:39 -06:00
J. Nick Koston
4e379ab235 [number] Reduce NumberCall size by 4 bytes on 32-bit platforms 2025-11-28 21:15:09 -06:00
J. Nick Koston
9e7086c11e Merge branch 'integration' into memory_api 2025-11-28 21:08:02 -06:00
J. Nick Koston
e983a19160 Merge branch 'speed_count_255' into integration 2025-11-28 21:07:53 -06:00
J. Nick Koston
192abf95ce [fan] Use uint8_t for speed_count and fix tuya max=256 validation bug 2025-11-28 21:07:02 -06:00
J. Nick Koston
28faecfc26 Merge branch 'integration' into memory_api 2025-11-28 20:53:47 -06:00
J. Nick Koston
8e6a4e94db Merge branch 'ble_client_ns' into integration 2025-11-28 20:53:39 -06:00
J. Nick Koston
1aaea4d3ab [ble_client] Convert to C++17 namespace style 2025-11-28 20:52:31 -06:00
J. Nick Koston
1120236f06 Revert "[api] Use shared static string for reboot timeout scheduler name"
This reverts commit bd958c5859.
2025-11-28 19:32:17 -06:00
J. Nick Koston
0bb79afa1f Revert "[api] Use shared static string for reboot timeout scheduler name"
This reverts commit bd958c5859.
2025-11-28 19:32:06 -06:00
J. Nick Koston
adbab2c288 Merge branch 'integration' into memory_api 2025-11-28 19:28:02 -06:00
J. Nick Koston
92131f2542 Merge branch 'reboot_timeout_cleanup' into integration 2025-11-28 19:27:54 -06:00
J. Nick Koston
bd958c5859 [api] Use shared static string for reboot timeout scheduler name 2025-11-28 19:27:21 -06:00
J. Nick Koston
f1dcd478bb Merge branch 'integration' into memory_api 2025-11-28 19:06:36 -06:00
J. Nick Koston
3d5987b701 Merge branch 'light_call_strings_flash' into integration 2025-11-28 19:06:28 -06:00
J. Nick Koston
23a177f9d7 [light] Store log_percent parameter strings in flash on ESP8266 2025-11-28 19:05:52 -06:00
J. Nick Koston
e6ea164a75 Merge branch 'integration' into memory_api 2025-11-28 18:55:13 -06:00
J. Nick Koston
d8e95a835f Merge branch 'esp8266_device_info_flash' into integration 2025-11-28 18:54:56 -06:00
J. Nick Koston
7f7ccd6c9c [api] Store device info strings in flash on ESP8266 2025-11-28 18:53:19 -06:00
J. Nick Koston
8a90fa302e Merge branch 'integration' into memory_api 2025-11-28 16:57:14 -06:00
J. Nick Koston
83dd53954b Merge branch 'alarm_control_panel_reduce_complexity' into integration 2025-11-28 16:57:04 -06:00
J. Nick Koston
ff8dbac54e Merge branch 'camera_listen' into integration 2025-11-28 16:57:00 -06:00
J. Nick Koston
b872d10583 simplify 2025-11-28 16:52:46 -06:00
J. Nick Koston
c7e8a3eea5 reduce 2025-11-28 16:43:22 -06:00
J. Nick Koston
913581e7ee reduce 2025-11-28 16:42:03 -06:00
J. Nick Koston
4ab1911d82 reduce 2025-11-28 16:40:27 -06:00
J. Nick Koston
d3918dc784 reduce 2025-11-28 16:39:05 -06:00
J. Nick Koston
2060ed0a92 tests 2025-11-28 16:32:28 -06:00
J. Nick Koston
3c1c19da1c tweaks 2025-11-28 16:23:31 -06:00
J. Nick Koston
bc50be6053 [logger] Conditionally compile log level change listener (#12168)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-28 22:14:00 +00:00
J. Nick Koston
e8bc19a07d [alarm_control_panel] Replace callbacks with listener interface 2025-11-28 16:11:23 -06:00
J. Nick Koston
ca599b25c2 [espnow] Initialize LwIP stack when running without WiFi component (#12169) 2025-11-28 16:33:28 -05:00
J. Nick Koston
22a60ec789 Merge branch 'integration' into memory_api 2025-11-28 14:49:29 -06:00
J. Nick Koston
9e7d6d7702 Merge branch 'logger_level_only_one_place' into integration 2025-11-28 14:49:24 -06:00
J. Nick Koston
3c7d48a5ef Merge branch 'dev' into logger_level_only_one_place 2025-11-28 14:49:06 -06:00
J. Nick Koston
200c0c77c7 Update esphome/components/logger/logger.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-28 14:48:52 -06:00
J. Nick Koston
2e55296640 [sensor] Replace timeout filter scheduler with loop-based implementation (#11922) 2025-11-28 20:43:11 +00:00
J. Nick Koston
6b756b81f3 Merge branch 'integration' into memory_api 2025-11-28 14:33:33 -06:00
J. Nick Koston
a01eeaa796 Merge branch 'logger_level_only_one_place' into integration 2025-11-28 14:33:26 -06:00
J. Nick Koston
ed0751246a [logger] Conditionally compile log level change listener 2025-11-28 14:28:02 -06:00
J. Nick Koston
63842b3795 Merge branch 'integration' into memory_api 2025-11-28 14:14:40 -06:00
J. Nick Koston
dc1b2d7a4b Merge branch 'ota_listeners' into integration 2025-11-28 14:14:31 -06:00
J. Nick Koston
e3dc9a715f tweak 2025-11-28 14:14:03 -06:00
J. Nick Koston
b1a318c0d7 simplify, no more register needed 2025-11-28 14:07:55 -06:00
J. Nick Koston
a45a2e8f5f guards 2025-11-28 14:01:37 -06:00
J. Nick Koston
ee91bb2405 dry 2025-11-28 13:54:46 -06:00
J. Nick Koston
ab6b4c77d2 dry 2025-11-28 13:52:58 -06:00
J. Nick Koston
d9701af9c1 dry 2025-11-28 13:51:21 -06:00
J. Nick Koston
a224d0acbd dry 2025-11-28 13:50:20 -06:00
J. Nick Koston
515cdf9b9f its always on 2025-11-28 13:48:19 -06:00
J. Nick Koston
8fe981b9f1 [ota] Replace std::function callbacks with listener interface 2025-11-28 13:46:00 -06:00
J. Nick Koston
f678686cde Merge branch 'integration' into memory_api 2025-11-28 13:02:54 -06:00
J. Nick Koston
8fe3717665 Merge branch 'timeout_filter_scheduler_churn_fix' into integration 2025-11-28 13:02:47 -06:00
J. Nick Koston
cc40f08574 use TimeoutFilterBase 2025-11-28 13:02:37 -06:00
J. Nick Koston
01f58e8662 Merge branch 'integration' into memory_api 2025-11-28 12:57:28 -06:00
J. Nick Koston
a8cd2d6728 Merge branch 'timeout_filter_scheduler_churn_fix' into integration 2025-11-28 12:57:24 -06:00
J. Nick Koston
087ed48dba cleanups per review 2025-11-28 12:56:13 -06:00
J. Nick Koston
30ee14813f cover 2025-11-28 12:48:41 -06:00
J. Nick Koston
9fa9ff6200 Merge branch 'integration' into memory_api 2025-11-28 12:38:33 -06:00
J. Nick Koston
695f2c949d Merge branch 'light_lazy_callbacks' into integration 2025-11-28 12:38:28 -06:00
J. Nick Koston
149f5e59ec [light] Use listener pattern for state callbacks with lazy allocation 2025-11-28 12:36:40 -06:00
J. Nick Koston
dcce2e3fbd Merge branch 'integration' into memory_api 2025-11-28 12:25:45 -06:00
J. Nick Koston
0229c200bc Merge branch 'camera_listen' into integration 2025-11-28 12:25:39 -06:00
Javier Peletier
d6ca01775e [packages] Restore remote shorthand vars and !remove in early package contents validation (#12158)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-28 18:24:09 +00:00
J. Nick Koston
13626680ca Merge branch 'integration' into memory_api 2025-11-28 12:22:27 -06:00
J. Nick Koston
6e0336c3cd Merge remote-tracking branch 'upstream/dev' into integration 2025-11-28 12:22:19 -06:00
Javier Peletier
e15f3a08ae [tests] Remote packages with substitutions (#12145) 2025-11-28 12:15:55 -06:00
J. Nick Koston
d43189cb07 Update esphome/components/camera/camera.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-28 12:14:19 -06:00
J. Nick Koston
fb82362e9c [api] Eliminate rx_buf heap churn and release buffers after initial sync (#12133) 2025-11-28 12:13:29 -06:00
J. Nick Koston
f1d8281489 [esp32_camera] Replace std::function callbacks with CameraListener interface 2025-11-28 12:05:41 -06:00
J. Nick Koston
26e979d3d5 [wifi] Replace std::function callbacks with listener interfaces (#12155) 2025-11-28 11:27:17 -06:00
J. Nick Koston
60ffa0e52e [esp32_ble_tracker] Replace scanner state callback with listener interface (#12156) 2025-11-28 11:27:08 -06:00
J. Nick Koston
0df9c2372c Merge branch 'integration' into memory_api 2025-11-28 10:30:48 -06:00
J. Nick Koston
7cc7883b17 Merge branch 'lock_state_store_progmem_esp8266' into integration 2025-11-28 10:30:43 -06:00
J. Nick Koston
2a67933062 small cleanups 2025-11-28 10:30:33 -06:00
J. Nick Koston
a212161f68 cleanup 2025-11-28 10:30:12 -06:00
J. Nick Koston
a57accc52e Merge branch 'integration' into memory_api 2025-11-28 10:13:39 -06:00
J. Nick Koston
345c0124a1 Merge branch 'lock_state_store_progmem_esp8266' into integration 2025-11-28 10:13:34 -06:00
J. Nick Koston
632af6bda3 [lock] Store lock state strings in flash on ESP8266 2025-11-28 10:13:03 -06:00
J. Nick Koston
b0c099c26e Merge branch 'integration' into memory_api 2025-11-28 09:58:42 -06:00
J. Nick Koston
9489021ea5 Merge branch 'analyze_memory_include_ram' into integration 2025-11-28 09:58:31 -06:00
J. Nick Koston
cd11f31887 address bot review 2025-11-28 09:57:34 -06:00
J. Nick Koston
e22d78cf4c tweaks 2025-11-28 09:47:25 -06:00
J. Nick Koston
eea02a5f0b ram 2025-11-28 09:44:29 -06:00
J. Nick Koston
3c854a02d7 add ram 2025-11-28 09:39:32 -06:00
J. Nick Koston
44127eec59 Merge branch 'integration' into memory_api 2025-11-27 22:43:40 -06:00
J. Nick Koston
775748f689 Merge branch 'bluetooth_scanner_state_listen' into integration 2025-11-27 22:43:33 -06:00
J. Nick Koston
e3ea585d54 [esp32_ble_tracker] Replace scanner state callback with listener interface 2025-11-27 22:42:21 -06:00
J. Nick Koston
b13369ab96 Merge branch 'integration' into memory_api 2025-11-27 22:29:45 -06:00
J. Nick Koston
6aee023eb3 Merge branch 'wifi_listener' into integration 2025-11-27 22:29:36 -06:00
J. Nick Koston
3752d5d2ab tweaks 2025-11-27 22:28:43 -06:00
J. Nick Koston
3a27a4d34e Merge branch 'integration' into memory_api 2025-11-27 22:18:35 -06:00
J. Nick Koston
4e96c17c42 Merge branch 'wifi_listener' into integration 2025-11-27 22:18:29 -06:00
J. Nick Koston
c9bb9c4d24 [wifi] Replace std::function callbacks with listener interfaces 2025-11-27 22:17:56 -06:00
J. Nick Koston
e1ec6146c0 [wifi] Save 112 bytes BSS on ESP8266 by calling SDK directly for BSSID (#12137)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-11-27 22:09:41 -06:00
J. Nick Koston
450065fdae [light] Replace sparse enum switch with linear search to save 156 bytes RAM (#12140) 2025-11-27 22:09:27 -06:00
J. Nick Koston
3c0241d013 Merge branch 'integration' into memory_api 2025-11-27 22:06:03 -06:00
J. Nick Koston
5a19ff4a89 Merge remote-tracking branch 'upstream/dev' into integration 2025-11-27 22:05:48 -06:00
J. Nick Koston
71dc402a30 [logger] Replace std::function callbacks with LogListener interface (#12153) 2025-11-28 04:00:33 +00:00
J. Nick Koston
f448a21df6 Merge branch 'integration' into memory_api 2025-11-27 20:54:11 -06:00
J. Nick Koston
4b0882ac76 Merge branch 'log_listener' into integration 2025-11-27 20:54:04 -06:00
J. Nick Koston
5c6d60ca2e unused param 2025-11-27 20:53:49 -06:00
J. Nick Koston
200491f9ce Merge branch 'integration' into memory_api 2025-11-27 20:03:54 -06:00
J. Nick Koston
8c4d886b4a Merge branch 'log_listener' into integration 2025-11-27 20:03:47 -06:00
J. Nick Koston
c1b12791c6 [logger] Replace std::function callbacks with LogListener interface 2025-11-27 20:02:31 -06:00
J. Nick Koston
eb2aa62d0d [logger] Replace std::function callbacks with LogListener interface 2025-11-27 20:01:15 -06:00
J. Nick Koston
9d191a61fe Merge branch 'integration' into memory_api 2025-11-27 18:42:29 -06:00
J. Nick Koston
483a8dd4c5 Merge branch 'ha_service_storage_strings_rodata' into integration 2025-11-27 18:42:20 -06:00
J. Nick Koston
9bc65c15be Merge remote-tracking branch 'origin/ha_service_storage_strings_rodata' into ha_service_storage_strings_rodata 2025-11-27 18:41:50 -06:00
J. Nick Koston
f94e4a30ac safer 2025-11-27 18:41:36 -06:00
J. Nick Koston
73990a8d45 Merge branch 'integration' into memory_api 2025-11-27 18:29:34 -06:00
J. Nick Koston
294cedc730 Merge remote-tracking branch 'origin/ha_service_storage_strings_rodata' into integration 2025-11-27 18:29:17 -06:00
J. Nick Koston
dbc2078b2e assert 2025-11-27 18:27:27 -06:00
J. Nick Koston
bb67f5a048 Merge branch 'integration' into memory_api 2025-11-27 18:20:20 -06:00
J. Nick Koston
14ca2d889d Merge branch 'ha_service_storage_strings_rodata' into integration 2025-11-27 18:20:15 -06:00
J. Nick Koston
09151e6814 [api] Reduce heap usage for Home Assistant service call string storage 2025-11-27 18:16:56 -06:00
J. Nick Koston
4fa6d04861 Merge branch 'integration' into memory_api 2025-11-27 17:42:57 -06:00
J. Nick Koston
4cdec33c85 Merge remote-tracking branch 'upstream/dev' into integration 2025-11-27 17:42:50 -06:00
Jonathan Swoboda
9bd148dfd1 Merge branch 'release' into dev 2025-11-27 18:19:20 -05:00
Jonathan Swoboda
50c1720c16 Merge pull request #12149 from esphome/bump-2025.11.2
2025.11.2
2025-11-27 18:19:05 -05:00
J. Nick Koston
4c549798bc [usb_uart] Wake main loop immediately when USB data arrives (#12148) 2025-11-27 16:33:08 -06:00
J. Nick Koston
a9d804cfbb Merge branch 'integration' into memory_api 2025-11-27 16:26:23 -06:00
J. Nick Koston
178b83c7f8 Merge branch 'usb_uart_wake' into integration 2025-11-27 16:26:17 -06:00
Jonathan Swoboda
4115dd7222 Bump version to 2025.11.2 2025-11-27 17:23:28 -05:00
J. Nick Koston
25e3d5bf91 [usb_uart] Wake main loop immediately when USB data arrives 2025-11-27 16:23:28 -06:00
J. Nick Koston
d5e2543751 [scheduler] Fix use-after-move crash in heap operations (#12124) 2025-11-27 17:23:28 -05:00
Clyde Stubbs
b4b34aee13 [wifi] Restore blocking setup until connected for RP2040 (#12142) 2025-11-27 17:23:28 -05:00
Jonathan Swoboda
6645994700 [esp32] Fix hosted update when there is no wifi (#12123) 2025-11-27 17:23:28 -05:00
Clyde Stubbs
ae140f52e3 [lvgl] Fix position of errors in widget config (#12111)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-27 17:23:28 -05:00
Clyde Stubbs
46ae6d35a2 [lvgl] Allow multiple widgets per grid cell (#12091) 2025-11-27 17:23:27 -05:00
J. Nick Koston
278f12fb99 [script] Fix script.wait hanging when triggered from on_boot (#12102) 2025-11-27 17:23:27 -05:00
Jonathan Swoboda
acdcd56395 [esp32] Fix platformio flash size print (#12099)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-11-27 17:23:27 -05:00
Edward Firmo
9289fc36f7 [nextion] Do not set alternative baud rate when not specified or <= 0 (#12097) 2025-11-27 17:23:27 -05:00
J. Nick Koston
1fadd1227d [scheduler] Fix use-after-move crash in heap operations (#12124) 2025-11-27 10:50:21 -06:00
Clyde Stubbs
91df0548ef [wifi] Restore blocking setup until connected for RP2040 (#12142) 2025-11-27 10:30:03 -05:00
J. Nick Koston
09cd056a3c Merge branch 'integration' into memory_api 2025-11-26 22:58:23 -06:00
J. Nick Koston
d93987f61a Merge branch 'light_sparse_table' into integration 2025-11-26 22:58:08 -06:00
J. Nick Koston
ca20a877bf Merge branch 'integration' into memory_api 2025-11-26 22:57:59 -06:00
J. Nick Koston
88ef4359b3 Merge branch 'webserver_reduce_ram' into integration 2025-11-26 22:57:44 -06:00
J. Nick Koston
75b4401cd4 disable tidy 2025-11-26 22:57:17 -06:00
J. Nick Koston
22eea92534 [light] Replace sparse enum switch with linear search to save 156 bytes RAM 2025-11-26 22:54:45 -06:00
J. Nick Koston
b6f589710d Merge branch 'integration' into memory_api 2025-11-26 22:47:17 -06:00
J. Nick Koston
da1e31ba0e Merge branch 'webserver_reduce_ram' into integration 2025-11-26 22:47:00 -06:00
J. Nick Koston
91ff949399 [web_server] Replace routing table with if-else chain to save 116 bytes RAM 2025-11-26 22:45:51 -06:00
J. Nick Koston
1a1bfd021a Merge branch 'integration' into memory_api 2025-11-26 22:18:57 -06:00
J. Nick Koston
ec151b477a Merge branch 'wifi_sta_8266' into integration 2025-11-26 22:18:41 -06:00
J. Nick Koston
8ecd40608b [wifi] Save 112 bytes BSS on ESP8266 by calling SDK directly for BSSID 2025-11-26 22:18:13 -06:00
J. Nick Koston
60d4b8da92 Merge branch 'integration' into memory_api 2025-11-26 21:52:24 -06:00
J. Nick Koston
2cd2c15911 Merge remote-tracking branch 'upstream/dev' into integration 2025-11-26 21:52:13 -06:00
Jonathan Swoboda
a7a5a0b9a2 [esp32] Improve IDF component support (#12127) 2025-11-26 22:46:17 -05:00
Jonathan Swoboda
9c85ec9182 [esp32] Fix hosted update when there is no wifi (#12123) 2025-11-26 20:01:35 -05:00
J. Nick Koston
4a7bdd4388 Merge branch 'integration' into memory_api 2025-11-26 18:59:52 -06:00
J. Nick Koston
7e53f96c4c Merge branch 'buffer_churn_init_sync' into integration 2025-11-26 18:59:47 -06:00
J. Nick Koston
406fa220f5 logs! 2025-11-26 18:59:11 -06:00
J. Nick Koston
31a9558445 Merge branch 'integration' into memory_api 2025-11-26 18:22:37 -06:00
J. Nick Koston
747341efa4 Merge branch 'buffer_churn_init_sync' into integration 2025-11-26 18:22:33 -06:00
J. Nick Koston
bbf7e8c1f2 [api] Eliminate rx_buf heap churn and release buffers after initial sync 2025-11-26 18:17:25 -06:00
J. Nick Koston
a42a84b9c3 Merge branch 'integration' into memory_api 2025-11-26 17:09:04 -06:00
J. Nick Koston
c81945e9be Merge remote-tracking branch 'upstream/dev' into integration 2025-11-26 17:08:54 -06:00
Jesse Hills
23e58c1c7b [inkplate] Ignore strapping pin warnings on default pins (#12110) 2025-11-26 17:08:40 -06:00
J. Nick Koston
5fa1d72d35 Merge branch 'integration' into memory_api 2025-11-26 17:08:12 -06:00
J. Nick Koston
6357f88abc Merge remote-tracking branch 'upstream/dev' into integration 2025-11-26 17:08:07 -06:00
Clyde Stubbs
b3955cd151 [epaper_spi] Add SSD1677 and Waveshare 4.26 (#11887)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-26 17:07:51 -06:00
J. Nick Koston
b2cc760ad2 Merge branch 'integration' into memory_api 2025-11-26 17:07:05 -06:00
J. Nick Koston
66652c5928 Merge branch 'dev' into integration 2025-11-26 17:06:58 -06:00
Clyde Stubbs
927d3715c1 [lvgl] Allow setting text directly on a button (#11964)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-26 17:06:40 -06:00
Clyde Stubbs
a2d9941c62 [lvgl] Add option to sync updates with display (#11896)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-26 17:06:32 -06:00
Clyde Stubbs
caaa08d678 [core] Fix for missing arguments to shared_lambda (#12115) 2025-11-26 17:05:45 -06:00
Jon Oberheide
eb970cf44e make thermostat humidification_action public (#12132) 2025-11-26 16:56:22 -06:00
J. Nick Koston
8d8ded74ae Merge branch 'schedule_use_after_free' into integration 2025-11-26 16:40:56 -06:00
J. Nick Koston
877d2b914c tweaks 2025-11-26 16:38:39 -06:00
J. Nick Koston
1d59c7a838 [scheduler] Fix use-after-move crash in heap operations 2025-11-26 12:08:49 -06:00
Pawelo
083886c4b0 [prometheus] Avoid generating unused light color metrics to reduce memory usage on ESP8266 (#9530)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-26 18:06:51 +00:00
Javier Peletier
12a51ff047 [packages] Fix package schema validation (#12116)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-26 11:00:44 -06:00
J. Nick Koston
b328758634 Revert "[core] Deduplicate identical stateless lambdas to reduce flash usage" (#12117) 2025-11-26 10:53:44 -06:00
J. Nick Koston
83db380dfa Merge branch 'integration' into memory_api 2025-11-25 21:41:45 -06:00
J. Nick Koston
70089e03d5 Merge branch 'timeout_filter_scheduler_churn_fix' into integration 2025-11-25 21:41:38 -06:00
J. Nick Koston
1d24bf8438 Merge branch 'integration' into memory_api 2025-11-25 21:21:30 -06:00
J. Nick Koston
cbbdd634c1 Merge upstream/dev into integration 2025-11-25 21:21:03 -06:00
Clyde Stubbs
1207b9e995 [lvgl] Automatically pad rows and columns (#11879)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-26 01:53:51 +00:00
Clyde Stubbs
e071380532 [lvgl] Add missing obj scroll properties (#11901)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-26 01:49:47 +00:00
Clyde Stubbs
f071b6232a [lvgl] Fix position of errors in widget config (#12111)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-26 01:47:27 +00:00
J. Nick Koston
d443dbbf34 [lvgl] Fix lambda return types for coord and font validators (#12113) 2025-11-25 19:42:09 -06:00
J. Nick Koston
03a8ef71ff [esp32_ble_client] Replace std::string with char[18] for BLE address storage (#12070) 2025-11-25 18:37:49 -06:00
J. Nick Koston
bda17180df [core] Deduplicate identical stateless lambdas to reduce flash usage (#11918) 2025-11-26 12:48:08 +13:00
J. Nick Koston
ffae3501ab [core] Replace seq<>/gens<> with std::index_sequence for code clarity (#11921) 2025-11-26 12:44:50 +13:00
Jesse Hills
50bdcdee0c Add developer-breaking-change labelling (#12095) 2025-11-26 12:39:41 +13:00
J. Nick Koston
2c6500511f Merge branch 'dev' into timeout_filter_scheduler_churn_fix 2025-11-25 14:30:36 -06:00
dependabot[bot]
ae60b5e6a1 Bump actions/setup-python from 6.0.0 to 6.1.0 in /.github/actions/restore-python (#12108)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-25 14:27:49 -06:00
dependabot[bot]
70df4ecaa9 Bump actions/setup-python from 6.0.0 to 6.1.0 (#12106)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-25 13:35:40 -06:00
Clyde Stubbs
b6be5e3eda [lvgl] Allow multiple widgets per grid cell (#12091) 2025-11-26 06:06:42 +11:00
Nikolai Ryzhkov
dec323e786 [sht4x] Read and store a serial number of SHT4x sensors (#12089)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-11-25 13:27:35 -05:00
J. Nick Koston
6ca0cd1e8b [ltr390] Simplify mode tracking with bitmask instead of vector/function (#12093) 2025-11-25 12:16:48 -06:00
J. Nick Koston
3106934678 [esp32_ble] Optimize name storage to reduce RAM and eliminate heap allocations (#12071) 2025-11-25 12:16:27 -06:00
J. Nick Koston
8c5985f68a [web_server] Consolidate turn_on/turn_off handlers to eliminate duplicate lambdas (#12094) 2025-11-25 12:16:02 -06:00
J. Nick Koston
cf8c205644 [core] Reduce flash size by combining set_name() and set_object_id() calls (#11941) 2025-11-25 12:15:45 -06:00
J. Nick Koston
a571033b43 [script] Fix script.wait hanging when triggered from on_boot (#12102) 2025-11-25 10:30:01 -06:00
Jonathan Swoboda
cdf27f1447 [esp32] Fix platformio flash size print (#12099)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-11-25 11:14:53 -05:00
Edward Firmo
c30b920193 [nextion] Do not set alternative baud rate when not specified or <= 0 (#12097) 2025-11-25 07:48:32 -05:00
J. Nick Koston
697c5f424e [api] Use const char* pointers for light effects to eliminate heap allocations (#12090) 2025-11-25 08:17:53 +00:00
J. Nick Koston
18c97a08c3 [esp8266] Use C++17 nested namespaces and constexpr (#12096) 2025-11-25 01:47:06 -06:00
bdm310
66a871840e Add more lvgl arc update parameters (#12066) 2025-11-25 17:14:23 +11:00
J. Nick Koston
dc3366c431 Merge branch 'integration' into memory_api 2025-11-24 21:35:43 -06:00
J. Nick Koston
e01aec79e3 Merge branch 'web_server_turn_on_off_cleanup' into integration 2025-11-24 21:35:37 -06:00
J. Nick Koston
b06c730a26 [web_server] Consolidate turn_on/turn_off handlers to eliminate duplicate lambdas 2025-11-24 21:34:36 -06:00
J. Nick Koston
46a26560fd [template.alarm_control_panel] Replace std::map with FixedVector for heap and flash savings (#11893) 2025-11-25 16:21:56 +13:00
J. Nick Koston
1c808a3375 [ble_client] Write static BLE data directly from flash without allocation (#11826) 2025-11-25 16:19:18 +13:00
J. Nick Koston
1969d1a9ff Merge branch 'integration' into memory_api 2025-11-24 21:04:37 -06:00
J. Nick Koston
ee18f19e88 Merge branch 'ltr390_containers' into integration 2025-11-24 21:04:17 -06:00
J. Nick Koston
24217eb257 [ltr390] Simplify mode tracking with bitmask instead of vector/function 2025-11-24 20:58:38 -06:00
Keith Burzinski
2bc8a4a779 [wifi_info] Use callbacks instead of polling (#10748)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-11-24 20:23:10 -06:00
dependabot[bot]
7f1a9a611f Bump aioesphomeapi from 42.7.0 to 42.8.0 (#12092)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-25 02:09:02 +00:00
J. Nick Koston
f478e2e841 Merge branch 'integration' into memory_api 2025-11-24 19:39:40 -06:00
J. Nick Koston
7a9e1964b1 Merge branch 'effects_are_const_char' into integration 2025-11-24 19:39:33 -06:00
J. Nick Koston
a018809404 [api] Use const char* pointers for light effects to eliminate heap allocations 2025-11-24 19:38:13 -06:00
J. Nick Koston
781de689c0 merge 2025-11-24 19:14:00 -06:00
J. Nick Koston
4496a6e7b2 Merge branch 'integration' into memory_api 2025-11-24 18:35:42 -06:00
J. Nick Koston
1a882ab406 Merge remote-tracking branch 'kbx81/20250915-wifi-info-use-callbacks' into integration 2025-11-24 18:35:31 -06:00
kbx81
27547313cd Suggestions from review 2025-11-24 18:31:11 -06:00
Keith Burzinski
f5bdbc7af2 More const
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-11-24 18:19:27 -06:00
Keith Burzinski
90f38566ea Update esphome/components/wifi/__init__.py
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-11-24 18:05:40 -06:00
J. Nick Koston
a50c744714 Update text_sensor.py
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-11-24 17:50:36 -06:00
kbx81
c7d485e8bd Use set.intersection 2025-11-24 17:08:55 -06:00
Keith Burzinski
da23215e05 Merge branch 'dev' into 20250915-wifi-info-use-callbacks 2025-11-24 16:59:23 -06:00
Jonathan Swoboda
b51409ed5e Merge branch 'release' into dev 2025-11-24 17:30:08 -05:00
Jonathan Swoboda
3775b54554 Merge pull request #12086 from esphome/bump-2025.11.1
2025.11.1
2025-11-24 17:29:53 -05:00
kbx81
9b50ed3589 conditionally compile callbacks 2025-11-24 16:09:12 -06:00
kbx81
0398b92de5 Merge remote-tracking branch 'upstream/dev' into 20250915-wifi-info-use-callbacks 2025-11-24 15:45:28 -06:00
J. Nick Koston
22b47eb258 Merge branch 'integration' into memory_api 2025-11-24 15:40:03 -06:00
J. Nick Koston
7912f19230 mege 2025-11-24 15:39:52 -06:00
J. Nick Koston
c3a81dbbaa Merge branch 'integration' into memory_api 2025-11-24 15:36:47 -06:00
J. Nick Koston
decba7c233 Merge branch 'mdns_arduino' into integration 2025-11-24 15:36:42 -06:00
J. Nick Koston
f5736303c3 fixs 2025-11-24 15:36:31 -06:00
J. Nick Koston
e6012f8f76 Merge branch 'integration' into memory_api 2025-11-24 15:34:54 -06:00
J. Nick Koston
39c2fea116 Merge branch 'mdns_arduino' into integration 2025-11-24 15:34:43 -06:00
J. Nick Koston
03767474b7 [mdns] Extract common Arduino mDNS registration to shared header 2025-11-24 15:28:45 -06:00
J. Nick Koston
fca4512370 [mdns] Extract common Arduino mDNS registration to shared header 2025-11-24 15:28:38 -06:00
Keith Burzinski
88b898458b [bluetooth_proxy] Fix crash due to null pointer (#12084)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-11-24 21:25:49 +00:00
Jonathan Swoboda
9186144dcd Bump version to 2025.11.1 2025-11-24 16:24:38 -05:00
Jesse Hills
25bcd0ea25 [online_image] Fix some large PNGs causing watchdog timeout (#12025)
Co-authored-by: guillempages <guillempages@users.noreply.github.com>
2025-11-24 16:24:38 -05:00
J. Nick Koston
50d08a2eba [esp_ldo,mipi_dsi,mipi_rgb] Fix dangling pointer bugs in mark_failed() (#12077) 2025-11-24 16:24:38 -05:00
J. Nick Koston
3a7a0c66ab [script][wait_until] Fix FIFO ordering and reentrancy bugs (#12049)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-24 16:24:38 -05:00
Jonathan Swoboda
83525b7a92 [core] Add support for passing yaml files to clean-all (#12039) 2025-11-24 16:24:38 -05:00
Jonathan Swoboda
f31f023c89 [esp32] Fix C2 builds (#12050) 2025-11-24 16:24:37 -05:00
J. Nick Koston
f8efefffaa [cst816][http_request] Fix status_set_error() dangling pointer bugs (#12033) 2025-11-24 16:24:37 -05:00
Jonathan Swoboda
d698083ede [jsn_sr04t] Fix model AJ_SR04M (#11992) 2025-11-24 16:24:37 -05:00
Jonathan Swoboda
11ba6440d7 [cst816][packet_transport][udp][wake_on_lan] Fix error messages (#12019) 2025-11-24 16:24:37 -05:00
Jonathan Swoboda
89ee37a2d5 [ltr501][ltr_als_ps] Rename enum to avoid collision with lwip defines (#12017) 2025-11-24 16:24:37 -05:00
J. Nick Koston
45b8c1e267 [network] Fix IPAddress constructor causing comparison failures and garbage output (#12005) 2025-11-24 16:24:37 -05:00
Jonathan Swoboda
fbe091f167 [graph] Fix legend border (#12000) 2025-11-24 16:24:37 -05:00
dependabot[bot]
e09656f20e Bump bleak from 1.1.1 to 2.0.0 (#12083)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 15:21:03 -06:00
Jesse Hills
eeb373fca9 [online_image] Fix some large PNGs causing watchdog timeout (#12025)
Co-authored-by: guillempages <guillempages@users.noreply.github.com>
2025-11-25 09:15:30 +13:00
J. Nick Koston
97ba67f4ee [core] Deprecate unsafe const char* APIs in mark_failed() and status_set_error(), add LogString* overloads (#12021) 2025-11-24 13:45:56 -06:00
J. Nick Koston
909baf5e7a [prometheus] Use current_option() instead of deprecated .state for select entities (#12079) 2025-11-24 13:45:29 -06:00
J. Nick Koston
a0440603b7 [wifi] Use ESP-IDF IP formatting macros directly to eliminate heap allocations (#12078) 2025-11-24 13:45:06 -06:00
dependabot[bot]
e2cd0ccd0e Bump actions/create-github-app-token from 2.1.4 to 2.2.0 (#12081)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 13:44:43 -06:00
dependabot[bot]
378fc4120a Bump peter-evans/create-pull-request from 7.0.8 to 7.0.9 (#12082)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 13:44:27 -06:00
dependabot[bot]
0dd842744a Bump github/codeql-action from 4.31.4 to 4.31.5 (#12080)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 13:44:09 -06:00
J. Nick Koston
a95f2ec484 Merge branch 'integration' into memory_api 2025-11-24 12:45:44 -06:00
J. Nick Koston
537ddcc880 Merge branch 'wifi_idf_cleanup' into integration 2025-11-24 12:45:38 -06:00
J. Nick Koston
d2483347d0 [wifi] Use ESP-IDF IP formatting macros directly to eliminate heap allocations 2025-11-24 12:44:41 -06:00
J. Nick Koston
b311d610df Merge branch 'integration' into memory_api 2025-11-24 12:24:06 -06:00
J. Nick Koston
301cf54ca6 Merge branch 'error_logstr' into integration 2025-11-24 12:24:02 -06:00
J. Nick Koston
bc7f67e0a2 clear 2025-11-24 12:23:51 -06:00
J. Nick Koston
7a73a524b9 [logger] Eliminate strlen overhead on LibreTiny (#11938) 2025-11-24 12:21:09 -06:00
J. Nick Koston
990a4442c7 Merge branch 'integration' into memory_api 2025-11-24 12:19:15 -06:00
J. Nick Koston
4eca6a7442 Merge branch 'error_logstr' into integration 2025-11-24 12:19:10 -06:00
J. Nick Koston
7496d20ae6 fix ambiguous 2025-11-24 12:18:59 -06:00
J. Nick Koston
83b5f061da Merge branch 'integration' into memory_api 2025-11-24 12:17:10 -06:00
J. Nick Koston
29999b3148 Merge branch 'error_logstr' into integration 2025-11-24 12:17:05 -06:00
J. Nick Koston
9d49ca58b5 silence warning for nullptr 2025-11-24 12:16:52 -06:00
J. Nick Koston
a279cc623a Merge branch 'integration' into memory_api 2025-11-24 12:12:22 -06:00
J. Nick Koston
7fc04c094c Merge branch 'error_logstr' into integration 2025-11-24 12:12:13 -06:00
J. Nick Koston
84b2bea706 fix dual dep 2025-11-24 12:12:05 -06:00
J. Nick Koston
fa1efb1048 Merge branch 'integration' into memory_api 2025-11-24 12:10:08 -06:00
J. Nick Koston
a6446ee179 Merge branch 'error_logstr' into integration 2025-11-24 12:09:58 -06:00
J. Nick Koston
04bb60fe5a Merge branch 'integration' into memory_api 2025-11-24 12:09:31 -06:00
J. Nick Koston
e2311d70e6 Merge branch 'libretiny_no_strlen' into integration 2025-11-24 12:09:26 -06:00
Kevin Ahrendt
d1a1bb446b [wifi] Add runtime power saving mode control (#11478)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-24 17:55:04 +00:00
J. Nick Koston
c146d92425 [api] Remove redundant socket pointer from APIFrameHelper (#11985) 2025-11-25 06:53:42 +13:00
J. Nick Koston
c888becfa7 [api] Optimize APINoiseContext memory usage by removing shared_ptr overhead (#11981) 2025-11-25 06:52:15 +13:00
Flo
09f3f62194 [api] Connected Condition - state_subscription_only flag (#11906)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-24 11:49:16 -06:00
J. Nick Koston
af9d0634cd Merge branch 'integration' into memory_api 2025-11-24 11:47:23 -06:00
J. Nick Koston
296e79d9e5 Merge branch 'copilot/fix-internal-gpio-attach-issues' into integration 2025-11-24 11:47:18 -06:00
Jordan Zucker
b820e67616 [prometheus] Add event and text base components metrics (#10240)
Co-authored-by: Jordan Zucker <jordan@Jordans-MacBook-Pro.local>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-24 11:42:07 -06:00
Sascha Ittner
d7da559885 [thermopro_ble] Add thermopro ble support (#11835)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-24 11:31:26 -06:00
Jonathan Swoboda
d7a197b3a3 [esp32] Use the IDF I2C implementation on Arduino (#12076) 2025-11-24 12:27:09 -05:00
Flo
66cda04664 [wifi] ap_active condition (#11852)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-11-24 11:19:38 -06:00
J. Nick Koston
c4dec5b3e3 Merge branch 'dev' into error_logstr 2025-11-24 11:02:54 -06:00
J. Nick Koston
0764f4da86 [esp_ldo,mipi_dsi,mipi_rgb] Fix dangling pointer bugs in mark_failed() (#12077) 2025-11-24 11:02:24 -06:00
J. Nick Koston
b29068cd40 Merge branch 'dev' into mdns_mac_storage_reduce_ram 2025-11-24 10:43:15 -06:00
J. Nick Koston
06815fe177 [script][wait_until] Fix FIFO ordering and reentrancy bugs (#12049)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-24 10:41:24 -06:00
J. Nick Koston
780fe37a13 fix mipi_dsi implementation 2025-11-24 10:27:53 -06:00
J. Nick Koston
4c1ec60d8b Merge remote-tracking branch 'origin/dev' into error_logstr 2025-11-24 10:27:12 -06:00
J. Nick Koston
5248e0139d handle mark_failed case 2025-11-24 10:25:15 -06:00
J. Nick Koston
04ec6a6999 [api] Use stack buffer for MAC address in Noise handshake (#12072) 2025-11-24 10:23:31 -06:00
J. Nick Koston
737f23a0bd [light] Dynamically disable loop when idle to reduce CPU overhead (#11881) 2025-11-24 10:23:11 -06:00
J. Nick Koston
011992f64d Merge branch 'dev' into libretiny_no_strlen 2025-11-24 10:22:44 -06:00
J. Nick Koston
3c48e13c9f [ethernet] Conditionally compile manual_ip to save 24 bytes RAM (#11832) 2025-11-24 10:22:13 -06:00
J. Nick Koston
426734beef [web_server_base] Replace shared_ptr with unique_ptr for AsyncWebServer (#11984) 2025-11-24 10:22:01 -06:00
J. Nick Koston
056b4375eb [api] Reduce heap allocations in DeviceInfoResponse (#11952) 2025-11-24 10:21:47 -06:00
J. Nick Koston
1f0a5e1eea [logger] Reduce UART overhead on ESP32/ESP8266 and fix buffer truncation (#11927) 2025-11-24 10:21:32 -06:00
Jonathan Swoboda
8607a0881d [core] Add support for passing yaml files to clean-all (#12039) 2025-11-24 10:10:24 -05:00
J. Nick Koston
87ded80310 Merge branch 'integration' into memory_api 2025-11-24 08:34:32 -06:00
J. Nick Koston
c141678abc Merge branch 'mdns_mac_storage_reduce_ram' into integration 2025-11-24 08:34:19 -06:00
J. Nick Koston
fd0a4e9111 dry 2025-11-24 08:34:04 -06:00
J. Nick Koston
12051813b8 dry 2025-11-24 08:33:47 -06:00
James
b4b98505ba [mipi_dsi] add guition JC4880P443 display (#12068) 2025-11-24 21:05:02 +11:00
kbx81
5b23b471bb preen 2025-11-24 02:34:46 -06:00
kbx81
84f9cbca58 preen 2025-11-24 02:21:34 -06:00
Keith Burzinski
87edf7ccf4 Merge branch 'dev' into 20250915-wifi-info-use-callbacks 2025-11-24 01:34:24 -06:00
kbx81
c1bc0358c3 preen 2025-11-24 01:33:32 -06:00
kbx81
deb8ffafa8 pico_w 2025-11-24 01:30:29 -06:00
J. Nick Koston
1fa4eedbb4 Merge branch 'integration' into memory_api 2025-11-23 22:43:50 -06:00
J. Nick Koston
9dd3ca7cf5 Merge branch 'mdns_mac_storage_reduce_ram' into integration 2025-11-23 22:43:43 -06:00
J. Nick Koston
b8719319fe cleanup 2025-11-23 22:42:07 -06:00
J. Nick Koston
39a4a0bf10 no dupe storage 2025-11-23 22:35:13 -06:00
Jonathan Swoboda
60d687c2c6 [esp32] Fix C2 builds (#12050) 2025-11-23 23:31:14 -05:00
J. Nick Koston
02c54bb373 Merge branch 'integration' into memory_api 2025-11-23 21:52:16 -06:00
J. Nick Koston
76406c91a5 Merge branch 'mdns_mac_storage_reduce_ram' into integration 2025-11-23 21:52:11 -06:00
J. Nick Koston
792a2b1ee1 tidy 2025-11-23 21:52:02 -06:00
J. Nick Koston
6fa7ad4e80 Merge branch 'integration' into memory_api 2025-11-23 21:46:25 -06:00
J. Nick Koston
98d3fb535f Merge branch 'mdns_mac_storage_reduce_ram' into integration 2025-11-23 21:46:19 -06:00
J. Nick Koston
fa299eed58 [mdns] Store MAC address in fixed buffer to reduce RAM usage 2025-11-23 21:45:28 -06:00
Jonathan Swoboda
5750f7fccb [ci] Fix test grouping (#12067) 2025-11-23 21:25:24 -06:00
J. Nick Koston
a018e07d3f Merge branch 'integration' into memory_api 2025-11-23 21:23:32 -06:00
J. Nick Koston
62823adc19 Merge branch 'esp32_ble_name_char' into integration 2025-11-23 21:23:25 -06:00
J. Nick Koston
2cd71bf273 one more 2025-11-23 21:22:26 -06:00
J. Nick Koston
ff4940d3b5 one more 2025-11-23 21:21:02 -06:00
J. Nick Koston
48f0e52f9d one more 2025-11-23 21:20:23 -06:00
J. Nick Koston
36f109c708 Merge branch 'integration' into memory_api 2025-11-23 21:15:36 -06:00
J. Nick Koston
8ed36e699f Merge branch 'api_noise_reduce_alloc' into integration 2025-11-23 21:15:29 -06:00
J. Nick Koston
268780dbeb [api] Use stack buffer for MAC address in Noise handshake 2025-11-23 21:13:27 -06:00
J. Nick Koston
a0bbce190a Merge branch 'integration' into memory_api 2025-11-23 21:01:42 -06:00
J. Nick Koston
214e6c358b Merge branch 'esp32_ble_name_char' into integration 2025-11-23 21:01:31 -06:00
J. Nick Koston
1e886b8885 [esp32_ble] Store device name in flash to reduce RAM usage 2025-11-23 20:56:27 -06:00
J. Nick Koston
531af6a277 [esp32_ble] Store device name in flash to reduce RAM usage 2025-11-23 20:50:31 -06:00
J. Nick Koston
b432c056dc [esp32_ble] Store device name in flash to reduce RAM usage 2025-11-23 20:48:27 -06:00
J. Nick Koston
cd9323ce70 overload 2025-11-23 20:45:31 -06:00
J. Nick Koston
10cc0c3bff overload 2025-11-23 20:43:51 -06:00
J. Nick Koston
5fcfe31be4 Merge branch 'integration' into memory_api 2025-11-23 20:39:13 -06:00
J. Nick Koston
9b8c9d38f5 Merge branch 'esp32_ble_name_char' into integration 2025-11-23 20:38:54 -06:00
J. Nick Koston
e7d09c0f62 [esp32_ble] Store device name in flash to reduce RAM usage 2025-11-23 20:36:54 -06:00
J. Nick Koston
0f5809765e Merge branch 'integration' into memory_api 2025-11-23 20:17:49 -06:00
J. Nick Koston
d3d5e4c8f4 Merge branch 'ble_address_str' into integration 2025-11-23 20:17:40 -06:00
J. Nick Koston
173912c68b more fixes 2025-11-23 20:10:44 -06:00
J. Nick Koston
4795ac7b1b [esp32_ble_client] Replace std::string with char[18] for BLE address storage 2025-11-23 20:03:25 -06:00
Jonathan Swoboda
c91a9495e6 [ci] Fix filename (#12065) 2025-11-23 16:19:26 -05:00
Javier Peletier
f42b806889 [core] Fix error on invalid id extend/remove (#12064) 2025-11-24 08:03:13 +11:00
Jesse Hills
a5751b294f [api] Rename USE_API_SERVICES to USE_API_USER_DEFINED_ACTIONS (#12029) 2025-11-24 08:13:23 +13:00
kbx81
66d6c85aa7 preen 2025-11-23 02:05:41 -06:00
kbx81
97572cc968 Merge remote-tracking branch 'upstream/dev' into 20250915-wifi-info-use-callbacks 2025-11-23 02:04:55 -06:00
Abílio Costa
3f6f2d7d65 [bm8563] Add bm8563 component (#11616)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-11-21 15:28:42 -05:00
Marko Draca
782aee92a7 [mcp3204] differential mode support (#7436)
Co-authored-by: marko <marko@>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-11-21 14:50:07 -05:00
J. Nick Koston
1fe1a3d2c8 fix date 2025-11-21 11:00:23 -06:00
J. Nick Koston
7de66024ca dry, fix load protected on esp8266 2025-11-21 10:56:12 -06:00
J. Nick Koston
6a48ba8d59 Merge branch 'dev' into error_logstr 2025-11-21 10:28:50 -06:00
Thomas Rupprecht
972b7e84fe [tests] Fix mipi_spi test board (#12031)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-11-21 08:38:44 -05:00
J. Nick Koston
d68fd02de4 Merge branch 'dev' into error_logstr 2025-11-21 06:42:25 -06:00
J. Nick Koston
150e26dc2b [cst816][http_request] Fix status_set_error() dangling pointer bugs (#12033) 2025-11-21 06:41:48 -06:00
Jonathan Swoboda
0dea7a23e3 [jsn_sr04t] Fix model AJ_SR04M (#11992) 2025-11-21 07:39:59 -05:00
copilot-swe-agent[bot]
ddf1e27ac3 Move gpio_intr_enable after gpio_isr_handler_add per review feedback
Co-authored-by: jesserockz <3060199+jesserockz@users.noreply.github.com>
2025-11-20 22:55:08 +00:00
J. Nick Koston
04c64c0f73 Merge branch 'integration' into memory_api 2025-11-20 15:10:21 -06:00
J. Nick Koston
a2a125a5c2 Merge remote-tracking branch 'upstream/copilot/fix-internal-gpio-attach-issues' into integration 2025-11-20 15:10:08 -06:00
copilot-swe-agent[bot]
55d7344086 Remove gpio_intr_enable() call to fix level-triggered interrupt panic
Co-authored-by: jesserockz <3060199+jesserockz@users.noreply.github.com>
2025-11-20 19:54:05 +00:00
copilot-swe-agent[bot]
fae833b73b Initial plan 2025-11-20 19:49:10 +00:00
dependabot[bot]
01addeae08 Bump actions/checkout from 5.0.1 to 6.0.0 (#12022)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-20 13:11:41 -06:00
J. Nick Koston
e37885ade5 syntax 2025-11-20 12:12:42 -06:00
J. Nick Koston
7cbc890c0d syntax 2025-11-20 12:12:14 -06:00
J. Nick Koston
3955b66379 [core] Deprecate status_set_error(const char*) and require LogString to prevent dangling pointers 2025-11-20 12:04:20 -06:00
Jonathan Swoboda
a1e507baf8 [cst816][packet_transport][udp][wake_on_lan] Fix error messages (#12019) 2025-11-20 12:10:28 -05:00
Jonathan Swoboda
1accb4ff34 [ltr501][ltr_als_ps] Rename enum to avoid collision with lwip defines (#12017) 2025-11-20 10:58:21 -05:00
damib
59cd6dbf70 [climate_ir] Add optional humidity sensor (#9805)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Djordje Mandic <6750655+DjordjeMandic@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-11-20 09:28:14 -05:00
omartijn
3c86f3894b [hc8] Add support for HC8 CO2 sensor (#11872)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-11-20 09:24:45 -05:00
J. Nick Koston
06bef148f4 [core] Optimize DelayAction for no-argument case using if constexpr (#11913) 2025-11-20 09:06:52 -05:00
tomaszduda23
5d883c6e06 [nrf52,i2c] fix review comment (#11931) 2025-11-20 09:06:40 -05:00
J. Nick Koston
b62053812b [core] Document threading model rationale in ThreadModel enum (#11979) 2025-11-20 09:06:28 -05:00
J. Nick Koston
a2321edf3c [network] Fix IPAddress constructor causing comparison failures and garbage output (#12005) 2025-11-20 08:59:16 -05:00
J. Nick Koston
24a6ad148c [lock] Modernize to C++17 nested namespaces (#11982) 2025-11-20 08:57:49 -05:00
J. Nick Koston
5071473767 [mdns] Modernize to C++17 nested namespace syntax (#11983) 2025-11-20 08:57:33 -05:00
J. Nick Koston
4825da8e9c [select] Modernize namespace declarations to C++17 syntax (#12007) 2025-11-20 08:57:04 -05:00
J. Nick Koston
48ba72ee34 Merge branch 'integration' into memory_api 2025-11-20 07:23:02 -06:00
J. Nick Koston
f494ca8e0f Merge branch 'api_ha_subs' into integration 2025-11-20 07:22:55 -06:00
J. Nick Koston
946f8deb3d tweak naming 2025-11-20 07:22:27 -06:00
Javier Peletier
b346666a52 [st7701s] Add explanatory comment (#12014) 2025-11-20 20:05:22 +11:00
J. Nick Koston
5fadeb5fd3 Merge branch 'integration' into memory_api 2025-11-19 23:26:03 -06:00
J. Nick Koston
56ef46fdd4 Merge branch 'api_ha_subs' into integration 2025-11-19 23:25:55 -06:00
J. Nick Koston
177026d8c4 simplify 2025-11-19 23:25:45 -06:00
J. Nick Koston
4533b8f92c tweaks 2025-11-19 23:20:24 -06:00
J. Nick Koston
0d3919747c Merge branch 'integration' into memory_api 2025-11-19 22:52:08 -06:00
J. Nick Koston
19c377b6de Merge branch 'api_ha_subs' into integration 2025-11-19 22:51:56 -06:00
J. Nick Koston
b9595c0795 cover 2025-11-19 22:49:52 -06:00
J. Nick Koston
efe2a1a506 cleanup 2025-11-19 22:32:41 -06:00
J. Nick Koston
185c1dec43 cleanup 2025-11-19 22:24:00 -06:00
J. Nick Koston
c39d17f864 cleanup 2025-11-19 22:20:12 -06:00
J. Nick Koston
b400a98fb3 [api] Store Home Assistant state subscriptions in flash instead of heap 2025-11-19 22:17:16 -06:00
B48D81EFCC
83307684a3 [stts22h] Add support for STTS22H temperature sensor (#11778)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-11-20 03:58:39 +00:00
J. Nick Koston
38f9d5d0b6 Merge branch 'integration' into memory_api 2025-11-19 21:39:05 -06:00
J. Nick Koston
c2ee7c7190 Merge remote-tracking branch 'upstream/dev' into integration 2025-11-19 21:38:37 -06:00
David Woodhouse
da25951f6e [socket] Fix IPv6 address parsing for BSD sockets (#11996) 2025-11-19 21:01:32 -06:00
J. Nick Koston
3b3a505283 Merge branch 'integration' into memory_api 2025-11-19 20:54:20 -06:00
J. Nick Koston
8ba330e992 Merge branch 'select_cpp17' into integration 2025-11-19 20:54:08 -06:00
J. Nick Koston
317a6082a1 [select] Modernize namespace declarations to C++17 syntax 2025-11-19 20:53:27 -06:00
J. Nick Koston
9f1b764c59 Merge branch 'integration' into memory_api 2025-11-19 18:25:36 -06:00
J. Nick Koston
463836fbdc Merge branch 'ipaddress_missing_type' into integration 2025-11-19 18:25:26 -06:00
J. Nick Koston
f478e09972 [network] Fix uninitialized type field in IPAddress esp_ip4_addr_t constructor 2025-11-19 18:12:18 -06:00
Jonathan Swoboda
4398fd84d2 [graph] Fix legend border (#12000) 2025-11-20 13:09:22 +13:00
J. Nick Koston
349aa41c1c Merge branch 'integration' into memory_api 2025-11-19 16:42:10 -06:00
J. Nick Koston
f6771dfdae Merge remote-tracking branch 'upstream/dev' into integration 2025-11-19 16:42:04 -06:00
Jonathan Swoboda
bbd6d019e5 Merge branch 'release' into dev 2025-11-19 17:37:58 -05:00
Jonathan Swoboda
625172e07d Merge pull request #12004 from esphome/bump-2025.11.0
2025.11.0
2025-11-19 17:37:42 -05:00
Jonathan Swoboda
1e9c7d3c6d Bump version to 2025.11.0 2025-11-19 16:02:52 -05:00
Jonathan Swoboda
4cdab4e2d8 Merge branch 'beta' into dev 2025-11-19 15:06:55 -05:00
Jonathan Swoboda
c2bc7b3cdc Merge pull request #12003 from esphome/bump-2025.11.0b5
2025.11.0b5
2025-11-19 15:06:44 -05:00
dependabot[bot]
2c3417062a Bump pyupgrade from 3.21.1 to 3.21.2 (#12002)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-19 13:47:40 -06:00
Jonathan Swoboda
c75abfb894 Bump version to 2025.11.0b5 2025-11-19 14:17:03 -05:00
Jesse Hills
1157b4aee8 [epaper_spi] Add basic 7.3in-Spectra-E6 model (#12001) 2025-11-19 14:17:03 -05:00
J. Nick Koston
71dc2d374d [web_server_idf] Fix pbuf_free crash by moving shutdown before close (#11995) 2025-11-19 14:17:03 -05:00
Jonathan Swoboda
0a224f919b [wifi] Fix positive RSSI values on 8266 (#11994) 2025-11-19 14:17:03 -05:00
Jonathan Swoboda
7ef4b4f3d9 [text_sensor] Fix infinite loop in substitute filter (#11989)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-19 14:17:03 -05:00
J. Nick Koston
13b875c763 [tests] Fix SNTP time ID conflicts in component tests for grouped testing (#11990) 2025-11-19 14:17:03 -05:00
Jesse Hills
b02b07ffaf [epaper_spi] Add basic 7.3in-Spectra-E6 model (#12001) 2025-11-19 14:11:45 -05:00
J. Nick Koston
8804bc2815 [web_server_idf] Fix pbuf_free crash by moving shutdown before close (#11995) 2025-11-20 07:58:33 +13:00
Jonathan Swoboda
61cef0a75c [api] Fix format warnings in dump (#11999) 2025-11-19 12:58:47 -05:00
J. Nick Koston
db8eb0ba89 Merge branch 'integration' into memory_api 2025-11-19 11:45:59 -06:00
J. Nick Koston
615cc8a9c0 Merge remote-tracking branch 'upstream/dev' into integration 2025-11-19 11:45:51 -06:00
Jonathan Swoboda
73bc5252a1 [wifi] Fix positive RSSI values on 8266 (#11994) 2025-11-19 10:12:57 -05:00
Jonathan Swoboda
f2b10ad132 [text_sensor] Fix infinite loop in substitute filter (#11989)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-19 10:12:34 -05:00
J. Nick Koston
100ea46f03 [tests] Fix SNTP time ID conflicts in component tests for grouped testing (#11990) 2025-11-18 23:19:54 -06:00
J. Nick Koston
b3ef05e5e1 [ld24xx] Modernize namespace declarations to C++17 syntax (#11988) 2025-11-19 04:00:39 +00:00
J. Nick Koston
45c994e4de [light] Modernize namespace declarations to C++17 syntax (#11986) 2025-11-18 21:56:23 -06:00
J. Nick Koston
71fa81088e Merge branch 'integration' into memory_api 2025-11-18 21:47:57 -06:00
J. Nick Koston
4933a2fbe1 Merge branch 'ld_namespace' into integration 2025-11-18 21:47:50 -06:00
J. Nick Koston
2d7942e788 [ld24xx] Modernize namespace declarations to C++17 syntax 2025-11-18 21:46:54 -06:00
J. Nick Koston
c81978c7e9 Merge branch 'integration' into memory_api 2025-11-18 21:09:31 -06:00
J. Nick Koston
a3cd3757b3 Merge branch 'light_namespace' into integration 2025-11-18 21:09:14 -06:00
J. Nick Koston
ecaa3f9f71 [light] Modernize namespace declarations to C++17 syntax 2025-11-18 21:07:13 -06:00
J. Nick Koston
99366eca89 Merge branch 'integration' into memory_api 2025-11-18 18:57:27 -06:00
J. Nick Koston
ab84d2dbeb Merge branch 'frame_helper_socket_dupe' into integration 2025-11-18 18:57:22 -06:00
J. Nick Koston
88717ac1f5 [api] Remove redundant socket pointer from APIFrameHelper 2025-11-18 18:53:50 -06:00
Jesse Hills
a72545639d Merge branch 'beta' into dev 2025-11-19 13:43:25 +13:00
Jesse Hills
dfd614c00c Merge pull request #11980 from esphome/bump-2025.11.0b4
2025.11.0b4
2025-11-19 13:22:09 +13:00
J. Nick Koston
29374837c6 [wifi, captive_portal, web_server, wifi_info] Use stack allocation for MAC address formatting (#11963) 2025-11-18 17:06:34 -06:00
J. Nick Koston
32e0470629 Merge branch 'integration' into memory_api 2025-11-18 16:21:30 -06:00
J. Nick Koston
fa9cc3d338 Merge branch 'web_server_is_singleton' into integration 2025-11-18 16:21:20 -06:00
J. Nick Koston
5c2cf9f37c [web_server_base] Replace shared_ptr with unique_ptr for AsyncWebServer 2025-11-18 16:10:07 -06:00
J. Nick Koston
c8cde24607 Merge branch 'integration' into memory_api 2025-11-18 15:58:19 -06:00
J. Nick Koston
b2bece2914 Merge branch 'mdns_namespace' into integration 2025-11-18 15:58:02 -06:00
J. Nick Koston
9f2e6d97d3 Merge branch 'lock_ns' into integration 2025-11-18 15:57:50 -06:00
J. Nick Koston
65b5619555 Merge branch 'api_noise' into integration 2025-11-18 15:57:44 -06:00
J. Nick Koston
b5ebe91150 [api] Optimize APINoiseContext memory usage by removing shared_ptr overhead 2025-11-18 15:24:50 -06:00
J. Nick Koston
99acc62c3b [lock] Modernize to C++17 nested namespaces 2025-11-18 14:51:37 -06:00
J. Nick Koston
66e471cf2a [mdns] Modernize to C++17 nested namespace syntax 2025-11-18 14:33:07 -06:00
J. Nick Koston
7ffff03823 Merge branch 'integration' into memory_api 2025-11-18 14:28:20 -06:00
J. Nick Koston
4e58c334d4 Merge remote-tracking branch 'upstream/dev' into integration 2025-11-18 14:28:07 -06:00
Jesse Hills
2681a14d05 Bump version to 2025.11.0b4 2025-11-19 09:17:33 +13:00
J. Nick Koston
f436f6ee2e [wifi] Fix captive portal unusable when WiFi credentials are wrong (#11965) 2025-11-19 09:17:33 +13:00
Jonathan Swoboda
f18bc62690 [sfa30] Fix negative temperature values (#11973) 2025-11-19 09:17:33 +13:00
J. Nick Koston
6db73df649 [scheduler] Add defensive nullptr checks and explicit locking requirements (#11974) 2025-11-19 09:17:33 +13:00
Jonathan Swoboda
93215f1737 [esp32] Fix Arduino build on some ESP32 S2 boards (#11972) 2025-11-19 09:17:33 +13:00
Clyde Stubbs
70aa94b8a4 [lvgl] Apply scale to spinbox value (#11946) 2025-11-19 09:17:33 +13:00
strange_v
e8998a79c7 [mipi_rgb] Fix GUITION-4848S040 colors (#11709) 2025-11-19 09:17:33 +13:00
Jonathan Swoboda
3b25fdbc5f [core] Add support for setting environment variables (#11953) 2025-11-19 09:17:33 +13:00
J. Nick Koston
6c8577678c [captive_portal] Warn when enabled without WiFi AP configured (#11856) 2025-11-19 09:17:33 +13:00
J. Nick Koston
70ed9c7c4d [wifi] Fix captive portal unusable when WiFi credentials are wrong (#11965) 2025-11-19 08:17:21 +13:00
dependabot[bot]
81fe5deaa9 Bump github/codeql-action from 4.31.3 to 4.31.4 (#11977)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-19 08:12:42 +13:00
Jonathan Swoboda
72e4b16a5b [sfa30] Fix negative temperature values (#11973) 2025-11-18 13:29:40 -05:00
Jonathan Swoboda
fe2befcec2 [bme68x] Print error when no sensors are configured (#11976) 2025-11-18 13:18:09 -05:00
J. Nick Koston
1888f5ffd5 [scheduler] Add defensive nullptr checks and explicit locking requirements (#11974) 2025-11-18 18:16:18 +00:00
Jonathan Swoboda
c59af22217 [esp32] Fix Arduino build on some ESP32 S2 boards (#11972) 2025-11-18 12:40:31 -05:00
J. Nick Koston
700e458352 Merge branch 'integration' into memory_api 2025-11-18 11:33:03 -06:00
J. Nick Koston
50982ced40 Merge branch 'scheduler_fix_nullptr' into integration 2025-11-18 11:32:58 -06:00
J. Nick Koston
d83a698398 [scheduler] Add defensive nullptr checks and explicit locking requirements 2025-11-18 11:31:01 -06:00
J. Nick Koston
33983b051b [ld24xx] Use stack allocation for MAC and version formatting (#11961) 2025-11-18 10:51:47 -06:00
J. Nick Koston
3ae68c0488 Merge branch 'integration' into memory_api 2025-11-18 10:13:31 -06:00
J. Nick Koston
0b8b5768b4 Merge branch 'captive_fix' into integration 2025-11-18 10:13:26 -06:00
J. Nick Koston
92e19c497e fixes 2025-11-18 10:13:03 -06:00
J. Nick Koston
62c9d83777 fixes 2025-11-18 10:09:14 -06:00
J. Nick Koston
53a3a5ddea fixes 2025-11-18 10:08:53 -06:00
J. Nick Koston
1f6aca5c17 fixes 2025-11-18 10:08:44 -06:00
J. Nick Koston
6253496192 Merge branch 'integration' into memory_api 2025-11-18 09:58:59 -06:00
J. Nick Koston
44d40804b2 Merge branch 'captive_fix' into integration 2025-11-18 09:58:50 -06:00
J. Nick Koston
303792bf8d make sure improv works if we are in connect loop 2025-11-18 09:58:34 -06:00
J. Nick Koston
9091285559 Merge branch 'integration' into memory_api 2025-11-18 09:37:39 -06:00
J. Nick Koston
8c028ce564 Merge branch 'captive_fix' into integration 2025-11-18 09:37:34 -06:00
J. Nick Koston
516f94671d fixes 2025-11-18 09:37:27 -06:00
J. Nick Koston
da70e4d9d0 Merge branch 'captive_fix' into integration 2025-11-18 09:35:20 -06:00
J. Nick Koston
19bd282274 fix tight loop 2025-11-18 09:35:14 -06:00
J. Nick Koston
61ca469a86 Merge branch 'integration' into memory_api 2025-11-18 09:33:37 -06:00
J. Nick Koston
46832306ad Merge branch 'captive_fix' into integration 2025-11-18 09:33:30 -06:00
J. Nick Koston
eaaaeecc92 there is a tight loop in improv 2025-11-18 09:32:50 -06:00
J. Nick Koston
bfea5c10d6 Merge branch 'integration' into memory_api 2025-11-18 09:28:23 -06:00
J. Nick Koston
3ac94fa6ab Merge branch 'captive_fix' into integration 2025-11-18 09:28:18 -06:00
J. Nick Koston
17b72061ad realign timeouts 2025-11-18 09:26:53 -06:00
J. Nick Koston
8025fc4a8b Merge branch 'integration' into memory_api 2025-11-18 09:26:00 -06:00
J. Nick Koston
05c2e31ef6 Merge branch 'captive_fix' into integration 2025-11-18 09:25:52 -06:00
J. Nick Koston
407f07a643 realign timeouts 2025-11-18 09:25:41 -06:00
J. Nick Koston
850978affe realign timeouts 2025-11-18 09:25:24 -06:00
J. Nick Koston
a8af45f60d Merge branch 'integration' into memory_api 2025-11-18 09:14:21 -06:00
J. Nick Koston
8708d4290c Merge branch 'captive_fix' into integration 2025-11-18 09:14:15 -06:00
J. Nick Koston
79b9e34f65 do not skip ssids in retry_hidden if we did not scan 2025-11-18 09:13:29 -06:00
J. Nick Koston
1457ef6e0b Merge branch 'integration' into memory_api 2025-11-18 00:15:41 -06:00
J. Nick Koston
9a2536a5f6 Merge branch 'captive_fix' into integration 2025-11-18 00:15:31 -06:00
J. Nick Koston
66fcf364a6 tweak 2025-11-18 00:09:51 -06:00
J. Nick Koston
048533a1fd no delay 2025-11-17 23:45:59 -06:00
J. Nick Koston
3f763b24c5 no delay 2025-11-17 23:45:32 -06:00
J. Nick Koston
efbf696f88 no delay 2025-11-17 23:45:25 -06:00
J. Nick Koston
29ef0a6740 no delay 2025-11-17 23:43:33 -06:00
J. Nick Koston
b9af06f5a4 no delay 2025-11-17 23:35:26 -06:00
J. Nick Koston
3f799a01a2 anotehr thread safety issue 2025-11-17 23:23:49 -06:00
J. Nick Koston
2ee5cc6f22 anotehr thread safety issue 2025-11-17 23:17:36 -06:00
J. Nick Koston
8d7090fcd6 fix thread safety issue 2025-11-17 23:11:55 -06:00
J. Nick Koston
3d83975d46 fix thread safety issue 2025-11-17 23:11:23 -06:00
J. Nick Koston
1815a7cf90 skip scan when ap mode 2025-11-17 23:03:38 -06:00
J. Nick Koston
bfe6fc0dd0 skip scan when ap mode 2025-11-17 23:00:22 -06:00
J. Nick Koston
87ccb777c6 esp32 2025-11-17 22:32:57 -06:00
J. Nick Koston
f0bae783cf cleanup 2025-11-17 22:31:53 -06:00
J. Nick Koston
6f96804a5d cleanup 2025-11-17 22:31:22 -06:00
Clyde Stubbs
11d0d4d128 [lvgl] Apply scale to spinbox value (#11946) 2025-11-18 17:27:50 +13:00
J. Nick Koston
a81f28a73b fixes 2025-11-17 22:14:56 -06:00
Clyde Stubbs
a4242dee64 [build] Don't clear pio cache unless requested (#11966) 2025-11-18 15:11:49 +11:00
J. Nick Koston
bbfff42f76 fixes 2025-11-17 22:11:27 -06:00
J. Nick Koston
11c8865248 fixes 2025-11-17 21:57:21 -06:00
J. Nick Koston
7f4205b82c reduce 2025-11-17 21:52:12 -06:00
J. Nick Koston
27a068e8b5 reduce 2025-11-17 21:44:18 -06:00
J. Nick Koston
15be275541 tweak 2025-11-17 21:03:35 -06:00
J. Nick Koston
0d6c9623ce [dashboard_import] Store package import URL in .rodata instead of RAM (#11951) 2025-11-17 20:02:16 -06:00
strange_v
0923bcd2ca [mipi_rgb] Fix GUITION-4848S040 colors (#11709) 2025-11-18 01:32:17 +00:00
J. Nick Koston
b0560894b7 [wifi] Fix captive portal unusable when WiFi credentials are wrong 2025-11-17 19:10:40 -06:00
J. Nick Koston
93e7db7b9c Merge branch 'integration' into memory_api 2025-11-17 18:02:31 -06:00
J. Nick Koston
1200e9c3ca Merge branch 'mac_address_buffer' into integration 2025-11-17 18:02:23 -06:00
J. Nick Koston
dc277e64f4 tweak 2025-11-17 18:00:15 -06:00
J. Nick Koston
6aa72f5449 Merge branch 'integration' into memory_api 2025-11-17 17:54:26 -06:00
J. Nick Koston
e312184a22 Merge branch 'mac_address_buffer' into integration 2025-11-17 17:54:18 -06:00
J. Nick Koston
6d67fd0b81 [wifi/captive_portal/web_server/wifi_info] Use stack allocation for MAC address formatting 2025-11-17 17:53:23 -06:00
J. Nick Koston
a08d67027d Merge branch 'integration' into memory_api 2025-11-17 17:34:09 -06:00
J. Nick Koston
0b1dd89fec Merge branch 'ld24xx_mac_version_format' into integration 2025-11-17 17:34:03 -06:00
J. Nick Koston
547f69011b tidy 2025-11-17 17:33:52 -06:00
J. Nick Koston
53bab00858 [ld24xx] Use stack allocation for MAC and version formatting 2025-11-17 17:27:08 -06:00
J. Nick Koston
fdc7ae7760 [wifi] Skip redundant setter calls for default values (#11943) 2025-11-17 17:20:32 -06:00
J. Nick Koston
1a73f49cd2 [number] Modernize to C++17 nested namespaces (#11945) 2025-11-17 17:20:18 -06:00
dependabot[bot]
23f85162d0 Bump actions/checkout from 5.0.0 to 5.0.1 (#11957)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-17 15:39:01 -06:00
dependabot[bot]
7a238028a7 Bump ruamel-yaml-clib from 0.2.14 to 0.2.15 (#11956)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-17 15:38:44 -06:00
J. Nick Koston
5b9d2e5e35 Merge branch 'dev' into timeout_filter_scheduler_churn_fix 2025-11-17 15:12:59 -06:00
Jonathan Swoboda
3d6c361037 [core] Add support for setting environment variables (#11953) 2025-11-17 12:32:08 -05:00
J. Nick Koston
f31a29272e Merge branch 'integration' into memory_api 2025-11-17 09:36:09 -06:00
J. Nick Koston
adf75630fe Merge branch 'device_info_less_alloc' into integration 2025-11-17 09:36:02 -06:00
J. Nick Koston
539597209f [api] Reduce heap allocations in DeviceInfoResponse 2025-11-17 09:35:05 -06:00
J. Nick Koston
44eb4c581c Merge branch 'integration' into memory_api 2025-11-17 09:21:02 -06:00
J. Nick Koston
8b1f3b2b08 Merge branch 'bh1750_loop' into integration 2025-11-17 09:20:55 -06:00
J. Nick Koston
70e44cd5a6 Merge branch 'integration' into memory_api 2025-11-17 09:13:38 -06:00
J. Nick Koston
499ad18475 Merge branch 'dashboard_import_url_store_rodata' into integration 2025-11-17 09:13:30 -06:00
J. Nick Koston
0afaf182da Merge branch 'dev' into dashboard_import_url_store_rodata 2025-11-17 09:12:57 -06:00
J. Nick Koston
43f2405dc3 [dashboard_import] Store package import URL in .rodata instead of RAM 2025-11-17 09:10:51 -06:00
J. Nick Koston
41ac12a0e1 Update esphome/components/bh1750/bh1750.cpp 2025-11-17 08:48:42 -06:00
J. Nick Koston
a6f416a09e Update esphome/components/bh1750/bh1750.cpp 2025-11-17 08:48:13 -06:00
J. Nick Koston
64b9e23728 Merge branch 'integration' into memory_api 2025-11-17 08:34:47 -06:00
J. Nick Koston
c155dbb4e6 Merge branch 'bh1750_loop' into integration 2025-11-17 08:34:37 -06:00
Javier Peletier
9e1f8d83f8 [config] Support !remove and !extend with LVGL-style configs (#11534) 2025-11-17 18:03:11 +11:00
Jesse Hills
fa0aa6defc Merge branch 'beta' into dev 2025-11-17 17:41:46 +13:00
Jesse Hills
70366d2124 Merge pull request #11944 from esphome/bump-2025.11.0b3
2025.11.0b3
2025-11-17 17:41:11 +13:00
J. Nick Koston
78a69cb744 tidy 2025-11-16 22:33:59 -06:00
J. Nick Koston
9b14444dad tidy 2025-11-16 22:30:59 -06:00
J. Nick Koston
8934d4b498 touch ups 2025-11-16 22:08:44 -06:00
J. Nick Koston
9b107e7f2a touch ups 2025-11-16 22:05:33 -06:00
J. Nick Koston
7edfdf9e65 Merge branch 'integration' into memory_api 2025-11-16 21:00:29 -06:00
J. Nick Koston
11b53800fb Merge branch 'number_namespaces' into integration 2025-11-16 21:00:21 -06:00
J. Nick Koston
bbd12609af Merge remote-tracking branch 'upstream/dev' into integration 2025-11-16 21:00:03 -06:00
J. Nick Koston
23be236133 [number] Modernize to C++17 nested namespaces 2025-11-16 20:54:43 -06:00
J. Nick Koston
10bdb47eae [cover] Modernize to C++17 nested namespaces (#11935) 2025-11-16 20:37:06 -06:00
Jesse Hills
a38c4e0c6e Bump version to 2025.11.0b3 2025-11-17 15:32:09 +13:00
Anton Sergunov
6c6b03bda0 [uart] Setup uart pins only if flags are set (#11914)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-11-17 15:32:09 +13:00
J. Nick Koston
9e02e31917 [web_server_idf] Fix lwIP assertion crash by shutting down sockets on connection close (#11937) 2025-11-17 15:32:09 +13:00
J. Nick Koston
3fd58f1a91 [web_server.ota] Merge multiple instances to prevent undefined behavior (#11905) 2025-11-17 15:32:09 +13:00
J. Nick Koston
9151489481 [sntp] Merge multiple instances to fix crash and undefined behavior (#11904) 2025-11-17 15:32:09 +13:00
J. Nick Koston
f19296ac7f [analyze-memory] Show all core symbols > 100 B instead of top 15 (#11909) 2025-11-17 15:32:09 +13:00
J. Nick Koston
36868ee7b1 [scheduler] Fix timing breakage after 49 days of uptime on ESP8266/RP2040 (#11924) 2025-11-17 15:32:09 +13:00
J. Nick Koston
d559f9f52e [ld2410] Add timeout filter to prevent stuck targets (#11920) 2025-11-17 15:32:09 +13:00
J. Nick Koston
6440b5fbf5 [ld2412] Fix stuck targets by adding timeout filter (#11919) 2025-11-17 15:32:09 +13:00
Jonathan Swoboda
97c4914573 [uart] Improve error handling and validate buffer size (#11895)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-11-17 15:32:09 +13:00
Edward Firmo
7ce94c27fe [wifi] Allow use_psram with Arduino (#11902) 2025-11-17 15:32:09 +13:00
Edward Firmo
eb54c0026d [light] Fix missing ColorMode::BRIGHTNESS case in logging (#11836) 2025-11-17 15:32:09 +13:00
Clyde Stubbs
fe00e209ff [esp32] Add sdkconfig flag to make OTA work for 32MB flash (#11883)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-11-17 15:32:08 +13:00
Clyde Stubbs
aed80732f9 [esp32] Make esp-idf default framework for P4 (#11884) 2025-11-17 15:32:08 +13:00
Anton Sergunov
aa097a2fe6 [uart] Setup uart pins only if flags are set (#11914)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-11-17 14:25:00 +13:00
J. Nick Koston
3b860e784c [web_server_idf] Fix lwIP assertion crash by shutting down sockets on connection close (#11937) 2025-11-17 13:39:01 +13:00
J. Nick Koston
96ee38759d [web_server.ota] Merge multiple instances to prevent undefined behavior (#11905) 2025-11-17 13:38:52 +13:00
J. Nick Koston
986d3c8f13 [sntp] Merge multiple instances to fix crash and undefined behavior (#11904) 2025-11-17 13:38:38 +13:00
J. Nick Koston
c4c1de915a Merge branch 'integration' into memory_api 2025-11-16 15:55:18 -06:00
J. Nick Koston
b8c216c646 Merge branch 'dev' into integration 2025-11-16 15:55:11 -06:00
Clyde Stubbs
320120883c [lvgl] Migrate lv_font creation into Font class and optimise (#11915) 2025-11-17 08:47:54 +11:00
J. Nick Koston
46ea962e4f Merge branch 'integration' into memory_api 2025-11-16 13:04:08 -06:00
J. Nick Koston
76546bade7 Merge branch 'combine_name_object_id' into integration 2025-11-16 13:04:00 -06:00
J. Nick Koston
8997fb3443 [core] Reduce flash size by combining set_name() and set_object_id() calls 2025-11-16 13:02:59 -06:00
J. Nick Koston
af58909bd7 Merge branch 'integration' into memory_api 2025-11-16 12:48:04 -06:00
J. Nick Koston
094ed59230 Merge branch 'de_dupe_lam' into integration 2025-11-16 12:47:44 -06:00
J. Nick Koston
5edcb62f6e Merge branch 'integration' into memory_api 2025-11-16 11:58:08 -06:00
J. Nick Koston
8512266068 Merge branch 'libretiny_no_strlen' into integration 2025-11-16 11:58:02 -06:00
J. Nick Koston
4c9d903773 [logger] Eliminate strlen overhead on LibreTiny 2025-11-16 11:56:52 -06:00
J. Nick Koston
fd0d1c41b7 Merge branch 'integration' into memory_api 2025-11-16 09:19:04 -06:00
J. Nick Koston
d878e9a8f2 Merge remote-tracking branch 'upstream/web_server_shutdown_race_fix' into integration 2025-11-16 09:18:58 -06:00
J. Nick Koston
02c5f18b5d [web_server_idf] Fix lwIP assertion crash by shutting down sockets on connection close 2025-11-16 09:18:07 -06:00
J. Nick Koston
a913e7df33 handles newlines, add test to prove it 2025-11-16 08:16:41 -06:00
J. Nick Koston
4fc4da6ed2 [analyze-memory] Show all core symbols > 100 B instead of top 15 (#11909) 2025-11-16 07:35:31 -06:00
J. Nick Koston
014bdd1ed0 Merge branch 'dev' into timeout_filter_scheduler_churn_fix 2025-11-15 22:21:57 -06:00
J. Nick Koston
6f4042f401 Add tests for sensor timeout filters (#11923) 2025-11-15 22:21:38 -06:00
J. Nick Koston
ea2b4c3e25 [binary_sensor] Modernize to C++17 nested namespaces and remove redundant qualifications (#11929) 2025-11-16 04:21:06 +00:00
J. Nick Koston
fc546ca3f6 [scheduler] Fix timing breakage after 49 days of uptime on ESP8266/RP2040 (#11924) 2025-11-15 22:20:57 -06:00
J. Nick Koston
6b158e760d [ld2410] Add timeout filter to prevent stuck targets (#11920) 2025-11-15 22:04:25 -06:00
J. Nick Koston
5710cab972 [ld2412] Fix stuck targets by adding timeout filter (#11919) 2025-11-15 22:03:43 -06:00
J. Nick Koston
bfea4220dc Merge branch 'integration' into memory_api 2025-11-15 21:34:05 -06:00
J. Nick Koston
027ede7ca2 Merge branch 'binary_sensor_namespace_cleanup' into integration 2025-11-15 21:33:54 -06:00
J. Nick Koston
6d03afecd0 [binary_sensor] Modernize to C++17 nested namespaces and remove redundant qualifications 2025-11-15 21:32:46 -06:00
Clyde Stubbs
eb759efb3d [font] Store glyph data in flash only (#11926) 2025-11-16 12:48:02 +11:00
J. Nick Koston
7aae4b4fce Merge branch 'integration' into memory_api 2025-11-15 18:43:54 -06:00
J. Nick Koston
3d9390498b Merge branch 'reduce_logger_locking' into integration 2025-11-15 18:43:48 -06:00
J. Nick Koston
d60c358f48 preen 2025-11-15 18:43:39 -06:00
J. Nick Koston
1138495efa Merge branch 'integration' into memory_api 2025-11-15 18:36:56 -06:00
J. Nick Koston
f725877b0e Merge branch 'reduce_logger_locking' into integration 2025-11-15 18:36:51 -06:00
J. Nick Koston
26b820272a optimize esp8266 as well 2025-11-15 18:36:39 -06:00
J. Nick Koston
d4648b51ab Merge branch 'integration' into memory_api 2025-11-15 18:31:34 -06:00
J. Nick Koston
e20d89d190 Merge branch 'reduce_logger_locking' into integration 2025-11-15 18:31:25 -06:00
J. Nick Koston
9557c90c20 comment 2025-11-15 18:31:07 -06:00
J. Nick Koston
50faae2d3c Merge branch 'integration' into memory_api 2025-11-15 18:18:11 -06:00
J. Nick Koston
693b27a190 Merge branch 'reduce_logger_locking' into integration 2025-11-15 18:18:04 -06:00
J. Nick Koston
d64bcf27b3 cleanup 2025-11-15 18:17:50 -06:00
J. Nick Koston
61520726ad Merge branch 'integration' into memory_api 2025-11-15 18:15:26 -06:00
J. Nick Koston
47d1081ebc Merge branch 'reduce_logger_locking' into integration 2025-11-15 18:15:21 -06:00
J. Nick Koston
d5d61546e7 cleanup 2025-11-15 18:15:10 -06:00
J. Nick Koston
7289a4e2c6 Merge branch 'integration' into memory_api 2025-11-15 18:03:53 -06:00
J. Nick Koston
0b33ba606c Merge branch 'reduce_logger_locking' into integration 2025-11-15 18:03:44 -06:00
J. Nick Koston
554cdbd5a4 bot is right 2025-11-15 18:03:08 -06:00
J. Nick Koston
8ec14bd57c bot is right 2025-11-15 18:02:54 -06:00
J. Nick Koston
a8a3e4d157 Merge branch 'integration' into memory_api 2025-11-15 17:42:14 -06:00
J. Nick Koston
0b132f9569 Merge branch 'reduce_logger_locking' into integration 2025-11-15 17:42:10 -06:00
J. Nick Koston
0d147e5d10 missed one 2025-11-15 17:42:01 -06:00
J. Nick Koston
a552e1d328 Merge branch 'integration' into memory_api 2025-11-15 17:37:49 -06:00
J. Nick Koston
46ddd253bd Merge branch 'reduce_logger_locking' into integration 2025-11-15 17:37:45 -06:00
J. Nick Koston
730a70ee8b missed header 2025-11-15 17:37:37 -06:00
J. Nick Koston
0f6963de27 Merge branch 'integration' into memory_api 2025-11-15 17:36:44 -06:00
J. Nick Koston
1b19e4e8ad Merge branch 'reduce_logger_locking' into integration 2025-11-15 17:36:37 -06:00
J. Nick Koston
d096f1192d make bot happy 2025-11-15 17:35:41 -06:00
J. Nick Koston
b14bab1fce make bot happy 2025-11-15 17:35:32 -06:00
J. Nick Koston
d84976715b Merge branch 'integration' into memory_api 2025-11-15 17:20:01 -06:00
J. Nick Koston
ae985bfb07 Merge branch 'reduce_logger_locking' into integration 2025-11-15 17:19:55 -06:00
J. Nick Koston
88a23acc4b tweak 2025-11-15 17:19:37 -06:00
J. Nick Koston
950dff1a38 [logger] Reduce ESP32 UART mutex overhead by 50% 2025-11-15 16:54:18 -06:00
J. Nick Koston
61eddfdcda [logger] Reduce ESP32 UART mutex overhead by 50% 2025-11-15 16:47:35 -06:00
J. Nick Koston
13ac071482 Merge branch 'integration' into memory_api 2025-11-15 15:35:53 -06:00
J. Nick Koston
0f10b9d76f Merge branch 'single_model_rollover_fix' into integration 2025-11-15 15:35:43 -06:00
J. Nick Koston
c61411c620 [scheduler] Fix timing breakage after 49 days of uptime on ESP8266/RP2040 2025-11-15 14:42:06 -06:00
J. Nick Koston
6a05c64e2a Merge branch 'sensor_timeout_filter' into timeout_filter_scheduler_churn_fix 2025-11-15 13:11:37 -06:00
J. Nick Koston
af77dfeacc helper 2025-11-15 13:11:04 -06:00
J. Nick Koston
aca74e34b8 Add tests for sensor timeout filters
ahead of optimization effort in https://github.com/esphome/esphome/pull/11922
2025-11-15 13:07:56 -06:00
J. Nick Koston
6f5f45f1e9 cover 2025-11-15 13:06:54 -06:00
J. Nick Koston
6cca3617d8 cover 2025-11-15 13:06:06 -06:00
J. Nick Koston
894ba341ba [sensor] Replace timeout filter scheduler with loop-based implementation 2025-11-15 12:56:25 -06:00
J. Nick Koston
e8e06db260 Merge branch 'integration' into memory_api 2025-11-15 12:26:53 -06:00
J. Nick Koston
219206057f Merge branch 'de_dupe_lam' into integration 2025-11-15 12:26:47 -06:00
J. Nick Koston
f6378990cd add tests for crazy edge cases 2025-11-15 12:19:06 -06:00
J. Nick Koston
5090762d5a Merge branch 'integration' into memory_api 2025-11-15 12:12:36 -06:00
J. Nick Koston
e604ec267e Merge remote-tracking branch 'origin/switch_to_std_index_sequence' into integration 2025-11-15 12:12:21 -06:00
J. Nick Koston
ae343a94ca disable around old code 2025-11-15 12:11:50 -06:00
J. Nick Koston
2229996c22 Merge branch 'memory_api' of https://github.com/esphome/esphome into memory_api 2025-11-15 12:09:18 -06:00
J. Nick Koston
b7d4e01fa2 Merge branch 'integration' into memory_api 2025-11-15 12:07:02 -06:00
J. Nick Koston
25c7be3970 Merge branch 'de_dupe_lam' into integration 2025-11-15 12:06:57 -06:00
J. Nick Koston
849c9b1625 Merge branch 'memory_api' of https://github.com/esphome/esphome into memory_api 2025-11-15 12:06:34 -06:00
J. Nick Koston
1c10485cee Merge branch 'integration' into memory_api 2025-11-15 12:06:27 -06:00
J. Nick Koston
8e6747c00e Merge branch 'switch_to_std_index_sequence' into integration 2025-11-15 12:06:22 -06:00
J. Nick Koston
d7892f2289 [core] Replace seq<>/gens<> with std::index_sequence for code clarity 2025-11-15 12:04:49 -06:00
J. Nick Koston
b7f6013378 [core] Replace seq<>/gens<> with std::index_sequence for code clarity 2025-11-15 12:04:02 -06:00
J. Nick Koston
fb9e7028a0 [core] Replace seq<>/gens<> with std::index_sequence for code clarity 2025-11-15 11:58:24 -06:00
J. Nick Koston
e9ff4d3c4e handle static 2025-11-15 11:47:35 -06:00
J. Nick Koston
35b6395449 Merge branch 'integration' into memory_api 2025-11-15 11:03:05 -06:00
J. Nick Koston
f29b191804 Merge branch 'ld2410_missing_timeout' into integration 2025-11-15 11:02:51 -06:00
J. Nick Koston
734f96140f Merge branch 'ld2412_missing_timeout' into integration 2025-11-15 11:02:46 -06:00
J. Nick Koston
ed60d8668e [ld2410] Add timeout filter to prevent stuck targets 2025-11-15 10:56:17 -06:00
J. Nick Koston
7892adb948 [ld2412] Fix stuck targets by adding timeout filter 2025-11-15 10:52:49 -06:00
J. Nick Koston
96ea6e8059 Merge branch 'integration' into memory_api 2025-11-15 10:43:19 -06:00
J. Nick Koston
107a0a23b1 Merge branch 'de_dupe_lam' into integration 2025-11-15 10:43:08 -06:00
J. Nick Koston
4081345013 address bot review 2025-11-15 10:42:57 -06:00
J. Nick Koston
3dd570fdd0 address bot review 2025-11-15 10:42:44 -06:00
J. Nick Koston
04f445dfaf Merge branch 'integration' into memory_api 2025-11-15 10:27:05 -06:00
J. Nick Koston
82d04c1548 Merge branch 'de_dupe_lam' into integration 2025-11-15 10:26:48 -06:00
J. Nick Koston
5989b78e93 preen 2025-11-15 10:25:57 -06:00
J. Nick Koston
5727043cec preen 2025-11-15 10:24:38 -06:00
J. Nick Koston
1441c7fab2 preen 2025-11-15 10:21:58 -06:00
J. Nick Koston
62248b6bba rpeen 2025-11-15 10:20:53 -06:00
J. Nick Koston
86833cbc3c rpeen 2025-11-15 10:20:40 -06:00
J. Nick Koston
6067ca36f7 Merge branch 'integration' into memory_api 2025-11-15 10:15:47 -06:00
J. Nick Koston
a98d2fa266 Merge branch 'de_dupe_lam' into integration 2025-11-15 10:15:40 -06:00
J. Nick Koston
b7c105125e proper codegen 2025-11-15 10:13:43 -06:00
J. Nick Koston
11de948698 proper codegen 2025-11-15 10:12:36 -06:00
J. Nick Koston
6ade327cde update tests 2025-11-15 10:05:27 -06:00
J. Nick Koston
cc1b547ad2 der dupe lam 2025-11-14 22:27:23 -06:00
J. Nick Koston
d1f3979c7f Merge branch 'integration' into memory_api 2025-11-14 20:26:28 -06:00
J. Nick Koston
25408dc445 Merge branch 'delay_action_avoid_bind_no_args' into integration 2025-11-14 20:18:15 -06:00
J. Nick Koston
f1bc3c68dd [core] Optimize DelayAction for no-argument case using if constexpr 2025-11-14 20:09:38 -06:00
J. Nick Koston
f8191410e3 [core] Optimize DelayAction for no-argument case using if constexpr 2025-11-14 20:05:43 -06:00
J. Nick Koston
90ba8ecacd Merge branch 'integration' into memory_api 2025-11-14 19:22:10 -06:00
J. Nick Koston
2f354a9c32 Merge remote-tracking branch 'upstream/dev' into integration 2025-11-14 19:21:57 -06:00
dependabot[bot]
1df996601d Bump ruff from 0.14.4 to 0.14.5 (#11910)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-11-14 19:14:07 +00:00
J. Nick Koston
c25b87350d Merge branch 'integration' into memory_api 2025-11-14 13:13:47 -06:00
J. Nick Koston
db826b4a2b Merge branch 'dev' into integration 2025-11-14 13:13:36 -06:00
dependabot[bot]
c32891ec02 Bump github/codeql-action from 4.31.2 to 4.31.3 (#11911)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-14 13:09:59 -06:00
Jonathan Swoboda
2bf6d48fcf [uart] Improve error handling and validate buffer size (#11895)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-11-14 14:06:08 -05:00
J. Nick Koston
51eb15bf8c Merge branch 'integration' into memory_api 2025-11-14 11:31:00 -06:00
J. Nick Koston
e19a99dd7f Merge branch 'analyze_memory_missing_symbols' into integration 2025-11-14 11:30:54 -06:00
J. Nick Koston
6666911ebf [analyze-memory] Show all core symbols > 100 B instead of top 15 2025-11-14 11:29:36 -06:00
J. Nick Koston
b890f097cf Merge branch 'integration' into memory_api 2025-11-14 09:03:31 -06:00
J. Nick Koston
5af5a86970 Merge branch 'sntp_single_instance' into integration 2025-11-14 09:02:00 -06:00
J. Nick Koston
3de847014b Merge branch 'webserver_ota_single_instance' into integration 2025-11-14 09:01:56 -06:00
J. Nick Koston
5f10fbc4f6 [web_server.ota] Merge multiple instances to prevent undefined behavior 2025-11-14 08:59:05 -06:00
J. Nick Koston
e8f2e91db3 [sntp] Merge multiple instances to fix crash and undefined behavior 2025-11-14 08:47:15 -06:00
Edward Firmo
e49a943cf7 [wifi] Allow use_psram with Arduino (#11902) 2025-11-14 09:13:48 -05:00
dependabot[bot]
67524e14ee Bump pylint from 4.0.2 to 4.0.3 (#11894)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-13 19:05:02 +00:00
J. Nick Koston
6370132cbb Merge branch 'integration' into memory_api 2025-11-13 12:38:14 -06:00
J. Nick Koston
3c0969d8a4 Merge branch 'template_alarm_control_panel_only_iterates' into integration 2025-11-13 12:38:08 -06:00
J. Nick Koston
1f408ce41c [template.alarm_control_panel] Use FixedVector for iteration-only sensor storage 2025-11-13 12:35:43 -06:00
Edward Firmo
2290eb0dd2 [light] Fix missing ColorMode::BRIGHTNESS case in logging (#11836) 2025-11-13 12:08:06 -06:00
J. Nick Koston
e1ed7f7fd0 Merge branch 'integration' into memory_api 2025-11-13 11:55:47 -06:00
J. Nick Koston
79b97452b7 Merge remote-tracking branch 'upstream/dev' into integration 2025-11-13 11:55:39 -06:00
Clyde Stubbs
0afcf67c32 [esp32] Add sdkconfig flag to make OTA work for 32MB flash (#11883)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-11-13 10:52:08 -05:00
Clyde Stubbs
952bdfaac2 [esp32] Make esp-idf default framework for P4 (#11884) 2025-11-13 09:55:48 -05:00
Jesse Hills
ed7e5cd325 Bump version to 2025.12.0-dev 2025-11-13 17:00:47 +13:00
J. Nick Koston
eefda8ce16 Merge branch 'integration' into memory_api 2025-11-12 21:50:25 -06:00
J. Nick Koston
9f5a6017af Merge branch 'light_loop' into integration 2025-11-12 21:50:20 -06:00
J. Nick Koston
20649ce8ce safer 2025-11-12 21:49:58 -06:00
Jonathan Swoboda
a15f46e741 Merge branch 'beta' into dev 2025-11-12 22:46:34 -05:00
Jonathan Swoboda
050a27a409 Merge pull request #11880 from esphome/bump-2025.11.0b2
2025.11.0b2
2025-11-12 22:46:23 -05:00
J. Nick Koston
2592119138 Merge branch 'integration' into memory_api 2025-11-12 21:30:59 -06:00
J. Nick Koston
8c9d1cc392 Merge branch 'light_loop' into integration 2025-11-12 21:30:53 -06:00
J. Nick Koston
9b458d25ea light loop 2025-11-12 21:20:11 -06:00
J. Nick Koston
4e23a7a3e1 light loop 2025-11-12 21:11:45 -06:00
Jonathan Swoboda
382483b063 Bump version to 2025.11.0b2 2025-11-12 21:56:11 -05:00
J. Nick Koston
1675408161 [wifi] Fix slow reconnection after connection loss for all network types (#11873)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-12 21:56:11 -05:00
J. Nick Koston
1d8b08dcce [wifi][ethernet] Fix spurious warnings and unclear status after PR #9823 (#11871) 2025-11-12 21:56:11 -05:00
J. Nick Koston
afed581079 [light] Fix dangling reference in compute_color_mode causing memory corruption (#11868) 2025-11-12 21:56:11 -05:00
J. Nick Koston
ff107a0674 [mqtt] Fix crash with empty broker during upload/logs (#11866)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-12 21:56:11 -05:00
J. Nick Koston
72da3d0f1e [thermostat] Replace std::map with FixedVector, reduce flash usage (#11875) 2025-11-12 21:56:11 -05:00
J. Nick Koston
5a2e6697e0 [api][event] Send events immediately to prevent loss during rapid triggers (#11777) 2025-11-12 21:56:11 -05:00
J. Nick Koston
799cfe1de4 [esp32_ble_tracker] Use initializer_list to eliminate compiler warning and reduce flash usage (#11861) 2025-11-12 21:56:11 -05:00
J. Nick Koston
6df0264d51 [api] Eliminate heap allocations when transmitting Event types (#11773) 2025-11-12 21:56:11 -05:00
J. Nick Koston
a859ecaad1 [core] Fix wait_until hanging when used in on_boot automations (#11869) 2025-11-12 21:56:11 -05:00
Jonathan Swoboda
4f088c93c9 [esp32] Update the recommended platform to 55.03.31-2 (#11865) 2025-11-12 21:56:11 -05:00
J. Nick Koston
a1ab19d127 [ci] Reduce release time by removing 21 redundant ESP32-S3 IDF tests (#11850) 2025-11-12 21:56:11 -05:00
J. Nick Koston
47a3e5e78b Merge branch 'integration' into memory_api 2025-11-12 20:09:05 -06:00
J. Nick Koston
f196b1c867 Merge remote-tracking branch 'upstream/dev' into integration 2025-11-12 20:08:51 -06:00
tomaszduda23
d869108416 [nrf52] add settings for dcdc converter (#11841) 2025-11-12 20:06:20 -06:00
J. Nick Koston
2d6618da3c [wifi] Fix slow reconnection after connection loss for all network types (#11873)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-13 13:44:22 +13:00
J. Nick Koston
47fe84e922 [wifi][ethernet] Fix spurious warnings and unclear status after PR #9823 (#11871) 2025-11-13 13:43:51 +13:00
J. Nick Koston
735bf9930a [light] Fix dangling reference in compute_color_mode causing memory corruption (#11868) 2025-11-13 13:41:28 +13:00
J. Nick Koston
769137fc09 [mqtt] Fix crash with empty broker during upload/logs (#11866)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-13 13:40:26 +13:00
J. Nick Koston
3a5b3ad77d [thermostat] Replace std::map with FixedVector, reduce flash usage (#11875) 2025-11-12 17:55:06 -06:00
J. Nick Koston
859101ddc9 [api][event] Send events immediately to prevent loss during rapid triggers (#11777) 2025-11-13 12:42:50 +13:00
J. Nick Koston
f19abab93f Merge branch 'thermostat_storage' into memory_api 2025-11-12 15:01:19 -06:00
J. Nick Koston
b8717fee4e Merge branch 'thermostat_storage' into integration 2025-11-12 15:01:13 -06:00
J. Nick Koston
4eb471b316 tweaks 2025-11-12 15:01:05 -06:00
J. Nick Koston
b017e034ee tweaks 2025-11-12 15:00:52 -06:00
J. Nick Koston
9a2574a2fe Merge branch 'integration' into memory_api 2025-11-12 14:56:02 -06:00
J. Nick Koston
72513897cc Merge branch 'thermostat_storage' into integration 2025-11-12 14:55:55 -06:00
J. Nick Koston
20388ce848 [thermostat] Replace std::map with FixedVector, reduce flash usage 2025-11-12 14:54:23 -06:00
J. Nick Koston
72185ac01f Merge branch 'integration' into memory_api 2025-11-12 14:32:28 -06:00
J. Nick Koston
9e8e5fd8aa Merge branch 'no_batch_events' into integration 2025-11-12 14:32:19 -06:00
J. Nick Koston
8a71a6bfdc Merge remote-tracking branch 'upstream/dev' into no_batch_events 2025-11-12 14:31:26 -06:00
J. Nick Koston
29a50da635 [wifi] Use stack allocation for BSSID formatting in logging (#11859) 2025-11-12 14:27:06 -06:00
J. Nick Koston
5f0fa68d73 [esp32_ble] Use stack allocation for MAC formatting in dump_config (#11860) 2025-11-12 14:26:57 -06:00
J. Nick Koston
2f39b10baa [esp32_ble_tracker] Use initializer_list to eliminate compiler warning and reduce flash usage (#11861) 2025-11-12 14:26:46 -06:00
J. Nick Koston
5a550cc579 [api] Eliminate heap allocations when transmitting Event types (#11773) 2025-11-12 14:26:36 -06:00
J. Nick Koston
4b58cb4ce6 [wifi] Pass ManualIP by const reference to reduce stack usage (#11858) 2025-11-12 14:01:19 -06:00
J. Nick Koston
3872a2fd91 [captive_portal] Warn when enabled without WiFi AP configured (#11856) 2025-11-12 14:01:07 -06:00
dependabot[bot]
5d613ada83 Bump pytest from 9.0.0 to 9.0.1 (#11874)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-12 14:00:50 -06:00
J. Nick Koston
53dacef4a6 Merge branch 'integration' into memory_api 2025-11-12 12:52:01 -06:00
J. Nick Koston
24701d95e5 Merge branch 'wifi_reconnect_fixes' into integration 2025-11-12 12:51:55 -06:00
J. Nick Koston
08127d0225 [wifi] Fix phase transition and error state on reconnection 2025-11-12 12:48:44 -06:00
J. Nick Koston
b28d8a7d22 Merge branch 'integration' into memory_api 2025-11-12 12:18:25 -06:00
J. Nick Koston
e7a5790276 Merge branch 'wifi_ethernet_now_connected_later_logconfig' into integration 2025-11-12 12:18:19 -06:00
J. Nick Koston
97d2f5ee25 [wifi][ethernet] Fix spurious warnings and unclear status after PR #9823 2025-11-12 12:17:47 -06:00
J. Nick Koston
9accb16b4a Merge branch 'integration' into memory_api 2025-11-12 12:02:04 -06:00
J. Nick Koston
8c0c38be21 Merge remote-tracking branch 'upstream/dev' into integration 2025-11-12 12:01:57 -06:00
J. Nick Koston
8037dbe2d3 Merge branch 'color_mode_dangling_ref_fix' into integration 2025-11-12 12:01:53 -06:00
J. Nick Koston
6395439d33 Merge branch 'mqtt_raise_early_invalid_host' into integration 2025-11-12 12:01:50 -06:00
J. Nick Koston
9de80b635a [core] Fix wait_until hanging when used in on_boot automations (#11869) 2025-11-12 17:56:19 +00:00
J. Nick Koston
c299361753 some basic tests 2025-11-12 11:51:56 -06:00
J. Nick Koston
4b3d3c4ca2 some basic tests 2025-11-12 11:51:35 -06:00
J. Nick Koston
8ce4d5cd4f by value 2025-11-12 10:39:18 -06:00
J. Nick Koston
c1fb8dae37 [light] Fix dangling reference in compute_color_mode causing memory corruption 2025-11-12 10:33:19 -06:00
Jonathan Swoboda
748aee584a [esp32] Update the recommended platform to 55.03.31-2 (#11865) 2025-11-12 10:41:22 -05:00
J. Nick Koston
d8454e7c0a Update esphome/mqtt.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-12 09:33:29 -06:00
J. Nick Koston
fb00f75192 [mqtt] Fix crash with empty broker during upload/logs 2025-11-12 09:30:46 -06:00
J. Nick Koston
1b487988c9 [mqtt] Fix crash with empty broker during upload/logs 2025-11-12 09:29:40 -06:00
Jonathan Swoboda
3cbfddcc83 Merge branch 'beta' into dev 2025-11-11 23:27:24 -05:00
Jonathan Swoboda
1d71b6b93e Merge pull request #11862 from esphome/bump-2025.11.0b1
2025.11.0b1
2025-11-11 23:27:12 -05:00
J. Nick Koston
398dba4fc8 [ci] Reduce release time by removing 21 redundant ESP32-S3 IDF tests (#11850) 2025-11-12 16:44:19 +13:00
Jonathan Swoboda
298813d4fa Bump version to 2025.11.0b1 2025-11-11 22:14:22 -05:00
J. Nick Koston
fd308a0687 Merge branch 'integration' into memory_api 2025-11-11 20:42:44 -06:00
J. Nick Koston
016de16181 Merge branch 'ble_mac_format' into integration 2025-11-11 20:42:39 -06:00
J. Nick Koston
0d46bc57d6 [esp32_ble] Use stack allocation for MAC formatting in dump_config 2025-11-11 20:42:14 -06:00
J. Nick Koston
0c506570a6 Merge branch 'integration' into memory_api 2025-11-11 20:38:55 -06:00
J. Nick Koston
c0507b2ad0 Merge branch 'bssid_logging_cleanup' into integration 2025-11-11 20:38:50 -06:00
J. Nick Koston
7cefb8d92c a few more 2025-11-11 20:38:19 -06:00
J. Nick Koston
089eb3bc95 Merge branch 'integration' into memory_api 2025-11-11 20:34:33 -06:00
J. Nick Koston
8de3bcd304 Merge branch 'bssid_logging_cleanup' into integration 2025-11-11 20:34:28 -06:00
J. Nick Koston
32456bee58 Merge remote-tracking branch 'origin/bssid_logging_cleanup' into bssid_logging_cleanup 2025-11-11 20:33:30 -06:00
J. Nick Koston
e104103366 two more 2025-11-11 20:33:20 -06:00
J. Nick Koston
304e0a2c65 Merge branch 'dev' into bssid_logging_cleanup 2025-11-11 20:27:30 -06:00
J. Nick Koston
9c871c39b5 Merge branch 'integration' into memory_api 2025-11-11 20:25:52 -06:00
J. Nick Koston
276ef4ee1d Merge branch 'bssid_logging_cleanup' into integration 2025-11-11 20:25:47 -06:00
J. Nick Koston
dd65e39d16 [wifi] Use stack allocation for BSSID formatting in start_connecting 2025-11-11 20:25:18 -06:00
Jonathan Swoboda
56d141c741 Merge branch 'release' into dev 2025-11-11 20:09:55 -05:00
Jonathan Swoboda
47a7f729dd Merge pull request #11857 from esphome/bump-2025.10.5
2025.10.5
2025-11-11 20:09:41 -05:00
J. Nick Koston
904bc11d5b Merge branch 'integration' into memory_api 2025-11-11 19:02:34 -06:00
J. Nick Koston
a6c8319ade Merge branch 'wifi_pass_manualip_by_const_ref' into integration 2025-11-11 19:01:44 -06:00
J. Nick Koston
7c6f6acf60 [wifi] Pass ManualIP by const reference to reduce stack usage 2025-11-11 19:01:11 -06:00
Jonathan Swoboda
7806eb980f Bump version to 2025.12.0-dev 2025-11-11 19:50:47 -05:00
Jonathan Swoboda
a59888224c Bump version to 2025.10.5 2025-11-11 19:44:37 -05:00
Clyde Stubbs
58ad4759f0 [lvgl] Fix rotation with unusual width (#11680) 2025-11-11 19:44:37 -05:00
Clyde Stubbs
87f79290ba [usb_uart] Fixes for transfer queue allocation (#11548) 2025-11-11 19:44:37 -05:00
Jonathan Swoboda
9326d78439 [core] Don't allow python 3.14 (#11527) 2025-11-11 19:44:37 -05:00
Stuart Parmenter
a93887a790 [const] Add CONF_ROWS (#11249) 2025-11-11 19:44:37 -05:00
Kevin Ahrendt
d7fa131a8a [network, psram, speaker wifi] Use CORE.data to enable high performance networking (#11812) 2025-11-11 18:43:06 -06:00
J. Nick Koston
7f40ef971d Merge branch 'integration' into memory_api 2025-11-11 18:39:11 -06:00
J. Nick Koston
0c127b6998 Merge remote-tracking branch 'origin/captive_portal_without_ap' into integration 2025-11-11 18:39:05 -06:00
J. Nick Koston
037620d75a [captive_portal] Warn when enabled without WiFi AP configured 2025-11-11 18:36:35 -06:00
J. Nick Koston
e0e308c396 Merge branch 'integration' into memory_api 2025-11-11 18:10:25 -06:00
J. Nick Koston
0ab3d3da4e Merge remote-tracking branch 'upstream/dev' into integration 2025-11-11 18:10:09 -06:00
J. Nick Koston
79a4444928 [wifi] Conditionally compile manual_ip to save 24-72 bytes RAM (#11833) 2025-11-11 23:27:08 +00:00
J. Nick Koston
572fae5c7d [wifi] Restore two-attempt BSSID filtering for mesh networks (#11844) 2025-11-12 12:12:53 +13:00
J. Nick Koston
5dafaaced4 [wifi] Fix scan and connection failures after adapter restart (#11851)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-11 23:12:10 +00:00
J. Nick Koston
65a303d48f [wifi] Add min_auth_mode configuration option (#11814) 2025-11-11 16:39:55 -06:00
J. Nick Koston
00c71b7236 [wifi] Fix all-hidden networks duplicate attempts and scan skipping (#11848)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-11 22:33:37 +00:00
J. Nick Koston
0ab0563b52 Merge branch 'integration' into memory_api 2025-11-11 16:23:09 -06:00
J. Nick Koston
ccf5591d14 Merge branch 'fix_scan_failing_after_restart' into integration 2025-11-11 16:23:01 -06:00
J. Nick Koston
1c7c559b69 touch ups 2025-11-11 16:22:24 -06:00
J. Nick Koston
6dbd961b3e Merge branch 'integration' into memory_api 2025-11-11 16:20:02 -06:00
J. Nick Koston
088964de4d Merge branch 'fix_scan_failing_after_restart' into integration 2025-11-11 16:19:57 -06:00
J. Nick Koston
f0a9ee871b keep 2025-11-11 16:19:47 -06:00
J. Nick Koston
f3a3f2e4f7 Merge branch 'integration' into memory_api 2025-11-11 16:15:31 -06:00
J. Nick Koston
3280ce936a Merge branch 'fix_scan_failing_after_restart' into integration 2025-11-11 16:15:22 -06:00
J. Nick Koston
efe6e58404 clear failure on restart 2025-11-11 16:15:12 -06:00
J. Nick Koston
ef04903a7a [wifi] Change priority type from float to int8_t (#11830) 2025-11-12 11:10:17 +13:00
J. Nick Koston
a2a05ba23a Merge branch 'integration' into memory_api 2025-11-11 16:09:58 -06:00
J. Nick Koston
08ea53633f Merge branch 'fix_scan_failing_after_restart' into integration 2025-11-11 16:09:53 -06:00
J. Nick Koston
d54179fd12 Merge remote-tracking branch 'origin/fix_scan_failing_after_restart' into fix_scan_failing_after_restart 2025-11-11 16:09:42 -06:00
J. Nick Koston
fb5b37c17a avoid breaking change 2025-11-11 16:09:33 -06:00
J. Nick Koston
9c6d9badf2 Merge branch 'retry_hidden_no_stuck_last_networks_visible' into fix_scan_failing_after_restart 2025-11-11 16:05:01 -06:00
J. Nick Koston
55bdbf60c9 Merge branch 'dev' into retry_hidden_no_stuck_last_networks_visible 2025-11-11 16:04:55 -06:00
J. Nick Koston
a2ec7f622c [wifi] Fix infinite retry loop when no hidden networks and captive portal active (#11831) 2025-11-11 16:04:37 -06:00
J. Nick Koston
c3111b1dd3 Merge branch 'integration' into memory_api 2025-11-11 16:02:24 -06:00
J. Nick Koston
530fc8f030 Merge branch 'fix_scan_failing_after_restart' into integration 2025-11-11 16:02:19 -06:00
J. Nick Koston
a8f253eecf tweaks on failure paths 2025-11-11 16:02:01 -06:00
J. Nick Koston
e85eeb3d99 Merge branch 'integration' into memory_api 2025-11-11 15:58:13 -06:00
J. Nick Koston
64c79f6363 Merge branch 'fix_scan_failing_after_restart' into integration 2025-11-11 15:58:06 -06:00
J. Nick Koston
7b60a8a21a cleanup conflicting logic 2025-11-11 15:55:09 -06:00
J. Nick Koston
42fa0b61a7 cleanup conflicting logic 2025-11-11 15:52:51 -06:00
tomaszduda23
2f91e7bd47 [nrf52] fix boot loop (#11854) 2025-11-11 15:33:53 -06:00
J. Nick Koston
3aed5f5eae Merge branch 'integration' into memory_api 2025-11-11 15:22:11 -06:00
J. Nick Koston
ec79eb3065 Merge branch 'fix_scan_failing_after_restart' into integration 2025-11-11 15:22:05 -06:00
J. Nick Koston
e589542bd3 make message more sane 2025-11-11 15:21:51 -06:00
J. Nick Koston
c804467277 Merge branch 'integration' into memory_api 2025-11-11 15:16:05 -06:00
J. Nick Koston
8ce7f9dfe8 Merge branch 'fix_scan_failing_after_restart' into integration 2025-11-11 15:16:00 -06:00
J. Nick Koston
c3967df6ce tweak 2025-11-11 15:15:41 -06:00
J. Nick Koston
ecb3eecf88 Merge branch 'integration' into memory_api 2025-11-11 15:00:36 -06:00
J. Nick Koston
f0d1cde35c Merge branch 'fix_scan_failing_after_restart' into integration 2025-11-11 15:00:31 -06:00
J. Nick Koston
191cf1b03c preen 2025-11-11 14:59:12 -06:00
tomaszduda23
80a7c6d3c3 [nrf52,debug] add partition dump (#11839)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-11-11 14:52:41 -06:00
J. Nick Koston
35ecaff089 Merge branch 'integration' into memory_api 2025-11-11 14:24:46 -06:00
J. Nick Koston
374d039f60 Merge branch 'fix_scan_failing_after_restart' into integration 2025-11-11 14:24:40 -06:00
J. Nick Koston
e19bdf63a5 Merge remote-tracking branch 'origin/retry_hidden_no_stuck_last_networks_visible' into fix_scan_failing_after_restart 2025-11-11 14:22:56 -06:00
J. Nick Koston
1bde521380 cleanups 2025-11-11 14:05:44 -06:00
J. Nick Koston
db9af4a862 cleanup 2025-11-11 14:00:39 -06:00
J. Nick Koston
d092e59a79 Merge branch 'dev' into retry_hidden_no_stuck_last_networks_visible 2025-11-11 13:56:26 -06:00
J. Nick Koston
5a77f63103 Merge remote-tracking branch 'upstream/dev' into fix_scan_failing_after_restart 2025-11-11 13:55:58 -06:00
J. Nick Koston
f6ac916bb2 cleanups 2025-11-11 13:55:43 -06:00
CzBiX
7a92565a0c [lvgl] Fix compile when using transform_zoom (#11845) 2025-11-12 06:24:52 +11:00
J. Nick Koston
93f8e40111 Fix scan failing after restart 2025-11-11 13:13:28 -06:00
J. Nick Koston
99bb6ead7e Merge branch 'dev' into no_batch_events 2025-11-09 22:04:58 -06:00
J. Nick Koston
d171406dff Merge branch 'dev' into no_batch_events 2025-11-09 17:35:33 -06:00
J. Nick Koston
65fd784fa7 tidy 2025-11-08 10:39:09 -06:00
J. Nick Koston
b9f208b63a [api][event] Send events immediately to prevent loss during rapid triggers 2025-11-08 10:16:18 -06:00
kbx81
ddef1f9ecd fix 2025-10-21 03:55:22 -05:00
kbx81
27714e052c fix 2025-10-21 03:30:41 -05:00
kbx81
17bba92111 Merge remote-tracking branch 'upstream/dev' into 20250915-wifi-info-use-callbacks 2025-10-21 02:32:41 -05:00
kbx81
b58a1bfc6c Merge remote-tracking branch 'upstream/dev' into 20250915-wifi-info-use-callbacks 2025-09-22 15:00:31 -05:00
kbx81
24649cd55c Merge remote-tracking branch 'upstream/dev' into 20250915-wifi-info-use-callbacks 2025-09-21 23:32:09 -05:00
kbx81
1b6f3fd0ec Merge remote-tracking branch 'upstream/dev' into 20250915-wifi-info-use-callbacks 2025-09-19 22:11:23 -05:00
Keith Burzinski
5e5f766697 Merge branch 'dev' into 20250915-wifi-info-use-callbacks 2025-09-18 17:54:56 -05:00
Keith Burzinski
946eccb2ee Merge branch 'dev' into 20250915-wifi-info-use-callbacks 2025-09-17 02:21:15 -05:00
kbx81
38719aaef8 tidy 2025-09-16 17:31:30 -05:00
kbx81
eae9335894 [wifi_info] Use callbacks instead of polling 2025-09-15 18:35:25 -05:00
1680 changed files with 60363 additions and 21441 deletions

View File

@@ -276,12 +276,12 @@ This document provides essential context for AI models interacting with this pro
## 7. Specific Instructions for AI Collaboration
* **Contribution Workflow (Pull Request Process):**
1. **Fork & Branch:** Create a new branch in your fork.
1. **Fork & Branch:** Create a new branch based on the `dev` branch (always use `git checkout -b <branch-name> dev` to ensure you're branching from `dev`, not the currently checked out branch).
2. **Make Changes:** Adhere to all coding conventions and patterns.
3. **Test:** Create component tests for all supported platforms and run the full test suite locally.
4. **Lint:** Run `pre-commit` to ensure code is compliant.
5. **Commit:** Commit your changes. There is no strict format for commit messages.
6. **Pull Request:** Submit a PR against the `dev` branch. The Pull Request title should have a prefix of the component being worked on (e.g., `[display] Fix bug`, `[abc123] Add new component`). Update documentation, examples, and add `CODEOWNERS` entries as needed. Pull requests should always be made with the PULL_REQUEST_TEMPLATE.md template filled out correctly.
6. **Pull Request:** Submit a PR against the `dev` branch. The Pull Request title should have a prefix of the component being worked on (e.g., `[display] Fix bug`, `[abc123] Add new component`). Update documentation, examples, and add `CODEOWNERS` entries as needed. Pull requests should always be made using the `.github/PULL_REQUEST_TEMPLATE.md` template - fill out all sections completely without removing any parts of the template.
* **Documentation Contributions:**
* Documentation is hosted in the separate `esphome/esphome-docs` repository.
@@ -293,6 +293,12 @@ This document provides essential context for AI models interacting with this pro
* **Configuration Design:** Aim for simplicity with sensible defaults, while allowing for advanced customization.
* **Embedded Systems Optimization:** ESPHome targets resource-constrained microcontrollers. Be mindful of flash size and RAM usage.
**Why Heap Allocation Matters:**
ESP devices run for months with small heaps shared between Wi-Fi, BLE, LWIP, and application code. Over time, repeated allocations of different sizes fragment the heap. Failures happen when the largest contiguous block shrinks, even if total free heap is still large. We have seen field crashes caused by this.
**Heap allocation after `setup()` should be avoided unless absolutely unavoidable.** Every allocation/deallocation cycle contributes to fragmentation. ESPHome treats runtime heap allocation as a long-term reliability bug, not a performance issue. Helpers that hide allocation (`std::string`, `std::to_string`, string-returning helpers) are being deprecated and replaced with buffer and view based APIs.
**STL Container Guidelines:**
ESPHome runs on embedded systems with limited resources. Choose containers carefully:
@@ -322,15 +328,15 @@ This document provides essential context for AI models interacting with this pro
std::array<uint8_t, 256> buffer;
```
2. **Compile-time-known fixed sizes with vector-like API:** Use `StaticVector` from `esphome/core/helpers.h` for fixed-size stack allocation with `push_back()` interface.
2. **Compile-time-known fixed sizes with vector-like API:** Use `StaticVector` from `esphome/core/helpers.h` for compile-time fixed size with `push_back()` interface (no dynamic allocation).
```cpp
// Bad - generates STL realloc code (_M_realloc_insert)
std::vector<ServiceRecord> services;
services.reserve(5); // Still includes reallocation machinery
// Good - compile-time fixed size, stack allocated, no reallocation machinery
StaticVector<ServiceRecord, MAX_SERVICES> services; // Allocates all MAX_SERVICES on stack
services.push_back(record1); // Tracks count but all slots allocated
// Good - compile-time fixed size, no dynamic allocation
StaticVector<ServiceRecord, MAX_SERVICES> services;
services.push_back(record1);
```
Use `cg.add_define("MAX_SERVICES", count)` to set the size from Python configuration.
Like `std::array` but with vector-like API (`push_back()`, `size()`) and no STL reallocation code.
@@ -372,22 +378,21 @@ This document provides essential context for AI models interacting with this pro
```
Linear search on small datasets (1-16 elements) is often faster than hashing/tree overhead, but this depends on lookup frequency and access patterns. For frequent lookups in hot code paths, the O(1) vs O(n) complexity difference may still matter even for small datasets. `std::vector` with simple structs is usually fine—it's the heavy containers (`map`, `set`, `unordered_map`) that should be avoided for small datasets unless profiling shows otherwise.
5. **Detection:** Look for these patterns in compiler output:
5. **Avoid `std::deque`:** It allocates in 512-byte blocks regardless of element size, guaranteeing at least 512 bytes of RAM usage immediately. This is a major source of crashes on memory-constrained devices.
6. **Detection:** Look for these patterns in compiler output:
- Large code sections with STL symbols (vector, map, set)
- `alloc`, `realloc`, `dealloc` in symbol names
- `_M_realloc_insert`, `_M_default_append` (vector reallocation)
- Red-black tree code (`rb_tree`, `_Rb_tree`)
- Hash table infrastructure (`unordered_map`, `hash`)
**When to optimize:**
**Prioritize optimization effort for:**
- Core components (API, network, logger)
- Widely-used components (mdns, wifi, ble)
- Components causing flash size complaints
**When not to optimize:**
- Single-use niche components
- Code where readability matters more than bytes
- Already using appropriate containers
Note: Avoiding heap allocation after `setup()` is always required regardless of component type. The prioritization above is about the effort spent on container optimization (e.g., migrating from `std::vector` to `StaticVector`).
* **State Management:** Use `CORE.data` for component state that needs to persist during configuration generation. Avoid module-level mutable globals.
@@ -402,35 +407,45 @@ This document provides essential context for AI models interacting with this pro
_use_feature = True
```
**Good Pattern (CORE.data with Helpers):**
**Bad Pattern (Flat Keys):**
```python
# Don't do this - keys should be namespaced under component domain
MY_FEATURE_KEY = "my_component_feature"
CORE.data[MY_FEATURE_KEY] = True
```
**Good Pattern (dataclass):**
```python
from dataclasses import dataclass, field
from esphome.core import CORE
# Keys for CORE.data storage
COMPONENT_STATE_KEY = "my_component_state"
USE_FEATURE_KEY = "my_component_use_feature"
DOMAIN = "my_component"
def _get_component_state() -> list:
"""Get component state from CORE.data."""
return CORE.data.setdefault(COMPONENT_STATE_KEY, [])
@dataclass
class MyComponentData:
feature_enabled: bool = False
item_count: int = 0
items: list[str] = field(default_factory=list)
def _get_use_feature() -> bool | None:
"""Get feature flag from CORE.data."""
return CORE.data.get(USE_FEATURE_KEY)
def _get_data() -> MyComponentData:
if DOMAIN not in CORE.data:
CORE.data[DOMAIN] = MyComponentData()
return CORE.data[DOMAIN]
def _set_use_feature(value: bool) -> None:
"""Set feature flag in CORE.data."""
CORE.data[USE_FEATURE_KEY] = value
def request_feature() -> None:
_get_data().feature_enabled = True
def enable_feature():
_set_use_feature(True)
def add_item(item: str) -> None:
_get_data().items.append(item)
```
If you need a real-world example, search for components that use `@dataclass` with `CORE.data` in the codebase. Note: Some components may use `TypedDict` for dictionary-based storage; both patterns are acceptable depending on your needs.
**Why this matters:**
- Module-level globals persist between compilation runs if the dashboard doesn't fork/exec
- `CORE.data` automatically clears between runs
- Typed helper functions provide better IDE support and maintainability
- Encapsulation makes state management explicit and testable
- Namespacing under `DOMAIN` prevents key collisions between components
- `@dataclass` provides type safety and cleaner attribute access
* **Security:** Be mindful of security when making changes to the API, web server, or any other network-related code. Do not hardcode secrets or keys.

View File

@@ -1 +1 @@
3d46b63015d761c85ca9cb77ab79a389509e5776701fb22aed16e7b79d432c0c
d272a88e8ca28ae9340a9a03295a566432a52cb696501908f57764475bf7ca65

View File

@@ -7,6 +7,7 @@
- [ ] Bugfix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Developer breaking change (an API change that could break external components)
- [ ] Code quality improvements to existing code or addition of tests
- [ ] Other
@@ -26,6 +27,7 @@
- [ ] RP2040
- [ ] BK72xx
- [ ] RTL87xx
- [ ] LN882x
- [ ] nRF52840
## Example entry for `config.yaml`:

View File

@@ -17,12 +17,12 @@ runs:
steps:
- name: Set up Python ${{ inputs.python-version }}
id: python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: ${{ inputs.python-version }}
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: venv
# yamllint disable-line rule:line-length

View File

@@ -22,11 +22,11 @@ jobs:
if: github.event.action != 'labeled' || github.event.sender.type != 'Bot'
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2
with:
app-id: ${{ secrets.ESPHOME_GITHUB_APP_ID }}
private-key: ${{ secrets.ESPHOME_GITHUB_APP_PRIVATE_KEY }}
@@ -68,6 +68,7 @@ jobs:
'bugfix',
'new-feature',
'breaking-change',
'developer-breaking-change',
'code-quality'
];
@@ -367,6 +368,7 @@ jobs:
{ pattern: /- \[x\] Bugfix \(non-breaking change which fixes an issue\)/i, label: 'bugfix' },
{ pattern: /- \[x\] New feature \(non-breaking change which adds functionality\)/i, label: 'new-feature' },
{ pattern: /- \[x\] Breaking change \(fix or feature that would cause existing functionality to not work as expected\)/i, label: 'breaking-change' },
{ pattern: /- \[x\] Developer breaking change \(an API change that could break external components\)/i, label: 'developer-breaking-change' },
{ pattern: /- \[x\] Code quality improvements to existing code or addition of tests/i, label: 'code-quality' }
];

View File

@@ -21,9 +21,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.11"
@@ -62,7 +62,7 @@ jobs:
run: git diff
- if: failure()
name: Archive artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: generated-proto-files
path: |

View File

@@ -21,10 +21,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.11"

View File

@@ -43,13 +43,13 @@ jobs:
- "docker"
# - "lint"
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.11"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Set TAG
run: |

View File

@@ -49,7 +49,7 @@ jobs:
- name: Check out code from base repository
if: steps.pr.outputs.skip != 'true'
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
# Always check out from the base repository (esphome/esphome), never from forks
# Use the PR's target branch to ensure we run trusted code from the main repo

View File

@@ -36,18 +36,18 @@ jobs:
cache-key: ${{ steps.cache-key.outputs.key }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Generate cache-key
id: cache-key
run: echo key="${{ hashFiles('requirements.txt', 'requirements_test.txt', '.pre-commit-config.yaml') }}" >> $GITHUB_OUTPUT
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: venv
# yamllint disable-line rule:line-length
@@ -70,7 +70,7 @@ jobs:
if: needs.determine-jobs.outputs.python-linters == 'true'
steps:
- name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Restore Python
uses: ./.github/actions/restore-python
with:
@@ -91,7 +91,7 @@ jobs:
- common
steps:
- name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Restore Python
uses: ./.github/actions/restore-python
with:
@@ -132,7 +132,7 @@ jobs:
- common
steps:
- name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Restore Python
id: restore-python
uses: ./.github/actions/restore-python
@@ -152,12 +152,12 @@ jobs:
. venv/bin/activate
pytest -vv --cov-report=xml --tb=native -n auto tests --ignore=tests/integration/
- name: Upload coverage to Codecov
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
with:
token: ${{ secrets.CODECOV_TOKEN }}
- name: Save Python virtual environment cache
if: github.ref == 'refs/heads/dev'
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/save@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: venv
key: ${{ runner.os }}-${{ steps.restore-python.outputs.python-version }}-venv-${{ needs.common.outputs.cache-key }}
@@ -183,7 +183,7 @@ jobs:
component-test-batches: ${{ steps.determine.outputs.component-test-batches }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
# Fetch enough history to find the merge base
fetch-depth: 2
@@ -193,7 +193,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
cache-key: ${{ needs.common.outputs.cache-key }}
- name: Restore components graph cache
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: .temp/components_graph.json
key: components-graph-${{ hashFiles('esphome/components/**/*.py') }}
@@ -223,7 +223,7 @@ jobs:
echo "component-test-batches=$(echo "$output" | jq -c '.component_test_batches')" >> $GITHUB_OUTPUT
- name: Save components graph cache
if: github.ref == 'refs/heads/dev'
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/save@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: .temp/components_graph.json
key: components-graph-${{ hashFiles('esphome/components/**/*.py') }}
@@ -237,15 +237,15 @@ jobs:
if: needs.determine-jobs.outputs.integration-tests == 'true'
steps:
- name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Python 3.13
id: python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.13"
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: venv
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv-${{ needs.common.outputs.cache-key }}
@@ -273,7 +273,7 @@ jobs:
if: github.event_name == 'pull_request' && (needs.determine-jobs.outputs.cpp-unit-tests-run-all == 'true' || needs.determine-jobs.outputs.cpp-unit-tests-components != '[]')
steps:
- name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Restore Python
uses: ./.github/actions/restore-python
@@ -321,7 +321,7 @@ jobs:
steps:
- name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
# Need history for HEAD~1 to work for checking changed files
fetch-depth: 2
@@ -334,14 +334,14 @@ jobs:
- name: Cache platformio
if: github.ref == 'refs/heads/dev'
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: ~/.platformio
key: platformio-${{ matrix.pio_cache_key }}-${{ hashFiles('platformio.ini') }}
- name: Cache platformio
if: github.ref != 'refs/heads/dev'
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: ~/.platformio
key: platformio-${{ matrix.pio_cache_key }}-${{ hashFiles('platformio.ini') }}
@@ -400,7 +400,7 @@ jobs:
GH_TOKEN: ${{ github.token }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
# Need history for HEAD~1 to work for checking changed files
fetch-depth: 2
@@ -413,14 +413,14 @@ jobs:
- name: Cache platformio
if: github.ref == 'refs/heads/dev'
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: ~/.platformio
key: platformio-tidyesp32-${{ hashFiles('platformio.ini') }}
- name: Cache platformio
if: github.ref != 'refs/heads/dev'
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: ~/.platformio
key: platformio-tidyesp32-${{ hashFiles('platformio.ini') }}
@@ -489,7 +489,7 @@ jobs:
steps:
- name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
# Need history for HEAD~1 to work for checking changed files
fetch-depth: 2
@@ -502,14 +502,14 @@ jobs:
- name: Cache platformio
if: github.ref == 'refs/heads/dev'
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: ~/.platformio
key: platformio-tidyesp32-${{ hashFiles('platformio.ini') }}
- name: Cache platformio
if: github.ref != 'refs/heads/dev'
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: ~/.platformio
key: platformio-tidyesp32-${{ hashFiles('platformio.ini') }}
@@ -577,7 +577,7 @@ jobs:
version: 1.0
- name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Restore Python
uses: ./.github/actions/restore-python
with:
@@ -662,13 +662,13 @@ jobs:
if: github.event_name == 'pull_request' && !startsWith(github.base_ref, 'beta') && !startsWith(github.base_ref, 'release')
steps:
- name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Restore Python
uses: ./.github/actions/restore-python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
cache-key: ${{ needs.common.outputs.cache-key }}
- uses: esphome/action@43cd1109c09c544d97196f7730ee5b2e0cc6d81e # v3.0.1 fork with pinned actions/cache
- uses: esphome/pre-commit-action@43cd1109c09c544d97196f7730ee5b2e0cc6d81e # v3.0.1 fork with pinned actions/cache
env:
SKIP: pylint,clang-tidy-hash
- uses: pre-commit-ci/lite-action@5d6cc0eb514c891a40562a58a8e71576c5c7fb43 # v1.1.0
@@ -688,7 +688,7 @@ jobs:
skip: ${{ steps.check-script.outputs.skip }}
steps:
- name: Check out target branch
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ github.base_ref }}
@@ -735,7 +735,7 @@ jobs:
- name: Restore cached memory analysis
id: cache-memory-analysis
if: steps.check-script.outputs.skip != 'true'
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: memory-analysis-target.json
key: ${{ steps.cache-key.outputs.cache-key }}
@@ -759,7 +759,7 @@ jobs:
- name: Cache platformio
if: steps.check-script.outputs.skip != 'true' && steps.cache-memory-analysis.outputs.cache-hit != 'true'
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: ~/.platformio
key: platformio-memory-${{ fromJSON(needs.determine-jobs.outputs.memory_impact).platform }}-${{ hashFiles('platformio.ini') }}
@@ -800,7 +800,7 @@ jobs:
- name: Save memory analysis to cache
if: steps.check-script.outputs.skip != 'true' && steps.cache-memory-analysis.outputs.cache-hit != 'true' && steps.build.outcome == 'success'
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/save@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: memory-analysis-target.json
key: ${{ steps.cache-key.outputs.cache-key }}
@@ -821,7 +821,7 @@ jobs:
fi
- name: Upload memory analysis JSON
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: memory-analysis-target
path: memory-analysis-target.json
@@ -840,14 +840,14 @@ jobs:
flash_usage: ${{ steps.extract.outputs.flash_usage }}
steps:
- name: Check out PR branch
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Restore Python
uses: ./.github/actions/restore-python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
cache-key: ${{ needs.common.outputs.cache-key }}
- name: Cache platformio
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: ~/.platformio
key: platformio-memory-${{ fromJSON(needs.determine-jobs.outputs.memory_impact).platform }}-${{ hashFiles('platformio.ini') }}
@@ -885,7 +885,7 @@ jobs:
--platform "$platform"
- name: Upload memory analysis JSON
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: memory-analysis-pr
path: memory-analysis-pr.json
@@ -908,20 +908,20 @@ jobs:
GH_TOKEN: ${{ github.token }}
steps:
- name: Check out code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Restore Python
uses: ./.github/actions/restore-python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
cache-key: ${{ needs.common.outputs.cache-key }}
- name: Download target analysis JSON
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: memory-analysis-target
path: ./memory-analysis
continue-on-error: true
- name: Download PR analysis JSON
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: memory-analysis-pr
path: ./memory-analysis
@@ -959,13 +959,13 @@ jobs:
- memory-impact-comment
if: always()
steps:
- name: Success
if: ${{ !(contains(needs.*.result, 'failure')) }}
run: exit 0
- name: Failure
if: ${{ contains(needs.*.result, 'failure') }}
- name: Check job results
env:
JSON_DOC: ${{ toJSON(needs) }}
NEEDS_JSON: ${{ toJSON(needs) }}
run: |
echo $JSON_DOC | jq
exit 1
# memory-impact-target-branch is allowed to fail without blocking CI.
# This job builds the target branch (dev/beta/release) which may fail because:
# 1. The target branch has a build issue independent of this PR
# 2. This PR fixes a build issue on the target branch
# In either case, we only care that the PR branch builds successfully.
echo "$NEEDS_JSON" | jq -e 'del(.["memory-impact-target-branch"]) | all(.result != "failure")'

View File

@@ -54,11 +54,11 @@ jobs:
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
@@ -86,6 +86,6 @@ jobs:
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
with:
category: "/language:${{matrix.language}}"

View File

@@ -20,7 +20,7 @@ jobs:
branch_build: ${{ steps.tag.outputs.branch_build }}
deploy_env: ${{ steps.tag.outputs.deploy_env }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Get tag
id: tag
# yamllint disable rule:line-length
@@ -60,9 +60,9 @@ jobs:
contents: read
id-token: write
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.x"
- name: Build
@@ -92,14 +92,14 @@ jobs:
os: "ubuntu-24.04-arm"
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.11"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Log in to docker hub
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
@@ -138,7 +138,7 @@ jobs:
# version: ${{ needs.init.outputs.tag }}
- name: Upload digests
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: digests-${{ matrix.platform.arch }}
path: /tmp/digests
@@ -168,17 +168,17 @@ jobs:
- ghcr
- dockerhub
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Download digests
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
pattern: digests-*
path: /tmp/digests
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Log in to docker hub
if: matrix.registry == 'dockerhub'
@@ -219,10 +219,19 @@ jobs:
- init
- deploy-manifest
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
with:
app-id: ${{ secrets.ESPHOME_GITHUB_APP_ID }}
private-key: ${{ secrets.ESPHOME_GITHUB_APP_PRIVATE_KEY }}
owner: esphome
repositories: home-assistant-addon
- name: Trigger Workflow
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
github-token: ${{ secrets.DEPLOY_HA_ADDON_REPO_TOKEN }}
github-token: ${{ steps.generate-token.outputs.token }}
script: |
let description = "ESPHome";
if (context.eventName == "release") {
@@ -245,10 +254,19 @@ jobs:
needs: [init]
environment: ${{ needs.init.outputs.deploy_env }}
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
with:
app-id: ${{ secrets.ESPHOME_GITHUB_APP_ID }}
private-key: ${{ secrets.ESPHOME_GITHUB_APP_PRIVATE_KEY }}
owner: esphome
repositories: esphome-schema
- name: Trigger Workflow
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
github-token: ${{ secrets.DEPLOY_ESPHOME_SCHEMA_REPO_TOKEN }}
github-token: ${{ steps.generate-token.outputs.token }}
script: |
github.rest.actions.createWorkflowDispatch({
owner: "esphome",
@@ -259,3 +277,34 @@ jobs:
version: "${{ needs.init.outputs.tag }}",
}
})
version-notifier:
if: github.repository == 'esphome/esphome' && needs.init.outputs.branch_build == 'false'
runs-on: ubuntu-latest
needs:
- init
- deploy-manifest
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
with:
app-id: ${{ secrets.ESPHOME_GITHUB_APP_ID }}
private-key: ${{ secrets.ESPHOME_GITHUB_APP_PRIVATE_KEY }}
owner: esphome
repositories: version-notifier
- name: Trigger Workflow
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
github.rest.actions.createWorkflowDispatch({
owner: "esphome",
repo: "version-notifier",
workflow_id: "notify.yml",
ref: "main",
inputs: {
version: "${{ needs.init.outputs.tag }}",
}
})

View File

@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Stale
uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1
with:
debug-only: ${{ github.ref != 'refs/heads/dev' }} # Dry-run when not run on dev branch
remove-stale-when-updated: true

View File

@@ -13,16 +13,16 @@ jobs:
if: github.repository == 'esphome/esphome'
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Checkout Home Assistant
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
repository: home-assistant/core
path: lib/home-assistant
- name: Setup Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: 3.13
@@ -41,7 +41,7 @@ jobs:
python script/run-in-env.py pre-commit run --all-files
- name: Commit changes
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
with:
commit-message: "Synchronise Device Classes from Home Assistant"
committer: esphomebot <esphome@openhomefoundation.org>

4
.gitignore vendored
View File

@@ -91,6 +91,10 @@ venv-*/
# mypy
.mypy_cache/
# nix
/default.nix
/shell.nix
.pioenvs
.piolibdeps
.pio

View File

@@ -11,7 +11,7 @@ ci:
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.14.4
rev: v0.14.11
hooks:
# Run the linter.
- id: ruff

View File

@@ -21,6 +21,7 @@ esphome/components/adc128s102/* @DeerMaximum
esphome/components/addressable_light/* @justfalter
esphome/components/ade7880/* @kpfleming
esphome/components/ade7953/* @angelnu
esphome/components/ade7953_base/* @angelnu
esphome/components/ade7953_i2c/* @angelnu
esphome/components/ade7953_spi/* @angelnu
esphome/components/ads1118/* @solomondg1
@@ -41,6 +42,7 @@ esphome/components/animation/* @syndlex
esphome/components/anova/* @buxtronix
esphome/components/apds9306/* @aodrenah
esphome/components/api/* @esphome/core
esphome/components/aqi/* @freekode @jasstrong @ximex
esphome/components/as5600/* @ammmze
esphome/components/as5600/sensor/* @ammmze
esphome/components/as7341/* @mrgnr
@@ -72,6 +74,7 @@ esphome/components/bl0942/* @dbuezas @dwmw2
esphome/components/ble_client/* @buxtronix @clydebarrow
esphome/components/ble_nus/* @tomaszduda23
esphome/components/bluetooth_proxy/* @bdraco @jesserockz
esphome/components/bm8563/* @abmantis
esphome/components/bme280_base/* @esphome/core
esphome/components/bme280_spi/* @apbodrov
esphome/components/bme680_bsec/* @trvrnrth
@@ -88,6 +91,7 @@ esphome/components/bmp3xx_spi/* @latonita
esphome/components/bmp581/* @kahrendt
esphome/components/bp1658cj/* @Cossid
esphome/components/bp5758d/* @Cossid
esphome/components/bthome_mithermometer/* @nagyrobi
esphome/components/button/* @esphome/core
esphome/components/bytebuffer/* @clydebarrow
esphome/components/camera/* @bdraco @DT-art1
@@ -95,6 +99,7 @@ esphome/components/camera_encoder/* @DT-art1
esphome/components/canbus/* @danielschramm @mvturnho
esphome/components/cap1188/* @mreditor97
esphome/components/captive_portal/* @esphome/core
esphome/components/cc1101/* @gabest11 @lygris
esphome/components/ccs811/* @habbie
esphome/components/cd74hc4067/* @asoehlke
esphome/components/ch422g/* @clydebarrow @jesterret
@@ -130,7 +135,7 @@ esphome/components/display_menu_base/* @numo68
esphome/components/dps310/* @kbx81
esphome/components/ds1307/* @badbadc0ffee
esphome/components/ds2484/* @mrk-its
esphome/components/dsmr/* @glmnet @zuidwijk
esphome/components/dsmr/* @glmnet @PolarGoose @zuidwijk
esphome/components/duty_time/* @dudanov
esphome/components/ee895/* @Stock-M
esphome/components/ektf2232/touchscreen/* @jesserockz
@@ -188,6 +193,7 @@ esphome/components/gps/* @coogle @ximex
esphome/components/graph/* @synco
esphome/components/graphical_display_menu/* @MrMDavidson
esphome/components/gree/* @orestismers
esphome/components/gree/switch/* @nagyrobi
esphome/components/grove_gas_mc_v2/* @YorkshireIoT
esphome/components/grove_tb6612fng/* @max246
esphome/components/growatt_solar/* @leeuwte
@@ -202,13 +208,16 @@ esphome/components/havells_solar/* @sourabhjaiswal
esphome/components/hbridge/fan/* @WeekendWarrior
esphome/components/hbridge/light/* @DotNetDann
esphome/components/hbridge/switch/* @dwmw2
esphome/components/hc8/* @omartijn
esphome/components/hdc2010/* @optimusprimespace @ssieb
esphome/components/he60r/* @clydebarrow
esphome/components/heatpumpir/* @rob-deutsch
esphome/components/hitachi_ac424/* @sourabhjaiswal
esphome/components/hlk_fm22x/* @OnFreund
esphome/components/hlw8032/* @rici4kubicek
esphome/components/hm3301/* @freekode
esphome/components/hmac_md5/* @dwmw2
esphome/components/hmac_sha256/* @dwmw2
esphome/components/homeassistant/* @esphome/core @OttoWinter
esphome/components/homeassistant/number/* @landonr
esphome/components/homeassistant/switch/* @Links2004
@@ -222,6 +231,7 @@ esphome/components/hte501/* @Stock-M
esphome/components/http_request/ota/* @oarcher
esphome/components/http_request/update/* @jesserockz
esphome/components/htu31d/* @betterengineering
esphome/components/hub75/* @stuartparmenter
esphome/components/hydreon_rgxx/* @functionpointer
esphome/components/hyt271/* @Philippe12
esphome/components/i2c/* @esphome/core
@@ -239,11 +249,13 @@ esphome/components/ina260/* @mreditor97
esphome/components/ina2xx_base/* @latonita
esphome/components/ina2xx_i2c/* @latonita
esphome/components/ina2xx_spi/* @latonita
esphome/components/infrared/* @kbx81
esphome/components/inkbird_ibsth1_mini/* @fkirill
esphome/components/inkplate/* @jesserockz @JosipKuci
esphome/components/integration/* @OttoWinter
esphome/components/internal_temperature/* @Mat931
esphome/components/interval/* @esphome/core
esphome/components/ir_rf_proxy/* @kbx81
esphome/components/jsn_sr04t/* @Mafus1
esphome/components/json/* @esphome/core
esphome/components/kamstrup_kmp/* @cfeenstra1024
@@ -301,7 +313,7 @@ esphome/components/md5/* @esphome/core
esphome/components/mdns/* @esphome/core
esphome/components/media_player/* @jesserockz
esphome/components/micro_wake_word/* @jesserockz @kahrendt
esphome/components/micronova/* @jorre05
esphome/components/micronova/* @edenhaus @jorre05
esphome/components/microphone/* @jesserockz @kahrendt
esphome/components/mics_4514/* @jesserockz
esphome/components/midea/* @dudanov
@@ -385,6 +397,7 @@ esphome/components/radon_eye_rd200/* @jeffeb3
esphome/components/rc522/* @glmnet
esphome/components/rc522_i2c/* @glmnet
esphome/components/rc522_spi/* @glmnet
esphome/components/rd03d/* @jasstrong
esphome/components/resampler/speaker/* @kahrendt
esphome/components/restart/* @esphome/core
esphome/components/rf_bridge/* @jesserockz
@@ -460,6 +473,7 @@ esphome/components/st7735/* @SenexCrenshaw
esphome/components/st7789v/* @kbx81
esphome/components/st7920/* @marsjan155
esphome/components/statsd/* @Links2004
esphome/components/stts22h/* @B48D81EFCC
esphome/components/substitutions/* @esphome/core
esphome/components/sun/* @OttoWinter
esphome/components/sun_gtil2/* @Mat931
@@ -481,6 +495,7 @@ esphome/components/template/datetime/* @rfdarter
esphome/components/template/event/* @nohat
esphome/components/template/fan/* @ssieb
esphome/components/text/* @mauritskorse
esphome/components/thermopro_ble/* @sittner
esphome/components/thermostat/* @kbx81
esphome/components/time/* @esphome/core
esphome/components/tinyusb/* @kbx81
@@ -508,6 +523,7 @@ esphome/components/tuya/switch/* @jesserockz
esphome/components/tuya/text_sensor/* @dentra
esphome/components/uart/* @esphome/core
esphome/components/uart/button/* @ssieb
esphome/components/uart/event/* @eoasmxd
esphome/components/uart/packet_transport/* @clydebarrow
esphome/components/udp/* @clydebarrow
esphome/components/ufire_ec/* @pvizeli
@@ -515,6 +531,7 @@ esphome/components/ufire_ise/* @pvizeli
esphome/components/ultrasonic/* @OttoWinter
esphome/components/update/* @jesserockz
esphome/components/uponor_smatrix/* @kroimon
esphome/components/usb_cdc_acm/* @kbx81
esphome/components/usb_host/* @clydebarrow
esphome/components/usb_uart/* @clydebarrow
esphome/components/valve/* @esphome/core
@@ -525,6 +542,7 @@ esphome/components/version/* @esphome/core
esphome/components/voice_assistant/* @jesserockz @kahrendt
esphome/components/wake_on_lan/* @clydebarrow @willwill2will54
esphome/components/watchdog/* @oarcher
esphome/components/water_heater/* @dhoeben
esphome/components/waveshare_epaper/* @clydebarrow
esphome/components/web_server/ota/* @esphome/core
esphome/components/web_server_base/* @esphome/core
@@ -560,5 +578,6 @@ esphome/components/xpt2046/touchscreen/* @nielsnl68 @numo68
esphome/components/xxtea/* @clydebarrow
esphome/components/zephyr/* @tomaszduda23
esphome/components/zhlt01/* @cfeenstra1024
esphome/components/zigbee/* @tomaszduda23
esphome/components/zio_ultrasonic/* @kahrendt
esphome/components/zwave_proxy/* @kbx81

View File

@@ -2,7 +2,7 @@
We welcome contributions to the ESPHome suite of code and documentation!
Please read our [contributing guide](https://esphome.io/guides/contributing.html) if you wish to contribute to the
Please read our [contributing guide](https://developers.esphome.io/contributing/code/) if you wish to contribute to the
project and be sure to join us on [Discord](https://discord.gg/KhAMKrd).
**See also:**

View File

@@ -48,7 +48,7 @@ PROJECT_NAME = ESPHome
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 2025.11.0-dev
PROJECT_NUMBER = 2026.1.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

View File

@@ -1,6 +1,7 @@
include LICENSE
include README.md
include requirements.txt
recursive-include esphome *.yaml
recursive-include esphome *.cpp *.h *.tcc *.c
recursive-include esphome *.py.script
recursive-include esphome LICENSE.txt

View File

@@ -2,8 +2,8 @@
<a href="https://esphome.io/">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://esphome.io/_static/logo-text-on-dark.svg", alt="ESPHome Logo">
<img src="https://esphome.io/_static/logo-text-on-light.svg" alt="ESPHome Logo">
<source media="(prefers-color-scheme: dark)" srcset="https://media.esphome.io/logo/logo-text-on-dark.svg">
<img src="https://media.esphome.io/logo/logo-text-on-light.svg" alt="ESPHome Logo">
</picture>
</a>

View File

@@ -11,6 +11,16 @@ FROM base-source-${BUILD_TYPE} AS base
RUN git config --system --add safe.directory "*"
# Install build tools for Python packages that require compilation
# (e.g., ruamel.yaml.clibz used by ESP-IDF's idf-component-manager)
RUN if command -v apk > /dev/null; then \
apk add --no-cache build-base; \
else \
apt-get update \
&& apt-get install -y --no-install-recommends build-essential \
&& rm -rf /var/lib/apt/lists/*; \
fi
ENV PIP_DISABLE_PIP_VERSION_CHECK=1
RUN pip install --no-cache-dir -U pip uv==0.6.14

View File

@@ -62,6 +62,9 @@ from esphome.util import (
_LOGGER = logging.getLogger(__name__)
# Maximum buffer size for serial log reading to prevent unbounded memory growth
SERIAL_BUFFER_MAX_SIZE = 65536
# Special non-component keys that appear in configs
_NON_COMPONENT_KEYS = frozenset(
{
@@ -431,25 +434,37 @@ def run_miniterm(config: ConfigType, port: str, args) -> int:
while tries < 5:
try:
with ser:
buffer = b""
ser.timeout = 0.1 # 100ms timeout for non-blocking reads
while True:
try:
raw = ser.readline()
# Read all available data and timestamp it
chunk = ser.read(ser.in_waiting or 1)
if not chunk:
continue
time_ = datetime.now()
milliseconds = time_.microsecond // 1000
time_str = f"[{time_.hour:02}:{time_.minute:02}:{time_.second:02}.{milliseconds:03}]"
# Add to buffer and process complete lines
# Limit buffer size to prevent unbounded memory growth
# if device sends data without newlines
buffer += chunk
if len(buffer) > SERIAL_BUFFER_MAX_SIZE:
buffer = buffer[-SERIAL_BUFFER_MAX_SIZE:]
while b"\n" in buffer:
raw_line, buffer = buffer.split(b"\n", 1)
line = raw_line.replace(b"\r", b"").decode(
"utf8", "backslashreplace"
)
safe_print(parser.parse_line(line, time_str))
backtrace_state = platformio_api.process_stacktrace(
config, line, backtrace_state=backtrace_state
)
except serial.SerialException:
_LOGGER.error("Serial port closed!")
return 0
line = (
raw.replace(b"\r", b"")
.replace(b"\n", b"")
.decode("utf8", "backslashreplace")
)
time_ = datetime.now()
nanoseconds = time_.microsecond // 1000
time_str = f"[{time_.hour:02}:{time_.minute:02}:{time_.second:02}.{nanoseconds:03}]"
safe_print(parser.parse_line(line, time_str))
backtrace_state = platformio_api.process_stacktrace(
config, line, backtrace_state=backtrace_state
)
except serial.SerialException:
tries += 1
time.sleep(1)
@@ -518,10 +533,49 @@ def compile_program(args: ArgsProtocol, config: ConfigType) -> int:
rc = platformio_api.run_compile(config, CORE.verbose)
if rc != 0:
return rc
# Check if firmware was rebuilt and emit build_info + create manifest
_check_and_emit_build_info()
idedata = platformio_api.get_idedata(config)
return 0 if idedata is not None else 1
def _check_and_emit_build_info() -> None:
"""Check if firmware was rebuilt and emit build_info."""
import json
firmware_path = CORE.firmware_bin
build_info_json_path = CORE.relative_build_path("build_info.json")
# Check if both files exist
if not firmware_path.exists() or not build_info_json_path.exists():
return
# Check if firmware is newer than build_info (indicating a relink occurred)
if firmware_path.stat().st_mtime <= build_info_json_path.stat().st_mtime:
return
# Read build_info from JSON
try:
with open(build_info_json_path, encoding="utf-8") as f:
build_info = json.load(f)
except (OSError, json.JSONDecodeError) as e:
_LOGGER.debug("Failed to read build_info: %s", e)
return
config_hash = build_info.get("config_hash")
build_time_str = build_info.get("build_time_str")
if config_hash is None or build_time_str is None:
return
# Emit build_info with human-readable time
_LOGGER.info(
"Build Info: config_hash=0x%08x build_time_str=%s", config_hash, build_time_str
)
def upload_using_esptool(
config: ConfigType, port: str, file: str, speed: int
) -> str | int:
@@ -757,7 +811,13 @@ def command_compile(args: ArgsProtocol, config: ConfigType) -> int | None:
exit_code = compile_program(args, config)
if exit_code != 0:
return exit_code
_LOGGER.info("Successfully compiled program.")
if CORE.is_host:
from esphome.platformio_api import get_idedata
program_path = str(get_idedata(config).firmware_elf_path)
_LOGGER.info("Successfully compiled program to path '%s'", program_path)
else:
_LOGGER.info("Successfully compiled program.")
return 0
@@ -807,10 +867,8 @@ def command_run(args: ArgsProtocol, config: ConfigType) -> int | None:
if CORE.is_host:
from esphome.platformio_api import get_idedata
idedata = get_idedata(config)
if idedata is None:
return 1
program_path = idedata.raw["prog_path"]
program_path = str(get_idedata(config).firmware_elf_path)
_LOGGER.info("Running program from path '%s'", program_path)
return run_external_process(program_path)
# Get devices, resolving special identifiers like OTA
@@ -951,6 +1009,7 @@ def command_analyze_memory(args: ArgsProtocol, config: ConfigType) -> int:
"""
from esphome import platformio_api
from esphome.analyze_memory.cli import MemoryAnalyzerCLI
from esphome.analyze_memory.ram_strings import RamStringsAnalyzer
# Always compile to ensure fresh data (fast if no changes - just relinks)
exit_code = write_cpp(config)
@@ -973,21 +1032,39 @@ def command_analyze_memory(args: ArgsProtocol, config: ConfigType) -> int:
external_components = detect_external_components(config)
_LOGGER.debug("Detected external components: %s", external_components)
# Perform memory analysis
# Perform component memory analysis
_LOGGER.info("Analyzing memory usage...")
analyzer = MemoryAnalyzerCLI(
str(firmware_elf),
idedata.objdump_path,
idedata.readelf_path,
external_components,
idedata=idedata,
)
analyzer.analyze()
# Generate and display report
# Generate and display component report
report = analyzer.generate_report()
print()
print(report)
# Perform RAM strings analysis
_LOGGER.info("Analyzing RAM strings...")
try:
ram_analyzer = RamStringsAnalyzer(
str(firmware_elf),
objdump_path=idedata.objdump_path,
platform=CORE.target_platform,
)
ram_analyzer.analyze()
# Generate and display RAM strings report
ram_report = ram_analyzer.generate_report()
print()
print(ram_report)
except Exception as e: # pylint: disable=broad-except
_LOGGER.warning("RAM strings analysis failed: %s", e)
return 0
@@ -1337,7 +1414,7 @@ def parse_args(argv):
"clean-all", help="Clean all build and platform files."
)
parser_clean_all.add_argument(
"configuration", help="Your YAML configuration directory.", nargs="*"
"configuration", help="Your YAML file or configuration directory.", nargs="*"
)
parser_dashboard = subparsers.add_parser(

View File

@@ -15,27 +15,20 @@ from .const import (
SECTION_TO_ATTR,
SYMBOL_PATTERNS,
)
from .demangle import batch_demangle
from .helpers import (
get_component_class_patterns,
get_esphome_components,
map_section_name,
parse_symbol_line,
)
from .toolchain import find_tool, run_tool
if TYPE_CHECKING:
from esphome.platformio_api import IDEData
_LOGGER = logging.getLogger(__name__)
# GCC global constructor/destructor prefix annotations
_GCC_PREFIX_ANNOTATIONS = {
"_GLOBAL__sub_I_": "global constructor for",
"_GLOBAL__sub_D_": "global destructor for",
}
# GCC optimization suffix pattern (e.g., $isra$0, $part$1, $constprop$2)
_GCC_OPTIMIZATION_SUFFIX_PATTERN = re.compile(r"(\$(?:isra|part|constprop)\$\d+)")
# C++ runtime patterns for categorization
_CPP_RUNTIME_PATTERNS = frozenset(["vtable", "typeinfo", "thunk"])
@@ -61,6 +54,9 @@ _NAMESPACE_STD = "std::"
# Type alias for symbol information: (symbol_name, size, component)
SymbolInfoType = tuple[str, int, str]
# RAM sections - symbols in these sections consume RAM
RAM_SECTIONS = frozenset([".data", ".bss"])
@dataclass
class MemorySection:
@@ -68,7 +64,20 @@ class MemorySection:
name: str
symbols: list[SymbolInfoType] = field(default_factory=list)
total_size: int = 0
total_size: int = 0 # Actual section size from ELF headers
symbol_size: int = 0 # Sum of symbol sizes (may be less than total_size)
@dataclass
class SDKSymbol:
"""Represents a symbol from an SDK library that's not in the ELF symbol table."""
name: str
size: int
library: str # Name of the .a file (e.g., "libpp.a")
section: str # ".bss" or ".data"
is_local: bool # True if static/local symbol (lowercase in nm output)
demangled: str = "" # Demangled name (populated after analysis)
@dataclass
@@ -126,6 +135,10 @@ class MemoryAnalyzer:
self.objdump_path = objdump_path or "objdump"
self.readelf_path = readelf_path or "readelf"
self.external_components = external_components or set()
self._idedata = idedata
# Derive nm path from objdump path using shared toolchain utility
self.nm_path = find_tool("nm", self.objdump_path)
self.sections: dict[str, MemorySection] = {}
self.components: dict[str, ComponentMemory] = defaultdict(
@@ -136,15 +149,25 @@ class MemoryAnalyzer:
self._esphome_core_symbols: list[
tuple[str, str, int]
] = [] # Track core symbols
self._component_symbols: dict[str, list[tuple[str, str, int]]] = defaultdict(
# Track symbols for all components: (symbol_name, demangled, size, section)
self._component_symbols: dict[str, list[tuple[str, str, int, str]]] = (
defaultdict(list)
)
# Track RAM symbols separately for detailed analysis: (symbol_name, demangled, size, section)
self._ram_symbols: dict[str, list[tuple[str, str, int, str]]] = defaultdict(
list
) # Track symbols for all components
)
# Track ELF symbol names for SDK cross-reference
self._elf_symbol_names: set[str] = set()
# SDK symbols not in ELF (static/local symbols from closed-source libs)
self._sdk_symbols: list[SDKSymbol] = []
def analyze(self) -> dict[str, ComponentMemory]:
"""Analyze the ELF file and return component memory usage."""
self._parse_sections()
self._parse_symbols()
self._categorize_symbols()
self._analyze_sdk_libraries()
return dict(self.components)
def _parse_sections(self) -> None:
@@ -198,6 +221,8 @@ class MemoryAnalyzer:
continue
self.sections[section].symbols.append((name, size, ""))
self.sections[section].symbol_size += size
self._elf_symbol_names.add(name)
seen_addresses.add(address)
def _categorize_symbols(self) -> None:
@@ -241,8 +266,13 @@ class MemoryAnalyzer:
if size > 0:
demangled = self._demangle_symbol(symbol_name)
self._component_symbols[component].append(
(symbol_name, demangled, size)
(symbol_name, demangled, size, section_name)
)
# Track RAM symbols separately for detailed RAM analysis
if section_name in RAM_SECTIONS:
self._ram_symbols[component].append(
(symbol_name, demangled, size, section_name)
)
def _identify_component(self, symbol_name: str) -> str:
"""Identify which component a symbol belongs to."""
@@ -312,168 +342,9 @@ class MemoryAnalyzer:
if not symbols:
return
# Try to find the appropriate c++filt for the platform
cppfilt_cmd = "c++filt"
_LOGGER.info("Demangling %d symbols", len(symbols))
_LOGGER.debug("objdump_path = %s", self.objdump_path)
# Check if we have a toolchain-specific c++filt
if self.objdump_path and self.objdump_path != "objdump":
# Replace objdump with c++filt in the path
potential_cppfilt = self.objdump_path.replace("objdump", "c++filt")
_LOGGER.info("Checking for toolchain c++filt at: %s", potential_cppfilt)
if Path(potential_cppfilt).exists():
cppfilt_cmd = potential_cppfilt
_LOGGER.info("✓ Using toolchain c++filt: %s", cppfilt_cmd)
else:
_LOGGER.info(
"✗ Toolchain c++filt not found at %s, using system c++filt",
potential_cppfilt,
)
else:
_LOGGER.info("✗ Using system c++filt (objdump_path=%s)", self.objdump_path)
# Strip GCC optimization suffixes and prefixes before demangling
# Suffixes like $isra$0, $part$0, $constprop$0 confuse c++filt
# Prefixes like _GLOBAL__sub_I_ need to be removed and tracked
symbols_stripped: list[str] = []
symbols_prefixes: list[str] = [] # Track removed prefixes
for symbol in symbols:
# Remove GCC optimization markers
stripped = _GCC_OPTIMIZATION_SUFFIX_PATTERN.sub("", symbol)
# Handle GCC global constructor/initializer prefixes
# _GLOBAL__sub_I_<mangled> -> extract <mangled> for demangling
prefix = ""
for gcc_prefix in _GCC_PREFIX_ANNOTATIONS:
if stripped.startswith(gcc_prefix):
prefix = gcc_prefix
stripped = stripped[len(prefix) :]
break
symbols_stripped.append(stripped)
symbols_prefixes.append(prefix)
try:
# Send all symbols to c++filt at once
result = subprocess.run(
[cppfilt_cmd],
input="\n".join(symbols_stripped),
capture_output=True,
text=True,
check=False,
)
except (subprocess.SubprocessError, OSError, UnicodeDecodeError) as e:
# On error, cache originals
_LOGGER.warning("Failed to batch demangle symbols: %s", e)
for symbol in symbols:
self._demangle_cache[symbol] = symbol
return
if result.returncode != 0:
_LOGGER.warning(
"c++filt exited with code %d: %s",
result.returncode,
result.stderr[:200] if result.stderr else "(no error output)",
)
# Cache originals on failure
for symbol in symbols:
self._demangle_cache[symbol] = symbol
return
# Process demangled output
self._process_demangled_output(
symbols, symbols_stripped, symbols_prefixes, result.stdout, cppfilt_cmd
)
def _process_demangled_output(
self,
symbols: list[str],
symbols_stripped: list[str],
symbols_prefixes: list[str],
demangled_output: str,
cppfilt_cmd: str,
) -> None:
"""Process demangled symbol output and populate cache.
Args:
symbols: Original symbol names
symbols_stripped: Stripped symbol names sent to c++filt
symbols_prefixes: Removed prefixes to restore
demangled_output: Output from c++filt
cppfilt_cmd: Path to c++filt command (for logging)
"""
demangled_lines = demangled_output.strip().split("\n")
failed_count = 0
for original, stripped, prefix, demangled in zip(
symbols, symbols_stripped, symbols_prefixes, demangled_lines
):
# Add back any prefix that was removed
demangled = self._restore_symbol_prefix(prefix, stripped, demangled)
# If we stripped a suffix, add it back to the demangled name for clarity
if original != stripped and not prefix:
demangled = self._restore_symbol_suffix(original, demangled)
self._demangle_cache[original] = demangled
# Log symbols that failed to demangle (stayed the same as stripped version)
if stripped == demangled and stripped.startswith("_Z"):
failed_count += 1
if failed_count <= 5: # Only log first 5 failures
_LOGGER.warning("Failed to demangle: %s", original)
if failed_count == 0:
_LOGGER.info("Successfully demangled all %d symbols", len(symbols))
return
_LOGGER.warning(
"Failed to demangle %d/%d symbols using %s",
failed_count,
len(symbols),
cppfilt_cmd,
)
@staticmethod
def _restore_symbol_prefix(prefix: str, stripped: str, demangled: str) -> str:
"""Restore prefix that was removed before demangling.
Args:
prefix: Prefix that was removed (e.g., "_GLOBAL__sub_I_")
stripped: Stripped symbol name
demangled: Demangled symbol name
Returns:
Demangled name with prefix restored/annotated
"""
if not prefix:
return demangled
# Successfully demangled - add descriptive prefix
if demangled != stripped and (
annotation := _GCC_PREFIX_ANNOTATIONS.get(prefix)
):
return f"[{annotation}: {demangled}]"
# Failed to demangle - restore original prefix
return prefix + demangled
@staticmethod
def _restore_symbol_suffix(original: str, demangled: str) -> str:
"""Restore GCC optimization suffix that was removed before demangling.
Args:
original: Original symbol name with suffix
demangled: Demangled symbol name without suffix
Returns:
Demangled name with suffix annotation
"""
if suffix_match := _GCC_OPTIMIZATION_SUFFIX_PATTERN.search(original):
return f"{demangled} [{suffix_match.group(1)}]"
return demangled
self._demangle_cache = batch_demangle(symbols, objdump_path=self.objdump_path)
_LOGGER.info("Successfully demangled %d symbols", len(self._demangle_cache))
def _demangle_symbol(self, symbol: str) -> str:
"""Get demangled C++ symbol name from cache."""
@@ -495,6 +366,247 @@ class MemoryAnalyzer:
return "Other Core"
def get_unattributed_ram(self) -> tuple[int, int, int]:
"""Get unattributed RAM sizes (SDK/framework overhead).
Returns:
Tuple of (unattributed_bss, unattributed_data, total_unattributed)
These are bytes in RAM sections that have no corresponding symbols.
"""
bss_section = self.sections.get(".bss")
data_section = self.sections.get(".data")
unattributed_bss = 0
unattributed_data = 0
if bss_section:
unattributed_bss = max(0, bss_section.total_size - bss_section.symbol_size)
if data_section:
unattributed_data = max(
0, data_section.total_size - data_section.symbol_size
)
return unattributed_bss, unattributed_data, unattributed_bss + unattributed_data
def _find_sdk_library_dirs(self) -> list[Path]:
"""Find SDK library directories based on platform.
Returns:
List of paths to SDK library directories containing .a files.
"""
sdk_dirs: list[Path] = []
if self._idedata is None:
return sdk_dirs
# Get the CC path to determine the framework location
cc_path = getattr(self._idedata, "cc_path", None)
if not cc_path:
return sdk_dirs
cc_path = Path(cc_path)
# For ESP8266 Arduino framework
# CC is like: ~/.platformio/packages/toolchain-xtensa/bin/xtensa-lx106-elf-gcc
# SDK libs are in: ~/.platformio/packages/framework-arduinoespressif8266/tools/sdk/lib/
if "xtensa-lx106" in str(cc_path):
platformio_dir = cc_path.parent.parent.parent
esp8266_sdk = (
platformio_dir
/ "framework-arduinoespressif8266"
/ "tools"
/ "sdk"
/ "lib"
)
if esp8266_sdk.exists():
sdk_dirs.append(esp8266_sdk)
# Also check for NONOSDK subdirectories (closed-source libs)
sdk_dirs.extend(
subdir
for subdir in esp8266_sdk.iterdir()
if subdir.is_dir() and subdir.name.startswith("NONOSDK")
)
# For ESP32 IDF framework
# CC is like: ~/.platformio/packages/toolchain-xtensa-esp-elf/bin/xtensa-esp32-elf-gcc
# or: ~/.platformio/packages/toolchain-riscv32-esp/bin/riscv32-esp-elf-gcc
elif "xtensa-esp" in str(cc_path) or "riscv32-esp" in str(cc_path):
# Detect ESP32 variant from CC path or defines
variant = self._detect_esp32_variant()
if variant:
platformio_dir = cc_path.parent.parent.parent
espidf_dir = platformio_dir / "framework-espidf" / "components"
if espidf_dir.exists():
# Find all directories named after the variant that contain .a files
# This handles various ESP-IDF library layouts:
# - components/*/lib/<variant>/
# - components/*/<variant>/
# - components/*/lib/lib/<variant>/
# - components/*/*/lib_*/<variant>/
sdk_dirs.extend(
variant_dir
for variant_dir in espidf_dir.rglob(variant)
if variant_dir.is_dir() and any(variant_dir.glob("*.a"))
)
return sdk_dirs
def _detect_esp32_variant(self) -> str | None:
"""Detect ESP32 variant from idedata defines.
Returns:
Variant string like 'esp32', 'esp32s2', 'esp32c3', etc. or None.
"""
if self._idedata is None:
return None
defines = getattr(self._idedata, "defines", [])
if not defines:
return None
# ESPHome always adds USE_ESP32_VARIANT_xxx defines
variant_prefix = "USE_ESP32_VARIANT_"
for define in defines:
if define.startswith(variant_prefix):
# Extract variant name and convert to lowercase
# USE_ESP32_VARIANT_ESP32 -> esp32
# USE_ESP32_VARIANT_ESP32S3 -> esp32s3
return define[len(variant_prefix) :].lower()
return None
def _parse_sdk_library(
self, lib_path: Path
) -> tuple[list[tuple[str, int, str, bool]], set[str]]:
"""Parse a single SDK library for symbols.
Args:
lib_path: Path to the .a library file
Returns:
Tuple of:
- List of BSS/DATA symbols: (symbol_name, size, section, is_local)
- Set of global BSS/DATA symbol names (for checking if RAM is linked)
"""
ram_symbols: list[tuple[str, int, str, bool]] = []
global_ram_symbols: set[str] = set()
result = run_tool([self.nm_path, "--size-sort", str(lib_path)], timeout=10)
if result is None:
return ram_symbols, global_ram_symbols
for line in result.stdout.splitlines():
parts = line.split()
if len(parts) < 3:
continue
try:
size = int(parts[0], 16)
sym_type = parts[1]
name = parts[2]
# Only collect BSS (b/B) and DATA (d/D) for RAM analysis
if sym_type in ("b", "B"):
section = ".bss"
is_local = sym_type == "b"
ram_symbols.append((name, size, section, is_local))
# Track global RAM symbols (B/D) for linking check
if sym_type == "B":
global_ram_symbols.add(name)
elif sym_type in ("d", "D"):
section = ".data"
is_local = sym_type == "d"
ram_symbols.append((name, size, section, is_local))
if sym_type == "D":
global_ram_symbols.add(name)
except (ValueError, IndexError):
continue
return ram_symbols, global_ram_symbols
def _analyze_sdk_libraries(self) -> None:
"""Analyze SDK libraries to find symbols not in the ELF.
This finds static/local symbols from closed-source SDK libraries
that consume RAM but don't appear in the final ELF symbol table.
Only includes symbols from libraries that have RAM actually linked
(at least one global BSS/DATA symbol in the ELF).
"""
sdk_dirs = self._find_sdk_library_dirs()
if not sdk_dirs:
_LOGGER.debug("No SDK library directories found")
return
_LOGGER.debug("Analyzing SDK libraries in %d directories", len(sdk_dirs))
# Track seen symbols to avoid duplicates from multiple SDK versions
seen_symbols: set[str] = set()
for sdk_dir in sdk_dirs:
for lib_path in sorted(sdk_dir.glob("*.a")):
lib_name = lib_path.name
ram_symbols, global_ram_symbols = self._parse_sdk_library(lib_path)
# Check if this library's RAM is actually linked by seeing if any
# of its global BSS/DATA symbols appear in the ELF
if not global_ram_symbols & self._elf_symbol_names:
# No RAM from this library is in the ELF - skip it
continue
for name, size, section, is_local in ram_symbols:
# Skip if already in ELF or already seen from another lib
if name in self._elf_symbol_names or name in seen_symbols:
continue
# Only track symbols with non-zero size
if size > 0:
self._sdk_symbols.append(
SDKSymbol(
name=name,
size=size,
library=lib_name,
section=section,
is_local=is_local,
)
)
seen_symbols.add(name)
# Demangle SDK symbols for better readability
if self._sdk_symbols:
sdk_names = [sym.name for sym in self._sdk_symbols]
demangled_map = batch_demangle(sdk_names, objdump_path=self.objdump_path)
for sym in self._sdk_symbols:
sym.demangled = demangled_map.get(sym.name, sym.name)
# Sort by size descending for reporting
self._sdk_symbols.sort(key=lambda s: s.size, reverse=True)
total_sdk_ram = sum(s.size for s in self._sdk_symbols)
_LOGGER.debug(
"Found %d SDK symbols not in ELF, totaling %d bytes",
len(self._sdk_symbols),
total_sdk_ram,
)
def get_sdk_ram_symbols(self) -> list[SDKSymbol]:
"""Get SDK symbols that consume RAM but aren't in the ELF symbol table.
Returns:
List of SDKSymbol objects sorted by size descending.
"""
return self._sdk_symbols
def get_sdk_ram_by_library(self) -> dict[str, list[SDKSymbol]]:
"""Get SDK RAM symbols grouped by library.
Returns:
Dictionary mapping library name to list of symbols.
"""
by_lib: dict[str, list[SDKSymbol]] = defaultdict(list)
for sym in self._sdk_symbols:
by_lib[sym.library].append(sym)
return dict(by_lib)
if __name__ == "__main__":
from .cli import main

View File

@@ -1,21 +1,36 @@
"""CLI interface for memory analysis with report generation."""
from __future__ import annotations
from collections import defaultdict
from collections.abc import Callable
import json
import sys
from typing import TYPE_CHECKING
from . import (
_COMPONENT_API,
_COMPONENT_CORE,
_COMPONENT_PREFIX_ESPHOME,
_COMPONENT_PREFIX_EXTERNAL,
RAM_SECTIONS,
MemoryAnalyzer,
)
if TYPE_CHECKING:
from . import ComponentMemory
class MemoryAnalyzerCLI(MemoryAnalyzer):
"""Memory analyzer with CLI-specific report generation."""
# Symbol size threshold for detailed analysis
SYMBOL_SIZE_THRESHOLD: int = (
100 # Show symbols larger than this in detailed analysis
)
# Lower threshold for RAM symbols (RAM is more constrained)
RAM_SYMBOL_SIZE_THRESHOLD: int = 24
# Column width constants
COL_COMPONENT: int = 29
COL_FLASH_TEXT: int = 14
@@ -79,6 +94,60 @@ class MemoryAnalyzerCLI(MemoryAnalyzer):
COL_CORE_PERCENT,
)
def _add_section_header(self, lines: list[str], title: str) -> None:
"""Add a section header with title centered between separator lines."""
lines.append("")
lines.append("=" * self.TABLE_WIDTH)
lines.append(title.center(self.TABLE_WIDTH))
lines.append("=" * self.TABLE_WIDTH)
lines.append("")
def _add_top_consumers(
self,
lines: list[str],
title: str,
components: list[tuple[str, ComponentMemory]],
get_size: Callable[[ComponentMemory], int],
total: int,
memory_type: str,
limit: int = 25,
) -> None:
"""Add a formatted list of top memory consumers to the report.
Args:
lines: List of report lines to append the output to.
title: Section title to print before the list.
components: Sequence of (name, ComponentMemory) tuples to analyze.
get_size: Callable that takes a ComponentMemory and returns the
size in bytes to use for ranking and display.
total: Total size in bytes for computing percentage usage.
memory_type: Label for the memory region (e.g., "flash" or "RAM").
limit: Maximum number of components to include in the list.
"""
lines.append("")
lines.append(f"{title}:")
for i, (name, mem) in enumerate(components[:limit]):
size = get_size(mem)
if size > 0:
percentage = (size / total * 100) if total > 0 else 0
lines.append(
f"{i + 1}. {name} ({size:,} B) - {percentage:.1f}% of analyzed {memory_type}"
)
def _format_symbol_with_section(
self, demangled: str, size: int, section: str | None = None
) -> str:
"""Format a symbol entry, optionally adding a RAM section label.
If section is one of the RAM sections (.data or .bss), a label like
" [data]" or " [bss]" is appended. For non-RAM sections or when
section is None, no section label is added.
"""
section_label = ""
if section in RAM_SECTIONS:
section_label = f" [{section[1:]}]" # .data -> [data], .bss -> [bss]
return f"{demangled} ({size:,} B){section_label}"
def generate_report(self, detailed: bool = False) -> str:
"""Generate a formatted memory report."""
components = sorted(
@@ -119,43 +188,70 @@ class MemoryAnalyzerCLI(MemoryAnalyzer):
f"{total_flash:>{self.COL_TOTAL_FLASH - 2},} B | {total_ram:>{self.COL_TOTAL_RAM - 2},} B"
)
# Top consumers
lines.append("")
lines.append("Top Flash Consumers:")
for i, (name, mem) in enumerate(components[:25]):
if mem.flash_total > 0:
percentage = (
(mem.flash_total / total_flash * 100) if total_flash > 0 else 0
)
lines.append(
f"{i + 1}. {name} ({mem.flash_total:,} B) - {percentage:.1f}% of analyzed flash"
)
lines.append("")
lines.append("Top RAM Consumers:")
ram_components = sorted(components, key=lambda x: x[1].ram_total, reverse=True)
for i, (name, mem) in enumerate(ram_components[:25]):
if mem.ram_total > 0:
percentage = (mem.ram_total / total_ram * 100) if total_ram > 0 else 0
lines.append(
f"{i + 1}. {name} ({mem.ram_total:,} B) - {percentage:.1f}% of analyzed RAM"
)
lines.append("")
lines.append(
"Note: This analysis covers symbols in the ELF file. Some runtime allocations may not be included."
# Show unattributed RAM (SDK/framework overhead)
unattributed_bss, unattributed_data, unattributed_total = (
self.get_unattributed_ram()
)
if unattributed_total > 0:
lines.append("")
lines.append(
f"Unattributed RAM: {unattributed_total:,} B (SDK/framework overhead)"
)
if unattributed_bss > 0 and unattributed_data > 0:
lines.append(
f" .bss: {unattributed_bss:,} B | .data: {unattributed_data:,} B"
)
# Show SDK symbol breakdown if available
sdk_by_lib = self.get_sdk_ram_by_library()
if sdk_by_lib:
lines.append("")
lines.append("SDK library breakdown (static symbols not in ELF):")
# Sort libraries by total size
lib_totals = [
(lib, sum(s.size for s in syms), syms)
for lib, syms in sdk_by_lib.items()
]
lib_totals.sort(key=lambda x: x[1], reverse=True)
for lib_name, lib_total, syms in lib_totals:
if lib_total == 0:
continue
lines.append(f" {lib_name}: {lib_total:,} B")
# Show top symbols from this library
for sym in sorted(syms, key=lambda s: s.size, reverse=True)[:3]:
section_label = sym.section.lstrip(".")
# Use demangled name (falls back to original if not demangled)
display_name = sym.demangled or sym.name
if len(display_name) > 50:
display_name = f"{display_name[:47]}..."
lines.append(
f" {sym.size:>6,} B [{section_label}] {display_name}"
)
# Top consumers
self._add_top_consumers(
lines,
"Top Flash Consumers",
components,
lambda m: m.flash_total,
total_flash,
"flash",
)
ram_components = sorted(components, key=lambda x: x[1].ram_total, reverse=True)
self._add_top_consumers(
lines,
"Top RAM Consumers",
ram_components,
lambda m: m.ram_total,
total_ram,
"RAM",
)
lines.append("=" * self.TABLE_WIDTH)
# Add ESPHome core detailed analysis if there are core symbols
if self._esphome_core_symbols:
lines.append("")
lines.append("=" * self.TABLE_WIDTH)
lines.append(
f"{_COMPONENT_CORE} Detailed Analysis".center(self.TABLE_WIDTH)
)
lines.append("=" * self.TABLE_WIDTH)
lines.append("")
self._add_section_header(lines, f"{_COMPONENT_CORE} Detailed Analysis")
# Group core symbols by subcategory
core_subcategories: dict[str, list[tuple[str, str, int]]] = defaultdict(
@@ -192,15 +288,26 @@ class MemoryAnalyzerCLI(MemoryAnalyzer):
f"{len(symbols):>{self.COL_CORE_COUNT}} | {percentage:>{self.COL_CORE_PERCENT - 1}.1f}%"
)
# Top 15 largest core symbols
# All core symbols above threshold
lines.append("")
lines.append(f"Top 15 Largest {_COMPONENT_CORE} Symbols:")
sorted_core_symbols = sorted(
self._esphome_core_symbols, key=lambda x: x[2], reverse=True
)
large_core_symbols = [
(symbol, demangled, size)
for symbol, demangled, size in sorted_core_symbols
if size > self.SYMBOL_SIZE_THRESHOLD
]
for i, (symbol, demangled, size) in enumerate(sorted_core_symbols[:15]):
lines.append(f"{i + 1}. {demangled} ({size:,} B)")
lines.append(
f"{_COMPONENT_CORE} Symbols > {self.SYMBOL_SIZE_THRESHOLD} B ({len(large_core_symbols)} symbols):"
)
for i, (symbol, demangled, size) in enumerate(large_core_symbols):
# Core symbols only track (symbol, demangled, size) without section info,
# so we don't show section labels here
lines.append(
f"{i + 1}. {self._format_symbol_with_section(demangled, size)}"
)
lines.append("=" * self.TABLE_WIDTH)
@@ -256,11 +363,7 @@ class MemoryAnalyzerCLI(MemoryAnalyzer):
for comp_name, comp_mem in components_to_analyze:
if not (comp_symbols := self._component_symbols.get(comp_name, [])):
continue
lines.append("")
lines.append("=" * self.TABLE_WIDTH)
lines.append(f"{comp_name} Detailed Analysis".center(self.TABLE_WIDTH))
lines.append("=" * self.TABLE_WIDTH)
lines.append("")
self._add_section_header(lines, f"{comp_name} Detailed Analysis")
# Sort symbols by size
sorted_symbols = sorted(comp_symbols, key=lambda x: x[2], reverse=True)
@@ -269,19 +372,71 @@ class MemoryAnalyzerCLI(MemoryAnalyzer):
lines.append(f"Total size: {comp_mem.flash_total:,} B")
lines.append("")
# Show all symbols > 100 bytes for better visibility
# Show all symbols above threshold for better visibility
large_symbols = [
(sym, dem, size) for sym, dem, size in sorted_symbols if size > 100
(sym, dem, size, sec)
for sym, dem, size, sec in sorted_symbols
if size > self.SYMBOL_SIZE_THRESHOLD
]
lines.append(
f"{comp_name} Symbols > 100 B ({len(large_symbols)} symbols):"
f"{comp_name} Symbols > {self.SYMBOL_SIZE_THRESHOLD} B ({len(large_symbols)} symbols):"
)
for i, (symbol, demangled, size) in enumerate(large_symbols):
lines.append(f"{i + 1}. {demangled} ({size:,} B)")
for i, (symbol, demangled, size, section) in enumerate(large_symbols):
lines.append(
f"{i + 1}. {self._format_symbol_with_section(demangled, size, section)}"
)
lines.append("=" * self.TABLE_WIDTH)
# Detailed RAM analysis by component (at end, before RAM strings analysis)
self._add_section_header(lines, "RAM Symbol Analysis by Component")
# Show top 15 RAM consumers with their large symbols
for name, mem in ram_components[:15]:
if mem.ram_total == 0:
continue
ram_syms = self._ram_symbols.get(name, [])
if not ram_syms:
continue
# Sort by size descending
sorted_ram_syms = sorted(ram_syms, key=lambda x: x[2], reverse=True)
large_ram_syms = [
s for s in sorted_ram_syms if s[2] > self.RAM_SYMBOL_SIZE_THRESHOLD
]
lines.append(f"{name} ({mem.ram_total:,} B total RAM):")
# Show breakdown by section type
data_size = sum(s[2] for s in ram_syms if s[3] == ".data")
bss_size = sum(s[2] for s in ram_syms if s[3] == ".bss")
lines.append(f" .data (initialized): {data_size:,} B")
lines.append(f" .bss (uninitialized): {bss_size:,} B")
if large_ram_syms:
lines.append(
f" Symbols > {self.RAM_SYMBOL_SIZE_THRESHOLD} B ({len(large_ram_syms)}):"
)
for symbol, demangled, size, section in large_ram_syms[:10]:
# Format section label consistently by stripping leading dot
section_label = section.lstrip(".") if section else ""
# Add ellipsis if name is truncated
demangled_display = (
f"{demangled[:70]}..." if len(demangled) > 70 else demangled
)
lines.append(
f" {size:>6,} B [{section_label}] {demangled_display}"
)
if len(large_ram_syms) > 10:
lines.append(f" ... and {len(large_ram_syms) - 10} more")
lines.append("")
lines.append(
"Note: This analysis covers symbols in the ELF file. Some runtime allocations may not be included."
)
lines.append("=" * self.TABLE_WIDTH)
return "\n".join(lines)
def to_json(self) -> str:

View File

@@ -7,11 +7,13 @@ ESPHOME_COMPONENT_PATTERN = re.compile(r"esphome::([a-zA-Z0-9_]+)::")
# Section mapping for ELF file sections
# Maps standard section names to their various platform-specific variants
# Note: Order matters! More specific patterns (.bss) must come before general ones (.dram)
# because ESP-IDF uses names like ".dram0.bss" which would match ".dram" otherwise
SECTION_MAPPING = {
".text": frozenset([".text", ".iram"]),
".rodata": frozenset([".rodata"]),
".bss": frozenset([".bss"]), # Must be before .data to catch ".dram0.bss"
".data": frozenset([".data", ".dram"]),
".bss": frozenset([".bss"]),
}
# Section to ComponentMemory attribute mapping
@@ -88,6 +90,77 @@ SYMBOL_PATTERNS = {
"sys_mbox_new",
"sys_arch_mbox_tryfetch",
],
# LibreTiny/Beken BK7231 radio calibration
"bk_radio_cal": [
"bk7011_",
"calibration_main",
"gcali_",
"rwnx_cal",
],
# LibreTiny/Beken WiFi MAC layer
"bk_wifi_mac": [
"rxu_", # RX upper layer
"txu_", # TX upper layer
"txl_", # TX lower layer
"rxl_", # RX lower layer
"scanu_", # Scan unit
"mm_hw_", # MAC management hardware
"mm_bcn", # MAC management beacon
"mm_tim", # MAC management TIM
"mm_check", # MAC management checks
"sm_connect", # Station management
"me_beacon", # Management entity beacon
"me_build", # Management entity build
"hapd_", # Host AP daemon
"chan_pre_", # Channel management
"handle_probe_", # Probe handling
],
# LibreTiny/Beken system control
"bk_system": [
"sctrl_", # System control
"icu_ctrl", # Interrupt control unit
"gdma_ctrl", # DMA control
"mpb_ctrl", # MPB control
"uf2_", # UF2 OTA
"bkreg_", # Beken registers
],
# LibreTiny/Beken BLE stack
"bk_ble": [
"gapc_", # GAP client
"gattc_", # GATT client
"attc_", # ATT client
"attmdb_", # ATT database
"atts_", # ATT server
"l2cc_", # L2CAP
"prf_env", # Profile environment
],
# LibreTiny/Beken scheduler
"bk_scheduler": [
"sch_plan_", # Scheduler plan
"sch_prog_", # Scheduler program
"sch_arb_", # Scheduler arbiter
],
# LibreTiny/Beken DMA descriptors
"bk_dma": [
"rx_payload_desc",
"rx_dma_hdrdesc",
"tx_hw_desc",
"host_event_data",
"host_cmd_data",
],
# ARM EABI compiler runtime (LibreTiny uses ARM Cortex-M)
"arm_runtime": [
"__aeabi_",
"__adddf3",
"__subdf3",
"__muldf3",
"__divdf3",
"__addsf3",
"__subsf3",
"__mulsf3",
"__divsf3",
"__gnu_unwind",
],
"xtensa": ["xt_", "_xt_", "xPortEnterCriticalTimeout"],
"heap": ["heap_", "multi_heap"],
"spi_flash": ["spi_flash"],
@@ -782,7 +855,22 @@ SYMBOL_PATTERNS = {
"math_internal": ["__mdiff", "__lshift", "__mprec_tens", "quorem"],
"character_class": ["__chclass"],
"camellia": ["camellia_", "camellia_feistel"],
"crypto_tables": ["FSb", "FSb2", "FSb3", "FSb4"],
"crypto_tables": [
"FSb",
"FSb2",
"FSb3",
"FSb4",
"Te0", # AES encryption table
"Td0", # AES decryption table
"crc32_table", # CRC32 lookup table
"crc_tab", # CRC lookup table
],
"crypto_hash": [
"SHA1Transform", # SHA1 hash function
"MD5Transform", # MD5 hash function
"SHA256",
"SHA512",
],
"event_buffer": ["g_eb_list_desc", "eb_space"],
"base_node": ["base_node_", "base_node_add_handler"],
"file_descriptor": ["s_fd_table"],

View File

@@ -0,0 +1,182 @@
"""Symbol demangling utilities for memory analysis.
This module provides functions for demangling C++ symbol names using c++filt.
"""
from __future__ import annotations
import logging
import re
import subprocess
from .toolchain import find_tool
_LOGGER = logging.getLogger(__name__)
# GCC global constructor/destructor prefix annotations
GCC_PREFIX_ANNOTATIONS = {
"_GLOBAL__sub_I_": "global constructor for",
"_GLOBAL__sub_D_": "global destructor for",
}
# GCC optimization suffix pattern (e.g., $isra$0, $part$1, $constprop$2)
GCC_OPTIMIZATION_SUFFIX_PATTERN = re.compile(r"(\$(?:isra|part|constprop)\$\d+)")
def _strip_gcc_annotations(symbol: str) -> tuple[str, str]:
"""Strip GCC optimization suffixes and prefixes from a symbol.
Args:
symbol: The mangled symbol name
Returns:
Tuple of (stripped_symbol, removed_prefix)
"""
# Remove GCC optimization markers
stripped = GCC_OPTIMIZATION_SUFFIX_PATTERN.sub("", symbol)
# Handle GCC global constructor/initializer prefixes
prefix = ""
for gcc_prefix in GCC_PREFIX_ANNOTATIONS:
if stripped.startswith(gcc_prefix):
prefix = gcc_prefix
stripped = stripped[len(prefix) :]
break
return stripped, prefix
def _restore_symbol_prefix(prefix: str, stripped: str, demangled: str) -> str:
"""Restore prefix that was removed before demangling.
Args:
prefix: Prefix that was removed (e.g., "_GLOBAL__sub_I_")
stripped: Stripped symbol name
demangled: Demangled symbol name
Returns:
Demangled name with prefix restored/annotated
"""
if not prefix:
return demangled
# Successfully demangled - add descriptive prefix
if demangled != stripped and (annotation := GCC_PREFIX_ANNOTATIONS.get(prefix)):
return f"[{annotation}: {demangled}]"
# Failed to demangle - restore original prefix
return prefix + demangled
def _restore_symbol_suffix(original: str, demangled: str) -> str:
"""Restore GCC optimization suffix that was removed before demangling.
Args:
original: Original symbol name with suffix
demangled: Demangled symbol name without suffix
Returns:
Demangled name with suffix annotation
"""
if suffix_match := GCC_OPTIMIZATION_SUFFIX_PATTERN.search(original):
return f"{demangled} [{suffix_match.group(1)}]"
return demangled
def batch_demangle(
symbols: list[str],
cppfilt_path: str | None = None,
objdump_path: str | None = None,
) -> dict[str, str]:
"""Batch demangle C++ symbol names.
Args:
symbols: List of symbol names to demangle
cppfilt_path: Path to c++filt binary (auto-detected if not provided)
objdump_path: Path to objdump binary to derive c++filt path from
Returns:
Dictionary mapping original symbol names to demangled names
"""
cache: dict[str, str] = {}
if not symbols:
return cache
# Find c++filt tool
cppfilt_cmd = cppfilt_path or find_tool("c++filt", objdump_path)
if not cppfilt_cmd:
_LOGGER.warning("Could not find c++filt, symbols will not be demangled")
return {s: s for s in symbols}
_LOGGER.debug("Demangling %d symbols using %s", len(symbols), cppfilt_cmd)
# Strip GCC optimization suffixes and prefixes before demangling
symbols_stripped: list[str] = []
symbols_prefixes: list[str] = []
for symbol in symbols:
stripped, prefix = _strip_gcc_annotations(symbol)
symbols_stripped.append(stripped)
symbols_prefixes.append(prefix)
try:
result = subprocess.run(
[cppfilt_cmd],
input="\n".join(symbols_stripped),
capture_output=True,
text=True,
check=False,
)
except (subprocess.SubprocessError, OSError, UnicodeDecodeError) as e:
_LOGGER.warning("Failed to batch demangle symbols: %s", e)
return {s: s for s in symbols}
if result.returncode != 0:
_LOGGER.warning(
"c++filt exited with code %d: %s",
result.returncode,
result.stderr[:200] if result.stderr else "(no error output)",
)
return {s: s for s in symbols}
# Process demangled output
demangled_lines = result.stdout.strip().split("\n")
# Check for output length mismatch
if len(demangled_lines) != len(symbols):
_LOGGER.warning(
"c++filt output mismatch: expected %d lines, got %d",
len(symbols),
len(demangled_lines),
)
return {s: s for s in symbols}
failed_count = 0
for original, stripped, prefix, demangled in zip(
symbols, symbols_stripped, symbols_prefixes, demangled_lines
):
# Add back any prefix that was removed
demangled = _restore_symbol_prefix(prefix, stripped, demangled)
# If we stripped a suffix, add it back to the demangled name for clarity
if original != stripped and not prefix:
demangled = _restore_symbol_suffix(original, demangled)
cache[original] = demangled
# Count symbols that failed to demangle
if stripped == demangled and stripped.startswith("_Z"):
failed_count += 1
if failed_count <= 5:
_LOGGER.debug("Failed to demangle: %s", original)
if failed_count > 0:
_LOGGER.debug(
"Failed to demangle %d/%d symbols using %s",
failed_count,
len(symbols),
cppfilt_cmd,
)
return cache

View File

@@ -0,0 +1,493 @@
"""Analyzer for RAM-stored strings in ESP8266/ESP32 firmware ELF files.
This module identifies strings that are stored in RAM sections (.data, .bss, .rodata)
rather than in flash sections (.irom0.text, .irom.text), which is important for
memory-constrained platforms like ESP8266.
"""
from __future__ import annotations
from collections import defaultdict
from dataclasses import dataclass
import logging
from pathlib import Path
import re
import subprocess
from .demangle import batch_demangle
from .toolchain import find_tool
_LOGGER = logging.getLogger(__name__)
# ESP8266: .rodata is in RAM (DRAM), not flash
# ESP32: .rodata is in flash, mapped to data bus
ESP8266_RAM_SECTIONS = frozenset([".data", ".rodata", ".bss"])
ESP8266_FLASH_SECTIONS = frozenset([".irom0.text", ".irom.text", ".text"])
# ESP32: .rodata is memory-mapped from flash
ESP32_RAM_SECTIONS = frozenset([".data", ".bss", ".dram0.data", ".dram0.bss"])
ESP32_FLASH_SECTIONS = frozenset([".text", ".rodata", ".flash.text", ".flash.rodata"])
# nm symbol types for data symbols (D=global data, d=local data, R=rodata, B=bss)
DATA_SYMBOL_TYPES = frozenset(["D", "d", "R", "r", "B", "b"])
@dataclass
class SectionInfo:
"""Information about an ELF section."""
name: str
address: int
size: int
@dataclass
class RamString:
"""A string found in RAM."""
section: str
address: int
content: str
@property
def size(self) -> int:
"""Size in bytes including null terminator."""
return len(self.content) + 1
@dataclass
class RamSymbol:
"""A symbol found in RAM."""
name: str
sym_type: str
address: int
size: int
section: str
demangled: str = "" # Demangled name, set after batch demangling
class RamStringsAnalyzer:
"""Analyzes ELF files to find strings stored in RAM."""
def __init__(
self,
elf_path: str,
objdump_path: str | None = None,
min_length: int = 8,
platform: str = "esp32",
) -> None:
"""Initialize the RAM strings analyzer.
Args:
elf_path: Path to the ELF file to analyze
objdump_path: Path to objdump binary (used to find other tools)
min_length: Minimum string length to report (default: 8)
platform: Platform name ("esp8266", "esp32", etc.) for section mapping
"""
self.elf_path = Path(elf_path)
if not self.elf_path.exists():
raise FileNotFoundError(f"ELF file not found: {elf_path}")
self.objdump_path = objdump_path
self.min_length = min_length
self.platform = platform
# Set RAM/flash sections based on platform
if self.platform == "esp8266":
self.ram_sections = ESP8266_RAM_SECTIONS
self.flash_sections = ESP8266_FLASH_SECTIONS
else:
# ESP32 and other platforms
self.ram_sections = ESP32_RAM_SECTIONS
self.flash_sections = ESP32_FLASH_SECTIONS
self.sections: dict[str, SectionInfo] = {}
self.ram_strings: list[RamString] = []
self.ram_symbols: list[RamSymbol] = []
def _run_command(self, cmd: list[str]) -> str:
"""Run a command and return its output."""
try:
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
return result.stdout
except subprocess.CalledProcessError as e:
_LOGGER.debug("Command failed: %s - %s", " ".join(cmd), e.stderr)
raise
except FileNotFoundError:
_LOGGER.warning("Command not found: %s", cmd[0])
raise
def analyze(self) -> None:
"""Perform the full RAM analysis."""
self._parse_sections()
self._extract_strings()
self._analyze_symbols()
self._demangle_symbols()
def _parse_sections(self) -> None:
"""Parse section headers from ELF file."""
objdump = find_tool("objdump", self.objdump_path)
if not objdump:
_LOGGER.error("Could not find objdump command")
return
try:
output = self._run_command([objdump, "-h", str(self.elf_path)])
except (subprocess.CalledProcessError, FileNotFoundError):
return
# Parse section headers
# Format: Idx Name Size VMA LMA File off Algn
section_pattern = re.compile(
r"^\s*\d+\s+(\S+)\s+([0-9a-fA-F]+)\s+([0-9a-fA-F]+)"
)
for line in output.split("\n"):
if match := section_pattern.match(line):
name = match.group(1)
size = int(match.group(2), 16)
vma = int(match.group(3), 16)
self.sections[name] = SectionInfo(name, vma, size)
def _extract_strings(self) -> None:
"""Extract strings from RAM sections."""
objdump = find_tool("objdump", self.objdump_path)
if not objdump:
return
for section_name in self.ram_sections:
if section_name not in self.sections:
continue
try:
output = self._run_command(
[objdump, "-s", "-j", section_name, str(self.elf_path)]
)
except subprocess.CalledProcessError:
# Section may exist but have no content (e.g., .bss)
continue
except FileNotFoundError:
continue
strings = self._parse_hex_dump(output, section_name)
self.ram_strings.extend(strings)
def _parse_hex_dump(self, output: str, section_name: str) -> list[RamString]:
"""Parse hex dump output to extract strings.
Args:
output: Output from objdump -s
section_name: Name of the section being parsed
Returns:
List of RamString objects
"""
strings: list[RamString] = []
current_string = bytearray()
string_start_addr = 0
for line in output.split("\n"):
# Lines look like: " 3ffef8a0 00000000 00000000 00000000 00000000 ................"
match = re.match(r"^\s+([0-9a-fA-F]+)\s+((?:[0-9a-fA-F]{2,8}\s*)+)", line)
if not match:
continue
addr = int(match.group(1), 16)
hex_data = match.group(2).strip()
# Convert hex to bytes
hex_bytes = hex_data.split()
byte_offset = 0
for hex_chunk in hex_bytes:
# Handle both byte-by-byte and word formats
for i in range(0, len(hex_chunk), 2):
byte_val = int(hex_chunk[i : i + 2], 16)
if 0x20 <= byte_val <= 0x7E: # Printable ASCII
if not current_string:
string_start_addr = addr + byte_offset
current_string.append(byte_val)
else:
if byte_val == 0 and len(current_string) >= self.min_length:
# Found null terminator
strings.append(
RamString(
section=section_name,
address=string_start_addr,
content=current_string.decode(
"ascii", errors="ignore"
),
)
)
current_string = bytearray()
byte_offset += 1
return strings
def _analyze_symbols(self) -> None:
"""Analyze symbols in RAM sections."""
nm = find_tool("nm", self.objdump_path)
if not nm:
return
try:
output = self._run_command([nm, "-S", "--size-sort", str(self.elf_path)])
except (subprocess.CalledProcessError, FileNotFoundError):
return
for line in output.split("\n"):
parts = line.split()
if len(parts) < 4:
continue
try:
addr = int(parts[0], 16)
size = int(parts[1], 16) if parts[1] != "?" else 0
except ValueError:
continue
sym_type = parts[2]
name = " ".join(parts[3:])
# Filter for data symbols
if sym_type not in DATA_SYMBOL_TYPES:
continue
# Check if symbol is in a RAM section
for section_name in self.ram_sections:
if section_name not in self.sections:
continue
section = self.sections[section_name]
if section.address <= addr < section.address + section.size:
self.ram_symbols.append(
RamSymbol(
name=name,
sym_type=sym_type,
address=addr,
size=size,
section=section_name,
)
)
break
def _demangle_symbols(self) -> None:
"""Batch demangle all RAM symbol names."""
if not self.ram_symbols:
return
# Collect all symbol names and demangle them
symbol_names = [s.name for s in self.ram_symbols]
demangle_cache = batch_demangle(symbol_names, objdump_path=self.objdump_path)
# Assign demangled names to symbols
for symbol in self.ram_symbols:
symbol.demangled = demangle_cache.get(symbol.name, symbol.name)
def _get_sections_size(self, section_names: frozenset[str]) -> int:
"""Get total size of specified sections."""
return sum(
section.size
for name, section in self.sections.items()
if name in section_names
)
def get_total_ram_usage(self) -> int:
"""Get total RAM usage from RAM sections."""
return self._get_sections_size(self.ram_sections)
def get_total_flash_usage(self) -> int:
"""Get total flash usage from flash sections."""
return self._get_sections_size(self.flash_sections)
def get_total_string_bytes(self) -> int:
"""Get total bytes used by strings in RAM."""
return sum(s.size for s in self.ram_strings)
def get_repeated_strings(self) -> list[tuple[str, int]]:
"""Find strings that appear multiple times.
Returns:
List of (string, count) tuples sorted by potential savings
"""
string_counts: dict[str, int] = defaultdict(int)
for ram_string in self.ram_strings:
string_counts[ram_string.content] += 1
return sorted(
[(s, c) for s, c in string_counts.items() if c > 1],
key=lambda x: x[1] * (len(x[0]) + 1),
reverse=True,
)
def get_long_strings(self, min_len: int = 20) -> list[RamString]:
"""Get strings longer than the specified length.
Args:
min_len: Minimum string length
Returns:
List of RamString objects sorted by length
"""
return sorted(
[s for s in self.ram_strings if len(s.content) >= min_len],
key=lambda x: len(x.content),
reverse=True,
)
def get_largest_symbols(self, min_size: int = 100) -> list[RamSymbol]:
"""Get RAM symbols larger than the specified size.
Args:
min_size: Minimum symbol size in bytes
Returns:
List of RamSymbol objects sorted by size
"""
return sorted(
[s for s in self.ram_symbols if s.size >= min_size],
key=lambda x: x.size,
reverse=True,
)
def generate_report(self, show_all_sections: bool = False) -> str:
"""Generate a formatted RAM strings analysis report.
Args:
show_all_sections: If True, show all sections, not just RAM
Returns:
Formatted report string
"""
lines: list[str] = []
table_width = 80
lines.append("=" * table_width)
lines.append(
f"RAM Strings Analysis ({self.platform.upper()})".center(table_width)
)
lines.append("=" * table_width)
lines.append("")
# Section Analysis
lines.append("SECTION ANALYSIS")
lines.append("-" * table_width)
lines.append(f"{'Section':<20} {'Address':<12} {'Size':<12} {'Location'}")
lines.append("-" * table_width)
total_ram_usage = 0
total_flash_usage = 0
for name, section in sorted(self.sections.items(), key=lambda x: x[1].address):
if name in self.ram_sections:
location = "RAM"
total_ram_usage += section.size
elif name in self.flash_sections:
location = "FLASH"
total_flash_usage += section.size
else:
location = "OTHER"
if show_all_sections or name in self.ram_sections:
lines.append(
f"{name:<20} 0x{section.address:08x} {section.size:>8} B {location}"
)
lines.append("-" * table_width)
lines.append(f"Total RAM sections size: {total_ram_usage:,} bytes")
lines.append(f"Total Flash sections size: {total_flash_usage:,} bytes")
# Strings in RAM
lines.append("")
lines.append("=" * table_width)
lines.append("STRINGS IN RAM SECTIONS")
lines.append("=" * table_width)
lines.append(
"Note: .bss sections contain uninitialized data (no strings to extract)"
)
# Group strings by section
strings_by_section: dict[str, list[RamString]] = defaultdict(list)
for ram_string in self.ram_strings:
strings_by_section[ram_string.section].append(ram_string)
for section_name in sorted(strings_by_section.keys()):
section_strings = strings_by_section[section_name]
lines.append(f"\nSection: {section_name}")
lines.append("-" * 40)
for ram_string in sorted(section_strings, key=lambda x: x.address):
clean_string = ram_string.content[:100] + (
"..." if len(ram_string.content) > 100 else ""
)
lines.append(
f' 0x{ram_string.address:08x}: "{clean_string}" (len={len(ram_string.content)})'
)
# Large RAM symbols
lines.append("")
lines.append("=" * table_width)
lines.append("LARGE DATA SYMBOLS IN RAM (>= 50 bytes)")
lines.append("=" * table_width)
largest_symbols = self.get_largest_symbols(50)
lines.append(f"\n{'Symbol':<50} {'Type':<6} {'Size':<10} {'Section'}")
lines.append("-" * table_width)
for symbol in largest_symbols:
# Use demangled name if available, otherwise raw name
display_name = symbol.demangled or symbol.name
name_display = display_name[:49] if len(display_name) > 49 else display_name
lines.append(
f"{name_display:<50} {symbol.sym_type:<6} {symbol.size:>8} B {symbol.section}"
)
# Summary
lines.append("")
lines.append("=" * table_width)
lines.append("SUMMARY")
lines.append("=" * table_width)
lines.append(f"Total strings found in RAM: {len(self.ram_strings)}")
total_string_bytes = self.get_total_string_bytes()
lines.append(f"Total bytes used by strings: {total_string_bytes:,}")
# Optimization targets
lines.append("")
lines.append("=" * table_width)
lines.append("POTENTIAL OPTIMIZATION TARGETS")
lines.append("=" * table_width)
# Repeated strings
repeated = self.get_repeated_strings()[:10]
if repeated:
lines.append("\nRepeated strings (could be deduplicated):")
for string, count in repeated:
savings = (count - 1) * (len(string) + 1)
clean_string = string[:50] + ("..." if len(string) > 50 else "")
lines.append(
f' "{clean_string}" - appears {count} times (potential savings: {savings} bytes)'
)
# Long strings - platform-specific advice
long_strings = self.get_long_strings(20)[:10]
if long_strings:
if self.platform == "esp8266":
lines.append(
"\nLong strings that could be moved to PROGMEM (>= 20 chars):"
)
else:
# ESP32: strings in DRAM are typically there for a reason
# (interrupt handlers, pre-flash-init code, etc.)
lines.append("\nLong strings in DRAM (>= 20 chars):")
lines.append(
"Note: ESP32 DRAM strings may be required for interrupt/early-boot contexts"
)
for ram_string in long_strings:
clean_string = ram_string.content[:60] + (
"..." if len(ram_string.content) > 60 else ""
)
lines.append(
f' {ram_string.section} @ 0x{ram_string.address:08x}: "{clean_string}" ({len(ram_string.content)} bytes)'
)
lines.append("")
return "\n".join(lines)

View File

@@ -0,0 +1,93 @@
"""Toolchain utilities for memory analysis."""
from __future__ import annotations
import logging
from pathlib import Path
import subprocess
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from collections.abc import Sequence
_LOGGER = logging.getLogger(__name__)
# Platform-specific toolchain prefixes
TOOLCHAIN_PREFIXES = [
"xtensa-lx106-elf-", # ESP8266
"xtensa-esp32-elf-", # ESP32
"xtensa-esp-elf-", # ESP32 (newer IDF)
"", # System default (no prefix)
]
def find_tool(
tool_name: str,
objdump_path: str | None = None,
) -> str | None:
"""Find a toolchain tool by name.
First tries to derive the tool path from objdump_path (if provided),
then falls back to searching for platform-specific tools.
Args:
tool_name: Name of the tool (e.g., "objdump", "nm", "c++filt")
objdump_path: Path to objdump binary to derive other tool paths from
Returns:
Path to the tool or None if not found
"""
# Try to derive from objdump path first (most reliable)
if objdump_path and objdump_path != "objdump":
objdump_file = Path(objdump_path)
# Replace just the filename portion, preserving any prefix (e.g., xtensa-esp32-elf-)
new_name = objdump_file.name.replace("objdump", tool_name)
potential_path = str(objdump_file.with_name(new_name))
if Path(potential_path).exists():
_LOGGER.debug("Found %s at: %s", tool_name, potential_path)
return potential_path
# Try platform-specific tools
for prefix in TOOLCHAIN_PREFIXES:
cmd = f"{prefix}{tool_name}"
try:
subprocess.run([cmd, "--version"], capture_output=True, check=True)
_LOGGER.debug("Found %s: %s", tool_name, cmd)
return cmd
except (subprocess.CalledProcessError, FileNotFoundError):
continue
_LOGGER.warning("Could not find %s tool", tool_name)
return None
def run_tool(
cmd: Sequence[str],
timeout: int = 30,
) -> subprocess.CompletedProcess[str] | None:
"""Run a toolchain command and return the result.
Args:
cmd: Command and arguments to run
timeout: Timeout in seconds
Returns:
CompletedProcess on success, None on failure
"""
try:
return subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=timeout,
check=False,
)
except subprocess.TimeoutExpired:
_LOGGER.warning("Command timed out: %s", " ".join(cmd))
return None
except FileNotFoundError:
_LOGGER.warning("Command not found: %s", cmd[0])
return None
except OSError as e:
_LOGGER.warning("Failed to run command %s: %s", cmd[0], e)
return None

View File

@@ -30,7 +30,9 @@ void A01nyubComponent::check_buffer_() {
ESP_LOGV(TAG, "Distance from sensor: %f mm, %f m", distance, meters);
this->publish_state(meters);
} else {
ESP_LOGW(TAG, "Invalid data read from sensor: %s", format_hex_pretty(this->buffer_).c_str());
char hex_buf[format_hex_pretty_size(4)];
ESP_LOGW(TAG, "Invalid data read from sensor: %s",
format_hex_pretty_to(hex_buf, this->buffer_.data(), this->buffer_.size()));
}
} else {
ESP_LOGW(TAG, "checksum failed: %02x != %02x", checksum, this->buffer_[3]);

View File

@@ -29,7 +29,9 @@ void A02yyuwComponent::check_buffer_() {
ESP_LOGV(TAG, "Distance from sensor: %f mm", distance);
this->publish_state(distance);
} else {
ESP_LOGW(TAG, "Invalid data read from sensor: %s", format_hex_pretty(this->buffer_).c_str());
char hex_buf[format_hex_pretty_size(4)];
ESP_LOGW(TAG, "Invalid data read from sensor: %s",
format_hex_pretty_to(hex_buf, this->buffer_.data(), this->buffer_.size()));
}
} else {
ESP_LOGW(TAG, "checksum failed: %02x != %02x", checksum, this->buffer_[3]);

View File

@@ -87,16 +87,19 @@ void AbsoluteHumidityComponent::loop() {
break;
default:
this->publish_state(NAN);
this->status_set_error("Invalid saturation vapor pressure equation selection!");
this->status_set_error(LOG_STR("Invalid saturation vapor pressure equation selection!"));
return;
}
ESP_LOGD(TAG, "Saturation vapor pressure %f kPa", es);
// Calculate absolute humidity
const float absolute_humidity = vapor_density(es, hr, temperature_k);
ESP_LOGD(TAG,
"Saturation vapor pressure %f kPa\n"
"Publishing absolute humidity %f g/m³",
es, absolute_humidity);
// Publish absolute humidity
ESP_LOGD(TAG, "Publishing absolute humidity %f g/m³", absolute_humidity);
this->status_clear_warning();
this->publish_state(absolute_humidity);
}
@@ -163,7 +166,7 @@ float AbsoluteHumidityComponent::es_wobus(float t) {
}
// From https://www.environmentalbiophysics.org/chalk-talk-how-to-calculate-absolute-humidity/
// H/T to https://esphome.io/cookbook/bme280_environment.html
// H/T to https://esphome.io/cookbook/bme280_environment/
// H/T to https://carnotcycle.wordpress.com/2012/08/04/how-to-convert-relative-humidity-to-absolute-humidity/
float AbsoluteHumidityComponent::vapor_density(float es, float hr, float ta) {
// es = saturated vapor pressure (kPa)

View File

@@ -1,5 +1,3 @@
#ifdef USE_ARDUINO
#include "ac_dimmer.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
@@ -9,12 +7,12 @@
#ifdef USE_ESP8266
#include <core_esp8266_waveform.h>
#endif
#ifdef USE_ESP32_FRAMEWORK_ARDUINO
#include <esp32-hal-timer.h>
#ifdef USE_ESP32
#include "hw_timer_esp_idf.h"
#endif
namespace esphome {
namespace ac_dimmer {
namespace esphome::ac_dimmer {
static const char *const TAG = "ac_dimmer";
@@ -27,7 +25,14 @@ static AcDimmerDataStore *all_dimmers[32]; // NOLINT(cppcoreguidelines-avoid-no
/// However other factors like gate driver propagation time
/// are also considered and a really low value is not important
/// See also: https://github.com/esphome/issues/issues/1632
static const uint32_t GATE_ENABLE_TIME = 50;
static constexpr uint32_t GATE_ENABLE_TIME = 50;
#ifdef USE_ESP32
/// Timer frequency in Hz (1 MHz = 1µs resolution)
static constexpr uint32_t TIMER_FREQUENCY_HZ = 1000000;
/// Timer interrupt interval in microseconds
static constexpr uint64_t TIMER_INTERVAL_US = 50;
#endif
/// Function called from timer interrupt
/// Input is current time in microseconds (micros())
@@ -154,7 +159,7 @@ void IRAM_ATTR HOT AcDimmerDataStore::s_gpio_intr(AcDimmerDataStore *store) {
#ifdef USE_ESP32
// ESP32 implementation, uses basically the same code but needs to wrap
// timer_interrupt() function to auto-reschedule
static hw_timer_t *dimmer_timer = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
static HWTimer *dimmer_timer = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
void IRAM_ATTR HOT AcDimmerDataStore::s_timer_intr() { timer_interrupt(); }
#endif
@@ -194,15 +199,15 @@ void AcDimmer::setup() {
setTimer1Callback(&timer_interrupt);
#endif
#ifdef USE_ESP32
// timer frequency of 1mhz
dimmer_timer = timerBegin(1000000);
timerAttachInterrupt(dimmer_timer, &AcDimmerDataStore::s_timer_intr);
dimmer_timer = timer_begin(TIMER_FREQUENCY_HZ);
timer_attach_interrupt(dimmer_timer, &AcDimmerDataStore::s_timer_intr);
// For ESP32, we can't use dynamic interval calculation because the timerX functions
// are not callable from ISR (placed in flash storage).
// Here we just use an interrupt firing every 50 µs.
timerAlarm(dimmer_timer, 50, true, 0);
timer_alarm(dimmer_timer, TIMER_INTERVAL_US, true, 0);
#endif
}
void AcDimmer::write_state(float state) {
state = std::acos(1 - (2 * state)) / std::numbers::pi; // RMS power compensation
auto new_value = static_cast<uint16_t>(roundf(state * 65535));
@@ -210,14 +215,15 @@ void AcDimmer::write_state(float state) {
this->store_.init_cycle = this->init_with_half_cycle_;
this->store_.value = new_value;
}
void AcDimmer::dump_config() {
ESP_LOGCONFIG(TAG, "AcDimmer:");
LOG_PIN(" Output Pin: ", this->gate_pin_);
LOG_PIN(" Zero-Cross Pin: ", this->zero_cross_pin_);
ESP_LOGCONFIG(TAG,
"AcDimmer:\n"
" Min Power: %.1f%%\n"
" Init with half cycle: %s",
this->store_.min_power / 10.0f, YESNO(this->init_with_half_cycle_));
LOG_PIN(" Output Pin: ", this->gate_pin_);
LOG_PIN(" Zero-Cross Pin: ", this->zero_cross_pin_);
if (method_ == DIM_METHOD_LEADING_PULSE) {
ESP_LOGCONFIG(TAG, " Method: leading pulse");
} else if (method_ == DIM_METHOD_LEADING) {
@@ -230,7 +236,4 @@ void AcDimmer::dump_config() {
ESP_LOGV(TAG, " Estimated Frequency: %.3fHz", 1e6f / this->store_.cycle_time_us / 2);
}
} // namespace ac_dimmer
} // namespace esphome
#endif // USE_ARDUINO
} // namespace esphome::ac_dimmer

View File

@@ -1,13 +1,10 @@
#pragma once
#ifdef USE_ARDUINO
#include "esphome/core/component.h"
#include "esphome/core/hal.h"
#include "esphome/components/output/float_output.h"
namespace esphome {
namespace ac_dimmer {
namespace esphome::ac_dimmer {
enum DimMethod { DIM_METHOD_LEADING_PULSE = 0, DIM_METHOD_LEADING, DIM_METHOD_TRAILING };
@@ -64,7 +61,4 @@ class AcDimmer : public output::FloatOutput, public Component {
DimMethod method_;
};
} // namespace ac_dimmer
} // namespace esphome
#endif // USE_ARDUINO
} // namespace esphome::ac_dimmer

View File

@@ -0,0 +1,152 @@
#ifdef USE_ESP32
#include "hw_timer_esp_idf.h"
#include "freertos/FreeRTOS.h"
#include "esphome/core/log.h"
#include "driver/gptimer.h"
#include "esp_clk_tree.h"
#include "soc/clk_tree_defs.h"
static const char *const TAG = "hw_timer_esp_idf";
namespace esphome::ac_dimmer {
// GPTimer divider constraints from ESP-IDF documentation
static constexpr uint32_t GPTIMER_DIVIDER_MIN = 2;
static constexpr uint32_t GPTIMER_DIVIDER_MAX = 65536;
using voidFuncPtr = void (*)();
using voidFuncPtrArg = void (*)(void *);
struct InterruptConfigT {
voidFuncPtr fn{nullptr};
void *arg{nullptr};
};
struct HWTimer {
gptimer_handle_t timer_handle{nullptr};
InterruptConfigT interrupt_handle{};
bool timer_started{false};
};
HWTimer *timer_begin(uint32_t frequency) {
esp_err_t err = ESP_OK;
uint32_t counter_src_hz = 0;
uint32_t divider = 0;
soc_module_clk_t clk;
for (auto clk_candidate : SOC_GPTIMER_CLKS) {
clk = clk_candidate;
esp_clk_tree_src_get_freq_hz(clk, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &counter_src_hz);
divider = counter_src_hz / frequency;
if ((divider >= GPTIMER_DIVIDER_MIN) && (divider <= GPTIMER_DIVIDER_MAX)) {
break;
} else {
divider = 0;
}
}
if (divider == 0) {
ESP_LOGE(TAG, "Resolution not possible; aborting");
return nullptr;
}
gptimer_config_t config = {
.clk_src = static_cast<gptimer_clock_source_t>(clk),
.direction = GPTIMER_COUNT_UP,
.resolution_hz = frequency,
.flags = {.intr_shared = true},
};
HWTimer *timer = new HWTimer();
err = gptimer_new_timer(&config, &timer->timer_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "GPTimer creation failed; error %d", err);
delete timer;
return nullptr;
}
err = gptimer_enable(timer->timer_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "GPTimer enable failed; error %d", err);
gptimer_del_timer(timer->timer_handle);
delete timer;
return nullptr;
}
err = gptimer_start(timer->timer_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "GPTimer start failed; error %d", err);
gptimer_disable(timer->timer_handle);
gptimer_del_timer(timer->timer_handle);
delete timer;
return nullptr;
}
timer->timer_started = true;
return timer;
}
bool IRAM_ATTR timer_fn_wrapper(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *args) {
auto *isr = static_cast<InterruptConfigT *>(args);
if (isr->fn) {
if (isr->arg) {
reinterpret_cast<voidFuncPtrArg>(isr->fn)(isr->arg);
} else {
isr->fn();
}
}
// Return false to indicate that no higher-priority task was woken and no context switch is requested.
return false;
}
static void timer_attach_interrupt_functional_arg(HWTimer *timer, void (*user_func)(void *), void *arg) {
if (timer == nullptr) {
ESP_LOGE(TAG, "Timer handle is nullptr");
return;
}
gptimer_event_callbacks_t cbs = {
.on_alarm = timer_fn_wrapper,
};
timer->interrupt_handle.fn = reinterpret_cast<voidFuncPtr>(user_func);
timer->interrupt_handle.arg = arg;
if (timer->timer_started) {
gptimer_stop(timer->timer_handle);
}
gptimer_disable(timer->timer_handle);
esp_err_t err = gptimer_register_event_callbacks(timer->timer_handle, &cbs, &timer->interrupt_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Timer Attach Interrupt failed; error %d", err);
}
gptimer_enable(timer->timer_handle);
if (timer->timer_started) {
gptimer_start(timer->timer_handle);
}
}
void timer_attach_interrupt(HWTimer *timer, voidFuncPtr user_func) {
timer_attach_interrupt_functional_arg(timer, reinterpret_cast<voidFuncPtrArg>(user_func), nullptr);
}
void timer_alarm(HWTimer *timer, uint64_t alarm_value, bool autoreload, uint64_t reload_count) {
if (timer == nullptr) {
ESP_LOGE(TAG, "Timer handle is nullptr");
return;
}
gptimer_alarm_config_t alarm_cfg = {
.alarm_count = alarm_value,
.reload_count = reload_count,
.flags = {.auto_reload_on_alarm = autoreload},
};
esp_err_t err = gptimer_set_alarm_action(timer->timer_handle, &alarm_cfg);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Timer Alarm Write failed; error %d", err);
}
}
} // namespace esphome::ac_dimmer
#endif

View File

@@ -0,0 +1,17 @@
#pragma once
#ifdef USE_ESP32
#include "driver/gptimer_types.h"
namespace esphome::ac_dimmer {
struct HWTimer;
HWTimer *timer_begin(uint32_t frequency);
void timer_attach_interrupt(HWTimer *timer, void (*user_func)());
void timer_alarm(HWTimer *timer, uint64_t alarm_value, bool autoreload, uint64_t reload_count);
} // namespace esphome::ac_dimmer
#endif

View File

@@ -3,6 +3,7 @@ import esphome.codegen as cg
from esphome.components import output
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_METHOD, CONF_MIN_POWER
from esphome.core import CORE
CODEOWNERS = ["@glmnet"]
@@ -31,11 +32,16 @@ CONFIG_SCHEMA = cv.All(
),
}
).extend(cv.COMPONENT_SCHEMA),
cv.only_with_arduino,
)
async def to_code(config):
if CORE.is_esp8266:
# ac_dimmer uses setTimer1Callback which requires the waveform generator
from esphome.components.esp8266.const import require_waveform
require_waveform()
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)

View File

@@ -1,15 +1,17 @@
from esphome import pins
import esphome.codegen as cg
from esphome.components.esp32 import VARIANT_ESP32P4, get_esp32_variant
from esphome.components.esp32.const import (
from esphome.components.esp32 import (
VARIANT_ESP32,
VARIANT_ESP32C2,
VARIANT_ESP32C3,
VARIANT_ESP32C5,
VARIANT_ESP32C6,
VARIANT_ESP32C61,
VARIANT_ESP32H2,
VARIANT_ESP32P4,
VARIANT_ESP32S2,
VARIANT_ESP32S3,
get_esp32_variant,
)
import esphome.config_validation as cv
from esphome.const import CONF_ANALOG, CONF_INPUT, CONF_NUMBER, PLATFORM_ESP8266
@@ -99,6 +101,13 @@ ESP32_VARIANT_ADC1_PIN_TO_CHANNEL = {
5: adc_channel_t.ADC_CHANNEL_5,
6: adc_channel_t.ADC_CHANNEL_6,
},
# https://docs.espressif.com/projects/esp-idf/en/latest/esp32c61/api-reference/peripherals/gpio.html
VARIANT_ESP32C61: {
1: adc_channel_t.ADC_CHANNEL_0,
3: adc_channel_t.ADC_CHANNEL_1,
4: adc_channel_t.ADC_CHANNEL_2,
5: adc_channel_t.ADC_CHANNEL_3,
},
# https://github.com/espressif/esp-idf/blob/master/components/soc/esp32h2/include/soc/adc_channel.h
VARIANT_ESP32H2: {
1: adc_channel_t.ADC_CHANNEL_0,
@@ -107,6 +116,17 @@ ESP32_VARIANT_ADC1_PIN_TO_CHANNEL = {
4: adc_channel_t.ADC_CHANNEL_3,
5: adc_channel_t.ADC_CHANNEL_4,
},
# https://github.com/espressif/esp-idf/blob/master/components/soc/esp32p4/include/soc/adc_channel.h
VARIANT_ESP32P4: {
16: adc_channel_t.ADC_CHANNEL_0,
17: adc_channel_t.ADC_CHANNEL_1,
18: adc_channel_t.ADC_CHANNEL_2,
19: adc_channel_t.ADC_CHANNEL_3,
20: adc_channel_t.ADC_CHANNEL_4,
21: adc_channel_t.ADC_CHANNEL_5,
22: adc_channel_t.ADC_CHANNEL_6,
23: adc_channel_t.ADC_CHANNEL_7,
},
# https://github.com/espressif/esp-idf/blob/master/components/soc/esp32s2/include/soc/adc_channel.h
VARIANT_ESP32S2: {
1: adc_channel_t.ADC_CHANNEL_0,
@@ -133,16 +153,6 @@ ESP32_VARIANT_ADC1_PIN_TO_CHANNEL = {
9: adc_channel_t.ADC_CHANNEL_8,
10: adc_channel_t.ADC_CHANNEL_9,
},
VARIANT_ESP32P4: {
16: adc_channel_t.ADC_CHANNEL_0,
17: adc_channel_t.ADC_CHANNEL_1,
18: adc_channel_t.ADC_CHANNEL_2,
19: adc_channel_t.ADC_CHANNEL_3,
20: adc_channel_t.ADC_CHANNEL_4,
21: adc_channel_t.ADC_CHANNEL_5,
22: adc_channel_t.ADC_CHANNEL_6,
23: adc_channel_t.ADC_CHANNEL_7,
},
}
# pin to adc2 channel mapping
@@ -173,8 +183,19 @@ ESP32_VARIANT_ADC2_PIN_TO_CHANNEL = {
VARIANT_ESP32C5: {}, # no ADC2
# https://github.com/espressif/esp-idf/blob/master/components/soc/esp32c6/include/soc/adc_channel.h
VARIANT_ESP32C6: {}, # no ADC2
# ESP32-C61 has no ADC2
VARIANT_ESP32C61: {}, # no ADC2
# https://github.com/espressif/esp-idf/blob/master/components/soc/esp32h2/include/soc/adc_channel.h
VARIANT_ESP32H2: {}, # no ADC2
# https://github.com/espressif/esp-idf/blob/master/components/soc/esp32p4/include/soc/adc_channel.h
VARIANT_ESP32P4: {
49: adc_channel_t.ADC_CHANNEL_0,
50: adc_channel_t.ADC_CHANNEL_1,
51: adc_channel_t.ADC_CHANNEL_2,
52: adc_channel_t.ADC_CHANNEL_3,
53: adc_channel_t.ADC_CHANNEL_4,
54: adc_channel_t.ADC_CHANNEL_5,
},
# https://github.com/espressif/esp-idf/blob/master/components/soc/esp32s2/include/soc/adc_channel.h
VARIANT_ESP32S2: {
11: adc_channel_t.ADC_CHANNEL_0,
@@ -201,14 +222,6 @@ ESP32_VARIANT_ADC2_PIN_TO_CHANNEL = {
19: adc_channel_t.ADC_CHANNEL_8,
20: adc_channel_t.ADC_CHANNEL_9,
},
VARIANT_ESP32P4: {
49: adc_channel_t.ADC_CHANNEL_0,
50: adc_channel_t.ADC_CHANNEL_1,
51: adc_channel_t.ADC_CHANNEL_2,
52: adc_channel_t.ADC_CHANNEL_3,
53: adc_channel_t.ADC_CHANNEL_4,
54: adc_channel_t.ADC_CHANNEL_5,
},
}

View File

@@ -42,10 +42,11 @@ void ADCSensor::setup() {
adc_oneshot_unit_init_cfg_t init_config = {}; // Zero initialize
init_config.unit_id = this->adc_unit_;
init_config.ulp_mode = ADC_ULP_MODE_DISABLE;
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || USE_ESP32_VARIANT_ESP32H2
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2
init_config.clk_src = ADC_DIGI_CLK_SRC_DEFAULT;
#endif // USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 ||
// USE_ESP32_VARIANT_ESP32H2
// USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2
esp_err_t err = adc_oneshot_new_unit(&init_config, &ADCSensor::shared_adc_handles[this->adc_unit_]);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error initializing %s: %d", LOG_STR_ARG(adc_unit_to_str(this->adc_unit_)), err);
@@ -74,7 +75,7 @@ void ADCSensor::setup() {
adc_cali_handle_t handle = nullptr;
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
// RISC-V variants and S3 use curve fitting calibration
adc_cali_curve_fitting_config_t cali_config = {}; // Zero initialize first
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
@@ -111,7 +112,7 @@ void ADCSensor::setup() {
ESP_LOGW(TAG, "Line fitting calibration failed with error %d, will use uncalibrated readings", err);
this->setup_flags_.calibration_complete = false;
}
#endif // USE_ESP32_VARIANT_ESP32C3 || ESP32C5 || ESP32C6 || ESP32S3 || ESP32H2
#endif // USE_ESP32_VARIANT_ESP32C3 || ESP32C5 || ESP32C6 || ESP32C61 || ESP32H2 || ESP32P4 || ESP32S3
}
this->setup_flags_.init_complete = true;
@@ -120,23 +121,21 @@ void ADCSensor::setup() {
void ADCSensor::dump_config() {
LOG_SENSOR("", "ADC Sensor", this);
LOG_PIN(" Pin: ", this->pin_);
ESP_LOGCONFIG(TAG,
" Channel: %d\n"
" Unit: %s\n"
" Attenuation: %s\n"
" Samples: %i\n"
" Sampling mode: %s",
this->channel_, LOG_STR_ARG(adc_unit_to_str(this->adc_unit_)),
this->autorange_ ? "Auto" : LOG_STR_ARG(attenuation_to_str(this->attenuation_)), this->sample_count_,
LOG_STR_ARG(sampling_mode_to_str(this->sampling_mode_)));
ESP_LOGCONFIG(
TAG,
" Channel: %d\n"
" Unit: %s\n"
" Attenuation: %s\n"
" Samples: %i\n"
" Sampling mode: %s\n"
" Setup Status:\n"
" Handle Init: %s\n"
" Config: %s\n"
" Calibration: %s\n"
" Overall Init: %s",
this->channel_, LOG_STR_ARG(adc_unit_to_str(this->adc_unit_)),
this->autorange_ ? "Auto" : LOG_STR_ARG(attenuation_to_str(this->attenuation_)), this->sample_count_,
LOG_STR_ARG(sampling_mode_to_str(this->sampling_mode_)),
this->setup_flags_.handle_init_complete ? "OK" : "FAILED", this->setup_flags_.config_complete ? "OK" : "FAILED",
this->setup_flags_.calibration_complete ? "OK" : "FAILED", this->setup_flags_.init_complete ? "OK" : "FAILED");
@@ -186,11 +185,11 @@ float ADCSensor::sample_fixed_attenuation_() {
ESP_LOGW(TAG, "ADC calibration conversion failed with error %d, disabling calibration", err);
if (this->calibration_handle_ != nullptr) {
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
adc_cali_delete_scheme_curve_fitting(this->calibration_handle_);
#else // Other ESP32 variants use line fitting calibration
adc_cali_delete_scheme_line_fitting(this->calibration_handle_);
#endif // USE_ESP32_VARIANT_ESP32C3 || ESP32C5 || ESP32C6 || ESP32S3 || ESP32H2
#endif // USE_ESP32_VARIANT_ESP32C3 || ESP32C5 || ESP32C6 || ESP32C61 || ESP32H2 || ESP32P4 || ESP32S3
this->calibration_handle_ = nullptr;
}
}
@@ -219,7 +218,7 @@ float ADCSensor::sample_autorange_() {
if (this->calibration_handle_ != nullptr) {
// Delete old calibration handle
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
adc_cali_delete_scheme_curve_fitting(this->calibration_handle_);
#else
adc_cali_delete_scheme_line_fitting(this->calibration_handle_);
@@ -231,7 +230,7 @@ float ADCSensor::sample_autorange_() {
adc_cali_handle_t handle = nullptr;
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
adc_cali_curve_fitting_config_t cali_config = {};
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
cali_config.chan = this->channel_;
@@ -266,7 +265,7 @@ float ADCSensor::sample_autorange_() {
ESP_LOGW(TAG, "ADC read failed in autorange with error %d", err);
if (handle != nullptr) {
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
adc_cali_delete_scheme_curve_fitting(handle);
#else
adc_cali_delete_scheme_line_fitting(handle);
@@ -288,7 +287,7 @@ float ADCSensor::sample_autorange_() {
}
// Clean up calibration handle
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
adc_cali_delete_scheme_curve_fitting(handle);
#else
adc_cali_delete_scheme_line_fitting(handle);

View File

@@ -25,11 +25,13 @@ class AddressableLightDisplay : public display::DisplayBuffer {
if (enabled_ && !enabled) { // enabled -> disabled
// - Tell the parent light to refresh, effectively wiping the display. Also
// restores the previous effect (if any).
light_state_->make_call().set_effect(this->last_effect_).perform();
if (this->last_effect_index_.has_value()) {
light_state_->make_call().set_effect(*this->last_effect_index_).perform();
}
} else if (!enabled_ && enabled) { // disabled -> enabled
// - Save the current effect.
this->last_effect_ = light_state_->get_effect_name();
// - Save the current effect index.
this->last_effect_index_ = light_state_->get_current_effect_index();
// - Disable any current effect.
light_state_->make_call().set_effect(0).perform();
}
@@ -56,7 +58,7 @@ class AddressableLightDisplay : public display::DisplayBuffer {
int32_t width_;
int32_t height_;
std::vector<Color> addressable_light_buffer_;
optional<std::string> last_effect_;
optional<uint32_t> last_effect_index_;
optional<std::function<int(int, int)>> pixel_mapper_f_;
};
} // namespace addressable_light

View File

@@ -162,11 +162,13 @@ void ADE7880::update() {
}
void ADE7880::dump_config() {
ESP_LOGCONFIG(TAG, "ADE7880:");
ESP_LOGCONFIG(TAG,
"ADE7880:\n"
" Frequency: %.0f Hz",
this->frequency_);
LOG_PIN(" IRQ0 Pin: ", this->irq0_pin_);
LOG_PIN(" IRQ1 Pin: ", this->irq1_pin_);
LOG_PIN(" RESET Pin: ", this->reset_pin_);
ESP_LOGCONFIG(TAG, " Frequency: %.0f Hz", this->frequency_);
if (this->channel_a_ != nullptr) {
ESP_LOGCONFIG(TAG, " Phase A:");

View File

@@ -227,7 +227,7 @@ CONFIG_SCHEMA = cv.All(
{
cv.GenerateID(): cv.declare_id(ADE7880),
cv.Optional(CONF_FREQUENCY, default="50Hz"): cv.All(
cv.frequency, cv.Range(min=45.0, max=66.0)
cv.frequency, cv.float_range(min=45.0, max=66.0)
),
cv.Optional(CONF_IRQ0_PIN): pins.internal_gpio_input_pin_schema,
cv.Required(CONF_IRQ1_PIN): pins.internal_gpio_input_pin_schema,

View File

@@ -24,6 +24,8 @@ from esphome.const import (
UNIT_WATT,
)
CODEOWNERS = ["@angelnu"]
CONF_CURRENT_A = "current_a"
CONF_CURRENT_B = "current_b"
CONF_ACTIVE_POWER_A = "active_power_a"

View File

@@ -25,7 +25,8 @@ void ADE7953::setup() {
this->ade_write_8(PGA_V_8, pga_v_);
this->ade_write_8(PGA_IA_8, pga_ia_);
this->ade_write_8(PGA_IB_8, pga_ib_);
this->ade_write_32(AVGAIN_32, vgain_);
this->ade_write_32(AVGAIN_32, avgain_);
this->ade_write_32(BVGAIN_32, bvgain_);
this->ade_write_32(AIGAIN_32, aigain_);
this->ade_write_32(BIGAIN_32, bigain_);
this->ade_write_32(AWGAIN_32, awgain_);
@@ -34,7 +35,8 @@ void ADE7953::setup() {
this->ade_read_8(PGA_V_8, &pga_v_);
this->ade_read_8(PGA_IA_8, &pga_ia_);
this->ade_read_8(PGA_IB_8, &pga_ib_);
this->ade_read_32(AVGAIN_32, &vgain_);
this->ade_read_32(AVGAIN_32, &avgain_);
this->ade_read_32(BVGAIN_32, &bvgain_);
this->ade_read_32(AIGAIN_32, &aigain_);
this->ade_read_32(BIGAIN_32, &bigain_);
this->ade_read_32(AWGAIN_32, &awgain_);
@@ -63,13 +65,14 @@ void ADE7953::dump_config() {
" PGA_V_8: 0x%X\n"
" PGA_IA_8: 0x%X\n"
" PGA_IB_8: 0x%X\n"
" VGAIN_32: 0x%08jX\n"
" AVGAIN_32: 0x%08jX\n"
" BVGAIN_32: 0x%08jX\n"
" AIGAIN_32: 0x%08jX\n"
" BIGAIN_32: 0x%08jX\n"
" AWGAIN_32: 0x%08jX\n"
" BWGAIN_32: 0x%08jX",
this->use_acc_energy_regs_, pga_v_, pga_ia_, pga_ib_, (uintmax_t) vgain_, (uintmax_t) aigain_,
(uintmax_t) bigain_, (uintmax_t) awgain_, (uintmax_t) bwgain_);
this->use_acc_energy_regs_, pga_v_, pga_ia_, pga_ib_, (uintmax_t) avgain_, (uintmax_t) bvgain_,
(uintmax_t) aigain_, (uintmax_t) bigain_, (uintmax_t) awgain_, (uintmax_t) bwgain_);
}
#define ADE_PUBLISH_(name, val, factor) \

View File

@@ -46,7 +46,12 @@ class ADE7953 : public PollingComponent, public sensor::Sensor {
void set_pga_ib(uint8_t pga_ib) { pga_ib_ = pga_ib; }
// Set input gains
void set_vgain(uint32_t vgain) { vgain_ = vgain; }
void set_vgain(uint32_t vgain) {
// Datasheet says: "to avoid discrepancies in other registers,
// if AVGAIN is set then BVGAIN should be set to the same value."
avgain_ = vgain;
bvgain_ = vgain;
}
void set_aigain(uint32_t aigain) { aigain_ = aigain; }
void set_bigain(uint32_t bigain) { bigain_ = bigain; }
void set_awgain(uint32_t awgain) { awgain_ = awgain; }
@@ -100,7 +105,8 @@ class ADE7953 : public PollingComponent, public sensor::Sensor {
uint8_t pga_v_;
uint8_t pga_ia_;
uint8_t pga_ib_;
uint32_t vgain_;
uint32_t avgain_;
uint32_t bvgain_;
uint32_t aigain_;
uint32_t bigain_;
uint32_t awgain_;

View File

@@ -21,10 +21,12 @@ void ADS1115Sensor::update() {
void ADS1115Sensor::dump_config() {
LOG_SENSOR(" ", "ADS1115 Sensor", this);
ESP_LOGCONFIG(TAG, " Multiplexer: %u", this->multiplexer_);
ESP_LOGCONFIG(TAG, " Gain: %u", this->gain_);
ESP_LOGCONFIG(TAG, " Resolution: %u", this->resolution_);
ESP_LOGCONFIG(TAG, " Sample rate: %u", this->samplerate_);
ESP_LOGCONFIG(TAG,
" Multiplexer: %u\n"
" Gain: %u\n"
" Resolution: %u\n"
" Sample rate: %u",
this->multiplexer_, this->gain_, this->resolution_, this->samplerate_);
}
} // namespace ads1115

View File

@@ -9,8 +9,10 @@ static const char *const TAG = "ads1118.sensor";
void ADS1118Sensor::dump_config() {
LOG_SENSOR(" ", "ADS1118 Sensor", this);
ESP_LOGCONFIG(TAG, " Multiplexer: %u", this->multiplexer_);
ESP_LOGCONFIG(TAG, " Gain: %u", this->gain_);
ESP_LOGCONFIG(TAG,
" Multiplexer: %u\n"
" Gain: %u",
this->multiplexer_, this->gain_);
}
float ADS1118Sensor::sample() {

View File

@@ -83,7 +83,7 @@ void AHT10Component::setup() {
void AHT10Component::restart_read_() {
if (this->read_count_ == AHT10_ATTEMPTS) {
this->read_count_ = 0;
this->status_set_error("Reading timed out");
this->status_set_error(LOG_STR("Reading timed out"));
return;
}
this->read_count_++;

View File

@@ -20,7 +20,8 @@ bool AirthingsListener::parse_device(const esp32_ble_tracker::ESPBTDevice &devic
sn |= ((uint32_t) it.data[2] << 16);
sn |= ((uint32_t) it.data[3] << 24);
ESP_LOGD(TAG, "Found AirThings device Serial:%" PRIu32 " (MAC: %s)", sn, device.address_str().c_str());
char addr_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE];
ESP_LOGD(TAG, "Found AirThings device Serial:%" PRIu32 " (MAC: %s)", sn, device.address_str_to(addr_buf));
return true;
}
}

View File

@@ -1,4 +1,5 @@
#include "airthings_wave_base.h"
#include "esphome/components/esp32_ble/ble_uuid.h"
// All information related to reading battery information came from the sensors.airthings_wave
// project by Sverre Hamre (https://github.com/sverrham/sensor.airthings_wave)
@@ -93,8 +94,10 @@ void AirthingsWaveBase::update() {
bool AirthingsWaveBase::request_read_values_() {
auto *chr = this->parent()->get_characteristic(this->service_uuid_, this->sensors_data_characteristic_uuid_);
if (chr == nullptr) {
ESP_LOGW(TAG, "No sensor characteristic found at service %s char %s", this->service_uuid_.to_string().c_str(),
this->sensors_data_characteristic_uuid_.to_string().c_str());
char service_buf[esp32_ble::UUID_STR_LEN];
char char_buf[esp32_ble::UUID_STR_LEN];
ESP_LOGW(TAG, "No sensor characteristic found at service %s char %s", this->service_uuid_.to_str(service_buf),
this->sensors_data_characteristic_uuid_.to_str(char_buf));
return false;
}
@@ -117,17 +120,20 @@ bool AirthingsWaveBase::request_battery_() {
auto *chr = this->parent()->get_characteristic(this->service_uuid_, this->access_control_point_characteristic_uuid_);
if (chr == nullptr) {
char service_buf[esp32_ble::UUID_STR_LEN];
char char_buf[esp32_ble::UUID_STR_LEN];
ESP_LOGW(TAG, "No access control point characteristic found at service %s char %s",
this->service_uuid_.to_string().c_str(),
this->access_control_point_characteristic_uuid_.to_string().c_str());
this->service_uuid_.to_str(service_buf), this->access_control_point_characteristic_uuid_.to_str(char_buf));
return false;
}
auto *descr = this->parent()->get_descriptor(this->service_uuid_, this->access_control_point_characteristic_uuid_,
CLIENT_CHARACTERISTIC_CONFIGURATION_DESCRIPTOR_UUID);
if (descr == nullptr) {
ESP_LOGW(TAG, "No CCC descriptor found at service %s char %s", this->service_uuid_.to_string().c_str(),
this->access_control_point_characteristic_uuid_.to_string().c_str());
char service_buf[esp32_ble::UUID_STR_LEN];
char char_buf[esp32_ble::UUID_STR_LEN];
ESP_LOGW(TAG, "No CCC descriptor found at service %s char %s", this->service_uuid_.to_str(service_buf),
this->access_control_point_characteristic_uuid_.to_str(char_buf));
return false;
}

View File

@@ -8,8 +8,7 @@
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace alarm_control_panel {
namespace esphome::alarm_control_panel {
static const char *const TAG = "alarm_control_panel";
@@ -35,26 +34,12 @@ void AlarmControlPanel::publish_state(AlarmControlPanelState state) {
ESP_LOGD(TAG, "Set state to: %s, previous: %s", LOG_STR_ARG(alarm_control_panel_state_to_string(state)),
LOG_STR_ARG(alarm_control_panel_state_to_string(prev_state)));
this->current_state_ = state;
// Single state callback - triggers check get_state() for specific states
this->state_callback_.call();
#if defined(USE_ALARM_CONTROL_PANEL) && defined(USE_CONTROLLER_REGISTRY)
ControllerRegistry::notify_alarm_control_panel_update(this);
#endif
if (state == ACP_STATE_TRIGGERED) {
this->triggered_callback_.call();
} else if (state == ACP_STATE_ARMING) {
this->arming_callback_.call();
} else if (state == ACP_STATE_PENDING) {
this->pending_callback_.call();
} else if (state == ACP_STATE_ARMED_HOME) {
this->armed_home_callback_.call();
} else if (state == ACP_STATE_ARMED_NIGHT) {
this->armed_night_callback_.call();
} else if (state == ACP_STATE_ARMED_AWAY) {
this->armed_away_callback_.call();
} else if (state == ACP_STATE_DISARMED) {
this->disarmed_callback_.call();
}
// Cleared fires when leaving TRIGGERED state
if (prev_state == ACP_STATE_TRIGGERED) {
this->cleared_callback_.call();
}
@@ -69,34 +54,6 @@ void AlarmControlPanel::add_on_state_callback(std::function<void()> &&callback)
this->state_callback_.add(std::move(callback));
}
void AlarmControlPanel::add_on_triggered_callback(std::function<void()> &&callback) {
this->triggered_callback_.add(std::move(callback));
}
void AlarmControlPanel::add_on_arming_callback(std::function<void()> &&callback) {
this->arming_callback_.add(std::move(callback));
}
void AlarmControlPanel::add_on_armed_home_callback(std::function<void()> &&callback) {
this->armed_home_callback_.add(std::move(callback));
}
void AlarmControlPanel::add_on_armed_night_callback(std::function<void()> &&callback) {
this->armed_night_callback_.add(std::move(callback));
}
void AlarmControlPanel::add_on_armed_away_callback(std::function<void()> &&callback) {
this->armed_away_callback_.add(std::move(callback));
}
void AlarmControlPanel::add_on_pending_callback(std::function<void()> &&callback) {
this->pending_callback_.add(std::move(callback));
}
void AlarmControlPanel::add_on_disarmed_callback(std::function<void()> &&callback) {
this->disarmed_callback_.add(std::move(callback));
}
void AlarmControlPanel::add_on_cleared_callback(std::function<void()> &&callback) {
this->cleared_callback_.add(std::move(callback));
}
@@ -157,5 +114,4 @@ void AlarmControlPanel::disarm(optional<std::string> code) {
call.perform();
}
} // namespace alarm_control_panel
} // namespace esphome
} // namespace esphome::alarm_control_panel

View File

@@ -1,7 +1,5 @@
#pragma once
#include <map>
#include "alarm_control_panel_call.h"
#include "alarm_control_panel_state.h"
@@ -9,8 +7,7 @@
#include "esphome/core/entity_base.h"
#include "esphome/core/log.h"
namespace esphome {
namespace alarm_control_panel {
namespace esphome::alarm_control_panel {
enum AlarmControlPanelFeature : uint8_t {
// Matches Home Assistant values
@@ -35,54 +32,13 @@ class AlarmControlPanel : public EntityBase {
*/
void publish_state(AlarmControlPanelState state);
/** Add a callback for when the state of the alarm_control_panel changes
/** Add a callback for when the state of the alarm_control_panel changes.
* Triggers can check get_state() to determine the new state.
*
* @param callback The callback function
*/
void add_on_state_callback(std::function<void()> &&callback);
/** Add a callback for when the state of the alarm_control_panel chanes to triggered
*
* @param callback The callback function
*/
void add_on_triggered_callback(std::function<void()> &&callback);
/** Add a callback for when the state of the alarm_control_panel chanes to arming
*
* @param callback The callback function
*/
void add_on_arming_callback(std::function<void()> &&callback);
/** Add a callback for when the state of the alarm_control_panel changes to pending
*
* @param callback The callback function
*/
void add_on_pending_callback(std::function<void()> &&callback);
/** Add a callback for when the state of the alarm_control_panel changes to armed_home
*
* @param callback The callback function
*/
void add_on_armed_home_callback(std::function<void()> &&callback);
/** Add a callback for when the state of the alarm_control_panel changes to armed_night
*
* @param callback The callback function
*/
void add_on_armed_night_callback(std::function<void()> &&callback);
/** Add a callback for when the state of the alarm_control_panel changes to armed_away
*
* @param callback The callback function
*/
void add_on_armed_away_callback(std::function<void()> &&callback);
/** Add a callback for when the state of the alarm_control_panel changes to disarmed
*
* @param callback The callback function
*/
void add_on_disarmed_callback(std::function<void()> &&callback);
/** Add a callback for when the state of the alarm_control_panel clears from triggered
*
* @param callback The callback function
@@ -172,29 +128,14 @@ class AlarmControlPanel : public EntityBase {
uint32_t last_update_;
// the call control function
virtual void control(const AlarmControlPanelCall &call) = 0;
// state callback
CallbackManager<void()> state_callback_{};
// trigger callback
CallbackManager<void()> triggered_callback_{};
// arming callback
CallbackManager<void()> arming_callback_{};
// pending callback
CallbackManager<void()> pending_callback_{};
// armed_home callback
CallbackManager<void()> armed_home_callback_{};
// armed_night callback
CallbackManager<void()> armed_night_callback_{};
// armed_away callback
CallbackManager<void()> armed_away_callback_{};
// disarmed callback
CallbackManager<void()> disarmed_callback_{};
// clear callback
CallbackManager<void()> cleared_callback_{};
// state callback - triggers check get_state() for specific state
LazyCallbackManager<void()> state_callback_{};
// clear callback - fires when leaving TRIGGERED state
LazyCallbackManager<void()> cleared_callback_{};
// chime callback
CallbackManager<void()> chime_callback_{};
LazyCallbackManager<void()> chime_callback_{};
// ready callback
CallbackManager<void()> ready_callback_{};
LazyCallbackManager<void()> ready_callback_{};
};
} // namespace alarm_control_panel
} // namespace esphome
} // namespace esphome::alarm_control_panel

View File

@@ -4,8 +4,7 @@
#include "esphome/core/log.h"
namespace esphome {
namespace alarm_control_panel {
namespace esphome::alarm_control_panel {
static const char *const TAG = "alarm_control_panel";
@@ -99,5 +98,4 @@ void AlarmControlPanelCall::perform() {
}
}
} // namespace alarm_control_panel
} // namespace esphome
} // namespace esphome::alarm_control_panel

View File

@@ -6,8 +6,7 @@
#include "esphome/core/helpers.h"
namespace esphome {
namespace alarm_control_panel {
namespace esphome::alarm_control_panel {
class AlarmControlPanel;
@@ -36,5 +35,4 @@ class AlarmControlPanelCall {
void validate_();
};
} // namespace alarm_control_panel
} // namespace esphome
} // namespace esphome::alarm_control_panel

View File

@@ -1,7 +1,6 @@
#include "alarm_control_panel_state.h"
namespace esphome {
namespace alarm_control_panel {
namespace esphome::alarm_control_panel {
const LogString *alarm_control_panel_state_to_string(AlarmControlPanelState state) {
switch (state) {
@@ -30,5 +29,4 @@ const LogString *alarm_control_panel_state_to_string(AlarmControlPanelState stat
}
}
} // namespace alarm_control_panel
} // namespace esphome
} // namespace esphome::alarm_control_panel

View File

@@ -3,8 +3,7 @@
#include <cstdint>
#include "esphome/core/log.h"
namespace esphome {
namespace alarm_control_panel {
namespace esphome::alarm_control_panel {
enum AlarmControlPanelState : uint8_t {
ACP_STATE_DISARMED = 0,
@@ -25,5 +24,4 @@ enum AlarmControlPanelState : uint8_t {
*/
const LogString *alarm_control_panel_state_to_string(AlarmControlPanelState state);
} // namespace alarm_control_panel
} // namespace esphome
} // namespace esphome::alarm_control_panel

View File

@@ -3,9 +3,9 @@
#include "esphome/core/automation.h"
#include "alarm_control_panel.h"
namespace esphome {
namespace alarm_control_panel {
namespace esphome::alarm_control_panel {
/// Trigger on any state change
class StateTrigger : public Trigger<> {
public:
explicit StateTrigger(AlarmControlPanel *alarm_control_panel) {
@@ -13,55 +13,30 @@ class StateTrigger : public Trigger<> {
}
};
class TriggeredTrigger : public Trigger<> {
/// Template trigger that fires when entering a specific state
template<AlarmControlPanelState State> class StateEnterTrigger : public Trigger<> {
public:
explicit TriggeredTrigger(AlarmControlPanel *alarm_control_panel) {
alarm_control_panel->add_on_triggered_callback([this]() { this->trigger(); });
explicit StateEnterTrigger(AlarmControlPanel *alarm_control_panel) : alarm_control_panel_(alarm_control_panel) {
alarm_control_panel->add_on_state_callback([this]() {
if (this->alarm_control_panel_->get_state() == State)
this->trigger();
});
}
protected:
AlarmControlPanel *alarm_control_panel_;
};
class ArmingTrigger : public Trigger<> {
public:
explicit ArmingTrigger(AlarmControlPanel *alarm_control_panel) {
alarm_control_panel->add_on_arming_callback([this]() { this->trigger(); });
}
};
class PendingTrigger : public Trigger<> {
public:
explicit PendingTrigger(AlarmControlPanel *alarm_control_panel) {
alarm_control_panel->add_on_pending_callback([this]() { this->trigger(); });
}
};
class ArmedHomeTrigger : public Trigger<> {
public:
explicit ArmedHomeTrigger(AlarmControlPanel *alarm_control_panel) {
alarm_control_panel->add_on_armed_home_callback([this]() { this->trigger(); });
}
};
class ArmedNightTrigger : public Trigger<> {
public:
explicit ArmedNightTrigger(AlarmControlPanel *alarm_control_panel) {
alarm_control_panel->add_on_armed_night_callback([this]() { this->trigger(); });
}
};
class ArmedAwayTrigger : public Trigger<> {
public:
explicit ArmedAwayTrigger(AlarmControlPanel *alarm_control_panel) {
alarm_control_panel->add_on_armed_away_callback([this]() { this->trigger(); });
}
};
class DisarmedTrigger : public Trigger<> {
public:
explicit DisarmedTrigger(AlarmControlPanel *alarm_control_panel) {
alarm_control_panel->add_on_disarmed_callback([this]() { this->trigger(); });
}
};
// Type aliases for state-specific triggers
using TriggeredTrigger = StateEnterTrigger<ACP_STATE_TRIGGERED>;
using ArmingTrigger = StateEnterTrigger<ACP_STATE_ARMING>;
using PendingTrigger = StateEnterTrigger<ACP_STATE_PENDING>;
using ArmedHomeTrigger = StateEnterTrigger<ACP_STATE_ARMED_HOME>;
using ArmedNightTrigger = StateEnterTrigger<ACP_STATE_ARMED_NIGHT>;
using ArmedAwayTrigger = StateEnterTrigger<ACP_STATE_ARMED_AWAY>;
using DisarmedTrigger = StateEnterTrigger<ACP_STATE_DISARMED>;
/// Trigger when leaving TRIGGERED state (alarm cleared)
class ClearedTrigger : public Trigger<> {
public:
explicit ClearedTrigger(AlarmControlPanel *alarm_control_panel) {
@@ -69,6 +44,7 @@ class ClearedTrigger : public Trigger<> {
}
};
/// Trigger on chime event (zone opened while disarmed)
class ChimeTrigger : public Trigger<> {
public:
explicit ChimeTrigger(AlarmControlPanel *alarm_control_panel) {
@@ -76,6 +52,7 @@ class ChimeTrigger : public Trigger<> {
}
};
/// Trigger on ready state change
class ReadyTrigger : public Trigger<> {
public:
explicit ReadyTrigger(AlarmControlPanel *alarm_control_panel) {
@@ -187,5 +164,4 @@ template<typename... Ts> class AlarmControlPanelCondition : public Condition<Ts.
AlarmControlPanel *parent_;
};
} // namespace alarm_control_panel
} // namespace esphome
} // namespace esphome::alarm_control_panel

View File

@@ -56,13 +56,13 @@ bool Alpha3::is_current_response_type_(const uint8_t *response_type) {
void Alpha3::handle_geni_response_(const uint8_t *response, uint16_t length) {
if (this->response_offset_ >= this->response_length_) {
ESP_LOGD(TAG, "[%s] GENI response begin", this->parent_->address_str().c_str());
ESP_LOGD(TAG, "[%s] GENI response begin", this->parent_->address_str());
if (length < GENI_RESPONSE_HEADER_LENGTH) {
ESP_LOGW(TAG, "[%s] response to short", this->parent_->address_str().c_str());
ESP_LOGW(TAG, "[%s] response too short", this->parent_->address_str());
return;
}
if (response[0] != 36 || response[2] != 248 || response[3] != 231 || response[4] != 10) {
ESP_LOGW(TAG, "[%s] response bytes %d %d %d %d %d don't match GENI HEADER", this->parent_->address_str().c_str(),
ESP_LOGW(TAG, "[%s] response bytes %d %d %d %d %d don't match GENI HEADER", this->parent_->address_str(),
response[0], response[1], response[2], response[3], response[4]);
return;
}
@@ -77,11 +77,11 @@ void Alpha3::handle_geni_response_(const uint8_t *response, uint16_t length) {
};
if (this->is_current_response_type_(GENI_RESPONSE_TYPE_FLOW_HEAD)) {
ESP_LOGD(TAG, "[%s] FLOW HEAD Response", this->parent_->address_str().c_str());
ESP_LOGD(TAG, "[%s] FLOW HEAD Response", this->parent_->address_str());
extract_publish_sensor_value(GENI_RESPONSE_FLOW_OFFSET, this->flow_sensor_, 3600.0F);
extract_publish_sensor_value(GENI_RESPONSE_HEAD_OFFSET, this->head_sensor_, .0001F);
} else if (this->is_current_response_type_(GENI_RESPONSE_TYPE_POWER)) {
ESP_LOGD(TAG, "[%s] POWER Response", this->parent_->address_str().c_str());
ESP_LOGD(TAG, "[%s] POWER Response", this->parent_->address_str());
extract_publish_sensor_value(GENI_RESPONSE_POWER_OFFSET, this->power_sensor_, 1.0F);
extract_publish_sensor_value(GENI_RESPONSE_CURRENT_OFFSET, this->current_sensor_, 1.0F);
extract_publish_sensor_value(GENI_RESPONSE_MOTOR_SPEED_OFFSET, this->speed_sensor_, 1.0F);
@@ -100,7 +100,7 @@ void Alpha3::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc
if (param->open.status == ESP_GATT_OK) {
this->response_offset_ = 0;
this->response_length_ = 0;
ESP_LOGI(TAG, "[%s] connection open", this->parent_->address_str().c_str());
ESP_LOGI(TAG, "[%s] connection open", this->parent_->address_str());
}
break;
}
@@ -132,7 +132,7 @@ void Alpha3::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc
case ESP_GATTC_SEARCH_CMPL_EVT: {
auto *chr = this->parent_->get_characteristic(ALPHA3_GENI_SERVICE_UUID, ALPHA3_GENI_CHARACTERISTIC_UUID);
if (chr == nullptr) {
ESP_LOGE(TAG, "[%s] No GENI service found at device, not an Alpha3..?", this->parent_->address_str().c_str());
ESP_LOGE(TAG, "[%s] No GENI service found at device, not an Alpha3..?", this->parent_->address_str());
break;
}
auto status = esp_ble_gattc_register_for_notify(this->parent_->get_gattc_if(), this->parent_->get_remote_bda(),
@@ -164,12 +164,12 @@ void Alpha3::send_request_(uint8_t *request, size_t len) {
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->geni_handle_, len,
request, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
if (status)
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str(), status);
}
void Alpha3::update() {
if (this->node_state != espbt::ClientState::ESTABLISHED) {
ESP_LOGW(TAG, "[%s] Cannot poll, not connected", this->parent_->address_str().c_str());
ESP_LOGW(TAG, "[%s] Cannot poll, not connected", this->parent_->address_str());
return;
}

View File

@@ -15,10 +15,8 @@ namespace alpha3 {
namespace espbt = esphome::esp32_ble_tracker;
static const espbt::ESPBTUUID ALPHA3_GENI_SERVICE_UUID = espbt::ESPBTUUID::from_uint16(0xfe5d);
static const espbt::ESPBTUUID ALPHA3_GENI_CHARACTERISTIC_UUID =
espbt::ESPBTUUID::from_raw({static_cast<char>(0xa9), 0x7b, static_cast<char>(0xb8), static_cast<char>(0x85), 0x0,
0x1a, 0x28, static_cast<char>(0xaa), 0x2a, 0x43, 0x6e, 0x3, static_cast<char>(0xd1),
static_cast<char>(0xff), static_cast<char>(0x9c), static_cast<char>(0x85)});
static const espbt::ESPBTUUID ALPHA3_GENI_CHARACTERISTIC_UUID = espbt::ESPBTUUID::from_raw(
{0xa9, 0x7b, 0xb8, 0x85, 0x00, 0x1a, 0x28, 0xaa, 0x2a, 0x43, 0x6e, 0x03, 0xd1, 0xff, 0x9c, 0x85});
static const int16_t GENI_RESPONSE_HEADER_LENGTH = 13;
static const size_t GENI_RESPONSE_TYPE_LENGTH = 8;

View File

@@ -44,11 +44,9 @@ void Am43::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_i
auto *chr = this->parent_->get_characteristic(AM43_SERVICE_UUID, AM43_CHARACTERISTIC_UUID);
if (chr == nullptr) {
if (this->parent_->get_characteristic(AM43_TUYA_SERVICE_UUID, AM43_TUYA_CHARACTERISTIC_UUID) != nullptr) {
ESP_LOGE(TAG, "[%s] Detected a Tuya AM43 which is not supported, sorry.",
this->parent_->address_str().c_str());
ESP_LOGE(TAG, "[%s] Detected a Tuya AM43 which is not supported, sorry.", this->parent_->address_str());
} else {
ESP_LOGE(TAG, "[%s] No control service found at device, not an AM43..?",
this->parent_->address_str().c_str());
ESP_LOGE(TAG, "[%s] No control service found at device, not an AM43..?", this->parent_->address_str());
}
break;
}
@@ -82,8 +80,7 @@ void Am43::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_i
this->char_handle_, packet->length, packet->data,
ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
if (status) {
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(),
status);
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str(), status);
}
}
this->current_sensor_ = 0;
@@ -97,7 +94,7 @@ void Am43::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_i
void Am43::update() {
if (this->node_state != espbt::ClientState::ESTABLISHED) {
ESP_LOGW(TAG, "[%s] Cannot poll, not connected", this->parent_->address_str().c_str());
ESP_LOGW(TAG, "[%s] Cannot poll, not connected", this->parent_->address_str());
return;
}
if (this->current_sensor_ == 0) {
@@ -107,7 +104,7 @@ void Am43::update() {
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
if (status) {
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str(), status);
}
}
this->current_sensor_++;

View File

@@ -12,10 +12,11 @@ void AnalogThresholdBinarySensor::setup() {
// TRUE state is defined to be when sensor is >= threshold
// so when undefined sensor value initialize to FALSE
if (std::isnan(sensor_value)) {
this->raw_state_ = false;
this->publish_initial_state(false);
} else {
this->publish_initial_state(sensor_value >=
(this->lower_threshold_.value() + this->upper_threshold_.value()) / 2.0f);
this->raw_state_ = sensor_value >= (this->lower_threshold_.value() + this->upper_threshold_.value()) / 2.0f;
this->publish_initial_state(this->raw_state_);
}
}
@@ -25,8 +26,10 @@ void AnalogThresholdBinarySensor::set_sensor(sensor::Sensor *analog_sensor) {
this->sensor_->add_on_state_callback([this](float sensor_value) {
// if there is an invalid sensor reading, ignore the change and keep the current state
if (!std::isnan(sensor_value)) {
this->publish_state(sensor_value >=
(this->state ? this->lower_threshold_.value() : this->upper_threshold_.value()));
// Use raw_state_ for hysteresis logic, not this->state which is post-filter
this->raw_state_ =
sensor_value >= (this->raw_state_ ? this->lower_threshold_.value() : this->upper_threshold_.value());
this->publish_state(this->raw_state_);
}
});
}

View File

@@ -20,6 +20,7 @@ class AnalogThresholdBinarySensor : public Component, public binary_sensor::Bina
sensor::Sensor *sensor_{nullptr};
TemplatableValue<float> upper_threshold_{};
TemplatableValue<float> lower_threshold_{};
bool raw_state_{false}; // Pre-filter state for hysteresis logic
};
} // namespace analog_threshold

View File

@@ -42,7 +42,7 @@ void Anova::control(const ClimateCall &call) {
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
pkt->length, pkt->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
if (status) {
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str(), status);
}
}
if (call.get_target_temperature().has_value()) {
@@ -51,7 +51,7 @@ void Anova::control(const ClimateCall &call) {
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
pkt->length, pkt->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
if (status) {
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str(), status);
}
}
}
@@ -67,8 +67,10 @@ void Anova::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_
case ESP_GATTC_SEARCH_CMPL_EVT: {
auto *chr = this->parent_->get_characteristic(ANOVA_SERVICE_UUID, ANOVA_CHARACTERISTIC_UUID);
if (chr == nullptr) {
ESP_LOGW(TAG, "[%s] No control service found at device, not an Anova..?", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] Note, this component does not currently support Anova Nano.", this->get_name().c_str());
ESP_LOGW(TAG,
"[%s] No control service found at device, not an Anova..?\n"
"[%s] Note, this component does not currently support Anova Nano.",
this->get_name().c_str(), this->get_name().c_str());
break;
}
this->char_handle_ = chr->handle;
@@ -124,8 +126,7 @@ void Anova::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
pkt->length, pkt->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
if (status) {
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(),
status);
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str(), status);
}
}
}
@@ -150,7 +151,7 @@ void Anova::update() {
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
pkt->length, pkt->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
if (status) {
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str(), status);
}
this->current_request_++;
}

View File

@@ -27,12 +27,13 @@ from esphome.const import (
CONF_SERVICE,
CONF_SERVICES,
CONF_TAG,
CONF_THEN,
CONF_TRIGGER_ID,
CONF_VARIABLES,
)
from esphome.core import CORE, ID, CoroPriority, coroutine_with_priority
from esphome.cpp_generator import TemplateArgsType
from esphome.types import ConfigType
from esphome.core import CORE, ID, CoroPriority, EsphomeError, coroutine_with_priority
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigFragmentType, ConfigType
_LOGGER = logging.getLogger(__name__)
@@ -63,17 +64,21 @@ HomeAssistantActionResponseTrigger = api_ns.class_(
"HomeAssistantActionResponseTrigger", automation.Trigger
)
APIConnectedCondition = api_ns.class_("APIConnectedCondition", Condition)
APIRespondAction = api_ns.class_("APIRespondAction", automation.Action)
APIUnregisterServiceCallAction = api_ns.class_(
"APIUnregisterServiceCallAction", automation.Action
)
UserServiceTrigger = api_ns.class_("UserServiceTrigger", automation.Trigger)
ListEntitiesServicesArgument = api_ns.class_("ListEntitiesServicesArgument")
SERVICE_ARG_NATIVE_TYPES = {
"bool": bool,
SERVICE_ARG_NATIVE_TYPES: dict[str, MockObj] = {
"bool": cg.bool_,
"int": cg.int32,
"float": float,
"float": cg.float_,
"string": cg.std_string,
"bool[]": cg.FixedVector.template(bool).operator("const").operator("ref"),
"bool[]": cg.FixedVector.template(cg.bool_).operator("const").operator("ref"),
"int[]": cg.FixedVector.template(cg.int32).operator("const").operator("ref"),
"float[]": cg.FixedVector.template(float).operator("const").operator("ref"),
"float[]": cg.FixedVector.template(cg.float_).operator("const").operator("ref"),
"string[]": cg.FixedVector.template(cg.std_string)
.operator("const")
.operator("ref"),
@@ -85,6 +90,7 @@ CONF_HOMEASSISTANT_SERVICES = "homeassistant_services"
CONF_HOMEASSISTANT_STATES = "homeassistant_states"
CONF_LISTEN_BACKLOG = "listen_backlog"
CONF_MAX_SEND_QUEUE = "max_send_queue"
CONF_STATE_SUBSCRIPTION_ONLY = "state_subscription_only"
def validate_encryption_key(value):
@@ -101,6 +107,85 @@ def validate_encryption_key(value):
return value
CONF_SUPPORTS_RESPONSE = "supports_response"
# Enum values in api::enums namespace
enums_ns = api_ns.namespace("enums")
SUPPORTS_RESPONSE_OPTIONS = {
"none": enums_ns.SUPPORTS_RESPONSE_NONE,
"optional": enums_ns.SUPPORTS_RESPONSE_OPTIONAL,
"only": enums_ns.SUPPORTS_RESPONSE_ONLY,
"status": enums_ns.SUPPORTS_RESPONSE_STATUS,
}
def _auto_detect_supports_response(config: ConfigType) -> ConfigType:
"""Auto-detect supports_response based on api.respond usage in the action's then block.
- If api.respond with data found: set to "optional" (unless user explicitly set)
- If api.respond without data found: set to "status" (unless user explicitly set)
- If no api.respond found: set to "none" (unless user explicitly set)
"""
def scan_actions(items: ConfigFragmentType) -> tuple[bool, bool]:
"""Recursively scan actions for api.respond.
Returns: (found, has_data) tuple - has_data is True if ANY api.respond has data
"""
found_any = False
has_data_any = False
if isinstance(items, list):
for item in items:
found, has_data = scan_actions(item)
if found:
found_any = True
has_data_any = has_data_any or has_data
elif isinstance(items, dict):
# Check if this is an api.respond action
if "api.respond" in items:
respond_config = items["api.respond"]
has_data = isinstance(respond_config, dict) and "data" in respond_config
return True, has_data
# Recursively check all values
for value in items.values():
found, has_data = scan_actions(value)
if found:
found_any = True
has_data_any = has_data_any or has_data
return found_any, has_data_any
then = config.get(CONF_THEN, [])
action_name = config.get(CONF_ACTION)
found, has_data = scan_actions(then)
# If user explicitly set supports_response, validate and use that
if CONF_SUPPORTS_RESPONSE in config:
user_value = config[CONF_SUPPORTS_RESPONSE]
# Validate: "only" requires api.respond with data
if user_value == "only" and not has_data:
raise cv.Invalid(
f"Action '{action_name}' has supports_response=only but no api.respond "
"action with 'data:' was found. Use 'status' for responses without data, "
"or add 'data:' to your api.respond action."
)
return config
# Auto-detect based on api.respond usage
if found:
config[CONF_SUPPORTS_RESPONSE] = "optional" if has_data else "status"
else:
config[CONF_SUPPORTS_RESPONSE] = "none"
return config
def _validate_supports_response(value):
"""Validate supports_response after auto-detection has set the value."""
return cv.enum(SUPPORTS_RESPONSE_OPTIONS, lower=True)(value)
ACTIONS_SCHEMA = automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(UserServiceTrigger),
@@ -111,10 +196,20 @@ ACTIONS_SCHEMA = automation.validate_automation(
cv.validate_id_name: cv.one_of(*SERVICE_ARG_NATIVE_TYPES, lower=True),
}
),
# No default - auto-detected by _auto_detect_supports_response
cv.Optional(CONF_SUPPORTS_RESPONSE): cv.enum(
SUPPORTS_RESPONSE_OPTIONS, lower=True
),
},
cv.All(
cv.has_exactly_one_key(CONF_SERVICE, CONF_ACTION),
cv.rename_key(CONF_SERVICE, CONF_ACTION),
_auto_detect_supports_response,
# Re-validate supports_response after auto-detection sets it
cv.Schema(
{cv.Required(CONF_SUPPORTS_RESPONSE): _validate_supports_response},
extra=cv.ALLOW_EXTRA,
),
),
)
@@ -131,32 +226,6 @@ def _encryption_schema(config):
return ENCRYPTION_SCHEMA(config)
def _validate_api_config(config: ConfigType) -> ConfigType:
"""Validate API configuration with mutual exclusivity check and deprecation warning."""
# Check if both password and encryption are configured
has_password = CONF_PASSWORD in config and config[CONF_PASSWORD]
has_encryption = CONF_ENCRYPTION in config
if has_password and has_encryption:
raise cv.Invalid(
"The 'password' and 'encryption' options are mutually exclusive. "
"The API client only supports one authentication method at a time. "
"Please remove one of them. "
"Note: 'password' authentication is deprecated and will be removed in version 2026.1.0. "
"We strongly recommend using 'encryption' instead for better security."
)
# Warn about password deprecation
if has_password:
_LOGGER.warning(
"API 'password' authentication has been deprecated since May 2022 and will be removed in version 2026.1.0. "
"Please migrate to the 'encryption' configuration. "
"See https://esphome.io/components/api.html#configuration-variables"
)
return config
def _consume_api_sockets(config: ConfigType) -> ConfigType:
"""Register socket needs for API component."""
from esphome.components import socket
@@ -173,7 +242,17 @@ CONFIG_SCHEMA = cv.All(
{
cv.GenerateID(): cv.declare_id(APIServer),
cv.Optional(CONF_PORT, default=6053): cv.port,
cv.Optional(CONF_PASSWORD, default=""): cv.string_strict,
# Removed in 2026.1.0 - kept to provide helpful error message
cv.Optional(CONF_PASSWORD): cv.invalid(
"The 'password' option has been removed in ESPHome 2026.1.0.\n"
"Password authentication was deprecated in May 2022.\n"
"Please migrate to encryption for secure API communication:\n\n"
"api:\n"
" encryption:\n"
" key: !secret api_encryption_key\n\n"
"Generate a key with: openssl rand -base64 32\n"
"Or visit https://esphome.io/components/api/#configuration-variables"
),
cv.Optional(
CONF_REBOOT_TIMEOUT, default="15min"
): cv.positive_time_period_milliseconds,
@@ -235,13 +314,12 @@ CONFIG_SCHEMA = cv.All(
}
).extend(cv.COMPONENT_SCHEMA),
cv.rename_key(CONF_SERVICES, CONF_ACTIONS),
_validate_api_config,
_consume_api_sockets,
)
@coroutine_with_priority(CoroPriority.WEB)
async def to_code(config):
async def to_code(config: ConfigType) -> None:
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
@@ -249,9 +327,6 @@ async def to_code(config):
CORE.register_controller()
cg.add(var.set_port(config[CONF_PORT]))
if config[CONF_PASSWORD]:
cg.add_define("USE_API_PASSWORD")
cg.add(var.set_password(config[CONF_PASSWORD]))
cg.add(var.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT]))
cg.add(var.set_batch_delay(config[CONF_BATCH_DELAY]))
if CONF_LISTEN_BACKLOG in config:
@@ -260,9 +335,9 @@ async def to_code(config):
cg.add(var.set_max_connections(config[CONF_MAX_CONNECTIONS]))
cg.add_define("API_MAX_SEND_QUEUE", config[CONF_MAX_SEND_QUEUE])
# Set USE_API_SERVICES if any services are enabled
# Set USE_API_USER_DEFINED_ACTIONS if any services are enabled
if config.get(CONF_ACTIONS) or config[CONF_CUSTOM_SERVICES]:
cg.add_define("USE_API_SERVICES")
cg.add_define("USE_API_USER_DEFINED_ACTIONS")
# Set USE_API_CUSTOM_SERVICES if external components need dynamic service registration
if config[CONF_CUSTOM_SERVICES]:
@@ -278,20 +353,61 @@ async def to_code(config):
# Collect all triggers first, then register all at once with initializer_list
triggers: list[cg.Pvariable] = []
for conf in actions:
template_args = []
func_args = []
service_arg_names = []
func_args: list[tuple[MockObj, str]] = []
service_template_args: list[MockObj] = [] # User service argument types
# Determine supports_response mode
# cv.enum returns the key with enum_value attribute containing the MockObj
supports_response_key = conf[CONF_SUPPORTS_RESPONSE]
supports_response = supports_response_key.enum_value
is_none = supports_response_key == "none"
is_optional = supports_response_key == "optional"
# Add call_id and return_response based on supports_response mode
# These must match the C++ Trigger template arguments
# - none: no extra args
# - status: call_id only (for reporting success/error without data)
# - only: call_id only (response always expected with data)
# - optional: call_id + return_response (client decides)
if not is_none:
# call_id is present for "optional", "only", and "status"
func_args.append((cg.uint32, "call_id"))
# return_response only present for "optional"
if is_optional:
func_args.append((cg.bool_, "return_response"))
service_arg_names: list[str] = []
for name, var_ in conf[CONF_VARIABLES].items():
native = SERVICE_ARG_NATIVE_TYPES[var_]
template_args.append(native)
service_template_args.append(native)
func_args.append((native, name))
service_arg_names.append(name)
templ = cg.TemplateArguments(*template_args)
# Template args: supports_response mode, then user service arg types
templ = cg.TemplateArguments(supports_response, *service_template_args)
trigger = cg.new_Pvariable(
conf[CONF_TRIGGER_ID], templ, conf[CONF_ACTION], service_arg_names
conf[CONF_TRIGGER_ID],
templ,
conf[CONF_ACTION],
service_arg_names,
)
triggers.append(trigger)
await automation.build_automation(trigger, func_args, conf)
auto = await automation.build_automation(trigger, func_args, conf)
# For non-none response modes, automatically append unregister action
# This ensures the call is unregistered after all actions complete (including async ones)
if not is_none:
arg_types = [arg[0] for arg in func_args]
action_templ = cg.TemplateArguments(*arg_types)
unregister_id = ID(
f"{conf[CONF_TRIGGER_ID]}__unregister",
is_declaration=True,
type=APIUnregisterServiceCallAction.template(action_templ),
)
unregister_action = cg.new_Pvariable(
unregister_id,
var,
)
cg.add(auto.add_actions([unregister_action]))
# Register all services at once - single allocation, no reallocations
cg.add(var.initialize_user_services(triggers))
@@ -537,9 +653,98 @@ async def homeassistant_tag_scanned_to_code(config, action_id, template_arg, arg
return var
@automation.register_condition("api.connected", APIConnectedCondition, {})
CONF_SUCCESS = "success"
CONF_ERROR_MESSAGE = "error_message"
def _validate_api_respond_data(config):
"""Set flag during validation so AUTO_LOAD can include json component."""
if CONF_DATA in config:
CORE.data.setdefault(DOMAIN, {})[CONF_CAPTURE_RESPONSE] = True
return config
API_RESPOND_ACTION_SCHEMA = cv.All(
cv.Schema(
{
cv.GenerateID(): cv.use_id(APIServer),
cv.Optional(CONF_SUCCESS, default=True): cv.templatable(cv.boolean),
cv.Optional(CONF_ERROR_MESSAGE, default=""): cv.templatable(cv.string),
cv.Optional(CONF_DATA): cv.lambda_,
}
),
_validate_api_respond_data,
)
@automation.register_action(
"api.respond",
APIRespondAction,
API_RESPOND_ACTION_SCHEMA,
)
async def api_respond_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
# Validate that api.respond is used inside an API action context.
# We can't easily validate this at config time since the schema validation
# doesn't have access to the parent action context. Validating here in to_code
# is still much better than a cryptic C++ compile error.
has_call_id = any(name == "call_id" for _, name in args)
if not has_call_id:
raise EsphomeError(
"api.respond can only be used inside an API action's 'then:' block. "
"The 'call_id' variable is required to send a response."
)
cg.add_define("USE_API_USER_DEFINED_ACTION_RESPONSES")
serv = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, serv)
# Check if we're in optional mode (has return_response arg)
is_optional = any(name == "return_response" for _, name in args)
if is_optional:
cg.add(var.set_is_optional_mode(True))
templ = await cg.templatable(config[CONF_SUCCESS], args, cg.bool_)
cg.add(var.set_success(templ))
templ = await cg.templatable(config[CONF_ERROR_MESSAGE], args, cg.std_string)
cg.add(var.set_error_message(templ))
if CONF_DATA in config:
cg.add_define("USE_API_USER_DEFINED_ACTION_RESPONSES_JSON")
# Lambda populates the JsonObject root - no return value needed
lambda_ = await cg.process_lambda(
config[CONF_DATA],
args + [(cg.JsonObject, "root")],
return_type=cg.void,
)
cg.add(var.set_data(lambda_))
return var
API_CONNECTED_CONDITION_SCHEMA = cv.Schema(
{
cv.GenerateID(): cv.use_id(APIServer),
cv.Optional(CONF_STATE_SUBSCRIPTION_ONLY, default=False): cv.templatable(
cv.boolean
),
}
)
@automation.register_condition(
"api.connected", APIConnectedCondition, API_CONNECTED_CONDITION_SCHEMA
)
async def api_connected_to_code(config, condition_id, template_arg, args):
return cg.new_Pvariable(condition_id, template_arg)
var = cg.new_Pvariable(condition_id, template_arg)
templ = await cg.templatable(config[CONF_STATE_SUBSCRIPTION_ONLY], args, cg.bool_)
cg.add(var.set_state_subscription_only(templ))
return var
def FILTER_SOURCE_FILES() -> list[str]:

View File

@@ -7,10 +7,7 @@ service APIConnection {
option (needs_setup_connection) = false;
option (needs_authentication) = false;
}
rpc authenticate (AuthenticationRequest) returns (AuthenticationResponse) {
option (needs_setup_connection) = false;
option (needs_authentication) = false;
}
// REMOVED in ESPHome 2026.1.0: rpc authenticate (AuthenticationRequest) returns (AuthenticationResponse)
rpc disconnect (DisconnectRequest) returns (DisconnectResponse) {
option (needs_setup_connection) = false;
option (needs_authentication) = false;
@@ -69,6 +66,8 @@ service APIConnection {
rpc zwave_proxy_frame(ZWaveProxyFrame) returns (void) {}
rpc zwave_proxy_request(ZWaveProxyRequest) returns (void) {}
rpc infrared_rf_transmit_raw_timings(InfraredRFTransmitRawTimingsRequest) returns (void) {}
}
@@ -82,14 +81,13 @@ service APIConnection {
// * VarInt denoting the type of message.
// * The message object encoded as a ProtoBuf message
// The connection is established in 4 steps:
// The connection is established in 2 steps:
// * First, the client connects to the server and sends a "Hello Request" identifying itself
// * The server responds with a "Hello Response" and selects the protocol version
// * After receiving this message, the client attempts to authenticate itself using
// the password and a "Connect Request"
// * The server responds with a "Connect Response" and notifies of invalid password.
// * The server responds with a "Hello Response" and the connection is authenticated
// If anything in this initial process fails, the connection must immediately closed
// by both sides and _no_ disconnection message is to be sent.
// Note: Password authentication via AuthenticationRequest/AuthenticationResponse (message IDs 3, 4)
// was removed in ESPHome 2026.1.0. Those message IDs are reserved and should not be reused.
// Message sent at the beginning of each connection
// Can only be sent by the client and only at the beginning of the connection
@@ -102,7 +100,7 @@ message HelloRequest {
// For example "Home Assistant"
// Not strictly necessary to send but nice for debugging
// purposes.
string client_info = 1 [(pointer_to_buffer) = true];
string client_info = 1;
uint32 api_version_major = 2;
uint32 api_version_minor = 3;
}
@@ -130,25 +128,23 @@ message HelloResponse {
string name = 4;
}
// Message sent at the beginning of each connection to authenticate the client
// Can only be sent by the client and only at the beginning of the connection
// DEPRECATED in ESPHome 2026.1.0 - Password authentication is no longer supported.
// These messages are kept for protocol documentation but are not processed by the server.
// Use noise encryption instead: https://esphome.io/components/api/#configuration-variables
message AuthenticationRequest {
option (id) = 3;
option (source) = SOURCE_CLIENT;
option (no_delay) = true;
option (ifdef) = "USE_API_PASSWORD";
option deprecated = true;
// The password to log in with
string password = 1 [(pointer_to_buffer) = true];
string password = 1;
}
// Confirmation of successful connection. After this the connection is available for all traffic.
// Can only be sent by the server and only at the beginning of the connection
message AuthenticationResponse {
option (id) = 4;
option (source) = SOURCE_SERVER;
option (no_delay) = true;
option (ifdef) = "USE_API_PASSWORD";
option deprecated = true;
bool invalid_password = 1;
}
@@ -205,7 +201,9 @@ message DeviceInfoResponse {
option (id) = 10;
option (source) = SOURCE_SERVER;
bool uses_password = 1 [(field_ifdef) = "USE_API_PASSWORD"];
// Deprecated in ESPHome 2026.1.0, but kept for backward compatibility
// with older ESPHome versions that still send this field.
bool uses_password = 1 [deprecated = true];
// The name of the node, given by "App.set_name()"
string name = 2;
@@ -518,7 +516,7 @@ message ListEntitiesLightResponse {
bool legacy_supports_color_temperature = 8 [deprecated=true];
float min_mireds = 9;
float max_mireds = 10;
repeated string effects = 11;
repeated string effects = 11 [(container_pointer_no_template) = "FixedVector<const char *>"];
bool disabled_by_default = 13;
string icon = 14 [(field_ifdef) = "USE_ENTITY_ICON"];
EntityCategory entity_category = 15;
@@ -589,6 +587,7 @@ enum SensorStateClass {
STATE_CLASS_MEASUREMENT = 1;
STATE_CLASS_TOTAL_INCREASING = 2;
STATE_CLASS_TOTAL = 3;
STATE_CLASS_MEASUREMENT_ANGLE = 4;
}
// Deprecated in API version 1.5
@@ -766,7 +765,7 @@ message SubscribeHomeassistantServicesRequest {
message HomeassistantServiceMap {
string key = 1;
string value = 2 [(no_zero_copy) = true];
string value = 2;
}
message HomeassistantActionRequest {
@@ -782,7 +781,7 @@ message HomeassistantActionRequest {
bool is_event = 5;
uint32 call_id = 6 [(field_ifdef) = "USE_API_HOMEASSISTANT_ACTION_RESPONSES"];
bool wants_response = 7 [(field_ifdef) = "USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON"];
string response_template = 8 [(no_zero_copy) = true, (field_ifdef) = "USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON"];
string response_template = 8 [(field_ifdef) = "USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON"];
}
// Message sent by Home Assistant to ESPHome with service call response data
@@ -795,7 +794,7 @@ message HomeassistantActionResponse {
uint32 call_id = 1; // Matches the call_id from HomeassistantActionRequest
bool success = 2; // Whether the service call succeeded
string error_message = 3; // Error message if success = false
bytes response_data = 4 [(pointer_to_buffer) = true, (field_ifdef) = "USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON"];
bytes response_data = 4 [(field_ifdef) = "USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON"];
}
// ==================== IMPORT HOME ASSISTANT STATES ====================
@@ -840,7 +839,7 @@ message GetTimeResponse {
option (no_delay) = true;
fixed32 epoch_seconds = 1;
string timezone = 2 [(pointer_to_buffer) = true];
string timezone = 2;
}
// ==================== USER-DEFINES SERVICES ====================
@@ -854,22 +853,31 @@ enum ServiceArgType {
SERVICE_ARG_TYPE_FLOAT_ARRAY = 6;
SERVICE_ARG_TYPE_STRING_ARRAY = 7;
}
enum SupportsResponseType {
SUPPORTS_RESPONSE_NONE = 0;
SUPPORTS_RESPONSE_OPTIONAL = 1;
SUPPORTS_RESPONSE_ONLY = 2;
// Status-only response - reports success/error without data payload
// Value is higher to avoid conflicts with future Home Assistant values
SUPPORTS_RESPONSE_STATUS = 100;
}
message ListEntitiesServicesArgument {
option (ifdef) = "USE_API_SERVICES";
option (ifdef) = "USE_API_USER_DEFINED_ACTIONS";
string name = 1;
ServiceArgType type = 2;
}
message ListEntitiesServicesResponse {
option (id) = 41;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_API_SERVICES";
option (ifdef) = "USE_API_USER_DEFINED_ACTIONS";
string name = 1;
fixed32 key = 2;
repeated ListEntitiesServicesArgument args = 3 [(fixed_vector) = true];
SupportsResponseType supports_response = 4;
}
message ExecuteServiceArgument {
option (ifdef) = "USE_API_SERVICES";
option (ifdef) = "USE_API_USER_DEFINED_ACTIONS";
bool bool_ = 1;
int32 legacy_int = 2;
float float_ = 3;
@@ -885,10 +893,25 @@ message ExecuteServiceRequest {
option (id) = 42;
option (source) = SOURCE_CLIENT;
option (no_delay) = true;
option (ifdef) = "USE_API_SERVICES";
option (ifdef) = "USE_API_USER_DEFINED_ACTIONS";
fixed32 key = 1;
repeated ExecuteServiceArgument args = 2 [(fixed_vector) = true];
uint32 call_id = 3 [(field_ifdef) = "USE_API_USER_DEFINED_ACTION_RESPONSES"];
bool return_response = 4 [(field_ifdef) = "USE_API_USER_DEFINED_ACTION_RESPONSES"];
}
// Message sent by ESPHome to Home Assistant with service execution response data
message ExecuteServiceResponse {
option (id) = 131;
option (source) = SOURCE_SERVER;
option (no_delay) = true;
option (ifdef) = "USE_API_USER_DEFINED_ACTION_RESPONSES";
uint32 call_id = 1; // Matches the call_id from ExecuteServiceRequest
bool success = 2; // Whether the service execution succeeded
string error_message = 3; // Error message if success = false
bytes response_data = 4 [(pointer_to_buffer) = true, (field_ifdef) = "USE_API_USER_DEFINED_ACTION_RESPONSES_JSON"];
}
// ==================== CAMERA ====================
@@ -1076,6 +1099,85 @@ message ClimateCommandRequest {
uint32 device_id = 24 [(field_ifdef) = "USE_DEVICES"];
}
// ==================== WATER_HEATER ====================
enum WaterHeaterMode {
WATER_HEATER_MODE_OFF = 0;
WATER_HEATER_MODE_ECO = 1;
WATER_HEATER_MODE_ELECTRIC = 2;
WATER_HEATER_MODE_PERFORMANCE = 3;
WATER_HEATER_MODE_HIGH_DEMAND = 4;
WATER_HEATER_MODE_HEAT_PUMP = 5;
WATER_HEATER_MODE_GAS = 6;
}
message ListEntitiesWaterHeaterResponse {
option (id) = 132;
option (base_class) = "InfoResponseProtoMessage";
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_WATER_HEATER";
string object_id = 1;
fixed32 key = 2;
string name = 3;
string icon = 4 [(field_ifdef) = "USE_ENTITY_ICON"];
bool disabled_by_default = 5;
EntityCategory entity_category = 6;
uint32 device_id = 7 [(field_ifdef) = "USE_DEVICES"];
float min_temperature = 8;
float max_temperature = 9;
float target_temperature_step = 10;
repeated WaterHeaterMode supported_modes = 11 [(container_pointer_no_template) = "water_heater::WaterHeaterModeMask"];
// Bitmask of WaterHeaterFeature flags
uint32 supported_features = 12;
}
message WaterHeaterStateResponse {
option (id) = 133;
option (base_class) = "StateResponseProtoMessage";
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_WATER_HEATER";
option (no_delay) = true;
fixed32 key = 1;
float current_temperature = 2;
float target_temperature = 3;
WaterHeaterMode mode = 4;
uint32 device_id = 5 [(field_ifdef) = "USE_DEVICES"];
// Bitmask of current state flags (bit 0 = away, bit 1 = on)
uint32 state = 6;
float target_temperature_low = 7;
float target_temperature_high = 8;
}
// Bitmask for WaterHeaterCommandRequest.has_fields
enum WaterHeaterCommandHasField {
WATER_HEATER_COMMAND_HAS_NONE = 0;
WATER_HEATER_COMMAND_HAS_MODE = 1;
WATER_HEATER_COMMAND_HAS_TARGET_TEMPERATURE = 2;
WATER_HEATER_COMMAND_HAS_STATE = 4;
WATER_HEATER_COMMAND_HAS_TARGET_TEMPERATURE_LOW = 8;
WATER_HEATER_COMMAND_HAS_TARGET_TEMPERATURE_HIGH = 16;
}
message WaterHeaterCommandRequest {
option (id) = 134;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_WATER_HEATER";
option (no_delay) = true;
option (base_class) = "CommandProtoMessage";
fixed32 key = 1;
// Bitmask of which fields are set (see WaterHeaterCommandHasField)
uint32 has_fields = 2;
WaterHeaterMode mode = 3;
float target_temperature = 4;
uint32 device_id = 5 [(field_ifdef) = "USE_DEVICES"];
// State flags bitmask (bit 0 = away, bit 1 = on)
uint32 state = 6;
float target_temperature_low = 7;
float target_temperature_high = 8;
}
// ==================== NUMBER ====================
enum NumberMode {
NUMBER_MODE_AUTO = 0;
@@ -1188,7 +1290,7 @@ message ListEntitiesSirenResponse {
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
bool disabled_by_default = 6;
repeated string tones = 7;
repeated string tones = 7 [(container_pointer_no_template) = "FixedVector<const char *>"];
bool supports_duration = 8;
bool supports_volume = 9;
EntityCategory entity_category = 10;
@@ -1588,7 +1690,7 @@ message BluetoothGATTWriteRequest {
uint32 handle = 2;
bool response = 3;
bytes data = 4 [(pointer_to_buffer) = true];
bytes data = 4;
}
message BluetoothGATTReadDescriptorRequest {
@@ -1608,7 +1710,7 @@ message BluetoothGATTWriteDescriptorRequest {
uint64 address = 1;
uint32 handle = 2;
bytes data = 3 [(pointer_to_buffer) = true];
bytes data = 3;
}
message BluetoothGATTNotifyRequest {
@@ -1833,7 +1935,7 @@ message VoiceAssistantAudio {
option (source) = SOURCE_BOTH;
option (ifdef) = "USE_VOICE_ASSISTANT";
bytes data = 1;
bytes data = 1 [(pointer_to_buffer) = true];
bool end = 2;
}
@@ -2321,7 +2423,7 @@ message ZWaveProxyFrame {
option (ifdef) = "USE_ZWAVE_PROXY";
option (no_delay) = true;
bytes data = 1 [(pointer_to_buffer) = true];
bytes data = 1;
}
enum ZWaveProxyRequestType {
@@ -2335,5 +2437,51 @@ message ZWaveProxyRequest {
option (ifdef) = "USE_ZWAVE_PROXY";
ZWaveProxyRequestType type = 1;
bytes data = 2 [(pointer_to_buffer) = true];
bytes data = 2;
}
// ==================== INFRARED ====================
// Note: Feature and capability flag enums are defined in
// esphome/components/infrared/infrared.h
// Listing of infrared instances
message ListEntitiesInfraredResponse {
option (id) = 135;
option (base_class) = "InfoResponseProtoMessage";
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_INFRARED";
string object_id = 1;
fixed32 key = 2;
string name = 3;
string icon = 4 [(field_ifdef) = "USE_ENTITY_ICON"];
bool disabled_by_default = 5;
EntityCategory entity_category = 6;
uint32 device_id = 7 [(field_ifdef) = "USE_DEVICES"];
uint32 capabilities = 8; // Bitfield of InfraredCapabilityFlags
}
// Command to transmit infrared/RF data using raw timings
message InfraredRFTransmitRawTimingsRequest {
option (id) = 136;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_IR_RF";
uint32 device_id = 1 [(field_ifdef) = "USE_DEVICES"];
fixed32 key = 2; // Key identifying the transmitter instance
uint32 carrier_frequency = 3; // Carrier frequency in Hz
uint32 repeat_count = 4; // Number of times to transmit (1 = once, 2 = twice, etc.)
repeated sint32 timings = 5 [packed = true, (packed_buffer) = true]; // Raw timings in microseconds (zigzag-encoded): positive = mark (LED/TX on), negative = space (LED/TX off)
}
// Event message for received infrared/RF data
message InfraredRFReceiveEvent {
option (id) = 137;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_IR_RF";
option (no_delay) = true;
uint32 device_id = 1 [(field_ifdef) = "USE_DEVICES"];
fixed32 key = 2; // Key identifying the receiver instance
repeated sint32 timings = 3 [packed = true, (container_pointer_no_template) = "std::vector<int32_t>"]; // Raw timings in microseconds (zigzag-encoded): alternating mark/space periods
}

File diff suppressed because it is too large Load Diff

View File

@@ -9,32 +9,23 @@
#include "esphome/core/application.h"
#include "esphome/core/component.h"
#include "esphome/core/entity_base.h"
#include "esphome/core/string_ref.h"
#include <functional>
#include <vector>
namespace esphome::api {
// Client information structure
struct ClientInfo {
std::string name; // Client name from Hello message
std::string peername; // IP:port from socket
};
// Keepalive timeout in milliseconds
static constexpr uint32_t KEEPALIVE_TIMEOUT_MS = 60000;
// Maximum number of entities to process in a single batch during initial state/info sending
// This was increased from 20 to 24 after removing the unique_id field from entity info messages,
// which reduced message sizes allowing more entities per batch without exceeding packet limits
static constexpr size_t MAX_INITIAL_PER_BATCH = 24;
// Maximum number of packets to process in a single batch (platform-dependent)
// This limit exists to prevent stack overflow from the PacketInfo array in process_batch_
// Each PacketInfo is 8 bytes, so 64 * 8 = 512 bytes, 32 * 8 = 256 bytes
#if defined(USE_ESP32) || defined(USE_HOST)
static constexpr size_t MAX_PACKETS_PER_BATCH = 64; // ESP32 has 8KB+ stack, HOST has plenty
#else
static constexpr size_t MAX_PACKETS_PER_BATCH = 32; // ESP8266/RP2040/etc have smaller stacks
#endif
// API 1.14+ clients compute object_id client-side, so messages are smaller and we can fit more per batch
// TODO: Remove MAX_INITIAL_PER_BATCH_LEGACY before 2026.7.0 - all clients should support API 1.14 by then
static constexpr size_t MAX_INITIAL_PER_BATCH_LEGACY = 24; // For clients < API 1.14 (includes object_id)
static constexpr size_t MAX_INITIAL_PER_BATCH = 34; // For clients >= API 1.14 (no object_id)
// Verify MAX_MESSAGES_PER_BATCH (defined in api_frame_helper.h) can hold the initial batch
static_assert(MAX_MESSAGES_PER_BATCH >= MAX_INITIAL_PER_BATCH,
"MAX_MESSAGES_PER_BATCH must be >= MAX_INITIAL_PER_BATCH");
class APIConnection final : public APIServerConnection {
public:
@@ -176,8 +167,18 @@ class APIConnection final : public APIServerConnection {
void alarm_control_panel_command(const AlarmControlPanelCommandRequest &msg) override;
#endif
#ifdef USE_WATER_HEATER
bool send_water_heater_state(water_heater::WaterHeater *water_heater);
void on_water_heater_command_request(const WaterHeaterCommandRequest &msg) override;
#endif
#ifdef USE_IR_RF
void infrared_rf_transmit_raw_timings(const InfraredRFTransmitRawTimingsRequest &msg) override;
void send_infrared_rf_receive_event(const InfraredRFReceiveEvent &msg);
#endif
#ifdef USE_EVENT
void send_event(event::Event *event, const char *event_type);
void send_event(event::Event *event, StringRef event_type);
#endif
#ifdef USE_UPDATE
@@ -197,16 +198,17 @@ class APIConnection final : public APIServerConnection {
void on_get_time_response(const GetTimeResponse &value) override;
#endif
bool send_hello_response(const HelloRequest &msg) override;
#ifdef USE_API_PASSWORD
bool send_authenticate_response(const AuthenticationRequest &msg) override;
#endif
bool send_disconnect_response(const DisconnectRequest &msg) override;
bool send_ping_response(const PingRequest &msg) override;
bool send_device_info_response(const DeviceInfoRequest &msg) override;
void list_entities(const ListEntitiesRequest &msg) override { this->list_entities_iterator_.begin(); }
void list_entities(const ListEntitiesRequest &msg) override { this->begin_iterator_(ActiveIterator::LIST_ENTITIES); }
void subscribe_states(const SubscribeStatesRequest &msg) override {
this->flags_.state_subscription = true;
this->initial_state_iterator_.begin();
// Start initial state iterator only if no iterator is active
// If list_entities is running, we'll start initial_state when it completes
if (this->active_iterator_ == ActiveIterator::NONE) {
this->begin_iterator_(ActiveIterator::INITIAL_STATE);
}
}
void subscribe_logs(const SubscribeLogsRequest &msg) override {
this->flags_.log_subscription = msg.level;
@@ -221,8 +223,15 @@ class APIConnection final : public APIServerConnection {
#ifdef USE_API_HOMEASSISTANT_STATES
void subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) override;
#endif
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
void execute_service(const ExecuteServiceRequest &msg) override;
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
void send_execute_service_response(uint32_t call_id, bool success, StringRef error_message);
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
void send_execute_service_response(uint32_t call_id, bool success, StringRef error_message,
const uint8_t *response_data, size_t response_data_len);
#endif // USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
#endif // USE_API_USER_DEFINED_ACTION_RESPONSES
#endif
#ifdef USE_API_NOISE
bool send_noise_encryption_set_key_response(const NoiseEncryptionSetKeyRequest &msg) override;
@@ -244,9 +253,6 @@ class APIConnection final : public APIServerConnection {
}
void on_fatal_error() override;
#ifdef USE_API_PASSWORD
void on_unauthenticated_access() override;
#endif
void on_no_setup_connection() override;
ProtoWriteBuffer create_buffer(uint32_t reserve_size) override {
// FIXME: ensure no recursive writes can happen
@@ -273,13 +279,18 @@ class APIConnection final : public APIServerConnection {
bool try_to_clear_buffer(bool log_out_of_space);
bool send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) override;
const std::string &get_name() const { return this->client_info_.name; }
const std::string &get_peername() const { return this->client_info_.peername; }
const char *get_name() const { return this->helper_->get_client_name(); }
/// Get peer name (IP address) - cached at connection init time
const char *get_peername() const { return this->helper_->get_client_peername(); }
protected:
// Helper function to handle authentication completion
void complete_authentication_();
#ifdef USE_CAMERA
void try_send_camera_image_();
#endif
#ifdef USE_API_HOMEASSISTANT_STATES
void process_state_subscriptions_();
#endif
@@ -303,25 +314,24 @@ class APIConnection final : public APIServerConnection {
APIConnection *conn, uint32_t remaining_size, bool is_single) {
// Set common fields that are shared by all entity types
msg.key = entity->get_object_id_hash();
// Try to use static reference first to avoid allocation
StringRef static_ref = entity->get_object_id_ref_for_api_();
// Store dynamic string outside the if-else to maintain lifetime
std::string object_id;
if (!static_ref.empty()) {
msg.set_object_id(static_ref);
} else {
// Dynamic case - need to allocate
object_id = entity->get_object_id();
msg.set_object_id(StringRef(object_id));
// API 1.14+ clients compute object_id client-side from the entity name
// For older clients, we must send object_id for backward compatibility
// See: https://github.com/esphome/backlog/issues/76
// TODO: Remove this backward compat code before 2026.7.0 - all clients should support API 1.14 by then
// Buffer must remain in scope until encode_message_to_buffer is called
char object_id_buf[OBJECT_ID_MAX_LEN];
if (!conn->client_supports_api_version(1, 14)) {
msg.object_id = entity->get_object_id_to(object_id_buf);
}
if (entity->has_own_name()) {
msg.set_name(entity->get_name());
msg.name = entity->get_name();
}
// Set common EntityBase properties
#ifdef USE_ENTITY_ICON
msg.set_icon(entity->get_icon_ref());
msg.icon = entity->get_icon_ref();
#endif
msg.disabled_by_default = entity->is_disabled_by_default();
msg.entity_category = static_cast<enums::EntityCategory>(entity->get_entity_category());
@@ -336,16 +346,24 @@ class APIConnection final : public APIServerConnection {
inline bool check_voice_assistant_api_connection_() const;
#endif
// Get the max batch size based on client API version
// API 1.14+ clients don't receive object_id, so messages are smaller and more fit per batch
// TODO: Remove this method before 2026.7.0 and use MAX_INITIAL_PER_BATCH directly
size_t get_max_batch_size_() const {
return this->client_supports_api_version(1, 14) ? MAX_INITIAL_PER_BATCH : MAX_INITIAL_PER_BATCH_LEGACY;
}
// Helper method to process multiple entities from an iterator in a batch
template<typename Iterator> void process_iterator_batch_(Iterator &iterator) {
size_t initial_size = this->deferred_batch_.size();
while (!iterator.completed() && (this->deferred_batch_.size() - initial_size) < MAX_INITIAL_PER_BATCH) {
size_t max_batch = this->get_max_batch_size_();
while (!iterator.completed() && (this->deferred_batch_.size() - initial_size) < max_batch) {
iterator.advance();
}
// If the batch is full, process it immediately
// Note: iterator.advance() already calls schedule_batch_() via schedule_message_()
if (this->deferred_batch_.size() >= MAX_INITIAL_PER_BATCH) {
if (this->deferred_batch_.size() >= max_batch) {
this->process_batch_();
}
}
@@ -449,8 +467,18 @@ class APIConnection final : public APIServerConnection {
static uint16_t try_send_alarm_control_panel_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
bool is_single);
#endif
#ifdef USE_WATER_HEATER
static uint16_t try_send_water_heater_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
bool is_single);
static uint16_t try_send_water_heater_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
bool is_single);
#endif
#ifdef USE_INFRARED
static uint16_t try_send_infrared_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
bool is_single);
#endif
#ifdef USE_EVENT
static uint16_t try_send_event_response(event::Event *event, const char *event_type, APIConnection *conn,
static uint16_t try_send_event_response(event::Event *event, StringRef event_type, APIConnection *conn,
uint32_t remaining_size, bool is_single);
static uint16_t try_send_event_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
#endif
@@ -483,18 +511,27 @@ class APIConnection final : public APIServerConnection {
std::unique_ptr<APIFrameHelper> helper_;
APIServer *parent_;
// Group 2: Larger objects (must be 4-byte aligned)
// These contain vectors/pointers internally, so putting them early ensures good alignment
InitialStateIterator initial_state_iterator_;
ListEntitiesIterator list_entities_iterator_;
// Group 2: Iterator union (saves ~16 bytes vs separate iterators)
// These iterators are never active simultaneously - list_entities runs to completion
// before initial_state begins, so we use a union with explicit construction/destruction.
enum class ActiveIterator : uint8_t { NONE, LIST_ENTITIES, INITIAL_STATE };
union IteratorUnion {
ListEntitiesIterator list_entities;
InitialStateIterator initial_state;
// Constructor/destructor do nothing - use placement new/explicit destructor
IteratorUnion() {}
~IteratorUnion() {}
} iterator_storage_;
// Helper methods for iterator lifecycle management
void destroy_active_iterator_();
void begin_iterator_(ActiveIterator type);
#ifdef USE_CAMERA
std::unique_ptr<camera::CameraImageReader> image_reader_;
#endif
// Group 3: Client info struct (24 bytes on 32-bit: 2 strings × 12 bytes each)
ClientInfo client_info_;
// Group 4: 4-byte types
// Group 3: 4-byte types
uint32_t last_traffic_;
#ifdef USE_API_HOMEASSISTANT_STATES
int state_subs_at_ = -1;
@@ -505,28 +542,9 @@ class APIConnection final : public APIServerConnection {
class MessageCreator {
public:
// Constructor for function pointer
MessageCreator(MessageCreatorPtr ptr) { data_.function_ptr = ptr; }
// Constructor for const char * (Event types - no allocation needed)
explicit MessageCreator(const char *str_value) { data_.const_char_ptr = str_value; }
// Delete copy operations - MessageCreator should only be moved
MessageCreator(const MessageCreator &other) = delete;
MessageCreator &operator=(const MessageCreator &other) = delete;
// Move constructor
MessageCreator(MessageCreator &&other) noexcept : data_(other.data_) { other.data_.function_ptr = nullptr; }
// Move assignment
MessageCreator &operator=(MessageCreator &&other) noexcept {
if (this != &other) {
data_ = other.data_;
other.data_.function_ptr = nullptr;
}
return *this;
}
// Call operator - uses message_type to determine union type
uint16_t operator()(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single,
uint8_t message_type) const;
@@ -535,7 +553,7 @@ class APIConnection final : public APIServerConnection {
union Data {
MessageCreatorPtr function_ptr;
const char *const_char_ptr;
} data_; // 4 bytes on 32-bit, 8 bytes on 64-bit - same as before
} data_; // 4 bytes on 32-bit, 8 bytes on 64-bit
};
// Generic batching mechanism for both state updates and entity info
@@ -548,16 +566,14 @@ class APIConnection final : public APIServerConnection {
// Constructor for creating BatchItem
BatchItem(EntityBase *entity, MessageCreator creator, uint8_t message_type, uint8_t estimated_size)
: entity(entity), creator(std::move(creator)), message_type(message_type), estimated_size(estimated_size) {}
: entity(entity), creator(creator), message_type(message_type), estimated_size(estimated_size) {}
};
std::vector<BatchItem> items;
uint32_t batch_start_time{0};
DeferredBatch() {
// Pre-allocate capacity for typical batch sizes to avoid reallocation
items.reserve(8);
}
// No pre-allocation - log connections never use batching, and for
// connections that do, buffers are released after initial sync anyway
// Add item to the batch
void add_item(EntityBase *entity, MessageCreator creator, uint8_t message_type, uint8_t estimated_size);
@@ -576,6 +592,15 @@ class APIConnection final : public APIServerConnection {
bool empty() const { return items.empty(); }
size_t size() const { return items.size(); }
const BatchItem &operator[](size_t index) const { return items[index]; }
// Release excess capacity - only releases if items already empty
void release_buffer() {
// Safe to call: batch is processed before release_buffer is called,
// and if any items remain (partial processing), we must not clear them.
// Use swap trick since shrink_to_fit() is non-binding and may be ignored.
if (items.empty()) {
std::vector<BatchItem>().swap(items);
}
}
};
// DeferredBatch here (16 bytes, 4-byte aligned)
@@ -613,7 +638,9 @@ class APIConnection final : public APIServerConnection {
// 2-byte types immediately after flags_ (no padding between them)
uint16_t client_api_version_major_{0};
uint16_t client_api_version_minor_{0};
// Total: 2 (flags) + 2 + 2 = 6 bytes, then 2 bytes padding to next 4-byte boundary
// 1-byte type to fill padding
ActiveIterator active_iterator_{ActiveIterator::NONE};
// Total: 2 (flags) + 2 + 2 + 1 = 7 bytes, then 1 byte padding to next 4-byte boundary
uint32_t get_batch_delay_ms_() const;
// Message will use 8 more bytes than the minimum size, and typical
@@ -650,21 +677,30 @@ class APIConnection final : public APIServerConnection {
}
#endif
// Helper to check if a message type should bypass batching
// Returns true if:
// 1. It's an UpdateStateResponse (always send immediately to handle cases where
// the main loop is blocked, e.g., during OTA updates)
// 2. It's an EventResponse (events are edge-triggered - every occurrence matters)
// 3. OR: User has opted into immediate sending (should_try_send_immediately = true
// AND batch_delay = 0)
inline bool should_send_immediately_(uint8_t message_type) const {
return (
#ifdef USE_UPDATE
message_type == UpdateStateResponse::MESSAGE_TYPE ||
#endif
#ifdef USE_EVENT
message_type == EventResponse::MESSAGE_TYPE ||
#endif
(this->flags_.should_try_send_immediately && this->get_batch_delay_ms_() == 0));
}
// Helper method to send a message either immediately or via batching
// Tries immediate send if should_send_immediately_() returns true and buffer has space
// Falls back to batching if immediate send fails or isn't applicable
bool send_message_smart_(EntityBase *entity, MessageCreatorPtr creator, uint8_t message_type,
uint8_t estimated_size) {
// Try to send immediately if:
// 1. It's an UpdateStateResponse (always send immediately to handle cases where
// the main loop is blocked, e.g., during OTA updates)
// 2. OR: We should try to send immediately (should_try_send_immediately = true)
// AND Batch delay is 0 (user has opted in to immediate sending)
// 3. AND: Buffer has space available
if ((
#ifdef USE_UPDATE
message_type == UpdateStateResponse::MESSAGE_TYPE ||
#endif
(this->flags_.should_try_send_immediately && this->get_batch_delay_ms_() == 0)) &&
this->helper_->can_write_without_blocking()) {
if (this->should_send_immediately_(message_type) && this->helper_->can_write_without_blocking()) {
// Now actually encode and send
if (creator(entity, this, MAX_BATCH_PACKET_SIZE, true) &&
this->send_buffer(ProtoWriteBuffer{&this->parent_->get_shared_buffer_ref()}, message_type)) {
@@ -682,9 +718,30 @@ class APIConnection final : public APIServerConnection {
return this->schedule_message_(entity, creator, message_type, estimated_size);
}
// Overload for MessageCreator (used by events which need to capture event_type)
bool send_message_smart_(EntityBase *entity, MessageCreator creator, uint8_t message_type, uint8_t estimated_size) {
// Try to send immediately if message type should bypass batching and buffer has space
if (this->should_send_immediately_(message_type) && this->helper_->can_write_without_blocking()) {
// Now actually encode and send
if (creator(entity, this, MAX_BATCH_PACKET_SIZE, true, message_type) &&
this->send_buffer(ProtoWriteBuffer{&this->parent_->get_shared_buffer_ref()}, message_type)) {
#ifdef HAS_PROTO_MESSAGE_DUMP
// Log the message in verbose mode
this->log_proto_message_(entity, creator, message_type);
#endif
return true;
}
// If immediate send failed, fall through to batching
}
// Fall back to scheduled batching
return this->schedule_message_(entity, creator, message_type, estimated_size);
}
// Helper function to schedule a deferred message with known message type
bool schedule_message_(EntityBase *entity, MessageCreator creator, uint8_t message_type, uint8_t estimated_size) {
this->deferred_batch_.add_item(entity, std::move(creator), message_type, estimated_size);
this->deferred_batch_.add_item(entity, creator, message_type, estimated_size);
return this->schedule_batch_();
}
@@ -701,6 +758,8 @@ class APIConnection final : public APIServerConnection {
return this->schedule_batch_();
}
// Helper function to log client messages with name and peername
void log_client_(int level, const LogString *message);
// Helper function to log API errors with errno
void log_warning_(const LogString *message, APIError err);
// Helper to handle fatal errors with logging

View File

@@ -1,6 +1,5 @@
#include "api_frame_helper.h"
#ifdef USE_API
#include "api_connection.h" // For ClientInfo struct
#include "esphome/core/application.h"
#include "esphome/core/hal.h"
#include "esphome/core/helpers.h"
@@ -13,12 +12,29 @@ namespace esphome::api {
static const char *const TAG = "api.frame_helper";
#define HELPER_LOG(msg, ...) \
ESP_LOGVV(TAG, "%s (%s): " msg, this->client_info_->name.c_str(), this->client_info_->peername.c_str(), ##__VA_ARGS__)
// Maximum bytes to log in hex format (168 * 3 = 504, under TX buffer size of 512)
static constexpr size_t API_MAX_LOG_BYTES = 168;
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE
#define HELPER_LOG(msg, ...) ESP_LOGVV(TAG, "%s (%s): " msg, this->client_name_, this->client_peername_, ##__VA_ARGS__)
#else
#define HELPER_LOG(msg, ...) ((void) 0)
#endif
#ifdef HELPER_LOG_PACKETS
#define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str())
#define LOG_PACKET_SENDING(data, len) ESP_LOGVV(TAG, "Sending raw: %s", format_hex_pretty(data, len).c_str())
#define LOG_PACKET_RECEIVED(buffer) \
do { \
char hex_buf_[format_hex_pretty_size(API_MAX_LOG_BYTES)]; \
ESP_LOGVV(TAG, "Received frame: %s", \
format_hex_pretty_to(hex_buf_, (buffer).data(), \
(buffer).size() < API_MAX_LOG_BYTES ? (buffer).size() : API_MAX_LOG_BYTES)); \
} while (0)
#define LOG_PACKET_SENDING(data, len) \
do { \
char hex_buf_[format_hex_pretty_size(API_MAX_LOG_BYTES)]; \
ESP_LOGVV(TAG, "Sending raw: %s", \
format_hex_pretty_to(hex_buf_, data, (len) < API_MAX_LOG_BYTES ? (len) : API_MAX_LOG_BYTES)); \
} while (0)
#else
#define LOG_PACKET_RECEIVED(buffer) ((void) 0)
#define LOG_PACKET_SENDING(data, len) ((void) 0)
@@ -229,6 +245,8 @@ APIError APIFrameHelper::init_common_() {
HELPER_LOG("Bad state for init %d", (int) state_);
return APIError::BAD_STATE;
}
// Cache peername now while socket is valid - needed for error logging after socket failure
this->socket_->getpeername_to(this->client_peername_);
int err = this->socket_->setblocking(false);
if (err != 0) {
state_ = State::FAILED;

View File

@@ -29,25 +29,28 @@ static constexpr uint16_t MAX_MESSAGE_SIZE = 8192; // 8 KiB for ESP8266
static constexpr uint16_t MAX_MESSAGE_SIZE = 32768; // 32 KiB for ESP32 and other platforms
#endif
// Forward declaration
struct ClientInfo;
// Maximum number of messages to batch in a single write operation
// Must be >= MAX_INITIAL_PER_BATCH in api_connection.h (enforced by static_assert there)
static constexpr size_t MAX_MESSAGES_PER_BATCH = 34;
class ProtoWriteBuffer;
// Max client name length (e.g., "Home Assistant 2026.1.0.dev0" = 28 chars)
static constexpr size_t CLIENT_INFO_NAME_MAX_LEN = 32;
struct ReadPacketBuffer {
std::vector<uint8_t> container;
uint16_t type;
uint16_t data_offset;
const uint8_t *data; // Points directly into frame helper's rx_buf_ (valid until next read_packet call)
uint16_t data_len;
uint16_t type;
};
// Packed packet info structure to minimize memory usage
struct PacketInfo {
// Packed message info structure to minimize memory usage
struct MessageInfo {
uint16_t offset; // Offset in buffer where message starts
uint16_t payload_size; // Size of the message payload
uint8_t message_type; // Message type (0-255)
PacketInfo(uint8_t type, uint16_t off, uint16_t size) : offset(off), payload_size(size), message_type(type) {}
MessageInfo(uint8_t type, uint16_t off, uint16_t size) : offset(off), payload_size(size), message_type(type) {}
};
enum class APIError : uint16_t {
@@ -83,16 +86,23 @@ const LogString *api_error_to_logstr(APIError err);
class APIFrameHelper {
public:
APIFrameHelper() = default;
explicit APIFrameHelper(std::unique_ptr<socket::Socket> socket, const ClientInfo *client_info)
: socket_owned_(std::move(socket)), client_info_(client_info) {
socket_ = socket_owned_.get();
explicit APIFrameHelper(std::unique_ptr<socket::Socket> socket) : socket_(std::move(socket)) {}
// Get client name (null-terminated)
const char *get_client_name() const { return this->client_name_; }
// Get client peername/IP (null-terminated, cached at init time for availability after socket failure)
const char *get_client_peername() const { return this->client_peername_; }
// Set client name from buffer with length (truncates if needed)
void set_client_name(const char *name, size_t len) {
size_t copy_len = std::min(len, sizeof(this->client_name_) - 1);
memcpy(this->client_name_, name, copy_len);
this->client_name_[copy_len] = '\0';
}
virtual ~APIFrameHelper() = default;
virtual APIError init() = 0;
virtual APIError loop();
virtual APIError read_packet(ReadPacketBuffer *buffer) = 0;
bool can_write_without_blocking() { return this->state_ == State::DATA && this->tx_buf_count_ == 0; }
std::string getpeername() { return socket_->getpeername(); }
int getpeername(struct sockaddr *addr, socklen_t *addrlen) { return socket_->getpeername(addr, addrlen); }
APIError close() {
state_ = State::CLOSED;
@@ -110,17 +120,48 @@ class APIFrameHelper {
}
return APIError::OK;
}
/// Toggle TCP_NODELAY socket option to control Nagle's algorithm.
///
/// This is used to allow log messages to coalesce (Nagle enabled) while keeping
/// state updates low-latency (NODELAY enabled). Without this, many small log
/// packets fill the TCP send buffer, crowding out important state updates.
///
/// State is tracked to minimize setsockopt() overhead - on lwip_raw (ESP8266/RP2040)
/// this is just a boolean assignment; on other platforms it's a lightweight syscall.
///
/// @param enable true to enable NODELAY (disable Nagle), false to enable Nagle
/// @return true if successful or already in desired state
bool set_nodelay(bool enable) {
if (this->nodelay_enabled_ == enable)
return true;
int val = enable ? 1 : 0;
int err = this->socket_->setsockopt(IPPROTO_TCP, TCP_NODELAY, &val, sizeof(int));
if (err == 0) {
this->nodelay_enabled_ = enable;
}
return err == 0;
}
virtual APIError write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) = 0;
// Write multiple protobuf packets in a single operation
// packets contains (message_type, offset, length) for each message in the buffer
// Write multiple protobuf messages in a single operation
// messages contains (message_type, offset, length) for each message in the buffer
// The buffer contains all messages with appropriate padding before each
virtual APIError write_protobuf_packets(ProtoWriteBuffer buffer, std::span<const PacketInfo> packets) = 0;
virtual APIError write_protobuf_messages(ProtoWriteBuffer buffer, std::span<const MessageInfo> messages) = 0;
// Get the frame header padding required by this protocol
uint8_t frame_header_padding() const { return frame_header_padding_; }
// Get the frame footer size required by this protocol
uint8_t frame_footer_size() const { return frame_footer_size_; }
// Check if socket has data ready to read
bool is_socket_ready() const { return socket_ != nullptr && socket_->ready(); }
// Release excess memory from internal buffers after initial sync
void release_buffers() {
// rx_buf_: Safe to clear only if no partial read in progress.
// rx_buf_len_ tracks bytes read so far; if non-zero, we're mid-frame
// and clearing would lose partially received data.
if (this->rx_buf_len_ == 0) {
// Use swap trick since shrink_to_fit() is non-binding and may be ignored
std::vector<uint8_t>().swap(this->rx_buf_);
}
}
protected:
// Buffer containing data to be sent
@@ -149,9 +190,8 @@ class APIFrameHelper {
APIError write_raw_(const struct iovec *iov, int iovcnt, socket::Socket *socket, std::vector<uint8_t> &tx_buf,
const std::string &info, StateEnum &state, StateEnum failed_state);
// Pointers first (4 bytes each)
socket::Socket *socket_{nullptr};
std::unique_ptr<socket::Socket> socket_owned_;
// Socket ownership (4 bytes on 32-bit, 8 bytes on 64-bit)
std::unique_ptr<socket::Socket> socket_;
// Common state enum for all frame helpers
// Note: Not all states are used by all implementations
@@ -174,12 +214,12 @@ class APIFrameHelper {
// Containers (size varies, but typically 12+ bytes on 32-bit)
std::array<std::unique_ptr<SendBuffer>, API_MAX_SEND_QUEUE> tx_buf_;
std::vector<struct iovec> reusable_iovs_;
std::vector<uint8_t> rx_buf_;
// Pointer to client info (4 bytes on 32-bit)
// Note: The pointed-to ClientInfo object must outlive this APIFrameHelper instance.
const ClientInfo *client_info_{nullptr};
// Client name buffer - stores name from Hello message or initial peername
char client_name_[CLIENT_INFO_NAME_MAX_LEN]{};
// Cached peername/IP address - captured at init time for availability after socket failure
char client_peername_[socket::SOCKADDR_STR_LEN]{};
// Group smaller types together
uint16_t rx_buf_len_ = 0;
@@ -189,7 +229,10 @@ class APIFrameHelper {
uint8_t tx_buf_head_{0};
uint8_t tx_buf_tail_{0};
uint8_t tx_buf_count_{0};
// 8 bytes total, 0 bytes padding
// Tracks TCP_NODELAY state to minimize setsockopt() calls. Initialized to true
// since init_common_() enables NODELAY. Used by set_nodelay() to allow log
// messages to coalesce while keeping state updates low-latency.
bool nodelay_enabled_{true};
// Common initialization for both plaintext and noise protocols
APIError init_common_();

View File

@@ -24,12 +24,29 @@ static const char *const PROLOGUE_INIT = "NoiseAPIInit";
#endif
static constexpr size_t PROLOGUE_INIT_LEN = 12; // strlen("NoiseAPIInit")
#define HELPER_LOG(msg, ...) \
ESP_LOGVV(TAG, "%s (%s): " msg, this->client_info_->name.c_str(), this->client_info_->peername.c_str(), ##__VA_ARGS__)
// Maximum bytes to log in hex format (168 * 3 = 504, under TX buffer size of 512)
static constexpr size_t API_MAX_LOG_BYTES = 168;
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE
#define HELPER_LOG(msg, ...) ESP_LOGVV(TAG, "%s (%s): " msg, this->client_name_, this->client_peername_, ##__VA_ARGS__)
#else
#define HELPER_LOG(msg, ...) ((void) 0)
#endif
#ifdef HELPER_LOG_PACKETS
#define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str())
#define LOG_PACKET_SENDING(data, len) ESP_LOGVV(TAG, "Sending raw: %s", format_hex_pretty(data, len).c_str())
#define LOG_PACKET_RECEIVED(buffer) \
do { \
char hex_buf_[format_hex_pretty_size(API_MAX_LOG_BYTES)]; \
ESP_LOGVV(TAG, "Received frame: %s", \
format_hex_pretty_to(hex_buf_, (buffer).data(), \
(buffer).size() < API_MAX_LOG_BYTES ? (buffer).size() : API_MAX_LOG_BYTES)); \
} while (0)
#define LOG_PACKET_SENDING(data, len) \
do { \
char hex_buf_[format_hex_pretty_size(API_MAX_LOG_BYTES)]; \
ESP_LOGVV(TAG, "Sending raw: %s", \
format_hex_pretty_to(hex_buf_, data, (len) < API_MAX_LOG_BYTES ? (len) : API_MAX_LOG_BYTES)); \
} while (0)
#else
#define LOG_PACKET_RECEIVED(buffer) ((void) 0)
#define LOG_PACKET_SENDING(data, len) ((void) 0)
@@ -239,12 +256,13 @@ APIError APINoiseFrameHelper::state_action_() {
}
if (state_ == State::SERVER_HELLO) {
// send server hello
constexpr size_t mac_len = 13; // 12 hex chars + null terminator
const std::string &name = App.get_name();
const std::string &mac = get_mac_address();
char mac[mac_len];
get_mac_address_into_buffer(mac);
// Calculate positions and sizes
size_t name_len = name.size() + 1; // including null terminator
size_t mac_len = mac.size() + 1; // including null terminator
size_t name_offset = 1;
size_t mac_offset = name_offset + name_len;
size_t total_size = 1 + name_len + mac_len;
@@ -257,7 +275,7 @@ APIError APINoiseFrameHelper::state_action_() {
// node name, terminated by null byte
std::memcpy(msg.get() + name_offset, name.c_str(), name_len);
// node mac, terminated by null byte
std::memcpy(msg.get() + mac_offset, mac.c_str(), mac_len);
std::memcpy(msg.get() + mac_offset, mac, mac_len);
aerr = write_frame_(msg.get(), total_size);
if (aerr != APIError::OK)
@@ -406,8 +424,7 @@ APIError APINoiseFrameHelper::read_packet(ReadPacketBuffer *buffer) {
return APIError::BAD_DATA_PACKET;
}
buffer->container = std::move(this->rx_buf_);
buffer->data_offset = 4;
buffer->data = msg_data + 4; // Skip 4-byte header (type + length)
buffer->data_len = data_len;
buffer->type = type;
return APIError::OK;
@@ -415,12 +432,12 @@ APIError APINoiseFrameHelper::read_packet(ReadPacketBuffer *buffer) {
APIError APINoiseFrameHelper::write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) {
// Resize to include MAC space (required for Noise encryption)
buffer.get_buffer()->resize(buffer.get_buffer()->size() + frame_footer_size_);
PacketInfo packet{type, 0,
static_cast<uint16_t>(buffer.get_buffer()->size() - frame_header_padding_ - frame_footer_size_)};
return write_protobuf_packets(buffer, std::span<const PacketInfo>(&packet, 1));
MessageInfo msg{type, 0,
static_cast<uint16_t>(buffer.get_buffer()->size() - frame_header_padding_ - frame_footer_size_)};
return write_protobuf_messages(buffer, std::span<const MessageInfo>(&msg, 1));
}
APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, std::span<const PacketInfo> packets) {
APIError APINoiseFrameHelper::write_protobuf_messages(ProtoWriteBuffer buffer, std::span<const MessageInfo> messages) {
APIError aerr = state_action_();
if (aerr != APIError::OK) {
return aerr;
@@ -430,20 +447,20 @@ APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, st
return APIError::WOULD_BLOCK;
}
if (packets.empty()) {
if (messages.empty()) {
return APIError::OK;
}
uint8_t *buffer_data = buffer.get_buffer()->data();
this->reusable_iovs_.clear();
this->reusable_iovs_.reserve(packets.size());
// Stack-allocated iovec array - no heap allocation
StaticVector<struct iovec, MAX_MESSAGES_PER_BATCH> iovs;
uint16_t total_write_len = 0;
// We need to encrypt each packet in place
for (const auto &packet : packets) {
// We need to encrypt each message in place
for (const auto &msg : messages) {
// The buffer already has padding at offset
uint8_t *buf_start = buffer_data + packet.offset;
uint8_t *buf_start = buffer_data + msg.offset;
// Write noise header
buf_start[0] = 0x01; // indicator
@@ -451,10 +468,10 @@ APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, st
// Write message header (to be encrypted)
const uint8_t msg_offset = 3;
buf_start[msg_offset] = static_cast<uint8_t>(packet.message_type >> 8); // type high byte
buf_start[msg_offset + 1] = static_cast<uint8_t>(packet.message_type); // type low byte
buf_start[msg_offset + 2] = static_cast<uint8_t>(packet.payload_size >> 8); // data_len high byte
buf_start[msg_offset + 3] = static_cast<uint8_t>(packet.payload_size); // data_len low byte
buf_start[msg_offset] = static_cast<uint8_t>(msg.message_type >> 8); // type high byte
buf_start[msg_offset + 1] = static_cast<uint8_t>(msg.message_type); // type low byte
buf_start[msg_offset + 2] = static_cast<uint8_t>(msg.payload_size >> 8); // data_len high byte
buf_start[msg_offset + 3] = static_cast<uint8_t>(msg.payload_size); // data_len low byte
// payload data is already in the buffer starting at offset + 7
// Make sure we have space for MAC
@@ -463,8 +480,8 @@ APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, st
// Encrypt the message in place
NoiseBuffer mbuf;
noise_buffer_init(mbuf);
noise_buffer_set_inout(mbuf, buf_start + msg_offset, 4 + packet.payload_size,
4 + packet.payload_size + frame_footer_size_);
noise_buffer_set_inout(mbuf, buf_start + msg_offset, 4 + msg.payload_size,
4 + msg.payload_size + frame_footer_size_);
int err = noise_cipherstate_encrypt(send_cipher_, &mbuf);
APIError aerr =
@@ -476,14 +493,14 @@ APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, st
buf_start[1] = static_cast<uint8_t>(mbuf.size >> 8);
buf_start[2] = static_cast<uint8_t>(mbuf.size);
// Add iovec for this encrypted packet
size_t packet_len = static_cast<size_t>(3 + mbuf.size); // indicator + size + encrypted data
this->reusable_iovs_.push_back({buf_start, packet_len});
total_write_len += packet_len;
// Add iovec for this encrypted message
size_t msg_len = static_cast<size_t>(3 + mbuf.size); // indicator + size + encrypted data
iovs.push_back({buf_start, msg_len});
total_write_len += msg_len;
}
// Send all encrypted packets in one writev call
return this->write_raw_(this->reusable_iovs_.data(), this->reusable_iovs_.size(), total_write_len);
// Send all encrypted messages in one writev call
return this->write_raw_(iovs.data(), iovs.size(), total_write_len);
}
APIError APINoiseFrameHelper::write_frame_(const uint8_t *data, uint16_t len) {
@@ -527,7 +544,7 @@ APIError APINoiseFrameHelper::init_handshake_() {
if (aerr != APIError::OK)
return aerr;
const auto &psk = ctx_->get_psk();
const auto &psk = this->ctx_.get_psk();
err = noise_handshakestate_set_pre_shared_key(handshake_, psk.data(), psk.size());
aerr = handle_noise_error_(err, LOG_STR("noise_handshakestate_set_pre_shared_key"),
APIError::HANDSHAKESTATE_SETUP_FAILED);
@@ -539,7 +556,8 @@ APIError APINoiseFrameHelper::init_handshake_() {
if (aerr != APIError::OK)
return aerr;
// set_prologue copies it into handshakestate, so we can get rid of it now
prologue_ = {};
// Use swap idiom to actually release memory (= {} only clears size, not capacity)
std::vector<uint8_t>().swap(prologue_);
err = noise_handshakestate_start(handshake_);
aerr = handle_noise_error_(err, LOG_STR("noise_handshakestate_start"), APIError::HANDSHAKESTATE_SETUP_FAILED);

View File

@@ -9,9 +9,8 @@ namespace esphome::api {
class APINoiseFrameHelper final : public APIFrameHelper {
public:
APINoiseFrameHelper(std::unique_ptr<socket::Socket> socket, std::shared_ptr<APINoiseContext> ctx,
const ClientInfo *client_info)
: APIFrameHelper(std::move(socket), client_info), ctx_(std::move(ctx)) {
APINoiseFrameHelper(std::unique_ptr<socket::Socket> socket, APINoiseContext &ctx)
: APIFrameHelper(std::move(socket)), ctx_(ctx) {
// Noise header structure:
// Pos 0: indicator (0x01)
// Pos 1-2: encrypted payload size (16-bit big-endian)
@@ -24,7 +23,7 @@ class APINoiseFrameHelper final : public APIFrameHelper {
APIError loop() override;
APIError read_packet(ReadPacketBuffer *buffer) override;
APIError write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) override;
APIError write_protobuf_packets(ProtoWriteBuffer buffer, std::span<const PacketInfo> packets) override;
APIError write_protobuf_messages(ProtoWriteBuffer buffer, std::span<const MessageInfo> messages) override;
protected:
APIError state_action_();
@@ -41,8 +40,8 @@ class APINoiseFrameHelper final : public APIFrameHelper {
NoiseCipherState *send_cipher_{nullptr};
NoiseCipherState *recv_cipher_{nullptr};
// Shared pointer (8 bytes on 32-bit = 4 bytes control block pointer + 4 bytes object pointer)
std::shared_ptr<APINoiseContext> ctx_;
// Reference to noise context (4 bytes on 32-bit)
APINoiseContext &ctx_;
// Vector (12 bytes on 32-bit)
std::vector<uint8_t> prologue_;

View File

@@ -1,7 +1,6 @@
#include "api_frame_helper_plaintext.h"
#ifdef USE_API
#ifdef USE_API_PLAINTEXT
#include "api_connection.h" // For ClientInfo struct
#include "esphome/core/application.h"
#include "esphome/core/hal.h"
#include "esphome/core/helpers.h"
@@ -18,12 +17,29 @@ namespace esphome::api {
static const char *const TAG = "api.plaintext";
#define HELPER_LOG(msg, ...) \
ESP_LOGVV(TAG, "%s (%s): " msg, this->client_info_->name.c_str(), this->client_info_->peername.c_str(), ##__VA_ARGS__)
// Maximum bytes to log in hex format (168 * 3 = 504, under TX buffer size of 512)
static constexpr size_t API_MAX_LOG_BYTES = 168;
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE
#define HELPER_LOG(msg, ...) ESP_LOGVV(TAG, "%s (%s): " msg, this->client_name_, this->client_peername_, ##__VA_ARGS__)
#else
#define HELPER_LOG(msg, ...) ((void) 0)
#endif
#ifdef HELPER_LOG_PACKETS
#define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str())
#define LOG_PACKET_SENDING(data, len) ESP_LOGVV(TAG, "Sending raw: %s", format_hex_pretty(data, len).c_str())
#define LOG_PACKET_RECEIVED(buffer) \
do { \
char hex_buf_[format_hex_pretty_size(API_MAX_LOG_BYTES)]; \
ESP_LOGVV(TAG, "Received frame: %s", \
format_hex_pretty_to(hex_buf_, (buffer).data(), \
(buffer).size() < API_MAX_LOG_BYTES ? (buffer).size() : API_MAX_LOG_BYTES)); \
} while (0)
#define LOG_PACKET_SENDING(data, len) \
do { \
char hex_buf_[format_hex_pretty_size(API_MAX_LOG_BYTES)]; \
ESP_LOGVV(TAG, "Sending raw: %s", \
format_hex_pretty_to(hex_buf_, data, (len) < API_MAX_LOG_BYTES ? (len) : API_MAX_LOG_BYTES)); \
} while (0)
#else
#define LOG_PACKET_RECEIVED(buffer) ((void) 0)
#define LOG_PACKET_SENDING(data, len) ((void) 0)
@@ -210,36 +226,36 @@ APIError APIPlaintextFrameHelper::read_packet(ReadPacketBuffer *buffer) {
return aerr;
}
buffer->container = std::move(this->rx_buf_);
buffer->data_offset = 0;
buffer->data = this->rx_buf_.data();
buffer->data_len = this->rx_header_parsed_len_;
buffer->type = this->rx_header_parsed_type_;
return APIError::OK;
}
APIError APIPlaintextFrameHelper::write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) {
PacketInfo packet{type, 0, static_cast<uint16_t>(buffer.get_buffer()->size() - frame_header_padding_)};
return write_protobuf_packets(buffer, std::span<const PacketInfo>(&packet, 1));
MessageInfo msg{type, 0, static_cast<uint16_t>(buffer.get_buffer()->size() - frame_header_padding_)};
return write_protobuf_messages(buffer, std::span<const MessageInfo>(&msg, 1));
}
APIError APIPlaintextFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, std::span<const PacketInfo> packets) {
APIError APIPlaintextFrameHelper::write_protobuf_messages(ProtoWriteBuffer buffer,
std::span<const MessageInfo> messages) {
if (state_ != State::DATA) {
return APIError::BAD_STATE;
}
if (packets.empty()) {
if (messages.empty()) {
return APIError::OK;
}
uint8_t *buffer_data = buffer.get_buffer()->data();
this->reusable_iovs_.clear();
this->reusable_iovs_.reserve(packets.size());
// Stack-allocated iovec array - no heap allocation
StaticVector<struct iovec, MAX_MESSAGES_PER_BATCH> iovs;
uint16_t total_write_len = 0;
for (const auto &packet : packets) {
for (const auto &msg : messages) {
// Calculate varint sizes for header layout
uint8_t size_varint_len = api::ProtoSize::varint(static_cast<uint32_t>(packet.payload_size));
uint8_t type_varint_len = api::ProtoSize::varint(static_cast<uint32_t>(packet.message_type));
uint8_t size_varint_len = api::ProtoSize::varint(static_cast<uint32_t>(msg.payload_size));
uint8_t type_varint_len = api::ProtoSize::varint(static_cast<uint32_t>(msg.message_type));
uint8_t total_header_len = 1 + size_varint_len + type_varint_len;
// Calculate where to start writing the header
@@ -267,25 +283,25 @@ APIError APIPlaintextFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer
//
// The message starts at offset + frame_header_padding_
// So we write the header starting at offset + frame_header_padding_ - total_header_len
uint8_t *buf_start = buffer_data + packet.offset;
uint8_t *buf_start = buffer_data + msg.offset;
uint32_t header_offset = frame_header_padding_ - total_header_len;
// Write the plaintext header
buf_start[header_offset] = 0x00; // indicator
// Encode varints directly into buffer
ProtoVarInt(packet.payload_size).encode_to_buffer_unchecked(buf_start + header_offset + 1, size_varint_len);
ProtoVarInt(packet.message_type)
ProtoVarInt(msg.payload_size).encode_to_buffer_unchecked(buf_start + header_offset + 1, size_varint_len);
ProtoVarInt(msg.message_type)
.encode_to_buffer_unchecked(buf_start + header_offset + 1 + size_varint_len, type_varint_len);
// Add iovec for this packet (header + payload)
size_t packet_len = static_cast<size_t>(total_header_len + packet.payload_size);
this->reusable_iovs_.push_back({buf_start + header_offset, packet_len});
total_write_len += packet_len;
// Add iovec for this message (header + payload)
size_t msg_len = static_cast<size_t>(total_header_len + msg.payload_size);
iovs.push_back({buf_start + header_offset, msg_len});
total_write_len += msg_len;
}
// Send all packets in one writev call
return write_raw_(this->reusable_iovs_.data(), this->reusable_iovs_.size(), total_write_len);
// Send all messages in one writev call
return write_raw_(iovs.data(), iovs.size(), total_write_len);
}
} // namespace esphome::api

View File

@@ -7,8 +7,7 @@ namespace esphome::api {
class APIPlaintextFrameHelper final : public APIFrameHelper {
public:
APIPlaintextFrameHelper(std::unique_ptr<socket::Socket> socket, const ClientInfo *client_info)
: APIFrameHelper(std::move(socket), client_info) {
explicit APIPlaintextFrameHelper(std::unique_ptr<socket::Socket> socket) : APIFrameHelper(std::move(socket)) {
// Plaintext header structure (worst case):
// Pos 0: indicator (0x00)
// Pos 1-3: payload size varint (up to 3 bytes)
@@ -21,7 +20,7 @@ class APIPlaintextFrameHelper final : public APIFrameHelper {
APIError loop() override;
APIError read_packet(ReadPacketBuffer *buffer) override;
APIError write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) override;
APIError write_protobuf_packets(ProtoWriteBuffer buffer, std::span<const PacketInfo> packets) override;
APIError write_protobuf_messages(ProtoWriteBuffer buffer, std::span<const MessageInfo> messages) override;
protected:
APIError try_read_frame_();

View File

@@ -27,7 +27,6 @@ extend google.protobuf.MessageOptions {
extend google.protobuf.FieldOptions {
optional string field_ifdef = 1042;
optional uint32 fixed_array_size = 50007;
optional bool no_zero_copy = 50008 [default=false];
optional bool fixed_array_skip_zero = 50009 [default=false];
optional string fixed_array_size_define = 50010;
optional string fixed_array_with_length_define = 50011;
@@ -80,4 +79,15 @@ extend google.protobuf.FieldOptions {
// Example: [(container_pointer_no_template) = "light::ColorModeMask"]
// generates: const light::ColorModeMask *supported_color_modes{};
optional string container_pointer_no_template = 50014;
// packed_buffer: Expose raw packed buffer instead of decoding into container
// When set on a packed repeated field, the generated code stores a pointer
// to the raw protobuf buffer instead of decoding values. This enables
// zero-copy passthrough when the consumer can decode on-demand.
// The field must be a packed repeated field (packed=true).
// Generates three fields:
// - const uint8_t *<field>_data_{nullptr};
// - uint16_t <field>_length_{0};
// - uint16_t <field>_count_{0};
optional bool packed_buffer = 50015 [default=false];
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,10 @@
#include "esphome/components/climate/climate_traits.h"
#endif
#ifdef USE_WATER_HEATER
#include "esphome/components/water_heater/water_heater.h"
#endif
#ifdef USE_LIGHT
#include "esphome/components/light/light_traits.h"
#endif

View File

@@ -8,38 +8,31 @@ namespace esphome::api {
static const char *const TAG = "api.service";
#ifdef HAS_PROTO_MESSAGE_DUMP
void APIServerConnectionBase::log_send_message_(const char *name, const std::string &dump) {
ESP_LOGVV(TAG, "send_message %s: %s", name, dump.c_str());
void APIServerConnectionBase::log_send_message_(const char *name, const char *dump) {
ESP_LOGVV(TAG, "send_message %s: %s", name, dump);
}
void APIServerConnectionBase::log_receive_message_(const LogString *name, const ProtoMessage &msg) {
DumpBuffer dump_buf;
ESP_LOGVV(TAG, "%s: %s", LOG_STR_ARG(name), msg.dump_to(dump_buf));
}
#endif
void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) {
void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type, const uint8_t *msg_data) {
switch (msg_type) {
case HelloRequest::MESSAGE_TYPE: {
HelloRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_hello_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_hello_request"), msg);
#endif
this->on_hello_request(msg);
break;
}
#ifdef USE_API_PASSWORD
case AuthenticationRequest::MESSAGE_TYPE: {
AuthenticationRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_authentication_request: %s", msg.dump().c_str());
#endif
this->on_authentication_request(msg);
break;
}
#endif
case DisconnectRequest::MESSAGE_TYPE: {
DisconnectRequest msg;
// Empty message: no decode needed
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_disconnect_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_disconnect_request"), msg);
#endif
this->on_disconnect_request(msg);
break;
@@ -48,7 +41,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
DisconnectResponse msg;
// Empty message: no decode needed
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_disconnect_response: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_disconnect_response"), msg);
#endif
this->on_disconnect_response(msg);
break;
@@ -57,7 +50,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
PingRequest msg;
// Empty message: no decode needed
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_ping_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_ping_request"), msg);
#endif
this->on_ping_request(msg);
break;
@@ -66,7 +59,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
PingResponse msg;
// Empty message: no decode needed
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_ping_response: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_ping_response"), msg);
#endif
this->on_ping_response(msg);
break;
@@ -75,7 +68,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
DeviceInfoRequest msg;
// Empty message: no decode needed
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_device_info_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_device_info_request"), msg);
#endif
this->on_device_info_request(msg);
break;
@@ -84,7 +77,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
ListEntitiesRequest msg;
// Empty message: no decode needed
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_list_entities_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_list_entities_request"), msg);
#endif
this->on_list_entities_request(msg);
break;
@@ -93,7 +86,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
SubscribeStatesRequest msg;
// Empty message: no decode needed
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_subscribe_states_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_subscribe_states_request"), msg);
#endif
this->on_subscribe_states_request(msg);
break;
@@ -102,7 +95,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
SubscribeLogsRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_subscribe_logs_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_subscribe_logs_request"), msg);
#endif
this->on_subscribe_logs_request(msg);
break;
@@ -112,7 +105,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
CoverCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_cover_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_cover_command_request"), msg);
#endif
this->on_cover_command_request(msg);
break;
@@ -123,7 +116,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
FanCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_fan_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_fan_command_request"), msg);
#endif
this->on_fan_command_request(msg);
break;
@@ -134,7 +127,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
LightCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_light_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_light_command_request"), msg);
#endif
this->on_light_command_request(msg);
break;
@@ -145,7 +138,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
SwitchCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_switch_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_switch_command_request"), msg);
#endif
this->on_switch_command_request(msg);
break;
@@ -156,7 +149,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
SubscribeHomeassistantServicesRequest msg;
// Empty message: no decode needed
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_subscribe_homeassistant_services_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_subscribe_homeassistant_services_request"), msg);
#endif
this->on_subscribe_homeassistant_services_request(msg);
break;
@@ -166,7 +159,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
GetTimeResponse msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_get_time_response: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_get_time_response"), msg);
#endif
this->on_get_time_response(msg);
break;
@@ -176,7 +169,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
SubscribeHomeAssistantStatesRequest msg;
// Empty message: no decode needed
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_subscribe_home_assistant_states_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_subscribe_home_assistant_states_request"), msg);
#endif
this->on_subscribe_home_assistant_states_request(msg);
break;
@@ -187,18 +180,18 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
HomeAssistantStateResponse msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_home_assistant_state_response: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_home_assistant_state_response"), msg);
#endif
this->on_home_assistant_state_response(msg);
break;
}
#endif
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
case ExecuteServiceRequest::MESSAGE_TYPE: {
ExecuteServiceRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_execute_service_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_execute_service_request"), msg);
#endif
this->on_execute_service_request(msg);
break;
@@ -209,7 +202,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
CameraImageRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_camera_image_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_camera_image_request"), msg);
#endif
this->on_camera_image_request(msg);
break;
@@ -220,7 +213,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
ClimateCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_climate_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_climate_command_request"), msg);
#endif
this->on_climate_command_request(msg);
break;
@@ -231,7 +224,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
NumberCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_number_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_number_command_request"), msg);
#endif
this->on_number_command_request(msg);
break;
@@ -242,7 +235,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
SelectCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_select_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_select_command_request"), msg);
#endif
this->on_select_command_request(msg);
break;
@@ -253,7 +246,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
SirenCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_siren_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_siren_command_request"), msg);
#endif
this->on_siren_command_request(msg);
break;
@@ -264,7 +257,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
LockCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_lock_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_lock_command_request"), msg);
#endif
this->on_lock_command_request(msg);
break;
@@ -275,7 +268,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
ButtonCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_button_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_button_command_request"), msg);
#endif
this->on_button_command_request(msg);
break;
@@ -286,7 +279,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
MediaPlayerCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_media_player_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_media_player_command_request"), msg);
#endif
this->on_media_player_command_request(msg);
break;
@@ -297,7 +290,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
SubscribeBluetoothLEAdvertisementsRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_subscribe_bluetooth_le_advertisements_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_subscribe_bluetooth_le_advertisements_request"), msg);
#endif
this->on_subscribe_bluetooth_le_advertisements_request(msg);
break;
@@ -308,7 +301,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
BluetoothDeviceRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_bluetooth_device_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_bluetooth_device_request"), msg);
#endif
this->on_bluetooth_device_request(msg);
break;
@@ -319,7 +312,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
BluetoothGATTGetServicesRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_bluetooth_gatt_get_services_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_bluetooth_gatt_get_services_request"), msg);
#endif
this->on_bluetooth_gatt_get_services_request(msg);
break;
@@ -330,7 +323,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
BluetoothGATTReadRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_bluetooth_gatt_read_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_bluetooth_gatt_read_request"), msg);
#endif
this->on_bluetooth_gatt_read_request(msg);
break;
@@ -341,7 +334,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
BluetoothGATTWriteRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_bluetooth_gatt_write_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_bluetooth_gatt_write_request"), msg);
#endif
this->on_bluetooth_gatt_write_request(msg);
break;
@@ -352,7 +345,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
BluetoothGATTReadDescriptorRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_bluetooth_gatt_read_descriptor_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_bluetooth_gatt_read_descriptor_request"), msg);
#endif
this->on_bluetooth_gatt_read_descriptor_request(msg);
break;
@@ -363,7 +356,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
BluetoothGATTWriteDescriptorRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_bluetooth_gatt_write_descriptor_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_bluetooth_gatt_write_descriptor_request"), msg);
#endif
this->on_bluetooth_gatt_write_descriptor_request(msg);
break;
@@ -374,7 +367,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
BluetoothGATTNotifyRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_bluetooth_gatt_notify_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_bluetooth_gatt_notify_request"), msg);
#endif
this->on_bluetooth_gatt_notify_request(msg);
break;
@@ -385,7 +378,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
SubscribeBluetoothConnectionsFreeRequest msg;
// Empty message: no decode needed
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_subscribe_bluetooth_connections_free_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_subscribe_bluetooth_connections_free_request"), msg);
#endif
this->on_subscribe_bluetooth_connections_free_request(msg);
break;
@@ -396,7 +389,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
UnsubscribeBluetoothLEAdvertisementsRequest msg;
// Empty message: no decode needed
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_unsubscribe_bluetooth_le_advertisements_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_unsubscribe_bluetooth_le_advertisements_request"), msg);
#endif
this->on_unsubscribe_bluetooth_le_advertisements_request(msg);
break;
@@ -407,7 +400,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
SubscribeVoiceAssistantRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_subscribe_voice_assistant_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_subscribe_voice_assistant_request"), msg);
#endif
this->on_subscribe_voice_assistant_request(msg);
break;
@@ -418,7 +411,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
VoiceAssistantResponse msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_voice_assistant_response: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_voice_assistant_response"), msg);
#endif
this->on_voice_assistant_response(msg);
break;
@@ -429,7 +422,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
VoiceAssistantEventResponse msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_voice_assistant_event_response: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_voice_assistant_event_response"), msg);
#endif
this->on_voice_assistant_event_response(msg);
break;
@@ -440,7 +433,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
AlarmControlPanelCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_alarm_control_panel_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_alarm_control_panel_command_request"), msg);
#endif
this->on_alarm_control_panel_command_request(msg);
break;
@@ -451,7 +444,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
TextCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_text_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_text_command_request"), msg);
#endif
this->on_text_command_request(msg);
break;
@@ -462,7 +455,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
DateCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_date_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_date_command_request"), msg);
#endif
this->on_date_command_request(msg);
break;
@@ -473,7 +466,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
TimeCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_time_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_time_command_request"), msg);
#endif
this->on_time_command_request(msg);
break;
@@ -484,7 +477,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
VoiceAssistantAudio msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_voice_assistant_audio: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_voice_assistant_audio"), msg);
#endif
this->on_voice_assistant_audio(msg);
break;
@@ -495,7 +488,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
ValveCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_valve_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_valve_command_request"), msg);
#endif
this->on_valve_command_request(msg);
break;
@@ -506,7 +499,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
DateTimeCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_date_time_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_date_time_command_request"), msg);
#endif
this->on_date_time_command_request(msg);
break;
@@ -517,7 +510,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
VoiceAssistantTimerEventResponse msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_voice_assistant_timer_event_response: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_voice_assistant_timer_event_response"), msg);
#endif
this->on_voice_assistant_timer_event_response(msg);
break;
@@ -528,7 +521,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
UpdateCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_update_command_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_update_command_request"), msg);
#endif
this->on_update_command_request(msg);
break;
@@ -539,7 +532,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
VoiceAssistantAnnounceRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_voice_assistant_announce_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_voice_assistant_announce_request"), msg);
#endif
this->on_voice_assistant_announce_request(msg);
break;
@@ -550,7 +543,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
VoiceAssistantConfigurationRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_voice_assistant_configuration_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_voice_assistant_configuration_request"), msg);
#endif
this->on_voice_assistant_configuration_request(msg);
break;
@@ -561,7 +554,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
VoiceAssistantSetConfiguration msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_voice_assistant_set_configuration: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_voice_assistant_set_configuration"), msg);
#endif
this->on_voice_assistant_set_configuration(msg);
break;
@@ -572,7 +565,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
NoiseEncryptionSetKeyRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_noise_encryption_set_key_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_noise_encryption_set_key_request"), msg);
#endif
this->on_noise_encryption_set_key_request(msg);
break;
@@ -583,7 +576,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
BluetoothScannerSetModeRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_bluetooth_scanner_set_mode_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_bluetooth_scanner_set_mode_request"), msg);
#endif
this->on_bluetooth_scanner_set_mode_request(msg);
break;
@@ -594,7 +587,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
ZWaveProxyFrame msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_z_wave_proxy_frame: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_z_wave_proxy_frame"), msg);
#endif
this->on_z_wave_proxy_frame(msg);
break;
@@ -605,7 +598,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
ZWaveProxyRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_z_wave_proxy_request: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_z_wave_proxy_request"), msg);
#endif
this->on_z_wave_proxy_request(msg);
break;
@@ -616,11 +609,33 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
HomeassistantActionResponse msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_homeassistant_action_response: %s", msg.dump().c_str());
this->log_receive_message_(LOG_STR("on_homeassistant_action_response"), msg);
#endif
this->on_homeassistant_action_response(msg);
break;
}
#endif
#ifdef USE_WATER_HEATER
case WaterHeaterCommandRequest::MESSAGE_TYPE: {
WaterHeaterCommandRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
this->log_receive_message_(LOG_STR("on_water_heater_command_request"), msg);
#endif
this->on_water_heater_command_request(msg);
break;
}
#endif
#ifdef USE_IR_RF
case InfraredRFTransmitRawTimingsRequest::MESSAGE_TYPE: {
InfraredRFTransmitRawTimingsRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
this->log_receive_message_(LOG_STR("on_infrared_rf_transmit_raw_timings_request"), msg);
#endif
this->on_infrared_rf_transmit_raw_timings_request(msg);
break;
}
#endif
default:
break;
@@ -632,13 +647,6 @@ void APIServerConnection::on_hello_request(const HelloRequest &msg) {
this->on_fatal_error();
}
}
#ifdef USE_API_PASSWORD
void APIServerConnection::on_authentication_request(const AuthenticationRequest &msg) {
if (!this->send_authenticate_response(msg)) {
this->on_fatal_error();
}
}
#endif
void APIServerConnection::on_disconnect_request(const DisconnectRequest &msg) {
if (!this->send_disconnect_response(msg)) {
this->on_fatal_error();
@@ -670,7 +678,7 @@ void APIServerConnection::on_subscribe_home_assistant_states_request(const Subsc
this->subscribe_home_assistant_states(msg);
}
#endif
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
void APIServerConnection::on_execute_service_request(const ExecuteServiceRequest &msg) { this->execute_service(msg); }
#endif
#ifdef USE_API_NOISE
@@ -826,14 +834,16 @@ void APIServerConnection::on_z_wave_proxy_frame(const ZWaveProxyFrame &msg) { th
#ifdef USE_ZWAVE_PROXY
void APIServerConnection::on_z_wave_proxy_request(const ZWaveProxyRequest &msg) { this->zwave_proxy_request(msg); }
#endif
#ifdef USE_IR_RF
void APIServerConnection::on_infrared_rf_transmit_raw_timings_request(const InfraredRFTransmitRawTimingsRequest &msg) {
this->infrared_rf_transmit_raw_timings(msg);
}
#endif
void APIServerConnection::read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) {
void APIServerConnection::read_message(uint32_t msg_size, uint32_t msg_type, const uint8_t *msg_data) {
// Check authentication/connection requirements for messages
switch (msg_type) {
case HelloRequest::MESSAGE_TYPE: // No setup required
#ifdef USE_API_PASSWORD
case AuthenticationRequest::MESSAGE_TYPE: // No setup required
#endif
case HelloRequest::MESSAGE_TYPE: // No setup required
case DisconnectRequest::MESSAGE_TYPE: // No setup required
case PingRequest::MESSAGE_TYPE: // No setup required
break; // Skip all checks for these messages

View File

@@ -12,24 +12,22 @@ class APIServerConnectionBase : public ProtoService {
public:
#ifdef HAS_PROTO_MESSAGE_DUMP
protected:
void log_send_message_(const char *name, const std::string &dump);
void log_send_message_(const char *name, const char *dump);
void log_receive_message_(const LogString *name, const ProtoMessage &msg);
public:
#endif
bool send_message(const ProtoMessage &msg, uint8_t message_type) {
#ifdef HAS_PROTO_MESSAGE_DUMP
this->log_send_message_(msg.message_name(), msg.dump());
DumpBuffer dump_buf;
this->log_send_message_(msg.message_name(), msg.dump_to(dump_buf));
#endif
return this->send_message_(msg, message_type);
}
virtual void on_hello_request(const HelloRequest &value){};
#ifdef USE_API_PASSWORD
virtual void on_authentication_request(const AuthenticationRequest &value){};
#endif
virtual void on_disconnect_request(const DisconnectRequest &value){};
virtual void on_disconnect_response(const DisconnectResponse &value){};
virtual void on_ping_request(const PingRequest &value){};
@@ -79,7 +77,7 @@ class APIServerConnectionBase : public ProtoService {
virtual void on_get_time_response(const GetTimeResponse &value){};
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
virtual void on_execute_service_request(const ExecuteServiceRequest &value){};
#endif
@@ -91,6 +89,10 @@ class APIServerConnectionBase : public ProtoService {
virtual void on_climate_command_request(const ClimateCommandRequest &value){};
#endif
#ifdef USE_WATER_HEATER
virtual void on_water_heater_command_request(const WaterHeaterCommandRequest &value){};
#endif
#ifdef USE_NUMBER
virtual void on_number_command_request(const NumberCommandRequest &value){};
#endif
@@ -217,16 +219,18 @@ class APIServerConnectionBase : public ProtoService {
#ifdef USE_ZWAVE_PROXY
virtual void on_z_wave_proxy_request(const ZWaveProxyRequest &value){};
#endif
#ifdef USE_IR_RF
virtual void on_infrared_rf_transmit_raw_timings_request(const InfraredRFTransmitRawTimingsRequest &value){};
#endif
protected:
void read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) override;
void read_message(uint32_t msg_size, uint32_t msg_type, const uint8_t *msg_data) override;
};
class APIServerConnection : public APIServerConnectionBase {
public:
virtual bool send_hello_response(const HelloRequest &msg) = 0;
#ifdef USE_API_PASSWORD
virtual bool send_authenticate_response(const AuthenticationRequest &msg) = 0;
#endif
virtual bool send_disconnect_response(const DisconnectRequest &msg) = 0;
virtual bool send_ping_response(const PingRequest &msg) = 0;
virtual bool send_device_info_response(const DeviceInfoRequest &msg) = 0;
@@ -239,7 +243,7 @@ class APIServerConnection : public APIServerConnectionBase {
#ifdef USE_API_HOMEASSISTANT_STATES
virtual void subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) = 0;
#endif
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
virtual void execute_service(const ExecuteServiceRequest &msg) = 0;
#endif
#ifdef USE_API_NOISE
@@ -350,12 +354,12 @@ class APIServerConnection : public APIServerConnectionBase {
#endif
#ifdef USE_ZWAVE_PROXY
virtual void zwave_proxy_request(const ZWaveProxyRequest &msg) = 0;
#endif
#ifdef USE_IR_RF
virtual void infrared_rf_transmit_raw_timings(const InfraredRFTransmitRawTimingsRequest &msg) = 0;
#endif
protected:
void on_hello_request(const HelloRequest &msg) override;
#ifdef USE_API_PASSWORD
void on_authentication_request(const AuthenticationRequest &msg) override;
#endif
void on_disconnect_request(const DisconnectRequest &msg) override;
void on_ping_request(const PingRequest &msg) override;
void on_device_info_request(const DeviceInfoRequest &msg) override;
@@ -368,7 +372,7 @@ class APIServerConnection : public APIServerConnectionBase {
#ifdef USE_API_HOMEASSISTANT_STATES
void on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &msg) override;
#endif
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
void on_execute_service_request(const ExecuteServiceRequest &msg) override;
#endif
#ifdef USE_API_NOISE
@@ -480,7 +484,10 @@ class APIServerConnection : public APIServerConnectionBase {
#ifdef USE_ZWAVE_PROXY
void on_z_wave_proxy_request(const ZWaveProxyRequest &msg) override;
#endif
void read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) override;
#ifdef USE_IR_RF
void on_infrared_rf_transmit_raw_timings_request(const InfraredRFTransmitRawTimingsRequest &msg) override;
#endif
void read_message(uint32_t msg_size, uint32_t msg_type, const uint8_t *msg_data) override;
};
} // namespace esphome::api

View File

@@ -4,8 +4,8 @@
#include "api_connection.h"
#include "esphome/components/network/util.h"
#include "esphome/core/application.h"
#include "esphome/core/defines.h"
#include "esphome/core/controller_registry.h"
#include "esphome/core/defines.h"
#include "esphome/core/hal.h"
#include "esphome/core/log.h"
#include "esphome/core/util.h"
@@ -52,11 +52,6 @@ void APIServer::setup() {
#endif
#endif
// Schedule reboot if no clients connect within timeout
if (this->reboot_timeout_ != 0) {
this->schedule_reboot_timeout_();
}
this->socket_ = socket::socket_ip_loop_monitored(SOCK_STREAM, 0); // monitored for incoming connections
if (this->socket_ == nullptr) {
ESP_LOGW(TAG, "Could not create socket");
@@ -101,42 +96,22 @@ void APIServer::setup() {
#ifdef USE_LOGGER
if (logger::global_logger != nullptr) {
logger::global_logger->add_on_log_callback(
[this](int level, const char *tag, const char *message, size_t message_len) {
if (this->shutting_down_) {
// Don't try to send logs during shutdown
// as it could result in a recursion and
// we would be filling a buffer we are trying to clear
return;
}
for (auto &c : this->clients_) {
if (!c->flags_.remove && c->get_log_subscription_level() >= level)
c->try_send_log_message(level, tag, message, message_len);
}
});
logger::global_logger->add_log_listener(this);
}
#endif
#ifdef USE_CAMERA
if (camera::Camera::instance() != nullptr && !camera::Camera::instance()->is_internal()) {
camera::Camera::instance()->add_image_callback([this](const std::shared_ptr<camera::CameraImage> &image) {
for (auto &c : this->clients_) {
if (!c->flags_.remove)
c->set_camera_state(image);
}
});
camera::Camera::instance()->add_listener(this);
}
#endif
}
void APIServer::schedule_reboot_timeout_() {
this->status_set_warning();
this->set_timeout("api_reboot", this->reboot_timeout_, []() {
if (!global_api_server->is_connected()) {
ESP_LOGE(TAG, "No clients; rebooting");
App.reboot();
}
});
// Initialize last_connected_ for reboot timeout tracking
this->last_connected_ = App.get_loop_component_start_time();
// Set warning status if reboot timeout is enabled
if (this->reboot_timeout_ != 0) {
this->status_set_warning();
}
}
void APIServer::loop() {
@@ -150,29 +125,41 @@ void APIServer::loop() {
if (!sock)
break;
char peername[socket::SOCKADDR_STR_LEN];
sock->getpeername_to(peername);
// Check if we're at the connection limit
if (this->clients_.size() >= this->max_connections_) {
ESP_LOGW(TAG, "Max connections (%d), rejecting %s", this->max_connections_, sock->getpeername().c_str());
ESP_LOGW(TAG, "Max connections (%d), rejecting %s", this->max_connections_, peername);
// Immediately close - socket destructor will handle cleanup
sock.reset();
continue;
}
ESP_LOGD(TAG, "Accept %s", sock->getpeername().c_str());
ESP_LOGD(TAG, "Accept %s", peername);
auto *conn = new APIConnection(std::move(sock), this);
this->clients_.emplace_back(conn);
conn->start();
// Clear warning status and cancel reboot when first client connects
// First client connected - clear warning and update timestamp
if (this->clients_.size() == 1 && this->reboot_timeout_ != 0) {
this->status_clear_warning();
this->cancel_timeout("api_reboot");
this->last_connected_ = App.get_loop_component_start_time();
}
}
}
if (this->clients_.empty()) {
// Check reboot timeout - done in loop to avoid scheduler heap churn
// (cancelled scheduler items sit in heap memory until their scheduled time)
if (this->reboot_timeout_ != 0) {
const uint32_t now = App.get_loop_component_start_time();
if (now - this->last_connected_ > this->reboot_timeout_) {
ESP_LOGE(TAG, "No clients; rebooting");
App.reboot();
}
}
return;
}
@@ -182,8 +169,7 @@ void APIServer::loop() {
// Network is down - disconnect all clients
for (auto &client : this->clients_) {
client->on_fatal_error();
ESP_LOGW(TAG, "%s (%s): Network down; disconnect", client->client_info_.name.c_str(),
client->client_info_.peername.c_str());
client->log_client_(ESPHOME_LOG_LEVEL_WARN, LOG_STR("Network down; disconnect"));
}
// Continue to process and clean up the clients below
}
@@ -200,10 +186,16 @@ void APIServer::loop() {
}
// Rare case: handle disconnection
#ifdef USE_API_CLIENT_DISCONNECTED_TRIGGER
this->client_disconnected_trigger_->trigger(client->client_info_.name, client->client_info_.peername);
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
this->unregister_active_action_calls_for_connection(client.get());
#endif
ESP_LOGV(TAG, "Remove connection %s", client->get_name());
#ifdef USE_API_CLIENT_DISCONNECTED_TRIGGER
// Save client info before removal for the trigger
std::string client_name(client->get_name());
std::string client_peername(client->get_peername());
#endif
ESP_LOGV(TAG, "Remove connection %s", client->client_info_.name.c_str());
// Swap with the last element and pop (avoids expensive vector shifts)
if (client_index < this->clients_.size() - 1) {
@@ -211,10 +203,16 @@ void APIServer::loop() {
}
this->clients_.pop_back();
// Schedule reboot when last client disconnects
// Last client disconnected - set warning and start tracking for reboot timeout
if (this->clients_.empty() && this->reboot_timeout_ != 0) {
this->schedule_reboot_timeout_();
this->status_set_warning();
this->last_connected_ = App.get_loop_component_start_time();
}
#ifdef USE_API_CLIENT_DISCONNECTED_TRIGGER
// Fire trigger after client is removed so api.connected reflects the true state
this->client_disconnected_trigger_->trigger(client_name, client_peername);
#endif
// Don't increment client_index since we need to process the swapped element
}
}
@@ -227,8 +225,8 @@ void APIServer::dump_config() {
" Max connections: %u",
network::get_use_address(), this->port_, this->listen_backlog_, this->max_connections_);
#ifdef USE_API_NOISE
ESP_LOGCONFIG(TAG, " Noise encryption: %s", YESNO(this->noise_ctx_->has_psk()));
if (!this->noise_ctx_->has_psk()) {
ESP_LOGCONFIG(TAG, " Noise encryption: %s", YESNO(this->noise_ctx_.has_psk()));
if (!this->noise_ctx_.has_psk()) {
ESP_LOGCONFIG(TAG, " Supports encryption: YES");
}
#else
@@ -236,38 +234,6 @@ void APIServer::dump_config() {
#endif
}
#ifdef USE_API_PASSWORD
bool APIServer::check_password(const uint8_t *password_data, size_t password_len) const {
// depend only on input password length
const char *a = this->password_.c_str();
uint32_t len_a = this->password_.length();
const char *b = reinterpret_cast<const char *>(password_data);
uint32_t len_b = password_len;
// disable optimization with volatile
volatile uint32_t length = len_b;
volatile const char *left = nullptr;
volatile const char *right = b;
uint8_t result = 0;
if (len_a == length) {
left = *((volatile const char **) &a);
result = 0;
}
if (len_a != length) {
left = b;
result = 1;
}
for (size_t i = 0; i < length; i++) {
result |= *left++ ^ *right++; // NOLINT
}
return result == 0;
}
#endif
void APIServer::handle_disconnect(APIConnection *conn) {}
// Macro for controller update dispatch
@@ -347,6 +313,10 @@ API_DISPATCH_UPDATE(valve::Valve, valve)
API_DISPATCH_UPDATE(media_player::MediaPlayer, media_player)
#endif
#ifdef USE_WATER_HEATER
API_DISPATCH_UPDATE(water_heater::WaterHeater, water_heater)
#endif
#ifdef USE_EVENT
// Event is a special case - unlike other entities with simple state fields,
// events store their state in a member accessed via obj->get_last_event_type()
@@ -377,6 +347,21 @@ void APIServer::on_zwave_proxy_request(const esphome::api::ProtoMessage &msg) {
}
#endif
#ifdef USE_IR_RF
void APIServer::send_infrared_rf_receive_event([[maybe_unused]] uint32_t device_id, uint32_t key,
const std::vector<int32_t> *timings) {
InfraredRFReceiveEvent resp{};
#ifdef USE_DEVICES
resp.device_id = device_id;
#endif
resp.key = key;
resp.timings = timings;
for (auto &c : this->clients_)
c->send_infrared_rf_receive_event(resp);
}
#endif
#ifdef USE_ALARM_CONTROL_PANEL
API_DISPATCH_UPDATE(alarm_control_panel::AlarmControlPanel, alarm_control_panel)
#endif
@@ -385,10 +370,6 @@ float APIServer::get_setup_priority() const { return setup_priority::AFTER_WIFI;
void APIServer::set_port(uint16_t port) { this->port_ = port; }
#ifdef USE_API_PASSWORD
void APIServer::set_password(const std::string &password) { this->password_ = password; }
#endif
void APIServer::set_batch_delay(uint16_t batch_delay) { this->batch_delay_ = batch_delay; }
#ifdef USE_API_HOMEASSISTANT_SERVICES
@@ -402,7 +383,7 @@ void APIServer::register_action_response_callback(uint32_t call_id, ActionRespon
this->action_response_callbacks_.push_back({call_id, std::move(callback)});
}
void APIServer::handle_action_response(uint32_t call_id, bool success, const std::string &error_message) {
void APIServer::handle_action_response(uint32_t call_id, bool success, StringRef error_message) {
for (auto it = this->action_response_callbacks_.begin(); it != this->action_response_callbacks_.end(); ++it) {
if (it->call_id == call_id) {
auto callback = std::move(it->callback);
@@ -414,7 +395,7 @@ void APIServer::handle_action_response(uint32_t call_id, bool success, const std
}
}
#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
void APIServer::handle_action_response(uint32_t call_id, bool success, const std::string &error_message,
void APIServer::handle_action_response(uint32_t call_id, bool success, StringRef error_message,
const uint8_t *response_data, size_t response_data_len) {
for (auto it = this->action_response_callbacks_.begin(); it != this->action_response_callbacks_.end(); ++it) {
if (it->call_id == call_id) {
@@ -431,25 +412,76 @@ void APIServer::handle_action_response(uint32_t call_id, bool success, const std
#endif // USE_API_HOMEASSISTANT_SERVICES
#ifdef USE_API_HOMEASSISTANT_STATES
void APIServer::subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
std::function<void(std::string)> f) {
// Helper to add subscription (reduces duplication)
void APIServer::add_state_subscription_(const char *entity_id, const char *attribute, std::function<void(StringRef)> f,
bool once) {
this->state_subs_.push_back(HomeAssistantStateSubscription{
.entity_id = std::move(entity_id),
.attribute = std::move(attribute),
.callback = std::move(f),
.once = false,
.entity_id = entity_id, .attribute = attribute, .callback = std::move(f), .once = once,
// entity_id_dynamic_storage and attribute_dynamic_storage remain nullptr (no heap allocation)
});
}
// Helper to add subscription with heap-allocated strings (reduces duplication)
void APIServer::add_state_subscription_(std::string entity_id, optional<std::string> attribute,
std::function<void(StringRef)> f, bool once) {
HomeAssistantStateSubscription sub;
// Allocate heap storage for the strings
sub.entity_id_dynamic_storage = std::make_unique<std::string>(std::move(entity_id));
sub.entity_id = sub.entity_id_dynamic_storage->c_str();
if (attribute.has_value()) {
sub.attribute_dynamic_storage = std::make_unique<std::string>(std::move(attribute.value()));
sub.attribute = sub.attribute_dynamic_storage->c_str();
} else {
sub.attribute = nullptr;
}
sub.callback = std::move(f);
sub.once = once;
this->state_subs_.push_back(std::move(sub));
}
// New const char* overload (for internal components - zero allocation)
void APIServer::subscribe_home_assistant_state(const char *entity_id, const char *attribute,
std::function<void(StringRef)> f) {
this->add_state_subscription_(entity_id, attribute, std::move(f), false);
}
void APIServer::get_home_assistant_state(const char *entity_id, const char *attribute,
std::function<void(StringRef)> f) {
this->add_state_subscription_(entity_id, attribute, std::move(f), true);
}
// std::string overload with StringRef callback (zero-allocation callback)
void APIServer::subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
std::function<void(StringRef)> f) {
this->add_state_subscription_(std::move(entity_id), std::move(attribute), std::move(f), false);
}
void APIServer::get_home_assistant_state(std::string entity_id, optional<std::string> attribute,
std::function<void(std::string)> f) {
this->state_subs_.push_back(HomeAssistantStateSubscription{
.entity_id = std::move(entity_id),
.attribute = std::move(attribute),
.callback = std::move(f),
.once = true,
});
};
std::function<void(StringRef)> f) {
this->add_state_subscription_(std::move(entity_id), std::move(attribute), std::move(f), true);
}
// Legacy helper: wraps std::string callback and delegates to StringRef version
void APIServer::add_state_subscription_(std::string entity_id, optional<std::string> attribute,
std::function<void(const std::string &)> f, bool once) {
// Wrap callback to convert StringRef -> std::string, then delegate
this->add_state_subscription_(std::move(entity_id), std::move(attribute),
std::function<void(StringRef)>([f = std::move(f)](StringRef state) { f(state.str()); }),
once);
}
// Legacy std::string overload (for custom_api_device.h - converts StringRef to std::string)
void APIServer::subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
std::function<void(const std::string &)> f) {
this->add_state_subscription_(std::move(entity_id), std::move(attribute), std::move(f), false);
}
void APIServer::get_home_assistant_state(std::string entity_id, optional<std::string> attribute,
std::function<void(const std::string &)> f) {
this->add_state_subscription_(std::move(entity_id), std::move(attribute), std::move(f), true);
}
const std::vector<APIServer::HomeAssistantStateSubscription> &APIServer::get_state_subs() const {
return this->state_subs_;
@@ -493,7 +525,7 @@ bool APIServer::save_noise_psk(psk_t psk, bool make_active) {
ESP_LOGW(TAG, "Key set in YAML");
return false;
#else
auto &old_psk = this->noise_ctx_->get_psk();
auto &old_psk = this->noise_ctx_.get_psk();
if (std::equal(old_psk.begin(), old_psk.end(), psk.begin())) {
ESP_LOGW(TAG, "New PSK matches old");
return true;
@@ -528,7 +560,42 @@ void APIServer::request_time() {
}
#endif
bool APIServer::is_connected() const { return !this->clients_.empty(); }
bool APIServer::is_connected(bool state_subscription_only) const {
if (!state_subscription_only) {
return !this->clients_.empty();
}
for (const auto &client : this->clients_) {
if (client->flags_.state_subscription) {
return true;
}
}
return false;
}
#ifdef USE_LOGGER
void APIServer::on_log(uint8_t level, const char *tag, const char *message, size_t message_len) {
if (this->shutting_down_) {
// Don't try to send logs during shutdown
// as it could result in a recursion and
// we would be filling a buffer we are trying to clear
return;
}
for (auto &c : this->clients_) {
if (!c->flags_.remove && c->get_log_subscription_level() >= level)
c->try_send_log_message(level, tag, message, message_len);
}
}
#endif
#ifdef USE_CAMERA
void APIServer::on_camera_image(const std::shared_ptr<camera::CameraImage> &image) {
for (auto &c : this->clients_) {
if (!c->flags_.remove)
c->set_camera_state(image);
}
}
#endif
void APIServer::on_shutdown() {
this->shutting_down_ = true;
@@ -565,5 +632,84 @@ bool APIServer::teardown() {
return this->clients_.empty();
}
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
// Timeout for action calls - matches aioesphomeapi client timeout (default 30s)
// Can be overridden via USE_API_ACTION_CALL_TIMEOUT_MS define for testing
#ifndef USE_API_ACTION_CALL_TIMEOUT_MS
#define USE_API_ACTION_CALL_TIMEOUT_MS 30000 // NOLINT
#endif
uint32_t APIServer::register_active_action_call(uint32_t client_call_id, APIConnection *conn) {
uint32_t action_call_id = this->next_action_call_id_++;
// Handle wraparound (skip 0 as it means "no call")
if (this->next_action_call_id_ == 0) {
this->next_action_call_id_ = 1;
}
this->active_action_calls_.push_back({action_call_id, client_call_id, conn});
// Schedule automatic cleanup after timeout (client will have given up by then)
this->set_timeout(str_sprintf("action_call_%u", action_call_id), USE_API_ACTION_CALL_TIMEOUT_MS,
[this, action_call_id]() {
ESP_LOGD(TAG, "Action call %u timed out", action_call_id);
this->unregister_active_action_call(action_call_id);
});
return action_call_id;
}
void APIServer::unregister_active_action_call(uint32_t action_call_id) {
// Cancel the timeout for this action call
this->cancel_timeout(str_sprintf("action_call_%u", action_call_id));
// Swap-and-pop is more efficient than remove_if for unordered vectors
for (size_t i = 0; i < this->active_action_calls_.size(); i++) {
if (this->active_action_calls_[i].action_call_id == action_call_id) {
std::swap(this->active_action_calls_[i], this->active_action_calls_.back());
this->active_action_calls_.pop_back();
return;
}
}
}
void APIServer::unregister_active_action_calls_for_connection(APIConnection *conn) {
// Remove all active action calls for disconnected connection using swap-and-pop
for (size_t i = 0; i < this->active_action_calls_.size();) {
if (this->active_action_calls_[i].connection == conn) {
// Cancel the timeout for this action call
this->cancel_timeout(str_sprintf("action_call_%u", this->active_action_calls_[i].action_call_id));
std::swap(this->active_action_calls_[i], this->active_action_calls_.back());
this->active_action_calls_.pop_back();
// Don't increment i - need to check the swapped element
} else {
i++;
}
}
}
void APIServer::send_action_response(uint32_t action_call_id, bool success, StringRef error_message) {
for (auto &call : this->active_action_calls_) {
if (call.action_call_id == action_call_id) {
call.connection->send_execute_service_response(call.client_call_id, success, error_message);
return;
}
}
ESP_LOGW(TAG, "Cannot send response: no active call found for action_call_id %u", action_call_id);
}
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
void APIServer::send_action_response(uint32_t action_call_id, bool success, StringRef error_message,
const uint8_t *response_data, size_t response_data_len) {
for (auto &call : this->active_action_calls_) {
if (call.action_call_id == action_call_id) {
call.connection->send_execute_service_response(call.client_call_id, success, error_message, response_data,
response_data_len);
return;
}
}
ESP_LOGW(TAG, "Cannot send response: no active call found for action_call_id %u", action_call_id);
}
#endif // USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
#endif // USE_API_USER_DEFINED_ACTION_RESPONSES
} // namespace esphome::api
#endif

View File

@@ -10,24 +10,42 @@
#include "esphome/core/component.h"
#include "esphome/core/controller.h"
#include "esphome/core/log.h"
#include "esphome/core/string_ref.h"
#include "list_entities.h"
#include "subscribe_state.h"
#ifdef USE_API_SERVICES
#include "user_services.h"
#ifdef USE_LOGGER
#include "esphome/components/logger/logger.h"
#endif
#ifdef USE_CAMERA
#include "esphome/components/camera/camera.h"
#endif
#include <map>
#include <vector>
namespace esphome::api {
#ifdef USE_API_USER_DEFINED_ACTIONS
// Forward declaration - full definition in user_services.h
class UserServiceDescriptor;
#endif
#ifdef USE_API_NOISE
struct SavedNoisePsk {
psk_t psk;
} PACKED; // NOLINT
#endif
class APIServer : public Component, public Controller {
class APIServer : public Component,
public Controller
#ifdef USE_LOGGER
,
public logger::LogListener
#endif
#ifdef USE_CAMERA
,
public camera::CameraListener
#endif
{
public:
APIServer();
void setup() override;
@@ -37,9 +55,11 @@ class APIServer : public Component, public Controller {
void dump_config() override;
void on_shutdown() override;
bool teardown() override;
#ifdef USE_API_PASSWORD
bool check_password(const uint8_t *password_data, size_t password_len) const;
void set_password(const std::string &password);
#ifdef USE_LOGGER
void on_log(uint8_t level, const char *tag, const char *message, size_t message_len) override;
#endif
#ifdef USE_CAMERA
void on_camera_image(const std::shared_ptr<camera::CameraImage> &image) override;
#endif
void set_port(uint16_t port);
void set_reboot_timeout(uint32_t reboot_timeout);
@@ -54,8 +74,8 @@ class APIServer : public Component, public Controller {
#ifdef USE_API_NOISE
bool save_noise_psk(psk_t psk, bool make_active = true);
bool clear_noise_psk(bool make_active = true);
void set_noise_psk(psk_t psk) { noise_ctx_->set_psk(psk); }
std::shared_ptr<APINoiseContext> get_noise_ctx() { return noise_ctx_; }
void set_noise_psk(psk_t psk) { this->noise_ctx_.set_psk(psk); }
APINoiseContext &get_noise_ctx() { return this->noise_ctx_; }
#endif // USE_API_NOISE
void handle_disconnect(APIConnection *conn);
@@ -110,6 +130,9 @@ class APIServer : public Component, public Controller {
#ifdef USE_MEDIA_PLAYER
void on_media_player_update(media_player::MediaPlayer *obj) override;
#endif
#ifdef USE_WATER_HEATER
void on_water_heater_update(water_heater::WaterHeater *obj) override;
#endif
#ifdef USE_API_HOMEASSISTANT_SERVICES
void send_homeassistant_action(const HomeassistantActionRequest &call);
@@ -117,14 +140,14 @@ class APIServer : public Component, public Controller {
// Action response handling
using ActionResponseCallback = std::function<void(const class ActionResponse &)>;
void register_action_response_callback(uint32_t call_id, ActionResponseCallback callback);
void handle_action_response(uint32_t call_id, bool success, const std::string &error_message);
void handle_action_response(uint32_t call_id, bool success, StringRef error_message);
#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
void handle_action_response(uint32_t call_id, bool success, const std::string &error_message,
const uint8_t *response_data, size_t response_data_len);
void handle_action_response(uint32_t call_id, bool success, StringRef error_message, const uint8_t *response_data,
size_t response_data_len);
#endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
#endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES
#endif // USE_API_HOMEASSISTANT_SERVICES
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
void initialize_user_services(std::initializer_list<UserServiceDescriptor *> services) {
this->user_services_.assign(services);
}
@@ -132,6 +155,19 @@ class APIServer : public Component, public Controller {
// Only compile push_back method when custom_services: true (external components)
void register_user_service(UserServiceDescriptor *descriptor) { this->user_services_.push_back(descriptor); }
#endif
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
// Action call context management - supports concurrent calls from multiple clients
// Returns server-generated action_call_id to avoid collisions when clients use same call_id
uint32_t register_active_action_call(uint32_t client_call_id, APIConnection *conn);
void unregister_active_action_call(uint32_t action_call_id);
void unregister_active_action_calls_for_connection(APIConnection *conn);
// Send response for a specific action call (uses action_call_id, sends client_call_id in response)
void send_action_response(uint32_t action_call_id, bool success, StringRef error_message);
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
void send_action_response(uint32_t action_call_id, bool success, StringRef error_message,
const uint8_t *response_data, size_t response_data_len);
#endif // USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
#endif // USE_API_USER_DEFINED_ACTION_RESPONSES
#endif
#ifdef USE_HOMEASSISTANT_TIME
void request_time();
@@ -149,24 +185,44 @@ class APIServer : public Component, public Controller {
#ifdef USE_ZWAVE_PROXY
void on_zwave_proxy_request(const esphome::api::ProtoMessage &msg);
#endif
#ifdef USE_IR_RF
void send_infrared_rf_receive_event(uint32_t device_id, uint32_t key, const std::vector<int32_t> *timings);
#endif
bool is_connected() const;
bool is_connected(bool state_subscription_only = false) const;
#ifdef USE_API_HOMEASSISTANT_STATES
struct HomeAssistantStateSubscription {
std::string entity_id;
optional<std::string> attribute;
std::function<void(std::string)> callback;
const char *entity_id; // Pointer to flash (internal) or heap (external)
const char *attribute; // Pointer to flash or nullptr (nullptr means no attribute)
std::function<void(StringRef)> callback;
bool once;
// Dynamic storage for external components using std::string API (custom_api_device.h)
// These are only allocated when using the std::string overload (nullptr for const char* overload)
std::unique_ptr<std::string> entity_id_dynamic_storage;
std::unique_ptr<std::string> attribute_dynamic_storage;
};
// New const char* overload (for internal components - zero allocation)
void subscribe_home_assistant_state(const char *entity_id, const char *attribute, std::function<void(StringRef)> f);
void get_home_assistant_state(const char *entity_id, const char *attribute, std::function<void(StringRef)> f);
// std::string overload with StringRef callback (for custom_api_device.h with zero-allocation callback)
void subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
std::function<void(std::string)> f);
std::function<void(StringRef)> f);
void get_home_assistant_state(std::string entity_id, optional<std::string> attribute,
std::function<void(std::string)> f);
std::function<void(StringRef)> f);
// Legacy std::string overload (for custom_api_device.h - converts StringRef to std::string for callback)
void subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
std::function<void(const std::string &)> f);
void get_home_assistant_state(std::string entity_id, optional<std::string> attribute,
std::function<void(const std::string &)> f);
const std::vector<HomeAssistantStateSubscription> &get_state_subs() const;
#endif
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
const std::vector<UserServiceDescriptor *> &get_user_services() const { return this->user_services_; }
#endif
@@ -180,11 +236,20 @@ class APIServer : public Component, public Controller {
#endif
protected:
void schedule_reboot_timeout_();
#ifdef USE_API_NOISE
bool update_noise_psk_(const SavedNoisePsk &new_psk, const LogString *save_log_msg, const LogString *fail_log_msg,
const psk_t &active_psk, bool make_active);
#endif // USE_API_NOISE
#ifdef USE_API_HOMEASSISTANT_STATES
// Helper methods to reduce code duplication
void add_state_subscription_(const char *entity_id, const char *attribute, std::function<void(StringRef)> f,
bool once);
void add_state_subscription_(std::string entity_id, optional<std::string> attribute, std::function<void(StringRef)> f,
bool once);
// Legacy helper: wraps std::string callback and delegates to StringRef version
void add_state_subscription_(std::string entity_id, optional<std::string> attribute,
std::function<void(const std::string &)> f, bool once);
#endif // USE_API_HOMEASSISTANT_STATES
// Pointers and pointer-like types first (4 bytes each)
std::unique_ptr<socket::Socket> socket_ = nullptr;
#ifdef USE_API_CLIENT_CONNECTED_TRIGGER
@@ -196,18 +261,27 @@ class APIServer : public Component, public Controller {
// 4-byte aligned types
uint32_t reboot_timeout_{300000};
uint32_t last_connected_{0};
// Vectors and strings (12 bytes each on 32-bit)
std::vector<std::unique_ptr<APIConnection>> clients_;
#ifdef USE_API_PASSWORD
std::string password_;
#endif
std::vector<uint8_t> shared_write_buffer_; // Shared proto write buffer for all connections
#ifdef USE_API_HOMEASSISTANT_STATES
std::vector<HomeAssistantStateSubscription> state_subs_;
#endif
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
std::vector<UserServiceDescriptor *> user_services_;
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
// Active action calls - supports concurrent calls from multiple clients
// Uses server-generated action_call_id to avoid collisions when multiple clients use same call_id
struct ActiveActionCall {
uint32_t action_call_id; // Server-generated unique ID (passed to actions)
uint32_t client_call_id; // Client's original call_id (used in response)
APIConnection *connection;
};
std::vector<ActiveActionCall> active_action_calls_;
uint32_t next_action_call_id_{1}; // Counter for generating unique action_call_ids
#endif // USE_API_USER_DEFINED_ACTION_RESPONSES
#endif
#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
struct PendingActionResponse {
@@ -228,7 +302,7 @@ class APIServer : public Component, public Controller {
// 7 bytes used, 1 byte padding
#ifdef USE_API_NOISE
std::shared_ptr<APINoiseContext> noise_ctx_ = std::make_shared<APINoiseContext>();
APINoiseContext noise_ctx_;
ESPPreferenceObject noise_pref_;
#endif // USE_API_NOISE
};
@@ -236,8 +310,11 @@ class APIServer : public Component, public Controller {
extern APIServer *global_api_server; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
template<typename... Ts> class APIConnectedCondition : public Condition<Ts...> {
TEMPLATABLE_VALUE(bool, state_subscription_only)
public:
bool check(const Ts &...x) override { return global_api_server->is_connected(); }
bool check(const Ts &...x) override {
return global_api_server->is_connected(this->state_subscription_only_.value(x...));
}
};
} // namespace esphome::api

View File

@@ -16,7 +16,7 @@ with warnings.catch_warnings():
import contextlib
from esphome.const import CONF_KEY, CONF_PASSWORD, CONF_PORT, __version__
from esphome.const import CONF_KEY, CONF_PORT, __version__
from esphome.core import CORE
from . import CONF_ENCRYPTION
@@ -35,7 +35,6 @@ async def async_run_logs(config: dict[str, Any], addresses: list[str]) -> None:
conf = config["api"]
name = config["esphome"]["name"]
port: int = int(conf[CONF_PORT])
password: str = conf[CONF_PASSWORD]
noise_psk: str | None = None
if (encryption := conf.get(CONF_ENCRYPTION)) and (key := encryption.get(CONF_KEY)):
noise_psk = key
@@ -50,7 +49,7 @@ async def async_run_logs(config: dict[str, Any], addresses: list[str]) -> None:
cli = APIClient(
addresses[0], # Primary address for compatibility
port,
password,
"", # Password auth removed in 2026.1.0
client_info=f"ESPHome Logs {__version__}",
noise_psk=noise_psk,
addresses=addresses, # Pass all addresses for automatic retry

View File

@@ -3,12 +3,12 @@
#include <map>
#include "api_server.h"
#ifdef USE_API
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
#include "user_services.h"
#endif
namespace esphome::api {
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
template<typename T, typename... Ts> class CustomAPIDeviceService : public UserServiceDynamic<Ts...> {
public:
CustomAPIDeviceService(const std::string &name, const std::array<std::string, sizeof...(Ts)> &arg_names, T *obj,
@@ -16,12 +16,15 @@ template<typename T, typename... Ts> class CustomAPIDeviceService : public UserS
: UserServiceDynamic<Ts...>(name, arg_names), obj_(obj), callback_(callback) {}
protected:
void execute(Ts... x) override { (this->obj_->*this->callback_)(x...); } // NOLINT
// CustomAPIDevice services don't support action responses - ignore call_id and return_response
void execute(uint32_t /*call_id*/, bool /*return_response*/, Ts... x) override {
(this->obj_->*this->callback_)(x...); // NOLINT
}
T *obj_;
void (T::*callback_)(Ts...);
};
#endif // USE_API_SERVICES
#endif // USE_API_USER_DEFINED_ACTIONS
class CustomAPIDevice {
public:
@@ -49,7 +52,7 @@ class CustomAPIDevice {
* @param name The name of the service to register.
* @param arg_names The name of the arguments for the service, must match the arguments of the function.
*/
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
template<typename T, typename... Ts>
void register_service(void (T::*callback)(Ts...), const std::string &name,
const std::array<std::string, sizeof...(Ts)> &arg_names) {
@@ -90,7 +93,7 @@ class CustomAPIDevice {
* @param callback The member function to call when the service is triggered.
* @param name The name of the arguments for the service, must match the arguments of the function.
*/
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
template<typename T> void register_service(void (T::*callback)(), const std::string &name) {
#ifdef USE_API_CUSTOM_SERVICES
auto *service = new CustomAPIDeviceService<T>(name, {}, (T *) this, callback); // NOLINT
@@ -119,21 +122,36 @@ class CustomAPIDevice {
* subscribe_homeassistant_state(&CustomNativeAPI::on_state_changed, "climate.kitchen", "current_temperature");
* }
*
* void on_state_changed(std::string state) {
* // State of sensor.weather_forecast is `state`
* void on_state_changed(StringRef state) {
* // State of climate.kitchen current_temperature is `state`
* // Use state.c_str() for C string, state.str() for std::string
* }
* ```
*
* @tparam T The class type creating the service, automatically deduced from the function pointer.
* @param callback The member function to call when the entity state changes.
* @param callback The member function to call when the entity state changes (zero-allocation).
* @param entity_id The entity_id to track.
* @param attribute The entity state attribute to track.
*/
template<typename T>
void subscribe_homeassistant_state(void (T::*callback)(StringRef), const std::string &entity_id,
const std::string &attribute = "") {
auto f = std::bind(callback, (T *) this, std::placeholders::_1);
global_api_server->subscribe_home_assistant_state(entity_id, optional<std::string>(attribute), std::move(f));
}
/** Subscribe to the state (or attribute state) of an entity from Home Assistant (legacy std::string version).
*
* @deprecated Use the StringRef overload for zero-allocation callbacks. Will be removed in 2027.1.0.
*/
template<typename T>
ESPDEPRECATED("Use void callback(StringRef) instead. Will be removed in 2027.1.0.", "2026.1.0")
void subscribe_homeassistant_state(void (T::*callback)(std::string), const std::string &entity_id,
const std::string &attribute = "") {
auto f = std::bind(callback, (T *) this, std::placeholders::_1);
global_api_server->subscribe_home_assistant_state(entity_id, optional<std::string>(attribute), f);
// Explicit type to disambiguate overload resolution
global_api_server->subscribe_home_assistant_state(entity_id, optional<std::string>(attribute),
std::function<void(const std::string &)>(f));
}
/** Subscribe to the state (or attribute state) of an entity from Home Assistant.
@@ -145,23 +163,45 @@ class CustomAPIDevice {
* subscribe_homeassistant_state(&CustomNativeAPI::on_state_changed, "sensor.weather_forecast");
* }
*
* void on_state_changed(std::string entity_id, std::string state) {
* void on_state_changed(const std::string &entity_id, StringRef state) {
* // State of `entity_id` is `state`
* }
* ```
*
* @tparam T The class type creating the service, automatically deduced from the function pointer.
* @param callback The member function to call when the entity state changes.
* @param callback The member function to call when the entity state changes (zero-allocation for state).
* @param entity_id The entity_id to track.
* @param attribute The entity state attribute to track.
*/
template<typename T>
void subscribe_homeassistant_state(void (T::*callback)(const std::string &, StringRef), const std::string &entity_id,
const std::string &attribute = "") {
auto f = std::bind(callback, (T *) this, entity_id, std::placeholders::_1);
global_api_server->subscribe_home_assistant_state(entity_id, optional<std::string>(attribute), std::move(f));
}
/** Subscribe to the state (or attribute state) of an entity from Home Assistant (legacy std::string version).
*
* @deprecated Use the StringRef overload for zero-allocation callbacks. Will be removed in 2027.1.0.
*/
template<typename T>
ESPDEPRECATED("Use void callback(const std::string &, StringRef) instead. Will be removed in 2027.1.0.", "2026.1.0")
void subscribe_homeassistant_state(void (T::*callback)(std::string, std::string), const std::string &entity_id,
const std::string &attribute = "") {
auto f = std::bind(callback, (T *) this, entity_id, std::placeholders::_1);
global_api_server->subscribe_home_assistant_state(entity_id, optional<std::string>(attribute), f);
// Explicit type to disambiguate overload resolution
global_api_server->subscribe_home_assistant_state(entity_id, optional<std::string>(attribute),
std::function<void(const std::string &)>(f));
}
#else
template<typename T>
void subscribe_homeassistant_state(void (T::*callback)(StringRef), const std::string &entity_id,
const std::string &attribute = "") {
static_assert(sizeof(T) == 0,
"subscribe_homeassistant_state() requires 'homeassistant_states: true' in the 'api:' section "
"of your YAML configuration");
}
template<typename T>
void subscribe_homeassistant_state(void (T::*callback)(std::string), const std::string &entity_id,
const std::string &attribute = "") {
@@ -170,6 +210,14 @@ class CustomAPIDevice {
"of your YAML configuration");
}
template<typename T>
void subscribe_homeassistant_state(void (T::*callback)(const std::string &, StringRef), const std::string &entity_id,
const std::string &attribute = "") {
static_assert(sizeof(T) == 0,
"subscribe_homeassistant_state() requires 'homeassistant_states: true' in the 'api:' section "
"of your YAML configuration");
}
template<typename T>
void subscribe_homeassistant_state(void (T::*callback)(std::string, std::string), const std::string &entity_id,
const std::string &attribute = "") {
@@ -192,7 +240,7 @@ class CustomAPIDevice {
*/
void call_homeassistant_service(const std::string &service_name) {
HomeassistantActionRequest resp;
resp.set_service(StringRef(service_name));
resp.service = StringRef(service_name);
global_api_server->send_homeassistant_action(resp);
}
@@ -212,12 +260,12 @@ class CustomAPIDevice {
*/
void call_homeassistant_service(const std::string &service_name, const std::map<std::string, std::string> &data) {
HomeassistantActionRequest resp;
resp.set_service(StringRef(service_name));
resp.service = StringRef(service_name);
resp.data.init(data.size());
for (auto &it : data) {
auto &kv = resp.data.emplace_back();
kv.set_key(StringRef(it.first));
kv.value = it.second;
kv.key = StringRef(it.first);
kv.value = StringRef(it.second); // data map lives until send completes
}
global_api_server->send_homeassistant_action(resp);
}
@@ -234,7 +282,7 @@ class CustomAPIDevice {
*/
void fire_homeassistant_event(const std::string &event_name) {
HomeassistantActionRequest resp;
resp.set_service(StringRef(event_name));
resp.service = StringRef(event_name);
resp.is_event = true;
global_api_server->send_homeassistant_action(resp);
}
@@ -254,13 +302,13 @@ class CustomAPIDevice {
*/
void fire_homeassistant_event(const std::string &service_name, const std::map<std::string, std::string> &data) {
HomeassistantActionRequest resp;
resp.set_service(StringRef(service_name));
resp.service = StringRef(service_name);
resp.is_event = true;
resp.data.init(data.size());
for (auto &it : data) {
auto &kv = resp.data.emplace_back();
kv.set_key(StringRef(it.first));
kv.value = it.second;
kv.key = StringRef(it.first);
kv.value = StringRef(it.second); // data map lives until send completes
}
global_api_server->send_homeassistant_action(resp);
}

View File

@@ -12,10 +12,17 @@
#endif
#include "esphome/core/automation.h"
#include "esphome/core/helpers.h"
#include "esphome/core/string_ref.h"
namespace esphome::api {
template<typename... X> class TemplatableStringValue : public TemplatableValue<std::string, X...> {
// Verify that const char* uses the base class STATIC_STRING optimization (no heap allocation)
// rather than being wrapped in a lambda. The base class constructor for const char* is more
// specialized than the templated constructor here, so it should be selected.
static_assert(std::is_constructible_v<TemplatableValue<std::string, X...>, const char *>,
"Base class must have const char* constructor for STATIC_STRING optimization");
private:
// Helper to convert value to string - handles the case where value is already a string
template<typename T> static std::string value_to_string(T &&val) { return to_string(std::forward<T>(val)); }
@@ -46,23 +53,25 @@ template<typename... Ts> class TemplatableKeyValuePair {
// Keys are always string literals from YAML dictionary keys (e.g., "code", "event")
// and never templatable values or lambdas. Only the value parameter can be a lambda/template.
// Using pass-by-value with std::move allows optimal performance for both lvalues and rvalues.
template<typename T> TemplatableKeyValuePair(std::string key, T value) : key(std::move(key)), value(value) {}
// Using const char* avoids std::string heap allocation - keys remain in flash.
template<typename T> TemplatableKeyValuePair(const char *key, T value) : key(key), value(value) {}
std::string key;
const char *key{nullptr};
TemplatableStringValue<Ts...> value;
};
#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
// Represents the response data from a Home Assistant action
// Note: This class holds a StringRef to the error_message from the protobuf message.
// The protobuf message must outlive the ActionResponse (which is guaranteed since
// the callback is invoked synchronously while the message is on the stack).
class ActionResponse {
public:
ActionResponse(bool success, std::string error_message = "")
: success_(success), error_message_(std::move(error_message)) {}
ActionResponse(bool success, StringRef error_message) : success_(success), error_message_(error_message) {}
#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
ActionResponse(bool success, std::string error_message, const uint8_t *data, size_t data_len)
: success_(success), error_message_(std::move(error_message)) {
ActionResponse(bool success, StringRef error_message, const uint8_t *data, size_t data_len)
: success_(success), error_message_(error_message) {
if (data == nullptr || data_len == 0)
return;
this->json_document_ = json::parse_json(data, data_len);
@@ -70,7 +79,8 @@ class ActionResponse {
#endif
bool is_success() const { return this->success_; }
const std::string &get_error_message() const { return this->error_message_; }
// Returns reference to error message - can be implicitly converted to std::string if needed
const StringRef &get_error_message() const { return this->error_message_; }
#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
// Get data as parsed JSON object (const version returns read-only view)
@@ -79,7 +89,7 @@ class ActionResponse {
protected:
bool success_;
std::string error_message_;
StringRef error_message_;
#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
JsonDocument json_document_;
#endif
@@ -105,14 +115,15 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
// Keys are always string literals from the Python code generation (e.g., cg.add(var.add_data("tag_id", templ))).
// The value parameter can be a lambda/template, but keys are never templatable.
template<typename K, typename V> void add_data(K &&key, V &&value) {
this->add_kv_(this->data_, std::forward<K>(key), std::forward<V>(value));
// Using const char* for keys avoids std::string heap allocation - keys remain in flash.
template<typename V> void add_data(const char *key, V &&value) {
this->add_kv_(this->data_, key, std::forward<V>(value));
}
template<typename K, typename V> void add_data_template(K &&key, V &&value) {
this->add_kv_(this->data_template_, std::forward<K>(key), std::forward<V>(value));
template<typename V> void add_data_template(const char *key, V &&value) {
this->add_kv_(this->data_template_, key, std::forward<V>(value));
}
template<typename K, typename V> void add_variable(K &&key, V &&value) {
this->add_kv_(this->variables_, std::forward<K>(key), std::forward<V>(value));
template<typename V> void add_variable(const char *key, V &&value) {
this->add_kv_(this->variables_, key, std::forward<V>(value));
}
#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
@@ -136,13 +147,23 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
void play(const Ts &...x) override {
HomeassistantActionRequest resp;
std::string service_value = this->service_.value(x...);
resp.set_service(StringRef(service_value));
resp.service = StringRef(service_value);
resp.is_event = this->flags_.is_event;
this->populate_service_map(resp.data, this->data_, x...);
this->populate_service_map(resp.data_template, this->data_template_, x...);
this->populate_service_map(resp.variables, this->variables_, x...);
// Local storage for lambda-evaluated strings - lives until after send
FixedVector<std::string> data_storage;
FixedVector<std::string> data_template_storage;
FixedVector<std::string> variables_storage;
this->populate_service_map(resp.data, this->data_, data_storage, x...);
this->populate_service_map(resp.data_template, this->data_template_, data_template_storage, x...);
this->populate_service_map(resp.variables, this->variables_, variables_storage, x...);
#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
// IMPORTANT: Declare at outer scope so it lives until send_homeassistant_action returns.
std::string response_template_value;
#endif
if (this->flags_.wants_status) {
// Generate a unique call ID for this service call
static uint32_t call_id_counter = 1;
@@ -153,8 +174,8 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
resp.wants_response = true;
// Set response template if provided
if (this->flags_.has_response_template) {
std::string response_template_value = this->response_template_.value(x...);
resp.response_template = response_template_value;
response_template_value = this->response_template_.value(x...);
resp.response_template = StringRef(response_template_value);
}
}
#endif
@@ -185,20 +206,40 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
}
protected:
// Helper to add key-value pairs to FixedVectors with perfect forwarding to avoid copies
template<typename K, typename V> void add_kv_(FixedVector<TemplatableKeyValuePair<Ts...>> &vec, K &&key, V &&value) {
// Helper to add key-value pairs to FixedVectors
// Keys are always string literals (const char*), values can be lambdas/templates
template<typename V> void add_kv_(FixedVector<TemplatableKeyValuePair<Ts...>> &vec, const char *key, V &&value) {
auto &kv = vec.emplace_back();
kv.key = std::forward<K>(key);
kv.key = key;
kv.value = std::forward<V>(value);
}
template<typename VectorType, typename SourceType>
static void populate_service_map(VectorType &dest, SourceType &source, Ts... x) {
static void populate_service_map(VectorType &dest, SourceType &source, FixedVector<std::string> &value_storage,
Ts... x) {
dest.init(source.size());
// Count non-static strings to allocate exact storage needed
size_t lambda_count = 0;
for (const auto &it : source) {
if (!it.value.is_static_string()) {
lambda_count++;
}
}
value_storage.init(lambda_count);
for (auto &it : source) {
auto &kv = dest.emplace_back();
kv.set_key(StringRef(it.key));
kv.value = it.value.value(x...);
kv.key = StringRef(it.key);
if (it.value.is_static_string()) {
// Static string from YAML - zero allocation
kv.value = StringRef(it.value.get_static_string());
} else {
// Lambda evaluation - store result, reference it
value_storage.push_back(it.value.value(x...));
kv.value = StringRef(value_storage.back());
}
}
}

View File

@@ -5,6 +5,9 @@
#include "esphome/core/application.h"
#include "esphome/core/log.h"
#include "esphome/core/util.h"
#ifdef USE_API_USER_DEFINED_ACTIONS
#include "user_services.h"
#endif
namespace esphome::api {
@@ -70,6 +73,12 @@ LIST_ENTITIES_HANDLER(media_player, media_player::MediaPlayer, ListEntitiesMedia
LIST_ENTITIES_HANDLER(alarm_control_panel, alarm_control_panel::AlarmControlPanel,
ListEntitiesAlarmControlPanelResponse)
#endif
#ifdef USE_WATER_HEATER
LIST_ENTITIES_HANDLER(water_heater, water_heater::WaterHeater, ListEntitiesWaterHeaterResponse)
#endif
#ifdef USE_INFRARED
LIST_ENTITIES_HANDLER(infrared, infrared::Infrared, ListEntitiesInfraredResponse)
#endif
#ifdef USE_EVENT
LIST_ENTITIES_HANDLER(event, event::Event, ListEntitiesEventResponse)
#endif
@@ -82,7 +91,7 @@ bool ListEntitiesIterator::on_end() { return this->client_->send_list_info_done(
ListEntitiesIterator::ListEntitiesIterator(APIConnection *client) : client_(client) {}
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
bool ListEntitiesIterator::on_service(UserServiceDescriptor *service) {
auto resp = service->encode_list_service_response();
return this->client_->send_message(resp, ListEntitiesServicesResponse::MESSAGE_TYPE);

View File

@@ -43,7 +43,7 @@ class ListEntitiesIterator : public ComponentIterator {
#ifdef USE_TEXT_SENSOR
bool on_text_sensor(text_sensor::TextSensor *entity) override;
#endif
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
bool on_service(UserServiceDescriptor *service) override;
#endif
#ifdef USE_CAMERA
@@ -82,6 +82,12 @@ class ListEntitiesIterator : public ComponentIterator {
#ifdef USE_ALARM_CONTROL_PANEL
bool on_alarm_control_panel(alarm_control_panel::AlarmControlPanel *entity) override;
#endif
#ifdef USE_WATER_HEATER
bool on_water_heater(water_heater::WaterHeater *entity) override;
#endif
#ifdef USE_INFRARED
bool on_infrared(infrared::Infrared *entity) override;
#endif
#ifdef USE_EVENT
bool on_event(event::Event *entity) override;
#endif

View File

@@ -139,12 +139,4 @@ void ProtoDecodableMessage::decode(const uint8_t *buffer, size_t length) {
}
}
#ifdef HAS_PROTO_MESSAGE_DUMP
std::string ProtoMessage::dump() const {
std::string out;
this->dump_to(out);
return out;
}
#endif
} // namespace esphome::api

View File

@@ -39,6 +39,24 @@ inline constexpr int64_t decode_zigzag64(uint64_t value) {
return (value & 1) ? static_cast<int64_t>(~(value >> 1)) : static_cast<int64_t>(value >> 1);
}
/// Count number of varints in a packed buffer
inline uint16_t count_packed_varints(const uint8_t *data, size_t len) {
uint16_t count = 0;
while (len > 0) {
// Skip varint bytes until we find one without continuation bit
while (len > 0 && (*data & 0x80)) {
data++;
len--;
}
if (len > 0) {
data++;
len--;
count++;
}
}
return count;
}
/*
* StringRef Ownership Model for API Protocol Messages
* ===================================================
@@ -54,16 +72,16 @@ inline constexpr int64_t decode_zigzag64(uint64_t value) {
* 3. Global/static strings: StringRef(GLOBAL_CONSTANT) - Always safe
* 4. Local variables: Safe ONLY if encoding happens before function returns:
* std::string temp = compute_value();
* msg.set_field(StringRef(temp));
* msg.field = StringRef(temp);
* return this->send_message(msg); // temp is valid during encoding
*
* Unsafe Patterns (WILL cause crashes/corruption):
* 1. Temporaries: msg.set_field(StringRef(obj.get_string())) // get_string() returns by value
* 2. Concatenation: msg.set_field(StringRef(str1 + str2)) // Result is temporary
* 1. Temporaries: msg.field = StringRef(obj.get_string()) // get_string() returns by value
* 2. Concatenation: msg.field = StringRef(str1 + str2) // Result is temporary
*
* For unsafe patterns, store in a local variable first:
* std::string temp = get_string(); // or str1 + str2
* msg.set_field(StringRef(temp));
* msg.field = StringRef(temp);
*
* The send_*_response pattern ensures proper lifetime management by encoding
* within the same function scope where temporaries are created.
@@ -180,9 +198,10 @@ class ProtoVarInt {
uint64_t value_;
};
// Forward declaration for decode_to_message and encode_to_writer
class ProtoMessage;
// Forward declarations for decode_to_message, encode_message and encode_packed_sint32
class ProtoDecodableMessage;
class ProtoMessage;
class ProtoSize;
class ProtoLengthDelimited {
public:
@@ -334,15 +353,71 @@ class ProtoWriteBuffer {
void encode_sint64(uint32_t field_id, int64_t value, bool force = false) {
this->encode_uint64(field_id, encode_zigzag64(value), force);
}
void encode_message(uint32_t field_id, const ProtoMessage &value, bool force = false);
/// Encode a packed repeated sint32 field (zero-copy from vector)
void encode_packed_sint32(uint32_t field_id, const std::vector<int32_t> &values);
void encode_message(uint32_t field_id, const ProtoMessage &value);
std::vector<uint8_t> *get_buffer() const { return buffer_; }
protected:
std::vector<uint8_t> *buffer_;
};
// Forward declaration
class ProtoSize;
#ifdef HAS_PROTO_MESSAGE_DUMP
/**
* Fixed-size buffer for message dumps - avoids heap allocation.
* Sized to match the logger's default tx_buffer_size (512 bytes)
* since anything larger gets truncated anyway.
*/
class DumpBuffer {
public:
// Matches default tx_buffer_size in logger component
static constexpr size_t CAPACITY = 512;
DumpBuffer() : pos_(0) { buf_[0] = '\0'; }
DumpBuffer &append(const char *str) {
if (str) {
append_impl_(str, strlen(str));
}
return *this;
}
DumpBuffer &append(const char *str, size_t len) {
append_impl_(str, len);
return *this;
}
DumpBuffer &append(size_t n, char c) {
size_t space = CAPACITY - 1 - pos_;
if (n > space)
n = space;
if (n > 0) {
memset(buf_ + pos_, c, n);
pos_ += n;
buf_[pos_] = '\0';
}
return *this;
}
const char *c_str() const { return buf_; }
size_t size() const { return pos_; }
private:
void append_impl_(const char *str, size_t len) {
size_t space = CAPACITY - 1 - pos_;
if (len > space)
len = space;
if (len > 0) {
memcpy(buf_ + pos_, str, len);
pos_ += len;
buf_[pos_] = '\0';
}
}
char buf_[CAPACITY];
size_t pos_;
};
#endif
class ProtoMessage {
public:
@@ -352,8 +427,7 @@ class ProtoMessage {
// Default implementation for messages with no fields
virtual void calculate_size(ProtoSize &size) const {}
#ifdef HAS_PROTO_MESSAGE_DUMP
std::string dump() const;
virtual void dump_to(std::string &out) const = 0;
virtual const char *dump_to(DumpBuffer &out) const = 0;
virtual const char *message_name() const { return "unknown"; }
#endif
};
@@ -792,10 +866,45 @@ class ProtoSize {
}
}
}
/**
* @brief Calculate size of a packed repeated sint32 field
*/
inline void add_packed_sint32(uint32_t field_id_size, const std::vector<int32_t> &values) {
if (values.empty())
return;
size_t packed_size = 0;
for (int value : values) {
packed_size += varint(encode_zigzag32(value));
}
// field_id + length varint + packed data
total_size_ += field_id_size + varint(static_cast<uint32_t>(packed_size)) + static_cast<uint32_t>(packed_size);
}
};
// Implementation of encode_packed_sint32 - must be after ProtoSize is defined
inline void ProtoWriteBuffer::encode_packed_sint32(uint32_t field_id, const std::vector<int32_t> &values) {
if (values.empty())
return;
// Calculate packed size
size_t packed_size = 0;
for (int value : values) {
packed_size += ProtoSize::varint(encode_zigzag32(value));
}
// Write tag (LENGTH_DELIMITED) + length + all zigzag-encoded values
this->encode_field_raw(field_id, WIRE_TYPE_LENGTH_DELIMITED);
this->encode_varint_raw(packed_size);
for (int value : values) {
this->encode_varint_raw(encode_zigzag32(value));
}
}
// Implementation of encode_message - must be after ProtoMessage is defined
inline void ProtoWriteBuffer::encode_message(uint32_t field_id, const ProtoMessage &value, bool force) {
inline void ProtoWriteBuffer::encode_message(uint32_t field_id, const ProtoMessage &value) {
this->encode_field_raw(field_id, 2); // type 2: Length-delimited message
// Calculate the message size first
@@ -833,9 +942,6 @@ class ProtoService {
virtual bool is_authenticated() = 0;
virtual bool is_connection_setup() = 0;
virtual void on_fatal_error() = 0;
#ifdef USE_API_PASSWORD
virtual void on_unauthenticated_access() = 0;
#endif
virtual void on_no_setup_connection() = 0;
/**
* Create a buffer with a reserved size.
@@ -846,7 +952,7 @@ class ProtoService {
*/
virtual ProtoWriteBuffer create_buffer(uint32_t reserve_size) = 0;
virtual bool send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) = 0;
virtual void read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) = 0;
virtual void read_message(uint32_t msg_size, uint32_t msg_type, const uint8_t *msg_data) = 0;
// Optimized method that pre-allocates buffer based on message size
bool send_message_(const ProtoMessage &msg, uint8_t message_type) {
@@ -873,20 +979,7 @@ class ProtoService {
return true;
}
inline bool check_authenticated_() {
#ifdef USE_API_PASSWORD
if (!this->check_connection_setup_()) {
return false;
}
if (!this->is_authenticated()) {
this->on_unauthenticated_access();
return false;
}
return true;
#else
return this->check_connection_setup_();
#endif
}
inline bool check_authenticated_() { return this->check_connection_setup_(); }
};
} // namespace esphome::api

View File

@@ -60,6 +60,9 @@ INITIAL_STATE_HANDLER(media_player, media_player::MediaPlayer)
#ifdef USE_ALARM_CONTROL_PANEL
INITIAL_STATE_HANDLER(alarm_control_panel, alarm_control_panel::AlarmControlPanel)
#endif
#ifdef USE_WATER_HEATER
INITIAL_STATE_HANDLER(water_heater, water_heater::WaterHeater)
#endif
#ifdef USE_UPDATE
INITIAL_STATE_HANDLER(update, update::UpdateEntity)
#endif

View File

@@ -76,6 +76,12 @@ class InitialStateIterator : public ComponentIterator {
#ifdef USE_ALARM_CONTROL_PANEL
bool on_alarm_control_panel(alarm_control_panel::AlarmControlPanel *entity) override;
#endif
#ifdef USE_WATER_HEATER
bool on_water_heater(water_heater::WaterHeater *entity) override;
#endif
#ifdef USE_INFRARED
bool on_infrared(infrared::Infrared *infrared) override { return true; };
#endif
#ifdef USE_EVENT
bool on_event(event::Event *event) override { return true; };
#endif

View File

@@ -1,20 +1,31 @@
#pragma once
#include <tuple>
#include <utility>
#include <vector>
#include "esphome/core/component.h"
#include "esphome/core/automation.h"
#include "api_pb2.h"
#include "esphome/core/automation.h"
#include "esphome/core/component.h"
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
#include "esphome/components/json/json_util.h"
#endif
#ifdef USE_API_SERVICES
#ifdef USE_API_USER_DEFINED_ACTIONS
namespace esphome::api {
// Forward declaration - full definition in api_server.h
class APIServer;
class UserServiceDescriptor {
public:
virtual ListEntitiesServicesResponse encode_list_service_response() = 0;
virtual bool execute_service(const ExecuteServiceRequest &req) = 0;
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
// Overload that accepts server-generated action_call_id (avoids client call_id collisions)
virtual bool execute_service(const ExecuteServiceRequest &req, uint32_t action_call_id) = 0;
#endif
bool is_internal() { return false; }
};
@@ -27,21 +38,23 @@ template<typename T> enums::ServiceArgType to_service_arg_type();
// Stores only pointers to string literals in flash - no heap allocation
template<typename... Ts> class UserServiceBase : public UserServiceDescriptor {
public:
UserServiceBase(const char *name, const std::array<const char *, sizeof...(Ts)> &arg_names)
: name_(name), arg_names_(arg_names) {
UserServiceBase(const char *name, const std::array<const char *, sizeof...(Ts)> &arg_names,
enums::SupportsResponseType supports_response = enums::SUPPORTS_RESPONSE_NONE)
: name_(name), arg_names_(arg_names), supports_response_(supports_response) {
this->key_ = fnv1_hash(name);
}
ListEntitiesServicesResponse encode_list_service_response() override {
ListEntitiesServicesResponse msg;
msg.set_name(StringRef(this->name_));
msg.name = StringRef(this->name_);
msg.key = this->key_;
msg.supports_response = this->supports_response_;
std::array<enums::ServiceArgType, sizeof...(Ts)> arg_types = {to_service_arg_type<Ts>()...};
msg.args.init(sizeof...(Ts));
for (size_t i = 0; i < sizeof...(Ts); i++) {
auto &arg = msg.args.emplace_back();
arg.type = arg_types[i];
arg.set_name(StringRef(this->arg_names_[i]));
arg.name = StringRef(this->arg_names_[i]);
}
return msg;
}
@@ -51,20 +64,37 @@ template<typename... Ts> class UserServiceBase : public UserServiceDescriptor {
return false;
if (req.args.size() != sizeof...(Ts))
return false;
this->execute_(req.args, typename gens<sizeof...(Ts)>::type());
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
this->execute_(req.args, req.call_id, req.return_response, std::make_index_sequence<sizeof...(Ts)>{});
#else
this->execute_(req.args, 0, false, std::make_index_sequence<sizeof...(Ts)>{});
#endif
return true;
}
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
bool execute_service(const ExecuteServiceRequest &req, uint32_t action_call_id) override {
if (req.key != this->key_)
return false;
if (req.args.size() != sizeof...(Ts))
return false;
this->execute_(req.args, action_call_id, req.return_response, std::make_index_sequence<sizeof...(Ts)>{});
return true;
}
#endif
protected:
virtual void execute(Ts... x) = 0;
template<typename ArgsContainer, int... S> void execute_(const ArgsContainer &args, seq<S...> type) {
this->execute((get_execute_arg_value<Ts>(args[S]))...);
virtual void execute(uint32_t call_id, bool return_response, Ts... x) = 0;
template<typename ArgsContainer, size_t... S>
void execute_(const ArgsContainer &args, uint32_t call_id, bool return_response, std::index_sequence<S...> /*type*/) {
this->execute(call_id, return_response, (get_execute_arg_value<Ts>(args[S]))...);
}
// Pointers to string literals in flash - no heap allocation
const char *name_;
std::array<const char *, sizeof...(Ts)> arg_names_;
uint32_t key_{0};
enums::SupportsResponseType supports_response_{enums::SUPPORTS_RESPONSE_NONE};
};
// Separate class for custom_api_device services (rare case)
@@ -78,14 +108,15 @@ template<typename... Ts> class UserServiceDynamic : public UserServiceDescriptor
ListEntitiesServicesResponse encode_list_service_response() override {
ListEntitiesServicesResponse msg;
msg.set_name(StringRef(this->name_));
msg.name = StringRef(this->name_);
msg.key = this->key_;
msg.supports_response = enums::SUPPORTS_RESPONSE_NONE; // Dynamic services don't support responses yet
std::array<enums::ServiceArgType, sizeof...(Ts)> arg_types = {to_service_arg_type<Ts>()...};
msg.args.init(sizeof...(Ts));
for (size_t i = 0; i < sizeof...(Ts); i++) {
auto &arg = msg.args.emplace_back();
arg.type = arg_types[i];
arg.set_name(StringRef(this->arg_names_[i]));
arg.name = StringRef(this->arg_names_[i]);
}
return msg;
}
@@ -95,14 +126,31 @@ template<typename... Ts> class UserServiceDynamic : public UserServiceDescriptor
return false;
if (req.args.size() != sizeof...(Ts))
return false;
this->execute_(req.args, typename gens<sizeof...(Ts)>::type());
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
this->execute_(req.args, req.call_id, req.return_response, std::make_index_sequence<sizeof...(Ts)>{});
#else
this->execute_(req.args, 0, false, std::make_index_sequence<sizeof...(Ts)>{});
#endif
return true;
}
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
// Dynamic services don't support responses yet, but need to implement the interface
bool execute_service(const ExecuteServiceRequest &req, uint32_t action_call_id) override {
if (req.key != this->key_)
return false;
if (req.args.size() != sizeof...(Ts))
return false;
this->execute_(req.args, action_call_id, req.return_response, std::make_index_sequence<sizeof...(Ts)>{});
return true;
}
#endif
protected:
virtual void execute(Ts... x) = 0;
template<typename ArgsContainer, int... S> void execute_(const ArgsContainer &args, seq<S...> type) {
this->execute((get_execute_arg_value<Ts>(args[S]))...);
virtual void execute(uint32_t call_id, bool return_response, Ts... x) = 0;
template<typename ArgsContainer, size_t... S>
void execute_(const ArgsContainer &args, uint32_t call_id, bool return_response, std::index_sequence<S...> /*type*/) {
this->execute(call_id, return_response, (get_execute_arg_value<Ts>(args[S]))...);
}
// Heap-allocated strings for runtime-generated names
@@ -111,15 +159,149 @@ template<typename... Ts> class UserServiceDynamic : public UserServiceDescriptor
uint32_t key_{0};
};
template<typename... Ts> class UserServiceTrigger : public UserServiceBase<Ts...>, public Trigger<Ts...> {
// Primary template declaration
template<enums::SupportsResponseType Mode, typename... Ts> class UserServiceTrigger;
// Specialization for NONE - no extra trigger arguments
template<typename... Ts>
class UserServiceTrigger<enums::SUPPORTS_RESPONSE_NONE, Ts...> : public UserServiceBase<Ts...>, public Trigger<Ts...> {
public:
// Constructor for static names (YAML-defined services - used by code generator)
UserServiceTrigger(const char *name, const std::array<const char *, sizeof...(Ts)> &arg_names)
: UserServiceBase<Ts...>(name, arg_names) {}
: UserServiceBase<Ts...>(name, arg_names, enums::SUPPORTS_RESPONSE_NONE) {}
protected:
void execute(Ts... x) override { this->trigger(x...); } // NOLINT
void execute(uint32_t /*call_id*/, bool /*return_response*/, Ts... x) override { this->trigger(x...); }
};
// Specialization for OPTIONAL - call_id and return_response trigger arguments
template<typename... Ts>
class UserServiceTrigger<enums::SUPPORTS_RESPONSE_OPTIONAL, Ts...> : public UserServiceBase<Ts...>,
public Trigger<uint32_t, bool, Ts...> {
public:
UserServiceTrigger(const char *name, const std::array<const char *, sizeof...(Ts)> &arg_names)
: UserServiceBase<Ts...>(name, arg_names, enums::SUPPORTS_RESPONSE_OPTIONAL) {}
protected:
void execute(uint32_t call_id, bool return_response, Ts... x) override {
this->trigger(call_id, return_response, x...);
}
};
// Specialization for ONLY - just call_id trigger argument
template<typename... Ts>
class UserServiceTrigger<enums::SUPPORTS_RESPONSE_ONLY, Ts...> : public UserServiceBase<Ts...>,
public Trigger<uint32_t, Ts...> {
public:
UserServiceTrigger(const char *name, const std::array<const char *, sizeof...(Ts)> &arg_names)
: UserServiceBase<Ts...>(name, arg_names, enums::SUPPORTS_RESPONSE_ONLY) {}
protected:
void execute(uint32_t call_id, bool /*return_response*/, Ts... x) override { this->trigger(call_id, x...); }
};
// Specialization for STATUS - just call_id trigger argument (reports success/error without data)
template<typename... Ts>
class UserServiceTrigger<enums::SUPPORTS_RESPONSE_STATUS, Ts...> : public UserServiceBase<Ts...>,
public Trigger<uint32_t, Ts...> {
public:
UserServiceTrigger(const char *name, const std::array<const char *, sizeof...(Ts)> &arg_names)
: UserServiceBase<Ts...>(name, arg_names, enums::SUPPORTS_RESPONSE_STATUS) {}
protected:
void execute(uint32_t call_id, bool /*return_response*/, Ts... x) override { this->trigger(call_id, x...); }
};
} // namespace esphome::api
#endif // USE_API_SERVICES
#endif // USE_API_USER_DEFINED_ACTIONS
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
// Include full definition of APIServer for template implementation
// Must be outside namespace to avoid including STL headers inside namespace
#include "api_server.h"
namespace esphome::api {
template<typename... Ts> class APIRespondAction : public Action<Ts...> {
public:
explicit APIRespondAction(APIServer *parent) : parent_(parent) {}
template<typename V> void set_success(V success) { this->success_ = success; }
template<typename V> void set_error_message(V error) { this->error_message_ = error; }
void set_is_optional_mode(bool is_optional) { this->is_optional_mode_ = is_optional; }
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
void set_data(std::function<void(Ts..., JsonObject)> func) {
this->json_builder_ = std::move(func);
this->has_data_ = true;
}
#endif
void play(const Ts &...x) override {
// Extract call_id from first argument - it's always first for optional/only/status modes
auto args = std::make_tuple(x...);
uint32_t call_id = std::get<0>(args);
bool success = this->success_.value(x...);
std::string error_message = this->error_message_.value(x...);
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
if (this->has_data_) {
// For optional mode, check return_response (second arg) to decide if client wants data
// Use nested if constexpr to avoid compile error when tuple doesn't have enough elements
// (std::tuple_element_t is evaluated before the && short-circuit, so we must nest)
if constexpr (sizeof...(Ts) >= 2) {
if constexpr (std::is_same_v<std::tuple_element_t<1, std::tuple<Ts...>>, bool>) {
if (this->is_optional_mode_) {
bool return_response = std::get<1>(args);
if (!return_response) {
// Client doesn't want response data, just send success/error
this->parent_->send_action_response(call_id, success, StringRef(error_message));
return;
}
}
}
}
// Build and send JSON response
json::JsonBuilder builder;
this->json_builder_(x..., builder.root());
std::string json_str = builder.serialize();
this->parent_->send_action_response(call_id, success, StringRef(error_message),
reinterpret_cast<const uint8_t *>(json_str.data()), json_str.size());
return;
}
#endif
this->parent_->send_action_response(call_id, success, StringRef(error_message));
}
protected:
APIServer *parent_;
TemplatableValue<bool, Ts...> success_{true};
TemplatableValue<std::string, Ts...> error_message_{""};
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
std::function<void(Ts..., JsonObject)> json_builder_;
bool has_data_{false};
#endif
bool is_optional_mode_{false};
};
// Action to unregister a service call after execution completes
// Automatically appended to the end of action lists for non-none response modes
template<typename... Ts> class APIUnregisterServiceCallAction : public Action<Ts...> {
public:
explicit APIUnregisterServiceCallAction(APIServer *parent) : parent_(parent) {}
void play(const Ts &...x) override {
// Extract call_id from first argument - same convention as APIRespondAction
auto args = std::make_tuple(x...);
uint32_t call_id = std::get<0>(args);
if (call_id != 0) {
this->parent_->unregister_active_action_call(call_id);
}
}
protected:
APIServer *parent_;
};
} // namespace esphome::api
#endif // USE_API_USER_DEFINED_ACTION_RESPONSES

View File

@@ -0,0 +1,14 @@
import esphome.codegen as cg
CODEOWNERS = ["@jasstrong", "@ximex", "@freekode"]
aqi_ns = cg.esphome_ns.namespace("aqi")
AQICalculatorType = aqi_ns.enum("AQICalculatorType")
CONF_AQI = "aqi"
CONF_CALCULATION_TYPE = "calculation_type"
AQI_CALCULATION_TYPE = {
"CAQI": AQICalculatorType.CAQI_TYPE,
"AQI": AQICalculatorType.AQI_TYPE,
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include <cstdint>
namespace esphome::aqi {
class AbstractAQICalculator {
public:
virtual uint16_t get_aqi(float pm2_5_value, float pm10_0_value) = 0;
};
} // namespace esphome::aqi

View File

@@ -0,0 +1,56 @@
#pragma once
#include <cmath>
#include <limits>
#include "abstract_aqi_calculator.h"
// https://document.airnow.gov/technical-assistance-document-for-the-reporting-of-daily-air-quailty.pdf
namespace esphome::aqi {
class AQICalculator : public AbstractAQICalculator {
public:
uint16_t get_aqi(float pm2_5_value, float pm10_0_value) override {
float pm2_5_index = calculate_index(pm2_5_value, PM2_5_GRID);
float pm10_0_index = calculate_index(pm10_0_value, PM10_0_GRID);
return static_cast<uint16_t>(std::round((pm2_5_index < pm10_0_index) ? pm10_0_index : pm2_5_index));
}
protected:
static constexpr int NUM_LEVELS = 6;
static constexpr int INDEX_GRID[NUM_LEVELS][2] = {{0, 50}, {51, 100}, {101, 150}, {151, 200}, {201, 300}, {301, 500}};
static constexpr float PM2_5_GRID[NUM_LEVELS][2] = {{0.0f, 9.0f}, {9.1f, 35.4f},
{35.5f, 55.4f}, {55.5f, 125.4f},
{125.5f, 225.4f}, {225.5f, std::numeric_limits<float>::max()}};
static constexpr float PM10_0_GRID[NUM_LEVELS][2] = {{0.0f, 54.0f}, {55.0f, 154.0f},
{155.0f, 254.0f}, {255.0f, 354.0f},
{355.0f, 424.0f}, {425.0f, std::numeric_limits<float>::max()}};
static float calculate_index(float value, const float array[NUM_LEVELS][2]) {
int grid_index = get_grid_index(value, array);
if (grid_index == -1) {
return -1.0f;
}
float aqi_lo = INDEX_GRID[grid_index][0];
float aqi_hi = INDEX_GRID[grid_index][1];
float conc_lo = array[grid_index][0];
float conc_hi = array[grid_index][1];
return (value - conc_lo) * (aqi_hi - aqi_lo) / (conc_hi - conc_lo) + aqi_lo;
}
static int get_grid_index(float value, const float array[NUM_LEVELS][2]) {
for (int i = 0; i < NUM_LEVELS; i++) {
if (value >= array[i][0] && value <= array[i][1]) {
return i;
}
}
return -1;
}
};
} // namespace esphome::aqi

View File

@@ -3,8 +3,7 @@
#include "caqi_calculator.h"
#include "aqi_calculator.h"
namespace esphome {
namespace hm3301 {
namespace esphome::aqi {
enum AQICalculatorType { CAQI_TYPE = 0, AQI_TYPE = 1 };
@@ -12,18 +11,17 @@ class AQICalculatorFactory {
public:
AbstractAQICalculator *get_calculator(AQICalculatorType type) {
if (type == 0) {
return caqi_calculator_;
return &this->caqi_calculator_;
} else if (type == 1) {
return aqi_calculator_;
return &this->aqi_calculator_;
}
return nullptr;
}
protected:
CAQICalculator *caqi_calculator_ = new CAQICalculator();
AQICalculator *aqi_calculator_ = new AQICalculator();
CAQICalculator caqi_calculator_;
AQICalculator aqi_calculator_;
};
} // namespace hm3301
} // namespace esphome
} // namespace esphome::aqi

View File

@@ -0,0 +1,51 @@
#include "aqi_sensor.h"
#include "esphome/core/log.h"
namespace esphome::aqi {
static const char *const TAG = "aqi";
void AQISensor::setup() {
if (this->pm_2_5_sensor_ != nullptr) {
this->pm_2_5_sensor_->add_on_state_callback([this](float value) {
this->pm_2_5_value_ = value;
// Defer calculation to avoid double-publishing if both sensors update in the same loop
this->defer("update", [this]() { this->calculate_aqi_(); });
});
}
if (this->pm_10_0_sensor_ != nullptr) {
this->pm_10_0_sensor_->add_on_state_callback([this](float value) {
this->pm_10_0_value_ = value;
this->defer("update", [this]() { this->calculate_aqi_(); });
});
}
}
void AQISensor::dump_config() {
ESP_LOGCONFIG(TAG, "AQI Sensor:");
ESP_LOGCONFIG(TAG, " Calculation Type: %s", this->aqi_calc_type_ == AQI_TYPE ? "AQI" : "CAQI");
if (this->pm_2_5_sensor_ != nullptr) {
ESP_LOGCONFIG(TAG, " PM2.5 Sensor: '%s'", this->pm_2_5_sensor_->get_name().c_str());
}
if (this->pm_10_0_sensor_ != nullptr) {
ESP_LOGCONFIG(TAG, " PM10 Sensor: '%s'", this->pm_10_0_sensor_->get_name().c_str());
}
LOG_SENSOR(" ", "AQI", this);
}
void AQISensor::calculate_aqi_() {
if (std::isnan(this->pm_2_5_value_) || std::isnan(this->pm_10_0_value_)) {
return;
}
AbstractAQICalculator *calculator = this->aqi_calculator_factory_.get_calculator(this->aqi_calc_type_);
if (calculator == nullptr) {
ESP_LOGW(TAG, "Unknown AQI calculator type");
return;
}
uint16_t aqi = calculator->get_aqi(this->pm_2_5_value_, this->pm_10_0_value_);
this->publish_state(aqi);
}
} // namespace esphome::aqi

View File

@@ -0,0 +1,31 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/sensor/sensor.h"
#include "aqi_calculator_factory.h"
namespace esphome::aqi {
class AQISensor : public sensor::Sensor, public Component {
public:
void setup() override;
void dump_config() override;
float get_setup_priority() const override { return setup_priority::DATA; }
void set_pm_2_5_sensor(sensor::Sensor *sensor) { this->pm_2_5_sensor_ = sensor; }
void set_pm_10_0_sensor(sensor::Sensor *sensor) { this->pm_10_0_sensor_ = sensor; }
void set_aqi_calculation_type(AQICalculatorType type) { this->aqi_calc_type_ = type; }
protected:
void calculate_aqi_();
sensor::Sensor *pm_2_5_sensor_{nullptr};
sensor::Sensor *pm_10_0_sensor_{nullptr};
AQICalculatorType aqi_calc_type_{AQI_TYPE};
AQICalculatorFactory aqi_calculator_factory_;
float pm_2_5_value_{NAN};
float pm_10_0_value_{NAN};
};
} // namespace esphome::aqi

View File

@@ -0,0 +1,53 @@
#pragma once
#include <cmath>
#include <limits>
#include "abstract_aqi_calculator.h"
namespace esphome::aqi {
class CAQICalculator : public AbstractAQICalculator {
public:
uint16_t get_aqi(float pm2_5_value, float pm10_0_value) override {
float pm2_5_index = calculate_index(pm2_5_value, PM2_5_GRID);
float pm10_0_index = calculate_index(pm10_0_value, PM10_0_GRID);
return static_cast<uint16_t>(std::round((pm2_5_index < pm10_0_index) ? pm10_0_index : pm2_5_index));
}
protected:
static constexpr int NUM_LEVELS = 5;
static constexpr int INDEX_GRID[NUM_LEVELS][2] = {{0, 25}, {26, 50}, {51, 75}, {76, 100}, {101, 400}};
static constexpr float PM2_5_GRID[NUM_LEVELS][2] = {
{0.0f, 15.0f}, {15.1f, 30.0f}, {30.1f, 55.0f}, {55.1f, 110.0f}, {110.1f, std::numeric_limits<float>::max()}};
static constexpr float PM10_0_GRID[NUM_LEVELS][2] = {
{0.0f, 25.0f}, {25.1f, 50.0f}, {50.1f, 90.0f}, {90.1f, 180.0f}, {180.1f, std::numeric_limits<float>::max()}};
static float calculate_index(float value, const float array[NUM_LEVELS][2]) {
int grid_index = get_grid_index(value, array);
if (grid_index == -1) {
return -1.0f;
}
float aqi_lo = INDEX_GRID[grid_index][0];
float aqi_hi = INDEX_GRID[grid_index][1];
float conc_lo = array[grid_index][0];
float conc_hi = array[grid_index][1];
return (value - conc_lo) * (aqi_hi - aqi_lo) / (conc_hi - conc_lo) + aqi_lo;
}
static int get_grid_index(float value, const float array[NUM_LEVELS][2]) {
for (int i = 0; i < NUM_LEVELS; i++) {
if (value >= array[i][0] && value <= array[i][1]) {
return i;
}
}
return -1;
}
};
} // namespace esphome::aqi

View File

@@ -0,0 +1,51 @@
import esphome.codegen as cg
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_PM_2_5,
CONF_PM_10_0,
DEVICE_CLASS_AQI,
STATE_CLASS_MEASUREMENT,
)
from . import AQI_CALCULATION_TYPE, CONF_CALCULATION_TYPE, aqi_ns
CODEOWNERS = ["@jasstrong"]
DEPENDENCIES = ["sensor"]
UNIT_INDEX = "index"
AQISensor = aqi_ns.class_("AQISensor", sensor.Sensor, cg.Component)
CONFIG_SCHEMA = (
sensor.sensor_schema(
AQISensor,
unit_of_measurement=UNIT_INDEX,
accuracy_decimals=0,
device_class=DEVICE_CLASS_AQI,
state_class=STATE_CLASS_MEASUREMENT,
)
.extend(
{
cv.Required(CONF_PM_2_5): cv.use_id(sensor.Sensor),
cv.Required(CONF_PM_10_0): cv.use_id(sensor.Sensor),
cv.Required(CONF_CALCULATION_TYPE): cv.enum(
AQI_CALCULATION_TYPE, upper=True
),
}
)
.extend(cv.COMPONENT_SCHEMA)
)
async def to_code(config):
var = await sensor.new_sensor(config)
await cg.register_component(var, config)
pm_2_5_sensor = await cg.get_variable(config[CONF_PM_2_5])
cg.add(var.set_pm_2_5_sensor(pm_2_5_sensor))
pm_10_0_sensor = await cg.get_variable(config[CONF_PM_10_0])
cg.add(var.set_pm_10_0_sensor(pm_10_0_sensor))
cg.add(var.set_aqi_calculation_type(config[CONF_CALCULATION_TYPE]))

Some files were not shown because too many files have changed in this diff Show More