Skip to content

Add parallel diagnostics forwarding pipeline (DiagnosticStatus → Zenoh → InfluxDB → Grafana + REST)#1

Draft
Copilot wants to merge 2 commits into
mainfrom
copilot/featurediagnostic-code-forwarding
Draft

Add parallel diagnostics forwarding pipeline (DiagnosticStatus → Zenoh → InfluxDB → Grafana + REST)#1
Copilot wants to merge 2 commits into
mainfrom
copilot/featurediagnostic-code-forwarding

Conversation

Copilot AI commented Jun 5, 2026

Copy link
Copy Markdown

Adds a complete diagnostics data path alongside the existing rFMS/VehicleStatus flow, without touching any existing behavior. The pipeline runs: diagnostic-source-simulator → Kuksa Databroker → fms-diagnostics-forwarder → uProtocol/Zenoh (D110) → fms-diagnostics-consumer → InfluxDB → Grafana + REST API.

Proto (fms-proto)

  • New messages: DiagnosticSummary, DiagnosticCode, DiagnosticStatus in fms.proto (proto3, package fms.v4)
  • fms-proto added to workspace members; integration test covers round-trip serialization

InfluxDB (influx-client)

  • 25+ new constants: MEASUREMENT_DIAGNOSTIC_SUMMARY, MEASUREMENT_DIAGNOSTIC_CODE, and associated tag/field names
  • write_diagnostic_status(&DiagnosticStatus) — fire-and-forget async method mirroring write_vehicle_status; writes one diagnostic_summary row and one diagnostic_code row per active/stored/pending DTC; normalizes empty tags to "UNKNOWN"

New crates

Crate Role
fms-diagnostics-forwarder Polls Vehicle.Diagnostics.* VSS paths from Kuksa, builds DiagnosticStatus, publishes to topic up://fms-diagnostics-forwarder/D110/1/D110
fms-diagnostics-consumer Subscribes to up://*/D110/1/D110, decodes DiagnosticStatus, writes to InfluxDB
diagnostic-source-simulator Alternates between cleared and faulted states every 10 s via Kuksa v2 publish_value

VSS overlay (spec/overlay/vss.json + fms.vspec)

  • Vehicle.Diagnostics branch: 4 DTC count fields (uint16), 7 string signals with allowed enumerations for severity/lifecycle state, E2EV sub-branch (CrcOk bool, AliveCounter uint16, LastFault string)

fms-server — diagnostics REST API

Five new routes (existing rFMS routes unchanged):

GET /diagnostics/vehicles
GET /diagnostics/vehicles/{vin}/summary
GET /diagnostics/vehicles/{vin}/dtcs
GET /diagnostics/vehicles/{vin}/dtcs/active
GET /diagnostics/vehicles/{vin}/timeline

Backed by four new Flux queries on diagnostic_summary / diagnostic_code measurements.

Compose & Grafana

  • Three new services in fms-blueprint-compose.yaml with Zenoh overrides in -zenoh.yaml; Hono compose annotated as Zenoh-only for now
  • grafana/dashboards/FMS-Diagnostics.json: 5 panels — Active DTC Count by VIN, Worst Severity by VIN, Active DTC table, Active Faults status, DTC timeline; provisioned via existing filesystem loader
  • Dockerfiles for all three new services following existing rust-musl-cross pattern
Original prompt

Extend Fleet Management Blueprint with Diagnostic Code Forwarding

Repository and baseline

  • Repository: chheis/fleet-management
  • Base commit: eedc2c373efb0a89d1de26c7ab9843bc574f8884
  • Work branch: feature/diagnostic-code-forwarding
  • Stack: Rust workspace under components/, Docker Compose orchestration, Kuksa Databroker (VSS), uProtocol over Zenoh/Hono, InfluxDB 2.7, Grafana 9.5.

Goal

Add a parallel diagnostics pipeline alongside the existing rFMS/VehicleStatus flow, without changing existing behavior. Target data path:

diagnostic source -> Kuksa Databroker diagnostic VSS paths -> fms-diagnostics-forwarder -> uProtocol notification (Zenoh) -> fms-diagnostics-consumer -> InfluxDB -> Grafana diagnostics dashboard + fms-server diagnostics REST API

The existing path MUST keep working unchanged:
csv-provider -> Databroker -> fms-forwarder -> uProtocol -> fms-consumer -> InfluxDB -> Grafana/rFMS API

Hard constraints

  1. Do NOT modify the VehicleStatus message, its writer, or its rFMS endpoints in a behavior-changing way.
  2. Diagnostics is a NEW protobuf message family, NEW uProtocol topic, NEW forwarder/consumer crates, NEW Influx measurements, NEW VSS paths, NEW Grafana dashboard, NEW REST endpoints.
  3. Zenoh transport parity is required. Hono parity is optional (see Phase 7).
  4. cargo fmt --all, cargo clippy --workspace --all-targets -- -D warnings, and cargo test --workspace must pass for everything you add. Run all cargo commands from components/.
  5. Maintain REUSE compliance: every new file needs an SPDX header or a .license sidecar, following existing files (Apache-2.0, "Contributors to the Eclipse Foundation").
  6. If the baseline build cannot complete in the environment (e.g. musl cross images, network), record this under "Baseline status" in docs/diagnostics-forwarding.md and proceed best-effort; still ensure new code compiles in the workspace.

Repository facts you must rely on (verified)

  • components/Cargo.toml [workspace].members does NOT include fms-proto (members are fms-consumer, fms-forwarder, fms-server, fms-zenoh, influx-client, up-transport-hono-kafka, up-transport-hono-mqtt). Add "fms-proto" plus the two new crates to members.
  • components/fms-proto/build.rs compiles only proto/fms/v4/fms.proto into cargo out dir module fms; src/lib.rs does include!(concat!(env!("OUT_DIR"), "/fms/mod.rs")). New messages are reachable as fms_proto::fms::*. No build.rs change required.
  • proto/fms/v4/fms.proto is proto3, package fms.v4, already imports google/protobuf/timestamp.proto.
  • components/influx-client/src/lib.rs defines constants including TAG_VIN = "vin", FIELD_CREATED_DATE_TIME = "createdDateTime", MEASUREMENT_HEADER, MEASUREMENT_SNAPSHOT, TAG_TRIGGER. Reuse TAG_VIN and FIELD_CREATED_DATE_TIME.
  • components/influx-client/src/writer.rs: InfluxWriter wraps InfluxConnection. write_vehicle_status(&self, &VehicleStatus) returns () and logs via warn!/debug! (fire-and-forget). Uses influxrs::Measurement::builder(name).tag(..).field(..).build() -> Result. Timestamps use protobuf::well_known_types::timestamp::Timestamp converted to SystemTime then millis since UNIX_EPOCH as u128. The crate error type is influxrs::InfluxError (NOT influxrs::Error).
  • components/fms-consumer/src/main.rs: subscribes to --topic-filter default up://*/D100/1/D100, local uService up://fms-consumer/D101/1/0, TransportType { Hono(HonoKafkaTransportConfig), Zenoh(ZenohTransportConfig) }, listener calls msg.extract_protobuf::<VehicleStatus>() then influx_writer.write_vehicle_status(...).
  • components/fms-forwarder/src/main.rs: publishes to --topic default up://fms-forwarder/D100/1/D100 using SimplePublisher + StaticUriProvider::try_from(&topic); payload via UPayload::try_from_protobuf(...); origin_resource_id = u16::try_from(topic.resource_id). TransportType { Hono(HonoMqttTransportConfig), Zenoh(ZenohTransportConfig) }. Vehicle data comes from mod vehicle_abstraction (vehicle_abstraction.rs + vehicle_abstraction/{kuksa.rs,vss.rs}).
  • vehicle_abstraction.rs: KuksaDatabrokerClientConfig (clap Args) exposes --databroker-uri (env KUKSA_DATABROKER_URI, default http://127.0.0.1:55555) and --timer-interval (env TIMER_INTERVAL). KuksaValDatabroker uses kuksa_rust_sdk::kuksa::val::v2::KuksaClientV2, get_values(paths), subscribe(...). VIN path constant Vehicle.VehicleIdentification.VIN.
  • components/fms-server/src/lib.rs: builds an axum Router with /, /rfms/vehiclepositions, /rfms/vehicles, /rfms/vehiclestatuses, state Arc<InfluxReader>. influx_reader.rs builds Flux queries against MEASUREMENT_SNAPSHOT etc. Response models live in src/models/{mod.rs,position.rs,status.rs,vehicle.rs}.
  • fms-blueprint-compose.yaml: networks fms-backend, fms-vehicle; databroker mounts ./spec/overlay/vss.json as config vss_overlay.json -> `/vss_o...

This pull request was created from Copilot chat.

Copilot AI changed the title [WIP] Add parallel diagnostics pipeline for forwarding Add parallel diagnostics forwarding pipeline (DiagnosticStatus → Zenoh → InfluxDB → Grafana + REST) Jun 5, 2026
Copilot finished work on behalf of chheis June 5, 2026 21:31
Copilot AI requested a review from chheis June 5, 2026 21:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants