can-dbc-matrix

v1.0.0

Automation skill for can-dbc-matrix.

0· 90·0 current·0 all-time
byfrankie@frankie-zeng

Install

OpenClaw Prompt Flow

Install with OpenClaw

Best for remote or guided setup. Copy the exact prompt, then paste it into OpenClaw for frankie-zeng/can-dbc-matrix.

Previewing Install & Setup.
Prompt PreviewInstall & Setup
Install the skill "can-dbc-matrix" (frankie-zeng/can-dbc-matrix) from ClawHub.
Skill page: https://clawhub.ai/frankie-zeng/can-dbc-matrix
Keep the work scoped to this skill only.
After install, inspect the skill metadata and help me finish setup.
Use only the metadata you can verify from ClawHub; do not invent missing requirements.
Ask before making any broader environment changes.

Command Line

CLI Commands

Use the direct CLI path if you want to install manually and keep every step visible.

OpenClaw CLI

Bare skill slug

openclaw skills install can-dbc-matrix

ClawHub CLI

Package manager switcher

npx clawhub@latest install can-dbc-matrix
Security Scan
VirusTotalVirusTotal
Pending
View report →
OpenClawOpenClaw
Benign
high confidence
Purpose & Capability
The name/description and the SKILL.md align: the skill documents how to parse and analyze JSON exported by canmatrix. One minor note: the docs show using the canmatrix CLI (pip install canmatrix / canconvert) but the skill metadata does not declare any required binaries or an install step; this is plausible for an instruction-only skill but means the agent/user must provide canmatrix if conversion is needed.
Instruction Scope
All runtime instructions are limited to loading a user-supplied canmatrix JSON file, parsing messages/signals, decoding frames, and summarizing data. The instructions do not direct the agent to read unrelated system files, access credentials, or transmit data to external endpoints.
Install Mechanism
There is no install spec and no code files. This is lowest-risk (instruction-only). The SKILL.md suggests installing canmatrix via pip only as a user step; no automatic downloads or archive extraction are defined by the skill itself.
Credentials
The skill declares no environment variables, credentials, or config paths. The documented operations (JSON parsing, numeric conversion, summary generation) do not require secrets, so the lack of requested env/creds is proportionate.
Persistence & Privilege
The skill is not always-enabled and does not request elevated or persistent system privileges. It does not modify other skills or system-wide agent settings. Autonomous invocation is allowed (the platform default) but is not combined with any other high-risk behavior here.
Assessment
This skill is an instruction guide for working with canmatrix-exported JSON and appears internally consistent. Before installing or using it: (1) be aware that converting .dbc to JSON requires the canmatrix package (pip install canmatrix) — installing packages downloads code from the Python ecosystem, so only do that if you trust the source; (2) the skill operates on user-provided JSON files, so do not feed it sensitive files you don't want parsed or logged; (3) because it's instruction-only, the skill itself will not auto-install tooling — if you allow an agent to run system commands, ensure you trust which commands it will run. If you want the skill to perform conversions automatically, ask the maintainer to declare required binaries or provide an explicit, auditable install step.

Like a lobster shell, security has layers — review code before you run it.

latestvk97dj16qgagdhjq26he3t4v04x84rhct
90downloads
0stars
1versions
Updated 2w ago
v1.0.0
MIT-0

name: can-dbc-matrix

description: Parse and analyze CAN DBC matrix JSON files exported by canmatrix. Use when working with CAN bus databases, DBC files, CAN messages, signals, ECUs, or when the user provides a canmatrix-exported JSON file for analysis, decoding, or signal lookup.

CAN DBC Matrix JSON Parser

Parse CAN database JSON files exported by the Python canmatrix library. The input is always a JSON file produced by canconvert with --jsonExportAll (full export mode).

Quick Reference: JSON Top-Level Keys

KeyTypeContent
messagesarrayCAN frames with nested signals
ecusobjectECU name → comment mapping
attributesobjectGlobal DB attributes
value_tablesobjectNamed value enumerations
signal_definesarraySignal attribute definitions
frame_definesarrayFrame attribute definitions
global_definesarrayGlobal attribute definitions
baudratenumberCAN bus baudrate
fd_baudratenumberCAN FD baudrate

Core Workflow

  1. Load the JSON with json.load()
  2. Navigate using the structure documented in json-schema.md
  3. Process messages and signals as needed

Common Tasks

List All Messages

import json

with open("can_db.json", encoding="utf-8") as f:
    db = json.load(f)

for msg in db["messages"]:
    print(f"0x{msg['id']:03X} {msg['name']}  DLC={msg['length']}  "
          f"cycle={msg.get('cycle_time', 'N/A')}ms  TX={msg.get('transmitters', [])}")

Find a Signal by Name

def find_signal(db, signal_name):
    for msg in db["messages"]:
        for sig in msg["signals"]:
            if sig["name"] == signal_name:
                return msg, sig
    return None, None

msg, sig = find_signal(db, "VehicleSpeed")

Decode a Raw CAN Frame

def decode_frame(db, arb_id, data_bytes):
    """Decode raw CAN data bytes into physical signal values."""
    msg = next((m for m in db["messages"] if m["id"] == arb_id), None)
    if not msg:
        return None

    results = {}
    for sig in msg["signals"]:
        raw = extract_raw_value(data_bytes, sig)
        physical = raw * float(sig["factor"]) + float(sig["offset"])

        # Value table lookup
        val_str = sig.get("values", {}).get(str(int(raw)))
        results[sig["name"]] = {
            "raw": raw,
            "physical": physical,
            "unit": sig.get("unit", ""),
            "enum": val_str,
        }
    return results


def extract_raw_value(data_bytes, sig):
    """Extract raw integer from CAN data bytes for one signal."""
    start_bit = sig["start_bit"]
    bit_length = sig["bit_length"]
    is_big_endian = sig.get("is_big_endian", False)
    is_signed = sig.get("is_signed", False)

    bits = ''.join(f'{b:08b}' for b in data_bytes)

    if is_big_endian:
        byte_pos = start_bit // 8
        bit_in_byte = start_bit % 8
        collected = []
        pos = byte_pos * 8 + (7 - bit_in_byte)
        for _ in range(bit_length):
            if 0 <= pos < len(bits):
                collected.append(bits[pos])
            curr_byte = pos // 8
            curr_bit = pos % 8
            if curr_bit == 0:
                pos = (curr_byte + 1) * 8 + 7
            else:
                pos -= 1
        raw = int(''.join(collected), 2)
    else:
        raw = 0
        for i in range(bit_length):
            byte_num = (start_bit + i) // 8
            bit_num = (start_bit + i) % 8
            if byte_num < len(data_bytes):
                if data_bytes[byte_num] & (1 << bit_num):
                    raw |= (1 << i)

    if is_signed and raw >= (1 << (bit_length - 1)):
        raw -= (1 << bit_length)
    return raw

Physical Value Formula

physical = raw_value * factor + offset
raw_value = (physical - offset) / factor

Signal range: [min, max] in physical units.

Generate Message/Signal Summary Table

def summarize(db):
    rows = []
    for msg in db["messages"]:
        for sig in msg["signals"]:
            rows.append({
                "Message": f"0x{msg['id']:03X} {msg['name']}",
                "Signal": sig["name"],
                "Start": sig["start_bit"],
                "Len": sig["bit_length"],
                "Factor": sig["factor"],
                "Offset": sig["offset"],
                "Unit": sig.get("unit", ""),
                "Min": sig.get("min", ""),
                "Max": sig.get("max", ""),
                "Endian": "BE" if sig.get("is_big_endian") else "LE",
            })
    return rows

Filter by ECU (Transmitter/Receiver)

def messages_by_tx(db, ecu_name):
    return [m for m in db["messages"] if ecu_name in m.get("transmitters", [])]

def signals_received_by(db, ecu_name):
    results = []
    for msg in db["messages"]:
        for sig in msg["signals"]:
            if ecu_name in sig.get("receivers", []):
                results.append((msg, sig))
    return results

Important Notes

  • Message id is a decimal integer. Convert with hex(id) for display.
  • is_extended_frame: True = 29-bit CAN ID, False = 11-bit standard ID.
  • is_fd: True = CAN FD frame (up to 64 bytes), False = Classic CAN (up to 8 bytes).
  • factor/offset may be strings or floats depending on export settings. Always cast to float().
  • values dict maps raw integer (as string key) → enum label string.
  • Motorola (big-endian) bit numbering: canmatrix exports in "lsb" format by default.
  • cycle_time is in milliseconds. 0 or absent means event-triggered.

DBC to JSON Conversion

Use canmatrix's built-in CLI tool:

pip install canmatrix
canconvert input.dbc output.json --jsonExportAll

Other supported input formats: .arxml, .kcd, .dbf, .xls(x), .sym, .ldf.

See json-schema.md for the complete JSON structure reference.

Comments

Loading comments...