You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python使用Bleak库无法读取BLE设备带indicate权限的特征值

核心原因

BLE GATT特征的不同权限是完全独立的,indicate权限不代表支持read操作:

  • 带read权限的特征:支持客户端(你的Python代码)主动向设备发起读请求,拉取当前值
  • 仅带indicate权限的特征:不支持主动读,只能由设备侧主动向客户端推送数据,且客户端收到推送后需要回复确认包,你收到的Protocol Error 0x02: Read Not Permitted错误就是设备明确拒绝了你的主动读请求。

你在手机BLE工具上能看到该特征的值,是因为手机工具自动注册了indicate的监听回调,接收设备主动推送的值再做展示,并非发起了主动读操作。

解决代码(基于Bleak)

你需要用start_notify方法注册indicate的回调函数来接收设备推送的值,而不是用read_gatt_char主动读取:

import sys
import platform
import asyncio
import logging

from bleak import BleakClient
logger = logging.getLogger(__name__)
# 替换为你要监听的indicate特征UUID,此处为Handle 2对应的00002a05
INDICATE_UUID = "00002a05-0000-1000-8000-00805f9b34fb"
ADDRESS = (
"00:80:E1:26:C4:5E"
if platform.system() != "Darwin"
else "B9EA5233-37EF-4DD6-87A8-2A875E821C46"
)

# indicate数据回调函数
def on_indicate(sender, data):
    print(f"收到indicate数据,来源:{sender},值:{data}")

async def main(address):
    async with BleakClient(address) as client:
        # 注册indicate监听,Bleak会自动处理2902描述符配置和ACK回复逻辑
        await client.start_notify(INDICATE_UUID, on_indicate)
        print("indicate监听已启动,等待设备推送数据...")
        # 保持连接不退出
        while True:
            await asyncio.sleep(1)
if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.run(main(sys.argv[1] if len(sys.argv) == 2 else ADDRESS))

注:Bleak的start_notify方法同时支持notify和indicate类型的特征,不需要额外区分,底层会自动处理indicate要求的ACK回复逻辑,你只需要处理回调里收到的数据即可。

内容的提问来源于stack exchange,提问作者Rifet Gazdic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 10:45:03