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.
When no text sensor filters are configured, the entire Filter class
hierarchy (filter.h/filter.cpp) was still compiled and linked. This
pulled in std::string manipulation code (_M_mutate, _M_create,
_M_append, _M_replace, _M_assign, _M_dispose) that is only needed
for filter chain processing.
Add USE_TEXT_SENSOR_FILTER define that is only emitted when at least
one text sensor has filters configured. Wrap filter-related code
behind this define to eliminate dead code from the binary.
Saves ~340 bytes of flash on configs with filterless text sensors.