Skip to main content

e36cli

CI License: GPL-3.0 Python 3.11+

A fast, honest, terminal-native diagnostic tool for the BMW E36 (M52 / MS41.x DME), speaking BMW's DS2 protocol over K-line through a ~$10 VAG KKL (FTDI) cable. Built on Linux, for Linux.

        e36 snapshot — ms41.1
┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━┓
┃ Param             ┃   Value ┃ Unit ┃
┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━┩
│ Engine RPM        │   817 ? │ rpm  │
│ Mass air flow     │  9.25 ? │ kg/h │
│ Intake air temp   │ 24.46 ? │ °C   │
│ Coolant temp      │ 19.98 ? │ °C   │
│ Vehicle speed     │     0 ? │ km/h │
│ Ignition advance  │ 12.58 ? │ °    │
│ VANOS angle       │ 59.92 ? │ °    │
│ Throttle position │  0.78 ? │ %    │
│ Short trim B1     │  1.00 ? │ %    │
│ Short trim B2     │  1.00 ? │ %    │
│ Battery voltage   │ 13.97 ? │ V    │
└───────────────────┴─────────┴──────┘
       ? = not verified on car
                     2 stored fault(s)
┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━┓
┃ Code ┃ Description                     ┃ Freq ┃ Age (h) ┃
┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━┩
│   25 │ Lambda Sensor Heater Bank 1 ?   │    1 │    30.0 │
│   52 │ Solenoid Valve - Exhaust Flap ? │    1 │    30.0 │
└──────┴─────────────────────────────────┴──────┴━━━━━━━━━┘

(real output — from the built-in simulator, no car attached)

Features

  • e36 live — live dashboard: gauges at the K-line's physical speed limit, stored faults refreshed alongside, staleness shown honestly.
  • e36 panel — the everything-view: ECU identification, every known parameter, decoded status bits, faults — and clear them with a guarded keypress.
  • e36 dashboard — full-screen engine HUD: one tile per parameter with history sparklines, min/max, live faults, and the same guarded fault-clear.
  • e36 dtc read / dtc clear — fault codes with plain-text descriptions, occurrence counts, and age in engine-hours. Writes always require confirmation.
  • e36 log — stream samples to CSV/JSONL for analysis.
  • e36 scan — probe every known E36 module address, show raw idents.
  • e36 sia — guided service-interval reset walkthrough (the safe, pin-7 way — see Philosophy).
  • e36 raw — send arbitrary DS2 frames when you know what you're doing.
  • e36 doctor — port, permissions, FTDI latency: diagnose the laptop before blaming the car.
  • Capture-everything: every byte exchanged with a real car is recorded to session files — your own regression corpus, replayable against the test suite with --sim-fixture.
  • Built-in simulated DME: every command works with --sim, no hardware needed. The simulator idles, warms up, stores and clears faults, and can inject wire faults.

Philosophy: provenance or it didn't happen

Community-sourced RAM maps are a minefield of copy-paste errors. Every parameter in this tool carries a source URL and a verified flag; anything not yet proven against a real engine renders with a ? marker in every output — tables, CSV headers, JSON fields. Parameters get promoted only with a capture file as evidence.

Current ground truth: verified on a 1996 Euro E36 (M52, MS41.0, ECU 1429373) — identification, fault read/clear (byte-exact), and the core sensor set live at idle, plus a RAM probe that located the fuel-trim and battery-voltage blocks on that ECU. US MS41.1/MS41.2 profiles ship with sourced-but-unverified addresses. See research/ for the sourced protocol documentation and SPEC.md for the architecture contract.

Writes are conservative by design: fault-clearing needs explicit confirmation, non-DME modules are strictly read-only, and there is deliberately no software service-interval reset — the E36 cluster's reset opcode was never published and sits one selector value away from an odometer reset (details). e36 sia walks you through the safe hardware method instead.

Install

uv tool install e36cli            # from PyPI, or:
uv tool install git+https://github.com/jjshoots/e36cli

Quickstart (no car needed)

e36 --sim ident                          # identification + profile match
E36CLI_SIM_DTCS=25,52 e36 --sim dtc read # seeded fault codes
e36 --sim live                           # live dashboard
e36 --sim panel                          # the everything-view

Hardware

  • Any VAG KKL 409.1 cable with a genuine FTDI chip (FT232RL). CH340 clones work for basic serial but are untested here.
  • E36s: the round 20-pin connector under the hood (K-line on pin 20), or the cabin OBD2 socket on later cars. Cheap 20-pin→OBD2 adapters exist.
  • One-time Linux setup (permissions + the critical 1 ms FTDI latency timer):
printf 'SUBSYSTEM=="usb-serial", DRIVER=="ftdi_sio", ATTR{latency_timer}="1"\nKERNEL=="ttyUSB[0-9]*", MODE="0666"\n' \
  | sudo tee /etc/udev/rules.d/99-e36cli.rules
sudo udevadm control --reload   # then replug the cable
e36 doctor                      # verifies all of it

Supported ECUs: MS41.0 / MS41.1 / MS41.2 (M52 and S52 engines, 1995–2000), with a generic fallback for unrecognized MS41 software. Pre-OBD2 E36 DMEs (ADS-protocol era) are not supported — they need different interface hardware entirely.

Contributing

PRs welcome — especially capture files and verified parameters from other MS41 variants. uv sync && uv run pytest is the whole dev loop; the test suite needs no hardware. See CONTRIBUTING.md, and open a profile request issue with your e36 ident output if your ECU isn't recognized.

Disclaimer

Use at your own risk. This tool talks to the engine control unit of a moving vehicle: reads are safe by design, writes are guarded, but you are the operator. Never use component-activation or fault-clearing functions while driving. This project is not affiliated with, endorsed by, or connected to BMW AG in any way. All trademarks are the property of their respective owners.

License

GPL-3.0-or-later. The fault-code database and parts of the parameter maps derive from GPL-licensed community tooling (BimmerStein, RomRaider definitions) — see research/ for full provenance.

Metadata

Release files for e36cli 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for e36cli 0.3.0
File Size Uploaded Provenance Actions
e36cli-0.3.0.tar.gz 191.9 kB With provenance Details for e36cli-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for e36cli 0.3.0
File Interpreter ABI Platform Actions
e36cli-0.3.0-py3-none-any.whl Python 3 none any Details for e36cli-0.3.0-py3-none-any.whl

Total release size: 278.0 kB

Release files / e36cli-0.3.0.tar.gz

Download URL e36cli-0.3.0.tar.gz
Size 191.9 kB
Tags Source
SHA-256 checksum
How to use checksums
4cf9193b9ba708fce1e0999f7fa58e91472d2c417b77834b1a080a49e6280f01
BLAKE2b-256 checksum
How to use checksums
65fdb7215914639f4d5d0b352e530868328e69be03c6dfa0337fc44c43bc4c2d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Release files / e36cli-0.3.0-py3-none-any.whl

Download URL e36cli-0.3.0-py3-none-any.whl
Size 86.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
616b4ca0a05b6954f4c5f69abd6d28ab7b5b5bd6e507e42f7d0db2c5f5654e8e
BLAKE2b-256 checksum
How to use checksums
d7188cec143f367dd88f6d19245b0d4a8b417224ca5c1534c91e8d191a0e8661
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Security for e36cli 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for e36cli-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page