8. CAN BUS INTEGRATION
rev 3.6 โ CAN lives on the OptiPlex only (awake), NOT on an always-on ESP32. The wake/state triggers (ignition, door, reverse) are physical DI wires on the Tier-0 controller โ so no always-on CAN node is needed (the WROOM-32 CAN-watch is retired). CAN's rich data (gear/RPM/trans-temp/speed) only exists while the engine runs = while driving = OptiPlex awake, read by its SH-C31G. The Tier-0 controller's onboard CAN port sits unused unless you later want parked CAN monitoring (then add a dedicated node). Data flow: OptiPlex SH-C31G โ
vehicle_stateโ gauges/voice + summaries to the Pi event-log/RAG (ยง9.3).
Hardware: SH-C31G (Canable 2.0, isolated) โ OBD2 pins 4/6/14 @ 500kbps. R120 OFF, BOOT OFF. Appears as COM port.
Owned OBD adapters (rev 3.38, ยง2 Tools): the SH-C31G stays the raw-CAN discovery/decoder interface (SavvyCAN/python-can). The owned OBDLink MX+ (BT) and OBDLink EX (USB) are app-level tools โ pair with AlfaOBD (the Mopar/FCA equivalent of FORScan; the EX's FORScan billing is Ford-only and doesn't apply here) to read/clear module codes, run actuator tests, and confirm which PIDs the truck answers before writing decoders. Use them to scope the work; use the SH-C31G to capture and decode it.
Workflow:
- SavvyCAN for visual "filter by change" discovery. โ ๏ธ Host gap (rev 3.3): the Z440 was the Windows box and it's shelved โ the in-truck OptiPlex is Linux Mint, so there is no Windows machine in the truck. SavvyCAN ships a native Linux build, so two clean options: (a) run SavvyCAN-Linux directly on the OptiPlex (X session or a laptop on the Cudy WiFi viewing it), or (b) do CAN discovery at home on the Dell Precision before install, export logs, and hand them to Claude Code. Either way, no Z440/RDP step.
- python-can decoders in production (
can_reader.py), feeding sharedvehicle_state.
Claude Code role: writes/runs the python-can scripts and analyzes exported SavvyCAN logs. Only one program holds the COM port at a time โ SavvyCAN for discovery, then close it and let python-can/Claude Code run. Hand exported logs to Claude Code for decoder writing (no port conflict).
Targets (priority): gear/RPM (power state + camera switch) โ door (via wire) โ speed โ steering (dynamic lines, last).
Transmission gear (MUST-HAVE): On high-speed bus at OBD2 โ one SH-C31G gets it. Use manual shift mode (+/-) to correlate gear changes faster. Enables real-time gear display + shift-point logging (verify the tune) + trans-temp alerts.
Multi-bus: Most data (gear, RPM, trans temp, speed, steering) is on the high-speed powertrain bus at OBD2. Body signals (doors) via Waveshare wires instead. A 2nd SH-C31G on the low-speed body bus (125kbps, behind BCM) is possible โ can_reader.py supports dual reader threads โ but likely unnecessary. Two adapters = two COM ports; identify by traffic (bus-ID script) or plug in one at a time. Body bus often 125kbps vs 500kbps powertrain โ set bitrate per thread.
Module: can_reader.py โ thread-safe vehicle_state, dual-bus reader loops, placeholder decoders (selector, current_gear, trans_temp, lockup, rpm, coolant, speed, steering, door). Fill IDs after discovery.