hbldh / bleak Goto Github PK
View Code? Open in Web Editor NEWA cross platform Bluetooth Low Energy Client for Python using asyncio
License: MIT License
A cross platform Bluetooth Low Energy Client for Python using asyncio
License: MIT License
Trying to modify service_explorer python code and adding GCP connection.
def sendDataToPubSub(data):
project_id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
topic_name = "cchain_test_topic"
cred = service_account.Credentials.from_service_account_file(
filename="//us-con-gcp-npr-0xxxxxxxxxxxx.json"
)
publisher = pub.PublisherClient(credentials=cred)
topic_path = publisher.topic_path(project_id, topic_name)
publisher.publish(
topic_path,
data="",
sensor_timestamp=str(data.get("timestamp")),
latitude=str(data.get("latitude")),
longitude=str(data.get("longitude")),
ambient_temperature=str(data.get("ambient_temperature")),
relative_humidity=str(data.get("relative_humidity")),
barometeric_pressure=str(data.get("barometeric_pressure")),
magnetometer_data_x=str(data.get("magnetometer_data_x")),
magnetometer_data_y=str(data.get("magnetometer_data_y")),
magnetometer_data_z=str(data.get("magnetometer_data_z")),
accerometer_data_x=str(data.get("accerometer_data_x")),
accerometer_data_y=str(data.get("accerometer_data_y")),
accerometer_data_z=str(data.get("accerometer_data_z")),
gyroscope_data_x=str(data.get("gyroscope_data_x")),
gyroscope_data_y=str(data.get("gyroscope_data_y")),
gyroscope_data_z=str(data.get("gyroscope_data_z")),
optical_sensor_data=str(data.get("optical_sensor_data")),
device_id=str(data.get("device_id")),
geo_location=str(data.get("latitude")) + "," + str(data.get("longitude"))
)
Trying to connect Bleak with GCP IoT
When I try reading protected characteristic, the Python process crashes, instead of throwing an exception.
import asyncio
import logging
from bleak import BleakClient
logging.basicConfig(level=logging.DEBUG)
address = "A0E49DB2-B7F1-4A65-AB2E-D75121192329"
async def read_char(address, loop):
async with BleakClient(address, loop=loop) as client:
characteristic = await client.read_gatt_char("0000fe01-0000-1000-8000-00805f9b34fb")
print(characteristic)
loop = asyncio.get_event_loop()
loop.run_until_complete(read_char(address, loop))
2019-08-18 13:17:46.582 Python[96403:3684947] *** Terminating app due to uncaught exception 'OC_PythonException', reason: '<class 'bleak.exc.BleakError'>: Failed to read characteristic FE01: Error Domain=CBATTErrorDomain Code=2 "Reading is not permitted." UserInfo={NSLocalizedDescription=Reading is not permitted.}'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff3d2662fd __exceptionPreprocess + 256
1 libobjc.A.dylib 0x00007fff67933a17 objc_exception_throw + 48
2 CoreFoundation 0x00007fff3d27fe59 -[NSException raise] + 9
3 _objc.cpython-37m-darwin.so 0x00000001038ca20e PyObjCErr_ToObjCWithGILState + 46
4 _objc.cpython-37m-darwin.so 0x00000001038db867 method_stub + 5367
5 _objc.cpython-37m-darwin.so 0x0000000103905560 ffi_closure_unix64_inner + 656
6 _objc.cpython-37m-darwin.so 0x0000000103904aa6 ffi_closure_unix64 + 70
7 CoreBluetooth 0x00007fff3cce500e -[CBPeripheral handleCharacteristicEvent:characteristicSelector:delegateSelector:delegateFlag:] + 115
8 CoreBluetooth 0x00007fff3cce0a7e -[CBPeripheral handleMsg:args:] + 297
9 CoreBluetooth 0x00007fff3ccdb368 -[CBCentralManager handleMsg:args:] + 198
10 CoreBluetooth 0x00007fff3ccd67db __30-[CBXpcConnection _handleMsg:]_block_invoke + 53
11 libdispatch.dylib 0x00007fff690b35f8 _dispatch_call_block_and_release + 12
12 libdispatch.dylib 0x00007fff690b463d _dispatch_client_callout + 8
13 libdispatch.dylib 0x00007fff690ba8e0 _dispatch_lane_serial_drain + 602
14 libdispatch.dylib 0x00007fff690bb3c6 _dispatch_lane_invoke + 433
15 libdispatch.dylib 0x00007fff690bf54b _dispatch_main_queue_callback_4CF + 813
16 CoreFoundation 0x00007fff3d1b02d7 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
17 CoreFoundation 0x00007fff3d1afa01 __CFRunLoopRun + 2289
18 CoreFoundation 0x00007fff3d1aeebe CFRunLoopRunSpecific + 455
19 Foundation 0x00007fff3f4137df -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 280
20 _objc.cpython-37m-darwin.so 0x0000000103904927 ffi_call_unix64 + 79
21 ??? 0x00000001052c5f10 0x0 + 4381761296
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
On linux (backends/bluezdbus/client.py
), connect()
function uses discover()
with a timeout : await discover(timeout=0.1, loop=self.loop)
(here).
On windows (backends/dotnet/client.py
), connect()
function uses discover()
with a defined value: devices = await discover(2.0, loop=self.loop)
(here), which leads to random errors due to the fact that Windows is unable to discover the device to connect to within 2 seconds.
Since discover()
has a timeout var, it can be good to use timeout=2.0
instead of 2.0
in client.py
, so developers can adapt the value without having to manually change Bleak.
Notification handler passed to start_notify cannot raise uncaught exception without leading to a cryptic crash
Using the enable_notification.py sample, I tried to add some code to the notification handler in order to parse the notified message. However, my code contained a bug which caused the code to raise an exception. I simplified the problem and realised that any exception in the notification handler will result in a terrible crash.
def p():
print('Yo')
raise ArithmeticError
def notification_handler(sender, data):
"""Simple notification handler which prints the data received."""
print("{0}: {1}".format(sender, data))
p()
which lead to
Yo
2019-09-03 19:57:12.341 Python[54571:306992] *** Terminating app due to uncaught exception 'OC_PythonException', reason: '<class 'ArithmeticError'>: '
*** First throw call stack:
(
0 CoreFoundation 0x00007fff2cedacfd __exceptionPreprocess + 256
1 libobjc.A.dylib 0x00007fff57580a17 objc_exception_throw + 48
2 CoreFoundation 0x00007fff2cef485d -[NSException raise] + 9
3 _objc.cpython-37m-darwin.so 0x000000010763b20e PyObjCErr_ToObjCWithGILState + 46
4 _objc.cpython-37m-darwin.so 0x000000010764c867 method_stub + 5367
5 _objc.cpython-37m-darwin.so 0x0000000107676560 ffi_closure_unix64_inner + 656
6 _objc.cpython-37m-darwin.so 0x0000000107675aa6 ffi_closure_unix64 + 70
7 CoreBluetooth 0x00007fff2c963022 -[CBPeripheral handleCharacteristicEvent:characteristicSelector:delegateSelector:delegateFlag:] + 115
8 CoreBluetooth 0x00007fff2c95ea92 -[CBPeripheral handleMsg:args:] + 297
9 CoreBluetooth 0x00007fff2c95937c -[CBCentralManager handleMsg:args:] + 198
10 CoreBluetooth 0x00007fff2c9547ef __30-[CBXpcConnection _handleMsg:]_block_invoke + 53
11 libdispatch.dylib 0x00007fff58d005f8 _dispatch_call_block_and_release + 12
12 libdispatch.dylib 0x00007fff58d0163d _dispatch_client_callout + 8
13 libdispatch.dylib 0x00007fff58d078e0 _dispatch_lane_serial_drain + 602
14 libdispatch.dylib 0x00007fff58d083c6 _dispatch_lane_invoke + 433
15 libdispatch.dylib 0x00007fff58d0c54b _dispatch_main_queue_callback_4CF + 813
16 CoreFoundation 0x00007fff2ce24cd7 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
17 CoreFoundation 0x00007fff2ce24401 __CFRunLoopRun + 2289
18 CoreFoundation 0x00007fff2ce238be CFRunLoopRunSpecific + 455
19 Foundation 0x00007fff2f0878ef -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 280
20 _objc.cpython-37m-darwin.so 0x0000000107675927 ffi_call_unix64 + 79
21 ??? 0x000000010aa44610 0x0 + 4473505296
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Abort trap: 6
Shouldn't it raise the python exception at least?
Trying to run example python code.
(base) C:\Users\amit\Documents\GitHub\bleak\examples>python sensortag.py
poll 2000.000 ms took 2000.000 ms: timeout
poll took 172.000 ms: 1 events
poll took 172.000 ms: 1 events
poll took 16.000 ms: 1 events
poll took 0.000 ms: 1 events
poll took 0.000 ms: 1 events
poll took 0.000 ms: 1 events
poll took 16.000 ms: 1 events
poll took 31.000 ms: 1 events
poll took 0.000 ms: 1 events
poll took 0.000 ms: 1 events
poll took 0.000 ms: 1 events
poll took 0.000 ms: 1 events
poll took 0.000 ms: 1 events
poll took 0.000 ms: 1 events
poll took 0.000 ms: 1 events
poll took 0.000 ms: 1 events
poll took 15.000 ms: 1 events
poll took 16.000 ms: 1 events
poll took 0.000 ms: 1 events
poll took 16.000 ms: 1 events
Traceback (most recent call last):
File "sensortag.py", line 156, in
loop.run_until_complete(run(address, loop, True))
File "C:\Users\amit\Anaconda3\lib\asyncio\base_events.py", line 473, in run_until_complete
return future.result()
File "sensortag.py", line 103, in run
async with BleakClient(address, loop=loop) as client:
File "C:\Users\amit\Anaconda3\lib\asyncio\coroutines.py", line 110, in next
return self.gen.send(None)
File "C:\Users\amit\Anaconda3\lib\site-packages\bleak\backends\client.py", line 41, in aenter
await self.connect()
File "C:\Users\amit\Anaconda3\lib\asyncio\coroutines.py", line 110, in next
return self.gen.send(None)
File "C:\Users\amit\Anaconda3\lib\site-packages\bleak\backends\dotnet\client.py", line 115, in connect
await self.get_services()
File "C:\Users\amit\Anaconda3\lib\asyncio\coroutines.py", line 110, in next
return self.gen.send(None)
File "C:\Users\amit\Anaconda3\lib\site-packages\bleak\backends\dotnet\client.py", line 202, in get_services
"Could not get GATT characteristics for {0}.".format(service)
bleak.exc.BleakDotNetTaskError: Could not get GATT characteristics for Windows.Devices.Bluetooth.GenericAttributeProfile.GattDeviceService.
Running
C:\Users\amit\Documents\GitHub\bleak\examples>python sensortag.py
Paste the command(s) you ran and the output.
await self.get_services()
File "C:\Users\amit\Anaconda3\lib\site-packages\bleak\backends\dotnet\client.py", line 202, in get_services
"Could not get GATT characteristics for {0}.".format(service)
bleak.exc.BleakDotNetTaskError: Could not get GATT characteristics for Windows.Devices.Bluetooth.GenericAttributeProfile.GattDeviceService.
![1111](https://user-images.githubusercontent.com/37605691/57596682-923ee500-7511-11e9-83de-10982bb737f2.JPG)
I want to try to wake up my devices via ble. On windows it works perfectly, when my Advertising Intervall is very long. But on Ubuntu it doesn't work. It works when I reduce my Intervall.
You have a fix for me?
Regards
The BleakUWPBridge.dll
library is currently built for Any CPU
and included in the repo and sdist.
Break it out and include artifacts from the hbldh/BleakUWPBridge project's Appveyor builds.
In my use case I have a long running application that is looking for devices with certain properties (like a name prefix, RSSI etc.) and connects to them. To accomplish this I have an infinite loop that calls discover and checks the list of devices until the proper one is available. Something like:
while True:
devices = await discover(timeout=1)
for d in devices:
if d.name.startswith("PREFIX"):
return d
I observed that if it is running for a while, the discover takes not only around a second but up to multiple minutes.
The issue is that the DBus callbacks in discovery() for InterfacesAdded, InterfacesRemoved and PropertiesChanged are never deleted again. Therefore they pile up and the parse_msg callback is called thousands of times after a couple of minutes.
The issue is therefore similar to #83 where the notifications are sent multiple times after a reconnection. I think it makes sense to go through all Bluez callback registrations and make sure they don't leak.
Use the Github repo stored logo if possible on https://bleak.readthedocs.io/en/latest/.
The currently deployed documentation logo was stored in my Dropbox and it got deleted during my last refactoring of storage...
I was trying to use to discover.py, but they all print out company's name of the bluetooth not the actual setup name for the device. For example, instead of showing "Micheal's Beats3", it will show "Microsoft".
33:FB:D9:92:DE:FA: Microsoft (b'\x01\t \x029\xc5\xc7\xbf\xdb\x88\xe6\xd1\x1e\\\xean\x82U\xb1\xa9Eo\xdc\xf39e9')
As mentioned in issue #58 I have problems receiving an answer from a characteristic that has no read attribute. I'm performing a write and would expect response ~WORLD
. This works fine in Bluetooth LE Explorer.
However, I can't seem to get this working in bleak
answer = await client.write_gatt_char(rw_charac, b'~HELLO', response=True)
# no response is given, answer is always None
according to the documentation, the write_gatt_char(..., response=True)
should return
if not response=True, a bytearray is returned.
, but this does not seem to happen? Any tips how I can receive an answer? Should I use any other method instead?
I am trying to communicate to device by bluetooth. I have the UUID, also I'm doing everything that you showed in issue #59 but no matter what I'm typing to 'data' in function client.write_gatt_char it shows me this type of error:
"Could not write value 'data' to characteristic"
I've tried bytes or bytearray, but everything ends with the same error.
I decided to comment this function. Unfortunately, the function callback has never been called.
My code:
def callback(sender, data):
print(f"{sender}: {data}")
async def run(address, loop, debug=False):
log = logging.getLogger(__name__)
if debug:
import sys
loop.set_debug(True)
log.setLevel(logging.DEBUG)
h = logging.StreamHandler(sys.stdout)
h.setLevel(logging.DEBUG)
log.addHandler(h)
async with BleakClient(address, loop=loop) as client:
x = await client.is_connected()
log.info("Connected: {0}".format(x))
write_value = bytearray([0xa0])
rw_charac = uuid.UUID('49365E80-CF3A-11E1-9AB4-0002A5D5C51B')
await client.get_services()
await client.start_notify(rw_charac, callback)
#await client.write_gatt_char(rw_charac, write_value, response=True)
await asyncio.sleep(0.5, loop=loop)
await client.stop_notify(rw_charac)
if __name__ == "__main__":
address = "9D:1C:2D:D3:E6:85"
loop = asyncio.get_event_loop()
loop.run_until_complete(run(address, loop, True))
Testing out the develop branch. BleakClientDotNet.connect()
throws BleakDotNetTaskError
because GetGattServicesAsync()
in BleakClientDotNet.get_services()
returns GattCommunicationStatus.Unreachable
.
This seems to be a timing issue. For some reason, GetGattServicesAsync
returns before it actually connects to the device. If I add a delay before calling GetGattServicesAsync
, it works more reliably. It also seems to work if I add a retry instead of a delay.
async def GetGattServicesAsync():
return await wrap_IAsyncOperation(
IAsyncOperation[GattDeviceServicesResult](
self._requester.GetGattServicesAsync()
),
return_type=GattDeviceServicesResult,
loop=self.loop,
)
services_result = await GetGattServicesAsync()
if services_result == GattCommunicationStatus.Unreachable:
# one retry because Windows is goofy
services_result = await GetGattServicesAsync()
if services_result.Status != GattCommunicationStatus.Success:
raise BleakDotNetTaskError("Could not get GATT services.")
This thread lead me to this thread which got me wondering if this behavior has something to do with needing a single threaded apartment on Windows.
I have a problem on the BLE device scan operartion, when I use the example code, it can detect and show the nearly BLE device, however, when I turn the device off, and run the program again, its still show up the device which is turned off, i think some info is saved and reload , how can I make a clear or initialize so that to prevent this issue?
for example, I turn off The Smart LED 4A72 and run the code, its still show up after I run the code
Paste the command(s) you ran and the output.
If there was a crash, please include the traceback here.
I am trying to communicate with a non-standard service. I have the UUID, which I can also read from client.get_services
, however, I cannot seem to get a handle of the corresponding characteristic. I do know the characteristic UUID from using Bluetooth LE Explorer.
However, when calling client.characteristics
, this UUID does not appear. If I try to obtain them via the service handle via service.GetAllCharacteristics()
, I get a FileLoadException
. If I try to directly access the characteristic via client.write_gatt_char
, I get a UUID not found
mac ='d1:10:31:fa:3a:22'
loop = asyncio.get_event_loop()
client = BleakClient(address, loop=loop)
await client.connect()
rw_service = '49535343-fe7d-4ae5-8fa9-9fafd205e455'
rw_charac = '49535343-1e4d-4bd9-ba61-23c647249616'
# let's see if we can find the service:
await client.get_services()
assert rw_service in client.services # True
# first I try to access the characteristic directly
client.write_gatt_char(rw_charac, b'~HELLO', response=True)
# BleakError: Characteristic 49535343-1e4d-4bd9-ba61-23c647249616 was not found!
# second I try to enumerate all characteristics to get a handle on the char
# ..... many UUIDS, but none of the above UUID are in .characteristics
assert rw_charac in client.characteristics # failed
# third I try to enumerate characteristics of the rw_service
service = client.services[rw_service]
characts = service.GetAllCharacteristics()
#FileLoadException: The process cannot access the file because it is being used by another process. (Exception from HRESULT: 0x80070020)
# at Windows.Devices.Bluetooth.GenericAttributeProfile.GattDeviceService.GetAllCharacteristics()
Am I doing anything wrong? Do you have a suggestion how I can send simple command to my custom r/w service?
Cannot set BTLE security level before connecting.
I'm currently rewriting an internal testing tool from bluepy to an async library. I decided to test out bleak, but one of the problems I ran into was our device giving an "LE security request" when connecting to it. This didn't happen with the old library.
After some talking with our Bluetooth guys and testing with gatttool
it seems that the old library defaults to what gatttool would call sec-level low
, while bleak seems to default to at least medium. bluepy
allows setting this, but I cannot find anything in the bleak
API description on how to set the security level, so I looked at the bluez dbus "documentation", hoping I could hack in a workaround, but couldn't find anything either.
Any help is appreciated.
Dependabot can't resolve your Python dependency files.
As a result, Dependabot couldn't update your dependencies.
The error Dependabot encountered was:
ERROR: ERROR: Could not find a version that matches black
No versions found
Was <redacted> reachable?
[pipenv.exceptions.ResolutionFailure]: req_dir=requirements_dir
[pipenv.exceptions.ResolutionFailure]: File "/usr/local/.pyenv/versions/2.7.16/lib/python2.7/site-packages/pipenv/utils.py", line 726, in resolve_deps
[pipenv.exceptions.ResolutionFailure]: req_dir=req_dir,
[pipenv.exceptions.ResolutionFailure]: File "/usr/local/.pyenv/versions/2.7.16/lib/python2.7/site-packages/pipenv/utils.py", line 480, in actually_resolve_deps
[pipenv.exceptions.ResolutionFailure]: resolved_tree = resolver.resolve()
[pipenv.exceptions.ResolutionFailure]: File "/usr/local/.pyenv/versions/2.7.16/lib/python2.7/site-packages/pipenv/utils.py", line 395, in resolve
[pipenv.exceptions.ResolutionFailure]: raise ResolutionFailure(message=str(e))
[pipenv.exceptions.ResolutionFailure]: ResolutionFailure: ERROR: ERROR: Could not find a version that matches black
[pipenv.exceptions.ResolutionFailure]: No versions found
[pipenv.exceptions.ResolutionFailure]: Warning: Your dependencies could not be resolved. You likely have a mismatch in your sub-dependencies.
First try clearing your dependency cache with $ pipenv lock --clear, then try the original command again.
Alternatively, you can use $ pipenv install --skip-lock to bypass this mechanism, then run $ pipenv graph to inspect the situation.
Hint: try $ pipenv lock --pre if it is a pre-release dependency.
ERROR: ERROR: Could not find a version that matches black
No versions found
Was <redacted> reachable?
['Traceback (most recent call last):\n', ' File "/usr/local/.pyenv/versions/2.7.16/lib/python2.7/site-packages/pipenv/utils.py", line 501, in create_spinner\n yield sp\n', ' File "/usr/local/.pyenv/versions/2.7.16/lib/python2.7/site-packages/pipenv/utils.py", line 649, in venv_resolve_deps\n c = resolve(cmd, sp)\n', ' File "/usr/local/.pyenv/versions/2.7.16/lib/python2.7/site-packages/pipenv/utils.py", line 539, in resolve\n sys.exit(c.return_code)\n', 'SystemExit: 1\n']
If you think the above is an error on Dependabot's side please don't hesitate to get in touch - we'll do whatever we can to fix it.
You can mention @dependabot in the comments below to contact the Dependabot team.
In the method write_gatt_char
, the WriteValue
command is only called if the write request is with response or if the BlueZ version is strictly greater then 5.50
. Shouldn't this be greater or equal to 5.50
?
if response or (self._bluez_version[0] == 5 and self._bluez_version[1] > 50):
In Bluez it should be possible to listen for an event if a device has disconnected (https://stackoverflow.com/questions/53664144/device-connect-disconnect-notification-via-bluez-dbus-api). Are there plans to add an disconnection callback to the client API (I have no idea whether this is possible on the other platforms) or even try to implement something like auto-reconnection in the library itself?
Currently, bleak establishes a BleakClient that can scan for BLE peripheral devices.
Are there any future plans to implement a BleakServer to establish a central device that can advertise services and characteristics that other devices can connect to?
I imagine a BleakServer could utilize BleakGATTService
and BleakGATTCharacteristic
objects to set up and manage user-defined services that are then advertised and could be read from, written and/or subscribed to.
Dependabot can't resolve your Python dependency files.
As a result, Dependabot couldn't update your dependencies.
The error Dependabot encountered was:
Dependabot detected a dependency that can't be built on linux. Currently, all Dependabot builds happen on linux boxes, so there is no way for Dependabot to resolve your dependency files.
Unless you think Dependabot has made a mistake (please tag us if so) you may wish to disable Dependabot on this repo.
If you think the above is an error on Dependabot's side please don't hesitate to get in touch - we'll do whatever we can to fix it.
You can mention @dependabot in the comments below to contact the Dependabot team.
Very infrequently (i.e. once every few hours of continuous scanning), running the discover()
function will cause a runtime error. It would appear that the internal dictionary devices
is being modified while Bleak iterates over it.
It's easy enough to work around (for now I'm catching this particular exception and re-running discover()
), but this bug is irritating, to say the least. Sometimes it happens within a few cycles of calling discover()
, sometimes it won't show up for a few hours at a time.
discover()
Traceback (most recent call last):
File "[my script].py", line 140, in <module>
loop.run_until_complete(scan_loop())
File "[My user folder]\Anaconda3\lib\asyncio\base_events.py", line 584, in run_until_complete
return future.result()
File "[my script].py", line 102, in scan_loop
devices = await discover(device="hci0", timeout=3)
File "[My user folder]\lib\site-packages\bleak\backends\dotnet\discovery.py", line 91, in discover
for d in devices.values():
RuntimeError: dictionary changed size during iteration
Trying to connect to device.
When i try connecting to the device (this device will close the server as soon as a client will disconnect) this device disappears from the detected devices list (i'm checking that with a mobile app). It looks like the call to bleak.BleakClient(address, loop=loop)
performs a connection of some sort and then disconnects.
async def connect(address, loop):
async with bleak.BleakClient(address, loop=loop) as client:
await client.connect()
print("Device is %d" % client.is_connected())
Trying to run the discovery example from usage section in the documentation in a virtualenv on a raspberry pi with default python 3.5.3 installed.
Saved the discovery code from the docs to discover.py
python3 -m venv venv
. venv/bin/activate
pip install bleak
python3 discover.py
Traceback (most recent call last):
File "discover.py", line 2, in <module>
from bleak import discover
File "/home/pi/venv/lib/python3.5/site-packages/bleak/__init__.py", line 47, in <module>
from bleak.backends.bluezdbus.discovery import discover # noqa
File "/home/pi/venv/lib/python3.5/site-packages/bleak/backends/bluezdbus/discovery.py", line 6, in <module>
from bleak.backends.device import BLEDevice
File "/home/pi/venv/lib/python3.5/site-packages/bleak/backends/device.py", line 30
return f"{self.address}: {self.name}"
^
SyntaxError: invalid syntax
I want to connect to an BLE device.
Traceback (most recent call last):
File "/home/jonas/Schreibtisch/TMRTFlib.py", line 572, in <module>
loop.run_until_complete(connect_device_bleak(address, loop))
File "/usr/lib/python3.6/asyncio/base_events.py", line 473, in run_until_complete
return future.result()
File "/home/jonas/Schreibtisch/TMRTFlib.py", line 552, in connect_device_bleak
async with BleakClient(address, loop=loop) as client:
File "/home/jonas/.local/lib/python3.6/site-packages/bleak/backends/client.py", line 35, in __aenter__
await self.connect()
File "/home/jonas/.local/lib/python3.6/site-packages/bleak/backends/bluezdbus/client.py", line 76, in connect
raise BleakError(str(e))
bleak.exc.BleakError: org.freedesktop.DBus.Error.UnknownObject: Method "Connect" with signature "" on interface "org.bluez.Device1" doesn't exist
DBus connections are not cleaned up after usage. Multiple calls to discover() result eventually in following error:
Traceback (most recent call last):
File "discover.py", line 29, in <module>
loop.run_until_complete(run())
File "/usr/lib64/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "discover.py", line 22, in run
devices = await discover(timeout=1)
File "/home/joe/code/proglove/python/bleak/bleak/backends/bluezdbus/discovery.py", line 125, in discover
bus = await client.connect(reactor, "system").asFuture(loop)
txdbus.error.RemoteError: org.freedesktop.DBus.Error.LimitsExceeded: The maximum number of active connections for UID 1000 has been reached
For me this happens at the 246th call to discover()
When installing bleak, there was an error importing basetsd.h. After installing Windows SDK, the installation output changed, but the error persists.
When I run pip install bleak
the following stack trace appears:
PS C:\Users\GuilhermeMussi\Desktop\esp32py> pip install bleak
Collecting bleak
Using cached https://files.pythonhosted.org/packages/3a/0e/ce9655465ac5455f9bbec5cb41b007a26bd889792fd1d4963f6f99d88b1a/bleak-0.4.0-py2.py3-none-any.whl
Collecting pythonnet; platform_system == "Windows" (from bleak)
Using cached https://files.pythonhosted.org/packages/89/3b/a22cd45b591d6cf490ee8b24d52b9db1f30b4b478b64a9b231c53474731e/pythonnet-2.3.0.tar.gz
Installing collected packages: pythonnet, bleak
Running setup.py install for pythonnet ... error
ERROR: Complete output from command 'c:\users\guilhermemussi\appdata\local\programs\python\python37\python.exe' -u -c 'import setuptools, tokenize;__file__='"'"'C:\\Users\\GUILHE~1\\AppData\\Local\\Temp\\pip-install-pbsf463r\\pythonnet\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\GUILHE~1\AppData\Local\Temp\pip-record-v4n1x0hi\install-record.txt' --single-version-externally-managed --compile:
ERROR: running install
running build
running build_ext
Checking for updates from https://www.nuget.org/api/v2/.
Currently running NuGet.exe 3.5.0.
Updating NuGet.exe to 4.9.4.
Update successful.
MSBuild auto-detection: using msbuild version '16.0.461.62831' from 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\bin'.
Restoring NuGet package NUnit.3.6.0.
Restoring NuGet package NUnit.ConsoleRunner.3.6.0.
Restoring NuGet package UnmanagedExports.1.2.7.
Adding package 'NUnit.ConsoleRunner.3.6.0' to folder 'C:\Users\GuilhermeMussi\AppData\Local\Temp\pip-install-pbsf463r\pythonnet\packages'
Adding package 'UnmanagedExports.1.2.7' to folder 'C:\Users\GuilhermeMussi\AppData\Local\Temp\pip-install-pbsf463r\pythonnet\packages'
Adding package 'NUnit.3.6.0' to folder 'C:\Users\GuilhermeMussi\AppData\Local\Temp\pip-install-pbsf463r\pythonnet\packages'
Added package 'UnmanagedExports.1.2.7' to folder 'C:\Users\GuilhermeMussi\AppData\Local\Temp\pip-install-pbsf463r\pythonnet\packages'
Added package 'NUnit.ConsoleRunner.3.6.0' to folder 'C:\Users\GuilhermeMussi\AppData\Local\Temp\pip-install-pbsf463r\pythonnet\packages'
Added package 'NUnit.3.6.0' to folder 'C:\Users\GuilhermeMussi\AppData\Local\Temp\pip-install-pbsf463r\pythonnet\packages'
NuGet Config files used:
C:\Users\GuilhermeMussi\AppData\Roaming\NuGet\NuGet.Config
Feeds used:
C:\Users\GuilhermeMussi\.nuget\packages\
https://api.nuget.org/v3/index.json
Installed:
3 package(s) to packages.config projects
clang.exe: warning: c:\users\guilhermemussi\appdata\local\programs\python\python37\Include: 'linker' input unused
In file included from c:\users\guilhermemussi\appdata\local\programs\python\python37\Include\Python.h:8:
c:\users\guilhermemussi\appdata\local\programs\python\python37\Include/pyconfig.h:215:10: fatal error: 'basetsd.h' file not found
#include <basetsd.h>
^
1 error generated.
Traceback (most recent call last):
File "tools\geninterop\geninterop.py", line 292, in <module>
sys.exit(main())
File "tools\geninterop\geninterop.py", line 272, in main
python_h = preprocess_python_headers()
File "tools\geninterop\geninterop.py", line 192, in preprocess_python_headers
for line in _check_output(cmd).splitlines():
File "tools\geninterop\geninterop.py", line 41, in _check_output
output = subprocess.check_output(*args, **kwargs)
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\subprocess.py", line 376, in check_output
**kwargs).stdout
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\subprocess.py", line 468, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['clang', '-I', 'tools\\geninterop\\fake_libc_include', 'c:\\users\\guilhermemussi\\appdata\\local\\programs\\python\\python37\\Include', '-D', '__attribute__(x)=', '-D', '__inline__=inline', '-D', '__asm__=;#pragma asm', '-D', '__int64=long long', '-E', 'c:\\users\\guilhermemussi\\appdata\\local\\programs\\python\\python37\\Include\\Python.h']' returned non-zero exit status 1.
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\GUILHE~1\AppData\Local\Temp\pip-install-pbsf463r\pythonnet\setup.py", line 405, in <module>
zip_safe=False,
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\site-packages\setuptools\__init__.py", line 145, in setup
return distutils.core.setup(**attrs)
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\distutils\core.py", line 148, in setup
dist.run_commands()
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\distutils\dist.py", line 966, in run_commands
self.run_command(cmd)
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\distutils\dist.py", line 985, in run_command
cmd_obj.run()
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\site-packages\setuptools\command\install.py", line 61, in run
return orig.install.run(self)
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\distutils\command\install.py", line 545, in run
self.run_command('build')
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\distutils\cmd.py", line 313, in run_command
self.distribution.run_command(command)
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\distutils\dist.py", line 985, in run_command
cmd_obj.run()
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\distutils\command\build.py", line 135, in run
self.run_command(cmd_name)
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\distutils\cmd.py", line 313, in run_command
self.distribution.run_command(command)
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\distutils\dist.py", line 985, in run_command
cmd_obj.run()
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\distutils\command\build_ext.py", line 339, in run
self.build_extensions()
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\distutils\command\build_ext.py", line 448, in build_extensions
self._build_extensions_serial()
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\distutils\command\build_ext.py", line 473, in _build_extensions_serial
self.build_extension(ext)
File "C:\Users\GUILHE~1\AppData\Local\Temp\pip-install-pbsf463r\pythonnet\setup.py", line 191, in build_extension
subprocess.check_call([sys.executable, geninterop, interop_file])
File "c:\users\guilhermemussi\appdata\local\programs\python\python37\lib\subprocess.py", line 328, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['c:\\users\\guilhermemussi\\appdata\\local\\programs\\python\\python37\\python.exe', 'tools\\geninterop\\geninterop.py', 'src\\runtime\\interop37.cs']' returned non-zero exit status 1.
----------------------------------------
ERROR: Command "'c:\users\guilhermemussi\appdata\local\programs\python\python37\python.exe' -u -c 'import setuptools, tokenize;__file__='"'"'C:\\Users\\GUILHE~1\\AppData\\Local\\Temp\\pip-install-pbsf463r\\pythonnet\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\GUILHE~1\AppData\Local\Temp\pip-record-v4n1x0hi\install-record.txt' --single-version-externally-managed --compile" failed with error code 1 in C:\Users\GUILHE~1\AppData\Local\Temp\pip-install-pbsf463r\pythonnet\
I am not sure what else I can do. Any help would be appreciated.
I want to write a small module that deals with a bluetoothle connection.
Everything works fine until I try to use a new event loop together with bleak.discover().
Please see MWE below for details.
import asyncio
from bleak import discover
import logging
async def printer2(loop: asyncio.AbstractEventLoop):
print("Start Printer2")
devices = await discover(loop=loop) # This function gets stuck here.
for d in devices:
print(d.name)
print("Hey")
return 42
async def printer(loop: asyncio.AbstractEventLoop): # This function works as expected
print("Start Printer")
await asyncio.sleep(5, loop=loop)
print("Hey")
return 42
def create():
loop = asyncio.new_event_loop() # replacing this with asyncio.get_event_loop() works..
asyncio.set_event_loop(loop)
return loop
logging.basicConfig(level=logging.DEBUG)
loop = create()
retval = loop.run_until_complete(printer(loop))
print(retval)
retval = loop.run_until_complete(printer2(loop))
print(retval)
I try to connect to a BLE device with a longer timeout than default (2s)
On windows 10, if I specify a longer timeout in connection string, like "async with BleakClient(address, loop=loop, timeout=5.0) as client:" in the sensor tag example, it doesn't work.
while using:
async with BleakClient(address, loop=loop, timeout=5.0) as client:
debug show:
poll 2000.000 ms took 2000.000 ms: timeout
The __init__
function fails with "no such file or directory 'dpkg-query'" when using the module. Dpkg is not used on Arch Linux, so i would not expect this check to pass.
Started the Python interpreter and attempted
import bleak
Many thanks for the nice looking library!
Every time I try to list BLE devices (using discover()
), bleak lists the devices and prints 20 to 50 times the same beautiful unhandled error.
It seems to appear randomly (1-2 times every 2-5 try).
The function is here.
Here's the error:
Unhandled Error
Traceback (most recent call last):
File "/home/usr/dir/virtualEnv/lib/python3.6/site-packages/txdbus/protocol.py", line 141, in dataReceived
self.rawDBusMessageReceived(raw_msg)
File "/home/usr/dir/virtualEnv/lib/python3.6/site-packages/txdbus/protocol.py", line 262, in rawDBusMessageReceived
self.signalReceived(m)
File "/home/usr/dir/virtualEnv/lib/python3.6/site-packages/txdbus/client.py", line 643, in signalReceived
self.router.routeMessage(msig)
File "/home/usr/dir/virtualEnv/lib/python3.6/site-packages/txdbus/router.py", line 128, in routeMessage
r.match(m)
--- <exception caught here> ---
File "/home/usr/dir/virtualEnv/lib/python3.6/site-packages/txdbus/router.py", line 67, in match
self.callback(m)
File "/home/usr/dir/virtualEnv/lib/python3.6/site-packages/bleak/backends/bluezdbus/discovery.py", line 109, in parse_msg
*_device_info(msg_path, devices.get(msg_path))
File "/home/usr/dir/virtualEnv/lib/python3.6/site-packages/bleak/backends/bluezdbus/discovery.py", line 39, in _device_info
name = props.get("Name", props.get("Alias", path.split("/")[-1]))
builtins.AttributeError: 'NoneType' object has no attribute 'get'
Attempting to print the available services. This fails because bleak has not yet discovered all services.
Here is a simplified version of the code i am trying to run
async def print_services(mac_addr : str, loop : asyncio.AbstractEventLoop):
async with BleakClient(mac_addr, loop=loop) as client:
svcs = await client.get_services()
print("Services:", svcs)
def do_thing(mac_addr : str):
loop = asyncio.get_event_loop()
loop.run_until_complete(print_services(mac_addr, loop))
The output is
Services: {}
There should be many services. I can add a delay and get the right result:
async def print_services(mac_addr : str, loop : asyncio.AbstractEventLoop):
async with BleakClient(mac_addr, loop=loop) as client:
await asyncio.sleep(10)
svcs = await client.get_services()
print("Services:", svcs)
Which results in
Services: {'0000180a-0000-1000-8000-00805f9b34fb': {'UUID': '0000180a-0000-1000-8000-00805f9b34fb', 'Device': '/org/bluez/hci0/dev_F4_B8_5E_F3_B6_84', 'Primary': True, 'Includes': [], 'Path': '/org/bluez/hci0/dev_F4_B8_5E_F3_B6_84/service0021'}, '00001000-0000-1000-8000-00805f9b34fb': {'UUID': '00001000-0000-1000-8000-00805f9b34fb', 'Device': '/org/bluez/hci0/dev_F4_B8_5E_F3_B6_84', 'Primary': True, 'Includes': [], 'Path': '/org/bluez/hci0/dev_F4_B8_5E_F3_B6_84/service0010'}, '00001801-0000-1000-8000-00805f9b34fb': {'UUID': '00001801-0000-1000-8000-00805f9b34fb', 'Device': '/org/bluez/hci0/dev_F4_B8_5E_F3_B6_84', 'Primary': True, 'Includes': [], 'Path': '/org/bluez/hci0/dev_F4_B8_5E_F3_B6_84/service000c'}}
Apologies if this is something i have not understood about the library.
I want to start a notification. But every time I want to start it, I get an error.
Traceback (most recent call last):
File "C:/Arbeit/Server_Bleak/temperaturesystem-master_KOPIE/TMRTFlib.py", line 572, in <module>
loop.run_until_complete(connect_device_bleak(address, loop))
File "C:\Users\Jonas\AppData\Local\Programs\Python\Python36\lib\asyncio\base_events.py", line 473, in run_until_complete
return future.result()
File "C:/Arbeit/Server_Bleak/temperaturesystem-master_KOPIE/TMRTFlib.py", line 565, in connect_device_bleak
await client.start_notify("23EF6F02-56AC-4519-AE11-0684C77CA30E", callback)
File "C:\Arbeit\Server_Bleak\temperaturesystem-master_KOPIE\interpreter\lib\site-packages\bleak\backends\dotnet\client.py", line 255, in start_notify
self._bridge.StartNotify(characteristic, dotnet_callback), loop=self.loop
File "C:\Arbeit\Server_Bleak\temperaturesystem-master_KOPIE\interpreter\lib\site-packages\bleak\backends\dotnet\utils.py", line 39, in wrap_Task
raise BleakDotNetTaskError(task.Exception.ToString())
bleak.exc.BleakDotNetTaskError: System.AggregateException: Mindestens ein Fehler ist aufgetreten. ---> System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
bei BleakBridge.Bridge.<StartNotify>d__8.MoveNext()
--- Ende der internen Ausnahmestapelรผberwachung ---
---> (Interne Ausnahme #0) System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
bei BleakBridge.Bridge.<StartNotify>d__8.MoveNext()<---
Since there seem to be major changes currently being worked on, I will bring this up in an issue instead of making a pull request.
Trying to get manufacturer data from BLE advertising packets. This does not seem to be possible using Windows.Devices.Enumeration.DeviceWatcher
.
Replaced Windows.Devices.Enumeration.DeviceWatcher
with Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher
in virantha@c681558.
Hello
I am facing a issue with using Bleak. I had problems before this issue with "Failed building wheel for pythonnet" but solved it by running "conda install git"
Now i am facing a problem after installing Bleak where i can't include Windows.Devices
Is this a library that has to be installed? I am running Anaconda if that's a useful infomation
While running the service_explorer.py
on my device, I found that a few characteristics are missing. When I explicitely request this characteristic to be read, I get a bleak.exc.BleakError: Characteristic with UUID xxxx could not be found
I ran the service_explorer.py
script. The output is
Connected: True
[Service] f1196f50-71a4-11e6-bdf4-0800200c9a66: Unknown
[Characteristic] f1196f57-71a4-11e6-bdf4-0800200c9a66: (write) | Name: , Value: None
[Characteristic] f1196f56-71a4-11e6-bdf4-0800200c9a66: (read,write) | Name: , Value: b''
[Characteristic] f1196f55-71a4-11e6-bdf4-0800200c9a66: (notify) | Name: , Value: None
[Descriptor] 00002902-0000-1000-8000-00805f9b34fb: (Handle: 33) | Value: b'\x00\x00'
[Characteristic] f1196f54-71a4-11e6-bdf4-0800200c9a66: (read,write) | Name: , Value: b''
[Characteristic] f1196f53-71a4-11e6-bdf4-0800200c9a66: (read) | Name: , Value: b''
[Characteristic] f1196f52-71a4-11e6-bdf4-0800200c9a66: (read,notify) | Name: , Value: b''
[Descriptor] 00002902-0000-1000-8000-00805f9b34fb: (Handle: 26) | Value: b'\x00\x00'
[Characteristic] f1196f51-71a4-11e6-bdf4-0800200c9a66: (read) | Name: , Value: b''
[Service] 0000180a-0000-1000-8000-00805f9b34fb: Device Information
[Characteristic] 00002a26-0000-1000-8000-00805f9b34fb: (read) | Name: , Value: b'TFv3.1'
[Service] 00001801-0000-1000-8000-00805f9b34fb: Generic Attribute Profile
[Characteristic] 00002a05-0000-1000-8000-00805f9b34fb: (indicate) | Name: , Value: None
[Descriptor] 00002902-0000-1000-8000-00805f9b34fb: (Handle: 11) | Value: b'\x02\x00'
On the other hand, if I use gatttool
, I get the following
~$ gatttool -b 98:07:2D:EE:21:0E -I
[98:07:2D:EE:21:0E][LE]> connect
Attempting to connect to 98:07:2D:EE:21:0E
Connection successful
[98:07:2D:EE:21:0E][LE]> primary
attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0008, end grp handle: 0x000b uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x000c, end grp handle: 0x000e uuid: 0000180a-0000-1000-8000-00805f9b34fb
attr handle: 0x000f, end grp handle: 0x0014 uuid: 0000180f-0000-1000-8000-00805f9b34fb
attr handle: 0x0015, end grp handle: 0xffff uuid: f1196f50-71a4-11e6-bdf4-0800200c9a66
[98:07:2D:EE:21:0E][LE]> characteristics
handle: 0x0002, char properties: 0x0e, char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb [* โ Device Name]
handle: 0x0004, char properties: 0x02, char value handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb [* โ Appearance]
handle: 0x0006, char properties: 0x02, char value handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb [* โ Peripherical Prefered Connection Parameter]
handle: 0x0009, char properties: 0x20, char value handle: 0x000a, uuid: 00002a05-0000-1000-8000-00805f9b34fb
handle: 0x000d, char properties: 0x02, char value handle: 0x000e, uuid: 00002a26-0000-1000-8000-00805f9b34fb
handle: 0x0010, char properties: 0x12, char value handle: 0x0011, uuid: 00002a19-0000-1000-8000-00805f9b34fb
handle: 0x0016, char properties: 0x02, char value handle: 0x0017, uuid: f1196f51-71a4-11e6-bdf4-0800200c9a66
handle: 0x0018, char properties: 0x12, char value handle: 0x0019, uuid: f1196f52-71a4-11e6-bdf4-0800200c9a66
handle: 0x001b, char properties: 0x02, char value handle: 0x001c, uuid: f1196f53-71a4-11e6-bdf4-0800200c9a66
handle: 0x001d, char properties: 0x0a, char value handle: 0x001e, uuid: f1196f54-71a4-11e6-bdf4-0800200c9a66
handle: 0x001f, char properties: 0x10, char value handle: 0x0020, uuid: f1196f55-71a4-11e6-bdf4-0800200c9a66
handle: 0x0022, char properties: 0x0a, char value handle: 0x0023, uuid: f1196f56-71a4-11e6-bdf4-0800200c9a66
handle: 0x0024, char properties: 0x08, char value handle: 0x0025, uuid: f1196f57-71a4-11e6-bdf4-0800200c9a66
[98:07:2D:EE:21:0E][LE]> char-read-uuid 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0003 value: 50 69 65 72 72 65 20 2d 20 54 4d 32
(please scroll right for the additional information)
As you can see, the three first characteristics (marked by a star in the output, added by me) are not reported by the script. Of course, reading their values through gatttool
works correctly (see last line), but as I mention, the following does not:
# not the smartest piece of code, but I'm just playing around ;)
import asyncio
from bleak import BleakClient
UUID_GENERIC = '0000{}-0000-1000-8000-00805f9b34fb'
CHARACTERISTIC_DEVICE_NAME = UUID_GENERIC.format('2a00')
CHARACTERISTIC_BATTERY_LEVEL = UUID_GENERIC.format('2a19')
CHARACTERISTIC_FIRMWARE_REV = UUID_GENERIC.format('2a26')
CURRENT_CHAR = CHARACTERISTIC_DEVICE_NAME
async def run(address, loop):
async with BleakClient(address, loop=loop) as client:
char_value = await client.read_gatt_char(CURRENT_CHAR)
print("{} = {} ({})".format(CURRENT_CHAR, char_value.hex(), char_value.decode()))
if __name__ == '__main__':
address = '98:07:2D:EE:21:0E'
loop = asyncio.get_event_loop()
loop.run_until_complete(run(address, loop))
Since it results in bleak.exc.BleakError: Characteristic with UUID 00002a00-0000-1000-8000-00805f9b34fb could not be found!
. Reading CHARACTERISTIC_BATTERY_LEVEL
does, on the other hand, work.
In itself, I'm not interested in those characteristics, but I think it worth reporting :)
I would like to connect with bleak to a few devices at the same moment and in one terminal. I use loop.create_task() and on windows everything works fine, my two devices notifing perfectly. On Mac os one device also works great but if I try to connect two devices, my devices show that they are connected but they are not notifing. I debug my program and devices get in connect _to_device but print() in 'async with BleakClient() don't show.
from bleak import BleakClient, discover, BleakError
import asyncio
temperatureUUID = "45366e80-cf3a-11e1-9ab4-0002a5d5c51b"
ecgUUID = "46366e80-cf3a-11e1-9ab4-0002a5d5c51b"
def callback(sender, data):
print(sender, data)
def run(addresses):
loop = asyncio.get_event_loop()
for address in addresses:
loop.create_task(connect_to_device(address, loop))
loop.run_forever()
async def connect_to_device(address, loop):
async with BleakClient(address, loop=loop) as client:
print("connect to ", address)
await client.start_notify(ecgUUID, callback)
while True:
await asyncio.sleep(1, loop=loop)
if __name__ == "__main__":
run(["9923F33A-0648-4FC4-A062-47C872A4C27D","4CFEB2B0-02E7-46E4-B80D-0B1F5D4AD7CC"])
I tried running the discover.py
example, and my iOS 12.1.4 iPhone SE was not recognized. I had the Bluetooth menu open on the device so it would be discoverable.
I tried getting the device's services by using the get_services.py
example with the iOS device's Bluetooth address filled into the script. The iOS device was opened to the Bluetooth menu. The device was not found.
Traceback for get_services.py
:
Traceback (most recent call last):
File "C:/Users/xx/services.py", line 21, in <module>
loop.run_until_complete(print_services(mac_addr, loop))
File "C:\Users\xx\AppData\Local\Programs\Python\Python37\lib\asyncio\base_events.py", line 584, in run_until_complete
return future.result()
File "C:/Users/xx/services.py", line 14, in print_services
async with BleakClient(mac_addr, loop=loop) as client:
File "C:\Users\xx\AppData\Roaming\Python\Python37\site-packages\bleak\backends\client.py", line 41, in __aenter__
await self.connect()
File "C:\Users\xx\AppData\Roaming\Python\Python37\site-packages\bleak\backends\dotnet\client.py", line 97, in connect
"Device with address {0} was " "not found.".format(self.address)
bleak.exc.BleakError: Device with address f0:xx:xx:xx:xx:xx was not found.
I try the LE device scan example get the error message in Spyder 3.6.8 as title mentioned, the program can should the nearly LE devices name and ID but it out of control after the output, just hang........
please anyone can help?
print
s for debugging, so line numbers might be off by 1 or 2)Linux 5.0.0-16-generic #17
Using an adapter other than 'hci0' does get set in the BleakClientBlueZDBus
instance, but not propagated to all called functions, like e.g. backends.bluezdbus.discovery.discover
Create an instance with a non-default device and have it try to connect. Very stripped down version of our code:
from bleak import BleakClient
import sys
import asyncio
class MyInternalStuff:
def __init__(self, ble_addr, *, adapter="hci0", loop):
self._adapter = adapter
self._dev = BleakClient(ble_addr, device=self._adapter, timeout=35)
async def __aenter__(self):
await self._dev.__aenter__()
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self._dev.__aexit__(exc_type, exc_val, exc_tb)
async def main(loop):
async with MyInternalStuff(ble_addr="12:34:56:78:90:ab", adapter='hci1', loop=loop):
pass
if __name__ == "__main__":
loop = asyncio.get_event_loop()
sys.exit(loop.run_until_complete(main(loop)))
gives
Traceback (most recent call last):
File "bug.py", line 25, in <module>
sys.exit(loop.run_until_complete(main(loop)))
File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "bug.py", line 19, in main
async with MyInternalStuff(ble_addr="12:34:56:78:90:ab", adapter='hci1', loop=loop):
File "bug.py", line 12, in __aenter__
await self._dev.__aenter__()
File "/home/yggdrasil/.virtualenvs/svhsystemtests/lib/python3.7/site-packages/bleak/backends/client.py", line 41, in __aenter__
await self.connect()
File "/home/yggdrasil/.virtualenvs/svhsystemtests/lib/python3.7/site-packages/bleak/backends/bluezdbus/client.py", line 65, in connect
await discover(timeout=0.1, loop=self.loop)
File "/home/yggdrasil/.virtualenvs/svhsystemtests/lib/python3.7/site-packages/bleak/backends/bluezdbus/discovery.py", line 143, in discover
adapter_path, interface = _filter_on_adapter(objects, device)
File "/home/yggdrasil/.virtualenvs/svhsystemtests/lib/python3.7/site-packages/bleak/backends/bluezdbus/discovery.py", line 26, in _filter_on_adapter
raise Exception("Bluetooth adapter not found")
Exception: Bluetooth adapter not found
Patching backends/bluezdbus/client.py:65
like so:
await discover(timeout=0.1, device=self.device, loop=self.loop)
fixes this particular instance, but there might be more places this is missing.
When launching discover function on Linux, we get a list of devices. And if the device name is unknown, it is replaced by its address.
On Windows however, the names are just "Unknown".
Will the output be the same in the next version ? Or is it a normal behavior ?
The Windows "Unknown" problem seems to be located here:
bleak/bleak/backends/dotnet/discovery.py
Line 57 in 4f3b890
I'm wrestling with the problem that I cannot connect to a BLE device on Windows. Sometimes it works, and sometimes it doesn't, but I have found out some clues.
I have seen that the Windows-Bluetooth-Indicator (Tray-Symbol) changes to 'Connected (1)' for a second, after which bleak
tells me 'BleakError("Connection to {0} was not successful!"'
.
Now I have tried bridging the line 118 in client.py
and it works fine:
#connected = await client.is_connected()
connected = True
So I think that we might need to increase the await asyncio.sleep(0.2, loop=self.loop)
to a higher value (500ms?). This also fixed my issue. However, it seems a bit strange to increase this timeout, should there not be a more deterministic method to know if we are connected, or a timeout-function (such that the wait is not enforced if a connection is established)?
Do you have any idea what is going wrong with the client.is_connected
? Does it just need more time? Or is there a better way to check if we are connected?
When connecting via DotNet backend, discover
is called with a timeout of 2.0
. However, this timeout is not always sufficient to get responses from the device necessary. In around 1/3rd of the cases it will not be able to connect to my device due to not finding it within 2 seconds.
Do you think that here a 'continue looking for device until found or timeout' loop would be useful? So the maximal timeout would be the default 5.0
, but it can be shorter if the device is found before. Else, the connect method might have a parameter force
that also tries to connect even if the device was not found during radio?
Bleak randomly throw an exception during any connexion attempt on linux (almost every time):
me@my-computer~$ python3 test.py
Traceback (most recent call last):
File "/home/me/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/client.py", line 98, in connect
).asFuture(self.loop)
txdbus.error.RemoteError: org.bluez.Error.Failed: Software caused connection abort
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "test.py", line 25, in <module>
loop.run_until_complete(run(address, loop, True))
File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "test.py", line 18, in run
async with BleakClient(address, loop=loop) as client:
File "/home/me/.local/lib/python3.7/site-packages/bleak/backends/client.py", line 41, in __aenter__
await self.connect()
File "/home/me/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/client.py", line 100, in connect
raise BleakError(str(e))
bleak.exc.BleakError: org.bluez.Error.Failed: Software caused connection abort
Pasted this program in a file named test.py
and then launched it.
import asyncio
from bleak import BleakClient
async def run(address, loop, debug=False):
async with BleakClient(address, loop=loop) as client:
x = await client.is_connected()
print("Connected: {0}".format(x))
if __name__ == "__main__":
address = "F8:F0:05:F4:C5:B4"
loop = asyncio.get_event_loop()
loop.run_until_complete(run(address, loop))
But discover()
works well though.
I created a small benchmark, who launch X times this program and display success/total attempts
:
import asyncio, bleak
async def run(address, loop, debug=False):
try:
async with bleak.BleakClient(address, loop=loop) as client:
x = await client.is_connected(timeout=5)
print(" V", end="", flush=True)
return True
except Exception as e:
print(" X", end="", flush=True)
return False
if __name__ == "__main__":
success = 0
address = "MAC ADDR"
for i in range(0, 10000):
loop = asyncio.get_event_loop()
if loop.run_until_complete(run(address, loop)):
success += 1
print("\033[K\r" + str(success) + "/" + str(i + 1), sep=" ", end="", flush=True)
# \033[K erase the line & \r return to the first char of the line
develop
branch)I am wondering about spots where the potential performance improvements could be made. This library is working great overall, however I am pushing the performance limits. My device is sending 500 notifications per second (of BLE max. 800) and I am not able to receive all of them. Using the code posted under What I Did below, the print output is:
Missed 1 samples (799 vs. 800 on remote)
Missed 11 samples (801 vs. 812 on remote)
Missed 5 samples (813 vs. 818 on remote)
Missed 1 samples (823 vs. 824 on remote)
Missed 6 samples (829 vs. 835 on remote)
Missed 1 samples (840 vs. 841 on remote)
Missed 1 samples (846 vs. 847 on remote)
Battery voltage = 4059 mV
Missed 2 samples (851 vs. 853 on remote)
Missed 3 samples (856 vs. 859 on remote)
Missed 2 samples (863 vs. 865 on remote)
Missed 1 samples (876 vs. 877 on remote)
Missed 2 samples (881 vs. 883 on remote)
iOS and Android apps are able to receive the notifications, so I set my goal to be able to receive them with Bleak as well.
I don't know where it would be the best to start. Would Make binary wheels for Windows noticeable improve performance?
I am currently working on my own branch with following improvements:
BluetoothLEAdvertisementWatcher
, which listens for BLE advertisements (without enumeration) and also supports additional filtering based on advertisement and scan response data.BluetoothLEDevice.FromBluetoothAddressAsync
to directly get the device instance from the MAC address and only perform (2 s) discovery combined with BluetoothLEDevice.FromIdAsync
if the first method is not successful (6f130fa)BleakGATTCharacteristic
directly without always re-querying them in I/O methods (002e7f9). This is more usability than performance improvement, as I usually make (data)classes for my services and retrieve all characteristics in the __init__
.service.get_characteristic()
on multiple service instances. Stripped example of my usage:@dataclass(init=False)
class PPGSensorService:
def __init__(self, client: BleakClient) -> None:
uuid_fmt = "0000{:04x}-99c1-8b45-835a-c30b7c408871"
self.client: BleakClient = client
self.service: BleakGATTService = client.services[uuid_fmt.format(0xe101)]
self.char_adc_sample: BleakGATTCharacteristic = self.service.get_characteristic(uuid_fmt.format(0xe201))
self.char_settings_basic: BleakGATTCharacteristic = self.service.get_characteristic(uuid_fmt.format(0xe202))
self.char_settings_advanced: BleakGATTCharacteristic = self.service.get_characteristic(uuid_fmt.format(0xe203))
self.char_analog: BleakGATTCharacteristic = self.service.get_characteristic(ble_uuid_to_128bit(0x2A58))
# Raise error if any char is not found - device not supported.
self.sample_counter: int = 0
async def enable_notifications(self) -> None:
await self.client.start_notify(self.char_adc_sample, self._on_adc_sample)
await self.client.start_notify(self.char_settings_basic, self._on_settings)
await self.client.start_notify(self.char_settings_advanced, self._on_settings)
await self.client.start_notify(self.char_analog, self._on_analog)
def _on_analog(self, uuid: str, data: bytearray):
voltage = struct.unpack("<H", data)[0]
print(f"Battery voltage = {voltage} mV")
def _on_adc_sample(self, uuid: str, data: bytearray) -> None:
unpacked = struct.unpack("<I4i4b4B4BH", data)
sample_counter = unpacked[0]
# ...
self.sample_counter += 1
if self.sample_counter != sample_counter:
print(f"Missed {sample_counter - self.sample_counter} samples"
f" ({self.sample_counter} vs. {sample_counter} on remote)")
self.sample_counter = sample_counter
def _on_settings(self, uuid: str, data: bytearray):
print(f"_on_settings({uuid}, {data})")
# ...
async def set_measuring(self, enabled: bool) -> None:
await self.client.write_gatt_char(self.char_settings_basic, bytearray([0x01 if enabled else 0x00]))
I haven't opened the PR as my changes are Python >=3.6.
I'd need to set a preferred MTU during the handshake with a device but I don't see this feature supported. Is it possible to add it?
Thanks for your excellent BLE library! Trying to use it to play with my wearable, but unfortunately Bleak throws an exception during service discovery.
This confuses me, because judging from the log, it actually did discover all services correctly. The device provides 4 services - information, battery, heart rate and proprietary. The two characteristics of the proprietary service are actually used to communicate over proprietary HUAWEI Link Protocol v2.
import logging
import asyncio
from bleak import BleakClient
logging.basicConfig(level=logging.DEBUG)
async def ble_get_services(mac_addr: str, loop: asyncio.AbstractEventLoop):
async with BleakClient(mac_addr, loop=loop) as client:
svcs = await client.get_services()
print("Services:", svcs)
address = "A0E49DB2-B7F1-4A65-AB2E-D75121192329"
loop = asyncio.get_event_loop()
loop.run_until_complete(ble_get_services(address, loop))
/Users/zaytsev/PycharmProjects/bluetooth/venv/bin/python /Users/zaytsev/PycharmProjects/bluetooth/bleak_demo.py
DEBUG:bleak.backends.corebluetooth.CentralManagerDelegate:Bluetooth powered on
DEBUG:bleak.backends.corebluetooth.CentralManagerDelegate:Discovered device A0E49DB2-B7F1-4A65-AB2E-D75121192329: Unknown @ RSSI: -79
A0E49DB2-B7F1-4A65-AB2E-D75121192329: HUAWEI Band 2-b6e
DEBUG:bleak.backends.corebluetooth.client:Connecting to BLE device @ A0E49DB2-B7F1-4A65-AB2E-D75121192329
DEBUG:bleak.backends.corebluetooth.CentralManagerDelegate:Successfully connected to device uuid A0E49DB2-B7F1-4A65-AB2E-D75121192329
WARNING:bleak.backends.corebluetooth.PeripheralDelegate:PeripheralDelegate is not compliant
DEBUG:bleak.backends.corebluetooth.client:Retrieving services...
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Services discovered
DEBUG:bleak.backends.corebluetooth.client:Retrieving characteristics for service 180F
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Characteristics discovered
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A19
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A19
DEBUG:bleak.backends.corebluetooth.client:Retrieving characteristics for service 180A
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Characteristics discovered
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A29
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A29
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A24
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A24
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A26
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A26
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A28
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A28
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A50
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A50
DEBUG:bleak.backends.corebluetooth.client:Retrieving characteristics for service 180D
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Characteristics discovered
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A37
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A37
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A38
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A38
DEBUG:bleak.backends.corebluetooth.client:Retrieving characteristics for service FE86
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Characteristics discovered
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic FE01
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered FE01
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic FE02
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered FE02
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic FE03
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered FE03
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic FE04
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered FE04
DEBUG:bleak.backends.corebluetooth.client:Retrieving services...
DEBUG:bleak.backends.corebluetooth.client:Retrieving characteristics for service 180F
DEBUG:bleak.backends.corebluetooth.CentralManagerDelegate:Peripheral Device disconnected!
Traceback (most recent call last):
File "/Users/zaytsev/PycharmProjects/bluetooth/bleak_demo.py", line 25, in <module>
loop.run_until_complete(ble_get_services(address, loop))
File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 579, in run_until_complete
return future.result()
File "/Users/zaytsev/PycharmProjects/bluetooth/bleak_demo.py", line 18, in ble_get_services
svcs = await client.get_services()
File "/Users/zaytsev/PycharmProjects/bluetooth/venv/lib/python3.7/site-packages/bleak/backends/corebluetooth/client.py", line 118, in get_services
self.services.add_service(BleakGATTServiceCoreBluetooth(service))
File "/Users/zaytsev/PycharmProjects/bluetooth/venv/lib/python3.7/site-packages/bleak/backends/service.py", line 101, in add_service
"This service is already present in this BleakGATTServiceCollection!"
bleak.exc.BleakError: This service is already present in this BleakGATTServiceCollection!
I'm trying to use bleak to write to a BLE characteristic.
If I write with a buffer shorter or equal to 127 bytes, the write succeeds, and the device behaves as expected.
However, if I write a buffer longer than 127 bytes, I got an exception.
Is there a length limit on the write_gatt_char() method?
See the exception below (only the bleak part):
File "C:\Tools\Python\lib\site-packages\bleak\backends\dotnet\client.py", line 372, in write_gatt_char
loop=self.loop,
File "C:\Tools\Python\lib\site-packages\bleak\backends\dotnet\utils.py", line 73, in wrap_IAsyncOperation
raise BleakDotNetTaskError(op.ErrorCode.ToString())
bleak.exc.BleakDotNetTaskError: System.ArgumentException: Value does not fall within the expected range.
`
Implement CoreBluetooth backend to use for macOS for true cross platform capabilities.
I'm trying to maintain a connection to a BLE device permanently. In case of connection lost (caused by an out of range o standby situation), I am reconnecting and resubscribing for the same notifications callback.
To accomplish this, my code looks something like this (simplified):
while self.running
async with BleakClient(device_mac, device="hci0", timeout=3) as bleak:
bleak.start_notify("FANCY UUID", callback=notification_handler)
while self.running and await bleak.is_connected():
await asyncio.sleep(2)
def notification_handler(self, uuid, value):
# do neat stuff
This seems to work, but every time I use start_notify the notification_handler method is triggered one additional time. Just to clarify: First connection, notification_handler is called 1 time per notification; second connection, notification_handler is called twice; an so on.
I verified the code and seems the problem is that DBUS is sending the notifications duplicated N times because of the resubscriptions. The cause of this is that when it's connecting, the library subscribes to PropertiesChanged rule which is only removed in case of controlled disconnection. I also tried to call disconnect function in case of uncontrolled disconnection but an exception is raised in such case.
File "/snap/pycharm-community/125/helpers/pydev/pydevd.py", line 1741, in <module>
main()
File "/snap/pycharm-community/125/helpers/pydev/pydevd.py", line 1735, in main
globals = debugger.run(setup['file'], None, None, is_module)
File "/snap/pycharm-community/125/helpers/pydev/pydevd.py", line 1135, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "/snap/pycharm-community/125/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "/home/marcx/btest/main.py", line 142, in <module>
asyncio.get_event_loop().run_until_complete(main())
File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "/home/marcx/btest/main.py", line 93, in main
await task
File "/home/marcx/btest/bleak_heart_rate_device.py", line 83, in start
await self.bleak.disconnect()
File "/home/marcx/btest/venv/lib/python3.7/site-packages/bleak/backends/client.py", line 45, in __aexit__
await self.disconnect()
File "/home/marcx/btest/venv/lib/python3.7/site-packages/bleak/backends/bluezdbus/client.py", line 131, in disconnect
await self._bus.delMatch(rule_id).asFuture(self.loop)
File "/home/marcx/btest/venv/lib/python3.7/site-packages/txdbus/client.py", line 185, in delMatch
rule = self.match_rules[rule_id]
KeyError: 1
Not sure what to do here. I'm doing something wrong? It is a bug?
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.