【问题标题】:Connect to a Bluetooth LE device using bluez python dbus interface使用 bluez python dbus 接口连接到蓝牙 LE 设备
【发布时间】:2023-03-22 00:00:01
【问题描述】:

我想连接到蓝牙 LE 设备并在 python 中接收来自它的通知。我想使用 Bluez dbus API,但找不到我能理解的示例。 :-)

使用 gatttool,我可以使用以下命令:

gatttool -b C4:8D:EE:C8:D2:D8 --char-write-req -a 0x001d -n 0100 --listen

如何在 python 中使用 Bluez 的 dbus API 做同样的事情?

【问题讨论】:

    标签: python dbus bluez gatt


    【解决方案1】:

    使用 BlueZ DBus API 作为 gatt 客户端可能是使用 pydbus 库最简单的方法。 https://pypi.org/project/pydbus/

    BlueZ DBus API 文档位于:

    https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/adapter-api.txt

    https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/device-api.txt

    https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/gatt-api.txt

    一些有用的知识可以帮助您入门:

    1. bluez 的 Dbus 服务称为“org.bluez”
    2. Raspberry Pi 上的蓝牙适配器通常将“/org/bluez/hci0”作为 DBus 对象路径。
    3. 设备的 DBus 对象路径是适配器路径加上前缀为“dev_”的 mac 地址,分号替换为 下划线。即'DE:82:35:E7:43:BE'将在 '/org/bluez/hci0/dev_DE_82_35_E7_43_BE'

    我没有你的设备,所以我做了一个示例,使用 BBC micro:bit 来更改它更新温度值(周期)的频率值,然后获取这些温度值的通知。希望这很容易适应您的情况。

    此代码假定您已经使用bluetoothctl 来配对您的设备。 在命令行中输入bluetoothctl devices,如果您的设备在列表中,那么这是一个好兆头。

    import pydbus
    from gi.repository import GLib
    
    # Setup of device specific values
    dev_id = 'DE:82:35:E7:43:BE'
    adapter_path = '/org/bluez/hci0'
    device_path = f"{adapter_path}/dev_{dev_id.replace(':', '_')}"
    temp_reading_uuid = 'e95d9250-251d-470a-a062-fa1922dfa9a8'
    temp_period_uuid = 'e95d1b25-251d-470a-a062-fa1922dfa9a8'
    
    # Setup DBus informaton for adapter and remote device
    bus = pydbus.SystemBus()
    mngr = bus.get('org.bluez', '/')
    adapter = bus.get('org.bluez', adapter_path)
    device = bus.get('org.bluez', device_path)
    # Connect to device (needs to have already been paired via bluetoothctl)
    device.Connect()
    
    # Some helper functions
    def get_characteristic_path(device_path, uuid):
        """Find DBus path for UUID on a device"""
        mng_objs = mngr.GetManagedObjects()
        for path in mng_objs:
            chr_uuid = mng_objs[path].get('org.bluez.GattCharacteristic1', {}).get('UUID')
            if path.startswith(device_path) and chr_uuid == uuid:
               return path
    
    def as_int(value):
        """Create integer from bytes"""
        return int.from_bytes(value, byteorder='little')
    
    # Get a couple of characteristics on the device we are connected to
    temp_reading_path = get_characteristic_path(device._path, temp_reading_uuid)
    temp_period_path = get_characteristic_path(device._path, temp_period_uuid)
    temp = bus.get('org.bluez', temp_reading_path)
    period = bus.get('org.bluez', temp_period_path)
    # Read value of characteristics
    print(temp.ReadValue({}))
    # [0]
    print(period.ReadValue({}))
    # [232, 3]
    print(as_int(period.ReadValue({})))
    # 1000
    
    # Write a new value to one of the characteristics
    new_value = int(1500).to_bytes(2, byteorder='little')
    period.WriteValue(new_value, {})
    
    # Enable eventloop for notifications
    def temp_handler(iface, prop_changed, prop_removed):
        """Notify event handler for temperature"""
        if 'Value' in prop_changed:
            print(f"Temp value: {as_int(prop_changed['Value'])} \u00B0C")
    
    mainloop = GLib.MainLoop()
    temp.onPropertiesChanged = temp_handler
    temp.StartNotify()
    try:
        mainloop.run()
    except KeyboardInterrupt:
        mainloop.quit()
        temp.StopNotify()
        device.Disconnect()
    

    【讨论】:

    • 非常感谢您的回答,但我需要这个的项目很久以前就结束了。由于当时我们无法直接在 python 中找到解决方案,据我所知,我们从 python 中调用了 bluetoothctl 并解析了结果。不太好,但对于我们想要的来说已经足够了。我希望那时我能得到你的答复。亲切的问候,安德烈亚斯
    • 这应该是这个问题的公认答案。
    【解决方案2】:

    查看 bluez 包中的“test/example-gatt-client”

    【讨论】:

    • 我看到了该文件夹中的所有示例,但不幸的是,我对底层技术的了解不足以理解,没有更多解释就在那里做了什么。 example-gatt-client 似乎做的比我想要的要多得多,我无法选择/识别我需要的部分:连接到 BLE 设备并启用从设备接收通知。下一步是向设备发送一些消息/通知并听取响应。
    猜你喜欢
    • 1970-01-01
    • 2015-06-08
    • 2018-11-16
    • 2014-10-04
    • 1970-01-01
    • 2016-03-20
    • 2021-12-10
    • 2013-04-11
    • 1970-01-01
    相关资源
    最近更新 更多