1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-01 15:41:52 +00:00

Compare commits

...

204 Commits

Author SHA1 Message Date
Jesse Hills
273343b182 Fix log api client when no hardcoded encryption key 2025-04-28 14:07:29 +12:00
Clyde Stubbs
38dae8489e [http_request] Implement for host platform (#8040) 2025-04-28 13:45:28 +12:00
Clyde Stubbs
22c0e1079e [const] Create component-level const repository (#8385) 2025-04-28 12:23:18 +12:00
Clyde Stubbs
2d3f141140 [core] Fix setting of log level/verbose (#8600) 2025-04-28 12:19:50 +12:00
Kevin Ahrendt
e49252ca3d [voice_assistant] Use mic callback and remove esp_adf code (#8627)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-04-28 00:15:28 +00:00
Kevin Ahrendt
c9d1476ae0 [voice_assisant] support start/continue conversation and deallocate buffers (#8610) 2025-04-28 11:30:21 +12:00
Kevin Ahrendt
ee646d7324 [micro_wake_word] Use microphone callback and avoid unnecessary allocation attempts (#8626) 2025-04-28 11:23:25 +12:00
Kevin Ahrendt
e557bca420 [i2s_audio] Microphone reads in loop for callbacks shouldn't ever delay (#8625) 2025-04-28 11:19:01 +12:00
Jesse Hills
adcd6517db [docker] Use new base container image (#8582) 2025-04-28 11:14:50 +12:00
Thomas Rupprecht
4c8f5275f9 replace http with https (#8628) 2025-04-25 14:47:45 -05:00
dependabot[bot]
526db0102c Bump actions/setup-python from 5.5.0 to 5.6.0 in /.github/actions/restore-python (#8616) 2025-04-24 16:18:33 -10:00
dependabot[bot]
8a3fe9ce4c Bump actions/setup-python from 5.5.0 to 5.6.0 (#8618) 2025-04-24 16:18:13 -10:00
dependabot[bot]
fb97ef33a8 Bump setuptools from 78.1.0 to 79.0.1 (#8614)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-24 16:17:39 -10:00
dependabot[bot]
805a6d85a5 Bump ruff from 0.11.6 to 0.11.7 (#8615)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-24 16:12:13 -10:00
dependabot[bot]
8f9fbb15b8 Bump docker/build-push-action from 6.15.0 to 6.16.0 in /.github/actions/build-image (#8619)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-24 15:31:50 -10:00
Guillermo Ruffino
3d24dea455 fix schema-gen-ci failures (#8621) 2025-04-24 15:30:22 -10:00
dependabot[bot]
666d5374ea Bump actions/download-artifact from 4.2.1 to 4.3.0 (#8617)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-24 13:08:24 -10:00
luar123
6792ff6d58 [i2s_audio, i2s_audio_microphone, i2s_audio_speaker] Add basic support for new esp-idf 5.x.x i2s driver. (#8181) 2025-04-24 15:33:58 -05:00
Guillermo Ruffino
f29ccb9e75 Schema gen action (#8593)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-04-24 15:43:37 +12:00
Jesse Hills
911bd54765 [watchdog] Fix for variants with single core (#8602) 2025-04-23 03:49:33 -05:00
Clyde Stubbs
89b1b12993 [online_image] Fix printf format; comment fixes (#8607) 2025-04-23 03:47:15 -05:00
Djordje Mandic
33d79e03d9 [sht4x] Reduce warn spam, added communication check in setup (#8250)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-04-23 03:45:29 -05:00
Craig Andrews
991f3d3a10 [http_request] Ability to get response headers (#8224)
Co-authored-by: guillempages <guillempages@users.noreply.github.com>
Co-authored-by: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com>
2025-04-23 14:30:50 +10:00
J. Nick Koston
97823ddd16 Rewrite BLE scanner to use a state machine (#8601) 2025-04-22 08:09:28 -10:00
Vasil Kalchev
6ff180152a Implement min_power for component ac_dimmer using method trailing (#8472) 2025-04-22 07:39:21 -03:00
bdm310
dbb7cbed3e [lvgl] Fix unexpected widget update behavior (#8260) 2025-04-22 20:13:43 +10:00
J. Nick Koston
fbf00f0af4 Fix BLE connection loop caused by timeout and pending disconnect race (#8597) 2025-04-22 21:17:09 +12:00
Roving Ronin
82c6a40371 Update const.py - Add UNIT_MEGAJOULE = "MJ" (#8594) 2025-04-22 09:13:31 +12:00
Clyde Stubbs
0242ac56df [lvgl] Ensure pages are created on the correct display (#8596) 2025-04-22 08:51:52 +12:00
J. Nick Koston
b82666002d Bump esp-idf to 5.1.6 (#8566)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-04-18 05:21:07 +00:00
Jonathan Swoboda
e11883e431 [psram] Add version check to fix 5.3.2 (#8588) 2025-04-17 21:06:41 -05:00
dependabot[bot]
ff5b9df607 Bump ruff from 0.11.5 to 0.11.6 (#8587)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-17 20:24:31 +00:00
Jesse Hills
e5b7e3039a Fix psram below idf 5 (#8584) 2025-04-17 00:04:43 -05:00
Jonathan Swoboda
31ed1eb6f0 [remote_receiver] Filtering fixes (#7777)
Co-authored-by: Jonathan Swoboda <jonathan.swoboda>
2025-04-16 23:33:46 -05:00
Michael Giacomelli
0c3daab649 Remove duplicate co2 and pressure constants (#8583) 2025-04-17 13:40:33 +12:00
dependabot[bot]
816371e3e9 Bump aioesphomeapi from 29.10.0 to 30.0.1 (#8579) 2025-04-16 15:24:15 -10:00
David Woodhouse
3c7bb65a23 Sort resolved IP addresses for dashboard (#8536)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-04-17 13:19:55 +12:00
Jonathan Swoboda
4a65fd76b3 [internal_temperature] Add p4 ifdefs (#8484) 2025-04-17 13:19:33 +12:00
Clyde Stubbs
2704db5eef [analog_threshold] Make thresholds templatable (#8452) 2025-04-17 13:19:12 +12:00
Clyde Stubbs
f10bc73d31 [mapping] Implement yaml-configured maps (#8333) 2025-04-17 13:18:48 +12:00
Clyde Stubbs
55e099450c [uptime] Add format config for text_sensor (#8304) 2025-04-17 13:18:08 +12:00
Andrew J.Swan
248dbd32a5 Add CUBIC PM2005/PM2105 Laser Particle Sensor Module (#8292)
Co-authored-by: Djordje <6750655+DjordjeMandic@users.noreply.github.com>
2025-04-17 13:17:35 +12:00
Jonathan Swoboda
a7b676231a [esp32_rmt_led_strip] Add use_dma option (#8270) 2025-04-17 13:16:10 +12:00
Keith Burzinski
2fd5f9ac58 [api] Allow noise encryption key to be set at runtime (#7296)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-04-17 13:15:25 +12:00
Jordan Zucker
ca4838a5f4 [prometheus] Add climate metrics (#8247) 2025-04-17 13:13:24 +12:00
Jesse Hills
1b72550236 Merge branch 'release' into dev 2025-04-17 12:56:09 +12:00
Jesse Hills
71afd49e3e Merge pull request #8581 from esphome/bump-2025.4.0
2025.4.0
2025-04-17 12:55:25 +12:00
Thomas Rupprecht
e5d718d1b1 fix typo USE_ESP32_VARIANT_ESP32H6 (#8580) 2025-04-16 21:23:58 +00:00
Jesse Hills
61f33d6401 Bump version to 2025.4.0 2025-04-17 09:03:08 +12:00
Jesse Hills
af9b568778 Merge branch 'beta' into dev 2025-04-16 12:13:17 +12:00
Jesse Hills
4a1eec567f Merge pull request #8573 from esphome/bump-2025.4.0b3
2025.4.0b3
2025-04-16 12:12:43 +12:00
Jesse Hills
5706b8476f Bump version to 2025.4.0b3 2025-04-16 08:48:38 +12:00
Marius Greuel
8981a86793 SML runtime optimizations (#8571) 2025-04-16 08:48:38 +12:00
Guillermo Ruffino
a7fd6dc382 Fix vscode validation not showing error squiggles (#8500)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-04-16 08:48:38 +12:00
dependabot[bot]
cb0a87c1f9 Bump zeroconf from 0.146.4 to 0.146.5 (#8569)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-16 08:48:38 +12:00
Jonathan Swoboda
b913a0b178 [am2315c] Use warning not fail during update (#8499) 2025-04-16 08:48:38 +12:00
David Woodhouse
214454ff51 Fix '--device MQTT' for devices with static IP (#8535) 2025-04-16 08:48:38 +12:00
J. Nick Koston
3677ef71d1 Add typing to protobuf code generator (#8541) 2025-04-16 08:19:22 +12:00
Marius Greuel
7e133171e0 SML runtime optimizations (#8571) 2025-04-16 07:58:14 +12:00
Guillermo Ruffino
bc56d319b5 Fix vscode validation not showing error squiggles (#8500)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-04-16 07:52:07 +12:00
dependabot[bot]
c423a6fb61 Bump codecov/codecov-action from 5.4.0 to 5.4.2 (#8572)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 19:48:51 +00:00
dependabot[bot]
4034bf4f04 Bump zeroconf from 0.146.4 to 0.146.5 (#8569)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 07:58:57 +00:00
Jonathan Swoboda
477abc05ae [am2315c] Use warning not fail during update (#8499) 2025-04-15 17:00:44 +12:00
David Woodhouse
ff2b93a3e4 Fix '--device MQTT' for devices with static IP (#8535) 2025-04-15 16:30:07 +12:00
Calum McConnell
a52d6388a9 Use python3 in place of python, as some systems don't emulate the former (#8568) 2025-04-15 04:13:37 +00:00
Clyde Stubbs
6259ca9ded [lvgl] Small buffers in internal RAM (#8523) 2025-04-15 13:10:44 +12:00
Jesse Hills
f6ef50505b Merge branch 'beta' into dev 2025-04-15 12:13:03 +12:00
Jesse Hills
b4cf437761 Merge pull request #8567 from esphome/bump-2025.4.0b2
2025.4.0b2
2025-04-15 12:12:31 +12:00
Jesse Hills
1d9f5f1f1e Bump version to 2025.4.0b2 2025-04-15 09:35:53 +12:00
Jonathan Swoboda
e47489708e Bump esphome-dashboard to 20250415.0 (#8565) 2025-04-15 09:35:53 +12:00
dependabot[bot]
8e1bdcd211 Bump zeroconf from 0.146.3 to 0.146.4 (#8563)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-04-15 09:35:53 +12:00
dependabot[bot]
3432d73584 Bump aioesphomeapi from 29.9.0 to 29.10.0 (#8562)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 09:35:53 +12:00
Clyde Stubbs
2bb86641f8 [lvgl] Ensure captured lambdas are in correct order (#8560) 2025-04-15 09:35:53 +12:00
Mischa Siekmann
6ca72a3a26 Speaker-Media-Player: Fix potential deadlock in audio pipeline (#8548) 2025-04-15 09:35:53 +12:00
Clyde Stubbs
c215098cb7 [lvgl] Add restore_value to select and number (#8494) 2025-04-15 09:35:53 +12:00
Clyde Stubbs
566968b6be [lvgl] Fix initial focus on roller (#8547) 2025-04-15 09:35:53 +12:00
Clyde Stubbs
fe51ee6257 [axs15231] Don't overwrite manual dimensions (#8553) 2025-04-15 09:35:53 +12:00
J. Nick Koston
2c499b326a Include MAC address in noise hello (#8551) 2025-04-15 09:35:53 +12:00
Clyde Stubbs
7c4ab7abfe [lvgl] Fix use of image without canvas (Bugfix) (#8540) 2025-04-15 09:35:52 +12:00
Jonathan Swoboda
3c242b7296 Bump esphome-dashboard to 20250415.0 (#8565) 2025-04-14 21:03:43 +00:00
Jesse Hills
00dd5b8339 [ci] Pin codecov action to v5.4.0 (#8564) 2025-04-15 08:09:51 +12:00
dependabot[bot]
a007a8237a Bump zeroconf from 0.146.3 to 0.146.4 (#8563)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-04-15 08:07:29 +12:00
dependabot[bot]
9b86cc37f0 Bump aioesphomeapi from 29.9.0 to 29.10.0 (#8562)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 08:06:48 +12:00
Clyde Stubbs
2dfcf950fa [lvgl] Ensure captured lambdas are in correct order (#8560) 2025-04-15 07:39:56 +12:00
Mischa Siekmann
5908b93e82 Speaker-Media-Player: Fix potential deadlock in audio pipeline (#8548) 2025-04-14 13:51:10 -05:00
Norbert Schulz
995db1f961 Add support for Waveshare 5.65" ACeP 7-Color display (#8557) 2025-04-14 12:02:40 +10:00
dependabot[bot]
abcc656a6f Bump ruff from 0.11.4 to 0.11.5 (#8546)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-13 14:41:33 -10:00
tomaszduda23
4a9f323d92 [core] make require_framework_version generic (#8412) 2025-04-14 10:59:40 +12:00
Calum McConnell
34a4e70cc5 Update setup to make .temp directory (#8558) 2025-04-14 10:48:45 +12:00
Clyde Stubbs
fb5d697c22 [lvgl] Add restore_value to select and number (#8494) 2025-04-14 10:45:30 +12:00
Clyde Stubbs
df4642208e [lvgl] Fix initial focus on roller (#8547) 2025-04-14 10:41:42 +12:00
Clyde Stubbs
264e234efc [axs15231] Don't overwrite manual dimensions (#8553) 2025-04-14 10:41:11 +12:00
J. Nick Koston
ca78dd44b5 Include MAC address in noise hello (#8551) 2025-04-12 09:16:14 -10:00
Jonathan Swoboda
7edf458898 [esp32] Allow pioarduino version 5.3.3 and 5.5.0 (#8526) 2025-04-11 21:34:43 -05:00
Clyde Stubbs
d9873e24a7 [lvgl] Fix use of image without canvas (Bugfix) (#8540) 2025-04-10 01:28:44 +00:00
dependabot[bot]
645bd490ba Bump pytest-cov from 6.0.0 to 6.1.1 (#8537)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-09 10:28:22 -10:00
dependabot[bot]
27f6d00e7a Bump ruff from 0.11.2 to 0.11.4 (#8538)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-09 10:28:07 -10:00
Jesse Hills
f9d668eeca Merge branch 'beta' into dev 2025-04-09 19:50:59 +12:00
Jesse Hills
92d1557efd Merge pull request #8534 from esphome/bump-2025.4.0b1
2025.4.0b1
2025-04-09 19:50:23 +12:00
Jesse Hills
6b930595e2 Bump version to 2025.5.0-dev 2025-04-09 14:19:05 +12:00
Jesse Hills
4a1cbfc533 Bump version to 2025.4.0b1 2025-04-09 14:19:05 +12:00
Clyde Stubbs
1f7a84cc8e [lvgl] Implement canvas widget (#8504) 2025-04-09 12:15:39 +12:00
David Woodhouse
8c5adfb33f real_time_clock: Apply timezone immediately in set_timezone() (#8531) 2025-04-09 12:03:38 +12:00
dependabot[bot]
399c9ba4be Bump pytest from 8.2.0 to 8.3.5 (#8528) 2025-04-08 23:38:06 +00:00
Clyde Stubbs
a866370a2e [spi] Implement octal mode (#8386) 2025-04-09 11:07:59 +12:00
Clyde Stubbs
6240bfff97 [lvgl] Make line points templatable (#8502) 2025-04-09 11:03:29 +12:00
Clyde Stubbs
1c72fd4674 [lvgl] add on_boot trigger (#8498) 2025-04-09 11:00:39 +12:00
J. Nick Koston
2291a1dc39 Bump aioesphomeapi to 29.9.0 (#8522) 2025-04-09 10:58:26 +12:00
J. Nick Koston
8269e2c961 Ensure plaintext responds with bad indicator byte before dropping the connection (#8521) 2025-04-09 10:27:23 +12:00
Clyde Stubbs
23dec912ad [psram] Allow use of experimental 120MHz octal mode (#8519) 2025-04-07 12:49:40 +00:00
Clyde Stubbs
9637ef35bd [component] Show error message for failed component (#8478) 2025-04-07 09:26:34 +00:00
J. Nick Koston
23e5cdb30e Rework max connections for BLE to avoid exceeding the hard limit (#8303) 2025-04-07 00:48:12 +00:00
dependabot[bot]
f3b1b11eba Bump flake8 from 7.0.0 to 7.2.0 (#8493)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-04-06 00:58:39 +00:00
dependabot[bot]
5ceba618f6 Bump setuptools from 76.0.0 to 78.1.0 (#8512)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-05 21:28:37 +00:00
victorclaessen
99d5ca3266 [ethernet_info] return actual ethernet MAC address (#8492)
Co-authored-by: clydebarrow <2366188+clydebarrow@users.noreply.github.com>
2025-04-04 18:59:46 +11:00
Jonathan Swoboda
219ba6152c [CI] Clang tidy fixes for 5.3.2 (#8510)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-04-03 07:32:17 +00:00
Jonathan Swoboda
ef0f969604 [core, qspi_dbi] Clang tidy fixes for 5.3.2 (#8509) 2025-04-03 02:03:04 -05:00
Curtis Malainey
82adcd656f [nau7802] fix bad blocking code (#8070) 2025-04-02 23:04:43 +00:00
Jesse Hills
fe35eee8df Update emails from nabucasa to OHF (#8508) 2025-04-03 11:08:46 +13:00
Shivam Maurya
864dd69038 Bump platformio to 6.1.18 (#8430)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-04-02 21:38:13 +00:00
dependabot[bot]
79f198ebff Bump zeroconf from 0.146.1 to 0.146.3 (#8507)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-02 20:47:46 +00:00
dependabot[bot]
4b0622aa23 Bump voluptuous from 0.14.2 to 0.15.2 (#8506)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-02 10:14:12 -10:00
dependabot[bot]
4ecc72ed54 Bump pyupgrade from 3.15.2 to 3.19.1 (#8496)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-02 23:50:30 +13:00
dependabot[bot]
791740e554 Bump yamllint from 1.35.1 to 1.37.0 (#8495)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-02 23:18:01 +13:00
dependabot[bot]
6bccc7e389 Bump ruamel-yaml from 0.18.6 to 0.18.10 (#8446)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-04-02 23:17:34 +13:00
dependabot[bot]
655075e71b Bump actions/upload-artifact from 4.6.1 to 4.6.2 (#8435)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-02 23:17:08 +13:00
dependabot[bot]
1df1e3cf48 Bump actions/download-artifact from 4.1.9 to 4.2.1 (#8434)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-02 23:16:42 +13:00
dependabot[bot]
05e52cae2b Bump docker/login-action from 3.3.0 to 3.4.0 in the docker-actions group (#8408)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-02 23:16:31 +13:00
dependabot[bot]
be60d9be9b Bump peter-evans/create-pull-request from 7.0.7 to 7.0.8 (#8362)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-02 23:16:17 +13:00
Oliver Kleinecke
e3eb3ee5d2 Add support for MCP4461 quad i2c digipot/rheostat (#8180)
Co-authored-by: Oliver Kleinecke <kleinecke.oliver@googlemail.com>
Co-authored-by: Djordje Mandic <6750655+DjordjeMandic@users.noreply.github.com>
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-04-01 23:55:06 +00:00
Clyde Stubbs
0812b3dd70 [lvgl] Add some defines (#8501) 2025-04-01 22:42:23 +00:00
NP v/d Spek
28a9f12595 Move CONF_DEFAULT to const.py (#8497) 2025-03-31 22:48:43 +00:00
Keith Burzinski
36b75c3faa Merge branch 'release' into dev 2025-03-31 17:07:16 -05:00
Keith Burzinski
584c5bd5be Merge pull request #8489 from esphome/bump-2025.3.3
2025.3.3
2025-03-31 17:07:02 -05:00
dependabot[bot]
bc372dbeb2 Bump platformio from 6.1.16 to 6.1.18 (#8449)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 21:28:47 +00:00
dependabot[bot]
37a03de849 Bump async-timeout from 4.0.3 to 5.0.1 (#8491)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 20:57:23 +00:00
dependabot[bot]
c8395cdf0a Bump pytest-asyncio from 0.25.3 to 0.26.0 (#8490)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 20:26:22 +00:00
Keith Burzinski
79c8a55459 Bump version to 2025.3.3 2025-03-31 12:48:16 -05:00
Kevin Ahrendt
36d6fe29f2 [speaker] Bugfixes: two pause state issues (#8488) 2025-03-31 12:48:16 -05:00
Clyde Stubbs
e1868ddecb [lvgl] Implement switch restore (#8481) 2025-03-31 12:48:16 -05:00
Kevin Ahrendt
6151644b96 [speaker] Bugfix: Media player always unpauses when receiving a stop command (#8474) 2025-03-31 12:48:15 -05:00
J. Nick Koston
a4914eb5b7 Bump ESP mdns to 1.8.2 (#8482) 2025-03-31 12:48:15 -05:00
Clyde Stubbs
57a57f0d6a [display] Don't assume glyph x_offset is zero. (#8473) 2025-03-31 12:48:15 -05:00
Kevin Ahrendt
7e9f93a290 [speaker] Bugfixes: two pause state issues (#8488) 2025-03-31 17:02:53 +00:00
dependabot[bot]
402ada07b5 Bump pytest-cov from 5.0.0 to 6.0.0 (#8462)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 14:33:00 +02:00
dependabot[bot]
9aa9abfc08 Bump actions/setup-python from 5.4.0 to 5.5.0 in /.github/actions/restore-python (#8467)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 14:28:21 +02:00
dependabot[bot]
4c1f83614b Bump actions/setup-python from 5.4.0 to 5.5.0 (#8468)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 14:28:11 +02:00
Clyde Stubbs
d1763f9831 [psram] 120MHz does not work in octal mode (#8477) 2025-03-31 09:03:59 +00:00
dependabot[bot]
c49391427f Bump ruff from 0.11.0 to 0.11.2 (#8461)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 01:52:10 +00:00
Clyde Stubbs
c42343be3a [lvgl] Implement switch restore (#8481) 2025-03-30 09:09:19 +00:00
Kevin Ahrendt
ffc233d99d [speaker] Bugfix: Media player always unpauses when receiving a stop command (#8474) 2025-03-30 08:41:08 +00:00
Jonathan Swoboda
5ed0046bdd [esp32] Allow pioarduino version 5.4.1 (#8480)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-03-29 07:28:10 +00:00
J. Nick Koston
2e16dd788c Bump ESP mdns to 1.8.2 (#8482) 2025-03-28 23:29:53 -05:00
Clyde Stubbs
58fe8b39b2 [scheduler] Properly handle millis() overflow (#8197) 2025-03-27 02:09:22 -05:00
Clyde Stubbs
ccd55a8e84 [display] Don't assume glyph x_offset is zero. (#8473) 2025-03-27 00:31:55 +00:00
Patrick
4bb59ce1d1 [esp32_can] Configurable enqueue timeout (#8453) 2025-03-26 04:06:23 +00:00
Keith Burzinski
bb988604c8 Merge branch 'release' into dev 2025-03-25 18:06:56 -05:00
Keith Burzinski
2dfd28ba3e [ld2450] Fix bluetooth state not reported correctly (#8458) 2025-03-25 15:21:10 -05:00
Kevin Ahrendt
63221d7a1f [speaker] Bugfix: Fix rapidly adding items to playlist (#8466)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-03-25 20:20:56 +00:00
Kevin Ahrendt
fb9a15f0af [media_player] Don't reset enqueue command (#8465) 2025-03-25 11:16:12 -05:00
Samuel Sieb
ce2e966005 fix 1bpp rendering (#8463) 2025-03-25 19:33:53 +11:00
Jonathan Swoboda
e7d1072c85 [core] Fix s2 build after crc header fix (#8459) 2025-03-24 18:04:25 -05:00
Clyde Stubbs
bc999b50b3 [font] More robust handling of fixed font sizes. (#8443)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-03-24 09:35:42 +00:00
Clyde Stubbs
6cfe3ac44d [gt911][cst226][ektf2232] Swap x and y calibration values (#8450)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-03-24 09:07:21 +00:00
Jonathan Swoboda
6787730aa4 [core] Fix 5.4.0 build issue (#8455)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-03-24 02:46:31 +00:00
Keith Burzinski
48a7927a60 Merge branch 'release' into dev 2025-03-22 23:45:32 -05:00
Clyde Stubbs
acce0bc45b [lvgl] Ensure non-zero screen dimensions during init (#8444) 2025-03-22 23:09:29 -05:00
dependabot[bot]
f5885de6f1 Bump pytest-asyncio from 0.23.6 to 0.25.3 (#8447)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-21 22:19:09 +00:00
dependabot[bot]
17e3bb7324 Bump aioesphomeapi from 29.6.0 to 29.7.0 (#8448)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-21 11:44:47 -10:00
Clyde Stubbs
d891521ce2 [lvgl] Set correct buffer size (#8442) 2025-03-21 04:12:27 +00:00
Clyde Stubbs
3320e4112b [cli] Add --reset and --upload_speed options (#8380) 2025-03-20 21:38:59 -05:00
Jonathan Swoboda
c0e4701e1d [esp32] Allow pioarduino versions 5.3.2 and 5.4.0 (#8440)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-03-20 21:31:58 -05:00
dependabot[bot]
f3390ff7f5 Bump tzlocal from 5.2 to 5.3.1 (#8423)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-20 14:41:23 -10:00
dependabot[bot]
dfbfb2a2bb Update wheel requirement from ~=0.43.0 to >=0.43,<0.46 (#8421)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-20 13:08:25 -10:00
dependabot[bot]
874026ca8f Bump pylint from 3.2.7 to 3.3.6 (#8441)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-03-20 22:07:38 +00:00
dependabot[bot]
4adda632bb Bump ruff from 0.9.2 to 0.11.0 (#8409) 2025-03-20 09:51:23 -10:00
Clyde Stubbs
6ea89644e7 [ft63x6] Get correct dimensions from display (#8417) 2025-03-19 23:37:44 -05:00
Keith Burzinski
64ff62c005 Merge branch 'release' into dev 2025-03-19 23:37:27 -05:00
dependabot[bot]
43805e6c56 Bump actions/cache from 4.2.2 to 4.2.3 (#8433)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 12:46:38 -10:00
dependabot[bot]
38bbfaccc6 Bump actions/cache from 4.2.2 to 4.2.3 in /.github/actions/restore-python (#8437)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 12:46:01 -10:00
Keith Burzinski
56b32aae11 Merge branch 'beta' into dev 2025-03-19 16:01:54 -05:00
Kevin Ahrendt
cbf68f1fd2 [audio] Bugfix: fix flac decoding glitches by using esp-audio-libs v1.1.3 (#8431) 2025-03-19 10:14:42 -05:00
Keith Burzinski
cf227d6f32 Merge branch 'beta' into dev 2025-03-18 15:21:26 -05:00
Clyde Stubbs
f993bb08c7 [core] Handle mis-typed platform name more cleanly (#8424) 2025-03-18 14:42:14 -05:00
Keith Burzinski
afa481aeea [docker] Bump libfreetype (#8426) 2025-03-18 17:28:15 +13:00
Keith Burzinski
dfb162e7a6 [docker] Bump curl, git, openssh-client, libopenjp2-7, nginx-light (#8419) 2025-03-17 01:55:29 -05:00
Keith Burzinski
098921b88f Merge branch 'beta' into dev 2025-03-16 01:54:05 -05:00
dependabot[bot]
c63a545750 Bump esphome-glyphsets from 0.1.0 to 0.2.0 (#8403)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-14 21:36:12 -10:00
dependabot[bot]
89f82be4cd Bump puremagic from 1.27 to 1.28 (#8406)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-14 21:35:51 -10:00
dependabot[bot]
c336dd9436 Bump setuptools from 69.2.0 to 76.0.0 (#8405)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-14 21:35:15 -10:00
Mikkel Jeppesen
fa25cebed5 Added getters for graphs ymin and ymax (#8112)
Co-authored-by: guillempages <guillempages@users.noreply.github.com>
2025-03-15 18:55:20 +13:00
Clyde Stubbs
7679c716b3 [font] Fix issues with bitmap fonts (#8407) 2025-03-14 20:17:16 +11:00
Keith Burzinski
225e2585e8 Merge branch 'beta' into dev 2025-03-13 01:31:27 -05:00
dependabot[bot]
c90185854e Bump tornado from 6.4 to 6.4.2 (#8398)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-12 23:22:08 -05:00
J. Nick Koston
7d8c39d295 Bump cryptography to 44.0.2 (#8399) 2025-03-12 23:21:45 -05:00
J. Nick Koston
59d282489a Rework pyproject.toml to make it parseable by dependabot (#8397) 2025-03-13 01:16:59 +00:00
J. Nick Koston
f9a0a63290 Bump aioesphomeapi to 29.6.0 (#8396) 2025-03-13 01:00:31 +00:00
Kevin Ahrendt
00000e0ea8 [api] add voice assistant announce to the api (#8395) 2025-03-12 14:35:10 -10:00
Kevin Ahrendt
bd853e6883 [core] add reallocation support to RAMAllocator (#8390) 2025-03-13 07:04:05 +11:00
Kevin Ahrendt
64d1d93fe0 [speaker, resampler, mixer] Make volume and mute getters virtual (#8391) 2025-03-12 14:34:38 -05:00
Kevin Ahrendt
266c2ef337 [audio, mixer] Memory and CPU performance improvements (#8387) 2025-03-12 14:18:31 -05:00
J. Nick Koston
35199c9b96 Bump mdns library to 1.8.0 (#8378)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2025-03-12 14:18:21 -05:00
Keith Burzinski
0a29138045 Merge branch 'beta' into dev 2025-03-12 03:40:43 -05:00
Keith Burzinski
04dc0ed129 Bump version to 2025.4.0-dev 2025-03-12 01:11:50 -05:00
896 changed files with 18272 additions and 4023 deletions

View File

@@ -114,4 +114,5 @@ config/
examples/
Dockerfile
.git/
tests/build/
tests/
.*

4
.github/FUNDING.yml vendored
View File

@@ -1,4 +0,0 @@
---
# These are supported funding model platforms
custom: https://www.nabucasa.com

View File

@@ -1,15 +1,11 @@
name: Build Image
inputs:
platform:
description: "Platform to build for"
required: true
example: "linux/amd64"
target:
description: "Target to build"
required: true
example: "docker"
baseimg:
description: "Base image type"
build_type:
description: "Build type"
required: true
example: "docker"
suffix:
@@ -19,6 +15,11 @@ inputs:
description: "Version to build"
required: true
example: "2023.12.0"
base_os:
description: "Base OS to use"
required: false
default: "debian"
example: "debian"
runs:
using: "composite"
steps:
@@ -46,52 +47,52 @@ runs:
- name: Build and push to ghcr by digest
id: build-ghcr
uses: docker/build-push-action@v6.15.0
uses: docker/build-push-action@v6.16.0
env:
DOCKER_BUILD_SUMMARY: false
DOCKER_BUILD_RECORD_UPLOAD: false
with:
context: .
file: ./docker/Dockerfile
platforms: ${{ inputs.platform }}
target: ${{ inputs.target }}
cache-from: type=gha
cache-to: ${{ steps.cache-to.outputs.value }}
build-args: |
BASEIMGTYPE=${{ inputs.baseimg }}
BUILD_TYPE=${{ inputs.build_type }}
BUILD_VERSION=${{ inputs.version }}
BUILD_OS=${{ inputs.base_os }}
outputs: |
type=image,name=ghcr.io/${{ steps.tags.outputs.image_name }},push-by-digest=true,name-canonical=true,push=true
- name: Export ghcr digests
shell: bash
run: |
mkdir -p /tmp/digests/${{ inputs.target }}/ghcr
mkdir -p /tmp/digests/${{ inputs.build_type }}/ghcr
digest="${{ steps.build-ghcr.outputs.digest }}"
touch "/tmp/digests/${{ inputs.target }}/ghcr/${digest#sha256:}"
touch "/tmp/digests/${{ inputs.build_type }}/ghcr/${digest#sha256:}"
- name: Build and push to dockerhub by digest
id: build-dockerhub
uses: docker/build-push-action@v6.15.0
uses: docker/build-push-action@v6.16.0
env:
DOCKER_BUILD_SUMMARY: false
DOCKER_BUILD_RECORD_UPLOAD: false
with:
context: .
file: ./docker/Dockerfile
platforms: ${{ inputs.platform }}
target: ${{ inputs.target }}
cache-from: type=gha
cache-to: ${{ steps.cache-to.outputs.value }}
build-args: |
BASEIMGTYPE=${{ inputs.baseimg }}
BUILD_TYPE=${{ inputs.build_type }}
BUILD_VERSION=${{ inputs.version }}
BUILD_OS=${{ inputs.base_os }}
outputs: |
type=image,name=docker.io/${{ steps.tags.outputs.image_name }},push-by-digest=true,name-canonical=true,push=true
- name: Export dockerhub digests
shell: bash
run: |
mkdir -p /tmp/digests/${{ inputs.target }}/dockerhub
mkdir -p /tmp/digests/${{ inputs.build_type }}/dockerhub
digest="${{ steps.build-dockerhub.outputs.digest }}"
touch "/tmp/digests/${{ inputs.target }}/dockerhub/${digest#sha256:}"
touch "/tmp/digests/${{ inputs.build_type }}/dockerhub/${digest#sha256:}"

View File

@@ -17,12 +17,12 @@ runs:
steps:
- name: Set up Python ${{ inputs.python-version }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.6.0
with:
python-version: ${{ inputs.python-version }}
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: venv
# yamllint disable-line rule:line-length
@@ -34,7 +34,7 @@ runs:
python -m venv venv
source venv/bin/activate
python --version
pip install -r requirements.txt -r requirements_optional.txt -r requirements_test.txt
pip install -r requirements.txt -r requirements_test.txt
pip install -e .
- name: Create Python virtual environment
if: steps.cache-venv.outputs.cache-hit != 'true' && runner.os == 'Windows'
@@ -43,5 +43,5 @@ runs:
python -m venv venv
./venv/Scripts/activate
python --version
pip install -r requirements.txt -r requirements_optional.txt -r requirements_test.txt
pip install -r requirements.txt -r requirements_test.txt
pip install -e .

View File

@@ -17,7 +17,6 @@ updates:
docker-actions:
applies-to: version-updates
patterns:
- "docker/setup-qemu-action"
- "docker/login-action"
- "docker/setup-buildx-action"
- package-ecosystem: github-actions

View File

@@ -23,7 +23,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v4.1.7
- name: Set up Python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.6.0
with:
python-version: "3.11"

View File

@@ -37,12 +37,15 @@ jobs:
strategy:
fail-fast: false
matrix:
os: ["ubuntu-latest", "ubuntu-24.04-arm"]
build_type: ["ha-addon", "docker", "lint"]
os: ["ubuntu-24.04", "ubuntu-24.04-arm"]
build_type:
- "ha-addon"
- "docker"
# - "lint"
steps:
- uses: actions/checkout@v4.1.7
- name: Set up Python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.6.0
with:
python-version: "3.9"
- name: Set up Docker Buildx

View File

@@ -39,15 +39,15 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Generate cache-key
id: cache-key
run: echo key="${{ hashFiles('requirements.txt', 'requirements_optional.txt', 'requirements_test.txt') }}" >> $GITHUB_OUTPUT
run: echo key="${{ hashFiles('requirements.txt', 'requirements_test.txt') }}" >> $GITHUB_OUTPUT
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.6.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache@v4.2.2
uses: actions/cache@v4.2.3
with:
path: venv
# yamllint disable-line rule:line-length
@@ -58,7 +58,7 @@ jobs:
python -m venv venv
. venv/bin/activate
python --version
pip install -r requirements.txt -r requirements_optional.txt -r requirements_test.txt
pip install -r requirements.txt -r requirements_test.txt
pip install -e .
ruff:
@@ -165,6 +165,7 @@ jobs:
. venv/bin/activate
script/ci-custom.py
script/build_codeowners.py --check
script/build_language_schema.py --check
pytest:
name: Run pytest
@@ -220,7 +221,7 @@ jobs:
. venv/bin/activate
pytest -vv --cov-report=xml --tb=native tests
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@v5.4.2
with:
token: ${{ secrets.CODECOV_TOKEN }}
@@ -303,14 +304,14 @@ jobs:
- name: Cache platformio
if: github.ref == 'refs/heads/dev'
uses: actions/cache@v4.2.2
uses: actions/cache@v4.2.3
with:
path: ~/.platformio
key: platformio-${{ matrix.pio_cache_key }}
- name: Cache platformio
if: github.ref != 'refs/heads/dev'
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: ~/.platformio
key: platformio-${{ matrix.pio_cache_key }}

View File

@@ -53,7 +53,7 @@ jobs:
steps:
- uses: actions/checkout@v4.1.7
- name: Set up Python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.6.0
with:
python-version: "3.x"
- name: Set up python environment
@@ -68,39 +68,39 @@ jobs:
uses: pypa/gh-action-pypi-publish@v1.12.4
deploy-docker:
name: Build ESPHome ${{ matrix.platform }}
name: Build ESPHome ${{ matrix.platform.arch }}
if: github.repository == 'esphome/esphome'
permissions:
contents: read
packages: write
runs-on: ubuntu-latest
runs-on: ${{ matrix.platform.os }}
needs: [init]
strategy:
fail-fast: false
matrix:
platform:
- linux/amd64
- linux/arm64
- arch: amd64
os: "ubuntu-24.04"
- arch: arm64
os: "ubuntu-24.04-arm"
steps:
- uses: actions/checkout@v4.1.7
- name: Set up Python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.6.0
with:
python-version: "3.9"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.10.0
- name: Set up QEMU
if: matrix.platform != 'linux/amd64'
uses: docker/setup-qemu-action@v3.6.0
- name: Log in to docker hub
uses: docker/login-action@v3.3.0
uses: docker/login-action@v3.4.0
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to the GitHub container registry
uses: docker/login-action@v3.3.0
uses: docker/login-action@v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -109,45 +109,36 @@ jobs:
- name: Build docker
uses: ./.github/actions/build-image
with:
platform: ${{ matrix.platform }}
target: docker
baseimg: docker
target: final
build_type: docker
suffix: ""
version: ${{ needs.init.outputs.tag }}
- name: Build ha-addon
uses: ./.github/actions/build-image
with:
platform: ${{ matrix.platform }}
target: hassio
baseimg: hassio
target: final
build_type: ha-addon
suffix: "hassio"
version: ${{ needs.init.outputs.tag }}
- name: Build lint
uses: ./.github/actions/build-image
with:
platform: ${{ matrix.platform }}
target: lint
baseimg: docker
suffix: lint
version: ${{ needs.init.outputs.tag }}
- name: Sanitize platform name
id: sanitize
run: |
echo "${{ matrix.platform }}" | sed 's|/|-|g' > /tmp/platform
echo name=$(cat /tmp/platform) >> $GITHUB_OUTPUT
# - name: Build lint
# uses: ./.github/actions/build-image
# with:
# target: lint
# build_type: lint
# suffix: lint
# version: ${{ needs.init.outputs.tag }}
- name: Upload digests
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: digests-${{ steps.sanitize.outputs.name }}
name: digests-${{ matrix.platform.arch }}
path: /tmp/digests
retention-days: 1
deploy-manifest:
name: Publish ESPHome ${{ matrix.image.title }} to ${{ matrix.registry }}
name: Publish ESPHome ${{ matrix.image.build_type }} to ${{ matrix.registry }}
runs-on: ubuntu-latest
needs:
- init
@@ -160,15 +151,12 @@ jobs:
fail-fast: false
matrix:
image:
- title: "ha-addon"
target: "hassio"
suffix: "hassio"
- title: "docker"
target: "docker"
- build_type: "docker"
suffix: ""
- title: "lint"
target: "lint"
suffix: "lint"
- build_type: "ha-addon"
suffix: "hassio"
# - build_type: "lint"
# suffix: "lint"
registry:
- ghcr
- dockerhub
@@ -176,7 +164,7 @@ jobs:
- uses: actions/checkout@v4.1.7
- name: Download digests
uses: actions/download-artifact@v4.1.9
uses: actions/download-artifact@v4.3.0
with:
pattern: digests-*
path: /tmp/digests
@@ -187,13 +175,13 @@ jobs:
- name: Log in to docker hub
if: matrix.registry == 'dockerhub'
uses: docker/login-action@v3.3.0
uses: docker/login-action@v3.4.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.3.0
uses: docker/login-action@v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -212,7 +200,7 @@ jobs:
done
- name: Create manifest list and push
working-directory: /tmp/digests/${{ matrix.image.target }}/${{ matrix.registry }}
working-directory: /tmp/digests/${{ matrix.image.build_type }}/${{ matrix.registry }}
run: |
docker buildx imagetools create $(jq -Rcnr 'inputs | . / "," | map("-t " + .) | join(" ")' <<< "${{ steps.tags.outputs.tags}}") \
$(printf '${{ steps.tags.outputs.image }}@sha256:%s ' *)

View File

@@ -22,7 +22,7 @@ jobs:
path: lib/home-assistant
- name: Setup Python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.6.0
with:
python-version: 3.12
@@ -36,11 +36,11 @@ jobs:
python ./script/sync-device_class.py
- name: Commit changes
uses: peter-evans/create-pull-request@v7.0.7
uses: peter-evans/create-pull-request@v7.0.8
with:
commit-message: "Synchronise Device Classes from Home Assistant"
committer: esphomebot <esphome@nabucasa.com>
author: esphomebot <esphome@nabucasa.com>
committer: esphomebot <esphome@openhomefoundation.org>
author: esphomebot <esphome@openhomefoundation.org>
branch: sync/device-classes
delete-branch: true
title: "Synchronise Device Classes from Home Assistant"

View File

@@ -4,7 +4,7 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.9.2
rev: v0.11.0
hooks:
# Run the linter.
- id: ruff
@@ -12,11 +12,11 @@ repos:
# Run the formatter.
- id: ruff-format
- repo: https://github.com/PyCQA/flake8
rev: 6.1.0
rev: 7.2.0
hooks:
- id: flake8
additional_dependencies:
- flake8-docstrings==1.5.0
- flake8-docstrings==1.7.0
- pydocstyle==5.1.1
files: ^(esphome|tests)/.+\.py$
- repo: https://github.com/pre-commit/pre-commit-hooks

View File

@@ -98,6 +98,7 @@ esphome/components/climate/* @esphome/core
esphome/components/climate_ir/* @glmnet
esphome/components/color_temperature/* @jesserockz
esphome/components/combination/* @Cat-Ion @kahrendt
esphome/components/const/* @esphome/core
esphome/components/coolix/* @glmnet
esphome/components/copy/* @OttoWinter
esphome/components/cover/* @esphome/core
@@ -250,6 +251,7 @@ esphome/components/ltr501/* @latonita
esphome/components/ltr_als_ps/* @latonita
esphome/components/lvgl/* @clydebarrow
esphome/components/m5stack_8angle/* @rnauber
esphome/components/mapping/* @clydebarrow
esphome/components/matrix_keypad/* @ssieb
esphome/components/max17043/* @blacknell
esphome/components/max31865/* @DAVe3283
@@ -266,6 +268,7 @@ esphome/components/mcp23x17_base/* @jesserockz
esphome/components/mcp23xxx_base/* @jesserockz
esphome/components/mcp2515/* @danielschramm @mvturnho
esphome/components/mcp3204/* @rsumner
esphome/components/mcp4461/* @p1ngb4ck
esphome/components/mcp4728/* @berfenger
esphome/components/mcp47a1/* @jesserockz
esphome/components/mcp9600/* @mreditor97
@@ -323,6 +326,7 @@ esphome/components/pcf8563/* @KoenBreeman
esphome/components/pid/* @OttoWinter
esphome/components/pipsolar/* @andreashergert1984
esphome/components/pm1006/* @habbie
esphome/components/pm2005/* @andrewjswan
esphome/components/pmsa003i/* @sjtrny
esphome/components/pmwcs3/* @SeByDocKy
esphome/components/pn532/* @OttoWinter @jesserockz

View File

@@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at esphome@nabucasa.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at esphome@openhomefoundation.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

View File

@@ -1,131 +1,54 @@
# Build these with the build.py script
# Example:
# python3 docker/build.py --tag dev --arch amd64 --build-type docker build
ARG BUILD_VERSION=dev
ARG BUILD_OS=alpine
ARG BUILD_BASE_VERSION=2025.04.0
ARG BUILD_TYPE=docker
# One of "docker", "hassio"
ARG BASEIMGTYPE=docker
FROM ghcr.io/esphome/docker-base:${BUILD_OS}-${BUILD_BASE_VERSION} AS base-source-docker
FROM ghcr.io/esphome/docker-base:${BUILD_OS}-ha-addon-${BUILD_BASE_VERSION} AS base-source-ha-addon
ARG BUILD_TYPE
FROM base-source-${BUILD_TYPE} AS base
# https://github.com/hassio-addons/addon-debian-base/releases
FROM ghcr.io/hassio-addons/debian-base:7.2.0 AS base-hassio
# https://hub.docker.com/_/debian?tab=tags&page=1&name=bookworm
FROM debian:12.2-slim AS base-docker
RUN git config --system --add safe.directory "*"
FROM base-${BASEIMGTYPE} AS base
RUN pip install uv==0.6.14
ARG TARGETARCH
ARG TARGETVARIANT
# Note that --break-system-packages is used below because
# https://peps.python.org/pep-0668/ added a safety check that prevents
# installing packages with the same name as a system package. This is
# not a problem for us because we are not concerned about overwriting
# system packages because we are running in an isolated container.
COPY requirements.txt /
RUN \
apt-get update \
# Use pinned versions so that we get updates with build caching
&& apt-get install -y --no-install-recommends \
python3-pip=23.0.1+dfsg-1 \
python3-setuptools=66.1.1-1+deb12u1 \
python3-venv=3.11.2-1+b1 \
python3-wheel=0.38.4-2 \
iputils-ping=3:20221126-1+deb12u1 \
git=1:2.39.5-0+deb12u2 \
curl=7.88.1-10+deb12u12 \
openssh-client=1:9.2p1-2+deb12u5 \
python3-cffi=1.15.1-5 \
libcairo2=1.16.0-7 \
libmagic1=1:5.44-3 \
patch=2.7.6-7 \
&& rm -rf \
/tmp/* \
/var/{cache,log}/* \
/var/lib/apt/lists/*
ENV \
# Fix click python3 lang warning https://click.palletsprojects.com/en/7.x/python3/
LANG=C.UTF-8 LC_ALL=C.UTF-8 \
# Store globally installed pio libs in /piolibs
PLATFORMIO_GLOBALLIB_DIR=/piolibs
uv pip install --no-cache-dir \
-r /requirements.txt
RUN \
pip3 install \
--break-system-packages --no-cache-dir \
# Keep platformio version in sync with requirements.txt
platformio==6.1.16 \
# Change some platformio settings
&& platformio settings set enable_telemetry No \
platformio settings set enable_telemetry No \
&& platformio settings set check_platformio_interval 1000000 \
&& mkdir -p /piolibs
# First install requirements to leverage caching when requirements don't change
# tmpfs is for https://github.com/rust-lang/cargo/issues/8719
COPY requirements.txt requirements_optional.txt /
RUN --mount=type=tmpfs,target=/root/.cargo <<END-OF-RUN
# Fail on any non-zero status
set -e
# install build tools in case wheels are not available
BUILD_DEPS="
build-essential=12.9
python3-dev=3.11.2-1+b1
zlib1g-dev=1:1.2.13.dfsg-1
libjpeg-dev=1:2.1.5-2
libfreetype-dev=2.12.1+dfsg-5+deb12u4
libssl-dev=3.0.15-1~deb12u1
libffi-dev=3.4.4-1
cargo=0.66.0+ds1-1
pkg-config=1.8.1-1
"
LIB_DEPS="
libtiff6=4.5.0-6+deb12u1
libopenjp2-7=2.5.0-2+deb12u1
"
if [ "$TARGETARCH$TARGETVARIANT" = "arm64" ]
then
apt-get update
apt-get install -y --no-install-recommends $BUILD_DEPS $LIB_DEPS
fi
CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse CARGO_HOME=/root/.cargo
pip3 install --break-system-packages --no-cache-dir -r /requirements.txt -r /requirements_optional.txt
if [ "$TARGETARCH$TARGETVARIANT" = "arm64" ]
then
apt-get remove -y --purge --auto-remove $BUILD_DEPS
rm -rf /tmp/* /var/{cache,log}/* /var/lib/apt/lists/*
fi
END-OF-RUN
COPY script/platformio_install_deps.py platformio.ini /
RUN /platformio_install_deps.py /platformio.ini --libraries
# Avoid unsafe git error when container user and file config volume permissions don't match
RUN git config --system --add safe.directory '*'
ARG BUILD_VERSION
LABEL \
org.opencontainers.image.authors="The ESPHome Authors" \
org.opencontainers.image.title="ESPHome" \
org.opencontainers.image.description="ESPHome is a system to configure your microcontrollers by simple yet powerful configuration files and control them remotely through Home Automation systems" \
org.opencontainers.image.url="https://esphome.io/" \
org.opencontainers.image.documentation="https://esphome.io/" \
org.opencontainers.image.source="https://github.com/esphome/esphome" \
org.opencontainers.image.licenses="ESPHome" \
org.opencontainers.image.version=${BUILD_VERSION}
# ======================= docker-type image =======================
FROM base AS docker
# Copy esphome and install
COPY . /esphome
RUN pip3 install --break-system-packages --no-cache-dir -e /esphome
# Settings for dashboard
ENV USERNAME="" PASSWORD=""
FROM base AS base-docker
# Expose the dashboard to Docker
EXPOSE 6052
# Run healthcheck (heartbeat)
HEALTHCHECK --interval=30s --timeout=30s \
CMD curl --fail http://localhost:6052/version -A "HealthCheck" || exit 1
CMD curl --fail http://localhost:6052/version -A "HealthCheck" || exit 1
COPY docker/docker_entrypoint.sh /entrypoint.sh
@@ -139,43 +62,13 @@ ENTRYPOINT ["/entrypoint.sh"]
CMD ["dashboard", "/config"]
ARG BUILD_VERSION=dev
# Labels
LABEL \
org.opencontainers.image.authors="The ESPHome Authors" \
org.opencontainers.image.title="ESPHome" \
org.opencontainers.image.description="ESPHome is a system to configure your microcontrollers by simple yet powerful configuration files and control them remotely through Home Automation systems" \
org.opencontainers.image.url="https://esphome.io/" \
org.opencontainers.image.documentation="https://esphome.io/" \
org.opencontainers.image.source="https://github.com/esphome/esphome" \
org.opencontainers.image.licenses="ESPHome" \
org.opencontainers.image.version=${BUILD_VERSION}
# ======================= hassio-type image =======================
FROM base AS hassio
RUN \
apt-get update \
# Use pinned versions so that we get updates with build caching
&& apt-get install -y --no-install-recommends \
nginx-light=1.22.1-9+deb12u1 \
&& rm -rf \
/tmp/* \
/var/{cache,log}/* \
/var/lib/apt/lists/*
ARG BUILD_VERSION=dev
# ======================= ha-addon-type image =======================
FROM base AS base-ha-addon
# Copy root filesystem
COPY docker/ha-addon-rootfs/ /
# Copy esphome and install
COPY . /esphome
RUN pip3 install --break-system-packages --no-cache-dir -e /esphome
# Labels
ARG BUILD_VERSION
LABEL \
io.hass.name="ESPHome" \
io.hass.description="ESPHome is a system to configure your microcontrollers by simple yet powerful configuration files and control them remotely through Home Automation systems" \
@@ -183,35 +76,9 @@ LABEL \
io.hass.version="${BUILD_VERSION}"
# io.hass.arch is inherited from addon-debian-base
ARG BUILD_TYPE
FROM base-${BUILD_TYPE} AS final
# ======================= lint-type image =======================
FROM base AS lint
ENV \
PLATFORMIO_CORE_DIR=/esphome/.temp/platformio
RUN \
curl -L https://apt.llvm.org/llvm-snapshot.gpg.key -o /etc/apt/trusted.gpg.d/apt.llvm.org.asc \
&& echo "deb http://apt.llvm.org/bookworm/ llvm-toolchain-bookworm-18 main" > /etc/apt/sources.list.d/llvm.sources.list \
&& apt-get update \
# Use pinned versions so that we get updates with build caching
&& apt-get install -y --no-install-recommends \
clang-format-13=1:13.0.1-11+b2 \
patch=2.7.6-7 \
software-properties-common=0.99.30-4.1~deb12u1 \
nano=7.2-1+deb12u1 \
build-essential=12.9 \
python3-dev=3.11.2-1+b1 \
clang-tidy-18=1:18.1.8~++20240731024826+3b5b5c1ec4a3-1~exp1~20240731144843.145 \
&& rm -rf \
/tmp/* \
/var/{cache,log}/* \
/var/lib/apt/lists/*
COPY requirements_test.txt /
RUN pip3 install --break-system-packages --no-cache-dir -r /requirements_test.txt
VOLUME ["/esphome"]
WORKDIR /esphome
# Copy esphome and install
COPY . /esphome
RUN uv pip install --no-cache-dir -e /esphome

View File

@@ -54,7 +54,7 @@ manifest_parser = subparsers.add_parser(
class DockerParams:
build_to: str
manifest_to: str
baseimgtype: str
build_type: str
platform: str
target: str
@@ -66,24 +66,19 @@ class DockerParams:
TYPE_LINT: "esphome/esphome-lint",
}[build_type]
build_to = f"{prefix}-{arch}"
baseimgtype = {
TYPE_DOCKER: "docker",
TYPE_HA_ADDON: "hassio",
TYPE_LINT: "docker",
}[build_type]
platform = {
ARCH_AMD64: "linux/amd64",
ARCH_AARCH64: "linux/arm64",
}[arch]
target = {
TYPE_DOCKER: "docker",
TYPE_HA_ADDON: "hassio",
TYPE_DOCKER: "final",
TYPE_HA_ADDON: "final",
TYPE_LINT: "lint",
}[build_type]
return cls(
build_to=build_to,
manifest_to=prefix,
baseimgtype=baseimgtype,
build_type=build_type,
platform=platform,
target=target,
)
@@ -145,7 +140,7 @@ def main():
"buildx",
"build",
"--build-arg",
f"BASEIMGTYPE={params.baseimgtype}",
f"BUILD_TYPE={params.build_type}",
"--build-arg",
f"BUILD_VERSION={args.tag}",
"--cache-from",

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python3
import re
import argparse
import re
CHANNEL_DEV = "dev"
CHANNEL_BETA = "beta"

View File

@@ -133,7 +133,7 @@ def get_port_type(port):
return "NETWORK"
def run_miniterm(config, port):
def run_miniterm(config, port, args):
import serial
from esphome import platformio_api
@@ -154,7 +154,7 @@ def run_miniterm(config, port):
# We can't set to False by default since it leads to toggling and hence
# ESP32 resets on some platforms.
if config["logger"][CONF_DEASSERT_RTS_DTR]:
if config["logger"][CONF_DEASSERT_RTS_DTR] or args.reset:
ser.dtr = False
ser.rts = False
@@ -244,11 +244,11 @@ def compile_program(args, config):
return 0 if idedata is not None else 1
def upload_using_esptool(config, port, file):
def upload_using_esptool(config, port, file, speed):
from esphome import platformio_api
first_baudrate = config[CONF_ESPHOME][CONF_PLATFORMIO_OPTIONS].get(
"upload_speed", 460800
first_baudrate = speed or config[CONF_ESPHOME][CONF_PLATFORMIO_OPTIONS].get(
"upload_speed", os.getenv("ESPHOME_UPLOAD_SPEED", "460800")
)
if file is not None:
@@ -348,7 +348,7 @@ def upload_program(config, args, host):
check_permissions(host)
if CORE.target_platform in (PLATFORM_ESP32, PLATFORM_ESP8266):
file = getattr(args, "file", None)
return upload_using_esptool(config, host, file)
return upload_using_esptool(config, host, file, args.upload_speed)
if CORE.target_platform in (PLATFORM_RP2040):
return upload_using_platformio(config, args.device)
@@ -375,10 +375,12 @@ def upload_program(config, args, host):
password = ota_conf.get(CONF_PASSWORD, "")
if (
not is_ip_address(CORE.address) # pylint: disable=too-many-boolean-expressions
and (get_port_type(host) == "MQTT" or config[CONF_MDNS][CONF_DISABLED])
and CONF_MQTT in config
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
@@ -397,7 +399,7 @@ def show_logs(config, args, port):
raise EsphomeError("Logger is not configured!")
if get_port_type(port) == "SERIAL":
check_permissions(port)
return run_miniterm(config, 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
@@ -842,6 +844,10 @@ def parse_args(argv):
"--device",
help="Manually specify the serial port/address to use, for example /dev/ttyUSB0.",
)
parser_upload.add_argument(
"--upload_speed",
help="Override the default or configured upload speed.",
)
parser_upload.add_argument(
"--file",
help="Manually specify the binary file to upload.",
@@ -860,6 +866,13 @@ def parse_args(argv):
"--device",
help="Manually specify the serial port/address to use, for example /dev/ttyUSB0.",
)
parser_logs.add_argument(
"--reset",
"-r",
action="store_true",
help="Reset the device before starting serial logs.",
default=os.getenv("ESPHOME_SERIAL_LOGGING_RESET"),
)
parser_discover = subparsers.add_parser(
"discover",
@@ -882,9 +895,20 @@ def parse_args(argv):
"--device",
help="Manually specify the serial port/address to use, for example /dev/ttyUSB0.",
)
parser_run.add_argument(
"--upload_speed",
help="Override the default or configured upload speed.",
)
parser_run.add_argument(
"--no-logs", help="Disable starting logs.", action="store_true"
)
parser_run.add_argument(
"--reset",
"-r",
action="store_true",
help="Reset the device before starting serial logs.",
default=os.getenv("ESPHOME_SERIAL_LOGGING_RESET"),
)
parser_clean = subparsers.add_parser(
"clean-mqtt",

View File

@@ -1,10 +1,10 @@
import esphome.codegen as cg
from esphome.components import sensor, uart
from esphome.const import (
DEVICE_CLASS_DISTANCE,
ICON_ARROW_EXPAND_VERTICAL,
STATE_CLASS_MEASUREMENT,
UNIT_METER,
ICON_ARROW_EXPAND_VERTICAL,
DEVICE_CLASS_DISTANCE,
)
CODEOWNERS = ["@MrSuicideParrot"]

View File

@@ -1,9 +1,9 @@
import esphome.codegen as cg
from esphome.components import sensor, uart
from esphome.const import (
STATE_CLASS_MEASUREMENT,
ICON_ARROW_EXPAND_VERTICAL,
DEVICE_CLASS_DISTANCE,
ICON_ARROW_EXPAND_VERTICAL,
STATE_CLASS_MEASUREMENT,
UNIT_MILLIMETER,
)

View File

@@ -1,10 +1,9 @@
from esphome import pins
import esphome.codegen as cg
from esphome.components import stepper
import esphome.config_validation as cv
import esphome.codegen as cg
from esphome.const import CONF_DIR_PIN, CONF_ID, CONF_SLEEP_PIN, CONF_STEP_PIN
a4988_ns = cg.esphome_ns.namespace("a4988")
A4988 = a4988_ns.class_("A4988", stepper.Stepper, cg.Component)

View File

@@ -1,12 +1,12 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_EQUATION,
CONF_HUMIDITY,
CONF_TEMPERATURE,
STATE_CLASS_MEASUREMENT,
CONF_EQUATION,
ICON_WATER,
STATE_CLASS_MEASUREMENT,
UNIT_GRAMS_PER_CUBIC_METER,
)

View File

@@ -114,13 +114,14 @@ void IRAM_ATTR HOT AcDimmerDataStore::gpio_intr() {
// fully off, disable output immediately
this->gate_pin.digital_write(false);
} else {
auto min_us = this->cycle_time_us * this->min_power / 1000;
if (this->method == DIM_METHOD_TRAILING) {
this->enable_time_us = 1; // cannot be 0
this->disable_time_us = std::max((uint32_t) 10, this->value * this->cycle_time_us / 65535);
// calculate time until disable in µs with integer arithmetic and take into account min_power
this->disable_time_us = std::max((uint32_t) 10, this->value * (this->cycle_time_us - min_us) / 65535 + min_us);
} else {
// calculate time until enable in µs: (1.0-value)*cycle_time, but with integer arithmetic
// also take into account min_power
auto min_us = this->cycle_time_us * this->min_power / 1000;
this->enable_time_us = std::max((uint32_t) 1, ((65535 - this->value) * (this->cycle_time_us - min_us)) / 65535);
if (this->method == DIM_METHOD_LEADING_PULSE) {

View File

@@ -1,8 +1,8 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
import esphome.codegen as cg
from esphome.components import output
from esphome.const import CONF_ID, CONF_MIN_POWER, CONF_METHOD
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_METHOD, CONF_MIN_POWER
CODEOWNERS = ["@glmnet"]

View File

@@ -1,8 +1,8 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import uart
from esphome.components.light.types import AddressableLightEffect
from esphome.components.light.effects import register_addressable_effect
from esphome.components.light.types import AddressableLightEffect
import esphome.config_validation as cv
from esphome.const import CONF_NAME, CONF_UART_ID
DEPENDENCIES = ["uart"]

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import spi
import esphome.config_validation as cv
from esphome.const import CONF_ID
DEPENDENCIES = ["spi"]

View File

@@ -1,9 +1,9 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor, voltage_sampler
from esphome.const import CONF_ID, CONF_CHANNEL
import esphome.config_validation as cv
from esphome.const import CONF_CHANNEL, CONF_ID
from .. import adc128s102_ns, ADC128S102
from .. import ADC128S102, adc128s102_ns
AUTO_LOAD = ["voltage_sampler"]
DEPENDENCIES = ["adc128s102"]

View File

@@ -1,15 +1,15 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import display, light
import esphome.config_validation as cv
from esphome.const import (
CONF_ADDRESSABLE_LIGHT_ID,
CONF_HEIGHT,
CONF_ID,
CONF_LAMBDA,
CONF_PAGES,
CONF_ADDRESSABLE_LIGHT_ID,
CONF_HEIGHT,
CONF_WIDTH,
CONF_UPDATE_INTERVAL,
CONF_PIXEL_MAPPER,
CONF_UPDATE_INTERVAL,
CONF_WIDTH,
)
CODEOWNERS = ["@justfalter"]

View File

@@ -1,7 +1,7 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor, i2c
from esphome import pins
import esphome.codegen as cg
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_ACTIVE_POWER,
CONF_APPARENT_POWER,

View File

@@ -1,27 +1,27 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor
from esphome import pins
import esphome.codegen as cg
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_FREQUENCY,
CONF_IRQ_PIN,
CONF_VOLTAGE,
CONF_FREQUENCY,
CONF_VOLTAGE_GAIN,
DEVICE_CLASS_CURRENT,
DEVICE_CLASS_APPARENT_POWER,
DEVICE_CLASS_POWER,
DEVICE_CLASS_REACTIVE_POWER,
DEVICE_CLASS_POWER_FACTOR,
DEVICE_CLASS_VOLTAGE,
DEVICE_CLASS_CURRENT,
DEVICE_CLASS_FREQUENCY,
DEVICE_CLASS_POWER,
DEVICE_CLASS_POWER_FACTOR,
DEVICE_CLASS_REACTIVE_POWER,
DEVICE_CLASS_VOLTAGE,
STATE_CLASS_MEASUREMENT,
UNIT_VOLT,
UNIT_HERTZ,
UNIT_AMPERE,
UNIT_VOLT_AMPS,
UNIT_WATT,
UNIT_VOLT_AMPS_REACTIVE,
UNIT_HERTZ,
UNIT_PERCENT,
UNIT_VOLT,
UNIT_VOLT_AMPS,
UNIT_VOLT_AMPS_REACTIVE,
UNIT_WATT,
)
CONF_CURRENT_A = "current_a"

View File

@@ -1,9 +1,8 @@
import esphome.codegen as cg
from esphome.components import ade7953_base, i2c
import esphome.config_validation as cv
from esphome.components import i2c, ade7953_base
from esphome.const import CONF_ID
DEPENDENCIES = ["i2c"]
AUTO_LOAD = ["ade7953_base"]

View File

@@ -1,9 +1,8 @@
import esphome.codegen as cg
from esphome.components import ade7953_base, spi
import esphome.config_validation as cv
from esphome.components import spi, ade7953_base
from esphome.const import CONF_ID
DEPENDENCIES = ["spi"]
AUTO_LOAD = ["ade7953_base"]

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import i2c
import esphome.config_validation as cv
from esphome.const import CONF_ID
DEPENDENCIES = ["i2c"]

View File

@@ -1,17 +1,18 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor, voltage_sampler
import esphome.config_validation as cv
from esphome.const import (
CONF_GAIN,
CONF_ID,
CONF_MULTIPLEXER,
CONF_RESOLUTION,
CONF_SAMPLE_RATE,
DEVICE_CLASS_VOLTAGE,
STATE_CLASS_MEASUREMENT,
UNIT_VOLT,
CONF_ID,
)
from .. import ads1115_ns, ADS1115Component, CONF_ADS1115_ID
from .. import CONF_ADS1115_ID, ADS1115Component, ads1115_ns
AUTO_LOAD = ["voltage_sampler"]
DEPENDENCIES = ["ads1115"]

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import spi
import esphome.config_validation as cv
from esphome.const import CONF_ID
CODEOWNERS = ["@solomondg1"]

View File

@@ -1,17 +1,18 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor, voltage_sampler
import esphome.config_validation as cv
from esphome.const import (
CONF_GAIN,
CONF_MULTIPLEXER,
DEVICE_CLASS_VOLTAGE,
CONF_TYPE,
DEVICE_CLASS_TEMPERATURE,
DEVICE_CLASS_VOLTAGE,
STATE_CLASS_MEASUREMENT,
UNIT_CELSIUS,
UNIT_VOLT,
CONF_TYPE,
)
from .. import ads1118_ns, ADS1118, CONF_ADS1118_ID
from .. import ADS1118, CONF_ADS1118_ID, ads1118_ns
AUTO_LOAD = ["voltage_sampler"]
DEPENDENCIES = ["ads1118"]

View File

@@ -1,21 +1,21 @@
import esphome.codegen as cg
from esphome import automation
import esphome.config_validation as cv
import esphome.codegen as cg
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_ADDRESS,
CONF_ID,
ICON_RADIATOR,
ICON_RESTART,
CONF_MODE,
CONF_TVOC,
CONF_VALUE,
CONF_VERSION,
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
ENTITY_CATEGORY_DIAGNOSTIC,
ICON_RADIATOR,
ICON_RESTART,
STATE_CLASS_MEASUREMENT,
UNIT_OHM,
UNIT_PARTS_PER_BILLION,
CONF_ADDRESS,
CONF_TVOC,
CONF_VERSION,
CONF_MODE,
CONF_VALUE,
)
CONF_RESISTANCE = "resistance"

View File

@@ -1,16 +1,16 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_HUMIDITY,
CONF_ID,
CONF_TEMPERATURE,
CONF_VARIANT,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_TEMPERATURE,
STATE_CLASS_MEASUREMENT,
UNIT_CELSIUS,
UNIT_PERCENT,
CONF_VARIANT,
)
DEPENDENCIES = ["i2c"]

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import esp32_ble_tracker
import esphome.config_validation as cv
from esphome.const import CONF_ID
DEPENDENCIES = ["esp32_ble_tracker"]

View File

@@ -1,18 +1,17 @@
import esphome.codegen as cg
from esphome.components import ble_client, sensor
import esphome.config_validation as cv
from esphome.components import sensor, ble_client
from esphome.const import (
CONF_BATTERY_VOLTAGE,
CONF_HUMIDITY,
CONF_PRESSURE,
CONF_TEMPERATURE,
CONF_TVOC,
DEVICE_CLASS_VOLTAGE,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_PRESSURE,
DEVICE_CLASS_TEMPERATURE,
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
DEVICE_CLASS_VOLTAGE,
ENTITY_CATEGORY_DIAGNOSTIC,
STATE_CLASS_MEASUREMENT,
UNIT_CELSIUS,

View File

@@ -1,10 +1,7 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import airthings_wave_base
from esphome.const import (
CONF_ID,
)
import esphome.config_validation as cv
from esphome.const import CONF_ID
DEPENDENCIES = airthings_wave_base.DEPENDENCIES

View File

@@ -1,20 +1,19 @@
import esphome.codegen as cg
from esphome.components import airthings_wave_base, sensor
import esphome.config_validation as cv
from esphome.components import sensor, airthings_wave_base
from esphome.const import (
DEVICE_CLASS_CARBON_DIOXIDE,
STATE_CLASS_MEASUREMENT,
ICON_RADIOACTIVE,
CONF_CO2,
CONF_ID,
CONF_ILLUMINANCE,
CONF_RADON,
CONF_RADON_LONG_TERM,
CONF_CO2,
UNIT_BECQUEREL_PER_CUBIC_METER,
UNIT_PARTS_PER_MILLION,
CONF_ILLUMINANCE,
UNIT_LUX,
DEVICE_CLASS_CARBON_DIOXIDE,
DEVICE_CLASS_ILLUMINANCE,
ICON_RADIOACTIVE,
STATE_CLASS_MEASUREMENT,
UNIT_BECQUEREL_PER_CUBIC_METER,
UNIT_LUX,
UNIT_PARTS_PER_MILLION,
)
DEPENDENCIES = airthings_wave_base.DEPENDENCIES

View File

@@ -1,20 +1,20 @@
import esphome.codegen as cg
from esphome.components import ble_client, sensor
import esphome.config_validation as cv
from esphome.components import sensor, ble_client
from esphome.const import (
CONF_ID,
CONF_CURRENT,
CONF_FLOW,
CONF_HEAD,
CONF_ID,
CONF_POWER,
CONF_SPEED,
CONF_VOLTAGE,
UNIT_AMPERE,
UNIT_CUBIC_METER_PER_HOUR,
UNIT_METER,
UNIT_REVOLUTIONS_PER_MINUTE,
UNIT_VOLT,
UNIT_WATT,
UNIT_METER,
UNIT_CUBIC_METER_PER_HOUR,
UNIT_REVOLUTIONS_PER_MINUTE,
)
alpha3_ns = cg.esphome_ns.namespace("alpha3")

View File

@@ -128,7 +128,7 @@ void AM2315C::update() {
data[2] = 0x00;
if (this->write(data, 3) != i2c::ERROR_OK) {
ESP_LOGE(TAG, "Write failed!");
this->mark_failed();
this->status_set_warning();
return;
}
@@ -138,12 +138,12 @@ void AM2315C::update() {
uint8_t status = 0;
if (this->read(&status, 1) != i2c::ERROR_OK) {
ESP_LOGE(TAG, "Read failed!");
this->mark_failed();
this->status_set_warning();
return;
}
if ((status & 0x80) == 0x80) {
ESP_LOGE(TAG, "HW still busy!");
this->mark_failed();
this->status_set_warning();
return;
}
@@ -151,7 +151,7 @@ void AM2315C::update() {
uint8_t data[7];
if (this->read(data, 7) != i2c::ERROR_OK) {
ESP_LOGE(TAG, "Read failed!");
this->mark_failed();
this->status_set_warning();
return;
}

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_HUMIDITY,
CONF_ID,

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_HUMIDITY,
CONF_ID,

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
from esphome.components import ble_client, cover
import esphome.config_validation as cv
from esphome.components import cover, ble_client
from esphome.const import CONF_ID, CONF_PIN
CODEOWNERS = ["@buxtronix"]

View File

@@ -1,12 +1,12 @@
import esphome.codegen as cg
from esphome.components import ble_client, sensor
import esphome.config_validation as cv
from esphome.components import sensor, ble_client
from esphome.const import (
CONF_ID,
CONF_BATTERY_LEVEL,
CONF_ID,
CONF_ILLUMINANCE,
DEVICE_CLASS_BATTERY,
ENTITY_CATEGORY_DIAGNOSTIC,
CONF_ILLUMINANCE,
ICON_BRIGHTNESS_5,
UNIT_PERCENT,
)

View File

@@ -14,7 +14,8 @@ void AnalogThresholdBinarySensor::setup() {
if (std::isnan(sensor_value)) {
this->publish_initial_state(false);
} else {
this->publish_initial_state(sensor_value >= (this->lower_threshold_ + this->upper_threshold_) / 2.0f);
this->publish_initial_state(sensor_value >=
(this->lower_threshold_.value() + this->upper_threshold_.value()) / 2.0f);
}
}
@@ -24,7 +25,8 @@ void AnalogThresholdBinarySensor::set_sensor(sensor::Sensor *analog_sensor) {
this->sensor_->add_on_state_callback([this](float sensor_value) {
// if there is an invalid sensor reading, ignore the change and keep the current state
if (!std::isnan(sensor_value)) {
this->publish_state(sensor_value >= (this->state ? this->lower_threshold_ : this->upper_threshold_));
this->publish_state(sensor_value >=
(this->state ? this->lower_threshold_.value() : this->upper_threshold_.value()));
}
});
}
@@ -32,8 +34,8 @@ void AnalogThresholdBinarySensor::set_sensor(sensor::Sensor *analog_sensor) {
void AnalogThresholdBinarySensor::dump_config() {
LOG_BINARY_SENSOR("", "Analog Threshold Binary Sensor", this);
LOG_SENSOR(" ", "Sensor", this->sensor_);
ESP_LOGCONFIG(TAG, " Upper threshold: %.11f", this->upper_threshold_);
ESP_LOGCONFIG(TAG, " Lower threshold: %.11f", this->lower_threshold_);
ESP_LOGCONFIG(TAG, " Upper threshold: %.11f", this->upper_threshold_.value());
ESP_LOGCONFIG(TAG, " Lower threshold: %.11f", this->lower_threshold_.value());
}
} // namespace analog_threshold

View File

@@ -15,14 +15,13 @@ class AnalogThresholdBinarySensor : public Component, public binary_sensor::Bina
float get_setup_priority() const override { return setup_priority::DATA; }
void set_sensor(sensor::Sensor *analog_sensor);
void set_upper_threshold(float threshold) { this->upper_threshold_ = threshold; }
void set_lower_threshold(float threshold) { this->lower_threshold_ = threshold; }
template<typename T> void set_upper_threshold(T upper_threshold) { this->upper_threshold_ = upper_threshold; }
template<typename T> void set_lower_threshold(T lower_threshold) { this->lower_threshold_ = lower_threshold; }
protected:
sensor::Sensor *sensor_{nullptr};
float upper_threshold_;
float lower_threshold_;
TemplatableValue<float> upper_threshold_{};
TemplatableValue<float> lower_threshold_{};
};
} // namespace analog_threshold

View File

@@ -1,10 +1,7 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import binary_sensor, sensor
from esphome.const import (
CONF_SENSOR_ID,
CONF_THRESHOLD,
)
import esphome.config_validation as cv
from esphome.const import CONF_SENSOR_ID, CONF_THRESHOLD
analog_threshold_ns = cg.esphome_ns.namespace("analog_threshold")
@@ -21,11 +18,11 @@ CONFIG_SCHEMA = (
{
cv.Required(CONF_SENSOR_ID): cv.use_id(sensor.Sensor),
cv.Required(CONF_THRESHOLD): cv.Any(
cv.float_,
cv.templatable(cv.float_),
cv.Schema(
{
cv.Required(CONF_UPPER): cv.float_,
cv.Required(CONF_LOWER): cv.float_,
cv.Required(CONF_UPPER): cv.templatable(cv.float_),
cv.Required(CONF_LOWER): cv.templatable(cv.float_),
}
),
),
@@ -42,9 +39,11 @@ async def to_code(config):
sens = await cg.get_variable(config[CONF_SENSOR_ID])
cg.add(var.set_sensor(sens))
if isinstance(config[CONF_THRESHOLD], float):
cg.add(var.set_upper_threshold(config[CONF_THRESHOLD]))
cg.add(var.set_lower_threshold(config[CONF_THRESHOLD]))
if isinstance(config[CONF_THRESHOLD], dict):
lower = await cg.templatable(config[CONF_THRESHOLD][CONF_LOWER], [], float)
upper = await cg.templatable(config[CONF_THRESHOLD][CONF_UPPER], [], float)
else:
cg.add(var.set_upper_threshold(config[CONF_THRESHOLD][CONF_UPPER]))
cg.add(var.set_lower_threshold(config[CONF_THRESHOLD][CONF_LOWER]))
lower = await cg.templatable(config[CONF_THRESHOLD], [], float)
upper = lower
cg.add(var.set_upper_threshold(upper))
cg.add(var.set_lower_threshold(lower))

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
from esphome.components import ble_client, climate
import esphome.config_validation as cv
from esphome.components import climate, ble_client
from esphome.const import CONF_ID, CONF_UNIT_OF_MEASUREMENT
UNITS = {

View File

@@ -2,8 +2,8 @@
# https://www.mouser.ca/datasheet/2/678/AVGO_S_A0002854364_1-2574547.pdf
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_GAIN,
DEVICE_CLASS_ILLUMINANCE,

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import i2c
import esphome.config_validation as cv
from esphome.const import CONF_ID
DEPENDENCIES = ["i2c"]

View File

@@ -1,7 +1,8 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import binary_sensor
import esphome.config_validation as cv
from esphome.const import CONF_DIRECTION, DEVICE_CLASS_MOVING
from . import APDS9960, CONF_APDS9960_ID
DEPENDENCIES = ["apds9960"]

View File

@@ -1,12 +1,13 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_TYPE,
ICON_LIGHTBULB,
STATE_CLASS_MEASUREMENT,
UNIT_PERCENT,
ICON_LIGHTBULB,
)
from . import APDS9960, CONF_APDS9960_ID
DEPENDENCIES = ["apds9960"]

View File

@@ -82,6 +82,19 @@ ACTIONS_SCHEMA = automation.validate_automation(
),
)
ENCRYPTION_SCHEMA = cv.Schema(
{
cv.Optional(CONF_KEY): validate_encryption_key,
}
)
def _encryption_schema(config):
if config is None:
config = {}
return ENCRYPTION_SCHEMA(config)
CONFIG_SCHEMA = cv.All(
cv.Schema(
{
@@ -95,11 +108,7 @@ CONFIG_SCHEMA = cv.All(
CONF_SERVICES, group_of_exclusion=CONF_ACTIONS
): ACTIONS_SCHEMA,
cv.Exclusive(CONF_ACTIONS, group_of_exclusion=CONF_ACTIONS): ACTIONS_SCHEMA,
cv.Optional(CONF_ENCRYPTION): cv.Schema(
{
cv.Required(CONF_KEY): validate_encryption_key,
}
),
cv.Optional(CONF_ENCRYPTION): _encryption_schema,
cv.Optional(CONF_ON_CLIENT_CONNECTED): automation.validate_automation(
single=True
),
@@ -151,9 +160,17 @@ async def to_code(config):
config[CONF_ON_CLIENT_DISCONNECTED],
)
if encryption_config := config.get(CONF_ENCRYPTION):
decoded = base64.b64decode(encryption_config[CONF_KEY])
cg.add(var.set_noise_psk(list(decoded)))
if (encryption_config := config.get(CONF_ENCRYPTION, None)) is not None:
if key := encryption_config.get(CONF_KEY):
decoded = base64.b64decode(key)
cg.add(var.set_noise_psk(list(decoded)))
else:
# No key provided, but encryption desired
# This will allow a plaintext client to provide a noise key,
# send it to the device, and then switch to noise.
# The key will be saved in flash and used for future connections
# and plaintext disabled. Only a factory reset can remove it.
cg.add_define("USE_API_PLAINTEXT")
cg.add_define("USE_API_NOISE")
cg.add_library("esphome/noise-c", "0.1.6")
else:

View File

@@ -31,6 +31,7 @@ service APIConnection {
option (needs_authentication) = false;
}
rpc execute_service (ExecuteServiceRequest) returns (void) {}
rpc noise_encryption_set_key (NoiseEncryptionSetKeyRequest) returns (NoiseEncryptionSetKeyResponse) {}
rpc cover_command (CoverCommandRequest) returns (void) {}
rpc fan_command (FanCommandRequest) returns (void) {}
@@ -230,6 +231,9 @@ message DeviceInfoResponse {
// The Bluetooth mac address of the device. For example "AC:BC:32:89:0E:AA"
string bluetooth_mac_address = 18;
// Supports receiving and saving api encryption key
bool api_encryption_supported = 19;
}
message ListEntitiesRequest {
@@ -654,6 +658,23 @@ message SubscribeLogsResponse {
bool send_failed = 4;
}
// ==================== NOISE ENCRYPTION ====================
message NoiseEncryptionSetKeyRequest {
option (id) = 124;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_API_NOISE";
bytes key = 1;
}
message NoiseEncryptionSetKeyResponse {
option (id) = 125;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_API_NOISE";
bool success = 1;
}
// ==================== HOMEASSISTANT.SERVICE ====================
message SubscribeHomeassistantServicesRequest {
option (id) = 34;

View File

@@ -62,7 +62,14 @@ APIConnection::APIConnection(std::unique_ptr<socket::Socket> sock, APIServer *pa
: parent_(parent), deferred_message_queue_(this), initial_state_iterator_(this), list_entities_iterator_(this) {
this->proto_write_buffer_.reserve(64);
#if defined(USE_API_PLAINTEXT)
#if defined(USE_API_PLAINTEXT) && defined(USE_API_NOISE)
auto noise_ctx = parent->get_noise_ctx();
if (noise_ctx->has_psk()) {
this->helper_ = std::unique_ptr<APIFrameHelper>{new APINoiseFrameHelper(std::move(sock), noise_ctx)};
} else {
this->helper_ = std::unique_ptr<APIFrameHelper>{new APIPlaintextFrameHelper(std::move(sock))};
}
#elif defined(USE_API_PLAINTEXT)
this->helper_ = std::unique_ptr<APIFrameHelper>{new APIPlaintextFrameHelper(std::move(sock))};
#elif defined(USE_API_NOISE)
this->helper_ = std::unique_ptr<APIFrameHelper>{new APINoiseFrameHelper(std::move(sock), parent->get_noise_ctx())};
@@ -1848,6 +1855,9 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
#ifdef USE_VOICE_ASSISTANT
resp.legacy_voice_assistant_version = voice_assistant::global_voice_assistant->get_legacy_version();
resp.voice_assistant_feature_flags = voice_assistant::global_voice_assistant->get_feature_flags();
#endif
#ifdef USE_API_NOISE
resp.api_encryption_supported = true;
#endif
return resp;
}
@@ -1869,6 +1879,26 @@ void APIConnection::execute_service(const ExecuteServiceRequest &msg) {
ESP_LOGV(TAG, "Could not find matching service!");
}
}
#ifdef USE_API_NOISE
NoiseEncryptionSetKeyResponse APIConnection::noise_encryption_set_key(const NoiseEncryptionSetKeyRequest &msg) {
psk_t psk{};
NoiseEncryptionSetKeyResponse resp;
if (base64_decode(msg.key, psk.data(), msg.key.size()) != psk.size()) {
ESP_LOGW(TAG, "Invalid encryption key length");
resp.success = false;
return resp;
}
if (!this->parent_->save_noise_psk(psk, true)) {
ESP_LOGW(TAG, "Failed to save encryption key");
resp.success = false;
return resp;
}
resp.success = true;
return resp;
}
#endif
void APIConnection::subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) {
state_subs_at_ = 0;
}

View File

@@ -300,6 +300,9 @@ class APIConnection : public APIServerConnection {
return {};
}
void execute_service(const ExecuteServiceRequest &msg) override;
#ifdef USE_API_NOISE
NoiseEncryptionSetKeyResponse noise_encryption_set_key(const NoiseEncryptionSetKeyRequest &msg) override;
#endif
bool is_authenticated() override { return this->connection_state_ == ConnectionState::AUTHENTICATED; }
bool is_connection_setup() override {

View File

@@ -311,6 +311,10 @@ APIError APINoiseFrameHelper::state_action_() {
const std::string &name = App.get_name();
const uint8_t *name_ptr = reinterpret_cast<const uint8_t *>(name.c_str());
msg.insert(msg.end(), name_ptr, name_ptr + name.size() + 1);
// node mac, terminated by null byte
const std::string &mac = get_mac_address();
const uint8_t *mac_ptr = reinterpret_cast<const uint8_t *>(mac.c_str());
msg.insert(msg.end(), mac_ptr, mac_ptr + mac.size() + 1);
aerr = write_frame_(msg.data(), msg.size());
if (aerr != APIError::OK)
@@ -893,8 +897,28 @@ APIError APIPlaintextFrameHelper::read_packet(ReadPacketBuffer *buffer) {
ParsedFrame frame;
aerr = try_read_frame_(&frame);
if (aerr != APIError::OK)
if (aerr != APIError::OK) {
if (aerr == APIError::BAD_INDICATOR) {
// Make sure to tell the remote that we don't
// understand the indicator byte so it knows
// we do not support it.
struct iovec iov[1];
// The \x00 first byte is the marker for plaintext.
//
// The remote will know how to handle the indicator byte,
// but it likely won't understand the rest of the message.
//
// 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";
iov[0].iov_base = (void *) msg;
iov[0].iov_len = 19;
write_raw_(iov, 1);
}
return aerr;
}
buffer->container = std::move(frame.msg);
buffer->data_offset = 0;

View File

@@ -1,6 +1,6 @@
#pragma once
#include <cstdint>
#include <array>
#include <cstdint>
#include "esphome/core/defines.h"
namespace esphome {
@@ -11,11 +11,20 @@ using psk_t = std::array<uint8_t, 32>;
class APINoiseContext {
public:
void set_psk(psk_t psk) { psk_ = psk; }
const psk_t &get_psk() const { return psk_; }
void set_psk(psk_t psk) {
this->psk_ = psk;
bool has_psk = false;
for (auto i : psk) {
has_psk |= i;
}
this->has_psk_ = has_psk;
}
const psk_t &get_psk() const { return this->psk_; }
bool has_psk() const { return this->has_psk_; }
protected:
psk_t psk_;
psk_t psk_{};
bool has_psk_{false};
};
#endif // USE_API_NOISE

View File

@@ -792,6 +792,10 @@ bool DeviceInfoResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
this->voice_assistant_feature_flags = value.as_uint32();
return true;
}
case 19: {
this->api_encryption_supported = value.as_bool();
return true;
}
default:
return false;
}
@@ -865,6 +869,7 @@ void DeviceInfoResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_uint32(17, this->voice_assistant_feature_flags);
buffer.encode_string(16, this->suggested_area);
buffer.encode_string(18, this->bluetooth_mac_address);
buffer.encode_bool(19, this->api_encryption_supported);
}
#ifdef HAS_PROTO_MESSAGE_DUMP
void DeviceInfoResponse::dump_to(std::string &out) const {
@@ -946,6 +951,10 @@ void DeviceInfoResponse::dump_to(std::string &out) const {
out.append(" bluetooth_mac_address: ");
out.append("'").append(this->bluetooth_mac_address).append("'");
out.append("\n");
out.append(" api_encryption_supported: ");
out.append(YESNO(this->api_encryption_supported));
out.append("\n");
out.append("}");
}
#endif
@@ -3009,6 +3018,48 @@ void SubscribeLogsResponse::dump_to(std::string &out) const {
out.append("}");
}
#endif
bool NoiseEncryptionSetKeyRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
switch (field_id) {
case 1: {
this->key = value.as_string();
return true;
}
default:
return false;
}
}
void NoiseEncryptionSetKeyRequest::encode(ProtoWriteBuffer buffer) const { buffer.encode_string(1, this->key); }
#ifdef HAS_PROTO_MESSAGE_DUMP
void NoiseEncryptionSetKeyRequest::dump_to(std::string &out) const {
__attribute__((unused)) char buffer[64];
out.append("NoiseEncryptionSetKeyRequest {\n");
out.append(" key: ");
out.append("'").append(this->key).append("'");
out.append("\n");
out.append("}");
}
#endif
bool NoiseEncryptionSetKeyResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 1: {
this->success = value.as_bool();
return true;
}
default:
return false;
}
}
void NoiseEncryptionSetKeyResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_bool(1, this->success); }
#ifdef HAS_PROTO_MESSAGE_DUMP
void NoiseEncryptionSetKeyResponse::dump_to(std::string &out) const {
__attribute__((unused)) char buffer[64];
out.append("NoiseEncryptionSetKeyResponse {\n");
out.append(" success: ");
out.append(YESNO(this->success));
out.append("\n");
out.append("}");
}
#endif
void SubscribeHomeassistantServicesRequest::encode(ProtoWriteBuffer buffer) const {}
#ifdef HAS_PROTO_MESSAGE_DUMP
void SubscribeHomeassistantServicesRequest::dump_to(std::string &out) const {

View File

@@ -355,6 +355,7 @@ class DeviceInfoResponse : public ProtoMessage {
uint32_t voice_assistant_feature_flags{0};
std::string suggested_area{};
std::string bluetooth_mac_address{};
bool api_encryption_supported{false};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
@@ -791,6 +792,28 @@ class SubscribeLogsResponse : public ProtoMessage {
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class NoiseEncryptionSetKeyRequest : public ProtoMessage {
public:
std::string key{};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
};
class NoiseEncryptionSetKeyResponse : public ProtoMessage {
public:
bool success{false};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class SubscribeHomeassistantServicesRequest : public ProtoMessage {
public:
void encode(ProtoWriteBuffer buffer) const override;

View File

@@ -179,6 +179,16 @@ bool APIServerConnectionBase::send_text_sensor_state_response(const TextSensorSt
bool APIServerConnectionBase::send_subscribe_logs_response(const SubscribeLogsResponse &msg) {
return this->send_message_<SubscribeLogsResponse>(msg, 29);
}
#ifdef USE_API_NOISE
#endif
#ifdef USE_API_NOISE
bool APIServerConnectionBase::send_noise_encryption_set_key_response(const NoiseEncryptionSetKeyResponse &msg) {
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "send_noise_encryption_set_key_response: %s", msg.dump().c_str());
#endif
return this->send_message_<NoiseEncryptionSetKeyResponse>(msg, 125);
}
#endif
bool APIServerConnectionBase::send_homeassistant_service_response(const HomeassistantServiceResponse &msg) {
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "send_homeassistant_service_response: %s", msg.dump().c_str());
@@ -1191,6 +1201,17 @@ bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
ESP_LOGVV(TAG, "on_voice_assistant_set_configuration: %s", msg.dump().c_str());
#endif
this->on_voice_assistant_set_configuration(msg);
#endif
break;
}
case 124: {
#ifdef USE_API_NOISE
NoiseEncryptionSetKeyRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_noise_encryption_set_key_request: %s", msg.dump().c_str());
#endif
this->on_noise_encryption_set_key_request(msg);
#endif
break;
}
@@ -1311,6 +1332,22 @@ void APIServerConnection::on_execute_service_request(const ExecuteServiceRequest
}
this->execute_service(msg);
}
#ifdef USE_API_NOISE
void APIServerConnection::on_noise_encryption_set_key_request(const NoiseEncryptionSetKeyRequest &msg) {
if (!this->is_connection_setup()) {
this->on_no_setup_connection();
return;
}
if (!this->is_authenticated()) {
this->on_unauthenticated_access();
return;
}
NoiseEncryptionSetKeyResponse ret = this->noise_encryption_set_key(msg);
if (!this->send_noise_encryption_set_key_response(ret)) {
this->on_fatal_error();
}
}
#endif
#ifdef USE_COVER
void APIServerConnection::on_cover_command_request(const CoverCommandRequest &msg) {
if (!this->is_connection_setup()) {

View File

@@ -83,6 +83,12 @@ class APIServerConnectionBase : public ProtoService {
#endif
virtual void on_subscribe_logs_request(const SubscribeLogsRequest &value){};
bool send_subscribe_logs_response(const SubscribeLogsResponse &msg);
#ifdef USE_API_NOISE
virtual void on_noise_encryption_set_key_request(const NoiseEncryptionSetKeyRequest &value){};
#endif
#ifdef USE_API_NOISE
bool send_noise_encryption_set_key_response(const NoiseEncryptionSetKeyResponse &msg);
#endif
virtual void on_subscribe_homeassistant_services_request(const SubscribeHomeassistantServicesRequest &value){};
bool send_homeassistant_service_response(const HomeassistantServiceResponse &msg);
virtual void on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &value){};
@@ -349,6 +355,9 @@ class APIServerConnection : public APIServerConnectionBase {
virtual void subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) = 0;
virtual GetTimeResponse get_time(const GetTimeRequest &msg) = 0;
virtual void execute_service(const ExecuteServiceRequest &msg) = 0;
#ifdef USE_API_NOISE
virtual NoiseEncryptionSetKeyResponse noise_encryption_set_key(const NoiseEncryptionSetKeyRequest &msg) = 0;
#endif
#ifdef USE_COVER
virtual void cover_command(const CoverCommandRequest &msg) = 0;
#endif
@@ -457,6 +466,9 @@ class APIServerConnection : public APIServerConnectionBase {
void on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &msg) override;
void on_get_time_request(const GetTimeRequest &msg) override;
void on_execute_service_request(const ExecuteServiceRequest &msg) override;
#ifdef USE_API_NOISE
void on_noise_encryption_set_key_request(const NoiseEncryptionSetKeyRequest &msg) override;
#endif
#ifdef USE_COVER
void on_cover_command_request(const CoverCommandRequest &msg) override;
#endif

View File

@@ -22,22 +22,40 @@ namespace api {
static const char *const TAG = "api";
// APIServer
APIServer *global_api_server = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
APIServer::APIServer() { global_api_server = this; }
void APIServer::setup() {
ESP_LOGCONFIG(TAG, "Setting up Home Assistant API server...");
this->setup_controller();
socket_ = socket::socket_ip(SOCK_STREAM, 0);
if (socket_ == nullptr) {
ESP_LOGW(TAG, "Could not create socket.");
#ifdef USE_API_NOISE
uint32_t hash = 88491486UL;
this->noise_pref_ = global_preferences->make_preference<SavedNoisePsk>(hash, true);
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
this->socket_ = socket::socket_ip(SOCK_STREAM, 0);
if (this->socket_ == nullptr) {
ESP_LOGW(TAG, "Could not create socket");
this->mark_failed();
return;
}
int enable = 1;
int err = socket_->setsockopt(SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
int err = this->socket_->setsockopt(SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
if (err != 0) {
ESP_LOGW(TAG, "Socket unable to set reuseaddr: errno %d", err);
// we can still continue
}
err = socket_->setblocking(false);
err = this->socket_->setblocking(false);
if (err != 0) {
ESP_LOGW(TAG, "Socket unable to set nonblocking mode: errno %d", err);
this->mark_failed();
@@ -53,14 +71,14 @@ void APIServer::setup() {
return;
}
err = socket_->bind((struct sockaddr *) &server, sl);
err = this->socket_->bind((struct sockaddr *) &server, sl);
if (err != 0) {
ESP_LOGW(TAG, "Socket unable to bind: errno %d", errno);
this->mark_failed();
return;
}
err = socket_->listen(4);
err = this->socket_->listen(4);
if (err != 0) {
ESP_LOGW(TAG, "Socket unable to listen: errno %d", errno);
this->mark_failed();
@@ -92,18 +110,19 @@ void APIServer::setup() {
}
#endif
}
void APIServer::loop() {
// Accept new clients
while (true) {
struct sockaddr_storage source_addr;
socklen_t addr_len = sizeof(source_addr);
auto sock = socket_->accept((struct sockaddr *) &source_addr, &addr_len);
auto sock = this->socket_->accept((struct sockaddr *) &source_addr, &addr_len);
if (!sock)
break;
ESP_LOGD(TAG, "Accepted %s", sock->getpeername().c_str());
auto *conn = new APIConnection(std::move(sock), this);
clients_.emplace_back(conn);
this->clients_.emplace_back(conn);
conn->start();
}
@@ -136,16 +155,22 @@ void APIServer::loop() {
}
}
}
void APIServer::dump_config() {
ESP_LOGCONFIG(TAG, "API Server:");
ESP_LOGCONFIG(TAG, " Address: %s:%u", network::get_use_address().c_str(), this->port_);
#ifdef USE_API_NOISE
ESP_LOGCONFIG(TAG, " Using noise encryption: YES");
ESP_LOGCONFIG(TAG, " Using noise encryption: %s", YESNO(this->noise_ctx_->has_psk()));
if (!this->noise_ctx_->has_psk()) {
ESP_LOGCONFIG(TAG, " Supports noise encryption: YES");
}
#else
ESP_LOGCONFIG(TAG, " Using noise encryption: NO");
#endif
}
bool APIServer::uses_password() const { return !this->password_.empty(); }
bool APIServer::check_password(const std::string &password) const {
// depend only on input password length
const char *a = this->password_.c_str();
@@ -174,7 +199,9 @@ bool APIServer::check_password(const std::string &password) const {
return result == 0;
}
void APIServer::handle_disconnect(APIConnection *conn) {}
#ifdef USE_BINARY_SENSOR
void APIServer::on_binary_sensor_update(binary_sensor::BinarySensor *obj, bool state) {
if (obj->is_internal())
@@ -342,57 +369,6 @@ void APIServer::on_update(update::UpdateEntity *obj) {
}
#endif
float APIServer::get_setup_priority() const { return setup_priority::AFTER_WIFI; }
void APIServer::set_port(uint16_t port) { this->port_ = port; }
APIServer *global_api_server = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
void APIServer::set_password(const std::string &password) { this->password_ = password; }
void APIServer::send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
for (auto &client : this->clients_) {
client->send_homeassistant_service_call(call);
}
}
APIServer::APIServer() { global_api_server = this; }
void APIServer::subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
std::function<void(std::string)> f) {
this->state_subs_.push_back(HomeAssistantStateSubscription{
.entity_id = std::move(entity_id),
.attribute = std::move(attribute),
.callback = std::move(f),
.once = false,
});
}
void APIServer::get_home_assistant_state(std::string entity_id, optional<std::string> attribute,
std::function<void(std::string)> f) {
this->state_subs_.push_back(HomeAssistantStateSubscription{
.entity_id = std::move(entity_id),
.attribute = std::move(attribute),
.callback = std::move(f),
.once = true,
});
};
const std::vector<APIServer::HomeAssistantStateSubscription> &APIServer::get_state_subs() const {
return this->state_subs_;
}
uint16_t APIServer::get_port() const { return this->port_; }
void APIServer::set_reboot_timeout(uint32_t reboot_timeout) { this->reboot_timeout_ = reboot_timeout; }
#ifdef USE_HOMEASSISTANT_TIME
void APIServer::request_time() {
for (auto &client : this->clients_) {
if (!client->remove_ && client->is_authenticated())
client->send_time_request();
}
}
#endif
bool APIServer::is_connected() const { return !this->clients_.empty(); }
void APIServer::on_shutdown() {
for (auto &c : this->clients_) {
c->send_disconnect_request(DisconnectRequest());
}
delay(10);
}
#ifdef USE_ALARM_CONTROL_PANEL
void APIServer::on_alarm_control_panel_update(alarm_control_panel::AlarmControlPanel *obj) {
if (obj->is_internal())
@@ -402,6 +378,96 @@ void APIServer::on_alarm_control_panel_update(alarm_control_panel::AlarmControlP
}
#endif
float APIServer::get_setup_priority() const { return setup_priority::AFTER_WIFI; }
void APIServer::set_port(uint16_t port) { this->port_ = port; }
void APIServer::set_password(const std::string &password) { this->password_ = password; }
void APIServer::send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
for (auto &client : this->clients_) {
client->send_homeassistant_service_call(call);
}
}
void APIServer::subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
std::function<void(std::string)> f) {
this->state_subs_.push_back(HomeAssistantStateSubscription{
.entity_id = std::move(entity_id),
.attribute = std::move(attribute),
.callback = std::move(f),
.once = false,
});
}
void APIServer::get_home_assistant_state(std::string entity_id, optional<std::string> attribute,
std::function<void(std::string)> f) {
this->state_subs_.push_back(HomeAssistantStateSubscription{
.entity_id = std::move(entity_id),
.attribute = std::move(attribute),
.callback = std::move(f),
.once = true,
});
};
const std::vector<APIServer::HomeAssistantStateSubscription> &APIServer::get_state_subs() const {
return this->state_subs_;
}
uint16_t APIServer::get_port() const { return this->port_; }
void APIServer::set_reboot_timeout(uint32_t reboot_timeout) { this->reboot_timeout_ = reboot_timeout; }
#ifdef USE_API_NOISE
bool APIServer::save_noise_psk(psk_t psk, bool make_active) {
auto &old_psk = this->noise_ctx_->get_psk();
if (std::equal(old_psk.begin(), old_psk.end(), psk.begin())) {
ESP_LOGW(TAG, "New PSK matches old");
return true;
}
SavedNoisePsk new_saved_psk{psk};
if (!this->noise_pref_.save(&new_saved_psk)) {
ESP_LOGW(TAG, "Failed to save Noise PSK");
return false;
}
// ensure it's written immediately
if (!global_preferences->sync()) {
ESP_LOGW(TAG, "Failed to sync preferences");
return false;
}
ESP_LOGD(TAG, "Noise PSK saved");
if (make_active) {
this->set_timeout(100, [this, psk]() {
ESP_LOGW(TAG, "Disconnecting all clients to reset connections");
this->set_noise_psk(psk);
for (auto &c : this->clients_) {
c->send_disconnect_request(DisconnectRequest());
}
});
}
return true;
}
#endif
#ifdef USE_HOMEASSISTANT_TIME
void APIServer::request_time() {
for (auto &client : this->clients_) {
if (!client->remove_ && client->is_authenticated())
client->send_time_request();
}
}
#endif
bool APIServer::is_connected() const { return !this->clients_.empty(); }
void APIServer::on_shutdown() {
for (auto &c : this->clients_) {
c->send_disconnect_request(DisconnectRequest());
}
delay(10);
}
} // namespace api
} // namespace esphome
#endif

View File

@@ -19,6 +19,12 @@
namespace esphome {
namespace api {
#ifdef USE_API_NOISE
struct SavedNoisePsk {
psk_t psk;
} PACKED; // NOLINT
#endif
class APIServer : public Component, public Controller {
public:
APIServer();
@@ -35,6 +41,7 @@ class APIServer : public Component, public Controller {
void set_reboot_timeout(uint32_t reboot_timeout);
#ifdef USE_API_NOISE
bool save_noise_psk(psk_t psk, bool make_active = true);
void set_noise_psk(psk_t psk) { noise_ctx_->set_psk(psk); }
std::shared_ptr<APINoiseContext> get_noise_ctx() { return noise_ctx_; }
#endif // USE_API_NOISE
@@ -142,6 +149,7 @@ class APIServer : public Component, public Controller {
#ifdef USE_API_NOISE
std::shared_ptr<APINoiseContext> noise_ctx_ = std::make_shared<APINoiseContext>();
ESPPreferenceObject noise_pref_;
#endif // USE_API_NOISE
};

View File

@@ -29,8 +29,9 @@ async def async_run_logs(config: dict[str, Any], address: str) -> None:
port: int = int(conf[CONF_PORT])
password: str = conf[CONF_PASSWORD]
noise_psk: str | None = None
if CONF_ENCRYPTION in conf:
noise_psk = conf[CONF_ENCRYPTION][CONF_KEY]
if encryption_config := conf.get(CONF_ENCRYPTION):
if key := encryption_config.get(CONF_KEY):
noise_psk = key
_LOGGER.info("Starting log output from %s using esphome API", address)
cli = APIClient(
address,

View File

@@ -1,17 +1,17 @@
from esphome import pins
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.const import (
CONF_CALIBRATION,
CONF_CAPACITANCE,
CONF_DIV_RATIO,
CONF_INDOOR,
CONF_IRQ_PIN,
CONF_LIGHTNING_THRESHOLD,
CONF_MASK_DISTURBER,
CONF_CALIBRATION,
CONF_TUNE_ANTENNA,
CONF_NOISE_LEVEL,
CONF_SPIKE_REJECTION,
CONF_TUNE_ANTENNA,
CONF_WATCHDOG_THRESHOLD,
)

View File

@@ -1,6 +1,7 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import binary_sensor
import esphome.config_validation as cv
from . import AS3935, CONF_AS3935_ID
DEPENDENCIES = ["as3935"]

View File

@@ -1,13 +1,14 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_DISTANCE,
CONF_LIGHTNING_ENERGY,
UNIT_KILOMETER,
ICON_SIGNAL_DISTANCE_VARIANT,
ICON_FLASH,
ICON_SIGNAL_DISTANCE_VARIANT,
UNIT_KILOMETER,
)
from . import AS3935, CONF_AS3935_ID
DEPENDENCIES = ["as3935"]

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import as3935, i2c
import esphome.config_validation as cv
from esphome.const import CONF_ID
AUTO_LOAD = ["as3935"]

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import as3935, spi
import esphome.config_validation as cv
from esphome.const import CONF_ID
AUTO_LOAD = ["as3935"]

View File

@@ -1,12 +1,12 @@
from esphome import pins
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import i2c
import esphome.config_validation as cv
from esphome.const import (
CONF_ID,
CONF_DIR_PIN,
CONF_DIRECTION,
CONF_HYSTERESIS,
CONF_ID,
CONF_RANGE,
)

View File

@@ -1,19 +1,20 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_ANGLE,
CONF_GAIN,
CONF_ID,
STATE_CLASS_MEASUREMENT,
CONF_MAGNITUDE,
CONF_POSITION,
CONF_STATUS,
ENTITY_CATEGORY_DIAGNOSTIC,
ICON_MAGNET,
ICON_ROTATE_RIGHT,
CONF_GAIN,
ENTITY_CATEGORY_DIAGNOSTIC,
CONF_MAGNITUDE,
CONF_STATUS,
CONF_POSITION,
CONF_ANGLE,
STATE_CLASS_MEASUREMENT,
)
from .. import as5600_ns, AS5600Component
from .. import AS5600Component, as5600_ns
CODEOWNERS = ["@ammmze"]
DEPENDENCIES = ["as5600"]

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_GAIN,
CONF_ID,
@@ -9,7 +9,6 @@ from esphome.const import (
STATE_CLASS_MEASUREMENT,
)
CODEOWNERS = ["@mrgnr"]
DEPENDENCIES = ["i2c"]

View File

@@ -1,13 +1,9 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import automation, core
from esphome.components import i2c
from esphome.automation import maybe_simple_id
from esphome.const import (
CONF_ID,
CONF_FREQUENCY,
)
import esphome.codegen as cg
from esphome.components import i2c
import esphome.config_validation as cv
from esphome.const import CONF_FREQUENCY, CONF_ID
CODEOWNERS = ["@X-Ryl669"]
DEPENDENCIES = ["i2c"]

View File

@@ -1,10 +1,8 @@
import esphome.codegen as cg
from esphome.components import switch
import esphome.config_validation as cv
from esphome.const import (
DEVICE_CLASS_SWITCH,
ICON_WIFI,
)
from esphome.const import DEVICE_CLASS_SWITCH, ICON_WIFI
from .. import CONF_AT581X_ID, AT581XComponent, at581x_ns
DEPENDENCIES = ["at581x"]

View File

@@ -1,14 +1,14 @@
import esphome.codegen as cg
from esphome.components import esp32_ble_tracker, sensor
import esphome.config_validation as cv
from esphome.components import sensor, esp32_ble_tracker
from esphome.const import (
CONF_BATTERY_LEVEL,
CONF_BATTERY_VOLTAGE,
CONF_MAC_ADDRESS,
CONF_HUMIDITY,
CONF_ID,
CONF_MAC_ADDRESS,
CONF_SIGNAL_STRENGTH,
CONF_TEMPERATURE,
CONF_ID,
DEVICE_CLASS_BATTERY,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_SIGNAL_STRENGTH,

View File

@@ -30,8 +30,12 @@ void AXS15231Touchscreen::setup() {
this->interrupt_pin_->setup();
this->attach_interrupt_(this->interrupt_pin_, gpio::INTERRUPT_FALLING_EDGE);
}
this->x_raw_max_ = this->display_->get_native_width();
this->y_raw_max_ = this->display_->get_native_height();
if (this->x_raw_max_ == 0) {
this->x_raw_max_ = this->display_->get_native_width();
}
if (this->y_raw_max_ == 0) {
this->y_raw_max_ = this->display_->get_native_height();
}
ESP_LOGCONFIG(TAG, "AXS15231 Touchscreen setup complete");
}
@@ -44,7 +48,7 @@ void AXS15231Touchscreen::update_touches() {
err = this->read(data, sizeof(data));
ERROR_CHECK(err);
this->status_clear_warning();
if (data[0] != 0) // no touches
if (data[0] != 0 || data[1] == 0) // no touches
return;
uint16_t x = encode_uint16(data[2] & 0xF, data[3]);
uint16_t y = encode_uint16(data[4] & 0xF, data[5]);

View File

@@ -1,13 +1,13 @@
import esphome.codegen as cg
from esphome.components import esp32_ble_tracker, sensor
import esphome.config_validation as cv
from esphome.components import sensor, esp32_ble_tracker
from esphome.const import (
CONF_BATTERY_VOLTAGE,
CONF_HUMIDITY,
CONF_ID,
CONF_ILLUMINANCE,
CONF_MOISTURE,
CONF_MAC_ADDRESS,
CONF_MOISTURE,
CONF_TEMPERATURE,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_ILLUMINANCE,

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import climate_ir
import esphome.config_validation as cv
from esphome.const import CONF_ID
AUTO_LOAD = ["climate_ir"]

View File

@@ -1,7 +1,7 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import automation
import esphome.codegen as cg
from esphome.components import climate, sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_AWAY_CONFIG,
CONF_COOL_ACTION,

View File

@@ -1,11 +1,7 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import ble_client, time
from esphome.const import (
CONF_ID,
CONF_RECEIVE_TIMEOUT,
CONF_TIME_ID,
)
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_RECEIVE_TIMEOUT, CONF_TIME_ID
CODEOWNERS = ["@jhansche"]
DEPENDENCIES = ["ble_client"]

View File

@@ -1,8 +1,8 @@
import logging
import esphome.codegen as cg
from esphome.components import ble_client, climate
import esphome.config_validation as cv
from esphome.components import climate, ble_client
from esphome.const import (
CONF_HEAT_MODE,
CONF_ID,
@@ -10,11 +10,8 @@ from esphome.const import (
CONF_TEMPERATURE_SOURCE,
CONF_TIME_ID,
)
from .. import (
BEDJET_CLIENT_SCHEMA,
bedjet_ns,
register_bedjet_child,
)
from .. import BEDJET_CLIENT_SCHEMA, bedjet_ns, register_bedjet_child
_LOGGER = logging.getLogger(__name__)
CODEOWNERS = ["@jhansche"]

View File

@@ -1,16 +1,11 @@
import logging
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import fan
from esphome.const import (
CONF_ID,
)
from .. import (
BEDJET_CLIENT_SCHEMA,
bedjet_ns,
register_bedjet_child,
)
import esphome.config_validation as cv
from esphome.const import CONF_ID
from .. import BEDJET_CLIENT_SCHEMA, bedjet_ns, register_bedjet_child
_LOGGER = logging.getLogger(__name__)
CODEOWNERS = ["@jhansche"]

View File

@@ -1,19 +1,16 @@
import logging
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_ID,
DEVICE_CLASS_TEMPERATURE,
STATE_CLASS_MEASUREMENT,
UNIT_CELSIUS,
)
from .. import (
BEDJET_CLIENT_SCHEMA,
bedjet_ns,
register_bedjet_child,
)
from .. import BEDJET_CLIENT_SCHEMA, bedjet_ns, register_bedjet_child
_LOGGER = logging.getLogger(__name__)
CODEOWNERS = ["@jhansche", "@javawizard"]

View File

@@ -1,9 +1,9 @@
from dataclasses import dataclass
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
import esphome.codegen as cg
from esphome.components import libretiny, light
import esphome.config_validation as cv
from esphome.const import (
CONF_CHIPSET,
CONF_IS_RGBW,

View File

@@ -1,11 +1,7 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import i2c, sensor
from esphome.const import (
DEVICE_CLASS_ILLUMINANCE,
STATE_CLASS_MEASUREMENT,
UNIT_LUX,
)
import esphome.config_validation as cv
from esphome.const import DEVICE_CLASS_ILLUMINANCE, STATE_CLASS_MEASUREMENT, UNIT_LUX
DEPENDENCIES = ["i2c"]
CODEOWNERS = ["@OttoWinter"]

View File

@@ -1,12 +1,13 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import fan, output
import esphome.config_validation as cv
from esphome.const import (
CONF_DIRECTION_OUTPUT,
CONF_OSCILLATION_OUTPUT,
CONF_OUTPUT,
CONF_OUTPUT_ID,
)
from .. import binary_ns
BinaryFan = binary_ns.class_("BinaryFan", fan.Fan, cg.Component)

View File

@@ -1,7 +1,8 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import light, output
from esphome.const import CONF_OUTPUT_ID, CONF_OUTPUT
import esphome.config_validation as cv
from esphome.const import CONF_OUTPUT, CONF_OUTPUT_ID
from .. import binary_ns
BinaryLightOutput = binary_ns.class_("BinaryLightOutput", light.LightOutput)

View File

@@ -1,15 +1,14 @@
import esphome.codegen as cg
from esphome.components import binary_sensor, sensor
import esphome.config_validation as cv
from esphome.components import sensor, binary_sensor
from esphome.const import (
CONF_CHANNELS,
CONF_VALUE,
CONF_TYPE,
ICON_CHECK_CIRCLE_OUTLINE,
CONF_BINARY_SENSOR,
CONF_CHANNELS,
CONF_GROUP,
CONF_SUM,
CONF_TYPE,
CONF_VALUE,
ICON_CHECK_CIRCLE_OUTLINE,
)
DEPENDENCIES = ["binary_sensor"]

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor, uart
import esphome.config_validation as cv
from esphome.const import (
CONF_ID,
CONF_VOLTAGE,

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor, uart
import esphome.config_validation as cv
from esphome.const import (
CONF_CURRENT,
CONF_ENERGY,
@@ -12,15 +12,15 @@ from esphome.const import (
DEVICE_CLASS_CURRENT,
DEVICE_CLASS_ENERGY,
DEVICE_CLASS_POWER,
DEVICE_CLASS_VOLTAGE,
DEVICE_CLASS_TEMPERATURE,
DEVICE_CLASS_VOLTAGE,
STATE_CLASS_MEASUREMENT,
STATE_CLASS_TOTAL_INCREASING,
UNIT_AMPERE,
UNIT_CELSIUS,
UNIT_KILOWATT_HOURS,
UNIT_VOLT,
UNIT_WATT,
STATE_CLASS_TOTAL_INCREASING,
)
DEPENDENCIES = ["uart"]

View File

@@ -67,7 +67,7 @@ CONF_AUTO_CONNECT = "auto_connect"
MULTI_CONF = True
CONFIG_SCHEMA = (
CONFIG_SCHEMA = cv.All(
cv.Schema(
{
cv.GenerateID(): cv.declare_id(BLEClient),
@@ -114,7 +114,8 @@ CONFIG_SCHEMA = (
}
)
.extend(cv.COMPONENT_SCHEMA)
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA),
esp32_ble_tracker.consume_connection_slots(1, "ble_client"),
)
CONF_BLE_CLIENT_ID = "ble_client_id"

View File

@@ -5,13 +5,13 @@ import esphome.config_validation as cv
from esphome.const import (
CONF_CHARACTERISTIC_UUID,
CONF_LAMBDA,
CONF_NOTIFY,
CONF_SERVICE_UUID,
CONF_TRIGGER_ID,
CONF_TYPE,
DEVICE_CLASS_SIGNAL_STRENGTH,
STATE_CLASS_MEASUREMENT,
UNIT_DECIBEL_MILLIWATT,
CONF_NOTIFY,
)
from .. import ble_client_ns

View File

@@ -5,8 +5,8 @@ import esphome.config_validation as cv
from esphome.const import (
CONF_CHARACTERISTIC_UUID,
CONF_ID,
CONF_SERVICE_UUID,
CONF_NOTIFY,
CONF_SERVICE_UUID,
CONF_TRIGGER_ID,
)

View File

@@ -8,9 +8,10 @@ AUTO_LOAD = ["esp32_ble_client", "esp32_ble_tracker"]
DEPENDENCIES = ["api", "esp32"]
CODEOWNERS = ["@jesserockz"]
CONF_CONNECTION_SLOTS = "connection_slots"
CONF_CACHE_SERVICES = "cache_services"
CONF_CONNECTIONS = "connections"
MAX_CONNECTIONS = 3
DEFAULT_CONNECTION_SLOTS = 3
bluetooth_proxy_ns = cg.esphome_ns.namespace("bluetooth_proxy")
@@ -34,32 +35,43 @@ def validate_connections(config):
raise cv.Invalid(
"Connections can only be used if the proxy is set to active"
)
else:
if config[CONF_ACTIVE]:
conf = config.copy()
conf[CONF_CONNECTIONS] = [
CONNECTION_SCHEMA({}) for _ in range(MAX_CONNECTIONS)
]
return conf
elif config[CONF_ACTIVE]:
connection_slots: int = config[CONF_CONNECTION_SLOTS]
esp32_ble_tracker.consume_connection_slots(connection_slots, "bluetooth_proxy")(
config
)
return {
**config,
CONF_CONNECTIONS: [CONNECTION_SCHEMA({}) for _ in range(connection_slots)],
}
return config
CONFIG_SCHEMA = cv.All(
cv.Schema(
{
cv.GenerateID(): cv.declare_id(BluetoothProxy),
cv.Optional(CONF_ACTIVE, default=False): cv.boolean,
cv.SplitDefault(CONF_CACHE_SERVICES, esp32_idf=True): cv.All(
cv.only_with_esp_idf, cv.boolean
),
cv.Optional(CONF_CONNECTIONS): cv.All(
cv.ensure_list(CONNECTION_SCHEMA),
cv.Length(min=1, max=MAX_CONNECTIONS),
),
}
)
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
.extend(cv.COMPONENT_SCHEMA),
(
cv.Schema(
{
cv.GenerateID(): cv.declare_id(BluetoothProxy),
cv.Optional(CONF_ACTIVE, default=False): cv.boolean,
cv.SplitDefault(CONF_CACHE_SERVICES, esp32_idf=True): cv.All(
cv.only_with_esp_idf, cv.boolean
),
cv.Optional(
CONF_CONNECTION_SLOTS,
default=DEFAULT_CONNECTION_SLOTS,
): cv.All(
cv.positive_int,
cv.Range(min=1, max=esp32_ble_tracker.max_connections()),
),
cv.Optional(CONF_CONNECTIONS): cv.All(
cv.ensure_list(CONNECTION_SCHEMA),
cv.Length(min=1, max=esp32_ble_tracker.max_connections()),
),
}
)
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
.extend(cv.COMPONENT_SCHEMA)
),
validate_connections,
)

View File

@@ -265,6 +265,12 @@ void BluetoothProxy::bluetooth_device_request(const api::BluetoothDeviceRequest
connection->get_connection_index(), connection->address_str().c_str());
return;
} else if (connection->state() == espbt::ClientState::CONNECTING) {
if (connection->disconnect_pending()) {
ESP_LOGW(TAG, "[%d] [%s] Connection request while pending disconnect, cancelling pending disconnect",
connection->get_connection_index(), connection->address_str().c_str());
connection->cancel_pending_disconnect();
return;
}
ESP_LOGW(TAG, "[%d] [%s] Connection request ignored, already connecting", connection->get_connection_index(),
connection->address_str().c_str());
return;

View File

@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_HUMIDITY,
CONF_ID,

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