I found it quite frustrating to get started with D-Bus and the lack of working examples.
I found this bit of example somewhere, can’t remember the original source, sorry about that.
I’ll be using python3 and dbus-python for this example
Prerequisite
You’ll need:
- python3
- build-essential
- libdbus-1-3
- dbus-python
For debugging and getting a clearer picture of what’s happening, install also d-feet.
Code
#!/usr/bin/python3
from gi.repository import GLib
import dbus
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop
class Example(dbus.service.Object):
def __init__(self, object_path):
super().__init__(dbus.SessionBus(), object_path)
self._last_input = 1.0
@dbus.service.method(dbus_interface='com.example.Sample',
in_signature='v', out_signature='s')
def StringifyVariant(self, var):
self.LastInputChanged(var) # emits the signal
return str(var)
@dbus.service.signal(dbus_interface='com.example.Sample',
signature='v')
def LastInputChanged(self, var):
# run just before the signal is actually emitted
# just put "pass" if nothing should happen
self._last_input = var
@dbus.service.method(dbus_interface='com.example.Sample',
in_signature='', out_signature='v')
def GetLastInput(self):
return self._last_input
if __name__ == '__main__':
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
name = dbus.service.BusName("com.example.Sample", dbus.SessionBus())
service = Example('/com/example/Sample')
mainloop = GLib.MainLoop()
print ("Running sample service.")
mainloop.run()
Code language: Python (python)
chmod +x your python file and make run it.
Testing
To execute the method declared in the service, use the dbus-send command line utility.
dbus-send --session --dest="com.example.Sample" --type="method_call" --print-reply "/com/example/Sample" "com.example.Sample.GetLastInput"
Code language: PHP (php)
From here you can either get the return value or some error.
The return value looks something like this.
method return time=1591277771.079203 sender=:1.139 -> destination=:1.144 serial=7 reply_serial=2
variant double 1
Code language: JavaScript (javascript)
You can also get this time of error
Error org.freedesktop.DBus.Error.ServiceUnknown: The name org.example.Sample was not provided by any .service files
Code language: CSS (css)
This one means 2 things either your service is not running or you made a mistake in the request.
Check first that your service in running. If it is then take a look at d-feet and correct your query
Another pitfall is to have multiple processes running at the same time. The new process is queued. So if you try to run a new modified instance and the behavior doesn’t match that’s another place to look
Now about the “The name org.example.Sample was not provided by any .service files“.
You can declare that service file yourself.
With root privilege, add com.example.Sample.service file in /usr/share/dbus-1/services/. The file name must match the service name
[D-BUS Service]
Name=com.example.Sample
Exec=/home/me/dbus_test/service.py
Code language: JavaScript (javascript)
After adding this file any D-Bus request to our org.example.Sample service will automatically start it
/usr/share/dbus-1/system-services/ are for D-Bus service running on the system bus and opposed to session bus.
For system service, you also need to add a file defining the permissions for the service. I’ll get back to that at some points and post an example.