Commit Graph
14443 Commits
Author SHA1 Message Date
J. Nick Koston 6491072a77 [light] Alias clamp fields via anonymous-union float[8] to eliminate pointer UB
Replaces the previous `float *p = &this->brightness_; p[bit]` pattern
(flagged by Copilot as pointer-into-scalar UB) with a shared anonymous
union that exposes brightness_..warm_white_ as unit_fields_[8] in both
LightCall and LightColorValues. validate_() now indexes the real array
directly — defined behavior — while the named members stay accessible
to getters/setters. Code generation is unchanged.

The union is declared once via ESPHOME_LIGHT_UNIT_FIELDS_UNION() in
light_color_values.h and expanded in both structs. The per-field
offsetof static_asserts collapse to a single FieldFlags bit-layout
assert since the union guarantees member ↔ array-index alignment.

Caught by Copilot on PR review.
2026-04-13 16:54:43 -10:00
J. Nick Koston 8ef1057674 [light] Treat -0.0f as in range in float_out_of_unit_range
-0.0f has bit pattern 0x80000000 which exceeds ONE_F_BITS as unsigned,
so the check previously flagged it and emitted a spurious out-of-range
warning. Add an explicit compare against NEG_ZERO_F_BITS (declared as
a named constexpr for readability) so -0.0f takes the in-range fast
path. clamp_unit_float() already returned 0.0f for it via the sign-bit
branch, so behavior on clamp is unchanged.

Caught by Copilot on PR review.
2026-04-13 16:48:00 -10:00
J. Nick Koston bdd1c413de [light] Eliminate static-local guard variables by hoisting names to PROGMEM_STRING_TABLE
The PROGMEM_STRING_TABLE expansion is entirely constexpr-initialized, so it doesn't require the per-static thread-safe-init guard variables that the previous `static const LogString *const FIELD_NAMES[8] PROGMEM = { LOG_STR(...) }` form emitted inside validate_() (LOG_STR contains a GCC statement-expression, which is not a constant expression, so GCC fell back to dynamic init with an 8-byte guard).

Combined the 8 clamp-field names and "Color temperature" into a single ValidateFieldNames table; index 8 is reserved for CT. log_value_out_of_range_() now takes the resolved `const LogString *` directly, so the helper no longer needs its internal progmem_read_ptr dereference.

Impact vs. prior commit (isolated light build):

  ESP8266 .irom0.text: 267912 -> 267784  (-128 B)

  ESP8266 .bss guard vars on light symbols: 16 -> 0 (-16 B RAM)

  ESP32-IDF .flash.text: 136988 -> 136996 (+8 B, marginal)
2026-04-13 16:38:44 -10:00
J. Nick Koston de44b8e859 [light] Tighten comments in validate_ clamp loop and LightColorValues helpers 2026-04-13 16:31:50 -10:00
J. Nick Koston 8eb8b3dc0f [light] Promote bit-pattern clamp to LightColorValues setters and add layout asserts
Move `float_out_of_unit_range()` / add `clamp_unit_float()` to
light_color_values.h so the nine `set_*(float)` setters can use the
unsigned bit-pattern clamp instead of `std::clamp(x, 0.0f, 1.0f)`.
`std::clamp` expands to two soft-float `__ltsf2`/`__gtsf2` calls per
invocation on ESP8266 — replacing it with a single unsigned compare
saves code across every caller of these setters (StrobeLightEffect,
the 11-arg LightColorValues constructor, external components).

Split the cold-path helper: `log_value_out_of_range_()` now only logs,
and each caller applies the clamp strategy appropriate to its range
(`clamp_unit_float` for the 8-field loop, `std::clamp` for color
temperature's runtime-variable range).

Add layout/format assertions:
- std::is_standard_layout_v on LightCall and LightColorValues so the
  offsetof arithmetic in the clamp loop is well-defined.
- sizeof(float) == 4 and is_iec559 so the bit-pattern trick is valid.
  A direct __builtin_bit_cast check would be cleaner but is not
  available on the ESP8266 xtensa toolchain.

Text-section delta vs. prior commit (isolated light build):
  ESP32-IDF: .flash.text  137760 -> 136988 (-772 B)
  ESP8266:   .irom0.text  268440 -> 267912 (-528 B)
2026-04-13 16:27:09 -10:00
J. Nick Koston 36881166a8 [light] Replace soft-float range check with union bit-cast + unsigned compare
The inlined `value < 0.0f || value > 1.0f` check in the clamp loop costs
~50 B per iteration on ESP8266 (two libgcc soft-float calls with register
spills). IEEE 754 floats in [0.0f, 1.0f] have bit patterns in
[0x00000000, 0x3F800000]; anything out of range — values > 1.0f, negatives
(sign bit set → huge unsigned interpretation), NaN, Infinity — has a
strictly larger unsigned interpretation. A single `pun.u > 0x3F800000u`
covers every case.

Using a union for the type-pun rather than memcpy/bit_cast because those
don't optimize to a no-op on xtensa-gcc (same reason api/proto.h's
float_to_raw() uses a union).

The loop body is now two instructions for the range check:
  l32i a2, a9, 0    ; load raw u32
  bgeu a10, a2, ... ; compare against pre-hoisted 1.0f bits

Size delta vs. the prior float-compare form:
  ESP32-IDF: validate_ -16 B, net -12 B
  ESP8266:   validate_ -20 B, net -20 B

vs. dev baseline (isolated light build, matched funcs):
  ESP32-IDF: -103 B code, +32 B PROGMEM table = -71 B net
  ESP8266:    -42 B code, +32 B PROGMEM table = -10 B net
2026-04-13 16:16:44 -10:00
J. Nick Koston cdde0abec7 [light] Refine validate_ clamp loop: ctz iteration, per-field asserts, typed pointers
Follow-up to edb2145a addressing three points:

1. Hoist the in-range check out of the logging helper. The loop now tests
   `value < 0.0f || value > 1.0f` inline and only calls the out-of-line
   log_out_of_range_and_clamp_ helper on the cold path. Hot path (value in
   range) skips the call8 and the register spill/reload around it, which
   matters because HA automations can drive perform() at high frequency.

2. Iterate only set bits with __builtin_ctz + (active & active-1). Common
   calls with one or two flags set now exit the loop after one or two
   iterations instead of always scanning all eight slots.

3. Replace the uint8_t* pointer arithmetic with typed float arrays aliasing
   &brightness_ in each struct. Per-field static_asserts (expanded via a
   local macro) now catch reorders of any single member in either struct,
   not just reorders at the endpoints. Compiles to the same machine code as
   the uint8_t* version.

Size delta vs. prior commit (isolated light build):
  ESP32-IDF: validate_ +60 B, helper -29 B, net +31 B
  ESP8266:   validate_ +72 B, helper -42 B, net +30 B
Still a net win vs. dev on both targets (ESP32-IDF -91 B, ESP8266 -22 B).
2026-04-13 16:07:34 -10:00
J. Nick Koston edb2145aca [light] Collapse 8 clamp-and-copy blocks in LightCall::validate_ into a loop
Reorder FieldFlags so the eight [0.0, 1.0]-clamped float fields occupy
bits 0-7 in the same order as they appear in LightCall and
LightColorValues, and move color_temperature_ to the end of both
structs. Under that layout the LightCall offset for clamp field i is
`offsetof(LightCall, brightness_) + i * 4`, and the LightColorValues
offset is exactly 12 bytes lower for every field. validate_() now
iterates the active clamp bits in a small loop that computes these
offsets from the bit position instead of expanding eight nearly
identical inline blocks via macro.

The field-name PROGMEM pointer is passed to clamp_and_log_if_invalid as
`const LogString *const *`; progmem_read_ptr only runs on the cold
(out-of-range) path, so the hot path performs no flash reads for the
name. The eight invariants the loop relies on (flag-bit layout,
field contiguity, and the constant 12-byte delta) are enforced by
static_asserts so any future reshuffle fails loudly at compile time.

Size deltas for the isolated light component build (vs dev):
  ESP32-IDF:  -118 B code, +32 B PROGMEM name table = -86 B net
  ESP8266:     -56 B code, +32 B PROGMEM name table = -24 B net
0 B RAM impact on both targets.
2026-04-13 15:55:50 -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 Kostonandpre-commit-ci-lite[bot] 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 YannandJonathan Swoboda 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 Kostonandpre-commit-ci-lite[bot] 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
Jesse Hills 0c06d78a4f Merge pull request #15675 from esphome/bump-2026.4.0b2
2026.4.0b2
2026.4.0b2
2026-04-13 12:44:27 +12:00
schrobandJ. Nick Koston 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
Jesse Hills a408b5a4fe Bump version to 2026.4.0b2 2026-04-13 08:48:19 +12:00
Clyde StubbsandJesse Hills e264c97454 [lvgl] Fix use of rotation on host SDL (#15611)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2026-04-13 08:48:19 +12:00
J. Nick Koston 8790dec137 [packages] Fix false deprecation warning and wrong error paths in nested packages (#15605) 2026-04-13 08:48:19 +12:00
Jonathan Swoboda 6480868e6e [esp32] Bump platform to 55.03.38, Arduino to 3.3.8, ESP-IDF to 5.5.4 (#15666) 2026-04-13 08:48:19 +12:00
Jonathan Swoboda 0578e43352 [canbus] Fix canbus.send can_id compile error (#15668) 2026-04-13 08:48:19 +12:00
Jonathan Swoboda 2a89d4835f [mdns] Bump espressif/mdns to 1.11.0 (#15670) 2026-04-13 08:48:19 +12:00
dependabot[bot] 5084c61016 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-13 08:48:19 +12:00
dependabot[bot] b45f94d511 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-13 08:48:18 +12:00
J. Nick KostonandCopilot 66a4752e13 [rp2040] Fix W5500 Ethernet pbuf corruption by mirroring LWIPMutex semantics (#15624)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-13 08:48:18 +12:00
Jonathan Swoboda 4d4f78de81 [sx127x][cc1101][sx126x] Use GPIO interrupt to wake loop (#15627) 2026-04-13 08:48:18 +12:00
Kevin Ahrendt 0faa641c8a [micro_wake_word] Pin esp-nn version (#15628) 2026-04-13 08:48:18 +12:00
J. Nick Koston 0f16d27a72 [api] Add (inline_encode) proto option for sub-message inlining (#15599) 2026-04-13 08:48:18 +12:00
J. Nick Koston 835ee456a5 [mcp23016] Add interrupt pin support (#15616) 2026-04-13 08:48:18 +12:00
J. Nick Koston 17f3b7dbd5 [pca6416a] Add interrupt pin support (#15614) 2026-04-13 08:48:18 +12:00
J. Nick Koston 171a429526 [tca9555] Add interrupt pin support (#15613) 2026-04-13 08:48:18 +12:00