zazzn

emublog2mlv

Community zazzn
Updated

Convert ECU Master EMU Black .emublog logs to MegaLogViewer HD (.msl/.csv) - CLI, standalone .exe, and MCP server

emublog2mlv

Convert ECU Master EMU Black .emublog binary logs into a formatMegaLogViewer HD can open —a MegaSquirt .msl (tab-delimited) or plain .csv.

CIReleaseLicense: MIT

The EMU Client stores logs in an undocumented gzip-compressed binary format thatonly its own software can open. This tool decodes that format directly, so youcan analyse EMU logs in MegaLogViewer HD (overlay channels, histograms, VE/AFRanalysis) instead of being locked into the EMU Client viewer.

Three ways to use it

1. Standalone .exe (no Python needed) — easiest

Download emublog2mlv.exe from theReleases page, then drag alog onto it, or from a terminal:

emublog2mlv.exe yourlog.emublog

This writes yourlog.msl next to it. Open that in MegaLogViewer HD.

2. Python package (CLI + library)

pip install git+https://github.com/zazzn/emublog2mlv
emublog2mlv yourlog.emublog              # -> yourlog.msl
emublog2mlv yourlog.emublog --csv        # -> yourlog.csv
emublog2mlv *.emublog                     # batch convert
emublog2mlv yourlog.emublog --summary     # print channel ranges as JSON (no file written)

As a library:

from emublog2mlv import convert, summarize
convert("yourlog.emublog", fmt="msl")     # returns stats dict
summarize("yourlog.emublog")              # per-channel min/max/mean

3. MCP server (let an AI use it as a tool)

emublog2mlv ships an MCP server so an AIassistant (Claude Desktop / Claude Code, etc.) can convert and inspect logs foryou.

pip install "emublog2mlv[mcp] @ git+https://github.com/zazzn/emublog2mlv"
claude mcp add emublog2mlv -- emublog2mlv-mcp

Tools exposed:

Tool What it does
convert_emublog(input_path, output_format="msl", output_path=None) Convert a log; returns stats
emublog_summary(input_path) Per-channel min/max/mean/first/last (no file written)
list_channels() The decoded channel map (offsets/scales)

Then just ask: "Convert C:\logs\drive.emublog and tell me where lambda goes lean."

Output

A .msl file has a name row, a units row, then one row per 25 Hz sample, with aTime column in seconds. Time is anchored to the device's frameStamp clock,so it stays accurate even though the real sample rate (~25.18 Hz) jitters — anaïve index / 25 drifts ~0.7% over a few minutes.

Decoded channels

24 measured channels plus 2 derived (AFR, AFRTarget = λ × 14.7):

RPM, MAP, TPS, VE, IgnitionAngle, IgnFromTable, InjectorsPW,InjectorsDC, InjCalTime, ShortTermTrim, Lambda, LambdaTarget, IAT,ChargeTemp, CLT, OilTemp, OilPressure, FuelPressure, IATCorrection,Ethanol, AirFlow, CAM1valveDC, IdleTarget, FCustomCorrActive.

Channels that stay flat in a gentle cruise log (knock level, boostduty/target/correction, EGT, gear, vehicle speed, AFR2, BARO, enginepower/torque, dwell, warmup) are not mapped yet — they need a dynamic driveto correlate. See Contributing.

How the format was reverse-engineered

ECU Master does not publish the .emublog layout. It was recovered bycorrelation:

  1. The file is gzip-compressed. Decompressed, it is a 12-byte headerfollowed by fixed 308-byte records, one per sample(records = (size − 12) / 308).
  2. Export the same drive from EMU Client to CSV (it caps at 13 channels perexport, so several exports are taken). These CSVs are row-aligned to thebinary (sample N = record N).
  3. For each known CSV channel, Pearson-correlate its series against a u16 (oru8) value read at every byte offset; the offset with |r| ≈ 1.0 is thechannel, and the linear fit gives the scale.
  4. Overlapping clusters (e.g. oil-pressure / oil-temp / fuel-pressure / coolantpacked into bytes 111–115) were pinned by dumping raw bytes next to the CSVtruth — temperatures turned out to be single-byte integers, pressures adominant high byte.

Every decoded channel matches the EMU CSV export to the decimal. (The onlydiscrepancies are ~0.8% of rows where EMU's own CSV export jitters ±1–2 framesagainst the binary — so this converter is actually more faithful thanre-exporting CSV from the EMU Client.)

This was reverse-engineered for EMU Black V2 (firmware 2.169). EMU BlackV3 writes a different .emublog3 layout, which is not supported.

Contributing: add a channel

The channel map lives in src/emublog2mlv/core.py asthe CHANNELS table: (name, unit, offset, kind, scale, extra). To map a newchannel, get a log that exercises it (e.g. a boost pull for boost/knock/EGT),export it to CSV from EMU Client, correlate each byte offset against the CSVcolumn, verify the decode against the CSV, then add a row. PRs welcome.

Run the tests:

pip install -e ".[dev]"
pytest -q

License

MIT © 2026 Eric W

MCP Server · Populars

MCP Server · New

    jackccrawford

    Geniuz

    Your AI remembers now. Geniuz stores everything in a local database locally on Mac, Windows, Linux, Raspberry Pi. No cloud. No account. No API keys. Nothing leaves your machine. It's open source; you can read every line of code.

    Community jackccrawford
    ggui-ai

    ggui

    The universal interface layer between AI agents and humans. Generate rich UIs on demand via MCP.

    Community ggui-ai
    aanno

    CocoIndex Code MCP Server

    An RAG for code development, implemented as MCP server with cocoindex

    Community aanno
    timescale

    Tiger Linear MCP Server

    A wrapper around the Linear API for internal LLMs

    Community timescale
    choplin

    MCP Gemini CLI

    MCP Server

    Community choplin