Vehicle support: other Pacificas, Stellantis minivans, and a data-driven VehicleProfile#
pacifica-obd is hardwired to one vehicle: a 2021 Chrysler Pacifica (RU), gas.
This document asks how far the existing transport + UDS approach stretches across
the rest of the Pacifica RU family (2017–2027, gas and PHEV, Voyager, Grand
Caravan), what is genuinely different on those vans, and what has to become
data instead of code to support them.
It is an analysis + design proposal. Nothing here is a claim that an untested model year "works" — see §7.
Related: enhanced-diagnostics.md (UDS roadmap,
P0–P6), chrysler-sgw.md (Security Gateway).
TL;DR#
- The transport layer does not change at all. Every vehicle in scope is
classic CAN (ISO 15765-2) over the same two diagnostic buses: CAN-C
(500 kbit/s, DLC pins 6/14) and CAN-IHS (125 kbit/s, DLC pins 3/11). The
STN1170 adapter already reaches both, and the repo already pins the matching
presets (
33/53). - The module map, bus assignment, request/response IDs and DID set change — by model year, by powertrain (PHEV), and by trim/equipment. Those are exactly the things currently hardcoded.
- The generic OBD-II half (
dtc,live,readiness,freeze,vin,scan,monitor) should work on every model year in scope, gas or PHEV, because OBD-II is federally mandated on all of them. This is the tool's strongest cross-year asset. - The UDS half is where the interesting risks live: response IDs that are
not
request + 8for most modules, SGW-gated writes from 2018, a PHEV-only controller family, and no public year-by-year DID matrix. - FORScan is irrelevant here — it explicitly supports only Ford, Mazda, Lincoln and Mercury ("Vehicles other than Ford, Mazda, Lincoln, Mercury are not supported!"). The Stellantis reference tools are Appcar DiagFCA and JScan (FORScan, Appcar, JScan).
- The vehicle half is already the right shape:
profiles.pyhasRU_GAS/RU_PHEVand year/powertrain selection, anduds.pycentralises the bus and DID tables. What is missing is the addressing layer (the−0x280rule), evidence/provenance, and a correct year span (2017–2027, not 2017–2024) — see §5.7.
1. Scope: the RU minivan family#
The Chrysler Pacifica (RU) entered production in 2016 for model year 2017 and is still in production; the 2027 refresh keeps the same 3.6 L Pentastar V6, AWD and Stow 'n Go. Two other nameplates are the same vehicle:
| Nameplate | Where / when | Platform |
|---|---|---|
| Chrysler Pacifica | US, MY2017–present (gas + PHEV) | RU |
| Chrysler Voyager | US, MY2020–2026 (fleet-only 2022–2024, retail 2025; retained pre-facelift styling) | RU |
| Chrysler Grand Caravan | Canada, MY2021–present | RU |
| Dodge Grand Caravan | US/CA, MY2008–2020 | RT — different platform |
So "other Pacificas" and "Stellantis minivans" mostly collapse into one platform with three nameplates. The RT Dodge Grand Caravan is not an RU van and needs its own profile (Wikipedia).
Powertrains#
| Powertrain | Years | Notes |
|---|---|---|
| 3.6 L Pentastar V6 (gas) | 2017–2027 | ZF 948TE 9-speed automatic; AWD added for MY2020 (Launch Edition) / MY2021 broadly |
| Pacifica Hybrid (PHEV) | 2017–2026 | 16 kWh pack, SiEVT + e-CVT, dual electric motors; FWD only; discontinued Jan 2026 after a short 2026 run |
Milestones that matter diagnostically#
- MY2018 — Security Gateway (SGW). FCA introduced the SGW "in some models in the 2018 model year and all models 2019 going forward". Appcar: "Most FCA vehicle starting from the 2018 model year (produced from the summer 2017) have a Security Gateway Module." (JScan, Appcar)
- MY2020 — AWD for gas models (not PHEV).
- MY2021 — facelift / Uconnect 5, and an architecture change. New exterior,
Android-based Uconnect 5 with a 10.1" display, and a dedicated
Telematics Box Module (TBM); the TBM is the source of many
B1498communication faults on 2021+ vans. More importantly for us, Uconnect 5 runs on FCA's "Atlantis" electrical architecture, which — in FCA's own words — "replaces Powernet as the next generation of FCA core in-vehicle electronics communication", and the 2021 Pacifica is its debut vehicle. So MY2021 is an architecture boundary, not just a styling refresh, and it lines up with where opendbc splits its Pacifica firmware groups (2017–18 / 2019–20 / 2021–23). (Wikipedia, go-parts B1498, FCA press release, Stellantis Media) - MY2022–2024 — Voyager is fleet-only; MY2025 returns to retail; MY2027 refresh is cosmetic (V6 retained, styling only). So across the whole 2017–2027 run there is exactly one architecture break — the MY2021 Atlantis/Uconnect 5 change — which makes the year axis unusually friendly.
- MY2026 — PHEV discontinued (January 2026).
Vendor coverage claims broadly agree on the span but differ, and they are marketing coverage, not guarantees for every controller:
| Tool | Published Pacifica coverage |
|---|---|
| Appcar DiagFCA | Chrysler Pacifica 2017–2026 (RU), separate "Hybrid LAN Network" ECU group |
| JScan | Chrysler Pacifica RU 2017+; SGW bypass describes it as RU 2017+ |
2. Support matrix by model year and powertrain#
Legend: Supported = implemented and adapter-tested, with the 2021 gas van as the intended baseline; Likely = same protocol/architecture, no code change expected, not yet observed on that vehicle; Unverified = plausibly fine but a real unknown (new architecture element); Out of scope = deliberately not attempted.
Honesty note: even in the 2021 column, only the generic OBD-II commands are genuinely exercised today. The UDS commands (P1–P4) are implemented and adapter-tested, but per
enhanced-diagnostics.mdthey still need a car to populate. Until §7 is run on a vehicle, read every UDS cell below as "implemented, target" rather than "proven".
| Model years | Powertrain | Generic OBD-II | UDS scan CAN-C | UDS scan CAN-IHS | All-module DTC (19 02) |
Module info DIDs | PHEV controllers | Clears / writes |
|---|---|---|---|---|---|---|---|---|
| 2017 | gas | Supported (std) | Likely | Likely | Likely | Likely | — | Out of scope (but no SGW — writes may actually pass) |
| 2017 | PHEV | Supported (std) | Likely | Likely | Likely | Likely | Likely (HYBRID @ 7E2) |
Out of scope (no SGW) |
| 2018–2020 | gas | Supported (std) | Likely (reads pass SGW) | Likely | Likely | Likely | — | Out of scope (SGW) |
| 2018–2020 | PHEV | Supported (std) | Likely | Likely | Likely | Likely | Likely | Out of scope (SGW) |
| 2021–2024 | gas | Supported | Supported (target) | Supported (target) | Supported (target) | Supported (target) | — | Out of scope (SGW) |
| 2021–2024 | PHEV | Supported (std) | Likely | Likely | Likely | Likely | Likely | Out of scope (SGW) |
| 2025–2026 | gas | Likely | Likely | Likely | Likely | Likely | — | Out of scope (SGW) |
| 2025–2026 | PHEV | Likely | Likely | Likely | Likely | Likely | Likely | Out of scope (SGW) |
| 2027 | gas | Likely | Unverified (refresh) | Unverified | Unverified | Unverified | — | Out of scope |
| 2008–2020 Dodge Grand Caravan (RT) | gas | Likely (std OBD-II) | Unverified — different platform | Unverified | Unverified | Unverified | — | Out of scope |
Reads-only is the design intent. The repo's own rule stands: "The SGW blocks writes on 2018+ vehicles; reads pass. Do not assume a write will succeed."
Where "Out of scope" is a safety statement, not a capability statement#
Clearing DTCs and adaptations are blocked by the SGW on 2018+ vans. On a
2017 van there is no SGW, so a write would likely be accepted by the
vehicle — which makes it more dangerous, not less. docs/chrysler-sgw.md already
treats writes as a separate, deliberate project; keep that.
3. What actually differs diagnostically#
3.1 Bus layout — stable#
| Bus | Speed | DLC pins | Adapter preset | Repo key |
|---|---|---|---|---|
| CAN-C (HS, powertrain/chassis) | 500 kbit/s | 6 / 14 | STP 33 |
can-c |
| CAN-IHS (MS, body/comfort) | 125 kbit/s | 3 / 11 | STP 53 |
can-ihs |
| (CAN-CH) | — | 12 / 13 | needs a gray cross-adapter | not used on RU |
Appcar documents the pin/rate mapping and states that STN1170/2120/2230/2231 interfaces support CAN-IHS natively (pins 3/11 "CAN Middle speed" and 6/14 "CAN High speed") (Appcar).
Caveat found on the vehicle side: the two buses are physically star-wired,
and the star connector itself is a known failure point on 2017–2018 vans
(loose pin retention → intermittent U0001/loss-of-communication across many
modules). If a scan finds half a module map, suspect the star connector before
blaming the tool (pacificaforums,
go-parts U0001).
3.2 Module inventory — mostly stable, PHEV adds a family, trim adds the rest#
Appcar's supported-module list for the RU Pacifica (2017–2026) is the best public inventory. Grouped by its bus annotation:
CAN-C (powertrain/chassis) — PCM, TCM, BCM (CAN-C instance), ABS/ABSO,
EBBM, ORC, OCM, EPS, IPC, ESM, RFH, PTS, FFCM, ACC, DTCM, HCP, FDCM (AWD),
plus SGW itself.
CAN-IHS (cabin/body) — BCM (CAN-IHS instance), HVAC, HVACR, ICS, RADIO, AMP, ANC, DDM, PDM, DMRL, DMRR, PSDML, PSDMR, PLGM, MSM, MSMP, CSWM, HSM, FSM, DSM, CVPM, LBSS, RBSS, TBM/TBM2, EOMR, VRM, EDM, AHLM, ITM, clock.
PHEV-only (Appcar calls this the "Hybrid LAN Network") — HCP (Hybrid Control Processor), AHCP (Auxiliary HCP), BPCM (Battery Pack Control Module), OBCM (On Board Charging Module), IDCM (Integrated Dual Charger Module), EAC (Electric A/C Compressor), APM (Accessory Power Module), EBBM (Electronic Brake Booster Module), plus hybrid-flavour PCM/ABS/ORC/ESM.
Two important readings of that list:
- It is a union over all years, trims and powertrains, not one van's inventory. A base Voyager has a fraction of it. Any static map will list modules that are absent — absence must be a normal, recorded outcome.
- The Hybrid LAN label suggests the PHEV controllers may sit on their own
network. This is not confirmed as a third DLC-reachable bus. At least the
HCP is reachable on CAN-C at
0x7E2(see §3.3), and a 2020 PHEV factory scan report lists its modules under CAN-C and the interior bus, with no third bus. Treat "Hybrid LAN" as a logical grouping in a third-party tool until verified on a car.
The repo's own CAN-IHS list (PLGM, ICS, HVAC, DDM/PDM/DMRL/DMRR, PSDML/PSDMR, MSM/CSWM) is consistent with a 2020 PHEV factory scan report that puts PCM, BCM, ORC, EPS, IPC, SCCM, RFH and ESM on CAN-C and the interior modules on the interior bus (NHTSA factory scan report).
3.3 Diagnostic addressing — the biggest surprise, and the strongest argument for data#
This is the single most important finding for the design. Using the
comma.ai openpilot/opendbc Chrysler database as a real, current,
vehicle-observed source:
- Most FCA modules respond at
request − 0x280, notrequest + 8.CHRYSLER_RX_OFFSET = -0x280inopendbc/car/chrysler/values.py. - The OBD-II address block (
7E0–7E7requests →7E8–7EFresponses) does userequest + 8, because it is legislated by ISO 15765-4.
Observed addresses (from
fingerprints.py),
stable across Pacifica 2017–18, 2019–20, 2021–23 gas, and both hybrid
generations — and also across Durango, Grand Cherokee and Ram 1500:
| ECU | Request | Response | Rule |
|---|---|---|---|
| PCM / engine | 0x7E0 |
0x7E8 |
+8 |
| TCM / transmission | 0x7E1 |
0x7E9 |
+8 |
| HCP / hybrid | 0x7E2 |
0x7EA |
+8 |
| IPC / combinationMeter | 0x742 |
0x4C2 |
−0x280 |
| ORC / SRS | 0x744 |
0x4C4 |
−0x280 |
| ABS | 0x747 |
0x4C7 |
−0x280 |
| FFCM / fwdRadar | 0x753 |
0x4D3 |
−0x280 |
| EPS | 0x75A |
0x4DA |
−0x280 |
| ABS alternate (hybrid) | 0x7E4 |
0x7EC |
+8, "not on all hybrid platforms" |
The PHEV's address map differs from the gas van's. opendbc queries the same
gas/hybrid request set (abs, hybrid, engine, transmission) at both offset
rules, and the recorded hybrid results are narrower: the PHEVs list no
transmission firmware at 0x7E1 and no abs at 0x747, while the gas vans
list both. Instead, hybrids have hybrid (HCP) at 0x7E2 and, on some
platforms, the alternate ABS at 0x7E4. That is consistent with the PHEV's
SiEVT/e-CVT being coordinated by the HCP (a.k.a. PIM — Hybrid Control
Processor / Power Inverter Module, which drives both motors) rather than a
standalone TCM at the gas address. Caveat: opendbc only records ECUs it actively
queries, so absence there is evidence, not proof — confirm on a car (§7).
(opendbc fingerprints,
NHTSA TSB — HCP/AHCP(PIM)/PCM/BPCM flashed together,
go-parts P2797 — HCP/AHCP software)
Three consequences:
request + 8is wrong for most modules. A scanner that assumes the OBD offset would look for IPC at0x74A, get nothing, and under-report the van. The current repo avoids this by not filtering —_collect_framesgroups by whatever header answered. That is the right instinct; make it explicit.- The addresses are stable across the years opendbc covers (2017–2023) and
across both powertrains. Good news: the address map is small and highly
reusable. Bad news for hardcoding: it is almost stable, and the exceptions
(
0x7E4hybrid ABS, AWD-only FDCM, no-TCM-on-PHEV) are exactly the cases that need per-profile data. - The family can switch addressing style. On Jeep Cherokee (KL, 5th gen) the
same vendor code uses 29-bit addresses (
0x18DA10F1for engine). FCA can and does move. Any address representation must not assume 11-bit.
3.4 DIDs — standard block is reusable, proprietary block is missing#
The repo already reads the ISO 14229 identification block F186–F191
(_DID_NAMES in cli.py). Those are standard and portable across all years
and modules. Beyond that:
- opendbc uses a non-standard FCA identification DID
0xF132plus the standard System Supplier ECU Software Number (0xF194), forabs / eps / srs / fwdRadar / combinationMeter / hybrid / engine / transmission(values.py).F132is a useful, cheap cross-check to add. - The live-data / adaptation DID map (the bulk of a manufacturer-aware
tool's value) is not public.
enhanced-diagnostics.md§7 already flags the reverse-engineeredfca-ecu-diagnosticsdataset as a lead (repos now 404).
So: identification reads are portable and testable; proprietary DID semantics are per-ECU and must remain a loadable, replaceable database.
3.5 Sessions, padding, timing#
No verified public RU year-by-year matrix exists. What we know:
- The repo currently probes with
10 03(extended session). That is the conventional choice, but on 2018+ vans it is a session-change request flowing into SGW-protected territory. It is not guaranteed to be accepted, and its acceptance may differ by module and year. This is a must-verify item (§7). - opendbc's identification queries send no session control — plain
22 F132in the default session. So at least some reads work in the default session on these vehicles. - Multi-frame responses (17-byte VIN, 10-char part numbers) rely on ISO-TP
flow-control, which the adapter handles.
uds.messages_from_framesenforces classic-CAN framing (≤8 bytes, single-frame length 1–7, sequenced consecutive frames) — correct and unaffected by vehicle choice. - Padding: ELM/STN
ATCAF1auto-formats; do not disable spacing (ATS1). Padding/STmindifferences are the usual cause of "works on my car, not yours" and belong in profile data, not constants.
3.6 Security Gateway — a year-gated, reads-pass firewall#
- Firewall between the public sector (DLC + telematics/radio) and the private sector (everything else); authentication is restricted to Chrysler-licensed devices (JScan).
- Reads pass; writes are blocked: clears, adaptations, activations.
- The standard bypass is a "Chrysler 12+8" cable that replaces the SGW's two connectors — so it un-gates everything downstream, both buses.
- Location varies by year/trim: behind the glove box, lower centre stack, or behind the radio. OBD Genie's walkthrough notes "2018 and newer Chrysler Pacifica and 2020 and newer Chrysler Voyager", confirming the Voyager carries the SGW too (OBD Genie video, AE Tools).
- Some vendors warn that no SGW bypass exists for their newest vehicles (Jeep GC WL, 2025/26 Ram, Tonale). Worth re-checking if the intent ever expands beyond RU.
3.7 CAN FD#
No evidence that any RU minivan needs CAN FD. Appcar's continued 2017–2026
two-bus/ELM-STN coverage and the vendor tools' continued pin-based coverage both
imply classic CAN. The plan's own note stands: the STN1170 cannot reach a CAN-FD-only
module, and that would be a hard hardware wall, not a software one. Treat CAN FD
as a profile-level flag to assert false for RU, so that a future
non-classic vehicle fails loudly instead of mysteriously.
3.8 Tool landscape (why this is worth doing at all)#
| Tool | Stellantis? | Notes |
|---|---|---|
| FORScan | No | "Vehicles other than Ford, Mazda, Lincoln, Mercury are not supported!" |
| Appcar DiagFCA | Yes | Windows; 500+ BCM parameters, routines |
| JScan | Yes | Mobile only, needs a BLE adapter |
| wiTECH | Dealer | Programming / proxy alignment |
An open, read-only, data-driven UDS scanner for these vans has real space: the capable tools are all closed, Windows/mobile-first and SGW-bypass-centric.
4. What must be data (not code)#
The dividing line: anything that varies with the vehicle is data; only the protocol is code.
| Concern | Data or code? | Why |
|---|---|---|
ISO-TP framing, ELM/STN commands, uds.parse_uds_frame |
Code | Bus-independent, vendor-neutral |
| Bus definitions (name → preset, pins, bitrate) | Data | RU needs 2; other platforms add CAN-CH or 29-bit |
Address decoder (request → response) |
Code (the rule engine) with data rules | Rules differ (−0x280, +8, +0x6A, 29-bit) |
| Module inventory, bus assignment, presence | Data | Varies by year, powertrain, trim |
| Module request/response IDs | Data | Almost stable; exceptions matter |
| DID map (IDs, names, encodings, scaling) | Data | The bulk of the value; proprietary |
Standard DIDs F186–F199, F190 |
Data, but ship as a shared default set | Portable, reusable |
| DTC read/clear service numbers | Data (with sane defaults) | Some ECUs differ |
Session/padding/STmin/timeout per module |
Data | Vehicle- and module-specific |
| SGW present? which ops blocked? | Data | Year-gated (2018+) |
PID scaling for mode 01/02 |
Code (python-OBD already does it) |
Standardized |
| Safety gates on writes | Code | Must not be data-overridable silently |
Concretely: the 0x700–0x7FF scan range and the 10 03 probe (in
uds.probe_ids / cli.py) become profile fields, joining module_buses in
profiles.py; BUS_PROTOCOL, DID_NAMES and INFO_DIDS are already
centralised in uds.py. elm.py and the framing/parser code stay as they are.
5. Proposed VehicleProfile shape#
A first cut of this design already exists in
src/pacifica_obd/profiles.py — see
§5.7 for how the shape below maps onto
it, and which gaps the research surfaces.
Design goals: declarative, diffable, additive-only overrides, and explicit
about what is known vs guessed. Every fact carries conf and src.
5.1 Envelope and selection fields#
schema: pacifica-obd/vehicle-profile@1
profile_id: chrysler-pacifica-ru-2021-gas
title: "2021–2023 Chrysler Pacifica (RU) — 3.6L Pentastar V6, gas"
extends: null # PHEV profile extends this one
match: # how a discovered vehicle is matched to this profile
platform: RU
make: Chrysler
models: [Pacifica, Voyager, Grand Caravan]
model_years: [2021, 2023]
powertrains: [gas]
vin_wmi: ["2C4"] # Windsor, ON; conf: inferred — confirm per model
require_any_module: [0x7E0]
exclude_any_module: [0x7E2] # HCP present => hybrid, reject this profile
priority: 100 # higher wins among equally-matching profiles
5.2 Environment: buses, addressing, security, timing#
buses:
can-c:
label: "CAN-C (HS powertrain/chassis)"
preset: 33 # STN STP; ISO 15765 11-bit 500k
pins: [6, 14]
bitrate: 500000
framing: classic # classic | canfd
can-ihs:
label: "CAN-IHS (MS body/comfort)"
preset: 53
pins: [3, 11]
bitrate: 125000
framing: classic
addressing:
functional_broadcast: 0x7DF
scan_range: [0x700, 0x7FF]
response_rule:
default: {op: sub, value: 0x280}
exceptions:
- {range: [0x7E0, 0x7E7], op: add, value: 0x8}
state: [0x600, 0x7FF] # region the tool may transmit into at all
session:
default: 0x01
extended: 0x03
probe_request: "1003" # probe used by `modules`
identify_without_session: true # ping with plain 22 F190 first
dids_without_session: [0xF190, 0xF187, 0xF188, 0xF189, 0xF191, 0xF132]
padding_byte: null # null = no explicit pad (ATCAF1 default)
stmin_ms: null
p2_timeout_ms: 40
conf: inferred
src: "repo-2021-baseline"
security:
sgw:
present: true
since_model_year: 2018
reads_pass: true
blocked_services: [0x14, 0x27, 0x2E, 0x31, "10 02"] # 10 02 = prog. session
bypass: "Chrysler 12+8 (Autel-style)"
write_path_enabled: false # hard gate; not data-overridable at runtime
services:
dtc_read: {sid: 0x19, subfunction: 0x02}
dtc_clear: {sid: 0x14, enabled: false}
read_did: {sid: 0x22}
5.3 Module inventory#
Presence and addressing are separate facts with separate confidence, because for many modules we know a module exists (bus + name) but not its address.
modules:
PCM:
name: PCM
aliases: [ECM, engine]
bus: can-c
presence: required
presence_conf: verified
addr: {req: 0x7E0, resp: 0x7E8, addr_conf: verified, src: opendbc}
did_sets: [iso14229-id, fca-id]
TCM:
name: TCM
aliases: [transmission]
bus: can-c
presence: required
presence_conf: verified
addr: {req: 0x7E1, resp: 0x7E9, addr_conf: verified, src: opendbc}
ABS:
name: ABS
aliases: [EBCM]
bus: can-c
presence: required
presence_conf: verified
addr: {req: 0x747, resp: 0x4C7, addr_conf: verified, src: opendbc}
ORC:
name: ORC
aliases: [SRS]
bus: can-c
presence: required
presence_conf: verified
addr: {req: 0x744, resp: 0x4C4, addr_conf: verified, src: opendbc}
IPC:
name: IPC
aliases: [combinationMeter, cluster]
bus: can-c
presence: required
presence_conf: verified
addr: {req: 0x742, resp: 0x4C2, addr_conf: verified, src: opendbc}
EPS:
name: EPS
bus: can-c
presence: required
presence_conf: verified
addr: {req: 0x75A, resp: 0x4DA, addr_conf: verified, src: opendbc}
FFCM:
name: FFCM
aliases: [fwdRadar, ACC radar]
bus: can-c
presence: optional
presence_conf: inferred
addr: {req: 0x753, resp: 0x4D3, addr_conf: verified, src: opendbc}
BCM:
name: BCM
bus: can-c
presence: required
presence_conf: verified
addr: null # unknown -> discover on vehicle
note: "Appcar lists BCM on BOTH CAN-C and CAN-IHS; treat the second
instance as a separate entry once its address is known."
HVAC:
name: HVAC
bus: can-ihs
presence: optional
presence_conf: verified
addr: null
PSDML:
name: PSDML
aliases: [power sliding door left]
bus: can-ihs
presence: optional
presence_conf: inferred
addr: null
# ... DDM, PDM, DMRL, DMRR, MSM, CSWM, PLGM, ICS, RADIO, TBM
# (can-ihs, addr null, presence inferred)
# ... RFH, ESM, SCCM, OCM, PTS, SGW (can-c, addr null, presence inferred)
A module with addr: null is not an error — it is a discovery instruction.
The scanner finds its ID by probing the range; the result is written back to the
local override layer (§6), which is how the map becomes self-improving.
5.4 DID databases#
dids:
inline: # small, portable, always available
F186: {name: "Active diagnostic session", type: u8, conf: standard}
F187: {name: "Spare part number", type: ascii, conf: verified}
F188: {name: "ECU software number", type: ascii, conf: verified}
F189: {name: "ECU software version", type: ascii, conf: verified}
F18A: {name: "System supplier identifier",type: ascii, conf: standard}
F18C: {name: "ECU serial number", type: ascii, conf: standard}
F190: {name: "VIN", type: ascii, len: 17, conf: verified}
F191: {name: "ECU hardware number", type: ascii, conf: verified}
F194: {name: "Supplier ECU software number", type: ascii, conf: standard}
F132: {name: "FCA identification/version", type: ascii, conf: inferred,
src: opendbc}
databases: # large, loadable, replaceable
- fca-ru-identification.yaml # keyed by ECU + software number
- fca-ru-livedata.yaml # proprietary DIDs + scaling (sparse!)
5.5 Example B — 2021 Pacifica Hybrid (delta over the gas profile)#
schema: pacifica-obd/vehicle-profile@1
profile_id: chrysler-pacifica-ru-2021-phev
title: "2021–2026 Chrysler Pacifica Hybrid (RU) — PHEV"
extends: chrysler-pacifica-ru-2021-gas # inherit everything, then delta
match:
powertrains: [phev]
require_any_module: [0x7E2] # HCP
exclude_any_module: [] # supersedes the gas profile's exclude
priority: 110
vehicle:
drive: [FWD] # PHEV is FWD-only
notes: "16 kWh pack; no Stow 'n Go; PHEV discontinued Jan 2026."
modules_add:
HCP:
name: HCP
aliases: [Hybrid Control Processor]
bus: can-c
presence: required
presence_conf: verified
addr: {req: 0x7E2, resp: 0x7EA, addr_conf: verified, src: opendbc}
AHCP:
name: AHCP
bus: can-c
presence: optional
presence_conf: inferred
addr: null
BPCM:
name: BPCM
aliases: [Battery Pack Control Module, BECM]
bus: can-c
presence: required
presence_conf: inferred
addr: null
OBCM:
name: OBCM
aliases: [On Board Charging Module]
bus: can-c
presence: required
presence_conf: inferred
addr: null
IDCM:
name: IDCM
aliases: [Integrated Dual Charger Module]
bus: can-c
presence: optional
presence_conf: inferred
addr: null
EAC:
name: EAC
aliases: [Electric A/C Compressor]
bus: can-c
presence: optional
presence_conf: inferred
addr: null
APM:
name: APM
aliases: [Accessory Power Module]
bus: can-c
presence: optional
presence_conf: inferred
addr: null
EBBM:
name: EBBM
aliases: [Electronic Brake Booster Module]
bus: can-c
presence: optional
presence_conf: inferred
addr: null
modules_remove: [TCM] # PHEV e-CVT is coordinated by the HCP;
# no TCM firmware observed at 0x7E1
modules_override:
ABS:
# on hybrids, ABS is queried at 0x7E4; 0x747 was not observed on PHEVs.
# Keep both: "not on all hybrid platforms" (opendbc).
addr: {req: 0x7E4, resp: 0x7EC, addr_conf: inferred, src: opendbc}
addr_alternatives:
- {req: 0x747, resp: 0x4C7, addr_conf: inferred, src: opendbc,
note: "gas address; probe as fallback"}
unverified:
- "Whether BPCM/OBCM/EAC/APM/EBBM are on CAN-C or a separate Hybrid LAN"
- "Whether the HCP is the only gateway to the remaining hybrid controllers"
- "Whether a standalone TCM exists on any PHEV year (none observed at 0x7E1)"
- "Whether ABS is at 0x7E4 or 0x747 on a given PHEV (opendbc: 'not on all')"
- "Whether 0x10 03 is accepted by PHEV controllers through the SGW"
Equivalent JSON is a direct encoding: yaml.safe_load ⇄ json.loads. Keep
YAML as the authoring format for comments and diffability, and load through a
single load_profile() that validates against a schema.
5.6 Resolved-profile output (what the tool should print)#
{
"selected_profile": "chrysler-pacifica-ru-2021-gas",
"match": {"vin": "<redacted>", "vin_hash": "<sha256>", "model_year": 2021,
"powertrain": "gas"},
"matched_by": ["vin.model_year", "positive_module:0x7E0", "negative_module:0x7E2"],
"confidence": "high",
"overrides_applied": ["profiles.d/2021-pacifica.local.yaml"],
"modules_expected": 24,
"modules_discovered": 21,
"modules_missing": ["TBM2", "MSMP", "VRM"],
"modules_unexpected": ["0x7D5"],
"open_questions": ["SGW acceptance of 0x10 03 unverified on this VIN"]
}
modules_missing and modules_unexpected are the feedback loop: missing
required modules usually mean a trim/equipment difference, a wrong profile, or a
bus fault (see the star-connector note); unexpected responders usually mean a
module the map does not know yet.
5.7 Relation to the current profiles.py#
A first cut of this design already exists in
src/pacifica_obd/profiles.py, and its
docstring points here for the full analysis. It defines a frozen
VehicleProfile dataclass (id, make, model, years, powertrain, platform,
module_buses, info_dids, notes), two instances (RU_GAS, RU_PHEV),
year_from_vin() and a best-effort resolve(), and uds.py now owns
BUS_PROTOCOL, DID_NAMES and INFO_DIDS. That is the right shape — the YAML
above is its evolution, not a replacement. Mapping:
| Proposed (this doc) | Today in profiles.py |
|---|---|
profile_id, models, model_years |
id, model, years (flat tuple) |
match.powertrains |
powertrain |
buses.* |
implicit in uds.BUS_PROTOCOL |
addressing.response_rule |
absent |
modules.*.addr.{req,resp} |
absent — module_buses is bus-only |
modules.*.presence + presence_conf |
absent — every listed module is assumed present |
dids.inline / databases |
info_dids (falls back to uds.INFO_DIDS) |
security.sgw |
free text in notes |
extends / modules_add / modules_override |
absent (no inheritance) |
conf / src / verified_by |
absent |
Gaps this research surfaces#
These are concrete, evidence-backed divergences — worth fixing whether or not the richer schema lands:
| Where | Issue | Evidence |
|---|---|---|
RU_GAS.years / RU_PHEV.years |
Stop at 2024; the RU platform runs to 2027 (PHEV to 2026). _VIN_YEAR_CODES also omits V = 2027. |
Wikipedia, Appcar (2017–2026) |
_COMMON_CAN_C |
Includes HCP and EAC, which are PHEV-only — so the gas profile currently claims them. |
Appcar hybrid group; opendbc hybrid @ 0x7E2 |
_PHEV_CAN_C |
Missing IDCM and EBBM; no place to express that PHEV ABS is 0x7E4, or that no TCM answers at 0x7E1. |
Appcar, opendbc |
resolve() / applies() |
With powertrain=None the guard short-circuits and RU_GAS always wins (it is first in all_profiles()), so an unknown-powertrain 2021 PHEV silently resolves to gas. Powertrain should be discovered (probe 0x7E2), not assumed. |
§6.1 step 4 |
model_buses |
Model names are Pacifica-only; the Voyager and Grand Caravan are the same RU vehicle with a thinner equipment mix. | Wikipedia |
applies() / platform |
platform is stored but never checked, and model/VIN WMI/VDS are not matched. |
— |
notes |
SGW is prose only; the tool cannot tell a user why a clear was refused. | §3.6 |
An honest read of the current code against this doc: the selection skeleton is right, the addressing and evidence layers are the missing pieces, and the year span is simply out of date.
6. Profile selection, uncertainty, and overrides#
6.1 Selection algorithm#
1. Read VIN (mode 09 PID 02, falling back to UDS 22 F190 on PCM @7E0).
2. Decode: WMI(1-3) VDS(4-8) check(9) year-code(10) plant(11) serial(12-17).
Year codes: 2017=H 2018=J 2019=K 2020=L 2021=M 2022=N
2023=P 2024=R 2025=S 2026=T 2027=V (I,O,Q,U,Z unused)
3. Filter candidate profiles: platform(WMI/VDS) ∩ model_year ∈ model_years.
4. Disambiguate powertrain by *evidence*, not by badge:
- probe 0x7E2 (HCP) on CAN-C with a plain 22 F194
- probe 0x7E0 (PCM) likewise
- a responding 0x7E2 selects the PHEV profile
5. Resolve inheritance: apply `extends` chains; later deltas win;
`modules_add` unions, `modules_override` patches, `exclude_any_module`
eliminates non-matching candidates.
6. Scan both buses over `addressing.scan_range` with `session.probe_request`.
7. Reconcile discovery against the profile -> resolved profile (§5.6).
8. Persist profile_id, VIN-derived keys, discovery set and any overrides.
Step 4 is deliberately discovery-based: year + powertrain from VIN/badge is a guess about equipment, and equipment is the thing that actually determines which modules answer. VIN narrows the search; the bus settles it.
6.2 How uncertainty is recorded#
Four confidence levels, on every fact, attached to every assertion:
conf |
Meaning | Trust |
|---|---|---|
standard |
ISO 14229 / ISO 15765 / OBD-II | High, year-independent |
verified |
Observed in a public vehicle-derived dataset or on our own van | Use directly |
inferred |
Derived from a vendor list / forum / manual; plausible, untested | Use, but flag |
unknown |
Placeholder; requires discovery (addr: null) |
Probe, never assume |
Plus provenance: every fact may carry src (URL or dataset id) and, for
vehicle-observed facts, verified_by (VIN hash + date). Repo rules already say
not to commit VINs — so store a hash, or just {date, note}, never the VIN.
Never silently widen a query because a fact is unknown. An unknown address means "probe", not "send to a broad range and hope".
6.3 Override mechanism#
Layered, lowest priority first:
built-in profiles/*.yaml (shipped, read-only)
$PACIFICA_OBD_HOME/profiles.d/*.yaml (user, merged in filename order)
CLI flags (per-invocation, highest)
Deliberately narrow CLI overrides, each of which is recorded:
uv run pacifica-obd profile show # resolved profile + provenance
uv run pacifica-obd profile select --vin <VIN> # or --year 2022 --powertrain phev
uv run pacifica-obd modules --bus both --profile chrysler-pacifica-ru-2017-gas
uv run pacifica-obd modules --bus can-c --assume-module 7D5=unknown-new-ecu
uv run pacifica-obd read-did --module 744 --did F132 --bus can-c
uv run pacifica-obd modules --bus both --record-addresses # write-back discoveries
Rules for overrides (they are safety-relevant, not cosmetics):
- Overrides may add or narrow; they may not silently widen a transmit range.
security.write_path_enabledand all write services are not overridable by profile data. Writes stay behind explicit user intent, perAGENTS.md.- Every override is appended to
events.jsonlwith its origin, and the session row records which profiles were in force. - A discovered address that contradicts a
verifiedentry is recorded as a conflict, surfaced to the user, and not auto-applied. --record-addresseswrites toprofiles.d/, never to the shipped profiles.
7. How to verify with a real car#
Run this against each vehicle before claiming support. Record results in the local store (never in the repo — VINs and captures stay out of git).
Pre-flight#
- [ ]
uv run pacifica-obd portsfinds the adapter;raw ATI/raw STIconfirmsSTN1170 v4.3.2or better. - [ ] Battery healthy:
raw ATRV≥ 12.0 V (12.4–12.6 V ideal). Low voltage causes flaky negative responses and false "no module" results. - [ ] Ignition ON, engine OFF (steady state; not during a keep-alive cycle).
- [ ] Snapshot VIN + record the model year, trim, and gas/PHEV locally.
- [ ] Identify whether an SGW is fitted (2018+ should be). Determine whether a 12+8 bypass is installed; note which connectors are in the adaptor path.
- [ ] Freeze the vehicle: no doors/hatch being cycled, HVAC off, no charging session on a PHEV (a charging PHEV will be busy and may NRC).
Bus sanity#
- [ ]
STP 33→STPRSreports HS CAN 500K/11-bit (CAN-C). - [ ]
STP 53→STPRSreports MS CAN 125K/11-bit (CAN-IHS). - [ ] Functional broadcast works:
ATSH 7DF+0100returns at least the PCM's41 00 …supported-PID bitmask. This proves the physical layer before any UDS work. - [ ] Restore the protocol snapshot afterwards (never
ATSP; never persist EEPROM).
Module discovery#
- [ ]
modules --bus can-c --identifyandmodules --bus can-ihs --identify. - [ ] Confirm each verified address in §3.3 answers on CAN-C:
7E0→7E8,7E1→7E9,742→4C2,744→4C4,747→4C7,753→4D3,75A→4DA. The4xxresponses are the acid test of the−0x280rule. - [ ] Confirm the BCM's request ID (currently
addr: null) and record it. - [ ] Confirm which CAN-IHS modules answer and record their IDs.
- [ ] Note responders outside the profile's expected list.
Per-module UDS behaviour#
For each responder, record:
- [ ]
10 03(extended session) →50 03, or NRC. This is the key unknown: does the SGW pass session control on the stock port? - [ ]
22 F190in the default session → VIN (tests session-free reads). - [ ]
22 F187,22 F188,22 F189,22 F191,22 F194, and22 F132. - [ ]
19 02(report DTCs by status mask) →59 02 …; also try19 01and19 0Aif19 02is refused. - [ ] Record the response ID actually used, and the request→response delta.
- [ ] Classify every NRC seen:
11service not supported ·12subfunction not supported ·13incorrect length ·22conditions not correct ·31request out of range ·33security access denied ·7Esubfunction not supported in active session ·7Fservice not supported in active session ·78response pending. - [ ] Note whether padding beyond the payload was required, and any multi-frame timing problems (missing/incomplete consecutive frames).
PHEV-only#
- [ ] Does
0x7E2(HCP) answer? Does0x7E4(alternate ABS) answer? - [ ] Which of BPCM / OBCM / IDCM / EAC / APM / EBBM / AHCP answer, and on which bus? This settles the "Hybrid LAN" question.
- [ ] Repeat with the charge cable disconnected (and, if safe, once charging) to see whether the HV system's state changes reachability.
Ground truth#
- [ ] Scan the same vehicle with Appcar DiagFCA on the same day and diff the module list against ours. Any module they see and we do not is a bug in our map, our addressing rule, or our probe.
- [ ] Save the resolved profile (§5.6) alongside the diff as evidence.
Coverage sweep#
- [ ] Run the above on as many of these as can be reached, in this order: 2021 gas (baseline) → 2021+ PHEV → 2017 gas (no SGW) → 2018–2020 → 2025/2026 → 2027 refresh.
- [ ] For each, explicitly record:
10 03accepted? SGW blocks reads? module count on each bus? PHEV controllers found?
8. Recommendations#
- Keep the transport and framing layers untouched.
elm.pyplus the ISO-TP/frame-reassembly code now inuds.py(parse_uds_frame) are already vehicle-agnostic, already accept 11-bit and 8-hex (29-bit) headers, and already enforce correct classic-CAN framing. - Finish extracting the remaining constants.
BUS_PROTOCOL,DID_NAMESandINFO_DIDShave already moved intouds.py; what is still hardcoded is the0x700–0x7FFscan range and the10 03probe inprobe_ids/cli.py. Those belong on the profile next tomodule_buses. - Make addressing rule-based, not arithmetic.
−0x280by default,+8for7E0–7E7, and a place for 29-bit later. This alone is what makes the existing scanner correct on these vans. - Separate presence from addressing, with independent confidence. Most of the module map is known-but-unaddressed.
- Build on the existing
RU_GAS/RU_PHEVsplit rather than replacing it, and add the PHEV delta (dropTCM, moveABSto0x7E4, addIDCM/EBBM, removeHCP/EACfrom the gas list) as the first realextendscase. - Add
0xF132to_INFO_DIDS— it is a cheap, FCA-specific cross-check already observed on these ECUs (mark it non-standard in the DID map). - Do not chase writes. The SGW gates them from 2018; the 2017 path being open makes writes more dangerous, not more attractive.
9. Open questions#
- Does the SGW pass UDS
0x10 03on the stock port? If not, themodulesprobe strategy (extended session) may need a session-free fallback (22 F194/22 F132) — which opendbc's usage suggests is viable. This is the highest-impact unknown in the whole plan. - Is there really a third "Hybrid LAN" bus? Appcar groups hybrid ECUs that way; no confirmed DLC-reachable third bus has been found. If it exists and is not on 3/11 or 6/14, the STN1170 alone may not reach it.
- Exactly how does the PHEV address map differ? Evidence says no TCM at
0x7E1and ABS at0x7E4rather than0x747— but "not on all hybrid platforms" leaves room for year-to-year variation. Probe both, record which answered. - BCM, RFH, ESM, SCCM, OCM, PTS, and the whole CAN-IHS set have no public
request/response IDs. All are
addr: nulltoday. This is discovery work. - No public year-by-year DID matrix. Year-specific DIDs, especially live data and adaptations, remain the gap that keeps this tool behind manufacturer-aware tools.
- VIN → platform mapping is assumed, not verified.
2C4(Windsor) is plausible for all three nameplates but has not been confirmed against a VIN decoder, and Voyager/Grand Caravan may use different WMI/VDS patterns. - Does the 2027 refresh change anything electrical? Reported as cosmetic (V6 retained), but no diagnostic architecture information found.
- Canada/US/Mexico market differences in module content (e.g. MY2021 Grand Caravan shipped Uconnect 4, 7-inch rather than Uconnect 5) mean the TBM and infotainment modules will differ across nameplates of the same model year. Infotainment is a profile boundary, not a platform boundary.
- What NRC/behaviour does a PHEV give while charging? Untested; may make PHEV scans state-dependent.
Sources#
Vehicle / platform - Chrysler Pacifica (minivan) — RU platform, Voyager & Grand Caravan badging, 2021 refresh (Uconnect 5), 2027 refresh: https://en.wikipedia.org/wiki/Chrysler_Pacifica_(minivan) - Appcar DiagFCA — Chrysler Pacifica (RU) 2017–2026: full module list, CAN-C/CAN-IHS, 2018+ SGW, hybrid LAN grouping: https://appcar-diagfca.com/en/supported-vehicles/chrysler-pacifica/ - Appcar DiagFCA — How it works: SGW since MY2018, CAN-C pins 6/14, CAN-IHS pins 3/11, STN1170/2120/2230/2231 support both buses: https://appcar-diagfca.com/en/how-it-works/ - JScan — FCA Security Gateway: introduced 2018, "some models in the 2018 model year and all models 2019 going forward"; bypass needed for writes only: https://jscan.net/fca-security-gateway-module-basic-info-and-location/ - FCA / Stellantis — Uconnect 5 press release: "The Atlantis architecture replaces Powernet as the next generation of FCA core in-vehicle electronics communication"; debut on the 2021 Pacifica: https://www.prnewswire.com/news-releases/fcas-all-new-uconnect-5-global-platform-is-the-most-advanced-uconnect-system-ever-powerful-personalized-connected-and-easy-to-use-300993133.html - Stellantis Media — Uconnect 5 "What's New" (Atlantis vs Powernet wording): https://media.fcanorthamerica.com/newsrelease.do?id=21511&mid=102 - Mopar Insiders — Uconnect 5 / Atlantis architecture detail: https://moparinsiders.com/podcast-we-dig-deeper-uconnect-5-infotainment-system - OBD Genie — SGW bypass location, "2018 and newer Chrysler Pacifica and 2020 and newer Chrysler Voyager": https://www.youtube.com/watch?v=wq_q_32UXhE - AE Tools — SGW overview and per-vehicle locations: https://knowledgebase.aetools.us/how-to-get-past-the-gateway-on-chrysler-vehicles-using-autel
Diagnostic addresses, DIDs and behaviour
- comma.ai opendbc — Chrysler values: CHRYSLER_RX_OFFSET = −0x280, non-standard FCA identification DID 0xF132, supplier software DID 0xF194, alternate hybrid ABS 0x7E4, ECU whitelists: https://github.com/commaai/opendbc/blob/master/opendbc/car/chrysler/values.py
- comma.ai opendbc — Chrysler fingerprints: per-model-year ECU request IDs (742, 744, 747, 753, 75A, 7E0, 7E1, 7E2, 761; 29-bit on Jeep Cherokee 5th gen): https://github.com/commaai/opendbc/blob/master/opendbc/car/chrysler/fingerprints.py
- NHTSA — factory vehicle scan report (2020 Pacifica PHEV), module/bus inventory: https://static.nhtsa.gov/odi/inv/2022/INRD-PE22008-13852P1.pdf
- NHTSA TSB — BPCM diagnostic/reprogramming (HCP ↔ BPCM lost-communication codes): https://static.nhtsa.gov/odi/tsbs/2023/MC-10248015-9999.pdf
- NHTSA TSB — transmission update requiring PCM + HCP + AHCP (PIM) + BPCM to be flashed together: https://static.nhtsa.gov/odi/tsbs/2022/MC-10214604-9999.pdf
- go-parts — P2797 on 2017–2019 Pacifica PHEV: HCP / AHCP software: https://www.go-parts.com/garage/obd-p2797-chrysler-pacifica-hybrid-2017-2019-phev
- go-parts — U0594 HCP data fault on 2017–2018 Pacifica PHEV (BPCM software): https://www.go-parts.com/garage/obd-u0594-chrysler-pacifica-plug-in-hybrid-2017-2018
- go-parts — B1498 on 2021–2026 Pacifica: Uconnect 5's dedicated Telematics Box Module (TBM): https://www.go-parts.com/garage/obd-b1498-chrysler-pacifica-2021-2026
- go-parts — U0001 HS CAN fault on 2017–2018 Pacifica: https://www.go-parts.com/garage/obd-u0001-chrysler-pacifica-2017-2018
- Pacifica Forums — CAN-C / CAN-IHS star-connector failure (module drop-out): https://www.pacificaforums.com/threads/failed-can-bus-star-connector-2017-hybrid.53931
- CSS Electronics — UDS tutorial (physical vs functional addressing, +8 pairing convention): https://www.csselectronics.com/pages/uds-protocol-tutorial-unified-diagnostic-services
Tool landscape - FORScan — "Vehicles other than Ford, Mazda, Lincoln, Mercury are not supported!": https://forscan.org/home.html
In-repo references
- src/pacifica_obd/profiles.py — current VehicleProfile dataclass, RU_GAS/RU_PHEV, year_from_vin(), resolve()
- src/pacifica_obd/uds.py — BUS_PROTOCOL, DID_NAMES, INFO_DIDS, parse_uds_frame, probe_ids
- docs/enhanced-diagnostics.md — module map, feasibility matrix, data sources, P0–P6
- docs/chrysler-sgw.md — SGW behaviour, 12+8 bypass, tool comparison
- AGENTS.md — adapter facts, protocol presets, safety rules