When an interval fires in Scheduler::call(), push it directly back into
items_ via push_back() + push_heap() instead of routing through the
to_add_ staging vector and process_to_add_slow_path_().
This eliminates per-cycle overhead of process_to_add_slow_path_() which
acquires a lock, iterates to_add_, pushes each item into the heap, clears
the vector, and resets the atomic counter.
Add cv.ByteLength() validator that checks UTF-8 byte length instead
of character count. This ensures multibyte characters don't cause
the encoded string to exceed the proto max_data_length limit.
Switch all length validators that feed into proto fields with
max_data_length annotations to use byte length:
- Entity names, friendly names, area names, device names
- Icons, device classes, units of measurement
- Board names, project name/version
Add BOARD_MAX_LENGTH and PROJECT_MAX_LENGTH constants (127) and
enforce them in YAML validation for all platform board schemas
and project name/version.
Add max_data_length + force proto options to model, project_name,
and project_version fields in DeviceInfoResponse.
Move the notify_*_update() method definitions from controller_registry.cpp
into controller_registry.h as inline functions. These are tiny loops over
1-2 controllers that each have a single call site in the entity's
notify_frontend_() method.
When defined in a separate TU, the compiler cannot inline them at the call
site without LTO, resulting in an unnecessary function-call frame on every
state publish. CodSpeed profiling of the CallbackManager container change
(#15272) showed this extra frame accounting for ~12% regression in text
sensor publish benchmarks.
controller_registry.h is only ever included from .cpp files (never from
other headers), so including controller.h after the class definition is
safe and introduces no circular dependencies.
Add a max_data_length field option to api_options.proto for string/bytes
fields. When max_data_length < 128 and force = true, the code generator
uses encode_short_string_force() — a single call that writes the tag
byte, 1-byte length varint, and raw string data with no branching. Size
calculation simplifies from calc_length(1, size) to 2 + size.
Annotate entity fields across all 25 ListEntities*Response messages:
- name and object_id: max_data_length = 120, force = true (50 fields)
- icon: max_data_length = 63 (25 fields)
The 120 and 63 values match NAME_MAX_LENGTH and ICON_MAX_LENGTH in
esphome/core/config.py, validated at config time.
Add a crash handler for ESP8266 that captures and logs crash data
from previous boots, matching the existing ESP32 and RP2040
implementations. Uses the SDK's rst_info (always available after
reboot) for basic crash info and Arduino's custom_crash_callback
to scan the stack for return addresses stored in RTC user memory.