Conversation
Two orthogonal hardening fixes for ESP32 setups that pair more than
one BRC1H and need to survive Wi-Fi flaps.
1. BLE watchdog. After a Wi-Fi flap the BLE stack occasionally reports
ESTABLISHED but the pulse never replies again — parse_cb_() stops,
current_temperature stays NAN, and HA's commands disappear into the
void. Only a physical power-cycle of the ESP32 recovers.
Track last_response_ms_; if it exceeds 5 minutes while node_state
is ESTABLISHED, issue a per-channel disconnect (the other BRC1H
pair is left alone). After 3 consecutive failures, fall back to
App.safe_reboot() as a safety net.
- parse_cb_() refreshes the timestamp on every successful reply.
- REG_FOR_NOTIFY_EVT refreshes the timestamp on (re)connect so a
long disconnect interval does not immediately trip the watchdog.
- The watchdog only runs once a reply has been seen at all
(last_response_ms_ > 0), so a fresh flash with an unpaired pulse
does not reboot-loop.
2. Multi-client gattc_if filter. Recent ESPHome versions dispatch the
same gattc_event_handler to every BLEClientNode registered against
the same esp32_ble interface, regardless of which BLE connection
the callback actually belongs to. Without filtering, a
DISCONNECT_EVT from the OTHER BRC1H wipes our
current_temperature/target_temperature to NAN. Filter at the top
of the handler by gattc_if.
|
To use the changes from this PR as an external component, add the following to your ESPHome configuration YAML file: external_components:
- source: github://Petapton/esphome@pull/16/head
components: [daikin_madoka]
refresh: 1h(Added by the PR bot) |
The same broadcast issue that affected gattc_event_handler also affects gap_event_handler — GAP security events are delivered to every BLEClientNode regardless of ownership. With two BRC1H paired to one ESP, an AUTH_CMPL_EVT from the OTHER pulse calls our handler with a remote address that doesn't match this->parent_->get_remote_bda(), drives try_register_notifications_() against the wrong remote, and logs a noisy 'No control service found at device, not a Daikin Madoka..?' warning. GAP events don't carry a gattc_if so filter by remote_bda extracted from whichever sub-struct of ble_security the specific event uses (ble_req.bd_addr or auth_cmpl.bd_addr).
Owner
|
Can't reproduce. Please at least provide logs. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three orthogonal hardening fixes for ESP32 setups that pair more than one BRC1H and need to survive Wi-Fi flaps.
1. BLE watchdog
After a Wi-Fi flap (or a stray bluedroid race) the BLE stack occasionally reports
ESTABLISHEDbut the pulse never replies again —parse_cb_()stops,current_temperaturestays NAN, and HA's commands disappear into the void. Only a physical power-cycle of the ESP32 recovers.Track
last_response_ms_; if it exceeds 5 minutes whilenode_stateisESTABLISHED, issue a per-channel disconnect (the other BRC1H pair is left alone). After 3 consecutive failures, fall back toApp.safe_reboot()as a safety net.parse_cb_()refreshes the timestamp on every successful reply.REG_FOR_NOTIFY_EVTrefreshes the timestamp on (re)connect so a long disconnect interval does not immediately trip the watchdog.last_response_ms_ > 0), so a fresh flash with an unpaired pulse does not reboot-loop.2. Multi-client
gattc_iffilterRecent ESPHome versions dispatch the same
gattc_event_handlerto everyBLEClientNoderegistered against the sameesp32_bleinterface, regardless of which BLE connection the callback actually belongs to. Without filtering, aDISCONNECT_EVTfrom the OTHER BRC1H wipes ourcurrent_temperature/target_temperatureto NAN — observed on dual-pair setups where one pulse stays connected and the other is in a reconnect loop.Filter at the top of the handler by
gattc_if.3. Multi-client
remote_bdafilter (GAP variant)Same broadcast issue affects
gap_event_handlertoo. AnAUTH_CMPL_EVTfrom the OTHER BRC1H reaches our handler with a remote address that doesn't matchthis->parent_->get_remote_bda(), drivestry_register_notifications_()against the wrong remote, and logs noisyNo control service found at device, not a Daikin Madoka..?warnings. GAP events don't carry agattc_if, so filter byremote_bdaextracted fromparam->ble_security.{ble_req,auth_cmpl}.bd_addr.Test plan
gattc_iffilter — DISCONNECT events from one BRC1H no longer wipecurrent_temperatureof the other one (reproducible regression on ESPHome 2026.5).remote_bdaGAP filter — eliminatesNo control service foundlog noise during reconnect of the second pair.🤖 Generated with Claude Code