CanLab/docs

Command line

The analysis modules are Qt-free, so everything here runs without a display: in CI over a folder of drives, from a notebook, piped into something else, or on a Raspberry Pi in a car. A test asserts the process never imports Qt.

The command line tour

1:42

Every command run for real against recordings this project did not produce, including a genuine capture: one process replays a real log onto a bus while canlab-cli capture records it and a mark is posted over HTTP.

The commands

canlab-cli ids      capture.csv                          # IDs, rates, moving bytes
canlab-cli detect   capture.csv --json out.json --dbc draft.dbc
canlab-cli decode   capture.csv --dbc signals.dbc --out decoded.csv
canlab-cli convert  capture.blf capture.csv              # csv, blf, asc, log
canlab-cli capture  --interface socketcan --channel can0 --keys b=brake

Every command reads any format the application does. detect runs the counter and checksum sweep, entropy boundaries, bit-level flags, value-table inference and multiplexer detection, and can draft a DBC from what it found with overlapping claims resolved so the file loads in cantools. convert writes SavvyCAN's own CSV layout, so the result opens there as well as here. Nothing here transmits.

Capture

canlab-cli capture is the capture kit: a headless, receive-only logger that writes SavvyCAN CSV segments as frames arrive, rotating by frame count (--max-frames, 200,000) or by time (--max-seconds, 600), keeps a marks.json updated on every mark, and when it stops folds the segments and marks into one .canlab project the desktop opens with every mark on the timeline.

sudo ip link set can0 up type can bitrate 500000 listen-only on
canlab-cli capture --interface socketcan --channel can0 --bitrate 500000 \
    --keys b=brake,h=horn --http 8765 --http-host 0.0.0.0 \
    --token-file ~/.canlab/kit-token --gpio 17=brake --duration 3600
Marks fromHow
The keyboard--keys b=brake: on a terminal, b opens a brake interval and b closes it, q stops. Without --keys, or when stdin is not a terminal, type a label and Enter: brake, brake off, brake point.
HTTP--http PORT serves the same REST API as the window with POST /mark, GET /frames and GET /status, and without /inject. The token is generated on the first run and written to --token-file. Binding to anything but loopback is announced at start.
GPIO--gpio 17=brake: a switch between the pin and ground marks brake for as long as it is held, through gpiozero when it is installed. Without it the kit says so and records without switches.

--adapter NAME opens an adapter saved in the desktop's Settings, which are mirrored to ~/.canlab/adapters.json for this purpose. Ctrl-C, SIGTERM or --duration stop the run cleanly: open marks are closed, the last segment is flushed, and the summary and the project path are printed. --no-project leaves the segments and marks only.

It never asks for privileges

A SocketCAN link that is down gets the ip link command printed and exit code 2. The systemd unit in canlab/examples/capture-kit/ brings can0 up in listen-only mode with CAP_NET_ADMIN before the kit starts, and runs the kit itself as an ordinary user.

The kit has been exercised on python-can's virtual backend and a fake bus, with marks from stdin, HTTP and a fake gpiozero, not yet in a vehicle.