Commit Graph
27863 Commits
Author SHA1 Message Date
J. Nick Koston cc8b8242fa Merge remote-tracking branch 'upstream/fast-millis-esp8266' into integration 2026-04-23 18:41:36 -05:00
J. Nick Koston d632e00e7d Trim overflow comment 2026-04-23 18:41:21 -05:00
J. Nick Koston 83b76f616b Address review: fix misleading static_assert, drop %= on LX106 2026-04-23 18:40:28 -05:00
J. Nick Koston d1af72e623 Merge remote-tracking branch 'upstream/fast-millis-esp8266' into integration 2026-04-23 18:34:27 -05:00
J. Nick Koston a82b00ba12 Merge branch 'dev' into fast-millis-esp8266 2026-04-23 18:34:11 -05:00
Kevin AhrendtandCopilot 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 c27977389f Merge remote-tracking branch 'upstream/dev' into integration 2026-04-23 16:54:55 -05: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 AhrendtandCopilot 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
J. Nick Koston 835b9a55a0 Merge remote-tracking branch 'upstream/dev' into integration 2026-04-23 14:53:33 -05:00
luar123pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>J. Nick KostonJ. Nick KostonJonathan SwobodaClaude Opus 4.6Copilot
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
J. Nick Koston c6d888e4d2 [scheduler][core] Address review: use preloaded major
In time_64.cpp's true-rollover branch, bump the just-loaded `major`
local first and __atomic_store_n that value to millis_major, instead
of reading the global again for the store expression. Equivalent
under the held lock; clearer and avoids a second read.

scheduler.h indent: the NO_ATOMICS #else branch bodies read at 2
spaces while the sibling #ifdef/#elif branches read at 4. clang-format
refuses to normalise these consistently — every manual re-indent to 4
spaces gets reverted by the hook. Leaving as clang-format produces it.
2026-04-23 06:34:40 -05:00
J. Nick Koston 3bfde7249a Merge branch 'scheduler-volatile-counters' into integration 2026-04-23 06:28:42 -05:00
J. Nick Koston 6d1d924ff9 [core] time_64 NO_ATOMICS: atomic re-reads + reload major under lock
Two fixes Copilot flagged on #15947:

1. Use __atomic_load_n to re-read last_millis under the lock, not a
   plain read. The forward-progression branch (else if) writes
   last_millis with __atomic_store_n without holding lock, so the
   under-lock plain read would race with it and be UB in the C++
   memory model.

2. Reload major from millis_major after acquiring the lock. The
   unlocked load at the top of the function can be stale by the time
   we get the lock: another thread may have completed a rollover
   between the unlocked load and the lock acquisition, leaving our
   local major behind by one. Without reload the function could
   return a 64-bit timestamp that jumps backwards by ~2^32 ms (~49.7
   days). The MULTI_ATOMICS branch already handles this via its retry
   loop; NO_ATOMICS just reloads under the lock.
2026-04-23 06:28:21 -05:00
J. Nick Koston 6ded06eff0 [core] time_64 NO_ATOMICS: atomic re-reads + reload major under lock
Two fixes Copilot flagged on #15947:

1. Use __atomic_load_n to re-read last_millis under the lock, not a
   plain read. The forward-progression branch (else if) writes
   last_millis with __atomic_store_n without holding lock, so the
   under-lock plain read would race with it and be UB in the C++
   memory model.

2. Reload major from millis_major after acquiring the lock. The
   unlocked load at the top of the function can be stale by the time
   we get the lock: another thread may have completed a rollover
   between the unlocked load and the lock acquisition, leaving our
   local major behind by one. Without reload the function could
   return a 64-bit timestamp that jumps backwards by ~2^32 ms (~49.7
   days). The MULTI_ATOMICS branch already handles this via its retry
   loop; NO_ATOMICS just reloads under the lock.
2026-04-23 06:28:01 -05:00
J. Nick Koston 8a7cd3683e Merge remote-tracking branch 'origin/scheduler-volatile-counters' into integration 2026-04-23 06:23:43 -05:00
J. Nick Koston 867fae3bb8 [scheduler,core] Make NO_ATOMICS writer paths fully memory-model-clean
Switch writer-side plain stores under lock_ to __atomic_store_n with
__ATOMIC_RELAXED on NO_ATOMICS. The input value for RMW is read
plainly (safe — only writers mutate, serialised by the lock; readers
only atomic-load so two reads don't race). Closes the formal C++
memory-model hole where plain-store vs atomic-load was a data race
in the standard even though aligned 32-bit STR/LDR on ARMv5TE is
atomic in practice.

Applies to scheduler.h counter mutators and the under-lock writes
to last_millis / millis_major in time_64.cpp's near-rollover branch.
Same ARMv5TE codegen (plain STR). ATOMICS / SINGLE paths unchanged.
2026-04-23 06:19:28 -05:00
J. Nick Koston 98e88ac02c [scheduler] Normalise to_remove_empty_/to_remove_count_ preprocessor form
Use `#if defined(X)` / `#elif defined(Y)` / `#else` for the three-way
ATOMICS / NO_ATOMICS / SINGLE split. Also fix the SINGLE-branch body
indentation to match the other branches.
2026-04-23 06:14:48 -05:00
J. Nick Koston b3f93a4da7 [core] Restore original Millis64 NO_ATOMICS comments
The preceding commit needlessly rewrote comments that were still
accurate. Revert the prose-only changes; keep only the two line-level
code changes (__atomic_load_n on the unlocked reads, __atomic_store_n
on the unlocked write).
2026-04-23 06:12:10 -05:00
J. Nick Koston 3c2396ab86 [core] Apply __atomic_load_n/store_n pattern to Millis64 NO_ATOMICS path
Same treatment as the scheduler counters (#15947):

  - Unlocked reads of millis_major / last_millis at the top of
    Millis64Impl::compute(): switch from plain reads to
    __atomic_load_n(&..., __ATOMIC_RELAXED).
  - Unlocked write of last_millis in the "normal forward progression"
    branch: switch from plain assignment to __atomic_store_n(...,
    __ATOMIC_RELAXED). This is the one write that happens without the
    lock, so it needs to be formally atomic to pair cleanly with the
    unlocked atomic reader in the C++ memory model.
  - Writes under `lock` stay plain (millis_major++, last_millis = now
    inside the near-rollover branch). The lock serialises them against
    other writers.

On ARMv5TE the builtins compile to plain LDR/STR — same codegen, no
libatomic dependency. Updates the "accepting minor races" comment to
describe the formally-defined version of the race.
2026-04-23 06:11:03 -05:00
J. Nick Koston 202bcf5b10 [scheduler] Use __atomic_load_n only on reader fast-path
Walk back the __atomic_store_n on the writer paths — the mutators
already hold lock_, so plain counter_++/=/+=/-- is sufficient to
serialise against other writers. The reader fast-path still uses
__atomic_load_n(&counter, __ATOMIC_RELAXED) to express concurrent-
read intent in the C++ memory model and keep the compiler from
caching/eliding the read. On ARMv5TE it compiles to a plain LDR —
same codegen as before.
2026-04-23 06:07:51 -05:00
J. Nick Koston 22ed9b3c1e [scheduler] Replace volatile with __atomic_{load,store}_n on NO_ATOMICS
Copilot review on #15947 flagged that `volatile uint32_t` is not a
well-defined concurrent access in the C++ memory model — it prevents
the compiler caching/eliding the read, but does not turn a plain
cross-thread read/write pair into a defined access. Technically still
a formal data race even though aligned 32-bit LDR/STR on ARMv5TE is
atomic at the hardware level.

Switch the NO_ATOMICS counter reads and writes to GCC's atomic
builtins with __ATOMIC_RELAXED:

  - Readers: __atomic_load_n(&counter, __ATOMIC_RELAXED)
  - Writers (under lock_): __atomic_store_n(&counter, new_value,
                                             __ATOMIC_RELAXED)
  - Increment/decrement (under lock_): explicit load + compute +
    __atomic_store_n. Lock_ serialises the load-modify-store against
    other writers; the atomic ops make the write visible to concurrent
    readers in the memory model.

On ARMv5TE these builtins compile to plain LDR/STR — same codegen as
the previous volatile approach, and no libatomic dependency (only RMW
builtins like __atomic_fetch_add would need the lib). ATOMICS and
SINGLE paths are unchanged.
2026-04-23 06:06:02 -05:00
J. Nick Koston 89fca4f446 merge 2026-04-23 06:01:08 -05:00
J. Nick Koston 2a0f2abd6b Merge remote-tracking branch 'origin/core-application-stale-includes' into integration 2026-04-23 05:57:27 -05:00
J. Nick Koston 64ca25ec84 Merge remote-tracking branch 'origin/scheduler-volatile-counters' into integration 2026-04-23 05:57:17 -05:00
J. Nick Koston 4ec2e42d4d [scheduler] Rename counter mutators with _locked_ suffix
Rename the seven counter RMW mutators to carry the `_locked_` suffix
that matches the existing convention (pop_raw_locked_,
is_item_removed_locked_, cancel_item_locked_, etc.):

  to_add_count_increment_   -> to_add_count_increment_locked_
  to_add_count_clear_       -> to_add_count_clear_locked_
  defer_count_increment_    -> defer_count_increment_locked_
  defer_count_clear_        -> defer_count_clear_locked_
  to_remove_add_            -> to_remove_add_locked_
  to_remove_decrement_      -> to_remove_decrement_locked_
  to_remove_clear_          -> to_remove_clear_locked_

The caller-must-hold-lock contract became load-bearing when the
underlying counters became volatile on NO_ATOMICS: ++/+=/-- compile to
a three-instruction LDR/OP/STR sequence that is not atomic against a
concurrent RMW from another task, so the lock is what keeps the
counter consistent. The new suffix makes the requirement explicit at
every call site, matching how the rest of the scheduler documents the
same invariant.

No behavioural change; all call sites already hold lock_.
2026-04-23 05:49:49 -05:00
J. Nick Koston c414cc393f [scheduler] Enable lock-free fast-path on ESPHOME_THREAD_MULTI_NO_ATOMICS
The _empty_() helpers (to_add_empty_, defer_empty_, to_remove_empty_)
forced the lock path on ESPHOME_THREAD_MULTI_NO_ATOMICS by hardcoding
`return false`. That made Scheduler::call() pay a FreeRTOS mutex
round-trip for each of process_defer_queue_ / process_to_add /
cleanup_ on every idle tick just to confirm "nothing to do".

On the only NO_ATOMICS target (BK72xx — ARMv5TE, single-core), an
aligned 32-bit load is atomic at the hardware level. Mark the three
skip-work counters volatile so the compiler cannot cache or elide the
read, and let _empty_() compare against zero directly. Writers still
hold lock_ for any RMW — that invariant is unchanged.

A stale 0 is benign: the counter is checked on every Scheduler::call()
iteration, so a missed update is caught next tick. Same pattern as the
NO_ATOMICS reads in time_64.cpp.

On BK72xx at ~3100 iter/min with ~8us/mutex this reclaims roughly
75ms/min of main-loop overhead. Measured on BK7238/BK7231N while
profiling alongside libretiny-eu/libretiny#360.

ATOMICS and SINGLE paths are unchanged (SINGLE keeps plain uint32_t,
no volatile-read overhead).
2026-04-23 05:47:52 -05:00
J. Nick Koston 8da2b8225a [core] Inline yield_with_select_ as direct wakeable_delay call
yield_with_select_ was a trivial one-line passthrough to
esphome::internal::wakeable_delay(). Remove the wrapper and call
wakeable_delay() directly at the two call sites.
2026-04-23 05:14:25 -05:00
J. Nick Koston 8fe40f33a6 [core] Drop unused lwip_fast_select.h include from application.h
No symbols from lwip_fast_select.h are referenced in application.h.
2026-04-23 05:13:12 -05:00
J. Nick Koston 14bd2f5a52 [core] Remove stale includes from application.cpp
socket.h is unused after #15931 moved the host wake mechanism to
wake.cpp. lwip_fast_select.h is already included via application.h
under the same guard.
2026-04-23 05:12:12 -05:00
J. Nick Koston 3b212b9944 [core] Add permalink to BDK sctrl_dpll_delay200us in WDT interval comment
So future readers can verify the errata claim without chasing the PR.
2026-04-23 04:47:52 -05:00
J. Nick Koston 72d4efb681 Merge remote-tracking branch 'upstream/bk72xx-wdt-feed-interval' into integration 2026-04-23 04:45:51 -05:00
J. Nick Koston c7fdd534bc [core] Raise WDT_FEED_INTERVAL_MS to 2000ms on BK72xx
BK72xx silicon requires a ~200us busy-wait (sctrl_dpll_delay200us) between
two watchdog register key writes on every reload, making each
arch_feed_wdt() call ~300us on BK7231T/N/BK7238. This is hardware errata
in the BDK's wdt_ctrl (beken378/driver/wdt/wdt.c:WCMD_RELOAD_PERIOD) and
cannot be worked around at the SDK level.

LibreTiny initialises the BK72xx HW watchdog at 10000ms, but ESPHome's
generic WDT_FEED_INTERVAL_MS of 300ms was sized for ESP8266's 1.6s soft
watchdog. That left BK72xx over-servicing the watchdog ~33x per timeout
window, paying ~60ms/min of main-loop overhead to no benefit.

Raise the interval to 2000ms on BK72xx only, which keeps a 5x safety
margin on the 10s HW WDT — matching the ESP8266 ratio that originally
motivated the 300ms value — while cutting feed frequency ~6x.

Measured on a NiceMCU XH-WB3S (BK7238) while testing
libretiny-eu/libretiny#360:

  Before (300ms interval):
    wdt_slow_path: hits=195 (5.9% of iters, avg=315.97us/hit)
    main_loop_before_breakdown: sched=73.2ms, wdt=61.6ms, residual=0.0ms

Other platforms retain the existing 300ms value.
2026-04-23 04:44:05 -05:00
J. Nick Koston b47a7e65a8 Merge remote-tracking branch 'upstream/wifi-bdk-bk7238-typedef-conflict' into integration 2026-04-23 04:25:52 -05:00
J. Nick Koston b4206f94bc [wifi] Avoid BDK 3.0.78 wifi_event_sta_disconnected_t collision on BK72xx
BDK 3.0.78 (required by LibreTiny for BK7238 support, see
libretiny-eu/libretiny#360) declares wifi_event_sta_disconnected_t in
wlan_defs_pub.h, which collides with the identically named typedef in
LibreTiny's Arduino WiFi API (WiFiEvents.h). Rename the BDK version
across the include so both headers can coexist. ESPHome only uses
bk_wlan_get_link_status from this header and doesn't reference the
renamed type.

The rename is a no-op on BDK 3.0.33 (BK7231T/N) since that version
doesn't declare the typedef.
2026-04-23 04:22:16 -05:00
PolarGoose 43a371caab [dsmr] Small refactoring: Move Aes128GcmDecryptorImpl type inside esphome::dsmr namespace. (#15940) 2026-04-23 04:08:49 -05:00
J. Nick Koston 6b0c510376 Merge remote-tracking branch 'origin/api-logger-plaintext-fallback' into integration 2026-04-23 04:05:55 -05:00
J. Nick Koston db06ae7952 Merge remote-tracking branch 'upstream/dev' into integration 2026-04-23 04:05:38 -05:00
J. Nick Koston e16566e4af [api] Fall back to plaintext for logger connections 2026-04-23 03:32:33 -05:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 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