Repository navigation
pb-service: aio-rfcomm 1.1, and say when macOS is asking for Bluetooth - #8
Merged
Merged
Conversation
1.1 stops waiting for the answer to macOS's Bluetooth permission dialog and reports AWAITING_PERMISSION meanwhile, says NOT_ALLOWED rather than UNSUPPORTED for a refused permission, and names the program in both messages. What follows depends on the first: until now a scan started while the dialog was open sat waiting and then told the user to pair the hub.
…ts answer On macOS the first use of Bluetooth Classic asks the user whether the service may use it, and with aio-rfcomm 1.1 nothing can be listed until they answer. A scan or connect started meanwhile ran out after ten seconds and told the user to pair a hub that was paired. Transports now name why an adapter cannot be used in a word, one per aio-rfcomm Availability, alongside the system's sentence. While a search runs, the service reports the adapters it cannot use as hub.adapters, and while permission is being asked and nothing has been found it holds the search's time limit still, for up to two minutes. Bluetooth errors carry the word too. pb-client follows those with watching_adapters(). pb scan and pb connect say at once that macOS is asking, under the name the dialog shows, and carry on when the dialog is answered. When Bluetooth cannot be used, the suggestion now fits the reason rather than covering every reason at once. A failed open keeps its reason instead of always reading unsupported. The RFCOMM transport replaces what it reports at the end of each pass, so a client watching does not see it flicker, and starts each scan without the last one's.
macOS shows this name in the permission dialog and under Privacy & Security. Plain "Pybricks" reads there as the Pybricks app or Pybricks Code, and says nothing about what is asking or why. What asks is the part of the service that reaches EV3 and NXT hubs over Bluetooth Classic. macOS remembers the answer against the name, so everyone is asked once more, and the old "Pybricks" entry stays in Privacy & Security until it is removed there.
There was a problem hiding this comment.
🟡 Changes recommended
Queued searches can inherit another search’s adapter state, causing unrelated permission prompts and incorrect timeout extensions.
1 open issue
What changed in this PR
Updates Bluetooth discovery for aio-rfcomm 1.1 so users receive permission guidance while scans and connections wait for an answer.
Changes:
- Adds adapter availability notifications and bounded permission-related timeout extensions.
- Exposes adapter watching in the client and reason-specific guidance in the CLI.
- Renames the macOS permission identity and adds regression coverage.
| File | Description |
|---|---|
| uv.lock | Locks aio-rfcomm 1.1.0. |
| tests/e2e/test_hub_lifecycle.py | Tests permission waiting and recovery. |
| tests/e2e/test_commands.py | Tests CLI permission guidance. |
| packages/pb-service/tests/test_rfcomm_transport.py | Tests availability reasons and recovery. |
| packages/pb-service/tests/test_rfcomm_lazy.py | Tests preserved opening errors and permission transitions. |
| packages/pb-service/src/pb_service/methods/hub.py | Reports adapter state and extends search deadlines. |
| packages/pb-service/src/pb_service/hub/transport.py | Adds structured availability reasons. |
| packages/pb-service/src/pb_service/hub/rfcomm/transport.py | Publishes stable adapter availability state. |
| packages/pb-service/src/pb_service/hub/rfcomm/lazy.py | Preserves Bluetooth opening failure reasons. |
| packages/pb-service/src/pb_service/hub/rfcomm/fake.py | Simulates specific availability states. |
| packages/pb-service/src/pb_service/backend.py | Sets the macOS permission identity. |
| packages/pb-service/pyproject.toml | Requires aio-rfcomm 1.1. |
| packages/pb-core/src/pb_core/protocol.py | Defines adapter notifications. |
| packages/pb-client/src/pb_client/service.py | Adds adapter watching. |
| packages/pb-client/src/pb_client/models.py | Adds the unusable-adapter model. |
| packages/pb-client/src/pb_client/__init__.py | Exports the adapter model. |
| packages/pb-cli/tests/test_errors.py | Tests availability advice and permission naming. |
| packages/pb-cli/src/pb_cli/errors.py | Provides reason-specific Bluetooth advice. |
| packages/pb-cli/src/pb_cli/commands/hub.py | Displays permission prompts during searches. |
Review effort: Balanced
Only one scan runs at a time, so a search arriving during another waits for the radio. Until it has it, what the transports report is the other search's. A USB-only search queued behind an RFCOMM one held by the permission dialog was told about that dialog, had its own time limit held by it, and, if its time ran out in the queue, failed with that search's Bluetooth error. HubManager.discover() now says when a scan has the radio. Until then the search follows nothing, holds nothing, and explains an empty result only as nothing found.
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.

Moves pb-service to aio-rfcomm 1.1.0, released today, and handles the one change in it that users see. On macOS, opening Bluetooth no longer waits for the user to answer the permission dialog. Until they answer, the availability is
AWAITING_PERMISSION.Before this change, a
pb scanorpb connectstarted while that dialog was open waited ten seconds. It then said "No hubs found. Is the hub paired with this computer?" or told the user to pair the hub, although the hub was paired.Three commits:
uv.lock. First, so that each commit passes on its own.Availability(UnavailableDevice.availability). The system's own sentence is kept alongside it.hub.adaptersnotification: while a scan or connect is looking, the service reports the adapters it can't use. Adding a notification doesn't move the protocol version.BLUETOOTH_UNAVAILABLEerrors carry the word indata.Service.watching_adapters().pb scanandpb connectsay at once that macOS is asking, under the name the dialog shows, and carry on when the dialog is answered. When Bluetooth can't be used, the suggestion now depends on the reason, rather than one suggestion covering every reason.Tested on macOS 26.6.2 with a Pybricks EV3, firmware 4.1.0:
pb scan --transport rfcommprinted "macOS is asking whether Pybricks RFCOMM Service may use Bluetooth. Answer the dialog to carry on." 2 s in, and carried on after Allow.Known, and not addressed here: