[英]Blocking DBus call from python API
我正在对 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
我也尝试过没有签名但没有成功。 我在这里也发现了类似的问题,但针对的是 C-API。 所以我试着让它适应 python dbus API,但仍然无法正常工作。 此外,官方文档也不是很有帮助,因为这里没有关于参数机制如何工作的明确说明或对此类解释的引用。 这很烦人,因为我可以通过这种方式从org.freedesktop.DBus.ObjectManager
接口调用GetManagedObjects
方法的阻塞调用,但是那个当然不需要 arguments ...
任何帮助表示赞赏。
有更多用于 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)
只是为了完整性,如果有人偶然发现这个:
如果出于某种原因将签名更改为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
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.