fix(hal): re-resolve a BLE device by name when its address goes stale - #141
Merged
Conversation
From the bench: a Maimu scanned fine, was added at the address the scan
reported, and then refused to initialize with bleak's
Device with address 20:79:13:0C:7D:30 was not found.
which reads like the device is switched off. It was not. Many BLE peripherals
advertise a resolvable private address that rotates every few minutes, so the
address the Scan button captured named nothing by the time anyone pressed
Connect. The same unit had a different address the day before.
_resolve_address returned the configured address and never consulted the
advertised name -- not even after a failure. Since the Scan button always fills
the address, the fragile path was the ordinary one, and the escape hatch (leave
the address blank, set the name) was the path nobody would find.
A connect failure now rescans for the configured name and retries once at
whatever address the peripheral is advertising now. A name does not rotate.
When the name resolves to the address that just failed this is not a rotation,
so the original error is reported rather than the same failure twice, and with
no name configured nothing changes.
The message for a name that resolves to nothing now names the two ordinary
causes, because "not found" is the most common BLE symptom and the least
informative: the peripheral is connected to something else -- one with a
central attached usually stops advertising, which is also why it vanishes from
scans -- or it is out of range.
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.
Straight from the bench. A Maimu scanned fine, was added at the address the scan reported, and then refused to initialize:
Which reads like the device is switched off. It wasn't — a phone app could see it the whole time.
Why
Many BLE peripherals advertise a resolvable private address that rotates every few minutes. The address the Scan button captured named nothing by the time Connect was pressed. Corroborating detail: the same unit had a different address the previous day (
68:7E:E9:…→20:79:13:…)._resolve_addressreturned the configured address and never consulted the advertised name — not even after a failure. Since the Scan button always fills the address, the fragile path was the ordinary one, and the escape hatch (leave address blank, set name) was the path nobody would find.The fix
A connect failure now rescans for the configured name and retries once at whatever address the peripheral is advertising now. A name doesn't rotate.
A better message for the most common BLE symptom
"Not found" is both the most frequent BLE failure and the least informative. When a name resolves to nothing, the error now names the two ordinary causes:
That second clause explains something else from the same session: the scan stopped listing the device while a phone app still showed it, because the phone was connected to it.
Tests — 4 new
A stale address re-resolved by name (asserting both connect attempts and exactly one rescan); no name means the original failure, unchanged, with no scan; a name resolving to the same dead address is not retried; and a name that resolves to nothing produces the explanatory message.
Verification
PYTHONPATH=src QT_QPA_PLATFORM=offscreen pytest tests/— 3641 passed, 4 skipped, ruff and black clean.