【问题标题】:Blocking DBus call from python API阻止来自 python API 的 DBus 调用
【发布时间】:2022-02-25 20:00:08
【问题描述】:

我正在对 BLE 设备进行编程,因此需要从 org.freedesktop.DBus.Properties 接口获取一些信息,但无法从 dbus python API 获取它。从控制台这没问题。例如,从dbus-send我可以成功调用以下方法调用(当然是正确的mac地址):

$ dbus-send --system --dest=org.bluez --print-reply "/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX" org.freedesktop.DBus.Properties.Get string:'org.bluez.Device1' string:'Paired'

>> method return time=1645780543.222377 sender=:1.7 -> destination=:1.329 serial=1113 reply_serial=2
   variant       boolean true

现在,我要做的实际上是这样的:

import dbus
bus = dbus.SystemBus()

connected = bus.call_blocking(
    'org.bluez',                             #bus_name
    '/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX', #object_path
    'org.freedesktop.DBus.Properties',       #dbus_interface
    'Get',                                   #method
    signature='(ss)',                        #signature
    args=['org.bluez.Device1', 'Connected'], #args
)
print(connected)

这给了我错误:ERROR:dbus.connection:Unable to set arguments ['org.bluez.Device1', 'Paired'] according to signature '(ss)': <class 'TypeError'>: Fewer items found in struct's D-Bus signature than in Python arguments

我也试过没有签名但没有成功。而且我还发现了一个类似的问题here,但对于 C-API。所以我试图让它适应python dbus API,但仍然无法让它工作。此外,官方documentation 也不是很有帮助,因为这里没有关于参数机制如何工作的明确声明或对此类解释的引用。这很烦人,因为我可以通过这种方式从org.freedesktop.DBus.ObjectManager 接口调用例如GetManagedObjects 方法上的阻塞调用,但那当然不需要任何参数...

任何帮助表示赞赏。

【问题讨论】:

    标签: python bluetooth-lowenergy dbus bluez


    【解决方案1】:

    还有更多用于 D-Bus 的 Pythonic 库,例如 pydbus

    device_path = "/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX"
    
    bus = pydbus.SystemBus()
    
    device = bus.get('org.bluez', device_path)
    print(device.Connected)
    

    如果您确实想使用已弃用的 python-dbus 库来做这件事,那么我一直都是这样做的:

    BLUEZ_SERVICE_NAME = 'org.bluez'
    DEVICE_INTERFACE = 'org.bluez.Device1'
    remote_device_path = device_path
    remote_device_obj = self.bus.get_object(BLUEZ_SERVICE_NAME,
                                            remote_device_path)
    remote_device_props = dbus.Interface(remote_device_obj,
                                         dbus.PROPERTIES_IFACE)
    print(remote_device_props.Get(DEVICE_INTERFACE, 'Connected'))
    

    如果你想用 PyGObject 库来做,那么一个例子是:

    from gi.repository import Gio, GLib
    
    bus_type = Gio.BusType.SYSTEM
    bus_name = 'org.bluez'
    object_path = '/org/bluez/hci0'
    prop_iface = 'org.freedesktop.DBus.Properties'
    adapter_iface = 'org.bluez.Adapter1'
    
    
    adapter_props_proxy = Gio.DBusProxy.new_for_bus_sync(
                bus_type=bus_type,
                flags=Gio.DBusProxyFlags.NONE,
                info=None,
                name=bus_name,
                object_path=object_path,
                interface_name=prop_iface,
                cancellable=None)
    
    all_props = adapter_props_proxy.GetAll('(s)', adapter_iface)
    print(all_props)
    powered = adapter_props_proxy.Get('(ss)', adapter_iface, 'Powered')
    print(powered)
    

    【讨论】:

    • 我不知道,python-dbus 库已被弃用。我开始使用它,因为官方的 bluez 示例正在使用它。我对整个 DBus 的东西还是陌生的。 pydbus 的实现看起来相当简单。我想这会让我免于一些麻烦......除此之外,与此同时,我还找到了我正在尝试使用 call_blocking() 的直接答案。我会发布它,但将您的标记为正确的,因为这是更详细的答案。谢谢!
    • 页面底部是python-dbus的信息freedesktop.org/wiki/Software/DBusBindings
    • 但是更让我困惑的是他们为什么不更新官方示例,例如:github.com/bluez/bluez/blob/master/test/example-gatt-server
    【解决方案2】:

    只是为了完整性,如果有人偶然发现:

    如果出于某种原因将签名更改为 ss 而不是 (ss),则可以使已弃用的 API 调用正常工作。这似乎与其他必须具有元组签名的 dbus API 不一致。

    connected = bus.call_blocking(
        'org.bluez',                             #bus_name
        '/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX', #object_path
        'org.freedesktop.DBus.Properties',       #dbus_interface
        'Get',                                   #method
        signature='ss',                          #signature
        args=['org.bluez.Device1', 'Connected'], #args
    )
    

    【讨论】:

      猜你喜欢
      • 2019-05-21
      • 1970-01-01
      • 2020-02-09
      • 1970-01-01
      • 1970-01-01
      • 2021-05-24
      • 1970-01-01
      • 2021-09-14
      • 1970-01-01
      相关资源
      最近更新 更多