The component that holds current vehicle values and serves them to everyone — decoupling producers from consumers, and making the whole stack testable without a vehicle.
Intermediate5 minKuksa · Data broker · Testing
You have a naming scheme () and transports (, ).
The missing piece is something that holds the current value of every signal and
serves it to whoever asks.
That is a data broker, and it is quietly one of the highest-leverage components
in an SDV stack.
Producers publish, consumers subscribe, neither knows the other — Feeders translate from whatever the vehicle actually speaks into VSS. Applications read and write VSS. Swapping a feeder for a simulator changes nothing above.
The CAN feeder can be replaced with a SOME/IP feeder when the underlying ECU is
modernised. Every application above continues working unchanged, because they all
talk VSS.
The most widely used open implementation is the Kuksa databroker, from the
Eclipse SDV working group. It stores current VSS values and exposes them over
gRPC.
Running one and driving itbash
docker run -p 55555:55555 ghcr.io/eclipse-kuksa/kuksa-databroker:latestkuksa-client set Vehicle.Speed 42.5kuksa-client get Vehicle.Speedkuksa-client subscribe Vehicle.Cabin.Seat.Row1.DriverSide.Heating
An application reading from itpython
from kuksa_client.grpc import VSSClientwith VSSClient('127.0.0.1', 55555) as client: for updates in client.subscribe_current_values(['Vehicle.Speed']): speed = updates['Vehicle.Speed'].value render(speed)
Writing to a sensor signal means "this is the current value" — that is what a
feeder does when reporting reality.
Writing to an actuator signal means "please make it so" — a request that
travels down to the vehicle and may be refused.
Target value versus current valuepython
# An application requests a changeclient.set_target_values({'Vehicle.Cabin.Seat.Row1.DriverSide.Heating': 80})# The feeder reports what actually happenedclient.set_current_values({'Vehicle.Cabin.Seat.Row1.DriverSide.Heating': 80})
It is a current-value store, not a message bus. Ask it what speed is now and
it answers. Ask for every speed sample over the last ten seconds and it cannot.
High-rate historical streams need something else.
It is a component that can fail. Everything depending on it is affected.
Production designs need to think about restart behaviour and what consumers do
while it is unavailable.
Latency is added. A hop through a broker costs something. For control loops
with tight budgets it may be the wrong path — direct service calls are shorter.
It does not make legacy signals into services. A signal exposed through a
broker is still a value. It does not gain request-response semantics or
meaningful errors just by being renamed.