question

Kevin Windrem avatar image
Kevin Windrem asked

VeDbusService calls failing

I am experiencing a situation where calls to VeDbusService fail. Specifically, the first call succeeds while subsequent calls fail with a path '/' already exists message in the traceback.

The service names are unique. In fact, I've made extremely simple service names as a test com.victronenergy.tank.foo and com.victronenergy.tank.bar and the second call still fails.

Splitting the VeDbusService in separate unix processes works fine. So it appears I can create at most one dbus service in each process.

Is there something I'm not doing right or is this a limitation of VeDbusService?

My application is to take what the NMEA2000 version of SeeLevel tank sensor system sends and split that out to separate dbus services. All SeeLevel information ends up in the same dBus object so each tank overwrites the sensor data for others. I have the system working with separate unix processes for each tank, but am wasting CPU cycles repeating the same data collection for each tank, then throwing it away if it is not for the right tank.

tank monitor
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

3 Answers
Izak (Victron Energy Staff) avatar image
Izak (Victron Energy Staff) answered ·

Hi Kevin,

You are right: You can have at most one dbus service per process. Well, that is not the whole truth, I will show you how to get past this requirement, but let me first explain why this happens.

The first half of the reason is within dbus-python. Right here:

https://github.com/freedesktop/dbus-python/blob/master/dbus/_dbus.py#L106

In short, when you create a multiple SessionBus or SystemBus objects in the same process, they all share the same connection to the dbus daemon.

The second half is this: A service name behaves like an alias. A dbus connection has a unique name that will be something like `:1.0`, and then it might also have zero or more services associated with that unique name. If you register more than one service name on the same dbus connection, both of them ends up being aliases for the same unique name. Both services end up being a mirror of the same thing, they have the same paths and reply with the same answers.

That is why you cannot register the same path on your "second" service. The two services are the same, and that path was already registered.

Now let me tell you how to get around it. It is simple: You need to create a connection for each service. dbus-python allows you to create private connections, but this is deprecated. You can however create a `dbus.bus.BusConnection` yourself and bypass the connection sharing noted above.

Finally, you can pass this connection object you created to the VeDbusService initialiser as the optional `bus` parameter:

https://github.com/victronenergy/velib_python/blob/master/vedbus.py#L60

Also see how I did this in digitalinputs, by overriding the default connection-sharing behaviour:

https://github.com/victronenergy/dbus-digitalinputs/blob/master/dbus_digitalinputs.py#L53

I hope that helps!

1 comment
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

Kevin Windrem avatar image Kevin Windrem commented ·

Your explanation is excellent and exactly what I was looking for. It really helps to have an explanation of why things behave a certain way, and most importantly what can be done about it. The examples are a huge help too.

I have implemented a solution with multiple processes but a common process that handles all tanks means less to set up.

Many thanks

0 Likes 0 ·
Kevin Windrem avatar image
Kevin Windrem answered ·

Izak, what you suggested works perfectly. It worked the first time actually!

Thanks

2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

Kevin Windrem avatar image
Kevin Windrem answered ·

Oh yes, I did need to update the libraries as the ones I had didn't support passing the bus to VeDbusService ( ).

I'm not sure why there isn't a common library directory on the system. I'm guessing that's to prevent breaking something that's working with a global library update?

2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.