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>
The CLOSE_EVT handler matches on conn_id_ to call set_idle_().
Resetting conn_id_ to UNSET_CONN_ID before CLOSE_EVT arrives
causes the event to be dropped, leaving the client stuck in
DISCONNECTING state permanently.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When OPEN_EVT arrives with a failure status, the connection was never
established so no CLOSE_EVT may follow. Reset conn_id_ to prevent a
stale value from matching a future CLOSE_EVT.
Instead of a separate early-return for DISCONNECTING state, let the
failed OPEN_EVT fall through to the existing failed-status handler
which already transitions to IDLE.
When a connection fails to establish, the ESP-IDF stack sends
DISCONNECT_EVT followed by OPEN_EVT with a failure status (e.g. 133).
No CLOSE_EVT follows since no GATT connection was established.
Previously the OPEN_EVT in DISCONNECTING state was silently ignored,
leaving the client stuck in DISCONNECTING forever. Now we treat this
failed OPEN_EVT as the terminal event and transition to IDLE.
Replace division-based line number formatting in LogBuffer::write_header
with subtraction loops. The ESP8266 (Xtensa lx106) lacks a hardware
divider, so each division compiles to an expensive software function call.
Measured on real ESP8266 hardware (10000 iterations x 13 test values):
- Division: 213,029 us
- Subtraction: 118,503 us (1.8x faster)
Flash savings:
- ESP8266: -36 bytes (323 -> 287)
- ESP32: -23 bytes (326 -> 303)
sound_level and wireguard were getting automation.h transitively
through sensor/filter.h. Now that filter.h is conditionally compiled,
add the direct includes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
bme680_bsec, haier, and kamstrup_kmp were getting <queue> transitively
through sensor/filter.h. Now that filter.h is conditionally compiled,
add the direct include.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When no binary sensor filters are configured, the entire Filter class
hierarchy (filter.h/filter.cpp) is still compiled and linked into the
binary. This includes delayed_on, delayed_off, delayed_on_off, invert,
autorepeat, lambda, settle, and timeout filter classes.
Add USE_BINARY_SENSOR_FILTER define that is only emitted when at least
one binary sensor has filters configured. Wrap filter-related code
behind this define to eliminate dead code from the binary.
When no sensor filters are configured, the entire Filter class
hierarchy (filter.h/filter.cpp) is still compiled and linked into
the binary. This includes ~20 filter classes (sliding window, median,
quantile, exponential moving average, throttle, debounce, heartbeat,
delta, calibrate, clamp, NTC, streaming filters, etc.)
Add USE_SENSOR_FILTER define that is only emitted when at least one
sensor has filters configured. Wrap filter-related code behind this
define to eliminate dead code from the binary.