I am programming a BLE device and therefore need to get some information from the org.freedesktop.DBus.Properties
interface, but can't get it to work from dbus python API. From the console this is no problem. For example, from dbus-send
I can invoke following method call successfully (with correct mac address of course):
$ 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
Now, what I'm trying to do is actually something like this:
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)
which gives me the error: 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
I tried also with no signature with no success. And I also found a similar question here, but for C-API. So I tried to adapt it to the python dbus API, but still can't get it to work. Moreover, the official documentation isn't very helpful as well, as there is no clear statement on how the argument mechanism works here or a reference to such an explanation. This is pretty annoying, since I can invoke a blocking call for instance on the GetManagedObjects
method from org.freedesktop.DBus.ObjectManager
interface that way, but that one takes no arguments of course...
Any help appreciated.
There are more Pythonic libraries for D-Bus such as 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)
If you did want to do it with the deprecated python-dbus library then I have always done it this way:
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'))
If you want to do it with PyGObject library then an example of that is:
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)