Compare commits

...

533 Commits

Author SHA1 Message Date
J. Nick Koston 5a7b1c411e [cli] DRY up --prebuilt-dir helpers
Two small simplifications surfaced by re-reading the diff with a 'is
this DRY?' lens:

- Extract _missing_prebuilt_flash_tool(): the
  _ensure_platform_packages_for_prebuilt_upload helper had two
  near-identical 'if platform check; if finder() is not None return 0;
  tool_label = ...' blocks. Lift the platform->(tool_name) selection
  into a tiny helper so the early-return is one line and the install
  body is no longer interleaved with the platform dispatch.

- Collapse the two near-duplicate 'firmware not found' return points in
  upload_using_picotool. Both branches just selected an error message
  and returned 1; reorder so the message selection happens first and
  there's a single 'return 1'.

No behavior change; pure refactor. 587 unit tests pass.

Issue: esphome/device-builder#572
2026-05-11 16:00:42 -05:00
J. Nick Koston bcac422e9e [cli] Address self-review on --prebuilt-dir
- CORE.firmware_bin priority is now platform-aware: RP2040 + libretiny
  prefer firmware.uf2 over firmware.bin (picotool / ltchiptool need the
  UF2 header for address/family info); ESP* prefer firmware.bin. The
  prior code returned .bin first for all platforms, which would have
  silently flashed the wrong artifact on RP2040 if a hand-staged dir
  shipped both files. New tests guard both directions.

- _rp2040_serial_reset_to_bootsel: check picotool exists *before*
  triggering the 1200bps touch. If picotool is missing, the touch
  would have left the device stranded in BOOTSEL with nothing able to
  flash it; with this order the device stays on the old firmware and
  can be retried.

- upload_using_ltchiptool: error message now mentions both firmware.uf2
  and firmware.bin since CORE.firmware_bin resolves either.

- prepare_platform_for_upload: return type tightened to int (capture_stdout
  is hardcoded False; assert the run helper returns int so a future caller
  that flips capture_stdout fails loudly instead of silently treating a
  string as success). Caller in __main__.py is now a one-liner.

- _load_idedata: narrative comment in the prebuilt branch shortened.
  _resolve_prebuilt_idedata_paths docstring now notes the
  POSIX-absolute-on-Windows quirk ("/foo/bar" is rooted but not absolute
  on win32; hand-staged dirs need OS-appropriate absolute paths).

- New defensive-coverage tests: _resolve_prebuilt_idedata_paths with
  missing prog_path, no extra section, empty flash_images list.

Issue: esphome/device-builder#572
Issue: esphome/device-builder#570
2026-05-11 13:32:36 -05:00
J. Nick Koston c870ad328e [cli] Fix Windows pytest: use platform-absolute path in --prebuilt-dir test
The 'absolute paths pass through unchanged' test for _load_idedata
hardcoded a POSIX-style absolute path ('/somewhere/else/bootloader.bin').
On Windows, Path.is_absolute() returns False for that shape -- absolute
paths there require a drive letter -- so _resolve_prebuilt_idedata_paths
classified it as relative and prepended CORE.prebuilt_dir, breaking the
test's assertion.

Replace the hardcoded POSIX path with a tmp_path-rooted one so it's
platform-absolute on every runner. No production code change; this is a
test-only fix surfaced by the windows-latest pytest matrix on PR #16348.

Note: the macOS 3.14 failure on the same CI run is a flaky timing test
(tests/dashboard/test_web_server.py::test_dashboard_subscriber_entries_update_interval,
50ms sleep expecting 2+ iterations at 10ms) unrelated to this PR.

Issue: esphome/device-builder#572
2026-05-11 11:09:36 -05:00
J. Nick Koston 1ba8b838da [cli] Address Copilot review on --prebuilt-dir
- get_ltchiptool_path: use 'Scripts/' on Windows, 'bin/' elsewhere when
  falling back to PlatformIO's libretiny penv. CPython venvs put scripts
  under Scripts/ on win32 and bin/ on POSIX; the prior hardcoded 'bin'
  would never have found ltchiptool on Windows.
- _load_idedata: wrap json.loads on the prebuilt idedata.json in a
  try/except and re-raise as EsphomeError with a one-line diagnostic so
  the failure mode is a clean error instead of an unhandled
  JSONDecodeError stack trace. Update the surrounding comment to match
  the new behavior.
- CORE.prebuilt_dir docstring: drop the dead 'docs/architecture/...'
  pointer (no docs/ tree in this repo); point at esphome-docs#6600 and
  device-builder#572 instead.

New regression test:
- test_load_idedata_prebuilt_malformed_json_raises_esphomeerror

Updated test:
- test_get_ltchiptool_path_pio_penv now uses Scripts/ on win32 to match
  the new platform-aware lookup.

Issue: esphome/device-builder#572
Issue: esphome/device-builder#570
2026-05-11 10:58:17 -05:00
J. Nick Koston 956c2a9780 Merge remote-tracking branch 'upstream/dev' into core-prebuilt-dir-upload
# Conflicts:
#	esphome/__main__.py
2026-05-11 10:55:31 -05:00
J. Nick Koston a52ca4f80a [ota] Implement host platform OTA backend with re-exec for integration testing (#16304) 2026-05-11 10:51:08 -05:00
luar123 4ac7bc4606 [zigbee] Add sensor support on esp32 (#16026) 2026-05-11 10:51:47 -04:00
tomaszduda23 8cf0eba043 [nrf52][zephyr] prepare for native builds (#16193)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-05-11 14:47:06 +00:00
Keith Burzinski 30e2f7e8e9 [thermostat] Fix supplemental action never firing via max run time (#16308) 2026-05-11 10:13:43 -04:00
@RubenKelevra a7299cb95b [esp32_camera] Downgrade esp32-camera to 2.1.5 (#16293) 2026-05-11 10:09:15 -04:00
tomaszduda23 2edb7ca5c2 [nrf52] add message that west update is running (#16321) 2026-05-11 10:05:41 -04:00
tomaszduda23 68534ea24d [logger] fix crash on zephyr (#16330) 2026-05-11 10:04:48 -04:00
rwrozelle 105842366e [openthread] Remove-freertos-portmacro-header-include (#16338) 2026-05-11 09:57:01 -04:00
J. Nick Koston 4d9d6e02e5 [core] Add stable esphome.upload_targets module for port classification (#16346) 2026-05-11 09:13:16 -04:00
J. Nick Koston b967adeb9d [wifi] Accept lowercase variant in variant_has_wifi (#16345) 2026-05-11 09:11:36 -04:00
Jonathan Swoboda e4d9786f00 [core] Move platformio files to subfolder (#16347) 2026-05-11 21:34:47 +12:00
Samuel Sieb 267836d098 [tuya] allow status pin that doesn't match the reported one (#16353) 2026-05-11 01:27:07 -07:00
Jesse Hills c82adc3892 [ci] Fix external-component-bot 403 on PR comments (#16354) 2026-05-11 19:52:39 +12:00
J. Nick Koston 5cc7719ae4 [cli] Use pio run -t idedata to set up libretiny penv on cold hosts
The prior commit invoked 'pio pkg install' for the on-demand prep step,
which installs the libretiny platform package but does NOT recreate the
~/.platformio/penv/.libretiny/ virtualenv -- that's set up by libretiny's
ConfigurePythonVenv SCons step, which only fires during 'pio run'. So a
cold host (penv missing) still failed to find ltchiptool after the install
returned 'Already up-to-date'.

Wet test against bw15-device.yaml on a host with the libretiny penv
deleted:
  esphome upload bw15-device.yaml --device /dev/null --prebuilt-dir ...
  INFO ltchiptool not found on this host; installing the PlatformIO
       rtl87xx platform package ...
  Resolving bw15-device dependencies...
  Already up-to-date.
  ERROR ltchiptool not found. ...

Replace pkg install with 'pio run -t idedata'. The idedata target runs
SConscript without the actual compile target, so penv creation (libretiny)
and tool-package install (RP2040) happen as side effects of the SCons
configure phase -- but the build itself is skipped. Cost is a few seconds
of SCons configure, paid once per cold host.

Rename run_pkg_install -> prepare_platform_for_upload to match the new
semantics.

Issue: esphome/device-builder#572
Issue: esphome/device-builder#570
2026-05-11 00:30:06 -05:00
Jesse Hills fe66f9ba41 [ci] Tighten workflow permissions to least-privilege (#16349) 2026-05-11 17:15:53 +12:00
Jesse Hills 5dadfe6367 [ci] codeowner-review-request: mint least-privilege App token (#16351) 2026-05-11 17:04:09 +12:00
J. Nick Koston aab7177f07 [cli] Add write_cpp-failure test for --prebuilt-dir pkg-install prep
Symmetric with test_upload_program_prebuilt_dir_pkg_install_failure_aborts_upload:
covers the early-return path when write_cpp fails (codegen error, disk
full, validation regression) before pkg install runs. Closes the
coverage matrix for _ensure_platform_packages_for_prebuilt_upload's
two failure points.

Issue: esphome/device-builder#572
2026-05-10 23:58:16 -05:00
Jesse Hills c4e85fbfc1 [ci] sync-device-classes: mint least-privilege App token (#16350) 2026-05-11 16:57:10 +12:00
J. Nick Koston 7674170600 [cli] Auto-install PlatformIO platform when --prebuilt-dir needs its flash tool
Revert ltchiptool as a hard dependency so the vast majority of ESPHome
users (ESP32 / ESP8266 / nRF52 OTA) don't pay for libretiny tooling.
Instead, on-demand install just the PlatformIO platform package when a
--prebuilt-dir upload needs a flash tool that isn't on disk yet.

Mechanism: when upload_program receives --prebuilt-dir for a libretiny
or RP2040 target and the corresponding flash tool (ltchiptool / picotool)
isn't found by get_ltchiptool_path / _find_picotool, run the same prep
that 'esphome compile' would (write_cpp + write platformio.ini), then
invoke 'pio pkg install -e <env>' instead of 'pio run'. PlatformIO
downloads the platform without compiling, the flash tool ends up on disk,
and the upload dispatch picks it up on the next lookup.

After install, the tool path lookups (PATH + PIO penv for ltchiptool,
PIO packages dir for picotool) succeed and the upload helper takes over.
ESP32 / ESP8266 / nRF52 paths are unchanged (esptool is already bundled
in requirements.txt; smpclient too for nRF52 mcumgr).

Issue: esphome/device-builder#572
Issue: esphome/device-builder#570
2026-05-10 23:48:05 -05:00
J. Nick Koston 758189fe56 [deps] Bundle ltchiptool for libretiny prebuilt-dir uploads
`esphome upload --prebuilt-dir` on a libretiny device routes through
ltchiptool to bypass the PlatformIO build-tree requirement. On hosts
that have never compiled a libretiny config locally (the dashboard's
transparent-install use case) the libretiny PlatformIO platform's
penv at ~/.platformio/penv/.libretiny/bin/ltchiptool doesn't exist
yet, leaving the upload to fail with an actionable but unwelcome
"install ltchiptool" hint.

Bundle ltchiptool as a direct dependency, mirroring esptool which is
already shipped even though only ESP users need it. `pip install
esphome` is now sufficient for libretiny serial uploads from a
prebuilt artifact set; get_ltchiptool_path's PATH lookup picks up
the pip-installed binary first, with the PIO penv fallback still in
place for environments that vendor esphome without the extra.

Issue: esphome/device-builder#572
Issue: esphome/device-builder#570
2026-05-10 23:40:56 -05:00
J. Nick Koston f4607cb521 [cli] Accept basenames in prebuilt idedata.json
The dashboard's source-routed runner ships idedata.json with bare
basenames in prog_path and extra.flash_images[*].path (the receiver's
build-host absolute paths don't resolve on the offloader, and the
in-memory Web Serial consumer keys by basename). Without this change,
the dashboard would have to write a fresh idedata.json into the staging
tmpdir on every install just to flip basenames to absolute paths.

Resolve relative paths in the prebuilt idedata against CORE.prebuilt_dir
so both the dashboard's wire format and a hand-built directory with
absolute paths work. cc_path is left alone because it points at a
PlatformIO toolchain binary outside the prebuilt dir; the offloader's
own PIO install provides the matching binary.

Issue: esphome/device-builder#570
Issue: esphome/device-builder#572
2026-05-10 23:21:23 -05:00
J. Nick Koston 0adfd08270 [cli] Address review feedback on --prebuilt-dir
- upload_using_ltchiptool: rename unused config arg to _config and note
  the signature parity with upload_using_platformio/upload_using_picotool
  so dispatch stays symmetric.
- upload_program: explicit exit_code = 1 when _rp2040_serial_reset_to_bootsel
  fails, instead of relying on the function-level default.
- upload_using_picotool: distinct error message for the prebuilt-dir case
  that names both candidates (idedata ELF + prebuilt firmware) instead of
  just pointing at the missing ELF.
- _load_idedata: document the prebuilt-dir idedata.json contract more
  loudly (absolute paths under prebuilt_dir, no schema validation, dashboard
  owns the rewrites).
- --prebuilt-dir help text: drop the placeholder docs URL; describe the
  dashboard-internal intent inline so users who hit the flag in --help
  understand they don't want it.
- New test: upload_using_esptool with ESP-IDF toolchain + --prebuilt-dir
  uses <prebuilt-dir>/firmware.factory.bin at offset 0x0.

Issue: esphome/device-builder#572
2026-05-10 23:18:48 -05:00
J. Nick Koston d96ad02b9f [nrf52] Honor --prebuilt-dir for mcumgr/BLE OTA uploads
nRF52 has its own upload_program that runs before the default dispatch
in esphome.__main__. The mcumgr/BLE OTA path reads the MCUboot-signed
update image from CORE.relative_pioenvs_path(name, 'zephyr',
'app_update.bin'), which assumes a local Zephyr build tree.

Consult CORE.prebuilt_artifact_path('app_update.bin') first so the
dashboard's transparent BLE install on a Bluetooth proxy can flash a
prebuilt update image without compiling locally.

Serial uploads on non-MCUboot bootloaders still go through
adafruit-nrfutil via _upload_using_platformio and are out of scope here;
they need their own bypass to work with --prebuilt-dir (tracked
separately).

Issue: esphome/device-builder#572
2026-05-10 23:07:04 -05:00
J. Nick Koston a6a0a404ae [cli] Flash RP2040 serial prebuilt-dir uploads via 1200bps touch + picotool
Mirror the libretiny/ltchiptool shape for RP2040 serial when
--prebuilt-dir is set: open the user-supplied serial port at 1200 baud
(arduino-pico's USB CDC interprets the open/close as a request to reboot
into BOOTSEL), poll picotool until the BOOTSEL device shows up on the
USB bus, then dispatch to upload_using_picotool with the prebuilt .uf2.

This removes the last path that required --prebuilt-dir to contain a
platformio.ini + .pioenvs/<name>/ tree, so upload_using_platformio is
now only invoked when no prebuilt dir is set (i.e. the existing
compile+upload flow on a developer machine).

Issue: esphome/device-builder#572
2026-05-10 23:04:18 -05:00
J. Nick Koston b8336cddf2 [cli] Flash libretiny prebuilt-dir uploads via ltchiptool
The libretiny upload path on `upload_program` SERIAL dispatch re-invokes
PlatformIO (`pio run -t upload -t nobuild`), which needs a full build
tree and `platformio.ini`. That makes it incompatible with a dashboard
that only has prebuilt artifacts.

Bypass PlatformIO for the libretiny+SERIAL+--prebuilt-dir case by calling
`ltchiptool flash write -d <port> <firmware.uf2>` directly. The .uf2
encodes the chip family in its header so no extra config is needed.

ltchiptool ships with the libretiny PlatformIO platform under
~/.platformio/penv/.libretiny/bin/ltchiptool; `get_ltchiptool_path()`
prefers PATH first (pip install ltchiptool) and falls back to the
PlatformIO penv. Without --prebuilt-dir the existing PlatformIO path
remains in place, so this is purely additive.

Issue: esphome/device-builder#572
2026-05-10 22:52:17 -05:00
J. Nick Koston 255d4c6b65 [cli] Add esphome upload --prebuilt-dir <path>
Adds a --prebuilt-dir flag to esphome upload that points the per-platform
upload helpers at a directory of prebuilt artifacts shipped from a paired
build server, instead of re-deriving paths from the local build tree.

Covers every upload-dispatch shape:
- ESP32 / ESP8266 serial (esptool) reads firmware.bin + extras via the
  prebuilt idedata.json the dashboard ships next to the artifacts.
- ESP32 / ESP8266 OTA (native API + web_server) reads CORE.firmware_bin,
  CORE.partition_table_bin and CORE.bootloader_bin which now consult the
  prebuilt-dir first.
- RP2040 BOOTSEL (picotool) falls back from the idedata ELF (absent in
  the flat layout) to the prebuilt firmware.uf2.
- RP2040 serial / libretiny serial / OTA (PlatformIO upload -t nobuild)
  point platformio at the prebuilt build tree via CORE.build_path so the
  -t upload -t nobuild path finds platformio.ini and .pioenvs/<name>/.

Issue: esphome/device-builder#572
2026-05-10 22:28:19 -05:00
Diorcet Yann e9cc10fedc [core] Native idf full support (#14678)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: Jonathan Swoboda <swoboda1337@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2026-05-11 02:12:07 +00:00
J. Nick Koston 66e2dcffc4 [cli] Tighten command_rename: scoped name rewrite, target-collision check (#16296) 2026-05-11 13:00:09 +12:00
J. Nick Koston 17080ddce6 [wifi][rp2040] Add stable wifi-capability helpers for device-builder (#16300) 2026-05-11 12:56:56 +12:00
J. Nick Koston 930d539969 [config_validation] Add a visibility UI-hint kwarg (#16267) 2026-05-11 12:07:15 +12:00
Clyde Stubbs 3c042e2e44 [lvgl] Ensure that on_value events fire on checked change (#16119) 2026-05-11 11:58:18 +12:00
Jesse Hills ed10fbea3e [docker] Silence CopyIgnoredFile warning for build context root (#16311) 2026-05-11 07:25:49 +12:00
Mat931 1365251365 [ota] Add bootloader update functionality to ota component (#16238)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-05-08 21:36:06 +00:00
rwrozelle 3abf2c99a2 [openthread] add coroutine-with-priority COMMUNICATION (#16318) 2026-05-08 16:35:47 -05:00
Kevin Ahrendt 70b9edfabe [i2s_audio] Refactor SPDIF output, fixing synchronization problems (#16319) 2026-05-08 21:26:09 +00:00
John Boiles 88c2a1c096 [speaker] Add SPDIF output support (#8065)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
Co-authored-by: Kevin Ahrendt <kevin.ahrendt@openhomefoundation.org>
2026-05-08 14:43:55 -04:00
Mat931 3d8fffbea9 [htu31d][kamstrup_kmp][ms8607] Use CRC functions from helpers.h (#16313) 2026-05-08 09:17:14 -04:00
Jonathan Swoboda eb52ca61fe [climate][ektf2232] Remove deprecations scheduled for 2026.5.0 (#16289) 2026-05-08 07:26:14 -04:00
Jonathan Swoboda a970f05b69 [clang-tidy] Enable readability-redundant-string-init (#16310) 2026-05-08 07:26:03 -04:00
Clyde Stubbs 7b6e2589f1 [modbus_server] Reduce log spam (#16283) 2026-05-08 14:09:22 +10:00
Jonathan Swoboda 696a654733 [clang-tidy] Concatenate nested namespaces (7/7: tests, platform-gated, enable check) (#16307) 2026-05-07 23:05:17 -04:00
Kevin Ahrendt 08b17c9da1 [core] Move core ring buffer to helper component (#16298) 2026-05-08 14:01:37 +12:00
Jesse Hills e152c6155b [ci] Skip needs-docs for new components without CONFIG_SCHEMA (#16303) 2026-05-08 14:00:50 +12:00
Jonathan Swoboda 6ffcb821ca [clang-tidy] Concatenate nested namespaces (6/7: components t-z) (#16305) 2026-05-08 01:13:38 +00:00
Jonathan Swoboda ded83812f4 [clang-tidy] Concatenate nested namespaces (5/7: components s) (#16302) 2026-05-08 00:16:51 +00:00
Jonathan Swoboda ab1d2de78e [clang-tidy] Concatenate nested namespaces (4/7: components n-r) (#16301) 2026-05-07 23:28:30 +00:00
Jonathan Swoboda cbe192df49 [clang-tidy] Concatenate nested namespaces (3/7: components i-m) (#16297) 2026-05-07 19:00:17 -04:00
dependabot[bot] 56ef357162 Bump github/codeql-action from 4.35.3 to 4.35.4 (#16299)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-07 17:51:30 -05:00
Jonathan Swoboda 4e4e4b4411 [clang-tidy] Concatenate nested namespaces (2/7: components d-h) (#16295) 2026-05-07 16:49:55 -04:00
Jonathan Swoboda 06bd92c388 [clang-tidy] Concatenate nested namespaces (1/7: components a-c) (#16294) 2026-05-07 14:21:39 -04:00
J. Nick Koston 71193e2b2c [helpers] Document write_file's external consumer contract (esphome-device-builder) (#16290) 2026-05-07 13:21:35 -05:00
Clyde Stubbs 9301f76482 [sensor] Add alternate calibration format for ntc (#15937) 2026-05-07 06:59:22 +10:00
Clyde Stubbs 004aa49131 [lvgl] Pass touch point to touch event lambdas (#16272) 2026-05-07 06:57:53 +10:00
dependabot[bot] 3b6250bcee Bump CodSpeedHQ/action from 4.15.0 to 4.15.1 (#16281)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-06 15:23:58 -05:00
Jesse Hills a7b4a2006a Merge branch 'release' into dev 2026-05-07 08:13:00 +12:00
Jesse Hills 09dc41435c Merge pull request #16282 from esphome/bump-2026.4.5
2026.4.5
2026-05-07 08:12:15 +12:00
Jesse Hills 5283cdec12 Bump version to 2026.4.5 2026-05-07 07:25:35 +12:00
Edward Firmo d9835c8705 [nextion] Fix text sensor state not updated on string response (#16280) 2026-05-07 07:25:35 +12:00
Mat931 b89c71c1ea [core] Fix WiFi connection in safe mode (#16269)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-05-07 07:25:35 +12:00
J. Nick Koston 7f6aef4f33 [substitutions] Fix sibling references inside dict-valued substitutions (#16273) 2026-05-07 07:25:35 +12:00
J. Nick Koston 016b509b55 [bundle] Include secrets.yaml when !secret keys are quoted (#16271) 2026-05-07 07:25:35 +12:00
Jesse Hills d2bbaeccf3 [ha-addon] Add opt-in toggle for the new ESPHome Device Builder (#16247) 2026-05-07 07:25:35 +12:00
puddly 1e58e8729a [uart] Use tcdrain for flushing instead oftcflush on host (#14877)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-05-06 18:53:48 +00:00
J. Nick Koston 6173656bf8 [schema] Surface OnlyWith / OnlyWithout default + gate components in schema generator (#16276) 2026-05-06 13:49:00 -04:00
dbl-0 0d94ffe15d [resolver] Make RESOLVE_TIMEOUT configurable via environment variable (#15951)
Co-authored-by: Daniel Lowe <dan@auth.dxj.app>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-05-06 17:48:38 +00:00
Edward Firmo 4da62067cf [nextion] Fix text sensor state not updated on string response (#16280) 2026-05-06 13:32:50 -04:00
Kevin Ahrendt 9f49e3f80e [audio] Bump microFLAC to v0.2.0 (#16279) 2026-05-06 17:22:18 +00:00
Kevin Ahrendt fc25ab0246 [i2s_audio] Optimize software volume control (#16278) 2026-05-06 12:57:03 -04:00
Kevin Ahrendt a4a57a540d [core] Adds acquire and release methods to the ring buffer class (#16277) 2026-05-06 12:56:54 -04:00
Didier A cfd2c9182c [bl0942] Remove broken 24-bit overflow tracking (#15650)
Co-authored-by: DidierA <1620015+didiera@users.noreply.github.com>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-05-06 12:34:55 -04:00
Mat931 2864922ac0 [ota] Partition table update: Fix log messages (#16241)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-06 09:59:10 -05:00
Mat931 90693fb39a [core] Fix WiFi connection in safe mode (#16269)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-05-06 09:56:33 -05:00
J. Nick Koston 6e1a59da3e [packages] Make package !include vars visible to its substitutions block (#16274) 2026-05-06 09:53:14 -05:00
John 545ee03f42 [atm90e32] Fix calibration instance not saving in flash properly (#14152)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-05-06 10:15:04 -04:00
J. Nick Koston caaa1aefc7 [substitutions] Fix sibling references inside dict-valued substitutions (#16273) 2026-05-06 08:41:17 -05:00
J. Nick Koston ff0c5f575e [bundle] Include secrets.yaml when !secret keys are quoted (#16271) 2026-05-06 07:32:35 -05:00
J. Nick Koston f06ad8c436 [http_request] Add regression test for light action inside on_response (#16270) 2026-05-06 07:32:19 -05:00
Jonathan Swoboda 29db5fa4bb [script] Make pre-commit and helpers work on Windows (#16260)
Co-authored-by: Jonathan Swoboda <swoboda1337@users.noreply.github.com>
2026-05-06 07:11:06 -05:00
J. Nick Koston 85f33978e7 [core] Skip external component update on esphome clean (#16268) 2026-05-06 07:23:35 -04:00
Clyde Stubbs 79786f1cc7 [lvgl] Allow line points as percentages (#16209) 2026-05-06 07:22:43 -04:00
Kevin Ahrendt febf8815c7 [audio_file][speaker] Eliminate code duplication for files built into firmware (#16266) 2026-05-06 05:59:51 -04:00
Jesse Hills 6f6d991dd2 [ha-addon] Add opt-in toggle for the new ESPHome Device Builder (#16247) 2026-05-06 21:42:11 +12:00
tomaszduda23 e9f7579910 [logger] give a chance to print crash (#16203)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-05-06 01:37:40 +00:00
tomaszduda23 a99c1b3e08 [nrf52] add reserve area for bootloader (#16204) 2026-05-05 20:37:03 -04:00
Kevin Ahrendt 2d6af1f7e5 [audio] Bump esp-audio-libs to v3.0.0 (#16263) 2026-05-05 20:22:53 -04:00
J. Nick Koston 700676b340 [api] Use entity_types.h X-macro for InitialStateIterator declarations (#16075) 2026-05-05 18:29:48 -05:00
J. Nick Koston bf1c339dc1 [api] Use entity_types.h X-macro for ListEntitiesIterator declarations (#16076) 2026-05-05 18:29:32 -05:00
J. Nick Koston f5c1b8839d [web_server] Use entity_types.h X-macro for ListEntitiesIterator declarations (#16077) 2026-05-05 18:29:10 -05:00
J. Nick Koston 4404dd68ba [cover] Fix ControlAction / CoverPublishAction trigger args with reference types (#16227) 2026-05-05 18:27:18 -05:00
J. Nick Koston 67491c3194 [packages] Add resolve_packages single-call seam (#16235) 2026-05-05 18:26:52 -05:00
J. Nick Koston 39b2b901f7 [core] Replace scheduler pool vector with unbounded intrusive freelist (#16172) 2026-05-05 18:26:19 -05:00
J. Nick Koston f30ad588ea [cli] Add --ota-platform flag to pick web_server or native API OTA (#16207) 2026-05-05 18:25:53 -05:00
tomaszduda23 be82e8faeb [debug] Remove unused buffer in uicr lambda function (#16208) 2026-05-05 19:02:26 -04:00
Kevin Ahrendt 57397a318a [audio] Use the microWAV library for decoding (#16251) 2026-05-05 11:21:02 -05:00
Kevin Ahrendt 87a705b1cc [audio] Bump microOpus to v0.4.1 (#16255) 2026-05-05 12:47:07 +00:00
Keith Burzinski edbb9f7b28 [i2s_audio] Fix stereo playback when slot bit width exceeds data bit width (#16248) 2026-05-05 08:15:32 -04:00
Jesse Hills efff8fe8be [platformio_api] Remove duplicated _strip_win_long_path_prefix (#16249) 2026-05-05 14:29:23 +12:00
Jesse Hills f248302370 Merge branch 'release' into dev 2026-05-05 14:22:23 +12:00
Jesse Hills 6fda5f41b2 Merge pull request #16240 from esphome/bump-2026.4.4
2026.4.4
2026-05-05 14:21:38 +12:00
Kevin Ahrendt ea2b2b3920 [audio_file] Use microDecoder library instead of manual task management/decoding (#16237) 2026-05-04 20:12:26 -05:00
Kevin Ahrendt f33d137669 [audio][media_player][speaker] WAV decoding is no longer always built (#16244) 2026-05-04 23:45:11 +00:00
dependabot[bot] d28498ac2c Bump cryptography from 47.0.0 to 48.0.0 (#16245)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-04 23:39:44 +00:00
Olivier ARCHER 556783b95b [http_request] remove slow http_request warning on 8266 (#16239) 2026-05-04 18:19:52 -05:00
Kevin Ahrendt 857e529803 [audio] Use the microMP3 library instead of esp-audio-libs (#16236) 2026-05-04 18:41:50 -04:00
Jesse Hills 197d4dac8e Bump version to 2026.4.4 2026-05-05 08:27:10 +12:00
Jesse Hills 2d7f9dc48d [api] Use safe_print for log output and fix safe_print bytes-repr fallback (#16160) 2026-05-05 08:27:04 +12:00
J. Nick Koston be84e6c9f4 [api] Fall back to owning types for service array args used after a delay (#16140) 2026-05-05 08:22:05 +12:00
J. Nick Koston 0418f2138a [esp32] Drop printf wrap on IDF 6.0+ (picolibc no longer needs it) (#16189) 2026-05-05 08:22:05 +12:00
Clyde Stubbs d9c22d6b56 [lvgl] Clamp values for meter line indicators (#16180) 2026-05-05 08:22:05 +12:00
J. Nick Koston 60a94fd109 [esp32] Replace 512B stack buffer in printf wraps with picolibc cookie FILE (#16170) 2026-05-05 08:22:05 +12:00
Jesse Hills 9371ec319a [core] Strip \\?\ prefix from sys.executable for PlatformIO subprocess (#16158) 2026-05-05 08:21:58 +12:00
J. Nick Koston ce466c6b60 [mcp23xxx_base] Reject unsupported interrupt_pin options (inverted, allow_other_uses) (#16149) 2026-05-05 08:14:03 +12:00
Brandon Harvey a460f5343c [automation] Fix codegen type for component.resume update_interval (#16069)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 08:14:02 +12:00
Jesse Hills 7c2a63bf82 [api] Use safe_print for log output and fix safe_print bytes-repr fallback (#16160) 2026-05-05 08:12:20 +12:00
Diorcet Yann 690a197346 [main] Move stacktrace handling out of platformio_api and FlashImage into platform components/util (#16186) 2026-05-04 15:07:31 -04:00
J. Nick Koston 24d4da1021 [sensor] Document why TimeoutFilterBase intentionally keeps Component (#16194)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-05-04 01:18:28 +00:00
J. Nick Koston 53c4e6f386 [tests] Drop duplicate on_boot_restore_from in host_mode_climate_basic_state (#16228) 2026-05-03 20:12:51 -05:00
J. Nick Koston 1d63158480 [zephyr] Add nRF52 component tests so CI runs on zephyr-only changes (#16188) 2026-05-03 20:05:56 -05:00
J. Nick Koston 013dee44eb [binary_sensor] Drop Component from AutorepeatFilter, use self-keyed scheduler (#16191) 2026-05-03 20:05:27 -05:00
J. Nick Koston 9ddb828da3 [api] Don't tear down log connection on stack-trace decode failure (#16196) 2026-05-03 20:05:13 -05:00
J. Nick Koston 120d1e51fb [tests] Fix flaky host_mode_climate_basic_state integration test (#16192) 2026-05-03 20:04:34 -05:00
J. Nick Koston 844a36f7a1 [api] Mark high-volume proxy messages as speed_optimized (Infrared/RF, Z-Wave, serial) (#16159) 2026-05-03 20:03:52 -05:00
J. Nick Koston 72a75f2d3f [cover] Fold ControlAction/CoverPublishAction fields into stateless lambdas (#16046) 2026-05-03 20:02:07 -05:00
J. Nick Koston b5eb444015 [dashboard] Stabilize device-builder dashboard backend's API surface (#16206)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-03 20:01:51 -05:00
J. Nick Koston 15ab5422c7 [ci] Run downstream device-builder tests against PR Python code (#16214) 2026-05-03 19:45:08 -05:00
J. Nick Koston 33f88619da [valve] Fix ControlAction trigger args with reference types (#16223) 2026-05-03 19:44:21 -05:00
J. Nick Koston df1200629f [tests] Fix flaky host_mode_climate_basic_state (#16225) 2026-05-03 19:44:11 -05:00
J. Nick Koston 41bd570d30 [light] Fix LightControlAction trigger args with reference types (#16220) 2026-05-03 19:44:01 -05:00
J. Nick Koston cf223674e5 [climate] Fix ControlAction trigger args with reference types (#16221) 2026-05-03 19:43:49 -05:00
J. Nick Koston af74b639cf [fan] Fix TurnOnAction trigger args with reference types (#16222) 2026-05-03 19:43:35 -05:00
J. Nick Koston 4108b27197 [esp8266] Lower WDT_FEED_INTERVAL_MS to 100 ms (#16197) 2026-05-03 19:43:09 -05:00
Mat931 7cfab58a05 [ota] Add partition table update functionality to ota component (#15780)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-05-03 19:42:10 -05:00
tomaszduda23 85e1e4b95e [zephyr] feed watchdog early. Otherwise OTA may rollback. (#16218) 2026-05-03 20:37:32 -04:00
J. Nick Koston 0f174ee626 [api] Fall back to owning types for service array args used after a delay (#16140) 2026-05-04 10:55:40 +12:00
Edward Firmo 8046ff7e1e [nextion] TFT upload no longer fails when the display sends a split 0x08 ack (#16205)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2026-05-03 03:40:09 -05:00
dependabot[bot] 5e9db1c8c6 Bump github/codeql-action from 4.35.2 to 4.35.3 (#16201)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-01 21:46:29 -05:00
J. Nick Koston 81d147ff9e [esp32] Drop printf wrap on IDF 6.0+ (picolibc no longer needs it) (#16189) 2026-05-01 14:31:56 -05:00
Mat931 58cb7effd4 [ota] Add extended OTA protocol (#16164)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-05-01 10:40:14 -05:00
Kevin Ahrendt 3dd60c5713 [core] Support allocating ring buffer in internal memory (#16187) 2026-05-01 07:55:08 -05:00
Oliver Kleinecke f073c1cabe [usb_host][usb_uart] Add configurable max packet size (#14584) 2026-05-01 20:43:13 +10:00
J. Nick Koston 5cc447e0da [core] Move per-platform hal_platform.h into components/platform/hal.h (#16183) 2026-04-30 21:27:31 -05:00
Clyde Stubbs 0980630f68 [lvgl] Clamp values for meter line indicators (#16180) 2026-04-30 22:23:14 -04:00
J. Nick Koston b8dfffdf06 [core] Enable ruff FLY (flynt) lint family (#16182) 2026-04-30 21:20:07 -05:00
luar123 f6e39d305d [zigbee] Add newlib compatibility for zigbee sdk in idf 6 (#16174) 2026-04-30 22:08:55 -04:00
Jonathan Swoboda 08e5cb5576 [esp32_hosted] Bump esp_hosted to 2.12.6 and esp_wifi_remote to 1.5.1 (#16176) 2026-04-30 20:47:22 -05:00
Kevin Ahrendt faa61696e0 [sendspin] Use sendspin-cpp to v0.4.0 to reduce stuttering (#16178) 2026-04-30 20:43:24 -05:00
J. Nick Koston 9999913d07 [zephyr] Move HAL bodies into components/zephyr/hal.cpp + inline trivial dispatches (#16116) 2026-04-30 20:10:51 -05:00
J. Nick Koston 92aa98f680 [host] Move HAL bodies into components/host/hal.cpp + inline trivial dispatches (#16115) 2026-05-01 00:42:38 +00:00
J. Nick Koston 3d69169141 [climate] Fold ControlAction fields into a single stateless lambda (#16044) 2026-04-30 19:16:16 -05:00
J. Nick Koston 24fdfcf1a1 [rp2040] Move HAL bodies into components/rp2040/hal.cpp + inline trivial dispatches (#16114) 2026-04-30 19:15:41 -05:00
J. Nick Koston 550444dc34 [binary_sensor] Drop Component from filter classes, use self-keyed scheduler (#16131) 2026-04-30 19:15:18 -05:00
J. Nick Koston ba7c06785a [mdns] Broadcast config_hash TXT record on _esphomelib._tcp (#16145) 2026-04-30 19:14:55 -05:00
J. Nick Koston b708d1a826 [core] Drop unused DELAY_ACTION from InternalSchedulerID enum (#16151) 2026-04-30 19:14:34 -05:00
J. Nick Koston 148d478dec [api] Add encode/decode benchmarks for Z-Wave, IR/RF, and serial proxy messages (#16157) 2026-04-30 19:14:20 -05:00
J. Nick Koston 45e78e4114 [core] Inline loop gate expression to avoid stale local reuse (#16167) 2026-04-30 19:13:54 -05:00
J. Nick Koston 3b3e003aa3 [sensor] Pack ThrottleAverageFilter have_nan_ into n_ bitfield (-4 B/instance) (#16169) 2026-04-30 19:13:10 -05:00
J. Nick Koston 2f3e16b482 [bk72xx] Apply CFG_SUPPORT_BLE=0 SDK option to BK7238 (#16181) 2026-04-30 19:12:06 -05:00
J. Nick Koston e085cb50d9 [sensor] Drop Component from filter classes, use self-keyed scheduler (#16132) 2026-04-30 19:11:30 -05:00
J. Nick Koston 2fbfb4c385 [ci] Split integration tests into 3 buckets when count is more than 10 (#16152) 2026-04-30 19:10:53 -05:00
J. Nick Koston 61261b4a59 [libretiny] Move HAL bodies into components/libretiny/hal.cpp + inline trivial dispatches (#16113) 2026-04-30 12:33:22 -05:00
J. Nick Koston d48aad8c4d [esp32] Replace 512B stack buffer in printf wraps with picolibc cookie FILE (#16170) 2026-04-30 13:27:54 -04:00
Kevin Ahrendt f1d3be4bda [core] Simplify RAMAllocator and add internal fallback to external mode (#16171) 2026-04-30 12:03:40 -04:00
Kevin Ahrendt 2758aa5517 [audio] bump microOpus to v0.4.0 to use fixed-point by default on ESP32 (#16168) 2026-04-30 09:12:39 -04:00
Kevin Ahrendt a8b0133ec1 [audio] Enable specific codecs and configure advanced features (#16166) 2026-04-30 08:49:28 -04:00
Clyde Stubbs 1398dcebb4 [st7789v] Add deprecation warnings (#16162) 2026-04-30 00:53:37 -05:00
dependabot[bot] 096d0c4279 Bump aioesphomeapi from 44.22.0 to 44.23.0 (#16161)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-30 04:45:19 +00:00
Jesse Hills e127268dac [core] Strip \\?\ prefix from sys.executable for PlatformIO subprocess (#16158) 2026-04-30 16:04:52 +12:00
J. Nick Koston f0bffed3c0 [esp8266] Move HAL bodies into components/esp8266/hal.cpp + inline arch_init (#16112) 2026-04-30 15:42:17 +12:00
Jesse Hills 1a871e231d [ci] Use client-id for GitHub App token generation (#16155) 2026-04-30 13:09:37 +12:00
Jesse Hills 47765bd2d0 [ci] Correct version comment on create-github-app-token pin (#16156) 2026-04-30 13:08:56 +12:00
dependabot[bot] 8066325e0b Bump esphome/workflows/.github/workflows/lock.yml from 2026.4.0 to 2026.4.1 (#16143)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-30 12:52:25 +12:00
J. Nick Koston b8d24c9e49 [mcp23xxx_base] Reject unsupported interrupt_pin options (inverted, allow_other_uses) (#16149) 2026-04-30 11:14:07 +12:00
J. Nick Koston 9b1f5c59bb [core] Fix null deref in WarnIfComponentBlockingGuard for self-keyed scheduler timers (#16150) 2026-04-29 23:05:38 +00:00
Jonathan Swoboda e4b33fddf5 [esp32] Add ESP-IDF 6.0.1 platform entry (#16146) 2026-04-29 18:43:15 -04:00
Jonathan Swoboda 77da64a367 [sx126x] Add cold sleep option and drop unused RTC wakeup bit (#16144) 2026-04-29 17:05:51 -04:00
J. Nick Koston cecccebc64 [core] DelayAction: drop Component inheritance, use self-keyed scheduler (#16129) 2026-04-29 20:35:04 +00:00
Jonathan Swoboda 53b682e48f [ci] Bump clang-tidy from 18.1.8 to 22.1.0.1 (#16078)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-29 20:19:33 +00:00
Mat931 14910e65d9 [ota] Use WatchdogManager for OTA on ESP32 (#16138)
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-04-29 20:15:21 +00:00
J. Nick Koston 813964714c [esp32] Move HAL bodies into components/esp32/hal.cpp + inline trivial dispatches (#16111) 2026-04-29 20:09:08 +00:00
J. Nick Koston 5a146ab6b7 [valve] Fold ControlAction fields into a single stateless lambda (#16123) 2026-04-29 19:20:15 +00:00
J. Nick Koston 61a41402df [fan] Fold TurnOnAction fields into a single stateless lambda (#16122) 2026-04-29 19:16:05 +00:00
Mat931 59b4cfd07c [watchdog] Use default CHECK_IDLE_TASK and PANIC when configuring the watchdog (#16142) 2026-04-29 18:41:12 +00:00
J. Nick Koston c41f38e16d [scheduler] Add self-keyed timer API for callers without a Component (#16127) 2026-04-29 13:24:37 -05:00
Clyde Stubbs 0ad8a071a7 [espnow] Cleanup method visibility and naming (#16109) 2026-04-29 14:18:21 -04:00
J. Nick Koston 985dba9332 [core] Defer heavy module-scope imports in __main__, loader, and config (#15955) 2026-04-29 13:17:59 -05:00
GelidusResearch ca3f7251d4 [ens160] Fix sensor initialization timing (#16024)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-29 14:07:28 -04:00
J. Nick Koston 44cabc191d [core] Catch body-read errors in download_content (#16023) 2026-04-29 14:06:41 -04:00
J. Nick Koston e5b1991cf7 [fan] Add tests for fan.turn_on action field combinations (#16125) 2026-04-29 12:46:06 -05:00
J. Nick Koston 7fba57ce51 [valve] Add tests for valve.control action field combinations (#16126) 2026-04-29 12:45:30 -05:00
J. Nick Koston 69a33d8ac0 [core] Inline HAL clock wrappers and split hal.h into per-platform headers (#15977) 2026-04-29 12:31:55 -05:00
Jonathan Swoboda ce61dcf387 [remote_base][core] Drop redundant typename in dependent type contexts (#16137) 2026-04-29 16:54:17 +00:00
Jonathan Swoboda bae6b51652 [kamstrup_kmp][toshiba] Fix signed/unsigned comparisons against sizeof (#16135) 2026-04-29 11:33:57 -04:00
Jonathan Swoboda 557c3d4436 [aqi] Use std::max initializer-list for non-negative AQI clamp (#16134) 2026-04-29 11:33:29 -04:00
Jonathan Swoboda bacee89bca [mixer_speaker] NOLINT bugprone-unchecked-optional-access in audio_mixer_task (#16130) 2026-04-29 10:56:13 -04:00
Jonathan Swoboda 2157d11913 [haier] Fix bugprone-unchecked-optional-access; switch HardwareInfo to char[9] (#16124) 2026-04-29 14:26:53 +00:00
Jonathan Swoboda 42b8597719 [api] Extend NOLINT to cover bugprone-random-generator-seed in MAC varint test (#16120) 2026-04-29 13:58:19 +00:00
Jonathan Swoboda 2bd28eee9d [tormatic] Use .value() for checked optional access in read_gate_status_ (#16121) 2026-04-29 09:51:31 -04:00
J. Nick Koston 0a497d3c22 [light] Fold LightControlAction fields into a single stateless lambda (#16118) 2026-04-29 08:35:17 -05:00
Jonathan Swoboda 79da2b9704 [time] Fix bugprone-unchecked-optional-access in CronTrigger::check_time_ (#16107) 2026-04-29 08:30:46 -04:00
Jonathan Swoboda ae5b211c89 [api] Avoid JsonDocument copy-and-swap operator= in ActionResponse ctor (#16106) 2026-04-29 08:30:35 -04:00
J. Nick Koston 8ceada8d04 [core] Download external_files in parallel (#16021) 2026-04-29 14:32:30 +12:00
J. Nick Koston 49c7a6928e [script] Fix cpp_unit_test crash for non-MULTI_CONF platform components (#16104) 2026-04-29 14:32:13 +12:00
J. Nick Koston 2fce71e0d4 [wifi] Add phy_mode option for ESP8266 (#16055) 2026-04-29 14:31:07 +12:00
J. Nick Koston 80251c54be [climate] Add climate.control coverage to component tests via thermostat (#16052) 2026-04-29 14:27:56 +12:00
J. Nick Koston 0d51a122d0 [cover] Add cover.control / cover.template.publish coverage to template tests (#16051) 2026-04-29 14:27:40 +12:00
J. Nick Koston 5a33c50015 [light] Use constexpr template for DimRelativeAction transition_length (#16038) 2026-04-29 14:26:38 +12:00
J. Nick Koston 0d150dc57e [light] Use constexpr template for ToggleAction transition_length (#16037) 2026-04-29 14:25:18 +12:00
J. Nick Koston d287876d8d [light] Use bitmask template for LightControlAction unused fields (#16039) 2026-04-29 14:20:37 +12:00
J. Nick Koston 592486ae9a [analyze_memory] Attribute main.cpp setup()/loop() to esphome core (#16033) 2026-04-29 14:06:54 +12:00
Jonathan Swoboda c3bd38af77 [feedback] Fix bugprone-unchecked-optional-access in start_direction_ (#16103) 2026-04-28 21:54:15 -04:00
J. Nick Koston eec770d622 [core] Use ETag in external_files cache to fix re-downloads from raw.githubusercontent.com (#16020) 2026-04-29 13:52:09 +12:00
J. Nick Koston d7b21a84a3 [git] Make ref fetches and submodule updates shallow (#16014) 2026-04-29 13:49:51 +12:00
J. Nick Koston f05243bd9d [api] Add 48-bit MAC address varint fast path for BLE advertisements (#15988) 2026-04-29 13:48:35 +12:00
J. Nick Koston 35cb28edfe [output] Gate FloatOutput power scaling fields behind USE_OUTPUT_FLOAT_POWER_SCALING (#15998) 2026-04-29 13:27:22 +12:00
J. Nick Koston 1363f661e6 [core] Inline ContinuationAction in If/While/RepeatAction (#16040) 2026-04-28 21:26:25 -04:00
J. Nick Koston 8af499b591 [api] Use custom deleter to fix incomplete-type error on macOS libc++ (#16050) 2026-04-28 21:26:21 -04:00
Jonathan Swoboda 1a57d9bc2f [sprinkler][pn532] Fix bugprone-unchecked-optional-access (#16102) 2026-04-29 01:04:19 +00:00
J. Nick Koston 9768380856 [api] Hoist memw out of socket ready check to once per main-loop iter (#15996) 2026-04-29 13:04:10 +12:00
J. Nick Koston 676f26919e [mdns] Drive MDNS.update() polling from IP state events on ESP8266/RP2040 (#15961) 2026-04-29 13:02:21 +12:00
J. Nick Koston 29d3a3a498 [esp8266] Replace millis() with fast accumulator, wrap Arduino callers (#15662) 2026-04-29 12:58:00 +12:00
Jonathan Swoboda 77b76ac48a [inkbird_ibsth1_mini][speaker][speaker_source] Fix performance-unnecessary-copy-initialization (#16101) 2026-04-29 00:56:03 +00:00
Clyde Stubbs 0b5835284a [lvgl] Additional layout features (#16041) 2026-04-29 12:35:24 +12:00
Jonathan Swoboda 15df477472 [core] Reduce copies in Callback/CallbackManager call paths (#16093)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2026-04-28 19:41:28 -04:00
Jonathan Swoboda be0ee73847 [i2c] NOLINT readability-identifier-naming on Zephyr struct forward-decl (#16099) 2026-04-28 19:22:42 -04:00
Jonathan Swoboda a241c9e622 [online_image][sim800l] Use std::string::starts_with for prefix checks (#16097) 2026-04-28 19:02:39 -04:00
Jonathan Swoboda 2f433c78bd [haier] Brace single-statement else-if in smartair2_climate (#16098) 2026-04-28 18:56:36 -04:00
Jonathan Swoboda e39c474577 [binary_sensor] Bind at_index_ once in MultiClick on_state_ (#16095) 2026-04-28 22:13:35 +00:00
Jonathan Swoboda a62e3fe4fc [json] NOLINT StackAddressEscape false positive in parse_json (#16091) 2026-04-28 21:35:40 +00:00
Jonathan Swoboda 7d6b9bee19 [wifi] Avoid copying EAP config in three connect handlers (#16094) 2026-04-28 21:22:29 +00:00
Jonathan Swoboda ab6bda50e4 [esp32_ble] Widen loop variable in as_128bit() to match uuid_.len type (#16088) 2026-04-28 20:58:40 +00:00
Jonathan Swoboda 3d195d748c [ezo] Use make_unique to construct EzoCommand (#16092) 2026-04-28 20:50:15 +00:00
Jonathan Swoboda 16cf4fb5e8 [nextion] Use std::string::starts_with for HTTPS URL check (#16090) 2026-04-28 20:47:20 +00:00
Jonathan Swoboda 70503442f4 [dfrobot_sen0395] Brace single-statement else-if in enqueue() (#16089) 2026-04-28 20:37:29 +00:00
Jonathan Swoboda 594b269dba [bme680] Rename cal1/cal2 to coeff1/coeff2 (#16087) 2026-04-28 20:33:57 +00:00
Clyde Stubbs 8157c721a5 [mapping] Implement default value (#15861) 2026-04-29 06:31:37 +10:00
Clyde Stubbs 9af557de6d [lvgl] Add utility gradient function (#16048) 2026-04-29 06:29:38 +10:00
Jonathan Swoboda 1f4136e76f [pipsolar] Guard handle_qmod_ against empty message (#16085) 2026-04-28 16:29:09 -04:00
Jonathan Swoboda c8dffcc9b8 [tlc5971] Remove dead bit-banging delay code (#16086) 2026-04-28 15:28:33 -05:00
dependabot[bot] 44fbb7f5a9 Bump CodSpeedHQ/action from 4.14.0 to 4.15.0 (#16084)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-28 15:10:21 -05:00
Jonathan Swoboda eb01d43feb [spi][http_request][demo] Fix latent clang-tidy issues in headers (#16080) 2026-04-28 16:09:35 -04:00
Jonathan Swoboda 7891fd5cf1 Add dependencies.lock to .gitignore (#16081) 2026-04-29 07:38:31 +12:00
Jonathan Swoboda 4ee9cc432b [ci] Install requirements_dev.txt in the cached venv (#16082) 2026-04-29 07:37:46 +12:00
Mat931 42ff10afe5 [watchdog] Fix WatchdogManager on single core apps (#16074) 2026-04-28 17:32:44 +00:00
tomaszduda23 6b3df66bdc [nrf52] make reset pin optional (#11684)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-04-28 12:20:38 -05:00
tomaszduda23 968878a62d [nrf52] implement wake_loop_threadsafe/wakeable_delay (#16032)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-28 16:35:12 +00:00
J. Nick Koston daf3f4d2f1 [core] wakeable_delay: yield on already-woken fast path (ESP8266, RP2040) (#16045) 2026-04-28 10:41:17 -05:00
Bonne Eggleston 52e8c50f45 [modbus] Split modbus_server from modbus_controller (#15509)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2026-04-28 10:21:25 -05:00
J. Nick Koston 0a4d9b430f [ci] Add import-time regression check for esphome.__main__ (#15954) 2026-04-28 14:05:12 +00:00
J. Nick Koston 0759a3c681 [core] Split wake.{h,cpp} into per-platform files (#15978) 2026-04-28 08:48:13 -05:00
Egor Vorontsov 8921e3bb3f [api] add open states for lock to api.proto (#15901)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-04-28 07:49:16 -05:00
Clyde Stubbs 52f80618d4 [lvgl] Allow a binary sensor to report checked or pressed state (#16073)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2026-04-28 22:00:29 +10:00
Jesse Hills 876c8c4c2a [ci-custom] Lint imports of esphome.components.const outside components (#16068)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 05:59:02 -05:00
Darafei Praliaskouski 41458d72e0 [esp32] Make Arduino app metadata reproducible (#16053) 2026-04-28 05:58:34 -05:00
Brandon Harvey 49d3df2698 [automation] Fix codegen type for component.resume update_interval (#16069)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 05:27:20 -05:00
J. Nick Koston 792f2e8363 [ota] Add wall-clock timeout to OTA data transfer loop (#16047) 2026-04-28 17:29:42 +12:00
J. Nick Koston 42c9fdc87e [feedback] Use App.get_loop_component_start_time() and constexpr timeout id (#16063) 2026-04-28 16:39:08 +12:00
Jesse Hills 5f6bbb98ce Merge branch 'release' into dev 2026-04-28 15:40:19 +12:00
Jesse Hills 4e0509435a Merge pull request #16067 from esphome/bump-2026.4.3
2026.4.3
2026-04-28 15:39:24 +12:00
J. Nick Koston a03de7cea2 [core] Freshen loop_component_start_time_ before scheduler dispatch (#16064) 2026-04-28 13:23:08 +12:00
Jesse Hills 95b5ab7e78 Bump version to 2026.4.3 2026-04-28 12:58:29 +12:00
J. Nick Koston 3ac0939f55 [image] Fix RGB565+alpha rendering for multi-frame animations (#16017)
Co-authored-by: Claude <noreply@anthropic.com>
2026-04-28 12:58:29 +12:00
Jesse Hills 191d3bc7e4 [esp32_touch] Feed wdt (#16066) 2026-04-28 12:58:29 +12:00
Edward Firmo a186f6fea9 [nextion] Unify TFT upload ack timeout to 5000ms (#15960) 2026-04-28 12:58:29 +12:00
Mat931 aea88aef5e [esp32][wifi] Fix bootloop and WiFi connection issue if nvs partition is missing or has non-default label (#16025)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-04-28 12:58:29 +12:00
J. Nick Koston 433bbdb016 [rotary_encoder][at581x] Fix templatable int field types (#16015) 2026-04-28 12:58:29 +12:00
J. Nick Koston 4137d93cbf [wifi] Fix stale wifi.connected after state transition (#15966) 2026-04-28 12:58:29 +12:00
J. Nick Koston 6a5919ee87 [deep_sleep] Fix sleep_duration codegen type to uint32_t (#15965) 2026-04-28 12:58:29 +12:00
Jesse Hills b753ee4e94 [time] Handle Windows EINVAL when validating POSIX TZ strings (#15934) 2026-04-28 12:58:29 +12:00
Clyde Stubbs c26ea52620 [lvgl] Triggers on tabview tabs fix (#15935) 2026-04-28 12:58:29 +12:00
J. Nick Koston 39a69385fb [image] Fix RGB565+alpha rendering for multi-frame animations (#16017)
Co-authored-by: Claude <noreply@anthropic.com>
2026-04-28 12:57:42 +12:00
Jesse Hills a34836c290 [esp32_touch] Feed wdt (#16066) 2026-04-28 11:27:08 +12:00
Edward Firmo 01ac223913 [nextion] Unify TFT upload ack timeout to 5000ms (#15960) 2026-04-28 08:30:40 +12:00
Mat931 7198c912c7 [esp32][wifi] Fix bootloop and WiFi connection issue if nvs partition is missing or has non-default label (#16025)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-04-27 12:41:28 -05:00
Kevin Ahrendt 24c6a0d711 [audio] Bump microDecoder library to v0.2.0 (#16054) 2026-04-27 12:17:02 +00:00
plazarre dec5d0449b [esp32_ble_tracker] Hold COEX_PREFER_BT for the lifetime of any active connection (#16036)
Co-authored-by: Paul Lazarre <plazarre@gmail.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2026-04-27 06:51:54 -05:00
J. Nick Koston 79b741b8dc [core] Combine entity register + configure_entity_ into one call (#16030) 2026-04-27 03:03:39 +00:00
tomaszduda23 112646a9c4 [zigbee] add router for nrf52 (#16034) 2026-04-26 23:02:09 -04:00
J. Nick Koston 2e096bb036 [core] Combine set_component_source_ + register_component_ into one call (#16029) 2026-04-26 21:54:15 -05:00
Johan Henkens e87e78c544 [api] Expose TemperatureUnit in water heater and climate api (#15815)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2026-04-26 12:58:14 +00:00
J. Nick Koston 0f25d91e68 [core] Unify skip_external_update and honor it in external_files for faster esphome logs (#16016) 2026-04-26 07:24:33 -05:00
J. Nick Koston 8dbdcfc128 [bk72xx] Prepare for BK7238 support (#16018) 2026-04-26 07:24:07 -05:00
J. Nick Koston 8950afc3c4 [bluetooth_proxy] Drop redundant remote_bda_ write in connect handler (#16000) 2026-04-26 07:23:53 -05:00
J. Nick Koston 04d067196d [rotary_encoder][at581x] Fix templatable int field types (#16015) 2026-04-26 07:23:41 -05:00
J. Nick Koston 502c010465 [bh1750] Downgrade per-reading Illuminance log to verbose (#16005) 2026-04-26 07:23:24 -05:00
J. Nick Koston 180105bb4b [bluetooth_proxy] Partial revert of loop() → set_interval migration (#15992) 2026-04-26 07:23:08 -05:00
J. Nick Koston 4c0dfb0e0d [core] Raise ESP32 WDT feed interval to 1/5 of configured timeout (#15984) 2026-04-26 07:22:50 -05:00
J. Nick Koston df987a7ffb [ci-custom] Suggest uint32_to_str/int8_to_str for integer formatting (#15970) 2026-04-26 07:22:34 -05:00
Boris Krivonog c8d4420408 [mitsubishi_cn105] add support for half-degree temperature setpoint (#15919) 2026-04-26 07:19:49 -05:00
Darafei Praliaskouski b084fa4490 [esp32] Make ESP-IDF builds reproducible (#16008)
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-04-26 06:31:32 -05:00
Darafei Praliaskouski 68625a1b76 [core] Isolate generated build metadata (#16007)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-04-26 09:11:09 +00:00
J. Nick Koston dc57969afd [host] Use integer math in millis()/micros() (#15994) 2026-04-26 08:39:24 +00:00
J. Nick Koston f092e619d8 [rtttl] Gate on_finished_playback callback storage behind define (#16003) 2026-04-26 00:03:59 -05:00
J. Nick Koston 58f6ad2d0c [safe_mode] Use StaticCallbackManager for on_safe_mode (#16002) 2026-04-26 00:01:21 -05:00
Keith Burzinski bc33260c61 [ir_rf_proxy] Extend for RF (#15744)
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-04-25 22:33:02 -05:00
J. Nick Koston 4cab262ef8 [ci] Trigger CodSpeed benchmarks on host platform changes (#15995) 2026-04-25 17:18:21 -04:00
dependabot[bot] 9ad820c921 Bump esphome-dashboard from 20260408.1 to 20260425.0 (#16006)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-25 20:59:01 +00:00
J. Nick Koston 4f8feb86f0 [dashboard] Add --no-states support to logs WebSocket handler (#15993) 2026-04-25 15:43:05 -05:00
Javier Peletier b5ccd55f4e [packages] Fix premature substitution of vars in remote package files (#15997)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-25 17:06:58 +00:00
dependabot[bot] a437b3086b Bump cryptography from 46.0.7 to 47.0.0 (#15990)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-25 02:30:10 +00:00
dependabot[bot] c27f9e512b Bump aioesphomeapi from 44.21.0 to 44.22.0 (#15989)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-25 02:28:04 +00:00
dependabot[bot] f62972c2c6 Bump ruff from 0.15.11 to 0.15.12 (#15981)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-04-24 19:34:00 +00:00
dependabot[bot] f36efbc762 Update tzdata requirement from >=2026.1 to >=2026.2 (#15980)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-24 19:27:12 +00:00
Kevin Ahrendt 9caf9ee023 [sendspin] Bumps sendspin-cpp library for a bugfix (#15976) 2026-04-24 11:53:03 -05:00
Kevin Ahrendt 94e300389c [sendspin] remove year and track number text sensors and refactor (#15975) 2026-04-24 15:35:32 +00:00
Kevin Ahrendt 55bcf33446 [sendspin] Add metadata sensor component (#15971) 2026-04-24 14:32:47 +00:00
Kevin Ahrendt f132b7dc07 [media_player][speaker][speaker_source] Centralize preferred format codegen (#14771) 2026-04-24 14:09:03 +00:00
J. Nick Koston baa6d5f96b [web_server_idf] Fix cross-thread race on SSE session state (#15967) 2026-04-24 08:11:47 -05:00
J. Nick Koston 773b4d887b [core] Scheduler: don't sleep while defer queue is non-empty (#15968) 2026-04-24 08:11:29 -05:00
Kevin Ahrendt ac7f0f0b74 [sendspin] Add a metadata text sensor component (#15969) 2026-04-24 11:07:00 +00:00
Kevin Ahrendt bc7f35b569 [sendspin] Add a Sendspin media source component for playing audio (PR4) (#15950)
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-04-24 10:00:22 +00:00
J. Nick Koston ae02ab3865 [wifi] Fix stale wifi.connected after state transition (#15966) 2026-04-24 03:42:36 -05:00
J. Nick Koston eceb534895 [deep_sleep] Fix sleep_duration codegen type to uint32_t (#15965) 2026-04-24 07:19:59 +00:00
tomaszduda23 404620b99c [deep_sleep][logger][zephyr][zigbee] add deep sleep support with zigbee wakeup (#13950)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-23 22:31:46 -04:00
Kevin Ahrendt 3ccaa771a7 [sendspin] Add a group media player controller (PR3) (#15948)
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-04-24 01:46:25 +00:00
Kevin Ahrendt b4a86e46b2 [sendspin] Add controller role and sendspin.switch action (PR2) (#15929)
Co-authored-by: Copilot <copilot@github.com>
2026-04-23 20:22:47 -05:00
Kevin Ahrendt ddf1426f86 [sendspin] Add initial Sendspin hub component (PR1) (#15924)
Co-authored-by: Copilot <copilot@github.com>
2026-04-23 22:09:36 +00:00
J. Nick Koston 90d7bfe02e [ci] Auto-close PRs opened from a fork's default branch (#15957) 2026-04-23 16:36:32 -05:00
Kevin Ahrendt d759f1a567 [audio_http] Add a media source for playing audio from HTTP URLs (#15741)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-23 15:53:52 -05:00
luar123 f757cd1210 [zigbee][core] Add support for Zigbee binary sensors on ESP32 H2 and C6 (#11553)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-23 12:46:56 -04:00
Paulus Schoutsen 9b45b046a8 [core] Allow finding all devices as target that match mac suffix (#13135) 2026-04-23 08:43:32 -05:00
J. Nick Koston 70ae614abd [api] Fall back to plaintext for logger connections (#15938) 2026-04-23 08:23:38 -05:00
J. Nick Koston 8f9b91eece [wifi] Avoid BDK 3.0.78 wifi_event_sta_disconnected_t collision on BK72xx (#15942) 2026-04-23 08:22:17 -05:00
J. Nick Koston 3ca86fc3fc [core] Raise WDT_FEED_INTERVAL_MS to 2000ms on BK72xx (#15943) 2026-04-23 08:21:46 -05:00
J. Nick Koston b38db617a2 [core] Clean up stale includes and inline yield_with_select_ in application (#15945) 2026-04-23 08:21:05 -05:00
J. Nick Koston 13fe881f70 [scheduler][core] Lock-free fast-path on ESPHOME_THREAD_MULTI_NO_ATOMICS via __atomic builtins (#15947) 2026-04-23 08:20:31 -05:00
J. Nick Koston 50c181671c [ci] Better explain too-big bot review message (#15939) 2026-04-23 06:47:16 -05:00
PolarGoose 43a371caab [dsmr] Small refactoring: Move Aes128GcmDecryptorImpl type inside esphome::dsmr namespace. (#15940) 2026-04-23 04:08:49 -05:00
dependabot[bot] 64290d32a1 Bump aioesphomeapi from 44.20.0 to 44.21.0 (#15941)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-23 03:32:12 -05:00
J. Nick Koston 9685d4eb0b [core] feed_wdt wraps feed_wdt_with_time (#15932) 2026-04-23 01:15:44 -05:00
Keith Burzinski 4c2efd4165 [radio_frequency] Add experimental radio_frequency entity type (base component + API) (#15556) 2026-04-23 01:15:25 -05:00
J. Nick Koston 6f00ea1457 [core] Move host socket-select wake mechanism into wake.h/wake.cpp (#15931) 2026-04-23 15:53:10 +12:00
Jonathan Swoboda a881121110 [ota] Make set_auth_password() lambda-callable via empty-password opt-in (#15928) 2026-04-22 23:06:31 -04:00
dependabot[bot] f8167c9a70 Bump aioesphomeapi from 44.19.0 to 44.20.0 (#15936)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-23 02:40:19 +00:00
Jesse Hills e1d629f0d2 [time] Handle Windows EINVAL when validating POSIX TZ strings (#15934) 2026-04-23 14:35:13 +12:00
Clyde Stubbs 224cc7b419 [lvgl] Triggers on tabview tabs fix (#15935) 2026-04-23 14:35:00 +12:00
Jesse Hills 4d4347d33a Merge branch 'release' into dev 2026-04-23 14:10:54 +12:00
dependabot[bot] 17f9269841 Update wheel requirement from <0.47,>=0.43 to >=0.43,<0.48 (#15926)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-22 19:12:15 -05:00
dependabot[bot] 6253947311 Bump click from 8.3.2 to 8.3.3 (#15927)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-22 19:12:02 -05:00
Keith Burzinski 70b1d9a087 [api_protobuf] Support compound ifdef conditions in proto generator (#15930) 2026-04-22 17:57:15 -05:00
Keith Burzinski 36720c8495 [usb_uart] Derive TX output chunk count from buffer_size config (#15909) 2026-04-23 09:16:14 +12:00
Jonathan Swoboda c48ab2ef92 [io_expanders] Self-heal interrupt-driven expanders when INT stays asserted across the read (#15923) 2026-04-23 09:05:15 +12:00
Keith Burzinski 162ee2ecaf [i2s_audio] Split speaker into base class and standard subclass (#15404) 2026-04-22 14:40:18 -05:00
Asela Fernando a73bac0b5f [ac_dimmer] Zero-crossing interrupt type (#15862)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-04-22 14:57:53 -04:00
Rishab Mehta 4e84611ae7 [internal_temperature] Fix internal Temperature discrepancy on BK7231T (#15771)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-04-22 17:50:59 +00:00
PolarGoose ea2e36e55a [dsmr] Improve performance. Add missing sensors. Remove Crypto-no-arduino. (#15875) 2026-04-22 13:49:14 -04:00
Michael Turner fcbc4d64fe [one_wire] Reset bus before SKIP ROM command (#14669)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2026-04-22 13:20:02 -04:00
Timothy dcd103cec0 [cse7761] bidirectional active power (#15162)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-04-22 13:11:18 -04:00
Ludovic BOUÉ 5e715692d6 [network] Reorder IPv6 configuration for network components (#11694)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-04-22 17:01:20 +00:00
rwrozelle d5263cd46e [esp32] add watchdog_timeout configuration variable (#15908)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-04-22 13:01:23 +00:00
J. Nick Koston c399cd2fa2 [core] RAII guard for component loop phase (#15897) 2026-04-22 14:04:29 +02:00
J. Nick Koston f6bf6dc8e5 [core] Dedupe yield() fast path in wakeable_delay and always-inline (#15915) 2026-04-22 13:52:40 +02:00
J. Nick Koston e35b435f02 [libretiny] Inline xTaskGetTickCount() for millis() fast path (#15918) 2026-04-22 13:52:27 +02:00
J. Nick Koston 886cd7ab72 [core] Collapse adjacent USE_HOST ifdef blocks in Application (#15914) 2026-04-22 07:47:01 -04:00
dependabot[bot] 73714dc489 Bump aioesphomeapi from 44.18.0 to 44.19.0 (#15920)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-22 12:26:25 +02:00
dependabot[bot] 5218bbd791 Update argcomplete requirement from >=2.0.0 to >=3.6.3 (#15921)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-22 12:19:47 +02:00
J. Nick Koston 23ad30cb4c [esp32] Use xTaskGetTickCount() for millis() when tick rate is 1kHz (#15661) 2026-04-22 06:44:53 +02:00
J. Nick Koston a3b49d1ed9 [core] Use MAC_ADDRESS_BUFFER_SIZE constant instead of duplicated literal (#15913) 2026-04-22 04:43:33 +00:00
J. Nick Koston 9c80cbf19c [light] Reduce validate_ clamp code size and speed up unit-range clamps (#15728) 2026-04-22 16:34:26 +12:00
J. Nick Koston 699cf9690a [core] Optimize value_accuracy_to_buf to avoid snprintf (#15596) 2026-04-22 16:31:34 +12:00
J. Nick Koston 67576d4879 [rp2040] Tune oversized lwIP defaults for ESPHome (#14843) 2026-04-22 06:29:13 +02:00
J. Nick Koston edcf96d057 [wifi] Use queue abstraction for LibreTiny WiFi events (#15343) 2026-04-22 06:24:09 +02:00
dependabot[bot] bb81c91d0c Update tzdata requirement from >=2021.1 to >=2026.1 (#15911)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-22 03:08:58 +00:00
dependabot[bot] 78f1467be4 Bump aioesphomeapi from 44.17.0 to 44.18.0 (#15912)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-22 03:08:42 +00:00
dependabot[bot] da44d43981 Update pyparsing requirement from >=3.0 to >=3.3.2 (#15910)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-22 05:07:48 +02:00
Javier Peletier 9cebce1b6e [substitutions] Improve error messages with include stack trace (#15874)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-04-22 03:19:01 +02:00
Jesse Hills b20fedd806 [bl0906] Disable loop when idle and introduce BL0906Stage enum (#15884)
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-04-22 03:18:21 +02:00
Keith Burzinski ee91ad8f06 [esp32] Add Secure Boot V1 ECDSA signing scheme for pre-rev-3.0 ESP32 (#15882) 2026-04-22 11:25:05 +12:00
dependabot[bot] 7560112144 Bump aioesphomeapi from 44.16.1 to 44.17.0 (#15906)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-21 22:08:41 +02:00
Geoff 43c6b839cd [sensor] Filter to round to significant digits (#11157)
Co-authored-by: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2026-04-21 14:00:03 +00:00
Edward Firmo 0c9d443a5c [esp32_ble] Add use_psram option to offload BT memory allocation to SPIRAM (#15644) 2026-04-21 15:18:46 +02:00
J. Nick Koston 14defb69b6 [template] Use placement new for template text restore saver (#15883) 2026-04-21 13:04:13 +00:00
Egor Vorontsov 3a6f3dfb94 [lock] Implemented open states support (#15120)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-04-21 13:03:07 +00:00
J. Nick Koston 7bd36e0c8d [debug] Migrate trivial buf_append_printf sites to buf_append_str (#15885) 2026-04-21 12:51:45 +00:00
J. Nick Koston e4f413adad [core] decouple main loop cadence from scheduler wake timing (#15792) 2026-04-21 14:48:21 +02:00
J. Nick Koston 1504ac3d19 [core] Replace strnlen in buf_append_str for Zephyr compatibility (#15892) 2026-04-21 12:32:29 +00:00
J. Nick Koston 947c714f89 [core] Inline api_is_connected() for hot-path callers (#15888) 2026-04-21 13:48:33 +02:00
J. Nick Koston e4d5886383 [zwave_proxy] Inline loop() hot-path fast-paths for response_handler_ and process_uart_ (#15887) 2026-04-21 13:48:16 +02:00
J. Nick Koston f504099485 [api] Replace clients_ std::vector with compile-time std::array + uint8_t count (#15889) 2026-04-21 13:47:37 +02:00
Jonathan Swoboda cb56f9a9bf [qmc5883l] Use GPIO interrupt when DRDY pin is configured (#15876) 2026-04-21 07:47:16 -04:00
Jonathan Swoboda 26a656af29 [ld2412] Fix null deref in set_basic_config when entities unconfigured (#15893) 2026-04-21 07:47:07 -04:00
dependabot[bot] a8bd035b62 Bump CodSpeedHQ/action from 4.13.1 to 4.14.0 (#15880)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-21 04:44:25 +02:00
J. Nick Koston f05fa45747 [sensor] Specialize throttle_with_priority NaN-only case (#15823) 2026-04-21 04:41:13 +02:00
J. Nick Koston 78875abee4 [core] Make buf_append_str PROGMEM-aware on ESP8266 (#15738)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-21 04:40:40 +02:00
J. Nick Koston 37608c2656 [ltr390] Reduce data polling delay and timeout (#15507) 2026-04-21 04:40:24 +02:00
J. Nick Koston a5b1f3eece [core] Remove pre-sleep socket scan from fast select path (#15639) 2026-04-21 04:40:03 +02:00
J. Nick Koston 0d3a3552da [core] Move heap-allocating helpers to alloc_helpers.h/cpp (#15623) 2026-04-21 04:39:49 +02:00
J. Nick Koston 0a0176d600 [core] raise WDT_FEED_INTERVAL_MS from 3 ms to 300 ms (#15846) 2026-04-21 04:38:12 +02:00
J. Nick Koston 4cb7ea2584 [light] Force-inline LightCall::set_flag_/clear_flag_ (#15729) 2026-04-21 04:37:56 +02:00
Jonathan Swoboda a43ee15b56 [core] Fix Pvariable placement new losing subclass identity (#15881) 2026-04-20 22:33:48 -04:00
Jonathan Swoboda 213ab312d2 [image] Fix rodata bloat for multi-frame RGB565+alpha animations (#15873) 2026-04-20 16:27:34 -04:00
Kevin Ahrendt 94f30d5950 [micro_wake_word] Use ESPMicroSpeechFeatures from Espressif registry (v1.2.3) (#15879) 2026-04-20 16:26:47 -04:00
Elvin Luff 6af341bb5b [epaper_spi] Support SSD1683 and GDEY042T81 4.2 inch display (#13910) 2026-04-20 09:34:31 -04:00
Clyde Stubbs 82656cb0cf [mipi_dsi] Add Seeed reTerminal d1001 display (#15867) 2026-04-20 09:28:52 -04:00
Rui Marinho b72f5447c3 [modbus] Simplify payload size validation in modbus_helpers (#15838) 2026-04-20 09:24:07 -04:00
Clyde Stubbs 73b8e8ac09 [lvgl] Fix update of textarea attached to keyboard (#15866) 2026-04-20 09:15:51 -04:00
Clyde Stubbs 9459f0426d [lvgl] Fix overloads for setting images on styles (#15864) 2026-04-20 09:14:15 -04:00
Clyde Stubbs 0dae41aa22 [lvgl] Fix format of hello world page (#15868) 2026-04-20 09:13:42 -04:00
Thomas Rupprecht 7321e6e52f [rtttl] allow any control parameters order and default value fallback (#14438)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-04-20 09:10:05 -04:00
guillempages f0c21520aa [mipi_rgb] Add definitions for sunton displays (#15858) 2026-04-20 21:56:56 +10:00
Jesse Hills b0c133201f Merge branch 'release' into dev 2026-04-20 13:53:30 +12:00
Clyde Stubbs e5f6a734ba [lvgl] Fix angles for arc (#15860) 2026-04-20 12:08:07 +12:00
J. Nick Koston 1847666e75 [core] Default PollingComponent() to not run when codegen is bypassed (#15832) 2026-04-19 17:05:27 -05:00
Javier Peletier aad1318b4a [packages] Improve error messages with include stack and fix missing path propagation (#15844)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2026-04-19 21:09:14 +00:00
J. Nick Koston 7a23a339e9 [substitutions] Fix substitutions: !include file.yaml regression (#15850) 2026-04-20 09:00:31 +12:00
J. Nick Koston 38d894dfe7 [ld2412] Fix flaky integration test race condition (#15833) 2026-04-18 08:17:22 -05:00
J. Nick Koston b293be23b0 [ci] Honor CONFLICTS_WITH when grouping component tests (#15834)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-04-18 08:11:38 -05:00
J. Nick Koston ccb53e34ca [core] Default PollingComponent() to 1ms when codegen is bypassed (#15831) 2026-04-18 09:04:51 -04:00
dependabot[bot] ec9d59f3dc Bump aioesphomeapi from 44.16.0 to 44.16.1 (#15836)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-18 12:32:36 +00:00
J. Nick Koston df72aa26c0 [core] Feed WDT unconditionally in main loop to fix empty-config panic (#15830) 2026-04-18 11:58:54 +00:00
Clyde Stubbs d3691c7ca5 [lvgl] Fix crash with snow on rotated display (#15822) 2026-04-18 09:17:28 +10:00
J. Nick Koston 562ce541a0 [bme680_bsec] [bme68x_bsec2] Mark the two BSEC variants as mutually exclusive (#15826) 2026-04-17 17:54:24 -05:00
J. Nick Koston 6ebe1e92eb [ci] Scope local pylint pre-commit hook to esphome/ (#15818) 2026-04-17 17:54:12 -05:00
Clyde Stubbs 1bf455cfbb [runtime_image] Fix RGB order (#15813) 2026-04-18 06:42:45 +10:00
Clyde Stubbs 290e213cd0 [mipi_spi] Add Sunton ESP32-2424S012 (#15812) 2026-04-18 06:41:33 +10:00
Jonathan Swoboda b1b0005574 [esp32] Downgrade unneeded ignore_pin_validation_error to a warning (#15811) 2026-04-17 16:14:54 -04:00
dependabot[bot] 70ea527161 Bump ruff from 0.15.10 to 0.15.11 (#15790)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-04-17 10:17:51 -05:00
J. Nick Koston 34c35c84d5 [core] Fix DelayAction compile error with non-const reference args (#15814) 2026-04-17 14:31:31 +00:00
Jonathan Swoboda bcbfc843ae [ethernet] Fix SPI3_HOST default breaking compile on variants without SPI3 (#15809)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-04-17 14:05:30 +00:00
J. Nick Koston d4fe46bb24 [core] Expose App.wake_loop_isrsafe() on ESP8266 (#15797) 2026-04-17 02:46:12 -10:00
J. Nick Koston 523c6f2376 [core] coerce set_interval(0) / update_interval: 0ms to 1ms (#15799) 2026-04-17 02:45:50 -10:00
Clyde Stubbs b018ac67bc [image] Fix byte order handling (#15800) 2026-04-17 22:11:05 +10:00
Clyde Stubbs 1a529a62aa [mipi_spi] Drawing fixes for native display (#15802) 2026-04-17 21:17:16 +10:00
Edvard Filistovič 6a46437a5f [wifi] Guard retry_phase_to_log_string with log level check to fix warning (#15801)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-04-17 10:58:39 +00:00
Diorcet Yann cfe8c0eeee [wireguard] Bump esp_wireguard to 0.4.5 for ESP-IDF v6 (#15804) 2026-04-17 06:20:55 -04:00
J. Nick Koston b232fc91ab [runtime_stats] Track main loop active time and report overhead (#15743) 2026-04-16 14:07:26 -10:00
Yves Fischer ac50f33388 Fix typo in devcontainer.json (#15791) 2026-04-16 18:27:50 -04:00
Jonathan Swoboda ff52bb3029 [lvgl] Guard lv_image_set_src wrapper with LV_USE_IMAGE (#15789) 2026-04-16 18:16:58 -04:00
J. Nick Koston 627e440bd6 [libretiny] Make IRAM_ATTR functional on RTL87xx and LN882H (#15766) 2026-04-16 19:38:49 +00:00
Jonathan Swoboda 6bb90a1268 [esp32] Accept unquoted minimum_chip_revision values (#15785) 2026-04-16 19:07:04 +00:00
J. Nick Koston 7d8add70a7 [ili9xxx] Guard against null buffer in display_() when allocation fails (#15786) 2026-04-16 09:01:55 -10:00
rwalker777 9094392870 [gpio] Keep interrupts enabled for gpio binary_sensor shared with deep_sleep wakeup pin (#15020)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-04-16 09:01:32 -10:00
J. Nick Koston c6ad23fbc0 [bundle] Force-resolve nested IncludeFile during file discovery (#15762) 2026-04-16 08:45:33 -10:00
Jonathan Swoboda 6af7a9ed8f [qmc5883l] Move per-update log line from DEBUG to VERBOSE (#15781) 2026-04-16 14:36:06 -04:00
SaVi 0b051289f5 [core] Add missing exception chaining (raise from) across codebase (#15648)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-04-16 15:19:33 +00:00
Clyde Stubbs d8329dba22 [mipi_spi] Add Waveshare C6 LCD 1.47 (#15776) 2026-04-16 11:17:51 -04:00
guillempages ee70a4aa72 [tm1637] Add set_brightness method (#15322)
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-04-16 09:46:27 -04:00
tomaszduda23 04a58159d0 [zephyr_ble_server] add support for on_numeric_comparison_request (#14400)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-04-16 09:43:03 -04:00
J. Nick Koston 4c758fa1da [time] Fix RTC is_valid() rejecting valid times after day_of_year cleanup (#15763) 2026-04-16 09:40:22 -04:00
J. Nick Koston c8e21802db [core] Diagnose missing cg.templatable in codegen for TEMPLATABLE_VALUE fields (#15758) 2026-04-16 09:36:55 -04:00
Boris Krivonog b40ffacb8d [mitsubishi_cn105] use HEAT_COOL mode to enable temperature slider (#15748) 2026-04-16 09:35:24 -04:00
Clyde Stubbs e0118dd8eb [lvgl] Clean the build if lv_conf.h changes (#15777) 2026-04-16 09:19:42 -04:00
J. Nick Koston e7194dce75 [core] Deduplicate entity type boilerplate with X-macro pattern (#15618) 2026-04-15 17:45:01 -10:00
J. Nick Koston 01b5bef37f [status_led] Disable loop when idle (#15642) 2026-04-15 17:44:42 -10:00
dependabot[bot] 403a9f7b7e Bump github/codeql-action from 4.35.1 to 4.35.2 (#15759)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-15 10:12:30 -10:00
dependabot[bot] 10f52f2056 Bump aioesphomeapi from 44.15.0 to 44.16.0 (#15757)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-15 09:07:49 -10:00
Jonathan Swoboda 274c01ca74 [sx126x][sx127x] Fix frequency precision loss from float32 codegen (#15753) 2026-04-15 14:32:33 -04:00
Jonathan Swoboda 3b82c6e38b [st7789v] Fix swapped offset_width/offset_height in model presets (#15755) 2026-04-15 14:32:11 -04:00
Jesse Hills f59a1011df Merge branch 'release' into dev 2026-04-15 22:45:16 +12:00
Jesse Hills 193e7d476d Pin GitHub Actions to commit SHAs
Replace mutable tag references with immutable commit SHAs
to prevent supply-chain attacks via compromised tags.
Version comments are preserved for readability.
2026-04-15 13:12:20 +12:00
Jesse Hills 1b3e7d5ec4 Merge branch 'beta' into dev 2026-04-15 13:10:45 +12:00
Edward Firmo 2db2b89eb1 [nextion] Fix command spacing pacer never throttling sends (#15664)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2026-04-15 07:47:44 +12:00
J. Nick Koston e48c7165c5 [light] Avoid addressable transition stall at low gamma-corrected values (#15726) 2026-04-15 07:45:42 +12:00
J. Nick Koston 506edaadd5 [core] Inline feed_wdt hot path with out-of-line slow path (#15656)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 19:08:30 +00:00
J. Nick Koston 3f82a3a519 [core] Inline Millis64Impl::compute() on single-threaded platforms (#15684)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-04-14 08:20:31 -10:00
J. Nick Koston 79cee864cb [esphome][ota] Disable loop while idle, wake on listening-socket activity (#15636) 2026-04-14 08:20:14 -10:00
Alexey Spirkov 9f5ed938e5 [i2s_audio] Add PDM mics support for ESP32-P4 (#15333)
Co-authored-by: Alexey Spirkov <dev@alsp.net>
2026-04-14 14:07:16 -04:00
J. Nick Koston 4729efbd04 [light] Deduplicate color_uncorrect channel math via shared helper (#15727) 2026-04-14 07:50:28 -10:00
J. Nick Koston da9fbb8044 [core] Fix app_state_ status bits clobbered for non-looping components (#15658) 2026-04-14 07:50:11 -10:00
J. Nick Koston cf01163c8c [core] Add uint32_to_str helper and use in preferences (#15597) 2026-04-14 07:49:44 -10:00
J. Nick Koston 5ba8c644e4 [ld24xx] Replace heap-allocated SensorWithDedup with inline SensorWithDedup (#15676) 2026-04-14 07:49:27 -10:00
Kevin Ahrendt c833ff4a84 [audio] Add/configure microDecoder library in preparation for use in future PRs (#15679)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 13:49:18 -04:00
J. Nick Koston 2a530a4bf4 [core] Optimize format_hex_internal by splitting separator loop (#15594) 2026-04-14 07:48:33 -10:00
J. Nick Koston 6b4b653462 [globals] Fix TemplatableFn deprecation warning for globals.set (#15733) 2026-04-14 09:18:38 -04:00
J. Nick Koston edb16a27d3 [esphome] Skip missing extra flash images in upload_using_esptool (#15723)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-04-13 16:58:48 -10:00
J. Nick Koston 21df5d9bf6 [web_server] Reset OTA backend on new upload to avoid brick after interrupted OTA (#15720) 2026-04-13 13:59:45 -10:00
J. Nick Koston 73c972a604 [adc] Place ADC oneshot control functions in IRAM for cache safety (#15717) 2026-04-13 13:59:32 -10:00
Jonathan Swoboda 8cdffef82a [heatpumpir] Bump tonia/HeatpumpIR to 1.0.41 (#15711) 2026-04-13 17:06:56 -04:00
dependabot[bot] 4034809281 Bump actions/create-github-app-token from 3.0.0 to 3.1.1 (#15712)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 11:00:46 -10:00
dependabot[bot] ce6bffb65c Bump actions/cache from 5.0.4 to 5.0.5 (#15713)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 11:00:24 -10:00
dependabot[bot] e8bc4bedb4 Bump actions/cache from 5.0.4 to 5.0.5 in /.github/actions/restore-python (#15714)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 11:00:11 -10:00
J. Nick Koston b85a7ef317 [scheduler] Force-inline process_to_add() fast path (#15685) 2026-04-13 08:40:58 -10:00
J. Nick Koston 9f7e310526 [scheduler] Force-inline cleanup_() fast path (#15683) 2026-04-13 08:40:39 -10:00
J. Nick Koston af7cb1d81e [scheduler] Force-inline process_defer_queue_() fast path (#15686) 2026-04-13 08:40:25 -10:00
J. Nick Koston 53ce2a2f7f [api] Add speed_optimized to SubscribeLogsResponse (#15698)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2026-04-14 06:25:05 +12:00
Jonathan Swoboda fb0283e0ee [esp32] Update the recommended platform to 55.03.38-1 (#15705) 2026-04-13 14:18:52 -04:00
Jonathan Swoboda 5d0cfc31fa [core] Move FILTER_PLATFORMIO_LINES into platformio_runner (#15707) 2026-04-13 14:18:44 -04:00
J. Nick Koston f30f0a0edc [zephyr] Remove redundant yield() from main loop (#15694) 2026-04-13 09:43:17 -04:00
Kevin Ahrendt 6aa538a61d [micro_wake_word] Bugfix: Use es-nn v1.1.2 (last known working version) (#15703) 2026-04-13 09:42:02 -04:00
Diorcet Yann 7918a93a7f [esp32] Fix some compiler warnings & bugs (#15610)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2026-04-13 09:40:49 -04:00
Diorcet Yann fe6ecb24b4 [bme68x_bsec2] use esphome-libs wrappers for ESP32 (#15697) 2026-04-13 07:49:13 -04:00
dependabot[bot] 6db787d5e4 Bump aioesphomeapi from 44.14.0 to 44.15.0 (#15699)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 08:12:57 +00:00
J. Nick Koston 5b4385a084 [api] Add speed_optimized proto option for hot encode paths (#15691)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2026-04-13 07:42:31 +00:00
J. Nick Koston 4f69c3b850 [benchmark] Add SubscribeLogsResponse encode benchmarks (#15696) 2026-04-13 02:03:53 -05:00
J. Nick Koston c62a75ee17 [benchmark] Use -Os to match firmware optimization level (#15688) 2026-04-13 01:40:33 -05:00
dependabot[bot] d4e9c62d92 Bump aioesphomeapi from 44.13.3 to 44.14.0 (#15695)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 06:23:49 +00:00
Jonathan Swoboda ac8a2467a5 [core] Fix PlatformIO progress bar rendering in subprocess mode (#15681) 2026-04-12 22:51:55 -04:00
Jesse Hills dc1dd9ebb7 Merge branch 'beta' into dev 2026-04-13 12:45:02 +12:00
schrob 41c9ed28cd [esp32] Use static stack memory for loop task instead of heap (#15659)
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-04-12 23:23:01 +00:00
Jesse Hills 5608aa10a5 [CI] Don't run label workflow on closed/merged PRs (#15678) 2026-04-12 12:46:49 -10:00
Javier Peletier daa68a2a60 [packages] fix support packages: !include mypackages.yaml (#15677) 2026-04-13 09:48:30 +12:00
Clyde Stubbs 8754bbfa89 [lvgl] Fix use of rotation on host SDL (#15611)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2026-04-12 20:29:11 +00:00
J. Nick Koston 6d92cc3d2b [packages] Fix false deprecation warning and wrong error paths in nested packages (#15605) 2026-04-13 08:24:23 +12:00
Jonathan Swoboda 2f684bf4f3 [esp32] Bump platform to 55.03.38, Arduino to 3.3.8, ESP-IDF to 5.5.4 (#15666) 2026-04-12 10:07:04 -10:00
Jonathan Swoboda 45af21bf38 [canbus] Fix canbus.send can_id compile error (#15668) 2026-04-12 09:58:51 -10:00
Jonathan Swoboda e6318a2d16 [mdns] Bump espressif/mdns to 1.11.0 (#15670) 2026-04-12 09:54:30 -10:00
Jonathan Swoboda bef4c8a86c [cc1101] Extract chip configuration into configure() method (#15635) 2026-04-11 17:36:27 -04:00
Farmer-shin 6e67864510 [epaper_spi] Add Waveshare 3.97inch E-Paper Display (#15466) 2026-04-11 21:27:25 +10:00
dependabot[bot] c2af4874f9 Bump aioesphomeapi from 44.13.2 to 44.13.3 (#15641)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-11 08:58:20 +00:00
dependabot[bot] 2001b91280 Bump resvg-py from 0.3.0 to 0.3.1 (#15640)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-11 08:57:39 +00:00
dependabot[bot] 5460ee7edd Bump aioesphomeapi from 44.13.1 to 44.13.2 (#15637)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-10 15:55:15 -10:00
J. Nick Koston 40081e5ae7 [rp2040] Fix W5500 Ethernet pbuf corruption by mirroring LWIPMutex semantics (#15624)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-10 13:13:05 -10:00
Jonathan Swoboda a7c5b0ab46 [sx127x][cc1101][sx126x] Use GPIO interrupt to wake loop (#15627) 2026-04-10 16:26:09 -04:00
dependabot[bot] e1a813e11f Bump peter-evans/create-pull-request from 8.1.0 to 8.1.1 (#15630)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-10 10:21:01 -10:00
dependabot[bot] 1dfeef0265 Bump actions/github-script from 8.0.0 to 9.0.0 (#15632)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-10 10:20:43 -10:00
dependabot[bot] 395610c117 Bump docker/build-push-action from 7.0.0 to 7.1.0 in /.github/actions/build-image (#15633)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-10 10:20:17 -10:00
dependabot[bot] ae96f82b82 Bump actions/upload-artifact from 7.0.0 to 7.0.1 (#15631)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-10 10:20:04 -10:00
dependabot[bot] 2c610abcd0 Bump resvg-py from 0.2.6 to 0.3.0 (#15629)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-10 10:19:52 -10:00
Kevin Ahrendt d3591c8d9e [micro_wake_word] Pin esp-nn version (#15628) 2026-04-10 15:21:26 -04:00
J. Nick Koston ec420d5792 [api] Add (inline_encode) proto option for sub-message inlining (#15599) 2026-04-10 15:33:56 +12:00
J. Nick Koston 17209df7b5 [mcp23016] Add interrupt pin support (#15616) 2026-04-10 15:29:52 +12:00
J. Nick Koston 9cf9b02ba2 [pca6416a] Add interrupt pin support (#15614) 2026-04-10 15:29:26 +12:00
J. Nick Koston c90fa2378a [tca9555] Add interrupt pin support (#15613) 2026-04-10 15:29:00 +12:00
Jesse Hills c04dfa922e [hbridge] Move light pin switching to loop (#15615) 2026-04-10 14:02:49 +12:00
Jesse Hills 668007707d [CI] Add org fork detection warning to auto-label PR workflow (#15588) 2026-04-10 12:13:22 +12:00
dependabot[bot] ab71f5276f Bump ruff from 0.15.9 to 0.15.10 (#15609)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-04-09 19:36:25 +00:00
Jonathan Swoboda d062f62656 [sx127x][cc1101] Disable loop when packet mode is inactive (#15606) 2026-04-09 15:00:52 -04:00
J. Nick Koston 03db32d045 [core] Add CodSpeed benchmarks for hot helper functions (#15593) 2026-04-09 07:48:32 -10:00
J. Nick Koston 8f6d489a9a [ci] Use --base-only for memory impact builds (#15598) 2026-04-09 11:48:33 -04:00
J. Nick Koston dd07fba943 [socket] Document ready() contract: callers must drain or track (#15590) 2026-04-09 11:48:18 -04:00
J. Nick Koston 6f5d642a31 [gdk101] Increase reset retries for slow-booting sensor MCU (#15584) 2026-04-09 11:48:10 -04:00
dependabot[bot] 2721f08bcc Bump aioesphomeapi from 44.12.0 to 44.13.1 (#15600)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-09 10:03:58 +00:00
J. Nick Koston eafc5df3f2 [safe_mode] Combine related OTA rollback log messages (#15592) 2026-04-09 05:30:39 +00:00
J. Nick Koston 46d0c29be5 [safe_mode] Use loop component start time instead of millis() (#15591) 2026-04-09 05:20:32 +00:00
J. Nick Koston abdbbf4dd2 [api] Fix ListEntitiesRequest not read due to LWIP rcvevent tracking (#15589) 2026-04-09 02:14:01 +00:00
Jesse Hills 4dc0599a7d Merge branch 'beta' into dev 2026-04-09 13:41:27 +12:00
Jesse Hills 52c35ec09c Bump version to 2026.5.0-dev 2026-04-09 11:28:48 +12:00
J. Nick Koston 76490e45bc [ci] Fix status-check-labels workflow flooding CI queue (#15585) 2026-04-08 13:08:29 -10:00
Angel Nunez Mencias 0a8130858c [ade7953_spi] Fix SPI mode on esp-idf (#14824)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-04-08 22:57:53 +00:00
2364 changed files with 43868 additions and 16153 deletions
+29 -6
View File
@@ -5,24 +5,30 @@ Checks: >-
-altera-*,
-android-*,
-boost-*,
-bugprone-derived-method-shadowing-base-method,
-bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-invalid-enum-default-initialization,
-bugprone-multi-level-implicit-pointer-conversion,
-bugprone-narrowing-conversions,
-bugprone-tagged-union-member-count,
-bugprone-signed-char-misuse,
-bugprone-switch-missing-default-case,
-cert-dcl50-cpp,
-cert-err33-c,
-cert-err58-cpp,
-cert-int09-c,
-cert-oop57-cpp,
-cert-str34-c,
-clang-analyzer-optin.core.EnumCastOutOfRange,
-clang-analyzer-optin.cplusplus.UninitializedObject,
-clang-analyzer-osx.*,
-clang-analyzer-security.ArrayBound,
-clang-diagnostic-delete-abstract-non-virtual-dtor,
-clang-diagnostic-delete-non-abstract-non-virtual-dtor,
-clang-diagnostic-deprecated-declarations,
-clang-diagnostic-ignored-optimization-argument,
-clang-diagnostic-missing-designated-field-initializers,
-clang-diagnostic-missing-field-initializers,
-clang-diagnostic-shadow-field,
-clang-diagnostic-unused-const-variable,
@@ -42,6 +48,7 @@ Checks: >-
-cppcoreguidelines-owning-memory,
-cppcoreguidelines-prefer-member-initializer,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
-cppcoreguidelines-pro-bounds-avoid-unchecked-container-access,
-cppcoreguidelines-pro-bounds-constant-array-index,
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
-cppcoreguidelines-pro-type-const-cast,
@@ -54,12 +61,13 @@ Checks: >-
-cppcoreguidelines-rvalue-reference-param-not-moved,
-cppcoreguidelines-special-member-functions,
-cppcoreguidelines-use-default-member-init,
-cppcoreguidelines-use-enum-class,
-cppcoreguidelines-virtual-class-destructor,
-fuchsia-default-arguments-calls,
-fuchsia-default-arguments-declarations,
-fuchsia-multiple-inheritance,
-fuchsia-overloaded-operator,
-fuchsia-statically-constructed-objects,
-fuchsia-default-arguments-declarations,
-fuchsia-default-arguments-calls,
-google-build-using-namespace,
-google-explicit-constructor,
-google-readability-braces-around-statements,
@@ -71,49 +79,64 @@ Checks: >-
-llvm-else-after-return,
-llvm-header-guard,
-llvm-include-order,
-llvm-prefer-static-over-anonymous-namespace,
-llvm-qualified-auto,
-llvm-use-ranges,
-llvmlibc-*,
-misc-const-correctness,
-misc-include-cleaner,
-misc-multiple-inheritance,
-misc-no-recursion,
-misc-non-private-member-variables-in-classes,
-misc-override-with-different-visibility,
-misc-unused-parameters,
-misc-use-anonymous-namespace,
-misc-use-internal-linkage,
-modernize-avoid-bind,
-modernize-avoid-variadic-functions,
-modernize-avoid-c-arrays,
-modernize-concat-nested-namespaces,
-modernize-avoid-c-style-cast,
-modernize-macro-to-enum,
-modernize-return-braced-init-list,
-modernize-type-traits,
-modernize-use-auto,
-modernize-use-constraints,
-modernize-use-default-member-init,
-modernize-use-designated-initializers,
-modernize-use-equals-default,
-modernize-use-integer-sign-comparison,
-modernize-use-nodiscard,
-modernize-use-nullptr,
-modernize-use-nodiscard,
-modernize-use-nullptr,
-modernize-use-ranges,
-modernize-use-trailing-return-type,
-mpi-*,
-objc-*,
-performance-enum-size,
-portability-avoid-pragma-once,
-portability-template-virtual-member-function,
-readability-ambiguous-smartptr-reset-call,
-readability-avoid-nested-conditional-operator,
-readability-container-contains,
-readability-container-data-pointer,
-readability-convert-member-functions-to-static,
-readability-else-after-return,
-readability-enum-initial-value,
-readability-function-cognitive-complexity,
-readability-implicit-bool-conversion,
-readability-isolate-declaration,
-readability-magic-numbers,
-readability-make-member-function-const,
-readability-math-missing-parentheses,
-readability-named-parameter,
-readability-redundant-casting,
-readability-redundant-inline-specifier,
-readability-redundant-member-init,
-readability-redundant-string-init,
-readability-redundant-parentheses,
-readability-redundant-typename,
-readability-uppercase-literal-suffix,
-readability-use-anyofallof,
-readability-use-std-min-max,
-readability-use-concise-preprocessor-directives,
WarningsAsErrors: '*'
FormatStyle: google
CheckOptions:
+1 -1
View File
@@ -1 +1 @@
10c432ae818f9ed7fd4a0176a04467b1f2634363f5ec985045a6d72747f60b90
96c95feaa60831da5f43e3c6a7c7a3a237e17c5d12995a730dbc3884c8dcd11c
+1 -1
View File
@@ -12,7 +12,7 @@
"--privileged",
"-e",
"GIT_EDITOR=code --wait"
// uncomment and edit the path in order to pass though local USB serial to the conatiner
// uncomment and edit the path in order to pass through local USB serial to the container
// , "--device=/dev/ttyACM0"
],
"appPort": 6052,
+1 -1
View File
@@ -115,4 +115,4 @@ examples/
Dockerfile
.git/
tests/
.*
.?*
+2 -2
View File
@@ -47,7 +47,7 @@ runs:
- name: Build and push to ghcr by digest
id: build-ghcr
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
env:
DOCKER_BUILD_SUMMARY: false
DOCKER_BUILD_RECORD_UPLOAD: false
@@ -73,7 +73,7 @@ runs:
- name: Build and push to dockerhub by digest
id: build-dockerhub
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
env:
DOCKER_BUILD_SUMMARY: false
DOCKER_BUILD_RECORD_UPLOAD: false
+1 -1
View File
@@ -22,7 +22,7 @@ runs:
python-version: ${{ inputs.python-version }}
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: venv
# yamllint disable-line rule:line-length
@@ -4,6 +4,7 @@ module.exports = {
CODEOWNERS_MARKER: '<!-- codeowners-request -->',
TOO_BIG_MARKER: '<!-- too-big-request -->',
DEPRECATED_COMPONENT_MARKER: '<!-- deprecated-component-request -->',
ORG_FORK_MARKER: '<!-- maintainer-access-warning -->',
MANAGED_LABELS: [
'new-component',
+93 -31
View File
@@ -1,4 +1,3 @@
const fs = require('fs');
const { DOCS_PR_PATTERNS } = require('./constants');
const {
COMPONENT_REGEX,
@@ -9,6 +8,31 @@ const {
} = require('../detect-tags');
const { loadCodeowners, getEffectiveOwners } = require('../codeowners');
// Top-level `CONFIG_SCHEMA = ...` (assignment) or `CONFIG_SCHEMA: ConfigType = ...` (annotation).
// Ruff/Black enforce exactly one space around `=` and no space before `:`,
// so we can match strictly: `CONFIG_SCHEMA ` or `CONFIG_SCHEMA:`.
const CONFIG_SCHEMA_REGEX = /^CONFIG_SCHEMA[ :]/m;
// Fetch a file's contents from the PR head SHA via the GitHub API.
// The auto-label workflow runs on `pull_request_target`, which checks out the
// base branch — files added by the PR don't exist in the workspace, so we have
// to fetch them from the head SHA. Returns null if the file can't be fetched.
async function fetchPrFileContent(github, context, path) {
try {
const { owner, repo } = context.repo;
const { data } = await github.rest.repos.getContent({
owner,
repo,
path,
ref: context.payload.pull_request.head.sha,
});
return Buffer.from(data.content, 'base64').toString('utf8');
} catch (error) {
console.log(`Failed to fetch ${path} from PR head:`, error.message);
return null;
}
}
// Strategy: Merge branch detection
async function detectMergeBranch(context) {
const labels = new Set();
@@ -45,52 +69,64 @@ async function detectComponentPlatforms(changedFiles, apiData) {
}
// Strategy: New component detection
async function detectNewComponents(prFiles) {
async function detectNewComponents(github, context, prFiles) {
const labels = new Set();
let hasYamlLoadable = false;
const addedFiles = prFiles.filter(file => file.status === 'added').map(file => file.filename);
for (const file of addedFiles) {
const componentMatch = file.match(/^esphome\/components\/([^\/]+)\/__init__\.py$/);
if (componentMatch) {
try {
const content = fs.readFileSync(file, 'utf8');
if (content.includes('IS_TARGET_PLATFORM = True')) {
labels.add('new-target-platform');
}
} catch (error) {
console.log(`Failed to read content of ${file}:`, error.message);
}
labels.add('new-component');
if (!componentMatch) continue;
labels.add('new-component');
const content = await fetchPrFileContent(github, context, file);
if (content === null) {
// Safe default: assume YAML-loadable so needs-docs behaviour is unchanged on fetch failure
hasYamlLoadable = true;
continue;
}
if (content.includes('IS_TARGET_PLATFORM = True')) {
labels.add('new-target-platform');
}
if (CONFIG_SCHEMA_REGEX.test(content)) {
hasYamlLoadable = true;
}
}
return labels;
return { labels, hasYamlLoadable };
}
// Strategy: New platform detection
async function detectNewPlatforms(prFiles, apiData) {
async function detectNewPlatforms(github, context, prFiles, apiData) {
const labels = new Set();
let hasYamlLoadable = false;
const addedFiles = prFiles.filter(file => file.status === 'added').map(file => file.filename);
for (const file of addedFiles) {
const platformFileMatch = file.match(/^esphome\/components\/([^\/]+)\/([^\/]+)\.py$/);
if (platformFileMatch) {
const [, component, platform] = platformFileMatch;
if (apiData.platformComponents.includes(platform)) {
labels.add('new-platform');
}
}
const platformPathPatterns = [
/^esphome\/components\/([^\/]+)\/([^\/]+)\.py$/,
/^esphome\/components\/([^\/]+)\/([^\/]+)\/__init__\.py$/,
];
const platformDirMatch = file.match(/^esphome\/components\/([^\/]+)\/([^\/]+)\/__init__\.py$/);
if (platformDirMatch) {
const [, component, platform] = platformDirMatch;
if (apiData.platformComponents.includes(platform)) {
labels.add('new-platform');
for (const file of addedFiles) {
for (const re of platformPathPatterns) {
const match = file.match(re);
if (!match) continue;
const platform = match[2];
if (!apiData.platformComponents.includes(platform)) break;
labels.add('new-platform');
const content = await fetchPrFileContent(github, context, file);
if (content === null) {
// Safe default: assume YAML-loadable so needs-docs behaviour is unchanged on fetch failure
hasYamlLoadable = true;
} else if (CONFIG_SCHEMA_REGEX.test(content)) {
hasYamlLoadable = true;
}
break;
}
}
return labels;
return { labels, hasYamlLoadable };
}
// Strategy: Core files detection
@@ -281,8 +317,26 @@ async function detectDeprecatedComponents(github, context, changedFiles) {
return { labels, deprecatedInfo };
}
// Strategy: Detect when maintainers cannot modify the PR branch
function detectMaintainerAccess(context) {
const pr = context.payload.pull_request;
// Only relevant for cross-repo PRs (forks)
if (!pr.head.repo || pr.head.repo.full_name === pr.base.repo.full_name) {
return null;
}
if (pr.maintainer_can_modify) {
return null;
}
const isOrgFork = pr.head.repo.owner.type === 'Organization';
console.log(`Maintainer cannot modify PR branch (${isOrgFork ? 'org fork: ' + pr.head.repo.owner.login : 'user disabled'})`);
return { isOrgFork, orgName: pr.head.repo.owner.login };
}
// Strategy: Requirements detection
async function detectRequirements(allLabels, prFiles, context) {
async function detectRequirements(allLabels, prFiles, context, hasYamlLoadable) {
const labels = new Set();
// Check for missing tests
@@ -290,8 +344,15 @@ async function detectRequirements(allLabels, prFiles, context) {
labels.add('needs-tests');
}
// Check for missing docs
if (allLabels.has('new-component') || allLabels.has('new-platform') || allLabels.has('new-feature')) {
// Check for missing docs.
// `new-feature` (PR-body checkbox) always counts. `new-component` / `new-platform`
// only count when at least one newly added file defines a top-level CONFIG_SCHEMA,
// i.e. the new component/platform is actually loadable from YAML.
const docsEligible =
allLabels.has('new-feature') ||
((allLabels.has('new-component') || allLabels.has('new-platform')) && hasYamlLoadable);
if (docsEligible) {
const prBody = context.payload.pull_request.body || '';
const hasDocsLink = DOCS_PR_PATTERNS.some(pattern => pattern.test(prBody));
@@ -329,5 +390,6 @@ module.exports = {
detectTests,
detectPRTemplateCheckboxes,
detectDeprecatedComponents,
detectMaintainerAccess,
detectRequirements
};
+23 -10
View File
@@ -12,9 +12,10 @@ const {
detectTests,
detectPRTemplateCheckboxes,
detectDeprecatedComponents,
detectMaintainerAccess,
detectRequirements
} = require('./detectors');
const { handleReviews } = require('./reviews');
const { handleReviews, handleMaintainerAccessComment } = require('./reviews');
const { applyLabels, removeOldLabels } = require('./labels');
// Fetch API data
@@ -105,8 +106,8 @@ module.exports = async ({ github, context }) => {
const [
branchLabels,
componentLabels,
newComponentLabels,
newPlatformLabels,
newComponentResult,
newPlatformResult,
coreLabels,
sizeLabels,
dashboardLabels,
@@ -114,12 +115,13 @@ module.exports = async ({ github, context }) => {
codeOwnerLabels,
testLabels,
checkboxLabels,
deprecatedResult
deprecatedResult,
maintainerAccess
] = await Promise.all([
detectMergeBranch(context),
detectComponentPlatforms(changedFiles, apiData),
detectNewComponents(prFiles),
detectNewPlatforms(prFiles, apiData),
detectNewComponents(github, context, prFiles),
detectNewPlatforms(github, context, prFiles, apiData),
detectCoreChanges(changedFiles),
detectPRSize(prFiles, totalAdditions, totalDeletions, totalChanges, isMegaPR, SMALL_PR_THRESHOLD, MEDIUM_PR_THRESHOLD, TOO_BIG_THRESHOLD),
detectDashboardChanges(changedFiles),
@@ -127,9 +129,17 @@ module.exports = async ({ github, context }) => {
detectCodeOwner(github, context, changedFiles),
detectTests(changedFiles),
detectPRTemplateCheckboxes(context),
detectDeprecatedComponents(github, context, changedFiles)
detectDeprecatedComponents(github, context, changedFiles),
detectMaintainerAccess(context)
]);
// Extract new-component / new-platform results
const newComponentLabels = newComponentResult.labels;
const newPlatformLabels = newPlatformResult.labels;
// Eligible for needs-docs only if any newly added component or platform file
// defines a top-level CONFIG_SCHEMA (i.e. is actually loadable from YAML).
const hasYamlLoadable = newComponentResult.hasYamlLoadable || newPlatformResult.hasYamlLoadable;
// Extract deprecated component info
const deprecatedLabels = deprecatedResult.labels;
const deprecatedInfo = deprecatedResult.deprecatedInfo;
@@ -151,7 +161,7 @@ module.exports = async ({ github, context }) => {
]);
// Detect requirements based on all other labels
const requirementLabels = await detectRequirements(allLabels, prFiles, context);
const requirementLabels = await detectRequirements(allLabels, prFiles, context, hasYamlLoadable);
for (const label of requirementLabels) {
allLabels.add(label);
}
@@ -177,8 +187,11 @@ module.exports = async ({ github, context }) => {
console.log('Computed labels:', finalLabels.join(', '));
// Handle reviews
await handleReviews(github, context, finalLabels, originalLabelCount, deprecatedInfo, prFiles, totalAdditions, totalDeletions, MAX_LABELS, TOO_BIG_THRESHOLD);
// Handle reviews and org fork comment
await Promise.all([
handleReviews(github, context, finalLabels, originalLabelCount, deprecatedInfo, prFiles, totalAdditions, totalDeletions, MAX_LABELS, TOO_BIG_THRESHOLD),
handleMaintainerAccessComment(github, context, maintainerAccess)
]);
// Apply labels
await applyLabels(github, context, finalLabels);
+85 -7
View File
@@ -2,7 +2,8 @@ const {
BOT_COMMENT_MARKER,
CODEOWNERS_MARKER,
TOO_BIG_MARKER,
DEPRECATED_COMPONENT_MARKER
DEPRECATED_COMPONENT_MARKER,
ORG_FORK_MARKER
} = require('./constants');
// Generate review messages
@@ -40,16 +41,36 @@ function generateReviewMessages(finalLabels, originalLabelCount, deprecatedInfo,
let message = `${TOO_BIG_MARKER}\n### 📦 Pull Request Size\n\n`;
message +=
`Hey @${prAuthor}, thanks for the contribution! Just a heads up, ` +
`this PR is on the large side `;
if (tooManyLabels && tooManyChanges) {
message += `This PR is too large with ${nonTestChanges} line changes (excluding tests) and affects ${originalLabelCount} different components/areas.`;
message +=
`(${nonTestChanges} line changes excluding tests, across ` +
`${originalLabelCount} different components/areas)`;
} else if (tooManyLabels) {
message += `This PR affects ${originalLabelCount} different components/areas.`;
message +=
`(it touches ${originalLabelCount} different components/areas)`;
} else {
message += `This PR is too large with ${nonTestChanges} line changes (excluding tests).`;
message += `(${nonTestChanges} line changes excluding tests)`;
}
message += ` Please consider breaking it down into smaller, focused PRs to make review easier and reduce the risk of conflicts.\n\n`;
message += `For guidance on breaking down large PRs, see: https://developers.esphome.io/contributing/submitting-your-work/#how-to-approach-large-submissions`;
message += `, which makes it harder for maintainers to review.\n\n`;
message +=
`Smaller, focused PRs tend to be reviewed much faster since they ` +
`fit into the short gaps between other maintainer work; large ones ` +
`often have to wait for a rare long uninterrupted block of time. ` +
`If you can break this up into smaller pieces that can be reviewed ` +
`independently, it will almost certainly land faster overall.\n\n`;
message +=
`Before putting more time in, it's also worth popping into ` +
`\`#devs\` on [Discord](https://esphome.io/chat) so we can help ` +
`you scope things and flag anything already in flight.\n\n`;
message +=
`For more details (including how to split the work up), see: ` +
`https://developers.esphome.io/contributing/submitting-your-work/` +
`#how-to-approach-large-submissions`;
messages.push(message);
}
@@ -136,6 +157,63 @@ async function handleReviews(github, context, finalLabels, originalLabelCount, d
}
}
// Handle maintainer access warning comment
async function handleMaintainerAccessComment(github, context, maintainerAccess) {
if (!maintainerAccess) {
return;
}
const { owner, repo } = context.repo;
const pr_number = context.issue.number;
const prAuthor = context.payload.pull_request.user.login;
// Check if we already posted the warning (iterate pages to exit early)
let existingComment;
for await (const { data: comments } of github.paginate.iterator(
github.rest.issues.listComments,
{ owner, repo, issue_number: pr_number }
)) {
existingComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body && comment.body.includes(ORG_FORK_MARKER)
);
if (existingComment) {
break;
}
}
if (existingComment) {
console.log('Maintainer access warning comment already exists, skipping');
return;
}
let body;
if (maintainerAccess.isOrgFork) {
body = `${ORG_FORK_MARKER}\n### ⚠️ Organization Fork Detected\n\n` +
`Hey there @${prAuthor},\n` +
`It looks like this PR was submitted from a fork owned by the **${maintainerAccess.orgName}** organization. ` +
`GitHub does not allow maintainers to push changes to pull request branches when the fork is owned by an organization. ` +
`This means we won't be able to make small adjustments or fixups to your PR directly.\n\n` +
`To allow maintainer collaboration, please re-submit this PR from a personal fork instead.\n\n` +
`See: [Setting up the local repository](https://developers.esphome.io/contributing/development-environment/?h=org#set-up-the-local-repository) for more details.`;
} else {
body = `${ORG_FORK_MARKER}\n### ⚠️ Maintainer Access Disabled\n\n` +
`Hey there @${prAuthor},\n` +
`It looks like this PR does not have the "Allow edits from maintainers" option enabled. ` +
`This means we won't be able to make small adjustments or fixups to your PR directly.\n\n` +
`Please enable this option in the PR sidebar to allow maintainer collaboration.`;
}
await github.rest.issues.createComment({
owner,
repo,
issue_number: pr_number,
body
});
console.log('Created maintainer access warning comment');
}
module.exports = {
handleReviews
handleReviews,
handleMaintainerAccessComment
};
+11 -6
View File
@@ -6,9 +6,10 @@ on:
pull_request_target:
types: [labeled, opened, reopened, synchronize, edited]
# All PR/label/review writes are performed with the App token minted below,
# so the workflow's GITHUB_TOKEN only needs read access for checkout.
permissions:
pull-requests: write
contents: read
contents: read # actions/checkout reads the workflow source
env:
SMALL_PR_THRESHOLD: 30
@@ -20,20 +21,24 @@ env:
jobs:
label:
runs-on: ubuntu-latest
if: github.event.action != 'labeled' || github.event.sender.type != 'Bot'
if: github.event.pull_request.state == 'open' && (github.event.action != 'labeled' || github.event.sender.type != 'Bot')
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v2
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
with:
app-id: ${{ secrets.ESPHOME_GITHUB_APP_ID }}
client-id: ${{ vars.ESPHOME_GITHUB_APP_CLIENT_ID }}
private-key: ${{ secrets.ESPHOME_GITHUB_APP_PRIVATE_KEY }}
# Scope the minted App token to the minimum needed by auto-label-pr/*.js.
permission-contents: read # repos.getContent for CODEOWNERS and file lookups in detectors.js
permission-issues: write # listLabelsOnIssue, addLabels, removeLabel, list/createComment
permission-pull-requests: write # pulls.listFiles, list/create/update/dismissReview
- name: Auto Label PR
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
+5 -5
View File
@@ -12,8 +12,8 @@ on:
- ".github/workflows/ci-api-proto.yml"
permissions:
contents: read
pull-requests: write
contents: read # actions/checkout for the PR head
pull-requests: write # pulls.createReview / listReviews / dismissReview when generated proto files are stale
jobs:
check:
@@ -47,7 +47,7 @@ jobs:
fi
- if: failure()
name: Review PR
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
await github.rest.pulls.createReview({
@@ -62,7 +62,7 @@ jobs:
run: git diff
- if: failure()
name: Archive artifacts
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: generated-proto-files
path: |
@@ -70,7 +70,7 @@ jobs:
esphome/components/api/api_pb2_service.*
- if: success()
name: Dismiss review
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
let reviews = await github.rest.pulls.listReviews({
+4 -4
View File
@@ -12,8 +12,8 @@ on:
- ".github/workflows/ci-clang-tidy-hash.yml"
permissions:
contents: read
pull-requests: write
contents: read # actions/checkout for the PR head
pull-requests: write # pulls.createReview / listReviews / dismissReview when the clang-tidy hash is out of date
jobs:
verify-hash:
@@ -42,7 +42,7 @@ jobs:
- if: failure() && github.event.pull_request.head.repo.full_name == github.repository
name: Request changes
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
await github.rest.pulls.createReview({
@@ -55,7 +55,7 @@ jobs:
- if: success() && github.event.pull_request.head.repo.full_name == github.repository
name: Dismiss review
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
let reviews = await github.rest.pulls.listReviews({
+1 -2
View File
@@ -22,8 +22,7 @@ on:
- "script/platformio_install_deps.py"
permissions:
contents: read
packages: read
contents: read # actions/checkout only; the build does not push images
concurrency:
# yamllint disable-line rule:line-length
@@ -7,9 +7,9 @@ on:
types: [completed]
permissions:
contents: read
pull-requests: write
actions: read
contents: read # actions/checkout of the base repo at the PR's target branch
pull-requests: write # gh api to look up the PR by head SHA and post/update the memory-impact comment
actions: read # gh run download for the memory-analysis artifacts produced by the CI workflow run
jobs:
memory-impact-comment:
+206 -41
View File
@@ -17,7 +17,7 @@ on:
merge_group:
permissions:
contents: read
contents: read # actions/checkout for all jobs; individual jobs add their own scopes when they need to write
env:
DEFAULT_PYTHON: "3.11"
@@ -39,7 +39,7 @@ jobs:
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Generate cache-key
id: cache-key
run: echo key="${{ hashFiles('requirements.txt', 'requirements_test.txt', '.pre-commit-config.yaml') }}" >> $GITHUB_OUTPUT
run: echo key="${{ hashFiles('requirements.txt', 'requirements_dev.txt', 'requirements_test.txt', '.pre-commit-config.yaml') }}" >> $GITHUB_OUTPUT
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
@@ -47,7 +47,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
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_test.txt pre-commit
pip install -r requirements.txt -r requirements_dev.txt -r requirements_test.txt pre-commit
pip install -e .
pylint:
@@ -108,6 +108,81 @@ jobs:
script/generate-esp32-boards.py --check
script/generate-rp2040-boards.py --check
import-time:
name: Check import esphome.__main__ time
runs-on: ubuntu-24.04
needs:
- common
- determine-jobs
if: needs.determine-jobs.outputs.import-time == 'true'
steps:
- name: Check out code from GitHub
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Restore Python
uses: ./.github/actions/restore-python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
cache-key: ${{ needs.common.outputs.cache-key }}
- name: Check import time against budget and write waterfall HAR
run: |
. venv/bin/activate
script/check_import_time.py --check --har importtime.har
- name: Upload waterfall HAR
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: import-time-waterfall
path: importtime.har
if-no-files-found: ignore
retention-days: 14
device-builder:
name: Test downstream esphome/device-builder
runs-on: ubuntu-24.04
needs:
- common
- determine-jobs
if: needs.determine-jobs.outputs.device-builder == 'true'
steps:
- name: Check out esphome (this PR)
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: esphome
- name: Check out esphome/device-builder
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: esphome/device-builder
ref: main
path: device-builder
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.13"
- name: Set up uv
# Mirrors the install shape device-builder's own CI uses
# (esphome/device-builder#192): uv replaces pip for the
# install step (order-of-magnitude faster on cold boots,
# with its own wheel cache). actions/setup-python still
# provides the interpreter.
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
enable-cache: true
- name: Install device-builder + esphome from PR
# Install device-builder with its esphome + test extras
# first so its pinned versions of pytest/etc. land, then
# overlay the PR's esphome so the downstream tests run
# against this PR's Python code. ``--system`` installs into
# the runner's Python instead of a venv.
run: |
uv pip install --system -e './device-builder[esphome,test]'
uv pip install --system -e ./esphome
- name: Run device-builder pytest
# ``-n auto`` runs under pytest-xdist (matches device-builder's
# own CI). No ``--cov`` here -- this is purely a downstream
# smoke check against this PR's esphome code.
working-directory: device-builder
run: pytest -q -n auto --maxfail=5 --durations=10 --no-cov --ignore=tests/benchmarks
pytest:
name: Run pytest
strategy:
@@ -159,7 +234,7 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
- name: Save Python virtual environment cache
if: github.ref == 'refs/heads/dev'
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: venv
key: ${{ runner.os }}-${{ steps.restore-python.outputs.python-version }}-venv-${{ needs.common.outputs.cache-key }}
@@ -171,11 +246,12 @@ jobs:
- common
outputs:
integration-tests: ${{ steps.determine.outputs.integration-tests }}
integration-tests-run-all: ${{ steps.determine.outputs.integration-tests-run-all }}
integration-test-files: ${{ steps.determine.outputs.integration-test-files }}
integration-test-buckets: ${{ steps.determine.outputs.integration-test-buckets }}
clang-tidy: ${{ steps.determine.outputs.clang-tidy }}
clang-tidy-mode: ${{ steps.determine.outputs.clang-tidy-mode }}
python-linters: ${{ steps.determine.outputs.python-linters }}
import-time: ${{ steps.determine.outputs.import-time }}
device-builder: ${{ steps.determine.outputs.device-builder }}
changed-components: ${{ steps.determine.outputs.changed-components }}
changed-components-with-tests: ${{ steps.determine.outputs.changed-components-with-tests }}
directly-changed-components-with-tests: ${{ steps.determine.outputs.directly-changed-components-with-tests }}
@@ -198,7 +274,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
cache-key: ${{ needs.common.outputs.cache-key }}
- name: Restore components graph cache
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: .temp/components_graph.json
key: components-graph-${{ hashFiles('esphome/components/**/*.py') }}
@@ -214,11 +290,12 @@ jobs:
# Extract individual fields
echo "integration-tests=$(echo "$output" | jq -r '.integration_tests')" >> $GITHUB_OUTPUT
echo "integration-tests-run-all=$(echo "$output" | jq -r '.integration_tests_run_all')" >> $GITHUB_OUTPUT
echo "integration-test-files=$(echo "$output" | jq -c '.integration_test_files')" >> $GITHUB_OUTPUT
echo "integration-test-buckets=$(echo "$output" | jq -c '.integration_test_buckets')" >> $GITHUB_OUTPUT
echo "clang-tidy=$(echo "$output" | jq -r '.clang_tidy')" >> $GITHUB_OUTPUT
echo "clang-tidy-mode=$(echo "$output" | jq -r '.clang_tidy_mode')" >> $GITHUB_OUTPUT
echo "python-linters=$(echo "$output" | jq -r '.python_linters')" >> $GITHUB_OUTPUT
echo "import-time=$(echo "$output" | jq -r '.import_time')" >> $GITHUB_OUTPUT
echo "device-builder=$(echo "$output" | jq -r '.device_builder')" >> $GITHUB_OUTPUT
echo "changed-components=$(echo "$output" | jq -c '.changed_components')" >> $GITHUB_OUTPUT
echo "changed-components-with-tests=$(echo "$output" | jq -c '.changed_components_with_tests')" >> $GITHUB_OUTPUT
echo "directly-changed-components-with-tests=$(echo "$output" | jq -c '.directly_changed_components_with_tests')" >> $GITHUB_OUTPUT
@@ -231,18 +308,22 @@ jobs:
echo "benchmarks=$(echo "$output" | jq -r '.benchmarks')" >> $GITHUB_OUTPUT
- name: Save components graph cache
if: github.ref == 'refs/heads/dev'
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: .temp/components_graph.json
key: components-graph-${{ hashFiles('esphome/components/**/*.py') }}
integration-tests:
name: Run integration tests
name: Run integration tests (${{ matrix.bucket.name }})
runs-on: ubuntu-latest
needs:
- common
- determine-jobs
if: needs.determine-jobs.outputs.integration-tests == 'true'
strategy:
fail-fast: false
matrix:
bucket: ${{ fromJson(needs.determine-jobs.outputs.integration-test-buckets) }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -253,7 +334,7 @@ jobs:
python-version: "3.13"
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: venv
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv-${{ needs.common.outputs.cache-key }}
@@ -269,19 +350,14 @@ jobs:
run: echo "::add-matcher::.github/workflows/matchers/pytest.json"
- name: Run integration tests
env:
INTEGRATION_TEST_FILES: ${{ needs.determine-jobs.outputs.integration-test-files }}
INTEGRATION_TESTS_RUN_ALL: ${{ needs.determine-jobs.outputs.integration-tests-run-all }}
# JSON array of test paths; parsed into a bash array below to avoid
# shell word-splitting / glob hazards.
BUCKET_TESTS: ${{ toJson(matrix.bucket.tests) }}
run: |
. venv/bin/activate
if [[ "$INTEGRATION_TESTS_RUN_ALL" == "true" ]]; then
echo "Running all integration tests"
pytest -vv --no-cov --tb=native -n auto tests/integration/
else
# Parse JSON array into bash array to avoid shell expansion issues
mapfile -t test_files < <(echo "$INTEGRATION_TEST_FILES" | jq -r '.[]')
echo "Running ${#test_files[@]} specific integration tests"
pytest -vv --no-cov --tb=native -n auto "${test_files[@]}"
fi
mapfile -t test_files < <(echo "$BUCKET_TESTS" | jq -r '.[]')
echo "Bucket ${{ matrix.bucket.name }}: running ${#test_files[@]} integration tests"
pytest -vv --no-cov --tb=native -n auto "${test_files[@]}"
cpp-unit-tests:
name: Run C++ unit tests
@@ -339,7 +415,7 @@ jobs:
echo "binary=$BINARY" >> $GITHUB_OUTPUT
- name: Run CodSpeed benchmarks
uses: CodSpeedHQ/action@db35df748deb45fdef0960669f57d627c1956c30 # v4
uses: CodSpeedHQ/action@3194d9a39c4d46684cb44bf7207fc56626aad8fd # v4.15.1
with:
run: ${{ steps.build.outputs.binary }}
mode: simulation
@@ -387,14 +463,14 @@ jobs:
- name: Cache platformio
if: github.ref == 'refs/heads/dev'
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.platformio
key: platformio-${{ matrix.pio_cache_key }}-${{ hashFiles('platformio.ini') }}
- name: Cache platformio
if: github.ref != 'refs/heads/dev'
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.platformio
key: platformio-${{ matrix.pio_cache_key }}-${{ hashFiles('platformio.ini') }}
@@ -466,14 +542,14 @@ jobs:
- name: Cache platformio
if: github.ref == 'refs/heads/dev'
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.platformio
key: platformio-tidyesp32-${{ hashFiles('platformio.ini') }}
- name: Cache platformio
if: github.ref != 'refs/heads/dev'
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.platformio
key: platformio-tidyesp32-${{ hashFiles('platformio.ini') }}
@@ -555,14 +631,14 @@ jobs:
- name: Cache platformio
if: github.ref == 'refs/heads/dev'
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.platformio
key: platformio-tidyesp32-${{ hashFiles('platformio.ini') }}
- name: Cache platformio
if: github.ref != 'refs/heads/dev'
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.platformio
key: platformio-tidyesp32-${{ hashFiles('platformio.ini') }}
@@ -707,6 +783,91 @@ jobs:
# Run compilation with grouping and isolation
python3 script/test_build_components.py -e compile -c "$components_csv" -f --isolate "$directly_changed_csv"
test-native-idf:
name: Test components with native ESP-IDF
runs-on: ubuntu-24.04
needs:
- common
- determine-jobs
if: github.event_name == 'pull_request'
env:
ESPHOME_ESP_IDF_PREFIX: ~/.esphome-idf
TEST_COMPONENTS: esp32,api,heatpumpir,bme280_i2c,bh1750,aht10,esp32_ble,esp32_ble_beacon,esp32_ble_client,esp32_ble_server,esp32_ble_tracker,ble_client,ble_presence,ble_rssi,ble_scanner
steps:
- name: Check out code from GitHub
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Restore Python
uses: ./.github/actions/restore-python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
cache-key: ${{ needs.common.outputs.cache-key }}
- name: Cache ESPHome
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
with:
path: ~/.esphome-idf
key: ${{ runner.os }}-esphome-${{ needs.common.outputs.cache-key }}
- name: Run native ESP-IDF compile test
run: |
. venv/bin/activate
# Check if /mnt has more free space than / before bind mounting
# Extract available space in KB for comparison
root_avail=$(df -k / | awk 'NR==2 {print $4}')
mnt_avail=$(df -k /mnt 2>/dev/null | awk 'NR==2 {print $4}')
echo "Available space: / has ${root_avail}KB, /mnt has ${mnt_avail}KB"
# Only use /mnt if it has more space than /
if [ -n "$mnt_avail" ] && [ "$mnt_avail" -gt "$root_avail" ]; then
echo "Using /mnt for build files (more space available)"
# Bind mount PlatformIO directory to /mnt (tools, packages, build cache all go there)
sudo mkdir -p /mnt/esphome-idf
sudo chown $USER:$USER /mnt/esphome-idf
mkdir -p ~/.esphome-idf
sudo mount --bind /mnt/esphome-idf ~/.esphome-idf
# Bind mount test build directory to /mnt
sudo mkdir -p /mnt/test_build_components_build
sudo chown $USER:$USER /mnt/test_build_components_build
mkdir -p tests/test_build_components/build
sudo mount --bind /mnt/test_build_components_build tests/test_build_components/build
else
echo "Using / for build files (more space available than /mnt or /mnt unavailable)"
fi
echo "Testing components: $TEST_COMPONENTS"
echo ""
# Show disk space before validation (after bind mounts setup)
echo "Disk space before config validation:"
df -h
echo ""
# Run config validation (auto-grouped by test_build_components.py)
python3 script/test_build_components.py -e config -t esp32-idf -c "$TEST_COMPONENTS" -f --toolchain esp-idf
echo ""
echo "Config validation passed! Starting compilation..."
echo ""
# Show disk space before compilation
echo "Disk space before compilation:"
df -h
echo ""
# Run compilation (auto-grouped by test_build_components.py)
python3 script/test_build_components.py -e compile -t esp32-idf -c "$TEST_COMPONENTS" -f --toolchain esp-idf
- name: Save ESPHome cache
if: github.ref == 'refs/heads/dev'
uses: actions/cache/save@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
with:
path: ~/.esphome-idf
key: ${{ runner.os }}-esphome-${{ needs.common.outputs.cache-key }}
pre-commit-ci-lite:
name: pre-commit.ci lite
runs-on: ubuntu-latest
@@ -817,7 +978,7 @@ jobs:
- name: Restore cached memory analysis
id: cache-memory-analysis
if: steps.check-script.outputs.skip != 'true' && steps.check-tests.outputs.skip != 'true'
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: memory-analysis-target.json
key: ${{ steps.cache-key.outputs.cache-key }}
@@ -841,7 +1002,7 @@ jobs:
- name: Cache platformio
if: steps.check-script.outputs.skip != 'true' && steps.check-tests.outputs.skip != 'true' && steps.cache-memory-analysis.outputs.cache-hit != 'true'
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.platformio
key: platformio-memory-${{ fromJSON(needs.determine-jobs.outputs.memory_impact).platform }}-${{ hashFiles('platformio.ini') }}
@@ -868,7 +1029,8 @@ jobs:
python script/test_build_components.py \
-e compile \
-c "$component_list" \
-t "$platform" 2>&1 | \
-t "$platform" \
--base-only 2>&1 | \
tee /dev/stderr | \
python script/ci_memory_impact_extract.py \
--output-env \
@@ -882,7 +1044,7 @@ jobs:
- name: Save memory analysis to cache
if: steps.check-script.outputs.skip != 'true' && steps.check-tests.outputs.skip != 'true' && steps.cache-memory-analysis.outputs.cache-hit != 'true' && steps.build.outcome == 'success'
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: memory-analysis-target.json
key: ${{ steps.cache-key.outputs.cache-key }}
@@ -903,7 +1065,7 @@ jobs:
fi
- name: Upload memory analysis JSON
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: memory-analysis-target
path: memory-analysis-target.json
@@ -929,7 +1091,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
cache-key: ${{ needs.common.outputs.cache-key }}
- name: Cache platformio
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.platformio
key: platformio-memory-${{ fromJSON(needs.determine-jobs.outputs.memory_impact).platform }}-${{ hashFiles('platformio.ini') }}
@@ -954,7 +1116,8 @@ jobs:
python script/test_build_components.py \
-e compile \
-c "$component_list" \
-t "$platform" 2>&1 | \
-t "$platform" \
--base-only 2>&1 | \
tee /dev/stderr | \
python script/ci_memory_impact_extract.py \
--output-env \
@@ -967,7 +1130,7 @@ jobs:
--platform "$platform"
- name: Upload memory analysis JSON
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: memory-analysis-pr
path: memory-analysis-pr.json
@@ -984,8 +1147,8 @@ jobs:
- memory-impact-pr-branch
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && fromJSON(needs.determine-jobs.outputs.memory_impact).should_run == 'true' && needs.memory-impact-target-branch.outputs.skip != 'true'
permissions:
contents: read
pull-requests: write
contents: read # actions/checkout to load the comment-posting script
pull-requests: write # ci_memory_impact_comment.py posts/updates the memory-impact comment on the PR
env:
GH_TOKEN: ${{ github.token }}
steps:
@@ -1034,7 +1197,9 @@ jobs:
- clang-tidy-nosplit
- clang-tidy-split
- determine-jobs
- device-builder
- test-build-components-split
- test-native-idf
- pre-commit-ci-lite
- memory-impact-target-branch
- memory-impact-pr-branch
@@ -0,0 +1,72 @@
name: Close PR From Fork Default Branch
on:
# pull_request_target is required so we have permission to comment and close PRs from forks.
pull_request_target:
types: [opened, reopened]
permissions:
pull-requests: write # pulls.update to close the PR opened from a fork's default branch
issues: write # issues.createComment to explain to the contributor why the PR was closed
jobs:
close:
name: Close PR opened from fork's default branch
runs-on: ubuntu-latest
if: >-
github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
&& github.event.pull_request.head.ref == github.event.repository.default_branch
steps:
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { owner, repo } = context.repo;
const prNumber = context.payload.pull_request.number;
const author = context.payload.pull_request.user.login;
const defaultBranch = context.payload.repository.default_branch;
const headRepo = context.payload.pull_request.head.repo.full_name;
const body = [
`Hi @${author}, thanks for opening a pull request! :tada:`,
``,
`It looks like this PR was opened from the \`${defaultBranch}\` branch of your fork (\`${headRepo}\`), which is the same name as this repository's default branch. Working directly on \`${defaultBranch}\` in your fork causes a few problems:`,
``,
`- Your fork's \`${defaultBranch}\` branch will permanently diverge from \`esphome/esphome:${defaultBranch}\`, making it hard to keep your fork up to date.`,
`- Any additional commits you push to \`${defaultBranch}\` will be added to this PR, so you can't easily work on multiple changes at once.`,
`- Pushing maintainer fixes to your branch is awkward, since it means committing directly to your fork's default branch.`,
`- It makes local collaboration painful — \`${defaultBranch}\` in a checkout becomes ambiguous between upstream and your fork, and maintainers end up with naming collisions when fetching your branch.`,
``,
`Please re-open this as a new PR from a dedicated feature branch. The usual flow looks like:`,
``,
`\`\`\`bash`,
`# Make sure your fork's ${defaultBranch} is up to date with upstream`,
`git remote add upstream https://github.com/${owner}/${repo}.git # if you haven't already`,
`git fetch upstream`,
`git checkout ${defaultBranch}`,
`git reset --hard upstream/${defaultBranch}`,
`git push --force-with-lease origin ${defaultBranch}`,
``,
`# Create a new branch for your change and cherry-pick / re-apply your commits there`,
`git checkout -b my-feature-branch upstream/${defaultBranch}`,
`# ...re-apply your changes, then:`,
`git push origin my-feature-branch`,
`\`\`\``,
``,
`Then open a new pull request from \`my-feature-branch\` into \`${owner}/${repo}:${defaultBranch}\`.`,
``,
`Closing this PR for now — sorry for the friction, and thanks again for contributing! :heart:`,
].join('\n');
await github.rest.issues.createComment({
owner,
repo,
issue_number: prNumber,
body,
});
await github.rest.pulls.update({
owner,
repo,
pull_number: prNumber,
state: 'closed',
});
@@ -15,9 +15,9 @@ on:
- beta
permissions:
issues: write
pull-requests: read
contents: read
issues: write # issues.addLabels / removeLabel to manage the 'code-owner-approved' label on the PR
pull-requests: read # listReviews to determine whether a codeowner has approved
contents: read # actions/checkout to read CODEOWNERS and the shared codeowners.js helper
jobs:
codeowner-approved:
@@ -34,7 +34,7 @@ jobs:
CODEOWNERS
- name: Check codeowner approval and update label
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
with:
+16 -4
View File
@@ -17,9 +17,10 @@ on:
- release
- beta
# PR/review writes (requestReviewers, issues.createComment) are performed with the App token minted below,
# so the workflow's GITHUB_TOKEN only needs read access for checkout.
permissions:
pull-requests: write
contents: read
contents: read # actions/checkout to read CODEOWNERS and the shared codeowners.js helper
jobs:
request-codeowner-reviews:
@@ -32,9 +33,20 @@ jobs:
with:
ref: ${{ github.event.pull_request.base.sha }}
- name: Request reviews from component codeowners
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
with:
client-id: ${{ vars.ESPHOME_GITHUB_APP_CLIENT_ID }}
private-key: ${{ secrets.ESPHOME_GITHUB_APP_PRIVATE_KEY }}
# Scope the minted App token to the minimum needed by the github-script step below.
permission-pull-requests: write # pulls.listFiles, pulls.get, pulls.listReviews, pulls.requestReviewers
permission-issues: write # issues.listComments and issues.createComment (PR comments use the issues API)
- name: Request reviews from component codeowners
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
const { loadCodeowners, getEffectiveOwners } = require('./.github/scripts/codeowners.js');
+9 -11
View File
@@ -16,6 +16,9 @@ on:
schedule:
- cron: "30 18 * * 4"
# Deny by default; the analyze job opts in to exactly what it needs.
permissions: {}
jobs:
analyze:
name: Analyze (${{ matrix.language }})
@@ -26,15 +29,10 @@ jobs:
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
# required for all workflows
security-events: write
# required to fetch internal or private CodeQL packs
packages: read
# only required for workflows in private repositories
actions: read
contents: read
security-events: write # upload CodeQL SARIF results to the Code Scanning API
packages: read # fetch internal or private CodeQL query packs
actions: read # required by codeql-action when run from a private repo
contents: read # actions/checkout to scan the repository
strategy:
fail-fast: false
@@ -58,7 +56,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
@@ -86,6 +84,6 @@ jobs:
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
with:
category: "/language:${{matrix.language}}"
+16 -7
View File
@@ -4,20 +4,29 @@ on:
pull_request_target:
types: [opened, synchronize]
permissions:
contents: read # Needed to fetch PR details
issues: write # Needed to create and update comments (PR comments are managed via the issues REST API)
pull-requests: write # also needed?
# All API calls (pulls.listFiles + issues.{list,create,update}Comment) are performed with
# the App token minted below, so the workflow's GITHUB_TOKEN does not need any scopes.
permissions: {}
jobs:
external-comment:
name: External component comment
runs-on: ubuntu-latest
steps:
- name: Add external component comment
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
client-id: ${{ vars.ESPHOME_GITHUB_APP_CLIENT_ID }}
private-key: ${{ secrets.ESPHOME_GITHUB_APP_PRIVATE_KEY }}
# pulls.listFiles + issues.{list,create,update}Comment on PRs. For PR resources
# the issues.*Comment APIs require the pull-requests scope, not issues.
permission-pull-requests: write
- name: Add external component comment
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
// Generate external component usage instructions
function generateExternalComponentInstructions(prNumber, componentNames, owner, repo) {
+3 -3
View File
@@ -9,8 +9,8 @@ on:
types: [labeled]
permissions:
issues: write
contents: read
issues: write # issues.createComment to mention component codeowners on the newly labelled issue
contents: read # repos.getContent to fetch CODEOWNERS from the default branch
jobs:
notify-codeowners:
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Notify codeowners for component issues
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const owner = context.repo.owner;
+7 -1
View File
@@ -6,6 +6,12 @@ on:
- cron: "30 0 * * *" # Run daily at 00:30 UTC
workflow_dispatch:
# Deny by default; the lock job opts in to exactly what the reusable workflow needs.
permissions: {}
jobs:
lock:
uses: esphome/workflows/.github/workflows/lock.yml@main
permissions:
issues: write # issues.lock on closed issues
pull-requests: write # issues.lock on closed pull requests
uses: esphome/workflows/.github/workflows/lock.yml@025a1e6255610c498ed590403b7e510b69e474df # 2026.4.1
+3 -3
View File
@@ -8,8 +8,8 @@ on:
- beta
permissions:
contents: read
pull-requests: read
contents: read # actions/checkout to load detect-tags.js
pull-requests: read # pulls.listFiles to map changed files to component/core/dashboard/ci tags
jobs:
check:
@@ -18,7 +18,7 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const {
+20 -17
View File
@@ -9,7 +9,7 @@ on:
- cron: "0 2 * * *"
permissions:
contents: read
contents: read # actions/checkout for all jobs; deploy jobs add their own scopes when they need to write
jobs:
init:
@@ -57,8 +57,8 @@ jobs:
if: github.repository == 'esphome/esphome' && github.event_name == 'release'
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
contents: read # actions/checkout to build the sdist/wheel
id-token: write # OIDC token for PyPI Trusted Publishing (pypa/gh-action-pypi-publish)
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Python
@@ -78,8 +78,8 @@ jobs:
name: Build ESPHome ${{ matrix.platform.arch }}
if: github.repository == 'esphome/esphome'
permissions:
contents: read
packages: write
contents: read # actions/checkout to load Dockerfile and build context
packages: write # docker/login-action + build-push-action push image digests to ghcr.io
runs-on: ${{ matrix.platform.os }}
needs: [init]
strategy:
@@ -138,7 +138,7 @@ jobs:
# version: ${{ needs.init.outputs.tag }}
- name: Upload digests
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: digests-${{ matrix.platform.arch }}
path: /tmp/digests
@@ -152,8 +152,8 @@ jobs:
- deploy-docker
if: github.repository == 'esphome/esphome'
permissions:
contents: read
packages: write
contents: read # actions/checkout to load Dockerfile and build context
packages: write # docker/login-action + build-push-action push image digests to ghcr.io
strategy:
fail-fast: false
matrix:
@@ -221,15 +221,16 @@ jobs:
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
with:
app-id: ${{ secrets.ESPHOME_GITHUB_APP_ID }}
client-id: ${{ vars.ESPHOME_GITHUB_APP_CLIENT_ID }}
private-key: ${{ secrets.ESPHOME_GITHUB_APP_PRIVATE_KEY }}
owner: esphome
repositories: home-assistant-addon
permission-actions: write # actions.createWorkflowDispatch on the target repo (only API call made with this token)
- name: Trigger Workflow
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
@@ -256,15 +257,16 @@ jobs:
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
with:
app-id: ${{ secrets.ESPHOME_GITHUB_APP_ID }}
client-id: ${{ vars.ESPHOME_GITHUB_APP_CLIENT_ID }}
private-key: ${{ secrets.ESPHOME_GITHUB_APP_PRIVATE_KEY }}
owner: esphome
repositories: esphome-schema
permission-actions: write # actions.createWorkflowDispatch on the target repo (only API call made with this token)
- name: Trigger Workflow
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
@@ -287,15 +289,16 @@ jobs:
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
with:
app-id: ${{ secrets.ESPHOME_GITHUB_APP_ID }}
client-id: ${{ vars.ESPHOME_GITHUB_APP_CLIENT_ID }}
private-key: ${{ secrets.ESPHOME_GITHUB_APP_PRIVATE_KEY }}
owner: esphome
repositories: version-notifier
permission-actions: write # actions.createWorkflowDispatch on the target repo (only API call made with this token)
- name: Trigger Workflow
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
+2 -2
View File
@@ -7,8 +7,8 @@ on:
workflow_dispatch:
permissions:
issues: write
pull-requests: write
issues: write # actions/stale labels, comments on, and closes stale issues
pull-requests: write # actions/stale labels, comments on, and closes stale pull requests
concurrency:
group: lock
+16 -14
View File
@@ -2,30 +2,32 @@ name: Status check labels
on:
pull_request:
types: [labeled, unlabeled]
types: [opened, reopened, labeled, unlabeled, synchronize]
permissions:
pull-requests: read # issues.listLabelsOnIssue to detect blocking labels (needs-docs, merge-after-release, chained-pr)
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
check:
name: Check ${{ matrix.label }}
name: Check blocking labels
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
label:
- needs-docs
- merge-after-release
- chained-pr
steps:
- name: Check for ${{ matrix.label }} label
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
- name: Check for blocking labels
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const blockingLabels = ['needs-docs', 'merge-after-release', 'chained-pr'];
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number
});
const hasLabel = labels.find(label => label.name === '${{ matrix.label }}');
if (hasLabel) {
core.setFailed('Pull request cannot be merged, it is labeled as ${{ matrix.label }}');
const labelNames = labels.map(l => l.name);
const found = blockingLabels.filter(bl => labelNames.includes(bl));
if (found.length > 0) {
core.setFailed(`Pull request cannot be merged, it has blocking label(s): ${found.join(', ')}`);
}
+17 -2
View File
@@ -6,12 +6,27 @@ on:
schedule:
- cron: "45 6 * * *"
# Repo writes (branch push, PR open) happen via the App token minted below,
# so the workflow's GITHUB_TOKEN does not need any write scopes.
permissions:
contents: read # actions/checkout for this repo and home-assistant/core
jobs:
sync:
name: Sync Device Classes
runs-on: ubuntu-latest
if: github.repository == 'esphome/esphome'
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
with:
client-id: ${{ vars.ESPHOME_GITHUB_APP_CLIENT_ID }}
private-key: ${{ secrets.ESPHOME_GITHUB_APP_PRIVATE_KEY }}
# Scope the minted App token to the minimum needed by peter-evans/create-pull-request.
permission-contents: write # git.createCommit + refs.create/update to push the sync/device-classes branch
permission-pull-requests: write # pulls.create / pulls.update to open or refresh the sync PR
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -41,7 +56,7 @@ jobs:
python script/run-in-env.py pre-commit run --all-files
- name: Commit changes
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with:
commit-message: "Synchronise Device Classes from Home Assistant"
committer: esphomebot <esphome@openhomefoundation.org>
@@ -50,4 +65,4 @@ jobs:
delete-branch: true
title: "Synchronise Device Classes from Home Assistant"
body-path: .github/PULL_REQUEST_TEMPLATE.md
token: ${{ secrets.DEVICE_CLASS_SYNC_TOKEN }}
token: ${{ steps.generate-token.outputs.token }}
+1
View File
@@ -146,5 +146,6 @@ sdkconfig.*
/components
/managed_components
/dependencies.lock
api-docs/
+4 -3
View File
@@ -11,7 +11,7 @@ ci:
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.15.9
rev: v0.15.12
hooks:
# Run the linter.
- id: ruff
@@ -55,9 +55,10 @@ repos:
hooks:
- id: pylint
name: pylint
entry: python3 script/run-in-env.py pylint
entry: python script/run-in-env.py pylint
language: system
types: [python]
files: ^esphome/.+\.py$
- id: clang-tidy-hash
name: Update clang-tidy hash
entry: python script/clang_tidy_hash.py --update-if-changed
@@ -67,5 +68,5 @@ repos:
additional_dependencies: []
- id: ci-custom
name: ci-custom
entry: python3 script/run-in-env.py script/ci-custom.py
entry: python script/run-in-env.py script/ci-custom.py
language: system
+10 -1
View File
@@ -56,6 +56,7 @@ esphome/components/audio_adc/* @kbx81
esphome/components/audio_dac/* @kbx81
esphome/components/audio_file/* @kahrendt
esphome/components/audio_file/media_source/* @kahrendt
esphome/components/audio_http/* @kahrendt
esphome/components/axs15231/* @clydebarrow
esphome/components/b_parasite/* @rbaron
esphome/components/ballu/* @bazuchan
@@ -346,6 +347,7 @@ esphome/components/modbus_controller/select/* @martgras @stegm
esphome/components/modbus_controller/sensor/* @martgras
esphome/components/modbus_controller/switch/* @martgras
esphome/components/modbus_controller/text_sensor/* @martgras
esphome/components/modbus_server/* @exciton
esphome/components/mopeka_ble/* @Fabian-Schmidt @spbrogan
esphome/components/mopeka_pro_check/* @spbrogan
esphome/components/mopeka_std_check/* @Fabian-Schmidt
@@ -403,6 +405,7 @@ esphome/components/qmp6988/* @andrewpc
esphome/components/qr_code/* @wjtje
esphome/components/qspi_dbi/* @clydebarrow
esphome/components/qwiic_pir/* @kahrendt
esphome/components/radio_frequency/* @kbx81
esphome/components/radon_eye_ble/* @jeffeb3
esphome/components/radon_eye_rd200/* @jeffeb3
esphome/components/rc522/* @glmnet
@@ -413,6 +416,7 @@ esphome/components/resampler/speaker/* @kahrendt
esphome/components/restart/* @esphome/core
esphome/components/rf_bridge/* @jesserockz
esphome/components/rgbct/* @jesserockz
esphome/components/ring_buffer/* @kahrendt
esphome/components/rp2040/* @jesserockz
esphome/components/rp2040_ble/* @bdraco
esphome/components/rp2040_pio_led_strip/* @Papa-DMan
@@ -438,6 +442,11 @@ esphome/components/sen0321/* @notjj
esphome/components/sen21231/* @shreyaskarnik
esphome/components/sen5x/* @martgras
esphome/components/sen6x/* @martgras @mebner86 @mikelawrence @tuct
esphome/components/sendspin/* @kahrendt
esphome/components/sendspin/media_player/* @kahrendt
esphome/components/sendspin/media_source/* @kahrendt
esphome/components/sendspin/sensor/* @kahrendt
esphome/components/sendspin/text_sensor/* @kahrendt
esphome/components/sensirion_common/* @martgras
esphome/components/sensor/* @esphome/core
esphome/components/serial_proxy/* @kbx81
@@ -599,6 +608,6 @@ esphome/components/xxtea/* @clydebarrow
esphome/components/zephyr/* @tomaszduda23
esphome/components/zephyr_mcumgr/ota/* @tomaszduda23
esphome/components/zhlt01/* @cfeenstra1024
esphome/components/zigbee/* @tomaszduda23
esphome/components/zigbee/* @luar123 @tomaszduda23
esphome/components/zio_ultrasonic/* @kahrendt
esphome/components/zwave_proxy/* @kbx81
+1 -1
View File
@@ -48,7 +48,7 @@ PROJECT_NAME = ESPHome
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 2026.4.2
PROJECT_NUMBER = 2026.5.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
+1
View File
@@ -4,4 +4,5 @@ include requirements.txt
recursive-include esphome *.yaml
recursive-include esphome *.cpp *.h *.tcc *.c
recursive-include esphome *.py.script
recursive-include esphome *.jinja
recursive-include esphome LICENSE.txt
@@ -0,0 +1,22 @@
#!/usr/bin/with-contenv bashio
# ==============================================================================
# Installs the latest prerelease of esphome-device-builder when the
# `use_new_device_builder` config option is enabled.
# This is a temporary install-on-boot step until esphome-device-builder
# becomes a direct dependency of esphome.
# ==============================================================================
if ! bashio::config.true 'use_new_device_builder'; then
exit 0
fi
bashio::log.info "Installing latest prerelease of esphome-device-builder..."
if command -v uv > /dev/null; then
uv pip install --system --no-cache-dir --prerelease=allow --upgrade \
esphome-device-builder ||
bashio::exit.nok "Failed installing esphome-device-builder."
else
pip install --no-cache-dir --pre --upgrade esphome-device-builder ||
bashio::exit.nok "Failed installing esphome-device-builder."
fi
bashio::log.info "Installed esphome-device-builder."
@@ -49,5 +49,12 @@ if bashio::fs.directory_exists '/config/esphome/.esphome'; then
rm -rf /config/esphome/.esphome
fi
if bashio::config.true 'use_new_device_builder'; then
bashio::log.info "Starting ESPHome Device Builder..."
exec esphome-device-builder /config/esphome \
--ha-addon \
--ingress-port "$(bashio::addon.ingress_port)"
fi
bashio::log.info "Starting ESPHome dashboard..."
exec esphome dashboard /config/esphome --socket /var/run/esphome.sock --ha-addon
@@ -4,6 +4,14 @@
# Community Hass.io Add-ons: ESPHome
# Configures NGINX for use with ESPHome
# ==============================================================================
# When the new device builder is enabled it serves HA ingress directly,
# so nginx is not used at all -- skip configuration.
if bashio::config.true 'use_new_device_builder'; then
bashio::log.info "Skipping NGINX setup: new device builder serves ingress directly."
bashio::exit.ok
fi
mkdir -p /var/log/nginx
# Generate Ingress configuration
@@ -5,6 +5,14 @@
# Runs the NGINX proxy
# ==============================================================================
# The new device builder handles HA ingress itself, so nginx is bypassed.
# Block the longrun forever so s6 keeps the dependency satisfied and does
# not respawn it.
if bashio::config.true 'use_new_device_builder'; then
bashio::log.info "NGINX bypassed: new device builder serves ingress directly."
exec sleep infinity
fi
bashio::log.info "Waiting for ESPHome dashboard to come up..."
while [[ ! -S /var/run/esphome.sock ]]; do
+805 -141
View File
File diff suppressed because it is too large Load Diff
+11
View File
@@ -101,6 +101,17 @@ class AddressCache:
"""Check if any cache entries exist."""
return bool(self.mdns_cache or self.dns_cache)
def add_mdns_addresses(self, hostname: str, addresses: list[str]) -> None:
"""Store resolved mDNS addresses for ``hostname`` in the cache.
Callers that discover ``.local`` hosts (e.g. via mDNS browse) can use
this to avoid a second resolution round-trip during the upload path.
No-op when ``addresses`` is empty.
"""
if not addresses:
return
self.mdns_cache[normalize_hostname(hostname)] = addresses
@classmethod
def from_cli_args(
cls, mdns_args: Iterable[str], dns_args: Iterable[str]
+14 -7
View File
@@ -24,7 +24,7 @@ from .helpers import (
from .toolchain import find_tool, resolve_tool_path, run_tool
if TYPE_CHECKING:
from esphome.platformio_api import IDEData
from esphome.platformio.toolchain import IDEData
_LOGGER = logging.getLogger(__name__)
@@ -793,8 +793,11 @@ class MemoryAnalyzer:
"""Scan ESPHome source object files to map extern "C" symbols to components.
When no linker map file is available, this uses ``nm`` to scan ``.o`` files
under ``src/esphome/`` and build a symbol-to-component mapping. This catches
``extern "C"`` functions and other symbols that lack C++ namespace prefixes.
under ``src/`` (including ``src/main.cpp.o`` and everything beneath
``src/esphome/``) and build a symbol-to-component mapping. This catches
``extern "C"`` functions, the ESPHome-generated ``setup()``/``loop()``
entry points in ``main.cpp``, and other symbols that lack C++ namespace
prefixes.
Skips scanning if ``_source_symbol_map`` was already populated by
``_parse_map_file()``.
@@ -806,12 +809,12 @@ class MemoryAnalyzer:
if obj_dir is None:
return
# Find ESPHome source object files
esphome_src_dir = obj_dir / "src" / "esphome"
if not esphome_src_dir.is_dir():
# Scan all ESPHome-owned source object files: src/main.cpp.o and src/esphome/...
src_dir = obj_dir / "src"
if not src_dir.is_dir():
return
obj_files = sorted(esphome_src_dir.rglob("*.o"))
obj_files = sorted(src_dir.rglob("*.o"))
if not obj_files:
return
@@ -1064,6 +1067,10 @@ class MemoryAnalyzer:
if component_name in self.external_components:
return f"{_COMPONENT_PREFIX_EXTERNAL}{component_name}"
# ESPHome-generated entry point: src/main.cpp.o (contains setup()/loop())
if len(parts) >= 2 and parts[-2:] == ("src", "main.cpp.o"):
return _COMPONENT_CORE
# ESPHome core: src/esphome/core/... or src/esphome/...
if "core" in parts and "esphome" in parts:
return _COMPONENT_CORE
+1 -1
View File
@@ -739,7 +739,7 @@ def main():
import json
from pathlib import Path
from esphome.platformio_api import IDEData
from esphome.platformio.toolchain import IDEData
build_path = Path(build_dir)
+56
View File
@@ -0,0 +1,56 @@
"""Helpers for running an async coroutine from sync code via a daemon thread.
``asyncio.run(coro())`` in the main thread blocks until the loop's cleanup
cycle finishes, which can add hundreds of milliseconds before the caller
receives the result. Running the loop in a daemon thread lets the caller
observe the result as soon as the coroutine completes while cleanup finishes
in the background.
"""
from __future__ import annotations
import asyncio
from collections.abc import Awaitable, Callable
import threading
from typing import Generic, TypeVar
_T = TypeVar("_T")
class AsyncThreadRunner(threading.Thread, Generic[_T]):
"""Run an async coroutine in a daemon thread and expose its result.
The runner catches all exceptions from the coroutine and stores them in
``exception`` so ``event`` is always set — this prevents callers waiting
on ``event`` from hanging forever when the coroutine crashes.
Typical usage::
runner = AsyncThreadRunner(lambda: my_coro(arg))
runner.start()
if not runner.event.wait(timeout=5.0):
... # timed out
if runner.exception is not None:
raise runner.exception
result = runner.result
"""
def __init__(self, coro_factory: Callable[[], Awaitable[_T]]) -> None:
super().__init__(daemon=True)
self._coro_factory = coro_factory
self.result: _T | None = None
self.exception: BaseException | None = None
self.event = threading.Event()
async def _runner(self) -> None:
try:
self.result = await self._coro_factory()
except Exception as exc: # pylint: disable=broad-except
# Capture all exceptions so ``event`` is always set — otherwise a
# crash would hang the waiter forever.
self.exception = exc
finally:
self.event.set()
def run(self) -> None:
asyncio.run(self._runner())
+5 -7
View File
@@ -127,7 +127,7 @@ def validate_potentially_or_condition(value):
return validate_condition(value)
DelayAction = cg.esphome_ns.class_("DelayAction", Action, cg.Component)
DelayAction = cg.esphome_ns.class_("DelayAction", Action)
LambdaAction = cg.esphome_ns.class_("LambdaAction", Action)
StatelessLambdaAction = cg.esphome_ns.class_("StatelessLambdaAction", Action)
IfAction = cg.esphome_ns.class_("IfAction", Action)
@@ -199,11 +199,10 @@ def validate_automation(extra_schema=None, extra_validators=None, single=False):
return cv.Schema([schema])(value)
except cv.Invalid as err2:
if "extra keys not allowed" in str(err2) and len(err2.path) == 2:
# pylint: disable=raise-missing-from
raise err
raise err from None
if "Unable to find action" in str(err):
raise err2
raise cv.MultipleInvalid([err, err2])
raise err2 from None
raise cv.MultipleInvalid([err, err2]) from None
elif isinstance(value, dict):
if CONF_THEN in value:
return [schema(value)]
@@ -397,7 +396,6 @@ async def delay_action_to_code(
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_component(var, {})
template_ = await cg.templatable(config, args, cg.uint32)
cg.add(var.set_delay(template_))
return var
@@ -598,7 +596,7 @@ async def component_resume_action_to_code(
comp = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, comp)
if CONF_UPDATE_INTERVAL in config:
template_ = await cg.templatable(config[CONF_UPDATE_INTERVAL], args, int)
template_ = await cg.templatable(config[CONF_UPDATE_INTERVAL], args, cg.uint32)
cg.add(var.set_update_interval(template_))
return var
+23 -1
View File
@@ -6,6 +6,7 @@ from pathlib import Path
from esphome.components.esp32 import get_esp32_variant
from esphome.core import CORE
from esphome.helpers import mkdir_p, write_file_if_changed
from esphome.writer import update_storage_json
def get_available_components() -> list[str] | None:
@@ -54,7 +55,7 @@ def get_project_cmakelists() -> str:
idf_target = variant.lower().replace("-", "")
# Extract compile definitions from build flags (-DXXX -> XXX)
compile_defs = [flag for flag in CORE.build_flags if flag.startswith("-D")]
compile_defs = [flag for flag in sorted(CORE.build_flags) if flag.startswith("-D")]
extra_compile_options = "\n".join(
f'idf_build_set_property(COMPILE_OPTIONS "{compile_def}" APPEND)'
for compile_def in compile_defs
@@ -64,6 +65,22 @@ def get_project_cmakelists() -> str:
# Auto-generated by ESPHome
cmake_minimum_required(VERSION 3.16)
# On Windows, Ninja can fail with:
# "CreateProcess: The parameter is incorrect (is the command line too long?)"
# when compiler/linker command lines exceed the OS length limit.
#
# The following settings force CMake/Ninja to use *response files* (@file.rsp)
# to pass long lists of includes, objects, and other arguments indirectly,
# avoiding command-line length limits and fixing the build failure.
#
# This is especially useful for large ESP-IDF / ESPHome projects with many
# source files or include directories.
set(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES 1)
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1)
set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1)
set(CMAKE_NINJA_FORCE_RESPONSE_FILE 1)
set(IDF_TARGET {idf_target})
set(EXTRA_COMPONENT_DIRS ${{CMAKE_SOURCE_DIR}}/src)
@@ -124,6 +141,11 @@ target_link_options(${{COMPONENT_LIB}} PUBLIC
def write_project(minimal: bool = False) -> None:
"""Write ESP-IDF project files."""
# Refresh <data_dir>/storage/<name>.yaml.json so the dashboard's
# /info and /downloads endpoints can locate the build (they 404
# otherwise). This mirrors the PlatformIO build-gen path's call
# in build_gen/platformio.py:write_ini().
update_storage_json()
mkdir_p(CORE.build_path)
mkdir_p(CORE.relative_src_path())
+7 -5
View File
@@ -98,11 +98,13 @@ _KNOWN_FILE_EXTENSIONS = frozenset(
)
# Matches !secret references in YAML text. This is intentionally a simple
# regex scan rather than a YAML parse — it may match inside comments or
# multi-line strings, which is the conservative direction (include more
# secrets rather than fewer).
_SECRET_RE = re.compile(r"!secret\s+(\S+)")
# Matches !secret references in YAML text. An optional surrounding
# quote pair around the key is allowed and ignored: YAML treats
# ``!secret 'foo'`` and ``!secret foo`` as the same key. This is
# intentionally a simple regex scan rather than a YAML parse — it may
# match inside comments or multi-line strings, which is the conservative
# direction (include more secrets rather than fewer).
_SECRET_RE = re.compile(r"""!secret\s+['"]?([^\s'"]+)""")
def _find_used_secret_keys(yaml_files: list[Path]) -> set[str]:
+2 -4
View File
@@ -4,8 +4,7 @@
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace a01nyub {
namespace esphome::a01nyub {
static const char *const TAG = "a01nyub.sensor";
@@ -42,5 +41,4 @@ void A01nyubComponent::check_buffer_() {
void A01nyubComponent::dump_config() { LOG_SENSOR("", "A01nyub Sensor", this); }
} // namespace a01nyub
} // namespace esphome
} // namespace esphome::a01nyub
+2 -4
View File
@@ -6,8 +6,7 @@
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/uart/uart.h"
namespace esphome {
namespace a01nyub {
namespace esphome::a01nyub {
class A01nyubComponent : public sensor::Sensor, public Component, public uart::UARTDevice {
public:
@@ -23,5 +22,4 @@ class A01nyubComponent : public sensor::Sensor, public Component, public uart::U
std::vector<uint8_t> buffer_;
};
} // namespace a01nyub
} // namespace esphome
} // namespace esphome::a01nyub
+2 -4
View File
@@ -4,8 +4,7 @@
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace a02yyuw {
namespace esphome::a02yyuw {
static const char *const TAG = "a02yyuw.sensor";
@@ -41,5 +40,4 @@ void A02yyuwComponent::check_buffer_() {
void A02yyuwComponent::dump_config() { LOG_SENSOR("", "A02yyuw Sensor", this); }
} // namespace a02yyuw
} // namespace esphome
} // namespace esphome::a02yyuw
+2 -4
View File
@@ -6,8 +6,7 @@
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/uart/uart.h"
namespace esphome {
namespace a02yyuw {
namespace esphome::a02yyuw {
class A02yyuwComponent : public sensor::Sensor, public Component, public uart::UARTDevice {
public:
@@ -23,5 +22,4 @@ class A02yyuwComponent : public sensor::Sensor, public Component, public uart::U
std::vector<uint8_t> buffer_;
};
} // namespace a02yyuw
} // namespace esphome
} // namespace esphome::a02yyuw
+2 -4
View File
@@ -1,8 +1,7 @@
#include "a4988.h"
#include "esphome/core/log.h"
namespace esphome {
namespace a4988 {
namespace esphome::a4988 {
static const char *const TAG = "a4988.stepper";
@@ -51,5 +50,4 @@ void A4988::loop() {
this->step_pin_->digital_write(false);
}
} // namespace a4988
} // namespace esphome
} // namespace esphome::a4988
+2 -4
View File
@@ -4,8 +4,7 @@
#include "esphome/core/hal.h"
#include "esphome/components/stepper/stepper.h"
namespace esphome {
namespace a4988 {
namespace esphome::a4988 {
class A4988 : public stepper::Stepper, public Component {
public:
@@ -25,5 +24,4 @@ class A4988 : public stepper::Stepper, public Component {
HighFrequencyLoopRequester high_freq_;
};
} // namespace a4988
} // namespace esphome
} // namespace esphome::a4988
+15 -9
View File
@@ -190,7 +190,7 @@ void AcDimmer::setup() {
this->zero_cross_pin_->setup();
this->store_.zero_cross_pin = this->zero_cross_pin_->to_isr();
this->zero_cross_pin_->attach_interrupt(&AcDimmerDataStore::s_gpio_intr, &this->store_,
gpio::INTERRUPT_FALLING_EDGE);
this->zero_cross_interrupt_type_);
}
#ifdef USE_ESP8266
@@ -226,19 +226,25 @@ void AcDimmer::write_state(float state) {
void AcDimmer::dump_config() {
ESP_LOGCONFIG(TAG,
"AcDimmer:\n"
" Min Power: %.1f%%\n"
" Init with half cycle: %s",
" Min Power: %.1f%%\n"
" Init with half cycle: %s",
this->store_.min_power / 10.0f, YESNO(this->init_with_half_cycle_));
LOG_PIN(" Output Pin: ", this->gate_pin_);
LOG_PIN(" Zero-Cross Pin: ", this->zero_cross_pin_);
if (method_ == DIM_METHOD_LEADING_PULSE) {
ESP_LOGCONFIG(TAG, " Method: leading pulse");
} else if (method_ == DIM_METHOD_LEADING) {
ESP_LOGCONFIG(TAG, " Method: leading");
if (this->zero_cross_interrupt_type_ == gpio::INTERRUPT_RISING_EDGE) {
ESP_LOGCONFIG(TAG, " Interrupt Type: rising");
} else if (this->zero_cross_interrupt_type_ == gpio::INTERRUPT_FALLING_EDGE) {
ESP_LOGCONFIG(TAG, " Interrupt Type: falling");
} else {
ESP_LOGCONFIG(TAG, " Method: trailing");
ESP_LOGCONFIG(TAG, " Interrupt Type: any");
}
if (method_ == DIM_METHOD_LEADING_PULSE) {
ESP_LOGCONFIG(TAG, " Method: leading pulse");
} else if (method_ == DIM_METHOD_LEADING) {
ESP_LOGCONFIG(TAG, " Method: leading");
} else {
ESP_LOGCONFIG(TAG, " Method: trailing");
}
LOG_FLOAT_OUTPUT(this);
ESP_LOGV(TAG, " Estimated Frequency: %.3fHz", 1e6f / this->store_.cycle_time_us / 2);
}
+2
View File
@@ -48,6 +48,7 @@ class AcDimmer : public output::FloatOutput, public Component {
void dump_config() override;
void set_gate_pin(InternalGPIOPin *gate_pin) { gate_pin_ = gate_pin; }
void set_zero_cross_pin(InternalGPIOPin *zero_cross_pin) { zero_cross_pin_ = zero_cross_pin; }
void set_zero_cross_interrupt_type(gpio::InterruptType type) { zero_cross_interrupt_type_ = type; }
void set_init_with_half_cycle(bool init_with_half_cycle) { init_with_half_cycle_ = init_with_half_cycle; }
void set_method(DimMethod method) { method_ = method; }
@@ -56,6 +57,7 @@ class AcDimmer : public output::FloatOutput, public Component {
InternalGPIOPin *gate_pin_;
InternalGPIOPin *zero_cross_pin_;
gpio::InterruptType zero_cross_interrupt_type_;
AcDimmerDataStore store_;
bool init_with_half_cycle_;
DimMethod method_;
+14
View File
@@ -7,6 +7,8 @@ from esphome.core import CORE
CODEOWNERS = ["@glmnet"]
gpio_ns = cg.esphome_ns.namespace("gpio")
ac_dimmer_ns = cg.esphome_ns.namespace("ac_dimmer")
AcDimmer = ac_dimmer_ns.class_("AcDimmer", output.FloatOutput, cg.Component)
@@ -17,15 +19,26 @@ DIM_METHODS = {
"TRAILING": DimMethod.DIM_METHOD_TRAILING,
}
ZC_INTERRUPT_TYPES = {
"RISING": gpio_ns.INTERRUPT_RISING_EDGE,
"FALLING": gpio_ns.INTERRUPT_FALLING_EDGE,
"ANY": gpio_ns.INTERRUPT_ANY_EDGE,
}
CONF_GATE_PIN = "gate_pin"
CONF_ZERO_CROSS_PIN = "zero_cross_pin"
CONF_INIT_WITH_HALF_CYCLE = "init_with_half_cycle"
CONF_ZERO_CROSS_INTERRUPT_TYPE = "zero_cross_interrupt_type"
CONFIG_SCHEMA = cv.All(
output.FLOAT_OUTPUT_SCHEMA.extend(
{
cv.Required(CONF_ID): cv.declare_id(AcDimmer),
cv.Required(CONF_GATE_PIN): pins.internal_gpio_output_pin_schema,
cv.Required(CONF_ZERO_CROSS_PIN): pins.internal_gpio_input_pin_schema,
cv.Optional(CONF_ZERO_CROSS_INTERRUPT_TYPE, default="FALLING"): cv.enum(
ZC_INTERRUPT_TYPES, upper=True, space="_"
),
cv.Optional(CONF_INIT_WITH_HALF_CYCLE, default=True): cv.boolean,
cv.Optional(CONF_METHOD, default="leading pulse"): cv.enum(
DIM_METHODS, upper=True, space="_"
@@ -54,5 +67,6 @@ async def to_code(config):
cg.add(var.set_gate_pin(pin))
pin = await cg.gpio_pin_expression(config[CONF_ZERO_CROSS_PIN])
cg.add(var.set_zero_cross_pin(pin))
cg.add(var.set_zero_cross_interrupt_type(config[CONF_ZERO_CROSS_INTERRUPT_TYPE]))
cg.add(var.set_init_with_half_cycle(config[CONF_INIT_WITH_HALF_CYCLE]))
cg.add(var.set_method(config[CONF_METHOD]))
@@ -1,8 +1,7 @@
#include "adalight_light_effect.h"
#include "esphome/core/log.h"
namespace esphome {
namespace adalight {
namespace esphome::adalight {
static const char *const TAG = "adalight_light_effect";
@@ -129,7 +128,7 @@ AdalightLightEffect::Frame AdalightLightEffect::parse_frame_(light::AddressableL
uint8_t *led_data = &frame_[6];
for (int led = 0; led < accepted_led_count; led++, led_data += 3) {
auto white = std::min(std::min(led_data[0], led_data[1]), led_data[2]);
auto white = std::min({led_data[0], led_data[1], led_data[2]});
it[led].set(Color(led_data[0], led_data[1], led_data[2], white));
}
@@ -138,5 +137,4 @@ AdalightLightEffect::Frame AdalightLightEffect::parse_frame_(light::AddressableL
return CONSUMED;
}
} // namespace adalight
} // namespace esphome
} // namespace esphome::adalight
@@ -6,8 +6,7 @@
#include <vector>
namespace esphome {
namespace adalight {
namespace esphome::adalight {
class AdalightLightEffect : public light::AddressableLightEffect, public uart::UARTDevice {
public:
@@ -35,5 +34,4 @@ class AdalightLightEffect : public light::AddressableLightEffect, public uart::U
std::vector<uint8_t> frame_;
};
} // namespace adalight
} // namespace esphome
} // namespace esphome::adalight
+2 -4
View File
@@ -17,8 +17,7 @@
#include <zephyr/drivers/adc.h>
#endif
namespace esphome {
namespace adc {
namespace esphome::adc {
#ifdef USE_ESP32
// clang-format off
@@ -162,5 +161,4 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
#endif
};
} // namespace adc
} // namespace esphome
} // namespace esphome::adc
+2 -4
View File
@@ -1,8 +1,7 @@
#include "adc_sensor.h"
#include "esphome/core/log.h"
namespace esphome {
namespace adc {
namespace esphome::adc {
static const char *const TAG = "adc.common";
@@ -79,5 +78,4 @@ void ADCSensor::set_sample_count(uint8_t sample_count) {
void ADCSensor::set_sampling_mode(SamplingMode sampling_mode) { this->sampling_mode_ = sampling_mode; }
} // namespace adc
} // namespace esphome
} // namespace esphome::adc
+2 -4
View File
@@ -4,8 +4,7 @@
#include "esphome/core/log.h"
#include <cinttypes>
namespace esphome {
namespace adc {
namespace esphome::adc {
static const char *const TAG = "adc.esp32";
@@ -364,7 +363,6 @@ float ADCSensor::sample_autorange_() {
return final_result;
}
} // namespace adc
} // namespace esphome
} // namespace esphome::adc
#endif // USE_ESP32
@@ -11,8 +11,7 @@ ADC_MODE(ADC_VCC)
#include <Arduino.h>
#endif // USE_ADC_SENSOR_VCC
namespace esphome {
namespace adc {
namespace esphome::adc {
static const char *const TAG = "adc.esp8266";
@@ -55,7 +54,6 @@ float ADCSensor::sample() {
return aggr.aggregate() / 1024.0f;
}
} // namespace adc
} // namespace esphome
} // namespace esphome::adc
#endif // USE_ESP8266
@@ -3,8 +3,7 @@
#include "adc_sensor.h"
#include "esphome/core/log.h"
namespace esphome {
namespace adc {
namespace esphome::adc {
static const char *const TAG = "adc.libretiny";
@@ -48,7 +47,6 @@ float ADCSensor::sample() {
return aggr.aggregate() / 1000.0f;
}
} // namespace adc
} // namespace esphome
} // namespace esphome::adc
#endif // USE_LIBRETINY
+2 -4
View File
@@ -15,8 +15,7 @@
#define PICO_VSYS_PIN 29 // NOLINT(cppcoreguidelines-macro-usage)
#endif
namespace esphome {
namespace adc {
namespace esphome::adc {
static const char *const TAG = "adc.rp2040";
@@ -98,7 +97,6 @@ float ADCSensor::sample() {
return aggr.aggregate() * 3.3f / 4096.0f * coeff;
}
} // namespace adc
} // namespace esphome
} // namespace esphome::adc
#endif // USE_RP2040
+2 -4
View File
@@ -5,8 +5,7 @@
#include "hal/nrf_saadc.h"
namespace esphome {
namespace adc {
namespace esphome::adc {
static const char *const TAG = "adc.zephyr";
@@ -202,6 +201,5 @@ float ADCSensor::sample() {
return val_mv / 1000.0f;
}
} // namespace adc
} // namespace esphome
} // namespace esphome::adc
#endif
+2 -4
View File
@@ -1,8 +1,7 @@
#include "adc128s102.h"
#include "esphome/core/log.h"
namespace esphome {
namespace adc128s102 {
namespace esphome::adc128s102 {
static const char *const TAG = "adc128s102";
@@ -28,5 +27,4 @@ uint16_t ADC128S102::read_data(uint8_t channel) {
return digital_value;
}
} // namespace adc128s102
} // namespace esphome
} // namespace esphome::adc128s102
+2 -4
View File
@@ -4,8 +4,7 @@
#include "esphome/core/hal.h"
#include "esphome/components/spi/spi.h"
namespace esphome {
namespace adc128s102 {
namespace esphome::adc128s102 {
class ADC128S102 : public Component,
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, spi::CLOCK_PHASE_LEADING,
@@ -19,5 +18,4 @@ class ADC128S102 : public Component,
uint16_t read_data(uint8_t channel);
};
} // namespace adc128s102
} // namespace esphome
} // namespace esphome::adc128s102
@@ -2,8 +2,7 @@
#include "esphome/core/log.h"
namespace esphome {
namespace adc128s102 {
namespace esphome::adc128s102 {
static const char *const TAG = "adc128s102.sensor";
@@ -18,5 +17,4 @@ void ADC128S102Sensor::dump_config() {
float ADC128S102Sensor::sample() { return this->parent_->read_data(this->channel_); }
void ADC128S102Sensor::update() { this->publish_state(this->sample()); }
} // namespace adc128s102
} // namespace esphome
} // namespace esphome::adc128s102
@@ -7,8 +7,7 @@
#include "../adc128s102.h"
namespace esphome {
namespace adc128s102 {
namespace esphome::adc128s102 {
class ADC128S102Sensor : public PollingComponent,
public Parented<ADC128S102>,
@@ -24,5 +23,4 @@ class ADC128S102Sensor : public PollingComponent,
protected:
uint8_t channel_;
};
} // namespace adc128s102
} // namespace esphome
} // namespace esphome::adc128s102
@@ -1,8 +1,7 @@
#include "addressable_light_display.h"
#include "esphome/core/log.h"
namespace esphome {
namespace addressable_light {
namespace esphome::addressable_light {
static const char *const TAG = "addressable_light.display";
@@ -66,5 +65,4 @@ void HOT AddressableLightDisplay::draw_absolute_pixel_internal(int x, int y, Col
this->addressable_light_buffer_[y * this->get_width_internal() + x] = color;
}
}
} // namespace addressable_light
} // namespace esphome
} // namespace esphome::addressable_light
@@ -7,8 +7,7 @@
#include <vector>
namespace esphome {
namespace addressable_light {
namespace esphome::addressable_light {
class AddressableLightDisplay : public display::DisplayBuffer {
public:
@@ -61,5 +60,4 @@ class AddressableLightDisplay : public display::DisplayBuffer {
optional<uint32_t> last_effect_index_;
optional<std::function<int(int, int)>> pixel_mapper_f_;
};
} // namespace addressable_light
} // namespace esphome
} // namespace esphome::addressable_light
+2 -4
View File
@@ -13,8 +13,7 @@
#include <cinttypes>
namespace esphome {
namespace ade7880 {
namespace esphome::ade7880 {
static const char *const TAG = "ade7880";
@@ -313,5 +312,4 @@ void ADE7880::reset_device_() {
this->store_.reset_pending = true;
}
} // namespace ade7880
} // namespace esphome
} // namespace esphome::ade7880
+2 -4
View File
@@ -16,8 +16,7 @@
#include "ade7880_registers.h"
namespace esphome {
namespace ade7880 {
namespace esphome::ade7880 {
struct NeutralChannel {
void set_current(sensor::Sensor *sens) { this->current = sens; }
@@ -125,5 +124,4 @@ class ADE7880 : public i2c::I2CDevice, public PollingComponent {
void write_u32_register16_(uint16_t a_register, uint32_t value);
};
} // namespace ade7880
} // namespace esphome
} // namespace esphome::ade7880
+2 -4
View File
@@ -9,8 +9,7 @@
#include "ade7880.h"
namespace esphome {
namespace ade7880 {
namespace esphome::ade7880 {
// adapted from https://stackoverflow.com/a/55912127/1886371
template<size_t Bits, typename T> inline T sign_extend(const T &v) noexcept {
@@ -97,5 +96,4 @@ void ADE7880::write_u32_register16_(uint16_t a_register, uint32_t value) {
this->write_register16(a_register, reinterpret_cast<uint8_t *>(&out), sizeof(out));
}
} // namespace ade7880
} // namespace esphome
} // namespace esphome::ade7880
@@ -4,8 +4,7 @@
// Source: https://www.analog.com/media/en/technical-documentation/application-notes/AN-1127.pdf
namespace esphome {
namespace ade7880 {
namespace esphome::ade7880 {
// DSP Data Memory RAM registers
constexpr uint16_t AIGAIN = 0x4380;
@@ -242,5 +241,4 @@ constexpr uint8_t DSPWP_SET_RO = (1 << 7);
// DSPWP_SEL Register Bits
constexpr uint8_t DSPWP_SEL_SET = 0xAD;
} // namespace ade7880
} // namespace esphome
} // namespace esphome::ade7880
@@ -3,11 +3,13 @@
#include <cinttypes>
namespace esphome {
namespace ade7953_base {
namespace esphome::ade7953_base {
static const char *const TAG = "ade7953";
constexpr uint16_t CONFIG_DEFAULT = 0x8004u;
constexpr uint16_t CONFIG_LOCK_BIT = 0x8000u;
static const float ADE_POWER_FACTOR = 154.0f;
static const float ADE_WATTSEC_POWER_FACTOR = ADE_POWER_FACTOR * ADE_POWER_FACTOR / 3600;
@@ -18,7 +20,12 @@ void ADE7953::setup() {
// The chip might take up to 100ms to initialise
this->set_timeout(100, [this]() {
// this->ade_write_8(0x0010, 0x04);
// Lock communication interface (SPI or I2C)
uint16_t config_v = CONFIG_DEFAULT;
this->ade_read_16(CONFIG_16, &config_v);
config_v &= static_cast<uint16_t>(~CONFIG_LOCK_BIT); // Clear the lock bit
this->ade_write_16(CONFIG_16, config_v);
// Configure optimum settings according to datasheet
this->ade_write_8(0x00FE, 0xAD);
this->ade_write_16(0x0120, 0x0030);
// Set gains
@@ -152,5 +159,4 @@ void ADE7953::update() {
ADE_PUBLISH(frequency, 223750.0f, 1 + val_16);
}
} // namespace ade7953_base
} // namespace esphome
} // namespace esphome::ade7953_base
+19 -17
View File
@@ -6,34 +6,37 @@
#include <vector>
namespace esphome {
namespace ade7953_base {
namespace esphome::ade7953_base {
static const uint8_t PGA_V_8 =
static constexpr uint8_t PGA_V_8 =
0x007; // PGA_V, (R/W) Default: 0x00, Unsigned, Voltage channel gain configuration (Bits[2:0])
static const uint8_t PGA_IA_8 =
static constexpr uint8_t PGA_IA_8 =
0x008; // PGA_IA, (R/W) Default: 0x00, Unsigned, Current Channel A gain configuration (Bits[2:0])
static const uint8_t PGA_IB_8 =
static constexpr uint8_t PGA_IB_8 =
0x009; // PGA_IB, (R/W) Default: 0x00, Unsigned, Current Channel B gain configuration (Bits[2:0])
static const uint32_t AIGAIN_32 =
static constexpr uint16_t CONFIG_16 = 0x102; // CONFIG, (R/W) Default: 0x8004, Unsigned, Configuration register
static constexpr uint16_t AIGAIN_32 =
0x380; // AIGAIN, (R/W) Default: 0x400000, Unsigned,Current channel gain (Current Channel A)(32 bit)
static const uint32_t AVGAIN_32 = 0x381; // AVGAIN, (R/W) Default: 0x400000, Unsigned,Voltage channel gain(32 bit)
static const uint32_t AWGAIN_32 =
static constexpr uint16_t AVGAIN_32 =
0x381; // AVGAIN, (R/W) Default: 0x400000, Unsigned,Voltage channel gain(32 bit)
static constexpr uint16_t AWGAIN_32 =
0x382; // AWGAIN, (R/W) Default: 0x400000, Unsigned,Active power gain (Current Channel A)(32 bit)
static const uint32_t AVARGAIN_32 =
static constexpr uint16_t AVARGAIN_32 =
0x383; // AVARGAIN, (R/W) Default: 0x400000, Unsigned, Reactive power gain (Current Channel A)(32 bit)
static const uint32_t AVAGAIN_32 =
static constexpr uint16_t AVAGAIN_32 =
0x384; // AVAGAIN, (R/W) Default: 0x400000, Unsigned,Apparent power gain (Current Channel A)(32 bit)
static const uint32_t BIGAIN_32 =
static constexpr uint16_t BIGAIN_32 =
0x38C; // BIGAIN, (R/W) Default: 0x400000, Unsigned,Current channel gain (Current Channel B)(32 bit)
static const uint32_t BVGAIN_32 = 0x38D; // BVGAIN, (R/W) Default: 0x400000, Unsigned,Voltage channel gain(32 bit)
static const uint32_t BWGAIN_32 =
static constexpr uint16_t BVGAIN_32 =
0x38D; // BVGAIN, (R/W) Default: 0x400000, Unsigned,Voltage channel gain(32 bit)
static constexpr uint16_t BWGAIN_32 =
0x38E; // BWGAIN, (R/W) Default: 0x400000, Unsigned,Active power gain (Current Channel B)(32 bit)
static const uint32_t BVARGAIN_32 =
static constexpr uint16_t BVARGAIN_32 =
0x38F; // BVARGAIN, (R/W) Default: 0x400000, Unsigned, Reactive power gain (Current Channel B)(32 bit)
static const uint32_t BVAGAIN_32 =
static constexpr uint16_t BVAGAIN_32 =
0x390; // BVAGAIN, (R/W) Default: 0x400000, Unsigned,Apparent power gain (Current Channel B)(32 bit)
class ADE7953 : public PollingComponent, public sensor::Sensor {
@@ -127,5 +130,4 @@ class ADE7953 : public PollingComponent, public sensor::Sensor {
virtual bool ade_read_32(uint16_t reg, uint32_t *value) = 0;
};
} // namespace ade7953_base
} // namespace esphome
} // namespace esphome::ade7953_base
@@ -2,8 +2,7 @@
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace ade7953_i2c {
namespace esphome::ade7953_i2c {
static const char *const TAG = "ade7953";
@@ -76,5 +75,4 @@ bool AdE7953I2c::ade_read_32(uint16_t reg, uint32_t *value) {
return false;
}
} // namespace ade7953_i2c
} // namespace esphome
} // namespace esphome::ade7953_i2c
+2 -4
View File
@@ -8,8 +8,7 @@
#include <vector>
namespace esphome {
namespace ade7953_i2c {
namespace esphome::ade7953_i2c {
class AdE7953I2c : public ade7953_base::ADE7953, public i2c::I2CDevice {
public:
@@ -24,5 +23,4 @@ class AdE7953I2c : public ade7953_base::ADE7953, public i2c::I2CDevice {
bool ade_read_32(uint16_t reg, uint32_t *value) override;
};
} // namespace ade7953_i2c
} // namespace esphome
} // namespace esphome::ade7953_i2c
@@ -2,11 +2,13 @@
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace ade7953_spi {
namespace esphome::ade7953_spi {
static const char *const TAG = "ade7953";
// Datasheet requires at least 1.2µs after clearing CONFIG LOCK_BIT before raising CS
constexpr uint8_t CONFIG_LOCK_SETTLE_US = 2;
void AdE7953Spi::setup() {
this->spi_setup();
ade7953_base::ADE7953::setup();
@@ -32,6 +34,9 @@ bool AdE7953Spi::ade_write_16(uint16_t reg, uint16_t value) {
this->write_byte16(reg);
this->transfer_byte(0);
this->write_byte16(value);
if (reg == ade7953_base::CONFIG_16) {
delayMicroseconds(CONFIG_LOCK_SETTLE_US);
}
this->disable();
return false;
}
@@ -77,5 +82,4 @@ bool AdE7953Spi::ade_read_32(uint16_t reg, uint32_t *value) {
return false;
}
} // namespace ade7953_spi
} // namespace esphome
} // namespace esphome::ade7953_spi
+3 -5
View File
@@ -8,11 +8,10 @@
#include <vector>
namespace esphome {
namespace ade7953_spi {
namespace esphome::ade7953_spi {
class AdE7953Spi : public ade7953_base::ADE7953,
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_HIGH, spi::CLOCK_PHASE_LEADING,
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_HIGH, spi::CLOCK_PHASE_TRAILING,
spi::DATA_RATE_1MHZ> {
public:
void setup() override;
@@ -28,5 +27,4 @@ class AdE7953Spi : public ade7953_base::ADE7953,
bool ade_read_32(uint16_t reg, uint32_t *value) override;
};
} // namespace ade7953_spi
} // namespace esphome
} // namespace esphome::ade7953_spi
+2 -4
View File
@@ -2,8 +2,7 @@
#include "esphome/core/hal.h"
#include "esphome/core/log.h"
namespace esphome {
namespace ads1115 {
namespace esphome::ads1115 {
static const char *const TAG = "ads1115";
static const uint8_t ADS1115_REGISTER_CONVERSION = 0x00;
@@ -208,5 +207,4 @@ float ADS1115Component::request_measurement(ADS1115Multiplexer multiplexer, ADS1
return millivolts / 1e3f;
}
} // namespace ads1115
} // namespace esphome
} // namespace esphome::ads1115
+2 -4
View File
@@ -5,8 +5,7 @@
#include <vector>
namespace esphome {
namespace ads1115 {
namespace esphome::ads1115 {
enum ADS1115Multiplexer {
ADS1115_MULTIPLEXER_P0_N1 = 0b000,
@@ -60,5 +59,4 @@ class ADS1115Component : public Component, public i2c::I2CDevice {
bool continuous_mode_;
};
} // namespace ads1115
} // namespace esphome
} // namespace esphome::ads1115
@@ -2,8 +2,7 @@
#include "esphome/core/log.h"
namespace esphome {
namespace ads1115 {
namespace esphome::ads1115 {
static const char *const TAG = "ads1115.sensor";
@@ -29,5 +28,4 @@ void ADS1115Sensor::dump_config() {
this->multiplexer_, this->gain_, this->resolution_, this->samplerate_);
}
} // namespace ads1115
} // namespace esphome
} // namespace esphome::ads1115
@@ -8,8 +8,7 @@
#include "../ads1115.h"
namespace esphome {
namespace ads1115 {
namespace esphome::ads1115 {
/// Internal holder class that is in instance of Sensor so that the hub can create individual sensors.
class ADS1115Sensor : public sensor::Sensor,
@@ -33,5 +32,4 @@ class ADS1115Sensor : public sensor::Sensor,
ADS1115Samplerate samplerate_;
};
} // namespace ads1115
} // namespace esphome
} // namespace esphome::ads1115
+2 -4
View File
@@ -2,8 +2,7 @@
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace ads1118 {
namespace esphome::ads1118 {
static const char *const TAG = "ads1118";
static const uint8_t ADS1118_DATA_RATE_860_SPS = 0b111;
@@ -122,5 +121,4 @@ float ADS1118::request_measurement(ADS1118Multiplexer multiplexer, ADS1118Gain g
}
}
} // namespace ads1118
} // namespace esphome
} // namespace esphome::ads1118
+2 -4
View File
@@ -4,8 +4,7 @@
#include "esphome/core/component.h"
#include "esphome/core/hal.h"
namespace esphome {
namespace ads1118 {
namespace esphome::ads1118 {
enum ADS1118Multiplexer {
ADS1118_MULTIPLEXER_P0_N1 = 0b000,
@@ -41,5 +40,4 @@ class ADS1118 : public Component,
uint16_t config_{0};
};
} // namespace ads1118
} // namespace esphome
} // namespace esphome::ads1118
@@ -2,8 +2,7 @@
#include "esphome/core/log.h"
namespace esphome {
namespace ads1118 {
namespace esphome::ads1118 {
static const char *const TAG = "ads1118.sensor";
@@ -27,5 +26,4 @@ void ADS1118Sensor::update() {
}
}
} // namespace ads1118
} // namespace esphome
} // namespace esphome::ads1118
@@ -8,8 +8,7 @@
#include "../ads1118.h"
namespace esphome {
namespace ads1118 {
namespace esphome::ads1118 {
class ADS1118Sensor : public PollingComponent,
public sensor::Sensor,
@@ -32,5 +31,4 @@ class ADS1118Sensor : public PollingComponent,
bool temperature_mode_;
};
} // namespace ads1118
} // namespace esphome
} // namespace esphome::ads1118
+2 -4
View File
@@ -3,8 +3,7 @@
#include <cinttypes>
namespace esphome {
namespace ags10 {
namespace esphome::ags10 {
static const char *const TAG = "ags10";
// Data acquisition.
@@ -192,5 +191,4 @@ template<size_t N> optional<std::array<uint8_t, N>> AGS10Component::read_and_che
return data;
}
} // namespace ags10
} // namespace esphome
} // namespace esphome::ags10
+2 -4
View File
@@ -5,8 +5,7 @@
#include "esphome/core/automation.h"
#include "esphome/core/component.h"
namespace esphome {
namespace ags10 {
namespace esphome::ags10 {
class AGS10Component : public PollingComponent, public i2c::I2CDevice {
public:
@@ -136,5 +135,4 @@ template<typename... Ts> class AGS10SetZeroPointAction : public Action<Ts...>, p
}
}
};
} // namespace ags10
} // namespace esphome
} // namespace esphome::ags10
+2 -4
View File
@@ -17,8 +17,7 @@
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace aht10 {
namespace esphome::aht10 {
static const char *const TAG = "aht10";
static const uint8_t AHT10_INITIALIZE_CMD[] = {0xE1, 0x08, 0x00};
@@ -160,5 +159,4 @@ void AHT10Component::dump_config() {
LOG_SENSOR(" ", "Humidity", this->humidity_sensor_);
}
} // namespace aht10
} // namespace esphome
} // namespace esphome::aht10
+2 -4
View File
@@ -6,8 +6,7 @@
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/i2c/i2c.h"
namespace esphome {
namespace aht10 {
namespace esphome::aht10 {
enum AHT10Variant { AHT10, AHT20 };
@@ -31,5 +30,4 @@ class AHT10Component : public PollingComponent, public i2c::I2CDevice {
uint32_t start_time_{};
};
} // namespace aht10
} // namespace esphome
} // namespace esphome::aht10
+2 -4
View File
@@ -4,8 +4,7 @@
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace aic3204 {
namespace esphome::aic3204 {
static const char *const TAG = "aic3204";
@@ -167,5 +166,4 @@ bool AIC3204::write_volume_() {
return true;
}
} // namespace aic3204
} // namespace esphome
} // namespace esphome::aic3204
+2 -4
View File
@@ -6,8 +6,7 @@
#include "esphome/core/defines.h"
#include "esphome/core/hal.h"
namespace esphome {
namespace aic3204 {
namespace esphome::aic3204 {
// TLV320AIC3204 Register Addresses
// Page 0
@@ -83,5 +82,4 @@ class AIC3204 : public audio_dac::AudioDac, public Component, public i2c::I2CDev
float volume_{0};
};
} // namespace aic3204
} // namespace esphome
} // namespace esphome::aic3204
+2 -4
View File
@@ -4,8 +4,7 @@
#include "esphome/core/component.h"
#include "aic3204.h"
namespace esphome {
namespace aic3204 {
namespace esphome::aic3204 {
template<typename... Ts> class SetAutoMuteAction : public Action<Ts...> {
public:
@@ -19,5 +18,4 @@ template<typename... Ts> class SetAutoMuteAction : public Action<Ts...> {
AIC3204 *aic3204_;
};
} // namespace aic3204
} // namespace esphome
} // namespace esphome::aic3204
@@ -4,8 +4,7 @@
#ifdef USE_ESP32
namespace esphome {
namespace airthings_ble {
namespace esphome::airthings_ble {
static const char *const TAG = "airthings_ble";
@@ -29,7 +28,6 @@ bool AirthingsListener::parse_device(const esp32_ble_tracker::ESPBTDevice &devic
return false;
}
} // namespace airthings_ble
} // namespace esphome
} // namespace esphome::airthings_ble
#endif
@@ -5,15 +5,13 @@
#include "esphome/core/component.h"
#include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h"
namespace esphome {
namespace airthings_ble {
namespace esphome::airthings_ble {
class AirthingsListener : public esp32_ble_tracker::ESPBTDeviceListener {
public:
bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override;
};
} // namespace airthings_ble
} // namespace esphome
} // namespace esphome::airthings_ble
#endif
@@ -6,8 +6,7 @@
#ifdef USE_ESP32
namespace esphome {
namespace airthings_wave_base {
namespace esphome::airthings_wave_base {
static const char *const TAG = "airthings_wave_base";
@@ -211,7 +210,6 @@ void AirthingsWaveBase::set_response_timeout_() {
});
}
} // namespace airthings_wave_base
} // namespace esphome
} // namespace esphome::airthings_wave_base
#endif // USE_ESP32
@@ -14,8 +14,7 @@
#include "esphome/core/component.h"
#include "esphome/core/log.h"
namespace esphome {
namespace airthings_wave_base {
namespace esphome::airthings_wave_base {
namespace espbt = esphome::esp32_ble_tracker;
@@ -84,7 +83,6 @@ class AirthingsWaveBase : public PollingComponent, public ble_client::BLEClientN
};
};
} // namespace airthings_wave_base
} // namespace esphome
} // namespace esphome::airthings_wave_base
#endif // USE_ESP32
@@ -2,8 +2,7 @@
#ifdef USE_ESP32
namespace esphome {
namespace airthings_wave_mini {
namespace esphome::airthings_wave_mini {
static const char *const TAG = "airthings_wave_mini";
@@ -49,7 +48,6 @@ AirthingsWaveMini::AirthingsWaveMini() {
espbt::ESPBTUUID::from_raw(ACCESS_CONTROL_POINT_CHARACTERISTIC_UUID);
}
} // namespace airthings_wave_mini
} // namespace esphome
} // namespace esphome::airthings_wave_mini
#endif // USE_ESP32
@@ -4,8 +4,7 @@
#include "esphome/components/airthings_wave_base/airthings_wave_base.h"
namespace esphome {
namespace airthings_wave_mini {
namespace esphome::airthings_wave_mini {
namespace espbt = esphome::esp32_ble_tracker;
@@ -34,7 +33,6 @@ class AirthingsWaveMini : public airthings_wave_base::AirthingsWaveBase {
};
};
} // namespace airthings_wave_mini
} // namespace esphome
} // namespace esphome::airthings_wave_mini
#endif // USE_ESP32

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