ianharvey / bluepy Goto Github PK
View Code? Open in Web Editor NEWPython interface to Bluetooth LE on Linux
License: Other
Python interface to Bluetooth LE on Linux
License: Other
I'm quite sure it's not an issue with bluepy, but I need confirmation. That's a discovery session with a heart rate sensor:
pi@occberry ~/bluepy/bluepy $ sudo hciconfig hci0 up
pi@occberry ~/bluez/bluez-5.26 $ sudo hcitool lescan
LE Scan ...
90:59:AF:16:93:12 (unknown)
90:59:AF:16:93:12 JipulseHrRateBT4.0
[..]
pi@occberry ~/bluepy/bluepy $ sudo python btle.py 90:59:AF:16:93:12
Connecting to: 90:59:AF:16:93:12
Service <uuid=Generic Attribute handleStart=12 handleEnd=15> :
Characteristic <2a05>
-> Error from Bluetooth stack (comerr)
Service <uuid=Generic Access handleStart=1 handleEnd=11> :
Characteristic
-> ''
Characteristic <2a01>
-> '\x00\x00'
Characteristic <2a02>
-> '\x00'
Characteristic <2a03>
-> '\x00\x00\x00\x00\x00\x00'
Characteristic <2a04>
-> 'P\x00\xa0\x00\x00\x00\xe8\x03'
Service <uuid=ffe0 handleStart=52 handleEnd=65535> :
Characteristic
-> Error from Bluetooth stack (comerr)
Service <uuid=fff0 handleStart=35 handleEnd=51> :
Characteristic
-> '\x01'
Characteristic
-> '\x02'
Characteristic
-> Error from Bluetooth stack (comerr)
Characteristic
-> Error from Bluetooth stack (comerr)
Characteristic
-> Error from Bluetooth stack (comerr)
Service <uuid=Device Information handleStart=16 handleEnd=34> :
Characteristic <2a23>
-> '\x12\x93\x16\x00\x00\xafY\x90'
Characteristic
-> 'Model Number\x00'
Characteristic
-> 'Serial Number\x00'
Characteristic
-> 'Firmware Revision\x00'
Characteristic
-> 'Hardware Revision\x00'
Characteristic
-> 'Software Revision\x00'
Characteristic
-> 'Manufacturer Name\x00'
Characteristic <2a2a>
-> '\xfe\x00experimental'
Characteristic <2a50>
-> '\x01\r\x00\x00\x00\x10\x01'
Does it look OK conparing to other BLE devices?
That sensor doesn't work properly with android, so I guess that the vendor at least partially ignored BLE specification. P.S. Running the bluepy-helper doesn't make any difference.
Hi I am writing a program that register for a notification, I register the delegate and after try to register for notification calling write('\x01\x00') as noted in another issue and described in the bluetooth 4.0 rfc.
But it doesn't work, any notification for the characteristic is received. Is there an error in the small snippet I wrote? Thank you so much.
class MyDelegate(btle.DefaultDelegate):
def __init__(self, hndl):
btle.DefaultDelegate.__init__(self)
self.hndl=hndl;
def handleNotification(self, cHandle, data):
if (cHandle==self.hndl):
val = binascii.b2a_hex(data)
val = binascii.unhexlify(val)
val = struct.unpack('f', val)[0]
print str(val) + " deg C"
p = btle.Peripheral("xx:xx:xx:xx", "random")
try:
srvs = (p.getServices());
chs=srvs[2].getCharacteristics();
ch=chs[1];
print(str(ch)+str(ch.propertiesToString()));
p.setDelegate(MyDelegate(ch.getHandle()));
# Setup to turn notifications on, e.g.
ch.write("\x01\x00");
# Main loop --------
while True:
if p.waitForNotifications(1.0):
continue
print "Waiting..."
# Perhaps do something else here
finally:
p.disconnect();
Can't setting up the address & connection be done within the program? In other words, can't establishing the initial connection be done in Python? Typing in manual commands goes against just simply powering up & running the app.
Hello,
I have successfully established an LE connection to my BLE device with Bluepy. Now for testing reasons, I would like to control the authentication and encryption of the link. Is this possible? I have tried setting the security level but it did not change anything. Is is possible to do this? If this is the case, who controls the storage of the link keys?
Thanks
I tried to replace the bluez-5.29 in this package, with the latest bluez-5.35 release.
Got compile error in "bluepy-helper.c", line 462. Made minor change there, and it
seems to work. I just set the new flag passed to the subroutine as "false". That
should be OK as it is for an external encryption option.
Just in case you want to upgrade and test it, below were the chaanges:
sudo leafpad Makefile (Change Bluez version's Directory)
BLUEZ_PATH=../bluez-5.35
sudo leafpad bluepy-helper.c (Add "false" for a 3rd/new parameter RE external encryption)
Line 462: attrib = g_attrib_new(iochannel, mtu, false);
Hi Ian,
I like a lot your code, because it is very elegant and nice. I have using it but I have some speed issues that I think that would be solved activating the notification mode of the sensors in a ST. Do you have any suggestion about it? Any plan to continue this project in this line?
Thanks for your work.
Uses the humidity sensor scaling for the older sensorTag instead of scaling for HTC1000 used in newer CC2650 sensorTag. Could keep track of which sensorTag is in use and use the appropriate scaling.
SHT21 (old sensorTag)
humidity =-6+125_raw/65536
temperature =-4686 + 175.72_raw/65536
HDC1000 (CC2650 sensorTag)
humidity = (raw/65536)_100
temperature = (raw/65536)_165 - 40
Note: at least one of these values should also have some status bits masked off and attention should be paid to data types and rounding.
I tried to build bluepy-helper against the current bluez source tree (bluez-5.29). It was straightforward to point the makefile at that source tree, but I got a raft of errors and did not pursue it further.
gcc -L. -O0 -g -DHAVE_CONFIG_H -I../bluez-5.29/attrib -I../bluez-5.29 -I../bluez-5.29/lib -I../bluez-5.29/src -I../bluez-5.29/gdbus -I../bluez-5.29/btio `pkg-config glib-2.0 dbus-1 --cflags` -o bluepy-helper bluepy-helper.c ../bluez-5.29/lib/bluetooth.c ../bluez-5.29/lib/hci.c ../bluez-5.29/lib/sdp.c ../bluez-5.29/lib/uuid.c ../bluez-5.29/attrib/att.c ../bluez-5.29/attrib/gatt.c ../bluez-5.29/attrib/gattrib.c ../bluez-5.29/attrib/utils.c ../bluez-5.29/btio/btio.c ../bluez-5.29/src/log.c `pkg-config glib-2.0 --libs`
bluepy-helper.c:25:20: fatal error: config.h: No such file or directory
#include "config.h"
^
compilation terminated.
../bluez-5.29/lib/bluetooth.c:27:20: fatal error: config.h: No such file or directory
#include <config.h>
^
compilation terminated.
../bluez-5.29/lib/hci.c:27:20: fatal error: config.h: No such file or directory
#include <config.h>
^
compilation terminated.
../bluez-5.29/lib/sdp.c:28:20: fatal error: config.h: No such file or directory
#include <config.h>
Hi Ian,
Not so much an issue as a request.
I'd need to add the -t address type [public|random] to the gatttool I believe during the connect. I specifically need random and could simply hard code it, but... Having the flag and option would be better your tool over time.
Rather than trial-and-error it, wasting an hour or two, might you suggest where it would be best added?
Thanks!
Jeff
I am using bluepy on Debian (on the Intel Edison i386 board). While there is no problem connecting to BLE devices that expose a 'public' address (it works just fine with the TI SensorTag and with the RedBearLab BLE Mini), there is a problem (main.BTLEException: Failed to connect to peripheral) connecting to devices that expose a 'random' address (e.g. the RedBearLab BLE Blend Micro).
Please note that 'gatttool -b xx:xx:xx:xx:xx:xx -I' connects to a device with 'public' address and 'gatttool -b xx:xx:xx:xx:xx:xx -I -t random' to a device with 'random' address.
As mentioned in the readme, an open issue to support RSSI in bluepy.
Are you OK to use your code in an GPLv3 project? I'm working on an open software/hardware cycling computer (raspberry pi + PiTFT + pygame) and looks like your code will be perfect to impelment speed, cadence and heart reate measurements from BLE sensors.
Update 2014-03-08: I built the BluePy again after installing Bluez5.4 and now I do not get the error anymore! It was because of my lack of knowledge. So please close this issue!
Running RPi with Raspbian distro and Bluez5.28 drivers
When I run the python code at the bottom I get the following result:
pi@pi ~/Desktop/bletest $ python BluePyTest.py
Running /usr/local/lib/python2.7/dist-packages/bluepy-helper
Traceback (most recent call last):
File "BluePyTest.py", line 22, in <module>
bean = btle.Peripheral(address)
File "/usr/local/lib/python2.7/dist-packages/btle.py", line 190, in __init__
self.connect(deviceAddr, addrType)
File "/usr/local/lib/python2.7/dist-packages/btle.py", line 294, in connect
self._startHelper()
File "/usr/local/lib/python2.7/dist-packages/btle.py", line 201, in _startHelper
universal_newlines=True)
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1259, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
The python code BluePyTest.py
:
import sys
import btle
class MyDelegate(btle.DefaultDelegate):
def __init__(self):
btle.DefaultDelegate.__init__(self)
# ... initialise here
def handleNotification(self, cHandle, data):
# ... perhaps check cHandle
# ... process 'data'
print "Received notification:"
print cHandle
print "Data:"
print data
# Initialisation -------
address = "6F:33:41:AA:C2:AB"
bean = btle.Peripheral(address)
# more code below, but not relevant here.
Is this because I have configured it wrong? I can not get it to play.
Probable cause: BluePy not supporting Bluez5.28? I tried to make the BluePy once more changing the Makefile Bluez path to a prebuilt Bluez5.28. This returned an error:
pi@pi ~/Desktop/bluepy/bluepy/bluepy $ make
gcc -L. -O0 -g -DHAVE_CONFIG_H -I..//../../bluez/bluez-5.28/attrib -I..//../../bluez/bluez-5.28 -I..//../../bluez/bluez-5.28/lib -I..//../../bluez/bluez-5.28/src -I..//../../bluez/bluez-5.28/gdbus -I..//../../bluez/bluez-5.28/btio `pkg-config glib-2.0 dbus-1 --cflags` -o bluepy-helper bluepy-helper.c ..//../../bluez/bluez-5.28/lib/bluetooth.c ..//../../bluez/bluez-5.28/lib/hci.c ..//../../bluez/bluez-5.28/lib/sdp.c ..//../../bluez/bluez-5.28/lib/uuid.c ..//../../bluez/bluez-5.28/attrib/att.c ..//../../bluez/bluez-5.28/attrib/gatt.c ..//../../bluez/bluez-5.28/attrib/gattrib.c ..//../../bluez/bluez-5.28/attrib/utils.c ..//../../bluez/bluez-5.28/btio/btio.c ..//../../bluez/bluez-5.28/src/log.c `pkg-config glib-2.0 --libs`
bluepy-helper.c: In function ‘connect_cb’:
bluepy-helper.c:225:2: error: too few arguments to function ‘g_attrib_new’
..//../../bluez/bluez-5.28/attrib/gattrib.h:45:10: note: declared here
bluepy-helper.c: In function ‘char_desc_cb’:
bluepy-helper.c:357:9: error: incompatible types when assigning to type ‘bt_uuid_t’ from type ‘int’
bluepy-helper.c:359:9: error: incompatible types when assigning to type ‘bt_uuid_t’ from type ‘int’
bluepy-helper.c: In function ‘cmd_connect’:
bluepy-helper.c:474:7: error: too few arguments to function ‘gatt_connect’
..//../../bluez/bluez-5.28/attrib/gatttool.h:26:13: note: declared here
bluepy-helper.c: In function ‘cmd_primary’:
bluepy-helper.c:497:3: warning: passing argument 3 of ‘gatt_discover_primary’ from incompatible pointer type [enabled by default]
..//../../bluez/bluez-5.28/attrib/gatt.h:76:7: note: expected ‘gatt_cb_t’ but argument is of type ‘void (*)(struct GSList *, guint8, void *)’
bluepy-helper.c:506:2: warning: passing argument 3 of ‘gatt_discover_primary’ from incompatible pointer type [enabled by default]
..//../../bluez/bluez-5.28/attrib/gatt.h:76:7: note: expected ‘gatt_cb_t’ but argument is of type ‘void (*)(struct GSList *, guint8, void *)’
bluepy-helper.c: In function ‘cmd_included’:
bluepy-helper.c:549:2: warning: passing argument 4 of ‘gatt_find_included’ from incompatible pointer type [enabled by default]
..//../../bluez/bluez-5.28/attrib/gatt.h:79:14: note: expected ‘gatt_cb_t’ but argument is of type ‘void (*)(struct GSList *, guint8, void *)’
bluepy-helper.c: In function ‘cmd_char’:
bluepy-helper.c:586:3: warning: passing argument 5 of ‘gatt_discover_char’ from incompatible pointer type [enabled by default]
..//../../bluez/bluez-5.28/attrib/gatt.h:82:7: note: expected ‘gatt_cb_t’ but argument is of type ‘void (*)(struct GSList *, guint8, void *)’
bluepy-helper.c:590:2: warning: passing argument 5 of ‘gatt_discover_char’ from incompatible pointer type [enabled by default]
..//../../bluez/bluez-5.28/attrib/gatt.h:82:7: note: expected ‘gatt_cb_t’ but argument is of type ‘void (*)(struct GSList *, guint8, void *)’
Makefile:23: recipe for target 'bluepy-helper' failed
make: *** [bluepy-helper] Error 1
Sorry if this is a simple question but I am having trouble compiling bluepy on Raspberry Pi:
Already installed libraries:
pi@rasp01 ~ $ sudo apt-get install build-essential libglib2.0-dev libdbus-1-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
build-essential is already the newest version.
libdbus-1-dev is already the newest version.
libglib2.0-dev is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 40 not upgraded.
Cloned bluepy:
pi@rasp01 - $ git clone https://github.com/IanHarvey/bluepy.git
pi@rasp01 - $ cd bluepy/bluepy
And tried to compile the source (this is where I ran into problems):
pi@rasp01 ~/bluepy/bluepy $ make
gcc -L. -Os -g -Wall -Werror -DHAVE_CONFIG_H -I../bluez-5.33/attrib -I../bluez-5.33 -I../bluez-5.33/lib -I../bluez-5.33/src -I../bluez-5.33/gdbus -I../bluez-5.33/btio pkg-config glib-2.0 dbus-1 --cflags
-o bluepy-helper bluepy-helper.c ../bluez-5.33/lib/bluetooth.c ../bluez-5.33/lib/hci.c ../bluez-5.33/lib/sdp.c ../bluez-5.33/lib/uuid.c ../bluez-5.33/attrib/att.c ../bluez-5.33/attrib/gatt.c ../bluez-5.33/attrib/gattrib.c ../bluez-5.33/attrib/utils.c ../bluez-5.33/btio/btio.c ../bluez-5.33/src/log.c ../bluez-5.33/src/shared/mgmt.c ../bluez-5.33/src/shared/crypto.c ../bluez-5.33/src/shared/att.c ../bluez-5.33/src/shared/queue.c ../bluez-5.33/src/shared/util.c ../bluez-5.33/src/shared/io-glib.c ../bluez-5.33/src/shared/timeout-glib.c pkg-config glib-2.0 --libs
bluepy-helper.c: In function âconnect_cbâ:
bluepy-helper.c:462:2: error: too few arguments to function âg_attrib_newâ
../bluez-5.33/attrib/gattrib.h:45:10: note: declared here
bluepy-helper.c: In function âcmd_pairâ:
bluepy-helper.c:1180:7: error: unused variable âaddrâ [-Werror=unused-variable]
bluepy-helper.c: In function âcmd_unpairâ:
bluepy-helper.c:1230:7: error: unused variable âaddrâ [-Werror=unused-variable]
bluepy-helper.c: In function âmgmt_debugâ:
bluepy-helper.c:1396:14: error: unused variable âprefixâ [-Werror=unused-variable]
cc1: all warnings being treated as errors
Makefile:26: recipe for target 'bluepy-helper' failed
make: *** [bluepy-helper] Error 1
I am using bluez-5.33 instead of 5.29.
Any insight would be much appreciated.
Thank you!!!
Hi,
I'm trying to run your lib on RPi. I removed everything and just put
conn = Peripheral("72:64:9D:DB:0A:11")
and I get
Running /home/pi/BT/LE/sandbox/bluepy-helper
Sent: conn 72:64:9D:DB:0A:11
Got: '# bluepy-helper.c built at 12:26:47 on Apr 11 2014\n'
Got: "rsp=$stat state=$tryconn dst='72:64:9D:DB:0A:11 mtu=h0 sec='low\n"
Any idea why?
Is there any example code other than included btle.py
?
I've installed bluez 5.30 (downloaded and built manually).
Then clone and build bluepy.
Then I ran python btle.py XX:YY:...... and it worked perfectly.
However after the first restart is doesnt work anymore.
Connecting to: C4:BE:84:76:F3:14, address type: public
Traceback (most recent call last):
File "btle.py", line 481, in
conn = Peripheral(devAddr, addrType)
File "btle.py", line 193, in init
self.connect(deviceAddr, addrType)
File "btle.py", line 321, in connect
rsp = self._getResp('stat')
File "btle.py", line 278, in _getResp
resp = Peripheral.parseResp(rv)
File "btle.py", line 241, in parseResp
(tag, tval) = item.split('=')
ValueError: need more than 1 value to unpack
Exception ValueError: 'need more than 1 value to unpack' in <bound method Peripheral.del of <main.Peripheral instance at 0x76aef4e0>> ignored
Hi Gents:
I came across this package (bluepy) in my quest to get some BLE Python apps created & up & running using the rpi and V4.0 USB dongle. Until now, I haven't seen much in the way of doing BLE & I'm no Bluetooth expert. But it seems like the ideal, low cost interface, when battery power is critical. Just have some ideas to send some data from place to place...Are there any more examples or commentary in setting up & using bluepy?
I have two copies of sensortag.py - each copy has its own BLE ID it listens to.
If only one Sensor Tag is powered on then its assigned sensortag.py works fine - the other does not because its associated device is not running. This works also if I swap sensotag.pys and devices.
When I launch two devices and one sensortag.py then the program is still behaving as expected.
As soon as I run the second sensortag.py, everything breaks.
the stack trace I get is:
File "sensortag.py", line 203, in
ir, hum, baro, gyro = [ s.read() for s in sensors ]
File "sensortag.py", line 60, in read
(rawVobj, rawTamb) = struct.unpack('<hh', self.data.read())
File "/root/sensors/bluepy/bluepy/btle.py", line 114, in read
return self.peripheral.readCharacteristic(self.valHandle)
File "/root/sensors/bluepy/bluepy/btle.py", line 296, in readCharacteristic
resp = self._getResp('rd')
File "/root/sensors/bluepy/bluepy/btle.py", line 210, in _getResp
raise BTLEException(BTLEException.COMM_ERROR, "Error from Bluetooth stack (%s)" % errcode)
btle.BTLEException: Error from Bluetooth stack (comerr)
The only file that I've modified is sensortag.py. The change was tiny and only related to the device ID.
Is bluepy working in some kind of single connection mode? Is there a way I could find the root cause? What would be the best workaround for reading from multiple sensorTags without making big changes to the bluepy internals?
I tried to read the Temperature data from the Sensor tag and I was able to do it. But reading accelerometer data throws error. This is the command I executed:
pi@raspberrypi ~/bluepy/bluepy $ sudo python sensortag.py 68:C9:0B:06:64:84 -n 5 -A
Which returned the following:
Connecting to 68:C9:0B:06:64:84
Traceback (most recent call last):
File "sensortag.py", line 293, in <module>
main()
File "sensortag.py", line 257, in main
tag.accelerometer.enable()
File "sensortag.py", line 21, in enable
self.service = self.periph.getServiceByUUID(self.svcUUID)
File "/home/pi/bluepy/bluepy/btle.py", line 365, in getServiceByUUID
svc = Service(self, uuid, rsp['hstart'][0], rsp['hend'][0])
KeyError: 'hstart'
The newest merge seems to have broken the _getResp() method. With the following test code:
from bluepy.btle import Peripheral
p = Peripheral("xx:xx:xx:xx:xx:xx")
I get the following error:
File "/home/edison/bluepy/bluepy/btle.py", line 188, in init
self.connect(deviceAddr, addrType)
connect: Device or resource busy (16)
File "/home/edison/bluepy/bluepy/btle.py", line 298, in connect
rsp = self._getResp('stat')
File "/home/edison/bluepy/bluepy/btle.py", line 250, in _getResp
rv = ''.join(map(chr, rv))
TypeError: an integer is required
Exception TypeError: 'an integer is required' in <bound method Peripheral.del of <bluepy.btle.Peripheral instance at 0xb72b98ec>> ignored
Are indications supported yet? They're very similar, and notifications are working fine for me, but indications aren't appearing at all.
Hi,
What is the default connection timeout value ?
Is it possible to change it ?
Thanks and regards.
Hi,
Could someone tell me how the GATT client has to subscribe to notifications ?. Writting 0x01 in the characteristic CCCD descriptor ?.
I don't understand the way to do this described in bluepy 0.9.0 documentation (working with notifications).
Thanks and regards.
See #5 (comment)
reported by @BrianAtLonmed
Shortly:
pi@raspberrypi ~ $ python3 work/bluepy/bluepy/bluepy/btle.py e0:c7:9d:5e:4a:9c
Connecting to: e0:c7:9d:5e:4a:9c
Running /home/pi/work/bluepy/bluepy/bluepy/bluepy-helper
Sent: conn e0:c7:9d:5e:4a:9cGot: '# bluepy-helper.c built at 13:33:00 on Sep 4 2014\n'
and then it does not read anything further.
Expected behaviour, send a conn command to the specified address.
I've had success using bluepy to connect to and read characteristics from the raspberry pi, but when I try to use the write() method, it isn't working:
baddr = 'xx:xx:xx:xx:xx:xx'
device = btle.Peripheral(baddr,'random')
chars = device.getCharacteristics()
chars[9].read()
returns '\x00'
but
chars[9].write('02')
and
chars[9].write('\x02')
accomplish nothing, because if I issue again
chars[9].read()
again I get '\x00'
with gatttool in bash the following works:
gatttool -b xx:xx:xx:xx:xx:xx -t random --char-write 0x001b -n 02
How can I pass data to a characteristic using the write() method?
Thanks!
I amended btle.py with some support for py3.4, I'll do a pull request at some point in the future.
Feel free to see my fork's branch "py3". I had to reformat many things, as they broke on python 3.4.
I took the chance to have them formatted as much I could with pylint, pep8 and pep257, as I'm planning to use the code later.
Back compatible with 2.7 in theory, I tried it out and it works, but there are no unit tests so it's hard to say.
bluepy-helper.c does not seem to print anything to stdout
bluepy and bluepy-helper depend on Linux's bluez.
It would be a useful thing to have an abstraction layer that let you write the same python code for both Mac OS X and Linux, along the lines of what noble does for node.js.
Tracking any specific issues here.
Hey Ian,
Have you given much thought to adding low-energy scanning to bluepy? I saw it in your TODO's, and I'm wondering whether you have a sense of what it would take (time, roadblocks, etc). I've been considering taking this on and have done a bit of research, but, if you've already started, I'd like to pick your brain.
Thanks,
Oren
Hi there!
I'm currently trying to read/write serial data from a HM10-BLE module.
The module is connected to my USB via an FTDI chip and I can read/write AT-commands.
I'm already able to write data via Bluetooth and can see the chars via my usb-interface but it does not seem to work the other way around.
Here are some details:
s9 bluepy # python btle.py 7C:66:9D:9A:6F:90 Connecting to: 7C:66:9D:9A:6F:90 Service : Characteristic <2a05> -> Error from Bluetooth stack (comerr) Service : Characteristic -> 'HMSoft' Characteristic <2a01> -> '\x00\x00' Characteristic <2a02> -> '\x00' Characteristic <2a03> -> '\x00\x00\x00\x00\x00\x00' Characteristic <2a04> -> 'P\x00\xa0\x00\x00\x00\xe8\x03' Service : Characteristic -> '\x00'
I have 3 services with differet characteristics:
== 00001801-0000-1000-8000-00805f9b34fb == [] == 00001800-0000-1000-8000-00805f9b34fb == [, , , , ] == 0000ffe0-0000-1000-8000-00805f9b34fb == []
So my data-channel seems to be 0000ffe0, writing here ends at my USB side.
Does anybody know how I'd be able to read? The read() on the data-channel just returns None.
My code:
import struct from btle import UUID, Peripheral class HM10(Peripheral): _ctrlUUID=UUID("00001800-0000-1000-8000-00805f9b34fb") _dataUUID=UUID("0000ffe0-0000-1000-8000-00805f9b34fb") def __init__(self, addr): Peripheral.__init__(self,addr) self.discoverServices() for cUUID in self.services: print("== %s =="%str(cUUID)) print(self.getServiceByUUID(cUUID).getCharacteristics()) self.ctrl_SRV=self.getServiceByUUID(self._ctrlUUID) self.data_SRV=self.getServiceByUUID(self._dataUUID) self.data = self.data_SRV.getCharacteristics()[0] #print("== CTRL ==") #print(self.ctrl_SRV.getCharacteristics()) self.ctrl = self.ctrl_SRV.getCharacteristics()[0] if __name__ == "__main__": import time cHM10 = HM10("7C:66:9D:9A:6F:90") cHM10.ctrl.write(struct.pack("B", 0xff)) #cHM10.ctrl.write(struct.pack("B", 0)) while True: print(cHM10.data.read()) print(cHM10.data.write("%s\n\r"%str(time.time()))) time.sleep(1.0)
Thanks for any hints!
Hey Ian,
I'm having an issue when trying get or discover services. I can establish the connection without an issue:
>>> conn = Peripheral("5C:F3:70:62:FE:5D", "public")
Running /home/pi/GitHub/bluepy/bluepy/bluepy-helper
Sent: conn 5C:F3:70:62:FE:5D public
Got: '# bluepy-helper.c built at 22:58:35 on Jun 8 2015\n'
Got: "rsp=$stat state=$tryconn dst='5C:F3:70:62:FE:5D mtu=h0 sec='low\n"
Got: "rsp=$stat state=$conn dst='5C:F3:70:62:FE:5D mtu=h0 sec='low\n"'
Then calling getServices() or discoverServices() causes the device to disconnect:
>>> conn.discoverServices()
Sent: svcs
Got: "rsp=$stat state=$disc mtu=h0 sec='low\n"
Stopping /home/pi/GitHub/bluepy/bluepy/bluepy-helper
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "btle.py", line 325, in discoverServices
rsp = self._getResp('find')
File "btle.py", line 286, in _getResp
raise BTLEException(BTLEException.DISCONNECTED, "Device disconnected")
btle.BTLEException: Device disconnected
But calling getCharacteristics() works fine:
>>> conn.getCharacteristics()
Sent: char 1 FFFF
Got: "rsp=$find hnd=h4 props=h2 vhnd=h6 uuid='00002a00-0000-1000-8000-00805f9b34fb hnd=h7 props=h2 vhnd=h8 uuid='00002a01-0000-1000-8000-00805f9b34fb hnd=hFFFD props=h1A vhnd=hFFFE uuid='faf69fd8-d058-45e3-a06e-86662c8c7918\n"
[<btle.Characteristic instance at 0x76abce40>, <btle.Characteristic instance at 0x76abe0a8>, <btle.Characteristic instance at 0x76abe170>]
And calling getDescriptors works (minus it seeming to hang at the end):
>>> conn.getDescriptors()
Sent: desc 1 FFFF
Got: "rsp=$desc hnd=h1 uuid='2800 hnd=h4 uuid='2803 hnd=h6 uuid='2a00 hnd=h7 uuid='2803 hnd=h8 uuid='2a01\n"
Got: "rsp=$desc hnd=h10 uuid='2800 hnd=hFFFC uuid='2800 hnd=hFFFD uuid='2803\n"
Got: "rsp=$desc hnd=hFFFE uuid='faf69fd8-d058-45e3-a06e-86662c8c7918\n"
Got: "rsp=$desc hnd=hFFFF uuid='2902\n"
Any ideas on why the device disconnects? Thanks!
Hi,
Maybe I missed something but how can my application be notified from characteristic changes without polling it ?
Thanks for your great tool !
Hi,
Trying write a characteristic appears the following error :
Unhandled exception in thread started by <function peticion_datos_PTHVcc at 0xb6adc830>
Traceback (most recent call last):
File "duracion_bateria.py", line 218, in peticion_datos_PTHVcc
carac_comando.write("58".decode("hex"), True)
File "/home/pi/python/btle.py", line 142, in write
self.peripheral.writeCharacteristic(self.valHandle, val, withResponse)
No se encuentra el dispositivo BLE
File "/home/pi/python/btle.py", line 377, in writeCharacteristic
return self._getResp('wr')
File "/home/pi/python/btle.py", line 262, in _getResp
resp = Peripheral.parseResp(rv)
File "/home/pi/python/btle.py", line 227, in parseResp
(tag, tval) = item.split('=')
ValueError: need more than 1 value to unpack
Could someone tell me what I am doing bad ?
Thanks and regards.
Hi,
Have you got any idea about the response time of the method write from the characteristic class ?
By response time, I mean time from the call of this method until the reception from the Peripheral.
I wrote a simple program on a raspberry which receive data by udp and send it to a bluetooth peripheral using bluepy.
I measure 40ms in average between the udp sending and the bluetooth reception. I would like it to be a bit faster, so I try to improve my program on the raspberry.
I don't know if this response time is due to a bad implementation of the udp reception, I made a non blocking reception in a thread which fill a queue. In another thread this queue is read and send by bluetooth. But it seems that threads can be tricky and maybe I did something bad.
Or maybe this response time is normal and is due to the time taking by the write method to execute, I don't know. Have you ever measured it ?
Anyway, thanks for this API, your work really helped me a lot !
Hi,
I have the following crash with python3.2:
Traceback (most recent call last):
File "./home.py", line 8, in
import sensortag
File "/home/pi/apps/bluepy/bluepy/sensortag.py", line 1, in
from btle import UUID, Peripheral
File "/home/pi/apps/bluepy/bluepy/btle.py", line 344, in
UUID(0x1811, "Alert Notification Service"),
File "/home/pi/apps/bluepy/bluepy/btle.py", line 58, in init
self.binVal = binascii.a2b_hex(val)
TypeError: 'str' does not support the buffer interface
I think the following fixes it:
git diff
diff --git a/bluepy/btle.py b/bluepy/btle.py
index 7226c47..31b4328 100644
--- a/bluepy/btle.py
+++ b/bluepy/btle.py
@@ -55,7 +55,7 @@ class UUID:
if len(val) <= 8: # Short form
val = ("0" * (8 - len(val))) + val + "00001000800000805F9B34FB"
self.binVal = binascii.a2b_hex(val)
self.binVal = binascii.a2b_hex(bytes(val, "ascii"))
if len(self.binVal) != 16:
raise ValueError(
"UUID must be 16 bytes, got '%s' (len=%d)" % (val,
val = binascii.a2b_hex(tval[1:])
val = binascii.a2b_hex(bytes(tval[1:], "ascii"))
else:
raise BTLEException(BTLEException.INTERNAL_ERROR,
"Cannot understand response value %s" % repr(tval))
and it has no downside since you just use a2b_hex for data/numerical values.
Hi Ian
I noticed the comment below on your readme for the project:
- Implement 'hcitool lescan' functionality
Are you aware of any python libs that will expose the raw advertisement payloads?
Any idea if / when yours may?
Thanks!
Running the example code on my sensortag, after a few succesful read, I had:
File "sensortag.py", line 196, in <module>
ir, hum, baro = [ s.read() for s in sensors ]
File "sensortag.py", line 196, in <listcomp>
ir, hum, baro = [ s.read() for s in sensors ]
File "sensortag.py", line 67, in read
tObj = math.pow( math.pow(tDie,4.0) + (fObj/S), 0.25 )
ValueError: math domain error
I suspect S==0
. I will try to confirm that
Hi the accelerometer equation devides by 64.
I found this to be inacurate as it did not give a resultant acceleration of 1 g when the sensortag was still on a table. I changed the code to devide by 16 instead and got better output.
Please someone do a simple test to verify this.
I realize I may be pushing the limits of how this is intended to work, and am using a modified bluepy, but here goes: The short version is that if a bluepy connection is pending (e.g., the receiver is powered off and we're waiting for it to time out), other connection attempts--in separate btle objects, with their own bluepy-helper processes--immediately fail.
I'm using a single python application to communicate with multiple BLE devices. Now normally you can't get into the state I described above (multiple pending connects) because connect() blocks. You might be able to get there by using threads, but for various reasons I took a different approach, and made my own asynchronous connect method. connect_async() initiates the connect, and you can poll a second method to detech when and how connect completes (either successfully or not). Aside from the problem described here, this appears to work perfectly. If all receivers are up, or if I wait for the first connection to fail before initiating the second connection, then they all connect and operate simultaneously as expected.
So in my code, the steps that cause this are:
When it fails this way, it prints the following message:
connect: Device or resource busy (16)
I believe I have tracked this to the connect() call in bluez btio.c line 360 (and output at like 1433), but I don't know enough about bluez to really dig further.
FWIW, I just tried it on the testing/bluez-5.29 branch, and it behaved exactly the same.
Thanks for any help, and let me know if you need additional info or if there's a better way I should be doing all of this; I realize this is a bit scattered. I'm also happy to share my async connection code, though it isn't robust and I'm 90% it's not the direct cause of the issue.
From #5 (comment)
Reported by @jordy33
Communication flow:
conn bc:6a:29:ac:29:31
rsp=$stat state=$tryconn dst='bc:6a:29:ac:29:31 mtu=h0 sec='low
rsp=$stat state=$conn dst='bc:6a:29:ac:29:31 mtu=h0 sec='low
it hangs the second time it hits line 191:
rv = self._helper.stdout.readline()
I am using your library in one of my projects as a submodule, and it screws up the git updating when there is no .gitignore.
Could you add at least the following:
# .gitignore file
__pycache__
.DS_Store
Thanks!
Not really an Issue, but I have a question:
The device I am trying to communicate with requires that I set the value of a characteristic and then write to the characteristic. The response from this write contains the result of the command. For instance if I write "read temp\r" I get back "66.0". I have looked through your code, but not being an expert in Python, I am having a bit of a time figuring out how I write a string (like "status") to the characteristic and then get back the response. I am pretty sure this is something simple, but I am stuck.
The Code in the main function which is related to the mgmt function always fails. However it doesnt affect connecting to Bluetooth (as long as the workaround from issue 72 is implemented)
It would be nice if the supported Python versions were displayed in the Readme. I took a look through closed issues and based on that I think this package supports Python 3.3+, but the setup.py only mentions Python 2.7.
Now that we have a setup.py
-- is there anything blocking a release to pypi?
Hi there, first of all thanks for reading this!
Currently i am working on a heart rate monitor in python with the polar H7 and i'm getting stuck with the notify part of BLE heart rate.
import struct
import btle
class MyDelegate(btle.DefaultDelegate):
def __init__(self):
btle.DefaultDelegate.__init__(self)
def handleNotification(self, cHandle, data):
print(data)
if __name__ == '__main__':
heartrate_uuid = btle.UUID(0x2a38)
p = btle.Peripheral("00:22:D0:2B:F8:EC")
p.setDelegate(MyDelegate())
print("Connected")
try:
print("Setting Characteristics")
ch = p.getCharacteristics(uuid=heartrate_uuid)[0]
print("Setting Done, writing now")
ch.write(struct.pack('<bb', 0x01, 0x00))
print("writing Done, looping now")
while True:
if p.waitForNotifications(1.0):
print("Notification trigger")
continue
print("Waiting")
finally:
p.disconnect()
Im not sure where i go wrong but i guess i dont have the right setup_data (from the example)
Can someone get me back on the right track?
Can't ctypes do the job as well ? It would really be a big improvement I think.
If the system has a bluetooth adapter which doesn't support LE there is no way to tell bluepy to not use it. It always tries to use the one most recently connected to the system.
TI has a new Sensortag 2, about the same shape and size as the original Sensortag but with a couple more sensors, a new processor, and better battery life.
When I try to connect to it with sensortag.py I get this:
emv@rubus ~/bluepy/bluepy $ python ./sensortag.py --all 68:C9:0B:06:C9:08
Connecting to 68:C9:0B:06:C9:08
Traceback (most recent call last):
File "./sensortag.py", line 255, in <module>
tag.barometer.enable()
File "./sensortag.py", line 128, in enable
self.calChr = self.service.getCharacteristics(self.calUUID) [0]
IndexError: list index out of range
There's been some porting work to support the Sensortag 2 from node.js, and there's UUIDs and sample code etc pointed to from here:
sandeepmistry/node-sensortag#34
which should be a useful stop to sort through what has changed.
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.