树莓派3b+
python3.7
蓝牙设备
github链接:https://github.com/pybluez/pybluez
sudo pip3 install pybluez
import bluetooth
nearby_devices = bluetooth.discover_devices(lookup_names=True)
print("Found {} devices.".format(len(nearby_devices)))
for addr, name in nearby_devices:
print(" {} - {}".format(addr, name))
能够正常运行,但只能扫描到手机。我用的是蓝牙卡片,手机扫描到的是在其他设备
栏里,查找资料发现是属于低功耗蓝牙设备ibeacon
。下面还有另一个官方示例,提示是扫描低功耗的,尝试一下。
from bluetooth.ble import DiscoveryService
service = DiscoveryService()
devices = service.discover(2)
for address, name in devices.items():
print("name: {}, address: {}".format(name, address))
运行后提示缺少gattlib
库,由于该库依赖其他环境,找了半天解决方案还是有问题,于是放弃了,暂时只能做到扫描手机设备。
github链接:https://github.com/IanHarvey/bluepy
找到了另外一个蓝牙扫描库,能扫出低功耗的蓝牙设备。
sudo pip3 install bluepy
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)
print(len(devices))
for dev in devices:
print("---------------")
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.scan(10.0)
代表扫描时间
---------------
Device ac:23:3f:58:4e:ca (public), RSSI=-61 dB
Flags = 06
Manufacturer = 4c000215fda50693a4e24fb1afcfc6eb0764782527114cb9c5
Tx Power = ec
Complete 16b Services = 0000fda5-0000-1000-8000-00805f9b34fb
16b Service Data = a5fd6427114cb9ac233f584eca
Complete Local Name = axon_33
---------------
Device ac:23:3f:58:4f:fd (public), RSSI=-86 dB
Flags = 06
Manufacturer = 4c000215fda50693a4e24fb1afcfc6eb0764782527114cb9c5
Tx Power = ec
Complete 16b Services = 0000fda5-0000-1000-8000-00805f9b34fb
16b Service Data = a5fd6427114cb9ac233f584ffd
Complete Local Name = axon_71
目前需求需要让设备持续扫描一段时间,将所有的蓝牙信息上报,为防止扫描遗漏,故需扫描时间延长到几十秒以上。
但发现若扫描时间过长,会报bluepy.btle.BTLEDisconnectError: Device disconnected
错误。原因是某个蓝牙设备的断开而使程序发生错误了,于是想到开启额外线程循环扫描,每次扫描时间设为5秒,代码如下:
from bluepy.btle import Scanner, DefaultDelegate
from multiprocessing import Process, Event
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)
class BLEScanner:
def __init__(self):
self.scanner = Scanner().withDelegate(ScanDelegate())
self.stop_event = Event()
def start(self):
self.stop_event.clear()
self.process = Process(target=self.scan, args = ())
self.process.start()
return self
def scan(self):
while True:
if self.stop_event.is_set():
return
self.devices = self.scanner.scan(5, passive=True)
def stop(self):
self.stop_event.set()
BLEScanner().start()
后续只要将mac地址扔到set集合中,收集一段时间后上报就行了。