bluetooth - 使用 bluez/bluetoothctl/gatttool 连接到蓝牙智能/LE 体重秤

标签 bluetooth bluetooth-lowenergy bluez

我想做什么:

我想将我的 Raspberry Pi 2 连接到蓝牙智能体重秤 (Medisana BS440) 并接收我的数据。

我所知道的:

只有一个有趣的主要服务具有 5 个特征:

 - handle: 0x001a
     -  properties: 0x20 (Indication), char value handle: 0x1b uuid:00008a21-0000-1000-8000-00805f9b34fb
 - handle: 0x001d
     -  properties: 0x20 (Indication), char value handle: 0x1e uuid:00008a22-0000-1000-8000-00805f9b34fb
 - handle: 0x0020
     -  properties: 0x02 (Read-Only),  char value handle: 0x21 uuid:00008a20-00..
 - handle: 0x0022
     -  properties: 0x08 (Write-Only), char value handle: 0x23 uuid:00008a81-00..
 - handle: 0x0024
     -  properties: 0x20 (Indication), char value handle: 0x25 uuid:00008a82-00..

我使用了我的 Android 手机的 HCI-Snoop-Developer-Funktion,看看相应的应用程序如何与我的体重秤通信。
  • 写入 0200 -> 0x1f(启用指示 0x1d)
  • 读取 0x21 -> 0x21(值:37fb)
  • 写入 0200 -> 0x1c(启用指示 0x1a)
  • 写入 0200 -> 0x26(启用指示 0x24)
  • 写 02a31e2c0b -> 0x23 (我在这里不完全理解这一点,但我知道你是否在 02 之后取字节(a3 1e 2c 0b -> 0b 2c 1e a3 -> 这是当前的 Unix 时间戳,但对于年份? 1975 年?)

  • 在第 4 步之后,有第一个指示(句柄 0x25),它为我提供了我存储的个人数据(我的高度、性别、年龄等)

    在第 5 步之后,有一些指示(句柄 0x1b 和句柄 0x1e)应该传输我的测量数据。 (此时没有分析十六进制值)

    我做了什么:

    我在我的 raspi(内核 4.1.13)上安装了 bluez.5.32,并使用 gatttool 执行了第 1 - 5 步,一切正常,直到第 5 步。我没有收到来自句柄 0x1b 和 0x1e 的任何指示消息)步骤之后没有任何 react 5.
    gatttool -t random -b DE:70:4A:XX:XX:XX -I
    char-write-cmd 0x1f 0200
    char-read-hnd 0x21 (37fb)
    char-write-cmd 0x1c 0200
    char-write-cmd 0x26 0200
    char-write-cmd 0x23 0000000000
    

    (我什至用 unix-timestamp-for 1975 做这件事……没有解决)

    数十亿小时后,我在我的 raspi 上使用 bluetoothctl 工作(有一个 dbus 问题),我用 bluetoothctl 进行了同样的尝试。我启用了所有指示并将 0000000000 写入 hnd=0x23。切换到处理 0x1a 并且它起作用了!我收到许多十六进制值,它们应该是我正在搜索的数据。

    所以有什么问题?
    我想将 gatttool 用于我的目的,或者至少我想了解,为什么 gatttool 不起作用

    我用bluetoothctl的时候,只能选择一个属性看,收到数据后,我的秤自动断开到我的树莓派。因此,当我选择特性 0x1a 时,我看不到特性 0x01d 的指示消息,反之亦然。

    当我使用 gatttool 或使用 bluetoothctl 时,我的 Pi 和我的 Scale 之间是否存在其他连接?或者在方式上有什么不同,他们如何与我的体重秤沟通?

    最佳答案

    在测量重量等之后,秤似乎可以连接一小段时间我在 bash 脚本中使用了 gatttool 的非交互模式,如下所示:

    gatttool -t random -b F1:37:57:XX:XX:XX --char-write --handle 0x001f -n 0200
    gatttool -t random -b F1:37:57:XX:XX:XX --char-read --handle 0x0021
    gatttool -t random -b F1:37:57:XX:XX:XX --char-write --handle 0x001c -n 0200
    gatttool -t random -b F1:37:57:XX:XX:XX --char-write --handle 0x0026 -n 0200
    gatttool -t random -b F1:37:57:XX:XX:XX --char-write-req --handle 0x0023 -n 0000000000 --listen
    

    信息取自 Pratik Sinha here .
    要显示响应,需要明确给出 --listen ,然后接收大约 25 行数据(交替 1b 和 1e 响应)。
    感谢您的信息,节省了我几天的工作!

    新年快乐!

    编辑:

    使用 Python 和 pygatt module这归结为:
    import pygatt.backends
    from binascii import hexlify
    
    def printIndication(handle, value):
        print('Indication received {} : {}'.format(hex(handle), hexlify(str(value))))
    
    adapter = pygatt.backends.GATTToolBackend()
    adapter.start()
    # wait for someone to step on the scale
    while True:  
        try:
            device = adapter.connect('f1:37:57:xx:xx:xx', 5, 'random')
            break
        except pygatt.exceptions.NotConnectedError:
            print('Waiting...')
    device.subscribe('00008a22-0000-1000-8000-00805f9b34fb', callback = printIndication, indication = True)
    device.subscribe('00008a21-0000-1000-8000-00805f9b34fb', callback = printIndication, indication = True)
    device.subscribe('00008a82-0000-1000-8000-00805f9b34fb', callback = printIndication, indication = True)
    try:
        device.char_write_handle(0x23, [02,00,00,00,00], True)
    except pygatt.exceptions.NotificationTimeout:
        pass
    device.disconnect()
    adapter.stop()
    

    笔记:
  • 根据我的经验,读取句柄 0x21 毫无用处
  • 写入句柄 0x23 与 02 后跟 unix 时间戳同步规模的 RTC
  • 使用多字节修改的 pygatt (pull 34) 能够在 Indication
  • 中接收多个字节
  • 尽管写入 0x23 不会产生任何通知,但需要等待通知才能接收 0x1b 和 0x1e 指示。当收到最后一个指示时,会收到 NotificationTimeout 异常。
  • 关于bluetooth - 使用 bluez/bluetoothctl/gatttool 连接到蓝牙智能/LE 体重秤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34271217/

    相关文章:

    Android 4.4 BLE 扫描不稳定

    iphone - 未连接蓝牙设备不再可用时 IOS 收到通知

    linux - Linux 中处理的 AVRCP 关键事件

    audio - 一次发送到两个蓝牙扬声器

    c++ - Serial.Read() 代码

    android - 如果调用 cancelDiscovery(),ACTION_DISCOVERY_FINISHED 还会出现吗?

    linux - 如何在 Linux 中保持与蓝牙 LE 体重计的连接

    android - WriteCharacteristic 和回调 onCharacteristicWrite 之间的延迟

    android - 文字量大如何写出特色

    c++ - 需要具有以下功能的 bluez API 的替代方案