Commit Graph

22641 Commits

Author SHA1 Message Date
J. Nick Koston
86ad7f287c Merge branch 'json_web_server_stack' into integration 2026-02-18 18:11:12 -06:00
J. Nick Koston
2dd767ed3f [json] Bump heap fallback cap from 4096 to 5120
Aligns with the doubling sequence from 640: 1280 -> 2560 -> 5120.
2026-02-18 18:10:29 -06:00
J. Nick Koston
d967f47f3e [json] Increase SerializationBuffer stack size from 512 to 640 bytes
The reduction from 768 to 512 was overly aggressive - the stack
overflow was caused by the 1400+ byte multipart parser, not the
serialization buffer. 640 bytes covers climate DETAIL_ALL payloads
(~520 bytes) on the stack without heap fallback.
2026-02-18 18:07:23 -06:00
J. Nick Koston
fee4dc6783 Merge remote-tracking branch 'origin/integration' into integration 2026-02-18 17:54:21 -06:00
J. Nick Koston
52e870a10b Merge branch 'json_web_server_stack' into integration 2026-02-18 17:54:03 -06:00
J. Nick Koston
bb6600985f [json] Make heap fallback max size constexpr 2026-02-18 17:53:29 -06:00
J. Nick Koston
1ba1ab7fe2 [json] Document heap fallback buffer sizing expectations
Payloads exceeding 1024 bytes are not known to exist in real
configurations. One doubling iteration covers all known entity types.
Cap at 4096 as a safety limit.
2026-02-18 17:53:12 -06:00
J. Nick Koston
b0669e3c81 Merge branch 'json_web_server_stack' into integration 2026-02-18 17:52:38 -06:00
J. Nick Koston
6bb8e7dae6 Merge branch 'json_web_server_stack' into integration 2026-02-18 17:52:26 -06:00
J. Nick Koston
90ed0db0d9 [json] Replace measureJson() with doubling strategy in heap fallback
Avoids instantiating DummyWriter templates (~736 bytes flash) by
doubling the heap buffer until the payload fits. The temporary
over-allocation (at most 2x) is acceptable since payloads exceeding
the 512-byte stack buffer are rare.
2026-02-18 17:51:20 -06:00
J. Nick Koston
6820e1d6b3 [json] Replace measureJson() with doubling strategy in heap fallback
Avoids instantiating DummyWriter templates (~736 bytes flash) by
doubling the heap buffer until the payload fits. The temporary
over-allocation (at most 2x) is acceptable since payloads exceeding
the 512-byte stack buffer are rare.
2026-02-18 17:51:02 -06:00
J. Nick Koston
8337743a22 Merge branch 'json_web_server_stack' into integration 2026-02-18 17:39:53 -06:00
J. Nick Koston
6a7925b3ce [json] Fix SerializationBuffer truncation when payload exceeds stack buffer
ArduinoJson's serializeJson() with a bounded buffer returns the actual
bytes written (truncated count), NOT the would-be size like snprintf().
When the payload exceeded the 512-byte stack buffer, the return value
was used as the exact size for heap reallocation, but this was only the
truncated count. The heap buffer was allocated too small, the second
serialization was also truncated, and no NUL terminator was written.

This caused corrupted JSON in SSE streams for entities with payloads
exceeding 512 bytes (e.g., climate DETAIL_ALL with many features).

Fix: use measureJson() in the heap fallback path to get the exact
untruncated size before allocating. Also add the missing set_size_()
call after the second serialization to ensure proper NUL termination.
2026-02-18 17:36:56 -06:00
J. Nick Koston
47ccb52184 Merge branch 'water-heater-web-server-traits' into integration 2026-02-18 17:06:53 -06:00
J. Nick Koston
1dc6801a19 Merge branch 'web-server-climate-preset' into integration 2026-02-18 17:06:44 -06:00
J. Nick Koston
3a53c5a689 [web_server] Fix water_heater traits in JSON state events
Move min/max temperature and step traits into DETAIL_ALL block
so they are only sent once on initial connection instead of on
every state update. Rename keys from min_temperature/max_temperature
to min_temp/max_temp to match what the frontend expects.

Discovered while reviewing #14061.
2026-02-18 16:58:08 -06:00
Ryan Wagoner
e27698f063 Fix clang-format for current_humidity ternary expression 2026-02-18 16:17:00 -05:00
J. Nick Koston
515ceaaf3e Merge remote-tracking branch 'origin/remove-iram-attr-yield-delay' into integration 2026-02-18 15:00:36 -06:00
J. Nick Koston
5bc9faa3de [core] Remove IRAM_ATTR from feed_wdt() and arch_feed_wdt()
feed_wdt() calls status_led::global_status_led->call() which is a
vtable dispatch into flash. arch_feed_wdt() calls esp_task_wdt_reset()
which is in .flash.text. Neither function can execute with the flash
cache disabled, so IRAM_ATTR provides no benefit.
2026-02-18 14:55:32 -06:00
J. Nick Koston
791bacfe59 Merge remote-tracking branch 'origin/remove-iram-attr-yield-delay' into integration 2026-02-18 14:51:42 -06:00
J. Nick Koston
ae1fa43799 [core] Remove unnecessary IRAM_ATTR from yield() and delay()
Neither yield() nor delay() can be called from ISR context or during
flash operations. yield() calls vPortYield/::yield which are not
ISR-safe, and delay() calls vTaskDelay/::delay which block the calling
task. IRAM_ATTR was applied as a blanket attribute when the HAL
abstraction was created in 2021 (#2303) but was never actually needed
for these two functions.

Retains HOT attribute for compiler optimization hints.
2026-02-18 14:44:12 -06:00
J. Nick Koston
6373aafe28 Merge branch 'http_request_remove_list' into integration
# Conflicts:
#	esphome/components/http_request/http_request.h
#	esphome/components/http_request/http_request_arduino.cpp
#	esphome/components/http_request/http_request_arduino.h
#	esphome/components/http_request/http_request_host.cpp
#	esphome/components/http_request/http_request_host.h
#	esphome/components/http_request/http_request_idf.cpp
#	esphome/components/http_request/http_request_idf.h
2026-02-18 14:32:52 -06:00
J. Nick Koston
4b6ba05e55 [http_request] Replace std::list<Header> with std::vector<Header> in perform() chain
std::list uses per-node heap allocation (one allocation per element)
and has poor cache locality. std::vector is contiguous and uses a
single allocation.

Changes:
- Replace std::list<Header> with std::vector<Header> in perform()
  virtual method signature across all platforms (IDF, Arduino, Host)
- Update all start(), get(), post() overloads accordingly
- Add ESPDEPRECATED overloads for std::list<Header> callers
- Update online_image to use std::vector<Header>
- Clean up request_headers construction in play() using structured
  bindings and reserve()
2026-02-18 14:29:07 -06:00
J. Nick Koston
ba6a1d192d [http_request] Use FixedVector for request_headers_ and json_ in action
The sizes are known at Python codegen time, so use FixedVector with
init() for a single allocation and no reallocation machinery. This
eliminates _M_realloc_append template instantiations for these types.
2026-02-18 14:25:10 -06:00
J. Nick Koston
bd07e6b014 [http_request] Replace std::map with std::vector<std::pair> in action template
request_headers_ and json_ are populated at config time via
add_request_header()/add_json() and only iterated linearly at
runtime. std::map's red-black tree is unnecessary overhead for
these small collections. Drop the <map> include.
2026-02-18 14:24:59 -06:00
J. Nick Koston
8307eadda2 [http_request] Lowercase collect headers at config time, eliminate per-request overhead
Move header lowercasing from the per-request start() path to config time:
- Python codegen now lowercases collect_headers values before passing to C++
- add_collect_header() stores values as-is (already lowered by Python)
- start() with std::vector is now a direct passthrough to perform()
- Deprecated std::set overload still lowercases for external callers

Rename collect_headers_ to lower_case_collect_headers_ and update all
parameter names throughout the chain to make the lowercase invariant
explicit in the API contract.

This eliminates per-request allocation of a temporary vector and
str_lower_case() calls on every HTTP request, reducing stack usage
in the perform() call chain where stack space is critical for HTTPS
TLS handshakes.
2026-02-18 14:21:17 -06:00
J. Nick Koston
4036accf7e Merge branch 'remove-dead-global-state' into integration 2026-02-18 13:51:03 -06:00
J. Nick Koston
6918624c69 [core] Remove dead global_state variable
The uint32_t global_state variable in component.cpp has no header
declaration and zero references anywhere in the codebase. Remove it.
2026-02-18 13:49:15 -06:00
Ryan Wagoner
fe6cec6a5d Fix fan_mode default when custom fan mode is active
Only default fan_mode to AUTO when no custom fan mode is set.
When a custom fan mode is active, send empty fan_mode to avoid
the frontend showing AUTO instead of the custom mode.
2026-02-18 14:32:51 -05:00
J. Nick Koston
f42ca69bf2 Merge branch 'conditionally-compile-setup-priority-override' into integration 2026-02-18 13:29:56 -06:00
J. Nick Koston
e4af9efa4e [core] Keep declarations unconditional to fix clang-tidy
component.h is included before defines.h in application.h,
so the #ifdef guards on declarations were evaluated before the
define was visible. Keep declarations always visible (harmless
unused declarations cost nothing) and only guard the definitions.
2026-02-18 13:28:53 -06:00
Ryan Wagoner
16deb55acb Add current_humidity to climate JSON when supported
Include current_humidity field in climate state JSON when the climate
device supports CLIMATE_SUPPORTS_CURRENT_HUMIDITY.
2026-02-18 14:17:58 -05:00
J. Nick Koston
6b7258c828 [core] Conditionally compile setup_priority override infrastructure
The setup_priority override mechanism (struct, vector, linear scan,
allocation, and cleanup) is only needed when a user explicitly sets
setup_priority: in their YAML config. In practice this is almost
never used - components define their priorities via C++ virtual
methods instead.

Gate the entire mechanism behind USE_SETUP_PRIORITY_OVERRIDE, which
is only defined when the codegen encounters a setup_priority: config
entry. This eliminates dead code (struct, std::vector with reserve,
new/delete, linear scan in get_actual_setup_priority) from nearly
all builds.

Also removes the unnecessary reserve(10) call since the override
count is always very small.
2026-02-18 13:17:22 -06:00
Ryan Wagoner
0cadca9c47 Default fan_mode to AUTO when supported but unset
Empty string is not a valid fan_mode value. When the climate supports
fan modes but no value has been set yet, default to AUTO.
2026-02-18 14:11:25 -05:00
Ryan Wagoner
4fe2fe8065 Always include fan_mode/custom_fan_mode in climate JSON and fix fan_modes trait check
Apply Option A (always include with empty string fallback) to fan_mode and
custom_fan_mode fields, matching the existing preset pattern. This prevents
stale values when SSE updates use Object.assign().

Also fix pre-existing bug where fan_modes list was gated on custom fan modes
instead of supports_fan_modes.
2026-02-18 13:54:12 -05:00
J. Nick Koston
e5267b3ebf Merge remote-tracking branch 'origin/app-placement-new' into integration 2026-02-18 12:43:14 -06:00
J. Nick Koston
f7f48abdf0 Fix #include <new> generating trailing semicolon 2026-02-18 12:42:52 -06:00
J. Nick Koston
2d9e214879 Merge branch 'app-dump-config-uint16' into integration 2026-02-18 12:41:59 -06:00
J. Nick Koston
103c234196 Add static_assert for Application default-constructibility 2026-02-18 12:31:31 -06:00
J. Nick Koston
386bd16fc4 [core] Shrink Application::dump_config_at_ from size_t to uint16_t
Components are indexed by ESPHOME_COMPONENT_COUNT which is a uint16_t-sized
StaticVector. Using size_t for the dump_config index wastes 2 bytes of storage
and adds padding. Move it to the uint16_t group for better struct packing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 12:28:26 -06:00
J. Nick Koston
c6792c980c Merge remote-tracking branch 'origin/app-placement-new' into integration 2026-02-18 12:24:26 -06:00
J. Nick Koston
0ba752e947 [core] Use placement new for global Application instance
Replace the global `Application App` with placement-new construction
in aligned .bss storage. This eliminates the global constructor and
destructor chain that were:

- Calling xSemaphoreCreateMutex() at static init time (via Scheduler's
  Mutex member) before app_main() runs
- Redundantly zero-initializing all members that .bss already zeroes
- Registering __cxa_atexit for ~Application() destructor chain
  (~Application, ~vector, ~Mutex) that never runs on embedded

The storage is a char[] with a GCC asm label matching the mangled name
of esphome::App. Other translation units see a typed extern Application
(identical codegen, no indirection), while the defining TU sees a
trivially-destructible char array — so the compiler never emits
__cxa_atexit or the destructor chain.

Construction happens in pre_setup() via placement new, which is always
the first method called on App in the generated setup() function.
2026-02-18 12:10:44 -06:00
Jonathan Swoboda
9cd7b0b32b [external_components] Clean up incomplete clone on failed ref fetch (#14051)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 18:09:33 +00:00
J. Nick Koston
2873f7f8f3 Merge branch 'api_varint_split_32_64' into integration 2026-02-18 10:23:08 -06:00
J. Nick Koston
65ef81656e Merge remote-tracking branch 'origin/integration' into integration 2026-02-18 10:21:35 -06:00
J. Nick Koston
960f83555d Merge remote-tracking branch 'origin/api-handshake-timeout' into integration 2026-02-18 10:21:24 -06:00
J. Nick Koston
5bc5ec921f [api] Add handshake timeout to prevent connection slot exhaustion
Add a 15-second timeout for completing the API handshake (Noise
transport + HelloRequest). Previously, a client could connect and
stall mid-handshake, holding a connection slot for up to 150 seconds
(the keepalive disconnect timeout). With max_connections defaulting
to 8 on ESP32, this allowed all slots to be blocked with minimal
effort.

Normal clients complete the full handshake in milliseconds, so 15
seconds is generous. The check short-circuits for authenticated
connections (single bitfield compare) so there is no overhead for
established sessions.
2026-02-18 10:20:34 -06:00
J. Nick Koston
f1d027262c Merge branch 'api-handshake-timeout' into integration 2026-02-18 10:05:07 -06:00
J. Nick Koston
473b7af9f0 [api] Add handshake timeout to prevent connection slot exhaustion
Add a 15-second timeout for completing the API handshake (Noise
transport + HelloRequest). Previously, a client could connect and
stall mid-handshake, holding a connection slot for up to 150 seconds
(the keepalive disconnect timeout). With max_connections defaulting
to 8 on ESP32, this allowed all slots to be blocked with minimal
effort.

Normal clients complete the full handshake in milliseconds, so 15
seconds is generous. The check short-circuits for authenticated
connections (single bitfield compare) so there is no overhead for
established sessions.
2026-02-18 10:04:09 -06:00
dependabot[bot]
f73bcc0e7b Bump cryptography from 45.0.1 to 46.0.5 (#14049)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-18 09:08:12 -06:00