Compare commits

..

2627 Commits

Author SHA1 Message Date
J. Nick Koston
a8d120ca09 fix dangling pointer 2025-10-03 16:36:43 -05:00
J. Nick Koston
4bd5e3da50 [web_server_idf] Improve parameter caching security and reduce memory overhead 2025-10-03 15:30:42 -05:00
J. Nick Koston
c78dc048d8 Merge branch 'integration' into memory_api 2025-10-03 14:58:25 -05:00
J. Nick Koston
3c3202bcf3 Merge branch 'fix_watchdog_reset_idf_web_server' into integration 2025-10-03 14:58:19 -05:00
J. Nick Koston
006f8e0bac tidy 2025-10-03 14:58:08 -05:00
J. Nick Koston
7b65279021 Merge branch 'integration' into memory_api 2025-10-03 14:32:17 -05:00
J. Nick Koston
85025ff3f7 Merge branch 'fix_watchdog_reset_idf_web_server' into integration 2025-10-03 14:32:11 -05:00
J. Nick Koston
0938abbcae fix 2025-10-03 14:32:02 -05:00
J. Nick Koston
916984b616 Merge branch 'integration' into memory_api 2025-10-03 14:23:48 -05:00
J. Nick Koston
5252a03102 Merge branch 'use_idf_webserver_esp32' into integration 2025-10-03 14:23:42 -05:00
J. Nick Koston
64268ff838 missed one 2025-10-03 14:23:29 -05:00
J. Nick Koston
095542035e Merge branch 'integration' into memory_api 2025-10-03 14:21:34 -05:00
J. Nick Koston
580cfebfcf Merge branch 'fix_watchdog_reset_idf_web_server' into integration 2025-10-03 14:21:26 -05:00
J. Nick Koston
88e40a3fc8 [web_server_idf] Fix watchdog timeout with unreliable event source connections 2025-10-03 14:17:12 -05:00
J. Nick Koston
834ce57a75 fix libs 2025-10-03 09:25:31 -05:00
J. Nick Koston
52a19e916c fix libs 2025-10-03 09:18:36 -05:00
J. Nick Koston
1a2be1e579 fix libs 2025-10-03 09:12:24 -05:00
J. Nick Koston
d687650bf2 fix libs 2025-10-03 09:02:16 -05:00
J. Nick Koston
eecf7093ce fix libs 2025-10-03 08:55:58 -05:00
J. Nick Koston
e068df06e2 fix libs 2025-10-03 08:45:17 -05:00
J. Nick Koston
b3edda224f fix 2025-10-03 08:37:07 -05:00
J. Nick Koston
03dd169f1b fix 2025-10-03 08:02:45 -05:00
J. Nick Koston
74a6ef2604 preen 2025-10-03 07:40:57 -05:00
J. Nick Koston
18dcd8ebbc Merge branch 'dev' into use_idf_webserver_esp32 2025-10-03 14:37:23 +02:00
J. Nick Koston
fddeb482b5 fix compat 2025-10-03 07:36:23 -05:00
Oliver Gründel
ba0532cda7 Fix UNIT_KILOVOLT_AMPS_REACTIVE constant definition (#10992) 2025-10-03 07:36:14 -04:00
J. Nick Koston
5419b8bddb [ci] Fix pre-commit action to comply with pinned SHA security policy (#10990) 2025-10-02 21:53:16 -05:00
J. Nick Koston
0388dad588 [web_server] Use ESP-IDF web server for ESP32 Arduino builds 2025-10-02 21:32:18 -05:00
J. Nick Koston
d8fe655285 always use idf webserver on esp32 2025-10-02 21:19:45 -05:00
J. Nick Koston
29551832b3 Merge branch 'integration' into memory_api 2025-10-03 00:46:01 +02:00
J. Nick Koston
f607388c5f Merge branch 'no_mod_logger' into integration 2025-10-03 00:45:53 +02:00
J. Nick Koston
abcbdece2e handle >999 2025-10-03 00:33:03 +02:00
J. Nick Koston
ed907f842d handle >999 2025-10-03 00:30:43 +02:00
J. Nick Koston
aa1c5b5daa show BIG on overflow 2025-10-03 00:26:17 +02:00
J. Nick Koston
f7cbb5d647 Merge branch 'integration' into memory_api 2025-10-02 23:06:43 +02:00
J. Nick Koston
976b55ed2e Merge branch 'webserver_string_construction_reduce' into integration 2025-10-02 23:06:36 +02:00
J. Nick Koston
f5fc06fd9e preen 2025-10-02 23:03:53 +02:00
J. Nick Koston
10a16c3761 preen 2025-10-02 23:03:01 +02:00
J. Nick Koston
cd1b47667b preen 2025-10-02 23:02:46 +02:00
dependabot[bot]
624868bb05 Bump github/codeql-action from 3.30.5 to 3.30.6 (#10985)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-02 22:58:06 +02:00
J. Nick Koston
86f2d2e5c2 Merge remote-tracking branch 'upstream/memory_api' into memory_api 2025-10-02 22:14:58 +02:00
J. Nick Koston
650f2f915a Merge branch 'webserver_string_construction_reduce' into memory_api 2025-10-02 22:14:12 +02:00
J. Nick Koston
403bfdc68a Merge branch 'webserver_string_construction_reduce' into integration 2025-10-02 22:14:02 +02:00
J. Nick Koston
e69d18195b [web_server] Reduce flash and RAM usage by optimizing string construction 2025-10-02 22:12:12 +02:00
J. Nick Koston
9865320c88 Merge branch 'integration' into memory_api 2025-10-02 20:08:01 +02:00
J. Nick Koston
dd38b911f1 Merge branch 'no_std_pair' into integration 2025-10-02 20:07:49 +02:00
J. Nick Koston
3b0393bd3b Merge branch 'integration' of https://github.com/esphome/esphome into integration 2025-10-02 20:07:46 +02:00
J. Nick Koston
9d8ff38a85 [core] Replace std::pair with purpose-built named structs for component metadata 2025-10-02 20:04:29 +02:00
J. Nick Koston
be4af0a977 Merge branch 'integration' into memory_api 2025-10-02 16:45:45 +02:00
J. Nick Koston
484af4a38b Merge branch 'number_call_logging' into integration 2025-10-02 16:45:00 +02:00
J. Nick Koston
8931dcf409 reduce 2025-10-02 16:33:22 +02:00
J. Nick Koston
1fc4d1acfb number 2025-10-02 16:20:42 +02:00
J. Nick Koston
5374df73ed number 2025-10-02 16:18:06 +02:00
J. Nick Koston
28e8750ad6 Merge branch 'integration' into memory_api 2025-10-02 14:20:41 +02:00
J. Nick Koston
c4d18ae292 Merge branch 'no_mod_logger' into integration 2025-10-02 14:20:30 +02:00
J. Nick Koston
a4cb14a76a Apply Copilot review suggestion: use remainder variable instead of modifying line parameter 2025-10-02 13:18:19 +02:00
J. Nick Koston
772450f1b3 no mod 2025-10-02 11:43:27 +02:00
J. Nick Koston
bd6169ce34 Merge branch 'integration' into memory_api 2025-10-02 10:08:55 +02:00
J. Nick Koston
e4388ba48b Merge remote-tracking branch 'upstream/dev' into integration 2025-10-02 10:08:46 +02:00
J. Nick Koston
f2aa5a754c [api] Remove ClientInfo::get_combined_info() to eliminate heap fragmentation (#10970) 2025-10-02 12:44:30 +13:00
J. Nick Koston
e845bb3404 Merge branch 'integration' into memory_api 2025-10-02 00:22:06 +02:00
J. Nick Koston
d0b6fbdf73 Merge branch 'lock_mask' into integration 2025-10-02 00:21:59 +02:00
J. Nick Koston
ff55e03a5f back compat 2025-10-02 00:20:25 +02:00
J. Nick Koston
b44b3cbb41 back compat 2025-10-02 00:15:55 +02:00
J. Nick Koston
2cdc04fa27 Merge branch 'integration' into memory_api 2025-10-02 00:04:56 +02:00
J. Nick Koston
fd65e560e8 Merge branch 'lock_mask' into integration 2025-10-02 00:04:47 +02:00
J. Nick Koston
efc8a8b904 [lock] Replace std::set with bitmask (saves 388B flash + 23B RAM per lock) 2025-10-02 00:04:10 +02:00
J. Nick Koston
28bc3c20ad Merge branch 'integration' into memory_api 2025-10-01 23:35:54 +02:00
J. Nick Koston
729de03305 Merge branch 'mdns_services_const' into integration 2025-10-01 23:35:47 +02:00
J. Nick Koston
15ca069d58 preen 2025-10-01 23:34:12 +02:00
J. Nick Koston
86bfedc30e preen 2025-10-01 23:30:33 +02:00
J. Nick Koston
785ad0cd47 preen 2025-10-01 23:27:14 +02:00
J. Nick Koston
76defeac39 preen 2025-10-01 23:26:29 +02:00
J. Nick Koston
fabeae554f Merge branch 'integration' into memory_api 2025-10-01 23:10:25 +02:00
J. Nick Koston
daf2e81f1d Merge branch 'mdns_services_const' into integration 2025-10-01 23:10:18 +02:00
J. Nick Koston
03c869bd43 update comment 2025-10-01 23:05:59 +02:00
J. Nick Koston
636d1e16f2 update comment 2025-10-01 23:05:30 +02:00
J. Nick Koston
4208bad94d Merge branch 'integration' into memory_api 2025-10-01 22:49:37 +02:00
J. Nick Koston
5df3745304 Merge branch 'mdns_services_const' into integration 2025-10-01 22:49:28 +02:00
J. Nick Koston
de2838fa66 preen 2025-10-01 22:35:33 +02:00
J. Nick Koston
b4b8b43bd7 preen 2025-10-01 22:34:32 +02:00
J. Nick Koston
30df2cb9ee preen 2025-10-01 22:33:50 +02:00
J. Nick Koston
03e0fbd657 preen 2025-10-01 22:33:22 +02:00
J. Nick Koston
c12eba9590 preen 2025-10-01 22:32:28 +02:00
J. Nick Koston
2eb35f83b7 preen 2025-10-01 22:31:55 +02:00
J. Nick Koston
518402f031 preen 2025-10-01 22:31:04 +02:00
J. Nick Koston
9647fd26f7 Merge remote-tracking branch 'upstream/dev' into mdns_services_const 2025-10-01 22:26:08 +02:00
J. Nick Koston
21d7dc2b9b [mdns][openthread] Use std::array for mdns services and remove unnecessary copy 2025-10-01 22:25:11 +02:00
J. Nick Koston
a9dc0628c4 [mdns][openthread] Use std::array for mdns services and remove unnecessary copy 2025-10-01 22:21:58 +02:00
J. Nick Koston
b89d969d09 Merge branch 'integration' into memory_api 2025-10-01 21:36:07 +02:00
J. Nick Koston
9e2e4f56ad Merge branch 'bound_tx_buf' into integration 2025-10-01 21:36:01 +02:00
J. Nick Koston
b252486587 preen 2025-10-01 21:13:05 +02:00
J. Nick Koston
73c6411a1b Merge branch 'bound_tx_buf' into integration 2025-10-01 21:08:59 +02:00
J. Nick Koston
65384ef31a style 2025-10-01 21:08:49 +02:00
J. Nick Koston
829f9fb9bc style 2025-10-01 21:08:31 +02:00
J. Nick Koston
5afe2ea48e Merge branch 'integration' into memory_api 2025-10-01 20:47:48 +02:00
J. Nick Koston
fa548e20da Merge branch 'bound_tx_buf' into integration 2025-10-01 20:47:21 +02:00
J. Nick Koston
4b10bf09be tweak, compiler optimizes it away anyways though 2025-10-01 20:36:40 +02:00
J. Nick Koston
a4c794c9fa tweak, compiler optimizes it away anyways though 2025-10-01 20:34:51 +02:00
J. Nick Koston
638c6cc14e [api] Reduce flash usage in user services by eliminating vector copy (#10971) 2025-10-01 20:26:47 +02:00
Jonathan Swoboda
8137d7600a [rtttl] Fix warning (#10972) 2025-10-01 20:26:25 +02:00
J. Nick Koston
b7ab9773a3 Merge branch 'integration' into memory_api 2025-10-01 18:20:48 +02:00
J. Nick Koston
cc5b9ba4d6 Merge branch 'bound_tx_buf' into integration 2025-10-01 18:20:40 +02:00
J. Nick Koston
adade2952a 64 2025-10-01 18:17:41 +02:00
J. Nick Koston
f3330118ba [api] Add configurable send queue limit to prevent OOM crashes 2025-10-01 18:13:57 +02:00
J. Nick Koston
0cabe6d28e Merge branch 'integration' into memory_api 2025-10-01 17:06:11 +02:00
J. Nick Koston
2b374529f4 Merge branch 'client_info_flash' into integration 2025-10-01 17:06:01 +02:00
J. Nick Koston
85a6f85f2d Merge remote-tracking branch 'upstream/dev' into client_info_flash 2025-10-01 16:39:08 +02:00
J. Nick Koston
f4aea8fa7a tweak 2025-10-01 16:35:26 +02:00
J. Nick Koston
767753bdda Merge branch 'integration' into memory_api 2025-10-01 16:08:09 +02:00
J. Nick Koston
7b89647217 Merge branch 'user_services' into integration 2025-10-01 16:08:01 +02:00
J. Nick Koston
dab9a77c1a lint 2025-10-01 16:01:52 +02:00
J. Nick Koston
8c9c2ea3ec Merge branch 'integration' into memory_api 2025-10-01 15:57:57 +02:00
J. Nick Koston
9a240b64ce Merge branch 'user_services' into integration 2025-10-01 15:57:51 +02:00
J. Nick Koston
1b5ad59da5 [api] Reduce flash usage in user services by eliminating vector copy 2025-10-01 15:57:16 +02:00
Carl Reid
08afc3030a [psram] raise instead of returning invalid object (#10954)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-10-01 09:47:32 -04:00
J. Nick Koston
5a407a7edf Merge branch 'dev' into client_info_flash 2025-10-01 15:41:14 +02:00
Jesse Hills
1deb79a24b [core] Add some types to loader.py (#10967)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-01 15:36:17 +02:00
J. Nick Koston
de21c61b6a [logger] Optimize log formatting performance (35-72% faster) (#10960) 2025-10-01 15:33:30 +02:00
J. Nick Koston
db1aa82350 [core] Fix ComponentIterator alignment for 32-bit platforms (#10969) 2025-10-01 15:33:14 +02:00
J. Nick Koston
d0f9b54d95 Merge branch 'dev' into client_info_flash 2025-10-01 15:24:17 +02:00
J. Nick Koston
8ef4fc4fe9 Merge branch 'integration' into memory_api 2025-10-01 15:20:45 +02:00
J. Nick Koston
dee7ae7f63 Merge branch 'client_info_flash' into integration 2025-10-01 15:20:36 +02:00
J. Nick Koston
a760f7d604 [api] Remove ClientInfo::get_combined_info() to eliminate heap fragmentation 2025-10-01 15:04:26 +02:00
J. Nick Koston
fc2f44fa77 Merge branch 'integration' into memory_api 2025-10-01 13:36:04 +02:00
J. Nick Koston
a1ce92e406 Merge branch 'comp_align' into integration 2025-10-01 13:35:55 +02:00
J. Nick Koston
57d4cc151d [core] Fix ComponentIterator alignment for 32-bit platforms 2025-10-01 13:34:54 +02:00
Jesse Hills
fe4799b300 Merge branch 'release' into dev 2025-10-02 00:30:42 +13:00
Jesse Hills
93e18e850e Merge pull request #10966 from esphome/bump-2025.9.3
2025.9.3
2025-10-02 00:29:56 +13:00
mrtoy-me
5cef75dbe1 [hdc1080] remove delays and fix no check for sensor nullptr (#10947)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-10-01 07:22:02 -04:00
Piotr Szulc
4194a940ae [remote_transmitter] fix sending codes on libretiny (#10959)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-10-01 07:10:37 -04:00
J. Nick Koston
ef0079609e Merge branch 'integration' into memory_api 2025-10-01 13:09:34 +02:00
J. Nick Koston
0e64d25a50 Merge branch 'logging_speed_up' into integration 2025-10-01 13:09:26 +02:00
J. Nick Koston
774efad78b preen 2025-10-01 12:59:01 +02:00
Jesse Hills
59c0ffb98b Bump version to 2025.9.3 2025-10-01 23:41:42 +13:00
Abílio Costa
29658b79bc [voice_assistant] Fix wakeword string being reset while referenced (#10945)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-10-01 23:41:42 +13:00
Vladimir Makeev
158a59aa83 [sim800l] Fixed ignoring incoming calls. (#10865)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-10-01 23:41:42 +13:00
J. Nick Koston
c95180504a [api] Prevent API from overriding noise encryption keys set in YAML (#10927) 2025-10-01 23:41:42 +13:00
J. Nick Koston
3c594a7520 preen 2025-10-01 12:38:33 +02:00
Jesse Hills
848ba6b717 [psram] Fix invalid variant error, add supported() check (#10962) 2025-10-01 23:29:10 +13:00
J. Nick Koston
40c4fadd2c ansi color 2025-10-01 12:10:19 +02:00
J. Nick Koston
f0408fb121 Merge branch 'integration' into memory_api 2025-10-01 04:58:22 +02:00
J. Nick Koston
d36b0a38c9 Merge branch 'logging_speed_up' into integration 2025-10-01 04:58:11 +02:00
J. Nick Koston
922f4b6352 [web_server] Optimize handler methods with lookup tables to reduce flash usage (#10951) 2025-10-01 15:52:35 +13:00
J. Nick Koston
e7b2cdd03c preen 2025-10-01 03:59:43 +02:00
J. Nick Koston
4a3475f94d preen 2025-10-01 03:54:28 +02:00
Javier Peletier
fd3c05b42e [substitutions] fix #10825 set evaluation error (#10830) 2025-10-01 14:33:56 +13:00
J. Nick Koston
21b22ccd34 Merge branch 'integration' into memory_api 2025-10-01 02:43:56 +02:00
J. Nick Koston
cf26ec66a0 Merge branch 'logging_speed_up' into integration 2025-10-01 02:43:50 +02:00
J. Nick Koston
2e47315d81 [logger] Optimize log formatting performance (33-67% faster) 2025-10-01 01:42:14 +02:00
J. Nick Koston
d558e68cf3 [logger] Optimize log formatting performance (33-67% faster) 2025-10-01 01:41:40 +02:00
J. Nick Koston
ec3adaae5c [logger] Optimize log formatting performance (33-67% faster) 2025-10-01 01:41:27 +02:00
J. Nick Koston
9bffa2faa6 [logger] Optimize log formatting performance (33-67% faster) 2025-10-01 01:36:35 +02:00
J. Nick Koston
502cd2b54d [logger] Optimize log formatting performance (33-67% faster) 2025-10-01 01:33:49 +02:00
Jesse Hills
ab1f8326ee [const] Move CONF_ON_RESPONSE to const.py (#10958) 2025-10-01 11:12:45 +13:00
J. Nick Koston
2a915e4efd [deep_sleep] esp32 fixes to align with variant support (#10929) 2025-10-01 08:42:42 +13:00
dependabot[bot]
f5e85a424f Bump docker/login-action from 3.5.0 to 3.6.0 in the docker-actions group (#10943)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-01 08:29:49 +13:00
J. Nick Koston
c69603d916 [dashboard] Replace polling with WebSocket for real-time updates (#10893) 2025-09-30 14:03:52 -04:00
J. Nick Koston
c9088fcaf2 Merge branch 'integration' into memory_api 2025-09-30 18:29:15 +02:00
J. Nick Koston
65dae1232f Merge remote-tracking branch 'upstream/dev' into integration 2025-09-30 18:28:49 +02:00
Jonathan Swoboda
d75b7708a5 [sx126x] Add additional FSK CRC options (#10928) 2025-09-30 12:08:28 -04:00
J. Nick Koston
b023453e81 [captive_portal] Add DHCP Option 114 support for ESP32 (#10952) 2025-09-30 17:52:37 +02:00
Stephen Boyle
a5ba6237cb [ethernet] Add mac_address yaml configuration option (#10861)
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: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-30 08:59:08 -04:00
Patrick
0e623055df [mcp2515, canbus] error handling improvments (#10526) 2025-09-30 08:56:28 -04:00
J. Nick Koston
212933ec29 Merge branch 'web_server_more_tables' into memory_api 2025-09-30 14:11:57 +02:00
J. Nick Koston
fa89617a56 Merge branch 'integration' into memory_api 2025-09-30 13:59:59 +02:00
J. Nick Koston
edff3af3ae Merge branch 'dhcp_option_114' into integration 2025-09-30 13:59:30 +02:00
J. Nick Koston
d30a3f0d83 [captive_portal] Add DHCP Option 114 support for ESP32 2025-09-30 11:53:15 +02:00
J. Nick Koston
6018f5f5d1 [api] Add configurable connection limits (#10939) 2025-09-30 22:24:19 +13:00
J. Nick Koston
950310e49a [web_server] Optimize handler methods with lookup tables to reduce flash usage 2025-09-30 11:08:48 +02:00
J. Nick Koston
823d97d216 Merge branch 'integration' into memory_api 2025-09-30 10:31:17 +02:00
J. Nick Koston
db6751570a Merge remote-tracking branch 'upstream/dev' into integration 2025-09-30 10:30:58 +02:00
J. Nick Koston
96868aa754 [socket] Reduce memory overhead for LWIP TCP accept queue on ESP8266/RP2040 (#10938) 2025-09-30 16:52:47 +13:00
J. Nick Koston
83d86c8c59 [ota] Complete non-blocking authentication implementation (#10912) 2025-09-30 16:46:47 +13:00
Abílio Costa
7703cabb7b [voice_assistant] Fix wakeword string being reset while referenced (#10945)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-30 02:29:16 +00:00
J. Nick Koston
29b6a1a6aa add comments to explain to copilot why std::vector convert is needed 2025-09-29 20:15:31 -05:00
J. Nick Koston
d381a220f7 Merge branch 'integration' into memory_api 2025-09-29 20:00:45 -05:00
J. Nick Koston
d7d66a1d2e Merge branch 'event_emitter_cleanup' into integration 2025-09-29 20:00:39 -05:00
J. Nick Koston
0dfb18a307 cleanup 2025-09-29 19:59:05 -05:00
J. Nick Koston
0cdfcad54d cleanup 2025-09-29 19:46:34 -05:00
J. Nick Koston
daa18bdbaf Merge branch 'integration' into memory_api 2025-09-29 19:14:40 -05:00
J. Nick Koston
3e50987963 Merge branch 'event_emitter_cleanup' into integration 2025-09-29 19:14:33 -05:00
J. Nick Koston
47a10e4be1 sever needs multi 2025-09-29 19:07:17 -05:00
J. Nick Koston
a260c31a63 preen 2025-09-29 18:57:05 -05:00
J. Nick Koston
e9299e8671 Apply suggestions from code review 2025-09-29 18:54:30 -05:00
J. Nick Koston
0eef3caa37 Merge branch 'integration' into memory_api 2025-09-29 18:51:24 -05:00
J. Nick Koston
caca945d18 Merge branch 'event_emitter_cleanup' into integration 2025-09-29 18:51:01 -05:00
J. Nick Koston
87b54daee0 wip 2025-09-29 18:17:25 -05:00
J. Nick Koston
43d8e213f6 wip 2025-09-29 18:15:25 -05:00
J. Nick Koston
9ff838bf35 wip 2025-09-29 18:13:46 -05:00
J. Nick Koston
d802d70311 wip 2025-09-29 18:07:46 -05:00
J. Nick Koston
e7750250e0 wip 2025-09-29 17:55:26 -05:00
J. Nick Koston
9efe9f1c19 wip 2025-09-29 17:49:03 -05:00
dependabot[bot]
300f1de11c Bump aioesphomeapi from 41.10.0 to 41.11.0 (#10942)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-29 17:00:23 -05:00
J. Nick Koston
ee50ea31b4 Merge branch 'integration' into memory_api 2025-09-29 16:41:35 -05:00
J. Nick Koston
8259fd29e3 Merge branch 'deep_sleep_fixes' into integration 2025-09-29 16:41:13 -05:00
J. Nick Koston
3b73738d9f [script] Reduce RAM usage by storing names in flash (#10941) 2025-09-30 10:35:53 +13:00
J. Nick Koston
c2d9d66bb0 Remove C2 and H2 from component test matrix to avoid CI disk space issues 2025-09-29 14:39:56 -05:00
J. Nick Koston
d1e068cdc3 Merge remote-tracking branch 'upstream/dev' into deep_sleep_fixes 2025-09-29 14:39:08 -05:00
J. Nick Koston
b11a52fd1e Remove C2 and H2 from component test matrix to avoid CI disk space issues 2025-09-29 14:38:54 -05:00
Jonathan Swoboda
b176d1f890 [core] Don't remove storage in clean-all (#10921) 2025-09-29 15:24:42 -04:00
J. Nick Koston
c1081fbff7 Merge branch 'integration' into memory_api 2025-09-29 14:05:43 -05:00
J. Nick Koston
26ab6291f1 Merge branch 'script_name' into integration 2025-09-29 14:05:36 -05:00
J. Nick Koston
c0ff48de17 fix 2025-09-29 14:05:27 -05:00
J. Nick Koston
07e230b6a7 Merge branch 'integration' into memory_api 2025-09-29 14:00:46 -05:00
J. Nick Koston
7249f3d167 Merge branch 'script_name' into integration 2025-09-29 14:00:40 -05:00
J. Nick Koston
8ca9e2d015 [script] Reduce RAM usage by storing names in flash 2025-09-29 13:59:39 -05:00
Jesse Hills
2aaafd6ebb Merge branch 'release' into dev 2025-09-30 07:51:02 +13:00
Jesse Hills
a96c013eb1 Merge pull request #10932 from esphome/bump-2025.9.2
2025.9.2
2025-09-30 07:50:17 +13:00
J. Nick Koston
4f1c4ada9f Merge branch 'integration' into memory_api 2025-09-29 13:13:52 -05:00
J. Nick Koston
6a849a1d49 Merge branch 'esp8266_socket_overhead' into integration 2025-09-29 13:13:26 -05:00
J. Nick Koston
e23c97d9e9 Merge branch 'api_limits' into integration 2025-09-29 13:13:17 -05:00
tomaszduda23
054b215d8d [nrf52] add more tests (#10694) 2025-09-29 14:11:57 -04:00
tomaszduda23
e3e98e2568 [nrf52] add more tests (#10695)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-09-29 14:09:41 -04:00
J. Nick Koston
3560d6ca96 sane 2025-09-29 12:45:24 -05:00
J. Nick Koston
8b76b59a45 [socket] Reduce memory overhead for LWIP TCP accept queue on ESP8266/RP2040 2025-09-29 12:05:59 -05:00
J. Nick Koston
bb82496c12 limtis 2025-09-29 12:04:27 -05:00
J. Nick Koston
825d24f4d0 Merge branch 'integration' into memory_api 2025-09-29 10:02:05 -05:00
J. Nick Koston
a888a72859 Merge branch 'api_size_limits' into integration 2025-09-29 10:01:54 -05:00
J. Nick Koston
6b83e55088 [api] Add message size limits to prevent memory exhaustion 2025-09-29 09:58:36 -05:00
Vladimir Makeev
29db576f79 [sim800l] Fixed ignoring incoming calls. (#10865)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-09-29 09:08:51 -04:00
Jesse Hills
58166b3e71 Bump version to 2025.9.2 2025-09-29 21:39:17 +13:00
Clyde Stubbs
345fc0b6ca [mipi_spi] Fix t-display-amoled (#10922) 2025-09-29 21:39:17 +13:00
Oliver Kleinecke
127058e700 [usb_uart] Disable flow control on ch34x 2025-09-29 21:39:17 +13:00
Jonathan Swoboda
57f7a709cf [sx126x] Fix issues with variable length FSK packets (#10911) 2025-09-29 21:39:17 +13:00
J. Nick Koston
f2a9e9265e [esp32_improv] Fix crashes from uninitialized pointers and missing null checks (#10902) 2025-09-29 21:39:16 +13:00
Stuart Parmenter
1ecd26adb5 Set color_order to RGB for the Waveshare ESP32-S3-TOUCH-LCD-4.3 and ESP32-S3-TOUCH-LCD-7-800X480 (#10835) 2025-09-29 21:39:16 +13:00
Jonathan Swoboda
6d9fc672d5 [libretiny] Fix lib_ignore handling and ignore incompatible libraries (#10846) 2025-09-29 21:39:16 +13:00
J. Nick Koston
b9361b0868 [esp32_improv] Disable loop by default until provisioning needed (#10764) 2025-09-29 21:39:16 +13:00
J. Nick Koston
0246a8eb1d [usb_host] Fix double-free crash with lock-free atomic pool allocation (#10926) 2025-09-29 14:48:51 +10:00
J. Nick Koston
a56d044d98 [api] Prevent API from overriding noise encryption keys set in YAML (#10927) 2025-09-28 22:42:58 -05:00
J. Nick Koston
7975f12d60 [esp32] deep sleep fixes to align with variant support 2025-09-28 22:31:27 -05:00
J. Nick Koston
0af79adb4a Merge branch 'integration' into memory_api 2025-09-28 21:34:32 -05:00
J. Nick Koston
7ead15c987 Merge branch 'guard_trq_allocation' into integration 2025-09-28 21:34:24 -05:00
J. Nick Koston
b8bbe91e67 switch to != per discord review comemnts 2025-09-28 21:33:35 -05:00
J. Nick Koston
9705663e62 no need to copy 2025-09-28 21:29:38 -05:00
J. Nick Koston
f6253d52b4 [esp32_ble_server] Conditionally compile BLE automation features to save memory (#10910)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-29 14:28:03 +13:00
J. Nick Koston
1917d2b0af Merge branch 'integration' into memory_api 2025-09-28 18:54:40 -05:00
J. Nick Koston
b74193e730 Merge branch 'guard_trq_allocation' into integration 2025-09-28 18:54:35 -05:00
J. Nick Koston
5334ddd9f0 Update esphome/components/usb_host/usb_host_client.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-28 18:54:14 -05:00
J. Nick Koston
f2ee0195de fix retry 2025-09-28 18:53:31 -05:00
J. Nick Koston
4652bfa312 Merge branch 'integration' into memory_api 2025-09-28 18:50:46 -05:00
J. Nick Koston
f2e1e1d8cc Merge branch 'guard_trq_allocation' into integration 2025-09-28 18:50:39 -05:00
J. Nick Koston
a37cd67bc3 add static assert to ensure we do not break it in the future 2025-09-28 18:49:53 -05:00
J. Nick Koston
d015457d76 Merge branch 'integration' into memory_api 2025-09-28 18:44:23 -05:00
J. Nick Koston
ef09159e4a Merge branch 'guard_trq_allocation' into integration 2025-09-28 18:44:16 -05:00
J. Nick Koston
73ce3d4ef6 reduce flash usag 2025-09-28 18:44:08 -05:00
J. Nick Koston
0945912979 Merge branch 'guard_trq_allocation' into memory_api 2025-09-28 18:43:06 -05:00
J. Nick Koston
c37cd31706 Merge branch 'guard_trq_allocation' into integration 2025-09-28 18:43:02 -05:00
J. Nick Koston
d65b1fad67 fix underflow 2025-09-28 18:41:20 -05:00
J. Nick Koston
e51b16a9c4 Merge branch 'integration' into memory_api 2025-09-28 18:27:26 -05:00
J. Nick Koston
19186507bb Merge branch 'guard_trq_allocation' into integration 2025-09-28 18:27:18 -05:00
J. Nick Koston
e07af13bef [usb_host] Fix double-free crash with lock-free atomic pool allocation 2025-09-28 18:25:29 -05:00
Clyde Stubbs
77dff52183 [mipi_spi] Fix t-display-amoled (#10922) 2025-09-29 12:12:06 +13:00
J. Nick Koston
4b86f31b66 [core] Fix platform component normalization happening too late in validation pipeline (#10908) 2025-09-29 12:09:08 +13:00
J. Nick Koston
78655968df [event_emitter] Replace unordered_map with vector - saves 2.6KB flash, 2.3x faster (#10900) 2025-09-29 12:07:13 +13:00
J. Nick Koston
ab79e596b5 [esp32_ble_server] Optimize notification and action managers for typical use cases (#10897) 2025-09-29 11:32:16 +13:00
J. Nick Koston
ef73ae2116 [esp32_ble_server] Replace HashMap with vector for services - saves 1KB flash, 26x faster (#10894) 2025-09-29 10:36:40 +13:00
J. Nick Koston
0111f725ff [esp32_ble_tracker] Reduce gap_scan_result log verbosity to VV (#10917) 2025-09-29 10:34:32 +13:00
J. Nick Koston
34b4cb46f6 [esp32_improv] Make device name visible to passive BLE scanners (#10918) 2025-09-29 10:33:36 +13:00
J. Nick Koston
a2f833d665 [captive_portal] Add DNS server support for ESP-IDF framework (#10919) 2025-09-29 10:07:26 +13:00
Brandon Ibach
a7042687c1 [spi] fix SPI interface selection on ESP32-S2 and -S3 (#10732) (#10766) 2025-09-28 10:58:42 +00:00
Oliver Kleinecke
0d2d18c198 [usb_uart] Disable flow control on ch34x 2025-09-28 19:35:40 +10:00
Oliver Kleinecke
3f03e8c423 [usb_host][usb_uart] Allow on ESP32-P4 (#10815) 2025-09-28 07:15:18 +00:00
Keith Burzinski
9dd6be4061 [zwave_proxy, api] Add notification message when Z-Wave HomeID changes (#10860) 2025-09-27 17:50:18 -05:00
Jonathan Swoboda
2bf79a607f [sx126x] Fix issues with variable length FSK packets (#10911) 2025-09-27 15:55:14 -04:00
J. Nick Koston
1af6432c31 Merge branch 'integration' into memory_api 2025-09-27 13:59:32 -05:00
J. Nick Koston
1e10ee8388 Merge branch 'make_captive_portal_captive' into integration 2025-09-27 13:59:27 -05:00
J. Nick Koston
ddd004985b fix auto load 2025-09-27 13:52:49 -05:00
J. Nick Koston
f6cc548d19 fix auto load 2025-09-27 13:52:38 -05:00
J. Nick Koston
4fa9c00158 Merge branch 'make_captive_portal_captive' into memory_api 2025-09-27 13:46:42 -05:00
J. Nick Koston
42c6a3b878 Merge branch 'integration' into memory_api 2025-09-27 13:46:33 -05:00
J. Nick Koston
d418b8d4d6 Merge branch 'imporv_name' into integration 2025-09-27 13:46:21 -05:00
J. Nick Koston
f387e7690c nesting 2025-09-27 13:46:12 -05:00
J. Nick Koston
7e4cfe369d make bot happy 2025-09-27 13:45:12 -05:00
J. Nick Koston
c17e38e58f order matters 2025-09-27 13:39:03 -05:00
J. Nick Koston
7612944616 tidy, i ts needed for arudino 2025-09-27 13:35:49 -05:00
J. Nick Koston
5841dc58a9 Merge branch 'integration' into memory_api 2025-09-27 13:32:55 -05:00
J. Nick Koston
17142239e0 Merge branch 'make_captive_portal_captive' into integration 2025-09-27 13:32:50 -05:00
J. Nick Koston
edea7c18ba fix existing code tidy is comlpaining about 2025-09-27 13:32:41 -05:00
J. Nick Koston
9e6a589ee4 Merge branch 'integration' into memory_api 2025-09-27 13:22:15 -05:00
J. Nick Koston
163301f7d8 Merge branch 'make_captive_portal_captive' into integration 2025-09-27 13:22:11 -05:00
J. Nick Koston
d66fd678c2 simple 2025-09-27 13:20:58 -05:00
J. Nick Koston
e5908389aa tidy 2025-09-27 13:19:23 -05:00
J. Nick Koston
10c4d3396e Merge branch 'make_captive_portal_captive' into memory_api 2025-09-27 13:13:05 -05:00
J. Nick Koston
b525b446e7 Merge branch 'make_captive_portal_captive' into integration 2025-09-27 13:13:01 -05:00
J. Nick Koston
89f41833d8 remove debugging 2025-09-27 13:11:50 -05:00
J. Nick Koston
c787495273 Merge branch 'integration' into memory_api 2025-09-27 13:09:45 -05:00
J. Nick Koston
b4ee4e4256 Merge branch 'make_captive_portal_captive' into integration 2025-09-27 13:09:17 -05:00
J. Nick Koston
cba69e6a36 preen 2025-09-27 13:09:09 -05:00
J. Nick Koston
3ab362214b preen 2025-09-27 13:09:06 -05:00
J. Nick Koston
f3fd86a50d Merge branch 'integration' into memory_api 2025-09-27 13:07:38 -05:00
J. Nick Koston
21c3a288a7 Merge branch 'make_captive_portal_captive' into integration 2025-09-27 13:07:32 -05:00
J. Nick Koston
cf650708d2 preen 2025-09-27 13:05:42 -05:00
J. Nick Koston
45a8b641b9 Merge branch 'integration' into memory_api 2025-09-27 13:04:20 -05:00
J. Nick Koston
2820322a0e Merge branch 'make_captive_portal_captive' into integration 2025-09-27 13:04:14 -05:00
J. Nick Koston
72c1830b9b preen 2025-09-27 12:49:08 -05:00
J. Nick Koston
29943bfef1 preen 2025-09-27 12:48:09 -05:00
J. Nick Koston
0356081961 make it captive 2025-09-27 12:47:00 -05:00
J. Nick Koston
6b72736d5e wip 2025-09-27 12:32:24 -05:00
J. Nick Koston
aed6fa14f0 make_captive_portal_captive 2025-09-27 12:23:45 -05:00
J. Nick Koston
3aec19a4a6 Merge branch 'integration' into memory_api 2025-09-27 11:15:54 -05:00
J. Nick Koston
b86b186188 Merge branch 'imporv_name' into memory_api 2025-09-27 11:10:16 -05:00
J. Nick Koston
6fc481a768 Merge branch 'imporv_name' into integration 2025-09-27 11:10:12 -05:00
J. Nick Koston
a9a5cef281 preen 2025-09-27 11:09:59 -05:00
J. Nick Koston
75adceb027 Merge branch 'imporv_name' into memory_api 2025-09-27 11:09:25 -05:00
J. Nick Koston
d897820dbf Merge branch 'imporv_name' into integration 2025-09-27 11:09:21 -05:00
J. Nick Koston
e6ca3afd56 preen 2025-09-27 11:09:10 -05:00
J. Nick Koston
3c06dda9f0 Merge branch 'integration' into memory_api 2025-09-27 10:54:33 -05:00
J. Nick Koston
b6810d4d67 Merge remote-tracking branch 'upstream/tracker_vv' into integration 2025-09-27 10:54:25 -05:00
J. Nick Koston
fa2abf2d19 Merge branch 'imporv_name' into integration 2025-09-27 10:54:19 -05:00
J. Nick Koston
bb986cfb6e [esp32_ble_tracker] Reduce gap_scan_result log verbosity to VV 2025-09-27 10:53:50 -05:00
J. Nick Koston
7aa0815cd2 imporv_name 2025-09-27 10:51:15 -05:00
J. Nick Koston
d51f1e0f0e Merge branch 'ota_password_block' into integration 2025-09-27 09:29:30 -05:00
J. Nick Koston
08cf92bec7 Merge branch 'ota_password_block' into memory_api 2025-09-27 09:29:15 -05:00
J. Nick Koston
b6e8eece18 Merge branch 'integration' into memory_api 2025-09-27 09:29:09 -05:00
J. Nick Koston
0e7112bcfb Merge remote-tracking branch 'upstream/dev' into integration 2025-09-27 09:29:03 -05:00
J. Nick Koston
e4460bc802 preen 2025-09-27 09:25:32 -05:00
J. Nick Koston
61a11547ca [esp32_improv] Fix crashes from uninitialized pointers and missing null checks (#10902) 2025-09-27 09:24:17 -05:00
J. Nick Koston
ceb1dcba40 fix 2025-09-27 02:04:18 -05:00
J. Nick Koston
8b98ed16e9 error 2025-09-27 01:52:34 -05:00
J. Nick Koston
91adbc2466 preen 2025-09-27 01:39:56 -05:00
J. Nick Koston
603bde05e7 preen 2025-09-27 01:11:30 -05:00
J. Nick Koston
5abde23432 merge 2025-09-27 01:08:10 -05:00
J. Nick Koston
9cdd4bc555 preen 2025-09-27 00:15:57 -05:00
J. Nick Koston
c526873d71 Merge branch 'integration' into memory_api 2025-09-27 00:04:03 -05:00
J. Nick Koston
b092c33e92 Merge remote-tracking branch 'upstream/dev' into integration 2025-09-27 00:03:57 -05:00
J. Nick Koston
93ca48d9aa stack it 2025-09-27 00:00:00 -05:00
J. Nick Koston
9875e96b13 stack it 2025-09-26 23:56:11 -05:00
J. Nick Koston
c789fbf9f3 stack it 2025-09-26 23:54:21 -05:00
J. Nick Koston
dba680a748 stack it 2025-09-26 23:52:48 -05:00
J. Nick Koston
20cbc48ad4 stack it 2025-09-26 23:45:56 -05:00
J. Nick Koston
7e8de7c92c stack it 2025-09-26 23:44:24 -05:00
J. Nick Koston
5fb99e9013 stack it 2025-09-26 23:42:58 -05:00
J. Nick Koston
2d6669068f stack it 2025-09-26 23:41:40 -05:00
J. Nick Koston
e5868a79a2 stack it 2025-09-26 23:40:50 -05:00
J. Nick Koston
6430ae80cf stack it 2025-09-26 23:38:13 -05:00
J. Nick Koston
9f421ca60c stack it 2025-09-26 23:32:02 -05:00
J. Nick Koston
a2d3e81c4e stack it 2025-09-26 23:29:09 -05:00
J. Nick Koston
d1d8efd5a2 stack it 2025-09-26 23:28:03 -05:00
J. Nick Koston
0fb3d7550e stack it 2025-09-26 23:27:04 -05:00
J. Nick Koston
e2c637cf48 stack it 2025-09-26 23:26:54 -05:00
J. Nick Koston
3b92c6630d stack it 2025-09-26 23:26:16 -05:00
J. Nick Koston
4b003389b8 stack it 2025-09-26 23:14:28 -05:00
J. Nick Koston
7251f7edec stack it 2025-09-26 23:13:21 -05:00
J. Nick Koston
abcc2d483b optimize 2025-09-26 22:33:41 -05:00
J. Nick Koston
3bec6efdc3 optimize 2025-09-26 22:10:41 -05:00
J. Nick Koston
e0f99e0596 optimize 2025-09-26 22:09:44 -05:00
J. Nick Koston
a08a99e3f4 optimize 2025-09-26 22:05:06 -05:00
J. Nick Koston
10c5a19503 optimize 2025-09-26 22:01:44 -05:00
J. Nick Koston
e7b9f17bbe optimize 2025-09-26 21:54:58 -05:00
J. Nick Koston
cc4c059429 optimize 2025-09-26 21:52:00 -05:00
J. Nick Koston
a12283ba35 optimize 2025-09-26 21:27:40 -05:00
J. Nick Koston
78333ef795 safe a write 2025-09-26 21:14:56 -05:00
J. Nick Koston
d4026f9333 Merge branch 'integration' into memory_api 2025-09-26 18:19:51 -05:00
J. Nick Koston
38c9cbd92d Merge branch 'ble_server_automations_conditional_compile' into integration 2025-09-26 18:19:34 -05:00
J. Nick Koston
581be5680e cond 2025-09-26 18:12:28 -05:00
J. Nick Koston
7e52eb5ee3 cond 2025-09-26 17:54:56 -05:00
J. Nick Koston
abf522bbb9 [ota] Add SHA256 password authentication with backward compatibility (#10809)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-26 17:50:27 -05:00
Patrick Van Oosterwijck
25fc16163b [ethernet] Fix Ethernet RMII capable variant validation (#10909) 2025-09-26 17:34:22 -05:00
dependabot[bot]
55593628ef Bump github/codeql-action from 3.30.4 to 3.30.5 (#10905)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-26 16:22:32 -05:00
dependabot[bot]
1f90d89731 Bump pyyaml from 6.0.2 to 6.0.3 (#10904)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-26 16:22:09 -05:00
J. Nick Koston
78f64d493c Merge branch 'integration' into memory_api 2025-09-26 16:17:40 -05:00
J. Nick Koston
5caf0a7a17 Merge branch 'platform_normalize_too_late' into integration 2025-09-26 16:17:33 -05:00
J. Nick Koston
ae2773a7a7 fixes 2025-09-26 16:14:43 -05:00
J. Nick Koston
f5bba6f8cc rename to workaround the test conflict 2025-09-26 16:13:38 -05:00
J. Nick Koston
b134f40201 [core] Fix platform component normalization happening too late in validation pipeline 2025-09-26 16:10:53 -05:00
J. Nick Koston
3f202c291a [core] Fix platform component normalization happening too late in validation pipeline 2025-09-26 16:10:04 -05:00
J. Nick Koston
7de2ed7658 [core] Fix platform component normalization happening too late in validation pipeline 2025-09-26 16:08:42 -05:00
J. Nick Koston
303b47cf00 [core] Fix platform component normalization happening too late in validation pipeline 2025-09-26 16:05:34 -05:00
J. Nick Koston
f4134f21ba Merge branch 'integration' into memory_api 2025-09-26 15:00:59 -05:00
J. Nick Koston
e94b3321c8 Merge branch 'improv_fix_crash' into integration 2025-09-26 15:00:52 -05:00
J. Nick Koston
886baab266 guard 2025-09-26 15:00:43 -05:00
J. Nick Koston
71f35c849d Merge branch 'integration' into memory_api 2025-09-26 14:27:10 -05:00
J. Nick Koston
44b673eafe Merge branch 'improv_fix_crash' into integration 2025-09-26 14:27:02 -05:00
J. Nick Koston
d1bd6492ad missing nullptr 2025-09-26 14:26:54 -05:00
J. Nick Koston
7136993f31 Merge branch 'integration' into memory_api 2025-09-26 12:36:43 -05:00
J. Nick Koston
21d7d27c7b Merge branch 'improv_fix_crash' into integration 2025-09-26 12:36:39 -05:00
J. Nick Koston
33ff0c59c4 [esp32_improv] Fix null pointer crashes and incorrect state advertising 2025-09-26 12:29:42 -05:00
J. Nick Koston
5ecdce9473 Merge branch 'integration' into memory_api 2025-09-26 10:32:23 -05:00
J. Nick Koston
63d690fb8d Merge branch 'event_emitter_vector' into integration 2025-09-26 10:32:13 -05:00
J. Nick Koston
2b0af0df84 preen 2025-09-26 10:32:05 -05:00
J. Nick Koston
70a0b4e1e4 Merge branch 'integration' into memory_api 2025-09-26 10:23:34 -05:00
J. Nick Koston
bbcdf140bb Merge branch 'event_emitter_vector' into integration 2025-09-26 10:23:28 -05:00
J. Nick Koston
a3f8173436 prefer this-> 2025-09-26 10:23:17 -05:00
J. Nick Koston
efe5057cc2 Merge branch 'integration' into memory_api 2025-09-26 10:18:10 -05:00
J. Nick Koston
285eb7a2e1 Merge branch 'event_emitter_vector' into integration 2025-09-26 10:17:59 -05:00
J. Nick Koston
4110d926dd preen 2025-09-26 10:17:48 -05:00
J. Nick Koston
fbf413690b Merge branch 'event_emitter_vector' into integration 2025-09-26 10:15:58 -05:00
J. Nick Koston
9ed99e52e2 Merge remote-tt racking branch 'upstream/ble_server_opt' into integration 2025-09-26 10:15:52 -05:00
J. Nick Koston
eeff69d50b [event_emitter] Replace unordered_map with vector - saves 2.6KB flash, 2.3x faster 2025-09-26 10:14:34 -05:00
J. Nick Koston
70685f2939 bot comments 2025-09-26 09:46:38 -05:00
J. Nick Koston
fb3ce6c783 bot comments 2025-09-26 09:43:36 -05:00
J. Nick Koston
75b9b56627 Merge branch 'integration' into memory_api 2025-09-26 09:15:34 -05:00
J. Nick Koston
8275b54594 Merge branch 'ble_server_opt' into integration 2025-09-26 09:15:26 -05:00
J. Nick Koston
baf09e2eed [esp32_ble_server] Optimize notification and action managers for typical use cases 2025-09-26 09:14:29 -05:00
J. Nick Koston
ba88187353 Merge branch 'integration' into memory_api 2025-09-26 00:13:24 -05:00
J. Nick Koston
cf6a33ab71 Merge branch 'esp32_ble_server_services_simple' into integration 2025-09-26 00:13:13 -05:00
J. Nick Koston
1eaa121ad2 [esp32_ble_server] Optimize service storage: 1KB flash savings, 84x-241x faster lookups 2025-09-26 00:04:05 -05:00
J. Nick Koston
91b2140916 Merge branch 'integration' into memory_api 2025-09-25 22:50:16 -05:00
J. Nick Koston
243695a1d3 Merge remote-tracking branch 'upstream/dev' into integration 2025-09-25 22:50:06 -05:00
J. Nick Koston
e9f78238d4 Merge branch 'sha256_ota' into memory_api 2025-09-25 20:36:24 -05:00
J. Nick Koston
bbe72ac738 Merge branch 'sha256_ota' into integration 2025-09-25 20:36:20 -05:00
J. Nick Koston
ba73061a4f random_bytes 2025-09-25 20:36:04 -05:00
Jesse Hills
f33819bb8e Add some more defines for dev/ci 2025-09-26 13:12:24 +12:00
J. Nick Koston
1560b8b8e2 [climate] Remove STL algorithm overhead in save_state() method (#10888) 2025-09-26 12:19:48 +12:00
J. Nick Koston
b26776fad4 [select] Remove STL algorithm overhead to reduce flash usage (#10887) 2025-09-26 12:19:06 +12:00
J. Nick Koston
875ada86b0 [web_server] Remove std::find_if overhead matching IDF implementation (#10889) 2025-09-26 12:14:16 +12:00
J. Nick Koston
195d1be4a9 [version] Reduce flash usage by optimizing string concatenation in setup() (#10890) 2025-09-26 12:12:39 +12:00
J. Nick Koston
2b12ff5874 [esp32_ble] Reduce RAM usage and firmware size by disabling unused GATT functionality (#10862) 2025-09-26 12:11:13 +12:00
J. Nick Koston
250b94d113 [text_sensor] Convert LOG_TEXT_SENSOR macro to function to reduce flash usage (#10884) 2025-09-26 12:10:31 +12:00
Jesse Hills
28199c1cf8 [stale] Clean up stale job (#10892) 2025-09-26 12:02:51 +12:00
Jesse Hills
eeb3ccaef7 Update stale bot rules (#10891) 2025-09-26 11:13:23 +12:00
Patrick Van Oosterwijck
460eb219ba [ethernet] Add LAN8670 PHY support (#10874)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-09-25 21:45:07 +00:00
J. Nick Koston
be696c40db Merge branch 'dev' into sha256_ota 2025-09-25 16:03:42 -05:00
Jonathan Swoboda
cef9cf49bf [htu21d] Fix I2C NACK issue and buffer overrun (#10801) 2025-09-25 15:54:38 -05:00
Jonathan Swoboda
28f09f9ed1 [dashboard] Fix progress bars on Windows (#10858) 2025-09-25 15:53:34 -05:00
J. Nick Koston
3eb502b328 Add sha256 support (#10882) 2025-09-26 08:53:21 +12:00
J. Nick Koston
3ce430985a Merge branch 'integration' into memory_api 2025-09-25 14:48:12 -05:00
J. Nick Koston
fa5245fcfc Merge branch 'version_text_sensor_flash' into integration 2025-09-25 14:48:02 -05:00
J. Nick Koston
c3266db03d [version] Reduce flash usage by optimizing string concatenation in setup() 2025-09-25 14:47:32 -05:00
dependabot[bot]
7af77d0f82 Bump ruff from 0.13.1 to 0.13.2 (#10885)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-09-25 19:39:14 +00:00
J. Nick Koston
24d034c674 Merge branch 'dependabot/pip/ruff-0.13.2' into memory_api 2025-09-25 14:37:14 -05:00
J. Nick Koston
d06175816c match pre-commit 2025-09-25 14:34:42 -05:00
dependabot[bot]
1c229947a8 Bump github/codeql-action from 3.30.3 to 3.30.4 (#10886)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-25 14:34:23 -05:00
J. Nick Koston
76a2725a25 Merge branch 'integration' into memory_api 2025-09-25 14:33:43 -05:00
J. Nick Koston
f7d617fabe Merge branch 'remove_std_find_web_server_like_we_did_for_idf' into integration 2025-09-25 14:33:36 -05:00
J. Nick Koston
55cc3a5646 Merge branch 'climate_stl_overhead' into integration 2025-09-25 14:33:31 -05:00
J. Nick Koston
829b6cfe6a review 2025-09-25 14:33:19 -05:00
J. Nick Koston
f62e66e52b [web_server] Remove std::find_if overhead matching IDF implementation 2025-09-25 14:31:08 -05:00
J. Nick Koston
a4af23ebe4 Merge branch 'integration' into memory_api 2025-09-25 14:24:58 -05:00
J. Nick Koston
7b24e10da0 Merge branch 'climate_stl_overhead' into integration 2025-09-25 14:24:53 -05:00
J. Nick Koston
1da9345af0 [climate] Remove STL algorithm overhead in save_state() method 2025-09-25 14:24:25 -05:00
J. Nick Koston
2d395d1f8d Merge branch 'integration' into memory_api 2025-09-25 14:20:58 -05:00
J. Nick Koston
a0bf1ba099 Merge branch 'select_stl_overhead' into integration 2025-09-25 14:20:51 -05:00
J. Nick Koston
62a466c013 [select] Remove STL algorithm overhead to reduce flash usage 2025-09-25 14:20:05 -05:00
dependabot[bot]
a4991a1d96 Bump ruff from 0.13.1 to 0.13.2
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.13.1 to 0.13.2.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.13.1...0.13.2)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.13.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-25 19:01:29 +00:00
J. Nick Koston
dadc557b01 Merge branch 'integration' into memory_api 2025-09-25 11:09:51 -05:00
J. Nick Koston
0ff72b8d42 Merge branch 'log_text_sensor' into integration 2025-09-25 11:09:46 -05:00
J. Nick Koston
f9c494ad9f Update esphome/components/text_sensor/text_sensor.cpp 2025-09-25 11:09:32 -05:00
J. Nick Koston
56c16e6893 [text_sensor] Convert LOG_TEXT_SENSOR macro to function to reduce flash usage 2025-09-25 11:08:45 -05:00
J. Nick Koston
c5062dab55 Merge branch 'integration' into memory_api 2025-09-25 10:56:43 -05:00
J. Nick Koston
9a0996567d Merge remote-tracking branch 'upstream/dev' into integration 2025-09-25 10:56:38 -05:00
Jonathan Swoboda
74f09a2b59 [core] Rename to clean-platform to clean-all (#10876) 2025-09-25 11:55:43 -04:00
J. Nick Koston
549626bee2 Fix flakey password auth failure integration test (#10883) 2025-09-25 11:39:56 -04:00
J. Nick Koston
a09ca274c3 Merge branch 'sha256_ota' into memory_api 2025-09-25 10:32:23 -05:00
J. Nick Koston
aa5ca91731 Merge branch 'sha256_ota' into integration 2025-09-25 10:32:16 -05:00
J. Nick Koston
8a620ccac0 Merge branch 'sha256' into sha256_ota 2025-09-25 10:32:06 -05:00
J. Nick Koston
640d98bb6f address review comments 2025-09-25 10:31:42 -05:00
Jonathan Swoboda
65a1d2b2ff [scd30] Fix temp offset (#10847) 2025-09-25 09:13:27 -05:00
J. Nick Koston
136c95656c codeowners 2025-09-25 08:57:27 -05:00
J. Nick Koston
2bc1cc2ae7 Add sha256 support
This is a breakout from https://github.com/esphome/esphome/pull/10809
2025-09-25 08:55:43 -05:00
J. Nick Koston
7899d4256c Add sha256 support
This is a breakout from https://github.com/esphome/esphome/pull/10809
2025-09-25 08:54:52 -05:00
J. Nick Koston
6a8c80a0f0 Merge remote-tracking branch 'upstream/dev' into sha256_ota 2025-09-25 08:53:57 -05:00
Antoine Lépée
f7ed127182 Add WTS01 temperature sensor component (#8539)
Co-authored-by: Antoine Lépée <alepee@MacBook-Pro-de-Antoine.local>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
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-09-25 13:38:31 +00:00
Jesse Hills
44767c32cf Pin SHA for github actions (#10879) 2025-09-25 08:08:16 -05:00
Jesse Hills
0cc03dfe32 [json] Parsing json without a lambda (#10838) 2025-09-25 16:35:19 +12:00
J. Nick Koston
97b59f7775 Merge branch 'integration' into memory_api 2025-09-24 22:21:00 -05:00
J. Nick Koston
fe1991e56e Merge remote-tracking branch 'upstream/dev' into integration 2025-09-24 22:20:55 -05:00
J. Nick Koston
1922b7b3ed [api] Make password and encryption mutually exclusive, add deprecation warning for password auth (#10871) 2025-09-24 22:20:35 -05:00
J. Nick Koston
8c894e76e7 Merge branch 'integration' into memory_api 2025-09-24 22:07:52 -05:00
J. Nick Koston
58b60c2dca Merge remote-tracking branch 'upstream/dev' into integration 2025-09-24 22:07:46 -05:00
J. Nick Koston
90ffdfd650 Merge remote-tracking branch 'upstream/dev' into memory_api 2025-09-24 22:07:31 -05:00
J. Nick Koston
50b479b8f1 Merge branch 'integration' into memory_api 2025-09-24 21:20:52 -05:00
J. Nick Koston
7a12d3e807 Merge branch 'disable_gattx_not_used' into integration 2025-09-24 21:20:44 -05:00
J. Nick Koston
e177905bde more 2025-09-24 21:20:29 -05:00
Michael Hansen
f22143f090 Add external wake word message (#10850) 2025-09-24 19:08:29 -05:00
dependabot[bot]
be92903a6f Bump actions/cache from 4.2.4 to 4.3.0 (#10868)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-24 19:06:31 -05:00
dependabot[bot]
538941b3fd Bump actions/cache from 4.2.4 to 4.3.0 in /.github/actions/restore-python (#10869)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-24 19:06:18 -05:00
dependabot[bot]
ce8ac8b89d Bump aioesphomeapi from 41.9.1 to 41.10.0 (#10872)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-24 23:11:53 +00:00
J. Nick Koston
8abdaceb51 Merge branch 'integration' into memory_api 2025-09-24 17:41:33 -05:00
J. Nick Koston
646f9375cd Merge branch 'disable_gattx_not_used' into integration 2025-09-24 17:41:26 -05:00
J. Nick Koston
5e94b5e997 missing gattc guard 2025-09-24 17:41:11 -05:00
J. Nick Koston
20bc9da534 Merge branch 'integration' into memory_api 2025-09-24 11:53:14 -05:00
J. Nick Koston
5ae4392285 Merge branch 'disable_gattx_not_used' into integration 2025-09-24 11:53:09 -05:00
J. Nick Koston
a71c04b4b1 [esp32_ble] Automatically disable unused GATT functionality to save RAM 2025-09-24 11:47:05 -05:00
J. Nick Koston
b91ae29142 Merge branch 'integration' into memory_api 2025-09-24 09:22:37 -05:00
J. Nick Koston
100ea930b8 Merge branch 'dev' into integration 2025-09-24 09:22:32 -05:00
Stuart Parmenter
6d0f134ff1 Set color_order to RGB for the Waveshare ESP32-S3-TOUCH-LCD-4.3 and ESP32-S3-TOUCH-LCD-7-800X480 (#10835) 2025-09-24 08:59:16 -05:00
J. Nick Koston
11ccf0e591 [usb_host] Prevent USB data corruption from missed events (#10859) 2025-09-24 08:58:42 -05:00
J. Nick Koston
42525b981e Merge branch 'integration' into memory_api 2025-09-23 23:42:09 -05:00
J. Nick Koston
d9b7de1e05 Merge branch 'usb_host_blocking_fix' into integration 2025-09-23 23:41:59 -05:00
J. Nick Koston
daf45d6117 Merge remote-tracking branch 'upstream/dev' into integration 2025-09-23 23:41:50 -05:00
J. Nick Koston
90921348e9 cleanup 2025-09-23 23:08:17 -05:00
J. Nick Koston
07e5ce78eb simplify 2025-09-23 23:04:20 -05:00
J. Nick Koston
dca79872bf simplify 2025-09-23 23:03:25 -05:00
J. Nick Koston
af031530ce remove debug 2025-09-23 22:48:52 -05:00
J. Nick Koston
b9a5c57b77 preen 2025-09-23 22:47:17 -05:00
J. Nick Koston
13911933a9 Merge branch 'usb_host_blocking_fix' of https://github.com/esphome/esphome into usb_host_blocking_fix 2025-09-23 22:45:32 -05:00
J. Nick Koston
6403c6ee64 preen 2025-09-23 22:45:30 -05:00
J. Nick Koston
1e2785e387 Update esphome/components/usb_host/usb_host_client.cpp 2025-09-23 22:45:16 -05:00
J. Nick Koston
7fbc7e3c37 lock free 2025-09-23 22:41:43 -05:00
J. Nick Koston
5f17a95f2e lock free 2025-09-23 22:37:02 -05:00
J. Nick Koston
9f2f33fc89 lock free 2025-09-23 22:36:48 -05:00
J. Nick Koston
7388a2c9a3 ato 2025-09-23 22:22:44 -05:00
J. Nick Koston
6ba720d126 ato 2025-09-23 22:21:44 -05:00
J. Nick Koston
efc0d86aa6 ato 2025-09-23 22:18:43 -05:00
J. Nick Koston
971931b877 ato 2025-09-23 22:15:53 -05:00
J. Nick Koston
fdb2e0b247 ato 2025-09-23 22:15:36 -05:00
J. Nick Koston
0b5964053e ato 2025-09-23 22:13:42 -05:00
J. Nick Koston
4d64a05334 ato 2025-09-23 22:12:59 -05:00
J. Nick Koston
02b144c2e5 fix 2025-09-23 22:02:03 -05:00
J. Nick Koston
fb9334e5ba fix 2025-09-23 21:59:38 -05:00
J. Nick Koston
d5ad9dc0fb fix 2025-09-23 21:58:01 -05:00
J. Nick Koston
c08c0c111a fix 2025-09-23 21:56:22 -05:00
J. Nick Koston
70e89f79db fix 2025-09-23 21:54:33 -05:00
J. Nick Koston
0370a3061d fix 2025-09-23 21:41:48 -05:00
J. Nick Koston
0ed6ba9afa wip 2025-09-23 21:37:07 -05:00
J. Nick Koston
4699e56832 wip 2025-09-23 21:28:14 -05:00
J. Nick Koston
ce784299d8 wip 2025-09-23 21:23:58 -05:00
J. Nick Koston
adfacdf1b7 [api] Consolidate authentication checks to reduce function call overhead (#10852) 2025-09-23 19:43:55 -05:00
J. Nick Koston
f8226cd481 [esp32_ble] Remove Arduino-specific BLE limitations and SplitDefaults (#10780) 2025-09-23 19:42:46 -05:00
J. Nick Koston
9ac0f4aa4d Merge branch 'integration' into memory_api 2025-09-23 17:59:18 -05:00
J. Nick Koston
fe5dbfa268 Merge remote-tracking branch 'upstream/auth_connection_checks_dry' into integration 2025-09-23 17:59:11 -05:00
J. Nick Koston
d87c212cf3 Merge remote-tracking branch 'upstream/dev' into integration 2025-09-23 17:59:03 -05:00
J. Nick Koston
50c45b8a20 Merge branch 'dev' into auth_connection_checks_dry 2025-09-23 17:58:45 -05:00
Jesse Hills
63326cbd6d [api] Rename HomeassistantServiceResponse to HomeassistantActionRequest (#10839)
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: Keith Burzinski <kbx81x@gmail.com>
2025-09-23 17:58:24 -05:00
J. Nick Koston
093e70ceb8 Merge branch 'integration' into memory_api 2025-09-23 17:44:51 -05:00
J. Nick Koston
3f5d51bf85 Merge remote-tracking branch 'upstream/dev' into integration 2025-09-23 17:44:34 -05:00
J. Nick Koston
d0d7abb542 Implement zero-copy for strings in base API calls (#10851) 2025-09-23 16:15:28 -05:00
dependabot[bot]
cd7922faaf Bump aioesphomeapi from 41.9.0 to 41.9.1 (#10857)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-23 20:58:49 +00:00
J. Nick Koston
7100d65f14 Merge remote-tracking branch 'upstream/core_api_no_allocate' into memory_api 2025-09-23 15:47:08 -05:00
J. Nick Koston
92539c288a Merge remote-tracking branch 'upstream/core_api_no_allocate' into integration 2025-09-23 15:46:58 -05:00
J. Nick Koston
15dc83d7c5 Merge branch 'dev' into core_api_no_allocate 2025-09-23 15:13:29 -05:00
J. Nick Koston
365e3afa9b Implement zero-copy API for zwave_proxy (#10836)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-09-23 20:12:54 +00:00
dependabot[bot]
e9c2e211ef Bump aioesphomeapi from 41.8.0 to 41.9.0 (#10855)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-23 20:09:04 +00:00
J. Nick Koston
886cca1095 Merge branch 'integration' into memory_api 2025-09-23 15:05:44 -05:00
J. Nick Koston
14463c5f5b Merge remote-tracking branch 'upstream/dev' into integration 2025-09-23 15:05:30 -05:00
J. Nick Koston
d28d4d449b Merge branch 'dev' into core_api_no_allocate 2025-09-23 14:33:00 -05:00
J. Nick Koston
afda9500bf [zwave_proxy] Fix race condition sending zero home ID on reboot (#10848)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-09-23 19:21:49 +00:00
dependabot[bot]
bc7fc8df18 Bump aioesphomeapi from 41.7.0 to 41.8.0 (#10853)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-23 14:19:43 -05:00
J. Nick Koston
2f8a4d0caa [api] Implement zero-copy API for bluetooth_proxy writes (#10840) 2025-09-23 13:48:57 -05:00
J. Nick Koston
a7ee7b962e [wifi] Unify ESP32 WiFi implementation to use ESP-IDF driver (#10849) 2025-09-23 12:15:12 -05:00
J. Nick Koston
7d8c97ac3b Merge branch 'integration' into memory_api 2025-09-23 11:52:10 -05:00
J. Nick Koston
34bc2ddebb Merge branch 'auth_connection_checks_dry' into integration 2025-09-23 11:52:05 -05:00
J. Nick Koston
43cfdb7919 Reduce duplicate code in API to check auth and connection 2025-09-23 11:47:38 -05:00
Jonathan Swoboda
3cb2a4569c [core] Add a clean-platform option (#10831) 2025-09-23 12:41:25 -04:00
J. Nick Koston
9984cfc039 Merge branch 'integration' into memory_api 2025-09-23 11:30:15 -05:00
J. Nick Koston
b8f8035461 Merge branch 'core_api_no_allocate' into integration 2025-09-23 11:30:08 -05:00
J. Nick Koston
40271f5a30 wip 2025-09-23 11:23:09 -05:00
J. Nick Koston
2a8c9de3a6 Merge remote-tracking branch 'upstream/dev' into core_api_no_allocate 2025-09-23 11:19:47 -05:00
J. Nick Koston
f3b685acf9 wip 2025-09-23 11:19:32 -05:00
J. Nick Koston
e368f4782d cleanup 2025-09-23 11:18:03 -05:00
J. Nick Koston
ed62cc22ad preen 2025-09-23 11:08:41 -05:00
J. Nick Koston
288b70669d Merge branch 'integration' into memory_api 2025-09-23 10:14:05 -05:00
J. Nick Koston
92d16122e9 Merge branch 'sha256_ota' into integration 2025-09-23 10:14:00 -05:00
J. Nick Koston
f42b523fd9 dry 2025-09-23 09:54:39 -05:00
J. Nick Koston
174cdac5e1 dry 2025-09-23 09:49:42 -05:00
J. Nick Koston
7ac0f1c9a2 dry 2025-09-23 09:49:03 -05:00
J. Nick Koston
106f8e6804 dry 2025-09-23 09:48:36 -05:00
J. Nick Koston
307ad1c18b reduce magic numbers 2025-09-23 09:46:58 -05:00
J. Nick Koston
7e273879b5 reduce magic numbers 2025-09-23 09:45:02 -05:00
Jesse Hills
3b20969171 [core] Add typing to some core files (#10843) 2025-09-23 09:32:13 -05:00
Jonathan Swoboda
3b40172073 [libretiny] Fix lib_ignore handling and ignore incompatible libraries (#10846) 2025-09-23 10:21:19 -04:00
J. Nick Koston
58add6d365 Merge branch 'integration' into memory_api 2025-09-23 09:17:25 -05:00
J. Nick Koston
6e7718a63e Merge branch 'remove-esp32-arduino-wifi-driver' into integration 2025-09-23 09:17:15 -05:00
J. Nick Koston
1ffa10c28f Merge branch 'remove-esp32-arduino-wifi-driver' into memory_api 2025-09-23 09:16:55 -05:00
J. Nick Koston
aa687be49d Merge branch 'integration' into memory_api 2025-09-23 09:11:09 -05:00
J. Nick Koston
f77191c789 Merge remote-tracking branch 'swoboda1337/libretiny_lib' into integration 2025-09-23 09:11:04 -05:00
J. Nick Koston
13c0aa1ba8 [wifi] Unify ESP32 WiFi implementation to use ESP-IDF driver 2025-09-23 08:53:11 -05:00
Jesse Hills
2e220fcca2 [camera-encoder] Use defines instead of build flags (#10824)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-09-23 08:44:43 -05:00
J. Nick Koston
c800e02ee8 Merge branch 'integration' into memory_api 2025-09-23 08:41:53 -05:00
J. Nick Koston
3133c320ae Merge branch 'remove_esp32_arduino_ble_limiations' into integration 2025-09-23 08:41:47 -05:00
J. Nick Koston
11b1f13646 Merge branch 'dev' into remove_esp32_arduino_ble_limiations 2025-09-23 08:36:06 -05:00
Jonathan Swoboda
373c2d31dd Fix lib_ignore handling and ingore some libraries on libretiny 2025-09-23 07:33:34 -04:00
J. Nick Koston
0e85cf7ed8 Merge branch 'integration' into memory_api 2025-09-23 00:42:34 -05:00
J. Nick Koston
81f822d275 Merge branch 'bluetooth_no_allocate' into integration 2025-09-23 00:42:26 -05:00
J. Nick Koston
94819fb946 add comments 2025-09-23 00:41:49 -05:00
J. Nick Koston
c0ea795348 Merge branch 'integration' into memory_api 2025-09-23 00:19:31 -05:00
J. Nick Koston
a41bd97883 Merge remote-tracking branch 'upstream/bluetooth_no_allocate' into integration 2025-09-23 00:19:24 -05:00
J. Nick Koston
f07034b161 Merge branch 'dev' into bluetooth_no_allocate 2025-09-23 00:18:23 -05:00
dependabot[bot]
56e8af79c3 Bump aioesphomeapi from 41.6.0 to 41.7.0 (#10841)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-23 00:18:13 -05:00
J. Nick Koston
af7fea3680 not string anymore 2025-09-22 23:49:32 -05:00
J. Nick Koston
85b5b859b5 Implement zero-copy API for bluetooth_proxy writes
This is the same as https://github.com/esphome/esphome/pull/10836 for Bluetooth proxy
writes. This avoids the copy since all the messages live on the stack anyways
and there are no lifetime concerns

Doing bluetooth first since there is a wider test case vs zwave
2025-09-22 23:44:09 -05:00
J. Nick Koston
6a91df841b Merge remote-tracking branch 'upstream/dev' into zwave_no_allocate 2025-09-22 23:35:49 -05:00
dependabot[bot]
25e9ec1782 Bump aioesphomeapi from 41.4.0 to 41.6.0 (#10833)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-09-22 23:06:11 -05:00
J. Nick Koston
1771c852af Pin ruamel.yaml.clib to 0.2.12 (#10837) 2025-09-22 23:01:37 -05:00
J. Nick Koston
8a54b6d76e fix dump 2025-09-22 22:43:56 -05:00
J. Nick Koston
cf7fad9c14 Implement zero-copy API for zwave_proxy 2025-09-22 22:37:57 -05:00
J. Nick Koston
d7bff38ad9 Implement zero-copy API for zwave_proxy 2025-09-22 22:30:30 -05:00
Nerdiy.de
8714a45a5c Fix incorrect factor for value calculation in MMC5603 component (#9925) 2025-09-22 21:48:34 -04:00
J. Nick Koston
ed5c0be283 Merge branch 'dev' into sha256_ota 2025-09-22 16:31:12 -06:00
J. Nick Koston
3d07a4a3c9 Merge branch 'integration' into memory_api 2025-09-22 16:23:34 -05:00
J. Nick Koston
fc55cfad0a Merge remote-tracking branch 'upstream/dev' into integration 2025-09-22 16:23:13 -05:00
Jesse Hills
5e94460608 [CI] Format files after sync (#10828) 2025-09-23 07:48:39 +12:00
brambo123
d302c0c600 [uart] Multiple ESP32 features and fixes (#8103)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
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-09-22 12:15:19 -05:00
Sam
5c943d7c13 tuya: handle WIFI_SELECT and WIFI_RESET (#10822)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-09-22 17:05:41 +12:00
J. Nick Koston
d8f9c2da5d Merge branch 'dev' into sha256_ota 2025-09-21 22:40:35 -06:00
Javier Peletier
7629903afb [substitutions] implement !literal (#10785) 2025-09-22 16:32:59 +12:00
Javier Peletier
68eb4091b8 [substitutions] add missing safe globals tests (#10814) 2025-09-22 16:29:15 +12:00
J. Nick Koston
00849aadb7 Merge branch 'dev' into sha256_ota 2025-09-21 16:06:29 -06:00
J. Nick Koston
5062e7a0e1 Fix missing os import after merge collisions (#10823) 2025-09-21 15:59:44 -06:00
J. Nick Koston
1069ed0363 Merge branch 'sha256_ota' into memory_api 2025-09-21 15:57:03 -06:00
J. Nick Koston
7554465287 Merge branch 'sha256_ota' into integration 2025-09-21 15:56:58 -06:00
J. Nick Koston
6c26f75a77 preen 2025-09-21 15:56:05 -06:00
J. Nick Koston
0ab4f69a9c Merge branch 'integration' into memory_api 2025-09-21 15:53:38 -06:00
J. Nick Koston
5121b955e2 Merge branch 'sha256_ota' into integration 2025-09-21 15:53:31 -06:00
J. Nick Koston
b1f90fb78d preen 2025-09-21 15:53:23 -06:00
J. Nick Koston
199d575052 Merge branch 'integration' into memory_api 2025-09-21 15:46:50 -06:00
J. Nick Koston
95c159a9fc Merge branch 'sha256_ota' into integration 2025-09-21 15:46:41 -06:00
J. Nick Koston
ba5e995fc1 preen 2025-09-21 15:40:47 -06:00
J. Nick Koston
57be58baa0 preen 2025-09-21 15:37:45 -06:00
J. Nick Koston
67e847773d Merge branch 'dev' into sha256_ota 2025-09-21 15:37:11 -06:00
J. Nick Koston
0d67d2de60 preen 2025-09-21 15:36:27 -06:00
J. Nick Koston
0e9a1fc80d cleanup 2025-09-21 15:30:36 -06:00
J. Nick Koston
fe4a0c94cf reduce 2025-09-21 15:27:38 -06:00
J. Nick Koston
30bb640c89 Skip external component updates when running logs command (#10756)
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-09-21 21:15:49 +00:00
J. Nick Koston
fbb48c504f [esp32_improv] Disable loop by default until provisioning needed (#10764) 2025-09-22 09:08:55 +12:00
J. Nick Koston
440b0b5574 [tests] Add integration tests for oversized payload handling in API (#10788) 2025-09-22 09:07:47 +12:00
J. Nick Koston
c64d385fa6 [web_server] Reduce flash usage by eliminating lambda overhead in JSON generation (#10749) 2025-09-22 09:06:59 +12:00
J. Nick Koston
0432a10543 Add coverage for Path to str fix in #10807 (#10808) 2025-09-22 08:59:19 +12:00
J. Nick Koston
457399f3af preen 2025-09-21 12:23:49 -06:00
J. Nick Koston
f58ea07ac3 preen 2025-09-21 12:22:50 -06:00
J. Nick Koston
61d6034838 preen 2025-09-21 12:20:18 -06:00
J. Nick Koston
05685b41cd merge 2025-09-21 12:12:53 -06:00
J. Nick Koston
7d96cf66c6 Merge branch 'integration' into memory_api 2025-09-21 12:11:12 -06:00
J. Nick Koston
ebb23c5b24 Merge branch 'sha256_ota' into integration 2025-09-21 12:11:05 -06:00
J. Nick Koston
f86d9b0aa6 remove testing 2025-09-21 12:09:46 -06:00
J. Nick Koston
8bf908a88a Merge branch 'integration' into memory_api 2025-09-21 12:06:47 -06:00
J. Nick Koston
5e4d7525e8 Merge branch 'sha256_ota' into integration 2025-09-21 12:06:25 -06:00
J. Nick Koston
8ea13115a0 preen 2025-09-21 12:06:12 -06:00
J. Nick Koston
0272228ece preen 2025-09-21 12:02:41 -06:00
J. Nick Koston
991409d315 cleanup 2025-09-21 11:56:16 -06:00
J. Nick Koston
d5c067acfa preen 2025-09-21 11:53:37 -06:00
J. Nick Koston
85ca03345c Merge branch 'integration' into memory_api 2025-09-21 11:47:33 -06:00
J. Nick Koston
32d39b4dcd Merge branch 'sha256_ota' into integration 2025-09-21 11:47:25 -06:00
J. Nick Koston
9cbbb167db preen 2025-09-21 11:47:15 -06:00
J. Nick Koston
70bbe3b825 Merge branch 'integration' into memory_api 2025-09-21 11:39:44 -06:00
J. Nick Koston
d17a6181cf Merge branch 'sha256_ota' into integration 2025-09-21 11:39:39 -06:00
J. Nick Koston
d5b57384bf was overly complex 2025-09-21 11:39:25 -06:00
J. Nick Koston
5e9a5798bd cleanup 2025-09-21 11:30:05 -06:00
J. Nick Koston
863588d313 Merge branch 'integration' into memory_api 2025-09-21 11:25:51 -06:00
J. Nick Koston
35afd10022 Merge branch 'sha256_ota' into integration 2025-09-21 11:25:46 -06:00
J. Nick Koston
f85f5aae46 base it 2025-09-21 11:23:57 -06:00
J. Nick Koston
4729bc87fa [core] Fix TypeError in update-all command after Path migration (#10821) 2025-09-21 13:07:27 -04:00
J. Nick Koston
cd90fb2cf7 Merge branch 'integration' into memory_api 2025-09-21 11:06:50 -06:00
J. Nick Koston
46055afeea Merge remote-tracking branch 'upstream/fix_update_all_after_path_convert' into integration 2025-09-21 11:06:40 -06:00
J. Nick Koston
abc5604c1f Merge branch 'integration' into memory_api 2025-09-21 11:06:30 -06:00
J. Nick Koston
dcd50b232a Merge branch 'sha256_ota' into integration 2025-09-21 11:06:21 -06:00
J. Nick Koston
56be0dfc90 preen 2025-09-21 11:04:02 -06:00
J. Nick Koston
7ea680a802 [core] Fix TypeError in update-all command after Path migration 2025-09-21 11:00:49 -06:00
J. Nick Koston
f3ced331a6 no esp32 ard needed 2025-09-21 10:57:06 -06:00
J. Nick Koston
3aa7da60e6 fix libretiny 2025-09-21 10:56:08 -06:00
J. Nick Koston
ada1b00cad use evp interface 2025-09-21 10:44:09 -06:00
J. Nick Koston
d1fb3336f0 reen 2025-09-21 10:42:51 -06:00
J. Nick Koston
ee7e30eaa8 doh 2025-09-21 10:41:44 -06:00
J. Nick Koston
4cdeb3f547 sha256 for host 2025-09-21 10:40:26 -06:00
J. Nick Koston
93c444ee15 sha256 for host 2025-09-21 10:37:44 -06:00
J. Nick Koston
113fe6dfd5 sha256 for host 2025-09-21 10:35:20 -06:00
J. Nick Koston
e47cecc5f0 remove unreachable code 2025-09-21 10:28:09 -06:00
J. Nick Koston
233cc08dc6 remove unreachable code 2025-09-21 10:27:27 -06:00
J. Nick Koston
7d4a7d48ee remove unreachable code 2025-09-21 10:26:52 -06:00
J. Nick Koston
97bc627d41 preen 2025-09-21 10:25:48 -06:00
J. Nick Koston
0e71662158 preen 2025-09-21 10:18:27 -06:00
J. Nick Koston
69cad7b3c7 preen 2025-09-21 10:15:22 -06:00
J. Nick Koston
2aa0ebd1d2 preen 2025-09-21 10:14:40 -06:00
J. Nick Koston
0cae1f28b0 preen 2025-09-21 10:12:48 -06:00
J. Nick Koston
eee8b11119 preen 2025-09-21 10:09:35 -06:00
J. Nick Koston
17704f712e preen 2025-09-21 10:07:27 -06:00
J. Nick Koston
594c60a4a4 preen 2025-09-21 10:07:01 -06:00
J. Nick Koston
0d622fa268 cleanup 2025-09-21 09:56:29 -06:00
J. Nick Koston
0b0eb5d4bf cleanup 2025-09-21 09:56:22 -06:00
J. Nick Koston
e2fd5190c2 cleanup 2025-09-21 09:55:01 -06:00
J. Nick Koston
1d6c6c917a cleanup 2025-09-21 09:54:17 -06:00
J. Nick Koston
6c8b66df96 cleanup 2025-09-21 09:52:39 -06:00
J. Nick Koston
139577f96a cleanup 2025-09-21 09:49:25 -06:00
J. Nick Koston
0ddd1037ca cleanup 2025-09-21 09:05:40 -06:00
J. Nick Koston
a81985bfba cleanup 2025-09-21 09:01:07 -06:00
Jonathan Swoboda
e3b64103cc [sensirion] Fix warning (#10813) 2025-09-20 21:23:33 -05:00
J. Nick Koston
8da7705927 fix nrf52 2025-09-20 18:29:17 -06:00
J. Nick Koston
cebacfcc59 fix rp2040 2025-09-20 08:52:06 -06:00
J. Nick Koston
d7245ebde6 try to make it work on 8266 2025-09-20 07:55:53 -06:00
esphomebot
ebdcb3e4d9 Synchronise Device Classes from Home Assistant (#10803)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-09-20 13:09:21 +00:00
J. Nick Koston
f171afca62 move context to .h 2025-09-20 07:03:48 -06:00
J. Nick Koston
dfc161b618 preen 2025-09-19 22:54:36 -06:00
J. Nick Koston
e49cbac46a optimize 2025-09-19 22:51:14 -06:00
J. Nick Koston
e5fd5425c1 Merge branch 'integration' into memory_api 2025-09-19 22:44:34 -06:00
J. Nick Koston
8fc3ffdea9 Merge remote-tracking branch 'upstream/dev' into integration 2025-09-19 22:44:16 -06:00
J. Nick Koston
6810e87fa7 reorder 2025-09-19 22:35:18 -06:00
J. Nick Koston
f6b9f802e8 Merge branch 'dev' into sha256_ota 2025-09-19 19:12:19 -05:00
J. Nick Koston
971522574d [http_request] Fix Path object passed to C++ codegen (#10812) 2025-09-19 20:10:02 -04:00
J. Nick Koston
73e939dbbc [zephyr] Fix compilation after Path migration (#10811) 2025-09-19 20:09:32 -04:00
J. Nick Koston
f80dfa9be7 Merge remote-tracking branch 'upstream/sha256_ota' into sha256_ota 2025-09-19 17:00:41 -06:00
J. Nick Koston
110b364c1f make member 2025-09-19 17:00:23 -06:00
J. Nick Koston
acb5616334 make member 2025-09-19 17:00:03 -06:00
J. Nick Koston
2ce07d8aae Merge branch 'dev' into sha256_ota 2025-09-19 17:32:58 -05:00
J. Nick Koston
e41ca7e888 tidy 2025-09-19 16:31:58 -06:00
J. Nick Koston
4b6fbc2a1e preen 2025-09-19 15:56:40 -06:00
J. Nick Koston
0919669fc6 preen 2025-09-19 15:56:21 -06:00
J. Nick Koston
e721e8c203 preen 2025-09-19 15:54:17 -06:00
J. Nick Koston
6215199c1a codeowners 2025-09-19 15:51:52 -06:00
J. Nick Koston
46f05b34e5 preen 2025-09-19 15:45:38 -06:00
J. Nick Koston
8e1b620a49 Merge remote-tracking branch 'upstream/dev' into sha256_ota 2025-09-19 15:42:09 -06:00
dependabot[bot]
a96798ef98 Bump esptool from 5.0.2 to 5.1.0 (#10758)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-19 15:13:47 -06:00
dependabot[bot]
923e7049f1 Bump aioesphomeapi from 41.1.0 to 41.4.0 (#10805)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-19 15:04:43 -06:00
Paulus Schoutsen
26df542036 Fix esphome run (#10807) 2025-09-19 15:36:46 -05:00
J. Nick Koston
88a98cfeef Merge remote-tracking branch 'upstream/dev' into sha256_ota 2025-09-19 09:10:11 -06:00
Keith Burzinski
1ccec6950a [zwave_proxy] Send Home ID in DeviceInfoResponse (#10798)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: AlCalzone <d.griesel@gmx.net>
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-09-19 14:52:54 +00:00
dependabot[bot]
b3a122de3c Bump ruff from 0.13.0 to 0.13.1 (#10802)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-09-19 08:04:29 -06:00
Jesse Hills
9ea3643b74 [core] os.path -> Path (#10654)
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>
2025-09-19 12:59:48 +00:00
Jesse Hills
de617c85c7 Merge branch 'release' into dev 2025-09-19 20:47:37 +12:00
Jesse Hills
e47f4ef602 Merge pull request #10796 from esphome/bump-2025.9.1
2025.9.1
2025-09-19 20:46:53 +12:00
Keith Burzinski
9c201afe76 [api_protobuf.py] Use type appropriate for estimated_size (#10797) 2025-09-18 20:55:45 -05:00
J. Nick Koston
2bb64a189d [dashboard] Transfer DNS/mDNS cache from dashboard to CLI to avoid blocking (#10685) 2025-09-18 20:13:13 -05:00
Jesse Hills
9853a2e6ab [ektf2232] Rename rts_pin to reset_pin (#10720) 2025-09-18 18:41:23 -06:00
Jesse Hills
961be7fd12 Bump version to 2025.9.1 2025-09-19 11:52:10 +12:00
J. Nick Koston
a5a21f47d1 [gpio] Fix unused function warnings when compiling with log level below DEBUG (#10779) 2025-09-19 11:52:09 +12:00
J. Nick Koston
a06cd84974 [core] Fix ESP8266 mDNS compilation failure caused by incorrect coroutine priorities (#10773) 2025-09-19 11:52:09 +12:00
Subhash Chandra
e3703b43c1 [packet_transport] Refactor sensor/provider list handling to be idempotent (#10765) 2025-09-19 11:52:09 +12:00
J. Nick Koston
f6dc25c0ce [mqtt] Fix KeyError when MQTT logging configured without explicit level (#10774) 2025-09-19 11:52:09 +12:00
Keith Burzinski
fad0ec7793 [zwave_proxy] New component (#10762)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-09-18 15:43:14 -05:00
J. Nick Koston
8b765715d6 preen 2025-09-18 15:17:25 -05:00
J. Nick Koston
080fe6eae5 preen 2025-09-18 15:11:52 -05:00
J. Nick Koston
f15c83462c preen 2025-09-18 15:06:51 -05:00
J. Nick Koston
853d3ae331 preen 2025-09-18 14:46:49 -05:00
J. Nick Koston
bff257258e preen 2025-09-18 14:33:37 -05:00
J. Nick Koston
a302cec993 [libretiny] Optimize preferences memory usage by replacing vector with unique_ptr (#10731) 2025-09-18 05:25:29 -05:00
J. Nick Koston
6781da45cb [esp32] Optimize NVS preferences memory usage by replacing vector with unique_ptr (#10729) 2025-09-18 05:24:50 -05:00
J. Nick Koston
37d526f003 [gpio] Fix unused function warnings when compiling with log level below DEBUG (#10779) 2025-09-18 05:22:22 -05:00
J. Nick Koston
d74cfefeef [ethernet] Remove redundant Arduino framework version check (#10781) 2025-09-17 23:39:14 -05:00
J. Nick Koston
1ffb9d972a [core] Fix ESP8266 mDNS compilation failure caused by incorrect coroutine priorities (#10773) 2025-09-18 13:11:30 +12:00
Subhash Chandra
4e5339801b [packet_transport] Refactor sensor/provider list handling to be idempotent (#10765) 2025-09-18 00:14:31 +00:00
J. Nick Koston
55232c711a drop splitdefault as well 2025-09-17 17:48:50 -05:00
J. Nick Koston
f8d380cb7d Merge branch 'integration' into memory_api 2025-09-17 17:45:29 -05:00
J. Nick Koston
951559d9ef Merge branch 'arduino_ethernet_checks_remove' into integration 2025-09-17 17:45:22 -05:00
J. Nick Koston
455d2c2332 [ethernet] Remove redundant Arduino framework version check 2025-09-17 17:44:36 -05:00
J. Nick Koston
4031dc2305 Merge branch 'integration' into memory_api 2025-09-17 17:40:18 -05:00
J. Nick Koston
ebf120b587 Merge branch 'remove_esp32_arduino_ble_limiations' into integration 2025-09-17 17:40:11 -05:00
J. Nick Koston
f2c20c8ca8 [esp32_ble_tracker] Remove Arduino-specific BLE limitations now that Arduino uses IDF 2025-09-17 17:38:55 -05:00
J. Nick Koston
c69dde4454 Merge branch 'integration' into memory_api 2025-09-17 17:25:33 -05:00
J. Nick Koston
32e6d079d3 Merge remote-tracking branch 'upstream/dev' into integration 2025-09-17 17:25:21 -05:00
Jonathan Swoboda
b8cee477fe [esp32] Use arduino as an idf component (#10647)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-09-17 17:23:34 -05:00
J. Nick Koston
ff2df278d6 [api] Rename ConnectRequest/Response to AuthenticationRequest/Response (#10726) 2025-09-18 07:42:37 +12:00
J. Nick Koston
429e989b69 [core] Make StringRef convertToJson inline to save 250+ bytes flash (#10751) 2025-09-18 07:40:32 +12:00
Martin Weinelt
28541bdb1c Migrate to SPDX license specifier in pyproject.toml (#10768) 2025-09-18 07:38:18 +12:00
J. Nick Koston
11c595bb09 [mqtt] Fix KeyError when MQTT logging configured without explicit level (#10774) 2025-09-18 07:38:02 +12:00
dependabot[bot]
fd888eaa68 Bump aioesphomeapi from 40.2.1 to 41.1.0 (#10776)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-17 14:29:58 -05:00
Jesse Hills
3a233b2fd0 Merge branch 'release' into dev 2025-09-17 18:52:06 +12:00
Jesse Hills
d2df232706 Merge pull request #10763 from esphome/bump-2025.9.0
2025.9.0
2025-09-17 18:51:21 +12:00
J. Nick Koston
db9b1c36f6 Merge branch 'integration' into memory_api 2025-09-16 21:31:32 -05:00
J. Nick Koston
d8a11958c5 Merge branch 'improv_wait_for_start' into integration 2025-09-16 21:31:27 -05:00
J. Nick Koston
0794235159 [esp32_improv] Disable loop by default until provisioning needed 2025-09-16 21:27:08 -05:00
Jesse Hills
404e679e66 Bump version to 2025.9.0 2025-09-17 11:02:12 +12:00
Jesse Hills
4426bf6029 Merge branch 'beta' into dev 2025-09-17 10:50:48 +12:00
Jesse Hills
8d401ad05a Merge pull request #10761 from esphome/bump-2025.9.0b4
2025.9.0b4
2025-09-17 10:50:15 +12:00
Jesse Hills
e542816f7d Bump version to 2025.9.0b4 2025-09-17 09:22:54 +12:00
J. Nick Koston
12cadf0a04 [core] Fix clean build files to properly clear PlatformIO cache (#10754) 2025-09-17 09:22:54 +12:00
J. Nick Koston
adc3d3127d [wizard] Fix KeyError when running wizard with empty OTA password (#10753) 2025-09-17 09:22:54 +12:00
J. Nick Koston
61ab682099 Add additional coverage for util and writer (#10683) 2025-09-17 09:22:54 +12:00
J. Nick Koston
27fa18dcec [core] Fix clean build files to properly clear PlatformIO cache (#10754) 2025-09-17 08:09:35 +12:00
J. Nick Koston
22989592f0 [wizard] Fix KeyError when running wizard with empty OTA password (#10753) 2025-09-17 07:56:54 +12:00
dependabot[bot]
1f4b10f523 Bump pytest-mock from 3.15.0 to 3.15.1 (#10759)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-16 14:54:56 -05:00
J. Nick Koston
e700ce6c61 Merge branch 'integration' into memory_api 2025-09-16 12:18:27 -05:00
J. Nick Koston
c0306f3d89 Merge branch 'no_git_opts_log' into integration 2025-09-16 12:18:22 -05:00
J. Nick Koston
d249e54e8b cleanup, less mocking 2025-09-16 12:08:18 -05:00
J. Nick Koston
c74777098f cleaner 2025-09-16 12:05:35 -05:00
J. Nick Koston
1793b6a27b cleaner 2025-09-16 12:04:05 -05:00
J. Nick Koston
81cfc30f3a cleaner 2025-09-16 12:03:28 -05:00
J. Nick Koston
edd8fa8d6f cleaner 2025-09-16 12:02:57 -05:00
J. Nick Koston
452a12892e fix reg 2025-09-16 12:01:01 -05:00
J. Nick Koston
c39320c515 fixes 2025-09-16 11:57:10 -05:00
J. Nick Koston
586f24e02d fixes 2025-09-16 11:54:09 -05:00
J. Nick Koston
9be832a23c fixes 2025-09-16 11:51:55 -05:00
J. Nick Koston
7d87dbe641 fixes 2025-09-16 11:51:44 -05:00
J. Nick Koston
8e13335ff6 fixes 2025-09-16 11:49:36 -05:00
J. Nick Koston
4a04f9f0f0 Merge branch 'integration' into memory_api 2025-09-16 10:53:06 -05:00
J. Nick Koston
48356ab86d Merge branch 'fix_clean_build_files_not_removing_platformio_cache' into memory_api 2025-09-16 10:52:06 -05:00
J. Nick Koston
34da6d7c5c Merge branch 'fix_clean_build_files_not_removing_platformio_cache' into integration 2025-09-16 10:52:02 -05:00
J. Nick Koston
cb73396225 review 2025-09-16 10:51:50 -05:00
J. Nick Koston
6d1cec6112 review 2025-09-16 10:51:39 -05:00
J. Nick Koston
f1f0fc858c Merge branch 'integration' into memory_api 2025-09-16 10:50:10 -05:00
J. Nick Koston
db24cc231e Merge branch 'fix_clean_build_files_not_removing_platformio_cache' into integration 2025-09-16 10:50:06 -05:00
J. Nick Koston
bc73346f1f [core] Fix clean build files to properly clear PlatformIO cache 2025-09-16 10:49:05 -05:00
Jesse Hills
cbaf8d309b Merge branch 'beta' into dev 2025-09-17 00:17:01 +12:00
Jesse Hills
c05b7cca5e Merge pull request #10752 from esphome/bump-2025.9.0b3
2025.9.0b3
2025-09-17 00:15:06 +12:00
Jesse Hills
6ac395da6d Bump version to 2025.9.0b3 2025-09-16 20:35:23 +12:00
jokujossai
54616ae1b4 [ade7880] fix channel a voltage registry (#10750) 2025-09-16 20:35:23 +12:00
jokujossai
e33dcda907 [mqtt] fix publish payload length when payload contains null characters (#10744) 2025-09-16 20:35:23 +12:00
J. Nick Koston
04c1b90e57 [ethernet] Conditionally compile PHY-specific code to reduce flash usage (#10747) 2025-09-16 20:35:23 +12:00
J. Nick Koston
ddb8fedef7 [dashboard] Fix archive handler to properly delete build folders using correct path (#10724) 2025-09-16 20:35:23 +12:00
J. Nick Koston
04f4f79cb4 [select] Use const references to avoid unnecessary vector copies (#10741) 2025-09-16 20:35:23 +12:00
J. Nick Koston
8890071360 Add additional test coverage ahead of Path conversion (#10700) 2025-09-16 20:35:23 +12:00
J. Nick Koston
4b3a997a8e Improve coverage for various core modules (#10663) 2025-09-16 20:35:23 +12:00
jokujossai
660223e269 [ade7880] fix channel a voltage registry (#10750) 2025-09-16 17:00:22 +12:00
J. Nick Koston
b69e6f2152 Merge branch 'integration' into memory_api 2025-09-15 23:26:46 -05:00
J. Nick Koston
2741f4f88d Merge branch 'inline_stringref_convertToJson' into integration 2025-09-15 23:26:35 -05:00
J. Nick Koston
157ea2daa4 [core] Make StringRef convertToJson inline to save 250+ bytes flash 2025-09-15 23:25:41 -05:00
jokujossai
6d1de2106e [mqtt] fix publish payload length when payload contains null characters (#10744) 2025-09-16 15:28:36 +12:00
J. Nick Koston
f0bce77adc Merge branch 'integration' into memory_api 2025-09-15 22:01:30 -05:00
J. Nick Koston
7f94d82e45 Merge branch 'webserver_remove_lambas' into integration 2025-09-15 22:01:09 -05:00
J. Nick Koston
192e935ef2 preen 2025-09-15 21:47:18 -05:00
J. Nick Koston
bd11ffd395 preen 2025-09-15 21:47:15 -05:00
J. Nick Koston
7aae946678 cleanup 2025-09-15 21:44:50 -05:00
J. Nick Koston
7549d031fd cleanup 2025-09-15 21:40:30 -05:00
J. Nick Koston
b0b207eddb cleanup 2025-09-15 21:34:19 -05:00
J. Nick Koston
7fe92085b4 preen 2025-09-15 21:28:53 -05:00
J. Nick Koston
35f50b710e preen 2025-09-15 21:28:42 -05:00
J. Nick Koston
0091a2b92b Merge branch 'integration' into memory_api 2025-09-15 21:20:26 -05:00
J. Nick Koston
5497e2d34e Merge branch 'webserver_remove_lambas' into integration 2025-09-15 21:20:17 -05:00
J. Nick Koston
703bb0c9c6 cleanup 2025-09-15 21:18:52 -05:00
J. Nick Koston
5acea1252b Merge branch 'webserver_remove_lambas' into memory_api 2025-09-15 20:55:41 -05:00
J. Nick Koston
e16042373c Merge branch 'webserver_remove_lambas' into integration 2025-09-15 20:55:36 -05:00
J. Nick Koston
290c2e17f5 simplier 2025-09-15 20:49:22 -05:00
DT-art1
90e33306f1 [const] Move CONF_CLEAR to const.py (#10742) 2025-09-16 13:24:23 +12:00
J. Nick Koston
f37c833c38 Merge branch 'integration' into memory_api 2025-09-15 19:01:16 -05:00
J. Nick Koston
bf7b5309b8 Merge branch 'webserver_remove_lambas' into integration 2025-09-15 19:01:09 -05:00
J. Nick Koston
c203f61e6b more ArduinoJson false positives 2025-09-15 18:58:07 -05:00
J. Nick Koston
f3ac21b3b4 [ethernet] Conditionally compile PHY-specific code to reduce flash usage (#10747) 2025-09-15 23:46:07 +00:00
J. Nick Koston
cd15a43d77 Merge branch 'integration' into memory_api 2025-09-15 18:45:20 -05:00
J. Nick Koston
572079f6d3 Merge branch 'webserver_remove_lambas' into integration 2025-09-15 18:45:14 -05:00
J. Nick Koston
044aeaa063 preen 2025-09-15 18:39:14 -05:00
J. Nick Koston
c1a90dad9e get rid of lambdas 2025-09-15 18:37:40 -05:00
J. Nick Koston
4859fe67eb [dashboard] Fix archive handler to properly delete build folders using correct path (#10724) 2025-09-16 11:04:35 +12:00
J. Nick Koston
beb80a2bb6 Merge branch 'integration' into memory_api 2025-09-15 18:00:13 -05:00
J. Nick Koston
f5f93db4bb Merge branch 'ethernet_cond_compile' into integration 2025-09-15 17:59:55 -05:00
J. Nick Koston
877ba13f4f [ethernet] Conditionally compile PHY-specific code to reduce flash usage 2025-09-15 17:57:46 -05:00
J. Nick Koston
64f267914e Merge branch 'integration' into memory_api 2025-09-15 17:45:01 -05:00
J. Nick Koston
c3736da9fb Merge branch 'archive_bug' into integration 2025-09-15 17:44:54 -05:00
J. Nick Koston
f91a6979b4 add more coverage to make sure we are more careful about deletes 2025-09-15 17:37:35 -05:00
J. Nick Koston
f3c156ca57 add more coverage to make sure we are more careful about deletes 2025-09-15 17:29:51 -05:00
J. Nick Koston
50f22a362f cleanup 2025-09-15 17:28:00 -05:00
J. Nick Koston
601c792913 cleanup 2025-09-15 17:25:56 -05:00
J. Nick Koston
62b713a04c cleanup 2025-09-15 17:25:23 -05:00
J. Nick Koston
55684d079e cleanup 2025-09-15 17:24:58 -05:00
J. Nick Koston
f7bfbb619d cleanup 2025-09-15 17:24:45 -05:00
J. Nick Koston
47d24edd0e cleanup 2025-09-15 17:23:01 -05:00
J. Nick Koston
fa00e07e10 fix 2025-09-15 17:19:28 -05:00
J. Nick Koston
313851f4df Merge remote-tracking branch 'upstream/dev' into archive_bug 2025-09-15 17:18:19 -05:00
J. Nick Koston
a723673dcc [select] Use const references to avoid unnecessary vector copies (#10741) 2025-09-16 09:16:26 +12:00
Jesse Hills
612fb4cc3c [CI] Check esp32 boards file is up to date (#10730) 2025-09-15 15:03:02 -05:00
J. Nick Koston
e02f2f625f Merge branch 'integration' into memory_api 2025-09-15 12:16:10 -05:00
J. Nick Koston
b01ef008bb Merge branch 'select_const_ref' into integration 2025-09-15 12:16:04 -05:00
J. Nick Koston
d8385780f1 [select] Use const references to avoid unnecessary vector copies 2025-09-15 12:15:29 -05:00
J. Nick Koston
d005408f71 Merge branch 'integration' into memory_api 2025-09-15 11:53:58 -05:00
J. Nick Koston
fd99a50f19 Merge remote-tracking branch 'upstream/dev' into integration 2025-09-15 11:53:50 -05:00
J. Nick Koston
5fac67d195 [json] Only compile SpiRamAllocator when PSRAM is enabled (#10728) 2025-09-15 11:50:11 -05:00
Jesse Hills
d671862e9a Merge branch 'beta' into dev 2025-09-15 18:29:26 +12:00
Jesse Hills
2a4ab6a811 Merge pull request #10725 from esphome/bump-2025.9.0b2
2025.9.0b2
2025-09-15 18:28:51 +12:00
J. Nick Koston
415593d05e Merge branch 'integration' into memory_api 2025-09-14 23:16:22 -05:00
J. Nick Koston
fe4a1c21b3 Merge branch 'libretiny_vector_prefs' into integration 2025-09-14 23:16:16 -05:00
J. Nick Koston
f8ff00af06 [libretiny] Optimize preferences memory usage by replacing vector with unique_ptr 2025-09-14 23:15:33 -05:00
J. Nick Koston
ca185cb28f Merge branch 'integration' into memory_api 2025-09-14 22:48:18 -05:00
J. Nick Koston
2e7a7a8617 Merge branch 'esp32_prefs_no_vector' into integration 2025-09-14 22:48:12 -05:00
J. Nick Koston
2df57e622c zu 2025-09-14 22:47:43 -05:00
J. Nick Koston
277b8aff73 Merge branch 'integration' into memory_api 2025-09-14 22:36:34 -05:00
J. Nick Koston
5195e2bf44 Merge branch 'esp32_prefs_no_vector' into integration 2025-09-14 22:36:29 -05:00
J. Nick Koston
c7ec5c820a [esp32] Optimize NVS preferences memory usage by replacing vector with unique_ptr 2025-09-14 22:35:26 -05:00
J. Nick Koston
adaebf64ba Merge branch 'integration' into memory_api 2025-09-14 22:19:20 -05:00
J. Nick Koston
bc63f9909d Merge branch 'json_psram' into integration 2025-09-14 22:19:13 -05:00
J. Nick Koston
43a2f20ea7 [json] Only compile SpiRamAllocator when PSRAM is enabled 2025-09-14 22:18:44 -05:00
J. Nick Koston
a8b8819826 Merge branch 'integration' into memory_api 2025-09-14 21:56:20 -05:00
J. Nick Koston
aad369463b Merge branch 'auth_request' into integration 2025-09-14 21:56:06 -05:00
J. Nick Koston
e2c00977cf Merge remote-tracking branch 'upstream/dependabot/pip/aioesphomeapi-41.0.0' into integration 2025-09-14 21:56:01 -05:00
J. Nick Koston
29870385ae Merge remote-tracking branch 'upstream/dashboard_dns_lookup_delay' into integration 2025-09-14 21:55:55 -05:00
J. Nick Koston
76132c3958 Merge remote-tracking branch 'upstream/dev' into integration 2025-09-14 21:55:50 -05:00
dependabot[bot]
913a088c33 Bump aioesphomeapi from 40.2.1 to 41.0.0
Bumps [aioesphomeapi](https://github.com/esphome/aioesphomeapi) from 40.2.1 to 41.0.0.
- [Release notes](https://github.com/esphome/aioesphomeapi/releases)
- [Commits](https://github.com/esphome/aioesphomeapi/compare/v40.2.1...v41.0.0)

---
updated-dependencies:
- dependency-name: aioesphomeapi
  dependency-version: 41.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 02:46:11 +00:00
J. Nick Koston
623878a9c3 Merge branch 'dev' into dashboard_dns_lookup_delay 2025-09-14 21:28:46 -05:00
J. Nick Koston
73773ed5c6 [api] Rename ConnectRequest/Response to AuthenticationRequest/Response in API 2025-09-14 21:22:17 -05:00
J. Nick Koston
459ef7f262 [api] Exclude ConnectRequest/Response when password is disabled (#10704) 2025-09-14 20:45:28 -05:00
J. Nick Koston
bd9dc43e59 Add additional coverage ahead of Path conversion (#10723) 2025-09-15 13:33:15 +12:00
Jesse Hills
971de64494 Bump version to 2025.9.0b2 2025-09-15 12:34:56 +12:00
J. Nick Koston
926fdcbecd [esp32_ble] Optimize BLE hex formatting to eliminate sprintf dependency (#10714)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-15 12:34:56 +12:00
J. Nick Koston
6b147312cd [wifi] Optimize WiFi MAC formatting to eliminate sprintf dependency (#10715)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-15 12:34:56 +12:00
J. Nick Koston
2d9152d9b9 [md5] Optimize MD5::get_hex() to eliminate sprintf dependency (#10710) 2025-09-15 12:34:56 +12:00
dependabot[bot]
24f9550ce5 Bump aioesphomeapi from 40.2.0 to 40.2.1 (#10721)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-15 12:34:56 +12:00
Big Mike
3427aaab8c ina2xx should be total increasing for energy sensor (#10711) 2025-09-15 12:34:56 +12:00
J. Nick Koston
4e17d14acc [scheduler] Fix timing accumulation in scheduler causing incorrect execution measurements (#10719) 2025-09-15 12:34:56 +12:00
J. Nick Koston
1750f02ef3 [api] Optimize HelloResponse server_info to reduce memory usage (#10701) 2025-09-15 12:34:56 +12:00
J. Nick Koston
ae158179bd [api] Revert unneeded GetTime bidirectional support added in #9790 (#10702) 2025-09-15 12:34:55 +12:00
J. Nick Koston
c601494779 [core] Optimize MAC address formatting to eliminate sprintf dependency (#10713) 2025-09-15 12:34:55 +12:00
J. Nick Koston
646f4e66be [ethernet] Fix permanent component failure from undocumented ESP_FAIL in IPv6 setup (#10708) 2025-09-15 12:34:55 +12:00
dependabot[bot]
5b5e5c213c Bump aioesphomeapi from 40.1.0 to 40.2.0 (#10703)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-15 12:34:55 +12:00
Markus
46235684b1 [core] fix upload to device via MQTT IP lookup (e.g. when mDNS is disable) (#10632)
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>
2025-09-15 12:34:55 +12:00
J. Nick Koston
5b702a1efa Add additional dashboard and main tests (#10688)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-15 12:34:55 +12:00
J. Nick Koston
56e9fd2e38 [tests] Add upload_program and show_logs test coverage to prevent regressions (#10684) 2025-09-15 12:34:55 +12:00
J. Nick Koston
65f15a706f Add some more coverage for dashboard web_server (#10682) 2025-09-15 12:34:55 +12:00
J. Nick Koston
eee64cc3a6 Add comprehensive tests for choose_upload_log_host to prevent regressions (#10679)
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-09-15 12:34:55 +12:00
J. Nick Koston
f43fb3c3a3 [core] Add millisecond precision to logging timestamps (#10677) 2025-09-15 12:34:55 +12:00
rwrozelle
79b0025fe6 Openthread Fix Factory Reset (#9281)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-15 12:34:55 +12:00
Jesse Hills
c6a039a72f [adc] Fix FILTER_SOURCE_FILES location (#10673) 2025-09-15 12:34:54 +12:00
esphomebot
6f1fa094c2 Update webserver local assets to 20250910-110003 (#10668) 2025-09-15 12:34:54 +12:00
J. Nick Koston
f857fa1f0d [dashboard] Fix archive handler incorrectly deleting build folders instead of archiving them 2025-09-14 19:22:33 -05:00
J. Nick Koston
1d5a3b647d [esp32_ble] Optimize BLE hex formatting to eliminate sprintf dependency (#10714)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-15 12:04:45 +12:00
Jimmy Hedman
af3e1788d1 Unpin libretiny version in network test (#10717) 2025-09-14 22:54:14 +00:00
J. Nick Koston
54a170242c Merge branch 'dev' into dashboard_dns_lookup_delay 2025-09-14 17:37:29 -05:00
J. Nick Koston
b946cb160d [wifi] Optimize WiFi MAC formatting to eliminate sprintf dependency (#10715)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-14 22:35:27 +00:00
J. Nick Koston
e0241e9dcd [md5] Optimize MD5::get_hex() to eliminate sprintf dependency (#10710) 2025-09-14 22:35:18 +00:00
dependabot[bot]
1accc409f6 Bump aioesphomeapi from 40.2.0 to 40.2.1 (#10721)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-14 22:33:07 +00:00
Big Mike
f756de276b ina2xx should be total increasing for energy sensor (#10711) 2025-09-15 10:16:01 +12:00
J. Nick Koston
ac07a00141 [scheduler] Fix timing accumulation in scheduler causing incorrect execution measurements (#10719) 2025-09-14 22:05:56 +00:00
J. Nick Koston
7ae11de2e4 [api] Optimize HelloResponse server_info to reduce memory usage (#10701) 2025-09-15 09:54:42 +12:00
J. Nick Koston
bb6be9c939 [api] Revert unneeded GetTime bidirectional support added in #9790 (#10702) 2025-09-15 09:52:19 +12:00
J. Nick Koston
9c85a7eff3 [core] Optimize MAC address formatting to eliminate sprintf dependency (#10713) 2025-09-15 09:50:38 +12:00
J. Nick Koston
10a665b864 [ethernet] Fix permanent component failure from undocumented ESP_FAIL in IPv6 setup (#10708) 2025-09-15 09:45:22 +12:00
J. Nick Koston
35dce3c80d Add additional test coverage ahead of Path conversion (#10700) 2025-09-15 09:31:38 +12:00
J. Nick Koston
2a0567c456 Merge branch 'integration' into memory_api 2025-09-14 16:19:26 -05:00
J. Nick Koston
bae0d4d097 Merge branch 'fix_scheduler_item_time_cap' into integration 2025-09-14 16:19:20 -05:00
J. Nick Koston
99649c3a8f [scheduler] Fix timing accumulation in scheduler causing incorrect execution measurements 2025-09-14 16:16:46 -05:00
J. Nick Koston
6378bb2ac4 Merge branch 'integration' into memory_api 2025-09-14 14:42:12 -05:00
J. Nick Koston
50e1f83d7c Merge branch 'mac_formatting_perf_wifi' into integration 2025-09-14 14:42:07 -05:00
J. Nick Koston
682d98f9b4 [wifi] Optimize WiFi MAC formatting to eliminate sprintf dependency 2025-09-14 14:30:30 -05:00
J. Nick Koston
35060416ba [wifi] Optimize WiFi MAC formatting to eliminate sprintf dependency 2025-09-14 14:29:25 -05:00
J. Nick Koston
cb439f31b9 Merge branch 'integration' into memory_api 2025-09-14 14:21:16 -05:00
J. Nick Koston
b8be8e187d Merge branch 'mac_formatting_perf_for_ble' into integration 2025-09-14 14:21:10 -05:00
J. Nick Koston
4e680020d1 [esp32_ble] Optimize BLE hex formatting to eliminate sprintf dependency 2025-09-14 14:20:34 -05:00
J. Nick Koston
0e9110482c Merge branch 'integration' into memory_api 2025-09-14 14:01:21 -05:00
J. Nick Koston
1e6dc467ec Merge branch 'md5_hex_performance' into integration 2025-09-14 14:01:16 -05:00
J. Nick Koston
d262526f31 preen 2025-09-14 14:00:01 -05:00
J. Nick Koston
53ab104c6a Merge branch 'integration' into memory_api 2025-09-14 13:54:27 -05:00
J. Nick Koston
38aea3d9b6 Merge branch 'md5_hex_performance' into integration 2025-09-14 13:54:16 -05:00
J. Nick Koston
6f387017aa Merge branch 'mac_formatting_perf' into integration 2025-09-14 13:53:46 -05:00
J. Nick Koston
16b7714990 preen 2025-09-14 13:53:36 -05:00
J. Nick Koston
22c91dfadc cleanup 2025-09-14 13:51:10 -05:00
J. Nick Koston
0b42250900 [core] Optimize MAC address formatting to eliminate sprintf dependency 2025-09-14 13:49:11 -05:00
J. Nick Koston
842006efa1 Merge branch 'integration' into memory_api 2025-09-14 10:50:16 -05:00
J. Nick Koston
69804f5ccf Merge branch 'md5_hex_performance' into integration 2025-09-14 10:50:11 -05:00
J. Nick Koston
b03a651499 [md5] Optimize MD5::get_hex() to eliminate sprintf dependency 2025-09-14 10:48:26 -05:00
J. Nick Koston
eb5d74f3b1 Merge branch 'fix_ethernet_reconnect_ipv6' into integration 2025-09-14 10:19:14 -05:00
J. Nick Koston
2eb02d5440 comments 2025-09-14 09:26:24 -05:00
J. Nick Koston
dfc7382c35 comments 2025-09-14 09:26:24 -05:00
J. Nick Koston
bcf8f4ef9d comments 2025-09-14 09:25:59 -05:00
J. Nick Koston
ea26f9319b comments 2025-09-14 09:25:46 -05:00
J. Nick Koston
f78ae3aa52 Merge branch 'integration' into memory_api 2025-09-14 09:18:36 -05:00
J. Nick Koston
0359c3120a Merge branch 'fix_ethernet_reconnect_ipv6' into integration 2025-09-14 09:18:32 -05:00
J. Nick Koston
4bb40418c5 comments 2025-09-14 09:17:51 -05:00
J. Nick Koston
09a4d51120 comments 2025-09-14 09:17:24 -05:00
J. Nick Koston
c1c4fabc28 comments 2025-09-14 09:16:11 -05:00
J. Nick Koston
dc8c5a6cb3 comments 2025-09-14 09:12:07 -05:00
J. Nick Koston
3a4a01ac51 [ethernet] Fix permanent component failure from undocumented ESP_FAIL in IPv6 setup 2025-09-14 09:05:28 -05:00
J. Nick Koston
a8c1f6e551 Merge branch 'integration' into memory_api 2025-09-13 22:42:36 -05:00
J. Nick Koston
2d27055860 Merge branch 'get_time_response_plus_connect_password_only' into integration 2025-09-13 22:42:27 -05:00
J. Nick Koston
c2f0e14e12 [api] Exclude ConnectRequest/Response when password is disabled 2025-09-13 22:39:52 -05:00
dependabot[bot]
7e6b11ce84 Bump aioesphomeapi from 40.1.0 to 40.2.0 (#10703)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-13 23:25:19 +00:00
J. Nick Koston
62c457fd87 Merge branch 'integration' into memory_api 2025-09-13 18:08:02 -05:00
J. Nick Koston
9f8ced865f Merge branch 'get_time_response' into integration 2025-09-13 18:07:56 -05:00
J. Nick Koston
722548e393 Revert unneeded GetTime bidirectional support added in #9790 2025-09-13 18:06:12 -05:00
J. Nick Koston
b118aa7339 Merge branch 'integration' into memory_api 2025-09-13 17:16:36 -05:00
J. Nick Koston
de4ae7fd84 Merge branch 'cleanup_server_info_hello' into integration 2025-09-13 17:16:23 -05:00
J. Nick Koston
38ef33fe5a [api] Optimize HelloResponse server_info to reduce memory usage 2025-09-13 17:16:14 -05:00
J. Nick Koston
51c943d21e [api] Optimize HelloResponse server_info to reduce memory usage 2025-09-13 17:16:09 -05:00
J. Nick Koston
1ea97e9caf [api] Optimize HelloResponse server_info to reduce memory usage 2025-09-13 17:15:05 -05:00
Keith Burzinski
adcba4fd9a [api_protobuf.py] Use type based on size/length (#10696) 2025-09-13 17:02:04 -05:00
J. Nick Koston
11691d05e2 Merge branch 'integration' into memory_api 2025-09-13 17:01:04 -05:00
J. Nick Koston
c1d990ee2b Merge remote-tracking branch 'upstream/dev' into integration 2025-09-13 17:00:51 -05:00
J. Nick Koston
4b15421d42 dry 2025-09-12 16:36:57 -05:00
J. Nick Koston
3909d271f7 Merge remote-tracking branch 'upstream/dev' into dashboard_dns_lookup_delay 2025-09-12 16:34:34 -05:00
Markus
d3592c451b [core] fix upload to device via MQTT IP lookup (e.g. when mDNS is disable) (#10632)
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>
2025-09-12 16:31:53 -05:00
J. Nick Koston
24eb33a1c0 Add additional dashboard and main tests (#10688)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-13 09:04:56 +12:00
dependabot[bot]
cf1fef8cfb Bump pytest-asyncio from 1.1.0 to 1.2.0 (#10691)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-12 14:09:38 -05:00
fakuivan
28bba0666c [packet_transport] initialize packet data after flushing (#10686) 2025-09-13 05:02:41 +10:00
J. Nick Koston
4390fd80a3 Add additional coverage for util and writer (#10683) 2025-09-12 17:04:51 +12:00
J. Nick Koston
4813c5134e [tests] Add upload_program and show_logs test coverage to prevent regressions (#10684) 2025-09-12 17:04:22 +12:00
J. Nick Koston
801c15a1e0 dry 2025-09-11 19:43:08 -05:00
J. Nick Koston
0be3387d37 break it out 2025-09-11 19:39:36 -05:00
J. Nick Koston
6744156434 break it out 2025-09-11 19:38:18 -05:00
J. Nick Koston
aaeb541bd0 break it out 2025-09-11 19:38:04 -05:00
J. Nick Koston
a86f35dbb6 break it up 2025-09-11 19:34:06 -05:00
J. Nick Koston
46c83c8824 fix type 2025-09-11 19:28:54 -05:00
J. Nick Koston
8925966119 reorder 2025-09-11 19:26:18 -05:00
J. Nick Koston
854a415805 wip 2025-09-11 19:17:54 -05:00
J. Nick Koston
384ded539d wip 2025-09-11 19:14:51 -05:00
J. Nick Koston
305b4504de wip 2025-09-11 19:14:03 -05:00
J. Nick Koston
5dbe56849a wip 2025-09-11 19:10:58 -05:00
J. Nick Koston
99403c5a36 wip 2025-09-11 19:08:43 -05:00
J. Nick Koston
b416f7c1fb fixes 2025-09-11 19:05:31 -05:00
J. Nick Koston
fd9df3a629 fixes 2025-09-11 19:02:33 -05:00
J. Nick Koston
7dcedbae09 fixes 2025-09-11 19:00:31 -05:00
J. Nick Koston
b9bf81fffc fixes 2025-09-11 18:57:35 -05:00
J. Nick Koston
23d82f8368 preen 2025-09-11 18:54:06 -05:00
J. Nick Koston
158236f819 preen 2025-09-11 18:51:44 -05:00
J. Nick Koston
817dba3d53 preen 2025-09-11 18:50:28 -05:00
J. Nick Koston
7fb8c84d6a cleanup 2025-09-11 18:47:09 -05:00
J. Nick Koston
80240437c5 cleanup 2025-09-11 18:35:51 -05:00
J. Nick Koston
29525febe1 cleanup 2025-09-11 18:28:28 -05:00
J. Nick Koston
bc9d16289e Fix dashboard dns lookup delay 2025-09-11 18:25:06 -05:00
J. Nick Koston
519bc5ef9e Fix dashboard dns lookup delay 2025-09-11 18:22:16 -05:00
J. Nick Koston
4d3405340d Fix dashboard dns lookup delay 2025-09-11 18:21:01 -05:00
J. Nick Koston
bbef0e173e [esp32_ble_tracker] Simplify BLE client state machine by removing READY_TO_CONNECT (#10672) 2025-09-12 08:54:34 +12:00
J. Nick Koston
3240e19a7c Add some more coverage for dashboard web_server (#10682) 2025-09-12 08:52:46 +12:00
J. Nick Koston
ac0cd946f0 Add comprehensive tests for choose_upload_log_host to prevent regressions (#10679)
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-09-12 08:51:58 +12:00
Jonathan Swoboda
61bac6c6e6 [esp32] Allow esp-idf 5.5.1 (#10680) 2025-09-11 20:13:05 +00:00
J. Nick Koston
5fd64c5c89 [core] Add millisecond precision to logging timestamps (#10677) 2025-09-11 14:25:55 -05:00
rwrozelle
625f108183 Openthread Fix Factory Reset (#9281)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-11 05:23:58 +00:00
J. Nick Koston
c45efe8f40 Add additional coverage for yaml_util (#10674) 2025-09-11 17:01:11 +12:00
Jesse Hills
fe1371f4dc [adc] Fix FILTER_SOURCE_FILES location (#10673) 2025-09-10 22:32:04 -05:00
J. Nick Koston
e3f8a36eaa Add coverage for dashboard ahead of Path conversion (#10669) 2025-09-10 22:16:04 -05:00
J. Nick Koston
f6ebe21509 Merge branch 'integration' into memory_api 2025-09-10 21:17:19 -05:00
J. Nick Koston
99d25cc0b3 Merge branch 'ble_cleanups' into integration 2025-09-10 21:17:10 -05:00
J. Nick Koston
ec97a464f7 [esp32_ble_tracker] Simplify BLE client state machine by removing READY_TO_CONNECT 2025-09-10 21:14:12 -05:00
J. Nick Koston
386b52f4a4 [esp32_ble_tracker] Simplify BLE client state machine by removing READY_TO_CONNECT 2025-09-10 21:06:35 -05:00
J. Nick Koston
604074e3bf [esp32_ble_tracker] Simplify BLE client state machine by removing READY_TO_CONNECT 2025-09-10 21:02:33 -05:00
dependabot[bot]
41f0d1c622 Bump ruff from 0.12.12 to 0.13.0 (#10670)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-09-10 21:09:45 +00:00
Jesse Hills
6469bb168d Merge branch 'beta' into dev 2025-09-11 07:25:06 +12:00
Jesse Hills
7a869a33f0 Merge pull request #10665 from esphome/bump-2025.9.0b1
2025.9.0b1
2025-09-11 07:24:33 +12:00
esphomebot
af0da3f897 Update webserver local assets to 20250910-110003 (#10668) 2025-09-10 10:41:18 -05:00
Jonathan Swoboda
32e4eb26ad [remote] Remove duplicate implementations of remote code (#10548) 2025-09-10 10:46:30 -04:00
J. Nick Koston
10aae33979 Improve coverage for various core modules (#10663) 2025-09-10 08:17:34 -05:00
Keith Burzinski
56e85b3ef9 [thermostat] Rename timer enums to mitigate naming conflict (#10666) 2025-09-10 22:58:35 +12:00
Keith Burzinski
55dd12c66b [thermostat] Rename timer enums to mitigate naming conflict (#10666) 2025-09-10 22:58:07 +12:00
Jesse Hills
9dd17b464d Bump version to 2025.10.0-dev 2025-09-10 19:48:02 +12:00
Jesse Hills
2401f81be3 Bump version to 2025.9.0b1 2025-09-10 19:48:01 +12:00
Josip Šimun Kuči
52a7e26c6d [inkplate] Rename component and fix grayscale (#10200)
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: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-10 18:46:58 +12:00
Jesse Hills
d729dc20a8 Merge branch 'release' into dev 2025-09-10 17:04:21 +12:00
Jesse Hills
d3b7a9687b Merge pull request #10664 from esphome/bump-2025.8.4
2025.8.4
2025-09-10 17:03:37 +12:00
Jesse Hills
9d7fc11108 Bump version to 2025.8.4 2025-09-10 13:56:50 +12:00
tomaszduda23
7969627d3e [light] add missing header (#10590) 2025-09-10 13:56:50 +12:00
Clyde Stubbs
82d2e367d4 [kmeteriso] Fix i2c call (#10618) 2025-09-10 13:56:50 +12:00
Keith Burzinski
972aa691e4 [sen5x] Fix initialization (#10603) 2025-09-10 13:56:50 +12:00
Daniel M
ac61b8f893 [bl0940] extend configuration options of bl0940 device (#8158)
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-09-10 13:50:49 +12:00
Keith Burzinski
d9f625e5c8 [thermostat] General clean-up, optimization, properly support "auto" mode (#10561)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-10 13:24:50 +12:00
Jonathan Swoboda
e218f16f0f Allow both files and directories to be passed to update-all (#10575)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-09-09 18:06:59 -05:00
J. Nick Koston
185a2c2fe7 Merge branch 'integration' into memory_api 2025-09-09 17:06:57 -05:00
J. Nick Koston
2ac3d19d96 Merge branch 'dev' into integration 2025-09-09 17:06:51 -05:00
J. Nick Koston
af45b63d51 Merge branch 'dev' into memory_api 2025-09-09 17:06:39 -05:00
J. Nick Koston
422d209786 [api] Add timezone support to GetTimeResponse for automatic timezone synchronization (#10661) 2025-09-09 15:54:50 -05:00
dependabot[bot]
e972e1f8c2 Bump aioesphomeapi from 40.0.2 to 40.1.0 (#10662)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-09 20:33:36 +00:00
dependabot[bot]
cfb90b7b18 Bump pytest-cov from 6.3.0 to 7.0.0 (#10660)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-09 15:15:53 -05:00
mrtoy-me
8976ea2436 [ms5611] remove delay in setup (#10658) 2025-09-10 07:31:06 +12:00
tomaszduda23
01ff09064d [nrf52] add more tests (#10591) 2025-09-10 07:29:49 +12:00
tomaszduda23
39212f0d7f allow to implement show_logs as external component (#10523) 2025-09-09 11:45:42 -05:00
Mischa Siekmann
8993f4e6b4 RingBuffer: Make partial writing optional (#10302) 2025-09-09 08:39:47 -05:00
J. Nick Koston
7adad0ee49 [core] Refactor insertion sort functions to eliminate code duplication (#10653) 2025-09-09 02:03:35 -05:00
J. Nick Koston
dd8815ec9d [core] Reduce flash usage by refactoring looping component partitioning (#10652) 2025-09-09 01:17:30 -05:00
Jesse Hills
59e62a1f44 Sort codeowners using case-insensitive (#10651)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-09-08 21:26:22 -05:00
J. Nick Koston
e59928166b Merge branch 'integration' into memory_api 2025-09-08 20:31:33 -05:00
J. Nick Koston
67603ba302 Merge branch 'insertion_sort_by_priority' into integration 2025-09-08 20:31:23 -05:00
J. Nick Koston
c0cab7ded3 [core] Refactor insertion sort functions to eliminate code duplication 2025-09-08 20:30:38 -05:00
Edward Firmo
f5f84fe825 [nextion] Increase delay before reboot to prevent TFT upload interruption (#10402) 2025-09-09 12:57:24 +12:00
Edward Firmo
90c2fdd565 [adc] Fix autorange negative coefficient bug causing incorrect voltage readings (#10549) 2025-09-09 12:56:18 +12:00
J. Nick Koston
6a7145fef8 Merge branch 'integration' into memory_api 2025-09-08 19:53:58 -05:00
J. Nick Koston
b955454852 Merge branch 'reduce_flash_loop_comp' into integration 2025-09-08 19:53:46 -05:00
J. Nick Koston
0495856f61 [core] Reduce flash usage by refactoring looping component partitioning 2025-09-08 19:53:08 -05:00
J. Nick Koston
29552b951d Merge branch 'integration' into memory_api 2025-09-08 19:28:32 -05:00
J. Nick Koston
959846ed89 Merge remote-tracking branch 'upstream/dev' into integration 2025-09-08 19:28:20 -05:00
tomaszduda23
f6d69231e8 [light] add missing header (#10590) 2025-09-09 11:10:29 +12:00
J. Nick Koston
5cc0e21bc7 [core] Reduce unnecessary nesting in scheduler loop (#10644) 2025-09-09 09:04:07 +12:00
Thomas Rupprecht
703b592793 Add I2S Audio Port for ESP32-C5/C6/H2 (#10414) 2025-09-08 14:03:41 -04:00
J. Nick Koston
75c9430d91 [core] Fix serial upload regression from DNS resolution PR #10595 (#10648) 2025-09-08 10:41:03 -05:00
J. Nick Koston
4c9fd2b800 Merge branch 'integration' into memory_api 2025-09-08 10:05:14 -05:00
J. Nick Koston
6b73cdbafb Merge branch 'fix_upload_run' into integration 2025-09-08 10:05:03 -05:00
J. Nick Koston
8179495fd7 [core] Fix serial upload regression from DNS resolution PR #10595 2025-09-08 10:03:56 -05:00
J. Nick Koston
e5bba00deb [esp32] Reduce GPIO memory usage by 50% through bit-packing (#10556) 2025-09-08 08:46:30 -05:00
J. Nick Koston
f37223c756 Merge branch 'integration' into memory_api 2025-09-07 22:03:07 -05:00
J. Nick Koston
2f66a9f586 Merge branch 'tiny_scheduler_cleanup_reduce_nesting' into integration 2025-09-07 22:02:55 -05:00
J. Nick Koston
9a9783bb21 [core] Reduce unnecessary nesting in scheduler loop 2025-09-07 22:02:03 -05:00
J. Nick Koston
5b4b026d1b Merge branch 'integration' into memory_api 2025-09-07 20:11:09 -05:00
J. Nick Koston
b78b4601f3 Merge remote-tracking branch 'upstream/dev' into integration 2025-09-07 20:10:59 -05:00
J. Nick Koston
8d90f13e97 [core] Store component source strings in flash on ESP8266 (breaking change) (#10621) 2025-09-07 20:10:00 -05:00
J. Nick Koston
666e33e70b [api] Store plaintext error message in PROGMEM on ESP8266 (#10634) 2025-09-07 20:09:47 -05:00
Clyde Stubbs
7eaaa4e426 [mipi_rgb] Unified driver for MIPI RGB displays (#9892)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-08 12:56:34 +12:00
J. Nick Koston
563216220d Merge branch 'integration' into memory_api 2025-09-07 18:54:50 -05:00
J. Nick Koston
66d301a120 Merge branch 'component_source_logstring' into integration 2025-09-07 18:54:29 -05:00
J. Nick Koston
b3c4c4b411 Merge remote-tracking branch 'upstream/dev' into component_source_logstring 2025-09-07 18:53:46 -05:00
J. Nick Koston
166ad942ef [scheduler] Reduce SchedulerItem memory usage by 7.4% on 32-bit platforms (#10553)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-07 18:51:07 -05:00
J. Nick Koston
d2e1135a56 Merge branch 'integration' into memory_api 2025-09-07 18:47:09 -05:00
J. Nick Koston
232c91fccf Merge branch 'dev' into integration 2025-09-07 18:46:59 -05:00
J. Nick Koston
0ff08bbc09 [mcp23016] Migrate to CachedGpioExpander to reduce I2C bus usage (#10581)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-07 18:26:49 -05:00
J. Nick Koston
6e2bcabbc9 [sx1509] Migrate to CachedGpioExpander to reduce I2C bus usage (#10588)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-07 18:26:33 -05:00
J. Nick Koston
afa191ae41 [pcf8574] Migrate to CachedGpioExpander to reduce I2C bus usage (#10573)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-07 18:26:22 -05:00
J. Nick Koston
93da52c4d2 [pca9554] Migrate to CachedGpioExpander to reduce I2C bus usage (#10571)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-07 18:26:11 -05:00
J. Nick Koston
aec6c3ae33 Merge branch 'integration' into memory_api 2025-09-07 18:23:31 -05:00
J. Nick Koston
a255e5be13 Merge branch 'bad_ind_flash_esp8266' into integration 2025-09-07 18:23:22 -05:00
J. Nick Koston
424e0a97b2 const 2025-09-07 18:23:03 -05:00
J. Nick Koston
72a1f467f0 Merge branch 'integration' into memory_api 2025-09-07 18:05:23 -05:00
J. Nick Koston
00e54961a2 fix merge 2025-09-07 18:05:14 -05:00
J. Nick Koston
c3b20bbda1 Merge branch 'dev' into bad_ind_flash_esp8266 2025-09-07 18:02:27 -05:00
J. Nick Koston
c634ef4b12 Merge branch 'integration' into memory_api 2025-09-07 18:02:14 -05:00
J. Nick Koston
bf5e0d6e28 Merge remote-tracking branch 'upstream/dev' into integration 2025-09-07 18:01:59 -05:00
J. Nick Koston
0cc0979674 [pca6416a] Migrate to CachedGpioExpander to reduce I2C bus usage (#10587) 2025-09-08 10:59:23 +12:00
Jesse Hills
629f1e94f1 [ota] Fix duplicate include and sort (#10643) 2025-09-07 22:58:41 +00:00
J. Nick Koston
8c28f346c7 [gpio_expander] Add intelligent pin type selection to CachedGpioExpander template (#10577) 2025-09-08 10:57:02 +12:00
dependabot[bot]
3cf36e2f94 Bump aioesphomeapi from 40.0.1 to 40.0.2 (#10641)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-07 17:32:21 -05:00
J. Nick Koston
1ac07c96b1 [esphome] Store OTA component log strings in flash on ESP8266 (#10570) 2025-09-08 10:30:39 +12:00
J. Nick Koston
91228c82e6 [esp8266][logger] Store LOG_LEVELS strings in PROGMEM to reduce RAM usage (#10569) 2025-09-08 10:29:45 +12:00
J. Nick Koston
28d16728d3 [core] Add memory pool to scheduler to reduce heap fragmentation (#10536) 2025-09-08 10:27:58 +12:00
dependabot[bot]
f24a182ba2 Bump pytest-cov from 6.2.1 to 6.3.0 (#10640)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-07 17:26:31 -05:00
dependabot[bot]
0065fe1516 Bump zeroconf from 0.147.0 to 0.147.2 (#10642)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-07 17:26:06 -05:00
J. Nick Koston
148fa698cc Fix DNS resolution inconsistency between logs and OTA operations (#10595)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-09-08 10:25:22 +12:00
J. Nick Koston
ffd607ee28 Merge branch 'integration' into memory_api 2025-09-07 17:21:57 -05:00
J. Nick Koston
5a5b528205 Merge branch 'optimize_pcf8574' into integration 2025-09-07 17:21:51 -05:00
J. Nick Koston
b227e83c08 Merge branch 'pca9554_loop_churn_fix' into integration 2025-09-07 17:21:48 -05:00
J. Nick Koston
e969fc3027 Merge branch 'sx1509_gpio_cache' into integration 2025-09-07 17:21:44 -05:00
J. Nick Koston
269fed6ccc Merge branch 'gpio_expander_fix_more_than_8_pins_in_bank' into sx1509_gpio_cache 2025-09-07 17:21:27 -05:00
J. Nick Koston
2d43f31fdb Merge branch 'gpio_expander_fix_more_than_8_pins_in_bank' into optimize_pcf8574 2025-09-07 17:21:09 -05:00
J. Nick Koston
c906eb881b Merge branch 'gpio_expander_fix_more_than_8_pins_in_bank' into pca9554_loop_churn_fix 2025-09-07 17:20:40 -05:00
J. Nick Koston
1964764dd0 Merge branch 'integration' into memory_api 2025-09-07 16:50:48 -05:00
J. Nick Koston
d0c157c92e Merge branch 'gpio_expander_fix_more_than_8_pins_in_bank' into integration 2025-09-07 16:50:42 -05:00
J. Nick Koston
7d65acf7db use conditional 2025-09-07 16:48:09 -05:00
J. Nick Koston
b25506b045 [core] Skip redundant process_to_add() call when no scheduler items added (#10630)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-08 09:10:55 +12:00
J. Nick Koston
0c737fc4df [core] Convert LOG_UPDATE_INTERVAL macro to function to reduce flash usage (#10636) 2025-09-08 09:09:15 +12:00
davidmonro
a8b8507ffc Atm90e32/26 device class fixes (#10629) 2025-09-08 08:06:10 +12:00
J. Nick Koston
f358f0a8f9 Merge branch 'integration' into memory_api 2025-09-07 09:48:20 -05:00
J. Nick Koston
8fb7cd2340 Merge branch 'base64_chars_flash_esp8266' into integration 2025-09-07 09:48:10 -05:00
J. Nick Koston
7bd8b1d137 Update esphome/core/helpers.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-07 09:46:54 -05:00
J. Nick Koston
f9d10954bb Merge branch 'integration' into memory_api 2025-09-07 09:33:29 -05:00
J. Nick Koston
3a9bc75b29 Merge branch 'log_update_interval' into integration 2025-09-07 09:33:21 -05:00
J. Nick Koston
0f2a8300b2 [core] Convert LOG_UPDATE_INTERVAL macro to function to reduce flash usage 2025-09-07 09:32:02 -05:00
J. Nick Koston
68c8a67677 Merge branch 'integration' into memory_api 2025-09-07 09:02:28 -05:00
J. Nick Koston
546a2e2fcc Merge branch 'component_source_logstring' into integration 2025-09-07 09:02:20 -05:00
J. Nick Koston
b70573e8ff Merge remote-tracking branch 'upstream/dev' into component_source_logstring 2025-09-07 09:02:07 -05:00
J. Nick Koston
5f8731a136 Merge branch 'integration' into memory_api 2025-09-07 08:59:12 -05:00
J. Nick Koston
3faea0b0cd Merge branch 'base64_chars_flash_esp8266' into integration 2025-09-07 08:58:54 -05:00
J. Nick Koston
960a65e2f3 [core] Store BASE64 chars in flash memory array 2025-09-07 08:56:44 -05:00
J. Nick Koston
28233180c9 tidy 2025-09-07 08:27:25 -05:00
J. Nick Koston
2be9f42ddd Merge branch 'integration' into memory_api 2025-09-07 08:23:54 -05:00
J. Nick Koston
11f5849e70 Merge branch 'bad_ind_flash_esp8266' into integration 2025-09-07 08:23:29 -05:00
J. Nick Koston
c198ef6b07 [api] Store plaintext error message in PROGMEM on ESP8266 2025-09-07 08:21:02 -05:00
J. Nick Koston
c33bb3a8a9 [esp8266] Store component warning strings in flash to reduce RAM usage (#10623) 2025-09-06 23:56:45 -05:00
J. Nick Koston
902619e46d Merge branch 'integration' into memory_api 2025-09-06 23:30:57 -05:00
J. Nick Koston
b738a8ba83 Merge branch 'scheduler_skip_add_no_change' into integration 2025-09-06 23:30:51 -05:00
J. Nick Koston
0364ea38e6 Merge remote-tracking branch 'upstream/scheduler_skip_add_no_change' into scheduler_skip_add_no_change 2025-09-06 23:30:40 -05:00
J. Nick Koston
fec9e63b0c rename 2025-09-06 23:29:40 -05:00
J. Nick Koston
97957b49f1 rename 2025-09-06 23:29:11 -05:00
J. Nick Koston
98f7ae93db Update esphome/core/scheduler.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-06 23:27:14 -05:00
J. Nick Koston
871d36e303 Merge branch 'integration' into memory_api 2025-09-06 22:58:10 -05:00
J. Nick Koston
d0b0ee704c Merge branch 'scheduler_skip_add_no_change' into integration 2025-09-06 22:58:00 -05:00
J. Nick Koston
4a9cfeddcd better name 2025-09-06 22:56:57 -05:00
J. Nick Koston
08f6286427 Merge branch 'integration' into memory_api 2025-09-06 22:53:35 -05:00
J. Nick Koston
7b7ec63b4a Merge branch 'scheduler_skip_add_no_change' into integration 2025-09-06 22:53:27 -05:00
J. Nick Koston
57fd7552e3 [core] Skip redundant process_to_add() call when no scheduler items added 2025-09-06 22:52:48 -05:00
J. Nick Koston
261ab786fd Merge branch 'integration' into memory_api 2025-09-06 09:23:33 -05:00
J. Nick Koston
a4e7805635 Merge remote-tracking branch 'origin/dev' into integration 2025-09-06 09:23:24 -05:00
Clyde Stubbs
4d09932320 [kmeteriso] Fix i2c call (#10618) 2025-09-06 13:51:44 +10:00
J. Nick Koston
5e44aa2ccc Merge branch 'integration' into memory_api 2025-09-05 22:23:30 -05:00
J. Nick Koston
5d039c3bbc Merge branch 'warning_strings_flash' into integration 2025-09-05 22:23:16 -05:00
J. Nick Koston
2aadf59219 cleanup 2025-09-05 22:22:52 -05:00
J. Nick Koston
e9498d65c5 Merge branch 'integration' into memory_api 2025-09-05 22:15:46 -05:00
J. Nick Koston
ba5324fa2f merge 2025-09-05 22:15:31 -05:00
J. Nick Koston
f2dede2861 Merge branch 'integration' into memory_api 2025-09-05 22:14:32 -05:00
J. Nick Koston
b793f94d9a Merge branch 'warning_strings_flash' into integration 2025-09-05 22:13:20 -05:00
J. Nick Koston
ad58b92abe more 2025-09-05 22:08:32 -05:00
J. Nick Koston
9360601f53 more 2025-09-05 22:07:20 -05:00
J. Nick Koston
52fe034bff wip 2025-09-05 22:01:10 -05:00
J. Nick Koston
1108dd8e78 warnings strings flash 2025-09-05 21:54:47 -05:00
J. Nick Koston
a6d43b5ec9 warnings strings flash 2025-09-05 21:49:19 -05:00
J. Nick Koston
a26c769b96 Merge branch 'integration' into memory_api 2025-09-05 21:28:09 -05:00
J. Nick Koston
d8d9c21ee6 Merge remote-tracking branch 'upstream/dev' into integration 2025-09-05 21:27:59 -05:00
Keith Burzinski
e018b15641 [sen5x] Various optimizing & tidying up (#10602) 2025-09-05 20:10:48 -05:00
J. Nick Koston
3fd469cfe8 [esp8266][api] Store error strings in PROGMEM to reduce RAM usage (#10568) 2025-09-05 18:16:43 -05:00
J. Nick Koston
1359142106 [api] Store Noise protocol prologue in flash on ESP8266 (#10598) 2025-09-05 18:10:18 -05:00
J. Nick Koston
487ba4dad0 [mdns] Move constant strings to flash on ESP8266 (#10599) 2025-09-05 18:08:25 -05:00
J. Nick Koston
694c590eb6 [captive_portal] ESP8266: Move strings to PROGMEM (saves 192 bytes RAM) (#10600) 2025-09-05 18:02:12 -05:00
J. Nick Koston
b74463c3e6 [light] ESP8266: Store log strings in flash memory (#10611) 2025-09-05 17:59:24 -05:00
J. Nick Koston
98e8a0c201 [gpio] ESP8266: Store log strings in flash memory (#10610) 2025-09-05 17:57:24 -05:00
J. Nick Koston
91b2f75d04 [script] ESP8266: Store log format strings in PROGMEM (saves 240 bytes RAM) (#10614) 2025-09-05 17:56:00 -05:00
J. Nick Koston
f1806046a9 [web_server] ESP8266: Store OTA response strings in PROGMEM (saves 52 bytes RAM) (#10616) 2025-09-05 17:53:23 -05:00
J. Nick Koston
5b283d6d38 [sensor] ESP8266: Use LogString for state_class_to_string() to save RAM (#10617) 2025-09-05 17:51:35 -05:00
J. Nick Koston
1340665ac7 [logger] Use LogString for UART selection strings (saves 28 bytes RAM on ESP8266) (#10615)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-05 17:47:53 -05:00
J. Nick Koston
1510db277c [esphome] ESP8266: Move OTA error strings to PROGMEM (saves 116 bytes RAM) (#10620) 2025-09-05 17:44:23 -05:00
J. Nick Koston
bf7ac26ab1 Merge branch 'integration' into memory_api 2025-09-05 17:20:13 -05:00
J. Nick Koston
65d8819a9e Merge branch 'component_source_logstring' into integration 2025-09-05 17:20:05 -05:00
J. Nick Koston
d90d7e77e9 cleanup 2025-09-05 17:19:52 -05:00
Keith Burzinski
a49669ee58 [sensirion_common] Tidy up, optimize (#10604) 2025-09-05 17:17:20 -05:00
J. Nick Koston
8e468ff645 Merge branch 'integration' into memory_api 2025-09-05 17:11:30 -05:00
J. Nick Koston
ac46cc0eea Merge branch 'component_source_logstring' into integration 2025-09-05 17:11:16 -05:00
J. Nick Koston
c84928aba5 [core] Store component source strings in flash on ESP8266 (breaking change) 2025-09-05 17:08:11 -05:00
J. Nick Koston
a891b34b01 Merge branch 'integration' into memory_api 2025-09-05 14:40:56 -05:00
J. Nick Koston
2d28a1a4f4 Merge branch 'mdns_progmem' into integration 2025-09-05 14:40:46 -05:00
J. Nick Koston
a1773e0a3c fix warning 2025-09-05 14:40:32 -05:00
Keith Burzinski
09b40b882e [sgp30] Tidy up, optimize (#10607) 2025-09-05 14:20:11 -05:00
Keith Burzinski
0069163d31 [sps30] Tidy up, optimize (#10606) 2025-09-05 14:11:14 -05:00
J. Nick Koston
48d9de7f24 Merge branch 'integration' into memory_api 2025-09-05 13:53:51 -05:00
J. Nick Koston
d8abd045e0 Merge branch 'ota_log_str' into integration 2025-09-05 13:53:40 -05:00
J. Nick Koston
bc67196556 [esphome] ESP8266: Move OTA error strings to PROGMEM (saves 116 bytes RAM) 2025-09-05 13:53:10 -05:00
J. Nick Koston
7ffe6459f6 Merge branch 'integration' into memory_api 2025-09-05 13:36:33 -05:00
J. Nick Koston
e968302251 Merge branch 'logger_esp8266_progmem' into integration 2025-09-05 13:35:39 -05:00
J. Nick Koston
f2bde66933 cleanup 2025-09-05 13:35:30 -05:00
J. Nick Koston
f6b97d3977 Merge branch 'logger_esp8266_progmem' into memory_api 2025-09-05 13:27:37 -05:00
J. Nick Koston
fd1086965a Merge branch 'logger_esp8266_progmem' into integration 2025-09-05 13:27:29 -05:00
J. Nick Koston
47fac7c99a standard way 2025-09-05 13:21:54 -05:00
J. Nick Koston
c311ed9e15 Merge remote-tracking branch 'upstream/dev' into logger_esp8266_progmem 2025-09-05 13:18:15 -05:00
J. Nick Koston
35ab40faf4 try to make tidy happy 2025-09-05 13:14:51 -05:00
J. Nick Koston
ce9cf27ca5 Merge branch 'integration' into memory_api 2025-09-05 13:10:56 -05:00
J. Nick Koston
b7fc25c69c Merge branch 'state_class_to_string_flash' into integration 2025-09-05 13:10:51 -05:00
J. Nick Koston
3f3b31a2b4 simplify 2025-09-05 13:04:27 -05:00
J. Nick Koston
2f7c1601e3 Merge branch 'integration' into memory_api 2025-09-05 13:02:18 -05:00
J. Nick Koston
dd6283bc4d Merge branch 'state_class_to_string_flash' into integration 2025-09-05 13:02:14 -05:00
J. Nick Koston
406e6852d2 preen 2025-09-05 13:01:58 -05:00
J. Nick Koston
bb5a973fdf Merge branch 'integration' into memory_api 2025-09-05 11:34:19 -05:00
J. Nick Koston
ba2f6027fb Merge branch 'state_class_to_string_flash' into memory_api 2025-09-05 11:34:06 -05:00
J. Nick Koston
fa9f8c829b Merge branch 'state_class_to_string_flash' into integration 2025-09-05 11:33:27 -05:00
J. Nick Koston
4248cbc596 [sensor] ESP8266: Use LogString for state_class_to_string() to save RAM 2025-09-05 11:32:52 -05:00
J. Nick Koston
ed7cbb9111 Merge branch 'integration' into memory_api 2025-09-05 11:20:33 -05:00
J. Nick Koston
394c20c54b Merge branch 'logger_esp8266_progmem' into integration 2025-09-05 11:20:29 -05:00
J. Nick Koston
dd870b0362 fix header 2025-09-05 11:19:38 -05:00
J. Nick Koston
b5dea4549c Merge branch 'integration' into memory_api 2025-09-05 11:17:17 -05:00
J. Nick Koston
71ac279adc revert 2025-09-05 11:17:08 -05:00
J. Nick Koston
c8d575aab7 revert 2025-09-05 11:15:09 -05:00
J. Nick Koston
9b882a8792 Merge branch 'integration' into memory_api 2025-09-05 11:12:43 -05:00
J. Nick Koston
9dabaf3c31 Merge branch 'web_server_8266_store_flash' into integration 2025-09-05 11:12:36 -05:00
J. Nick Koston
a0b2d9c34c Revert "json keys"
This reverts commit ae3f4ad919.
2025-09-05 11:12:25 -05:00
J. Nick Koston
4321fc86c2 Revert "more"
This reverts commit ef0e93a9cb.
2025-09-05 11:12:15 -05:00
J. Nick Koston
210680a4cb Merge branch 'integration' into memory_api 2025-09-05 11:06:50 -05:00
J. Nick Koston
20935a9b9b Merge branch 'web_server_8266_store_flash' into integration 2025-09-05 11:06:43 -05:00
J. Nick Koston
ef0e93a9cb more 2025-09-05 11:05:10 -05:00
J. Nick Koston
ae3f4ad919 json keys 2025-09-05 11:02:14 -05:00
J. Nick Koston
c6f8aa45eb Merge branch 'integration' into memory_api 2025-09-05 10:45:36 -05:00
J. Nick Koston
820fffbf71 Merge branch 'logger_esp8266_progmem' into integration 2025-09-05 10:45:31 -05:00
J. Nick Koston
abe768a704 header 2025-09-05 10:45:21 -05:00
J. Nick Koston
def3992af5 Merge branch 'integration' into memory_api 2025-09-05 10:43:11 -05:00
J. Nick Koston
c598366e61 Merge branch 'web_server_8266_store_flash' into integration 2025-09-05 10:43:07 -05:00
J. Nick Koston
6d70417cae silence false positive 2025-09-05 10:42:39 -05:00
J. Nick Koston
f28691edb4 Merge branch 'integration' into memory_api 2025-09-05 10:39:27 -05:00
J. Nick Koston
da09a2d76c Merge branch 'ota_web_server_esp8266_flash' into integration 2025-09-05 10:39:20 -05:00
J. Nick Koston
4911c859d4 beginResponse_P 2025-09-05 10:39:11 -05:00
J. Nick Koston
4b57f1e619 beginResponse_P 2025-09-05 10:38:58 -05:00
J. Nick Koston
f9d3cddd23 Merge branch 'integration' into memory_api 2025-09-05 10:34:18 -05:00
J. Nick Koston
3603b6c18d Merge branch 'web_server_8266_store_flash' into integration 2025-09-05 10:34:11 -05:00
J. Nick Koston
6e24048a90 preen 2025-09-05 10:30:45 -05:00
J. Nick Koston
b7ef1cd7d4 Merge branch 'integration' into memory_api 2025-09-05 10:26:16 -05:00
J. Nick Koston
1ca66767ba Merge branch 'ota_web_server_esp8266_flash' into integration 2025-09-05 10:26:10 -05:00
J. Nick Koston
70358c27d3 [web_server] ESP8266: Store OTA response strings in PROGMEM (saves 52 bytes RAM) 2025-09-05 10:25:34 -05:00
J. Nick Koston
40794bca78 Merge branch 'logger_esp8266_progmem' into memory_api 2025-09-05 10:20:37 -05:00
J. Nick Koston
7c15311622 Merge branch 'logger_esp8266_progmem' into integration 2025-09-05 10:20:34 -05:00
J. Nick Koston
d323d49185 Revert "Update esphome/components/logger/logger_esp8266.cpp"
This reverts commit 9e56bc1710.
2025-09-05 10:20:13 -05:00
J. Nick Koston
f4f1b9d8c3 Merge branch 'integration' into memory_api 2025-09-05 10:19:29 -05:00
J. Nick Koston
0a72155c42 Merge branch 'logger_esp8266_progmem' into integration 2025-09-05 10:19:25 -05:00
J. Nick Koston
9e56bc1710 Update esphome/components/logger/logger_esp8266.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-05 10:19:03 -05:00
J. Nick Koston
7903e43a66 [logger] ESP8266: Store UART selection strings in PROGMEM (saves 36 bytes RAM) 2025-09-05 10:18:07 -05:00
J. Nick Koston
8c90675eb2 Merge branch 'integration' into memory_api 2025-09-05 10:12:10 -05:00
J. Nick Koston
d4e49f6705 Merge branch 'script_ram' into integration 2025-09-05 10:12:03 -05:00
J. Nick Koston
d2d0f06be3 [script] ESP8266: Store log format strings in PROGMEM (saves 240 bytes RAM) 2025-09-05 10:11:11 -05:00
J. Nick Koston
51c29f7c61 Merge branch 'integration' into memory_api 2025-09-05 09:43:38 -05:00
J. Nick Koston
0dfa34d961 Merge branch 'light_missing_macros' into integration 2025-09-05 09:43:33 -05:00
J. Nick Koston
4969b8ab80 [light] ESP8266: Store log strings in flash memory 2025-09-05 09:42:53 -05:00
J. Nick Koston
5760d5c995 Merge branch 'integration' into memory_api 2025-09-05 09:22:50 -05:00
J. Nick Koston
2c571dbe68 Merge branch 'gpio_binary_sensor_progmem_logs' into integration 2025-09-05 09:22:43 -05:00
J. Nick Koston
fd67da9fb0 [gpio] ESP8266: Store log strings in flash memory 2025-09-05 09:22:06 -05:00
J. Nick Koston
62fbda4cc3 Merge branch 'integration' into memory_api 2025-09-05 09:14:09 -05:00
J. Nick Koston
a580d83954 Merge branch 'web_server_8266_store_flash' into integration 2025-09-05 09:14:04 -05:00
J. Nick Koston
f67c5fbab2 [web_server] ESP8266: Move strings to PROGMEM (saves 128 bytes RAM) 2025-09-05 09:13:15 -05:00
J. Nick Koston
33697e95ac Merge branch 'captive_portal_progmem_8266' into memory_api 2025-09-05 08:43:02 -05:00
J. Nick Koston
14b0a84ca7 Merge branch 'captive_portal_progmem_8266' into integration 2025-09-05 08:42:58 -05:00
J. Nick Koston
3f622169b9 missed one 2025-09-05 08:42:46 -05:00
J. Nick Koston
894bbd27c3 Merge branch 'integration' into memory_api 2025-09-05 08:32:09 -05:00
J. Nick Koston
8a53229bfb Merge branch 'captive_portal_progmem_8266' into integration 2025-09-05 08:32:01 -05:00
J. Nick Koston
a8352ef2cb preen 2025-09-05 08:29:32 -05:00
J. Nick Koston
6ff31bdbbf fix refactoring error 2025-09-05 08:27:39 -05:00
Keith Burzinski
86c2af4882 [sen5x] Fix initialization (#10603) 2025-09-05 18:37:57 +12:00
J. Nick Koston
eb666324fe Merge branch 'integration' into memory_api 2025-09-04 23:32:23 -05:00
J. Nick Koston
fde9d70f95 Merge branch 'captive_portal_progmem_8266' into integration 2025-09-04 23:32:15 -05:00
J. Nick Koston
089430abc9 [captive_portal] ESP8266: Move strings to PROGMEM (saves 192 bytes RAM) 2025-09-04 23:31:44 -05:00
J. Nick Koston
b4b795dcaf [i2c] Optimize memory usage with stack allocation for small buffers (#10565)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-09-05 04:26:46 +00:00
J. Nick Koston
2433ac4821 Merge branch 'integration' into memory_api 2025-09-04 22:58:41 -05:00
J. Nick Koston
f53c9be729 Merge branch 'mdns_progmem' into integration 2025-09-04 22:58:35 -05:00
J. Nick Koston
639b924be3 [mdns] Move constant strings to flash on ESP8266 2025-09-04 22:57:44 -05:00
J. Nick Koston
cf7140ce1a Merge branch 'integration' into memory_api 2025-09-04 22:29:59 -05:00
J. Nick Koston
38ccfc7b5c Merge branch 'noise_prologue_flash_esp8266' into integration 2025-09-04 22:29:53 -05:00
J. Nick Koston
e2b6efd8de [api] Store Noise protocol prologue in flash on ESP8266 2025-09-04 22:28:42 -05:00
J. Nick Koston
f762d3a6e2 Merge branch 'integration' into memory_api 2025-09-04 21:42:14 -05:00
J. Nick Koston
c45b8a33d4 Merge branch 'align_resolver' into integration 2025-09-04 21:42:09 -05:00
J. Nick Koston
830b9a881a redesign 2025-09-04 21:39:50 -05:00
pre-commit-ci-lite[bot]
6ab0581c93 [pre-commit.ci lite] apply automatic fixes 2025-09-05 02:12:35 +00:00
J. Nick Koston
f836b71e1c Update test_resolver.py 2025-09-04 21:11:22 -05:00
J. Nick Koston
f18303fe2b fix test 2025-09-04 20:56:05 -05:00
J. Nick Koston
3fc928f5d1 fix, cover 2025-09-04 20:17:08 -05:00
J. Nick Koston
2d37518c00 fix, cover 2025-09-04 20:16:30 -05:00
dependabot[bot]
b8ed7ec145 Bump aioesphomeapi from 40.0.0 to 40.0.1 (#10596)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-05 01:08:15 +00:00
J. Nick Koston
a282920d7c fix, cover 2025-09-04 20:06:55 -05:00
J. Nick Koston
d7aec744b7 preen 2025-09-04 20:00:31 -05:00
J. Nick Koston
ccbe629f8d Fix DNS resolution inconsistency between logs and OTA operations 2025-09-04 19:58:44 -05:00
dependabot[bot]
365a427b57 Bump aioesphomeapi from 39.0.1 to 40.0.0 (#10594)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 23:37:03 +00:00
dependabot[bot]
e327ae8c95 Bump pytest-mock from 3.14.1 to 3.15.0 (#10593)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 23:36:11 +00:00
J. Nick Koston
d5f855004e Merge branch 'integration' into memory_api 2025-09-04 14:45:52 -05:00
J. Nick Koston
85b8925d17 Merge branch 'sx1509_gpio_cache' into integration 2025-09-04 14:45:46 -05:00
J. Nick Koston
245c36e628 fix 2025-09-04 14:45:34 -05:00
J. Nick Koston
025da5ac30 Merge branch 'integration' into memory_api 2025-09-04 14:40:26 -05:00
J. Nick Koston
140b970ac5 Merge branch 'pca6414a_cached_gpio_expander' into integration 2025-09-04 14:40:15 -05:00
J. Nick Koston
87b6fbfb47 Merge branch 'mcp_23016_gpio_cache' into integration 2025-09-04 14:40:12 -05:00
J. Nick Koston
ead5ba4da6 Merge branch 'sx1509_gpio_cache' into integration 2025-09-04 14:40:07 -05:00
J. Nick Koston
06833d6f8b [sx1509] Migrate to CachedGpioExpander to reduce I2C bus usage 2025-09-04 14:36:27 -05:00
J. Nick Koston
d9ded6b87e [sx1509] Migrate to CachedGpioExpander to reduce I2C bus usage 2025-09-04 14:35:34 -05:00
dependabot[bot]
4c2f356b35 Bump ruff from 0.12.11 to 0.12.12 (#10578)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-09-04 19:24:23 +00:00
J. Nick Koston
977f07c338 [pca6416a] Migrate to reduce I2C bus usage 2025-09-04 14:22:33 -05:00
dependabot[bot]
e55bce83e3 Bump actions/stale from 9.1.0 to 10.0.0 (#10582)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 14:20:11 -05:00
dependabot[bot]
ba2433197e Bump actions/github-script from 7.0.1 to 8.0.0 (#10583)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 14:16:17 -05:00
dependabot[bot]
c471bdb446 Bump actions/setup-python from 5.6.0 to 6.0.0 in /.github/actions/restore-python (#10586)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 14:15:57 -05:00
dependabot[bot]
cbac9caa52 Bump actions/setup-python from 5.6.0 to 6.0.0 (#10584)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 14:15:43 -05:00
dependabot[bot]
edf7094662 Bump esphome-dashboard from 20250828.0 to 20250904.0 (#10580)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 14:14:50 -05:00
dependabot[bot]
25489b6009 Bump codecov/codecov-action from 5.5.0 to 5.5.1 (#10585)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 14:14:28 -05:00
dependabot[bot]
dc45a613f3 Bump pytest from 8.4.1 to 8.4.2 (#10579)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 14:14:18 -05:00
J. Nick Koston
053415a22e [mcp23016] Migrate to CachedGpioExpander to reduce I2C bus usage 2025-09-04 14:02:31 -05:00
J. Nick Koston
ed0b1b02ed Merge branch 'integration' into memory_api 2025-09-04 13:51:40 -05:00
J. Nick Koston
66d3e8c5c2 Merge branch 'pca9554_loop_churn_fix' into integration 2025-09-04 13:51:29 -05:00
J. Nick Koston
04a238d851 Merge branch 'optimize_pcf8574' into integration 2025-09-04 13:51:15 -05:00
J. Nick Koston
a63927a5f6 Merge branch 'gpio_expander_fix_more_than_8_pins_in_bank' into optimize_pcf8574 2025-09-04 13:51:05 -05:00
J. Nick Koston
c29c5b754a Merge branch 'gpio_expander_fix_more_than_8_pins_in_bank' into pca9554_loop_churn_fix 2025-09-04 13:50:39 -05:00
J. Nick Koston
2b4bf270fd Merge branch 'integration' into memory_api 2025-09-04 13:49:39 -05:00
J. Nick Koston
71c5f3c6b2 Merge branch 'gpio_expander_fix_more_than_8_pins_in_bank' into integration 2025-09-04 13:49:30 -05:00
J. Nick Koston
e843f1759b update docs 2025-09-04 13:49:19 -05:00
J. Nick Koston
feecc734fb update docs 2025-09-04 13:49:10 -05:00
J. Nick Koston
a6ed4bb844 Merge branch 'integration' into memory_api 2025-09-04 13:27:13 -05:00
J. Nick Koston
058f04232f Merge branch 'gpio_expander_fix_more_than_8_pins_in_bank' into integration 2025-09-04 13:27:07 -05:00
J. Nick Koston
ef50033766 [gpio_expander] Fix CachedGpioExpander template to support >8 pins per bank 2025-09-04 13:16:48 -05:00
J. Nick Koston
56652ce763 Merge branch 'integration' into memory_api 2025-09-04 13:10:35 -05:00
J. Nick Koston
5920508c32 Merge branch 'pca9554_loop_churn_fix' into integration 2025-09-04 13:10:31 -05:00
J. Nick Koston
d29586ba5a fix 2025-09-04 13:10:21 -05:00
J. Nick Koston
42c8624f95 Merge branch 'integration' into memory_api 2025-09-04 13:09:32 -05:00
J. Nick Koston
960590434c Merge branch 'pca9554_loop_churn_fix' into integration 2025-09-04 13:09:27 -05:00
J. Nick Koston
4065bdaea6 merge 2025-09-04 13:08:57 -05:00
J. Nick Koston
1528c06599 Merge branch 'integration' into memory_api 2025-09-04 13:05:31 -05:00
J. Nick Koston
b814edd43c Merge branch 'optimize_pcf8574' into integration 2025-09-04 13:05:23 -05:00
J. Nick Koston
2d409b017e Merge branch 'optimize_pcf8574' into memory_api 2025-09-04 13:05:15 -05:00
J. Nick Koston
20d3e4a1b8 Merge branch 'integration' into memory_api 2025-09-04 13:05:08 -05:00
J. Nick Koston
c36dc5c4ad Merge branch 'pca9554_loop_churn_fix' into integration 2025-09-04 13:05:04 -05:00
J. Nick Koston
cf9c8e3786 update pca as well 2025-09-04 13:03:33 -05:00
J. Nick Koston
5b0d1fb30e cleanup 2025-09-04 12:57:44 -05:00
J. Nick Koston
ee090c7c38 cleanup 2025-09-04 12:32:52 -05:00
J. Nick Koston
e866ae0f50 handle 16 pins 2025-09-04 12:28:23 -05:00
J. Nick Koston
f5dbc44662 Merge branch 'optimize_pcf8574' into memory_api 2025-09-04 12:24:02 -05:00
J. Nick Koston
75de980f58 Merge branch 'optimize_pcf8574' into integration 2025-09-04 12:23:58 -05:00
J. Nick Koston
4885819881 use helper 2025-09-04 12:21:48 -05:00
J. Nick Koston
ec88aefebf Merge branch 'integration' into memory_api 2025-09-04 11:21:29 -05:00
J. Nick Koston
03c64b1ae5 Merge branch 'pca9554_loop_churn_fix' into integration 2025-09-04 11:21:22 -05:00
J. Nick Koston
c1c522dc08 fix stale comment 2025-09-04 11:21:17 -05:00
J. Nick Koston
0585f05d90 Merge branch 'optimize_pcf8574' into memory_api 2025-09-04 11:20:27 -05:00
J. Nick Koston
8211220cc4 Merge branch 'optimize_pcf8574' into integration 2025-09-04 11:20:21 -05:00
J. Nick Koston
784d547294 correctness 2025-09-04 11:19:30 -05:00
dependabot[bot]
e0617e01e0 Bump pypa/gh-action-pypi-publish from 1.12.4 to 1.13.0 in /.github/workflows (#10572)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 11:10:53 -05:00
J. Nick Koston
526ba902ae Merge branch 'integration' into memory_api 2025-09-04 11:04:30 -05:00
J. Nick Koston
339a2e2d0f Merge branch 'optimize_pcf8574' into integration 2025-09-04 11:04:21 -05:00
J. Nick Koston
1d91bf5759 [pcf8574] Add lazy input caching to reduce I2C bus usage 2025-09-04 11:02:23 -05:00
J. Nick Koston
888a1539c5 Merge branch 'integration' into memory_api 2025-09-04 10:56:08 -05:00
J. Nick Koston
abb6e1c2ab Merge branch 'pca9554_loop_churn_fix' into integration 2025-09-04 10:55:54 -05:00
J. Nick Koston
d2a9e0ef7a build 2025-09-04 10:55:27 -05:00
J. Nick Koston
52ce1f8985 Merge branch 'integration' into memory_api 2025-09-04 10:53:37 -05:00
J. Nick Koston
2d84834d6d Merge branch 'pca9554_loop_churn_fix' into integration 2025-09-04 10:53:31 -05:00
J. Nick Koston
cd4a6bbe37 add myself since I use this in production now and will be swithing more devices to use it 2025-09-04 10:52:47 -05:00
J. Nick Koston
30ed4717de Merge branch 'integration' into memory_api 2025-09-04 10:43:24 -05:00
J. Nick Koston
727b271079 Merge branch 'pca9554_loop_churn_fix' into integration 2025-09-04 10:43:19 -05:00
J. Nick Koston
faca78aeb9 [pca9554] Reduce I2C bus usage with lazy input caching 2025-09-04 10:33:05 -05:00
J. Nick Koston
b0ec9abbc4 Merge branch 'i2c_std_vector_heap' into memory_api 2025-09-04 10:14:22 -05:00
J. Nick Koston
b1413ac0e0 Merge branch 'integration' into memory_api 2025-09-04 09:06:59 -05:00
J. Nick Koston
80ed40426a Merge branch 'logger_8266_str_to_flash' into integration 2025-09-04 09:06:54 -05:00
J. Nick Koston
e6ab45a78d esp32 fix 2025-09-04 09:06:11 -05:00
J. Nick Koston
049606607a Merge branch 'ota_esp8266_logstr' into memory_api 2025-09-04 09:02:48 -05:00
J. Nick Koston
8fdb62b4f7 Merge branch 'ota_esp8266_logstr' into integration 2025-09-04 09:02:41 -05:00
J. Nick Koston
2e7ebc6258 [esphome] Store OTA component log strings in flash on ESP8266 2025-09-04 09:01:59 -05:00
J. Nick Koston
b5df54d900 Merge branch 'integration' into memory_api 2025-09-04 08:58:18 -05:00
J. Nick Koston
072bbcd30b Merge branch 'logger_8266_str_to_flash' into integration 2025-09-04 08:58:12 -05:00
J. Nick Koston
b4154831a6 cleanup 2025-09-04 08:58:03 -05:00
J. Nick Koston
81783ef49d cleanup 2025-09-04 08:57:43 -05:00
J. Nick Koston
85314be7a2 Merge branch 'logger_8266_str_to_flash' into memory_api 2025-09-04 08:53:18 -05:00
J. Nick Koston
8d7dfc1a75 Merge branch 'logger_8266_str_to_flash' into integration 2025-09-04 08:53:13 -05:00
J. Nick Koston
313556bb49 [esp8266][logger] Store LOG_LEVELS strings in PROGMEM to reduce RAM usage 2025-09-04 08:52:06 -05:00
J. Nick Koston
a58b7abde7 Merge branch 'integration' into memory_api 2025-09-04 08:37:41 -05:00
J. Nick Koston
faa243227f Merge branch 'esp8266_api_progmem' into integration 2025-09-04 08:37:35 -05:00
J. Nick Koston
70da50b32f [esp8266][api] Store error strings in PROGMEM to reduce RAM usage 2025-09-04 08:32:49 -05:00
J. Nick Koston
85a4a61d14 [i2c] Optimize memory usage with stack allocation for small buffers 2025-09-04 08:07:22 -05:00
Jesse Hills
c7ee727af4 Merge branch 'release' into dev 2025-09-04 22:10:21 +12:00
Jesse Hills
c5b2a9e24b Merge pull request #10558 from esphome/bump-2025.8.3
2025.8.3
2025-09-04 22:09:37 +12:00
J. Nick Koston
101d553df9 [esp8266] Reduce preference memory usage by 40% through field optimization (#10557) 2025-09-04 02:46:50 -05:00
J. Nick Koston
8fb6420b1c [esp8266] Store GPIO initialization arrays in PROGMEM to save RAM (#10560) 2025-09-04 02:44:12 -05:00
J. Nick Koston
e1b9b57cd7 Merge branch 'esp8266_gpio_progmem' into memory_api 2025-09-03 22:58:53 -05:00
J. Nick Koston
07fba41139 Merge branch 'esp8266_gpio_progmem' into integration 2025-09-03 22:58:48 -05:00
J. Nick Koston
0fa3d79c38 fixes 2025-09-03 22:58:35 -05:00
J. Nick Koston
27594869e2 fixes 2025-09-03 22:58:14 -05:00
J. Nick Koston
7587be3dfd Merge branch 'integration' into memory_api 2025-09-03 22:57:33 -05:00
J. Nick Koston
4cc17031a0 Merge branch 'esp8266_gpio_progmem' into integration 2025-09-03 22:57:23 -05:00
J. Nick Koston
ace79b1886 fixes 2025-09-03 22:57:15 -05:00
J. Nick Koston
28c2af69ea Merge branch 'integration' into memory_api 2025-09-03 22:56:34 -05:00
J. Nick Koston
5026406d90 Merge branch 'esp8266_gpio_progmem' into integration 2025-09-03 22:56:27 -05:00
J. Nick Koston
87f40cf24a cleanup 2025-09-03 22:56:15 -05:00
J. Nick Koston
897bb4d13f [esp8266] Store GPIO initialization arrays in PROGMEM to save RAM 2025-09-03 22:53:24 -05:00
J. Nick Koston
c57631394c Revert "[esp8266] Store component source strings in PROGMEM to save RAM"
This reverts commit ea01cc598b.
2025-09-03 22:17:41 -05:00
J. Nick Koston
aadbc41d6a Revert "preen"
This reverts commit da9a7c41d1.
2025-09-03 22:17:36 -05:00
J. Nick Koston
2d3243d631 Revert "[esp8266] Store component source strings in PROGMEM to save RAM"
This reverts commit ea01cc598b.
2025-09-03 22:16:59 -05:00
J. Nick Koston
105e94db2e Revert "preen"
This reverts commit da9a7c41d1.
2025-09-03 22:16:41 -05:00
J. Nick Koston
32fec42130 Merge branch 'integration' into memory_api 2025-09-03 22:06:30 -05:00
J. Nick Koston
b04f4e949d Merge branch 'esp8266_component_source_progmem' into integration 2025-09-03 22:06:22 -05:00
J. Nick Koston
da9a7c41d1 preen 2025-09-03 22:05:21 -05:00
J. Nick Koston
ea01cc598b [esp8266] Store component source strings in PROGMEM to save RAM 2025-09-03 21:56:47 -05:00
Maxim Raznatovski
c03d978b46 [wizard] extend the wizard dashboard API to allow upload and empty config options (#10203) 2025-09-04 14:02:49 +12:00
J. Nick Koston
4766abc461 Merge branch 'integration' into memory_api 2025-09-03 19:11:03 -05:00
J. Nick Koston
e453da6161 Merge remote-tracking branch 'origin/esp8266_prefs' into memory_api 2025-09-03 19:10:44 -05:00
J. Nick Koston
64902373e4 Merge remote-tracking branch 'origin/esp8266_prefs' into integration 2025-09-03 19:10:37 -05:00
J. Nick Koston
3b4ed0a51f preen 2025-09-03 19:04:21 -05:00
J. Nick Koston
2d2ca0de52 Merge branch 'integration' into memory_api 2025-09-03 18:41:23 -05:00
J. Nick Koston
6cee81589e Merge remote-tracking branch 'origin/esp8266_prefs' into integration 2025-09-03 18:41:13 -05:00
J. Nick Koston
63cd8a6a58 [esp8266] Reduce preference memory usage by 40% through field optimization 2025-09-03 18:40:28 -05:00
J. Nick Koston
9495a885ed Merge branch 'integration' into memory_api 2025-09-03 17:56:30 -05:00
J. Nick Koston
8f2903dee8 Merge branch 'esp32_gpio_memory' into integration 2025-09-03 17:56:23 -05:00
J. Nick Koston
7249716a3c [esp32] Reduce GPIO memory usage by 50% through bit-packing 2025-09-03 17:53:48 -05:00
J. Nick Koston
6c3dba06ba Merge branch 'integration' into memory_api 2025-09-03 16:37:56 -05:00
J. Nick Koston
0ffd011286 Merge branch 'reduce_scheduler_item_memory' into integration 2025-09-03 16:37:20 -05:00
J. Nick Koston
1298268937 Update esphome/core/scheduler.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-03 16:37:01 -05:00
J. Nick Koston
26e0151fee Update esphome/core/scheduler.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-03 16:36:49 -05:00
J. Nick Koston
4192930b0f Merge remote-tracking branch 'upstream/reduce_scheduler_item_memory' into reduce_scheduler_item_memory 2025-09-03 16:35:28 -05:00
J. Nick Koston
ca0029e002 explain why its safe 2025-09-03 16:35:00 -05:00
J. Nick Koston
9d7f606a39 explain why its safe 2025-09-03 16:34:47 -05:00
J. Nick Koston
191e9dedc5 Update esphome/core/scheduler.h 2025-09-03 16:30:37 -05:00
J. Nick Koston
93c453c8f9 Merge branch 'integration' into memory_api 2025-09-03 16:23:14 -05:00
J. Nick Koston
34472313f4 Merge branch 'reduce_scheduler_item_memory' into integration 2025-09-03 16:22:50 -05:00
J. Nick Koston
ce0271aab1 Merge branch 'scheduler_pool_v2' into integration 2025-09-03 16:21:50 -05:00
J. Nick Koston
d505f5ecaa [scheduler] Reduce SchedulerItem memory usage by 7.4% on 32-bit platforms 2025-09-03 16:13:07 -05:00
Jesse Hills
2d3cdf60ba Bump version to 2025.8.3 2025-09-04 09:06:00 +12:00
J. Nick Koston
a29fef166b [api] Fix VERY_VERBOSE logging compilation error with bool arrays (#10539) 2025-09-04 09:06:00 +12:00
Jonathan Swoboda
9fe94f1201 [esp32] Clear IDF environment variables (#10527)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-09-04 09:06:00 +12:00
Anton Viktorov
1b8978a89a [i2c] Fix bug write_register16 (#10547) 2025-09-04 09:06:00 +12:00
Jonathan Swoboda
6f188d1284 [esp32] Rebuild when idf_component.yml changes (#10540) 2025-09-04 09:06:00 +12:00
Clyde Stubbs
a1a336783e [mcp4461] Fix read transaction (#10465)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-04 09:06:00 +12:00
Clyde Stubbs
c55bc93f70 [mipi_dsi] Fix config for Guition screen (#10464) 2025-09-04 09:06:00 +12:00
J. Nick Koston
de998f2f39 Fix incorrect entity count due to undefined execution order with globals (#10497) 2025-09-04 09:06:00 +12:00
Oliver Kleinecke
950299e52b Update mcp4461.cpp (#10479) 2025-09-04 09:06:00 +12:00
J. Nick Koston
00ea769787 Merge branch 'dev' into scheduler_pool_v2 2025-09-03 15:31:41 -05:00
J. Nick Koston
23c6650902 [api] Fix VERY_VERBOSE logging compilation error with bool arrays (#10539) 2025-09-04 08:07:13 +12:00
Jonathan Swoboda
5759692627 [esp32] Clear IDF environment variables (#10527)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-09-03 19:59:47 +00:00
Jonathan Swoboda
0ab65c225e [wifi] Check for esp32_hosted on no wifi variants (#10528) 2025-09-04 07:58:42 +12:00
J. Nick Koston
8aeb6d3ba2 [bluetooth_proxy] Change default for active connections to true (#10546) 2025-09-04 07:27:39 +12:00
Anton Viktorov
c3359edb33 [i2c] Fix bug write_register16 (#10547) 2025-09-03 17:18:26 +00:00
Jonathan Swoboda
4d681ffe3d [esp32] Rebuild when idf_component.yml changes (#10540) 2025-09-03 11:47:51 -04:00
J. Nick Koston
68628a85b1 [core] Use get_unit_of_measurement_ref() in entity logging to avoid string allocations (#10532) 2025-09-03 06:08:57 +00:00
J. Nick Koston
a9bd37bacd Merge branch 'integration' into memory_api 2025-09-02 23:32:49 -05:00
J. Nick Koston
3206afdc2a Merge branch 'scheduler_pool_v2' into integration 2025-09-02 23:32:37 -05:00
J. Nick Koston
af10a809de cleanup 2025-09-02 22:43:26 -05:00
J. Nick Koston
1a5402f35c preen 2025-09-02 22:27:40 -05:00
J. Nick Koston
9a6e678621 Merge remote-tracking branch 'upstream/dev' into scheduler_pool_v2 2025-09-02 21:31:24 -05:00
J. Nick Koston
4e54bd8c45 Merge remote-tracking branch 'upstream/dev' into scheduler_pool_v2 2025-09-02 21:31:12 -05:00
J. Nick Koston
086f1982fa [core] Use get_device_class_ref() in entity platform logging to avoid string allocations (#10531) 2025-09-03 14:26:53 +12:00
J. Nick Koston
5ba1c32242 [host] Fix memory allocation in preferences load() method (#10506) 2025-09-03 14:26:43 +12:00
J. Nick Koston
d2b23ba3a7 [sensor] Change state_class_to_string() to return const char* to avoid allocations (#10533) 2025-09-03 14:24:16 +12:00
J. Nick Koston
83fbd77c4a [core] Use get_icon_ref() in entity platform logging to avoid string allocations (#10530) 2025-09-03 14:23:46 +12:00
J. Nick Koston
1a054299d4 [core] Optimize fnv1_hash to avoid string allocations for static entities (#10529) 2025-09-02 21:17:14 -05:00
J. Nick Koston
5aa54bfff4 preen 2025-09-02 20:30:16 -05:00
J. Nick Koston
91eabc983e cleanup 2025-09-02 20:20:02 -05:00
J. Nick Koston
3066afef24 fix churn on last itme 2025-09-02 20:07:47 -05:00
J. Nick Koston
979a021a27 preen 2025-09-02 19:55:38 -05:00
J. Nick Koston
e90ae09354 preen 2025-09-02 19:54:01 -05:00
J. Nick Koston
c8a4a3b752 more churn 2025-09-02 19:52:44 -05:00
J. Nick Koston
41628d2193 improve debug logging 2025-09-02 19:47:15 -05:00
J. Nick Koston
be4c8956ad debug 2025-09-02 19:39:49 -05:00
J. Nick Koston
6e14050351 preen 2025-09-02 19:11:14 -05:00
J. Nick Koston
0c5b63c382 preen 2025-09-02 18:59:54 -05:00
Jonathan Swoboda
e3fb9c2a78 [esp32] Remove hardcoding of ulp (#10535) 2025-09-02 23:51:17 +00:00
J. Nick Koston
43634257f6 fix defer churn 2025-09-02 18:43:38 -05:00
J. Nick Koston
d1276dc6df [core] Replace magic coroutine priority numbers with self-documenting CoroPriority enum (#10518) 2025-09-02 21:41:50 +00:00
J. Nick Koston
d061feafdd Merge branch 'scheduler_pool_v2' into integration 2025-09-02 16:14:01 -05:00
J. Nick Koston
f72f80ed7b cleanup 2025-09-02 16:13:51 -05:00
J. Nick Koston
e0e8a982d5 improve pool hit rate 2025-09-02 16:12:59 -05:00
J. Nick Koston
b009a0f967 improve pool hit rate 2025-09-02 16:10:28 -05:00
J. Nick Koston
c4efdf5766 preen 2025-09-02 11:14:43 -05:00
J. Nick Koston
05c71bda91 preen 2025-09-02 11:10:46 -05:00
J. Nick Koston
ef33f630c2 preen 2025-09-02 11:07:13 -05:00
J. Nick Koston
3115c6fdbf preen 2025-09-02 11:05:42 -05:00
J. Nick Koston
154023f017 preen 2025-09-02 11:04:42 -05:00
J. Nick Koston
50f5728c76 preen 2025-09-02 11:00:18 -05:00
J. Nick Koston
4400535775 some tests 2025-09-02 10:45:59 -05:00
J. Nick Koston
4c12150200 debug logging 2025-09-02 10:31:27 -05:00
J. Nick Koston
2080f881da Merge branch 'integration' into memory_api 2025-09-02 10:18:22 -05:00
J. Nick Koston
86a6edd612 Merge branch 'scheduler_pool_v2' into integration 2025-09-02 10:18:16 -05:00
J. Nick Koston
4eb744d05e Merge branch 'integration' into memory_api 2025-09-02 10:11:55 -05:00
J. Nick Koston
1da1144e5b Merge remote-tracking branch 'upstream/dev' into integration 2025-09-02 10:11:50 -05:00
J. Nick Koston
ce4d422da8 comments 2025-09-02 10:06:51 -05:00
J. Nick Koston
98b8f15576 pool scheduler items 2025-09-02 08:48:39 -05:00
J. Nick Koston
98c1b01fe7 pool scheduler items 2025-09-02 08:47:07 -05:00
J. Nick Koston
1855877abe Merge branch 'integration' into memory_api 2025-09-02 08:00:14 -05:00
J. Nick Koston
01187a9000 Merge branch 'state_class_to_string_no_alloc' into integration 2025-09-02 08:00:04 -05:00
Eyal
f286bc57f3 [core] Fix timezone offset calculation (#10426) 2025-09-02 16:45:25 +12:00
J. Nick Koston
48070be829 [sensor] Change state_class_to_string() to return const char* to avoid allocations 2025-09-01 23:24:37 -05:00
J. Nick Koston
d738962d8d Merge branch 'integration' into memory_api 2025-09-01 23:14:34 -05:00
J. Nick Koston
3527ca75b6 Merge branch 'get_icon_avoid_string_alloc' into integration 2025-09-01 23:14:19 -05:00
J. Nick Koston
0affd158cb Merge branch 'get_device_class_avoid_string_alloc' into integration 2025-09-01 23:14:14 -05:00
J. Nick Koston
085647a1cd Merge branch 'get_uom_avoid_string_alloc' into integration 2025-09-01 23:14:06 -05:00
J. Nick Koston
4746eb65f7 [core] Use get_unit_of_measurement_ref() in entity logging to avoid string allocations 2025-09-01 23:11:47 -05:00
J. Nick Koston
4da18133f4 [core] Use get_device_class_ref() in entity platform logging to avoid string allocations 2025-09-01 23:07:33 -05:00
J. Nick Koston
ae46100af8 [core] Use get_icon_ref() in entity platform logging to avoid string allocations 2025-09-01 23:01:11 -05:00
J. Nick Koston
64a2b688a5 Merge branch 'integration' into memory_api 2025-09-01 22:34:38 -05:00
J. Nick Koston
e55b05ed32 Merge branch 'hash_avoid_temp_heap_std_string' into integration 2025-09-01 22:34:28 -05:00
J. Nick Koston
f75a50206f [core] Optimize fnv1_hash to avoid string allocations for static entities 2025-09-01 22:28:43 -05:00
Clyde Stubbs
ed48282d09 [mcp4461] Fix read transaction (#10465)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-02 08:53:03 +12:00
Clyde Stubbs
2ddd8c72d6 [mipi_dsi] Fix config for Guition screen (#10464) 2025-09-02 08:51:31 +12:00
Mischa Siekmann
d0b4bc48e4 [wifi] Guard wifi error cases introduced in IDF5.2 by a version check (#10466) 2025-09-02 08:51:03 +12:00
tomaszduda23
77dbe77117 [nrf52] fix missing bootloader (#10519) 2025-09-01 12:30:02 -05:00
J. Nick Koston
6daeffcefd [bluetooth_proxy] Expose configured scanning mode in API responses (#10490) 2025-09-01 13:07:29 +12:00
J. Nick Koston
6d834c019d Fix incorrect entity count due to undefined execution order with globals (#10497) 2025-09-01 13:01:15 +12:00
tomaszduda23
905e2906fe [nrf52] add dfu (#9319)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-01 10:54:35 +12:00
Jesse Hills
a25b544c3b [display] Allow page actions to have auto generated display id (#10460) 2025-09-01 09:22:11 +12:00
Felix Kaechele
da21174c6d [sntp] Use callbacks to trigger on_time_sync for ESP32 and ESP8266 (#10390)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-09-01 09:02:56 +12:00
DT-art1
e29f0ee7f8 Add JPEG encoder support via new camera_encoder component (#9459)
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>
2025-08-31 09:26:15 -05:00
Jesse Hills
983b3cb879 [mipi] Add type to models for better type hinting downstream (#10475) 2025-08-30 16:43:26 +10:00
J. Nick Koston
9ebdfde287 Merge branch 'integration' into memory_api 2025-08-29 22:11:17 -05:00
J. Nick Koston
fb234ee9bf Merge branch 'entity_count_order_fix' into integration 2025-08-29 22:11:09 -05:00
J. Nick Koston
8be40bf1ca Fix incorrect entity count when lambdas are present (priority ordering issue) 2025-08-29 18:21:41 -05:00
J. Nick Koston
bcea7e9fb1 Merge branch 'integration' into memory_api 2025-08-29 10:49:02 -05:00
J. Nick Koston
d8fbe2457e Merge remote-tracking branch 'upstream/proxy_configured_mode' into integration 2025-08-29 10:48:51 -05:00
dependabot[bot]
fd568d9af3 Bump aioesphomeapi from 39.0.0 to 39.0.1 (#10491)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-29 10:14:15 -05:00
J. Nick Koston
a6eaf59eff [bluetooth_proxy] Expose configured scanning mode in API responses 2025-08-29 08:59:09 -05:00
Clyde Stubbs
ca72286386 [lvgl] Update hello world (#10469) 2025-08-29 15:42:39 +10:00
Ben Curtis
dea68bebd8 Adjust sen5x to match VOC/NOX datasheet (#9894)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-08-29 14:00:54 +12:00
Clyde Stubbs
ef98f67b41 [lvgl] Replace spinbox step with selected_digit (#10349)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-08-29 13:58:58 +12:00
Oliver Kleinecke
6a92b691a0 Update mcp4461.cpp (#10479) 2025-08-29 12:53:54 +12:00
Clyde Stubbs
bc960cf6d2 [mapping] Use custom allocator (#9972) 2025-08-29 12:52:37 +12:00
Jesse Hills
461ce69296 Merge branch 'release' into dev 2025-08-29 12:39:26 +12:00
Jesse Hills
6a20e6f9ad Merge pull request #10485 from esphome/bump-2025.8.2
2025.8.2
2025-08-29 12:38:45 +12:00
dependabot[bot]
cde00a1f4c Bump esphome-dashboard from 20250814.0 to 20250828.0 (#10484)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-29 11:02:15 +12:00
J. Nick Koston
5dc691874b [bluetooth_proxy] Remove unused ClientState::SEARCHING state (#10318) 2025-08-29 10:30:14 +12:00
dependabot[bot]
c526ab9a3f Bump ruff from 0.12.10 to 0.12.11 (#10483)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-08-28 22:20:23 +00:00
Jesse Hills
07875a8b1e Bump version to 2025.8.2 2025-08-29 10:16:19 +12:00
J. Nick Koston
ba4789970c [esphome] Fix OTA watchdog resets by validating all magic bytes before blocking (#10401) 2025-08-29 10:16:19 +12:00
Vinicius Fortuna
015977cfdf [rtttl] Fix RTTTL for speakers (#10381) 2025-08-29 10:16:19 +12:00
J. Nick Koston
e513c0f004 Fix AttributeError when uploading OTA to offline OpenThread devices (#10459) 2025-08-29 10:16:19 +12:00
Clyde Stubbs
a11970aee0 [wifi] Fix retry with hidden networks. (#10445) 2025-08-29 10:16:19 +12:00
Clyde Stubbs
4ab37b069b [i2c] Perform register reads as single transactions (#10389)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-08-29 10:16:08 +12:00
Clyde Stubbs
b6bb6699d1 [mipi_spi] Fix dimensions (#10443) 2025-08-29 10:15:30 +12:00
J. Nick Koston
078eaff9a8 [wifi] Fix reconnection failures after adapter restart by not clearing netif pointers (#10458) 2025-08-29 10:15:30 +12:00
J. Nick Koston
a7786b75a0 [esp32_ble_tracker] Remove duplicate client promotion logic (#10321) 2025-08-29 10:14:51 +12:00
J. Nick Koston
d4c11dac8c [esphome] Fix OTA watchdog resets by validating all magic bytes before blocking (#10401) 2025-08-29 10:12:38 +12:00
DAVe3283
2f2f2f7d15 [absolute_humidity] Fix typo (#10474) 2025-08-29 10:04:19 +12:00
J. Nick Koston
a92a08c2de [api] Fix string lifetime issue in fill_and_encode_entity_info for dynamic object_id (#10482) 2025-08-28 18:40:36 +00:00
J. Nick Koston
c828941e16 Merge branch 'integration' into memory_api 2025-08-28 13:13:27 -05:00
J. Nick Koston
a8df3fa249 Merge branch 'fix_string_lifetime_fill_and_encode_entity_info' into integration 2025-08-28 13:13:18 -05:00
J. Nick Koston
4930027557 [api] Fix string lifetime issue in fill_and_encode_entity_info for dynamic object_id 2025-08-28 13:11:58 -05:00
Vinicius Fortuna
75595b08be [rtttl] Fix RTTTL for speakers (#10381) 2025-08-28 13:53:57 +12:00
J. Nick Koston
3c7aba0681 Fix AttributeError when uploading OTA to offline OpenThread devices (#10459) 2025-08-28 09:23:43 +12:00
Clyde Stubbs
e5d1c30797 [wifi] Fix retry with hidden networks. (#10445) 2025-08-28 09:16:26 +12:00
J. Nick Koston
c90b4c0f81 Merge branch 'integration' into memory_api 2025-08-27 09:47:26 -05:00
J. Nick Koston
0df992ee44 Merge remote-tracking branch 'upstream/dev' into integration 2025-08-27 09:47:18 -05:00
J. Nick Koston
2f699b3c20 Merge branch 'integration' into memory_api 2025-08-27 09:47:03 -05:00
J. Nick Koston
170f99ee08 Merge branch 'ota_magic_validation' into integration 2025-08-27 09:46:58 -05:00
Clyde Stubbs
c171d13c8c [i2c] Perform register reads as single transactions (#10389)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-08-27 19:30:33 +10:00
Clyde Stubbs
65d63de9b6 [mipi_spi] Fix dimensions (#10443) 2025-08-27 19:30:01 +10:00
J. Nick Koston
9e712e4127 [wifi] Fix reconnection failures after adapter restart by not clearing netif pointers (#10458) 2025-08-26 23:49:47 -05:00
J. Nick Koston
001d05b8f2 Merge branch 'integration' into memory_api 2025-08-26 18:22:10 -05:00
J. Nick Koston
be7578ef9a Merge branch 'none_address_fix' into integration 2025-08-26 18:22:05 -05:00
J. Nick Koston
ed7054cdb7 Fix AttributeError when uploading OTA to offline OpenThread devices 2025-08-26 18:20:38 -05:00
J. Nick Koston
a61300b82f Merge branch 'integration' into memory_api 2025-08-26 17:22:56 -05:00
J. Nick Koston
830e8969a3 Merge branch 'partial_revert_wifi_race_fix' into integration 2025-08-26 17:22:50 -05:00
J. Nick Koston
6e681a5f3e [wifi] Fix reconnection failures after adapter restart by not clearing netif pointers 2025-08-26 17:20:55 -05:00
J. Nick Koston
9e0600ec45 Merge branch 'integration' into memory_api 2025-08-26 16:34:04 -05:00
J. Nick Koston
7a7a6825a2 Merge branch 'dev' into integration 2025-08-26 16:33:49 -05:00
Clyde Stubbs
9007621fd7 Revert "[core] Dont copy platform source files if there are no entities of that type" (#10441) 2025-08-26 09:15:44 +10:00
Thomas Rupprecht
c01a26607e improve const imports of esphome.const (#10438) 2025-08-26 09:45:03 +12:00
Jesse Hills
f6ca70970f Merge branch 'release' into dev 2025-08-26 08:48:51 +12:00
Jesse Hills
4dc11f05a7 Merge pull request #10427 from esphome/bump-2025.8.1
2025.8.1
2025-08-26 08:48:10 +12:00
Jesse Hills
5e508f7461 [core] Dont copy platform source files if there are no entities of that type (#10436) 2025-08-25 14:46:54 -05:00
Jonathan Rascher
2aceb56606 Merge commit from fork
Ensures auth check doesn't pass erroneously when the client-supplied
digest is shorter than the correct digest, but happens to match a
prefix of the correct value (e.g., same username + certain substrings of
the password).
2025-08-25 16:00:04 +12:00
Jesse Hills
d071a074ef Bump version to 2025.8.1 2025-08-25 15:59:35 +12:00
Clyde Stubbs
7a459c8c20 [web_server] Use oi.esphome.io for css and js assets (#10296) 2025-08-25 15:59:35 +12:00
J. Nick Koston
aebd21958a [test] Add integration test for light effect memory corruption fix (#10417) 2025-08-25 15:59:35 +12:00
J. Nick Koston
c542db8bfe [esp32_ble_tracker] Fix on_scan_end trigger compilation without USE_ESP32_BLE_DEVICE (#10399) 2025-08-25 15:59:35 +12:00
Clyde Stubbs
d9dcfe66ec [lvgl] Fix meter rotation (#10342) 2025-08-25 15:59:35 +12:00
J. Nick Koston
8517c2e903 [esp32_ble_client] Reduce log level for harmless BLE timeout race conditions (#10339)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-25 15:59:34 +12:00
J. Nick Koston
684384892a [deep_sleep] Fix ESP32-C6 compilation error with gpio_deep_sleep_hold_en() (#10345) 2025-08-25 15:59:34 +12:00
J. Nick Koston
d560831d79 [script] Fix parallel mode scripts with delays cancelling each other (#10324) 2025-08-25 15:59:34 +12:00
J. Nick Koston
fcc3c8e1b6 [esp32_ble] Increase GATT connection retry count to use full timeout window (#10376) 2025-08-25 15:59:34 +12:00
J. Nick Koston
959ffde60e [esp32_ble_client] Optimize BLE connection parameters for different connection types (#10356) 2025-08-25 15:59:34 +12:00
J. Nick Koston
07715dd50f [pvvx_mithermometer] Fix race condition with BLE authentication (#10327) 2025-08-25 15:59:34 +12:00
J. Nick Koston
03836ee2d2 [core] Improve error reporting for entity name conflicts with non-ASCII characters (#10329) 2025-08-25 15:59:34 +12:00
Clyde Stubbs
50408d9abb [http_request] Fix for host after ArduinoJson library bump (#10348) 2025-08-25 15:59:34 +12:00
Jesse Hills
0de7259428 [api] Add `USE_API_HOMEASSISTANT_SERVICES if using tag_scanned` action (#10316) 2025-08-25 15:59:34 +12:00
J. Nick Koston
d054709c2d [esp32_ble_client] Add log helper functions to reduce flash usage by 120 bytes (#10243) 2025-08-25 15:59:34 +12:00
J. Nick Koston
da16887915 [api] Add zero-copy StringRef methods for compilation_time and effect_name (#10257) 2025-08-25 15:59:34 +12:00
Jonathan Rascher
6da8ec8d55 Merge commit from fork
Ensures auth check doesn't pass erroneously when the client-supplied
digest is shorter than the correct digest, but happens to match a
prefix of the correct value (e.g., same username + certain substrings of
the password).
2025-08-25 15:40:19 +12:00
J. Nick Koston
d2752b38c9 [core] Fix preference storage to account for device_id (#10333)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-25 12:22:16 +12:00
J. Nick Koston
6004367ee2 [esp32_ble_client] Add missing ESP_GATTC_UNREG_FOR_NOTIFY_EVT logging (#10347) 2025-08-25 12:07:04 +12:00
Thomas Rupprecht
ecfeb8e4d3 improve AI instructions (#10416) 2025-08-25 11:51:28 +12:00
Clyde Stubbs
456c31262d [web_server] Use oi.esphome.io for css and js assets (#10296) 2025-08-25 09:04:32 +12:00
J. Nick Koston
9f02575287 [test] Add integration test for light effect memory corruption fix (#10417) 2025-08-25 08:58:46 +12:00
J. Nick Koston
07bca6103f [esp32_ble_tracker] Fix on_scan_end trigger compilation without USE_ESP32_BLE_DEVICE (#10399) 2025-08-25 08:57:09 +12:00
Clyde Stubbs
a58c3950bc [lvgl] Fix meter rotation (#10342) 2025-08-25 06:52:37 +10:00
J. Nick Koston
8fe582309e [esp32_ble_client] Reduce log level for harmless BLE timeout race conditions (#10339)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-25 08:51:54 +12:00
J. Nick Koston
b41a61c76e [deep_sleep] Fix ESP32-C6 compilation error with gpio_deep_sleep_hold_en() (#10345) 2025-08-25 08:51:23 +12:00
J. Nick Koston
61a5023888 [script] Fix parallel mode scripts with delays cancelling each other (#10324) 2025-08-25 08:49:52 +12:00
J. Nick Koston
4396bc0d1a [esp32_ble] Increase GATT connection retry count to use full timeout window (#10376) 2025-08-25 08:49:37 +12:00
J. Nick Koston
acfce581fa [esp32_ble_client] Optimize BLE connection parameters for different connection types (#10356) 2025-08-25 08:17:26 +12:00
J. Nick Koston
88303f39fa [pvvx_mithermometer] Fix race condition with BLE authentication (#10327) 2025-08-25 08:16:12 +12:00
J. Nick Koston
ca19959d7c [core] Improve error reporting for entity name conflicts with non-ASCII characters (#10329) 2025-08-25 08:11:54 +12:00
Clyde Stubbs
9737b35579 [http_request] Fix for host after ArduinoJson library bump (#10348) 2025-08-25 07:55:44 +12:00
Clyde Stubbs
be9c20c357 [mipi_spi] Add model (#10392) 2025-08-25 07:52:52 +12:00
Thomas Rupprecht
12ba4b142e Update Python to 3.11 in AI instructions (#10407) 2025-08-24 21:03:14 +12:00
Thomas Rupprecht
c096c6934d fix temperature config validation regex (#9575)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-08-24 08:56:06 +00:00
J. Nick Koston
bef783451b [esphome] Fix OTA watchdog resets by validating all magic bytes before blocking 2025-08-23 19:03:18 -05:00
J. Nick Koston
b871456c1e Merge branch 'integration' into memory_api 2025-08-23 16:19:19 -05:00
J. Nick Koston
5c6f92a83e Merge branch 'on_scan_end' into integration 2025-08-23 16:19:11 -05:00
J. Nick Koston
f4deb0f70b [esp32_ble_tracker] Fix on_scan_end trigger compilation without USE_ESP32_BLE_DEVICE 2025-08-23 14:41:45 -05:00
tomaszduda23
17f787fc36 [nrf52] fix build in dashboard (#10323) 2025-08-23 12:17:42 +00:00
tomaszduda23
5cd9a86dcb [nrf52] update toolchain to v0.17.4, support mac (#10391) 2025-08-23 16:20:16 +10:00
J. Nick Koston
e44eb59e3c Merge branch 'integration' into memory_api 2025-08-22 08:52:52 -05:00
J. Nick Koston
6e9acfdebd Merge branch 'ble_retries_no_give_up_before_timeout' into integration 2025-08-22 08:52:45 -05:00
J. Nick Koston
29b25194ba [esp32_ble] Increase GATT connection retry count to use full timeout window 2025-08-22 08:48:27 -05:00
J. Nick Koston
a38b994f2b [esp32_ble] Increase GATT connection retry count to use full timeout window 2025-08-22 08:45:35 -05:00
J. Nick Koston
101d98014d Merge branch 'integration' into memory_api 2025-08-21 21:47:24 -05:00
J. Nick Koston
9fd9c1b9d3 Merge branch 'connection_params' into integration 2025-08-21 21:47:16 -05:00
J. Nick Koston
7d7dbefb60 tweak 2025-08-21 21:46:36 -05:00
J. Nick Koston
caf4fcce5f Merge branch 'dev' into connection_params 2025-08-21 21:45:18 -05:00
J. Nick Koston
65eb57ca1b tweak 2025-08-21 21:44:59 -05:00
J. Nick Koston
082f795adc Merge branch 'integration' into memory_api 2025-08-21 20:27:21 -05:00
J. Nick Koston
f83f05b704 Merge branch 'connection_params' into integration 2025-08-21 20:27:15 -05:00
J. Nick Koston
9d16eeeb77 tweak 2025-08-21 20:27:04 -05:00
dependabot[bot]
83fe4b4ff3 Bump ruff from 0.12.9 to 0.12.10 (#10362)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-08-21 15:36:06 -05:00
J. Nick Koston
3ac5285515 Merge branch 'integration' into memory_api 2025-08-21 09:00:18 -05:00
J. Nick Koston
8f44ec0b51 Merge branch 'connection_params' into integration 2025-08-21 09:00:12 -05:00
J. Nick Koston
f12bcc621c dry, review 2025-08-21 09:00:01 -05:00
J. Nick Koston
2993940e1d Merge branch 'integration' into memory_api 2025-08-21 08:25:28 -05:00
J. Nick Koston
f4077fdd52 Merge branch 'connection_params' into integration 2025-08-21 08:25:23 -05:00
J. Nick Koston
1ba37ca7c9 preen 2025-08-21 08:25:13 -05:00
J. Nick Koston
db96cfaf14 Merge branch 'integration' into memory_api 2025-08-21 08:12:51 -05:00
J. Nick Koston
6054c3eac8 Merge branch 'connection_params' into integration 2025-08-21 08:12:43 -05:00
J. Nick Koston
2f101c0a20 [esp32_ble_client] Adjust connection parameters to improve device compatibility 2025-08-21 08:11:17 -05:00
Jesse Hills
94accd5abe [ld2420] Rename c++ files for predictable doxygen generation (#10315) 2025-08-21 18:49:26 +12:00
Jesse Hills
3ca0015284 [opentherm] Rename c++ files for predictable doxygen generation (#10314) 2025-08-21 18:48:48 +12:00
J. Nick Koston
bad7b0598b Merge branch 'integration' into memory_api 2025-08-20 20:26:20 -05:00
J. Nick Koston
840a814f75 Merge remote-tracking branch 'origin/event_39' into integration 2025-08-20 20:26:14 -05:00
J. Nick Koston
4dd01ea9ac [esp32_ble_client] Add missing ESP_GATTC_UNREG_FOR_NOTIFY_EVT logging 2025-08-20 20:25:50 -05:00
J. Nick Koston
b4f0d4b0c3 Merge branch 'integration' into memory_api 2025-08-20 20:24:31 -05:00
J. Nick Koston
7577153baa Merge remote-tracking branch 'origin/event_39' into integration 2025-08-20 20:24:22 -05:00
J. Nick Koston
a6850786e2 [esp32_ble_client] Add missing ESP_GATTC_UNREG_FOR_NOTIFY_EVT logging 2025-08-20 20:23:37 -05:00
J. Nick Koston
df7c2473c1 Merge branch 'integration' into memory_api 2025-08-20 20:07:21 -05:00
J. Nick Koston
18ad9804d3 Merge branch 'open_error_fix' into integration 2025-08-20 20:07:13 -05:00
J. Nick Koston
8ee46435a3 cleanup 2025-08-20 20:04:13 -05:00
dependabot[bot]
33eddb6035 Bump codecov/codecov-action from 5.4.3 to 5.5.0 (#10336)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-20 16:46:04 -05:00
J. Nick Koston
dde1cec3ce Merge branch 'integration' into memory_api 2025-08-20 14:54:39 -05:00
J. Nick Koston
fbd3cb0965 Merge branch 'open_error_fix' into integration 2025-08-20 14:54:31 -05:00
J. Nick Koston
977ff9b481 [esp32_ble_client] Fix race condition causing "ESP_GATTC_OPEN_EVT in IDLE state" error spam 2025-08-20 14:53:42 -05:00
J. Nick Koston
3c6a54bb70 Merge branch 'integration' into memory_api 2025-08-20 13:26:15 -05:00
J. Nick Koston
ec7919e294 Merge branch 'pvvx_mithermometer_defer_write' into integration 2025-08-20 13:26:09 -05:00
J. Nick Koston
5253b77cfe Merge branch 'improve_entity_error_reporting_sanitized_name' into integration 2025-08-20 13:26:04 -05:00
J. Nick Koston
77aba57078 Merge branch 'prefs_device_id' into integration 2025-08-20 13:26:00 -05:00
J. Nick Koston
6c01e7196c preen 2025-08-20 13:09:15 -05:00
J. Nick Koston
2c44198cb5 preen 2025-08-20 13:06:18 -05:00
J. Nick Koston
757ad2ff96 [core] Fix preference storage to account for device_id 2025-08-20 13:02:14 -05:00
J. Nick Koston
86c3812174 preen 2025-08-20 12:15:54 -05:00
J. Nick Koston
d182ce8bf6 preen 2025-08-20 12:12:39 -05:00
J. Nick Koston
ea5da950c0 [core] Improve error reporting for entity name conflicts with non-ASCII characters 2025-08-20 12:09:26 -05:00
J. Nick Koston
c88f2eb4d1 reduce 2025-08-20 11:38:07 -05:00
J. Nick Koston
998a9264a1 fix race 2025-08-20 10:05:46 -05:00
Jesse Hills
72c58ae36d [core] Add idf-tidy env for esp32-c6 (#10270) 2025-08-20 10:13:50 -04:00
J. Nick Koston
35411d199f [homeassistant] Add compilation test for homeassistant.tag_scanned action (#10319) 2025-08-20 10:10:20 -04:00
J. Nick Koston
6fd46966e2 Merge branch 'integration' into memory_api 2025-08-20 08:07:50 -05:00
J. Nick Koston
916c661544 Merge branch 'duplicate_stop_path' into integration 2025-08-20 08:07:45 -05:00
J. Nick Koston
4d4ab5b804 preen 2025-08-20 08:07:16 -05:00
J. Nick Koston
558cdda8a4 Merge branch 'integration' into memory_api 2025-08-20 08:06:47 -05:00
J. Nick Koston
3e1be2b987 Merge branch 'duplicate_stop_path' into integration 2025-08-20 08:06:39 -05:00
J. Nick Koston
d555766306 fix 2025-08-20 08:06:27 -05:00
J. Nick Koston
856ffc2e86 Merge branch 'integration' into memory_api 2025-08-20 07:46:07 -05:00
J. Nick Koston
5a740fb390 Merge branch 'remove_searching' into integration 2025-08-20 07:46:01 -05:00
J. Nick Koston
cdf85b419b Merge branch 'duplicate_stop_path' into integration 2025-08-20 07:45:56 -05:00
J. Nick Koston
d03eec5a58 [esp32_ble_tracker] Remove duplicate client promotion logic 2025-08-20 07:44:35 -05:00
J. Nick Koston
9f4e31b07c preen 2025-08-20 07:01:13 -05:00
J. Nick Koston
df0ed57667 preen 2025-08-20 06:58:43 -05:00
J. Nick Koston
963b0333ba preen 2025-08-20 06:58:27 -05:00
J. Nick Koston
fbc9b751c5 preen 2025-08-20 06:58:20 -05:00
Jesse Hills
d45944a9e2 [api] Add `USE_API_HOMEASSISTANT_SERVICES if using tag_scanned` action (#10316) 2025-08-20 06:47:20 -05:00
J. Nick Koston
d8c85bfc44 [bluetooth_proxy] Remove unused ClientState::SEARCHING state 2025-08-20 06:44:25 -05:00
Jesse Hills
86f306ba9e [CI] Also require tests for `new-features` (#10311) 2025-08-20 22:02:14 +12:00
Jesse Hills
1b3b2f6e6f Merge branch 'release' into dev 2025-08-20 19:58:48 +12:00
Jesse Hills
2adb993242 Merge pull request #10309 from esphome/bump-2025.8.0
2025.8.0
2025-08-20 19:58:01 +12:00
J. Nick Koston
518443606c Merge branch 'integration' into memory_api 2025-08-19 21:53:35 -05:00
J. Nick Koston
c5b794e41c merge 2025-08-19 21:53:28 -05:00
J. Nick Koston
72dd419c49 Merge branch 'integration' into memory_api 2025-08-19 21:52:31 -05:00
J. Nick Koston
951842e30f Merge remote-tracking branch 'upstream/dev' into integration 2025-08-19 21:52:22 -05:00
J. Nick Koston
3ff5b4773b [bluetooth_proxy] Mark BluetoothConnection and BluetoothProxy as final for compiler optimizations (#10280) 2025-08-20 14:48:40 +12:00
J. Nick Koston
2cbf4f30f9 [libretiny] Optimize preferences is_changed() by replacing temporary vector with unique_ptr (#10272) 2025-08-20 14:48:04 +12:00
J. Nick Koston
56b6dd31f1 [core] Eliminate heap allocation in teardown_components by using StaticVector (#10256)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-20 14:45:13 +12:00
J. Nick Koston
997223c93e Merge branch 'integration' into memory_api 2025-08-19 21:43:20 -05:00
J. Nick Koston
f0da3d6c09 Merge branch 'dev' into integration 2025-08-19 21:43:09 -05:00
dependabot[bot]
fc1b49e87d Bump ruamel-yaml from 0.18.14 to 0.18.15 (#10310)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-20 14:42:33 +12:00
J. Nick Koston
0089619518 [web_server] Reduce flash usage by consolidating defer calls in switch and lock handlers (#10297) 2025-08-19 21:41:34 -05:00
Jesse Hills
5a6db28f1d [CI] Base `too-big` label on new additions only (#10307) 2025-08-20 14:39:29 +12:00
J. Nick Koston
6819bbd8f8 [esp32_ble_client] Add log helper functions to reduce flash usage by 120 bytes (#10243) 2025-08-20 14:38:32 +12:00
Edward Firmo
634f687c3e [light] Add support for querying effects by index (#10195)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-08-20 14:38:13 +12:00
J. Nick Koston
e2a9b85924 [number] Convert LOG_NUMBER macro to function to reduce flash usage (#10293) 2025-08-20 14:36:05 +12:00
J. Nick Koston
4ccc6aee09 [button] Convert LOG_BUTTON macro to function to reduce flash usage (#10295)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-20 14:35:53 +12:00
J. Nick Koston
0eab908b0e [sensor] Convert LOG_SENSOR macro to function to reduce flash usage (#10290) 2025-08-20 14:35:45 +12:00
J. Nick Koston
3964f9794b [binary_sensor] Convert LOG_BINARY_SENSOR macro to function to reduce flash usage (#10294) 2025-08-20 14:35:09 +12:00
Jesse Hills
a45137434b [quality] Convert remaining `to_code to async` (#10271) 2025-08-20 14:34:45 +12:00
J. Nick Koston
9b1ebdb6da [mdns] Reduce flash usage and prevent RAM over-allocation in service compilation (#10287) 2025-08-20 14:34:34 +12:00
J. Nick Koston
5a1533bea9 [api] Avoid object_id string allocations for all entity info messages (#10260) 2025-08-20 14:28:13 +12:00
Jesse Hills
0b50ef227b [helper] Make crc8 function more flexible to avoid reimplementation in individual components (#10201) 2025-08-20 14:27:08 +12:00
J. Nick Koston
0e31bc1a67 [api] Add zero-copy StringRef methods for compilation_time and effect_name (#10257) 2025-08-20 14:26:53 +12:00
Jesse Hills
8e67df8059 Bump version to 2025.8.0 2025-08-20 10:45:57 +12:00
Jesse Hills
e1a0949ddb Merge branch 'beta' into dev 2025-08-20 10:31:10 +12:00
Jesse Hills
c5b2c8d971 Merge pull request #10308 from esphome/bump-2025.8.0b4
2025.8.0b4
2025-08-20 10:30:37 +12:00
J. Nick Koston
a8775ba60b [safe_mode] Reduce flash usage by 184 bytes through code optimization (#10284) 2025-08-19 16:57:24 -05:00
Jesse Hills
104906ca11 Bump version to 2025.8.0b4 2025-08-20 09:40:19 +12:00
J. Nick Koston
ad5f6f0cfe [bluetooth_proxy] Fix connection slot race by deferring slot release until GATT close (#10303) 2025-08-20 09:40:19 +12:00
Patrick
8356f7fcd3 [pipsolar] fix faults_present, fix update interval (#10289) 2025-08-20 09:40:19 +12:00
Ben Winslow
225de226b0 [atm90e32] Only read 1 register per SPI transaction per datasheet. (#10258) 2025-08-20 09:40:19 +12:00
J. Nick Koston
d1b9902e41 Merge branch 'integration' into memory_api 2025-08-19 15:38:10 -05:00
J. Nick Koston
9554c82c0b Merge branch 'optimize_safemode_flash' into integration 2025-08-19 15:38:04 -05:00
J. Nick Koston
2aaf951357 [bluetooth_proxy] Fix connection slot race by deferring slot release until GATT close (#10303) 2025-08-20 07:27:22 +12:00
J. Nick Koston
c5998690ba Merge branch 'integration' into memory_api 2025-08-19 09:48:25 -05:00
J. Nick Koston
084d8828a6 Merge branch 'slot_freed_too_early' into integration 2025-08-19 09:48:20 -05:00
J. Nick Koston
0c86241aed [bluetooth_proxy] Fix connection slot race by deferring slot release until GATT close 2025-08-19 09:40:21 -05:00
Jesse Hills
82718e62e7 Merge branch 'beta' into dev 2025-08-19 20:40:45 +12:00
Jesse Hills
fd07e1d979 Merge pull request #10298 from esphome/bump-2025.8.0b3
2025.8.0b3
2025-08-19 20:40:12 +12:00
Patrick
4dab9c4400 [pipsolar] fix faults_present, fix update interval (#10289) 2025-08-19 15:52:01 +12:00
Ben Winslow
7e23d865e6 [atm90e32] Only read 1 register per SPI transaction per datasheet. (#10258) 2025-08-19 15:45:30 +12:00
Jesse Hills
8f118232e4 [CI] Rename and expand needs-docs workflow (#10299) 2025-08-19 15:35:48 +12:00
J. Nick Koston
db10185c7e Merge branch 'integration' into memory_api 2025-08-18 21:07:11 -05:00
J. Nick Koston
9a7ffa4bbc Merge branch 'log_sensor' into integration 2025-08-18 21:07:04 -05:00
J. Nick Koston
9ec6b3144a Merge remote-tracking branch 'origin/log_sensor' into log_sensor 2025-08-18 21:06:34 -05:00
J. Nick Koston
70eb45b5d3 lint 2025-08-18 21:06:24 -05:00
Jesse Hills
23554cda06 Bump version to 2025.8.0b3 2025-08-19 13:09:22 +12:00
Ben Winslow
064385eac6 [nextion] Don't include terminating NUL in nextion text_sensor states (#10273) 2025-08-19 13:09:22 +12:00
Jesse Hills
6502ed70de [esp32] Write variant to sdkconfig file (#10267) 2025-08-19 13:09:22 +12:00
J. Nick Koston
bb894c3e32 [core] Fix scheduler race condition where cancelled items still execute (#10268) 2025-08-19 13:09:22 +12:00
Ben Winslow
c5858b7032 [core] Fix post-OTA logs display when using esphome run and MQTT (#10274) 2025-08-19 13:09:22 +12:00
Ben Winslow
99f57ecb73 [senseair] Discard 0 ppm readings with "Out Of Range" bit set. (#10275) 2025-08-19 13:09:22 +12:00
J. Nick Koston
cc6c892678 [esp32_ble] Store GATTC/GATTS param and small data inline to nearly eliminate heap allocations (#10249)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-19 13:09:22 +12:00
RFDarter
07a98d2525 [web_server] fix cover_all_json_generator wrong detail (#10252) 2025-08-19 13:09:22 +12:00
J. Nick Koston
e80f616366 [esp32_ble] Optimize BLE event memory usage by eliminating std::vector overhead (#10247)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-19 13:09:22 +12:00
J. Nick Koston
46be877594 [bluetooth_proxy] Remove redundant connection type check after V1 removal (#10208) 2025-08-19 13:09:21 +12:00
J. Nick Koston
ac8b48a53c [core] Trigger clean build when components are removed from configuration (#10235)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-19 13:09:21 +12:00
J. Nick Koston
7fdbd8528a [wifi] Automatically disable Enterprise WiFi support when EAP is not configured (#10242) 2025-08-19 13:09:21 +12:00
Katherine Whitlock
80970f972b Improve error reporting for add_library (#10226)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-19 13:09:21 +12:00
Jesse Hills
3c7865cd6f [esp32_ble] Add `USE_ESP32_BLE_UUID` when advertising is desired (#10230) 2025-08-19 13:09:21 +12:00
J. Nick Koston
7f34757ded Merge branch 'integration' into memory_api 2025-08-18 20:03:00 -05:00
J. Nick Koston
0c0e8491d2 Merge branch 'webserver_reduce_defer_calls' into integration 2025-08-18 20:02:53 -05:00
J. Nick Koston
1786934242 [web_server] Reduce flash usage by consolidating defer calls in switch and lock handlers 2025-08-18 20:01:42 -05:00
Ben Winslow
3a6a66537c [nextion] Don't include terminating NUL in nextion text_sensor states (#10273) 2025-08-18 19:20:13 -05:00
Jesse Hills
7118bea031 [esp32] Write variant to sdkconfig file (#10267) 2025-08-19 12:17:34 +12:00
J. Nick Koston
8fd430e423 Update esphome/components/sensor/sensor.h 2025-08-18 19:17:26 -05:00
J. Nick Koston
8dc3958b0c Update esphome/components/sensor/sensor.h 2025-08-18 19:17:19 -05:00
J. Nick Koston
bbd5ab1340 Merge branch 'integration' into memory_api 2025-08-18 18:33:43 -05:00
J. Nick Koston
63cd279cd4 Merge branch 'log_number' into integration 2025-08-18 18:33:26 -05:00
J. Nick Koston
6f6b38762a Merge branch 'log_button' into integration 2025-08-18 18:33:23 -05:00
J. Nick Koston
2dc57d6236 Merge branch 'log_binary_sensor' into integration 2025-08-18 18:33:20 -05:00
J. Nick Koston
deadb8d9be Merge branch 'log_sensor' into integration 2025-08-18 18:33:15 -05:00
J. Nick Koston
59c93cf3f1 preen 2025-08-18 18:32:50 -05:00
J. Nick Koston
9d25dd5dd2 [button] Convert LOG_BUTTON macro to function to reduce flash usage 2025-08-18 18:29:13 -05:00
J. Nick Koston
a21ee3c483 [binary_sensor] Convert LOG_BINARY_SENSOR macro to function to reduce flash usage 2025-08-18 18:19:53 -05:00
J. Nick Koston
8971e2e9a4 [number] Convert LOG_NUMBER macro to function to reduce flash usage 2025-08-18 18:14:55 -05:00
J. Nick Koston
e7fadef15c [sensor] Convert LOG_SENSOR macro to function to reduce flash usage 2025-08-18 18:00:46 -05:00
J. Nick Koston
67ae6ce00a tweak 2025-08-18 17:36:20 -05:00
J. Nick Koston
24cee8ae03 tweak 2025-08-18 17:35:21 -05:00
J. Nick Koston
58a9944601 tweak 2025-08-18 17:34:08 -05:00
J. Nick Koston
a999540d4b Merge branch 'integration' into memory_api 2025-08-18 17:13:49 -05:00
J. Nick Koston
aa608f3a92 Merge remote-tracking branch 'upstream/dev' into integration 2025-08-18 17:13:42 -05:00
J. Nick Koston
44bd8e5b54 [api] Optimize protobuf decode loop for better performance and maintainability (#10277) 2025-08-18 16:14:20 -05:00
J. Nick Koston
efaeb91803 [api] Mark APIConnection as final for compiler optimizations (#10279) 2025-08-18 16:01:45 -05:00
J. Nick Koston
761c6c6685 [api] Mark protobuf message classes as final to enable compiler optimizations (#10276) 2025-08-18 15:55:30 -05:00
J. Nick Koston
1f55486896 [api] Optimize APIFrameHelper virtual methods and mark implementations as final (#10278) 2025-08-18 15:55:11 -05:00
J. Nick Koston
727e04c424 Merge branch 'integration' into memory_api 2025-08-18 14:37:37 -05:00
J. Nick Koston
0ea3018bd1 Merge branch 'mdns_cleanups' into integration 2025-08-18 14:37:30 -05:00
J. Nick Koston
fd6002e334 [mdns] Reduce flash usage and prevent RAM over-allocation in service compilation 2025-08-18 14:36:41 -05:00
J. Nick Koston
6248c3d729 preen 2025-08-18 12:47:22 -05:00
J. Nick Koston
3d03053eb5 Merge branch 'optimize_safemode_flash' into memory_api 2025-08-18 12:42:22 -05:00
J. Nick Koston
571e6be404 [safe_mode] Reduce flash usage by 172 bytes through code optimization 2025-08-18 12:41:35 -05:00
J. Nick Koston
7d3a87c603 [safe_mode] Reduce flash usage by 172 bytes through code optimization 2025-08-18 12:40:24 -05:00
J. Nick Koston
be2a680e8f [safe_mode] Reduce flash usage by 172 bytes through code optimization 2025-08-18 12:39:33 -05:00
J. Nick Koston
a36942b760 [safe_mode] Reduce flash usage by 172 bytes through code optimization 2025-08-18 12:37:44 -05:00
J. Nick Koston
8332893661 Merge branch 'integration' into memory_api 2025-08-18 11:06:58 -05:00
J. Nick Koston
ed3884e5aa Merge branch 'bluetooth_connection_final' into integration 2025-08-18 11:06:53 -05:00
J. Nick Koston
fb3a01e84e might as well do both 2025-08-18 11:05:09 -05:00
J. Nick Koston
6818439109 [core] Fix scheduler race condition where cancelled items still execute (#10268) 2025-08-18 11:14:41 -04:00
J. Nick Koston
54696eac67 Merge branch 'integration' into memory_api 2025-08-18 09:02:43 -05:00
J. Nick Koston
60e27e3ed7 Merge branch 'more_zero_copy_api_followup' into integration 2025-08-18 09:02:36 -05:00
J. Nick Koston
dbda2d5b6a Merge branch 'integration' into memory_api 2025-08-18 08:29:23 -05:00
J. Nick Koston
23fa231ca2 Merge branch 'decode_cleanup' into integration 2025-08-18 08:29:17 -05:00
J. Nick Koston
a9227148f5 review comments 2025-08-18 08:28:58 -05:00
J. Nick Koston
0a77423073 [esp8266] Replace std::vector with std::unique_ptr in preferences to save flash (#10245) 2025-08-18 09:01:39 -04:00
J. Nick Koston
7e67f0432d Merge branch 'integration' into memory_api 2025-08-18 01:07:43 -05:00
J. Nick Koston
b249cc25d9 Merge branch 'bluetooth_connection_final' into integration 2025-08-18 01:07:35 -05:00
J. Nick Koston
5678621cd5 [bluetooth_proxy] Mark BluetoothConnection as final for compiler optimizations 2025-08-18 01:06:47 -05:00
J. Nick Koston
c9932342eb Merge branch 'integration' into memory_api 2025-08-18 01:01:20 -05:00
J. Nick Koston
e68a44bcba Merge branch 'api_connection_final' into integration 2025-08-18 01:01:12 -05:00
J. Nick Koston
af87e27382 [api] Mark APIConnection as final for compiler optimizations 2025-08-18 01:00:12 -05:00
J. Nick Koston
f556ab1515 Merge branch 'frame_helper_opt' into memory_api 2025-08-18 00:57:04 -05:00
J. Nick Koston
76b6d77337 Merge branch 'frame_helper_opt' into integration 2025-08-18 00:56:57 -05:00
J. Nick Koston
134526e0ec [api] Optimize APIFrameHelper virtual methods and mark implementations as final 2025-08-18 00:56:19 -05:00
J. Nick Koston
cb157822d0 Merge branch 'decode_cleanup' into memory_api 2025-08-17 22:22:50 -05:00
J. Nick Koston
d7b28752e0 Merge branch 'decode_cleanup' into integration 2025-08-17 22:22:41 -05:00
J. Nick Koston
a2ad2dd10e [api] Optimize protobuf decode loop for better performance and maintainability 2025-08-17 22:21:51 -05:00
J. Nick Koston
4ee84b6d53 Merge remote-tracking branch 'origin/libretiny_no_vector' into memory_api 2025-08-17 21:40:59 -05:00
J. Nick Koston
0a483012ae Update esphome/components/libretiny/preferences.cpp 2025-08-17 21:40:45 -05:00
J. Nick Koston
b12666f356 Merge branch 'integration' into memory_api 2025-08-17 21:38:18 -05:00
J. Nick Koston
a82eeabbc8 Merge branch 'libretiny_no_vector' into memory_api 2025-08-17 21:37:42 -05:00
J. Nick Koston
6b9fc783b6 Merge remote-tracking branch 'upstream/libretiny_no_vector' into integration 2025-08-17 21:37:32 -05:00
Ben Winslow
c29f8d0187 [core] Fix post-OTA logs display when using esphome run and MQTT (#10274) 2025-08-17 21:36:35 -05:00
J. Nick Koston
2b23899750 Merge branch 'integration' into memory_api 2025-08-17 21:15:01 -05:00
J. Nick Koston
afc2ba066e Merge remote-tracking branch 'origin/atomic_remove' into integration 2025-08-17 21:14:54 -05:00
J. Nick Koston
b0e8aba426 Merge branch 'integration' into memory_api 2025-08-17 21:13:44 -05:00
J. Nick Koston
898b7b079e Merge branch 'final_proto' into integration 2025-08-17 21:13:34 -05:00
J. Nick Koston
37e36a3d1d [api] Mark protobuf message classes as final to enable compiler optimizations 2025-08-17 21:12:38 -05:00
Ben Winslow
2a3f80a82c [senseair] Discard 0 ppm readings with "Out Of Range" bit set. (#10275) 2025-08-18 14:09:42 +12:00
J. Nick Koston
89732f30f4 [libretiny] Optimize preferences is_changed() by replacing temporary vector with unique_ptr 2025-08-17 18:46:53 -04:00
J. Nick Koston
c56fd00a7c cleanup 2025-08-17 16:28:32 -04:00
J. Nick Koston
e06dbffe9f fix 2025-08-17 16:12:53 -04:00
J. Nick Koston
5b674dc28c atomic remove 2025-08-17 16:09:57 -04:00
J. Nick Koston
75f3adcd95 [esp32_ble] Store GATTC/GATTS param and small data inline to nearly eliminate heap allocations (#10249)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-18 07:49:50 +12:00
J. Nick Koston
17467150d8 Merge branch 'integration' into memory_api 2025-08-17 08:43:10 -04:00
J. Nick Koston
cb1d4830d8 Merge remote-tracking branch 'upstream/dev' into integration 2025-08-17 08:42:46 -04:00
J. Nick Koston
1666aae105 Merge branch 'integration' into memory_api 2025-08-16 09:45:27 -04:00
J. Nick Koston
05a0380a9f Merge branch 'object_id_alloc' into integration 2025-08-16 09:45:17 -04:00
J. Nick Koston
0b004a7d9b tweak 2025-08-16 09:38:00 -04:00
J. Nick Koston
15fca7dea8 Avoid object_id string allocations for all entity info API messages 2025-08-16 09:35:12 -04:00
J. Nick Koston
29daef230d [api] Add zero-copy StringRef methods for compilation_time and effect_name 2025-08-15 23:51:24 -04:00
J. Nick Koston
daf8ec36ab [core] Remove unnecessary FD_SETSIZE check on ESP32 and improve logging (#10255) 2025-08-15 21:26:48 -05:00
J. Nick Koston
82d7255a16 Merge branch 'integration' into memory_api 2025-08-15 21:36:21 -04:00
J. Nick Koston
c05db304ef Merge branch 'teardown_fix_size' into integration 2025-08-15 21:30:37 -04:00
J. Nick Koston
59037458d6 Update esphome/core/application.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-15 21:27:31 -04:00
J. Nick Koston
769a874d33 Merge branch 'integration' into memory_api 2025-08-15 21:16:44 -04:00
J. Nick Koston
50d284f21f Merge branch 'teardown_fix_size' into integration 2025-08-15 21:16:22 -04:00
J. Nick Koston
0a66612399 teardown 2025-08-15 15:40:19 -05:00
J. Nick Koston
405ebe90f5 teardown 2025-08-15 15:39:33 -05:00
J. Nick Koston
15d1e1f8dd Merge branch 'integration' into memory_api 2025-08-15 15:05:19 -05:00
J. Nick Koston
fdf3db465c Merge branch 'useless_fd_setsize_check' into integration 2025-08-15 15:05:13 -05:00
J. Nick Koston
2b887033c5 [core] Remove unnecessary FD_SETSIZE check on ESP32 and improve logging 2025-08-15 14:49:22 -05:00
J. Nick Koston
e4a6dcd9c7 Merge branch 'integration' into memory_api 2025-08-15 12:33:32 -05:00
J. Nick Koston
ffc234f934 Merge remote-tracking branch 'upstream/dev' into integration 2025-08-15 12:33:27 -05:00
J. Nick Koston
6c5632a0b3 [esp32] Optimize preferences is_changed() by replacing temporary vector with unique_ptr (#10246)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-15 10:11:49 -05:00
J. Nick Koston
9f8f1f5bc9 Merge branch 'integration' into memory_api 2025-08-15 09:54:57 -05:00
J. Nick Koston
b43ab33662 Merge branch 'esp32_ble_no_vector_no_heap_small' into integration 2025-08-15 09:54:47 -05:00
J. Nick Koston
d78d2c8710 Apply suggestions from code review 2025-08-15 09:53:07 -05:00
RFDarter
abecc0e8d8 [web_server] fix cover_all_json_generator wrong detail (#10252) 2025-08-15 09:44:24 -05:00
J. Nick Koston
3aae84fade preen 2025-08-15 08:54:17 -05:00
J. Nick Koston
7005da42bb preen 2025-08-15 08:52:21 -05:00
J. Nick Koston
0c06b02af4 Merge remote-tracking branch 'upstream/dev' into esp32_ble_no_vector_no_heap_small 2025-08-15 08:43:53 -05:00
J. Nick Koston
af9ecf3429 [esp32_ble] Optimize BLE event memory usage by eliminating std::vector overhead (#10247)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-15 07:38:27 +00:00
J. Nick Koston
57b4c65c6c Merge branch 'integration' into memory_api 2025-08-15 00:59:09 -05:00
J. Nick Koston
d632fc930c Merge branch 'esp32_ble_no_vector_no_heap_small' into integration 2025-08-15 00:59:00 -05:00
J. Nick Koston
0d966ac115 preen 2025-08-15 00:58:52 -05:00
J. Nick Koston
c2abb2c8ba [esp32_ble] Use union space for inline GATTC/GATTS data storage to reduce heap allocations 2025-08-15 00:49:25 -05:00
J. Nick Koston
ce328bc9b9 Merge branch 'integration' into memory_api 2025-08-14 23:49:39 -05:00
J. Nick Koston
0757a18fe7 Merge remote-tracking branch 'upstream/esp32_prefs_vector' into integration 2025-08-14 23:49:33 -05:00
J. Nick Koston
04b0a82963 Update esphome/components/esp32/preferences.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-14 23:49:05 -05:00
J. Nick Koston
306f7263b2 Merge branch 'integration' into memory_api 2025-08-14 23:39:56 -05:00
J. Nick Koston
2cb9f65830 Merge branch 'esp32_ble_no_vector' into integration 2025-08-14 23:39:47 -05:00
J. Nick Koston
c32584d48e preen 2025-08-14 23:39:29 -05:00
J. Nick Koston
ce6d71e942 Update esphome/components/esp32_ble/ble_event.h 2025-08-14 23:38:54 -05:00
J. Nick Koston
14895adf47 Update esphome/components/esp32_ble/ble_event.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-14 23:38:25 -05:00
J. Nick Koston
d2faac10a5 Merge branch 'integration' into memory_api 2025-08-14 23:01:08 -05:00
J. Nick Koston
8e485b521a Merge branch 'esp32_prefs_vector' into integration 2025-08-14 23:00:59 -05:00
J. Nick Koston
da5020354f preen 2025-08-14 22:59:37 -05:00
J. Nick Koston
7b46be523a Merge branch 'integration' into memory_api 2025-08-14 22:42:39 -05:00
J. Nick Koston
b695b6b31e Merge branch 'esp32_prefs_vector' into integration 2025-08-14 22:42:34 -05:00
J. Nick Koston
9f4d0d3f23 preen 2025-08-14 22:42:19 -05:00
J. Nick Koston
3585ed185f Merge branch 'integration' into memory_api 2025-08-14 22:22:14 -05:00
J. Nick Koston
a7c60e76df Merge branch 'esp32_ble_no_vector' into integration 2025-08-14 22:22:04 -05:00
J. Nick Koston
0ee3155123 fix 2025-08-14 22:20:08 -05:00
J. Nick Koston
1bd458c868 Merge branch 'integration' into memory_api 2025-08-14 22:14:23 -05:00
J. Nick Koston
792f9392a1 Merge branch 'esp32_ble_no_vector' into integration 2025-08-14 22:14:18 -05:00
J. Nick Koston
1fa33253f8 wip 2025-08-14 22:04:10 -05:00
J. Nick Koston
269786cac9 preen 2025-08-14 21:59:46 -05:00
J. Nick Koston
9f22de449a Merge branch 'integration' into memory_api 2025-08-14 21:20:40 -05:00
J. Nick Koston
3aa6901861 Merge branch 'esp32_prefs_vector' into integration 2025-08-14 21:20:33 -05:00
J. Nick Koston
e9e94bcd45 [esp32] Optimize preferences is_changed() by replacing temporary vector with unique_ptr 2025-08-14 21:19:36 -05:00
J. Nick Koston
bf4070ad75 Merge branch 'integration' into memory_api 2025-08-14 21:04:59 -05:00
J. Nick Koston
c562ef6b79 Merge branch 'esp8266_prefs_no_vector' into integration 2025-08-14 21:04:53 -05:00
J. Nick Koston
df73d81aca [esp8266] Replace std::vector with std::unique_ptr in preferences to save flash 2025-08-14 21:03:51 -05:00
J. Nick Koston
00ae0fea31 Merge branch 'integration' into memory_api 2025-08-14 20:29:21 -05:00
J. Nick Koston
8cadb011a9 Merge remote-tracking branch 'upstream/dev' into integration 2025-08-14 20:28:41 -05:00
J. Nick Koston
5fa84439c2 [api] Optimize message buffer allocation and eliminate redundant methods (#10231) 2025-08-14 20:26:09 -05:00
dependabot[bot]
5d18afcd99 Bump ruff from 0.12.8 to 0.12.9 (#10239)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-08-14 22:54:35 +00:00
J. Nick Koston
117cffd2b0 [bluetooth_proxy] Remove redundant connection type check after V1 removal (#10208) 2025-08-15 10:51:15 +12:00
J. Nick Koston
8ea1a3ed64 [core] Trigger clean build when components are removed from configuration (#10235)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-15 10:50:03 +12:00
J. Nick Koston
0d288ceef3 Merge branch 'integration' into memory_api 2025-08-14 17:46:43 -05:00
J. Nick Koston
0413914eda Merge branch 'esp32_ble_client_strings_2' into integration 2025-08-14 17:46:34 -05:00
J. Nick Koston
8a9d30c8d3 [esp32_ble_client] Add log helper functions to reduce flash usage by 120 bytes 2025-08-14 17:44:15 -05:00
J. Nick Koston
4f29b3c7aa [wifi] Automatically disable Enterprise WiFi support when EAP is not configured (#10242) 2025-08-15 10:43:45 +12:00
J. Nick Koston
40d35f3dff Merge branch 'integration' into memory_api 2025-08-14 16:32:51 -05:00
J. Nick Koston
bf3436f3b3 Merge branch 'no_eap_when_not_configured' into integration 2025-08-14 16:32:40 -05:00
J. Nick Koston
b7e0627b21 [wifi] Automatically disable Enterprise WiFi support when EAP is not configured 2025-08-14 16:29:53 -05:00
J. Nick Koston
4d0049aa62 Merge branch 'integration' into memory_api 2025-08-14 16:04:37 -05:00
J. Nick Koston
9a0d663fb0 Merge branch 'clean_comp_removed' into integration 2025-08-14 16:04:30 -05:00
J. Nick Koston
9af016e2ce preen 2025-08-14 16:03:44 -05:00
J. Nick Koston
256f81f514 Merge branch 'clean_comp_removed' into memory_api 2025-08-14 15:59:52 -05:00
J. Nick Koston
a5a0ec907d Merge branch 'clean_comp_removed' into integration 2025-08-14 15:59:46 -05:00
J. Nick Koston
da73cb06cc cover other case 2025-08-14 15:59:36 -05:00
Jesse Hills
3325592d67 Merge branch 'beta' into dev 2025-08-15 08:46:48 +12:00
Jesse Hills
0a3ee7d84e Merge pull request #10228 from esphome/bump-2025.8.0b2
2025.8.0b2
2025-08-15 08:46:15 +12:00
Katherine Whitlock
882237120e Improve error reporting for add_library (#10226)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-15 08:14:53 +12:00
J. Nick Koston
c0c1b4738a Merge branch 'integration' into memory_api 2025-08-14 14:21:14 -05:00
J. Nick Koston
6a9dcc7d76 merge 2025-08-14 14:20:55 -05:00
J. Nick Koston
93c90124ee Merge branch 'integration' into memory_api 2025-08-14 10:07:27 -05:00
J. Nick Koston
82de6516c6 Merge branch 'clean_comp_removed' into integration 2025-08-14 10:07:19 -05:00
J. Nick Koston
7e7bfb00aa fix typing 2025-08-14 10:06:48 -05:00
J. Nick Koston
d42d9fa41e Update esphome/writer.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-14 10:05:11 -05:00
J. Nick Koston
6dd818a320 Merge branch 'integration' into memory_api 2025-08-14 09:41:12 -05:00
J. Nick Koston
7637b77394 Merge branch 'clean_comp_removed' into integration 2025-08-14 09:41:04 -05:00
J. Nick Koston
ef07d3e0c8 [core] Trigger clean build when components are removed from configuration 2025-08-14 09:34:41 -05:00
Jesse Hills
71efaf097b [esp32_ble] Add `USE_ESP32_BLE_UUID` when advertising is desired (#10230) 2025-08-14 08:49:14 -05:00
Jesse Hills
bd60dbb746 [quality] Remove period from audio related Invalid raises (#10229) 2025-08-14 08:48:25 -05:00
J. Nick Koston
6e9fb8201b Merge branch 'integration' into memory_api 2025-08-13 23:10:18 -05:00
J. Nick Koston
912f676133 Merge branch 'api_reduce_2' into integration 2025-08-13 23:10:10 -05:00
J. Nick Koston
9bcd6c7a85 fix 2025-08-13 23:07:22 -05:00
J. Nick Koston
09fa349349 Revert "Revert "preen""
This reverts commit d83ed9ebe1.
2025-08-13 23:06:23 -05:00
J. Nick Koston
58074e0357 Revert "preen"
This reverts commit 51bf2c3511.
2025-08-13 23:05:12 -05:00
J. Nick Koston
d83ed9ebe1 Revert "preen"
This reverts commit 0207444765.
2025-08-13 23:04:38 -05:00
J. Nick Koston
6fc0831762 Merge branch 'integration' into memory_api 2025-08-13 23:01:43 -05:00
J. Nick Koston
dfa2aa481d Merge branch 'api_reduce_2' into integration 2025-08-13 23:01:30 -05:00
J. Nick Koston
0207444765 preen 2025-08-13 22:58:04 -05:00
J. Nick Koston
51bf2c3511 preen 2025-08-13 22:55:06 -05:00
J. Nick Koston
97c405b57e preen 2025-08-13 22:53:33 -05:00
J. Nick Koston
deff1c4bc7 preen 2025-08-13 22:53:12 -05:00
J. Nick Koston
d37390412c preen 2025-08-13 22:52:51 -05:00
J. Nick Koston
62a2b5e736 Merge branch 'integration' into memory_api 2025-08-13 22:46:00 -05:00
J. Nick Koston
6c0d21f116 Merge branch 'api_reduce_2' into integration 2025-08-13 22:45:49 -05:00
J. Nick Koston
f0decc4716 tweak 2025-08-13 22:42:08 -05:00
J. Nick Koston
3346e09785 preen 2025-08-13 22:23:47 -05:00
J. Nick Koston
b43ca2bbab [api] Optimize message buffer allocation and eliminate redundant methods 2025-08-13 22:10:15 -05:00
J. Nick Koston
3bf8624b87 Merge remote-tracking branch 'upstream/dev' into memory_api 2025-08-13 21:43:55 -05:00
Jesse Hills
6b5e43ca72 [qm6988] Clean up code (#10216) 2025-08-13 21:19:03 -05:00
Jesse Hills
8d61b1e8df Bump version to 2025.8.0b2 2025-08-14 14:00:27 +12:00
dependabot[bot]
9c897993bb Bump esphome-dashboard from 20250514.0 to 20250814.0 (#10227)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-14 14:00:26 +12:00
dependabot[bot]
93f9475105 Bump aioesphomeapi from 38.2.1 to 39.0.0 (#10222)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-14 14:00:26 +12:00
Samuel Sieb
95cd224e3e [psram] allow disabling (#10224)
Co-authored-by: Samuel Sieb <samuel@sieb.net>
2025-08-14 14:00:26 +12:00
Jesse Hills
b7afeafda9 [espnow] Set state to enabled before adding initial peers (#10225) 2025-08-14 14:00:26 +12:00
Jesse Hills
7922462bcf [entity] Allow `device_id` to be blank on entities (#10217) 2025-08-14 14:00:26 +12:00
dependabot[bot]
46d433775b Bump esphome-dashboard from 20250514.0 to 20250814.0 (#10227)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-14 12:40:20 +12:00
dependabot[bot]
7c4a54de90 Bump aioesphomeapi from 38.2.1 to 39.0.0 (#10222)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-13 17:42:54 -05:00
Samuel Sieb
c3f1596498 [psram] allow disabling (#10224)
Co-authored-by: Samuel Sieb <samuel@sieb.net>
2025-08-14 10:40:12 +12:00
Jesse Hills
0d1949a61b [espnow] Set state to enabled before adding initial peers (#10225) 2025-08-14 10:30:28 +12:00
Jesse Hills
6a8722f33e [entity] Allow `device_id` to be blank on entities (#10217) 2025-08-14 09:42:11 +12:00
J. Nick Koston
0c92dc77ad Merge branch 'integration' into memory_api 2025-08-13 11:24:22 -05:00
J. Nick Koston
203da37390 Merge remote-tracking branch 'upstream/dev' into integration 2025-08-13 11:24:14 -05:00
Jesse Hills
fff66072d4 Merge branch 'beta' into dev 2025-08-14 00:02:17 +12:00
Jesse Hills
1c2e1ab3e5 Merge pull request #10214 from esphome/bump-2025.8.0b1
2025.8.0b1
2025-08-13 23:56:34 +12:00
J. Nick Koston
68ddd98f5f [CI] Fix CI job failures for PRs with >300 changed files (#10215) 2025-08-13 15:49:38 +12:00
J. Nick Koston
0dda3faed5 [CI] Fix CI job failures for PRs with >300 changed files (#10215) 2025-08-13 15:46:56 +12:00
Jesse Hills
40c0c36179 Bump version to 2025.9.0-dev 2025-08-13 14:46:51 +12:00
Jesse Hills
6b7ced1970 Bump version to 2025.8.0b1 2025-08-13 14:46:50 +12:00
J. Nick Koston
ed2b76050b [bluetooth_proxy] Remove ESPBTUUID dependency to save 296 bytes of flash (#10213) 2025-08-13 14:18:53 +12:00
Samuel Sieb
113813617d [bme280_base, bmp280_base] add reasons to the fails, clean up logging (#10209)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-08-13 02:05:22 +00:00
J. Nick Koston
bb6ce91c9d Merge branch 'integration' into memory_api 2025-08-12 21:03:55 -05:00
J. Nick Koston
b3e6a0e417 Merge branch 'proxy_uuids_services' into integration 2025-08-12 21:03:43 -05:00
J. Nick Koston
4acc7f77cc one more 2025-08-12 20:22:24 -05:00
J. Nick Koston
9238916b32 one more 2025-08-12 20:22:10 -05:00
Keith Burzinski
c3a209d3f4 [ld2450] Replace `throttle` with native filters (#10196)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-08-12 19:35:19 -05:00
J. Nick Koston
ed9e717703 Merge branch 'integration' into memory_api 2025-08-12 19:33:42 -05:00
J. Nick Koston
ae4f051cd4 Merge branch 'proxy_uuids_services' into integration 2025-08-12 19:33:36 -05:00
J. Nick Koston
dec9810177 fix 2025-08-12 19:26:41 -05:00
J. Nick Koston
235050fe58 fix 2025-08-12 19:25:20 -05:00
J. Nick Koston
b5c381982c fix 2025-08-12 19:23:44 -05:00
J. Nick Koston
5c12f638bd fix 2025-08-12 19:22:27 -05:00
J. Nick Koston
36613507be fix 2025-08-12 19:19:21 -05:00
J. Nick Koston
803d665a94 tweak 2025-08-12 19:16:02 -05:00
J. Nick Koston
5b279f5f92 tweak 2025-08-12 19:14:37 -05:00
J. Nick Koston
841deff578 [bluetooth_proxy] Optimize UUID conversion and reduce flash usage by 296 bytes 2025-08-12 18:57:17 -05:00
J. Nick Koston
c2ebfe8f27 [bluetooth_proxy] Optimize UUID conversion and reduce flash usage by 296 bytes 2025-08-12 18:56:20 -05:00
J. Nick Koston
7b116be48b [bluetooth_proxy] Optimize UUID conversion and reduce flash usage by 296 bytes 2025-08-12 18:54:23 -05:00
J. Nick Koston
1c409e1b51 Merge branch 'integration' into memory_api 2025-08-12 15:34:36 -05:00
J. Nick Koston
ffdf80533e Merge branch 'redudant_checks_bluetooth_proxy' into integration 2025-08-12 15:34:29 -05:00
J. Nick Koston
b85185f821 [bluetooth_proxy] Remove redundant connection type check after V1 removal 2025-08-12 15:12:58 -05:00
John
7ffdaa1f06 [atm90e32] energy meter calibration log output enhancements & software SPI fix (#10143)
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>
2025-08-12 20:26:53 +12:00
dependabot[bot]
3a857950bf Bump actions/checkout from 4 to 5 (#10198)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-08-12 20:23:41 +12:00
Rihan9
0256e0005e [ld2412] New component (#9075)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-08-12 00:34:37 -05:00
Jesse Hills
c65af68e63 [core] Reset pin registry after target platform validations (#10199) 2025-08-12 16:33:07 +12:00
dependabot[bot]
ef2121a215 Bump aioesphomeapi from 38.1.0 to 38.2.1 (#10197)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-11 20:47:53 -05:00
Joshua Sing
bb40b7702d [const] Add CONF_POWER_MODE (#10173) 2025-08-12 11:13:24 +12:00
Kevin Ahrendt
6c48f3d719 [wifi] Remove restriction from using NONE power saving mode with BLE (#10181) 2025-08-12 11:09:58 +12:00
J. Nick Koston
daa7633ebb Merge branch 'integration' into memory_api 2025-08-11 17:22:09 -05:00
J. Nick Koston
a62d846dd1 Merge remote-tracking branch 'upstream/dev' into integration 2025-08-11 17:22:00 -05:00
J. Nick Koston
ff52869b4c [api] Add constexpr optimizations to protobuf encoding (#10192) 2025-08-12 10:10:38 +12:00
J. Nick Koston
82b7c1224c [core] Improve entity duplicate validation error messages (#10184) 2025-08-12 09:58:51 +12:00
Jesse Hills
c14c4fb658 [substitutions] Add some safe built-in functions to jinja parsing (#10178)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-11 16:12:54 -05:00
J. Nick Koston
42aee53dde [bluetooth_proxy] Replace dynamic vector with fixed array for BLE advertisements (#10174) 2025-08-11 15:47:46 -05:00
J. Nick Koston
9aa21956c8 [api] Optimize single vector writes to use write() instead of writev() (#10193) 2025-08-11 15:41:08 -05:00
J. Nick Koston
4c2874a32b [esphome] Fix OTA watchdog resets during port scanning and network delays (#10152) 2025-08-11 15:37:01 -05:00
J. Nick Koston
0813362ea8 Merge branch 'integration' into memory_api 2025-08-11 14:53:48 -05:00
J. Nick Koston
53da4391a0 Merge branch 'api_writev' into integration 2025-08-11 14:53:36 -05:00
J. Nick Koston
04415211e6 [api] Optimize single vector writes to use write() instead of writev() 2025-08-11 14:52:41 -05:00
J. Nick Koston
4b62f48e12 Merge branch 'integration' into memory_api 2025-08-11 14:37:19 -05:00
J. Nick Koston
d46843f6f1 Merge branch 'small_proto_cleanups' into integration 2025-08-11 14:37:11 -05:00
J. Nick Koston
1bd4098cea [api] Add constexpr optimizations to protobuf encoding 2025-08-11 14:36:31 -05:00
J. Nick Koston
11dd8ccd1e Merge branch 'integration' into memory_api 2025-08-11 13:29:31 -05:00
J. Nick Koston
8e0915a3a5 Merge branch 'improve_entity_validation_message' into integration 2025-08-11 13:29:15 -05:00
J. Nick Koston
d04422e27d add missing file 2025-08-11 11:36:15 -05:00
J. Nick Koston
753ee1badc [core] Improve entity duplicate validation error messages 2025-08-11 11:32:23 -05:00
Keith Burzinski
45b88f2da9 [sensor] Extend timeout filter with option to return last value received (#10115) 2025-08-11 10:36:44 -05:00
dependabot[bot]
8f53961496 Bump pylint from 3.3.7 to 3.3.8 (#10177)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-11 01:05:14 -05:00
J. Nick Koston
073957a310 Merge branch 'integration' into memory_api 2025-08-11 00:44:05 -05:00
J. Nick Koston
075d533b93 Merge branch 'fixed_ble_adv' into integration 2025-08-11 00:43:57 -05:00
J. Nick Koston
a847aab65e preen 2025-08-11 00:42:58 -05:00
J. Nick Koston
3d821f1223 preen 2025-08-11 00:42:42 -05:00
J. Nick Koston
9d29031d81 Merge remote-tracking branch 'origin/fixed_ble_adv' into fixed_ble_adv 2025-08-11 00:40:51 -05:00
J. Nick Koston
dc0c4a8991 Merge remote-tracking branch 'origin/dev' into fixed_ble_adv 2025-08-11 00:40:41 -05:00
J. Nick Koston
af9c008ccb fix off by 1 2025-08-11 00:40:28 -05:00
J. Nick Koston
c437d0057c Merge branch 'dev' into fixed_ble_adv 2025-08-11 00:12:22 -05:00
dependabot[bot]
5cf0e4d9dd Bump aioesphomeapi from 38.0.0 to 38.1.0 (#10176)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-11 05:11:22 +00:00
J. Nick Koston
cfe2bfea92 Merge branch 'integration' into memory_api 2025-08-11 00:09:51 -05:00
J. Nick Koston
7d3cc0b811 Merge branch 'fixed_ble_adv' into integration 2025-08-11 00:09:45 -05:00
J. Nick Koston
07db443207 fixed ble adv 2025-08-10 23:31:40 -05:00
J. Nick Koston
35a51280d4 fixed ble adv 2025-08-10 23:29:46 -05:00
J. Nick Koston
336fea4251 Merge branch 'integration' into memory_api 2025-08-10 19:29:03 -05:00
J. Nick Koston
2fc44ac831 Merge branch 'ota_fixes' into integration 2025-08-10 19:28:57 -05:00
J. Nick Koston
8f8d6734db dry 2025-08-10 19:26:12 -05:00
J. Nick Koston
6f817fd06a Merge branch 'integration' into memory_api 2025-08-10 19:09:54 -05:00
J. Nick Koston
96cc7f4b99 Merge remote-tracking branch 'origin/ota_fixes' into integration 2025-08-10 19:09:44 -05:00
J. Nick Koston
9021de9c1c preen 2025-08-10 19:04:24 -05:00
J. Nick Koston
7c0856c460 Merge branch 'integration' into memory_api 2025-08-10 18:54:14 -05:00
J. Nick Koston
7148500fa2 Merge branch 'ota_fixes' into integration 2025-08-10 18:54:07 -05:00
J. Nick Koston
d337da3d3c cleanp 2025-08-10 18:53:48 -05:00
J. Nick Koston
3cc916b9d8 Merge branch 'integration' into memory_api 2025-08-10 18:47:30 -05:00
J. Nick Koston
5c9816e51b Merge branch 'ota_fixes' into integration 2025-08-10 18:47:24 -05:00
J. Nick Koston
9ce75d2f0f preen 2025-08-10 18:45:44 -05:00
Chad Matsalla
b70983ed09 [display] Disallow `show_test_card: true and update_interval: never` (#9927)
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>
2025-08-11 11:41:37 +12:00
J. Nick Koston
bcd4386fe4 Merge branch 'integration' into memory_api 2025-08-10 18:36:04 -05:00
J. Nick Koston
d5e831b93a Merge branch 'ota_fixes' into integration 2025-08-10 18:35:41 -05:00
J. Nick Koston
2f9d1e6dac preen 2025-08-10 18:33:30 -05:00
J. Nick Koston
ef676a5a77 preen 2025-08-10 18:30:28 -05:00
J. Nick Koston
4faa9231a9 preen 2025-08-10 18:29:00 -05:00
J. Nick Koston
4bdf44bb78 preen 2025-08-10 18:28:27 -05:00
J. Nick Koston
856e13986a preen 2025-08-10 18:25:51 -05:00
J. Nick Koston
4a8369ef93 preen 2025-08-10 18:24:41 -05:00
tomaszduda23
ffa89eb2d3 [nrf52, zephyr_debug] add zephyr debug component (#8319) 2025-08-11 11:20:45 +12:00
J. Nick Koston
f5790bff73 adjust 2025-08-10 18:19:52 -05:00
J. Nick Koston
adf941f68e Merge remote-tracking branch 'upstream/dev' into ota_fixes 2025-08-10 18:04:22 -05:00
J. Nick Koston
e48a223eac preen 2025-08-10 18:04:08 -05:00
J. Nick Koston
cd5f7fdc98 preen 2025-08-10 18:03:56 -05:00
J. Nick Koston
8ca671ad6f Merge branch 'integration' into memory_api 2025-08-10 17:53:46 -05:00
J. Nick Koston
e535c62b47 Merge branch 'ota_fixes' into integration 2025-08-10 17:53:40 -05:00
J. Nick Koston
2bdf335127 uint32_t 2025-08-10 17:53:24 -05:00
J. Nick Koston
f0c97c299f uint32_t 2025-08-10 17:53:02 -05:00
J. Nick Koston
17cdf9c8d6 do not block until we get first magic byte 2025-08-10 17:48:47 -05:00
Clyde Stubbs
8b67d6dfec [lvgl] fix allocation of reduced size buffer with rotation (#10147) 2025-08-11 10:32:01 +12:00
Clyde Stubbs
581b4ef5a1 [lvgl] Various validation fixes (#10141) 2025-08-11 10:27:54 +12:00
Jonathan Swoboda
da02f970d4 [neopixelbus] Fix neopixelbus on esp32 (#10123) 2025-08-11 10:24:12 +12:00
Jesse Hills
2fc0a11596 [CI] Print more info for when consts are duplicated (#10166) 2025-08-11 09:53:40 +12:00
J. Nick Koston
5a8f722316 Optimize subprocess performance with close_fds=False (#10145) 2025-08-11 09:14:13 +12:00
J. Nick Koston
279f56141e [ade7880] Fix duplicate sensor name validation error (#10155) 2025-08-11 09:12:36 +12:00
J. Nick Koston
6bfe281d18 [web_server] Reduce flash usage by consolidating parameter parsing (#10154) 2025-08-11 09:09:31 +12:00
J. Nick Koston
a1371aea37 [dashboard] Fix port fallback regression when device is offline (#10135) 2025-08-11 09:04:40 +12:00
J. Nick Koston
3edb1e0726 Merge branch 'integration' into memory_api 2025-08-10 12:41:54 -05:00
J. Nick Koston
089721606b Merge branch 'ota_fixes' into integration 2025-08-10 12:41:38 -05:00
J. Nick Koston
0c230fcd10 increase to 30s 2025-08-10 12:39:44 -05:00
Jonathan Swoboda
d5c9c10b3b [esp32] Add IDF log_level option (#10134) 2025-08-10 17:27:08 +00:00
J. Nick Koston
7ff8094be2 Merge branch 'integration' into memory_api 2025-08-10 11:12:57 -05:00
J. Nick Koston
88642ec717 Merge remote-tracking branch 'swoboda1337/idf_logger' into integration 2025-08-10 11:12:46 -05:00
Jonathan Swoboda
d052dec11b Use CONF_LOG_LEVEL from const 2025-08-10 09:11:17 -04:00
Jonathan Swoboda
6d0e86cf25 Add log_level option to idf framework 2025-08-10 09:00:03 -04:00
J. Nick Koston
cef39e7c59 [esp32_ble_tracker] Fix false reboots when event loop is blocked (#10144) 2025-08-10 04:44:23 -05:00
J. Nick Koston
5394ee37f9 Merge branch 'integration' into memory_api 2025-08-09 21:02:17 -05:00
J. Nick Koston
8a87336aa8 Merge branch 'webserver_flash' into integration 2025-08-09 21:02:12 -05:00
J. Nick Koston
e64ecca771 tidy 2025-08-09 21:02:02 -05:00
J. Nick Koston
6aedcab37e Merge branch 'integration' into memory_api 2025-08-09 20:52:47 -05:00
J. Nick Koston
da9a29a1dd Merge branch 'webserver_flash' into integration 2025-08-09 20:52:37 -05:00
J. Nick Koston
4e07c50490 tweak 2025-08-09 20:52:28 -05:00
J. Nick Koston
5b91c5f043 Merge branch 'integration' into memory_api 2025-08-09 20:46:51 -05:00
J. Nick Koston
73b11896d4 Merge branch 'webserver_flash' into integration 2025-08-09 20:46:44 -05:00
J. Nick Koston
8faac0c184 [web_server] Reduce flash usage by consolidating parameter parsing 2025-08-09 20:41:44 -05:00
J. Nick Koston
233882e1c2 Merge branch 'integration' into memory_api 2025-08-09 14:06:01 -05:00
J. Nick Koston
54a2ac92bf Merge branch 'ota_fixes' into integration 2025-08-09 14:05:52 -05:00
J. Nick Koston
ea74a9ec8f [esphome] Fix OTA watchdog reset when port scanning 2025-08-09 14:01:49 -05:00
Edward Firmo
2b9e1ce315 [switch] Add trigger `on_state` (#10108) 2025-08-09 21:09:40 +10:00
J. Nick Koston
48a94b686d Merge branch 'integration' into memory_api 2025-08-08 16:23:20 -05:00
J. Nick Koston
32a968784c Merge branch 'subproc' into integration 2025-08-08 16:23:03 -05:00
J. Nick Koston
3ded96bb26 Optimize subprocess performance with close_fds=False 2025-08-08 16:18:04 -05:00
J. Nick Koston
c982e35189 Merge branch 'integration' into memory_api 2025-08-08 16:05:26 -05:00
J. Nick Koston
507ec82886 Merge branch 'port_fallback' into integration 2025-08-08 16:05:20 -05:00
J. Nick Koston
e316fe3b80 Merge branch 'esp32_ble_tracker_reboot_on_blocked_loop' into integration 2025-08-08 16:05:15 -05:00
dependabot[bot]
ff9ddb9d68 Bump tornado from 6.5.1 to 6.5.2 (#10142)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-08 16:03:13 -05:00
Edward Firmo
676c51ffa0 [switch] Add control() method to API (#10118) 2025-08-08 05:51:19 +00:00
J. Nick Koston
cdcf5fd74c [dashboard] Fix port fallback regression when device is offline 2025-08-07 18:47:54 -10:00
J. Nick Koston
7e4d09dbd8 [bluetooth_proxy] Optimize connection loop to reduce CPU usage (#10133) 2025-08-07 16:24:26 -10:00
J. Nick Koston
58504662d8 [cover] Reduce flash usage by optimizing validation messages (#10130) 2025-08-08 10:44:47 +10:00
J. Nick Koston
83b69519dd [wifi] Reduce flash usage by optimizing logging (#10127) 2025-08-08 10:43:13 +10:00
J. Nick Koston
d4d1a96f9b [esp32_ble_client] Reduce flash usage by optimizing logging strings (#10119) 2025-08-08 10:42:03 +10:00
J. Nick Koston
76fd104fb6 [mdns] Conditionally compile extra services to reduce flash usage (#10129) 2025-08-08 10:32:35 +10:00
Edward Firmo
c4d1b1317a [switch] Add switch.control automation action (#10105)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-08-08 08:55:54 +10:00
J. Nick Koston
61fbf7cd81 Merge branch 'integration' into memory_api 2025-08-07 12:55:44 -10:00
J. Nick Koston
11b82fe3d4 Merge branch 'startup_herd_ble_fix' into integration 2025-08-07 12:55:38 -10:00
J. Nick Koston
1de0a73a63 preen 2025-08-07 12:55:31 -10:00
J. Nick Koston
760add7d29 Merge branch 'integration' into memory_api 2025-08-07 12:39:23 -10:00
J. Nick Koston
86798e3a2b Merge branch 'startup_herd_ble_fix' into integration 2025-08-07 12:39:19 -10:00
J. Nick Koston
543e5099a4 [bluetooth_proxy] Optimize connection loop to reduce CPU usage 2025-08-07 12:38:15 -10:00
J. Nick Koston
3f31bcacad Merge branch 'integration' into memory_api 2025-08-07 10:28:59 -10:00
J. Nick Koston
4ba5718ddd Merge branch 'cover_logging' into integration 2025-08-07 10:28:51 -10:00
J. Nick Koston
ac05ab6de1 [cover] Reduce flash usage by optimizing validation messages 2025-08-07 10:28:07 -10:00
dependabot[bot]
14bc83342f Bump ruff from 0.12.7 to 0.12.8 (#10126)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-08-07 20:15:14 +00:00
dependabot[bot]
a1461c5293 Bump actions/cache from 4.2.3 to 4.2.4 (#10128)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-07 10:09:53 -10:00
J. Nick Koston
75249775ee Merge branch 'integration' into memory_api 2025-08-07 09:57:32 -10:00
J. Nick Koston
902846c6da Merge branch 'mdns_extra' into integration 2025-08-07 09:57:27 -10:00
J. Nick Koston
887d43d76c [mdns] Conditionally compile extra services to reduce flash usage 2025-08-07 09:56:47 -10:00
J. Nick Koston
2ff418c8f9 Merge branch 'integration' into memory_api 2025-08-07 09:44:14 -10:00
J. Nick Koston
3a2c7c9154 Merge branch 'wifi_flash' into integration 2025-08-07 09:44:08 -10:00
J. Nick Koston
c5c71bd85e [wifi] Reduce flash usage by optimizing logging 2025-08-07 09:43:24 -10:00
dependabot[bot]
73b2db8af5 Bump actions/cache from 4.2.3 to 4.2.4 in /.github/actions/restore-python (#10125)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-07 09:16:58 -10:00
J. Nick Koston
a7a119f576 [bluetooth_proxy] Remove V1 connection support (#10107) 2025-08-07 03:52:46 -05:00
J. Nick Koston
1ba76f5f2e [esp32_ble_client] Conditionally compile BLE service classes to reduce flash usage (#10114) 2025-08-07 03:46:34 -05:00
J. Nick Koston
fb86bd05db Merge branch 'integration' into memory_api 2025-08-06 22:42:38 -10:00
J. Nick Koston
4d56781be9 Merge branch 'esp32_ble_client_strings' into integration 2025-08-06 22:42:31 -10:00
J. Nick Koston
481bbeb6b5 [esp32_ble_client] Reduce flash usage by optimizing logging strings 2025-08-06 22:41:50 -10:00
J. Nick Koston
37a9ad6a0d [esp32_ble_tracker] Optimize member variable ordering to reduce memory padding (#10113) 2025-08-07 03:34:46 -05:00
J. Nick Koston
431a8dd374 Merge branch 'integration' into memory_api 2025-08-06 22:04:44 -10:00
J. Nick Koston
469076c7dd Merge branch 'cond_compile_service_char_desc_cond' into integration 2025-08-06 22:04:31 -10:00
J. Nick Koston
c5065f21b8 condtional 2025-08-06 19:53:57 -10:00
J. Nick Koston
c0a62c0be1 [esp32_ble_client] Avoid iterating empty services vector for bluetooth_proxy connections (#10110) 2025-08-07 03:40:12 +00:00
J. Nick Koston
9841d7cf87 Merge branch 'integration' into memory_api 2025-08-06 17:31:53 -10:00
J. Nick Koston
24246a136e Merge branch 'esp32_tracker_touch_ups' into integration 2025-08-06 17:31:48 -10:00
J. Nick Koston
cf1b24145b [esp32_ble_tracker] Optimize member variable ordering to reduce memory padding 2025-08-06 17:30:48 -10:00
J. Nick Koston
bfb14e1cf9 [esp32_touch] Restore get_value() for ESP32-S2/S3 variants (#10112) 2025-08-06 21:21:32 -05:00
mbo18
1415e02e40 Add device class absolute_humidity to the absolute humidity component (#10100)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-08-07 13:48:26 +12:00
dependabot[bot]
81f907e994 Bump actions/download-artifact from 4.3.0 to 5.0.0 (#10106)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-07 13:47:03 +12:00
J. Nick Koston
61008bc8a9 [bluetooth_proxy] Remove unnecessary heap allocation for response object (#10104) 2025-08-07 13:42:04 +12:00
J. Nick Koston
6d66ddd68d [bluetooth_proxy][esp32_ble_tracker][esp32_ble_client] Consolidate duplicate logging code to reduce flash usage (#10097) 2025-08-07 13:41:03 +12:00
J. Nick Koston
fc180251be [bluetooth_proxy] Consolidate dump_config() log calls (#10103) 2025-08-07 12:43:59 +12:00
J. Nick Koston
ee1d4f27ef [esp32_ble] Conditionally compile BLE advertising to reduce flash usage (#10099) 2025-08-07 12:29:24 +12:00
J. Nick Koston
325ec0a0ae [esp32_ble_client] Convert to C++17 nested namespace syntax (#10111) 2025-08-07 12:18:03 +12:00
J. Nick Koston
28d2c86a91 Merge branch 'dev' into memory_api 2025-08-06 14:08:07 -10:00
Keith Burzinski
6071f4b02c [ld2410] Replace `throttle` with native filters (#10019) 2025-08-07 10:26:11 +12:00
J. Nick Koston
5e8768084b Merge branch 'integration' into memory_api 2025-08-06 10:56:41 -10:00
J. Nick Koston
28c4460f8b Merge branch 'esp32_ble_client_namespace' into integration 2025-08-06 10:56:28 -10:00
J. Nick Koston
cb4d3d37cf [esp32_ble_client] Convert to C++17 nested namespace syntax 2025-08-06 10:55:56 -10:00
J. Nick Koston
e29b04bcfe Merge branch 'integration' into memory_api 2025-08-06 10:45:16 -10:00
J. Nick Koston
341d2febd6 Merge branch 'entire_service_list_copied_discarded' into integration 2025-08-06 10:45:06 -10:00
J. Nick Koston
534681b988 [esp32_ble_client] Fix V3_WITH_CACHE connections unnecessarily populating services vector
preen
2025-08-06 10:40:48 -10:00
J. Nick Koston
ddb1fcd0f9 preen 2025-08-06 10:39:44 -10:00
J. Nick Koston
2327c5bddf Merge branch 'integration' into memory_api 2025-08-06 10:28:49 -10:00
J. Nick Koston
a962bb4af2 Merge branch 'entire_service_list_copied_discarded' into integration 2025-08-06 10:28:43 -10:00
J. Nick Koston
ee98abe9f1 [esp32_ble_client] Fix V3_WITH_CACHE connections unnecessarily populating services vector 2025-08-06 10:27:18 -10:00
dependabot[bot]
083ac8ce8e Bump aioesphomeapi from 37.2.5 to 38.0.0 (#10109)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-06 10:21:29 -10:00
J. Nick Koston
2cdf50a025 tweak 2025-08-06 10:11:28 -10:00
J. Nick Koston
b75719d37e Merge branch 'integration' into memory_api 2025-08-06 10:03:29 -10:00
J. Nick Koston
e99794fe9b Merge branch 'drop_v1_connection_type_proxy_only' into integration 2025-08-06 10:03:22 -10:00
J. Nick Koston
16a2677bcf [bluetooth_proxy] Remove V1 connection support 2025-08-06 09:55:01 -10:00
J. Nick Koston
4ceda31f32 [bluetooth_proxy] Replace std::find with simple loop for small fixed array (#10102) 2025-08-07 07:53:42 +12:00
J. Nick Koston
27397593c1 Merge branch 'integration' into memory_api 2025-08-06 07:47:47 -10:00
J. Nick Koston
cb4cd00ad1 Merge branch 'proxy_alloc_cleanup' into integration 2025-08-06 07:47:41 -10:00
J. Nick Koston
0893d1d958 [bluetooth_proxy] Remove unnecessary heap allocation for response object 2025-08-06 07:47:14 -10:00
J. Nick Koston
5511dae2fa Merge branch 'integration' into memory_api 2025-08-06 07:38:12 -10:00
J. Nick Koston
1b65d2b1d3 Merge branch 'proxy_log_config' into integration 2025-08-06 07:38:05 -10:00
J. Nick Koston
2af29aab6f [bluetooth_proxy] Consolidate dump_config() log calls 2025-08-06 07:37:30 -10:00
J. Nick Koston
e1cb364436 Merge branch 'integration' into memory_api 2025-08-06 07:31:43 -10:00
J. Nick Koston
fdc4be8c0c Merge branch 'no_std_find_alloc' into integration 2025-08-06 07:31:35 -10:00
J. Nick Koston
a10e7b2a54 [bluetooth_proxy] Replace std::find with simple loop for small fixed array 2025-08-06 07:30:53 -10:00
J. Nick Koston
5021cc6d5f [esp32_ble] Make BLE notification limit configurable to fix ESP_GATT_NO_RESOURCES errors (#10098) 2025-08-06 17:24:02 +00:00
J. Nick Koston
e5a1820708 Merge branch 'integration' into memory_api 2025-08-06 07:09:31 -10:00
J. Nick Koston
211db40cb4 Merge branch 'conditional_compile_ble_adv' into integration 2025-08-06 07:09:21 -10:00
J. Nick Koston
0aec58665a remove filter, its too early 2025-08-06 07:09:05 -10:00
J. Nick Koston
c667218f3f Merge branch 'conditional_compile_ble_adv' into memory_api 2025-08-05 22:22:42 -10:00
J. Nick Koston
f19ed094b7 Merge branch 'conditional_compile_ble_adv' into integration 2025-08-05 22:22:36 -10:00
J. Nick Koston
f55ab960bb order 2025-08-05 22:22:26 -10:00
J. Nick Koston
2da1974a80 Merge branch 'integration' into memory_api 2025-08-05 22:02:28 -10:00
J. Nick Koston
bb4ddbd218 Merge branch 'ble_logging_cleanup' into integration 2025-08-05 22:02:18 -10:00
J. Nick Koston
9cc907778b Merge remote-tracking branch 'upstream/dev' into ble_logging_cleanup 2025-08-05 21:55:13 -10:00
J. Nick Koston
a11f32d6aa dry 2025-08-05 21:54:44 -10:00
J. Nick Koston
ba713737bc Merge branch 'integration' into memory_api 2025-08-05 21:36:58 -10:00
J. Nick Koston
0240c68771 Merge branch 'conditional_compile_ble_adv' into integration 2025-08-05 21:36:46 -10:00
J. Nick Koston
722d76565c [esp32_ble] Conditionally compile BLE advertising to reduce flash usage 2025-08-05 21:30:07 -10:00
J. Nick Koston
096b9c9651 Merge branch 'integration' into memory_api 2025-08-05 20:54:21 -10:00
J. Nick Koston
605e840f81 Merge branch 'out_of_notify' into integration 2025-08-05 20:53:50 -10:00
J. Nick Koston
3bfd77426a [esp32_ble] Make BLE notification limit configurable to fix ESP_GATT_NO_RESOURCES errors 2025-08-05 20:49:35 -10:00
Craig Andrews
2b3e546203 [deep_sleep] enable sleep pull up/down for wakeup pin (#9395) 2025-08-05 23:47:45 -07:00
J. Nick Koston
7e288126fa Merge branch 'integration' into memory_api 2025-08-05 20:30:40 -10:00
J. Nick Koston
b475542c8b Merge branch 'ble_logging_cleanup' into integration 2025-08-05 20:30:34 -10:00
J. Nick Koston
5d93388a5f [bluetooth_proxy][esp32_ble_tracker][esp32_ble_client] Consolidate duplicate logging code to reduce flash usage 2025-08-05 20:26:43 -10:00
J. Nick Koston
1642d34d29 [esp32_ble_tracker] Simplify state machine guards with helper functions (#10092) 2025-08-06 01:03:19 -05:00
J. Nick Koston
8ceb1b9d60 [bluetooth_proxy] Reduce flash usage by consolidating duplicate logging (#10094) 2025-08-06 00:49:20 -05:00
Jesse Hills
d872c8a999 [light] Allow light effect schema to be a schema object already (#10091) 2025-08-06 00:05:48 -05:00
Pawelo
99125c045f [bme680] Eliminate warnings due to unused functions (#9735)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-08-06 00:02:54 -05:00
Jonathan Swoboda
860a5ef5c0 [esp32_rmt_led_strip] Work around IDFGH-16195 (#10093) 2025-08-05 23:28:09 -05:00
J. Nick Koston
addeec572a Merge branch 'integration' into memory_api 2025-08-05 17:26:40 -10:00
J. Nick Koston
bb95320348 Merge branch 'bluetooth_proxy_flash' into integration 2025-08-05 17:26:34 -10:00
J. Nick Koston
c1ace213ab [bluetooth_proxy] Reduce flash usage by consolidating duplicate logging 2025-08-05 17:26:06 -10:00
J. Nick Koston
c253eb2362 Merge branch 'integration' into memory_api 2025-08-05 17:06:06 -10:00
J. Nick Koston
8fbef8e71e Merge branch 'esp32_ble_tracker_more_cleanups' into integration 2025-08-05 17:05:56 -10:00
J. Nick Koston
c5d5e66f30 dry 2025-08-05 17:04:02 -10:00
J. Nick Koston
eea84a43d6 Merge branch 'integration' into memory_api 2025-08-05 17:02:43 -10:00
J. Nick Koston
c52bd6fecf Merge branch 'esp32_ble_tracker_more_cleanups' into integration 2025-08-05 17:02:34 -10:00
J. Nick Koston
028d20908e Merge remote-tracking branch 'upstream/dev' into integration 2025-08-05 17:02:31 -10:00
J. Nick Koston
ef271cbd3b [esp32_ble_tracker] Simplify state machine guards with helper functions 2025-08-05 17:01:53 -10:00
J. Nick Koston
b01f03cc24 [esp32_ble_tracker] Refactor loop() method for improved readability and performance (#10074) 2025-08-06 14:26:11 +12:00
J. Nick Koston
cfb22e33c9 [esp32_ble_tracker] Add missing USE_ESP32_BLE_DEVICE guard for already_discovered_ member (#10085) 2025-08-06 14:22:32 +12:00
@RubenKelevra
96bbb58f34 update espressif's esp32-camera library to 2.1.1 (#10090) 2025-08-05 14:33:15 -10:00
Jesse Hills
3edd746c6c [mcp23xxx] Use CachedGpioExpander (#10078) 2025-08-06 11:01:57 +12:00
Copilot
c308e03e92 [select] Fix new_select() not forwarding constructor args while preserving keyword-only options parameter (#10036)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: clydebarrow <2366188+clydebarrow@users.noreply.github.com>
Co-authored-by: jesserockz <3060199+jesserockz@users.noreply.github.com>
2025-08-06 08:09:36 +12:00
NP v/d Spek
bd2b3b9da5 [espnow] Small changes and fixes (#10014)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-08-06 07:46:40 +12:00
Kevin Ahrendt
d443a97dd8 [speaker] Media player fixes for IDF5.4 (#10088) 2025-08-05 14:55:40 -04:00
J. Nick Koston
58a088e06b Add myself to multiple bluetooth codeowners (#10083) 2025-08-05 09:00:04 +00:00
J. Nick Koston
7344ff6941 merge 2025-08-04 21:50:36 -10:00
J. Nick Koston
2b5d035c39 Merge branch 'integration' into memory_api 2025-08-04 21:49:10 -10:00
J. Nick Koston
6cc5f83c71 Merge branch 'already_discovered_missing_guard' into integration 2025-08-04 21:48:48 -10:00
Jesse Hills
49a46883ed [core] Update core component codeowners to `@esphome/core` (#10082) 2025-08-05 06:24:24 +00:00
J. Nick Koston
acdcf514b9 [esp32_ble_tracker] Add missing USE_ESP32_BLE_DEVICE guard for already_discovered_ member 2025-08-04 20:14:30 -10:00
J. Nick Koston
89cf81baaa Merge branch 'integration' into memory_api 2025-08-04 20:06:47 -10:00
J. Nick Koston
7c328e51c4 Merge branch 'esp32_ble_co' into integration 2025-08-04 20:06:29 -10:00
J. Nick Koston
ba9cf1b5f6 Add myself to multiple bluetooth codeowners 2025-08-04 19:56:22 -10:00
J. Nick Koston
bc03538e25 Support multiple --device arguments for address fallback (#10003)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-08-05 16:40:46 +12:00
dependabot[bot]
969034b61a Bump docker/login-action from 3.4.0 to 3.5.0 in the docker-actions group (#10081)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-05 16:18:42 +12:00
Jonathan Swoboda
06eb1b6014 [remote_transmitter] Add digital_write automation (#10069)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-08-05 16:09:37 +12:00
Jesse Hills
589d00f17f Merge branch 'release' into dev 2025-08-05 15:38:25 +12:00
Jesse Hills
68c0aa4d6d Merge pull request #10079 from esphome/bump-2025.7.5
2025.7.5
2025-08-05 15:37:42 +12:00
J. Nick Koston
1c7200545b Merge branch 'integration' into memory_api 2025-08-04 16:52:44 -10:00
J. Nick Koston
e499374964 Merge branch 'multi_device_args' into integration 2025-08-04 16:52:30 -10:00
J. Nick Koston
63705c5a6e Merge branch 'dev' into multi_device_args 2025-08-04 16:51:57 -10:00
dependabot[bot]
2fddb061e1 Bump aioesphomeapi from 37.2.4 to 37.2.5 (#10080)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-04 16:51:42 -10:00
J. Nick Koston
3bbd3acea6 Merge branch 'integration' into memory_api 2025-08-04 16:26:55 -10:00
J. Nick Koston
8fc1835e5b Merge branch 'esp32_ble_tracker_cleanup_code' into integration 2025-08-04 16:26:49 -10:00
J. Nick Koston
655d001d72 address bot comments 2025-08-04 16:26:40 -10:00
J. Nick Koston
5f9080dac9 fix --device OTA 2025-08-04 15:57:29 -10:00
Jesse Hills
c85eb448e4 [gpio_expander] Fix bank caching (#10077)
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>
2025-08-05 13:45:52 +12:00
J. Nick Koston
1d6c491dea Merge branch 'dev' into multi_device_args 2025-08-04 15:43:15 -10:00
Jesse Hills
396c02c6de [core] Allow extra args on cli and just ignore them (#9814)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-05 13:33:12 +12:00
Jesse Hills
52c4509208 [esp32_dac] Always use esp-idf APIs (#9833) 2025-08-05 13:31:56 +12:00
J. Nick Koston
9e1054cb87 Merge branch 'integration' into memory_api 2025-08-04 15:25:44 -10:00
J. Nick Koston
e0fe73ec5b Merge branch 'esp32_ble_tracker_cleanup_code' into integration 2025-08-04 15:25:37 -10:00
J. Nick Koston
166ed736a9 Merge remote-tracking branch 'upstream/dev' into esp32_ble_tracker_cleanup_code 2025-08-04 15:24:55 -10:00
Jesse Hills
d29cae9c3b Bump version to 2025.7.5 2025-08-05 13:21:00 +12:00
Chris Beswick
532e3e370f [i2s_audio] Use high-pass filter for dc offset correction (#10005) 2025-08-05 13:21:00 +12:00
Clyde Stubbs
da573a217d [font] Catch file load exception (#10058)
Co-authored-by: clydeps <U5yx99dok9>
2025-08-05 13:21:00 +12:00
J. Nick Koston
a9b27d1966 [api] Fix OTA progress updates not being sent when main loop is blocked (#10049) 2025-08-05 13:21:00 +12:00
Clyde Stubbs
0aa3c9685e [lvgl] Bugfix for tileview (#9938) 2025-08-05 13:21:00 +12:00
J. Nick Koston
93b28447ee [bluetooth_proxy] Optimize memory usage with fixed-size array and const string references (#10015) 2025-08-05 13:13:55 +12:00
J. Nick Koston
52634dac2a [tests] Add datetime entities to host_mode_many_entities integration test (#10032) 2025-08-05 13:12:05 +12:00
J. Nick Koston
64c94c1440 [esp32_ble_client] Fix connection parameter timing by setting preferences before connection (#10059) 2025-08-05 13:11:32 +12:00
J. Nick Koston
f7bf1ef52c [esp32_ble_tracker] Eliminate redundant ring buffer for lower latency (#10057)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-08-05 13:10:32 +12:00
J. Nick Koston
fa8c5e880c [esp32_ble_tracker] Optimize connection by promoting client immediately after scan stop trigger (#10061)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-05 13:10:02 +12:00
J. Nick Koston
27ba90ea95 [esp32_ble_client] Start MTU negotiation earlier following ESP-IDF examples (#10062) 2025-08-05 12:59:23 +12:00
J. Nick Koston
469246b8d8 [bluetooth_proxy] Warn about BLE connection timeout mismatch on Arduino framework (#10063)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-05 12:58:41 +12:00
J. Nick Koston
50f15735dc [api] Add helpful compile-time errors for Custom API Device methods (#10076) 2025-08-05 12:57:31 +12:00
mschnaubelt
83d9c02a1b Add CO5300 display support (#9739) 2025-08-05 09:41:55 +10:00
J. Nick Koston
df83205997 Merge branch 'integration' into memory_api 2025-08-04 11:17:58 -10:00
J. Nick Koston
d8a2e020a9 Merge branch 'helpful_custom_api_error' into integration 2025-08-04 11:17:48 -10:00
J. Nick Koston
fb1d2368a9 fix 2025-08-04 11:15:47 -10:00
J. Nick Koston
76cdef966b fix 2025-08-04 11:14:22 -10:00
J. Nick Koston
c6aeeb98b6 Merge branch 'integration' into memory_api 2025-08-04 11:10:01 -10:00
J. Nick Koston
b5bd065f94 Merge branch 'helpful_custom_api_error' into integration 2025-08-04 11:09:42 -10:00
J. Nick Koston
734b2691c8 [api] Add helpful compile-time errors for Custom API Device methods 2025-08-04 11:08:00 -10:00
J. Nick Koston
739cc5ff50 [esp32_ble_tracker] Refactor loop() method for improved readability and performance 2025-08-04 09:24:22 -10:00
J. Nick Koston
2facd1b436 Cleanup esp32_ble_tracker 2025-08-04 09:18:30 -10:00
Jonathan Swoboda
701e6099aa [espnow, web_server_idf] Fix IDF 5.5 compile issues (#10068) 2025-08-04 08:56:34 -10:00
J. Nick Koston
d4ff83bf6e Merge branch 'integration' into memory_api 2025-08-04 08:52:25 -10:00
J. Nick Koston
97544869bd Merge branch '5_5_fixes' into integration 2025-08-04 08:52:17 -10:00
Chris Beswick
d59476d0e1 [i2s_audio] Use high-pass filter for dc offset correction (#10005) 2025-08-04 10:43:44 -04:00
Jonathan Swoboda
608cc4f0d1 Fix 5.5 compile issues 2025-08-04 08:45:04 -04:00
Djordje Mandic
fbbb791b0d [gt911] Use timeout instead of delay, shortened log msg (#10024)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-08-04 03:37:43 -05:00
J. Nick Koston
15790145b2 Merge branch 'integration' into memory_api 2025-08-03 22:31:55 -10:00
J. Nick Koston
75b6bb9f76 Merge branch 'warn_ble_timeout_mismatch' into integration 2025-08-03 22:31:48 -10:00
J. Nick Koston
74c0e63a1d cleanup 2025-08-03 22:31:27 -10:00
J. Nick Koston
1d3cd0500e Merge branch 'integration' into memory_api 2025-08-03 22:20:15 -10:00
J. Nick Koston
0cebde66bd Merge branch 'warn_ble_timeout_mismatch' into integration 2025-08-03 22:20:11 -10:00
J. Nick Koston
081f0a1871 Update esphome/components/bluetooth_proxy/__init__.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-03 22:19:48 -10:00
J. Nick Koston
5062bab73f Merge branch 'integration' into memory_api 2025-08-03 22:17:25 -10:00
J. Nick Koston
8694cf71fd Merge branch 'warn_ble_timeout_mismatch' into integration 2025-08-03 22:17:17 -10:00
J. Nick Koston
2bc77be5ab [bluetooth_proxy] Warn about BLE connection timeout mismatch on Arduino framework 2025-08-03 22:16:40 -10:00
J. Nick Koston
cccbe4293b Merge branch 'integration' into memory_api 2025-08-03 21:42:00 -10:00
J. Nick Koston
8077dbd892 Merge branch 'mtu_sooner' into integration 2025-08-03 21:41:55 -10:00
J. Nick Koston
e6629f662c [esp32_ble_client] Start MTU negotiation earlier following ESP-IDF examples 2025-08-03 21:41:15 -10:00
J. Nick Koston
5126aefe13 Merge branch 'integration' into memory_api 2025-08-03 21:23:05 -10:00
J. Nick Koston
da3c6ade7b Merge branch 'promote_after_stop' into integration 2025-08-03 21:22:55 -10:00
J. Nick Koston
dd80fcdb62 Update esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-03 21:22:38 -10:00
J. Nick Koston
3a99929619 Merge branch 'integration' into memory_api 2025-08-03 21:02:31 -10:00
J. Nick Koston
d4449f372a Merge branch 'fix_connection_param_order' into integration 2025-08-03 21:02:14 -10:00
J. Nick Koston
a645c02476 Merge branch 'integration' into memory_api 2025-08-03 20:58:39 -10:00
J. Nick Koston
951d0de52d Merge branch 'promote_after_stop' into integration 2025-08-03 20:58:34 -10:00
J. Nick Koston
8d4f1802fb [esp32_ble_tracker] Optimize connection by promoting client immediately after scan stop trigger 2025-08-03 20:57:02 -10:00
J. Nick Koston
fffa9b813c [esp32_ble_client] Fix connection parameter timing by setting preferences before connection 2025-08-03 19:51:18 -10:00
J. Nick Koston
36c4430317 [esp32_ble] Fix BLE connection slot waste by aligning ESP-IDF timeout with client timeout (#10013) 2025-08-04 17:41:41 +12:00
J. Nick Koston
5ddf32b0a6 Merge branch 'integration' into memory_api 2025-08-03 19:32:46 -10:00
J. Nick Koston
8cc6cf2bbd Merge remote-tracking branch 'upstream/fold_ring_buffer_esp32_ble_tracker' into integration 2025-08-03 19:32:34 -10:00
J. Nick Koston
6be22a5ea9 [esp32_ble_client] Connect immediately on READY_TO_CONNECT to reduce latency (#10051) 2025-08-04 17:15:28 +12:00
J. Nick Koston
989058e6a9 [esp32_ble_client] Use FAST connection parameters for all v3 connections (#10052) 2025-08-04 17:12:06 +12:00
Jesse Hills
61386aaf6e Merge branch 'dev' into fold_ring_buffer_esp32_ble_tracker 2025-08-04 17:00:08 +12:00
J. Nick Koston
7c297366c7 [esp32_ble_tracker] Remove unnecessary STOPPED scanner state to reduce latency (#10055) 2025-08-04 16:57:59 +12:00
Clyde Stubbs
bb3ebaf955 [font] Catch file load exception (#10058)
Co-authored-by: clydeps <U5yx99dok9>
2025-08-04 16:55:54 +12:00
Jesse Hills
3007ca4d57 [core] Move docs url generator to helpers.py (#10056)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-03 23:55:46 -05:00
Jesse Hills
a5f1661643 [nfc] Rename `binary_sensor` source files (#10053) 2025-08-03 23:43:04 -05:00
J. Nick Koston
85fd10f06e Merge branch 'integration' into memory_api 2025-08-03 18:06:01 -10:00
J. Nick Koston
fe8f24cad7 Merge branch 'fold_ring_buffer_esp32_ble_tracker' into integration 2025-08-03 18:05:54 -10:00
J. Nick Koston
5a695267aa [esp32_ble_tracker] Eliminate redundant ring buffer for lower latency 2025-08-03 18:04:09 -10:00
Jesse Hills
4d683d5a69 [AI] Add note about the defines.h file needing to include all new defines added (#10054) 2025-08-03 16:45:35 -10:00
J. Nick Koston
c0c0a42362 [api] Use static allocation for areas and devices in DeviceInfoResponse (#10038)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-08-04 02:37:47 +00:00
J. Nick Koston
a6c8651298 Merge branch 'integration' into memory_api 2025-08-03 16:31:11 -10:00
J. Nick Koston
4945855415 Merge branch 'no_more_stopped_state' into integration 2025-08-03 16:31:01 -10:00
J. Nick Koston
9ff89dfb81 dry 2025-08-03 16:29:31 -10:00
J. Nick Koston
6a5eb460ef [esp32] Add framework migration warning for upcoming ESP-IDF default change (#10030)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-04 14:27:05 +12:00
J. Nick Koston
ef372eeeb7 [wifi] Replace std::stable_sort with insertion sort to save 2.4KB flash (#10037) 2025-08-04 14:19:24 +12:00
J. Nick Koston
7a7132f1c8 Merge branch 'integration' into memory_api 2025-08-03 16:16:40 -10:00
J. Nick Koston
5c491b385e Merge branch 'no_more_stopped_state' into integration 2025-08-03 16:16:33 -10:00
J. Nick Koston
2e08285570 [esp32_ble_tracker] Remove unnecessary STOPPED scanner state to reduce latency 2025-08-03 16:14:34 -10:00
J. Nick Koston
9aad0733ef [core] Update to esptool 5.0+ command syntax (#10011) 2025-08-04 14:14:17 +12:00
J. Nick Koston
494a1a216c [web_server] Conditionally compile authentication code to save flash memory (#10022) 2025-08-04 14:09:12 +12:00
J. Nick Koston
a75f73dbf0 [web_server] Reduce binary size by using EntityBase and minimizing template instantiations (#10033) 2025-08-04 14:03:37 +12:00
J. Nick Koston
c9d865a061 [core] Optimize Application::pre_setup() to reduce duplicate MAC address operations (#10039) 2025-08-04 14:02:10 +12:00
J. Nick Koston
3fbbdb4589 [web_server_idf] Replace std::find_if with simple loop to reduce binary size (#10042)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-04 14:00:56 +12:00
J. Nick Koston
cd6cf074d9 [core] Replace std::stable_sort with insertion sort to save 3.5KB flash (#10035) 2025-08-04 13:56:06 +12:00
J. Nick Koston
d86e1e29a9 [core] Convert components, devices, and areas vectors to static allocation (#10020) 2025-08-04 13:51:50 +12:00
J. Nick Koston
367e35771e Merge branch 'integration' into memory_api 2025-08-03 15:51:48 -10:00
J. Nick Koston
86af0d7965 Merge branch 'second_connection_fix' into integration 2025-08-03 15:51:42 -10:00
J. Nick Koston
e17a200b7c [esp32_ble_client] Use FAST connection parameters for all v3 connections 2025-08-03 15:51:02 -10:00
J. Nick Koston
dbaf2cdd50 [core] Replace std::find and std::max_element with simple loops to reduce binary size (#10044) 2025-08-04 13:46:06 +12:00
J. Nick Koston
27d66e5cfe Merge branch 'integration' into memory_api 2025-08-03 15:45:56 -10:00
J. Nick Koston
72142bc7d7 Merge branch 'reduce_connect_one_loop' into integration 2025-08-03 15:45:50 -10:00
J. Nick Koston
137df4ff20 [esp32_ble_client] Connect immediately on READY_TO_CONNECT to reduce latency 2025-08-03 15:45:03 -10:00
dependabot[bot]
b44d2183aa Bump aioesphomeapi from 37.2.3 to 37.2.4 (#10050)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-04 01:19:12 +00:00
@RubenKelevra
0f13af0076 Update esp32-camera library version to 2.1.0 (#9527) 2025-08-03 15:08:11 -10:00
J. Nick Koston
ef33d36d63 Merge branch 'integration' into memory_api 2025-08-03 15:04:46 -10:00
J. Nick Koston
ee899147ff Merge branch 'update_esp32_camera' into integration 2025-08-03 15:04:39 -10:00
Clyde Stubbs
339c26c815 [color][lvgl] Allow Color to be used for lv_color_t (#10016) 2025-08-04 12:51:34 +12:00
J. Nick Koston
d69e98e15d [api] Fix OTA progress updates not being sent when main loop is blocked (#10049) 2025-08-04 00:23:45 +00:00
J. Nick Koston
e95baa67d5 Merge branch 'integration' into memory_api 2025-08-03 13:55:26 -10:00
J. Nick Koston
72eaba6e2c Merge branch 'update_no_batch' into integration 2025-08-03 13:55:19 -10:00
J. Nick Koston
3e69f41b42 needs ifdef 2025-08-03 13:54:03 -10:00
J. Nick Koston
be7b63898f [api] Fix OTA progress updates not being sent when main loop is blocked 2025-08-03 13:43:15 -10:00
J. Nick Koston
a86c0b66c8 Merge branch 'unregister_fd_flash' into memory_api 2025-08-02 22:45:29 -10:00
J. Nick Koston
fb004fd0c9 Merge branch 'unregister_fd_flash' into integration 2025-08-02 22:45:24 -10:00
J. Nick Koston
53449f298e lint 2025-08-02 22:45:13 -10:00
Clyde Stubbs
b1b0638fab [config] Fix reversion of excessive yaml output after error (#10043)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-08-02 22:35:52 -10:00
J. Nick Koston
f34e7a0051 Merge branch 'integration' into memory_api 2025-08-02 22:03:23 -10:00
J. Nick Koston
68e8966b47 Merge branch 'webserver_std_find' into integration 2025-08-02 22:03:09 -10:00
J. Nick Koston
5c7ddc584e Merge branch 'unregister_fd_flash' into integration 2025-08-02 22:03:05 -10:00
J. Nick Koston
451095eef4 [core] Replace std::find and std::max_element with simple loops to reduce binary size 2025-08-02 21:50:39 -10:00
J. Nick Koston
b667cc45cc [web_server_idf] Replace std::find_if with simple loop to reduce binary size 2025-08-02 17:22:41 -10:00
J. Nick Koston
be701c58e1 Merge branch 'integration' into memory_api 2025-08-02 15:57:31 -10:00
J. Nick Koston
aafa1190ce Merge branch 'core_dupe_add_mac' into integration 2025-08-02 15:57:25 -10:00
J. Nick Koston
7a8b2feec6 [core] Optimize Application::pre_setup() to reduce duplicate MAC address operations 2025-08-02 15:56:47 -10:00
J. Nick Koston
5d6a152c45 Merge branch 'integration' into memory_api 2025-08-02 15:37:27 -10:00
J. Nick Koston
f9e15558e7 Merge branch 'static_areas_devices_api' into integration 2025-08-02 15:37:11 -10:00
J. Nick Koston
88f251b29c [api] Use static allocation for areas and devices in DeviceInfoResponse 2025-08-02 14:48:51 -10:00
J. Nick Koston
7faded49d3 Merge branch 'integration' into memory_api 2025-08-02 14:23:48 -10:00
J. Nick Koston
07ce321e99 Merge branch 'webserver_entity_base' into integration 2025-08-02 14:23:41 -10:00
J. Nick Koston
7391bbc6ee suggestion 2025-08-02 14:20:18 -10:00
J. Nick Koston
901fd47f48 Merge branch 'dev' into webserver_entity_base 2025-08-02 14:00:47 -10:00
J. Nick Koston
296442d8f1 [core] Fix compilation errors when platform sections have no entities (#10023) 2025-08-02 13:59:20 -10:00
J. Nick Koston
5f0e1f8ab5 Merge branch 'integration' into memory_api 2025-08-02 13:01:22 -10:00
J. Nick Koston
eb5def5ad7 Merge branch 'wifi_sort' into integration 2025-08-02 13:01:11 -10:00
J. Nick Koston
61c97b029c preen 2025-08-02 13:01:03 -10:00
J. Nick Koston
3ef334c882 Merge branch 'integration' into memory_api 2025-08-02 12:54:39 -10:00
J. Nick Koston
a5a64edf9a Merge branch 'sort_core' into integration 2025-08-02 12:54:29 -10:00
J. Nick Koston
67abbc833f flex 2025-08-02 12:49:03 -10:00
J. Nick Koston
ade5aba423 Merge branch 'integration' into memory_api 2025-08-02 12:47:00 -10:00
J. Nick Koston
56eedad727 Merge branch 'wifi_sort' into integration 2025-08-02 12:46:51 -10:00
J. Nick Koston
9c76847aca [wifi] Replace std::stable_sort with insertion sort to save 2.4KB flash 2025-08-02 12:45:44 -10:00
J. Nick Koston
711eb2d7eb Merge branch 'sort_core' into integration 2025-08-02 12:28:09 -10:00
J. Nick Koston
40dcee594b preen 2025-08-02 12:27:54 -10:00
Copilot
fd442cc485 [syslog] Fix RFC3164 timestamp compliance for single-digit days (#10034)
Co-authored-by: clydebarrow <2366188+clydebarrow@users.noreply.github.com>
2025-08-03 08:21:54 +10:00
J. Nick Koston
36eab00eac preen 2025-08-02 12:14:17 -10:00
J. Nick Koston
178910d15e Merge branch 'integration' into memory_api 2025-08-02 12:04:28 -10:00
J. Nick Koston
c609341605 Merge branch 'sort_core' into integration 2025-08-02 12:04:09 -10:00
J. Nick Koston
c89bc0bfd7 [core] Replace std::stable_sort with insertion sort to save 1.3KB flash 2025-08-02 12:02:30 -10:00
J. Nick Koston
18dca1a07d Merge branch 'integration' into memory_api 2025-08-02 10:30:55 -10:00
J. Nick Koston
7ac9bdb36b Merge branch 'webserver_entity_base' into integration 2025-08-02 10:30:48 -10:00
J. Nick Koston
894565a97f [web_server] Reduce binary size by using EntityBase and minimizing template instantiations 2025-08-02 10:15:41 -10:00
J. Nick Koston
79bc7ba206 Merge branch 'integration' into memory_api 2025-08-02 10:05:56 -10:00
J. Nick Koston
2575913880 Merge branch 'drop_py_esptool' into integration 2025-08-02 10:05:48 -10:00
J. Nick Koston
716c25366c do the others 2025-08-02 10:01:36 -10:00
J. Nick Koston
aa33baf5a2 Merge branch 'integration' into memory_api 2025-08-02 09:47:48 -10:00
J. Nick Koston
ce74f07218 Merge branch 'no_entites_fix' into integration 2025-08-02 09:47:35 -10:00
J. Nick Koston
4dd175df90 Merge branch 'idf_default' into integration 2025-08-02 09:47:23 -10:00
J. Nick Koston
e4db32d73e tweak 2025-08-02 09:21:57 -10:00
J. Nick Koston
a1e7317f5e [esp32] Add framework migration warning for upcoming ESP-IDF default change 2025-08-02 08:46:08 -10:00
J. Nick Koston
30f988c5f3 [esp32] Add framework migration warning for upcoming ESP-IDF default change 2025-08-02 08:42:46 -10:00
J. Nick Koston
ed2e8466c8 [esp32] Add framework migration warning for upcoming ESP-IDF default change 2025-08-02 08:42:17 -10:00
J. Nick Koston
2c01c06828 remove test 2025-08-02 07:53:32 -10:00
J. Nick Koston
466f8d2050 remove test 2025-08-02 07:53:14 -10:00
J. Nick Koston
90b68d6fa0 Merge branch 'integration' into memory_api 2025-08-02 00:00:58 -10:00
J. Nick Koston
ee4a1528d7 Merge branch 'no_entites_fix' into integration 2025-08-02 00:00:40 -10:00
J. Nick Koston
bba63625a4 [core] Fix compilation errors when platform sections have no entities 2025-08-01 23:58:32 -10:00
J. Nick Koston
37827c1272 Merge branch 'integration' into memory_api 2025-08-01 23:08:30 -10:00
J. Nick Koston
58a5b6ac71 Merge branch 'webserver_conditional_auth' into integration 2025-08-01 23:08:19 -10:00
J. Nick Koston
49b5dd3299 missed one 2025-08-01 23:08:03 -10:00
J. Nick Koston
3986399e93 missed one 2025-08-01 23:07:37 -10:00
J. Nick Koston
9088790e63 Merge branch 'integration' into memory_api 2025-08-01 23:00:24 -10:00
J. Nick Koston
151718ccf2 Merge branch 'webserver_conditional_auth' into integration 2025-08-01 23:00:15 -10:00
J. Nick Koston
fefa35a418 define 2025-08-01 22:57:26 -10:00
J. Nick Koston
204b54ce38 preen 2025-08-01 22:53:17 -10:00
J. Nick Koston
c28147b3a4 test 2025-08-01 22:43:42 -10:00
J. Nick Koston
fdb437deb2 Merge branch 'integration' into memory_api 2025-08-01 22:39:01 -10:00
J. Nick Koston
11c48ab9c7 Merge branch 'webserver_conditional_auth' into integration 2025-08-01 22:38:54 -10:00
J. Nick Koston
e50135ef8a [web_server] Conditionally compile authentication code to save flash memory 2025-08-01 22:37:35 -10:00
J. Nick Koston
9b3ee6936d Merge branch 'integration' into memory_api 2025-08-01 21:26:51 -10:00
J. Nick Koston
983690f56d Merge branch 'static_comp_areas' into integration 2025-08-01 21:26:44 -10:00
J. Nick Koston
72d0660261 Merge branch 'integration' into memory_api 2025-08-01 21:26:29 -10:00
J. Nick Koston
dcecbb9fa8 Merge branch 'bluetooth_connection_churn_array' into integration 2025-08-01 21:26:19 -10:00
J. Nick Koston
a8f4b5c4e2 fixes 2025-08-01 21:25:58 -10:00
J. Nick Koston
015bb6f602 reorder 2025-08-01 21:05:28 -10:00
J. Nick Koston
f1650fc647 static comp, areas, devices 2025-08-01 20:54:41 -10:00
J. Nick Koston
9d0df67a9e Merge branch 'integration' into memory_api 2025-08-01 20:33:14 -10:00
J. Nick Koston
833602db74 Merge branch 'bluetooth_connection_churn_array' into integration 2025-08-01 20:32:48 -10:00
J. Nick Koston
20959c2366 [bluetooth_proxy] Optimize memory usage with fixed-size array and const string references 2025-08-01 20:32:09 -10:00
J. Nick Koston
4f58e1c8b9 [core] Convert entity vectors to static allocation for reduced memory usage (#10018) 2025-08-01 20:26:22 -10:00
J. Nick Koston
00d9baed11 [bluetooth_proxy] Eliminate heap allocations in connection state reporting (#10010) 2025-08-01 20:26:00 -10:00
J. Nick Koston
18fb3618a0 Merge branch 'integration' into memory_api 2025-08-01 15:41:50 -10:00
J. Nick Koston
0fc874b7d3 Merge branch 'static_entity_vectors' into integration 2025-08-01 15:41:43 -10:00
J. Nick Koston
d8d9123c58 fix clang-tiy 2025-08-01 15:41:33 -10:00
J. Nick Koston
4019bf9027 Merge branch 'integration' into memory_api 2025-08-01 15:36:16 -10:00
J. Nick Koston
8c2f0580d6 Merge branch 'static_entity_vectors' into integration 2025-08-01 15:36:01 -10:00
J. Nick Koston
4de68ded79 preen 2025-08-01 15:31:01 -10:00
J. Nick Koston
591b9ce87b preen 2025-08-01 15:28:48 -10:00
J. Nick Koston
7e25846cad preen 2025-08-01 15:26:51 -10:00
J. Nick Koston
a25edf93d6 preen 2025-08-01 15:26:13 -10:00
J. Nick Koston
13c749ceda preen 2025-08-01 15:26:04 -10:00
J. Nick Koston
8bf3d52fb0 tidy 2025-08-01 15:25:10 -10:00
J. Nick Koston
082e365f82 Merge branch 'integration' into memory_api 2025-08-01 15:00:49 -10:00
J. Nick Koston
48060f2f7f Merge branch 'static_entity_vectors' into integration 2025-08-01 15:00:41 -10:00
J. Nick Koston
7351fb374f [core] Convert entity vectors to static allocation for reduced memory usage 2025-08-01 14:59:01 -10:00
J. Nick Koston
9005767b67 Merge branch 'integration' into memory_api 2025-08-01 14:13:33 -10:00
J. Nick Koston
d401200404 Merge branch 'bluetooth_connection_churn_array' into integration 2025-08-01 14:13:22 -10:00
J. Nick Koston
68ab351cc8 [bluetooth_proxy] Optimize memory usage with fixed-size array and const string references 2025-08-01 14:12:08 -10:00
J. Nick Koston
1c469747d4 Merge branch 'integration' into memory_api 2025-08-01 13:01:25 -10:00
J. Nick Koston
ee6e24b424 Merge branch 'bluetooth_connection_churn' into integration 2025-08-01 13:01:10 -10:00
J. Nick Koston
11e8cfba3d tidy 2025-08-01 13:00:54 -10:00
J. Nick Koston
7d1a816c5e Merge branch 'integration' into memory_api 2025-08-01 12:47:49 -10:00
J. Nick Koston
b86722dfa4 Merge branch 'wasted_slot_fix' into integration 2025-08-01 12:47:41 -10:00
J. Nick Koston
54227ff768 fix 2025-08-01 12:43:51 -10:00
J. Nick Koston
23519c9211 fix 2025-08-01 12:43:10 -10:00
J. Nick Koston
559872fa31 Fix BLE connection slot waste by aligning ESP-IDF timeout with client timeout 2025-08-01 12:39:21 -10:00
J. Nick Koston
1a55885fc3 Merge branch 'integration' into memory_api 2025-08-01 11:21:24 -10:00
J. Nick Koston
1bd4951713 Merge branch 'bluetooth_connection_churn' into integration 2025-08-01 11:21:10 -10:00
J. Nick Koston
fa267f94ea preen 2025-08-01 11:20:57 -10:00
J. Nick Koston
9f52caf3b6 Merge branch 'integration' into memory_api 2025-08-01 11:19:46 -10:00
J. Nick Koston
c111b8bc11 Merge branch 'bluetooth_connection_churn' into integration 2025-08-01 11:19:33 -10:00
J. Nick Koston
f77d15a381 preen 2025-08-01 11:19:27 -10:00
J. Nick Koston
7667325788 Merge branch 'integration' into memory_api 2025-08-01 11:17:16 -10:00
J. Nick Koston
b51b3bf9ce Merge branch 'drop_py_esptool' into integration 2025-08-01 11:17:09 -10:00
J. Nick Koston
3aaf11f404 missed some 2025-08-01 11:15:34 -10:00
J. Nick Koston
ee7c44c3b0 Merge branch 'integration' into memory_api 2025-08-01 11:06:26 -10:00
J. Nick Koston
e079e46d99 Merge branch 'bluetooth_connection_churn' into memory_api 2025-08-01 11:06:24 -10:00
J. Nick Koston
d65fa4b5fa Merge branch 'bluetooth_connection_churn' into integration 2025-08-01 11:06:14 -10:00
J. Nick Koston
493bfaf76a cleanup 2025-08-01 11:02:48 -10:00
J. Nick Koston
f7c7aa9f9a Merge branch 'integration' into memory_api 2025-08-01 10:43:58 -10:00
J. Nick Koston
eb851174d3 merge 2025-08-01 10:43:40 -10:00
J. Nick Koston
b84fc1e777 Merge branch 'bluetooth_connection_churn' into integration 2025-08-01 10:41:46 -10:00
J. Nick Koston
3a52b754c0 preen 2025-08-01 10:30:02 -10:00
J. Nick Koston
a8af06b4dc Merge remote-tracking branch 'origin/bluetooth_connection_churn' into bluetooth_connection_churn 2025-08-01 10:29:36 -10:00
J. Nick Koston
d3cbe21fa3 preen 2025-08-01 10:29:24 -10:00
J. Nick Koston
1ce52f2b0f Update esphome/components/bluetooth_proxy/bluetooth_connection.cpp 2025-08-01 10:22:03 -10:00
J. Nick Koston
a41adad41a Merge branch 'dev' into bluetooth_connection_churn 2025-08-01 10:21:46 -10:00
dependabot[bot]
f1877ca084 Bump aioesphomeapi from 37.2.2 to 37.2.3 (#10012)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-01 20:16:28 +00:00
J. Nick Koston
7c12f1a5bf [core] Update to use esptool instead of deprecated esptool.py 2025-08-01 10:06:16 -10:00
dependabot[bot]
1f7c59f88d Bump esptool from 4.9.0 to 5.0.2 (#9983)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-01 10:02:29 -10:00
J. Nick Koston
7d06013608 missing define 2025-08-01 10:01:33 -10:00
dependabot[bot]
b5f42bc493 Bump aioesphomeapi from 37.2.1 to 37.2.2 (#10009)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-01 09:53:56 -10:00
J. Nick Koston
aa0b80b004 Eliminate heap allocations in bluetooth_proxy connection state reporting 2025-08-01 09:50:11 -10:00
Jesse Hills
d8a46c7482 [CI] Allow multiple grep options for clang-tidy (#10004) 2025-08-01 21:40:53 +12:00
J. Nick Koston
e17af87f6e preen 2025-07-31 22:25:44 -10:00
J. Nick Koston
20ad1ab4eb [wifi] Fix crash during WiFi reconnection on ESP32 with poor signal quality (#9989) 2025-08-01 02:46:52 -05:00
Clyde Stubbs
940a8b43fa [esp32] Add config option to execute from PSRAM (#9907)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-08-01 16:07:11 +10:00
J. Nick Koston
bea2f4971e preen 2025-07-31 20:07:06 -10:00
J. Nick Koston
42fe7d9fb2 preen 2025-07-31 20:05:34 -10:00
J. Nick Koston
204da1af8b preen 2025-07-31 20:03:31 -10:00
J. Nick Koston
65e2c20bcf preen 2025-07-31 20:02:25 -10:00
J. Nick Koston
837863568f preen 2025-07-31 19:52:34 -10:00
J. Nick Koston
8a15d2ea8c preen 2025-07-31 19:51:21 -10:00
J. Nick Koston
082d741066 preen 2025-07-31 19:46:40 -10:00
J. Nick Koston
264fbb4029 preen 2025-07-31 19:45:54 -10:00
J. Nick Koston
b96cd2b932 preen 2025-07-31 19:41:04 -10:00
J. Nick Koston
5fac039a06 preen 2025-07-31 19:39:08 -10:00
J. Nick Koston
1161bfcc93 preen 2025-07-31 19:35:49 -10:00
tomaszduda23
f761404bf6 [nrf52, gpio] check different port notation (#9737) 2025-08-01 16:54:20 +12:00
tomaszduda23
e4dc62ea74 [nrf52, debug] debug component for nrf52 (#8315) 2025-08-01 16:53:40 +12:00
NP v/d Spek
c42c5dd946 [espnow] Basic communication between ESP32 devices (#9582)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-08-01 16:51:01 +12:00
J. Nick Koston
d3f103c789 make entry.address take priority over mdns 2025-07-31 17:28:04 -10:00
J. Nick Koston
4caf2b7042 cleanup 2025-07-31 17:16:15 -10:00
J. Nick Koston
13e9350568 cleanup 2025-07-31 17:13:42 -10:00
J. Nick Koston
1c67dfc850 Support multiple --device arguments for address fallback 2025-07-31 17:02:39 -10:00
Keith Burzinski
291215909a [sensor] A little bit of filter clean-up (#9986) 2025-08-01 02:55:59 +00:00
Jonathan Swoboda
0954a6185c [sensor] Fix bug in percentage based delta filter (#8157)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-08-01 02:15:56 +00:00
J. Nick Koston
f13e742bd5 [ruff] Enable RET and fix all violations (#9929) 2025-08-01 02:10:56 +00:00
tomaszduda23
7a4738ec4e [nrf52] add adc (#9321)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-08-01 13:49:39 +12:00
Clyde Stubbs
549b0d12b6 [image] Improve schemas (#9791) 2025-08-01 13:19:32 +12:00
Djordje Mandic
412f4ac341 [midea] Use c++17 constexpr and inline static in IrFollowMeData (#10002) 2025-07-31 14:28:22 -10:00
J. Nick Koston
d4ff1bcf5c [bluetooth_proxy] Implement dynamic service batching based on MTU constraints (#10001)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-31 14:15:12 -10:00
Clyde Stubbs
161f51e1f4 [esp32] Fix strapping pin validation for P4 and H2 (#9980) 2025-08-01 11:48:25 +12:00
Jonathan Swoboda
da0c47629a [esp32] Bump ESP32 platform to 54.03.21-2 (#10000) 2025-07-31 21:58:57 +00:00
J. Nick Koston
f3a57bd248 Merge branch 'integration' into memory_api 2025-07-31 11:51:50 -10:00
J. Nick Koston
151530836c Merge branch 'btp_uuids_dynamic_services_sq' into integration 2025-07-31 11:51:39 -10:00
J. Nick Koston
69d33cdd3d preen 2025-07-31 11:51:24 -10:00
J. Nick Koston
038548500c Merge branch 'integration' into memory_api 2025-07-31 11:45:32 -10:00
J. Nick Koston
5d0323d6ea Merge branch 'btp_uuids_dynamic_services_sq' into memory_api 2025-07-31 11:45:28 -10:00
J. Nick Koston
e57205793c Merge branch 'btp_uuids_dynamic_services_sq' into integration 2025-07-31 11:45:23 -10:00
J. Nick Koston
30b687ccbb fix name 2025-07-31 11:45:12 -10:00
J. Nick Koston
6d40866231 Merge branch 'integration' into memory_api 2025-07-31 11:44:07 -10:00
J. Nick Koston
b06c307ec8 Merge branch 'btp_uuids_dynamic_services_sq' into integration 2025-07-31 11:43:59 -10:00
J. Nick Koston
854e29161b only needed once 2025-07-31 11:43:49 -10:00
J. Nick Koston
6ac8c47b6e preen 2025-07-31 11:41:35 -10:00
J. Nick Koston
c10330b890 preen 2025-07-31 11:40:28 -10:00
J. Nick Koston
27861d85fe preen 2025-07-31 11:40:04 -10:00
J. Nick Koston
abb775fc53 Merge branch 'integration' into memory_api 2025-07-31 11:37:40 -10:00
J. Nick Koston
27141f2886 Merge branch 'btp_uuids_dynamic_services_sq' into integration 2025-07-31 11:37:27 -10:00
J. Nick Koston
8729ba17a0 preen 2025-07-31 11:37:17 -10:00
J. Nick Koston
ce6aee873f Merge branch 'integration' into memory_api 2025-07-31 11:27:15 -10:00
J. Nick Koston
a808d00b88 Merge branch 'btp_uuids_dynamic_services_sq' into integration 2025-07-31 11:27:01 -10:00
J. Nick Koston
3c88d8388e Merge branch 'btp_uuids_dynamic_services' into integration 2025-07-31 11:26:41 -10:00
J. Nick Koston
dd7441e104 Update esphome/components/bluetooth_proxy/bluetooth_connection.cpp 2025-07-31 11:25:48 -10:00
J. Nick Koston
0f19e23486 Update esphome/components/bluetooth_proxy/bluetooth_connection.cpp 2025-07-31 11:25:33 -10:00
J. Nick Koston
7205b1edf0 [bluetooth_proxy] Implement dynamic service batching based on MTU constraints 2025-07-31 11:24:31 -10:00
J. Nick Koston
28b277c1c4 [bluetooth_proxy] Optimize UUID transmission with efficient short_uuid field (#9995) 2025-07-31 16:20:53 -05:00
J. Nick Koston
f2b3f413fc back 2025-07-31 07:56:57 -10:00
J. Nick Koston
0ae7dcdb62 tweak 2025-07-31 07:48:54 -10:00
J. Nick Koston
0356e24bae tweak 2025-07-31 07:46:18 -10:00
J. Nick Koston
d6776804ae tweak 2025-07-31 07:45:03 -10:00
J. Nick Koston
255cf4b661 wip 2025-07-31 07:34:02 -10:00
J. Nick Koston
38e2b6c5f3 wip 2025-07-31 07:33:14 -10:00
J. Nick Koston
fe2b2d5280 fix 2025-07-31 07:19:03 -10:00
J. Nick Koston
b66141e5ba fix 2025-07-31 07:12:53 -10:00
J. Nick Koston
1225df594f preen 2025-07-31 06:59:10 -10:00
J. Nick Koston
551bff33c2 preen 2025-07-31 06:47:31 -10:00
J. Nick Koston
3a80aac6e8 ble dynamic batch 2025-07-31 06:35:19 -10:00
J. Nick Koston
3988b48708 Merge branch 'btp_uuids' into memory_api 2025-07-31 05:15:41 -10:00
J. Nick Koston
d338f753a5 Merge branch 'btp_uuids' into integration 2025-07-31 05:15:34 -10:00
J. Nick Koston
1877d5d11d Merge remote-tracking branch 'upstream/btp_uuids' into btp_uuids 2025-07-31 05:15:22 -10:00
J. Nick Koston
f120240350 dry 2025-07-31 05:15:12 -10:00
J. Nick Koston
c6aa704d39 Merge branch 'dev' into btp_uuids 2025-07-31 04:41:32 -10:00
dependabot[bot]
936a090aaa Bump aioesphomeapi from 37.2.0 to 37.2.1 (#9998)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-31 04:41:19 -10:00
J. Nick Koston
ccae1bbe15 Merge branch 'integration' into memory_api 2025-07-31 04:17:55 -10:00
J. Nick Koston
d11a3ed742 Merge branch 'btp_uuids' into integration 2025-07-31 04:17:46 -10:00
J. Nick Koston
ef05c97984 Merge remote-tracking branch 'upstream/btp_uuids' into btp_uuids 2025-07-31 04:06:06 -10:00
J. Nick Koston
f3d42ef6e4 save 4 bytes since we must store as uint32_t anyways 2025-07-31 04:05:48 -10:00
J. Nick Koston
766e3480cf Merge branch 'dev' into btp_uuids 2025-07-30 23:20:50 -10:00
dependabot[bot]
1be6d27012 Bump aioesphomeapi from 37.1.6 to 37.2.0 (#9996)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-30 23:20:43 -10:00
J. Nick Koston
40e2960264 fixes 2025-07-30 22:15:39 -10:00
J. Nick Koston
712de79973 tidy 2025-07-30 22:06:31 -10:00
J. Nick Koston
37911e84f2 [bluetooth_proxy] Send native 16/32-bit UUIDs instead of always converting to 128-bit 2025-07-30 21:24:40 -10:00
J. Nick Koston
6f4a8100ef Merge branch 'integration' into memory_api 2025-07-30 19:26:41 -10:00
J. Nick Koston
f52dadab41 Merge remote-tracking branch 'upstream/dev' into integration 2025-07-30 19:26:28 -10:00
J. Nick Koston
71557c9f58 [bluetooth_proxy] Batch BLE service discovery messages for 67% reduction in API traffic (#9992) 2025-07-30 23:11:11 -05:00
J. Nick Koston
88cfcc1967 [esp32_ble_client] Fix BLE connection stability for WiFi-based proxies (#9993)
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-07-30 22:36:33 -05:00
GilDev
fb379bbb88 [wifi] Allow fast_connect with multiple networks (#9947) 2025-07-31 15:34:49 +12:00
J. Nick Koston
383f54810c Merge branch 'fix_normal_opts' into memory_api 2025-07-30 16:12:47 -10:00
J. Nick Koston
3abc959e37 Merge branch 'fix_normal_opts' into integration 2025-07-30 16:12:42 -10:00
J. Nick Koston
d1cf6c2b14 [esp32_ble_client] Fix BLE connection stability for WiFi-based proxies 2025-07-30 16:12:07 -10:00
J. Nick Koston
77677f3edc Merge branch 'integration' into memory_api 2025-07-30 15:39:40 -10:00
J. Nick Koston
a46d9f3ff2 Merge branch 'service_batching_ble' into integration 2025-07-30 15:39:30 -10:00
J. Nick Koston
97b522da98 Merge branch 'dev' into service_batching_ble 2025-07-30 15:39:11 -10:00
J. Nick Koston
2b58f78082 fix busy loop on fail 2025-07-30 15:38:19 -10:00
mrtoy-me
88d8cfe6a2 [tm1651] Remove dependency on Arduino Library (#9645)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-07-30 20:20:55 -05:00
J. Nick Koston
f25abc3248 [esp32_ble] Fix spurious BLE 5.0 event warnings on ESP32-S3 (#9969) 2025-07-30 20:18:50 -05:00
J. Nick Koston
5b6e152d6c [esp32_touch] Work around ESP-IDF v5.4 regression in touch_pad_read_filtered (#9957)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-30 20:17:35 -05:00
J. Nick Koston
1d0a38446f [api] Reduce flash usage through targeted optimizations (#9979) 2025-07-30 20:10:23 -05:00
rwrozelle
853dca6c5c [api] Bump APIVersion to 1.11 (#9990) 2025-07-30 15:02:09 -10:00
J. Nick Koston
caa9f6fdc7 Merge branch 'integration' into memory_api 2025-07-30 15:00:31 -10:00
J. Nick Koston
e50840232e Merge branch 'service_batching_ble' into integration 2025-07-30 15:00:20 -10:00
J. Nick Koston
08aad73af9 did not need 2025-07-30 15:00:11 -10:00
J. Nick Koston
093e8093f5 Merge branch 'integration' into memory_api 2025-07-30 14:54:05 -10:00
J. Nick Koston
60b548fccd Merge branch 'service_batching_ble' into integration 2025-07-30 14:53:59 -10:00
J. Nick Koston
7692aacc2d [bluetooth_proxy] Batch BLE service discovery messages for 67% reduction in API traffic 2025-07-30 14:51:35 -10:00
J. Nick Koston
ecb029e0a7 [bluetooth_proxy] Batch BLE service discovery messages for 67% reduction in API traffic 2025-07-30 14:50:20 -10:00
J. Nick Koston
12cd1ec525 [bluetooth_proxy] Batch BLE service discovery messages for 67% reduction in API traffic 2025-07-30 14:46:13 -10:00
J. Nick Koston
a4ebcc691a Batch 3 services 2025-07-30 14:33:11 -10:00
Jesse Hills
97560fd9ef [CI] Add labels for checkboxes (#9991) 2025-07-31 12:17:20 +12:00
J. Nick Koston
de51f0f205 Merge branch 'integration' into memory_api 2025-07-30 13:18:01 -10:00
J. Nick Koston
1194b20b09 Merge branch 'wifi_reconnect_race_fix' into integration 2025-07-30 13:17:49 -10:00
J. Nick Koston
79bee386ff [wifi] Fix crash during WiFi reconnection on ESP32 with poor signal quality 2025-07-30 13:16:40 -10:00
Clyde Stubbs
4b7f3355ea [core] Fix regex for lambda id() replacement (#9975) 2025-07-30 12:56:43 -10:00
dependabot[bot]
110eac4f09 Bump aioesphomeapi from 37.1.5 to 37.1.6 (#9988)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-30 12:46:01 -10:00
rwrozelle
79533cb0d7 media_player add off on capability (#9294)
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+github@koston.org>
2025-07-30 12:02:53 -10:00
J. Nick Koston
07bc41a900 Merge branch 'integration' into memory_api 2025-07-30 09:43:05 -10:00
J. Nick Koston
e23fb2bf4e Merge branch 'api_polish' into integration 2025-07-30 09:42:52 -10:00
J. Nick Koston
8d9daca386 address copilot review comments 2025-07-30 09:42:28 -10:00
J. Nick Koston
1600ab58a1 Merge branch 'integration' into memory_api 2025-07-30 00:12:36 -10:00
J. Nick Koston
3e2b7e8309 Merge branch 'api_polish' into integration 2025-07-30 00:12:29 -10:00
J. Nick Koston
1568fc36cc preen 2025-07-29 23:39:32 -10:00
J. Nick Koston
a8493df659 api polish 2025-07-29 23:33:43 -10:00
dependabot[bot]
f4f69e827b Bump ruff from 0.12.5 to 0.12.7 (#9976)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-07-30 09:17:47 +00:00
dependabot[bot]
48a4dde824 Bump aioesphomeapi from 37.1.4 to 37.1.5 (#9977)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-30 09:16:00 +00:00
J. Nick Koston
24174c3eed Merge branch 'integration' into memory_api 2025-07-29 22:55:46 -10:00
J. Nick Koston
e81c5ef61e Merge branch 'ruff_ret' into integration 2025-07-29 22:55:33 -10:00
J. Nick Koston
8e68b1a7d9 Merge remote-tracking branch 'upstream/dev' into ruff_ret 2025-07-29 22:48:15 -10:00
J. Nick Koston
9b4fe54f45 [esp32_ble_client] Fix connection failures with short discovery timeout devices and speed up BLE connections (#9971) 2025-07-29 19:19:12 -10:00
Keith Burzinski
913c58cd2c [template] Add tests for more sensor filters (#9973) 2025-07-30 14:20:25 +12:00
J. Nick Koston
4441d0ea8d Merge branch 'integration' into memory_api 2025-07-29 15:53:43 -10:00
J. Nick Koston
fdde5ea0f1 Merge branch 'service_discovery' into integration 2025-07-29 15:53:31 -10:00
J. Nick Koston
68b8fab33a const 2025-07-29 15:53:15 -10:00
J. Nick Koston
537c774a6c use const 2025-07-29 15:47:36 -10:00
J. Nick Koston
4aec2a95f2 Merge branch 'integration' into memory_api 2025-07-29 14:58:15 -10:00
J. Nick Koston
7698e7faee Merge branch 'service_discovery' into integration 2025-07-29 14:58:04 -10:00
J. Nick Koston
561d7ec978 cleanup 2025-07-29 14:57:52 -10:00
Keith Burzinski
374858efeb [sensor] Add new filter: `throttle_with_priority` (#9937) 2025-07-30 12:53:14 +12:00
Samuel Sieb
14dd48f9c3 [wifi] add more disconnect reason descriptions (#9955)
Co-authored-by: Samuel Sieb <samuel@sieb.net>
2025-07-30 12:41:31 +12:00
J. Nick Koston
579c6c57e0 Merge branch 'service_discovery' into memory_api 2025-07-29 14:32:55 -10:00
J. Nick Koston
3018b1a7e5 Merge branch 'service_discovery' into integration 2025-07-29 14:32:49 -10:00
J. Nick Koston
63484d9f08 tidy 2025-07-29 14:32:34 -10:00
J. Nick Koston
ff1239c2a4 Merge branch 'integration' into memory_api 2025-07-29 14:27:04 -10:00
J. Nick Koston
4999b5793f Merge branch 'service_discovery' into integration 2025-07-29 14:26:53 -10:00
J. Nick Koston
f794506002 Revert "[esp32_ble] Add PHY configuration and default to 1M for compatibility"
This reverts commit 5c44cd8962.
2025-07-29 14:26:47 -10:00
J. Nick Koston
92055b221a Revert "test"
This reverts commit 51d2e70854.
2025-07-29 14:26:37 -10:00
J. Nick Koston
f810ebbf79 [esp32_ble_client] Fix connection failures with short discovery timeout devices and speed up BLE connections 2025-07-29 14:24:46 -10:00
J. Nick Koston
76d33308d9 [api] Eliminate heap allocations when populating repeated fields from containers (#9948) 2025-07-30 10:41:37 +12:00
Dayowe
daccaf36a7 Fix WiFi to prefer strongest AP when multiple APs have same SSID (#9963)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-07-30 09:10:53 +12:00
J. Nick Koston
53d68abf79 Merge branch 'integration' into memory_api 2025-07-29 10:17:46 -10:00
J. Nick Koston
ad86f1352b Merge branch 's3_ble_events' into integration 2025-07-29 10:17:35 -10:00
J. Nick Koston
1adf45eebf [esp32_ble] Fix spurious BLE 5.0 event warnings on ESP32-S3 2025-07-29 10:17:00 -10:00
Clyde Stubbs
56c88807ee [mipi_dsi] Add dependencies (#9952) 2025-07-30 08:16:32 +12:00
J. Nick Koston
11f0d0015c Merge branch 'integration' into memory_api 2025-07-29 09:55:31 -10:00
J. Nick Koston
dadcab1581 Merge branch 'ble_phy_defaults' into integration 2025-07-29 09:55:25 -10:00
J. Nick Koston
51d2e70854 test 2025-07-29 09:54:44 -10:00
J. Nick Koston
5c44cd8962 [esp32_ble] Add PHY configuration and default to 1M for compatibility 2025-07-29 09:50:11 -10:00
dependabot[bot]
9c6dbbd8ea Bump aioesphomeapi from 37.1.3 to 37.1.4 (#9964) 2025-07-29 17:43:35 +00:00
J. Nick Koston
2537c4437f cleanup 2025-07-29 07:15:12 -10:00
J. Nick Koston
9133554588 Merge branch 'integration' into memory_api 2025-07-29 07:06:56 -10:00
J. Nick Koston
f577c857c5 Merge remote-tracking branch 'upstream/api_heap_churn_info' into integration 2025-07-29 07:06:40 -10:00
J. Nick Koston
5c5f29fbc8 Merge branch 'dev' into api_heap_churn_info 2025-07-29 07:06:25 -10:00
J. Nick Koston
e222232376 Merge branch 'integration' into memory_api 2025-07-29 07:04:07 -10:00
J. Nick Koston
05ad1d310b Merge remote-tracking branch 'upstream/dev' into integration 2025-07-29 07:03:50 -10:00
rwrozelle
a7dd849a8e Media player API enumeration alignment and feature flags (#9949)
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-07-29 07:00:47 -10:00
J. Nick Koston
aeec9a9379 Merge branch 'integration' into memory_api 2025-07-28 22:11:00 -10:00
J. Nick Koston
e12458c30f Merge branch 'api_heap_churn_info' into integration 2025-07-28 22:10:49 -10:00
J. Nick Koston
8b52a9a02e Merge branch 'integration' into memory_api 2025-07-28 22:10:32 -10:00
J. Nick Koston
b324978c9d Merge branch 'disable_touch_pad_read_filtered' into integration 2025-07-28 22:10:19 -10:00
J. Nick Koston
e0e0a1a420 [esp32_touch] Work around ESP-IDF v5.4 regression in touch_pad_read_filtered() 2025-07-28 22:08:29 -10:00
Clyde Stubbs
1f0c606be4 [component] Revert setup messages to LOG_CONFIG level (#9956) 2025-07-29 07:32:45 +00:00
Jesse Hills
ace375944c [esp32] Fix post build (#9951)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-29 06:44:45 +00:00
Clyde Stubbs
5f7c2f771f [adc] Enable ADC on ESP32-P4 (#9954) 2025-07-29 18:20:37 +12:00
J. Nick Koston
20294e9307 Merge remote-tracking branch 'upstream/api_heap_churn_info' into api_heap_churn_info 2025-07-28 19:54:27 -10:00
J. Nick Koston
e113078f82 document 2025-07-28 19:54:08 -10:00
Jonathan Swoboda
3d5b602288 [esp32] Bump platform to 54.03.21-1 and add support for tagged releases (#9926)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-07-29 05:52:34 +00:00
J. Nick Koston
b4fe1e61f5 Merge branch 'dev' into api_heap_churn_info 2025-07-28 19:46:05 -10:00
J. Nick Koston
7822865aee limit change 2025-07-28 19:37:44 -10:00
J. Nick Koston
14d1fd02cc fix 2025-07-28 19:30:32 -10:00
Djordje Mandic
6d30269565 [output] Add set_min_power & set_max_power actions for FloatOutput (#8934)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-07-29 17:22:44 +12:00
Keith Burzinski
4ff3137c0d [gps] Fix slow parsing (#9953) 2025-07-29 17:21:52 +12:00
rwrozelle
9d43ddd6f1 Openthread add Teardown (#9275)
Co-authored-by: mc <mc@debian>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-07-29 16:25:17 +12:00
Jonathan Swoboda
f733c43dec [heatpumpir] Fix issue with IRremoteESP8266 being included on ESP32 (#9950) 2025-07-29 15:59:58 +12:00
J. Nick Koston
397bc80a15 Merge branch 'dev' into api_heap_churn_info 2025-07-28 13:41:46 -10:00
Keith Burzinski
f5f0a01a85 [text_sensor] Add support for default filters (#9936) 2025-07-29 11:35:40 +12:00
Keith Burzinski
908891a096 [binary_sensor] Add support for default filters (#9935) 2025-07-29 11:35:11 +12:00
Keith Burzinski
7657316a92 [sensor] Add support for default filters (#9934) 2025-07-29 11:34:52 +12:00
J. Nick Koston
8ebde566d2 Merge branch 'dev' into api_heap_churn_info 2025-07-28 13:34:26 -10:00
J. Nick Koston
4f425c700a [esp32] Enable LWIP core locking on ESP-IDF to reduce socket operation overhead (#9857) 2025-07-29 11:33:54 +12:00
J. Nick Koston
dbe895f0a3 preen 2025-07-28 12:46:58 -10:00
J. Nick Koston
7ab8cc49c6 preen 2025-07-28 12:44:07 -10:00
J. Nick Koston
5b7085287f preen 2025-07-28 12:43:50 -10:00
J. Nick Koston
4e565202e4 preen 2025-07-28 12:42:46 -10:00
J. Nick Koston
224ea51cd7 zero copy vectors 2025-07-28 12:35:38 -10:00
J. Nick Koston
2c9987869e [api] Align ProtoSize API design with ProtoWriteBuffer pattern (#9920) 2025-07-29 10:28:32 +12:00
J. Nick Koston
68f388f78e [api] Optimize protobuf empty message handling to reduce flash and runtime overhead (#9908) 2025-07-29 10:25:07 +12:00
Jesse Hills
189d20a822 [heatpumpir] Bump library to 1.0.37 (#9944) 2025-07-28 16:21:53 -05:00
dependabot[bot]
08defd7360 Bump aioesphomeapi from 37.1.2 to 37.1.3 (#9943)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-28 11:02:53 -10:00
J. Nick Koston
59d466a6c8 [api] Remove unnecessary string copies from optional access (#9897) 2025-07-29 08:55:41 +12:00
J. Nick Koston
85435e6b5f [scheduler] Eliminate more runtime string allocations from retry (#9930) 2025-07-29 08:54:16 +12:00
Clyde Stubbs
f9453f9642 [lvgl] Bugfix for tileview (#9938) 2025-07-29 08:43:22 +12:00
Jesse Hills
f6cdbe37f9 Merge branch 'release' into dev 2025-07-28 19:34:23 +12:00
Jesse Hills
d6b222c370 Merge pull request #9933 from esphome/bump-2025.7.4
2025.7.4
2025-07-28 19:33:19 +12:00
Clyde Stubbs
eecdaa5163 [config_validation] extend should combine extra validations (#9939) 2025-07-28 19:23:35 +12:00
J. Nick Koston
4933ef780b [bluetooth_proxy] Fix service discovery cache pollution and descriptor count parameter bug (#9902) 2025-07-27 23:50:17 -05:00
Jesse Hills
573dad1736 Bump version to 2025.7.4 2025-07-28 15:55:07 +12:00
Jimmy Hedman
3a6cc0ea3d Fail with old lerp (#9914)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-07-28 15:55:07 +12:00
cryptk
2f9475a927 Add seed flag when running setup with uv present (#9932) 2025-07-28 15:55:07 +12:00
Jesse Hills
8dce7b0905 [logger] Don't allow `logger.log actions without configuring the logger` (#9821) 2025-07-28 15:55:07 +12:00
Eric Hoffmann
8b0ad3072f fix: non-optional x/y target calculation for ld2450 (#9849) 2025-07-28 15:55:07 +12:00
Clyde Stubbs
93028a4d90 [gt911] i2c fixes (#9822) 2025-07-28 15:55:07 +12:00
Jonathan Swoboda
c9793f3741 [remote_receiver] Fix idle validation (#9819) 2025-07-28 15:55:07 +12:00
J. Nick Koston
a4026d6ba1 [ruff] Enable RET and fix all violations 2025-07-27 08:34:43 -10:00
RubenKelevra
25666811c6 Update esp32-camera library version to 2.1.0 2025-07-24 20:49:59 +02:00
1041 changed files with 41883 additions and 12050 deletions

View File

@@ -9,7 +9,7 @@ This document provides essential context for AI models interacting with this pro
## 2. Core Technologies & Stack
* **Languages:** Python (>=3.10), C++ (gnu++20)
* **Languages:** Python (>=3.11), C++ (gnu++20)
* **Frameworks & Runtimes:** PlatformIO, Arduino, ESP-IDF.
* **Build Systems:** PlatformIO is the primary build system. CMake is used as an alternative.
* **Configuration:** YAML.
@@ -38,7 +38,7 @@ This document provides essential context for AI models interacting with this pro
5. **Dashboard** (`esphome/dashboard/`): A web-based interface for device configuration, management, and OTA updates.
* **Platform Support:**
1. **ESP32** (`components/esp32/`): Espressif ESP32 family. Supports multiple variants (S2, S3, C3, etc.) and both IDF and Arduino frameworks.
1. **ESP32** (`components/esp32/`): Espressif ESP32 family. Supports multiple variants (Original, C2, C3, C5, C6, H2, P4, S2, S3) with ESP-IDF framework. Arduino framework supports only a subset of the variants (Original, C3, S2, S3).
2. **ESP8266** (`components/esp8266/`): Espressif ESP8266. Arduino framework only, with memory constraints.
3. **RP2040** (`components/rp2040/`): Raspberry Pi Pico/RP2040. Arduino framework with PIO (Programmable I/O) support.
4. **LibreTiny** (`components/libretiny/`): Realtek and Beken chips. Supports multiple chip families and auto-generated components.
@@ -60,7 +60,7 @@ This document provides essential context for AI models interacting with this pro
├── __init__.py # Component configuration schema and code generation
├── [component].h # C++ header file (if needed)
├── [component].cpp # C++ implementation (if needed)
└── [platform]/ # Platform-specific implementations
└── [platform]/ # Platform-specific implementations
├── __init__.py # Platform-specific configuration
├── [platform].h # Platform C++ header
└── [platform].cpp # Platform C++ implementation
@@ -150,7 +150,8 @@ This document provides essential context for AI models interacting with this pro
* **Configuration Validation:**
* **Common Validators:** `cv.int_`, `cv.float_`, `cv.string`, `cv.boolean`, `cv.int_range(min=0, max=100)`, `cv.positive_int`, `cv.percentage`.
* **Complex Validation:** `cv.All(cv.string, cv.Length(min=1, max=50))`, `cv.Any(cv.int_, cv.string)`.
* **Platform-Specific:** `cv.only_on(["esp32", "esp8266"])`, `cv.only_with_arduino`.
* **Platform-Specific:** `cv.only_on(["esp32", "esp8266"])`, `esp32.only_on_variant(...)`, `cv.only_on_esp32`, `cv.only_on_esp8266`, `cv.only_on_rp2040`.
* **Framework-Specific:** `cv.only_with_framework(...)`, `cv.only_with_arduino`, `cv.only_with_esp_idf`.
* **Schema Extensions:**
```python
CONFIG_SCHEMA = cv.Schema({ ... })
@@ -168,6 +169,8 @@ This document provides essential context for AI models interacting with this pro
* `platformio.ini`: Configures the PlatformIO build environments for different microcontrollers.
* `.pre-commit-config.yaml`: Configures the pre-commit hooks for linting and formatting.
* **CI/CD Pipeline:** Defined in `.github/workflows`.
* **Static Analysis & Development:**
* `esphome/core/defines.h`: A comprehensive header file containing all `#define` directives that can be added by components using `cg.add_define()` in Python. This file is used exclusively for development, static analysis tools, and CI testing - it is not used during runtime compilation. When developing components that add new defines, they must be added to this file to ensure proper IDE support and static analysis coverage. The file includes feature flags, build configurations, and platform-specific defines that help static analyzers understand the complete codebase without needing to compile for specific platforms.
## 6. Development & Testing Workflow

View File

@@ -1 +1 @@
32b0db73b3ae01ba18c9cbb1dabbd8156bc14dded500471919bd0a3dc33916e0
499db61c1aa55b98b6629df603a56a1ba7aff5a9a7c781a5c1552a9dcd186c08

View File

@@ -47,7 +47,7 @@ runs:
- name: Build and push to ghcr by digest
id: build-ghcr
uses: docker/build-push-action@v6.18.0
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
env:
DOCKER_BUILD_SUMMARY: false
DOCKER_BUILD_RECORD_UPLOAD: false
@@ -73,7 +73,7 @@ runs:
- name: Build and push to dockerhub by digest
id: build-dockerhub
uses: docker/build-push-action@v6.18.0
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
env:
DOCKER_BUILD_SUMMARY: false
DOCKER_BUILD_RECORD_UPLOAD: false

View File

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

View File

@@ -22,17 +22,17 @@ jobs:
if: github.event.action != 'labeled' || github.event.sender.type != 'Bot'
steps:
- name: Checkout
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v2
uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2
with:
app-id: ${{ secrets.ESPHOME_GITHUB_APP_ID }}
private-key: ${{ secrets.ESPHOME_GITHUB_APP_PRIVATE_KEY }}
- name: Auto Label PR
uses: actions/github-script@v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
@@ -63,7 +63,11 @@ jobs:
'needs-docs',
'needs-codeowners',
'too-big',
'labeller-recheck'
'labeller-recheck',
'bugfix',
'new-feature',
'breaking-change',
'code-quality'
];
const DOCS_PR_PATTERNS = [
@@ -101,7 +105,9 @@ jobs:
// Calculate data from PR files
const changedFiles = prFiles.map(file => file.filename);
const totalChanges = prFiles.reduce((sum, file) => sum + (file.additions || 0) + (file.deletions || 0), 0);
const totalAdditions = prFiles.reduce((sum, file) => sum + (file.additions || 0), 0);
const totalDeletions = prFiles.reduce((sum, file) => sum + (file.deletions || 0), 0);
const totalChanges = totalAdditions + totalDeletions;
console.log('Current labels:', currentLabels.join(', '));
console.log('Changed files:', changedFiles.length);
@@ -227,16 +233,21 @@ jobs:
// Strategy: PR size detection
async function detectPRSize() {
const labels = new Set();
const testChanges = prFiles
.filter(file => file.filename.startsWith('tests/'))
.reduce((sum, file) => sum + (file.additions || 0) + (file.deletions || 0), 0);
const nonTestChanges = totalChanges - testChanges;
if (totalChanges <= SMALL_PR_THRESHOLD) {
labels.add('small-pr');
return labels;
}
const testAdditions = prFiles
.filter(file => file.filename.startsWith('tests/'))
.reduce((sum, file) => sum + (file.additions || 0), 0);
const testDeletions = prFiles
.filter(file => file.filename.startsWith('tests/'))
.reduce((sum, file) => sum + (file.deletions || 0), 0);
const nonTestChanges = (totalAdditions - testAdditions) - (totalDeletions - testDeletions);
// Don't add too-big if mega-pr label is already present
if (nonTestChanges > TOO_BIG_THRESHOLD && !isMegaPR) {
labels.add('too-big');
@@ -341,17 +352,42 @@ jobs:
return labels;
}
// Strategy: PR Template Checkbox detection
async function detectPRTemplateCheckboxes() {
const labels = new Set();
const prBody = context.payload.pull_request.body || '';
console.log('Checking PR template checkboxes...');
// Check for checked checkboxes in the "Types of changes" section
const checkboxPatterns = [
{ 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\] Code quality improvements to existing code or addition of tests/i, label: 'code-quality' }
];
for (const { pattern, label } of checkboxPatterns) {
if (pattern.test(prBody)) {
console.log(`Found checked checkbox for: ${label}`);
labels.add(label);
}
}
return labels;
}
// Strategy: Requirements detection
async function detectRequirements(allLabels) {
const labels = new Set();
// Check for missing tests
if ((allLabels.has('new-component') || allLabels.has('new-platform')) && !allLabels.has('has-tests')) {
if ((allLabels.has('new-component') || allLabels.has('new-platform') || allLabels.has('new-feature')) && !allLabels.has('has-tests')) {
labels.add('needs-tests');
}
// Check for missing docs
if (allLabels.has('new-component') || allLabels.has('new-platform')) {
if (allLabels.has('new-component') || allLabels.has('new-platform') || allLabels.has('new-feature')) {
const prBody = context.payload.pull_request.body || '';
const hasDocsLink = DOCS_PR_PATTERNS.some(pattern => pattern.test(prBody));
@@ -383,10 +419,13 @@ jobs:
// Too big message
if (finalLabels.includes('too-big')) {
const testChanges = prFiles
const testAdditions = prFiles
.filter(file => file.filename.startsWith('tests/'))
.reduce((sum, file) => sum + (file.additions || 0) + (file.deletions || 0), 0);
const nonTestChanges = totalChanges - testChanges;
.reduce((sum, file) => sum + (file.additions || 0), 0);
const testDeletions = prFiles
.filter(file => file.filename.startsWith('tests/'))
.reduce((sum, file) => sum + (file.deletions || 0), 0);
const nonTestChanges = (totalAdditions - testAdditions) - (totalDeletions - testDeletions);
const tooManyLabels = finalLabels.length > MAX_LABELS;
const tooManyChanges = nonTestChanges > TOO_BIG_THRESHOLD;
@@ -535,7 +574,8 @@ jobs:
dashboardLabels,
actionsLabels,
codeOwnerLabels,
testLabels
testLabels,
checkboxLabels
] = await Promise.all([
detectMergeBranch(),
detectComponentPlatforms(apiData),
@@ -546,7 +586,8 @@ jobs:
detectDashboardChanges(),
detectGitHubActionsChanges(),
detectCodeOwner(),
detectTests()
detectTests(),
detectPRTemplateCheckboxes()
]);
// Combine all labels
@@ -560,7 +601,8 @@ jobs:
...dashboardLabels,
...actionsLabels,
...codeOwnerLabels,
...testLabels
...testLabels,
...checkboxLabels
]);
// Detect requirements based on all other labels

View File

@@ -21,9 +21,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: "3.11"
@@ -47,7 +47,7 @@ jobs:
fi
- if: failure()
name: Review PR
uses: actions/github-script@v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
await github.rest.pulls.createReview({
@@ -62,7 +62,7 @@ jobs:
run: git diff
- if: failure()
name: Archive artifacts
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: generated-proto-files
path: |
@@ -70,7 +70,7 @@ jobs:
esphome/components/api/api_pb2_service.*
- if: success()
name: Dismiss review
uses: actions/github-script@v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
let reviews = await github.rest.pulls.listReviews({

View File

@@ -20,10 +20,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: "3.11"
@@ -41,7 +41,7 @@ jobs:
- if: failure()
name: Request changes
uses: actions/github-script@v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
await github.rest.pulls.createReview({
@@ -54,7 +54,7 @@ jobs:
- if: success()
name: Dismiss review
uses: actions/github-script@v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
let reviews = await github.rest.pulls.listReviews({

View File

@@ -43,13 +43,13 @@ jobs:
- "docker"
# - "lint"
steps:
- uses: actions/checkout@v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: "3.11"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.11.1
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Set TAG
run: |

View File

@@ -36,18 +36,18 @@ jobs:
cache-key: ${{ steps.cache-key.outputs.key }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- 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@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache@v4.2.3
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
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@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- 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@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Restore Python
uses: ./.github/actions/restore-python
with:
@@ -105,6 +105,7 @@ jobs:
script/ci-custom.py
script/build_codeowners.py --check
script/build_language_schema.py --check
script/generate-esp32-boards.py --check
pytest:
name: Run pytest
@@ -136,7 +137,7 @@ jobs:
- common
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Restore Python
id: restore-python
uses: ./.github/actions/restore-python
@@ -156,12 +157,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@v5.4.3
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
with:
token: ${{ secrets.CODECOV_TOKEN }}
- name: Save Python virtual environment cache
if: github.ref == 'refs/heads/dev'
uses: actions/cache/save@v4.2.3
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
key: ${{ runner.os }}-${{ steps.restore-python.outputs.python-version }}-venv-${{ needs.common.outputs.cache-key }}
@@ -179,7 +180,7 @@ jobs:
component-test-count: ${{ steps.determine.outputs.component-test-count }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
# Fetch enough history to find the merge base
fetch-depth: 2
@@ -214,15 +215,15 @@ jobs:
if: needs.determine-jobs.outputs.integration-tests == 'true'
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python 3.13
id: python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: "3.13"
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache@v4.2.3
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv-${{ needs.common.outputs.cache-key }}
@@ -281,13 +282,13 @@ jobs:
pio_cache_key: tidyesp32-idf
- id: clang-tidy
name: Run script/clang-tidy for ZEPHYR
options: --environment nrf52-tidy --grep USE_ZEPHYR
options: --environment nrf52-tidy --grep USE_ZEPHYR --grep USE_NRF52
pio_cache_key: tidy-zephyr
ignore_errors: false
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
# Need history for HEAD~1 to work for checking changed files
fetch-depth: 2
@@ -300,14 +301,14 @@ jobs:
- name: Cache platformio
if: github.ref == 'refs/heads/dev'
uses: actions/cache@v4.2.3
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
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@v4.2.3
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ~/.platformio
key: platformio-${{ matrix.pio_cache_key }}-${{ hashFiles('platformio.ini') }}
@@ -374,7 +375,7 @@ jobs:
sudo apt-get install libsdl2-dev
- name: Check out code from GitHub
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Restore Python
uses: ./.github/actions/restore-python
with:
@@ -400,7 +401,7 @@ jobs:
matrix: ${{ steps.split.outputs.components }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Split components into 20 groups
id: split
run: |
@@ -430,7 +431,7 @@ jobs:
sudo apt-get install libsdl2-dev
- name: Check out code from GitHub
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Restore Python
uses: ./.github/actions/restore-python
with:
@@ -459,16 +460,16 @@ jobs:
if: github.event_name == 'pull_request' && github.base_ref != 'beta' && github.base_ref != 'release'
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Restore Python
uses: ./.github/actions/restore-python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
cache-key: ${{ needs.common.outputs.cache-key }}
- uses: pre-commit/action@v3.0.1
- uses: esphome/action@43cd1109c09c544d97196f7730ee5b2e0cc6d81e # v3.0.1 fork with pinned actions/cache
env:
SKIP: pylint,clang-tidy-hash
- uses: pre-commit-ci/lite-action@v1.1.0
- uses: pre-commit-ci/lite-action@5d6cc0eb514c891a40562a58a8e71576c5c7fb43 # v1.1.0
if: always()
ci-status:

View File

@@ -25,7 +25,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Request reviews from component codeowners
uses: actions/github-script@v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const owner = context.repo.owner;

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@v4
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
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@v3
uses: github/codeql-action/analyze@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
with:
category: "/language:${{matrix.language}}"

View File

@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Add external component comment
uses: actions/github-script@v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |

View File

@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Notify codeowners for component issues
uses: actions/github-script@v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const owner = context.repo.owner;

View File

@@ -1,24 +0,0 @@
name: Needs Docs
on:
pull_request:
types: [labeled, unlabeled]
jobs:
check:
name: Check
runs-on: ubuntu-latest
steps:
- name: Check for needs-docs label
uses: actions/github-script@v7.0.1
with:
script: |
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number
});
const needsDocs = labels.find(label => label.name === 'needs-docs');
if (needsDocs) {
core.setFailed('Pull request needs docs');
}

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@v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Get tag
id: tag
# yamllint disable rule:line-length
@@ -60,9 +60,9 @@ jobs:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: "3.x"
- name: Build
@@ -70,7 +70,7 @@ jobs:
pip3 install build
python3 -m build
- name: Publish
uses: pypa/gh-action-pypi-publish@v1.12.4
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
with:
skip-existing: true
@@ -92,22 +92,22 @@ jobs:
os: "ubuntu-24.04-arm"
steps:
- uses: actions/checkout@v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: "3.11"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.11.1
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Log in to docker hub
uses: docker/login-action@v3.4.0
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to the GitHub container registry
uses: docker/login-action@v3.4.0
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -138,7 +138,7 @@ jobs:
# version: ${{ needs.init.outputs.tag }}
- name: Upload digests
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: digests-${{ matrix.platform.arch }}
path: /tmp/digests
@@ -168,27 +168,27 @@ jobs:
- ghcr
- dockerhub
steps:
- uses: actions/checkout@v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Download digests
uses: actions/download-artifact@v4.3.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
pattern: digests-*
path: /tmp/digests
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.11.1
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Log in to docker hub
if: matrix.registry == 'dockerhub'
uses: docker/login-action@v3.4.0
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to the GitHub container registry
if: matrix.registry == 'ghcr'
uses: docker/login-action@v3.4.0
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -220,7 +220,7 @@ jobs:
- deploy-manifest
steps:
- name: Trigger Workflow
uses: actions/github-script@v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
github-token: ${{ secrets.DEPLOY_HA_ADDON_REPO_TOKEN }}
script: |
@@ -246,7 +246,7 @@ jobs:
environment: ${{ needs.init.outputs.deploy_env }}
steps:
- name: Trigger Workflow
uses: actions/github-script@v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
github-token: ${{ secrets.DEPLOY_ESPHOME_SCHEMA_REPO_TOKEN }}
script: |

View File

@@ -15,36 +15,52 @@ concurrency:
jobs:
stale:
if: github.repository_owner == 'esphome'
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9.1.0
- name: Stale
uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10.0.0
with:
debug-only: ${{ github.ref != 'refs/heads/dev' }} # Dry-run when not run on dev branch
remove-stale-when-updated: true
operations-per-run: 150
# The 90 day stale policy for PRs
# - PRs
# - No PRs marked as "not-stale"
# - No Issues (see below)
days-before-pr-stale: 90
days-before-pr-close: 7
days-before-issue-stale: -1
days-before-issue-close: -1
remove-stale-when-updated: true
stale-pr-label: "stale"
exempt-pr-labels: "not-stale"
stale-pr-message: >
There hasn't been any activity on this pull request recently. This
pull request has been automatically marked as stale because of that
and will be closed if no further activity occurs within 7 days.
Thank you for your contributions.
# Use stale to automatically close issues with a
# reference to the issue tracker
close-issues:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9.1.0
with:
days-before-pr-stale: -1
days-before-pr-close: -1
days-before-issue-stale: 1
days-before-issue-close: 1
remove-stale-when-updated: true
If you are the author of this PR, please leave a comment if you want
to keep it open. Also, please rebase your PR onto the latest dev
branch to ensure that it's up to date with the latest changes.
Thank you for your contribution!
# The 90 day stale policy for Issues
# - Issues
# - No Issues marked as "not-stale"
# - No PRs (see above)
days-before-issue-stale: 90
days-before-issue-close: 7
stale-issue-label: "stale"
exempt-issue-labels: "not-stale"
stale-issue-message: >
https://github.com/esphome/esphome/issues/430
There hasn't been any activity on this issue recently. Due to the
high number of incoming GitHub notifications, we have to clean some
of the old issues, as many of them have already been resolved with
the latest updates.
Please make sure to update to the latest ESPHome version and
check if that solves the issue. Let us know if that works for you by
adding a comment 👍
This issue has now been marked as stale and will be closed if no
further activity occurs. Thank you for your contributions.

View File

@@ -0,0 +1,30 @@
name: Status check labels
on:
pull_request:
types: [labeled, unlabeled]
jobs:
check:
name: Check ${{ matrix.label }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
label:
- needs-docs
- merge-after-release
steps:
- name: Check for ${{ matrix.label }} label
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number
});
const hasLabel = labels.find(label => label.name === '${{ matrix.label }}');
if (hasLabel) {
core.setFailed('Pull request cannot be merged, it is labeled as ${{ matrix.label }}');
}

View File

@@ -13,16 +13,16 @@ jobs:
if: github.repository == 'esphome/esphome'
steps:
- name: Checkout
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Checkout Home Assistant
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
repository: home-assistant/core
path: lib/home-assistant
- name: Setup Python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: 3.13
@@ -30,13 +30,18 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install -e lib/home-assistant
pip install -r requirements_test.txt pre-commit
- name: Sync
run: |
python ./script/sync-device_class.py
- name: Run pre-commit hooks
run: |
python script/run-in-env.py pre-commit run --all-files
- name: Commit changes
uses: peter-evans/create-pull-request@v7.0.8
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
commit-message: "Synchronise Device Classes from Home Assistant"
committer: esphomebot <esphome@openhomefoundation.org>

View File

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

View File

@@ -40,11 +40,11 @@ esphome/components/analog_threshold/* @ianchi
esphome/components/animation/* @syndlex
esphome/components/anova/* @buxtronix
esphome/components/apds9306/* @aodrenah
esphome/components/api/* @OttoWinter
esphome/components/api/* @esphome/core
esphome/components/as5600/* @ammmze
esphome/components/as5600/sensor/* @ammmze
esphome/components/as7341/* @mrgnr
esphome/components/async_tcp/* @OttoWinter
esphome/components/async_tcp/* @esphome/core
esphome/components/at581x/* @X-Ryl669
esphome/components/atc_mithermometer/* @ahpohl
esphome/components/atm90e26/* @danieltwagner
@@ -66,10 +66,10 @@ esphome/components/binary_sensor/* @esphome/core
esphome/components/bk72xx/* @kuba2k2
esphome/components/bl0906/* @athom-tech @jesserockz @tarontop
esphome/components/bl0939/* @ziceva
esphome/components/bl0940/* @tobias-
esphome/components/bl0940/* @dan-s-github @tobias-
esphome/components/bl0942/* @dbuezas @dwmw2
esphome/components/ble_client/* @buxtronix @clydebarrow
esphome/components/bluetooth_proxy/* @jesserockz
esphome/components/bluetooth_proxy/* @bdraco @jesserockz
esphome/components/bme280_base/* @esphome/core
esphome/components/bme280_spi/* @apbodrov
esphome/components/bme680_bsec/* @trvrnrth
@@ -88,10 +88,11 @@ esphome/components/bp1658cj/* @Cossid
esphome/components/bp5758d/* @Cossid
esphome/components/button/* @esphome/core
esphome/components/bytebuffer/* @clydebarrow
esphome/components/camera/* @DT-art1 @bdraco
esphome/components/camera/* @bdraco @DT-art1
esphome/components/camera_encoder/* @DT-art1
esphome/components/canbus/* @danielschramm @mvturnho
esphome/components/cap1188/* @mreditor97
esphome/components/captive_portal/* @OttoWinter
esphome/components/captive_portal/* @esphome/core
esphome/components/ccs811/* @habbie
esphome/components/cd74hc4067/* @asoehlke
esphome/components/ch422g/* @clydebarrow @jesterret
@@ -118,7 +119,7 @@ esphome/components/dallas_temp/* @ssieb
esphome/components/daly_bms/* @s1lvi0
esphome/components/dashboard_import/* @esphome/core
esphome/components/datetime/* @jesserockz @rfdarter
esphome/components/debug/* @OttoWinter
esphome/components/debug/* @esphome/core
esphome/components/delonghi/* @grob6000
esphome/components/dfplayer/* @glmnet
esphome/components/dfrobot_sen0395/* @niklasweber
@@ -144,9 +145,10 @@ esphome/components/es8156/* @kbx81
esphome/components/es8311/* @kahrendt @kroimon
esphome/components/es8388/* @P4uLT
esphome/components/esp32/* @esphome/core
esphome/components/esp32_ble/* @Rapsssito @jesserockz
esphome/components/esp32_ble_client/* @jesserockz
esphome/components/esp32_ble_server/* @Rapsssito @clydebarrow @jesserockz
esphome/components/esp32_ble/* @bdraco @jesserockz @Rapsssito
esphome/components/esp32_ble_client/* @bdraco @jesserockz
esphome/components/esp32_ble_server/* @clydebarrow @jesserockz @Rapsssito
esphome/components/esp32_ble_tracker/* @bdraco
esphome/components/esp32_camera_web_server/* @ayufan
esphome/components/esp32_can/* @Sympatron
esphome/components/esp32_hosted/* @swoboda1337
@@ -155,16 +157,16 @@ esphome/components/esp32_rmt/* @jesserockz
esphome/components/esp32_rmt_led_strip/* @jesserockz
esphome/components/esp8266/* @esphome/core
esphome/components/esp_ldo/* @clydebarrow
esphome/components/espnow/* @jesserockz
esphome/components/ethernet_info/* @gtjadsonsantos
esphome/components/event/* @nohat
esphome/components/event_emitter/* @Rapsssito
esphome/components/exposure_notifications/* @OttoWinter
esphome/components/ezo/* @ssieb
esphome/components/ezo_pmp/* @carlos-sarmiento
esphome/components/factory_reset/* @anatoly-savchenkov
esphome/components/fastled_base/* @OttoWinter
esphome/components/feedback/* @ianchi
esphome/components/fingerprint_grow/* @OnFreund @alexborro @loongyh
esphome/components/fingerprint_grow/* @alexborro @loongyh @OnFreund
esphome/components/font/* @clydebarrow @esphome/core
esphome/components/fs3000/* @kahrendt
esphome/components/ft5x06/* @clydebarrow
@@ -200,7 +202,7 @@ esphome/components/heatpumpir/* @rob-deutsch
esphome/components/hitachi_ac424/* @sourabhjaiswal
esphome/components/hm3301/* @freekode
esphome/components/hmac_md5/* @dwmw2
esphome/components/homeassistant/* @OttoWinter @esphome/core
esphome/components/homeassistant/* @esphome/core @OttoWinter
esphome/components/homeassistant/number/* @landonr
esphome/components/homeassistant/switch/* @Links2004
esphome/components/honeywell_hih_i2c/* @Benichou34
@@ -225,18 +227,18 @@ esphome/components/iaqcore/* @yozik04
esphome/components/ili9xxx/* @clydebarrow @nielsnl68
esphome/components/improv_base/* @esphome/core
esphome/components/improv_serial/* @esphome/core
esphome/components/ina226/* @Sergio303 @latonita
esphome/components/ina226/* @latonita @Sergio303
esphome/components/ina260/* @mreditor97
esphome/components/ina2xx_base/* @latonita
esphome/components/ina2xx_i2c/* @latonita
esphome/components/ina2xx_spi/* @latonita
esphome/components/inkbird_ibsth1_mini/* @fkirill
esphome/components/inkplate6/* @jesserockz
esphome/components/inkplate/* @jesserockz @JosipKuci
esphome/components/integration/* @OttoWinter
esphome/components/internal_temperature/* @Mat931
esphome/components/interval/* @esphome/core
esphome/components/jsn_sr04t/* @Mafus1
esphome/components/json/* @OttoWinter
esphome/components/json/* @esphome/core
esphome/components/kamstrup_kmp/* @cfeenstra1024
esphome/components/key_collector/* @ssieb
esphome/components/key_provider/* @ssieb
@@ -244,6 +246,7 @@ esphome/components/kuntze/* @ssieb
esphome/components/lc709203f/* @ilikecake
esphome/components/lcd_menu/* @numo68
esphome/components/ld2410/* @regevbr @sebcaps
esphome/components/ld2412/* @Rihan9
esphome/components/ld2420/* @descipher
esphome/components/ld2450/* @hareeshmu
esphome/components/ld24xx/* @kbx81
@@ -273,8 +276,8 @@ esphome/components/max7219digit/* @rspaargaren
esphome/components/max9611/* @mckaymatthew
esphome/components/mcp23008/* @jesserockz
esphome/components/mcp23017/* @jesserockz
esphome/components/mcp23s08/* @SenexCrenshaw @jesserockz
esphome/components/mcp23s17/* @SenexCrenshaw @jesserockz
esphome/components/mcp23s08/* @jesserockz @SenexCrenshaw
esphome/components/mcp23s17/* @jesserockz @SenexCrenshaw
esphome/components/mcp23x08_base/* @jesserockz
esphome/components/mcp23x17_base/* @jesserockz
esphome/components/mcp23xxx_base/* @jesserockz
@@ -295,6 +298,7 @@ esphome/components/mics_4514/* @jesserockz
esphome/components/midea/* @dudanov
esphome/components/midea_ir/* @dudanov
esphome/components/mipi_dsi/* @clydebarrow
esphome/components/mipi_rgb/* @clydebarrow
esphome/components/mipi_spi/* @clydebarrow
esphome/components/mitsubishi/* @RubyBailey
esphome/components/mixer/speaker/* @kahrendt
@@ -338,7 +342,7 @@ esphome/components/ota/* @esphome/core
esphome/components/output/* @esphome/core
esphome/components/packet_transport/* @clydebarrow
esphome/components/pca6416a/* @Mat931
esphome/components/pca9554/* @clydebarrow @hwstar
esphome/components/pca9554/* @bdraco @clydebarrow @hwstar
esphome/components/pcf85063/* @brogon
esphome/components/pcf8563/* @KoenBreeman
esphome/components/pi4ioe5v6408/* @jesserockz
@@ -349,9 +353,9 @@ esphome/components/pm2005/* @andrewjswan
esphome/components/pmsa003i/* @sjtrny
esphome/components/pmsx003/* @ximex
esphome/components/pmwcs3/* @SeByDocKy
esphome/components/pn532/* @OttoWinter @jesserockz
esphome/components/pn532_i2c/* @OttoWinter @jesserockz
esphome/components/pn532_spi/* @OttoWinter @jesserockz
esphome/components/pn532/* @jesserockz @OttoWinter
esphome/components/pn532_i2c/* @jesserockz @OttoWinter
esphome/components/pn532_spi/* @jesserockz @OttoWinter
esphome/components/pn7150/* @jesserockz @kbx81
esphome/components/pn7150_i2c/* @jesserockz @kbx81
esphome/components/pn7160/* @jesserockz @kbx81
@@ -360,7 +364,7 @@ esphome/components/pn7160_spi/* @jesserockz @kbx81
esphome/components/power_supply/* @esphome/core
esphome/components/preferences/* @esphome/core
esphome/components/psram/* @esphome/core
esphome/components/pulse_meter/* @TrentHouliston @cstaahl @stevebaxter
esphome/components/pulse_meter/* @cstaahl @stevebaxter @TrentHouliston
esphome/components/pvvx_mithermometer/* @pasiz
esphome/components/pylontech/* @functionpointer
esphome/components/qmp6988/* @andrewpc
@@ -401,7 +405,8 @@ esphome/components/sensirion_common/* @martgras
esphome/components/sensor/* @esphome/core
esphome/components/sfa30/* @ghsensdev
esphome/components/sgp40/* @SenexCrenshaw
esphome/components/sgp4x/* @SenexCrenshaw @martgras
esphome/components/sgp4x/* @martgras @SenexCrenshaw
esphome/components/sha256/* @esphome/core
esphome/components/shelly_dimmer/* @edge90 @rnauber
esphome/components/sht3xd/* @mrtoy-me
esphome/components/sht4x/* @sjtrny
@@ -466,13 +471,13 @@ esphome/components/template/event/* @nohat
esphome/components/template/fan/* @ssieb
esphome/components/text/* @mauritskorse
esphome/components/thermostat/* @kbx81
esphome/components/time/* @OttoWinter
esphome/components/time/* @esphome/core
esphome/components/tlc5947/* @rnauber
esphome/components/tlc5971/* @IJIJI
esphome/components/tm1621/* @Philippe12
esphome/components/tm1637/* @glmnet
esphome/components/tm1638/* @skykingjwc
esphome/components/tm1651/* @freekode
esphome/components/tm1651/* @mrtoy-me
esphome/components/tmp102/* @timsavage
esphome/components/tmp1075/* @sybrenstuvel
esphome/components/tmp117/* @Azimath
@@ -510,7 +515,7 @@ esphome/components/wake_on_lan/* @clydebarrow @willwill2will54
esphome/components/watchdog/* @oarcher
esphome/components/waveshare_epaper/* @clydebarrow
esphome/components/web_server/ota/* @esphome/core
esphome/components/web_server_base/* @OttoWinter
esphome/components/web_server_base/* @esphome/core
esphome/components/web_server_idf/* @dentra
esphome/components/weikai/* @DrCoolZic
esphome/components/weikai_i2c/* @DrCoolZic
@@ -528,6 +533,7 @@ esphome/components/wk2204_spi/* @DrCoolZic
esphome/components/wk2212_i2c/* @DrCoolZic
esphome/components/wk2212_spi/* @DrCoolZic
esphome/components/wl_134/* @hobbypunk90
esphome/components/wts01/* @alepee
esphome/components/x9c/* @EtienneMD
esphome/components/xgzp68xx/* @gcormier
esphome/components/xiaomi_hhccjcy10/* @fariouche
@@ -543,3 +549,4 @@ esphome/components/xxtea/* @clydebarrow
esphome/components/zephyr/* @tomaszduda23
esphome/components/zhlt01/* @cfeenstra1024
esphome/components/zio_ultrasonic/* @kahrendt
esphome/components/zwave_proxy/* @kbx81

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.8.0-dev
PROJECT_NUMBER = 2025.10.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

@@ -90,7 +90,7 @@ def main():
def run_command(*cmd, ignore_error: bool = False):
print(f"$ {shlex.join(list(cmd))}")
if not args.dry_run:
rc = subprocess.call(list(cmd))
rc = subprocess.call(list(cmd), close_fds=False)
if rc != 0 and not ignore_error:
print("Command failed")
sys.exit(1)

View File

@@ -6,17 +6,21 @@ import getpass
import importlib
import logging
import os
from pathlib import Path
import re
import sys
import time
from typing import Protocol
import argcomplete
from esphome import const, writer, yaml_util
import esphome.codegen as cg
from esphome.components.mqtt import CONF_DISCOVER_IP
from esphome.config import iter_component_configs, read_config, strip_default_ids
from esphome.const import (
ALLOWED_NAME_CHARS,
CONF_API,
CONF_BAUD_RATE,
CONF_BROKER,
CONF_DEASSERT_RTS_DTR,
@@ -42,8 +46,10 @@ from esphome.const import (
SECRETS_FILES,
)
from esphome.core import CORE, EsphomeError, coroutine
from esphome.enum import StrEnum
from esphome.helpers import get_bool_env, indent, is_ip_address
from esphome.log import AnsiFore, color, setup_log
from esphome.types import ConfigType
from esphome.util import (
get_serial_ports,
list_yaml_files,
@@ -55,6 +61,23 @@ from esphome.util import (
_LOGGER = logging.getLogger(__name__)
class ArgsProtocol(Protocol):
device: list[str] | None
reset: bool
username: str | None
password: str | None
client_id: str | None
topic: str | None
file: str | None
no_logs: bool
only_generate: bool
show_secrets: bool
dashboard: bool
configuration: str
name: str
upload_speed: str | None
def choose_prompt(options, purpose: str = None):
if not options:
raise EsphomeError(
@@ -87,51 +110,183 @@ def choose_prompt(options, purpose: str = None):
return options[opt - 1][1]
class Purpose(StrEnum):
UPLOADING = "uploading"
LOGGING = "logging"
def _resolve_with_cache(address: str, purpose: Purpose) -> list[str]:
"""Resolve an address using cache if available, otherwise return the address itself."""
if CORE.address_cache and (cached := CORE.address_cache.get_addresses(address)):
_LOGGER.debug("Using cached addresses for %s: %s", purpose.value, cached)
return cached
return [address]
def choose_upload_log_host(
default, check_default, show_ota, show_mqtt, show_api, purpose: str = None
):
default: list[str] | str | None,
check_default: str | None,
purpose: Purpose,
) -> list[str]:
# Convert to list for uniform handling
defaults = [default] if isinstance(default, str) else default or []
# If devices specified, resolve them
if defaults:
resolved: list[str] = []
for device in defaults:
if device == "SERIAL":
serial_ports = get_serial_ports()
if not serial_ports:
_LOGGER.warning("No serial ports found, skipping SERIAL device")
continue
options = [
(f"{port.path} ({port.description})", port.path)
for port in serial_ports
]
resolved.append(choose_prompt(options, purpose=purpose))
elif device == "OTA":
# ensure IP adresses are used first
if is_ip_address(CORE.address) and (
(purpose == Purpose.LOGGING and has_api())
or (purpose == Purpose.UPLOADING and has_ota())
):
resolved.extend(_resolve_with_cache(CORE.address, purpose))
if purpose == Purpose.LOGGING:
if has_api() and has_mqtt_ip_lookup():
resolved.append("MQTTIP")
if has_mqtt_logging():
resolved.append("MQTT")
if has_api() and has_non_ip_address():
resolved.extend(_resolve_with_cache(CORE.address, purpose))
elif purpose == Purpose.UPLOADING:
if has_ota() and has_mqtt_ip_lookup():
resolved.append("MQTTIP")
if has_ota() and has_non_ip_address():
resolved.extend(_resolve_with_cache(CORE.address, purpose))
else:
resolved.append(device)
if not resolved:
_LOGGER.error("All specified devices: %s could not be resolved.", defaults)
return resolved
# No devices specified, show interactive chooser
options = [
(f"{port.path} ({port.description})", port.path) for port in get_serial_ports()
]
if default == "SERIAL":
return choose_prompt(options, purpose=purpose)
if (show_ota and "ota" in CORE.config) or (show_api and "api" in CORE.config):
options.append((f"Over The Air ({CORE.address})", CORE.address))
if default == "OTA":
return CORE.address
if (
show_mqtt
and (mqtt_config := CORE.config.get(CONF_MQTT))
and mqtt_logging_enabled(mqtt_config)
):
options.append((f"MQTT ({mqtt_config[CONF_BROKER]})", "MQTT"))
if default == "OTA":
return "MQTT"
if default is not None:
return default
if purpose == Purpose.LOGGING:
if has_mqtt_logging():
mqtt_config = CORE.config[CONF_MQTT]
options.append((f"MQTT ({mqtt_config[CONF_BROKER]})", "MQTT"))
if has_api():
if has_resolvable_address():
options.append((f"Over The Air ({CORE.address})", CORE.address))
if has_mqtt_ip_lookup():
options.append(("Over The Air (MQTT IP lookup)", "MQTTIP"))
elif purpose == Purpose.UPLOADING and has_ota():
if has_resolvable_address():
options.append((f"Over The Air ({CORE.address})", CORE.address))
if has_mqtt_ip_lookup():
options.append(("Over The Air (MQTT IP lookup)", "MQTTIP"))
if check_default is not None and check_default in [opt[1] for opt in options]:
return check_default
return choose_prompt(options, purpose=purpose)
return [check_default]
return [choose_prompt(options, purpose=purpose)]
def mqtt_logging_enabled(mqtt_config):
def has_mqtt_logging() -> bool:
"""Check if MQTT logging is available."""
if CONF_MQTT not in CORE.config:
return False
mqtt_config = CORE.config[CONF_MQTT]
# enabled by default
if CONF_LOG_TOPIC not in mqtt_config:
return True
log_topic = mqtt_config[CONF_LOG_TOPIC]
if log_topic is None:
return False
if CONF_TOPIC not in log_topic:
return False
return log_topic.get(CONF_LEVEL, None) != "NONE"
def get_port_type(port):
def has_mqtt() -> bool:
"""Check if MQTT is available."""
return CONF_MQTT in CORE.config
def has_api() -> bool:
"""Check if API is available."""
return CONF_API in CORE.config
def has_ota() -> bool:
"""Check if OTA is available."""
return CONF_OTA in CORE.config
def has_mqtt_ip_lookup() -> bool:
"""Check if MQTT is available and IP lookup is supported."""
if CONF_MQTT not in CORE.config:
return False
# Default Enabled
if CONF_DISCOVER_IP not in CORE.config[CONF_MQTT]:
return True
return CORE.config[CONF_MQTT][CONF_DISCOVER_IP]
def has_mdns() -> bool:
"""Check if MDNS is available."""
return CONF_MDNS not in CORE.config or not CORE.config[CONF_MDNS][CONF_DISABLED]
def has_non_ip_address() -> bool:
"""Check if CORE.address is set and is not an IP address."""
return CORE.address is not None and not is_ip_address(CORE.address)
def has_ip_address() -> bool:
"""Check if CORE.address is a valid IP address."""
return CORE.address is not None and is_ip_address(CORE.address)
def has_resolvable_address() -> bool:
"""Check if CORE.address is resolvable (via mDNS or is an IP address)."""
return has_mdns() or has_ip_address()
def mqtt_get_ip(config: ConfigType, username: str, password: str, client_id: str):
from esphome import mqtt
return mqtt.get_esphome_device_ip(config, username, password, client_id)
_PORT_TO_PORT_TYPE = {
"MQTT": "MQTT",
"MQTTIP": "MQTTIP",
}
def get_port_type(port: str) -> str:
if port.startswith("/") or port.startswith("COM"):
return "SERIAL"
if port == "MQTT":
return "MQTT"
return "NETWORK"
return _PORT_TO_PORT_TYPE.get(port, "NETWORK")
def run_miniterm(config, port, args):
def run_miniterm(config: ConfigType, port: str, args) -> int:
from aioesphomeapi import LogParser
import serial
@@ -173,7 +328,9 @@ def run_miniterm(config, port, args):
.replace(b"\n", b"")
.decode("utf8", "backslashreplace")
)
time_str = datetime.now().time().strftime("[%H:%M:%S]")
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(
@@ -208,7 +365,7 @@ def wrap_to_code(name, comp):
return wrapped
def write_cpp(config):
def write_cpp(config: ConfigType) -> int:
if not get_bool_env(ENV_NOGITIGNORE):
writer.write_gitignore()
@@ -216,7 +373,7 @@ def write_cpp(config):
return write_cpp_file()
def generate_cpp_contents(config):
def generate_cpp_contents(config: ConfigType) -> None:
_LOGGER.info("Generating C++ source...")
for name, component, conf in iter_component_configs(CORE.config):
@@ -227,7 +384,7 @@ def generate_cpp_contents(config):
CORE.flush_tasks()
def write_cpp_file():
def write_cpp_file() -> int:
code_s = indent(CORE.cpp_main_section)
writer.write_cpp(code_s)
@@ -238,7 +395,7 @@ def write_cpp_file():
return 0
def compile_program(args, config):
def compile_program(args: ArgsProtocol, config: ConfigType) -> int:
from esphome import platformio_api
_LOGGER.info("Compiling app...")
@@ -249,7 +406,9 @@ def compile_program(args, config):
return 0 if idedata is not None else 1
def upload_using_esptool(config, port, file, speed):
def upload_using_esptool(
config: ConfigType, port: str, file: str, speed: int
) -> str | int:
from esphome import platformio_api
first_baudrate = speed or config[CONF_ESPHOME][CONF_PLATFORMIO_OPTIONS].get(
@@ -277,24 +436,24 @@ def upload_using_esptool(config, port, file, speed):
def run_esptool(baud_rate):
cmd = [
"esptool.py",
"esptool",
"--before",
"default_reset",
"default-reset",
"--after",
"hard_reset",
"hard-reset",
"--baud",
str(baud_rate),
"--port",
port,
"--chip",
mcu,
"write_flash",
"write-flash",
"-z",
"--flash_size",
"--flash-size",
"detect",
]
for img in flash_images:
cmd += [img.offset, img.path]
cmd += [img.offset, str(img.path)]
if os.environ.get("ESPHOME_USE_SUBPROCESS") is None:
import esptool
@@ -314,7 +473,7 @@ def upload_using_esptool(config, port, file, speed):
return run_esptool(115200)
def upload_using_platformio(config, port):
def upload_using_platformio(config: ConfigType, port: str):
from esphome import platformio_api
upload_args = ["-t", "upload", "-t", "nobuild"]
@@ -323,7 +482,7 @@ def upload_using_platformio(config, port):
return platformio_api.run_platformio_cli_run(config, CORE.verbose, *upload_args)
def check_permissions(port):
def check_permissions(port: str):
if os.name == "posix" and get_port_type(port) == "SERIAL":
# Check if we can open selected serial port
if not os.access(port, os.F_OK):
@@ -341,27 +500,29 @@ def check_permissions(port):
)
def upload_program(config, args, host):
def upload_program(
config: ConfigType, args: ArgsProtocol, devices: list[str]
) -> tuple[int, str | None]:
host = devices[0]
try:
module = importlib.import_module("esphome.components." + CORE.target_platform)
if getattr(module, "upload_program")(config, args, host):
return 0
return 0, host
except AttributeError:
pass
if get_port_type(host) == "SERIAL":
check_permissions(host)
exit_code = 1
if CORE.target_platform in (PLATFORM_ESP32, PLATFORM_ESP8266):
file = getattr(args, "file", None)
return upload_using_esptool(config, host, file, args.upload_speed)
exit_code = upload_using_esptool(config, host, file, args.upload_speed)
elif CORE.target_platform == PLATFORM_RP2040 or CORE.is_libretiny:
exit_code = upload_using_platformio(config, host)
# else: Unknown target platform, exit_code remains 1
if CORE.target_platform in (PLATFORM_RP2040):
return upload_using_platformio(config, args.device)
if CORE.is_libretiny:
return upload_using_platformio(config, host)
return 1 # Unknown target platform
return exit_code, host if exit_code == 0 else None
ota_conf = {}
for ota_item in config.get(CONF_OTA, []):
@@ -378,45 +539,56 @@ def upload_program(config, args, host):
remote_port = int(ota_conf[CONF_PORT])
password = ota_conf.get(CONF_PASSWORD, "")
if (
CONF_MQTT in config # pylint: disable=too-many-boolean-expressions
and (not args.device or args.device in ("MQTT", "OTA"))
and (
((config[CONF_MDNS][CONF_DISABLED]) and not is_ip_address(CORE.address))
or get_port_type(host) == "MQTT"
)
):
from esphome import mqtt
host = mqtt.get_esphome_device_ip(
config, args.username, args.password, args.client_id
)
if getattr(args, "file", None) is not None:
return espota2.run_ota(host, remote_port, password, args.file)
binary = Path(args.file)
else:
binary = CORE.firmware_bin
return espota2.run_ota(host, remote_port, password, CORE.firmware_bin)
# MQTT address resolution
if get_port_type(host) in ("MQTT", "MQTTIP"):
devices = mqtt_get_ip(config, args.username, args.password, args.client_id)
return espota2.run_ota(devices, remote_port, password, binary)
def show_logs(config, args, port):
def show_logs(config: ConfigType, args: ArgsProtocol, devices: list[str]) -> int | None:
try:
module = importlib.import_module("esphome.components." + CORE.target_platform)
if getattr(module, "show_logs")(config, args, devices):
return 0
except AttributeError:
pass
if "logger" not in config:
raise EsphomeError("Logger is not configured!")
port = devices[0]
if get_port_type(port) == "SERIAL":
check_permissions(port)
return run_miniterm(config, port, args)
if get_port_type(port) == "NETWORK" and "api" in config:
if config[CONF_MDNS][CONF_DISABLED] and CONF_MQTT in config:
from esphome import mqtt
port = mqtt.get_esphome_device_ip(
port_type = get_port_type(port)
# Check if we should use API for logging
if has_api():
addresses_to_use: list[str] | None = None
if port_type == "NETWORK" and (has_mdns() or is_ip_address(port)):
addresses_to_use = devices
elif port_type in ("NETWORK", "MQTT", "MQTTIP") and has_mqtt_ip_lookup():
# Only use MQTT IP lookup if the first condition didn't match
# (for MQTT/MQTTIP types, or for NETWORK when mdns/ip check fails)
addresses_to_use = mqtt_get_ip(
config, args.username, args.password, args.client_id
)[0]
)
from esphome.components.api.client import run_logs
if addresses_to_use is not None:
from esphome.components.api.client import run_logs
return run_logs(config, port)
if get_port_type(port) == "MQTT" and "mqtt" in config:
return run_logs(config, addresses_to_use)
if port_type in ("NETWORK", "MQTT") and has_mqtt_logging():
from esphome import mqtt
return mqtt.show_logs(
@@ -426,7 +598,7 @@ def show_logs(config, args, port):
raise EsphomeError("No remote or local logging method configured (api/mqtt/logger)")
def clean_mqtt(config, args):
def clean_mqtt(config: ConfigType, args: ArgsProtocol) -> int | None:
from esphome import mqtt
return mqtt.clear_topic(
@@ -434,13 +606,13 @@ def clean_mqtt(config, args):
)
def command_wizard(args):
def command_wizard(args: ArgsProtocol) -> int | None:
from esphome import wizard
return wizard.wizard(args.configuration)
return wizard.wizard(Path(args.configuration))
def command_config(args, config):
def command_config(args: ArgsProtocol, config: ConfigType) -> int | None:
if not CORE.verbose:
config = strip_default_ids(config)
output = yaml_util.dump(config, args.show_secrets)
@@ -455,7 +627,7 @@ def command_config(args, config):
return 0
def command_vscode(args):
def command_vscode(args: ArgsProtocol) -> int | None:
from esphome import vscode
logging.disable(logging.INFO)
@@ -463,7 +635,7 @@ def command_vscode(args):
vscode.read_config(args)
def command_compile(args, config):
def command_compile(args: ArgsProtocol, config: ConfigType) -> int | None:
# Set memory analysis options in config
if args.analyze_memory:
config.setdefault(CONF_ESPHOME, {})["analyze_memory"] = True
@@ -484,23 +656,23 @@ def command_compile(args, config):
return 0
def command_upload(args, config):
port = choose_upload_log_host(
def command_upload(args: ArgsProtocol, config: ConfigType) -> int | None:
# Get devices, resolving special identifiers like OTA
devices = choose_upload_log_host(
default=args.device,
check_default=None,
show_ota=True,
show_mqtt=False,
show_api=False,
purpose="uploading",
purpose=Purpose.UPLOADING,
)
exit_code = upload_program(config, args, port)
if exit_code != 0:
return exit_code
_LOGGER.info("Successfully uploaded program.")
return 0
exit_code, _ = upload_program(config, args, devices)
if exit_code == 0:
_LOGGER.info("Successfully uploaded program.")
else:
_LOGGER.warning("Failed to upload to %s", devices)
return exit_code
def command_discover(args, config):
def command_discover(args: ArgsProtocol, config: ConfigType) -> int | None:
if "mqtt" in config:
from esphome import mqtt
@@ -509,19 +681,17 @@ def command_discover(args, config):
raise EsphomeError("No discover method configured (mqtt)")
def command_logs(args, config):
port = choose_upload_log_host(
def command_logs(args: ArgsProtocol, config: ConfigType) -> int | None:
# Get devices, resolving special identifiers like OTA
devices = choose_upload_log_host(
default=args.device,
check_default=None,
show_ota=False,
show_mqtt=True,
show_api=True,
purpose="logging",
purpose=Purpose.LOGGING,
)
return show_logs(config, args, port)
return show_logs(config, args, devices)
def command_run(args, config):
def command_run(args: ArgsProtocol, config: ConfigType) -> int | None:
exit_code = write_cpp(config)
if exit_code != 0:
return exit_code
@@ -538,47 +708,58 @@ def command_run(args, config):
program_path = idedata.raw["prog_path"]
return run_external_process(program_path)
port = choose_upload_log_host(
# Get devices, resolving special identifiers like OTA
devices = choose_upload_log_host(
default=args.device,
check_default=None,
show_ota=True,
show_mqtt=False,
show_api=True,
purpose="uploading",
purpose=Purpose.UPLOADING,
)
exit_code = upload_program(config, args, port)
if exit_code != 0:
exit_code, successful_device = upload_program(config, args, devices)
if exit_code == 0:
_LOGGER.info("Successfully uploaded program.")
else:
_LOGGER.warning("Failed to upload to %s", devices)
return exit_code
_LOGGER.info("Successfully uploaded program.")
if args.no_logs:
return 0
port = choose_upload_log_host(
default=args.device,
check_default=port,
show_ota=False,
show_mqtt=True,
show_api=True,
purpose="logging",
# For logs, prefer the device we successfully uploaded to
devices = choose_upload_log_host(
default=successful_device,
check_default=successful_device,
purpose=Purpose.LOGGING,
)
return show_logs(config, args, port)
return show_logs(config, args, devices)
def command_clean_mqtt(args, config):
def command_clean_mqtt(args: ArgsProtocol, config: ConfigType) -> int | None:
return clean_mqtt(config, args)
def command_mqtt_fingerprint(args, config):
def command_clean_all(args: ArgsProtocol) -> int | None:
try:
writer.clean_all(args.configuration)
except OSError as err:
_LOGGER.error("Error cleaning all files: %s", err)
return 1
_LOGGER.info("Done!")
return 0
def command_mqtt_fingerprint(args: ArgsProtocol, config: ConfigType) -> int | None:
from esphome import mqtt
return mqtt.get_fingerprint(config)
def command_version(args):
def command_version(args: ArgsProtocol) -> int | None:
safe_print(f"Version: {const.__version__}")
return 0
def command_clean(args, config):
def command_clean(args: ArgsProtocol, config: ConfigType) -> int | None:
try:
writer.clean_build()
except OSError as err:
@@ -588,13 +769,13 @@ def command_clean(args, config):
return 0
def command_dashboard(args):
def command_dashboard(args: ArgsProtocol) -> int | None:
from esphome.dashboard import dashboard
return dashboard.start_dashboard(args)
def command_update_all(args):
def command_update_all(args: ArgsProtocol) -> int | None:
import click
success = {}
@@ -608,7 +789,7 @@ def command_update_all(args):
safe_print(f"{half_line}{middle_text}{half_line}")
for f in files:
safe_print(f"Updating {color(AnsiFore.CYAN, f)}")
safe_print(f"Updating {color(AnsiFore.CYAN, str(f))}")
safe_print("-" * twidth)
safe_print()
if CORE.dashboard:
@@ -620,10 +801,10 @@ def command_update_all(args):
"esphome", "run", f, "--no-logs", "--device", "OTA"
)
if rc == 0:
print_bar(f"[{color(AnsiFore.BOLD_GREEN, 'SUCCESS')}] {f}")
print_bar(f"[{color(AnsiFore.BOLD_GREEN, 'SUCCESS')}] {str(f)}")
success[f] = True
else:
print_bar(f"[{color(AnsiFore.BOLD_RED, 'ERROR')}] {f}")
print_bar(f"[{color(AnsiFore.BOLD_RED, 'ERROR')}] {str(f)}")
success[f] = False
safe_print()
@@ -634,14 +815,14 @@ def command_update_all(args):
failed = 0
for f in files:
if success[f]:
safe_print(f" - {f}: {color(AnsiFore.GREEN, 'SUCCESS')}")
safe_print(f" - {str(f)}: {color(AnsiFore.GREEN, 'SUCCESS')}")
else:
safe_print(f" - {f}: {color(AnsiFore.BOLD_RED, 'FAILED')}")
safe_print(f" - {str(f)}: {color(AnsiFore.BOLD_RED, 'FAILED')}")
failed += 1
return failed
def command_idedata(args, config):
def command_idedata(args: ArgsProtocol, config: ConfigType) -> int:
import json
from esphome import platformio_api
@@ -657,8 +838,9 @@ def command_idedata(args, config):
return 0
def command_rename(args, config):
for c in args.name:
def command_rename(args: ArgsProtocol, config: ConfigType) -> int | None:
new_name = args.name
for c in new_name:
if c not in ALLOWED_NAME_CHARS:
print(
color(
@@ -669,8 +851,7 @@ def command_rename(args, config):
)
return 1
# Load existing yaml file
with open(CORE.config_path, mode="r+", encoding="utf-8") as raw_file:
raw_contents = raw_file.read()
raw_contents = CORE.config_path.read_text(encoding="utf-8")
yaml = yaml_util.load_yaml(CORE.config_path)
if CONF_ESPHOME not in yaml or CONF_NAME not in yaml[CONF_ESPHOME]:
@@ -685,7 +866,7 @@ def command_rename(args, config):
if match is None:
new_raw = re.sub(
rf"name:\s+[\"']?{old_name}[\"']?",
f'name: "{args.name}"',
f'name: "{new_name}"',
raw_contents,
)
else:
@@ -705,29 +886,28 @@ def command_rename(args, config):
new_raw = re.sub(
rf"^(\s+{match.group(1)}):\s+[\"']?{old_name}[\"']?",
f'\\1: "{args.name}"',
f'\\1: "{new_name}"',
raw_contents,
flags=re.MULTILINE,
)
new_path = os.path.join(CORE.config_dir, args.name + ".yaml")
new_path: Path = CORE.config_dir / (new_name + ".yaml")
print(
f"Updating {color(AnsiFore.CYAN, CORE.config_path)} to {color(AnsiFore.CYAN, new_path)}"
f"Updating {color(AnsiFore.CYAN, str(CORE.config_path))} to {color(AnsiFore.CYAN, str(new_path))}"
)
print()
with open(new_path, mode="w", encoding="utf-8") as new_file:
new_file.write(new_raw)
new_path.write_text(new_raw, encoding="utf-8")
rc = run_external_process("esphome", "config", new_path)
rc = run_external_process("esphome", "config", str(new_path))
if rc != 0:
print(color(AnsiFore.BOLD_RED, "Rename failed. Reverting changes."))
os.remove(new_path)
new_path.unlink()
return 1
cli_args = [
"run",
new_path,
str(new_path),
"--no-logs",
"--device",
CORE.address,
@@ -741,11 +921,11 @@ def command_rename(args, config):
except KeyboardInterrupt:
rc = 1
if rc != 0:
os.remove(new_path)
new_path.unlink()
return 1
if CORE.config_path != new_path:
os.remove(CORE.config_path)
CORE.config_path.unlink()
print(color(AnsiFore.BOLD_GREEN, "SUCCESS"))
print()
@@ -758,6 +938,7 @@ PRE_CONFIG_ACTIONS = {
"dashboard": command_dashboard,
"vscode": command_vscode,
"update-all": command_update_all,
"clean-all": command_clean_all,
}
POST_CONFIG_ACTIONS = {
@@ -766,14 +947,20 @@ POST_CONFIG_ACTIONS = {
"upload": command_upload,
"logs": command_logs,
"run": command_run,
"clean": command_clean,
"clean-mqtt": command_clean_mqtt,
"mqtt-fingerprint": command_mqtt_fingerprint,
"clean": command_clean,
"idedata": command_idedata,
"rename": command_rename,
"discover": command_discover,
}
SIMPLE_CONFIG_ACTIONS = [
"clean",
"clean-mqtt",
"config",
]
def parse_args(argv):
options_parser = argparse.ArgumentParser(add_help=False)
@@ -806,6 +993,18 @@ def parse_args(argv):
help="Add a substitution",
metavar=("key", "value"),
)
options_parser.add_argument(
"--mdns-address-cache",
help="mDNS address cache mapping in format 'hostname=ip1,ip2'",
action="append",
default=[],
)
options_parser.add_argument(
"--dns-address-cache",
help="DNS address cache mapping in format 'hostname=ip1,ip2'",
action="append",
default=[],
)
parser = argparse.ArgumentParser(
description=f"ESPHome {const.__version__}", parents=[options_parser]
@@ -872,7 +1071,8 @@ def parse_args(argv):
)
parser_upload.add_argument(
"--device",
help="Manually specify the serial port/address to use, for example /dev/ttyUSB0.",
action="append",
help="Manually specify the serial port/address to use, for example /dev/ttyUSB0. Can be specified multiple times for fallback addresses.",
)
parser_upload.add_argument(
"--upload_speed",
@@ -894,7 +1094,8 @@ def parse_args(argv):
)
parser_logs.add_argument(
"--device",
help="Manually specify the serial port/address to use, for example /dev/ttyUSB0.",
action="append",
help="Manually specify the serial port/address to use, for example /dev/ttyUSB0. Can be specified multiple times for fallback addresses.",
)
parser_logs.add_argument(
"--reset",
@@ -923,7 +1124,8 @@ def parse_args(argv):
)
parser_run.add_argument(
"--device",
help="Manually specify the serial port/address to use, for example /dev/ttyUSB0.",
action="append",
help="Manually specify the serial port/address to use, for example /dev/ttyUSB0. Can be specified multiple times for fallback addresses.",
)
parser_run.add_argument(
"--upload_speed",
@@ -971,6 +1173,13 @@ def parse_args(argv):
"configuration", help="Your YAML configuration file(s).", nargs="+"
)
parser_clean_all = subparsers.add_parser(
"clean-all", help="Clean all build and platform files."
)
parser_clean_all.add_argument(
"configuration", help="Your YAML configuration directory.", nargs="*"
)
parser_dashboard = subparsers.add_parser(
"dashboard", help="Create a simple web server for a dashboard."
)
@@ -1017,7 +1226,7 @@ def parse_args(argv):
parser_update = subparsers.add_parser("update-all")
parser_update.add_argument(
"configuration", help="Your YAML configuration file directories.", nargs="+"
"configuration", help="Your YAML configuration file or directory.", nargs="+"
)
parser_idedata = subparsers.add_parser("idedata")
@@ -1050,13 +1259,26 @@ def parse_args(argv):
arguments = argv[1:]
argcomplete.autocomplete(parser)
if len(arguments) > 0 and arguments[0] in SIMPLE_CONFIG_ACTIONS:
args, unknown_args = parser.parse_known_args(arguments)
if unknown_args:
_LOGGER.warning("Ignored unrecognized arguments: %s", unknown_args)
return args
return parser.parse_args(arguments)
def run_esphome(argv):
from esphome.address_cache import AddressCache
args = parse_args(argv)
CORE.dashboard = args.dashboard
# Create address cache from command-line arguments
CORE.address_cache = AddressCache.from_cli_args(
args.mdns_address_cache, args.dns_address_cache
)
# Override log level if verbose is set
if args.verbose:
args.log_level = "DEBUG"
@@ -1079,14 +1301,20 @@ def run_esphome(argv):
_LOGGER.info("ESPHome %s", const.__version__)
for conf_path in args.configuration:
if any(os.path.basename(conf_path) == x for x in SECRETS_FILES):
conf_path = Path(conf_path)
if any(conf_path.name == x for x in SECRETS_FILES):
_LOGGER.warning("Skipping secrets file %s", conf_path)
continue
CORE.config_path = conf_path
CORE.dashboard = args.dashboard
config = read_config(dict(args.substitution) if args.substitution else {})
# For logs command, skip updating external components
skip_external = args.command == "logs"
config = read_config(
dict(args.substitution) if args.substitution else {},
skip_external_update=skip_external,
)
if config is None:
return 2
CORE.config = config

142
esphome/address_cache.py Normal file
View File

@@ -0,0 +1,142 @@
"""Address cache for DNS and mDNS lookups."""
from __future__ import annotations
import logging
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from collections.abc import Iterable
_LOGGER = logging.getLogger(__name__)
def normalize_hostname(hostname: str) -> str:
"""Normalize hostname for cache lookups.
Removes trailing dots and converts to lowercase.
"""
return hostname.rstrip(".").lower()
class AddressCache:
"""Cache for DNS and mDNS address lookups.
This cache stores pre-resolved addresses from command-line arguments
to avoid slow DNS/mDNS lookups during builds.
"""
def __init__(
self,
mdns_cache: dict[str, list[str]] | None = None,
dns_cache: dict[str, list[str]] | None = None,
) -> None:
"""Initialize the address cache.
Args:
mdns_cache: Pre-populated mDNS addresses (hostname -> IPs)
dns_cache: Pre-populated DNS addresses (hostname -> IPs)
"""
self.mdns_cache = mdns_cache or {}
self.dns_cache = dns_cache or {}
def _get_cached_addresses(
self, hostname: str, cache: dict[str, list[str]], cache_type: str
) -> list[str] | None:
"""Get cached addresses from a specific cache.
Args:
hostname: The hostname to look up
cache: The cache dictionary to check
cache_type: Type of cache for logging ("mDNS" or "DNS")
Returns:
List of IP addresses if found in cache, None otherwise
"""
normalized = normalize_hostname(hostname)
if addresses := cache.get(normalized):
_LOGGER.debug("Using %s cache for %s: %s", cache_type, hostname, addresses)
return addresses
return None
def get_mdns_addresses(self, hostname: str) -> list[str] | None:
"""Get cached mDNS addresses for a hostname.
Args:
hostname: The hostname to look up (should end with .local)
Returns:
List of IP addresses if found in cache, None otherwise
"""
return self._get_cached_addresses(hostname, self.mdns_cache, "mDNS")
def get_dns_addresses(self, hostname: str) -> list[str] | None:
"""Get cached DNS addresses for a hostname.
Args:
hostname: The hostname to look up
Returns:
List of IP addresses if found in cache, None otherwise
"""
return self._get_cached_addresses(hostname, self.dns_cache, "DNS")
def get_addresses(self, hostname: str) -> list[str] | None:
"""Get cached addresses for a hostname.
Checks mDNS cache for .local domains, DNS cache otherwise.
Args:
hostname: The hostname to look up
Returns:
List of IP addresses if found in cache, None otherwise
"""
normalized = normalize_hostname(hostname)
if normalized.endswith(".local"):
return self.get_mdns_addresses(hostname)
return self.get_dns_addresses(hostname)
def has_cache(self) -> bool:
"""Check if any cache entries exist."""
return bool(self.mdns_cache or self.dns_cache)
@classmethod
def from_cli_args(
cls, mdns_args: Iterable[str], dns_args: Iterable[str]
) -> AddressCache:
"""Create cache from command-line arguments.
Args:
mdns_args: List of mDNS cache entries like ['host=ip1,ip2']
dns_args: List of DNS cache entries like ['host=ip1,ip2']
Returns:
Configured AddressCache instance
"""
mdns_cache = cls._parse_cache_args(mdns_args)
dns_cache = cls._parse_cache_args(dns_args)
return cls(mdns_cache=mdns_cache, dns_cache=dns_cache)
@staticmethod
def _parse_cache_args(cache_args: Iterable[str]) -> dict[str, list[str]]:
"""Parse cache arguments into a dictionary.
Args:
cache_args: List of cache mappings like ['host1=ip1,ip2', 'host2=ip3']
Returns:
Dictionary mapping normalized hostnames to list of IP addresses
"""
cache: dict[str, list[str]] = {}
for arg in cache_args:
if "=" not in arg:
_LOGGER.warning(
"Invalid cache format: %s (expected 'hostname=ip1,ip2')", arg
)
continue
hostname, ips = arg.split("=", 1)
# Normalize hostname for consistent lookups
normalized = normalize_hostname(hostname)
cache[normalized] = [ip.strip() for ip in ips.split(",")]
return cache

View File

@@ -1161,11 +1161,10 @@ class MemoryAnalyzer:
if component_name in ESPHOME_COMPONENTS:
return f"[esphome]{component_name}"
# Check if this is a known external component from the config
elif component_name in self.external_components:
if component_name in self.external_components:
return f"[external]{component_name}"
else:
# Everything else in esphome:: namespace is core
return "[esphome]core"
# Everything else in esphome:: namespace is core
return "[esphome]core"
# Check for esphome core namespace (no component namespace)
if "esphome::" in demangled:
@@ -1188,8 +1187,7 @@ class MemoryAnalyzer:
if "spi_" in symbol_name or "SPI" in symbol_name:
if "spi_flash" in symbol_name:
return "spi_flash"
else:
return "spi_driver"
return "spi_driver"
# libc special printf variants
if symbol_name.startswith("_") and symbol_name[1:].replace("_r", "").replace(
@@ -1391,7 +1389,7 @@ class MemoryAnalyzer:
# Top consumers
lines.append("")
lines.append("Top Flash Consumers:")
for i, (name, mem) in enumerate(components[:10]):
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
@@ -1403,7 +1401,7 @@ class MemoryAnalyzer:
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[:10]):
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(
@@ -1474,7 +1472,7 @@ class MemoryAnalyzer:
self._esphome_core_symbols, key=lambda x: x[2], reverse=True
)
for i, (symbol, demangled, size) in enumerate(sorted_core_symbols[:10]):
for i, (symbol, demangled, size) in enumerate(sorted_core_symbols[:15]):
lines.append(f"{i + 1}. {demangled} ({size:,} B)")
lines.append("=" * table_width)
@@ -1487,7 +1485,7 @@ class MemoryAnalyzer:
]
top_esphome_components = sorted(
esphome_components, key=lambda x: x[1].flash_total, reverse=True
)[:5]
)[:25]
# Check if API component exists and ensure it's included
api_component = None

View File

@@ -15,7 +15,10 @@ from esphome.const import (
CONF_TYPE_ID,
CONF_UPDATE_INTERVAL,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, MockObjClass, TemplateArgsType
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
from esphome.types import ConfigType
from esphome.util import Registry
@@ -49,11 +52,11 @@ def maybe_conf(conf, *validators):
return validate
def register_action(name, action_type, schema):
def register_action(name: str, action_type: MockObjClass, schema: cv.Schema):
return ACTION_REGISTRY.register(name, action_type, schema)
def register_condition(name, condition_type, schema):
def register_condition(name: str, condition_type: MockObjClass, schema: cv.Schema):
return CONDITION_REGISTRY.register(name, condition_type, schema)
@@ -164,43 +167,78 @@ XorCondition = cg.esphome_ns.class_("XorCondition", Condition)
@register_condition("and", AndCondition, validate_condition_list)
async def and_condition_to_code(config, condition_id, template_arg, args):
async def and_condition_to_code(
config: ConfigType,
condition_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
conditions = await build_condition_list(config, template_arg, args)
return cg.new_Pvariable(condition_id, template_arg, conditions)
@register_condition("or", OrCondition, validate_condition_list)
async def or_condition_to_code(config, condition_id, template_arg, args):
async def or_condition_to_code(
config: ConfigType,
condition_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
conditions = await build_condition_list(config, template_arg, args)
return cg.new_Pvariable(condition_id, template_arg, conditions)
@register_condition("all", AndCondition, validate_condition_list)
async def all_condition_to_code(config, condition_id, template_arg, args):
async def all_condition_to_code(
config: ConfigType,
condition_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
conditions = await build_condition_list(config, template_arg, args)
return cg.new_Pvariable(condition_id, template_arg, conditions)
@register_condition("any", OrCondition, validate_condition_list)
async def any_condition_to_code(config, condition_id, template_arg, args):
async def any_condition_to_code(
config: ConfigType,
condition_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
conditions = await build_condition_list(config, template_arg, args)
return cg.new_Pvariable(condition_id, template_arg, conditions)
@register_condition("not", NotCondition, validate_potentially_and_condition)
async def not_condition_to_code(config, condition_id, template_arg, args):
async def not_condition_to_code(
config: ConfigType,
condition_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
condition = await build_condition(config, template_arg, args)
return cg.new_Pvariable(condition_id, template_arg, condition)
@register_condition("xor", XorCondition, validate_condition_list)
async def xor_condition_to_code(config, condition_id, template_arg, args):
async def xor_condition_to_code(
config: ConfigType,
condition_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
conditions = await build_condition_list(config, template_arg, args)
return cg.new_Pvariable(condition_id, template_arg, conditions)
@register_condition("lambda", LambdaCondition, cv.returning_lambda)
async def lambda_condition_to_code(config, condition_id, template_arg, args):
async def lambda_condition_to_code(
config: ConfigType,
condition_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
lambda_ = await cg.process_lambda(config, args, return_type=bool)
return cg.new_Pvariable(condition_id, template_arg, lambda_)
@@ -217,7 +255,12 @@ async def lambda_condition_to_code(config, condition_id, template_arg, args):
}
).extend(cv.COMPONENT_SCHEMA),
)
async def for_condition_to_code(config, condition_id, template_arg, args):
async def for_condition_to_code(
config: ConfigType,
condition_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
condition = await build_condition(
config[CONF_CONDITION], cg.TemplateArguments(), []
)
@@ -231,7 +274,12 @@ async def for_condition_to_code(config, condition_id, template_arg, args):
@register_action(
"delay", DelayAction, cv.templatable(cv.positive_time_period_milliseconds)
)
async def delay_action_to_code(config, action_id, template_arg, args):
async def delay_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_component(var, {})
template_ = await cg.templatable(config, args, cg.uint32)
@@ -256,10 +304,15 @@ async def delay_action_to_code(config, action_id, template_arg, args):
cv.has_at_least_one_key(CONF_CONDITION, CONF_ANY, CONF_ALL),
),
)
async def if_action_to_code(config, action_id, template_arg, args):
async def if_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
cond_conf = next(el for el in config if el in (CONF_ANY, CONF_ALL, CONF_CONDITION))
conditions = await build_condition(config[cond_conf], template_arg, args)
var = cg.new_Pvariable(action_id, template_arg, conditions)
condition = await build_condition(config[cond_conf], template_arg, args)
var = cg.new_Pvariable(action_id, template_arg, condition)
if CONF_THEN in config:
actions = await build_action_list(config[CONF_THEN], template_arg, args)
cg.add(var.add_then(actions))
@@ -279,9 +332,14 @@ async def if_action_to_code(config, action_id, template_arg, args):
}
),
)
async def while_action_to_code(config, action_id, template_arg, args):
conditions = await build_condition(config[CONF_CONDITION], template_arg, args)
var = cg.new_Pvariable(action_id, template_arg, conditions)
async def while_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
condition = await build_condition(config[CONF_CONDITION], template_arg, args)
var = cg.new_Pvariable(action_id, template_arg, condition)
actions = await build_action_list(config[CONF_THEN], template_arg, args)
cg.add(var.add_then(actions))
return var
@@ -297,7 +355,12 @@ async def while_action_to_code(config, action_id, template_arg, args):
}
),
)
async def repeat_action_to_code(config, action_id, template_arg, args):
async def repeat_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
count_template = await cg.templatable(config[CONF_COUNT], args, cg.uint32)
cg.add(var.set_count(count_template))
@@ -320,9 +383,14 @@ _validate_wait_until = cv.maybe_simple_value(
@register_action("wait_until", WaitUntilAction, _validate_wait_until)
async def wait_until_action_to_code(config, action_id, template_arg, args):
conditions = await build_condition(config[CONF_CONDITION], template_arg, args)
var = cg.new_Pvariable(action_id, template_arg, conditions)
async def wait_until_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
condition = await build_condition(config[CONF_CONDITION], template_arg, args)
var = cg.new_Pvariable(action_id, template_arg, condition)
if CONF_TIMEOUT in config:
template_ = await cg.templatable(config[CONF_TIMEOUT], args, cg.uint32)
cg.add(var.set_timeout_value(template_))
@@ -331,7 +399,12 @@ async def wait_until_action_to_code(config, action_id, template_arg, args):
@register_action("lambda", LambdaAction, cv.lambda_)
async def lambda_action_to_code(config, action_id, template_arg, args):
async def lambda_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
lambda_ = await cg.process_lambda(config, args, return_type=cg.void)
return cg.new_Pvariable(action_id, template_arg, lambda_)
@@ -345,7 +418,12 @@ async def lambda_action_to_code(config, action_id, template_arg, args):
}
),
)
async def component_update_action_to_code(config, action_id, template_arg, args):
async def component_update_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
comp = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, comp)
@@ -359,7 +437,12 @@ async def component_update_action_to_code(config, action_id, template_arg, args)
}
),
)
async def component_suspend_action_to_code(config, action_id, template_arg, args):
async def component_suspend_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
comp = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, comp)
@@ -376,7 +459,12 @@ async def component_suspend_action_to_code(config, action_id, template_arg, args
}
),
)
async def component_resume_action_to_code(config, action_id, template_arg, args):
async def component_resume_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
comp = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, comp)
if CONF_UPDATE_INTERVAL in config:
@@ -385,43 +473,51 @@ async def component_resume_action_to_code(config, action_id, template_arg, args)
return var
async def build_action(full_config, template_arg, args):
async def build_action(
full_config: ConfigType, template_arg: cg.TemplateArguments, args: TemplateArgsType
) -> MockObj:
registry_entry, config = cg.extract_registry_entry_config(
ACTION_REGISTRY, full_config
)
action_id = full_config[CONF_TYPE_ID]
builder = registry_entry.coroutine_fun
ret = await builder(config, action_id, template_arg, args)
return ret
return await builder(config, action_id, template_arg, args)
async def build_action_list(config, templ, arg_type):
actions = []
async def build_action_list(
config: list[ConfigType], templ: cg.TemplateArguments, arg_type: TemplateArgsType
) -> list[MockObj]:
actions: list[MockObj] = []
for conf in config:
action = await build_action(conf, templ, arg_type)
actions.append(action)
return actions
async def build_condition(full_config, template_arg, args):
async def build_condition(
full_config: ConfigType, template_arg: cg.TemplateArguments, args: TemplateArgsType
) -> MockObj:
registry_entry, config = cg.extract_registry_entry_config(
CONDITION_REGISTRY, full_config
)
action_id = full_config[CONF_TYPE_ID]
builder = registry_entry.coroutine_fun
ret = await builder(config, action_id, template_arg, args)
return ret
return await builder(config, action_id, template_arg, args)
async def build_condition_list(config, templ, args):
conditions = []
async def build_condition_list(
config: ConfigType, templ: cg.TemplateArguments, args: TemplateArgsType
) -> list[MockObj]:
conditions: list[MockObj] = []
for conf in config:
condition = await build_condition(conf, templ, args)
conditions.append(condition)
return conditions
async def build_automation(trigger, args, config):
async def build_automation(
trigger: MockObj, args: TemplateArgsType, config: ConfigType
) -> MockObj:
arg_types = [arg[0] for arg in args]
templ = cg.TemplateArguments(*arg_types)
obj = cg.new_Pvariable(config[CONF_AUTOMATION_ID], templ, trigger)

View File

@@ -1,5 +1,3 @@
import os
from esphome.const import __version__
from esphome.core import CORE
from esphome.helpers import mkdir_p, read_file, write_file_if_changed
@@ -63,7 +61,7 @@ def write_ini(content):
update_storage_json()
path = CORE.relative_build_path("platformio.ini")
if os.path.isfile(path):
if path.is_file():
text = read_file(path)
content_format = find_begin_end(
text, INI_AUTO_GENERATE_BEGIN, INI_AUTO_GENERATE_END

View File

@@ -12,6 +12,7 @@ from esphome.cpp_generator import ( # noqa: F401
ArrayInitializer,
Expression,
LineComment,
LogStringLiteral,
MockObj,
MockObjClass,
Pvariable,

View File

@@ -61,11 +61,10 @@ void AbsoluteHumidityComponent::loop() {
ESP_LOGW(TAG, "No valid state from temperature sensor!");
}
if (no_humidity) {
ESP_LOGW(TAG, "No valid state from temperature sensor!");
ESP_LOGW(TAG, "No valid state from humidity sensor!");
}
ESP_LOGW(TAG, "Unable to calculate absolute humidity.");
this->publish_state(NAN);
this->status_set_warning();
this->status_set_warning(LOG_STR("Unable to calculate absolute humidity."));
return;
}
@@ -87,9 +86,8 @@ void AbsoluteHumidityComponent::loop() {
es = es_wobus(temperature_c);
break;
default:
ESP_LOGE(TAG, "Invalid saturation vapor pressure equation selection!");
this->publish_state(NAN);
this->status_set_error();
this->status_set_error("Invalid saturation vapor pressure equation selection!");
return;
}
ESP_LOGD(TAG, "Saturation vapor pressure %f kPa", es);

View File

@@ -5,7 +5,7 @@ from esphome.const import (
CONF_EQUATION,
CONF_HUMIDITY,
CONF_TEMPERATURE,
ICON_WATER,
DEVICE_CLASS_ABSOLUTE_HUMIDITY,
STATE_CLASS_MEASUREMENT,
UNIT_GRAMS_PER_CUBIC_METER,
)
@@ -27,8 +27,8 @@ EQUATION = {
CONFIG_SCHEMA = (
sensor.sensor_schema(
unit_of_measurement=UNIT_GRAMS_PER_CUBIC_METER,
icon=ICON_WATER,
accuracy_decimals=2,
device_class=DEVICE_CLASS_ABSOLUTE_HUMIDITY,
state_class=STATE_CLASS_MEASUREMENT,
)
.extend(

View File

@@ -1,6 +1,6 @@
from esphome import pins
import esphome.codegen as cg
from esphome.components.esp32 import get_esp32_variant
from esphome.components.esp32 import VARIANT_ESP32P4, get_esp32_variant
from esphome.components.esp32.const import (
VARIANT_ESP32,
VARIANT_ESP32C2,
@@ -11,15 +11,8 @@ from esphome.components.esp32.const import (
VARIANT_ESP32S2,
VARIANT_ESP32S3,
)
from esphome.config_helpers import filter_source_files_from_platform
import esphome.config_validation as cv
from esphome.const import (
CONF_ANALOG,
CONF_INPUT,
CONF_NUMBER,
PLATFORM_ESP8266,
PlatformFramework,
)
from esphome.const import CONF_ANALOG, CONF_INPUT, CONF_NUMBER, PLATFORM_ESP8266
from esphome.core import CORE
CODEOWNERS = ["@esphome/core"]
@@ -140,6 +133,16 @@ 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
@@ -198,6 +201,14 @@ 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,
},
}
@@ -249,21 +260,9 @@ def validate_adc_pin(value):
{CONF_ANALOG: True, CONF_INPUT: True}, internal=True
)(value)
if CORE.is_nrf52:
return pins.gpio_pin_schema(
{CONF_ANALOG: True, CONF_INPUT: True}, internal=True
)(value)
raise NotImplementedError
FILTER_SOURCE_FILES = filter_source_files_from_platform(
{
"adc_sensor_esp32.cpp": {
PlatformFramework.ESP32_ARDUINO,
PlatformFramework.ESP32_IDF,
},
"adc_sensor_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO},
"adc_sensor_rp2040.cpp": {PlatformFramework.RP2040_ARDUINO},
"adc_sensor_libretiny.cpp": {
PlatformFramework.BK72XX_ARDUINO,
PlatformFramework.RTL87XX_ARDUINO,
PlatformFramework.LN882X_ARDUINO,
},
}
)

View File

@@ -13,6 +13,10 @@
#include "hal/adc_types.h" // This defines ADC_CHANNEL_MAX
#endif // USE_ESP32
#ifdef USE_ZEPHYR
#include <zephyr/drivers/adc.h>
#endif
namespace esphome {
namespace adc {
@@ -38,15 +42,15 @@ enum class SamplingMode : uint8_t {
const LogString *sampling_mode_to_str(SamplingMode mode);
class Aggregator {
template<typename T> class Aggregator {
public:
Aggregator(SamplingMode mode);
void add_sample(uint32_t value);
uint32_t aggregate();
void add_sample(T value);
T aggregate();
protected:
uint32_t aggr_{0};
uint32_t samples_{0};
T aggr_{0};
uint8_t samples_{0};
SamplingMode mode_{SamplingMode::AVG};
};
@@ -69,6 +73,11 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
/// @return A float representing the setup priority.
float get_setup_priority() const override;
#ifdef USE_ZEPHYR
/// Set the ADC channel to be used by the ADC sensor.
/// @param channel Pointer to an adc_dt_spec structure representing the ADC channel.
void set_adc_channel(const adc_dt_spec *channel) { this->channel_ = channel; }
#endif
/// Set the GPIO pin to be used by the ADC sensor.
/// @param pin Pointer to an InternalGPIOPin representing the ADC input pin.
void set_pin(InternalGPIOPin *pin) { this->pin_ = pin; }
@@ -136,8 +145,8 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
adc_oneshot_unit_handle_t adc_handle_{nullptr};
adc_cali_handle_t calibration_handle_{nullptr};
adc_atten_t attenuation_{ADC_ATTEN_DB_0};
adc_channel_t channel_;
adc_unit_t adc_unit_;
adc_channel_t channel_{};
adc_unit_t adc_unit_{};
struct SetupFlags {
uint8_t init_complete : 1;
uint8_t config_complete : 1;
@@ -151,6 +160,10 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
#ifdef USE_RP2040
bool is_temperature_{false};
#endif // USE_RP2040
#ifdef USE_ZEPHYR
const struct adc_dt_spec *channel_ = nullptr;
#endif
};
} // namespace adc

View File

@@ -18,15 +18,15 @@ const LogString *sampling_mode_to_str(SamplingMode mode) {
return LOG_STR("unknown");
}
Aggregator::Aggregator(SamplingMode mode) {
template<typename T> Aggregator<T>::Aggregator(SamplingMode mode) {
this->mode_ = mode;
// set to max uint if mode is "min"
if (mode == SamplingMode::MIN) {
this->aggr_ = UINT32_MAX;
this->aggr_ = std::numeric_limits<T>::max();
}
}
void Aggregator::add_sample(uint32_t value) {
template<typename T> void Aggregator<T>::add_sample(T value) {
this->samples_ += 1;
switch (this->mode_) {
@@ -47,7 +47,7 @@ void Aggregator::add_sample(uint32_t value) {
}
}
uint32_t Aggregator::aggregate() {
template<typename T> T Aggregator<T>::aggregate() {
if (this->mode_ == SamplingMode::AVG) {
if (this->samples_ == 0) {
return this->aggr_;
@@ -59,6 +59,12 @@ uint32_t Aggregator::aggregate() {
return this->aggr_;
}
#ifdef USE_ZEPHYR
template class Aggregator<int32_t>;
#else
template class Aggregator<uint32_t>;
#endif
void ADCSensor::update() {
float value_v = this->sample();
ESP_LOGV(TAG, "'%s': Voltage=%.4fV", this->get_name().c_str(), value_v);

View File

@@ -72,10 +72,9 @@ void ADCSensor::setup() {
// Initialize ADC calibration
if (this->calibration_handle_ == nullptr) {
adc_cali_handle_t handle = nullptr;
esp_err_t err;
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
// 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)
@@ -153,7 +152,7 @@ float ADCSensor::sample() {
}
float ADCSensor::sample_fixed_attenuation_() {
auto aggr = Aggregator(this->sampling_mode_);
auto aggr = Aggregator<uint32_t>(this->sampling_mode_);
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
int raw;
@@ -187,7 +186,7 @@ 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_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
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_);
@@ -220,7 +219,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_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
adc_cali_delete_scheme_curve_fitting(this->calibration_handle_);
#else
adc_cali_delete_scheme_line_fitting(this->calibration_handle_);
@@ -232,7 +231,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_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
adc_cali_curve_fitting_config_t cali_config = {};
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
cali_config.chan = this->channel_;
@@ -242,6 +241,8 @@ float ADCSensor::sample_autorange_() {
cali_config.bitwidth = ADC_BITWIDTH_DEFAULT;
err = adc_cali_create_scheme_curve_fitting(&cali_config, &handle);
ESP_LOGVV(TAG, "Autorange atten=%d: Calibration handle creation %s (err=%d)", atten,
(err == ESP_OK) ? "SUCCESS" : "FAILED", err);
#else
adc_cali_line_fitting_config_t cali_config = {
.unit_id = this->adc_unit_,
@@ -252,16 +253,20 @@ float ADCSensor::sample_autorange_() {
#endif
};
err = adc_cali_create_scheme_line_fitting(&cali_config, &handle);
ESP_LOGVV(TAG, "Autorange atten=%d: Calibration handle creation %s (err=%d)", atten,
(err == ESP_OK) ? "SUCCESS" : "FAILED", err);
#endif
int raw;
err = adc_oneshot_read(this->adc_handle_, this->channel_, &raw);
ESP_LOGVV(TAG, "Autorange atten=%d: Raw ADC read %s, value=%d (err=%d)", atten,
(err == ESP_OK) ? "SUCCESS" : "FAILED", raw, err);
if (err != ESP_OK) {
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_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
adc_cali_delete_scheme_curve_fitting(handle);
#else
adc_cali_delete_scheme_line_fitting(handle);
@@ -276,18 +281,21 @@ float ADCSensor::sample_autorange_() {
err = adc_cali_raw_to_voltage(handle, raw, &voltage_mv);
if (err == ESP_OK) {
voltage = voltage_mv / 1000.0f;
ESP_LOGVV(TAG, "Autorange atten=%d: CALIBRATED - raw=%d -> %dmV -> %.6fV", atten, raw, voltage_mv, voltage);
} else {
voltage = raw * 3.3f / 4095.0f;
ESP_LOGVV(TAG, "Autorange atten=%d: UNCALIBRATED FALLBACK - raw=%d -> %.6fV (3.3V ref)", atten, raw, voltage);
}
// 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_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
adc_cali_delete_scheme_curve_fitting(handle);
#else
adc_cali_delete_scheme_line_fitting(handle);
#endif
} else {
voltage = raw * 3.3f / 4095.0f;
ESP_LOGVV(TAG, "Autorange atten=%d: NO CALIBRATION - raw=%d -> %.6fV (3.3V ref)", atten, raw, voltage);
}
return {raw, voltage};
@@ -325,18 +333,32 @@ float ADCSensor::sample_autorange_() {
}
const int adc_half = 2048;
uint32_t c12 = std::min(raw12, adc_half);
uint32_t c6 = adc_half - std::abs(raw6 - adc_half);
uint32_t c2 = adc_half - std::abs(raw2 - adc_half);
uint32_t c0 = std::min(4095 - raw0, adc_half);
uint32_t csum = c12 + c6 + c2 + c0;
const uint32_t c12 = std::min(raw12, adc_half);
const int32_t c6_signed = adc_half - std::abs(raw6 - adc_half);
const uint32_t c6 = (c6_signed > 0) ? c6_signed : 0; // Clamp to prevent underflow
const int32_t c2_signed = adc_half - std::abs(raw2 - adc_half);
const uint32_t c2 = (c2_signed > 0) ? c2_signed : 0; // Clamp to prevent underflow
const uint32_t c0 = std::min(4095 - raw0, adc_half);
const uint32_t csum = c12 + c6 + c2 + c0;
ESP_LOGVV(TAG, "Autorange summary:");
ESP_LOGVV(TAG, " Raw readings: 12db=%d, 6db=%d, 2.5db=%d, 0db=%d", raw12, raw6, raw2, raw0);
ESP_LOGVV(TAG, " Voltages: 12db=%.6f, 6db=%.6f, 2.5db=%.6f, 0db=%.6f", mv12, mv6, mv2, mv0);
ESP_LOGVV(TAG, " Coefficients: c12=%u, c6=%u, c2=%u, c0=%u, sum=%u", c12, c6, c2, c0, csum);
if (csum == 0) {
ESP_LOGE(TAG, "Invalid weight sum in autorange calculation");
return NAN;
}
return (mv12 * c12 + mv6 * c6 + mv2 * c2 + mv0 * c0) / csum;
const float final_result = (mv12 * c12 + mv6 * c6 + mv2 * c2 + mv0 * c0) / csum;
ESP_LOGV(TAG, "Autorange final: (%.6f*%u + %.6f*%u + %.6f*%u + %.6f*%u)/%u = %.6fV", mv12, c12, mv6, c6, mv2, c2, mv0,
c0, csum, final_result);
return final_result;
}
} // namespace adc

View File

@@ -37,7 +37,7 @@ void ADCSensor::dump_config() {
}
float ADCSensor::sample() {
auto aggr = Aggregator(this->sampling_mode_);
auto aggr = Aggregator<uint32_t>(this->sampling_mode_);
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
uint32_t raw = 0;

View File

@@ -30,7 +30,7 @@ void ADCSensor::dump_config() {
float ADCSensor::sample() {
uint32_t raw = 0;
auto aggr = Aggregator(this->sampling_mode_);
auto aggr = Aggregator<uint32_t>(this->sampling_mode_);
if (this->output_raw_) {
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {

View File

@@ -41,7 +41,7 @@ void ADCSensor::dump_config() {
float ADCSensor::sample() {
uint32_t raw = 0;
auto aggr = Aggregator(this->sampling_mode_);
auto aggr = Aggregator<uint32_t>(this->sampling_mode_);
if (this->is_temperature_) {
adc_set_temp_sensor_enabled(true);

View File

@@ -0,0 +1,207 @@
#include "adc_sensor.h"
#ifdef USE_ZEPHYR
#include "esphome/core/log.h"
#include "hal/nrf_saadc.h"
namespace esphome {
namespace adc {
static const char *const TAG = "adc.zephyr";
void ADCSensor::setup() {
if (!adc_is_ready_dt(this->channel_)) {
ESP_LOGE(TAG, "ADC controller device %s not ready", this->channel_->dev->name);
return;
}
auto err = adc_channel_setup_dt(this->channel_);
if (err < 0) {
ESP_LOGE(TAG, "Could not setup channel %s (%d)", this->channel_->dev->name, err);
return;
}
}
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
static const LogString *gain_to_str(enum adc_gain gain) {
switch (gain) {
case ADC_GAIN_1_6:
return LOG_STR("1/6");
case ADC_GAIN_1_5:
return LOG_STR("1/5");
case ADC_GAIN_1_4:
return LOG_STR("1/4");
case ADC_GAIN_1_3:
return LOG_STR("1/3");
case ADC_GAIN_2_5:
return LOG_STR("2/5");
case ADC_GAIN_1_2:
return LOG_STR("1/2");
case ADC_GAIN_2_3:
return LOG_STR("2/3");
case ADC_GAIN_4_5:
return LOG_STR("4/5");
case ADC_GAIN_1:
return LOG_STR("1");
case ADC_GAIN_2:
return LOG_STR("2");
case ADC_GAIN_3:
return LOG_STR("3");
case ADC_GAIN_4:
return LOG_STR("4");
case ADC_GAIN_6:
return LOG_STR("6");
case ADC_GAIN_8:
return LOG_STR("8");
case ADC_GAIN_12:
return LOG_STR("12");
case ADC_GAIN_16:
return LOG_STR("16");
case ADC_GAIN_24:
return LOG_STR("24");
case ADC_GAIN_32:
return LOG_STR("32");
case ADC_GAIN_64:
return LOG_STR("64");
case ADC_GAIN_128:
return LOG_STR("128");
}
return LOG_STR("undefined gain");
}
static const LogString *reference_to_str(enum adc_reference reference) {
switch (reference) {
case ADC_REF_VDD_1:
return LOG_STR("VDD");
case ADC_REF_VDD_1_2:
return LOG_STR("VDD/2");
case ADC_REF_VDD_1_3:
return LOG_STR("VDD/3");
case ADC_REF_VDD_1_4:
return LOG_STR("VDD/4");
case ADC_REF_INTERNAL:
return LOG_STR("INTERNAL");
case ADC_REF_EXTERNAL0:
return LOG_STR("External, input 0");
case ADC_REF_EXTERNAL1:
return LOG_STR("External, input 1");
}
return LOG_STR("undefined reference");
}
static const LogString *input_to_str(uint8_t input) {
switch (input) {
case NRF_SAADC_INPUT_AIN0:
return LOG_STR("AIN0");
case NRF_SAADC_INPUT_AIN1:
return LOG_STR("AIN1");
case NRF_SAADC_INPUT_AIN2:
return LOG_STR("AIN2");
case NRF_SAADC_INPUT_AIN3:
return LOG_STR("AIN3");
case NRF_SAADC_INPUT_AIN4:
return LOG_STR("AIN4");
case NRF_SAADC_INPUT_AIN5:
return LOG_STR("AIN5");
case NRF_SAADC_INPUT_AIN6:
return LOG_STR("AIN6");
case NRF_SAADC_INPUT_AIN7:
return LOG_STR("AIN7");
case NRF_SAADC_INPUT_VDD:
return LOG_STR("VDD");
case NRF_SAADC_INPUT_VDDHDIV5:
return LOG_STR("VDDHDIV5");
}
return LOG_STR("undefined input");
}
#endif // ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
void ADCSensor::dump_config() {
LOG_SENSOR("", "ADC Sensor", this);
LOG_PIN(" Pin: ", this->pin_);
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
ESP_LOGV(TAG,
" Name: %s\n"
" Channel: %d\n"
" vref_mv: %d\n"
" Resolution %d\n"
" Oversampling %d",
this->channel_->dev->name, this->channel_->channel_id, this->channel_->vref_mv, this->channel_->resolution,
this->channel_->oversampling);
ESP_LOGV(TAG,
" Gain: %s\n"
" reference: %s\n"
" acquisition_time: %d\n"
" differential %s",
LOG_STR_ARG(gain_to_str(this->channel_->channel_cfg.gain)),
LOG_STR_ARG(reference_to_str(this->channel_->channel_cfg.reference)),
this->channel_->channel_cfg.acquisition_time, YESNO(this->channel_->channel_cfg.differential));
if (this->channel_->channel_cfg.differential) {
ESP_LOGV(TAG,
" Positive: %s\n"
" Negative: %s",
LOG_STR_ARG(input_to_str(this->channel_->channel_cfg.input_positive)),
LOG_STR_ARG(input_to_str(this->channel_->channel_cfg.input_negative)));
} else {
ESP_LOGV(TAG, " Positive: %s", LOG_STR_ARG(input_to_str(this->channel_->channel_cfg.input_positive)));
}
#endif
LOG_UPDATE_INTERVAL(this);
}
float ADCSensor::sample() {
auto aggr = Aggregator<int32_t>(this->sampling_mode_);
int err;
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
int16_t buf = 0;
struct adc_sequence sequence = {
.buffer = &buf,
/* buffer size in bytes, not number of samples */
.buffer_size = sizeof(buf),
};
int32_t val_raw;
err = adc_sequence_init_dt(this->channel_, &sequence);
if (err < 0) {
ESP_LOGE(TAG, "Could sequence init %s (%d)", this->channel_->dev->name, err);
return 0.0;
}
err = adc_read(this->channel_->dev, &sequence);
if (err < 0) {
ESP_LOGE(TAG, "Could not read %s (%d)", this->channel_->dev->name, err);
return 0.0;
}
val_raw = (int32_t) buf;
if (!this->channel_->channel_cfg.differential) {
// https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/0ed4d9ffc674ae407be7cacf5696a02f5e789861/cores/nRF5/wiring_analog_nRF52.c#L222
if (val_raw < 0) {
val_raw = 0;
}
}
aggr.add_sample(val_raw);
}
int32_t val_mv = aggr.aggregate();
if (this->output_raw_) {
return val_mv;
}
err = adc_raw_to_millivolts_dt(this->channel_, &val_mv);
/* conversion to mV may not be supported, skip if not */
if (err < 0) {
ESP_LOGE(TAG, "Value in mV not available %s (%d)", this->channel_->dev->name, err);
return 0.0;
}
return val_mv / 1000.0f;
}
} // namespace adc
} // namespace esphome
#endif

View File

@@ -3,6 +3,13 @@ import logging
import esphome.codegen as cg
from esphome.components import sensor, voltage_sampler
from esphome.components.esp32 import get_esp32_variant
from esphome.components.nrf52.const import AIN_TO_GPIO, EXTRA_ADC
from esphome.components.zephyr import (
zephyr_add_overlay,
zephyr_add_prj_conf,
zephyr_add_user,
)
from esphome.config_helpers import filter_source_files_from_platform
import esphome.config_validation as cv
from esphome.const import (
CONF_ATTENUATION,
@@ -11,8 +18,10 @@ from esphome.const import (
CONF_PIN,
CONF_RAW,
DEVICE_CLASS_VOLTAGE,
PLATFORM_NRF52,
STATE_CLASS_MEASUREMENT,
UNIT_VOLT,
PlatformFramework,
)
from esphome.core import CORE
@@ -60,6 +69,10 @@ ADCSensor = adc_ns.class_(
"ADCSensor", sensor.Sensor, cg.PollingComponent, voltage_sampler.VoltageSampler
)
CONF_NRF_SAADC = "nrf_saadc"
adc_dt_spec = cg.global_ns.class_("adc_dt_spec")
CONFIG_SCHEMA = cv.All(
sensor.sensor_schema(
ADCSensor,
@@ -75,6 +88,7 @@ CONFIG_SCHEMA = cv.All(
cv.SplitDefault(CONF_ATTENUATION, esp32="0db"): cv.All(
cv.only_on_esp32, _attenuation
),
cv.OnlyWith(CONF_NRF_SAADC, PLATFORM_NRF52): cv.declare_id(adc_dt_spec),
cv.Optional(CONF_SAMPLES, default=1): cv.int_range(min=1, max=255),
cv.Optional(CONF_SAMPLING_MODE, default="avg"): _sampling_mode,
}
@@ -83,6 +97,8 @@ CONFIG_SCHEMA = cv.All(
validate_config,
)
CONF_ADC_CHANNEL_ID = "adc_channel_id"
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
@@ -93,7 +109,7 @@ async def to_code(config):
cg.add_define("USE_ADC_SENSOR_VCC")
elif config[CONF_PIN] == "TEMPERATURE":
cg.add(var.set_is_temperature())
else:
elif not CORE.is_nrf52 or config[CONF_PIN][CONF_NUMBER] not in EXTRA_ADC:
pin = await cg.gpio_pin_expression(config[CONF_PIN])
cg.add(var.set_pin(pin))
@@ -122,3 +138,59 @@ async def to_code(config):
):
chan = ESP32_VARIANT_ADC2_PIN_TO_CHANNEL[variant][pin_num]
cg.add(var.set_channel(adc_unit_t.ADC_UNIT_2, chan))
elif CORE.is_nrf52:
CORE.data.setdefault(CONF_ADC_CHANNEL_ID, 0)
channel_id = CORE.data[CONF_ADC_CHANNEL_ID]
CORE.data[CONF_ADC_CHANNEL_ID] = channel_id + 1
zephyr_add_prj_conf("ADC", True)
nrf_saadc = config[CONF_NRF_SAADC]
rhs = cg.RawExpression(
f"ADC_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), {channel_id})"
)
adc = cg.new_Pvariable(nrf_saadc, rhs)
cg.add(var.set_adc_channel(adc))
gain = "ADC_GAIN_1_6"
pin_number = config[CONF_PIN][CONF_NUMBER]
if pin_number == "VDDHDIV5":
gain = "ADC_GAIN_1_2"
if isinstance(pin_number, int):
GPIO_TO_AIN = {v: k for k, v in AIN_TO_GPIO.items()}
pin_number = GPIO_TO_AIN[pin_number]
zephyr_add_user("io-channels", f"<&adc {channel_id}>")
zephyr_add_overlay(
f"""
&adc {{
#address-cells = <1>;
#size-cells = <0>;
channel@{channel_id} {{
reg = <{channel_id}>;
zephyr,gain = "{gain}";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,input-positive = <NRF_SAADC_{pin_number}>;
zephyr,resolution = <14>;
zephyr,oversampling = <8>;
}};
}};
"""
)
FILTER_SOURCE_FILES = filter_source_files_from_platform(
{
"adc_sensor_esp32.cpp": {
PlatformFramework.ESP32_ARDUINO,
PlatformFramework.ESP32_IDF,
},
"adc_sensor_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO},
"adc_sensor_rp2040.cpp": {PlatformFramework.RP2040_ARDUINO},
"adc_sensor_libretiny.cpp": {
PlatformFramework.BK72XX_ARDUINO,
PlatformFramework.RTL87XX_ARDUINO,
PlatformFramework.LN882X_ARDUINO,
},
"adc_sensor_zephyr.cpp": {PlatformFramework.NRF52_ZEPHYR},
}
)

View File

@@ -113,7 +113,7 @@ void ADE7880::update() {
if (this->channel_a_ != nullptr) {
auto *chan = this->channel_a_;
this->update_sensor_from_s24zp_register16_(chan->current, AIRMS, [](float val) { return val / 100000.0f; });
this->update_sensor_from_s24zp_register16_(chan->voltage, BVRMS, [](float val) { return val / 10000.0f; });
this->update_sensor_from_s24zp_register16_(chan->voltage, AVRMS, [](float val) { return val / 10000.0f; });
this->update_sensor_from_s24zp_register16_(chan->active_power, AWATT, [](float val) { return val / 100.0f; });
this->update_sensor_from_s24zp_register16_(chan->apparent_power, AVA, [](float val) { return val / 100.0f; });
this->update_sensor_from_s16_register16_(chan->power_factor, APF,

View File

@@ -36,6 +36,7 @@ from esphome.const import (
UNIT_WATT,
UNIT_WATT_HOURS,
)
from esphome.types import ConfigType
DEPENDENCIES = ["i2c"]
@@ -51,6 +52,20 @@ CONF_POWER_GAIN = "power_gain"
CONF_NEUTRAL = "neutral"
# Tuple of power channel phases
POWER_PHASES = (CONF_PHASE_A, CONF_PHASE_B, CONF_PHASE_C)
# Tuple of sensor types that can be configured for power channels
POWER_SENSOR_TYPES = (
CONF_CURRENT,
CONF_VOLTAGE,
CONF_ACTIVE_POWER,
CONF_APPARENT_POWER,
CONF_POWER_FACTOR,
CONF_FORWARD_ACTIVE_ENERGY,
CONF_REVERSE_ACTIVE_ENERGY,
)
NEUTRAL_CHANNEL_SCHEMA = cv.Schema(
{
cv.GenerateID(): cv.declare_id(NeutralChannel),
@@ -150,7 +165,64 @@ POWER_CHANNEL_SCHEMA = cv.Schema(
}
)
CONFIG_SCHEMA = (
def prefix_sensor_name(
sensor_conf: ConfigType,
channel_name: str,
channel_config: ConfigType,
sensor_type: str,
) -> None:
"""Helper to prefix sensor name with channel name.
Args:
sensor_conf: The sensor configuration (dict or string)
channel_name: The channel name to prefix with
channel_config: The channel configuration to update
sensor_type: The sensor type key in the channel config
"""
if isinstance(sensor_conf, dict) and CONF_NAME in sensor_conf:
sensor_name = sensor_conf[CONF_NAME]
if sensor_name and not sensor_name.startswith(channel_name):
sensor_conf[CONF_NAME] = f"{channel_name} {sensor_name}"
elif isinstance(sensor_conf, str):
# Simple value case - convert to dict with prefixed name
channel_config[sensor_type] = {CONF_NAME: f"{channel_name} {sensor_conf}"}
def process_channel_sensors(
config: ConfigType, channel_key: str, sensor_types: tuple
) -> None:
"""Process sensors for a channel and prefix their names.
Args:
config: The main configuration
channel_key: The channel key (e.g., CONF_PHASE_A, CONF_NEUTRAL)
sensor_types: Tuple of sensor types to process for this channel
"""
if not (channel_config := config.get(channel_key)) or not (
channel_name := channel_config.get(CONF_NAME)
):
return
for sensor_type in sensor_types:
if sensor_conf := channel_config.get(sensor_type):
prefix_sensor_name(sensor_conf, channel_name, channel_config, sensor_type)
def preprocess_channels(config: ConfigType) -> ConfigType:
"""Preprocess channel configurations to add channel name prefix to sensor names."""
# Process power channels
for channel in POWER_PHASES:
process_channel_sensors(config, channel, POWER_SENSOR_TYPES)
# Process neutral channel
process_channel_sensors(config, CONF_NEUTRAL, (CONF_CURRENT,))
return config
CONFIG_SCHEMA = cv.All(
preprocess_channels,
cv.Schema(
{
cv.GenerateID(): cv.declare_id(ADE7880),
@@ -167,7 +239,7 @@ CONFIG_SCHEMA = (
}
)
.extend(cv.polling_component_schema("60s"))
.extend(i2c.i2c_device_schema(0x38))
.extend(i2c.i2c_device_schema(0x38)),
)
@@ -188,15 +260,7 @@ async def neutral_channel(config):
async def power_channel(config):
var = cg.new_Pvariable(config[CONF_ID])
for sensor_type in [
CONF_CURRENT,
CONF_VOLTAGE,
CONF_ACTIVE_POWER,
CONF_APPARENT_POWER,
CONF_POWER_FACTOR,
CONF_FORWARD_ACTIVE_ENERGY,
CONF_REVERSE_ACTIVE_ENERGY,
]:
for sensor_type in POWER_SENSOR_TYPES:
if conf := config.get(sensor_type):
sens = await sensor.new_sensor(conf)
cg.add(getattr(var, f"set_{sensor_type}")(sens))
@@ -216,44 +280,6 @@ async def power_channel(config):
return var
def final_validate(config):
for channel in [CONF_PHASE_A, CONF_PHASE_B, CONF_PHASE_C]:
if channel := config.get(channel):
channel_name = channel.get(CONF_NAME)
for sensor_type in [
CONF_CURRENT,
CONF_VOLTAGE,
CONF_ACTIVE_POWER,
CONF_APPARENT_POWER,
CONF_POWER_FACTOR,
CONF_FORWARD_ACTIVE_ENERGY,
CONF_REVERSE_ACTIVE_ENERGY,
]:
if conf := channel.get(sensor_type):
sensor_name = conf.get(CONF_NAME)
if (
sensor_name
and channel_name
and not sensor_name.startswith(channel_name)
):
conf[CONF_NAME] = f"{channel_name} {sensor_name}"
if channel := config.get(CONF_NEUTRAL):
channel_name = channel.get(CONF_NAME)
if conf := channel.get(CONF_CURRENT):
sensor_name = conf.get(CONF_NAME)
if (
sensor_name
and channel_name
and not sensor_name.startswith(channel_name)
):
conf[CONF_NAME] = f"{channel_name} {sensor_name}"
FINAL_VALIDATE_SCHEMA = final_validate
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)

View File

@@ -89,7 +89,7 @@ void AGS10Component::dump_config() {
bool AGS10Component::new_i2c_address(uint8_t newaddress) {
uint8_t rev_newaddress = ~newaddress;
std::array<uint8_t, 5> data{newaddress, rev_newaddress, newaddress, rev_newaddress, 0};
data[4] = calc_crc8_(data, 4);
data[4] = crc8(data.data(), 4, 0xFF, 0x31, true);
if (!this->write_bytes(REG_ADDRESS, data)) {
this->error_code_ = COMMUNICATION_FAILED;
this->status_set_warning();
@@ -109,7 +109,7 @@ bool AGS10Component::set_zero_point_with_current_resistance() { return this->set
bool AGS10Component::set_zero_point_with(uint16_t value) {
std::array<uint8_t, 5> data{0x00, 0x0C, (uint8_t) ((value >> 8) & 0xFF), (uint8_t) (value & 0xFF), 0};
data[4] = calc_crc8_(data, 4);
data[4] = crc8(data.data(), 4, 0xFF, 0x31, true);
if (!this->write_bytes(REG_CALIBRATION, data)) {
this->error_code_ = COMMUNICATION_FAILED;
this->status_set_warning();
@@ -184,7 +184,7 @@ template<size_t N> optional<std::array<uint8_t, N>> AGS10Component::read_and_che
auto res = *data;
auto crc_byte = res[len];
if (crc_byte != calc_crc8_(res, len)) {
if (crc_byte != crc8(res.data(), len, 0xFF, 0x31, true)) {
this->error_code_ = CRC_CHECK_FAILED;
ESP_LOGE(TAG, "Reading AGS10 version failed: crc error!");
return optional<std::array<uint8_t, N>>();
@@ -192,20 +192,5 @@ template<size_t N> optional<std::array<uint8_t, N>> AGS10Component::read_and_che
return data;
}
template<size_t N> uint8_t AGS10Component::calc_crc8_(std::array<uint8_t, N> dat, uint8_t num) {
uint8_t i, byte1, crc = 0xFF;
for (byte1 = 0; byte1 < num; byte1++) {
crc ^= (dat[byte1]);
for (i = 0; i < 8; i++) {
if (crc & 0x80) {
crc = (crc << 1) ^ 0x31;
} else {
crc = (crc << 1);
}
}
}
return crc;
}
} // namespace ags10
} // namespace esphome

View File

@@ -1,9 +1,9 @@
#pragma once
#include "esphome/components/i2c/i2c.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/core/automation.h"
#include "esphome/core/component.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/i2c/i2c.h"
namespace esphome {
namespace ags10 {
@@ -99,16 +99,6 @@ class AGS10Component : public PollingComponent, public i2c::I2CDevice {
* Read, checks and returns data from the sensor.
*/
template<size_t N> optional<std::array<uint8_t, N>> read_and_check_(uint8_t a_register);
/**
* Calculates CRC8 value.
*
* CRC8 calculation, initial value: 0xFF, polynomial: 0x31 (x8+ x5+ x4+1)
*
* @param[in] dat the data buffer
* @param num number of bytes in the buffer
*/
template<size_t N> uint8_t calc_crc8_(std::array<uint8_t, N> dat, uint8_t num);
};
template<typename... Ts> class AGS10NewI2cAddressAction : public Action<Ts...>, public Parented<AGS10Component> {

View File

@@ -96,7 +96,7 @@ void AHT10Component::read_data_() {
ESP_LOGD(TAG, "Read attempt %d at %ums", this->read_count_, (unsigned) (millis() - this->start_time_));
}
if (this->read(data, 6) != i2c::ERROR_OK) {
this->status_set_warning("Read failed, will retry");
this->status_set_warning(LOG_STR("Read failed, will retry"));
this->restart_read_();
return;
}
@@ -113,7 +113,7 @@ void AHT10Component::read_data_() {
} else {
ESP_LOGD(TAG, "Invalid humidity, retrying");
if (this->write(AHT10_MEASURE_CMD, sizeof(AHT10_MEASURE_CMD)) != i2c::ERROR_OK) {
this->status_set_warning(ESP_LOG_MSG_COMM_FAIL);
this->status_set_warning(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
}
this->restart_read_();
return;
@@ -144,7 +144,7 @@ void AHT10Component::update() {
return;
this->start_time_ = millis();
if (this->write(AHT10_MEASURE_CMD, sizeof(AHT10_MEASURE_CMD)) != i2c::ERROR_OK) {
this->status_set_warning(ESP_LOG_MSG_COMM_FAIL);
this->status_set_warning(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
return;
}
this->restart_read_();

View File

@@ -18,6 +18,6 @@ CONFIG_SCHEMA = cv.Schema(
).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
def to_code(config):
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
yield esp32_ble_tracker.register_ble_device(var, config)
await esp32_ble_tracker.register_ble_device(var, config)

View File

@@ -13,7 +13,7 @@ from esphome.const import (
CONF_TRIGGER_ID,
CONF_WEB_SERVER,
)
from esphome.core import CORE, coroutine_with_priority
from esphome.core import CORE, CoroPriority, coroutine_with_priority
from esphome.core.entity_helpers import entity_duplicate_validator, setup_entity
from esphome.cpp_generator import MockObjClass
@@ -301,8 +301,7 @@ async def alarm_action_disarm_to_code(config, action_id, template_arg, args):
)
async def alarm_action_pending_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
return var
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
@@ -310,8 +309,7 @@ async def alarm_action_pending_to_code(config, action_id, template_arg, args):
)
async def alarm_action_trigger_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
return var
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
@@ -319,8 +317,7 @@ async def alarm_action_trigger_to_code(config, action_id, template_arg, args):
)
async def alarm_action_chime_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
return var
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
@@ -333,8 +330,7 @@ async def alarm_action_chime_to_code(config, action_id, template_arg, args):
)
async def alarm_action_ready_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
return var
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_condition(
@@ -349,7 +345,6 @@ async def alarm_control_panel_is_armed_to_code(
return cg.new_Pvariable(condition_id, template_arg, paren)
@coroutine_with_priority(100.0)
@coroutine_with_priority(CoroPriority.CORE)
async def to_code(config):
cg.add_global(alarm_control_panel_ns.using)
cg.add_define("USE_ALARM_CONTROL_PANEL")

View File

@@ -29,22 +29,6 @@ namespace am2315c {
static const char *const TAG = "am2315c";
uint8_t AM2315C::crc8_(uint8_t *data, uint8_t len) {
uint8_t crc = 0xFF;
while (len--) {
crc ^= *data++;
for (uint8_t i = 0; i < 8; i++) {
if (crc & 0x80) {
crc <<= 1;
crc ^= 0x31;
} else {
crc <<= 1;
}
}
}
return crc;
}
bool AM2315C::reset_register_(uint8_t reg) {
// code based on demo code sent by www.aosong.com
// no further documentation.
@@ -86,7 +70,7 @@ bool AM2315C::convert_(uint8_t *data, float &humidity, float &temperature) {
humidity = raw * 9.5367431640625e-5;
raw = ((data[3] & 0x0F) << 16) | (data[4] << 8) | data[5];
temperature = raw * 1.9073486328125e-4 - 50;
return this->crc8_(data, 6) == data[6];
return crc8(data, 6, 0xFF, 0x31, true) == data[6];
}
void AM2315C::setup() {

View File

@@ -21,9 +21,9 @@
// SOFTWARE.
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/i2c/i2c.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/core/component.h"
namespace esphome {
namespace am2315c {
@@ -39,7 +39,6 @@ class AM2315C : public PollingComponent, public i2c::I2CDevice {
void set_humidity_sensor(sensor::Sensor *humidity_sensor) { this->humidity_sensor_ = humidity_sensor; }
protected:
uint8_t crc8_(uint8_t *data, uint8_t len);
bool convert_(uint8_t *data, float &humidity, float &temperature);
bool reset_register_(uint8_t reg);

View File

@@ -34,17 +34,20 @@ SetFrameAction = animation_ns.class_(
"AnimationSetFrameAction", automation.Action, cg.Parented.template(Animation_)
)
CONFIG_SCHEMA = espImage.IMAGE_SCHEMA.extend(
{
cv.Required(CONF_ID): cv.declare_id(Animation_),
cv.Optional(CONF_LOOP): cv.All(
{
cv.Optional(CONF_START_FRAME, default=0): cv.positive_int,
cv.Optional(CONF_END_FRAME): cv.positive_int,
cv.Optional(CONF_REPEAT): cv.positive_int,
}
),
},
CONFIG_SCHEMA = cv.All(
espImage.IMAGE_SCHEMA.extend(
{
cv.Required(CONF_ID): cv.declare_id(Animation_),
cv.Optional(CONF_LOOP): cv.All(
{
cv.Optional(CONF_START_FRAME, default=0): cv.positive_int,
cv.Optional(CONF_END_FRAME): cv.positive_int,
cv.Optional(CONF_REPEAT): cv.positive_int,
}
),
},
),
espImage.validate_settings,
)

View File

@@ -1,4 +1,5 @@
import base64
import logging
from esphome import automation
from esphome.automation import Condition
@@ -24,12 +25,15 @@ from esphome.const import (
CONF_TRIGGER_ID,
CONF_VARIABLES,
)
from esphome.core import CORE, coroutine_with_priority
from esphome.core import CORE, CoroPriority, coroutine_with_priority
from esphome.types import ConfigType
_LOGGER = logging.getLogger(__name__)
DOMAIN = "api"
DEPENDENCIES = ["network"]
AUTO_LOAD = ["socket"]
CODEOWNERS = ["@OttoWinter"]
CODEOWNERS = ["@esphome/core"]
api_ns = cg.esphome_ns.namespace("api")
APIServer = api_ns.class_("APIServer", cg.Component, cg.Controller)
@@ -55,6 +59,9 @@ CONF_BATCH_DELAY = "batch_delay"
CONF_CUSTOM_SERVICES = "custom_services"
CONF_HOMEASSISTANT_SERVICES = "homeassistant_services"
CONF_HOMEASSISTANT_STATES = "homeassistant_states"
CONF_LISTEN_BACKLOG = "listen_backlog"
CONF_MAX_CONNECTIONS = "max_connections"
CONF_MAX_SEND_QUEUE = "max_send_queue"
def validate_encryption_key(value):
@@ -101,6 +108,32 @@ 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
CONFIG_SCHEMA = cv.All(
cv.Schema(
{
@@ -122,21 +155,56 @@ CONFIG_SCHEMA = cv.All(
cv.Optional(CONF_CUSTOM_SERVICES, default=False): cv.boolean,
cv.Optional(CONF_HOMEASSISTANT_SERVICES, default=False): cv.boolean,
cv.Optional(CONF_HOMEASSISTANT_STATES, default=False): cv.boolean,
cv.Optional(CONF_HOMEASSISTANT_SERVICES, default=False): cv.boolean,
cv.Optional(CONF_HOMEASSISTANT_STATES, default=False): cv.boolean,
cv.Optional(CONF_ON_CLIENT_CONNECTED): automation.validate_automation(
single=True
),
cv.Optional(CONF_ON_CLIENT_DISCONNECTED): automation.validate_automation(
single=True
),
# Connection limits to prevent memory exhaustion on resource-constrained devices
# Each connection uses ~500-1000 bytes of RAM plus system resources
# Platform defaults based on available RAM and network stack implementation:
cv.SplitDefault(
CONF_LISTEN_BACKLOG,
esp8266=1, # Limited RAM (~40KB free), LWIP raw sockets
esp32=4, # More RAM (520KB), BSD sockets
rp2040=1, # Limited RAM (264KB), LWIP raw sockets like ESP8266
bk72xx=4, # Moderate RAM, BSD-style sockets
rtl87xx=4, # Moderate RAM, BSD-style sockets
host=4, # Abundant resources
ln882x=4, # Moderate RAM
): cv.int_range(min=1, max=10),
cv.SplitDefault(
CONF_MAX_CONNECTIONS,
esp8266=4, # ~40KB free RAM, each connection uses ~500-1000 bytes
esp32=8, # 520KB RAM available
rp2040=4, # 264KB RAM but LWIP constraints
bk72xx=8, # Moderate RAM
rtl87xx=8, # Moderate RAM
host=8, # Abundant resources
ln882x=8, # Moderate RAM
): cv.int_range(min=1, max=20),
# Maximum queued send buffers per connection before dropping connection
# Each buffer uses ~8-12 bytes overhead plus actual message size
# Platform defaults based on available RAM and typical message rates:
cv.SplitDefault(
CONF_MAX_SEND_QUEUE,
esp8266=5, # Limited RAM, need to fail fast
esp32=8, # More RAM, can buffer more
rp2040=5, # Limited RAM
bk72xx=8, # Moderate RAM
rtl87xx=8, # Moderate RAM
host=16, # Abundant resources
ln882x=8, # Moderate RAM
): cv.int_range(min=1, max=64),
}
).extend(cv.COMPONENT_SCHEMA),
cv.rename_key(CONF_SERVICES, CONF_ACTIONS),
_validate_api_config,
)
@coroutine_with_priority(40.0)
@coroutine_with_priority(CoroPriority.WEB)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
@@ -147,6 +215,11 @@ async def to_code(config):
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:
cg.add(var.set_listen_backlog(config[CONF_LISTEN_BACKLOG]))
if CONF_MAX_CONNECTIONS in 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
if config.get(CONF_ACTIONS) or config[CONF_CUSTOM_SERVICES]:
@@ -195,6 +268,7 @@ async def to_code(config):
if key := encryption_config.get(CONF_KEY):
decoded = base64.b64decode(key)
cg.add(var.set_noise_psk(list(decoded)))
cg.add_define("USE_API_NOISE_PSK_FROM_YAML")
else:
# No key provided, but encryption desired
# This will allow a plaintext client to provide a noise key,
@@ -323,6 +397,7 @@ HOMEASSISTANT_TAG_SCANNED_ACTION_SCHEMA = cv.maybe_simple_value(
HOMEASSISTANT_TAG_SCANNED_ACTION_SCHEMA,
)
async def homeassistant_tag_scanned_to_code(config, action_id, template_arg, args):
cg.add_define("USE_API_HOMEASSISTANT_SERVICES")
serv = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, serv, True)
cg.add(var.set_service("esphome.tag_scanned"))

View File

@@ -7,7 +7,7 @@ service APIConnection {
option (needs_setup_connection) = false;
option (needs_authentication) = false;
}
rpc connect (ConnectRequest) returns (ConnectResponse) {
rpc authenticate (AuthenticationRequest) returns (AuthenticationResponse) {
option (needs_setup_connection) = false;
option (needs_authentication) = false;
}
@@ -27,9 +27,6 @@ service APIConnection {
rpc subscribe_logs (SubscribeLogsRequest) returns (void) {}
rpc subscribe_homeassistant_services (SubscribeHomeassistantServicesRequest) returns (void) {}
rpc subscribe_home_assistant_states (SubscribeHomeAssistantStatesRequest) returns (void) {}
rpc get_time (GetTimeRequest) returns (GetTimeResponse) {
option (needs_authentication) = false;
}
rpc execute_service (ExecuteServiceRequest) returns (void) {}
rpc noise_encryption_set_key (NoiseEncryptionSetKeyRequest) returns (NoiseEncryptionSetKeyResponse) {}
@@ -69,6 +66,9 @@ service APIConnection {
rpc voice_assistant_set_configuration(VoiceAssistantSetConfiguration) returns (void) {}
rpc alarm_control_panel_command (AlarmControlPanelCommandRequest) returns (void) {}
rpc zwave_proxy_frame(ZWaveProxyFrame) returns (void) {}
rpc zwave_proxy_request(ZWaveProxyRequest) returns (void) {}
}
@@ -102,7 +102,7 @@ message HelloRequest {
// For example "Home Assistant"
// Not strictly necessary to send but nice for debugging
// purposes.
string client_info = 1;
string client_info = 1 [(pointer_to_buffer) = true];
uint32 api_version_major = 2;
uint32 api_version_minor = 3;
}
@@ -132,21 +132,23 @@ message HelloResponse {
// 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
message ConnectRequest {
message AuthenticationRequest {
option (id) = 3;
option (source) = SOURCE_CLIENT;
option (no_delay) = true;
option (ifdef) = "USE_API_PASSWORD";
// The password to log in with
string password = 1;
string password = 1 [(pointer_to_buffer) = true];
}
// 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 ConnectResponse {
message AuthenticationResponse {
option (id) = 4;
option (source) = SOURCE_SERVER;
option (no_delay) = true;
option (ifdef) = "USE_API_PASSWORD";
bool invalid_password = 1;
}
@@ -250,11 +252,15 @@ message DeviceInfoResponse {
// Supports receiving and saving api encryption key
bool api_encryption_supported = 19 [(field_ifdef) = "USE_API_NOISE"];
repeated DeviceInfo devices = 20 [(field_ifdef) = "USE_DEVICES"];
repeated AreaInfo areas = 21 [(field_ifdef) = "USE_AREAS"];
repeated DeviceInfo devices = 20 [(field_ifdef) = "USE_DEVICES", (fixed_array_size_define) = "ESPHOME_DEVICE_COUNT"];
repeated AreaInfo areas = 21 [(field_ifdef) = "USE_AREAS", (fixed_array_size_define) = "ESPHOME_AREA_COUNT"];
// Top-level area info to phase out suggested_area
AreaInfo area = 22 [(field_ifdef) = "USE_AREAS"];
// Indicates if Z-Wave proxy support is available and features supported
uint32 zwave_proxy_feature_flags = 23 [(field_ifdef) = "USE_ZWAVE_PROXY"];
uint32 zwave_home_id = 24 [(field_ifdef) = "USE_ZWAVE_PROXY"];
}
message ListEntitiesRequest {
@@ -763,7 +769,7 @@ message HomeassistantServiceMap {
string value = 2 [(no_zero_copy) = true];
}
message HomeassistantServiceResponse {
message HomeassistantActionRequest {
option (id) = 35;
option (source) = SOURCE_SERVER;
option (no_delay) = true;
@@ -809,15 +815,16 @@ message HomeAssistantStateResponse {
// ==================== IMPORT TIME ====================
message GetTimeRequest {
option (id) = 36;
option (source) = SOURCE_BOTH;
option (source) = SOURCE_SERVER;
}
message GetTimeResponse {
option (id) = 37;
option (source) = SOURCE_BOTH;
option (source) = SOURCE_CLIENT;
option (no_delay) = true;
fixed32 epoch_seconds = 1;
string timezone = 2 [(pointer_to_buffer) = true];
}
// ==================== USER-DEFINES SERVICES ====================
@@ -1297,6 +1304,9 @@ enum MediaPlayerState {
MEDIA_PLAYER_STATE_IDLE = 1;
MEDIA_PLAYER_STATE_PLAYING = 2;
MEDIA_PLAYER_STATE_PAUSED = 3;
MEDIA_PLAYER_STATE_ANNOUNCING = 4;
MEDIA_PLAYER_STATE_OFF = 5;
MEDIA_PLAYER_STATE_ON = 6;
}
enum MediaPlayerCommand {
MEDIA_PLAYER_COMMAND_PLAY = 0;
@@ -1304,6 +1314,15 @@ enum MediaPlayerCommand {
MEDIA_PLAYER_COMMAND_STOP = 2;
MEDIA_PLAYER_COMMAND_MUTE = 3;
MEDIA_PLAYER_COMMAND_UNMUTE = 4;
MEDIA_PLAYER_COMMAND_TOGGLE = 5;
MEDIA_PLAYER_COMMAND_VOLUME_UP = 6;
MEDIA_PLAYER_COMMAND_VOLUME_DOWN = 7;
MEDIA_PLAYER_COMMAND_ENQUEUE = 8;
MEDIA_PLAYER_COMMAND_REPEAT_ONE = 9;
MEDIA_PLAYER_COMMAND_REPEAT_OFF = 10;
MEDIA_PLAYER_COMMAND_CLEAR_PLAYLIST = 11;
MEDIA_PLAYER_COMMAND_TURN_ON = 12;
MEDIA_PLAYER_COMMAND_TURN_OFF = 13;
}
enum MediaPlayerFormatPurpose {
MEDIA_PLAYER_FORMAT_PURPOSE_DEFAULT = 0;
@@ -1338,6 +1357,8 @@ message ListEntitiesMediaPlayerResponse {
repeated MediaPlayerSupportedFormat supported_formats = 9;
uint32 device_id = 10 [(field_ifdef) = "USE_DEVICES"];
uint32 feature_flags = 11;
}
message MediaPlayerStateResponse {
option (id) = 64;
@@ -1424,11 +1445,11 @@ message BluetoothLERawAdvertisementsResponse {
option (ifdef) = "USE_BLUETOOTH_PROXY";
option (no_delay) = true;
repeated BluetoothLERawAdvertisement advertisements = 1;
repeated BluetoothLERawAdvertisement advertisements = 1 [(fixed_array_with_length_define) = "BLUETOOTH_PROXY_ADVERTISEMENT_BATCH_SIZE"];
}
enum BluetoothDeviceRequestType {
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT = 0;
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT = 0 [deprecated = true]; // V1 removed, use V3 variants
BLUETOOTH_DEVICE_REQUEST_TYPE_DISCONNECT = 1;
BLUETOOTH_DEVICE_REQUEST_TYPE_PAIR = 2;
BLUETOOTH_DEVICE_REQUEST_TYPE_UNPAIR = 3;
@@ -1444,7 +1465,7 @@ message BluetoothDeviceRequest {
uint64 address = 1;
BluetoothDeviceRequestType request_type = 2;
bool has_address_type = 3;
bool has_address_type = 3; // Deprecated, should be removed in 2027.8 - https://github.com/esphome/esphome/pull/10318
uint32 address_type = 4;
}
@@ -1468,21 +1489,39 @@ message BluetoothGATTGetServicesRequest {
}
message BluetoothGATTDescriptor {
repeated uint64 uuid = 1 [(fixed_array_size) = 2];
repeated uint64 uuid = 1 [(fixed_array_size) = 2, (fixed_array_skip_zero) = true];
uint32 handle = 2;
// New field for efficient UUID (v1.12+)
// Only one of uuid or short_uuid will be set.
// short_uuid is used for both 16-bit and 32-bit UUIDs with v1.12+ clients.
// 128-bit UUIDs always use the uuid field for backwards compatibility.
uint32 short_uuid = 3; // 16-bit or 32-bit UUID
}
message BluetoothGATTCharacteristic {
repeated uint64 uuid = 1 [(fixed_array_size) = 2];
repeated uint64 uuid = 1 [(fixed_array_size) = 2, (fixed_array_skip_zero) = true];
uint32 handle = 2;
uint32 properties = 3;
repeated BluetoothGATTDescriptor descriptors = 4;
// New field for efficient UUID (v1.12+)
// Only one of uuid or short_uuid will be set.
// short_uuid is used for both 16-bit and 32-bit UUIDs with v1.12+ clients.
// 128-bit UUIDs always use the uuid field for backwards compatibility.
uint32 short_uuid = 5; // 16-bit or 32-bit UUID
}
message BluetoothGATTService {
repeated uint64 uuid = 1 [(fixed_array_size) = 2];
repeated uint64 uuid = 1 [(fixed_array_size) = 2, (fixed_array_skip_zero) = true];
uint32 handle = 2;
repeated BluetoothGATTCharacteristic characteristics = 3;
// New field for efficient UUID (v1.12+)
// Only one of uuid or short_uuid will be set.
// short_uuid is used for both 16-bit and 32-bit UUIDs with v1.12+ clients.
// 128-bit UUIDs always use the uuid field for backwards compatibility.
uint32 short_uuid = 4; // 16-bit or 32-bit UUID
}
message BluetoothGATTGetServicesResponse {
@@ -1491,7 +1530,7 @@ message BluetoothGATTGetServicesResponse {
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
repeated BluetoothGATTService services = 2 [(fixed_array_size) = 1];
repeated BluetoothGATTService services = 2;
}
message BluetoothGATTGetServicesDoneResponse {
@@ -1532,7 +1571,7 @@ message BluetoothGATTWriteRequest {
uint32 handle = 2;
bool response = 3;
bytes data = 4;
bytes data = 4 [(pointer_to_buffer) = true];
}
message BluetoothGATTReadDescriptorRequest {
@@ -1552,7 +1591,7 @@ message BluetoothGATTWriteDescriptorRequest {
uint64 address = 1;
uint32 handle = 2;
bytes data = 3;
bytes data = 3 [(pointer_to_buffer) = true];
}
message BluetoothGATTNotifyRequest {
@@ -1589,7 +1628,10 @@ message BluetoothConnectionsFreeResponse {
uint32 free = 1;
uint32 limit = 2;
repeated uint64 allocated = 3;
repeated uint64 allocated = 3 [
(fixed_array_size_define) = "BLUETOOTH_PROXY_MAX_CONNECTIONS",
(fixed_array_skip_zero) = true
];
}
message BluetoothGATTErrorResponse {
@@ -1677,6 +1719,7 @@ message BluetoothScannerStateResponse {
BluetoothScannerState state = 1;
BluetoothScannerMode mode = 2;
BluetoothScannerMode configured_mode = 3;
}
message BluetoothScannerSetModeRequest {
@@ -1822,10 +1865,22 @@ message VoiceAssistantWakeWord {
repeated string trained_languages = 3;
}
message VoiceAssistantExternalWakeWord {
string id = 1;
string wake_word = 2;
repeated string trained_languages = 3;
string model_type = 4;
uint32 model_size = 5;
string model_hash = 6;
string url = 7;
}
message VoiceAssistantConfigurationRequest {
option (id) = 121;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_VOICE_ASSISTANT";
repeated VoiceAssistantExternalWakeWord external_wake_words = 1;
}
message VoiceAssistantConfigurationResponse {
@@ -2240,3 +2295,28 @@ message UpdateCommandRequest {
UpdateCommand command = 2;
uint32 device_id = 3 [(field_ifdef) = "USE_DEVICES"];
}
// ==================== Z-WAVE ====================
message ZWaveProxyFrame {
option (id) = 128;
option (source) = SOURCE_BOTH;
option (ifdef) = "USE_ZWAVE_PROXY";
option (no_delay) = true;
bytes data = 1 [(pointer_to_buffer) = true];
}
enum ZWaveProxyRequestType {
ZWAVE_PROXY_REQUEST_TYPE_SUBSCRIBE = 0;
ZWAVE_PROXY_REQUEST_TYPE_UNSUBSCRIBE = 1;
ZWAVE_PROXY_REQUEST_TYPE_HOME_ID_CHANGE = 2;
}
message ZWaveProxyRequest {
option (id) = 129;
option (source) = SOURCE_BOTH;
option (ifdef) = "USE_ZWAVE_PROXY";
ZWaveProxyRequestType type = 1;
bytes data = 2 [(pointer_to_buffer) = true];
}

View File

@@ -30,6 +30,9 @@
#ifdef USE_VOICE_ASSISTANT
#include "esphome/components/voice_assistant/voice_assistant.h"
#endif
#ifdef USE_ZWAVE_PROXY
#include "esphome/components/zwave_proxy/zwave_proxy.h"
#endif
namespace esphome::api {
@@ -42,6 +45,8 @@ static constexpr uint8_t MAX_PING_RETRIES = 60;
static constexpr uint16_t PING_RETRY_INTERVAL = 1000;
static constexpr uint32_t KEEPALIVE_DISCONNECT_TIMEOUT = (KEEPALIVE_TIMEOUT_MS * 5) / 2;
static constexpr auto ESPHOME_VERSION_REF = StringRef::from_lit(ESPHOME_VERSION);
static const char *const TAG = "api.connection";
#ifdef USE_CAMERA
static const int CAMERA_STOP_STREAM = 5000;
@@ -112,8 +117,7 @@ void APIConnection::start() {
APIError err = this->helper_->init();
if (err != APIError::OK) {
on_fatal_error();
ESP_LOGW(TAG, "%s: Helper init failed %s errno=%d", this->get_client_combined_info().c_str(), api_error_to_str(err),
errno);
this->log_warning_(LOG_STR("Helper init failed"), err);
return;
}
this->client_info_.peername = helper_->getpeername();
@@ -144,8 +148,7 @@ void APIConnection::loop() {
APIError err = this->helper_->loop();
if (err != APIError::OK) {
on_fatal_error();
ESP_LOGW(TAG, "%s: Socket operation failed %s errno=%d", this->get_client_combined_info().c_str(),
api_error_to_str(err), errno);
this->log_socket_operation_failed_(err);
return;
}
@@ -161,8 +164,7 @@ void APIConnection::loop() {
break;
} else if (err != APIError::OK) {
on_fatal_error();
ESP_LOGW(TAG, "%s: Reading failed %s errno=%d", this->get_client_combined_info().c_str(), api_error_to_str(err),
errno);
this->log_warning_(LOG_STR("Reading failed"), err);
return;
} else {
this->last_traffic_ = now;
@@ -203,7 +205,8 @@ void APIConnection::loop() {
// Disconnect if not responded within 2.5*keepalive
if (now - this->last_traffic_ > KEEPALIVE_DISCONNECT_TIMEOUT) {
on_fatal_error();
ESP_LOGW(TAG, "%s is unresponsive; disconnecting", this->get_client_combined_info().c_str());
ESP_LOGW(TAG, "%s (%s) is unresponsive; disconnecting", this->client_info_.name.c_str(),
this->client_info_.peername.c_str());
}
} else if (now - this->last_traffic_ > KEEPALIVE_TIMEOUT_MS && !this->flags_.remove) {
// Only send ping if we're not disconnecting
@@ -253,7 +256,7 @@ bool APIConnection::send_disconnect_response(const DisconnectRequest &msg) {
// remote initiated disconnect_client
// don't close yet, we still need to send the disconnect response
// close will happen on next loop
ESP_LOGD(TAG, "%s disconnected", this->get_client_combined_info().c_str());
ESP_LOGD(TAG, "%s (%s) disconnected", this->client_info_.name.c_str(), this->client_info_.peername.c_str());
this->flags_.next_close = true;
DisconnectResponse resp;
return this->send_message(resp, DisconnectResponse::MESSAGE_TYPE);
@@ -292,16 +295,26 @@ uint16_t APIConnection::encode_message_to_buffer(ProtoMessage &msg, uint8_t mess
return 0; // Doesn't fit
}
// Allocate buffer space - pass payload size, allocation functions add header/footer space
ProtoWriteBuffer buffer = is_single ? conn->allocate_single_message_buffer(calculated_size)
: conn->allocate_batch_message_buffer(calculated_size);
// Get buffer size after allocation (which includes header padding)
std::vector<uint8_t> &shared_buf = conn->parent_->get_shared_buffer_ref();
size_t size_before_encode = shared_buf.size();
if (is_single || conn->flags_.batch_first_message) {
// Single message or first batch message
conn->prepare_first_message_buffer(shared_buf, header_padding, total_calculated_size);
if (conn->flags_.batch_first_message) {
conn->flags_.batch_first_message = false;
}
} else {
// Batch message second or later
// Add padding for previous message footer + this message header
size_t current_size = shared_buf.size();
shared_buf.reserve(current_size + total_calculated_size);
shared_buf.resize(current_size + footer_size + header_padding);
}
// Encode directly into buffer
msg.encode(buffer);
size_t size_before_encode = shared_buf.size();
msg.encode({&shared_buf});
// Calculate actual encoded size (not including header that was already added)
size_t actual_payload_size = shared_buf.size() - size_before_encode;
@@ -413,7 +426,7 @@ uint16_t APIConnection::try_send_fan_info(EntityBase *entity, APIConnection *con
msg.supports_speed = traits.supports_speed();
msg.supports_direction = traits.supports_direction();
msg.supported_speed_count = traits.supported_speed_count();
msg.supported_preset_modes = &traits.supported_preset_modes();
msg.supported_preset_modes = &traits.supported_preset_modes_for_api_();
return fill_and_encode_entity_info(fan, msg, ListEntitiesFanResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
}
void APIConnection::fan_command(const FanCommandRequest &msg) {
@@ -458,9 +471,7 @@ uint16_t APIConnection::try_send_light_state(EntityBase *entity, APIConnection *
resp.cold_white = values.get_cold_white();
resp.warm_white = values.get_warm_white();
if (light->supports_effects()) {
// get_effect_name() returns temporary std::string - must store it
std::string effect_name = light->get_effect_name();
resp.set_effect(StringRef(effect_name));
resp.set_effect(light->get_effect_name_ref());
}
return fill_and_encode_entity_state(light, resp, LightStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
}
@@ -469,7 +480,7 @@ uint16_t APIConnection::try_send_light_info(EntityBase *entity, APIConnection *c
auto *light = static_cast<light::LightState *>(entity);
ListEntitiesLightResponse msg;
auto traits = light->get_traits();
msg.supported_color_modes = &traits.get_supported_color_modes();
msg.supported_color_modes = &traits.get_supported_color_modes_for_api_();
if (traits.supports_color_capability(light::ColorCapability::COLOR_TEMPERATURE) ||
traits.supports_color_capability(light::ColorCapability::COLD_WARM_WHITE)) {
msg.min_mireds = traits.get_min_mireds();
@@ -655,7 +666,7 @@ uint16_t APIConnection::try_send_climate_info(EntityBase *entity, APIConnection
msg.supports_current_humidity = traits.get_supports_current_humidity();
msg.supports_two_point_target_temperature = traits.get_supports_two_point_target_temperature();
msg.supports_target_humidity = traits.get_supports_target_humidity();
msg.supported_modes = &traits.get_supported_modes();
msg.supported_modes = &traits.get_supported_modes_for_api_();
msg.visual_min_temperature = traits.get_visual_min_temperature();
msg.visual_max_temperature = traits.get_visual_max_temperature();
msg.visual_target_temperature_step = traits.get_visual_target_temperature_step();
@@ -663,11 +674,11 @@ uint16_t APIConnection::try_send_climate_info(EntityBase *entity, APIConnection
msg.visual_min_humidity = traits.get_visual_min_humidity();
msg.visual_max_humidity = traits.get_visual_max_humidity();
msg.supports_action = traits.get_supports_action();
msg.supported_fan_modes = &traits.get_supported_fan_modes();
msg.supported_custom_fan_modes = &traits.get_supported_custom_fan_modes();
msg.supported_presets = &traits.get_supported_presets();
msg.supported_custom_presets = &traits.get_supported_custom_presets();
msg.supported_swing_modes = &traits.get_supported_swing_modes();
msg.supported_fan_modes = &traits.get_supported_fan_modes_for_api_();
msg.supported_custom_fan_modes = &traits.get_supported_custom_fan_modes_for_api_();
msg.supported_presets = &traits.get_supported_presets_for_api_();
msg.supported_custom_presets = &traits.get_supported_custom_presets_for_api_();
msg.supported_swing_modes = &traits.get_supported_swing_modes_for_api_();
return fill_and_encode_entity_info(climate, msg, ListEntitiesClimateResponse::MESSAGE_TYPE, conn, remaining_size,
is_single);
}
@@ -999,6 +1010,7 @@ uint16_t APIConnection::try_send_media_player_info(EntityBase *entity, APIConnec
ListEntitiesMediaPlayerResponse msg;
auto traits = media_player->get_traits();
msg.supports_pause = traits.get_supports_pause();
msg.feature_flags = traits.get_feature_flags();
for (auto &supported_format : traits.get_supported_formats()) {
msg.supported_formats.emplace_back();
auto &media_format = msg.supported_formats.back();
@@ -1064,17 +1076,23 @@ void APIConnection::camera_image(const CameraImageRequest &msg) {
#ifdef USE_HOMEASSISTANT_TIME
void APIConnection::on_get_time_response(const GetTimeResponse &value) {
if (homeassistant::global_homeassistant_time != nullptr)
if (homeassistant::global_homeassistant_time != nullptr) {
homeassistant::global_homeassistant_time->set_epoch_time(value.epoch_seconds);
#ifdef USE_TIME_TIMEZONE
if (value.timezone_len > 0) {
const std::string &current_tz = homeassistant::global_homeassistant_time->get_timezone();
// Compare without allocating a string
if (current_tz.length() != value.timezone_len ||
memcmp(current_tz.c_str(), value.timezone, value.timezone_len) != 0) {
homeassistant::global_homeassistant_time->set_timezone(
std::string(reinterpret_cast<const char *>(value.timezone), value.timezone_len));
}
}
#endif
}
}
#endif
bool APIConnection::send_get_time_response(const GetTimeRequest &msg) {
GetTimeResponse resp;
resp.epoch_seconds = ::time(nullptr);
return this->send_message(resp, GetTimeResponse::MESSAGE_TYPE);
}
#ifdef USE_BLUETOOTH_PROXY
void APIConnection::subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) {
bluetooth_proxy::global_bluetooth_proxy->subscribe_api_connection(this, msg.flags);
@@ -1107,10 +1125,8 @@ void APIConnection::bluetooth_gatt_notify(const BluetoothGATTNotifyRequest &msg)
bool APIConnection::send_subscribe_bluetooth_connections_free_response(
const SubscribeBluetoothConnectionsFreeRequest &msg) {
BluetoothConnectionsFreeResponse resp;
resp.free = bluetooth_proxy::global_bluetooth_proxy->get_bluetooth_connections_free();
resp.limit = bluetooth_proxy::global_bluetooth_proxy->get_bluetooth_connections_limit();
return this->send_message(resp, BluetoothConnectionsFreeResponse::MESSAGE_TYPE);
bluetooth_proxy::global_bluetooth_proxy->send_connections_free(this);
return true;
}
void APIConnection::bluetooth_scanner_set_mode(const BluetoothScannerSetModeRequest &msg) {
@@ -1187,6 +1203,23 @@ bool APIConnection::send_voice_assistant_get_configuration_response(const VoiceA
resp_wake_word.trained_languages.push_back(lang);
}
}
// Filter external wake words
for (auto &wake_word : msg.external_wake_words) {
if (wake_word.model_type != "micro") {
// microWakeWord only
continue;
}
resp.available_wake_words.emplace_back();
auto &resp_wake_word = resp.available_wake_words.back();
resp_wake_word.set_id(StringRef(wake_word.id));
resp_wake_word.set_wake_word(StringRef(wake_word.wake_word));
for (const auto &lang : wake_word.trained_languages) {
resp_wake_word.trained_languages.push_back(lang);
}
}
resp.active_wake_words = &config.active_wake_words;
resp.max_active_wake_words = config.max_active_wake_words;
return this->send_message(resp, VoiceAssistantConfigurationResponse::MESSAGE_TYPE);
@@ -1197,7 +1230,16 @@ void APIConnection::voice_assistant_set_configuration(const VoiceAssistantSetCon
voice_assistant::global_voice_assistant->on_set_configuration(msg.active_wake_words);
}
}
#endif
#ifdef USE_ZWAVE_PROXY
void APIConnection::zwave_proxy_frame(const ZWaveProxyFrame &msg) {
zwave_proxy::global_zwave_proxy->send_frame(msg.data, msg.data_len);
}
void APIConnection::zwave_proxy_request(const ZWaveProxyRequest &msg) {
zwave_proxy::global_zwave_proxy->zwave_proxy_request(this, msg.type);
}
#endif
#ifdef USE_ALARM_CONTROL_PANEL
@@ -1344,7 +1386,7 @@ void APIConnection::complete_authentication_() {
}
this->flags_.connection_state = static_cast<uint8_t>(ConnectionState::AUTHENTICATED);
ESP_LOGD(TAG, "%s connected", this->get_client_combined_info().c_str());
ESP_LOGD(TAG, "%s (%s) connected", this->client_info_.name.c_str(), this->client_info_.peername.c_str());
#ifdef USE_API_CLIENT_CONNECTED_TRIGGER
this->parent_->get_client_connected_trigger()->trigger(this->client_info_.name, this->client_info_.peername);
#endif
@@ -1356,7 +1398,7 @@ void APIConnection::complete_authentication_() {
}
bool APIConnection::send_hello_response(const HelloRequest &msg) {
this->client_info_.name = msg.client_info;
this->client_info_.name.assign(reinterpret_cast<const char *>(msg.client_info), msg.client_info_len);
this->client_info_.peername = this->helper_->getpeername();
this->client_api_version_major_ = msg.api_version_major;
this->client_api_version_minor_ = msg.api_version_minor;
@@ -1365,10 +1407,9 @@ bool APIConnection::send_hello_response(const HelloRequest &msg) {
HelloResponse resp;
resp.api_version_major = 1;
resp.api_version_minor = 10;
// Temporary string for concatenation - will be valid during send_message call
std::string server_info = App.get_name() + " (esphome v" ESPHOME_VERSION ")";
resp.set_server_info(StringRef(server_info));
resp.api_version_minor = 12;
// Send only the version string - the client only logs this for debugging and doesn't use it otherwise
resp.set_server_info(ESPHOME_VERSION_REF);
resp.set_name(StringRef(App.get_name()));
#ifdef USE_API_PASSWORD
@@ -1381,20 +1422,17 @@ bool APIConnection::send_hello_response(const HelloRequest &msg) {
return this->send_message(resp, HelloResponse::MESSAGE_TYPE);
}
bool APIConnection::send_connect_response(const ConnectRequest &msg) {
bool correct = true;
#ifdef USE_API_PASSWORD
correct = this->parent_->check_password(msg.password);
#endif
ConnectResponse resp;
bool APIConnection::send_authenticate_response(const AuthenticationRequest &msg) {
AuthenticationResponse resp;
// bool invalid_password = 1;
resp.invalid_password = !correct;
if (correct) {
resp.invalid_password = !this->parent_->check_password(msg.password, msg.password_len);
if (!resp.invalid_password) {
this->complete_authentication_();
}
return this->send_message(resp, ConnectResponse::MESSAGE_TYPE);
return this->send_message(resp, AuthenticationResponse::MESSAGE_TYPE);
}
#endif // USE_API_PASSWORD
bool APIConnection::send_ping_response(const PingRequest &msg) {
PingResponse resp;
@@ -1415,13 +1453,9 @@ bool APIConnection::send_device_info_response(const DeviceInfoRequest &msg) {
std::string mac_address = get_mac_address_pretty();
resp.set_mac_address(StringRef(mac_address));
// Compile-time StringRef constants
static constexpr auto ESPHOME_VERSION_REF = StringRef::from_lit(ESPHOME_VERSION);
resp.set_esphome_version(ESPHOME_VERSION_REF);
// get_compilation_time() returns temporary std::string - must store it
std::string compilation_time = App.get_compilation_time();
resp.set_compilation_time(StringRef(compilation_time));
resp.set_compilation_time(App.get_compilation_time_ref());
// Compile-time StringRef constants for manufacturers
#if defined(USE_ESP8266) || defined(USE_ESP32)
@@ -1462,22 +1496,30 @@ bool APIConnection::send_device_info_response(const DeviceInfoRequest &msg) {
#ifdef USE_VOICE_ASSISTANT
resp.voice_assistant_feature_flags = voice_assistant::global_voice_assistant->get_feature_flags();
#endif
#ifdef USE_ZWAVE_PROXY
resp.zwave_proxy_feature_flags = zwave_proxy::global_zwave_proxy->get_feature_flags();
resp.zwave_home_id = zwave_proxy::global_zwave_proxy->get_home_id();
#endif
#ifdef USE_API_NOISE
resp.api_encryption_supported = true;
#endif
#ifdef USE_DEVICES
size_t device_index = 0;
for (auto const &device : App.get_devices()) {
resp.devices.emplace_back();
auto &device_info = resp.devices.back();
if (device_index >= ESPHOME_DEVICE_COUNT)
break;
auto &device_info = resp.devices[device_index++];
device_info.device_id = device->get_device_id();
device_info.set_name(StringRef(device->get_name()));
device_info.area_id = device->get_area_id();
}
#endif
#ifdef USE_AREAS
size_t area_index = 0;
for (auto const &area : App.get_areas()) {
resp.areas.emplace_back();
auto &area_info = resp.areas.back();
if (area_index >= ESPHOME_AREA_COUNT)
break;
auto &area_info = resp.areas[area_index++];
area_info.area_id = area->get_area_id();
area_info.set_name(StringRef(area->get_name()));
}
@@ -1539,8 +1581,7 @@ bool APIConnection::try_to_clear_buffer(bool log_out_of_space) {
APIError err = this->helper_->loop();
if (err != APIError::OK) {
on_fatal_error();
ESP_LOGW(TAG, "%s: Socket operation failed %s errno=%d", this->get_client_combined_info().c_str(),
api_error_to_str(err), errno);
this->log_socket_operation_failed_(err);
return false;
}
if (this->helper_->can_write_without_blocking())
@@ -1560,8 +1601,7 @@ bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) {
return false;
if (err != APIError::OK) {
on_fatal_error();
ESP_LOGW(TAG, "%s: Packet write failed %s errno=%d", this->get_client_combined_info().c_str(),
api_error_to_str(err), errno);
this->log_warning_(LOG_STR("Packet write failed"), err);
return false;
}
// Do not set last_traffic_ on send
@@ -1570,12 +1610,12 @@ bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) {
#ifdef USE_API_PASSWORD
void APIConnection::on_unauthenticated_access() {
this->on_fatal_error();
ESP_LOGD(TAG, "%s access without authentication", this->get_client_combined_info().c_str());
ESP_LOGD(TAG, "%s (%s) no authentication", this->client_info_.name.c_str(), this->client_info_.peername.c_str());
}
#endif
void APIConnection::on_no_setup_connection() {
this->on_fatal_error();
ESP_LOGD(TAG, "%s access without full connection", this->get_client_combined_info().c_str());
ESP_LOGD(TAG, "%s (%s) no connection setup", this->client_info_.name.c_str(), this->client_info_.peername.c_str());
}
void APIConnection::on_fatal_error() {
this->helper_->close();
@@ -1622,14 +1662,6 @@ bool APIConnection::schedule_batch_() {
return true;
}
ProtoWriteBuffer APIConnection::allocate_single_message_buffer(uint16_t size) { return this->create_buffer(size); }
ProtoWriteBuffer APIConnection::allocate_batch_message_buffer(uint16_t size) {
ProtoWriteBuffer result = this->prepare_message_buffer(size, this->flags_.batch_first_message);
this->flags_.batch_first_message = false;
return result;
}
void APIConnection::process_batch_() {
// Ensure PacketInfo remains trivially destructible for our placement new approach
static_assert(std::is_trivially_destructible<PacketInfo>::value,
@@ -1646,6 +1678,8 @@ void APIConnection::process_batch_() {
return;
}
// Get shared buffer reference once to avoid multiple calls
auto &shared_buf = this->parent_->get_shared_buffer_ref();
size_t num_items = this->deferred_batch_.size();
// Fast path for single message - allocate exact size needed
@@ -1656,8 +1690,7 @@ void APIConnection::process_batch_() {
uint16_t payload_size =
item.creator(item.entity, this, std::numeric_limits<uint16_t>::max(), true, item.message_type);
if (payload_size > 0 &&
this->send_buffer(ProtoWriteBuffer{&this->parent_->get_shared_buffer_ref()}, item.message_type)) {
if (payload_size > 0 && this->send_buffer(ProtoWriteBuffer{&shared_buf}, item.message_type)) {
#ifdef HAS_PROTO_MESSAGE_DUMP
// Log messages after send attempt for VV debugging
// It's safe to use the buffer for logging at this point regardless of send result
@@ -1684,20 +1717,18 @@ void APIConnection::process_batch_() {
const uint8_t footer_size = this->helper_->frame_footer_size();
// Initialize buffer and tracking variables
this->parent_->get_shared_buffer_ref().clear();
shared_buf.clear();
// Pre-calculate exact buffer size needed based on message types
uint32_t total_estimated_size = 0;
uint32_t total_estimated_size = num_items * (header_padding + footer_size);
for (size_t i = 0; i < this->deferred_batch_.size(); i++) {
const auto &item = this->deferred_batch_[i];
total_estimated_size += item.estimated_size;
}
// Calculate total overhead for all messages
uint32_t total_overhead = (header_padding + footer_size) * num_items;
// Reserve based on estimated size (much more accurate than 24-byte worst-case)
this->parent_->get_shared_buffer_ref().reserve(total_estimated_size + total_overhead);
shared_buf.reserve(total_estimated_size);
this->flags_.batch_first_message = true;
size_t items_processed = 0;
@@ -1738,8 +1769,8 @@ void APIConnection::process_batch_() {
}
remaining_size -= payload_size;
// Calculate where the next message's header padding will start
// Current buffer size + footer space (that prepare_message_buffer will add for this message)
current_offset = this->parent_->get_shared_buffer_ref().size() + footer_size;
// Current buffer size + footer space for this message
current_offset = shared_buf.size() + footer_size;
}
if (items_processed == 0) {
@@ -1749,17 +1780,15 @@ void APIConnection::process_batch_() {
// Add footer space for the last message (for Noise protocol MAC)
if (footer_size > 0) {
auto &shared_buf = this->parent_->get_shared_buffer_ref();
shared_buf.resize(shared_buf.size() + footer_size);
}
// Send all collected packets
APIError err = this->helper_->write_protobuf_packets(ProtoWriteBuffer{&this->parent_->get_shared_buffer_ref()},
APIError err = this->helper_->write_protobuf_packets(ProtoWriteBuffer{&shared_buf},
std::span<const PacketInfo>(packet_info, packet_count));
if (err != APIError::OK && err != APIError::WOULD_BLOCK) {
on_fatal_error();
ESP_LOGW(TAG, "%s: Batch write failed %s errno=%d", this->get_client_combined_info().c_str(), api_error_to_str(err),
errno);
this->log_warning_(LOG_STR("Batch write failed"), err);
}
#ifdef HAS_PROTO_MESSAGE_DUMP
@@ -1837,5 +1866,14 @@ void APIConnection::process_state_subscriptions_() {
}
#endif // USE_API_HOMEASSISTANT_STATES
void APIConnection::log_warning_(const LogString *message, APIError err) {
ESP_LOGW(TAG, "%s (%s): %s %s errno=%d", this->client_info_.name.c_str(), this->client_info_.peername.c_str(),
LOG_STR_ARG(message), LOG_STR_ARG(api_error_to_logstr(err)), errno);
}
void APIConnection::log_socket_operation_failed_(APIError err) {
this->log_warning_(LOG_STR("Socket operation failed"), err);
}
} // namespace esphome::api
#endif

View File

@@ -10,8 +10,8 @@
#include "esphome/core/component.h"
#include "esphome/core/entity_base.h"
#include <vector>
#include <functional>
#include <vector>
namespace esphome::api {
@@ -19,14 +19,6 @@ namespace esphome::api {
struct ClientInfo {
std::string name; // Client name from Hello message
std::string peername; // IP:port from socket
std::string get_combined_info() const {
if (name == peername) {
// Before Hello message, both are the same
return name;
}
return name + " (" + peername + ")";
}
};
// Keepalive timeout in milliseconds
@@ -44,7 +36,7 @@ static constexpr size_t MAX_PACKETS_PER_BATCH = 64; // ESP32 has 8KB+ stack, HO
static constexpr size_t MAX_PACKETS_PER_BATCH = 32; // ESP8266/RP2040/etc have smaller stacks
#endif
class APIConnection : public APIServerConnection {
class APIConnection final : public APIServerConnection {
public:
friend class APIServer;
friend class ListEntitiesIterator;
@@ -132,10 +124,10 @@ class APIConnection : public APIServerConnection {
#endif
bool try_send_log_message(int level, const char *tag, const char *line, size_t message_len);
#ifdef USE_API_HOMEASSISTANT_SERVICES
void send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
void send_homeassistant_action(const HomeassistantActionRequest &call) {
if (!this->flags_.service_call_subscription)
return;
this->send_message(call, HomeassistantServiceResponse::MESSAGE_TYPE);
this->send_message(call, HomeassistantActionRequest::MESSAGE_TYPE);
}
#endif
#ifdef USE_BLUETOOTH_PROXY
@@ -171,6 +163,11 @@ class APIConnection : public APIServerConnection {
void voice_assistant_set_configuration(const VoiceAssistantSetConfiguration &msg) override;
#endif
#ifdef USE_ZWAVE_PROXY
void zwave_proxy_frame(const ZWaveProxyFrame &msg) override;
void zwave_proxy_request(const ZWaveProxyRequest &msg) override;
#endif
#ifdef USE_ALARM_CONTROL_PANEL
bool send_alarm_control_panel_state(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
void alarm_control_panel_command(const AlarmControlPanelCommandRequest &msg) override;
@@ -197,7 +194,9 @@ class APIConnection : public APIServerConnection {
void on_get_time_response(const GetTimeResponse &value) override;
#endif
bool send_hello_response(const HelloRequest &msg) override;
bool send_connect_response(const ConnectRequest &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;
@@ -219,7 +218,6 @@ class APIConnection : public APIServerConnection {
#ifdef USE_API_HOMEASSISTANT_STATES
void subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) override;
#endif
bool send_get_time_response(const GetTimeRequest &msg) override;
#ifdef USE_API_SERVICES
void execute_service(const ExecuteServiceRequest &msg) override;
#endif
@@ -235,6 +233,13 @@ class APIConnection : public APIServerConnection {
this->is_authenticated();
}
uint8_t get_log_subscription_level() const { return this->flags_.log_subscription; }
// Get client API version for feature detection
bool client_supports_api_version(uint16_t major, uint16_t minor) const {
return this->client_api_version_major_ > major ||
(this->client_api_version_major_ == major && this->client_api_version_minor_ >= minor);
}
void on_fatal_error() override;
#ifdef USE_API_PASSWORD
void on_unauthenticated_access() override;
@@ -245,54 +250,28 @@ class APIConnection : public APIServerConnection {
// Get header padding size - used for both reserve and insert
uint8_t header_padding = this->helper_->frame_header_padding();
// Get shared buffer from parent server
std::vector<uint8_t> &shared_buf = this->parent_->get_shared_buffer_ref();
this->prepare_first_message_buffer(shared_buf, header_padding,
reserve_size + header_padding + this->helper_->frame_footer_size());
return {&shared_buf};
}
void prepare_first_message_buffer(std::vector<uint8_t> &shared_buf, size_t header_padding, size_t total_size) {
shared_buf.clear();
// Reserve space for header padding + message + footer
// - Header padding: space for protocol headers (7 bytes for Noise, 6 for Plaintext)
// - Footer: space for MAC (16 bytes for Noise, 0 for Plaintext)
shared_buf.reserve(reserve_size + header_padding + this->helper_->frame_footer_size());
shared_buf.reserve(total_size);
// Resize to add header padding so message encoding starts at the correct position
shared_buf.resize(header_padding);
return {&shared_buf};
}
// Prepare buffer for next message in batch
ProtoWriteBuffer prepare_message_buffer(uint16_t message_size, bool is_first_message) {
// Get reference to shared buffer (it maintains state between batch messages)
std::vector<uint8_t> &shared_buf = this->parent_->get_shared_buffer_ref();
if (is_first_message) {
shared_buf.clear();
}
size_t current_size = shared_buf.size();
// Calculate padding to add:
// - First message: just header padding
// - Subsequent messages: footer for previous message + header padding for this message
size_t padding_to_add = is_first_message
? this->helper_->frame_header_padding()
: this->helper_->frame_header_padding() + this->helper_->frame_footer_size();
// Reserve space for padding + message
shared_buf.reserve(current_size + padding_to_add + message_size);
// Resize to add the padding bytes
shared_buf.resize(current_size + padding_to_add);
return {&shared_buf};
}
bool try_to_clear_buffer(bool log_out_of_space);
bool send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) override;
std::string get_client_combined_info() const { return this->client_info_.get_combined_info(); }
// Buffer allocator methods for batch processing
ProtoWriteBuffer allocate_single_message_buffer(uint16_t size);
ProtoWriteBuffer allocate_batch_message_buffer(uint16_t size);
const std::string &get_name() const { return this->client_info_.name; }
const std::string &get_peername() const { return this->client_info_.peername; }
protected:
// Helper function to handle authentication completion
@@ -300,7 +279,7 @@ class APIConnection : public APIServerConnection {
#ifdef USE_API_HOMEASSISTANT_STATES
void process_state_subscriptions_();
#endif // USE_API_HOMEASSISTANT_STATES
#endif
// Non-template helper to encode any ProtoMessage
static uint16_t encode_message_to_buffer(ProtoMessage &msg, uint8_t message_type, APIConnection *conn,
@@ -321,9 +300,17 @@ class APIConnection : 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();
// IMPORTANT: get_object_id() may return a temporary std::string
std::string object_id = entity->get_object_id();
msg.set_object_id(StringRef(object_id));
// 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));
}
if (entity->has_own_name()) {
msg.set_name(entity->get_name());
@@ -696,10 +683,16 @@ class APIConnection : public APIServerConnection {
bool send_message_smart_(EntityBase *entity, MessageCreatorPtr creator, uint8_t message_type,
uint8_t estimated_size) {
// Try to send immediately if:
// 1. We should try to send immediately (should_try_send_immediately = true)
// 2. Batch delay is 0 (user has opted in to immediate sending)
// 3. Buffer has space available
if (this->flags_.should_try_send_immediately && this->get_batch_delay_ms_() == 0 &&
// 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()) {
// Now actually encode and send
if (creator(entity, this, MAX_BATCH_PACKET_SIZE, true) &&
@@ -736,6 +729,11 @@ class APIConnection : public APIServerConnection {
this->deferred_batch_.add_item_front(entity, MessageCreator(function_ptr), message_type, estimated_size);
return this->schedule_batch_();
}
// Helper function to log API errors with errno
void log_warning_(const LogString *message, APIError err);
// Specific helper for duplicated error message
void log_socket_operation_failed_(APIError err);
};
} // namespace esphome::api

View File

@@ -13,7 +13,8 @@ namespace esphome::api {
static const char *const TAG = "api.frame_helper";
#define HELPER_LOG(msg, ...) ESP_LOGVV(TAG, "%s: " msg, this->client_info_->get_combined_info().c_str(), ##__VA_ARGS__)
#define HELPER_LOG(msg, ...) \
ESP_LOGVV(TAG, "%s (%s): " msg, this->client_info_->name.c_str(), this->client_info_->peername.c_str(), ##__VA_ARGS__)
#ifdef HELPER_LOG_PACKETS
#define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str())
@@ -23,64 +24,64 @@ static const char *const TAG = "api.frame_helper";
#define LOG_PACKET_SENDING(data, len) ((void) 0)
#endif
const char *api_error_to_str(APIError err) {
const LogString *api_error_to_logstr(APIError err) {
// not using switch to ensure compiler doesn't try to build a big table out of it
if (err == APIError::OK) {
return "OK";
return LOG_STR("OK");
} else if (err == APIError::WOULD_BLOCK) {
return "WOULD_BLOCK";
return LOG_STR("WOULD_BLOCK");
} else if (err == APIError::BAD_INDICATOR) {
return "BAD_INDICATOR";
return LOG_STR("BAD_INDICATOR");
} else if (err == APIError::BAD_DATA_PACKET) {
return "BAD_DATA_PACKET";
return LOG_STR("BAD_DATA_PACKET");
} else if (err == APIError::TCP_NODELAY_FAILED) {
return "TCP_NODELAY_FAILED";
return LOG_STR("TCP_NODELAY_FAILED");
} else if (err == APIError::TCP_NONBLOCKING_FAILED) {
return "TCP_NONBLOCKING_FAILED";
return LOG_STR("TCP_NONBLOCKING_FAILED");
} else if (err == APIError::CLOSE_FAILED) {
return "CLOSE_FAILED";
return LOG_STR("CLOSE_FAILED");
} else if (err == APIError::SHUTDOWN_FAILED) {
return "SHUTDOWN_FAILED";
return LOG_STR("SHUTDOWN_FAILED");
} else if (err == APIError::BAD_STATE) {
return "BAD_STATE";
return LOG_STR("BAD_STATE");
} else if (err == APIError::BAD_ARG) {
return "BAD_ARG";
return LOG_STR("BAD_ARG");
} else if (err == APIError::SOCKET_READ_FAILED) {
return "SOCKET_READ_FAILED";
return LOG_STR("SOCKET_READ_FAILED");
} else if (err == APIError::SOCKET_WRITE_FAILED) {
return "SOCKET_WRITE_FAILED";
return LOG_STR("SOCKET_WRITE_FAILED");
} else if (err == APIError::OUT_OF_MEMORY) {
return "OUT_OF_MEMORY";
return LOG_STR("OUT_OF_MEMORY");
} else if (err == APIError::CONNECTION_CLOSED) {
return "CONNECTION_CLOSED";
return LOG_STR("CONNECTION_CLOSED");
}
#ifdef USE_API_NOISE
else if (err == APIError::BAD_HANDSHAKE_PACKET_LEN) {
return "BAD_HANDSHAKE_PACKET_LEN";
return LOG_STR("BAD_HANDSHAKE_PACKET_LEN");
} else if (err == APIError::HANDSHAKESTATE_READ_FAILED) {
return "HANDSHAKESTATE_READ_FAILED";
return LOG_STR("HANDSHAKESTATE_READ_FAILED");
} else if (err == APIError::HANDSHAKESTATE_WRITE_FAILED) {
return "HANDSHAKESTATE_WRITE_FAILED";
return LOG_STR("HANDSHAKESTATE_WRITE_FAILED");
} else if (err == APIError::HANDSHAKESTATE_BAD_STATE) {
return "HANDSHAKESTATE_BAD_STATE";
return LOG_STR("HANDSHAKESTATE_BAD_STATE");
} else if (err == APIError::CIPHERSTATE_DECRYPT_FAILED) {
return "CIPHERSTATE_DECRYPT_FAILED";
return LOG_STR("CIPHERSTATE_DECRYPT_FAILED");
} else if (err == APIError::CIPHERSTATE_ENCRYPT_FAILED) {
return "CIPHERSTATE_ENCRYPT_FAILED";
return LOG_STR("CIPHERSTATE_ENCRYPT_FAILED");
} else if (err == APIError::HANDSHAKESTATE_SETUP_FAILED) {
return "HANDSHAKESTATE_SETUP_FAILED";
return LOG_STR("HANDSHAKESTATE_SETUP_FAILED");
} else if (err == APIError::HANDSHAKESTATE_SPLIT_FAILED) {
return "HANDSHAKESTATE_SPLIT_FAILED";
return LOG_STR("HANDSHAKESTATE_SPLIT_FAILED");
} else if (err == APIError::BAD_HANDSHAKE_ERROR_BYTE) {
return "BAD_HANDSHAKE_ERROR_BYTE";
return LOG_STR("BAD_HANDSHAKE_ERROR_BYTE");
}
#endif
return "UNKNOWN";
return LOG_STR("UNKNOWN");
}
// Default implementation for loop - handles sending buffered data
APIError APIFrameHelper::loop() {
if (!this->tx_buf_.empty()) {
if (this->tx_buf_count_ > 0) {
APIError err = try_send_tx_buf_();
if (err != APIError::OK && err != APIError::WOULD_BLOCK) {
return err;
@@ -102,9 +103,20 @@ APIError APIFrameHelper::handle_socket_write_error_() {
// Helper method to buffer data from IOVs
void APIFrameHelper::buffer_data_from_iov_(const struct iovec *iov, int iovcnt, uint16_t total_write_len,
uint16_t offset) {
SendBuffer buffer;
buffer.size = total_write_len - offset;
buffer.data = std::make_unique<uint8_t[]>(buffer.size);
// Check if queue is full
if (this->tx_buf_count_ >= API_MAX_SEND_QUEUE) {
HELPER_LOG("Send queue full (%u buffers), dropping connection", this->tx_buf_count_);
this->state_ = State::FAILED;
return;
}
uint16_t buffer_size = total_write_len - offset;
auto &buffer = this->tx_buf_[this->tx_buf_tail_];
buffer = std::make_unique<SendBuffer>(SendBuffer{
.data = std::make_unique<uint8_t[]>(buffer_size),
.size = buffer_size,
.offset = 0,
});
uint16_t to_skip = offset;
uint16_t write_pos = 0;
@@ -117,12 +129,15 @@ void APIFrameHelper::buffer_data_from_iov_(const struct iovec *iov, int iovcnt,
// Include this segment (partially or fully)
const uint8_t *src = reinterpret_cast<uint8_t *>(iov[i].iov_base) + to_skip;
uint16_t len = static_cast<uint16_t>(iov[i].iov_len) - to_skip;
std::memcpy(buffer.data.get() + write_pos, src, len);
std::memcpy(buffer->data.get() + write_pos, src, len);
write_pos += len;
to_skip = 0;
}
}
this->tx_buf_.push_back(std::move(buffer));
// Update circular buffer tracking
this->tx_buf_tail_ = (this->tx_buf_tail_ + 1) % API_MAX_SEND_QUEUE;
this->tx_buf_count_++;
}
// This method writes data to socket or buffers it
@@ -140,7 +155,7 @@ APIError APIFrameHelper::write_raw_(const struct iovec *iov, int iovcnt, uint16_
#endif
// Try to send any existing buffered data first if there is any
if (!this->tx_buf_.empty()) {
if (this->tx_buf_count_ > 0) {
APIError send_result = try_send_tx_buf_();
// If real error occurred (not just WOULD_BLOCK), return it
if (send_result != APIError::OK && send_result != APIError::WOULD_BLOCK) {
@@ -149,14 +164,16 @@ APIError APIFrameHelper::write_raw_(const struct iovec *iov, int iovcnt, uint16_
// If there is still data in the buffer, we can't send, buffer
// the new data and return
if (!this->tx_buf_.empty()) {
if (this->tx_buf_count_ > 0) {
this->buffer_data_from_iov_(iov, iovcnt, total_write_len, 0);
return APIError::OK; // Success, data buffered
}
}
// Try to send directly if no buffered data
ssize_t sent = this->socket_->writev(iov, iovcnt);
// Optimize for single iovec case (common for plaintext API)
ssize_t sent =
(iovcnt == 1) ? this->socket_->write(iov[0].iov_base, iov[0].iov_len) : this->socket_->writev(iov, iovcnt);
if (sent == -1) {
APIError err = this->handle_socket_write_error_();
@@ -175,32 +192,31 @@ APIError APIFrameHelper::write_raw_(const struct iovec *iov, int iovcnt, uint16_
}
// Common implementation for trying to send buffered data
// IMPORTANT: Caller MUST ensure tx_buf_ is not empty before calling this method
// IMPORTANT: Caller MUST ensure tx_buf_count_ > 0 before calling this method
APIError APIFrameHelper::try_send_tx_buf_() {
// Try to send from tx_buf - we assume it's not empty as it's the caller's responsibility to check
bool tx_buf_empty = false;
while (!tx_buf_empty) {
while (this->tx_buf_count_ > 0) {
// Get the first buffer in the queue
SendBuffer &front_buffer = this->tx_buf_.front();
SendBuffer *front_buffer = this->tx_buf_[this->tx_buf_head_].get();
// Try to send the remaining data in this buffer
ssize_t sent = this->socket_->write(front_buffer.current_data(), front_buffer.remaining());
ssize_t sent = this->socket_->write(front_buffer->current_data(), front_buffer->remaining());
if (sent == -1) {
return this->handle_socket_write_error_();
} else if (sent == 0) {
// Nothing sent but not an error
return APIError::WOULD_BLOCK;
} else if (static_cast<uint16_t>(sent) < front_buffer.remaining()) {
} else if (static_cast<uint16_t>(sent) < front_buffer->remaining()) {
// Partially sent, update offset
// Cast to ensure no overflow issues with uint16_t
front_buffer.offset += static_cast<uint16_t>(sent);
front_buffer->offset += static_cast<uint16_t>(sent);
return APIError::WOULD_BLOCK; // Stop processing more buffers if we couldn't send a complete buffer
} else {
// Buffer completely sent, remove it from the queue
this->tx_buf_.pop_front();
// Update empty status for the loop condition
tx_buf_empty = this->tx_buf_.empty();
this->tx_buf_[this->tx_buf_head_].reset();
this->tx_buf_head_ = (this->tx_buf_head_ + 1) % API_MAX_SEND_QUEUE;
this->tx_buf_count_--;
// Continue loop to try sending the next buffer
}
}

View File

@@ -1,7 +1,8 @@
#pragma once
#include <array>
#include <cstdint>
#include <deque>
#include <limits>
#include <memory>
#include <span>
#include <utility>
#include <vector>
@@ -17,6 +18,16 @@ namespace esphome::api {
// uncomment to log raw packets
//#define HELPER_LOG_PACKETS
// Maximum message size limits to prevent OOM on constrained devices
// Voice Assistant is our largest user at 1024 bytes per audio chunk
// Using 2048 + 256 bytes overhead = 2304 bytes total to support voice and future needs
// ESP8266 has very limited RAM and cannot support voice assistant
#ifdef USE_ESP8266
static constexpr uint16_t MAX_MESSAGE_SIZE = 512; // Keep small for memory constrained ESP8266
#else
static constexpr uint16_t MAX_MESSAGE_SIZE = 2304; // Support voice (1024) + headroom for larger messages
#endif
// Forward declaration
struct ClientInfo;
@@ -66,7 +77,7 @@ enum class APIError : uint16_t {
#endif
};
const char *api_error_to_str(APIError err);
const LogString *api_error_to_logstr(APIError err);
class APIFrameHelper {
public:
@@ -79,7 +90,7 @@ class APIFrameHelper {
virtual APIError init() = 0;
virtual APIError loop();
virtual APIError read_packet(ReadPacketBuffer *buffer) = 0;
bool can_write_without_blocking() { return state_ == State::DATA && tx_buf_.empty(); }
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() {
@@ -104,9 +115,9 @@ class APIFrameHelper {
// The buffer contains all messages with appropriate padding before each
virtual APIError write_protobuf_packets(ProtoWriteBuffer buffer, std::span<const PacketInfo> packets) = 0;
// Get the frame header padding required by this protocol
virtual uint8_t frame_header_padding() = 0;
uint8_t frame_header_padding() const { return frame_header_padding_; }
// Get the frame footer size required by this protocol
virtual uint8_t frame_footer_size() = 0;
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(); }
@@ -161,7 +172,7 @@ class APIFrameHelper {
};
// Containers (size varies, but typically 12+ bytes on 32-bit)
std::deque<SendBuffer> tx_buf_;
std::array<std::unique_ptr<SendBuffer>, API_MAX_SEND_QUEUE> tx_buf_;
std::vector<struct iovec> reusable_iovs_;
std::vector<uint8_t> rx_buf_;
@@ -174,7 +185,10 @@ class APIFrameHelper {
State state_{State::INITIALIZE};
uint8_t frame_header_padding_{0};
uint8_t frame_footer_size_{0};
// 5 bytes total, 3 bytes padding
uint8_t tx_buf_head_{0};
uint8_t tx_buf_tail_{0};
uint8_t tx_buf_count_{0};
// 8 bytes total, 0 bytes padding
// Common initialization for both plaintext and noise protocols
APIError init_common_();

View File

@@ -10,13 +10,22 @@
#include <cstring>
#include <cinttypes>
#ifdef USE_ESP8266
#include <pgmspace.h>
#endif
namespace esphome::api {
static const char *const TAG = "api.noise";
#ifdef USE_ESP8266
static const char PROLOGUE_INIT[] PROGMEM = "NoiseAPIInit";
#else
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: " msg, this->client_info_->get_combined_info().c_str(), ##__VA_ARGS__)
#define HELPER_LOG(msg, ...) \
ESP_LOGVV(TAG, "%s (%s): " msg, this->client_info_->name.c_str(), this->client_info_->peername.c_str(), ##__VA_ARGS__)
#ifdef HELPER_LOG_PACKETS
#define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str())
@@ -27,42 +36,42 @@ static constexpr size_t PROLOGUE_INIT_LEN = 12; // strlen("NoiseAPIInit")
#endif
/// Convert a noise error code to a readable error
std::string noise_err_to_str(int err) {
const LogString *noise_err_to_logstr(int err) {
if (err == NOISE_ERROR_NO_MEMORY)
return "NO_MEMORY";
return LOG_STR("NO_MEMORY");
if (err == NOISE_ERROR_UNKNOWN_ID)
return "UNKNOWN_ID";
return LOG_STR("UNKNOWN_ID");
if (err == NOISE_ERROR_UNKNOWN_NAME)
return "UNKNOWN_NAME";
return LOG_STR("UNKNOWN_NAME");
if (err == NOISE_ERROR_MAC_FAILURE)
return "MAC_FAILURE";
return LOG_STR("MAC_FAILURE");
if (err == NOISE_ERROR_NOT_APPLICABLE)
return "NOT_APPLICABLE";
return LOG_STR("NOT_APPLICABLE");
if (err == NOISE_ERROR_SYSTEM)
return "SYSTEM";
return LOG_STR("SYSTEM");
if (err == NOISE_ERROR_REMOTE_KEY_REQUIRED)
return "REMOTE_KEY_REQUIRED";
return LOG_STR("REMOTE_KEY_REQUIRED");
if (err == NOISE_ERROR_LOCAL_KEY_REQUIRED)
return "LOCAL_KEY_REQUIRED";
return LOG_STR("LOCAL_KEY_REQUIRED");
if (err == NOISE_ERROR_PSK_REQUIRED)
return "PSK_REQUIRED";
return LOG_STR("PSK_REQUIRED");
if (err == NOISE_ERROR_INVALID_LENGTH)
return "INVALID_LENGTH";
return LOG_STR("INVALID_LENGTH");
if (err == NOISE_ERROR_INVALID_PARAM)
return "INVALID_PARAM";
return LOG_STR("INVALID_PARAM");
if (err == NOISE_ERROR_INVALID_STATE)
return "INVALID_STATE";
return LOG_STR("INVALID_STATE");
if (err == NOISE_ERROR_INVALID_NONCE)
return "INVALID_NONCE";
return LOG_STR("INVALID_NONCE");
if (err == NOISE_ERROR_INVALID_PRIVATE_KEY)
return "INVALID_PRIVATE_KEY";
return LOG_STR("INVALID_PRIVATE_KEY");
if (err == NOISE_ERROR_INVALID_PUBLIC_KEY)
return "INVALID_PUBLIC_KEY";
return LOG_STR("INVALID_PUBLIC_KEY");
if (err == NOISE_ERROR_INVALID_FORMAT)
return "INVALID_FORMAT";
return LOG_STR("INVALID_FORMAT");
if (err == NOISE_ERROR_INVALID_SIGNATURE)
return "INVALID_SIGNATURE";
return to_string(err);
return LOG_STR("INVALID_SIGNATURE");
return LOG_STR("UNKNOWN");
}
/// Initialize the frame helper, returns OK if successful.
@@ -75,7 +84,11 @@ APIError APINoiseFrameHelper::init() {
// init prologue
size_t old_size = prologue_.size();
prologue_.resize(old_size + PROLOGUE_INIT_LEN);
#ifdef USE_ESP8266
memcpy_P(prologue_.data() + old_size, PROLOGUE_INIT, PROLOGUE_INIT_LEN);
#else
std::memcpy(prologue_.data() + old_size, PROLOGUE_INIT, PROLOGUE_INIT_LEN);
#endif
state_ = State::CLIENT_HELLO;
return APIError::OK;
@@ -83,18 +96,18 @@ APIError APINoiseFrameHelper::init() {
// Helper for handling handshake frame errors
APIError APINoiseFrameHelper::handle_handshake_frame_error_(APIError aerr) {
if (aerr == APIError::BAD_INDICATOR) {
send_explicit_handshake_reject_("Bad indicator byte");
send_explicit_handshake_reject_(LOG_STR("Bad indicator byte"));
} else if (aerr == APIError::BAD_HANDSHAKE_PACKET_LEN) {
send_explicit_handshake_reject_("Bad handshake packet len");
send_explicit_handshake_reject_(LOG_STR("Bad handshake packet len"));
}
return aerr;
}
// Helper for handling noise library errors
APIError APINoiseFrameHelper::handle_noise_error_(int err, const char *func_name, APIError api_err) {
APIError APINoiseFrameHelper::handle_noise_error_(int err, const LogString *func_name, APIError api_err) {
if (err != 0) {
state_ = State::FAILED;
HELPER_LOG("%s failed: %s", func_name, noise_err_to_str(err).c_str());
HELPER_LOG("%s failed: %s", LOG_STR_ARG(func_name), LOG_STR_ARG(noise_err_to_logstr(err)));
return api_err;
}
return APIError::OK;
@@ -172,6 +185,13 @@ APIError APINoiseFrameHelper::try_read_frame_(std::vector<uint8_t> *frame) {
return APIError::BAD_HANDSHAKE_PACKET_LEN;
}
// Check against maximum message size to prevent OOM
if (msg_size > MAX_MESSAGE_SIZE) {
state_ = State::FAILED;
HELPER_LOG("Bad packet: message size %u exceeds maximum %u", msg_size, MAX_MESSAGE_SIZE);
return APIError::BAD_DATA_PACKET;
}
// reserve space for body
if (rx_buf_.size() != msg_size) {
rx_buf_.resize(msg_size);
@@ -279,11 +299,11 @@ APIError APINoiseFrameHelper::state_action_() {
}
if (frame.empty()) {
send_explicit_handshake_reject_("Empty handshake message");
send_explicit_handshake_reject_(LOG_STR("Empty handshake message"));
return APIError::BAD_HANDSHAKE_ERROR_BYTE;
} else if (frame[0] != 0x00) {
HELPER_LOG("Bad handshake error byte: %u", frame[0]);
send_explicit_handshake_reject_("Bad handshake error byte");
send_explicit_handshake_reject_(LOG_STR("Bad handshake error byte"));
return APIError::BAD_HANDSHAKE_ERROR_BYTE;
}
@@ -293,8 +313,10 @@ APIError APINoiseFrameHelper::state_action_() {
err = noise_handshakestate_read_message(handshake_, &mbuf, nullptr);
if (err != 0) {
// Special handling for MAC failure
send_explicit_handshake_reject_(err == NOISE_ERROR_MAC_FAILURE ? "Handshake MAC failure" : "Handshake error");
return handle_noise_error_(err, "noise_handshakestate_read_message", APIError::HANDSHAKESTATE_READ_FAILED);
send_explicit_handshake_reject_(err == NOISE_ERROR_MAC_FAILURE ? LOG_STR("Handshake MAC failure")
: LOG_STR("Handshake error"));
return handle_noise_error_(err, LOG_STR("noise_handshakestate_read_message"),
APIError::HANDSHAKESTATE_READ_FAILED);
}
aerr = check_handshake_finished_();
@@ -307,8 +329,8 @@ APIError APINoiseFrameHelper::state_action_() {
noise_buffer_set_output(mbuf, buffer + 1, sizeof(buffer) - 1);
err = noise_handshakestate_write_message(handshake_, &mbuf, nullptr);
APIError aerr_write =
handle_noise_error_(err, "noise_handshakestate_write_message", APIError::HANDSHAKESTATE_WRITE_FAILED);
APIError aerr_write = handle_noise_error_(err, LOG_STR("noise_handshakestate_write_message"),
APIError::HANDSHAKESTATE_WRITE_FAILED);
if (aerr_write != APIError::OK)
return aerr_write;
buffer[0] = 0x00; // success
@@ -331,15 +353,31 @@ APIError APINoiseFrameHelper::state_action_() {
}
return APIError::OK;
}
void APINoiseFrameHelper::send_explicit_handshake_reject_(const std::string &reason) {
void APINoiseFrameHelper::send_explicit_handshake_reject_(const LogString *reason) {
#ifdef USE_STORE_LOG_STR_IN_FLASH
// On ESP8266 with flash strings, we need to use PROGMEM-aware functions
size_t reason_len = strlen_P(reinterpret_cast<PGM_P>(reason));
std::vector<uint8_t> data;
data.resize(reason.length() + 1);
data.resize(reason_len + 1);
data[0] = 0x01; // failure
// Copy error message from PROGMEM
if (reason_len > 0) {
memcpy_P(data.data() + 1, reinterpret_cast<PGM_P>(reason), reason_len);
}
#else
// Normal memory access
const char *reason_str = LOG_STR_ARG(reason);
size_t reason_len = strlen(reason_str);
std::vector<uint8_t> data;
data.resize(reason_len + 1);
data[0] = 0x01; // failure
// Copy error message in bulk
if (!reason.empty()) {
std::memcpy(data.data() + 1, reason.c_str(), reason.length());
if (reason_len > 0) {
std::memcpy(data.data() + 1, reason_str, reason_len);
}
#endif
// temporarily remove failed state
auto orig_state = state_;
@@ -368,7 +406,8 @@ APIError APINoiseFrameHelper::read_packet(ReadPacketBuffer *buffer) {
noise_buffer_init(mbuf);
noise_buffer_set_inout(mbuf, frame.data(), frame.size(), frame.size());
err = noise_cipherstate_decrypt(recv_cipher_, &mbuf);
APIError decrypt_err = handle_noise_error_(err, "noise_cipherstate_decrypt", APIError::CIPHERSTATE_DECRYPT_FAILED);
APIError decrypt_err =
handle_noise_error_(err, LOG_STR("noise_cipherstate_decrypt"), APIError::CIPHERSTATE_DECRYPT_FAILED);
if (decrypt_err != APIError::OK)
return decrypt_err;
@@ -450,7 +489,8 @@ APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, st
4 + packet.payload_size + frame_footer_size_);
int err = noise_cipherstate_encrypt(send_cipher_, &mbuf);
APIError aerr = handle_noise_error_(err, "noise_cipherstate_encrypt", APIError::CIPHERSTATE_ENCRYPT_FAILED);
APIError aerr =
handle_noise_error_(err, LOG_STR("noise_cipherstate_encrypt"), APIError::CIPHERSTATE_ENCRYPT_FAILED);
if (aerr != APIError::OK)
return aerr;
@@ -504,25 +544,27 @@ APIError APINoiseFrameHelper::init_handshake_() {
nid_.modifier_ids[0] = NOISE_MODIFIER_PSK0;
err = noise_handshakestate_new_by_id(&handshake_, &nid_, NOISE_ROLE_RESPONDER);
APIError aerr = handle_noise_error_(err, "noise_handshakestate_new_by_id", APIError::HANDSHAKESTATE_SETUP_FAILED);
APIError aerr =
handle_noise_error_(err, LOG_STR("noise_handshakestate_new_by_id"), APIError::HANDSHAKESTATE_SETUP_FAILED);
if (aerr != APIError::OK)
return aerr;
const auto &psk = ctx_->get_psk();
err = noise_handshakestate_set_pre_shared_key(handshake_, psk.data(), psk.size());
aerr = handle_noise_error_(err, "noise_handshakestate_set_pre_shared_key", APIError::HANDSHAKESTATE_SETUP_FAILED);
aerr = handle_noise_error_(err, LOG_STR("noise_handshakestate_set_pre_shared_key"),
APIError::HANDSHAKESTATE_SETUP_FAILED);
if (aerr != APIError::OK)
return aerr;
err = noise_handshakestate_set_prologue(handshake_, prologue_.data(), prologue_.size());
aerr = handle_noise_error_(err, "noise_handshakestate_set_prologue", APIError::HANDSHAKESTATE_SETUP_FAILED);
aerr = handle_noise_error_(err, LOG_STR("noise_handshakestate_set_prologue"), APIError::HANDSHAKESTATE_SETUP_FAILED);
if (aerr != APIError::OK)
return aerr;
// set_prologue copies it into handshakestate, so we can get rid of it now
prologue_ = {};
err = noise_handshakestate_start(handshake_);
aerr = handle_noise_error_(err, "noise_handshakestate_start", APIError::HANDSHAKESTATE_SETUP_FAILED);
aerr = handle_noise_error_(err, LOG_STR("noise_handshakestate_start"), APIError::HANDSHAKESTATE_SETUP_FAILED);
if (aerr != APIError::OK)
return aerr;
return APIError::OK;
@@ -540,7 +582,8 @@ APIError APINoiseFrameHelper::check_handshake_finished_() {
return APIError::HANDSHAKESTATE_BAD_STATE;
}
int err = noise_handshakestate_split(handshake_, &send_cipher_, &recv_cipher_);
APIError aerr = handle_noise_error_(err, "noise_handshakestate_split", APIError::HANDSHAKESTATE_SPLIT_FAILED);
APIError aerr =
handle_noise_error_(err, LOG_STR("noise_handshakestate_split"), APIError::HANDSHAKESTATE_SPLIT_FAILED);
if (aerr != APIError::OK)
return aerr;

View File

@@ -7,7 +7,7 @@
namespace esphome::api {
class APINoiseFrameHelper : public APIFrameHelper {
class APINoiseFrameHelper final : public APIFrameHelper {
public:
APINoiseFrameHelper(std::unique_ptr<socket::Socket> socket, std::shared_ptr<APINoiseContext> ctx,
const ClientInfo *client_info)
@@ -25,10 +25,6 @@ class APINoiseFrameHelper : public APIFrameHelper {
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;
// Get the frame header padding required by this protocol
uint8_t frame_header_padding() override { return frame_header_padding_; }
// Get the frame footer size required by this protocol
uint8_t frame_footer_size() override { return frame_footer_size_; }
protected:
APIError state_action_();
@@ -36,9 +32,9 @@ class APINoiseFrameHelper : public APIFrameHelper {
APIError write_frame_(const uint8_t *data, uint16_t len);
APIError init_handshake_();
APIError check_handshake_finished_();
void send_explicit_handshake_reject_(const std::string &reason);
void send_explicit_handshake_reject_(const LogString *reason);
APIError handle_handshake_frame_error_(APIError aerr);
APIError handle_noise_error_(int err, const char *func_name, APIError api_err);
APIError handle_noise_error_(int err, const LogString *func_name, APIError api_err);
// Pointers first (4 bytes each)
NoiseHandshakeState *handshake_{nullptr};

View File

@@ -10,11 +10,16 @@
#include <cstring>
#include <cinttypes>
#ifdef USE_ESP8266
#include <pgmspace.h>
#endif
namespace esphome::api {
static const char *const TAG = "api.plaintext";
#define HELPER_LOG(msg, ...) ESP_LOGVV(TAG, "%s: " msg, this->client_info_->get_combined_info().c_str(), ##__VA_ARGS__)
#define HELPER_LOG(msg, ...) \
ESP_LOGVV(TAG, "%s (%s): " msg, this->client_info_->name.c_str(), this->client_info_->peername.c_str(), ##__VA_ARGS__)
#ifdef HELPER_LOG_PACKETS
#define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str())
@@ -118,10 +123,10 @@ APIError APIPlaintextFrameHelper::try_read_frame_(std::vector<uint8_t> *frame) {
continue;
}
if (msg_size_varint->as_uint32() > std::numeric_limits<uint16_t>::max()) {
if (msg_size_varint->as_uint32() > MAX_MESSAGE_SIZE) {
state_ = State::FAILED;
HELPER_LOG("Bad packet: message size %" PRIu32 " exceeds maximum %u", msg_size_varint->as_uint32(),
std::numeric_limits<uint16_t>::max());
MAX_MESSAGE_SIZE);
return APIError::BAD_DATA_PACKET;
}
rx_header_parsed_len_ = msg_size_varint->as_uint16();
@@ -197,11 +202,20 @@ APIError APIPlaintextFrameHelper::read_packet(ReadPacketBuffer *buffer) {
// We must send at least 3 bytes to be read, so we add
// a message after the indicator byte to ensures its long
// enough and can aid in debugging.
const char msg[] = "\x00"
"Bad indicator byte";
static constexpr uint8_t INDICATOR_MSG_SIZE = 19;
#ifdef USE_ESP8266
static const char MSG_PROGMEM[] PROGMEM = "\x00"
"Bad indicator byte";
char msg[INDICATOR_MSG_SIZE];
memcpy_P(msg, MSG_PROGMEM, INDICATOR_MSG_SIZE);
iov[0].iov_base = (void *) msg;
iov[0].iov_len = 19;
this->write_raw_(iov, 1, 19);
#else
static const char MSG[] = "\x00"
"Bad indicator byte";
iov[0].iov_base = (void *) MSG;
#endif
iov[0].iov_len = INDICATOR_MSG_SIZE;
this->write_raw_(iov, 1, INDICATOR_MSG_SIZE);
}
return aerr;
}

View File

@@ -5,7 +5,7 @@
namespace esphome::api {
class APIPlaintextFrameHelper : public APIFrameHelper {
class APIPlaintextFrameHelper final : public APIFrameHelper {
public:
APIPlaintextFrameHelper(std::unique_ptr<socket::Socket> socket, const ClientInfo *client_info)
: APIFrameHelper(std::move(socket), client_info) {
@@ -22,9 +22,6 @@ class APIPlaintextFrameHelper : public APIFrameHelper {
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;
uint8_t frame_header_padding() override { return frame_header_padding_; }
// Get the frame footer size required by this protocol
uint8_t frame_footer_size() override { return frame_footer_size_; }
protected:
APIError try_read_frame_(std::vector<uint8_t> *frame);

View File

@@ -28,5 +28,40 @@ 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;
// pointer_to_buffer: Use pointer instead of array for fixed-size byte fields
// When set, the field will be declared as a pointer (const uint8_t *data)
// instead of an array (uint8_t data[N]). This allows zero-copy on decode
// by pointing directly to the protobuf buffer. The buffer must remain valid
// until the message is processed (which is guaranteed for stack-allocated messages).
optional bool pointer_to_buffer = 50012 [default=false];
// container_pointer: Zero-copy optimization for repeated fields.
//
// When container_pointer is set on a repeated field, the generated message will
// store a pointer to an existing container instead of copying the data into the
// message's own repeated field. This eliminates heap allocations and improves performance.
//
// Requirements for safe usage:
// 1. The source container must remain valid until the message is encoded
// 2. Messages must be encoded immediately (which ESPHome does by default)
// 3. The container type must match the field type exactly
//
// Supported container types:
// - "std::vector<T>" for most repeated fields
// - "std::set<T>" for unique/sorted data
// - Full type specification required for enums (e.g., "std::set<climate::ClimateMode>")
//
// Example usage in .proto file:
// repeated string supported_modes = 12 [(container_pointer) = "std::set"];
// repeated ColorMode color_modes = 13 [(container_pointer) = "std::set<light::ColorMode>"];
//
// The corresponding C++ code must provide const reference access to a container
// that matches the specified type and remains valid during message encoding.
// This is typically done through methods returning const T& or special accessor
// methods like get_options() or supported_modes_for_api_().
optional string container_pointer = 50001;
}

View File

@@ -22,9 +22,12 @@ bool HelloRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
}
bool HelloRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
switch (field_id) {
case 1:
this->client_info = value.as_string();
case 1: {
// Use raw data directly to avoid allocation
this->client_info = value.data();
this->client_info_len = value.size();
break;
}
default:
return false;
}
@@ -42,18 +45,23 @@ void HelloResponse::calculate_size(ProtoSize &size) const {
size.add_length(1, this->server_info_ref_.size());
size.add_length(1, this->name_ref_.size());
}
bool ConnectRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
#ifdef USE_API_PASSWORD
bool AuthenticationRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
switch (field_id) {
case 1:
this->password = value.as_string();
case 1: {
// Use raw data directly to avoid allocation
this->password = value.data();
this->password_len = value.size();
break;
}
default:
return false;
}
return true;
}
void ConnectResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_bool(1, this->invalid_password); }
void ConnectResponse::calculate_size(ProtoSize &size) const { size.add_bool(1, this->invalid_password); }
void AuthenticationResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_bool(1, this->invalid_password); }
void AuthenticationResponse::calculate_size(ProtoSize &size) const { size.add_bool(1, this->invalid_password); }
#endif
#ifdef USE_AREAS
void AreaInfo::encode(ProtoWriteBuffer buffer) const {
buffer.encode_uint32(1, this->area_id);
@@ -115,18 +123,24 @@ void DeviceInfoResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_bool(19, this->api_encryption_supported);
#endif
#ifdef USE_DEVICES
for (auto &it : this->devices) {
for (const auto &it : this->devices) {
buffer.encode_message(20, it, true);
}
#endif
#ifdef USE_AREAS
for (auto &it : this->areas) {
for (const auto &it : this->areas) {
buffer.encode_message(21, it, true);
}
#endif
#ifdef USE_AREAS
buffer.encode_message(22, this->area);
#endif
#ifdef USE_ZWAVE_PROXY
buffer.encode_uint32(23, this->zwave_proxy_feature_flags);
#endif
#ifdef USE_ZWAVE_PROXY
buffer.encode_uint32(24, this->zwave_home_id);
#endif
}
void DeviceInfoResponse::calculate_size(ProtoSize &size) const {
#ifdef USE_API_PASSWORD
@@ -167,14 +181,24 @@ void DeviceInfoResponse::calculate_size(ProtoSize &size) const {
size.add_bool(2, this->api_encryption_supported);
#endif
#ifdef USE_DEVICES
size.add_repeated_message(2, this->devices);
for (const auto &it : this->devices) {
size.add_message_object_force(2, it);
}
#endif
#ifdef USE_AREAS
size.add_repeated_message(2, this->areas);
for (const auto &it : this->areas) {
size.add_message_object_force(2, it);
}
#endif
#ifdef USE_AREAS
size.add_message_object(2, this->area);
#endif
#ifdef USE_ZWAVE_PROXY
size.add_uint32(2, this->zwave_proxy_feature_flags);
#endif
#ifdef USE_ZWAVE_PROXY
size.add_uint32(2, this->zwave_home_id);
#endif
}
#ifdef USE_BINARY_SENSOR
void ListEntitiesBinarySensorResponse::encode(ProtoWriteBuffer buffer) const {
@@ -848,7 +872,7 @@ void HomeassistantServiceMap::calculate_size(ProtoSize &size) const {
size.add_length(1, this->key_ref_.size());
size.add_length(1, this->value.size());
}
void HomeassistantServiceResponse::encode(ProtoWriteBuffer buffer) const {
void HomeassistantActionRequest::encode(ProtoWriteBuffer buffer) const {
buffer.encode_string(1, this->service_ref_);
for (auto &it : this->data) {
buffer.encode_message(2, it, true);
@@ -861,7 +885,7 @@ void HomeassistantServiceResponse::encode(ProtoWriteBuffer buffer) const {
}
buffer.encode_bool(5, this->is_event);
}
void HomeassistantServiceResponse::calculate_size(ProtoSize &size) const {
void HomeassistantActionRequest::calculate_size(ProtoSize &size) const {
size.add_length(1, this->service_ref_.size());
size.add_repeated_message(1, this->data);
size.add_repeated_message(1, this->data_template);
@@ -897,6 +921,19 @@ bool HomeAssistantStateResponse::decode_length(uint32_t field_id, ProtoLengthDel
return true;
}
#endif
bool GetTimeResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
switch (field_id) {
case 2: {
// Use raw data directly to avoid allocation
this->timezone = value.data();
this->timezone_len = value.size();
break;
}
default:
return false;
}
return true;
}
bool GetTimeResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
switch (field_id) {
case 1:
@@ -907,8 +944,6 @@ bool GetTimeResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
}
return true;
}
void GetTimeResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_fixed32(1, this->epoch_seconds); }
void GetTimeResponse::calculate_size(ProtoSize &size) const { size.add_fixed32(1, this->epoch_seconds); }
#ifdef USE_API_SERVICES
void ListEntitiesServicesArgument::encode(ProtoWriteBuffer buffer) const {
buffer.encode_string(1, this->name_ref_);
@@ -1725,6 +1760,7 @@ void ListEntitiesMediaPlayerResponse::encode(ProtoWriteBuffer buffer) const {
#ifdef USE_DEVICES
buffer.encode_uint32(10, this->device_id);
#endif
buffer.encode_uint32(11, this->feature_flags);
}
void ListEntitiesMediaPlayerResponse::calculate_size(ProtoSize &size) const {
size.add_length(1, this->object_id_ref_.size());
@@ -1740,6 +1776,7 @@ void ListEntitiesMediaPlayerResponse::calculate_size(ProtoSize &size) const {
#ifdef USE_DEVICES
size.add_uint32(1, this->device_id);
#endif
size.add_uint32(1, this->feature_flags);
}
void MediaPlayerStateResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_fixed32(1, this->key);
@@ -1837,12 +1874,14 @@ void BluetoothLERawAdvertisement::calculate_size(ProtoSize &size) const {
size.add_length(1, this->data_len);
}
void BluetoothLERawAdvertisementsResponse::encode(ProtoWriteBuffer buffer) const {
for (auto &it : this->advertisements) {
buffer.encode_message(1, it, true);
for (uint16_t i = 0; i < this->advertisements_len; i++) {
buffer.encode_message(1, this->advertisements[i], true);
}
}
void BluetoothLERawAdvertisementsResponse::calculate_size(ProtoSize &size) const {
size.add_repeated_message(1, this->advertisements);
for (uint16_t i = 0; i < this->advertisements_len; i++) {
size.add_message_object_force(1, this->advertisements[i]);
}
}
bool BluetoothDeviceRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
@@ -1886,52 +1925,72 @@ bool BluetoothGATTGetServicesRequest::decode_varint(uint32_t field_id, ProtoVarI
return true;
}
void BluetoothGATTDescriptor::encode(ProtoWriteBuffer buffer) const {
buffer.encode_uint64(1, this->uuid[0], true);
buffer.encode_uint64(1, this->uuid[1], true);
if (this->uuid[0] != 0 || this->uuid[1] != 0) {
buffer.encode_uint64(1, this->uuid[0], true);
buffer.encode_uint64(1, this->uuid[1], true);
}
buffer.encode_uint32(2, this->handle);
buffer.encode_uint32(3, this->short_uuid);
}
void BluetoothGATTDescriptor::calculate_size(ProtoSize &size) const {
size.add_uint64_force(1, this->uuid[0]);
size.add_uint64_force(1, this->uuid[1]);
if (this->uuid[0] != 0 || this->uuid[1] != 0) {
size.add_uint64_force(1, this->uuid[0]);
size.add_uint64_force(1, this->uuid[1]);
}
size.add_uint32(1, this->handle);
size.add_uint32(1, this->short_uuid);
}
void BluetoothGATTCharacteristic::encode(ProtoWriteBuffer buffer) const {
buffer.encode_uint64(1, this->uuid[0], true);
buffer.encode_uint64(1, this->uuid[1], true);
if (this->uuid[0] != 0 || this->uuid[1] != 0) {
buffer.encode_uint64(1, this->uuid[0], true);
buffer.encode_uint64(1, this->uuid[1], true);
}
buffer.encode_uint32(2, this->handle);
buffer.encode_uint32(3, this->properties);
for (auto &it : this->descriptors) {
buffer.encode_message(4, it, true);
}
buffer.encode_uint32(5, this->short_uuid);
}
void BluetoothGATTCharacteristic::calculate_size(ProtoSize &size) const {
size.add_uint64_force(1, this->uuid[0]);
size.add_uint64_force(1, this->uuid[1]);
if (this->uuid[0] != 0 || this->uuid[1] != 0) {
size.add_uint64_force(1, this->uuid[0]);
size.add_uint64_force(1, this->uuid[1]);
}
size.add_uint32(1, this->handle);
size.add_uint32(1, this->properties);
size.add_repeated_message(1, this->descriptors);
size.add_uint32(1, this->short_uuid);
}
void BluetoothGATTService::encode(ProtoWriteBuffer buffer) const {
buffer.encode_uint64(1, this->uuid[0], true);
buffer.encode_uint64(1, this->uuid[1], true);
if (this->uuid[0] != 0 || this->uuid[1] != 0) {
buffer.encode_uint64(1, this->uuid[0], true);
buffer.encode_uint64(1, this->uuid[1], true);
}
buffer.encode_uint32(2, this->handle);
for (auto &it : this->characteristics) {
buffer.encode_message(3, it, true);
}
buffer.encode_uint32(4, this->short_uuid);
}
void BluetoothGATTService::calculate_size(ProtoSize &size) const {
size.add_uint64_force(1, this->uuid[0]);
size.add_uint64_force(1, this->uuid[1]);
if (this->uuid[0] != 0 || this->uuid[1] != 0) {
size.add_uint64_force(1, this->uuid[0]);
size.add_uint64_force(1, this->uuid[1]);
}
size.add_uint32(1, this->handle);
size.add_repeated_message(1, this->characteristics);
size.add_uint32(1, this->short_uuid);
}
void BluetoothGATTGetServicesResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_uint64(1, this->address);
buffer.encode_message(2, this->services[0], true);
for (auto &it : this->services) {
buffer.encode_message(2, it, true);
}
}
void BluetoothGATTGetServicesResponse::calculate_size(ProtoSize &size) const {
size.add_uint64(1, this->address);
size.add_message_object_force(1, this->services[0]);
size.add_repeated_message(1, this->services);
}
void BluetoothGATTGetServicesDoneResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_uint64(1, this->address);
@@ -1978,9 +2037,12 @@ bool BluetoothGATTWriteRequest::decode_varint(uint32_t field_id, ProtoVarInt val
}
bool BluetoothGATTWriteRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
switch (field_id) {
case 4:
this->data = value.as_string();
case 4: {
// Use raw data directly to avoid allocation
this->data = value.data();
this->data_len = value.size();
break;
}
default:
return false;
}
@@ -2014,9 +2076,12 @@ bool BluetoothGATTWriteDescriptorRequest::decode_varint(uint32_t field_id, Proto
}
bool BluetoothGATTWriteDescriptorRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
switch (field_id) {
case 3:
this->data = value.as_string();
case 3: {
// Use raw data directly to avoid allocation
this->data = value.data();
this->data_len = value.size();
break;
}
default:
return false;
}
@@ -2051,15 +2116,17 @@ void BluetoothGATTNotifyDataResponse::calculate_size(ProtoSize &size) const {
void BluetoothConnectionsFreeResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_uint32(1, this->free);
buffer.encode_uint32(2, this->limit);
for (auto &it : this->allocated) {
buffer.encode_uint64(3, it, true);
for (const auto &it : this->allocated) {
if (it != 0) {
buffer.encode_uint64(3, it, true);
}
}
}
void BluetoothConnectionsFreeResponse::calculate_size(ProtoSize &size) const {
size.add_uint32(1, this->free);
size.add_uint32(1, this->limit);
if (!this->allocated.empty()) {
for (const auto &it : this->allocated) {
for (const auto &it : this->allocated) {
if (it != 0) {
size.add_uint64_force(1, it);
}
}
@@ -2123,10 +2190,12 @@ void BluetoothDeviceClearCacheResponse::calculate_size(ProtoSize &size) const {
void BluetoothScannerStateResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_uint32(1, static_cast<uint32_t>(this->state));
buffer.encode_uint32(2, static_cast<uint32_t>(this->mode));
buffer.encode_uint32(3, static_cast<uint32_t>(this->configured_mode));
}
void BluetoothScannerStateResponse::calculate_size(ProtoSize &size) const {
size.add_uint32(1, static_cast<uint32_t>(this->state));
size.add_uint32(1, static_cast<uint32_t>(this->mode));
size.add_uint32(1, static_cast<uint32_t>(this->configured_mode));
}
bool BluetoothScannerSetModeRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
@@ -2328,6 +2397,52 @@ void VoiceAssistantWakeWord::calculate_size(ProtoSize &size) const {
}
}
}
bool VoiceAssistantExternalWakeWord::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 5:
this->model_size = value.as_uint32();
break;
default:
return false;
}
return true;
}
bool VoiceAssistantExternalWakeWord::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
switch (field_id) {
case 1:
this->id = value.as_string();
break;
case 2:
this->wake_word = value.as_string();
break;
case 3:
this->trained_languages.push_back(value.as_string());
break;
case 4:
this->model_type = value.as_string();
break;
case 6:
this->model_hash = value.as_string();
break;
case 7:
this->url = value.as_string();
break;
default:
return false;
}
return true;
}
bool VoiceAssistantConfigurationRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
switch (field_id) {
case 1:
this->external_wake_words.emplace_back();
value.decode_to_message(this->external_wake_words.back());
break;
default:
return false;
}
return true;
}
void VoiceAssistantConfigurationResponse::encode(ProtoWriteBuffer buffer) const {
for (auto &it : this->available_wake_words) {
buffer.encode_message(1, it, true);
@@ -2971,5 +3086,53 @@ bool UpdateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
return true;
}
#endif
#ifdef USE_ZWAVE_PROXY
bool ZWaveProxyFrame::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
switch (field_id) {
case 1: {
// Use raw data directly to avoid allocation
this->data = value.data();
this->data_len = value.size();
break;
}
default:
return false;
}
return true;
}
void ZWaveProxyFrame::encode(ProtoWriteBuffer buffer) const { buffer.encode_bytes(1, this->data, this->data_len); }
void ZWaveProxyFrame::calculate_size(ProtoSize &size) const { size.add_length(1, this->data_len); }
bool ZWaveProxyRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 1:
this->type = static_cast<enums::ZWaveProxyRequestType>(value.as_uint32());
break;
default:
return false;
}
return true;
}
bool ZWaveProxyRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
switch (field_id) {
case 2: {
// Use raw data directly to avoid allocation
this->data = value.data();
this->data_len = value.size();
break;
}
default:
return false;
}
return true;
}
void ZWaveProxyRequest::encode(ProtoWriteBuffer buffer) const {
buffer.encode_uint32(1, static_cast<uint32_t>(this->type));
buffer.encode_bytes(2, this->data, this->data_len);
}
void ZWaveProxyRequest::calculate_size(ProtoSize &size) const {
size.add_uint32(1, static_cast<uint32_t>(this->type));
size.add_length(2, this->data_len);
}
#endif
} // namespace esphome::api

File diff suppressed because it is too large Load Diff

View File

@@ -383,6 +383,12 @@ template<> const char *proto_enum_to_string<enums::MediaPlayerState>(enums::Medi
return "MEDIA_PLAYER_STATE_PLAYING";
case enums::MEDIA_PLAYER_STATE_PAUSED:
return "MEDIA_PLAYER_STATE_PAUSED";
case enums::MEDIA_PLAYER_STATE_ANNOUNCING:
return "MEDIA_PLAYER_STATE_ANNOUNCING";
case enums::MEDIA_PLAYER_STATE_OFF:
return "MEDIA_PLAYER_STATE_OFF";
case enums::MEDIA_PLAYER_STATE_ON:
return "MEDIA_PLAYER_STATE_ON";
default:
return "UNKNOWN";
}
@@ -399,6 +405,24 @@ template<> const char *proto_enum_to_string<enums::MediaPlayerCommand>(enums::Me
return "MEDIA_PLAYER_COMMAND_MUTE";
case enums::MEDIA_PLAYER_COMMAND_UNMUTE:
return "MEDIA_PLAYER_COMMAND_UNMUTE";
case enums::MEDIA_PLAYER_COMMAND_TOGGLE:
return "MEDIA_PLAYER_COMMAND_TOGGLE";
case enums::MEDIA_PLAYER_COMMAND_VOLUME_UP:
return "MEDIA_PLAYER_COMMAND_VOLUME_UP";
case enums::MEDIA_PLAYER_COMMAND_VOLUME_DOWN:
return "MEDIA_PLAYER_COMMAND_VOLUME_DOWN";
case enums::MEDIA_PLAYER_COMMAND_ENQUEUE:
return "MEDIA_PLAYER_COMMAND_ENQUEUE";
case enums::MEDIA_PLAYER_COMMAND_REPEAT_ONE:
return "MEDIA_PLAYER_COMMAND_REPEAT_ONE";
case enums::MEDIA_PLAYER_COMMAND_REPEAT_OFF:
return "MEDIA_PLAYER_COMMAND_REPEAT_OFF";
case enums::MEDIA_PLAYER_COMMAND_CLEAR_PLAYLIST:
return "MEDIA_PLAYER_COMMAND_CLEAR_PLAYLIST";
case enums::MEDIA_PLAYER_COMMAND_TURN_ON:
return "MEDIA_PLAYER_COMMAND_TURN_ON";
case enums::MEDIA_PLAYER_COMMAND_TURN_OFF:
return "MEDIA_PLAYER_COMMAND_TURN_OFF";
default:
return "UNKNOWN";
}
@@ -631,10 +655,26 @@ template<> const char *proto_enum_to_string<enums::UpdateCommand>(enums::UpdateC
}
}
#endif
#ifdef USE_ZWAVE_PROXY
template<> const char *proto_enum_to_string<enums::ZWaveProxyRequestType>(enums::ZWaveProxyRequestType value) {
switch (value) {
case enums::ZWAVE_PROXY_REQUEST_TYPE_SUBSCRIBE:
return "ZWAVE_PROXY_REQUEST_TYPE_SUBSCRIBE";
case enums::ZWAVE_PROXY_REQUEST_TYPE_UNSUBSCRIBE:
return "ZWAVE_PROXY_REQUEST_TYPE_UNSUBSCRIBE";
case enums::ZWAVE_PROXY_REQUEST_TYPE_HOME_ID_CHANGE:
return "ZWAVE_PROXY_REQUEST_TYPE_HOME_ID_CHANGE";
default:
return "UNKNOWN";
}
}
#endif
void HelloRequest::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "HelloRequest");
dump_field(out, "client_info", this->client_info);
out.append(" client_info: ");
out.append(format_hex_pretty(this->client_info, this->client_info_len));
out.append("\n");
dump_field(out, "api_version_major", this->api_version_major);
dump_field(out, "api_version_minor", this->api_version_minor);
}
@@ -645,8 +685,18 @@ void HelloResponse::dump_to(std::string &out) const {
dump_field(out, "server_info", this->server_info_ref_);
dump_field(out, "name", this->name_ref_);
}
void ConnectRequest::dump_to(std::string &out) const { dump_field(out, "password", this->password); }
void ConnectResponse::dump_to(std::string &out) const { dump_field(out, "invalid_password", this->invalid_password); }
#ifdef USE_API_PASSWORD
void AuthenticationRequest::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "AuthenticationRequest");
out.append(" password: ");
out.append(format_hex_pretty(this->password, this->password_len));
out.append("\n");
}
void AuthenticationResponse::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "AuthenticationResponse");
dump_field(out, "invalid_password", this->invalid_password);
}
#endif
void DisconnectRequest::dump_to(std::string &out) const { out.append("DisconnectRequest {}"); }
void DisconnectResponse::dump_to(std::string &out) const { out.append("DisconnectResponse {}"); }
void PingRequest::dump_to(std::string &out) const { out.append("PingRequest {}"); }
@@ -725,6 +775,12 @@ void DeviceInfoResponse::dump_to(std::string &out) const {
this->area.dump_to(out);
out.append("\n");
#endif
#ifdef USE_ZWAVE_PROXY
dump_field(out, "zwave_proxy_feature_flags", this->zwave_proxy_feature_flags);
#endif
#ifdef USE_ZWAVE_PROXY
dump_field(out, "zwave_home_id", this->zwave_home_id);
#endif
}
void ListEntitiesRequest::dump_to(std::string &out) const { out.append("ListEntitiesRequest {}"); }
void ListEntitiesDoneResponse::dump_to(std::string &out) const { out.append("ListEntitiesDoneResponse {}"); }
@@ -1047,8 +1103,8 @@ void HomeassistantServiceMap::dump_to(std::string &out) const {
dump_field(out, "key", this->key_ref_);
dump_field(out, "value", this->value);
}
void HomeassistantServiceResponse::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "HomeassistantServiceResponse");
void HomeassistantActionRequest::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "HomeassistantActionRequest");
dump_field(out, "service", this->service_ref_);
for (const auto &it : this->data) {
out.append(" data: ");
@@ -1086,7 +1142,13 @@ void HomeAssistantStateResponse::dump_to(std::string &out) const {
}
#endif
void GetTimeRequest::dump_to(std::string &out) const { out.append("GetTimeRequest {}"); }
void GetTimeResponse::dump_to(std::string &out) const { dump_field(out, "epoch_seconds", this->epoch_seconds); }
void GetTimeResponse::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "GetTimeResponse");
dump_field(out, "epoch_seconds", this->epoch_seconds);
out.append(" timezone: ");
out.append(format_hex_pretty(this->timezone, this->timezone_len));
out.append("\n");
}
#ifdef USE_API_SERVICES
void ListEntitiesServicesArgument::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "ListEntitiesServicesArgument");
@@ -1111,7 +1173,7 @@ void ExecuteServiceArgument::dump_to(std::string &out) const {
dump_field(out, "string_", this->string_);
dump_field(out, "int_", this->int_);
for (const auto it : this->bool_array) {
dump_field(out, "bool_array", it, 4);
dump_field(out, "bool_array", static_cast<bool>(it), 4);
}
for (const auto &it : this->int_array) {
dump_field(out, "int_array", it, 4);
@@ -1466,6 +1528,7 @@ void ListEntitiesMediaPlayerResponse::dump_to(std::string &out) const {
#ifdef USE_DEVICES
dump_field(out, "device_id", this->device_id);
#endif
dump_field(out, "feature_flags", this->feature_flags);
}
void MediaPlayerStateResponse::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "MediaPlayerStateResponse");
@@ -1509,9 +1572,9 @@ void BluetoothLERawAdvertisement::dump_to(std::string &out) const {
}
void BluetoothLERawAdvertisementsResponse::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "BluetoothLERawAdvertisementsResponse");
for (const auto &it : this->advertisements) {
for (uint16_t i = 0; i < this->advertisements_len; i++) {
out.append(" advertisements: ");
it.dump_to(out);
this->advertisements[i].dump_to(out);
out.append("\n");
}
}
@@ -1536,6 +1599,7 @@ void BluetoothGATTDescriptor::dump_to(std::string &out) const {
dump_field(out, "uuid", it, 4);
}
dump_field(out, "handle", this->handle);
dump_field(out, "short_uuid", this->short_uuid);
}
void BluetoothGATTCharacteristic::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "BluetoothGATTCharacteristic");
@@ -1549,6 +1613,7 @@ void BluetoothGATTCharacteristic::dump_to(std::string &out) const {
it.dump_to(out);
out.append("\n");
}
dump_field(out, "short_uuid", this->short_uuid);
}
void BluetoothGATTService::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "BluetoothGATTService");
@@ -1561,6 +1626,7 @@ void BluetoothGATTService::dump_to(std::string &out) const {
it.dump_to(out);
out.append("\n");
}
dump_field(out, "short_uuid", this->short_uuid);
}
void BluetoothGATTGetServicesResponse::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "BluetoothGATTGetServicesResponse");
@@ -1594,7 +1660,7 @@ void BluetoothGATTWriteRequest::dump_to(std::string &out) const {
dump_field(out, "handle", this->handle);
dump_field(out, "response", this->response);
out.append(" data: ");
out.append(format_hex_pretty(reinterpret_cast<const uint8_t *>(this->data.data()), this->data.size()));
out.append(format_hex_pretty(this->data, this->data_len));
out.append("\n");
}
void BluetoothGATTReadDescriptorRequest::dump_to(std::string &out) const {
@@ -1607,7 +1673,7 @@ void BluetoothGATTWriteDescriptorRequest::dump_to(std::string &out) const {
dump_field(out, "address", this->address);
dump_field(out, "handle", this->handle);
out.append(" data: ");
out.append(format_hex_pretty(reinterpret_cast<const uint8_t *>(this->data.data()), this->data.size()));
out.append(format_hex_pretty(this->data, this->data_len));
out.append("\n");
}
void BluetoothGATTNotifyRequest::dump_to(std::string &out) const {
@@ -1676,6 +1742,7 @@ void BluetoothScannerStateResponse::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "BluetoothScannerStateResponse");
dump_field(out, "state", static_cast<enums::BluetoothScannerState>(this->state));
dump_field(out, "mode", static_cast<enums::BluetoothScannerMode>(this->mode));
dump_field(out, "configured_mode", static_cast<enums::BluetoothScannerMode>(this->configured_mode));
}
void BluetoothScannerSetModeRequest::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "BluetoothScannerSetModeRequest");
@@ -1759,8 +1826,25 @@ void VoiceAssistantWakeWord::dump_to(std::string &out) const {
dump_field(out, "trained_languages", it, 4);
}
}
void VoiceAssistantExternalWakeWord::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "VoiceAssistantExternalWakeWord");
dump_field(out, "id", this->id);
dump_field(out, "wake_word", this->wake_word);
for (const auto &it : this->trained_languages) {
dump_field(out, "trained_languages", it, 4);
}
dump_field(out, "model_type", this->model_type);
dump_field(out, "model_size", this->model_size);
dump_field(out, "model_hash", this->model_hash);
dump_field(out, "url", this->url);
}
void VoiceAssistantConfigurationRequest::dump_to(std::string &out) const {
out.append("VoiceAssistantConfigurationRequest {}");
MessageDumpHelper helper(out, "VoiceAssistantConfigurationRequest");
for (const auto &it : this->external_wake_words) {
out.append(" external_wake_words: ");
it.dump_to(out);
out.append("\n");
}
}
void VoiceAssistantConfigurationResponse::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "VoiceAssistantConfigurationResponse");
@@ -2069,6 +2153,21 @@ void UpdateCommandRequest::dump_to(std::string &out) const {
#endif
}
#endif
#ifdef USE_ZWAVE_PROXY
void ZWaveProxyFrame::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "ZWaveProxyFrame");
out.append(" data: ");
out.append(format_hex_pretty(this->data, this->data_len));
out.append("\n");
}
void ZWaveProxyRequest::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "ZWaveProxyRequest");
dump_field(out, "type", static_cast<enums::ZWaveProxyRequestType>(this->type));
out.append(" data: ");
out.append(format_hex_pretty(this->data, this->data_len));
out.append("\n");
}
#endif
} // namespace esphome::api

View File

@@ -1,5 +1,7 @@
#pragma once
#include "esphome/core/defines.h"
// This file provides includes needed by the generated protobuf code
// when using pointer optimizations for component-specific types
@@ -20,11 +22,13 @@
#include "esphome/components/select/select_traits.h"
#endif
#ifdef USE_MEDIA_PLAYER
#include "esphome/components/media_player/media_player_traits.h"
#endif
// Standard library includes that might be needed
#include <set>
#include <vector>
#include <string>
namespace esphome::api {
// This file only provides includes, no actual code
} // namespace esphome::api

View File

@@ -24,15 +24,17 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
this->on_hello_request(msg);
break;
}
case ConnectRequest::MESSAGE_TYPE: {
ConnectRequest msg;
#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_connect_request: %s", msg.dump().c_str());
ESP_LOGVV(TAG, "on_authentication_request: %s", msg.dump().c_str());
#endif
this->on_connect_request(msg);
this->on_authentication_request(msg);
break;
}
#endif
case DisconnectRequest::MESSAGE_TYPE: {
DisconnectRequest msg;
// Empty message: no decode needed
@@ -160,15 +162,6 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
break;
}
#endif
case GetTimeRequest::MESSAGE_TYPE: {
GetTimeRequest msg;
// Empty message: no decode needed
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_get_time_request: %s", msg.dump().c_str());
#endif
this->on_get_time_request(msg);
break;
}
case GetTimeResponse::MESSAGE_TYPE: {
GetTimeResponse msg;
msg.decode(msg_data, msg_size);
@@ -555,7 +548,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
#ifdef USE_VOICE_ASSISTANT
case VoiceAssistantConfigurationRequest::MESSAGE_TYPE: {
VoiceAssistantConfigurationRequest msg;
// Empty message: no decode needed
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_voice_assistant_configuration_request: %s", msg.dump().c_str());
#endif
@@ -595,6 +588,28 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
this->on_bluetooth_scanner_set_mode_request(msg);
break;
}
#endif
#ifdef USE_ZWAVE_PROXY
case ZWaveProxyFrame::MESSAGE_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());
#endif
this->on_z_wave_proxy_frame(msg);
break;
}
#endif
#ifdef USE_ZWAVE_PROXY
case ZWaveProxyRequest::MESSAGE_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());
#endif
this->on_z_wave_proxy_request(msg);
break;
}
#endif
default:
break;
@@ -606,11 +621,13 @@ void APIServerConnection::on_hello_request(const HelloRequest &msg) {
this->on_fatal_error();
}
}
void APIServerConnection::on_connect_request(const ConnectRequest &msg) {
if (!this->send_connect_response(msg)) {
#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();
@@ -622,246 +639,139 @@ void APIServerConnection::on_ping_request(const PingRequest &msg) {
}
}
void APIServerConnection::on_device_info_request(const DeviceInfoRequest &msg) {
if (this->check_connection_setup_() && !this->send_device_info_response(msg)) {
if (!this->send_device_info_response(msg)) {
this->on_fatal_error();
}
}
void APIServerConnection::on_list_entities_request(const ListEntitiesRequest &msg) {
if (this->check_authenticated_()) {
this->list_entities(msg);
}
}
void APIServerConnection::on_list_entities_request(const ListEntitiesRequest &msg) { this->list_entities(msg); }
void APIServerConnection::on_subscribe_states_request(const SubscribeStatesRequest &msg) {
if (this->check_authenticated_()) {
this->subscribe_states(msg);
}
}
void APIServerConnection::on_subscribe_logs_request(const SubscribeLogsRequest &msg) {
if (this->check_authenticated_()) {
this->subscribe_logs(msg);
}
this->subscribe_states(msg);
}
void APIServerConnection::on_subscribe_logs_request(const SubscribeLogsRequest &msg) { this->subscribe_logs(msg); }
#ifdef USE_API_HOMEASSISTANT_SERVICES
void APIServerConnection::on_subscribe_homeassistant_services_request(
const SubscribeHomeassistantServicesRequest &msg) {
if (this->check_authenticated_()) {
this->subscribe_homeassistant_services(msg);
}
this->subscribe_homeassistant_services(msg);
}
#endif
#ifdef USE_API_HOMEASSISTANT_STATES
void APIServerConnection::on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &msg) {
if (this->check_authenticated_()) {
this->subscribe_home_assistant_states(msg);
}
this->subscribe_home_assistant_states(msg);
}
#endif
void APIServerConnection::on_get_time_request(const GetTimeRequest &msg) {
if (this->check_connection_setup_() && !this->send_get_time_response(msg)) {
this->on_fatal_error();
}
}
#ifdef USE_API_SERVICES
void APIServerConnection::on_execute_service_request(const ExecuteServiceRequest &msg) {
if (this->check_authenticated_()) {
this->execute_service(msg);
}
}
void APIServerConnection::on_execute_service_request(const ExecuteServiceRequest &msg) { this->execute_service(msg); }
#endif
#ifdef USE_API_NOISE
void APIServerConnection::on_noise_encryption_set_key_request(const NoiseEncryptionSetKeyRequest &msg) {
if (this->check_authenticated_() && !this->send_noise_encryption_set_key_response(msg)) {
if (!this->send_noise_encryption_set_key_response(msg)) {
this->on_fatal_error();
}
}
#endif
#ifdef USE_BUTTON
void APIServerConnection::on_button_command_request(const ButtonCommandRequest &msg) {
if (this->check_authenticated_()) {
this->button_command(msg);
}
}
void APIServerConnection::on_button_command_request(const ButtonCommandRequest &msg) { this->button_command(msg); }
#endif
#ifdef USE_CAMERA
void APIServerConnection::on_camera_image_request(const CameraImageRequest &msg) {
if (this->check_authenticated_()) {
this->camera_image(msg);
}
}
void APIServerConnection::on_camera_image_request(const CameraImageRequest &msg) { this->camera_image(msg); }
#endif
#ifdef USE_CLIMATE
void APIServerConnection::on_climate_command_request(const ClimateCommandRequest &msg) {
if (this->check_authenticated_()) {
this->climate_command(msg);
}
}
void APIServerConnection::on_climate_command_request(const ClimateCommandRequest &msg) { this->climate_command(msg); }
#endif
#ifdef USE_COVER
void APIServerConnection::on_cover_command_request(const CoverCommandRequest &msg) {
if (this->check_authenticated_()) {
this->cover_command(msg);
}
}
void APIServerConnection::on_cover_command_request(const CoverCommandRequest &msg) { this->cover_command(msg); }
#endif
#ifdef USE_DATETIME_DATE
void APIServerConnection::on_date_command_request(const DateCommandRequest &msg) {
if (this->check_authenticated_()) {
this->date_command(msg);
}
}
void APIServerConnection::on_date_command_request(const DateCommandRequest &msg) { this->date_command(msg); }
#endif
#ifdef USE_DATETIME_DATETIME
void APIServerConnection::on_date_time_command_request(const DateTimeCommandRequest &msg) {
if (this->check_authenticated_()) {
this->datetime_command(msg);
}
this->datetime_command(msg);
}
#endif
#ifdef USE_FAN
void APIServerConnection::on_fan_command_request(const FanCommandRequest &msg) {
if (this->check_authenticated_()) {
this->fan_command(msg);
}
}
void APIServerConnection::on_fan_command_request(const FanCommandRequest &msg) { this->fan_command(msg); }
#endif
#ifdef USE_LIGHT
void APIServerConnection::on_light_command_request(const LightCommandRequest &msg) {
if (this->check_authenticated_()) {
this->light_command(msg);
}
}
void APIServerConnection::on_light_command_request(const LightCommandRequest &msg) { this->light_command(msg); }
#endif
#ifdef USE_LOCK
void APIServerConnection::on_lock_command_request(const LockCommandRequest &msg) {
if (this->check_authenticated_()) {
this->lock_command(msg);
}
}
void APIServerConnection::on_lock_command_request(const LockCommandRequest &msg) { this->lock_command(msg); }
#endif
#ifdef USE_MEDIA_PLAYER
void APIServerConnection::on_media_player_command_request(const MediaPlayerCommandRequest &msg) {
if (this->check_authenticated_()) {
this->media_player_command(msg);
}
this->media_player_command(msg);
}
#endif
#ifdef USE_NUMBER
void APIServerConnection::on_number_command_request(const NumberCommandRequest &msg) {
if (this->check_authenticated_()) {
this->number_command(msg);
}
}
void APIServerConnection::on_number_command_request(const NumberCommandRequest &msg) { this->number_command(msg); }
#endif
#ifdef USE_SELECT
void APIServerConnection::on_select_command_request(const SelectCommandRequest &msg) {
if (this->check_authenticated_()) {
this->select_command(msg);
}
}
void APIServerConnection::on_select_command_request(const SelectCommandRequest &msg) { this->select_command(msg); }
#endif
#ifdef USE_SIREN
void APIServerConnection::on_siren_command_request(const SirenCommandRequest &msg) {
if (this->check_authenticated_()) {
this->siren_command(msg);
}
}
void APIServerConnection::on_siren_command_request(const SirenCommandRequest &msg) { this->siren_command(msg); }
#endif
#ifdef USE_SWITCH
void APIServerConnection::on_switch_command_request(const SwitchCommandRequest &msg) {
if (this->check_authenticated_()) {
this->switch_command(msg);
}
}
void APIServerConnection::on_switch_command_request(const SwitchCommandRequest &msg) { this->switch_command(msg); }
#endif
#ifdef USE_TEXT
void APIServerConnection::on_text_command_request(const TextCommandRequest &msg) {
if (this->check_authenticated_()) {
this->text_command(msg);
}
}
void APIServerConnection::on_text_command_request(const TextCommandRequest &msg) { this->text_command(msg); }
#endif
#ifdef USE_DATETIME_TIME
void APIServerConnection::on_time_command_request(const TimeCommandRequest &msg) {
if (this->check_authenticated_()) {
this->time_command(msg);
}
}
void APIServerConnection::on_time_command_request(const TimeCommandRequest &msg) { this->time_command(msg); }
#endif
#ifdef USE_UPDATE
void APIServerConnection::on_update_command_request(const UpdateCommandRequest &msg) {
if (this->check_authenticated_()) {
this->update_command(msg);
}
}
void APIServerConnection::on_update_command_request(const UpdateCommandRequest &msg) { this->update_command(msg); }
#endif
#ifdef USE_VALVE
void APIServerConnection::on_valve_command_request(const ValveCommandRequest &msg) {
if (this->check_authenticated_()) {
this->valve_command(msg);
}
}
void APIServerConnection::on_valve_command_request(const ValveCommandRequest &msg) { this->valve_command(msg); }
#endif
#ifdef USE_BLUETOOTH_PROXY
void APIServerConnection::on_subscribe_bluetooth_le_advertisements_request(
const SubscribeBluetoothLEAdvertisementsRequest &msg) {
if (this->check_authenticated_()) {
this->subscribe_bluetooth_le_advertisements(msg);
}
this->subscribe_bluetooth_le_advertisements(msg);
}
#endif
#ifdef USE_BLUETOOTH_PROXY
void APIServerConnection::on_bluetooth_device_request(const BluetoothDeviceRequest &msg) {
if (this->check_authenticated_()) {
this->bluetooth_device_request(msg);
}
this->bluetooth_device_request(msg);
}
#endif
#ifdef USE_BLUETOOTH_PROXY
void APIServerConnection::on_bluetooth_gatt_get_services_request(const BluetoothGATTGetServicesRequest &msg) {
if (this->check_authenticated_()) {
this->bluetooth_gatt_get_services(msg);
}
this->bluetooth_gatt_get_services(msg);
}
#endif
#ifdef USE_BLUETOOTH_PROXY
void APIServerConnection::on_bluetooth_gatt_read_request(const BluetoothGATTReadRequest &msg) {
if (this->check_authenticated_()) {
this->bluetooth_gatt_read(msg);
}
this->bluetooth_gatt_read(msg);
}
#endif
#ifdef USE_BLUETOOTH_PROXY
void APIServerConnection::on_bluetooth_gatt_write_request(const BluetoothGATTWriteRequest &msg) {
if (this->check_authenticated_()) {
this->bluetooth_gatt_write(msg);
}
this->bluetooth_gatt_write(msg);
}
#endif
#ifdef USE_BLUETOOTH_PROXY
void APIServerConnection::on_bluetooth_gatt_read_descriptor_request(const BluetoothGATTReadDescriptorRequest &msg) {
if (this->check_authenticated_()) {
this->bluetooth_gatt_read_descriptor(msg);
}
this->bluetooth_gatt_read_descriptor(msg);
}
#endif
#ifdef USE_BLUETOOTH_PROXY
void APIServerConnection::on_bluetooth_gatt_write_descriptor_request(const BluetoothGATTWriteDescriptorRequest &msg) {
if (this->check_authenticated_()) {
this->bluetooth_gatt_write_descriptor(msg);
}
this->bluetooth_gatt_write_descriptor(msg);
}
#endif
#ifdef USE_BLUETOOTH_PROXY
void APIServerConnection::on_bluetooth_gatt_notify_request(const BluetoothGATTNotifyRequest &msg) {
if (this->check_authenticated_()) {
this->bluetooth_gatt_notify(msg);
}
this->bluetooth_gatt_notify(msg);
}
#endif
#ifdef USE_BLUETOOTH_PROXY
void APIServerConnection::on_subscribe_bluetooth_connections_free_request(
const SubscribeBluetoothConnectionsFreeRequest &msg) {
if (this->check_authenticated_() && !this->send_subscribe_bluetooth_connections_free_response(msg)) {
if (!this->send_subscribe_bluetooth_connections_free_response(msg)) {
this->on_fatal_error();
}
}
@@ -869,45 +779,68 @@ void APIServerConnection::on_subscribe_bluetooth_connections_free_request(
#ifdef USE_BLUETOOTH_PROXY
void APIServerConnection::on_unsubscribe_bluetooth_le_advertisements_request(
const UnsubscribeBluetoothLEAdvertisementsRequest &msg) {
if (this->check_authenticated_()) {
this->unsubscribe_bluetooth_le_advertisements(msg);
}
this->unsubscribe_bluetooth_le_advertisements(msg);
}
#endif
#ifdef USE_BLUETOOTH_PROXY
void APIServerConnection::on_bluetooth_scanner_set_mode_request(const BluetoothScannerSetModeRequest &msg) {
if (this->check_authenticated_()) {
this->bluetooth_scanner_set_mode(msg);
}
this->bluetooth_scanner_set_mode(msg);
}
#endif
#ifdef USE_VOICE_ASSISTANT
void APIServerConnection::on_subscribe_voice_assistant_request(const SubscribeVoiceAssistantRequest &msg) {
if (this->check_authenticated_()) {
this->subscribe_voice_assistant(msg);
}
this->subscribe_voice_assistant(msg);
}
#endif
#ifdef USE_VOICE_ASSISTANT
void APIServerConnection::on_voice_assistant_configuration_request(const VoiceAssistantConfigurationRequest &msg) {
if (this->check_authenticated_() && !this->send_voice_assistant_get_configuration_response(msg)) {
if (!this->send_voice_assistant_get_configuration_response(msg)) {
this->on_fatal_error();
}
}
#endif
#ifdef USE_VOICE_ASSISTANT
void APIServerConnection::on_voice_assistant_set_configuration(const VoiceAssistantSetConfiguration &msg) {
if (this->check_authenticated_()) {
this->voice_assistant_set_configuration(msg);
}
this->voice_assistant_set_configuration(msg);
}
#endif
#ifdef USE_ALARM_CONTROL_PANEL
void APIServerConnection::on_alarm_control_panel_command_request(const AlarmControlPanelCommandRequest &msg) {
if (this->check_authenticated_()) {
this->alarm_control_panel_command(msg);
}
this->alarm_control_panel_command(msg);
}
#endif
#ifdef USE_ZWAVE_PROXY
void APIServerConnection::on_z_wave_proxy_frame(const ZWaveProxyFrame &msg) { this->zwave_proxy_frame(msg); }
#endif
#ifdef USE_ZWAVE_PROXY
void APIServerConnection::on_z_wave_proxy_request(const ZWaveProxyRequest &msg) { this->zwave_proxy_request(msg); }
#endif
void APIServerConnection::read_message(uint32_t msg_size, uint32_t msg_type, 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 DisconnectRequest::MESSAGE_TYPE: // No setup required
case PingRequest::MESSAGE_TYPE: // No setup required
break; // Skip all checks for these messages
case DeviceInfoRequest::MESSAGE_TYPE: // Connection setup only
if (!this->check_connection_setup_()) {
return; // Connection not setup
}
break;
default:
// All other messages require authentication (which includes connection check)
if (!this->check_authenticated_()) {
return; // Authentication failed
}
break;
}
// Call base implementation to process the message
APIServerConnectionBase::read_message(msg_size, msg_type, msg_data);
}
} // namespace esphome::api

View File

@@ -26,7 +26,9 @@ class APIServerConnectionBase : public ProtoService {
virtual void on_hello_request(const HelloRequest &value){};
virtual void on_connect_request(const ConnectRequest &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){};
@@ -71,7 +73,7 @@ class APIServerConnectionBase : public ProtoService {
#ifdef USE_API_HOMEASSISTANT_STATES
virtual void on_home_assistant_state_response(const HomeAssistantStateResponse &value){};
#endif
virtual void on_get_time_request(const GetTimeRequest &value){};
virtual void on_get_time_response(const GetTimeResponse &value){};
#ifdef USE_API_SERVICES
@@ -205,6 +207,12 @@ class APIServerConnectionBase : public ProtoService {
#ifdef USE_UPDATE
virtual void on_update_command_request(const UpdateCommandRequest &value){};
#endif
#ifdef USE_ZWAVE_PROXY
virtual void on_z_wave_proxy_frame(const ZWaveProxyFrame &value){};
#endif
#ifdef USE_ZWAVE_PROXY
virtual void on_z_wave_proxy_request(const ZWaveProxyRequest &value){};
#endif
protected:
void read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) override;
@@ -213,7 +221,9 @@ class APIServerConnectionBase : public ProtoService {
class APIServerConnection : public APIServerConnectionBase {
public:
virtual bool send_hello_response(const HelloRequest &msg) = 0;
virtual bool send_connect_response(const ConnectRequest &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;
@@ -226,7 +236,6 @@ class APIServerConnection : public APIServerConnectionBase {
#ifdef USE_API_HOMEASSISTANT_STATES
virtual void subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) = 0;
#endif
virtual bool send_get_time_response(const GetTimeRequest &msg) = 0;
#ifdef USE_API_SERVICES
virtual void execute_service(const ExecuteServiceRequest &msg) = 0;
#endif
@@ -332,10 +341,18 @@ class APIServerConnection : public APIServerConnectionBase {
#endif
#ifdef USE_ALARM_CONTROL_PANEL
virtual void alarm_control_panel_command(const AlarmControlPanelCommandRequest &msg) = 0;
#endif
#ifdef USE_ZWAVE_PROXY
virtual void zwave_proxy_frame(const ZWaveProxyFrame &msg) = 0;
#endif
#ifdef USE_ZWAVE_PROXY
virtual void zwave_proxy_request(const ZWaveProxyRequest &msg) = 0;
#endif
protected:
void on_hello_request(const HelloRequest &msg) override;
void on_connect_request(const ConnectRequest &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;
@@ -348,7 +365,6 @@ class APIServerConnection : public APIServerConnectionBase {
#ifdef USE_API_HOMEASSISTANT_STATES
void on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &msg) override;
#endif
void on_get_time_request(const GetTimeRequest &msg) override;
#ifdef USE_API_SERVICES
void on_execute_service_request(const ExecuteServiceRequest &msg) override;
#endif
@@ -455,6 +471,13 @@ class APIServerConnection : public APIServerConnectionBase {
#ifdef USE_ALARM_CONTROL_PANEL
void on_alarm_control_panel_command_request(const AlarmControlPanelCommandRequest &msg) override;
#endif
#ifdef USE_ZWAVE_PROXY
void on_z_wave_proxy_frame(const ZWaveProxyFrame &msg) override;
#endif
#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;
};
} // namespace esphome::api

View File

@@ -37,12 +37,14 @@ void APIServer::setup() {
this->noise_pref_ = global_preferences->make_preference<SavedNoisePsk>(hash, true);
#ifndef USE_API_NOISE_PSK_FROM_YAML
// Only load saved PSK if not set from YAML
SavedNoisePsk noise_pref_saved{};
if (this->noise_pref_.load(&noise_pref_saved)) {
ESP_LOGD(TAG, "Loaded saved Noise PSK");
this->set_noise_psk(noise_pref_saved.psk);
}
#endif
#endif
// Schedule reboot if no clients connect within timeout
@@ -85,7 +87,7 @@ void APIServer::setup() {
return;
}
err = this->socket_->listen(4);
err = this->socket_->listen(this->listen_backlog_);
if (err != 0) {
ESP_LOGW(TAG, "Socket unable to listen: errno %d", errno);
this->mark_failed();
@@ -138,9 +140,19 @@ void APIServer::loop() {
while (true) {
struct sockaddr_storage source_addr;
socklen_t addr_len = sizeof(source_addr);
auto sock = this->socket_->accept_loop_monitored((struct sockaddr *) &source_addr, &addr_len);
if (!sock)
break;
// 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());
// Immediately close - socket destructor will handle cleanup
sock.reset();
continue;
}
ESP_LOGD(TAG, "Accept %s", sock->getpeername().c_str());
auto *conn = new APIConnection(std::move(sock), this);
@@ -165,7 +177,8 @@ void APIServer::loop() {
// Network is down - disconnect all clients
for (auto &client : this->clients_) {
client->on_fatal_error();
ESP_LOGW(TAG, "%s: Network down; disconnect", client->get_client_combined_info().c_str());
ESP_LOGW(TAG, "%s (%s): Network down; disconnect", client->client_info_.name.c_str(),
client->client_info_.peername.c_str());
}
// Continue to process and clean up the clients below
}
@@ -204,8 +217,10 @@ void APIServer::loop() {
void APIServer::dump_config() {
ESP_LOGCONFIG(TAG,
"Server:\n"
" Address: %s:%u",
network::get_use_address().c_str(), this->port_);
" Address: %s:%u\n"
" Listen backlog: %u\n"
" Max connections: %u",
network::get_use_address().c_str(), 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()) {
@@ -217,12 +232,12 @@ void APIServer::dump_config() {
}
#ifdef USE_API_PASSWORD
bool APIServer::check_password(const std::string &password) const {
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 = password.c_str();
uint32_t len_b = 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;
@@ -245,6 +260,7 @@ bool APIServer::check_password(const std::string &password) const {
return result == 0;
}
#endif
void APIServer::handle_disconnect(APIConnection *conn) {}
@@ -355,6 +371,15 @@ void APIServer::on_update(update::UpdateEntity *obj) {
}
#endif
#ifdef USE_ZWAVE_PROXY
void APIServer::on_zwave_proxy_request(const esphome::api::ProtoMessage &msg) {
// We could add code to manage a second subscription type, but, since this message type is
// very infrequent and small, we simply send it to all clients
for (auto &c : this->clients_)
c->send_message(msg, api::ZWaveProxyRequest::MESSAGE_TYPE);
}
#endif
#ifdef USE_ALARM_CONTROL_PANEL
API_DISPATCH_UPDATE(alarm_control_panel::AlarmControlPanel, alarm_control_panel)
#endif
@@ -370,9 +395,9 @@ void APIServer::set_password(const std::string &password) { this->password_ = pa
void APIServer::set_batch_delay(uint16_t batch_delay) { this->batch_delay_ = batch_delay; }
#ifdef USE_API_HOMEASSISTANT_SERVICES
void APIServer::send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
void APIServer::send_homeassistant_action(const HomeassistantActionRequest &call) {
for (auto &client : this->clients_) {
client->send_homeassistant_service_call(call);
client->send_homeassistant_action(call);
}
}
#endif
@@ -409,6 +434,12 @@ void APIServer::set_reboot_timeout(uint32_t reboot_timeout) { this->reboot_timeo
#ifdef USE_API_NOISE
bool APIServer::save_noise_psk(psk_t psk, bool make_active) {
#ifdef USE_API_NOISE_PSK_FROM_YAML
// When PSK is set from YAML, this function should never be called
// but if it is, reject the change
ESP_LOGW(TAG, "Key set in YAML");
return false;
#else
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");
@@ -437,6 +468,7 @@ bool APIServer::save_noise_psk(psk_t psk, bool make_active) {
});
}
return true;
#endif
}
#endif

View File

@@ -37,13 +37,15 @@ class APIServer : public Component, public Controller {
void on_shutdown() override;
bool teardown() override;
#ifdef USE_API_PASSWORD
bool check_password(const std::string &password) const;
bool check_password(const uint8_t *password_data, size_t password_len) const;
void set_password(const std::string &password);
#endif
void set_port(uint16_t port);
void set_reboot_timeout(uint32_t reboot_timeout);
void set_batch_delay(uint16_t batch_delay);
uint16_t get_batch_delay() const { return batch_delay_; }
void set_listen_backlog(uint8_t listen_backlog) { this->listen_backlog_ = listen_backlog; }
void set_max_connections(uint8_t max_connections) { this->max_connections_ = max_connections; }
// Get reference to shared buffer for API connections
std::vector<uint8_t> &get_shared_buffer_ref() { return shared_write_buffer_; }
@@ -107,7 +109,8 @@ class APIServer : public Component, public Controller {
void on_media_player_update(media_player::MediaPlayer *obj) override;
#endif
#ifdef USE_API_HOMEASSISTANT_SERVICES
void send_homeassistant_service_call(const HomeassistantServiceResponse &call);
void send_homeassistant_action(const HomeassistantActionRequest &call);
#endif
#ifdef USE_API_SERVICES
void register_user_service(UserServiceDescriptor *descriptor) { this->user_services_.push_back(descriptor); }
@@ -125,6 +128,9 @@ class APIServer : public Component, public Controller {
#ifdef USE_UPDATE
void on_update(update::UpdateEntity *obj) override;
#endif
#ifdef USE_ZWAVE_PROXY
void on_zwave_proxy_request(const esphome::api::ProtoMessage &msg);
#endif
bool is_connected() const;
@@ -185,8 +191,12 @@ class APIServer : public Component, public Controller {
// Group smaller types together
uint16_t port_{6053};
uint16_t batch_delay_{100};
// Connection limits - these defaults will be overridden by config values
// from cv.SplitDefault in __init__.py which sets platform-specific defaults
uint8_t listen_backlog_{4};
uint8_t max_connections_{8};
bool shutting_down_ = false;
// 5 bytes used, 3 bytes padding
// 7 bytes used, 1 byte padding
#ifdef USE_API_NOISE
std::shared_ptr<APINoiseContext> noise_ctx_ = std::make_shared<APINoiseContext>();

View File

@@ -30,7 +30,7 @@ if TYPE_CHECKING:
_LOGGER = logging.getLogger(__name__)
async def async_run_logs(config: dict[str, Any], address: str) -> None:
async def async_run_logs(config: dict[str, Any], addresses: list[str]) -> None:
"""Run the logs command in the event loop."""
conf = config["api"]
name = config["esphome"]["name"]
@@ -39,13 +39,21 @@ async def async_run_logs(config: dict[str, Any], address: str) -> None:
noise_psk: str | None = None
if (encryption := conf.get(CONF_ENCRYPTION)) and (key := encryption.get(CONF_KEY)):
noise_psk = key
_LOGGER.info("Starting log output from %s using esphome API", address)
if len(addresses) == 1:
_LOGGER.info("Starting log output from %s using esphome API", addresses[0])
else:
_LOGGER.info(
"Starting log output from %s using esphome API", " or ".join(addresses)
)
cli = APIClient(
address,
addresses[0], # Primary address for compatibility
port,
password,
client_info=f"ESPHome Logs {__version__}",
noise_psk=noise_psk,
addresses=addresses, # Pass all addresses for automatic retry
)
dashboard = CORE.dashboard
@@ -54,9 +62,11 @@ async def async_run_logs(config: dict[str, Any], address: str) -> None:
time_ = datetime.now()
message: bytes = msg.message
text = message.decode("utf8", "backslashreplace")
for parsed_msg in parse_log_message(
text, f"[{time_.hour:02}:{time_.minute:02}:{time_.second:02}]"
):
nanoseconds = time_.microsecond // 1000
timestamp = (
f"[{time_.hour:02}:{time_.minute:02}:{time_.second:02}.{nanoseconds:03}]"
)
for parsed_msg in parse_log_message(text, timestamp):
print(parsed_msg.replace("\033", "\\033") if dashboard else parsed_msg)
stop = await async_run(cli, on_log, name=name)
@@ -66,7 +76,7 @@ async def async_run_logs(config: dict[str, Any], address: str) -> None:
await stop()
def run_logs(config: dict[str, Any], address: str) -> None:
def run_logs(config: dict[str, Any], addresses: list[str]) -> None:
"""Run the logs command."""
with contextlib.suppress(KeyboardInterrupt):
asyncio.run(async_run_logs(config, address))
asyncio.run(async_run_logs(config, addresses))

View File

@@ -56,6 +56,14 @@ class CustomAPIDevice {
auto *service = new CustomAPIDeviceService<T, Ts...>(name, arg_names, (T *) this, callback); // NOLINT
global_api_server->register_user_service(service);
}
#else
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) {
static_assert(
sizeof(T) == 0,
"register_service() requires 'custom_services: true' in the 'api:' section of your YAML configuration");
}
#endif
/** Register a custom native API service that will show up in Home Assistant.
@@ -81,6 +89,12 @@ class CustomAPIDevice {
auto *service = new CustomAPIDeviceService<T>(name, {}, (T *) this, callback); // NOLINT
global_api_server->register_user_service(service);
}
#else
template<typename T> void register_service(void (T::*callback)(), const std::string &name) {
static_assert(
sizeof(T) == 0,
"register_service() requires 'custom_services: true' in the 'api:' section of your YAML configuration");
}
#endif
#ifdef USE_API_HOMEASSISTANT_STATES
@@ -135,6 +149,22 @@ class CustomAPIDevice {
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);
}
#else
template<typename T>
void subscribe_homeassistant_state(void (T::*callback)(std::string), 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 = "") {
static_assert(sizeof(T) == 0,
"subscribe_homeassistant_state() requires 'homeassistant_states: true' in the 'api:' section "
"of your YAML configuration");
}
#endif
#ifdef USE_API_HOMEASSISTANT_SERVICES
@@ -149,9 +179,9 @@ class CustomAPIDevice {
* @param service_name The service to call.
*/
void call_homeassistant_service(const std::string &service_name) {
HomeassistantServiceResponse resp;
HomeassistantActionRequest resp;
resp.set_service(StringRef(service_name));
global_api_server->send_homeassistant_service_call(resp);
global_api_server->send_homeassistant_action(resp);
}
/** Call a Home Assistant service from ESPHome.
@@ -169,7 +199,7 @@ class CustomAPIDevice {
* @param data The data for the service call, mapping from string to string.
*/
void call_homeassistant_service(const std::string &service_name, const std::map<std::string, std::string> &data) {
HomeassistantServiceResponse resp;
HomeassistantActionRequest resp;
resp.set_service(StringRef(service_name));
for (auto &it : data) {
resp.data.emplace_back();
@@ -177,7 +207,7 @@ class CustomAPIDevice {
kv.set_key(StringRef(it.first));
kv.value = it.second;
}
global_api_server->send_homeassistant_service_call(resp);
global_api_server->send_homeassistant_action(resp);
}
/** Fire an ESPHome event in Home Assistant.
@@ -191,10 +221,10 @@ class CustomAPIDevice {
* @param event_name The event to fire.
*/
void fire_homeassistant_event(const std::string &event_name) {
HomeassistantServiceResponse resp;
HomeassistantActionRequest resp;
resp.set_service(StringRef(event_name));
resp.is_event = true;
global_api_server->send_homeassistant_service_call(resp);
global_api_server->send_homeassistant_action(resp);
}
/** Fire an ESPHome event in Home Assistant.
@@ -211,7 +241,7 @@ class CustomAPIDevice {
* @param data The data for the event, mapping from string to string.
*/
void fire_homeassistant_event(const std::string &service_name, const std::map<std::string, std::string> &data) {
HomeassistantServiceResponse resp;
HomeassistantActionRequest resp;
resp.set_service(StringRef(service_name));
resp.is_event = true;
for (auto &it : data) {
@@ -220,7 +250,29 @@ class CustomAPIDevice {
kv.set_key(StringRef(it.first));
kv.value = it.second;
}
global_api_server->send_homeassistant_service_call(resp);
global_api_server->send_homeassistant_action(resp);
}
#else
template<typename T = void> void call_homeassistant_service(const std::string &service_name) {
static_assert(sizeof(T) == 0, "call_homeassistant_service() requires 'homeassistant_services: true' in the 'api:' "
"section of your YAML configuration");
}
template<typename T = void>
void call_homeassistant_service(const std::string &service_name, const std::map<std::string, std::string> &data) {
static_assert(sizeof(T) == 0, "call_homeassistant_service() requires 'homeassistant_services: true' in the 'api:' "
"section of your YAML configuration");
}
template<typename T = void> void fire_homeassistant_event(const std::string &event_name) {
static_assert(sizeof(T) == 0, "fire_homeassistant_event() requires 'homeassistant_services: true' in the 'api:' "
"section of your YAML configuration");
}
template<typename T = void>
void fire_homeassistant_event(const std::string &service_name, const std::map<std::string, std::string> &data) {
static_assert(sizeof(T) == 0, "fire_homeassistant_event() requires 'homeassistant_services: true' in the 'api:' "
"section of your YAML configuration");
}
#endif
};

View File

@@ -3,10 +3,10 @@
#include "api_server.h"
#ifdef USE_API
#ifdef USE_API_HOMEASSISTANT_SERVICES
#include <vector>
#include "api_pb2.h"
#include "esphome/core/automation.h"
#include "esphome/core/helpers.h"
#include <vector>
namespace esphome::api {
@@ -62,7 +62,7 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
}
void play(Ts... x) override {
HomeassistantServiceResponse resp;
HomeassistantActionRequest resp;
std::string service_value = this->service_.value(x...);
resp.set_service(StringRef(service_value));
resp.is_event = this->is_event_;
@@ -84,7 +84,7 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
kv.set_key(StringRef(it.key));
kv.value = it.value.value(x...);
}
this->parent_->send_homeassistant_service_call(resp);
this->parent_->send_homeassistant_action(resp);
}
protected:

View File

@@ -8,74 +8,70 @@ namespace esphome::api {
static const char *const TAG = "api.proto";
void ProtoDecodableMessage::decode(const uint8_t *buffer, size_t length) {
uint32_t i = 0;
bool error = false;
while (i < length) {
const uint8_t *ptr = buffer;
const uint8_t *end = buffer + length;
while (ptr < end) {
uint32_t consumed;
auto res = ProtoVarInt::parse(&buffer[i], length - i, &consumed);
// Parse field header
auto res = ProtoVarInt::parse(ptr, end - ptr, &consumed);
if (!res.has_value()) {
ESP_LOGV(TAG, "Invalid field start at %" PRIu32, i);
break;
ESP_LOGV(TAG, "Invalid field start at offset %ld", (long) (ptr - buffer));
return;
}
uint32_t field_type = (res->as_uint32()) & 0b111;
uint32_t field_id = (res->as_uint32()) >> 3;
i += consumed;
uint32_t tag = res->as_uint32();
uint32_t field_type = tag & 0b111;
uint32_t field_id = tag >> 3;
ptr += consumed;
switch (field_type) {
case 0: { // VarInt
res = ProtoVarInt::parse(&buffer[i], length - i, &consumed);
res = ProtoVarInt::parse(ptr, end - ptr, &consumed);
if (!res.has_value()) {
ESP_LOGV(TAG, "Invalid VarInt at %" PRIu32, i);
error = true;
break;
ESP_LOGV(TAG, "Invalid VarInt at offset %ld", (long) (ptr - buffer));
return;
}
if (!this->decode_varint(field_id, *res)) {
ESP_LOGV(TAG, "Cannot decode VarInt field %" PRIu32 " with value %" PRIu32 "!", field_id, res->as_uint32());
}
i += consumed;
ptr += consumed;
break;
}
case 2: { // Length-delimited
res = ProtoVarInt::parse(&buffer[i], length - i, &consumed);
res = ProtoVarInt::parse(ptr, end - ptr, &consumed);
if (!res.has_value()) {
ESP_LOGV(TAG, "Invalid Length Delimited at %" PRIu32, i);
error = true;
break;
ESP_LOGV(TAG, "Invalid Length Delimited at offset %ld", (long) (ptr - buffer));
return;
}
uint32_t field_length = res->as_uint32();
i += consumed;
if (field_length > length - i) {
ESP_LOGV(TAG, "Out-of-bounds Length Delimited at %" PRIu32, i);
error = true;
break;
ptr += consumed;
if (ptr + field_length > end) {
ESP_LOGV(TAG, "Out-of-bounds Length Delimited at offset %ld", (long) (ptr - buffer));
return;
}
if (!this->decode_length(field_id, ProtoLengthDelimited(&buffer[i], field_length))) {
if (!this->decode_length(field_id, ProtoLengthDelimited(ptr, field_length))) {
ESP_LOGV(TAG, "Cannot decode Length Delimited field %" PRIu32 "!", field_id);
}
i += field_length;
ptr += field_length;
break;
}
case 5: { // 32-bit
if (length - i < 4) {
ESP_LOGV(TAG, "Out-of-bounds Fixed32-bit at %" PRIu32, i);
error = true;
break;
if (ptr + 4 > end) {
ESP_LOGV(TAG, "Out-of-bounds Fixed32-bit at offset %ld", (long) (ptr - buffer));
return;
}
uint32_t val = encode_uint32(buffer[i + 3], buffer[i + 2], buffer[i + 1], buffer[i]);
uint32_t val = encode_uint32(ptr[3], ptr[2], ptr[1], ptr[0]);
if (!this->decode_32bit(field_id, Proto32Bit(val))) {
ESP_LOGV(TAG, "Cannot decode 32-bit field %" PRIu32 " with value %" PRIu32 "!", field_id, val);
}
i += 4;
ptr += 4;
break;
}
default:
ESP_LOGV(TAG, "Invalid field type at %" PRIu32, i);
error = true;
break;
}
if (error) {
break;
ESP_LOGV(TAG, "Invalid field type %u at offset %ld", field_type, (long) (ptr - buffer));
return;
}
}
}

View File

@@ -15,6 +15,23 @@
namespace esphome::api {
// Helper functions for ZigZag encoding/decoding
inline constexpr uint32_t encode_zigzag32(int32_t value) {
return (static_cast<uint32_t>(value) << 1) ^ (static_cast<uint32_t>(value >> 31));
}
inline constexpr uint64_t encode_zigzag64(int64_t value) {
return (static_cast<uint64_t>(value) << 1) ^ (static_cast<uint64_t>(value >> 63));
}
inline constexpr int32_t decode_zigzag32(uint32_t value) {
return (value & 1) ? static_cast<int32_t>(~(value >> 1)) : static_cast<int32_t>(value >> 1);
}
inline constexpr int64_t decode_zigzag64(uint64_t value) {
return (value & 1) ? static_cast<int64_t>(~(value >> 1)) : static_cast<int64_t>(value >> 1);
}
/*
* StringRef Ownership Model for API Protocol Messages
* ===================================================
@@ -87,33 +104,25 @@ class ProtoVarInt {
return {}; // Incomplete or invalid varint
}
uint16_t as_uint16() const { return this->value_; }
uint32_t as_uint32() const { return this->value_; }
uint64_t as_uint64() const { return this->value_; }
bool as_bool() const { return this->value_; }
int32_t as_int32() const {
constexpr uint16_t as_uint16() const { return this->value_; }
constexpr uint32_t as_uint32() const { return this->value_; }
constexpr uint64_t as_uint64() const { return this->value_; }
constexpr bool as_bool() const { return this->value_; }
constexpr int32_t as_int32() const {
// Not ZigZag encoded
return static_cast<int32_t>(this->as_int64());
}
int64_t as_int64() const {
constexpr int64_t as_int64() const {
// Not ZigZag encoded
return static_cast<int64_t>(this->value_);
}
int32_t as_sint32() const {
constexpr int32_t as_sint32() const {
// with ZigZag encoding
if (this->value_ & 1) {
return static_cast<int32_t>(~(this->value_ >> 1));
} else {
return static_cast<int32_t>(this->value_ >> 1);
}
return decode_zigzag32(static_cast<uint32_t>(this->value_));
}
int64_t as_sint64() const {
constexpr int64_t as_sint64() const {
// with ZigZag encoding
if (this->value_ & 1) {
return static_cast<int64_t>(~(this->value_ >> 1));
} else {
return static_cast<int64_t>(this->value_ >> 1);
}
return decode_zigzag64(this->value_);
}
/**
* Encode the varint value to a pre-allocated buffer without bounds checking.
@@ -173,6 +182,10 @@ class ProtoLengthDelimited {
explicit ProtoLengthDelimited(const uint8_t *value, size_t length) : value_(value), length_(length) {}
std::string as_string() const { return std::string(reinterpret_cast<const char *>(this->value_), this->length_); }
// Direct access to raw data without string allocation
const uint8_t *data() const { return this->value_; }
size_t size() const { return this->length_; }
/**
* Decode the length-delimited data into an existing ProtoDecodableMessage instance.
*
@@ -309,22 +322,10 @@ class ProtoWriteBuffer {
this->encode_uint64(field_id, static_cast<uint64_t>(value), force);
}
void encode_sint32(uint32_t field_id, int32_t value, bool force = false) {
uint32_t uvalue;
if (value < 0) {
uvalue = ~(value << 1);
} else {
uvalue = value << 1;
}
this->encode_uint32(field_id, uvalue, force);
this->encode_uint32(field_id, encode_zigzag32(value), force);
}
void encode_sint64(uint32_t field_id, int64_t value, bool force = false) {
uint64_t uvalue;
if (value < 0) {
uvalue = ~(value << 1);
} else {
uvalue = value << 1;
}
this->encode_uint64(field_id, uvalue, force);
this->encode_uint64(field_id, encode_zigzag64(value), force);
}
void encode_message(uint32_t field_id, const ProtoMessage &value, bool force = false);
std::vector<uint8_t> *get_buffer() const { return buffer_; }
@@ -395,7 +396,7 @@ class ProtoSize {
* @param value The uint32_t value to calculate size for
* @return The number of bytes needed to encode the value
*/
static inline uint32_t varint(uint32_t value) {
static constexpr uint32_t varint(uint32_t value) {
// Optimized varint size calculation using leading zeros
// Each 7 bits requires one byte in the varint encoding
if (value < 128)
@@ -419,7 +420,7 @@ class ProtoSize {
* @param value The uint64_t value to calculate size for
* @return The number of bytes needed to encode the value
*/
static inline uint32_t varint(uint64_t value) {
static constexpr uint32_t varint(uint64_t value) {
// Handle common case of values fitting in uint32_t (vast majority of use cases)
if (value <= UINT32_MAX) {
return varint(static_cast<uint32_t>(value));
@@ -450,7 +451,7 @@ class ProtoSize {
* @param value The int32_t value to calculate size for
* @return The number of bytes needed to encode the value
*/
static inline uint32_t varint(int32_t value) {
static constexpr uint32_t varint(int32_t value) {
// Negative values are sign-extended to 64 bits in protocol buffers,
// which always results in a 10-byte varint for negative int32
if (value < 0) {
@@ -466,7 +467,7 @@ class ProtoSize {
* @param value The int64_t value to calculate size for
* @return The number of bytes needed to encode the value
*/
static inline uint32_t varint(int64_t value) {
static constexpr uint32_t varint(int64_t value) {
// For int64_t, we convert to uint64_t and calculate the size
// This works because the bit pattern determines the encoding size,
// and we've handled negative int32 values as a special case above
@@ -480,7 +481,7 @@ class ProtoSize {
* @param type The wire type value (from the WireType enum in the protobuf spec)
* @return The number of bytes needed to encode the field ID and wire type
*/
static inline uint32_t field(uint32_t field_id, uint32_t type) {
static constexpr uint32_t field(uint32_t field_id, uint32_t type) {
uint32_t tag = (field_id << 3) | (type & 0b111);
return varint(tag);
}
@@ -607,9 +608,8 @@ class ProtoSize {
*/
inline void add_sint32_force(uint32_t field_id_size, int32_t value) {
// Always calculate size when force is true
// ZigZag encoding for sint32: (n << 1) ^ (n >> 31)
uint32_t zigzag = (static_cast<uint32_t>(value) << 1) ^ (static_cast<uint32_t>(value >> 31));
total_size_ += field_id_size + varint(zigzag);
// ZigZag encoding for sint32
total_size_ += field_id_size + varint(encode_zigzag32(value));
}
/**
@@ -831,7 +831,7 @@ class ProtoService {
}
// Authentication helper methods
bool check_connection_setup_() {
inline bool check_connection_setup_() {
if (!this->is_connection_setup()) {
this->on_no_setup_connection();
return false;
@@ -839,7 +839,7 @@ class ProtoService {
return true;
}
bool check_authenticated_() {
inline bool check_authenticated_() {
#ifdef USE_API_PASSWORD
if (!this->check_connection_setup_()) {
return false;

View File

@@ -55,7 +55,7 @@ template<typename... Ts> class UserServiceBase : public UserServiceDescriptor {
protected:
virtual void execute(Ts... x) = 0;
template<int... S> void execute_(std::vector<ExecuteServiceArgument> args, seq<S...> type) {
template<int... S> void execute_(const std::vector<ExecuteServiceArgument> &args, seq<S...> type) {
this->execute((get_execute_arg_value<Ts>(args[S]))...);
}

View File

@@ -7,6 +7,7 @@ from esphome.const import (
CONF_DIRECTION,
CONF_HYSTERESIS,
CONF_ID,
CONF_POWER_MODE,
CONF_RANGE,
)
@@ -57,7 +58,6 @@ FAST_FILTER = {
CONF_RAW_ANGLE = "raw_angle"
CONF_RAW_POSITION = "raw_position"
CONF_WATCHDOG = "watchdog"
CONF_POWER_MODE = "power_mode"
CONF_SLOW_FILTER = "slow_filter"
CONF_FAST_FILTER = "fast_filter"
CONF_START_POSITION = "start_position"

View File

@@ -24,7 +24,6 @@ AS5600Sensor = as5600_ns.class_("AS5600Sensor", sensor.Sensor, cg.PollingCompone
CONF_RAW_ANGLE = "raw_angle"
CONF_RAW_POSITION = "raw_position"
CONF_WATCHDOG = "watchdog"
CONF_POWER_MODE = "power_mode"
CONF_SLOW_FILTER = "slow_filter"
CONF_FAST_FILTER = "fast_filter"
CONF_PWM_FREQUENCY = "pwm_frequency"

View File

@@ -2,6 +2,7 @@ import esphome.codegen as cg
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_CLEAR,
CONF_GAIN,
CONF_ID,
DEVICE_CLASS_ILLUMINANCE,
@@ -29,7 +30,6 @@ CONF_F5 = "f5"
CONF_F6 = "f6"
CONF_F7 = "f7"
CONF_F8 = "f8"
CONF_CLEAR = "clear"
CONF_NIR = "nir"
UNIT_COUNTS = "#"

View File

@@ -8,9 +8,9 @@ from esphome.const import (
PLATFORM_LN882X,
PLATFORM_RTL87XX,
)
from esphome.core import CORE, coroutine_with_priority
from esphome.core import CORE, CoroPriority, coroutine_with_priority
CODEOWNERS = ["@OttoWinter"]
CODEOWNERS = ["@esphome/core"]
CONFIG_SCHEMA = cv.All(
cv.Schema({}),
@@ -27,7 +27,7 @@ CONFIG_SCHEMA = cv.All(
)
@coroutine_with_priority(200.0)
@coroutine_with_priority(CoroPriority.NETWORK_TRANSPORT)
async def to_code(config):
if CORE.is_esp32 or CORE.is_libretiny:
# https://github.com/ESP32Async/AsyncTCP

View File

@@ -16,6 +16,7 @@ from esphome.const import (
DEVICE_CLASS_ENERGY,
DEVICE_CLASS_POWER,
DEVICE_CLASS_POWER_FACTOR,
DEVICE_CLASS_REACTIVE_POWER,
DEVICE_CLASS_VOLTAGE,
ICON_CURRENT_AC,
ICON_LIGHTBULB,
@@ -78,6 +79,7 @@ CONFIG_SCHEMA = (
unit_of_measurement=UNIT_VOLT_AMPS_REACTIVE,
icon=ICON_LIGHTBULB,
accuracy_decimals=2,
device_class=DEVICE_CLASS_REACTIVE_POWER,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_POWER_FACTOR): sensor.sensor_schema(

View File

@@ -110,6 +110,8 @@ void ATM90E32Component::update() {
void ATM90E32Component::setup() {
this->spi_setup();
this->cs_summary_ = this->cs_->dump_summary();
const char *cs = this->cs_summary_.c_str();
uint16_t mmode0 = 0x87; // 3P4W 50Hz
uint16_t high_thresh = 0;
@@ -130,9 +132,9 @@ void ATM90E32Component::setup() {
mmode0 |= 0 << 1; // sets 1st bit to 0, phase b is not counted into the all-phase sum energy/power (P/Q/S)
}
this->write16_(ATM90E32_REGISTER_SOFTRESET, 0x789A); // Perform soft reset
delay(6); // Wait for the minimum 5ms + 1ms
this->write16_(ATM90E32_REGISTER_CFGREGACCEN, 0x55AA); // enable register config access
this->write16_(ATM90E32_REGISTER_SOFTRESET, 0x789A, false); // Perform soft reset
delay(6); // Wait for the minimum 5ms + 1ms
this->write16_(ATM90E32_REGISTER_CFGREGACCEN, 0x55AA); // enable register config access
if (!this->validate_spi_read_(0x55AA, "setup()")) {
ESP_LOGW(TAG, "Could not initialize ATM90E32 IC, check SPI settings");
this->mark_failed();
@@ -156,16 +158,17 @@ void ATM90E32Component::setup() {
if (this->enable_offset_calibration_) {
// Initialize flash storage for offset calibrations
uint32_t o_hash = fnv1_hash(std::string("_offset_calibration_") + this->cs_->dump_summary());
uint32_t o_hash = fnv1_hash(std::string("_offset_calibration_") + this->cs_summary_);
this->offset_pref_ = global_preferences->make_preference<OffsetCalibration[3]>(o_hash, true);
this->restore_offset_calibrations_();
// Initialize flash storage for power offset calibrations
uint32_t po_hash = fnv1_hash(std::string("_power_offset_calibration_") + this->cs_->dump_summary());
uint32_t po_hash = fnv1_hash(std::string("_power_offset_calibration_") + this->cs_summary_);
this->power_offset_pref_ = global_preferences->make_preference<PowerOffsetCalibration[3]>(po_hash, true);
this->restore_power_offset_calibrations_();
} else {
ESP_LOGI(TAG, "[CALIBRATION] Power & Voltage/Current offset calibration is disabled. Using config file values.");
ESP_LOGI(TAG, "[CALIBRATION][%s] Power & Voltage/Current offset calibration is disabled. Using config file values.",
cs);
for (uint8_t phase = 0; phase < 3; ++phase) {
this->write16_(this->voltage_offset_registers[phase],
static_cast<uint16_t>(this->offset_phase_[phase].voltage_offset_));
@@ -180,21 +183,18 @@ void ATM90E32Component::setup() {
if (this->enable_gain_calibration_) {
// Initialize flash storage for gain calibration
uint32_t g_hash = fnv1_hash(std::string("_gain_calibration_") + this->cs_->dump_summary());
uint32_t g_hash = fnv1_hash(std::string("_gain_calibration_") + this->cs_summary_);
this->gain_calibration_pref_ = global_preferences->make_preference<GainCalibration[3]>(g_hash, true);
this->restore_gain_calibrations_();
if (this->using_saved_calibrations_) {
ESP_LOGI(TAG, "[CALIBRATION] Successfully restored gain calibration from memory.");
} else {
if (!this->using_saved_calibrations_) {
for (uint8_t phase = 0; phase < 3; ++phase) {
this->write16_(voltage_gain_registers[phase], this->phase_[phase].voltage_gain_);
this->write16_(current_gain_registers[phase], this->phase_[phase].ct_gain_);
}
}
} else {
ESP_LOGI(TAG, "[CALIBRATION] Gain calibration is disabled. Using config file values.");
ESP_LOGI(TAG, "[CALIBRATION][%s] Gain calibration is disabled. Using config file values.", cs);
for (uint8_t phase = 0; phase < 3; ++phase) {
this->write16_(voltage_gain_registers[phase], this->phase_[phase].voltage_gain_);
this->write16_(current_gain_registers[phase], this->phase_[phase].ct_gain_);
@@ -213,6 +213,122 @@ void ATM90E32Component::setup() {
this->write16_(ATM90E32_REGISTER_CFGREGACCEN, 0x0000); // end configuration
}
void ATM90E32Component::log_calibration_status_() {
const char *cs = this->cs_summary_.c_str();
bool offset_mismatch = false;
bool power_mismatch = false;
bool gain_mismatch = false;
for (uint8_t phase = 0; phase < 3; ++phase) {
offset_mismatch |= this->offset_calibration_mismatch_[phase];
power_mismatch |= this->power_offset_calibration_mismatch_[phase];
gain_mismatch |= this->gain_calibration_mismatch_[phase];
}
if (offset_mismatch) {
ESP_LOGW(TAG, "[CALIBRATION][%s] ", cs);
ESP_LOGW(TAG,
"[CALIBRATION][%s] ===================== Offset mismatch: using flash values =====================", cs);
ESP_LOGW(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------------------",
cs);
ESP_LOGW(TAG, "[CALIBRATION][%s] | Phase | offset_voltage | offset_current |", cs);
ESP_LOGW(TAG, "[CALIBRATION][%s] | | config | flash | config | flash |", cs);
ESP_LOGW(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------------------",
cs);
for (uint8_t phase = 0; phase < 3; ++phase) {
ESP_LOGW(TAG, "[CALIBRATION][%s] | %c | %6d | %6d | %6d | %6d |", cs, 'A' + phase,
this->config_offset_phase_[phase].voltage_offset_, this->offset_phase_[phase].voltage_offset_,
this->config_offset_phase_[phase].current_offset_, this->offset_phase_[phase].current_offset_);
}
ESP_LOGW(TAG,
"[CALIBRATION][%s] ===============================================================================", cs);
}
if (power_mismatch) {
ESP_LOGW(TAG, "[CALIBRATION][%s] ", cs);
ESP_LOGW(TAG,
"[CALIBRATION][%s] ================= Power offset mismatch: using flash values =================", cs);
ESP_LOGW(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------------------",
cs);
ESP_LOGW(TAG, "[CALIBRATION][%s] | Phase | offset_active_power|offset_reactive_power|", cs);
ESP_LOGW(TAG, "[CALIBRATION][%s] | | config | flash | config | flash |", cs);
ESP_LOGW(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------------------",
cs);
for (uint8_t phase = 0; phase < 3; ++phase) {
ESP_LOGW(TAG, "[CALIBRATION][%s] | %c | %6d | %6d | %6d | %6d |", cs, 'A' + phase,
this->config_power_offset_phase_[phase].active_power_offset,
this->power_offset_phase_[phase].active_power_offset,
this->config_power_offset_phase_[phase].reactive_power_offset,
this->power_offset_phase_[phase].reactive_power_offset);
}
ESP_LOGW(TAG,
"[CALIBRATION][%s] ===============================================================================", cs);
}
if (gain_mismatch) {
ESP_LOGW(TAG, "[CALIBRATION][%s] ", cs);
ESP_LOGW(TAG,
"[CALIBRATION][%s] ====================== Gain mismatch: using flash values =====================", cs);
ESP_LOGW(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------------------",
cs);
ESP_LOGW(TAG, "[CALIBRATION][%s] | Phase | voltage_gain | current_gain |", cs);
ESP_LOGW(TAG, "[CALIBRATION][%s] | | config | flash | config | flash |", cs);
ESP_LOGW(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------------------",
cs);
for (uint8_t phase = 0; phase < 3; ++phase) {
ESP_LOGW(TAG, "[CALIBRATION][%s] | %c | %6u | %6u | %6u | %6u |", cs, 'A' + phase,
this->config_gain_phase_[phase].voltage_gain, this->gain_phase_[phase].voltage_gain,
this->config_gain_phase_[phase].current_gain, this->gain_phase_[phase].current_gain);
}
ESP_LOGW(TAG,
"[CALIBRATION][%s] ===============================================================================", cs);
}
if (!this->enable_offset_calibration_) {
ESP_LOGI(TAG, "[CALIBRATION][%s] Power & Voltage/Current offset calibration is disabled. Using config file values.",
cs);
} else if (this->restored_offset_calibration_ && !offset_mismatch) {
ESP_LOGI(TAG, "[CALIBRATION][%s] ", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ============== Restored offset calibration from memory ==============", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] --------------------------------------------------------------", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_voltage | offset_current |", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] --------------------------------------------------------------", cs);
for (uint8_t phase = 0; phase < 3; phase++) {
ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase,
this->offset_phase_[phase].voltage_offset_, this->offset_phase_[phase].current_offset_);
}
ESP_LOGI(TAG, "[CALIBRATION][%s] ==============================================================\\n", cs);
}
if (this->restored_power_offset_calibration_ && !power_mismatch) {
ESP_LOGI(TAG, "[CALIBRATION][%s] ", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ============ Restored power offset calibration from memory ============", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_active_power | offset_reactive_power |", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
for (uint8_t phase = 0; phase < 3; phase++) {
ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase,
this->power_offset_phase_[phase].active_power_offset,
this->power_offset_phase_[phase].reactive_power_offset);
}
ESP_LOGI(TAG, "[CALIBRATION][%s] =====================================================================\n", cs);
}
if (!this->enable_gain_calibration_) {
ESP_LOGI(TAG, "[CALIBRATION][%s] Gain calibration is disabled. Using config file values.", cs);
} else if (this->restored_gain_calibration_ && !gain_mismatch) {
ESP_LOGI(TAG, "[CALIBRATION][%s] ", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ============ Restoring saved gain calibrations to registers ============", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | voltage_gain | current_gain |", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
for (uint8_t phase = 0; phase < 3; phase++) {
ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6u | %6u |", cs, 'A' + phase,
this->gain_phase_[phase].voltage_gain, this->gain_phase_[phase].current_gain);
}
ESP_LOGI(TAG, "[CALIBRATION][%s] =====================================================================\\n", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] Gain calibration loaded and verified successfully.\n", cs);
}
this->calibration_message_printed_ = true;
}
void ATM90E32Component::dump_config() {
ESP_LOGCONFIG("", "ATM90E32:");
LOG_PIN(" CS Pin: ", this->cs_);
@@ -255,6 +371,10 @@ void ATM90E32Component::dump_config() {
LOG_SENSOR(" ", "Peak Current C", this->phase_[PHASEC].peak_current_sensor_);
LOG_SENSOR(" ", "Frequency", this->freq_sensor_);
LOG_SENSOR(" ", "Chip Temp", this->chip_temperature_sensor_);
if (this->restored_offset_calibration_ || this->restored_power_offset_calibration_ ||
this->restored_gain_calibration_ || !this->enable_offset_calibration_ || !this->enable_gain_calibration_) {
this->log_calibration_status_();
}
}
float ATM90E32Component::get_setup_priority() const { return setup_priority::IO; }
@@ -263,19 +383,17 @@ float ATM90E32Component::get_setup_priority() const { return setup_priority::IO;
// Peakdetect period: 05H. Bit 15:8 are PeakDet_period in ms. 7:0 are Sag_period
// Default is 143FH (20ms, 63ms)
uint16_t ATM90E32Component::read16_(uint16_t a_register) {
this->enable();
delay_microseconds_safe(1); // min delay between CS low and first SCK is 200ns - 1us is plenty
uint8_t addrh = (1 << 7) | ((a_register >> 8) & 0x03);
uint8_t addrl = (a_register & 0xFF);
uint8_t data[2];
uint16_t output;
this->enable();
delay_microseconds_safe(1); // min delay between CS low and first SCK is 200ns - 1ms is plenty
this->write_byte(addrh);
this->write_byte(addrl);
this->read_array(data, 2);
this->disable();
output = (uint16_t(data[0] & 0xFF) << 8) | (data[1] & 0xFF);
uint8_t data[4] = {addrh, addrl, 0x00, 0x00};
this->transfer_array(data, 4);
uint16_t output = encode_uint16(data[2], data[3]);
ESP_LOGVV(TAG, "read16_ 0x%04" PRIX16 " output 0x%04" PRIX16, a_register, output);
delay_microseconds_safe(1); // allow the last clock to propagate before releasing CS
this->disable();
delay_microseconds_safe(1); // meet minimum CS high time before next transaction
return output;
}
@@ -292,13 +410,19 @@ int ATM90E32Component::read32_(uint16_t addr_h, uint16_t addr_l) {
return val;
}
void ATM90E32Component::write16_(uint16_t a_register, uint16_t val) {
void ATM90E32Component::write16_(uint16_t a_register, uint16_t val, bool validate) {
ESP_LOGVV(TAG, "write16_ 0x%04" PRIX16 " val 0x%04" PRIX16, a_register, val);
uint8_t addrh = ((a_register >> 8) & 0x03);
uint8_t addrl = (a_register & 0xFF);
uint8_t data[4] = {addrh, addrl, uint8_t((val >> 8) & 0xFF), uint8_t(val & 0xFF)};
this->enable();
this->write_byte16(a_register);
this->write_byte16(val);
delay_microseconds_safe(1); // ensure CS setup time
this->write_array(data, 4);
delay_microseconds_safe(1); // allow clock to settle before raising CS
this->disable();
this->validate_spi_read_(val, "write16()");
delay_microseconds_safe(1); // ensure minimum CS high time
if (validate)
this->validate_spi_read_(val, "write16()");
}
float ATM90E32Component::get_local_phase_voltage_(uint8_t phase) { return this->phase_[phase].voltage_; }
@@ -441,8 +565,10 @@ float ATM90E32Component::get_chip_temperature_() {
}
void ATM90E32Component::run_gain_calibrations() {
const char *cs = this->cs_summary_.c_str();
if (!this->enable_gain_calibration_) {
ESP_LOGW(TAG, "[CALIBRATION] Gain calibration is disabled! Enable it first with enable_gain_calibration: true");
ESP_LOGW(TAG, "[CALIBRATION][%s] Gain calibration is disabled! Enable it first with enable_gain_calibration: true",
cs);
return;
}
@@ -454,12 +580,14 @@ void ATM90E32Component::run_gain_calibrations() {
float ref_currents[3] = {this->get_reference_current(0), this->get_reference_current(1),
this->get_reference_current(2)};
ESP_LOGI(TAG, "[CALIBRATION] ");
ESP_LOGI(TAG, "[CALIBRATION] ========================= Gain Calibration =========================");
ESP_LOGI(TAG, "[CALIBRATION] ---------------------------------------------------------------------");
ESP_LOGI(TAG,
"[CALIBRATION] | Phase | V_meas (V) | I_meas (A) | V_ref | I_ref | V_gain (old→new) | I_gain (old→new) |");
ESP_LOGI(TAG, "[CALIBRATION] ---------------------------------------------------------------------");
ESP_LOGI(TAG, "[CALIBRATION][%s] ", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ========================= Gain Calibration =========================", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
ESP_LOGI(
TAG,
"[CALIBRATION][%s] | Phase | V_meas (V) | I_meas (A) | V_ref | I_ref | V_gain (old→new) | I_gain (old→new) |",
cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
for (uint8_t phase = 0; phase < 3; phase++) {
float measured_voltage = this->get_phase_voltage_avg_(phase);
@@ -476,22 +604,22 @@ void ATM90E32Component::run_gain_calibrations() {
// Voltage calibration
if (ref_voltage <= 0.0f) {
ESP_LOGW(TAG, "[CALIBRATION] Phase %s - Skipping voltage calibration: reference voltage is 0.",
ESP_LOGW(TAG, "[CALIBRATION][%s] Phase %s - Skipping voltage calibration: reference voltage is 0.", cs,
phase_labels[phase]);
} else if (measured_voltage == 0.0f) {
ESP_LOGW(TAG, "[CALIBRATION] Phase %s - Skipping voltage calibration: measured voltage is 0.",
ESP_LOGW(TAG, "[CALIBRATION][%s] Phase %s - Skipping voltage calibration: measured voltage is 0.", cs,
phase_labels[phase]);
} else {
uint32_t new_voltage_gain = static_cast<uint16_t>((ref_voltage / measured_voltage) * current_voltage_gain);
if (new_voltage_gain == 0) {
ESP_LOGW(TAG, "[CALIBRATION] Phase %s - Voltage gain would be 0. Check reference and measured voltage.",
ESP_LOGW(TAG, "[CALIBRATION][%s] Phase %s - Voltage gain would be 0. Check reference and measured voltage.", cs,
phase_labels[phase]);
} else {
if (new_voltage_gain >= 65535) {
ESP_LOGW(
TAG,
"[CALIBRATION] Phase %s - Voltage gain exceeds 65535. You may need a higher output voltage transformer.",
phase_labels[phase]);
ESP_LOGW(TAG,
"[CALIBRATION][%s] Phase %s - Voltage gain exceeds 65535. You may need a higher output voltage "
"transformer.",
cs, phase_labels[phase]);
new_voltage_gain = 65535;
}
this->gain_phase_[phase].voltage_gain = static_cast<uint16_t>(new_voltage_gain);
@@ -501,20 +629,20 @@ void ATM90E32Component::run_gain_calibrations() {
// Current calibration
if (ref_current == 0.0f) {
ESP_LOGW(TAG, "[CALIBRATION] Phase %s - Skipping current calibration: reference current is 0.",
ESP_LOGW(TAG, "[CALIBRATION][%s] Phase %s - Skipping current calibration: reference current is 0.", cs,
phase_labels[phase]);
} else if (measured_current == 0.0f) {
ESP_LOGW(TAG, "[CALIBRATION] Phase %s - Skipping current calibration: measured current is 0.",
ESP_LOGW(TAG, "[CALIBRATION][%s] Phase %s - Skipping current calibration: measured current is 0.", cs,
phase_labels[phase]);
} else {
uint32_t new_current_gain = static_cast<uint16_t>((ref_current / measured_current) * current_current_gain);
if (new_current_gain == 0) {
ESP_LOGW(TAG, "[CALIBRATION] Phase %s - Current gain would be 0. Check reference and measured current.",
ESP_LOGW(TAG, "[CALIBRATION][%s] Phase %s - Current gain would be 0. Check reference and measured current.", cs,
phase_labels[phase]);
} else {
if (new_current_gain >= 65535) {
ESP_LOGW(TAG, "[CALIBRATION] Phase %s - Current gain exceeds 65535. You may need to turn up pga gain.",
phase_labels[phase]);
ESP_LOGW(TAG, "[CALIBRATION][%s] Phase %s - Current gain exceeds 65535. You may need to turn up pga gain.",
cs, phase_labels[phase]);
new_current_gain = 65535;
}
this->gain_phase_[phase].current_gain = static_cast<uint16_t>(new_current_gain);
@@ -523,13 +651,13 @@ void ATM90E32Component::run_gain_calibrations() {
}
// Final row output
ESP_LOGI(TAG, "[CALIBRATION] | %c | %9.2f | %9.4f | %5.2f | %6.4f | %5u → %-5u | %5u → %-5u |",
ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %9.2f | %9.4f | %5.2f | %6.4f | %5u → %-5u | %5u → %-5u |", cs,
'A' + phase, measured_voltage, measured_current, ref_voltage, ref_current, current_voltage_gain,
did_voltage ? this->gain_phase_[phase].voltage_gain : current_voltage_gain, current_current_gain,
did_current ? this->gain_phase_[phase].current_gain : current_current_gain);
}
ESP_LOGI(TAG, "[CALIBRATION] =====================================================================\n");
ESP_LOGI(TAG, "[CALIBRATION][%s] =====================================================================\n", cs);
this->save_gain_calibration_to_memory_();
this->write_gains_to_registers_();
@@ -537,54 +665,108 @@ void ATM90E32Component::run_gain_calibrations() {
}
void ATM90E32Component::save_gain_calibration_to_memory_() {
const char *cs = this->cs_summary_.c_str();
bool success = this->gain_calibration_pref_.save(&this->gain_phase_);
global_preferences->sync();
if (success) {
this->using_saved_calibrations_ = true;
ESP_LOGI(TAG, "[CALIBRATION] Gain calibration saved to memory.");
ESP_LOGI(TAG, "[CALIBRATION][%s] Gain calibration saved to memory.", cs);
} else {
this->using_saved_calibrations_ = false;
ESP_LOGE(TAG, "[CALIBRATION] Failed to save gain calibration to memory!");
ESP_LOGE(TAG, "[CALIBRATION][%s] Failed to save gain calibration to memory!", cs);
}
}
void ATM90E32Component::save_offset_calibration_to_memory_() {
const char *cs = this->cs_summary_.c_str();
bool success = this->offset_pref_.save(&this->offset_phase_);
global_preferences->sync();
if (success) {
this->using_saved_calibrations_ = true;
this->restored_offset_calibration_ = true;
for (bool &phase : this->offset_calibration_mismatch_)
phase = false;
ESP_LOGI(TAG, "[CALIBRATION][%s] Offset calibration saved to memory.", cs);
} else {
this->using_saved_calibrations_ = false;
ESP_LOGE(TAG, "[CALIBRATION][%s] Failed to save offset calibration to memory!", cs);
}
}
void ATM90E32Component::save_power_offset_calibration_to_memory_() {
const char *cs = this->cs_summary_.c_str();
bool success = this->power_offset_pref_.save(&this->power_offset_phase_);
global_preferences->sync();
if (success) {
this->using_saved_calibrations_ = true;
this->restored_power_offset_calibration_ = true;
for (bool &phase : this->power_offset_calibration_mismatch_)
phase = false;
ESP_LOGI(TAG, "[CALIBRATION][%s] Power offset calibration saved to memory.", cs);
} else {
this->using_saved_calibrations_ = false;
ESP_LOGE(TAG, "[CALIBRATION][%s] Failed to save power offset calibration to memory!", cs);
}
}
void ATM90E32Component::run_offset_calibrations() {
const char *cs = this->cs_summary_.c_str();
if (!this->enable_offset_calibration_) {
ESP_LOGW(TAG, "[CALIBRATION] Offset calibration is disabled! Enable it first with enable_offset_calibration: true");
ESP_LOGW(TAG,
"[CALIBRATION][%s] Offset calibration is disabled! Enable it first with enable_offset_calibration: true",
cs);
return;
}
ESP_LOGI(TAG, "[CALIBRATION][%s] ", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ======================== Offset Calibration ========================", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_voltage | offset_current |", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------", cs);
for (uint8_t phase = 0; phase < 3; phase++) {
int16_t voltage_offset = calibrate_offset(phase, true);
int16_t current_offset = calibrate_offset(phase, false);
this->write_offsets_to_registers_(phase, voltage_offset, current_offset);
ESP_LOGI(TAG, "[CALIBRATION] Phase %c - offset_voltage: %d, offset_current: %d", 'A' + phase, voltage_offset,
ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase, voltage_offset,
current_offset);
}
this->offset_pref_.save(&this->offset_phase_); // Save to flash
ESP_LOGI(TAG, "[CALIBRATION][%s] ==================================================================\n", cs);
this->save_offset_calibration_to_memory_();
}
void ATM90E32Component::run_power_offset_calibrations() {
const char *cs = this->cs_summary_.c_str();
if (!this->enable_offset_calibration_) {
ESP_LOGW(
TAG,
"[CALIBRATION] Offset power calibration is disabled! Enable it first with enable_offset_calibration: true");
"[CALIBRATION][%s] Offset power calibration is disabled! Enable it first with enable_offset_calibration: true",
cs);
return;
}
ESP_LOGI(TAG, "[CALIBRATION][%s] ", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ===================== Power Offset Calibration =====================", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_active_power | offset_reactive_power |", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
for (uint8_t phase = 0; phase < 3; ++phase) {
int16_t active_offset = calibrate_power_offset(phase, false);
int16_t reactive_offset = calibrate_power_offset(phase, true);
this->write_power_offsets_to_registers_(phase, active_offset, reactive_offset);
ESP_LOGI(TAG, "[CALIBRATION] Phase %c - offset_active_power: %d, offset_reactive_power: %d", 'A' + phase,
active_offset, reactive_offset);
ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase, active_offset,
reactive_offset);
}
ESP_LOGI(TAG, "[CALIBRATION][%s] =====================================================================\n", cs);
this->power_offset_pref_.save(&this->power_offset_phase_); // Save to flash
this->save_power_offset_calibration_to_memory_();
}
void ATM90E32Component::write_gains_to_registers_() {
@@ -631,102 +813,276 @@ void ATM90E32Component::write_power_offsets_to_registers_(uint8_t phase, int16_t
}
void ATM90E32Component::restore_gain_calibrations_() {
if (this->gain_calibration_pref_.load(&this->gain_phase_)) {
ESP_LOGI(TAG, "[CALIBRATION] Restoring saved gain calibrations to registers:");
for (uint8_t phase = 0; phase < 3; phase++) {
uint16_t v_gain = this->gain_phase_[phase].voltage_gain;
uint16_t i_gain = this->gain_phase_[phase].current_gain;
ESP_LOGI(TAG, "[CALIBRATION] Phase %c - Voltage Gain: %u, Current Gain: %u", 'A' + phase, v_gain, i_gain);
}
this->write_gains_to_registers_();
if (this->verify_gain_writes_()) {
this->using_saved_calibrations_ = true;
ESP_LOGI(TAG, "[CALIBRATION] Gain calibration loaded and verified successfully.");
} else {
this->using_saved_calibrations_ = false;
ESP_LOGE(TAG, "[CALIBRATION] Gain verification failed! Calibration may not be applied correctly.");
}
} else {
this->using_saved_calibrations_ = false;
ESP_LOGW(TAG, "[CALIBRATION] No stored gain calibrations found. Using config file values.");
const char *cs = this->cs_summary_.c_str();
for (uint8_t i = 0; i < 3; ++i) {
this->config_gain_phase_[i].voltage_gain = this->phase_[i].voltage_gain_;
this->config_gain_phase_[i].current_gain = this->phase_[i].ct_gain_;
this->gain_phase_[i] = this->config_gain_phase_[i];
}
if (this->gain_calibration_pref_.load(&this->gain_phase_)) {
bool all_zero = true;
bool same_as_config = true;
for (uint8_t phase = 0; phase < 3; ++phase) {
const auto &cfg = this->config_gain_phase_[phase];
const auto &saved = this->gain_phase_[phase];
if (saved.voltage_gain != 0 || saved.current_gain != 0)
all_zero = false;
if (saved.voltage_gain != cfg.voltage_gain || saved.current_gain != cfg.current_gain)
same_as_config = false;
}
if (!all_zero && !same_as_config) {
for (uint8_t phase = 0; phase < 3; ++phase) {
bool mismatch = false;
if (this->has_config_voltage_gain_[phase] &&
this->gain_phase_[phase].voltage_gain != this->config_gain_phase_[phase].voltage_gain)
mismatch = true;
if (this->has_config_current_gain_[phase] &&
this->gain_phase_[phase].current_gain != this->config_gain_phase_[phase].current_gain)
mismatch = true;
if (mismatch)
this->gain_calibration_mismatch_[phase] = true;
}
this->write_gains_to_registers_();
if (this->verify_gain_writes_()) {
this->using_saved_calibrations_ = true;
this->restored_gain_calibration_ = true;
return;
}
this->using_saved_calibrations_ = false;
ESP_LOGE(TAG, "[CALIBRATION][%s] Gain verification failed! Calibration may not be applied correctly.", cs);
}
}
this->using_saved_calibrations_ = false;
for (uint8_t i = 0; i < 3; ++i)
this->gain_phase_[i] = this->config_gain_phase_[i];
this->write_gains_to_registers_();
ESP_LOGW(TAG, "[CALIBRATION][%s] No stored gain calibrations found. Using config file values.", cs);
}
void ATM90E32Component::restore_offset_calibrations_() {
if (this->offset_pref_.load(&this->offset_phase_)) {
ESP_LOGI(TAG, "[CALIBRATION] Successfully restored offset calibration from memory.");
const char *cs = this->cs_summary_.c_str();
for (uint8_t i = 0; i < 3; ++i)
this->config_offset_phase_[i] = this->offset_phase_[i];
bool have_data = this->offset_pref_.load(&this->offset_phase_);
bool all_zero = true;
if (have_data) {
for (auto &phase : this->offset_phase_) {
if (phase.voltage_offset_ != 0 || phase.current_offset_ != 0) {
all_zero = false;
break;
}
}
}
if (have_data && !all_zero) {
this->restored_offset_calibration_ = true;
for (uint8_t phase = 0; phase < 3; phase++) {
auto &offset = this->offset_phase_[phase];
write_offsets_to_registers_(phase, offset.voltage_offset_, offset.current_offset_);
ESP_LOGI(TAG, "[CALIBRATION] Phase %c - offset_voltage:: %d, offset_current: %d", 'A' + phase,
offset.voltage_offset_, offset.current_offset_);
bool mismatch = false;
if (this->has_config_voltage_offset_[phase] &&
offset.voltage_offset_ != this->config_offset_phase_[phase].voltage_offset_)
mismatch = true;
if (this->has_config_current_offset_[phase] &&
offset.current_offset_ != this->config_offset_phase_[phase].current_offset_)
mismatch = true;
if (mismatch)
this->offset_calibration_mismatch_[phase] = true;
}
} else {
ESP_LOGW(TAG, "[CALIBRATION] No stored offset calibrations found. Using default values.");
for (uint8_t phase = 0; phase < 3; phase++)
this->offset_phase_[phase] = this->config_offset_phase_[phase];
ESP_LOGW(TAG, "[CALIBRATION][%s] No stored offset calibrations found. Using default values.", cs);
}
for (uint8_t phase = 0; phase < 3; phase++) {
write_offsets_to_registers_(phase, this->offset_phase_[phase].voltage_offset_,
this->offset_phase_[phase].current_offset_);
}
}
void ATM90E32Component::restore_power_offset_calibrations_() {
if (this->power_offset_pref_.load(&this->power_offset_phase_)) {
ESP_LOGI(TAG, "[CALIBRATION] Successfully restored power offset calibration from memory.");
const char *cs = this->cs_summary_.c_str();
for (uint8_t i = 0; i < 3; ++i)
this->config_power_offset_phase_[i] = this->power_offset_phase_[i];
bool have_data = this->power_offset_pref_.load(&this->power_offset_phase_);
bool all_zero = true;
if (have_data) {
for (auto &phase : this->power_offset_phase_) {
if (phase.active_power_offset != 0 || phase.reactive_power_offset != 0) {
all_zero = false;
break;
}
}
}
if (have_data && !all_zero) {
this->restored_power_offset_calibration_ = true;
for (uint8_t phase = 0; phase < 3; ++phase) {
auto &offset = this->power_offset_phase_[phase];
write_power_offsets_to_registers_(phase, offset.active_power_offset, offset.reactive_power_offset);
ESP_LOGI(TAG, "[CALIBRATION] Phase %c - offset_active_power: %d, offset_reactive_power: %d", 'A' + phase,
offset.active_power_offset, offset.reactive_power_offset);
bool mismatch = false;
if (this->has_config_active_power_offset_[phase] &&
offset.active_power_offset != this->config_power_offset_phase_[phase].active_power_offset)
mismatch = true;
if (this->has_config_reactive_power_offset_[phase] &&
offset.reactive_power_offset != this->config_power_offset_phase_[phase].reactive_power_offset)
mismatch = true;
if (mismatch)
this->power_offset_calibration_mismatch_[phase] = true;
}
} else {
ESP_LOGW(TAG, "[CALIBRATION] No stored power offsets found. Using default values.");
for (uint8_t phase = 0; phase < 3; ++phase)
this->power_offset_phase_[phase] = this->config_power_offset_phase_[phase];
ESP_LOGW(TAG, "[CALIBRATION][%s] No stored power offsets found. Using default values.", cs);
}
for (uint8_t phase = 0; phase < 3; ++phase) {
write_power_offsets_to_registers_(phase, this->power_offset_phase_[phase].active_power_offset,
this->power_offset_phase_[phase].reactive_power_offset);
}
}
void ATM90E32Component::clear_gain_calibrations() {
ESP_LOGI(TAG, "[CALIBRATION] Clearing stored gain calibrations and restoring config-defined values");
for (int phase = 0; phase < 3; phase++) {
gain_phase_[phase].voltage_gain = this->phase_[phase].voltage_gain_;
gain_phase_[phase].current_gain = this->phase_[phase].ct_gain_;
const char *cs = this->cs_summary_.c_str();
if (!this->using_saved_calibrations_) {
ESP_LOGI(TAG, "[CALIBRATION][%s] No stored gain calibrations to clear. Current values:", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ----------------------------------------------------------", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | voltage_gain | current_gain |", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ----------------------------------------------------------", cs);
for (int phase = 0; phase < 3; phase++) {
ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6u | %6u |", cs, 'A' + phase,
this->gain_phase_[phase].voltage_gain, this->gain_phase_[phase].current_gain);
}
ESP_LOGI(TAG, "[CALIBRATION][%s] ==========================================================\n", cs);
return;
}
bool success = this->gain_calibration_pref_.save(&this->gain_phase_);
this->using_saved_calibrations_ = false;
ESP_LOGI(TAG, "[CALIBRATION][%s] Clearing stored gain calibrations and restoring config-defined values", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ----------------------------------------------------------", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | voltage_gain | current_gain |", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ----------------------------------------------------------", cs);
if (success) {
ESP_LOGI(TAG, "[CALIBRATION] Gain calibrations cleared. Config values restored:");
for (int phase = 0; phase < 3; phase++) {
ESP_LOGI(TAG, "[CALIBRATION] Phase %c - Voltage Gain: %u, Current Gain: %u", 'A' + phase,
gain_phase_[phase].voltage_gain, gain_phase_[phase].current_gain);
}
} else {
ESP_LOGE(TAG, "[CALIBRATION] Failed to clear gain calibrations!");
for (int phase = 0; phase < 3; phase++) {
uint16_t voltage_gain = this->phase_[phase].voltage_gain_;
uint16_t current_gain = this->phase_[phase].ct_gain_;
this->config_gain_phase_[phase].voltage_gain = voltage_gain;
this->config_gain_phase_[phase].current_gain = current_gain;
this->gain_phase_[phase].voltage_gain = voltage_gain;
this->gain_phase_[phase].current_gain = current_gain;
ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6u | %6u |", cs, 'A' + phase, voltage_gain, current_gain);
}
ESP_LOGI(TAG, "[CALIBRATION][%s] ==========================================================\n", cs);
GainCalibration zero_gains[3]{{0, 0}, {0, 0}, {0, 0}};
bool success = this->gain_calibration_pref_.save(&zero_gains);
global_preferences->sync();
this->using_saved_calibrations_ = false;
this->restored_gain_calibration_ = false;
for (bool &phase : this->gain_calibration_mismatch_)
phase = false;
if (!success) {
ESP_LOGE(TAG, "[CALIBRATION][%s] Failed to clear gain calibrations!", cs);
}
this->write_gains_to_registers_(); // Apply them to the chip immediately
}
void ATM90E32Component::clear_offset_calibrations() {
for (uint8_t phase = 0; phase < 3; phase++) {
this->write_offsets_to_registers_(phase, 0, 0);
const char *cs = this->cs_summary_.c_str();
if (!this->restored_offset_calibration_) {
ESP_LOGI(TAG, "[CALIBRATION][%s] No stored offset calibrations to clear. Current values:", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] --------------------------------------------------------------", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_voltage | offset_current |", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] --------------------------------------------------------------", cs);
for (uint8_t phase = 0; phase < 3; phase++) {
ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase,
this->offset_phase_[phase].voltage_offset_, this->offset_phase_[phase].current_offset_);
}
ESP_LOGI(TAG, "[CALIBRATION][%s] ==============================================================\n", cs);
return;
}
this->offset_pref_.save(&this->offset_phase_); // Save cleared values to flash memory
ESP_LOGI(TAG, "[CALIBRATION][%s] Clearing stored offset calibrations and restoring config-defined values", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] --------------------------------------------------------------", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_voltage | offset_current |", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] --------------------------------------------------------------", cs);
ESP_LOGI(TAG, "[CALIBRATION] Offsets cleared.");
for (uint8_t phase = 0; phase < 3; phase++) {
int16_t voltage_offset =
this->has_config_voltage_offset_[phase] ? this->config_offset_phase_[phase].voltage_offset_ : 0;
int16_t current_offset =
this->has_config_current_offset_[phase] ? this->config_offset_phase_[phase].current_offset_ : 0;
this->write_offsets_to_registers_(phase, voltage_offset, current_offset);
ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase, voltage_offset,
current_offset);
}
ESP_LOGI(TAG, "[CALIBRATION][%s] ==============================================================\n", cs);
OffsetCalibration zero_offsets[3]{{0, 0}, {0, 0}, {0, 0}};
this->offset_pref_.save(&zero_offsets); // Clear stored values in flash
global_preferences->sync();
this->restored_offset_calibration_ = false;
for (bool &phase : this->offset_calibration_mismatch_)
phase = false;
ESP_LOGI(TAG, "[CALIBRATION][%s] Offsets cleared.", cs);
}
void ATM90E32Component::clear_power_offset_calibrations() {
for (uint8_t phase = 0; phase < 3; phase++) {
this->write_power_offsets_to_registers_(phase, 0, 0);
const char *cs = this->cs_summary_.c_str();
if (!this->restored_power_offset_calibration_) {
ESP_LOGI(TAG, "[CALIBRATION][%s] No stored power offsets to clear. Current values:", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_active_power | offset_reactive_power |", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
for (uint8_t phase = 0; phase < 3; phase++) {
ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase,
this->power_offset_phase_[phase].active_power_offset,
this->power_offset_phase_[phase].reactive_power_offset);
}
ESP_LOGI(TAG, "[CALIBRATION][%s] =====================================================================\n", cs);
return;
}
this->power_offset_pref_.save(&this->power_offset_phase_);
ESP_LOGI(TAG, "[CALIBRATION][%s] Clearing stored power offsets and restoring config-defined values", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_active_power | offset_reactive_power |", cs);
ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
ESP_LOGI(TAG, "[CALIBRATION] Power offsets cleared.");
for (uint8_t phase = 0; phase < 3; phase++) {
int16_t active_offset =
this->has_config_active_power_offset_[phase] ? this->config_power_offset_phase_[phase].active_power_offset : 0;
int16_t reactive_offset = this->has_config_reactive_power_offset_[phase]
? this->config_power_offset_phase_[phase].reactive_power_offset
: 0;
this->write_power_offsets_to_registers_(phase, active_offset, reactive_offset);
ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase, active_offset,
reactive_offset);
}
ESP_LOGI(TAG, "[CALIBRATION][%s] =====================================================================\n", cs);
PowerOffsetCalibration zero_power_offsets[3]{{0, 0}, {0, 0}, {0, 0}};
this->power_offset_pref_.save(&zero_power_offsets);
global_preferences->sync();
this->restored_power_offset_calibration_ = false;
for (bool &phase : this->power_offset_calibration_mismatch_)
phase = false;
ESP_LOGI(TAG, "[CALIBRATION][%s] Power offsets cleared.", cs);
}
int16_t ATM90E32Component::calibrate_offset(uint8_t phase, bool voltage) {
@@ -747,20 +1103,21 @@ int16_t ATM90E32Component::calibrate_offset(uint8_t phase, bool voltage) {
int16_t ATM90E32Component::calibrate_power_offset(uint8_t phase, bool reactive) {
const uint8_t num_reads = 5;
uint64_t total_value = 0;
int64_t total_value = 0;
for (uint8_t i = 0; i < num_reads; ++i) {
uint32_t reading = reactive ? this->read32_(ATM90E32_REGISTER_QMEAN + phase, ATM90E32_REGISTER_QMEANLSB + phase)
: this->read32_(ATM90E32_REGISTER_PMEAN + phase, ATM90E32_REGISTER_PMEANLSB + phase);
int32_t reading = reactive ? this->read32_(ATM90E32_REGISTER_QMEAN + phase, ATM90E32_REGISTER_QMEANLSB + phase)
: this->read32_(ATM90E32_REGISTER_PMEAN + phase, ATM90E32_REGISTER_PMEANLSB + phase);
total_value += reading;
}
const uint32_t average_value = total_value / num_reads;
const uint32_t power_offset = ~average_value + 1;
int32_t average_value = total_value / num_reads;
int32_t power_offset = -average_value;
return static_cast<int16_t>(power_offset); // Takes the lower 16 bits
}
bool ATM90E32Component::verify_gain_writes_() {
const char *cs = this->cs_summary_.c_str();
bool success = true;
for (uint8_t phase = 0; phase < 3; phase++) {
uint16_t read_voltage = this->read16_(voltage_gain_registers[phase]);
@@ -768,7 +1125,7 @@ bool ATM90E32Component::verify_gain_writes_() {
if (read_voltage != this->gain_phase_[phase].voltage_gain ||
read_current != this->gain_phase_[phase].current_gain) {
ESP_LOGE(TAG, "[CALIBRATION] Mismatch detected for Phase %s!", phase_labels[phase]);
ESP_LOGE(TAG, "[CALIBRATION][%s] Mismatch detected for Phase %s!", cs, phase_labels[phase]);
success = false;
}
}
@@ -791,16 +1148,16 @@ void ATM90E32Component::check_phase_status() {
status += "Phase Loss; ";
auto *sensor = this->phase_status_text_sensor_[phase];
const char *phase_name = sensor ? sensor->get_name().c_str() : "Unknown Phase";
if (sensor == nullptr)
continue;
if (!status.empty()) {
status.pop_back(); // remove space
status.pop_back(); // remove semicolon
ESP_LOGW(TAG, "%s: %s", phase_name, status.c_str());
if (sensor != nullptr)
sensor->publish_state(status);
ESP_LOGW(TAG, "%s: %s", sensor->get_name().c_str(), status.c_str());
sensor->publish_state(status);
} else {
if (sensor != nullptr)
sensor->publish_state("Okay");
sensor->publish_state("Okay");
}
}
}
@@ -817,9 +1174,12 @@ void ATM90E32Component::check_freq_status() {
} else {
freq_status = "Normal";
}
ESP_LOGW(TAG, "Frequency status: %s", freq_status.c_str());
if (this->freq_status_text_sensor_ != nullptr) {
if (freq_status == "Normal") {
ESP_LOGD(TAG, "Frequency status: %s", freq_status.c_str());
} else {
ESP_LOGW(TAG, "Frequency status: %s", freq_status.c_str());
}
this->freq_status_text_sensor_->publish_state(freq_status);
}
}

View File

@@ -61,15 +61,29 @@ class ATM90E32Component : public PollingComponent,
this->phase_[phase].harmonic_active_power_sensor_ = obj;
}
void set_peak_current_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].peak_current_sensor_ = obj; }
void set_volt_gain(int phase, uint16_t gain) { this->phase_[phase].voltage_gain_ = gain; }
void set_ct_gain(int phase, uint16_t gain) { this->phase_[phase].ct_gain_ = gain; }
void set_voltage_offset(uint8_t phase, int16_t offset) { this->offset_phase_[phase].voltage_offset_ = offset; }
void set_current_offset(uint8_t phase, int16_t offset) { this->offset_phase_[phase].current_offset_ = offset; }
void set_volt_gain(int phase, uint16_t gain) {
this->phase_[phase].voltage_gain_ = gain;
this->has_config_voltage_gain_[phase] = true;
}
void set_ct_gain(int phase, uint16_t gain) {
this->phase_[phase].ct_gain_ = gain;
this->has_config_current_gain_[phase] = true;
}
void set_voltage_offset(uint8_t phase, int16_t offset) {
this->offset_phase_[phase].voltage_offset_ = offset;
this->has_config_voltage_offset_[phase] = true;
}
void set_current_offset(uint8_t phase, int16_t offset) {
this->offset_phase_[phase].current_offset_ = offset;
this->has_config_current_offset_[phase] = true;
}
void set_active_power_offset(uint8_t phase, int16_t offset) {
this->power_offset_phase_[phase].active_power_offset = offset;
this->has_config_active_power_offset_[phase] = true;
}
void set_reactive_power_offset(uint8_t phase, int16_t offset) {
this->power_offset_phase_[phase].reactive_power_offset = offset;
this->has_config_reactive_power_offset_[phase] = true;
}
void set_freq_sensor(sensor::Sensor *freq_sensor) { freq_sensor_ = freq_sensor; }
void set_peak_current_signed(bool flag) { peak_current_signed_ = flag; }
@@ -127,7 +141,7 @@ class ATM90E32Component : public PollingComponent,
#endif
uint16_t read16_(uint16_t a_register);
int read32_(uint16_t addr_h, uint16_t addr_l);
void write16_(uint16_t a_register, uint16_t val);
void write16_(uint16_t a_register, uint16_t val, bool validate = true);
float get_local_phase_voltage_(uint8_t phase);
float get_local_phase_current_(uint8_t phase);
float get_local_phase_active_power_(uint8_t phase);
@@ -159,12 +173,15 @@ class ATM90E32Component : public PollingComponent,
void restore_offset_calibrations_();
void restore_power_offset_calibrations_();
void restore_gain_calibrations_();
void save_offset_calibration_to_memory_();
void save_gain_calibration_to_memory_();
void save_power_offset_calibration_to_memory_();
void write_offsets_to_registers_(uint8_t phase, int16_t voltage_offset, int16_t current_offset);
void write_power_offsets_to_registers_(uint8_t phase, int16_t p_offset, int16_t q_offset);
void write_gains_to_registers_();
bool verify_gain_writes_();
bool validate_spi_read_(uint16_t expected, const char *context = nullptr);
void log_calibration_status_();
struct ATM90E32Phase {
uint16_t voltage_gain_{0};
@@ -204,19 +221,33 @@ class ATM90E32Component : public PollingComponent,
int16_t current_offset_{0};
} offset_phase_[3];
OffsetCalibration config_offset_phase_[3];
struct PowerOffsetCalibration {
int16_t active_power_offset{0};
int16_t reactive_power_offset{0};
} power_offset_phase_[3];
PowerOffsetCalibration config_power_offset_phase_[3];
struct GainCalibration {
uint16_t voltage_gain{1};
uint16_t current_gain{1};
} gain_phase_[3];
GainCalibration config_gain_phase_[3];
bool has_config_voltage_offset_[3]{false, false, false};
bool has_config_current_offset_[3]{false, false, false};
bool has_config_active_power_offset_[3]{false, false, false};
bool has_config_reactive_power_offset_[3]{false, false, false};
bool has_config_voltage_gain_[3]{false, false, false};
bool has_config_current_gain_[3]{false, false, false};
ESPPreferenceObject offset_pref_;
ESPPreferenceObject power_offset_pref_;
ESPPreferenceObject gain_calibration_pref_;
std::string cs_summary_;
sensor::Sensor *freq_sensor_{nullptr};
#ifdef USE_TEXT_SENSOR
@@ -231,6 +262,13 @@ class ATM90E32Component : public PollingComponent,
bool peak_current_signed_{false};
bool enable_offset_calibration_{false};
bool enable_gain_calibration_{false};
bool restored_offset_calibration_{false};
bool restored_power_offset_calibration_{false};
bool restored_gain_calibration_{false};
bool calibration_message_printed_{false};
bool offset_calibration_mismatch_[3]{false, false, false};
bool power_offset_calibration_mismatch_[3]{false, false, false};
bool gain_calibration_mismatch_[3]{false, false, false};
};
} // namespace atm90e32

View File

@@ -17,10 +17,12 @@ from esphome.const import (
CONF_REACTIVE_POWER,
CONF_REVERSE_ACTIVE_ENERGY,
CONF_VOLTAGE,
DEVICE_CLASS_APPARENT_POWER,
DEVICE_CLASS_CURRENT,
DEVICE_CLASS_ENERGY,
DEVICE_CLASS_POWER,
DEVICE_CLASS_POWER_FACTOR,
DEVICE_CLASS_REACTIVE_POWER,
DEVICE_CLASS_TEMPERATURE,
DEVICE_CLASS_VOLTAGE,
ENTITY_CATEGORY_DIAGNOSTIC,
@@ -100,13 +102,13 @@ ATM90E32_PHASE_SCHEMA = cv.Schema(
unit_of_measurement=UNIT_VOLT_AMPS_REACTIVE,
icon=ICON_LIGHTBULB,
accuracy_decimals=2,
device_class=DEVICE_CLASS_POWER,
device_class=DEVICE_CLASS_REACTIVE_POWER,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_APPARENT_POWER): sensor.sensor_schema(
unit_of_measurement=UNIT_VOLT_AMPS,
accuracy_decimals=2,
device_class=DEVICE_CLASS_POWER,
device_class=DEVICE_CLASS_APPARENT_POWER,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_POWER_FACTOR): sensor.sensor_schema(

View File

@@ -2,7 +2,7 @@ from esphome import automation
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_MIC_GAIN
from esphome.core import coroutine_with_priority
from esphome.core import CoroPriority, coroutine_with_priority
CODEOWNERS = ["@kbx81"]
IS_PLATFORM_COMPONENT = True
@@ -35,7 +35,7 @@ async def audio_adc_set_mic_gain_to_code(config, action_id, template_arg, args):
return var
@coroutine_with_priority(100.0)
@coroutine_with_priority(CoroPriority.CORE)
async def to_code(config):
cg.add_define("USE_AUDIO_ADC")
cg.add_global(audio_adc_ns.using)

View File

@@ -3,7 +3,7 @@ from esphome.automation import maybe_simple_id
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_VOLUME
from esphome.core import coroutine_with_priority
from esphome.core import CoroPriority, coroutine_with_priority
CODEOWNERS = ["@kbx81"]
IS_PLATFORM_COMPONENT = True
@@ -51,7 +51,7 @@ async def audio_dac_set_volume_to_code(config, action_id, template_arg, args):
return var
@coroutine_with_priority(100.0)
@coroutine_with_priority(CoroPriority.CORE)
async def to_code(config):
cg.add_define("USE_AUDIO_DAC")
cg.add_global(audio_dac_ns.using)

View File

@@ -12,7 +12,7 @@ constexpr static const uint8_t AXS_READ_TOUCHPAD[11] = {0xb5, 0xab, 0xa5, 0x5a,
#define ERROR_CHECK(err) \
if ((err) != i2c::ERROR_OK) { \
this->status_set_warning("Failed to communicate"); \
this->status_set_warning(LOG_STR("Failed to communicate")); \
return; \
}
@@ -41,7 +41,7 @@ void AXS15231Touchscreen::update_touches() {
i2c::ErrorCode err;
uint8_t data[8]{};
err = this->write(AXS_READ_TOUCHPAD, sizeof(AXS_READ_TOUCHPAD), false);
err = this->write(AXS_READ_TOUCHPAD, sizeof(AXS_READ_TOUCHPAD));
ERROR_CHECK(err);
err = this->read(data, sizeof(data));
ERROR_CHECK(err);

View File

@@ -493,7 +493,7 @@ void BedJetHub::dump_config() {
" ble_client.app_id: %d\n"
" ble_client.conn_id: %d",
this->get_name().c_str(), this->parent()->app_id, this->parent()->get_conn_id());
LOG_UPDATE_INTERVAL(this)
LOG_UPDATE_INTERVAL(this);
ESP_LOGCONFIG(TAG, " Child components (%d):", this->children_.size());
for (auto *child : this->children_) {
ESP_LOGCONFIG(TAG, " - %s", child->describe().c_str());

View File

@@ -59,7 +59,7 @@ from esphome.const import (
DEVICE_CLASS_VIBRATION,
DEVICE_CLASS_WINDOW,
)
from esphome.core import CORE, coroutine_with_priority
from esphome.core import CORE, CoroPriority, coroutine_with_priority
from esphome.core.entity_helpers import entity_duplicate_validator, setup_entity
from esphome.cpp_generator import MockObjClass
from esphome.util import Registry
@@ -516,6 +516,7 @@ def binary_sensor_schema(
icon: str = cv.UNDEFINED,
entity_category: str = cv.UNDEFINED,
device_class: str = cv.UNDEFINED,
filters: list = cv.UNDEFINED,
) -> cv.Schema:
schema = {}
@@ -527,6 +528,7 @@ def binary_sensor_schema(
(CONF_ICON, icon, cv.icon),
(CONF_ENTITY_CATEGORY, entity_category, cv.entity_category),
(CONF_DEVICE_CLASS, device_class, validate_device_class),
(CONF_FILTERS, filters, validate_filters),
]:
if default is not cv.UNDEFINED:
schema[cv.Optional(key, default=default)] = validator
@@ -650,9 +652,8 @@ async def binary_sensor_is_off_to_code(config, condition_id, template_arg, args)
return cg.new_Pvariable(condition_id, template_arg, paren, False)
@coroutine_with_priority(100.0)
@coroutine_with_priority(CoroPriority.CORE)
async def to_code(config):
cg.add_define("USE_BINARY_SENSOR")
cg.add_global(binary_sensor_ns.using)

View File

@@ -7,6 +7,19 @@ namespace binary_sensor {
static const char *const TAG = "binary_sensor";
// Function implementation of LOG_BINARY_SENSOR macro to reduce code size
void log_binary_sensor(const char *tag, const char *prefix, const char *type, BinarySensor *obj) {
if (obj == nullptr) {
return;
}
ESP_LOGCONFIG(tag, "%s%s '%s'", prefix, type, obj->get_name().c_str());
if (!obj->get_device_class_ref().empty()) {
ESP_LOGCONFIG(tag, "%s Device Class: '%s'", prefix, obj->get_device_class_ref().c_str());
}
}
void BinarySensor::publish_state(bool new_state) {
if (this->filter_list_ == nullptr) {
this->send_state_internal(new_state);

View File

@@ -10,13 +10,10 @@ namespace esphome {
namespace binary_sensor {
#define LOG_BINARY_SENSOR(prefix, type, obj) \
if ((obj) != nullptr) { \
ESP_LOGCONFIG(TAG, "%s%s '%s'", prefix, LOG_STR_LITERAL(type), (obj)->get_name().c_str()); \
if (!(obj)->get_device_class().empty()) { \
ESP_LOGCONFIG(TAG, "%s Device Class: '%s'", prefix, (obj)->get_device_class().c_str()); \
} \
}
class BinarySensor;
void log_binary_sensor(const char *tag, const char *prefix, const char *type, BinarySensor *obj);
#define LOG_BINARY_SENSOR(prefix, type, obj) log_binary_sensor(TAG, prefix, LOG_STR_LITERAL(type), obj)
#define SUB_BINARY_SENSOR(name) \
protected: \

View File

@@ -1 +1,6 @@
CODEOWNERS = ["@tobias-"]
import esphome.codegen as cg
CODEOWNERS = ["@tobias-", "@dan-s-github"]
CONF_BL0940_ID = "bl0940_id"
bl0940_ns = cg.esphome_ns.namespace("bl0940")

View File

@@ -7,28 +7,26 @@ namespace bl0940 {
static const char *const TAG = "bl0940";
static const uint8_t BL0940_READ_COMMAND = 0x50; // 0x58 according to documentation
static const uint8_t BL0940_FULL_PACKET = 0xAA;
static const uint8_t BL0940_PACKET_HEADER = 0x55; // 0x58 according to documentation
static const uint8_t BL0940_PACKET_HEADER = 0x55; // 0x58 according to en doc but 0x55 in cn doc
static const uint8_t BL0940_WRITE_COMMAND = 0xA0; // 0xA8 according to documentation
static const uint8_t BL0940_REG_I_FAST_RMS_CTRL = 0x10;
static const uint8_t BL0940_REG_MODE = 0x18;
static const uint8_t BL0940_REG_SOFT_RESET = 0x19;
static const uint8_t BL0940_REG_USR_WRPROT = 0x1A;
static const uint8_t BL0940_REG_TPS_CTRL = 0x1B;
const uint8_t BL0940_INIT[5][6] = {
static const uint8_t BL0940_INIT[5][5] = {
// Reset to default
{BL0940_WRITE_COMMAND, BL0940_REG_SOFT_RESET, 0x5A, 0x5A, 0x5A, 0x38},
{BL0940_REG_SOFT_RESET, 0x5A, 0x5A, 0x5A, 0x38},
// Enable User Operation Write
{BL0940_WRITE_COMMAND, BL0940_REG_USR_WRPROT, 0x55, 0x00, 0x00, 0xF0},
{BL0940_REG_USR_WRPROT, 0x55, 0x00, 0x00, 0xF0},
// 0x0100 = CF_UNABLE energy pulse, AC_FREQ_SEL 50Hz, RMS_UPDATE_SEL 800mS
{BL0940_WRITE_COMMAND, BL0940_REG_MODE, 0x00, 0x10, 0x00, 0x37},
{BL0940_REG_MODE, 0x00, 0x10, 0x00, 0x37},
// 0x47FF = Over-current and leakage alarm on, Automatic temperature measurement, Interval 100mS
{BL0940_WRITE_COMMAND, BL0940_REG_TPS_CTRL, 0xFF, 0x47, 0x00, 0xFE},
{BL0940_REG_TPS_CTRL, 0xFF, 0x47, 0x00, 0xFE},
// 0x181C = Half cycle, Fast RMS threshold 6172
{BL0940_WRITE_COMMAND, BL0940_REG_I_FAST_RMS_CTRL, 0x1C, 0x18, 0x00, 0x1B}};
{BL0940_REG_I_FAST_RMS_CTRL, 0x1C, 0x18, 0x00, 0x1B}};
void BL0940::loop() {
DataPacket buffer;
@@ -36,8 +34,8 @@ void BL0940::loop() {
return;
}
if (read_array((uint8_t *) &buffer, sizeof(buffer))) {
if (validate_checksum(&buffer)) {
received_package_(&buffer);
if (this->validate_checksum_(&buffer)) {
this->received_package_(&buffer);
}
} else {
ESP_LOGW(TAG, "Junk on wire. Throwing away partial message");
@@ -46,35 +44,151 @@ void BL0940::loop() {
}
}
bool BL0940::validate_checksum(const DataPacket *data) {
uint8_t checksum = BL0940_READ_COMMAND;
bool BL0940::validate_checksum_(DataPacket *data) {
uint8_t checksum = this->read_command_;
// Whole package but checksum
for (uint32_t i = 0; i < sizeof(data->raw) - 1; i++) {
checksum += data->raw[i];
uint8_t *raw = (uint8_t *) data;
for (uint32_t i = 0; i < sizeof(*data) - 1; i++) {
checksum += raw[i];
}
checksum ^= 0xFF;
if (checksum != data->checksum) {
ESP_LOGW(TAG, "BL0940 invalid checksum! 0x%02X != 0x%02X", checksum, data->checksum);
ESP_LOGW(TAG, "Invalid checksum! 0x%02X != 0x%02X", checksum, data->checksum);
}
return checksum == data->checksum;
}
void BL0940::update() {
this->flush();
this->write_byte(BL0940_READ_COMMAND);
this->write_byte(this->read_command_);
this->write_byte(BL0940_FULL_PACKET);
}
void BL0940::setup() {
#ifdef USE_NUMBER
// add calibration callbacks
if (this->voltage_calibration_number_ != nullptr) {
this->voltage_calibration_number_->add_on_state_callback(
[this](float state) { this->voltage_calibration_callback_(state); });
if (this->voltage_calibration_number_->has_state()) {
this->voltage_calibration_callback_(this->voltage_calibration_number_->state);
}
}
if (this->current_calibration_number_ != nullptr) {
this->current_calibration_number_->add_on_state_callback(
[this](float state) { this->current_calibration_callback_(state); });
if (this->current_calibration_number_->has_state()) {
this->current_calibration_callback_(this->current_calibration_number_->state);
}
}
if (this->power_calibration_number_ != nullptr) {
this->power_calibration_number_->add_on_state_callback(
[this](float state) { this->power_calibration_callback_(state); });
if (this->power_calibration_number_->has_state()) {
this->power_calibration_callback_(this->power_calibration_number_->state);
}
}
if (this->energy_calibration_number_ != nullptr) {
this->energy_calibration_number_->add_on_state_callback(
[this](float state) { this->energy_calibration_callback_(state); });
if (this->energy_calibration_number_->has_state()) {
this->energy_calibration_callback_(this->energy_calibration_number_->state);
}
}
#endif
// calculate calibrated reference values
this->voltage_reference_cal_ = this->voltage_reference_ / this->voltage_cal_;
this->current_reference_cal_ = this->current_reference_ / this->current_cal_;
this->power_reference_cal_ = this->power_reference_ / this->power_cal_;
this->energy_reference_cal_ = this->energy_reference_ / this->energy_cal_;
for (auto *i : BL0940_INIT) {
this->write_array(i, 6);
this->write_byte(this->write_command_), this->write_array(i, 5);
delay(1);
}
this->flush();
}
float BL0940::update_temp_(sensor::Sensor *sensor, ube16_t temperature) const {
auto tb = (float) (temperature.h << 8 | temperature.l);
float BL0940::calculate_power_reference_() {
// calculate power reference based on voltage and current reference
return this->voltage_reference_cal_ * this->current_reference_cal_ * 4046 / 324004 / 79931;
}
float BL0940::calculate_energy_reference_() {
// formula: 3600000 * 4046 * RL * R1 * 1000 / (1638.4 * 256) / Vref² / (R1 + R2)
// or: power_reference_ * 3600000 / (1638.4 * 256)
return this->power_reference_cal_ * 3600000 / (1638.4 * 256);
}
float BL0940::calculate_calibration_value_(float state) { return (100 + state) / 100; }
void BL0940::reset_calibration() {
#ifdef USE_NUMBER
if (this->current_calibration_number_ != nullptr && this->current_cal_ != 1) {
this->current_calibration_number_->make_call().set_value(0).perform();
}
if (this->voltage_calibration_number_ != nullptr && this->voltage_cal_ != 1) {
this->voltage_calibration_number_->make_call().set_value(0).perform();
}
if (this->power_calibration_number_ != nullptr && this->power_cal_ != 1) {
this->power_calibration_number_->make_call().set_value(0).perform();
}
if (this->energy_calibration_number_ != nullptr && this->energy_cal_ != 1) {
this->energy_calibration_number_->make_call().set_value(0).perform();
}
#endif
ESP_LOGD(TAG, "external calibration values restored to initial state");
}
void BL0940::current_calibration_callback_(float state) {
this->current_cal_ = this->calculate_calibration_value_(state);
ESP_LOGV(TAG, "update current calibration state: %f", this->current_cal_);
this->recalibrate_();
}
void BL0940::voltage_calibration_callback_(float state) {
this->voltage_cal_ = this->calculate_calibration_value_(state);
ESP_LOGV(TAG, "update voltage calibration state: %f", this->voltage_cal_);
this->recalibrate_();
}
void BL0940::power_calibration_callback_(float state) {
this->power_cal_ = this->calculate_calibration_value_(state);
ESP_LOGV(TAG, "update power calibration state: %f", this->power_cal_);
this->recalibrate_();
}
void BL0940::energy_calibration_callback_(float state) {
this->energy_cal_ = this->calculate_calibration_value_(state);
ESP_LOGV(TAG, "update energy calibration state: %f", this->energy_cal_);
this->recalibrate_();
}
void BL0940::recalibrate_() {
ESP_LOGV(TAG, "Recalibrating reference values");
this->voltage_reference_cal_ = this->voltage_reference_ / this->voltage_cal_;
this->current_reference_cal_ = this->current_reference_ / this->current_cal_;
if (this->voltage_cal_ != 1 || this->current_cal_ != 1) {
this->power_reference_ = this->calculate_power_reference_();
}
this->power_reference_cal_ = this->power_reference_ / this->power_cal_;
if (this->voltage_cal_ != 1 || this->current_cal_ != 1 || this->power_cal_ != 1) {
this->energy_reference_ = this->calculate_energy_reference_();
}
this->energy_reference_cal_ = this->energy_reference_ / this->energy_cal_;
ESP_LOGD(TAG,
"Recalibrated reference values:\n"
"Voltage: %f\n, Current: %f\n, Power: %f\n, Energy: %f\n",
this->voltage_reference_cal_, this->current_reference_cal_, this->power_reference_cal_,
this->energy_reference_cal_);
}
float BL0940::update_temp_(sensor::Sensor *sensor, uint16_le_t temperature) const {
auto tb = (float) temperature;
float converted_temp = ((float) 170 / 448) * (tb / 2 - 32) - 45;
if (sensor != nullptr) {
if (sensor->has_state() && std::abs(converted_temp - sensor->get_state()) > max_temperature_diff_) {
@@ -87,33 +201,40 @@ float BL0940::update_temp_(sensor::Sensor *sensor, ube16_t temperature) const {
return converted_temp;
}
void BL0940::received_package_(const DataPacket *data) const {
void BL0940::received_package_(DataPacket *data) {
// Bad header
if (data->frame_header != BL0940_PACKET_HEADER) {
ESP_LOGI(TAG, "Invalid data. Header mismatch: %d", data->frame_header);
return;
}
float v_rms = (float) to_uint32_t(data->v_rms) / voltage_reference_;
float i_rms = (float) to_uint32_t(data->i_rms) / current_reference_;
float watt = (float) to_int32_t(data->watt) / power_reference_;
uint32_t cf_cnt = to_uint32_t(data->cf_cnt);
float total_energy_consumption = (float) cf_cnt / energy_reference_;
// cf_cnt is only 24 bits, so track overflows
uint32_t cf_cnt = (uint24_t) data->cf_cnt;
cf_cnt |= this->prev_cf_cnt_ & 0xff000000;
if (cf_cnt < this->prev_cf_cnt_) {
cf_cnt += 0x1000000;
}
this->prev_cf_cnt_ = cf_cnt;
float tps1 = update_temp_(internal_temperature_sensor_, data->tps1);
float tps2 = update_temp_(external_temperature_sensor_, data->tps2);
float v_rms = (uint24_t) data->v_rms / this->voltage_reference_cal_;
float i_rms = (uint24_t) data->i_rms / this->current_reference_cal_;
float watt = (int24_t) data->watt / this->power_reference_cal_;
float total_energy_consumption = cf_cnt / this->energy_reference_cal_;
if (voltage_sensor_ != nullptr) {
voltage_sensor_->publish_state(v_rms);
float tps1 = update_temp_(this->internal_temperature_sensor_, data->tps1);
float tps2 = update_temp_(this->external_temperature_sensor_, data->tps2);
if (this->voltage_sensor_ != nullptr) {
this->voltage_sensor_->publish_state(v_rms);
}
if (current_sensor_ != nullptr) {
current_sensor_->publish_state(i_rms);
if (this->current_sensor_ != nullptr) {
this->current_sensor_->publish_state(i_rms);
}
if (power_sensor_ != nullptr) {
power_sensor_->publish_state(watt);
if (this->power_sensor_ != nullptr) {
this->power_sensor_->publish_state(watt);
}
if (energy_sensor_ != nullptr) {
energy_sensor_->publish_state(total_energy_consumption);
if (this->energy_sensor_ != nullptr) {
this->energy_sensor_->publish_state(total_energy_consumption);
}
ESP_LOGV(TAG, "BL0940: U %fV, I %fA, P %fW, Cnt %" PRId32 ", ∫P %fkWh, T1 %f°C, T2 %f°C", v_rms, i_rms, watt, cf_cnt,
@@ -121,7 +242,27 @@ void BL0940::received_package_(const DataPacket *data) const {
}
void BL0940::dump_config() { // NOLINT(readability-function-cognitive-complexity)
ESP_LOGCONFIG(TAG, "BL0940:");
ESP_LOGCONFIG(TAG,
"BL0940:\n"
" LEGACY MODE: %s\n"
" READ CMD: 0x%02X\n"
" WRITE CMD: 0x%02X\n"
" ------------------\n"
" Current reference: %f\n"
" Energy reference: %f\n"
" Power reference: %f\n"
" Voltage reference: %f\n",
TRUEFALSE(this->legacy_mode_enabled_), this->read_command_, this->write_command_,
this->current_reference_, this->energy_reference_, this->power_reference_, this->voltage_reference_);
#ifdef USE_NUMBER
ESP_LOGCONFIG(TAG,
"BL0940:\n"
" Current calibration: %f\n"
" Energy calibration: %f\n"
" Power calibration: %f\n"
" Voltage calibration: %f\n",
this->current_cal_, this->energy_cal_, this->power_cal_, this->voltage_cal_);
#endif
LOG_SENSOR("", "Voltage", this->voltage_sensor_);
LOG_SENSOR("", "Current", this->current_sensor_);
LOG_SENSOR("", "Power", this->power_sensor_);
@@ -130,9 +271,5 @@ void BL0940::dump_config() { // NOLINT(readability-function-cognitive-complexit
LOG_SENSOR("", "External temperature", this->external_temperature_sensor_);
}
uint32_t BL0940::to_uint32_t(ube24_t input) { return input.h << 16 | input.m << 8 | input.l; }
int32_t BL0940::to_int32_t(sbe24_t input) { return input.h << 16 | input.m << 8 | input.l; }
} // namespace bl0940
} // namespace esphome

View File

@@ -1,66 +1,48 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/uart/uart.h"
#include "esphome/core/datatypes.h"
#include "esphome/core/defines.h"
#ifdef USE_BUTTON
#include "esphome/components/button/button.h"
#endif
#ifdef USE_NUMBER
#include "esphome/components/number/number.h"
#endif
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/uart/uart.h"
namespace esphome {
namespace bl0940 {
static const float BL0940_PREF = 1430;
static const float BL0940_UREF = 33000;
static const float BL0940_IREF = 275000; // 2750 from tasmota. Seems to generate values 100 times too high
// Measured to 297J per click according to power consumption of 5 minutes
// Converted to kWh (3.6MJ per kwH). Used to be 256 * 1638.4
static const float BL0940_EREF = 3.6e6 / 297;
struct ube24_t { // NOLINT(readability-identifier-naming,altera-struct-pack-align)
uint8_t l;
uint8_t m;
uint8_t h;
} __attribute__((packed));
struct ube16_t { // NOLINT(readability-identifier-naming,altera-struct-pack-align)
uint8_t l;
uint8_t h;
} __attribute__((packed));
struct sbe24_t { // NOLINT(readability-identifier-naming,altera-struct-pack-align)
uint8_t l;
uint8_t m;
int8_t h;
} __attribute__((packed));
// Caveat: All these values are big endian (low - middle - high)
union DataPacket { // NOLINT(altera-struct-pack-align)
uint8_t raw[35];
struct {
uint8_t frame_header; // value of 0x58 according to docs. 0x55 according to Tasmota real world tests. Reality wins.
ube24_t i_fast_rms; // 0x00
ube24_t i_rms; // 0x04
ube24_t RESERVED0; // reserved
ube24_t v_rms; // 0x06
ube24_t RESERVED1; // reserved
sbe24_t watt; // 0x08
ube24_t RESERVED2; // reserved
ube24_t cf_cnt; // 0x0A
ube24_t RESERVED3; // reserved
ube16_t tps1; // 0x0c
uint8_t RESERVED4; // value of 0x00
ube16_t tps2; // 0x0c
uint8_t RESERVED5; // value of 0x00
uint8_t checksum; // checksum
};
struct DataPacket {
uint8_t frame_header; // Packet header (0x58 in EN docs, 0x55 in CN docs and Tasmota tests)
uint24_le_t i_fast_rms; // Fast RMS current
uint24_le_t i_rms; // RMS current
uint24_t RESERVED0; // Reserved
uint24_le_t v_rms; // RMS voltage
uint24_t RESERVED1; // Reserved
int24_le_t watt; // Active power (can be negative for bidirectional measurement)
uint24_t RESERVED2; // Reserved
uint24_le_t cf_cnt; // Energy pulse count
uint24_t RESERVED3; // Reserved
uint16_le_t tps1; // Internal temperature sensor 1
uint8_t RESERVED4; // Reserved (should be 0x00)
uint16_le_t tps2; // Internal temperature sensor 2
uint8_t RESERVED5; // Reserved (should be 0x00)
uint8_t checksum; // Packet checksum
} __attribute__((packed));
class BL0940 : public PollingComponent, public uart::UARTDevice {
public:
// Sensor setters
void set_voltage_sensor(sensor::Sensor *voltage_sensor) { voltage_sensor_ = voltage_sensor; }
void set_current_sensor(sensor::Sensor *current_sensor) { current_sensor_ = current_sensor; }
void set_power_sensor(sensor::Sensor *power_sensor) { power_sensor_ = power_sensor; }
void set_energy_sensor(sensor::Sensor *energy_sensor) { energy_sensor_ = energy_sensor; }
// Temperature sensor setters
void set_internal_temperature_sensor(sensor::Sensor *internal_temperature_sensor) {
internal_temperature_sensor_ = internal_temperature_sensor;
}
@@ -68,42 +50,105 @@ class BL0940 : public PollingComponent, public uart::UARTDevice {
external_temperature_sensor_ = external_temperature_sensor;
}
void loop() override;
// Configuration setters
void set_legacy_mode(bool enable) { this->legacy_mode_enabled_ = enable; }
void set_read_command(uint8_t read_command) { this->read_command_ = read_command; }
void set_write_command(uint8_t write_command) { this->write_command_ = write_command; }
// Reference value setters (used for calibration and conversion)
void set_current_reference(float current_ref) { this->current_reference_ = current_ref; }
void set_energy_reference(float energy_ref) { this->energy_reference_ = energy_ref; }
void set_power_reference(float power_ref) { this->power_reference_ = power_ref; }
void set_voltage_reference(float voltage_ref) { this->voltage_reference_ = voltage_ref; }
#ifdef USE_NUMBER
// Calibration number setters (for Home Assistant number entities)
void set_current_calibration_number(number::Number *num) { this->current_calibration_number_ = num; }
void set_voltage_calibration_number(number::Number *num) { this->voltage_calibration_number_ = num; }
void set_power_calibration_number(number::Number *num) { this->power_calibration_number_ = num; }
void set_energy_calibration_number(number::Number *num) { this->energy_calibration_number_ = num; }
#endif
#ifdef USE_BUTTON
// Resets all calibration values to defaults (can be triggered by a button)
void reset_calibration();
#endif
// Core component methods
void loop() override;
void update() override;
void setup() override;
void dump_config() override;
protected:
sensor::Sensor *voltage_sensor_{nullptr};
sensor::Sensor *current_sensor_{nullptr};
// NB This may be negative as the circuits is seemingly able to measure
// power in both directions
sensor::Sensor *power_sensor_{nullptr};
sensor::Sensor *energy_sensor_{nullptr};
sensor::Sensor *internal_temperature_sensor_{nullptr};
sensor::Sensor *external_temperature_sensor_{nullptr};
// --- Sensor pointers ---
sensor::Sensor *voltage_sensor_{nullptr}; // Voltage sensor
sensor::Sensor *current_sensor_{nullptr}; // Current sensor
sensor::Sensor *power_sensor_{nullptr}; // Power sensor (can be negative for bidirectional)
sensor::Sensor *energy_sensor_{nullptr}; // Energy sensor
sensor::Sensor *internal_temperature_sensor_{nullptr}; // Internal temperature sensor
sensor::Sensor *external_temperature_sensor_{nullptr}; // External temperature sensor
// Max difference between two measurements of the temperature. Used to avoid noise.
float max_temperature_diff_{0};
// Divide by this to turn into Watt
float power_reference_ = BL0940_PREF;
// Divide by this to turn into Volt
float voltage_reference_ = BL0940_UREF;
// Divide by this to turn into Ampere
float current_reference_ = BL0940_IREF;
// Divide by this to turn into kWh
float energy_reference_ = BL0940_EREF;
#ifdef USE_NUMBER
// --- Calibration number entities (for dynamic calibration via HA UI) ---
number::Number *voltage_calibration_number_{nullptr};
number::Number *current_calibration_number_{nullptr};
number::Number *power_calibration_number_{nullptr};
number::Number *energy_calibration_number_{nullptr};
#endif
float update_temp_(sensor::Sensor *sensor, ube16_t packed_temperature) const;
// --- Internal state ---
uint32_t prev_cf_cnt_ = 0; // Previous energy pulse count (for energy calculation)
float max_temperature_diff_{0}; // Max allowed temperature difference between two measurements (noise filter)
static uint32_t to_uint32_t(ube24_t input);
// --- Reference values for conversion ---
float power_reference_; // Divider for raw power to get Watts
float power_reference_cal_; // Calibrated power reference
float voltage_reference_; // Divider for raw voltage to get Volts
float voltage_reference_cal_; // Calibrated voltage reference
float current_reference_; // Divider for raw current to get Amperes
float current_reference_cal_; // Calibrated current reference
float energy_reference_; // Divider for raw energy to get kWh
float energy_reference_cal_; // Calibrated energy reference
static int32_t to_int32_t(sbe24_t input);
// --- Home Assistant calibration values (multipliers, default 1) ---
float current_cal_{1};
float voltage_cal_{1};
float power_cal_{1};
float energy_cal_{1};
static bool validate_checksum(const DataPacket *data);
// --- Protocol commands ---
uint8_t read_command_;
uint8_t write_command_;
void received_package_(const DataPacket *data) const;
// --- Mode flags ---
bool legacy_mode_enabled_ = true;
// --- Methods ---
// Converts packed temperature value to float and updates the sensor
float update_temp_(sensor::Sensor *sensor, uint16_le_t packed_temperature) const;
// Validates the checksum of a received data packet
bool validate_checksum_(DataPacket *data);
// Handles a received data packet
void received_package_(DataPacket *data);
// Calculates reference values for calibration and conversion
float calculate_energy_reference_();
float calculate_power_reference_();
float calculate_calibration_value_(float state);
// Calibration update callbacks (used with number entities)
void current_calibration_callback_(float state);
void voltage_calibration_callback_(float state);
void power_calibration_callback_(float state);
void energy_calibration_callback_(float state);
void reset_calibration_callback_();
// Recalculates all reference values after calibration changes
void recalibrate_();
};
} // namespace bl0940
} // namespace esphome

View File

@@ -0,0 +1,27 @@
import esphome.codegen as cg
from esphome.components import button
import esphome.config_validation as cv
from esphome.const import ENTITY_CATEGORY_CONFIG, ICON_RESTART
from .. import CONF_BL0940_ID, bl0940_ns
from ..sensor import BL0940
CalibrationResetButton = bl0940_ns.class_(
"CalibrationResetButton", button.Button, cg.Component
)
CONFIG_SCHEMA = cv.All(
button.button_schema(
CalibrationResetButton,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_RESTART,
)
.extend({cv.GenerateID(CONF_BL0940_ID): cv.use_id(BL0940)})
.extend(cv.COMPONENT_SCHEMA)
)
async def to_code(config):
var = await button.new_button(config)
await cg.register_component(var, config)
await cg.register_parented(var, config[CONF_BL0940_ID])

View File

@@ -0,0 +1,20 @@
#include "calibration_reset_button.h"
#include "../bl0940.h"
#include "esphome/core/hal.h"
#include "esphome/core/log.h"
#include "esphome/core/application.h"
namespace esphome {
namespace bl0940 {
static const char *const TAG = "bl0940.button.calibration_reset";
void CalibrationResetButton::dump_config() { LOG_BUTTON("", "Calibration Reset Button", this); }
void CalibrationResetButton::press_action() {
ESP_LOGI(TAG, "Resetting calibration defaults...");
this->parent_->reset_calibration();
}
} // namespace bl0940
} // namespace esphome

View File

@@ -0,0 +1,19 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/button/button.h"
namespace esphome {
namespace bl0940 {
class BL0940; // Forward declaration of BL0940 class
class CalibrationResetButton : public button::Button, public Component, public Parented<BL0940> {
public:
void dump_config() override;
void press_action() override;
};
} // namespace bl0940
} // namespace esphome

View File

@@ -0,0 +1,94 @@
import esphome.codegen as cg
from esphome.components import number
import esphome.config_validation as cv
from esphome.const import (
CONF_MAX_VALUE,
CONF_MIN_VALUE,
CONF_MODE,
CONF_RESTORE_VALUE,
CONF_STEP,
ENTITY_CATEGORY_CONFIG,
UNIT_PERCENT,
)
from .. import CONF_BL0940_ID, bl0940_ns
from ..sensor import BL0940
# Define calibration types
CONF_CURRENT_CALIBRATION = "current_calibration"
CONF_VOLTAGE_CALIBRATION = "voltage_calibration"
CONF_POWER_CALIBRATION = "power_calibration"
CONF_ENERGY_CALIBRATION = "energy_calibration"
BL0940Number = bl0940_ns.class_("BL0940Number")
CalibrationNumber = bl0940_ns.class_(
"CalibrationNumber", number.Number, cg.PollingComponent
)
def validate_min_max(config):
if config[CONF_MAX_VALUE] <= config[CONF_MIN_VALUE]:
raise cv.Invalid("max_value must be greater than min_value")
return config
CALIBRATION_SCHEMA = cv.All(
number.number_schema(
CalibrationNumber,
entity_category=ENTITY_CATEGORY_CONFIG,
unit_of_measurement=UNIT_PERCENT,
)
.extend(
{
cv.Optional(CONF_MODE, default="BOX"): cv.enum(number.NUMBER_MODES),
cv.Optional(CONF_MAX_VALUE, default=10): cv.All(
cv.float_, cv.Range(max=50)
),
cv.Optional(CONF_MIN_VALUE, default=-10): cv.All(
cv.float_, cv.Range(min=-50)
),
cv.Optional(CONF_STEP, default=0.1): cv.positive_float,
cv.Optional(CONF_RESTORE_VALUE): cv.boolean,
}
)
.extend(cv.COMPONENT_SCHEMA),
validate_min_max,
)
# Configuration schema for BL0940 numbers
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(): cv.declare_id(BL0940Number),
cv.GenerateID(CONF_BL0940_ID): cv.use_id(BL0940),
cv.Optional(CONF_CURRENT_CALIBRATION): CALIBRATION_SCHEMA,
cv.Optional(CONF_VOLTAGE_CALIBRATION): CALIBRATION_SCHEMA,
cv.Optional(CONF_POWER_CALIBRATION): CALIBRATION_SCHEMA,
cv.Optional(CONF_ENERGY_CALIBRATION): CALIBRATION_SCHEMA,
}
)
async def to_code(config):
# Get the BL0940 component instance
bl0940 = await cg.get_variable(config[CONF_BL0940_ID])
# Process all calibration types
for cal_type, setter_method in [
(CONF_CURRENT_CALIBRATION, "set_current_calibration_number"),
(CONF_VOLTAGE_CALIBRATION, "set_voltage_calibration_number"),
(CONF_POWER_CALIBRATION, "set_power_calibration_number"),
(CONF_ENERGY_CALIBRATION, "set_energy_calibration_number"),
]:
if conf := config.get(cal_type):
var = await number.new_number(
conf,
min_value=conf.get(CONF_MIN_VALUE),
max_value=conf.get(CONF_MAX_VALUE),
step=conf.get(CONF_STEP),
)
await cg.register_component(var, conf)
if restore_value := config.get(CONF_RESTORE_VALUE):
cg.add(var.set_restore_value(restore_value))
cg.add(getattr(bl0940, setter_method)(var))

View File

@@ -0,0 +1,29 @@
#include "calibration_number.h"
#include "esphome/core/log.h"
namespace esphome {
namespace bl0940 {
static const char *const TAG = "bl0940.number";
void CalibrationNumber::setup() {
float value = 0.0f;
if (this->restore_value_) {
this->pref_ = global_preferences->make_preference<float>(this->get_object_id_hash());
if (!this->pref_.load(&value)) {
value = 0.0f;
}
}
this->publish_state(value);
}
void CalibrationNumber::control(float value) {
this->publish_state(value);
if (this->restore_value_)
this->pref_.save(&value);
}
void CalibrationNumber::dump_config() { LOG_NUMBER("", "Calibration Number", this); }
} // namespace bl0940
} // namespace esphome

View File

@@ -0,0 +1,26 @@
#pragma once
#include "esphome/components/number/number.h"
#include "esphome/core/component.h"
#include "esphome/core/preferences.h"
namespace esphome {
namespace bl0940 {
class CalibrationNumber : public number::Number, public Component {
public:
void setup() override;
void dump_config() override;
float get_setup_priority() const override { return setup_priority::HARDWARE; }
void set_restore_value(bool restore_value) { this->restore_value_ = restore_value; }
protected:
void control(float value) override;
bool restore_value_{true};
ESPPreferenceObject pref_;
};
} // namespace bl0940
} // namespace esphome

View File

@@ -8,6 +8,7 @@ from esphome.const import (
CONF_ID,
CONF_INTERNAL_TEMPERATURE,
CONF_POWER,
CONF_REFERENCE_VOLTAGE,
CONF_VOLTAGE,
DEVICE_CLASS_CURRENT,
DEVICE_CLASS_ENERGY,
@@ -23,12 +24,133 @@ from esphome.const import (
UNIT_WATT,
)
from . import bl0940_ns
DEPENDENCIES = ["uart"]
bl0940_ns = cg.esphome_ns.namespace("bl0940")
BL0940 = bl0940_ns.class_("BL0940", cg.PollingComponent, uart.UARTDevice)
CONF_LEGACY_MODE = "legacy_mode"
CONF_READ_COMMAND = "read_command"
CONF_WRITE_COMMAND = "write_command"
CONF_RESISTOR_SHUNT = "resistor_shunt"
CONF_RESISTOR_ONE = "resistor_one"
CONF_RESISTOR_TWO = "resistor_two"
CONF_CURRENT_REFERENCE = "current_reference"
CONF_ENERGY_REFERENCE = "energy_reference"
CONF_POWER_REFERENCE = "power_reference"
CONF_VOLTAGE_REFERENCE = "voltage_reference"
DEFAULT_BL0940_READ_COMMAND = 0x58
DEFAULT_BL0940_WRITE_COMMAND = 0xA1
# Values according to BL0940 application note:
# https://www.belling.com.cn/media/file_object/bel_product/BL0940/guide/BL0940_APPNote_TSSOP14_V1.04_EN.pdf
DEFAULT_BL0940_VREF = 1.218 # Vref = 1.218
DEFAULT_BL0940_RL = 1 # RL = 1 mΩ
DEFAULT_BL0940_R1 = 0.51 # R1 = 0.51 kΩ
DEFAULT_BL0940_R2 = 1950 # R2 = 5 x 390 kΩ -> 1950 kΩ
# ----------------------------------------------------
# values from initial implementation
DEFAULT_BL0940_LEGACY_READ_COMMAND = 0x50
DEFAULT_BL0940_LEGACY_WRITE_COMMAND = 0xA0
DEFAULT_BL0940_LEGACY_UREF = 33000
DEFAULT_BL0940_LEGACY_IREF = 275000
DEFAULT_BL0940_LEGACY_PREF = 1430
# Measured to 297J per click according to power consumption of 5 minutes
# Converted to kWh (3.6MJ per kwH). Used to be 256 * 1638.4
DEFAULT_BL0940_LEGACY_EREF = 3.6e6 / 297
# ----------------------------------------------------
# methods to calculate voltage and current reference values
def calculate_voltage_reference(vref, r_one, r_two):
# formula: 79931 / Vref * (R1 * 1000) / (R1 + R2)
return 79931 / vref * (r_one * 1000) / (r_one + r_two)
def calculate_current_reference(vref, r_shunt):
# formula: 324004 * RL / Vref
return 324004 * r_shunt / vref
def calculate_power_reference(voltage_reference, current_reference):
# calculate power reference based on voltage and current reference
return voltage_reference * current_reference * 4046 / 324004 / 79931
def calculate_energy_reference(power_reference):
# formula: power_reference * 3600000 / (1638.4 * 256)
return power_reference * 3600000 / (1638.4 * 256)
def validate_legacy_mode(config):
# Only allow schematic calibration options if legacy_mode is False
if config.get(CONF_LEGACY_MODE, True):
forbidden = [
CONF_REFERENCE_VOLTAGE,
CONF_RESISTOR_SHUNT,
CONF_RESISTOR_ONE,
CONF_RESISTOR_TWO,
]
for key in forbidden:
if key in config:
raise cv.Invalid(
f"Option '{key}' is only allowed when legacy_mode: false"
)
return config
def set_command_defaults(config):
# Set defaults for read_command and write_command based on legacy_mode
legacy = config.get(CONF_LEGACY_MODE, True)
if legacy:
config.setdefault(CONF_READ_COMMAND, DEFAULT_BL0940_LEGACY_READ_COMMAND)
config.setdefault(CONF_WRITE_COMMAND, DEFAULT_BL0940_LEGACY_WRITE_COMMAND)
else:
config.setdefault(CONF_READ_COMMAND, DEFAULT_BL0940_READ_COMMAND)
config.setdefault(CONF_WRITE_COMMAND, DEFAULT_BL0940_WRITE_COMMAND)
return config
def set_reference_values(config):
# Set default reference values based on legacy_mode
if config.get(CONF_LEGACY_MODE, True):
config.setdefault(CONF_VOLTAGE_REFERENCE, DEFAULT_BL0940_LEGACY_UREF)
config.setdefault(CONF_CURRENT_REFERENCE, DEFAULT_BL0940_LEGACY_IREF)
config.setdefault(CONF_POWER_REFERENCE, DEFAULT_BL0940_LEGACY_PREF)
config.setdefault(CONF_ENERGY_REFERENCE, DEFAULT_BL0940_LEGACY_PREF)
else:
vref = config.get(CONF_VOLTAGE_REFERENCE, DEFAULT_BL0940_VREF)
r_one = config.get(CONF_RESISTOR_ONE, DEFAULT_BL0940_R1)
r_two = config.get(CONF_RESISTOR_TWO, DEFAULT_BL0940_R2)
r_shunt = config.get(CONF_RESISTOR_SHUNT, DEFAULT_BL0940_RL)
config.setdefault(
CONF_VOLTAGE_REFERENCE, calculate_voltage_reference(vref, r_one, r_two)
)
config.setdefault(
CONF_CURRENT_REFERENCE, calculate_current_reference(vref, r_shunt)
)
config.setdefault(
CONF_POWER_REFERENCE,
calculate_power_reference(
config.get(CONF_VOLTAGE_REFERENCE), config.get(CONF_CURRENT_REFERENCE)
),
)
config.setdefault(
CONF_ENERGY_REFERENCE,
calculate_energy_reference(config.get(CONF_POWER_REFERENCE)),
)
return config
CONFIG_SCHEMA = (
cv.Schema(
{
@@ -69,10 +191,24 @@ CONFIG_SCHEMA = (
device_class=DEVICE_CLASS_TEMPERATURE,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_LEGACY_MODE, default=True): cv.boolean,
cv.Optional(CONF_READ_COMMAND): cv.hex_uint8_t,
cv.Optional(CONF_WRITE_COMMAND): cv.hex_uint8_t,
cv.Optional(CONF_REFERENCE_VOLTAGE): cv.float_,
cv.Optional(CONF_RESISTOR_SHUNT): cv.float_,
cv.Optional(CONF_RESISTOR_ONE): cv.float_,
cv.Optional(CONF_RESISTOR_TWO): cv.float_,
cv.Optional(CONF_CURRENT_REFERENCE): cv.float_,
cv.Optional(CONF_ENERGY_REFERENCE): cv.float_,
cv.Optional(CONF_POWER_REFERENCE): cv.float_,
cv.Optional(CONF_VOLTAGE_REFERENCE): cv.float_,
}
)
.extend(cv.polling_component_schema("60s"))
.extend(uart.UART_DEVICE_SCHEMA)
.add_extra(validate_legacy_mode)
.add_extra(set_command_defaults)
.add_extra(set_reference_values)
)
@@ -99,3 +235,16 @@ async def to_code(config):
if external_temperature_config := config.get(CONF_EXTERNAL_TEMPERATURE):
sens = await sensor.new_sensor(external_temperature_config)
cg.add(var.set_external_temperature_sensor(sens))
# enable legacy mode
cg.add(var.set_legacy_mode(config.get(CONF_LEGACY_MODE)))
# Set bl0940 commands after validator has determined which defaults to use if not set
cg.add(var.set_read_command(config.get(CONF_READ_COMMAND)))
cg.add(var.set_write_command(config.get(CONF_WRITE_COMMAND)))
# Set reference values after validator has set the values either from defaults or calculated
cg.add(var.set_current_reference(config.get(CONF_CURRENT_REFERENCE)))
cg.add(var.set_voltage_reference(config.get(CONF_VOLTAGE_REFERENCE)))
cg.add(var.set_power_reference(config.get(CONF_POWER_REFERENCE)))
cg.add(var.set_energy_reference(config.get(CONF_ENERGY_REFERENCE)))

View File

@@ -149,7 +149,7 @@ void BL0942::setup() {
this->write_reg_(BL0942_REG_USR_WRPROT, 0);
if (this->read_reg_(BL0942_REG_MODE) != mode)
this->status_set_warning("BL0942 setup failed!");
this->status_set_warning(LOG_STR("BL0942 setup failed!"));
this->flush();
}

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