【问题标题】:How can I receive all indications from BLE Watch with pygatt - bluez?如何使用 pygatt - bluez 从 BLE Watch 接收所有指示?
【发布时间】:2022-12-10 21:42:45
【问题描述】:

我有一个 AS97 健身手表,想使用 pygatt 通过树莓派接收活动数据。

我必须写入自定义服务 uuid。

我需要 device.char_write 到 uuid ff01 并收到来自 ff02 的指示。

如果我只使用device.char_read,我只会得到第一个指示。 我尝试了 device.subscribe 函数,但这不起作用。

#!/usr/bin/env python3
import pygatt
import logging
from binascii import hexlify
from time import sleep
        
logging.basicConfig()
logging.getLogger('pygatt').setLevel(logging.DEBUG) # Logger to see the debug
        
watch = "C4:C1:88:F8:58:59"   # watch bluetooth-adress
adapter = pygatt.GATTToolBackend()
        
adapter.start() # start bluetooth
device = adapter.connect(watch, address_type=pygatt.BLEAddressType.random, timeout=20)  
#connects with watch
        
try:
    device.char_write('7905ff01-b5ce-4e99-a40f-4b1e122d00d0',
                      bytearray([0xBE, 0x02, 0x01, 0xFE, 0x07, 0xE6, 0x01, 0x19, 0x00, 
                      0x00]))  #command bytes - 07e6 year - 01 month 
                      # - 19 day - 0000 - minute start
    activity_data = device.char_read('7905ff02-b5ce-4e99-a40f-4b1e122d00d0')
except:
    print("Can't read informations")
    adapter.stop()
        
print(activity_data)
adapter.stop()

我收到第一个指示:

bytearray(b'\xde\x02\x01\xfe\x07\xe6\x01\x19\x00\x00\x0bz\x00\x00\x07M\x00\xc8\x00')

Custom UUID Write/Indications

Get activity data

Get activity data 2nd 3rd indication

我猜读取功能没有很好地工作,因为该特性仅使用写入和指示。

感谢大家的帮助!

我也试过类似的东西:

def data_handler_cb(handle, value):
    print("Data: {}".format(value.hex()))
    print("Handle: {}".format(handle))
            
try:
    device.char_write('7905ff01-b5ce-4e99-a40f-4b1e122d00d0',
                       bytearray([0xBE, 0x02, 0x01, 0xFE, 0x07, 0xE6, 0x01, 0x19, 0x00, 0x00]))
        
           
    device.subscribe("7905ff02-b5ce-4e99-a40f-4b1e122d00d0",  callback=data_handler_cb, indication = True)
    print("Wait for callback")
    sleep(3)      
finally:
    adapter.stop()

我也换了顺序,先订阅,然后就等了

DEBUG:pygatt.device:Looking up handle for characteristic 7905ff02-b5ce-4e99-a40f-4b1e122d00d0
DEBUG:pygatt.device:Found <Characteristic uuid=7905ff02-b5ce-4e99-a40f-4b1e122d00d0 handle=26>
DEBUG:pygatt.backends.gatttool.gatttool:Sending cmd=char-write-req 0x1b 0200

并因错误而中断:

ERROR:pygatt.backends.gatttool.gatttool:No response received

【问题讨论】:

  • 您使用 pygatt 库是否有特殊原因?它似乎是基于 gatttool 而一直是 deprecated。如果您确实想使用它,则需要使用 subscribe 功能从设置了 indicate 标志的特征接收数据。
  • 不,我没有理由使用 pygatt,但我没有在树莓派上找到 python 3.x 的其他库。你能帮我选择另一个图书馆或解决这个订阅问题吗?

标签: bluetooth raspberry-pi bluez gatt


【解决方案1】:

我会将问题分为三个阶段,以帮助调试问题所在。

  1. 证明您可以使用手机上的通用蓝牙低功耗扫描和探索工具(例如nRF connect)从手表上获取数据。

  2. 使用 RPi 上的 bluetoothctl 命令行工具来证明它可以在 RPi 的当前配置下完成。

    • 打开两个终端并在两个终端中运行bluetoothctl

    • connect C4:C1:88:F8:58:59 在一个bluetoothctl 将连接两个。

    • menu gatt 在两个终端。

    • select-attribute 7905ff02-b5ce-4e99-a40f-4b1e122d00d0合一

    • 在同一个notify on

    • select-attribute 7905ff01-b5ce-4e99-a40f-4b1e122d00d0 在二号航站楼

    • 在 2 号航站楼 notify on

    • 在 2 号航站楼 write "0xBE 0x02 0x01 0xFE 0x07 0xE6 0x01 0x19 0x00 0x00"

      您应该会在写入后看到通知。

    1. 如果上述两个实验都成功,则表明手表和 RPi 正在按预期工作。这使您可以确信问题出在 Python 上。关于如何使用 Python(不使用 pygatt)创建 BLE Central 设备的替代示例位于:https://stackoverflow.com/a/63751113/7721752。这使用记录在以下位置的 BlueZ D-Bus API: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc

    通过这些实验,它应该可以帮助您缩小问题的范围。

【讨论】:

  • 第一个实验是我的第一个尝试和解决方案,用于测试手表是否在没有任何特定应用程序的情况下工作。它仍然有效。但是如果我在两个终端上尝试它,它总是通过为notify on编写命令来断开与手表的连接。我尝试使用 DBus,但我想这是一个你需要同时编写和订阅的问题。
【解决方案2】:

订阅代码是正确的。问题是服务器(蓝牙手表)的授权指示。在电话上你会被要求输入密码,但在 RPi 上则不会。只需首次将手表与终端连接,先使用bluetoothctl,然后使用agent KeyboardOnly,然后配对设备。现在你会被要求输入密码。一旦 RPi 获得授权,您就可以在 Python 中使用该函数。

import pygatt
import logging
import time
from binascii import hexlify

def handle_data(handle, value):
    """
    handle -- integer, characteristic read handle the data was received on
    value -- bytearray, the data returned in the notification
    """
    print("Received data: %s" % hexlify(value))

logging.basicConfig()
logging.getLogger('pygatt').setLevel(logging.DEBUG)
watch = "C4:C1:88:F8:58:59"
adapter = pygatt.GATTToolBackend()


try:
    time.sleep(5)
    adapter.start()
    time.sleep(5)
    device = adapter.connect(watch,address_type=pygatt.BLEAddressType.random,timeout=20)

    time.sleep(5)
    for uuid in device.discover_characteristics().keys():
        print("Read UUID %s" % (uuid))
        #read all characteristic uuids
    device.subscribe("7905ff02-b5ce-4e99-a40f-4b1e122d00d0",
                     callback=handle_data, indication = True)
    time.sleep(5)
    device.char_write('7905ff01-b5ce-4e99-a40f-4b1e122d00d0',
                  bytearray([0xBE, 0x02, 0x01, 0xFE, 0x07, 0xE6, 0x02, 0x01, 0x00, 0x00]))

    while 1:
        pass
finally:
    print("Adapter Stopped")
    adapter.stop()

【讨论】:

    猜你喜欢
    • 2015-03-08
    • 2017-12-11
    • 2020-11-07
    • 2015-08-03
    • 2016-02-02
    • 2016-02-02
    • 2013-04-19
    • 2016-04-18
    • 2014-04-27
    相关资源
    最近更新 更多