Skip to content

Cascadia dashboards for TEL, MDI, DRD and STR - #206

Merged
clbears merged 18 commits into
mainfrom
user/clbears/grafana/cascadia-dashboards
Nov 3, 2026
Merged

clbears merged 18 commits into
mainfrom
user/clbears/grafana/cascadia-dashboards

Conversation

@clbears

@clbears clbears commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Cascadia dashboards for TEL, MDI, DRD and STR

Rebuilds the four board dashboards for Cascadia, fixes cascadia.dbc where it disagrees with firmware, and adds a scenario simulator for testing dashboards without the car. The Brightside dashboards are unchanged.

Tested with simulated data and with real Cascadia data from the 2026-10-24 bench integration test (see Testing).

DRD with an active fault, a warning and a cleared fault

Layout (same on all four boards)

  • Fault banner across the top, full width so it is noticed out of the corner of your eye:
    • Blank when everything is normal.
    • Red "ACTIVE FAULT: …" while a firmware fault bit is set. It names the bits.
    • Orange "WARNING: …" when something is wrong that isn't a fault bit: link lost, board rebooted in the last minute, GPS with fewer than 4 satellites or no 3D fix, CAN bus load ≥ 70 %, motor RTD not reading, motor in the 95–100 °C caution band, DRD cyclic-data timeouts, DRD drive state INVALID.
    • Faults and warnings together show red, faults first.
  • Health row: link freshness (seconds since the board's last frame, red after 3 s), uptime, MCU Vdd and temperature (red at the firmware limits), and the board's key state. Tiles stay unfilled unless something is abnormal.
  • Fault strip: one row per fault bit. Grey OK, red FAULT while set, then yellow CLEARED for the rest of the time range, so a fault that came and went isn't missed.
  • Grouped data rows: trends with units and the alarm band drawn in (at most 4 traces each), and state timelines with a word for every state.
  • Raw / diagnostic row (collapsed): every signal the board sent, with its latest value and arrival time, for bench work and bug reports.
  • Titles follow docs/GRAFANA.md. Fixed uids cascadia-prod-{tel,mdi,drd,str}, and a link bar to switch between the Cascadia boards.
TEL MDI DRD STR
TEL MDI DRD STR
More screenshots: GPS warning, motor overtemp, raw diagnostic row, simulator

TEL, GPS lost (warning, not a fault)
TEL GPS warning

MDI, motor past 100 °C (fault)
MDI overtemp

DRD, raw diagnostic row expanded
DRD raw

Simulator control panel (tools/cascadia_sim)
Simulator

DBC changes (dbc/cascadia.dbc), checked against firmware_v4 origin/main ecd8735

Message Change Firmware evidence
TEL 0x764 TELMCUHealth (MCU_Voltage mV, MCU_Temperature °C) replaces CPULoad; no firmware sends a CPU load tel/app/diagnostics.c:74-93
TEL 0x751 + MCUOvertemp, MCUUndervoltage (bits 5-6) tel/app/diagnostics.h
MDI 0x501 + MDIRTDFault, MDIRTDCommError (bits 3-4) mdi/app/diagnostic.h:14-23
MDI 0x502 DLC 5→6, + RTDFaultFlags (byte 5) and a value table mdi/app/diagnostic.c:96-131
DRD 0x402 new DRDMCUHealth drd/app/diagnostic.c:142-157
DRD 0x403 + DRDMCUOverTemp, DRDMCUUnderVoltage (bits 38-39) drd/app/diagnostic.h:20-32
STR 0x591 / 0x592 new STRMCUHealth, STRFlags (bit 0 = undervoltage, bit 1 = overtemp; brightside.dbc has them reversed) str/app/diagnostic_app.{c,h}

scripts/check_dbc.py passes. A hand-packed frame for each changed message decodes to the value the firmware encodes.

Panels from the Brightside boards that were dropped or renamed

  • TEL GPSLatitude/Longitude/Fix/SatCount are now GpsLatitude, GpsLongitude, GpsFixType and GpsSatsUsed.
  • DRD SpeedUnitKPH is now MotorCommand.SpeedUnits.
  • MDI MCUVoltage/MCUTemperature/MDIOverVoltage are dropped: MDI has no MCU-health code, and 0x503 carries the commit hash.
  • STR STRWatchdogReset is dropped: nothing sends 0x582.

Simulator (tools/cascadia_sim, separate commits, can be dropped)

Realistic, adjustable TEL/MDI/DRD/STR data for testing dashboards without the car. Frames use firmware IDs, rates and fault thresholds, are encoded and decoded with cascadia.dbc, and are written with sunlink's InfluxDB layout.

python tools/cascadia_sim/cascadia_sim.py                       # browser control panel on localhost:8090
python tools/cascadia_sim/cascadia_sim.py --headless --scenario motor_overheat --duration 120
  • Control panel: 13 one-click scenarios (GPS lost, motor overheat, RTD failure, STR brownout, link down, …), toggles and sliders per board, and "Reset everything to normal", which also clears the simulated fault history.
  • Tagging: every simulated point is tagged source=cascadia_sim, and reset deletes only those points. Real logs imported into the same local bucket are never touched. Dashboards ignore the tag.
  • Safety: refuses to write anywhere but localhost unless --allow-remote is passed.
  • How it differs from the existing CAN simulators:
    • firmware_v4/tools/Simulate_CAN_Bus (also in sunlite) replays fixed raw payloads from YAML onto a real CAN bus (socketcan). It is for bus timing, load and startup tests on hardware.
    • drd/test/test_scripts/simulate_mc.py fakes the motor controller for DRD bench tests.
    • This one needs no CAN hardware. It produces changing, realistic signal values with firmware fault logic straight into InfluxDB, so dashboards can be tested and demoed scenario by scenario. The tools complement each other.

Design basis (user interview, 2026-10-31)

  • Who: pit crew during races; embedded on the bench.
  • Situation: mostly live race and test drives (last 5 min, 1 s refresh).
  • Decisions made from these boards: call the driver or stop the car; reboot or swap a board; file a bug for embedded.
  • Doing at the same time: radio, other screens, typing/debugging, so attention is often elsewhere.
  • Must be noticed peripherally: active faults and warnings, on the banner.
  • Past faults: yellow CLEARED on their fault-strip row.
  • Screens: a mix. The first screen (banner, health, fault strip) fits a ~15" laptop at 1440×900; detail sits lower.
  • Threshold sources:
    • Firmware: MCU undervoltage/overtemp (TEL/DRD 2000 mV / 125 °C, STR 2400 mV / 105 °C), motor overtemp 100 °C set / 95 °C clear.
    • Designer default, confirmed by the user: link lost after 3 s; GPS < 4 satellites / no 3D fix; CAN bus load 70 % / 90 %; GPS accuracy 5 m / 20 m; PDOP 2.5 / 6; "rebooted" for 60 s after boot.

The layout follows situation-awareness and high-performance HMI principles (Endsley 1995, PAS High Performance HMI, Wickens 2008, FAA HF-STD-001B).

Testing

  • Local stack: grafana-oss 9.5.2 + influxdb 2.7.1, fed by the simulator.
  • DBC lint: every panel field exists for its board in cascadia.dbc (0 errors, 0 warnings on all four dashboards).
  • Live query check: all 61 panel queries return data. Each scenario was run and its banner text, tiles and fault rows checked.
  • Real Cascadia data, 2026-10-24 bench integration test (current firmware apart from the Oct 31 commits; decoded at the time with the old cascadia.dbc). The data is in CAN_prod on the Sunlink laptop used for that test (ckalitin-victus, 19:39–23:47 UTC). On a 30-minute slice (603k points), every panel whose signal was decoded shows real data, and the banners catch the real bench problems from that day:
    • DRD's cyclic-data timeouts (the motor controller only sent request frames).
    • A latched MDI watchdog reset.
    • TEL GPSReadFail toggling.
  • Expected empty panels on that data:
    • MCU health (TEL/DRD/STR), STRFlags, RTDFaultFlags and SpeedUnits weren't in the old DBC, so they weren't decoded.
    • GPS sent no frames all day.
    • IMU sent only 302 frames in 1.5 h (IMU over CAN was fixed in firmware on Oct 31).
  • DBC fix confirmed on real frames: the old DBC stored TEL 0x764 as CPULoad, reading about 2e-39. Re-decoded with this PR's layout, the same 28 frames give MCU_Voltage 3419–3467 mV and MCU_Temperature 21–25 °C. The slightly high voltage fits the uncalibrated TEL ADC noted below.
  • Also tested: a 30-minute bench log from 2026-08-27 (team InfluxDB, CAN_log).
  • Still to see on hardware: GPS, IMU and the new MCU-health/fault signals, once sunlink runs on the new cascadia.dbc.

🤖 Generated with Claude Code

clbears and others added 14 commits October 31, 2026 18:16
Ports the diagnostics added to firmware_v4 in October (and to
brightside.dbc only) into cascadia.dbc, with layouts checked against
firmware origin/main ecd8735:
- TEL 0x764: TELMCUHealth (MCU_Voltage mV, MCU_Temperature degC) replaces
  CPULoad; no firmware sends a CPU load (tel/app/diagnostics.c:74-93)
- TEL 0x751: MCUOvertemp, MCUUndervoltage bits 5-6
- MDI 0x501: MDIRTDFault, MDIRTDCommError bits 3-4
- MDI 0x502: DLC 6, RTDFaultFlags byte 5 (+ value table)
- DRD 0x402: new DRDMCUHealth; 0x403 DRDMCUOverTemp/UnderVoltage bits 38-39
- STR 0x591 STRMCUHealth, 0x592 STRFlags (bit0 undervoltage, bit1 overtemp
  per str/app/diagnostic_app.h; brightside.dbc has these reversed)
Temperatures are int16 (signed) as sent by firmware.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- CAN_Msg.py and randomizer.py imported CAR_DBC by value, so
  link_telemetry --dbc changed nothing: decoding and random generation
  always used brightside.dbc. Read parameters.CAR_DBC at call time.
- decode with decode_choices=False (CAN_Msg, cellular_parser): signals
  with a VAL_ table decode to NamedSignalValue, which influxdb_client
  rejects, failing the whole batch. cascadia.dbc has 29 VAL_ tables.
  Grafana maps the raw ints back to names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One layout for all four boards: health and faults on top (link
freshness, uptime, MCU health with firmware fault limits, one fault
strip), then grouped trends and state timelines, units on every numeric
panel. TEL adds GPS position/status/motion. Generated with the
clbears-hmi-design sunskill (telemetry-hmi) and checked against
cascadia.dbc and live random data. Brightside dashboards are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tools/cascadia_sim: realistic, adjustable TEL/MDI/DRD/STR data for testing
dashboards. Frames use firmware IDs, rates and fault logic, are encoded and
decoded with cascadia.dbc, and written with sunlink's InfluxDB layout. Tk
window with sliders/toggles per board and 13 preset scenarios (GPS lost,
motor overheat, RTD failure, STR brownout, link down, ...). Headless mode
for scripted runs. Refuses non-localhost InfluxDB unless --allow-remote.

Dashboards: MCU Vdd shown in mV (Grafana rescaled to whole volts), motor
temperature axis starts at 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One page on localhost:8090 (stdlib http.server, bound to 127.0.0.1):
one-click scenario buttons, toggle buttons, sliders with firmware limits
highlighted, action buttons (reboot, motor temp jumps), live readout and
links to each board's dashboard. Now the default; --tk keeps the Tk window.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saturated red, white bold text on a red pill with glow for out-of-limit
values, active fault toggles and motor OVERTEMP.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…normal

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Red ACTIVE FAULT if any fault bit is set in the latest frame, yellow
FAULT IN WINDOW if one was set in the time range shown but has cleared,
NO FAULTS otherwise. Sits left of each fault strip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each fault row is OK until it faults, FAULT (red) while set, then CLEARED
(yellow) for the rest of the time range shown. Removes the separate
fault status tile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blank until a fault bit is set, then solid red 'ACTIVE FAULT: <signals>'
across the top of the board, for peripheral vision. Stat tiles use a
solid fill. MCU Vdd tile no longer turns red when there is no data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resets inputs to the normal scenario, clears the motor overtemp latch and
RTD fault counter, and deletes the simulated TEL/MDI/DRD/STR data written
since 2026-10-01 from the local bucket, so old faults no longer show as
CLEARED. Older data (e.g. copied real logs) is kept. Button in the browser
panel and the Tk window. Writes and the delete share a lock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Banner now also shows orange WARNING for abnormal conditions that are not
fault bits: link lost, board rebooted < 60 s ago, GPS < 4 satellites or no
3D fix, CAN bus load >= 70 %, motor RTD not reading, motor temperature in
the 95-100 degC caution band, DRD cyclic-data timeouts, DRD drive state
INVALID. Red (faults) takes priority and lists warnings after.

cascadia_sim: fewer than 4 satellites degrades a 3D fix to 2D, fewer than
3 to no fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the user interview (pit crew + embedded on the bench; reboot/swap
boards and file bugs): a collapsed table of every signal the board sent,
with its latest value and arrival time. First screen (banner, health,
fault strip) checked to fit a laptop at 1440x900.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
images/cascadia_dashboards: the four boards in normal operation, an active
fault with a warning and a cleared fault (DRD), a GPS warning (TEL), motor
overtemp (MDI), the raw diagnostic row and the simulator panel. Taken from
the local stack fed by tools/cascadia_sim.

cascadia_sim: motor model capped at 140 degC so runaway heating stays
plausible.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@clbears
clbears marked this pull request as ready for review November 1, 2026 18:21
Every simulated point now carries source=cascadia_sim and 'Reset
everything to normal' deletes only points with that tag. Before, reset
deleted all TEL/MDI/DRD/STR data after 2026-10-01 in the target bucket,
which would also wipe real logs imported into a local stack. Dashboards
ignore the tag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@clbears
clbears requested a review from gregorybian November 1, 2026 18:28
Comment thread tools/cascadia_sim/web_ui.py Resolved
Comment thread parser/data_classes/CAN_Msg.py Resolved
clbears and others added 2 commits November 1, 2026 23:25
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Takes parser/cellular_parser.py, parser/data_classes/CAN_Msg.py and
parser/randomizer.py back to main. This undoes 71c05ae.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The parser changes are out of this PR, so the parser on main decodes
enum signals to names while the simulator stores raw ints. Say what the
simulator does instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@clbears
clbears merged commit a6aa87c into main Nov 3, 2026
2 checks passed
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.

3 participants