通过扫描蓝牙设备并获取原始广播数据的功能实现。通过异步编程和回调函数,可以实时处理扫描到的设备和广播数据,并将其打印输出
- 引入必要的模块和库:
import asyncio from bleak import BleakScanner import binascii import datetime
这里使用了
asyncio
库来实现异步编程,BleakScanner
用于扫描蓝牙设备,binascii
用于将字节转换为十六进制字符串,datetime
用于获取当前时间。 - 定义函数
run_scan_rawdata(self)
,该函数用于执行蓝牙设备扫描,并处理广播数据:async def scan_callback(device, advertisement_data): # 如果扫描到目标设备,则将广播数据处理打印 if device.address == target_mac_address: self.thread.update_signal.emit(str(datetime.datetime.now()) + "\t" + f"{device.name} {device.address}" + "\t") manufacturer_data = advertisement_data.manufacturer_data # manufacturer_data服务下原始数据,bytes转16进制再转字符串 for key, value in manufacturer_data.items(): hex_data: str = binascii.hexlify(value).decode("utf-8") self.thread.update_signal.emit(f"{hex_data.upper()}") service_data = advertisement_data.service_data # service_data服务下原始数据,bytes转16进制再转字符串 for key, value in service_data.items(): hex_data: str = binascii.hexlify(value).decode("utf-8") self.thread.update_signal.emit(f"{hex_data.upper()}")
scan_callback
函数是一个回调函数,用于处理扫描到的蓝牙设备和广播数据。首先判断是否扫描到目标设备(通过比较设备地址),如果是目标设备,则将广播数据进行处理和打印。 - 定义异步函数
main(self)
,该函数用于执行蓝牙设备扫描:async def main(self): scanner = BleakScanner() scanner.register_detection_callback(scan_callback) await scanner.start() await asyncio.sleep(65535.0) await scanner.stop()
在
main
函数中,创建了一个BleakScanner
对象scanner
,并注册了之前定义的回调函数scan_callback
。然后调用scanner.start()
开始扫描,并使用asyncio.sleep(65535.0)
进行等待,最后调用scanner.stop()
停止扫描。 - 执行主程序:
try: s = self.lineEdit_mac_three_axis_11.text() target_mac_address = ':'.join([s[i:i + 2] for i in range(0, len(s), 2)]) loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) loop.run_until_complete(main(self)) loop.close() except Exception as e: self.thread.update_signal.emit(f"Error: {e},请检查")
获取目标设备的MAC地址,并将其格式化为冒号分隔的形式。然后创建一个新的事件循环
loop
,并将其设置为当前asyncio
的事件循环。接着调用loop.run_until_complete(main(self))
来执行主程序,最后关闭事件循环。 -
原代码如下:
def run_scan_rawdata(self): async def scan_callback(device, advertisement_data): # 如果扫描到目标设备,则将广播数据处理打印 if device.address == target_mac_address: # print(advertisement_data) self.thread.update_signal.emit(str(datetime.datetime.now()) + "\t" + f"{device.name} {device.address}" + "\t") manufacturer_data = advertisement_data.manufacturer_data # manufacturer_data服务下原始数据,bytes转16进制再转字符串 for key, value in manufacturer_data.items(): hex_data:str = binascii.hexlify(value).decode("utf-8") self.thread.update_signal.emit(f"{hex_data.upper()}") service_data = advertisement_data.service_data # service_data服务下原始数据,bytes转16进制再转字符串 for key, value in service_data.items(): hex_data:str = binascii.hexlify(value).decode("utf-8") self.thread.update_signal.emit(f"{hex_data.upper()}") # self.thread_14.update_signal.emit(f"rssi={advertisement_data.rssi}dBm") async def main(self): scanner = BleakScanner() scanner.register_detection_callback(scan_callback) await scanner.start() await asyncio.sleep(65535.0) await scanner.stop() try: s = self.lineEdit_mac_three_axis_11.text() target_mac_address = ':'.join([s[i:i + 2] for i in range(0, len(s), 2)]) loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) loop.run_until_complete(main(self)) loop.close() except Exception as e: self.thread.update_signal.emit(f"Error: {e},请检查")#此条可忽略,为配合上位机发送信号用