繁体   English   中英

如何在python中使用pygatt从BLE设备获取通知?

[英]How to get notifications from BLE Device using pygatt in python?

我正在使用python开发Linux应用程序,该应用程序将连接到我的BLE设备并通过通知特性来获取数据。 我正在使用pygatt进行BLE通信。 我可以成功连接并绑定到设备并读取/写入特征。 甚至我都可以订阅通知特性,但是问题是,我的BLE设备是一台自定义计算机,内部有4个计数器,每次更改计数器数据之一时,它都会设置相应的通知标志,因此,使用onDataChanged-像方法一样,我可以从读取特征中读取计数器的数据。 在使用pygatt的Python中,我可以通过以下方式订阅通知特性:

class_name.device.subscribe(uuid.UUID(notify_characteristic),callback=notifyBle)

而notifyBle是:

def notifyBle(self,handle,data):
    read_data = class_name.device.char_read(uuid.UUID(read_characteristic))
    print(read_data)

运行程序时,首先扫描设备并连接到设备并与之绑定,然后发现特征并将其列出。 一切成功。 列出特性后,我写写入特性来清除通知标志,它也成功。 最后我订阅通知它成功。

完成所有这些过程后,我会物理上增加设备的计数器(设备上有用于增加计数器的按钮)。 当我按下按钮时,程序转到notifyBle方法,它给出了错误,即:

Exception in thread Thread-3:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.5/dist-packages/pygatt/backends/gatttool/gatttool.py", line 137, in run
    event["callback"](event)
  File "/usr/local/lib/python3.5/dist-packages/pygatt/backends/gatttool/gatttool.py", line 479, in _handle_notification_string
    self._connected_device.receive_notification(handle, values)
  File "/usr/local/lib/python3.5/dist-packages/pygatt/device.py", line 226, in receive_notification
    callback(handle, value)
  File "/home/acd/Masaüstü/python_workspace/ble.py", line 54, in notifyBle
    read_data = bleFunctions.dev.char_read(uuid.UUID(bleFunctions.read_characteristic))
  File "/usr/local/lib/python3.5/dist-packages/pygatt/backends/gatttool/device.py", line 17, in wrapper
    return func(self, *args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/pygatt/backends/gatttool/device.py", line 40, in char_read
    return self._backend.char_read(self, uuid, *args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/pygatt/backends/gatttool/gatttool.py", line 53, in wrapper
    return func(self, *args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/pygatt/backends/gatttool/gatttool.py", line 519, in char_read
    self.sendline('char-read-uuid %s' % uuid)
  File "/usr/lib/python3.5/contextlib.py", line 66, in __exit__
    next(self.gen)
  File "/usr/local/lib/python3.5/dist-packages/pygatt/backends/gatttool/gatttool.py", line 180, in event
    self.wait(event, timeout)
  File "/usr/local/lib/python3.5/dist-packages/pygatt/backends/gatttool/gatttool.py", line 154, in wait
    raise NotificationTimeout()
pygatt.exceptions.NotificationTimeout

任何帮助,将不胜感激。

PS:我在Android和Windows UWP中编写了完全相同的程序。 我的目标是使用python在树莓派3上运行它。

PSS:我正在使用安装了Ubuntu Mate的raspberry pi 3,用python开发此程序。

首先,如下创建事件类,

class Event:
    def __init__(self):
        self.handlers = set()

    def handle(self, handler):
        self.handlers.add(handler)
        return self

    def unhandle(self, handler):
        try:
            self.handlers.remove(handler)
        except:
            raise ValueError("Handler is not handling this event, so cannot unhandle it.")
        return self

    def fire(self, *args, **kargs):
        for handler in self.handlers:
            handler(*args, **kargs)

    def getHandlerCount(self):
        return len(self.handlers)

    __iadd__ = handle
    __isub__ = unhandle
    __call__ = fire
    __len__  = getHandlerCount

然后,创建一个ble类

import pygatt
from eventclass import Event

class myBle:
    ADDRESS_TYPE = pygatt.BLEAddressType.random
    read_characteristic = "0000xxxx-0000-1000-8000-00805f9b34fb"
    write_characteristic = "0000xxxx-0000-1000-8000-00805f9b34fb"
    notify_characteristic = "0000xxxxx-0000-1000-8000-00805f9b34fb"
    def __init__(self,device):
        self.device = device
        self.valueChanged = Event()
        self.checkdata = False

    def alert(self):
         self.valueChanged(self.checkdata)

    def write(self,data):
        self.device.write_char(self.write_characteristic,binascii.unhexlify(data))

    def notify(self,handle,data):
        self.checkdata = True

    def read(self):
        if(self.checkdata):
            self.read_data = self.device.char_read(uuid.UUID(self.read_characteristic))
            self.write(bytearray(b'\x10\x00'))
            self.checkdata = False
            return self.read_data
    def discover(self):
        return self.device.discover_characteristics().keys()

收到通知时,将boolean值设置为true,alert方法将通知boolean值已更改。

def triggerEvent(checkdata):
   print(str(checkdata))

ble = myBle(device)
ble.valueChanged += triggerEvent
ble.alert()

您可以调用read方法以使用triggerEvent方法获取特征值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM