Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finding the MAC address on macOS #284

Closed
bardiabarabadi opened this issue Sep 9, 2020 · 10 comments
Closed

Finding the MAC address on macOS #284

bardiabarabadi opened this issue Sep 9, 2020 · 10 comments

Comments

@bardiabarabadi
Copy link

  • bleak version: 0.7.1
  • Python version: 3.8
  • Operating System: macOS Catalina 10.15.6

Description

I managed to get a list of BLE devices using the same procedure as the scanner.py, i.e. the discover() method. Since I am using bleak on macOS, the returned device type is BLEDeviceCoreBluetooth which has some attributes including address.

The problem is that according to the documentation, the address field when using the macOS backend is actually the CBPeripheral identifier (and not the MAC address). Of course, this is not an issue by itself, but when I want to connect to the device using the BleakClient class, I need to have the MAC address (not the identifier).

Apparently, it is not possible to obtain the MAC address from the identifier (it changes every time).

Can you please tell me how can I get the MAC address, or alternatively use the identifier to connect to the BLE device via BleakClient class?

Thank you.

@dlech
Copy link
Collaborator

dlech commented Sep 9, 2020

Please see #140. Apple does not expose the Bluetooth address for security/privacy reasons.

@bardiabarabadi
Copy link
Author

Thanks for the response @dlech
Is there any way to connect to the BLE device using the BleakClient class on macOS (considering the fact that the Bluetooth address is not available?)

@dlech
Copy link
Collaborator

dlech commented Sep 9, 2020

If you are using the discover() function, then just call the connect() method on the device that was discovered.

@bardiabarabadi
Copy link
Author

Yes, I am using the discover() function. The only connect() method I found is in bleak/bleak/backends/corebluetooth/client.py in the BleakClientCoreBluetooth class. However, BleakClientCoreBluetooth requires an address to initialize (that is not available). Is this the connect() function you are referring to? If not, can you show me a quick example of how to import and use it?

@dlech
Copy link
Collaborator

dlech commented Sep 9, 2020

Right. So you can use the address attribute of the discovered device to create the client object. Bleak knows that macOS uses the UUID instead of the Bluetooth address.

import asyncio
from bleak import BleakClient, discover

async def run():
    devices = await discover()
    for d in devices:
        print(d)
        client = BleakClient(d.address)
        await client.connect()
        # do something with client


loop = asyncio.get_event_loop()
loop.run_until_complete(run())

@bardiabarabadi
Copy link
Author

Thank you for the code. That was actually the first thing I tried before opening this case. However, I rewrote the code to make sure that I am not missing anything and I got the same error (Device with address xxxxxx-xx-xxx-xxxxx was not found)

here is my code and the error I get:

import asyncio
from bleak import discover, BleakClient

async def find_muses():
    devices = await discover()
    muses = []
    print('found ' + str(len(devices)))
    for d in devices:
        if 'Muse' in d.name:
            print(d)
            muses.append(d)
            client = BleakClient(d.address)
            await client.connect()
    return muses

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    muses = loop.run_until_complete(find_muses())

Output:

found 20
55C835D6-B712-4109-8AFD-6760C227F601: Muse-C3DD
Traceback (most recent call last):
  File "/Users/bardiabarabadi/PycharmProjects/bleakTest/tester.py", line 26, in <module>
    muses = loop.run_until_complete(find_muses())
  File "/Users/bardiabarabadi/opt/miniconda3/envs/condaMuse/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/Users/bardiabarabadi/PycharmProjects/bleakTest/tester.py", line 16, in find_muses
    await client.connect()
  File "/Users/bardiabarabadi/opt/miniconda3/envs/condaMuse/lib/python3.8/site-packages/bleak/backends/corebluetooth/client.py", line 77, in connect
    raise BleakError(
bleak.exc.BleakError: Device with address 55C835D6-B712-4109-8AFD-6760C227F601 was not found

@dlech
Copy link
Collaborator

dlech commented Sep 10, 2020

Thanks for your persistence 😄 I see what is going on now. The connect() method in the BleakClient object does discovery again. For some reason your device doesn't get discovered the second time. Maybe you could add a longer timeout when calling connect()?

I think we could improve things by adding a connect method to the device object that returns a connected BleakClient object (and takes an arg for callbacks like suggested in #276 (comment)). This way we don't have to detect a device twice.

@dhalbert
Copy link

Also see #191.

@bardiabarabadi
Copy link
Author

Hello again. So the issue is gone now (by increasing the timeout) and I have to say that I impressed by your quick and professional responses. Thank you so much for developing and maintaining this library. I probably will get back with more questions, but until then I am going to close this thread. Cheers.

@dlech
Copy link
Collaborator

dlech commented Oct 7, 2022

FYI, I have found a hack for this. See #1073. Give it a 👍 if this is still a needed feature.

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

No branches or pull requests

3 participants