如何基于服务高效筛选CH9141K BLE设备?Bleak使用咨询
解决方案
一、优先利用广播中的厂商特定数据筛选(最高效)
如果CH9141在广播帧中携带了厂商特定数据(这是BLE设备常见的标识方式),可以直接在扫描阶段过滤,无需连接设备。
先通过BLE调试工具(如nRF Connect)抓取CH9141的广播包,确认以下信息:
- 沁恒(CH9141厂商)的厂商ID(通常为
0x0483,需以实际抓包结果为准) - 厂商数据段中是否包含CH9141的专属标识(比如固定字节序列
\x91\x41)
- 沁恒(CH9141厂商)的厂商ID(通常为
用Bleak扫描时过滤匹配的设备:
import asyncio from bleak import BleakScanner async def scan_ch9141_via_manu_data(): devices = await BleakScanner.discover(timeout=5) valid_devices = [] # 替换为实际抓取到的厂商ID和标识 QINHENG_MANU_ID = 0x0483 CH9141_IDENTIFIER = b'\x91\x41' for dev in devices: adv_data = dev.advertisement_data # 检查厂商数据是否存在并匹配 if QINHENG_MANU_ID in adv_data.manufacturer_data: manu_data = adv_data.manufacturer_data[QINHENG_MANU_ID] if CH9141_IDENTIFIER in manu_data: valid_devices.append(dev) return valid_devices asyncio.run(scan_ch9141_via_manu_data())
二、批量快速连接验证(最可靠)
如果设备未在广播中携带可识别的信息,只能通过短暂连接后检查服务信息来筛选。用异步并发处理可以大幅提升效率。
核心思路:
- 对扫描到的所有设备发起短超时连接(比如2秒)
- 连接后立即检查是否存在
0xFFF0服务,可选验证Device Information服务中的型号是否为CH9141
实现代码:
import asyncio from bleak import BleakScanner, BleakClient # 目标服务和特征UUID TARGET_SERVICE = "0000fff0-0000-1000-8000-00805f9b34fb" MODEL_CHAR = "00002a24-0000-1000-8000-00805f9b34fb" async def validate_device(device): try: async with BleakClient(device, timeout=2.0) as client: # 检查是否存在目标服务 services = await client.get_services() if TARGET_SERVICE in [s.uuid for s in services]: # 可选:验证设备型号 model_char = client.services.get_characteristic(MODEL_CHAR) if model_char: model_str = (await client.read_gatt_char(model_char)).decode().strip() if model_str == "CH9141": return device, True # 不需要型号验证的话直接返回True return device, True except Exception: # 连接失败/服务不存在则跳过 pass return device, False async def scan_and_validate(): devices = await BleakScanner.discover(timeout=5) # 并发验证所有设备 tasks = [validate_device(dev) for dev in devices] results = await asyncio.gather(*tasks) # 过滤有效设备 return [dev for dev, is_valid in results if is_valid] asyncio.run(scan_and_validate())
三、关于Bleak配置的补充说明
- Bleak扫描时的
services参数仅对广播了服务UUID的设备有效,你的设备未广播0xFFF0,因此该参数无法用于筛选。 - 扫描阶段的
advertisement_data还包含service_data、tx_power等字段,但根据你的描述,这些字段可能不包含CH9141的专属标识,优先级低于厂商数据和连接验证。
内容的提问来源于stack exchange,提问作者user1387
相关产品推荐
相关产品推荐

