std::lerp includes NaN/infinity edge-case handling per C++20 spec which
adds ~200 bytes of overhead per call. With 10 fields interpolated, this
bloated the symbol to 2,038 bytes on BK72xx. Since all light color values
are pre-clamped finite floats, a simple a + t * (b - a) is sufficient.
Reduces LightColorValues::lerp from 2,038 B to 286 B on BK72xx.
Also saves 16 bytes on ESP8266.
std::lerp includes NaN/infinity edge-case handling per C++20 spec, which
generates ~200 bytes of overhead per call. With 10 fields interpolated,
this bloated the symbol to 2,038 bytes. Since all light color values are
pre-clamped finite floats, a simple a + t * (b - a) is sufficient.
Reduces LightColorValues::lerp from 2,038 B to 286 B (86% reduction).
Old clients (before 2026.3.0) send only the timezone string without the
parsed_timezone struct, so all fields default to zero. Without this check,
the device would overwrite its codegen-configured timezone with UTC.
Keep the codegen timezone when the struct is unpopulated (all zeros).
For actual UTC this also skips, which is harmless since UTC is the default.
Move tests that use make_us_central(), set_global_tz(), ParsedTimezone,
and DSTRuleType into esphome::time::testing namespace where those symbols
are declared.
Remove the runtime POSIX TZ string parser and all associated bridge code
now that timezone data is sent as pre-parsed structs via protobuf.
Removed:
- parse_posix_tz() and internal parsing helpers (skip_tz_name, parse_offset,
parse_dst_rule, parse_uint, parse_transition_time)
- RealTimeClock::set_timezone() overloads and apply_timezone_()
- API connection fallback path for string-based timezone
Kept:
- All conversion functions (epoch_to_local_tm, is_in_dst, calculate_dst_transition)
- Internal helpers used by conversion functions
- localtime_r/localtime overrides
- Tests for all permanent functions
On ESP8266, .rodata is mapped to DRAM (RAM), not flash. When
StructInitializer is used with all compile-time constant fields,
the compiler places the entire struct as a const blob in .rodata,
silently consuming ~20 bytes of RAM.
Switch to field-by-field assignment on ESP8266 so the IP address
values are encoded as immediate operands in flash instructions
instead of a .rodata blob. Other platforms continue to use the
aggregate initializer since their .rodata is flash-mapped.
Fixes redeclaration error when multiple time platforms are in the
same build by wrapping the local ParsedTimezone variable in a scope block.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The C++ POSIX TZ string parser is only needed for backward compatibility
with older Home Assistant clients that send the timezone as a string.
Once all clients send the pre-parsed ParsedTimezone protobuf struct,
the parser and its helpers can be removed entirely.
See https://github.com/esphome/backlog/issues/91
build_info_data.h contains ESPHOME_BUILD_TIME which changes every build.
Since application.h included it, changing any source file caused
build_info_data.h to be rewritten (via sources_changed), which then
triggered a rebuild of every file that includes application.h.
Move all build_info_data.h dependent code from application.h inline
methods to application.cpp, so only application.cpp recompiles when
build info changes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
build_info_data.h contains ESPHOME_BUILD_TIME which changes every build.
Since application.h included it, changing any source file caused
build_info_data.h to be rewritten (via sources_changed), which then
triggered a rebuild of every file that includes application.h.
Move all build_info_data.h dependent code from application.h inline
methods to application.cpp, so only application.cpp recompiles when
build info changes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
build_info_data.h contains ESPHOME_BUILD_TIME which changes every build.
Since application.h included it, changing any source file caused
build_info_data.h to be rewritten (via sources_changed), which then
triggered a rebuild of every file that includes application.h.
Move all build_info_data.h dependent code from application.h inline
methods to application.cpp, so only application.cpp recompiles when
build info changes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
build_info_data.h contains ESPHOME_BUILD_TIME which changes every build.
Since application.h included it, changing any source file caused
build_info_data.h to be rewritten (via sources_changed), which then
triggered a rebuild of every file that includes application.h.
Move all build_info_data.h dependent code from application.h inline
methods to application.cpp, so only application.cpp recompiles when
build info changes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
build_info_data.h contains ESPHOME_BUILD_TIME which changes every build.
Since application.h included it, changing any source file caused
build_info_data.h to be rewritten (via sources_changed), which then
triggered a rebuild of every file that includes application.h.
Move all build_info_data.h dependent code from application.h inline
methods to application.cpp, so only application.cpp recompiles when
build info changes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
If CLOSE_EVT never arrives after DISCONNECT_EVT, the client gets
stuck in DISCONNECTING forever, blocking reconnection and scanner
restart. Add a 10s timeout watchdog in loop() that forces IDLE
as a recovery path.
Introduce set_disconnecting_() helper to ensure the timeout
timestamp is always set when entering DISCONNECTING state.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Separate the DISCONNECTING state into its own log message that
mentions waiting for CLOSE_EVT, making it easier to diagnose
stuck connections vs normal in-progress connections.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Separate the DISCONNECTING state into its own log message that
mentions waiting for CLOSE_EVT, making it easier to diagnose
stuck connections vs normal in-progress connections.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>