BEANalyzer UltraPro 5 · Technical Guide

How to design
BEAN-DBC definitions.

Learn how BEANalyzer UltraPro 5 describes Toyota/Lexus BEAN MPX messages, signals, formulas, evidence, transmission templates and Lab Workbench controls using its project-specific JSON format.

CURRENT IMPLEMENTATION

BEAN-DBC is not a CAN Vector DBC.

BEAN-DBC is BEANalyzer's own JSON database format. It identifies BEAN messages, describes signals inside DATA, applies safe decoding formulas, records evidence and can define transmission templates.

DID + MIDBase message identity
offsetStarts at DATA0
formulaRAW → physical value
workbenchPhysical value → TX RAW
01 The format

What BEAN-DBC actually is

BEAN-DBC is a project-specific JSON database used by BEANalyzer UltraPro 5. It is conceptually inspired by the role of a DBC, but it is not a standard Vector CAN .dbc file.

The application normally uses a JSON database such as config/bean_dbc_default.json. A BEAN-DBC file can identify messages, assign names, describe signals, define formulas and units, preserve engineering metadata and evidence, and optionally provide transmission templates for Lab Workbench.

Core rule

Do not force CAN DBC assumptions onto BEAN-DBC. Treat the BEANalyzer implementation and JSON schema described here as the authority.

Minimal functional database
{
  "name": "My BEAN Database",
  "version": "1.0",
  "description": "Minimal example",
  "plausible_dids": ["FE"],
  "messages": [
    {
      "name": "Vehicle speed",
      "did": "FE",
      "mid": "24",
      "category": "vehicle",
      "function": "vehicle_speed",
      "doc_status": "EXPERIMENTAL",
      "signals": [
        {
          "name": "speed",
          "kind": "u8",
          "offset": 0,
          "unit": "km/h"
        }
      ]
    }
  ]
}
02 BEAN frame anatomy

Find DATA before you define signals

A captured physical frame can include interface/SOF marker, BEAN header/context, DID, MID, DATA, CRC, EOM and a post-EOM response byte. BEANalyzer separates these fields before giving DATA to the decoder when the physical frame validates correctly.

01A3FE1F40027E40
MarkerContextDIDMIDDATA0CRCEOMRSP/EOF
The most common offset mistake

offset begins at DATA, not at the first captured byte. In the frame above, DATA[0] = 0x40, so a signal in that byte uses "offset": 0.

The BEAN header used by BEANalyzer combines priority and ML. Conceptually, bits 7..4 are priority and bits 3..0 are ML. ML counts DID + MID + DATA, therefore DATA length = ML - 2. The current implementation treats ML 3..13 as the normal range, giving 1..11 DATA bytes.

03 Top-level JSON

Keep the database simple and explicit

The two most important top-level elements for decoding are plausible_dids and messages. Metadata such as name, version, description and notes makes the file understandable and traceable.

plausible_dids

Used when a message definition does not declare a fixed DID. If the DID is already known, define it explicitly to reduce false matches.

messages

The central array. Each object represents one BEAN message interpretation, including its identity, signals, evidence and optional TX templates.

JSON rules still apply

Use double-quoted strings, no trailing comma on the final item, and no // or /* */ comments. Put engineering notes in real fields such as notes.

04 Message matching

DID + MID is the base identity. Context can disambiguate it.

A message normally declares hexadecimal did and mid strings. The same DID/MID pair can still mean different things under different BEAN headers, so BEANalyzer also supports context, header or bean_header as equivalent context declarations.

1Exact context + DID + MID match
→
2Generic DID + MID definition if no exact context exists

Use descriptive metadata such as category, function, source, source_ecu, doc_status, example, notes and references. These fields are valuable even when they do not participate directly in decoding.

CONFIRMED BY MANUFACTURERCONFIRMED IN VEHICLECONFIRMED BY CAPTURECONFIRMED BY WORKING CODECORROBORATEDEXPERIMENTALHYPOTHESISPENDING VALIDATIONUNKNOWN
05 Signal definitions

Choose the signal kind that matches the data

Each item in signals describes how to interpret one or more bytes inside DATA. The current decoder supports the following signal kinds.

kindUse it forKey fields
u8Unsigned single-byte valueoffset, optional formula
u16beTwo-byte big-endian valueoffset, optional formula
boolOne specific bitoffset + hex mask
bool_exprBoolean state requiring an expressionoffset + formula
flagsIndependent bits sharing one byteflags map
mapMutually exclusive enumerated valuesmap object
constantThe message presence is itself meaningfulvalue

map is recommended for new enumerations; the decoder also keeps compatibility with the historical values form. A bool mask is hexadecimal: 01, 02, 04, 08, 10, 20, 40, 80.

unit, card, plot

Use unit for the physical unit, card to associate a dashboard card, and plot: true when the signal is a candidate for graphing.

special_values

Use named exceptional raw values only with the behavior supported by the current decoder. At present, the documented path applies them to u8 signals with a formula; test this pattern before extending it.

Do not invent signal types

The current route does not natively provide u16le, s8, s16 or float32. Extend the decoder explicitly when the real data requires a new type.

06 Decoding math

formula transforms RAW into the physical value

For numeric signals, raw is the value extracted before conversion. A formula such as raw / 5.12 turns the stored integer into the value shown by BEANalyzer.

raw / 10.0Division
raw * 0.01Scaling
raw - 48Offset
raw * 0.5 + 16Scale + offset

The formula evaluator is intentionally restricted rather than executing arbitrary Python. It supports arithmetic, bitwise operators, comparisons, boolean logic, the Python ternary expression, variables raw and data, functions len, min, max, abs, round, and allowed public math functions/constants after validation.

You can access other DATA bytes with constant indices such as data[2]. Protect variable-length frames, for example: (raw + data[2]) / 2 if len(data) > 2 else raw.

Formula failure can look deceptively valid

For u8 and u16be, the current implementation falls back to RAW if formula evaluation fails. Always test known input/output examples.

07 Practical patterns

Three patterns cover a lot of real work

Vehicle speed — one-byte value
{
  "name": "Vehicle speed",
  "did": "FE",
  "mid": "24",
  "category": "vehicle",
  "function": "vehicle_speed",
  "signals": [
    {
      "name": "speed",
      "kind": "u8",
      "offset": 0,
      "unit": "km/h",
      "card": "speed",
      "plot": true
    }
  ]
}

If DATA0 is 0x3C, u8 produces decimal 60, so the value is 60 km/h.

Engine RPM — two-byte big-endian + formula
{
  "name": "Engine RPM",
  "did": "FE",
  "mid": "26",
  "category": "engine",
  "function": "tachometer_rpm",
  "signals": [
    {
      "name": "rpm",
      "kind": "u16be",
      "offset": 0,
      "formula": "raw / 5.12",
      "unit": "rpm",
      "card": "rpm",
      "plot": true
    }
  ]
}

With DATA 0D E1, RAW is 0x0DE1 = 3553, therefore 3553 / 5.12 ≈ 694 rpm.

Lighting mode — map + derived boolean
{
  "name": "Light switch position",
  "context": "A3",
  "did": "FE",
  "mid": "1E",
  "category": "body_lighting",
  "signals": [
    {
      "name": "light_switch_mode",
      "kind": "map",
      "offset": 0,
      "map": {
        "00": "OFF",
        "02": "POSITION",
        "03": "LOW_BEAM",
        "04": "AUTO"
      }
    },
    {
      "name": "low_beam_switch",
      "kind": "bool_expr",
      "offset": 0,
      "formula": "raw == 0x03"
    }
  ]
}

Multiple signals may intentionally read the same DATA byte: keep the RAW view, a friendly enumeration and derived states when that helps analysis.

08 Transmission

Keep RX knowledge separate from TX knowledge

A BEAN-DBC can include tx_templates, but a received DID/MID never proves the correct transmit payload. BEANalyzer prefers bridge_payload; historical payload and bytes forms are fallback inputs.

Transmission template
"tx_templates": [
  {
    "name": "Light switch POSITION reference",
    "bridge_payload": "62 1E 02",
    "reset_payload": "62 1E 00",
    "notes": "EXPERIMENTAL — validate before use"
  }
]

bridge_payload

The preferred logical payload sent by the bridge, for example 62 26 0D E1. It is not a complete physical capture.

low_level_payload

Can preserve a logical low-level DST + MID + DATA reference separately from the validated bridge route.

reset_payload defines a neutral/release message for momentary controls. The complete physical capture — marker, header, CRC, EOM and post-EOM response — must never be pasted into bridge_payload.

Workbench runtime actions such as Send Once, Pulse, Periodic and Repeat Times are not the basic message-definition schema. The BEAN-DBC describes the message/template; Workbench decides how it is exercised at runtime.

RX CONFIRMED ≠ TX CONFIRMED

The receiver may require wake-up state, keep-alives, timing, bursts or another destination/prefix. Mark candidate TX templates as experimental until tested.

09 Lab Workbench

Decode in one direction. Encode in the other.

Lab Workbench can construct controls from BEAN-DBC metadata: boolean signals can become checkboxes, flags become multiple checkboxes, maps become selections, numeric signals become sliders, and control: "dial" can request dial-like behavior.

Explicit Workbench encoder
{
  "name": "rpm",
  "kind": "u16be",
  "offset": 0,
  "formula": "raw / 5.12",
  "unit": "rpm",
  "workbench": {
    "control": "dial",
    "value_min": 0,
    "value_max": 8000,
    "value_step": 1,
    "encode": {
      "type": "linear",
      "raw_scale": 5.12,
      "raw_offset": 0
    }
  }
}
Decodephysical = raw / 5.12
⇄
Encoderaw = physical × 5.12

Workbench may derive an inverse automatically only when it can prove an affine relationship decoded = a × raw + b. Bitfields, comparisons, saturation, formulas using other bytes and other non-linear expressions must stay RAW or use explicit encoding metadata.

10 Engineering method

Start RAW. Promote meaning only with evidence.

  1. Capture RAW.Create a conservative u8 view before assigning semantics.
  2. Form a hypothesis.Add candidate bits, masks or enumerations while keeping the status explicit.
  3. Repeat controlled tests.Compare states, transitions, events and multiple captures.
  4. Rename only when justified.Do not turn correlation into confirmation silently.
  5. Add TX last.Only after a real or clearly experimental transmission route exists.

For documented work, prefer explicit DID, use uppercase two-digit hexadecimal strings, keep context-specific interpretations separate, and record what remains unknown in notes.

Metadata can serve layers beyond decoding

Fields such as source, source_ecu, function, category, references, notes and optional gateway metadata may support UI, search, documentation or CAN-gateway planning without changing the basic decoded value.

11 Before publishing

Production checklist

Validate JSON syntax before loading it: python3 -m json.tool bean_dbc_custom.json > /dev/null
Prefer a browser tool?

Use the Hub's JSON Syntax Verifier to paste JSON or read a local file directly in your browser. The draft is not uploaded to the server.

12 Reusable starting point

Begin conservatively, then add evidence

This template intentionally starts with one RAW byte and a pending-validation status. Remove context if the message truly is generic. Do not add tx_templates until TX evidence exists.

Message starter template
{
  "name": "MESSAGE NAME",
  "context": "A3",
  "did": "FE",
  "mid": "00",
  "category": "unknown",
  "function": "unknown_function",
  "source": "Unknown",
  "source_ecu": "Unknown",
  "doc_status": "PENDING VALIDATION",
  "example": "FE 00 00",
  "notes": [
    "Explain what was observed.",
    "Explain what remains unknown."
  ],
  "references": [
    "Capture / document / test source"
  ],
  "signals": [
    {
      "name": "data0_raw",
      "kind": "u8",
      "offset": 0,
      "unit": "raw"
    }
  ]
}
13 Current implementation limits

Document what the decoder supports — not what BEAN could theoretically support

No CAN DBC parserBEAN-DBC remains a project-specific JSON format.
No native u16leDo not pretend big-endian matches little-endian data.
No native signed integer kindsUse a safe formula when viable or extend the decoder.
Not every formula is invertibleWorkbench needs explicit encoding for complex cases.
TX cannot be inferred from RXKeep transmission evidence independent.
Context and vehicle matterSemantics may differ across Toyota/Lexus implementations.
Final engineering rule

Every BEAN-DBC entry should let another engineer reconstruct what the message is, which bytes are DATA, what each signal means, how it is transformed, what evidence supports it, how TX differs from RX, how Workbench controls it, and what remains unconfirmed.