Python BlueZ DBUS自定义GATT Server:如何通知int16值变更
解决BlueZ GATT Server温度特征通知无法送达客户端的问题
你的问题核心是通知时传递的Value格式不符合BlueZ的要求。在ReadValue中你正确返回了小端序的2字节数组,但通知时直接传入dbus.Int16对象,这会被BlueZ识别为整数类型而非BLE特征要求的原始字节载荷。
修正后的通知实现代码
将温度值转为小端序字节数组后,需要包装成dbus.Array类型(元素为dbus.Byte),再传入PropertiesChanged:
def send_notification(self): # 将sint16值转为小端序2字节数组 byte_data = dbus.Int16(self.value).to_bytes(2, byteorder="little") # 转为dbus.Array[dbus.Byte]格式 dbus_byte_array = dbus.Array([dbus.Byte(b) for b in byte_data], signature="y") self.PropertiesChanged( GATT_CHRC_IFACE, dbus.Dictionary( { "Value": dbus_byte_array, }, signature="sv", ), [], )
关键验证点
- 确认特征支持通知:在定义Temperature特征时,Flags必须包含
"notify",示例如下:chrc = BluezGattCharacteristic( self.bus, 0, { "UUID": "00002a6e-0000-1000-8000-00805f9b34fb", "Flags": ["read", "notify"], }, self ) - 确认客户端已订阅通知:只有当客户端(比如nRF Connect)明确开启了该特征的通知订阅后,BlueZ才会将你的
PropertiesChanged信号转发到BLE链路。
为什么之前的实现无效
BlueZ的GATT特征Value属性在通知时要求的是字节数组类型(signature "ay"),而你传入的dbus.Int16是整数类型(signature "n"),虽然dbus-monitor能捕获到信号,但BlueZ会因为类型不匹配而拒绝将其转发到BLE客户端,这也是btmon无活动记录的原因。
内容的提问来源于stack exchange,提问作者Danilo Fuchs
相关产品推荐
相关产品推荐

