使用Python gatt库时如何停止重复打印蓝牙设备发现结果
问题原因
- 第一处错误是类继承关系写错:自定义的扫描管理类错误继承了
gatt.Device,扫描相关的管理逻辑需要继承gatt.DeviceManager才能正常工作,基类误用会导致扫描生命周期控制失效。 - 第二点是gatt库默认扫描逻辑:
start_discovery()默认启动持续扫描,周边BLE设备会周期性发送广播包,每次扫描到同一设备都会触发device_discovered回调,因此会反复打印重复的设备信息。
修复方案
按以下两点调整代码即可解决重复打印问题:
- 修正类继承关系,将自定义管理类的父类从
gatt.Device改为gatt.DeviceManager - 增加去重逻辑/主动停止扫描逻辑,二选一或者组合使用:
- 去重逻辑:用集合存储已经发现过的设备MAC地址,已处理过的设备直接跳过回调逻辑
- 主动停扫:满足扫描需求(比如扫描到目标设备、达到预设扫描时长)后,调用
stop_discovery()终止扫描,或者给run()方法传入timeout参数设置扫描最长运行时长,超时自动退出。
修正后可运行代码
import gatt class AnyDeviceManager(gatt.DeviceManager): def __init__(self, adapter_name): super().__init__(adapter_name=adapter_name) # 存储已发现设备的MAC地址,用于去重 self.found_devices = set() def device_discovered(self, device): # 跳过已经处理过的设备 if device.mac_address in self.found_devices: return self.found_devices.add(device.mac_address) print("Discovered [%s] %s" % (device.mac_address, device.alias())) # 可选:找到指定目标设备后立刻停止扫描 # if device.alias() == "你的目标设备名称": # self.stop_discovery() if __name__ == "__main__": manager = AnyDeviceManager(adapter_name='hci0') manager.start_discovery() # 传入timeout参数设置扫描最长运行时间,单位秒,比如10秒后自动停止扫描退出 # 如果不需要自动退出,可以去掉timeout参数,仅靠上面的去重逻辑避免重复打印 manager.run(timeout=10)
补充说明:如果需要持续扫描但不想重复输出,只保留
found_devices去重逻辑即可,不需要加timeout或者主动调用stop_discovery;如果只需要做一次性设备发现,加timeout或者主动停扫的逻辑资源占用更低。
内容的提问来源于stack exchange,提问作者Abhishek Borse
相关产品推荐
相关产品推荐

