Skip to main content

Communication Workflow

This page describes the end-to-end signal flow through the demo system — from driver input to physical LED actuation and back.

Signal Flow Overview

Detailed Data Paths

1. Command Path — Joystick to LEDs

This is the primary signal path that turns driver input into physical LED output:

Joystick sensor (analog)
→ Arduino sketch reads X/Y/button
→ JSON payload published to MQTT topic "InVehicleTopics"
→ Mosquitto delivers to grpc-mqtt-bridge
→ Bridge extracts VSS values via JSON pointers
→ gRPC Val/Set to Kuksa Databroker (target values)
→ Kuksa CAN Provider subscribes to target values (val2dbc)
→ CAN frame BlinkerCommand (ID 0x120) emitted on SocketCAN
→ MCP2515 receives on Arduino LED ECU
→ Arduino parses bit field and drives WS2812 LEDs

Latency: Typically < 100 ms end-to-end over Wi-Fi + CAN for the blinker command.

2. Driver Identity Path — RFID to VSS

RFID card tap on RC522 reader
→ Arduino sketch reads UID bytes
→ JSON payload {"Vehicle.Driver.Identifier.Subject": "A1B2C3D4"}
→ Published to MQTT topic "InVehicleTopics"
→ Bridge writes to Kuksa Databroker (string value)
→ FMS Forwarder maps to telemetry field "driver1Id"
→ Stored in InfluxDB → visible in Grafana "Driver Identifier (RFID)" panel

3. Feedback Path — CAN Status to VSS

The LED control ECU reports its current state back to the system:

Arduino LED ECU applies blinker/brake state
→ Encodes current state as CAN frame BlinkerStatus (ID 0x121)
→ Kuksa CAN Provider reads from SocketCAN (dbc2val)
→ Writes current values to Kuksa Databroker
→ Available to all VSS subscribers (Fleet, UI, CLI)

4. IVI Telemetry Path — VSS to LIVI Dashboard (Optional)

When the IVI Raspberry Pi 4 running LIVI is connected via Ethernet, the Kuksa-to-LIVI Telemetry Bridge workload mirrors VSS state into the head unit:

Kuksa Databroker (VSS, gRPC)
→ kuksa-livi-bridge subscribes via VSSClient.subscribe_current_values(...)
→ enumMap / scale / offset / type cast per mapping
→ batched every 250 ms into a TelemetryPayload JSON object
→ Socket.IO emit "telemetry:push" to ws://<pi4-ivi>:4000
→ LIVI merges into its telemetry store
→ Dash widgets + Android Auto cluster re-render
→ optionally projected to the paired Android phone over Wi-Fi/Bluetooth

The bridge handles two independent signal families in parallel:

  1. In-vehicle demo signalsVehicle.Body.Lights.*, Vehicle.Driver.Identifier.Subject. Originate from the Joystick/RFID ECUs via MQTT → grpc-mqtt-bridge → Kuksa.
  2. Fleet Management telemetry signals — replayed from signalsFmsRecording.csv by the Fleet Management csv-provider directly into Kuksa. All 15 recorded signals (speed, RPM, fuel level, DEF level, engine hours, parking brake, ambient temperature, odometer, weight, VIN, and both tachograph driver working-states / card-presence flags) flow through the bridge and land in the corresponding LIVI TelemetryPayload field — see the full mapping table in Kuksa-to-LIVI Telemetry Bridge → Fleet Management telemetry signals.

Because the bridge subscribes to current values on Kuksa, both producers (MQTT-driven ECUs and the CSV replay) can run at the same time without coordination — every Kuksa write reaches LIVI through the same coalescing window.

See the Kuksa-to-LIVI Telemetry Bridge for the full VSS → LIVI field mapping and configuration reference, and the IVI Head Unit (LIVI) page for the Pi 4 device setup.

5. ThreadX SOME/IP Relay Path (Optional)

Mosquitto → AZ3166 Device 1 (MQTT subscriber)
→ Parses direction + brake from MQTT payload
→ Publishes via SOME/IP over Wi-Fi (UDP)
→ AZ3166 Device 2 receives event
→ Updates LED / OLED / UI display

AZ3166 Device 1 ↔ AZ3166 Device 2
→ Bidirectional button state sync via SOME/IP

MQTT Topic Structure

All in-vehicle VSS signal updates flow through a single MQTT topic:

TopicPublisherSubscriberPayload
InVehicleTopicsJoystick ECU, RFID ECUMQTT-to-gRPC BridgeJSON with VSS path keys
InVehicleTopicsJoystick ECUAZ3166 Device 1 (optional)Same JSON payload

Bridge Mapping Configuration

The grpc-mqtt.yaml configuration defines how MQTT payloads are mapped to Kuksa gRPC updates:

mappings:
- name: "joystick-vss-update"
mqtt:
topic: "InVehicleTopics"
jsonPointer: "/"
grpc:
updates:
- path: "Vehicle.Body.Lights.DirectionIndicator.Left.IsSignaling"
type: "bool"
jsonPointer: "/Vehicle.Body.Lights.DirectionIndicator.Left.IsSignaling"
- path: "Vehicle.Body.Lights.DirectionIndicator.Right.IsSignaling"
type: "bool"
jsonPointer: "/Vehicle.Body.Lights.DirectionIndicator.Right.IsSignaling"
- path: "Vehicle.Body.Lights.Brake.IsActive"
type: "string"
jsonPointer: "/Vehicle.Body.Lights.Brake.IsActive"
- path: "Vehicle.Driver.Identifier.Subject"
type: "string"
jsonPointer: "/Vehicle.Driver.Identifier.Subject"

Each mapping entry specifies:

  • MQTT topic and JSON pointer to extract the root or a sub-object from the payload
  • gRPC updates with the VSS path, expected data type, and JSON pointer within the extracted object

The bridge queries Kuksa Databroker metadata to determine whether each VSS path is a sensor or actuator and routes the value to the appropriate field (current value vs. target value).

LED Blinking Behavior

The LED control Arduino implements the following visual behavior:

Signal StateLED Behavior
Left indicator ONLEDs 0–1 blink at 1 Hz (500 ms on/off)
Right indicator ONLEDs 6–7 blink at 1 Hz (500 ms on/off)
Brake ACTIVELEDs 3–4 solid on
All OFFAll LEDs off