0%

bluepy - Python 版的 BLE 利器

无意间发现了一个 python 版的 BLE 利器 - bluepy

简介

bluepy 是 github 上的一个开源项目,它用 python 封装了 linux 上的 BLE 接口。

作者主要基于树莓派开发,也可以运行在 x86 Debian Linux 上。

bluepy 其实是 BlueZ 的 python 封装。

使用

对于 Windows 和 macOS 用户,可以用虚拟机安装 Ubuntu(基于 Debian 系统)。

安装

1
2
$ sudo apt-get install python3-pip libglib2.0-dev
$ sudo pip3 install bluepy

实战

bluepy 的文档中的 demo 很少,所幸 github 上有个仓库有丰富的例程,不过都是 python2,自己转了几个 python3 的例子。

注意:需要 root 权限来运行这些脚本。

Scan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from bluepy.btle import Scanner, DefaultDelegate

class ScanDelegate(DefaultDelegate):
def __init__(self):
DefaultDelegate.__init__(self)

def handleDiscovery(self, dev, isNewDev, isNewData):
if isNewDev:
print("Discovered device", dev.addr)
elif isNewData:
print("Received new data from", dev.addr)

scanner = Scanner().withDelegate(ScanDelegate())
devices = scanner.scan(10.0)

for dev in devices:
print("Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi))
for (adtype, desc, value) in dev.getScanData():
print(" %s = %s" % (desc, value))
  • Scanner([index=0])用于产生并初始化一个新的scanner对象,index 用来指名哪一个蓝牙设备就会被用(默认0表示使用/dev/hci0)。调用start或scan函数之后开始扫描。
  • withDelegate(delegate)存储对委托对象的引用,委托对象在接收来自设备的广播时接收回调。有关详细信息,请参阅DefaultDelegate的文档。
  • scan([timeout = 10])开始扫描并带有扫描时间,在此扫描期间扫描到的设备会触发Delegate的回调函数,我们可以在其回调函数中实时获取并打印。当扫描结束后后会返回一个设备列表。

运行结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Discovered device 01:d1:c5:88:91:8e
Discovered device 0d:1e:9d:f4:5a:62
Received new data from 01:d1:c5:88:91:8e
Discovered device 3c:32:dc:9d:24:6b
Discovered device f4:d7:60:14:88:84
Discovered device ab:36:be:b6:43:43
Discovered device 96:bb:75:92:ca:8a
Discovered device fb:ac:56:d9:44:cf

Device 01:d1:c5:88:91:8e (public), RSSI=-62 dB
Manufacturer = a8010a05c90e000038d2ca307de1
Complete Local Name = MeshDevice
Device 0d:1e:9d:f4:5a:62 (public), RSSI=-61 dB
Device 3c:32:dc:9d:24:6b (public), RSSI=-76 dB
Manufacturer = 8f030a101c0000fa987f4f5e80ec
Device f4:d7:60:14:88:84 (public), RSSI=-86 dB
Manufacturer = 8f030a101c0000590435ee35acec
Device ab:36:be:b6:43:43 (public), RSSI=-69 dB
Device 96:bb:75:92:ca:8a (public), RSSI=-59 dB
Device fb:ac:56:d9:44:cf (public), RSSI=-70 dB

Connect

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import sys
from bluepy.btle import UUID, Peripheral

if len(sys.argv) != 2:
print("Fatal, must pass device address:", sys.argv[0], "<device address>")
quit()

p = Peripheral(sys.argv[1], "public")

# get all services
services=p.getServices()
for service in services:
print(service)

# get all characteristics
chList = p.getCharacteristics()
print("Handle UUID Properties")
print("-------------------------------------------------------")
for ch in chList:
print(" 0x"+ format(ch.getHandle(),'02X') +" "+str(ch.uuid) +" " + ch.propertiesToString())
  • Peripheral(sys.argv[1],"public")是用mac地址创建一个连接,由于我们上一步用scan搜索到的mac地址为public类型,因此这里第二个参数为”public”。
  • getServices会返回所连接设备的服务。
  • getCharacteristics会返回所连接设备的特征值。

运行结果如下:

1
2
3
4
5
6
7
8
9
10
Service <uuid=feb3 handleStart=1 handleEnd=13>
Service <uuid=1828 handleStart=14 handleEnd=20>
Handle UUID Properties-------------------------------------------------------
0x03 0000fed4-0000-1000-8000-00805f9b34fb READ
0x05 0000fed5-0000-1000-8000-00805f9b34fb READ WRITE
0x07 0000fed6-0000-1000-8000-00805f9b34fb READ INDICATE
0x09 0000fed7-0000-1000-8000-00805f9b34fb READ WRITE NO RESPONSE
0x0B 0000fed8-0000-1000-8000-00805f9b34fb READ NOTIFY
0x10 00002add-0000-1000-8000-00805f9b34fb WRITE NO RESPONSE
0x12 00002ade-0000-1000-8000-00805f9b34fb NOTIFY

Notification

参考

坚持原创技术分享,您的支持将鼓励我继续创作!