使用gattool或bluepy订阅通知

2024-06-13 01:13:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用bluepy编写一个程序,该程序监听蓝牙设备发送的特征。我也可以使用任何库或语言,唯一的限制是在Linux上运行,而不是在移动环境中运行(它似乎只在移动设备中广泛使用,没有人可以与桌面一起使用)。 使用bluepy,我注册委托,然后尝试注册通知调用write('\x01\x00'),如蓝牙rfc中所述。 但它不起作用,接收到任何有关该特性的通知。 也许我写错了订阅信息。 我写的小片段有错吗?非常感谢。

class MyDelegate(btle.DefaultDelegate):

    def __init__(self, hndl):
        btle.DefaultDelegate.__init__(self)
   self.hndl=hndl;

   def handleNotification(self, cHandle, data):
   if (cHandle==self.hndl):
            val = binascii.b2a_hex(data)
            val = binascii.unhexlify(val)
            val = struct.unpack('f', val)[0]
            print str(val) + " deg C"


p = btle.Peripheral("xx:xx:xx:xx", "random")

try:
   srvs = (p.getServices());
   chs=srvs[2].getCharacteristics();
   ch=chs[1];
   print(str(ch)+str(ch.propertiesToString()));
   p.setDelegate(MyDelegate(ch.getHandle()));
   # Setup to turn notifications on, e.g.
   ch.write("\x01\x00");

   # Main loop --------
   while True:
      if p.waitForNotifications(1.0):
      continue

      print "Waiting..."
finally:
    p.disconnect();

Tags: self程序valchwriteprintxxx00
3条回答

看起来问题在于您试图将\x01\x00写入特性本身。您需要将其写入处理它的客户机特征配置描述符(0x2902)。句柄可能比特征大1(但您可能希望通过读取描述符来确认)。

ch=chs[1]
cccd = ch.valHandle + 1
cccd.write("\x01\x00")

我自己也在挣扎,jgrant的评论真的很有帮助。我想分享我的解决方案,如果它能帮助任何人的话。

注意,我需要指示,因此是x02而不是x01。

如果可以使用bluepy读取描述符,我会这么做,但似乎不起作用(bluepy v 1.0.5)。服务类中的方法似乎丢失了,当我尝试使用它时,外围类中的方法被卡住了。

from bluepy import btle

class MyDelegate(btle.DefaultDelegate):
    def __init__(self):
        btle.DefaultDelegate.__init__(self)

    def handleNotification(self, cHandle, data):
        print("A notification was received: %s" %data)


p = btle.Peripheral(<MAC ADDRESS>, btle.ADDR_TYPE_RANDOM)
p.setDelegate( MyDelegate() )

# Setup to turn notifications on, e.g.
svc = p.getServiceByUUID( <UUID> )
ch = svc.getCharacteristics()[0]
print(ch.valHandle)

p.writeCharacteristic(ch.valHandle+1, "\x02\x00")

while True:
    if p.waitForNotifications(1.0):
        # handleNotification() was called
        continue

    print("Waiting...")
    # Perhaps do something else here

令我困惑的是 启用通知的部分是在注释中,所以在我看来这不是必须的。

对我来说,最起码的(如果你知道MAC地址已经包含了所有内容并声明了Delegateclass)是

p1 = Peripheral(<MAC>)
ch1 = p1.getCharacteristics()[3]
p1.setDelegate(MyDelegate())
p1.writeCharacteristic(ch1.valHandle + 1, b"\x01\x00")

注意,我已经知道我想从characteristic#3获得通知。 另外,如果没有“\x0\x00”前面的“b”-bytesprefix,它对我也不起作用。

相关问题 更多 >