Skip to content

Fix BLE connection leaks and pair during setup - #24

Merged
Nailik merged 1 commit into
mainfrom
fix/connection-leaks-and-pairing
Oct 17, 2026
Merged

Nailik merged 1 commit into
mainfrom
fix/connection-leaks-and-pairing

Conversation

@Nailik

@Nailik Nailik commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

Fixes connection leaks and missing BLE pairing found while looking into #2.

Pairing during setup (#2)

client.py already connects with pair=True (#13), but the config flow and the random MAC scan open their own connections without it. All tracebacks in #2 come from config_flow.py validate_input → establish_connection, failing with failed to discover services, device disconnected.

Through an ESPHome proxy this works without a bond. ESP-IDF only runs service discovery and accepts the device's security request. BlueZ does more during discovery: it writes the Client Features and Service Changed descriptors and reads the GAP characteristics. On an "insufficient encryption/authentication" error it also raises link security by itself (src/shared/att.c change_security). Bonding first gives an encrypted link from the start, which matches the reports that it works after bluetoothctl pair or with test_cli.py. Which attribute the unit rejects is not confirmed yet; a btmon capture would show it.

Changes

  • Pair when connecting in the config flow and the random MAC scan
  • Skip random MAC candidates that raise a BleakError (BleakConnectionError is not an OSError) instead of aborting the scan
  • Filter the random MAC scan and the discovery callbacks by the advertised service UUID (847bba10…, as in manifest.json) instead of the characteristic UUID, which is never advertised
  • Close the BLE connection when pairing fails after connecting; before, it stayed open with nothing referencing it
  • Ignore disconnect callbacks of a previous client, so they no longer drop the current session and orphan a live connection
  • Disconnect after a failed request so the next call reconnects instead of reusing a half dead link

Tests

New tests for each change

Still needs testing with a CHOICE.All on a local adapter.

🤖 Generated with Claude Code

- Pair when connecting in the config flow and the random MAC scan,
  BlueZ fails service discovery without a bond (#2)
- Skip random MAC candidates that raise a BleakError instead of
  aborting the scan
- Filter scan and discovery callbacks by the advertised service UUID
  instead of the characteristic UUID
- Close the BLE connection when pairing fails after connecting
- Ignore disconnect callbacks of a previous client so they don't drop
  the current session
- Disconnect after a failed request so the next call reconnects

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Nailik
Nailik merged commit c6d1d42 into main Oct 17, 2026
3 checks passed
@Vurgus

Vurgus commented Oct 17, 2026

Copy link
Copy Markdown

Habe soeben das Pre-Release 0.0.13 mit meinem CHOICE.All getestet. Das Pairing mit lokalen Adapter hat bei mir leider nicht geklappt.
image

@Nailik

Nailik commented Oct 17, 2026

Copy link
Copy Markdown
Owner Author

@Vurgus kannst du debug logging anschalten und die logs hier hinzufügen?

@Vurgus

Vurgus commented Oct 17, 2026

Copy link
Copy Markdown

@Nailik klar kein Problem. Bin neu im HA. Daher hoffe ich, dass ich das richtig gemacht habe.
Habe in meiner configuration.yaml folgendes hinzugefügt:

logs:
    custom_components.blanco_unit: debug
    homeassistant.components.bluetooth: debug
    bleak: debug

nach dem Verbindungsversuch ist unter Einstellungen -> System -> Protokolle folgendes aufgetaucht:

Dieser Fehler stammt von einer benutzerdefinierten Integration

Logger: custom_components.blanco_unit.config_flow
Quelle: custom_components/blanco_unit/config_flow.py:177
Integration: Blanco Unit (Dokumentation, Probleme)
Erstmals aufgetreten: 19:11:11 (1 Vorkommnis)
Zuletzt protokolliert: 19:11:11

Unexpected error during validation
Traceback (most recent call last):
  File "/config/custom_components/blanco_unit/config_flow.py", line 177, in validate_input
    validation = await validate_pin(client, pin_str)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/blanco_unit/client.py", line 993, in validate_pin
    response = await protocol.send_pairing_request(client, pin)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/blanco_unit/client.py", line 365, in send_pairing_request
    await client.write_gatt_char(CHARACTERISTIC_UUID, packet, response=True)
  File "/usr/local/lib/python3.14/site-packages/bleak/__init__.py", line 835, in write_gatt_char
    await self._backend.write_gatt_char(characteristic, data, response)
  File "/usr/local/lib/python3.14/site-packages/bleak/backends/bluezdbus/client.py", line 834, in write_gatt_char
    assert_gatt_reply(reply)
    ~~~~~~~~~~~~~~~~~^^^^^^^
  File "/usr/local/lib/python3.14/site-packages/bleak/backends/bluezdbus/utils.py", line 112, in assert_gatt_reply
    assert_reply(reply)
    ~~~~~~~~~~~~^^^^^^^
  File "/usr/local/lib/python3.14/site-packages/bleak/backends/bluezdbus/utils.py", line 34, in assert_reply
    raise BleakDBusError(reply.error_name, reply.body)
bleak.exc.BleakDBusError: [org.bluez.Error.Failed] Not connected

Ansonsten sag mir, was ich machen kann oder ob du mehr brauchst.

@Vurgus

Vurgus commented Oct 17, 2026

Copy link
Copy Markdown

@Nailik habe noch das hier gefunden:
home-assistant_2026-10-17T17-20-52.228Z.log

@Nailik

Nailik commented Oct 17, 2026

Copy link
Copy Markdown
Owner Author

@Vurgus please test https://github.com/Nailik/blanco_unit/releases/tag/0.0.14 and https://github.com/Nailik/blanco_unit/releases/tag/0.0.15-mtu-sized-packages

Before testing please try to remove the old integration and reboot HomeAssistant (maybe also the OS HomeAssistant is running on), potentially also reboot the blanco unit just to make sure.
If that doesn't help either factory resetting the blanco unit might help.

@Vurgus

Vurgus commented Oct 23, 2026

Copy link
Copy Markdown

@Nailik I tested https://github.com/Nailik/blanco_unit/releases/tag/0.0.14
I only "updated" the integration to this version (0.0.14) without reinstall, reboot or factory reset.
Pairing is now available with my Blanco Choice All:
image
After some time there are no values and the device is disconnected:
image
After 1 minute it reconnects:
image
I upload a new log:
home-assistant_2026-10-23T17-50-27.409Z.log
image

Let me test the pre-release 0.0.14 for the next days an I will give you an update.

github-actions Bot pushed a commit to alexhaller/blanco_unit that referenced this pull request Nov 9, 2026
## [2.0.2](v2.0.1...v2.0.2) (2026-11-09)

### Bug Fixes

* harden the BLE connection against leaks and stuck GATT operations ([ef3c1fa](ef3c1fa)), closes [Nailik#24](https://github.com/alexhaller/blanco_unit/issues/24) [Nailik#25](https://github.com/alexhaller/blanco_unit/issues/25) [Nailik#27](https://github.com/alexhaller/blanco_unit/issues/27)
* point the documentation and issue links at this repository ([d423f16](d423f16)), closes [hacs/default#13647](hacs/default#13647)
* stop reporting the filter and CO2 capacity as a battery ([5311f42](5311f42))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants