i99dash docs
Reference

Trim × capability matrix

What every BYD trim seeds in `VehicleCapability` by default, plus the per-sub-trim action-support entries that aren't visible in the cap bitmask.

What features each BYD trim ships by default, before any empirical probe data lands. The matrix is the host's compiled-in seed (CarProfileSeed) — it's what the resolver returns at Tier 5 of the fallback chain when the backend overlay can't answer.

This is what your mini-app sees on a fresh install on a never- probed car. Once the CapabilityProber ships and starts feeding the backend overlay, the empirical set may be a strict superset on cars where probes confirm something the seed didn't grant.

Capability bitmask coverage

Columns are abbreviated forms of VEHICLE_CAPABILITIES. Rows are (variantId, subTrim). ✓ = bit set in seed; — = bit not set. Cells reflect the seed in CarProfileSeed.staticSeed().

Trimdisplay.readpkg.readlaunch.ivilaunch.passengerlaunch.cluster.pixellaunch.cluster.iconslaunch.disharesurface.ivisurface.passengersurface.clustercursor.writegesture.dispatchac.getac.setdoor.setwindow.set
L8 base
L5L lidar
L5 flagship
L5 navigator
L5 ultra
L5U (Leopard 5 Ultra trim of L5U variant)
L7 base
HAN L base
Generic / unknown

Reading the matrix

  • Cluster pixel rendering (launch.cluster.pixel + surface.cluster) is L8 + L5L only. Every other trim has the cluster panel daemon-locked at the firmware level. See byd/l5/dlink-unit/Driver Cluster/STATUS.md for the empirical evidence on Leopard 5.
  • Cluster icons (launch.cluster.icons) is L5 family only (L5, L5U, L5L). The MCU mux exposed via IAutoContainer.sendInfo lets us toggle theme / day-night / ADAS visibility on the cluster even when pixel control is denied.
  • DiShare (launch.dishare) is Di5.0 only (L5, L5U). On Di5.0 the passenger panel isn't reachable via am start --display N — DiShare's mirror chain is the only non-root path.
  • surface.write.passenger is excluded for Di5.0 trims even though they have pkg.launch.passenger — DiShare casts an existing activity, it can't host the host's WebView surface.
  • Generic / unknown falls through to a conservative IVI-only seed. A car identified only by its DiLink generation gets one of the trim-specific seeds via the tier-4 DiLink-default fallback.

Per-action support (CarGate)

Beyond the capability bitmask, the host's CarCommandRouter consults a per-action support map (CarActionSupport) to short-circuit known-bad calls before the rate-limit + bridge round-trip. Mini-apps don't read this map directly — it's what makes a tap on an unsupported actuator return code: ACTION_UNSUPPORTED in <1 ms.

The static seeds:

TrimKnown-UNSUPPORTED actions
L5 navigatorset_seat_massage, set_seat_heat, set_hud_brightness
L5 ultraset_seat_massage
L5 flagship(none — full feature set)
L5 lidar(none — full L5L feature set)
L8 base(none)
L7 baseset_hud_brightness
HAN L base(none)

Anything not listed defaults to UNKNOWN_ASSUME_SUPPORTED — the router proceeds and lets the daemon stay the authority. The probe

  • Quick Report loop refines the map over time.

Action-class fallback strategy

When profile.isFallback === true (the resolver fell back to a sub-trim / trim / DiLink aggregate), the CarGate's strict deny is disabled and actions are tried with the daemon as authority. Within that "try" mode, actions are still classified to drive the UX:

ClassActionsTier-5 unknown behaviour
BASIClock_door, unlock_door, set_ac_*, set_window_positionTry silently — these are universal, the daemon will catch a bad fit.
CRITICALset_sunroof, fold_mirrors, open_hood, open_trunk_motorPre-deny — even a probe attempt could fail loud on bad actuator wiring.
ADVANCEDeverything else (set_seat_massage, set_hud_brightness, …)Try with a "best-effort" warning surfaced to the user.

The classification lives in CarActionSupport.classOf.

Display topology by trim

For pickers that show a per-display chip, here's what display.list typically returns by trim. The IDs are unstable across firmware updates — use role / clusterAvailable flags, not raw IDs.

TrimIVIPassengerCluster slots
L8id=0 iviid=2 fseid=3 base, id=4 _0 (contested), id=5 _1 (friendly)
L5Lid=0 iviid=2 fseid=3 base, id=4 _0 (contested), id=5 _1 (friendly)
L5 / L5Uid=0 ivi(none addressable directly)id=2 fission_bg_XDJAScreenProjection (daemon-locked)
L7id=0 iviid=2 fseid=4 (clusterAvailable: false — vendor-locked)
HAN Lid=0 iviid=2 fseid=4 (clusterAvailable: false)

hidden: true flags on shadow / mirror displays (display 3 on L8 mirrors display 5) keep them out of default pickers — see the multi-display guide.

Fields you can rely on per trim

For mini-apps that want to render trim-aware UX (header strings, trim-specific affordances), here's what the vehicle block of display.list carries on each trim:

// L8
{ dilinkFamily: 'di5.1', variantId: 'l8', subTrim: 'base',
  friendlyName: 'Leopard 8' }

// L5 Flagship (when sub-trim detection succeeds)
{ dilinkFamily: 'di5.0', variantId: 'l5', subTrim: 'flagship',
  friendlyName: 'Leopard 5 Flagship' }

// L5 anything (when sub-trim detection misses)
{ dilinkFamily: 'di5.0', variantId: 'l5', subTrim: '',
  friendlyName: 'Leopard 5',
  isFallback: true, fallbackReason: 'unknown_sub_trim' }

// Unidentified BYD on Di5.1
{ dilinkFamily: 'di5.1', variantId: '', subTrim: '',
  friendlyName: 'Generic BYD DiLink',
  isFallback: true, fallbackReason: 'unknown_variant' }

How to keep this page accurate

The matrix is hand-maintained alongside the seed code. When adding a new trim or capability:

  1. Update CarProfileSeed.staticSeed() (Kotlin host).
  2. Update CarActionSupport.SEED if the trim has known UNSUPPORTED actions.
  3. Append a row / column to the matrix above and to the per-action table.
  4. Run the SDK's node scripts/check-capability-drift.mjs to confirm the taxonomy is in sync across all four mirrors.

On this page