Skip to content

Releases

What changed

Every version, from the GitHub release notes.

Security: stop trusting the compromised eMudhra root

Eight eMudhra intermediate CA keys were found to be recoverable from their public certificates (CVE-2026-111943). Anyone with those keys could issue a certificate for any website. Browsers and operating systems removed trust in the affected root on 18–20 October 2026.

UltraLog does not use your operating system's certificate store. It carries its own list of trusted roots, so an OS update does not protect it. This release updates that list.

What changed

  • webpki-roots 1.0.10. Removes emSign ECC Root CA - G3, the root that signed the compromised intermediates. UltraLog uses these roots for update checks and the OpenECU Alliance spec download.
  • rustls-webpki 0.103.16. The matching certificate verifier update.

No log formats, GUI features or MCP server behavior changed. Update when the app offers it.

Fixed: rusEFI logs from current firmware open again

Logs from current rusEFI firmware failed to open with "Unreasonable field count: 1096". This closes #100. Thanks to @rusefillc for the report and the example log, and to @FDSoftware for the fix in #101.

The cause was a hard limit of 1,000 channels in the MLG parser. Current rusEFI firmware logs 1,096 channels, so every log it writes was rejected. Older rusEFI logs with fewer channels were not affected.

What changed

  • No fixed channel limit for .mlg logs. The parser now checks the channel count against the file itself: the channel definitions must fit before the start of the data. A damaged or crafted file is still rejected, but a real log with any number of channels loads. The reporter's 1,096-channel log loads all 1,096 channels and 8,053 records.
  • rustls 0.23.45. UltraLog uses rustls for update checks and the OpenECU Alliance spec download. 0.23.45 fixes a medium-severity TLS 1.3 handshake bug.

Other formats, the GUI and the MCP server are unchanged.

Format details are on the Supported ECU Formats wiki. If a rusEFI or Speeduino log still fails to open, open an issue and attach the .mlg.

New: Torque Pro logs

UltraLog now opens the trackLog CSV files from the Torque Pro OBD-II app for Android. Before this release a Torque log did not load at all. This closes #97. Thanks to @ESKLAR09 for the request and the sample file.

What you get

  • One timeline for the phone and the car. Phone GPS (latitude, longitude, speed, altitude, bearing), the phone accelerometer, and every OBD-II and custom PID Torque logged, on the millisecond Device Time clock.
  • Only the PIDs your car answered. With "log all PIDs" Torque writes 200+ columns, most of them empty. Columns with no reading anywhere are hidden. A - between readings keeps the last value.
  • Track Map works out of the box. Lap detection, channel-colored track line and cursor sync work with the phone GPS.
  • Restarts in one file are joined. When logging restarts, Torque writes the header again, and the PID list can change. UltraLog loads all sections as one log.
  • Files re-saved in Excel still load. Excel shortens Device Time to mm:ss.0; UltraLog reads that clock and handles the hourly rollover. A phone clock that steps back (time-zone change, daylight saving time) does not drop rows.
  • A clear message for empty logs. If a file has only the header row, Torque recorded no samples in that session, and UltraLog says so.

Other formats, the GUI and the MCP server are unchanged.

Format details and logging steps are on the Supported ECU Formats wiki. If a Torque log loads wrong, open an issue and attach the .csv.

Fixed: Motorsport Electronics logs with a custom channel list load at the right length

An ME442 log with a short channel list (RPM, MAP, coolant, AFR) opened with its time axis 1,000x too short. A 31-minute log showed as 1.9 seconds. This closes #95. Thanks to @Iosy-Aloustas for the report and the example log.

The cause was detection. UltraLog identified ME Tuner exports by ME221 channel names such as Sync status and MAP Raw. ME Tuner logs only the channels you pick, so a short log had none of those names. The file then loaded through the generic CSV parser, which reads a bare Time column as milliseconds. ME Tuner writes Time in seconds.

What changed

  • ME Tuner logs are detected by the Time, Marker header. ME Tuner writes those two columns first in every export, whatever channels you log. ME221 and ME442 logs with any channel list now load through the Motorsport Electronics parser, with the time axis in seconds.
  • Raw and status channels have no unit. MAP Raw, Coolant temperature Raw and similar channels are raw sensor counts. They were labelled kPa or °C, so with imperial units selected a MAP Raw reading of 5908 showed as 857 psi. Status channels (Sync status, ALS Status) are also shown without a unit now.
  • Coolant Temp. is shown in °C, the same as Coolant temperature.

Other formats, the GUI and the MCP server are unchanged. If you don't use a Motorsport Electronics ECU, nothing in this release affects you.

Format details are on the Supported ECU Formats wiki. If an ME Tuner channel shows the wrong unit, open an issue and attach the .csv.

Fixed: Emerald logs show the right channels

Emerald K6/M3D logs could open with channels under the wrong names and with the wrong values. Throttle position showed up as Channel 2 (ID 41). The lambda input was labelled TPS, and ignition advance, injector duration, boost PWM and load site were all mislabelled. MAP could also read 10x low. This closes #93.

The cause was the channel table. An Emerald .lg2 file does not store channel names. It stores one ID number per logger slot, and Emerald does not publish what those IDs mean. UltraLog's table was reverse-engineered, and most of it was wrong. The IDs below are now confirmed against EM Soft from a real log:

EM Soft label UltraLog channel Unit
Engine Speed RPM rpm
Throttle Pos TPS %
AFR/Lambda Lambda Sensor Voltage V
MAP MAP kPa
Ign Adv Ignition Advance °
Inj Duration Inj Duration %
BoostPWM Boost PWM %
Load site Load Site 0–15

What changed

  • MAP follows your logger's pressure setting. EM Soft stores MAP in the pressure unit the logger is set to, and records that setting in the .lg2. UltraLog now reads it, so kPa and bar logs both show the correct kPa value. Other pressure settings are not supported yet.
  • AFR/Lambda is shown in volts. It is the K6's own 0–1 V lambda input. If a wideband controller feeds that input, convert it to AFR with a computed channel that uses your controller's output curve. The Lambda Delay and Accel Enrichment tools no longer offer this channel as wideband lambda.
  • Ignition Advance uses an offset worked out from log data (about 5° at idle, 14–17° on full boost). Compare it with EM Soft for your own log before you tune from it.
  • Each value comes from its own slot. A missing or unreadable [chanN] entry in the .lg2 no longer shifts later channels onto the wrong data.
  • Repeated names get the channel ID added, for example Ignition Advance (ID 21). Before this release, the second channel with the same name could not be selected by name.

Other formats, the GUI and the MCP server are unchanged. If you don't use an Emerald ECU, nothing in this release affects you.

Emerald channel details are on the Supported ECU Formats wiki. If a channel still shows the wrong name or value, open an issue and attach the .lg1/.lg2 pair and an EM Soft screenshot of the same point.

New: Lambda Delay and Accel Enrichment table generators

Two new tools mine your logs for events and turn them into tuning tables. They sit beside Log Viewer, Scatter Plots and Histogram in the tool switcher (⌘4 / ⌘5, Ctrl+4 / Ctrl+5), with setup in the Tool Properties panel and the table in the center. This closes #4 and #3, which asked for exactly this instead of hand-reading several logs.

Lambda Delay

Finds injector pulse-width steps, measures how long the wideband takes to respond, and bins the result by RPM × load (MAP or TPS). That number is what your ECU's closed-loop O2 control wants in its delay table.

  • Dead time is the primary value; T63 (time to 63 % of the settled response) is a second view.
  • Events are gated on a steady operating point, event spacing, fuel cut, clutch, coolant temperature and closed-loop correction movement. Every rejection is counted and shown, so the tool tells you what to log next ("208 events found · 206 rejected: 109 unsteady, 93 overlap, 4 wrong direction").
  • Strict profile for trim-bump logs, relaxed for driving logs. An injector dead-time parameter handles PW channels that include it (Haltech on-time does).
  • CAN widebands often update at 10–20 Hz inside a 50–500 Hz log. The tool measures the sensor's real update rate and interpolates between updates, and warns when that limits resolution.
  • Exports in milliseconds, engine cycles or ignition events to match your ECU.

Accel Enrichment

Detects tip-ins from a native throttle-rate channel (TPS DOT, Throttle Position Derivative, TPS Delta) or a computed derivative, shifts the lambda window by the measured delay, and reports the lean or rich excursion against target with a suggested starting correction, binned by RPM × throttle rate.

  • Signed corrections: negative means the ECU is already over-enriching.
  • If you map the ECU's own AE-activity channel, the table is labelled additional and the suggestion is a multiplier on your current AE value; otherwise it is absolute. One cell never mixes the two.
  • Uses a Lambda Delay table generated in the same session for the delay compensation when the matching cell is trustworthy, else a configurable assumed delay.

Shared

  • Channel roles are auto-detected from the log with a data-plausibility check; near-ties are flagged ⚠ for you to confirm. Haltech's "no reading" sentinel values are masked before any math.
  • Each cell shows the median with a sample-count badge coloured by confidence (Low / Medium / High). Empty and low cells are never interpolated and export blank by default.
  • Hover a cell for its statistics; click it for the event inspector, and Jump to that moment in the Log Viewer.
  • Fold several logs into one table with Add current file; remove a log or reset at any time. Tables survive tab and tool switches.
  • Export as CSV (value, count and spread grids), clipboard (bare tab-separated grid for pasting into tuning software), PNG or PDF.
  • New field normalizations: injector on-time names → Pulse Width; TPS DOT / Throttle Position Derivative / TPS Delta → TPS Rate.
  • All strings in the 15 supported languages.

Full guide: Tuning Table Generators on the wiki.

Thanks to @Barneyjm for building the generators (#90).

Fixed: MCP tool calls no longer hang on large logs

If you drive UltraLog from Claude Desktop, evaluate_formula and get_channel_data would hang forever on any log over roughly 22,000 rows — no result and no error, just silence until you gave up. Smaller logs worked fine, which made it look like a slowdown rather than a hard failure.

The cause was response size. Both tools returned one entry per log record, and MCP clients discard any single response over 1 MiB inside their decoder without reporting anything. A 178,000-row session produced several megabytes, so the reply was dropped in transit and nothing ever came back.

Responses are now bounded. A 500,000-row log returns in well under a second.

What changed

  • Series are downsampled for transport. evaluate_formula and get_channel_data return 2,000 samples by default and take a new max_points argument for up to 10,000. Downsampling uses the same LTTB algorithm as the chart, so peaks and dropouts survive rather than being skipped past. For full resolution, narrow the window with start_time/end_time.
  • Responses say what you got. Every reply now carries total_samples and downsampled, so a reduced series is never mistaken for a complete one.
  • Statistics are still exact. Min, max, mean, median and standard deviation are computed over every record in range — not over the samples that came back.
  • find_peaks reports its cap. It returns at most 500 peaks, selected by prominence and listed chronologically, and now includes total_peaks and truncated. Previously a capped list was indistinguishable from a complete one, so counting events off it gave exactly 500 every time.
  • Oversized replies error instead of hanging. Anything still too large to deliver comes back as a clear message naming max_points and the time range.

Also fixed

  • A log with ragged rows — where some rows are missing a column — could crash UltraLog when that channel was requested over MCP. It's now reported as an error instead.

Parsing, the GUI and ECU format support are unchanged. If you don't use the Claude Desktop integration, the ragged-log crash fix is the only thing here that affects you.

Highlights

UltraLog now opens TunerStudio .msl datalogs. That's the tab-delimited legacy ASCII format from TunerStudio's Data Logging menu — and, more to the point, what RealDash writes when it logs your ECU over Bluetooth. Drop the file straight into UltraLog: no export step, no conversion, no cable.

This one came from issue #86. A Speeduino user logs over Bluetooth with RealDash on a phone, which writes .msl by default — so every session meant either reconfiguring RealDash to emit CSV or converting files by hand before they could be opened. They shared two real sessions to build against, 3.6 MB and 10 MB, and both now load in full: 29 channels across 16,903 and 46,288 rows. Thank you for the files — real logs are what make format support solid.


New: TunerStudio MSL imports

An .msl is a header row, a units row, then tab-delimited data:

Time    SecL    RPM     MAP     ...     GPS Latitude    GPS Longitude   GPS Time
sec     s       RPM     kPa     ...     lat             lon             time
0.0     202.0   965.0   33.0    ...     -26.253315      -51.06884       21:51
  • Units come from the file. That second row carries the unit for every column, including the time base. A log recorded in milliseconds scales correctly instead of being read as seconds — the failure mode that once made a 34-minute log render as two seconds.
  • The Track Map just works. GPS latitude and longitude arrive in decimal degrees under their exported names, so a logged session draws the circuit beside your chart with lap detection and channel coloring, same as any other GPS-bearing format.
  • Gaps before GPS lock don't punch holes in your data. RealDash leaves GPS fields blank until it gets a fix, and writes GPS Date as text. Those fields carry the previous value forward rather than dropping to zero mid-log. GPS Time is converted to seconds since midnight, so the clock plots as a real channel instead of reading zero.
  • Multi-session files stay in order. A .msl can concatenate sessions, which sends the time column backwards partway through. UltraLog shifts each restart forward so the timeline never doubles back — which is what keeps computed-channel time shifts (RPM[-1], Boost@-0.5s) correct on these files.
  • Faulted sensors stay readable. A logger that writes NaN or inf for a dropped sensor no longer blanks out the chart's auto-scaling or the min/max legend for that channel.
  • Marks and preambles are handled. TunerStudio MARK lines are skipped, and a firmware banner or capture-date preamble ahead of the header is fine.

Not to be confused with the MegaSquirt CSV. TunerStudio also exports a comma-delimited .csv, which UltraLog has read for a while via the MegaSquirt parser. Both are supported and UltraLog picks the right one automatically — you don't need to tell it which you have.

Under the hood

  • .msl joins the file-dialog filter, so the picker stops hiding your logs.
  • Format detection keys on the header/units row pair rather than the Time column alone. Several formats lead with Time; only MSL puts a time unit directly beneath it. A regression test now walks every bundled example log and asserts the new detector claims none of them — adding a parser to the chain is exactly when a detector can start stealing another format's files.

Documentation

  • The Supported ECU Formats wiki gains a full TunerStudio MSL page covering the layout, GPS behavior, and how blank and non-numeric columns are handled. It also corrects a long-standing error: the format table listed .msl under MegaSquirt, which was never accurate — that parser only ever read the comma-delimited CSV.
  • README and ultralog.co list MSL in the format roster.

Highlights

UltraLog now opens RaceChrono track sessions. Export a session from RaceChrono or RaceChrono Pro as CSV v3 and drop it straight into UltraLog — your GPS trace, phone sensors, and OBD/CAN channels land on one synchronized timeline, with lap numbers and the GPS Track Map working out of the box. Analyze your track days on a big screen instead of a phone.

This one came straight from a user request: a RaceChrono user asked whether UltraLog could read their lap-timing exports and shared a full 2.5-hour, 125 MB session from a track day to test against. That real session — 515,000 rows, 34 channels, six recording fragments — now parses in under half a second. Thank you for the data; real files are what make format support solid.


New: RaceChrono CSV v3 imports

  • Everything on one timeline. RaceChrono merges GPS (position, speed, bearing, altitude, fix quality), phone sensors (accelerometer, gyroscope, magnetometer, lean angle), and any OBD-II/CAN channels you logged (RPM, oil temperature, throttle, …) into one table — UltraLog reads it all.
  • The Track Map just works. Latitude/longitude arrive in decimal degrees under their standard names, so the v2.13.0 GPS Track Map appears automatically: the circuit drawn beside your chart, laps detected, any channel painted onto the racing line.
  • Lap and fragment aware. RaceChrono sessions that were paused and resumed at the track record multiple fragments, and the in-file elapsed time resets at each one. UltraLog builds its time axis from the GPS timestamps instead, so the whole day stays in order. Lap numbers come along as a channel.
  • Duplicate channels stay distinguishable. RaceChrono logs some channels once per source — you'll see speed (gps) next to speed (calc) so you can compare the GPS speed against RaceChrono's calculated one.
  • Resilient parsing. Sessions survive an Excel/Numbers/Sheets round-trip (trailing-comma padding is handled), a malformed row is skipped rather than failing the file, and temperatures exported as .C display as °C.
  • Clear guidance on the wrong export. Only CSV v3 is supported — pick it in RaceChrono's export dialog. Loading a CSV v1/v2 export shows a clear "re-export as CSV v3" message instead of a confusing failure, and .vbo/.rcz are not supported.

Improved: unit preferences now cover more source units

Channels logged in °C, °F, m/s, or meters now honor your display unit preferences — previously they were shown as logged regardless of your settings. This applies to RaceChrono's GPS speed (m/s) and altitude (m), and to the °C temperatures written by the AiM, ECUMaster, Emerald, MHD, RomRaider, and Woolich parsers. Meters follow the short-distance convention: the metric preference keeps meters, the miles preference shows feet — so GPS altitude never displays as 0.003 mi.

Documentation catch-up

  • The Supported ECU Formats wiki gained full pages for RaceChrono plus the five formats that shipped without one: MHD Tuning, BlueDriver, Motorsport Electronics, DynamicEFI, and Locomotive — and its auto-detection list now covers all 15 formats.
  • README and ultralog.co now list the complete format roster.

Under the hood

  • Fixed a fixture path casing bug that had been silently skipping the RomRaider and OBDLink example-file tests on Linux CI — they run (and pass) again.
  • A RaceChrono file missing its Format metadata line now reports exactly that, instead of an unsupported-version error.

UltraLog GPS Track Map — a lap drawn over satellite imagery, colored by channel data

Highlights

UltraLog can now show you where your log happened. Open any log that contains GPS data and a Track Map appears beside your chart: your session drawn as a racing line, laps detected automatically, and any channel painted onto the track so you can see exactly where the boost spiked or the AFR went lean.

This entire feature — the track map, lap detection, the tile system, and the data-panel framework it lives in — was designed and built by @irudoy. It arrived as a complete, polished, tested contribution, and it is one of the best PRs this project has ever received. Thank you, Ivan. 🏁


New: GPS Track Map

  • Works with every supported log format. Detection is data-driven, not format-driven — if your log has recognizable latitude/longitude channels (MLG logs from rusEFI/MegaSquirt/Speeduino, AiM, Link, Haltech, generic OBD-II CSVs, and more), the map appears. No configuration needed.
  • Automatic lap detection. Closed loops are detected and listed in a lap selector; pick one to focus the map on a single lap with the rest of the session dimmed.
  • Color the track by any channel. Pick any selected channel and the racing line is painted with the Viridis or Turbo colormap — with an editable min/max range and a legend. Watch coolant temperature climb corner by corner.
  • Synchronized with your chart. Hovering the track scrubs the chart cursor and timeline while playback is stopped; clicking seeks to that exact moment. The cursor dot follows along during playback.
  • Optional satellite and street map backgrounds. Turn on Esri World Imagery or OpenStreetMap tiles under your track, with opacity and grayscale controls so the map never fights your data. Tiles are off by default and opt-in — nothing is downloaded until you enable them, a one-time notice explains that tile requests share your track's approximate location with the provider, and downloads are cached on disk so repeat sessions are instant.
  • Any GPS coordinate encoding. Logs that store coordinates as NMEA degrees-decimal-minutes, scaled integers (milli/micro/1e-7 degrees), or 0–360 longitude are detected and normalized automatically — they just work.
  • An extensible data panel. The Track Map is the first widget in a new right-side panel built to host more (think g-force plots and gauges) — resizable, collapsible, per-file.

Also in this release

  • MLG hex bitfield support — bitfield type IDs written in hexadecimal (0x10–0x12), as the MLG specification defines them, are now accepted alongside the legacy decimal interpretation. Fixes channel misalignment in MegaSquirt and rusEFI logs from newer tooling.
  • Accessibility — the new data-panel controls carry proper accessible labels and are fully keyboard-operable.
  • Localization — every new UI string ships in all 15 supported languages.

Thanks

💚 @irudoy built the GPS Track Map, lap detection, tile system, and data-panel framework — the headline of this release, end to end. If you enjoy this feature, go give Ivan's work some love on #83.

What's New

A maintenance release covering two security advisories and two bug fixes. Recommended for all users.

Security

  • Fixed a DNS-rebinding vulnerability in the MCP server. The Claude Desktop integration's HTTP transport was affected by an advisory in rmcp (all versions below 1.4.0). Updated to 3.1.2, which restricts connections to localhost by default.
  • Removed two unsound, unmaintained dependencies. serde_yml and libyml, used for reading adapter specs, were flagged unsound with no fixed release available (RUSTSEC-2025-0068). They have been replaced with the maintained serde_norway, so both are gone from the build entirely.

Fixes

  • OBDLink logs now show the correct time axis. A 2049-second OBDLink (iOS) CSV export was rendering as a 2.05-second log, because the time column was always read as milliseconds. The unit is now taken from the column header, so both Time (sec) and Time (msec) exports read correctly. Thanks to the reporter of #80.
  • ECU adapter definitions now load from the OpenECU Alliance API again. Every adapter and protocol fetch had been failing silently, so the app always fell back to the specs built in at compile time. Channel-name normalisation now picks up current definitions, and the MegaSquirt adapter — which was being dropped entirely — loads again.

Under the hood

Migrated to Rust edition 2024, and refreshed every dependency to its latest release, including egui 0.34 to 0.36 (the UI framework), egui_plot 0.35 to 0.37, printpdf 0.9 to 0.12 (chart PDF export), and rust-i18n 3.1 to 4.2 (translations). No functional change is expected from these, but they touch rendering, PDF export, and the 15 shipped languages — please report anything that looks off.

Highlights

First stable release since v2.10.1. It carries the MHD Tuning support below plus everything that was staged for 2.11.0 but never shipped stable — a deep correctness and performance sweep, settings persistence, and a rewritten expression engine.


New: MHD Tuning log support

UltraLog now reads CSV datalogs exported from the MHD Tuning app — BMW N54, N55, S55, B58 and other platforms flashed with MHD.

  • Units are read straight from the column headers, with MHD's degree notation translated: (*C) → °C, (*) → °, (*CRK) → °CRK, and (-) for unitless channels
  • Time is read as seconds and normalized to start at zero
  • The tune file name (e.g. MHD 5.26 IJE0S ST2V7.bin) is kept as log metadata instead of cluttering the channel list
  • Unparseable fields carry the last known value forward, so columns never shift out of alignment

Fixed: logs with # metadata headers loaded with no channels

This is the bug behind #78. MHD exports — and OBD-II app exports such as OBDLink — start with a block of #-prefixed metadata lines before the real CSV header:

#Encoding: UTF-8
#Ecu PRGID: 7616431
#VIN: ...
Time,Boost (Bar),Coolant (*C),RPM (RPM),...

Every format detector inspects the first line of a file. That line was a comment, so nothing matched, detection fell through to the default parser, and the log opened with zero channels — the app appeared to do nothing at all.

Text logs are now normalized before format detection: a leading UTF-8 BOM is stripped, and a leading block of # comment lines is dropped so the real header row is what detection sees. This fixes MHD and the OBDLink class of failure together, and any future exporter that writes a comment preamble.

Thanks to @Turbo-Tuning for the report and the sample log, and to @andris-silis for spotting the same failure with OBDLink and narrowing it to the # lines.


Also in this release (staged for 2.11.0)

Crash and data-correctness fixes

  • Speeduino: truncated MLG v2 headers caused an index-out-of-bounds panic
  • App: a parser panic on the loader thread left the UI stuck on the loading spinner forever — errors now surface as a toast
  • Haltech: unparseable fields (blank, N/A, text gears) shifted every later column left, misaligning the whole row
  • Haltech: sessions crossing midnight produced non-monotonic timestamps, breaking time-shifted computed channels like RPM@-0.1s
  • Normalization: a channel named Speed normalized to RPM or Vehicle Speed nondeterministically between launches
  • App: opening a file while another was loading silently dropped the first result; multi-file drag-and-drop loaded only the first file
  • App: analysis results were not reindexed when a file was removed, attaching cached analyses to the wrong file
  • Adapters: spec cache filenames are sanitized against path traversal

Performance

  • The MCP/IPC server no longer forces a 10 Hz repaint forever — the GUI wakes on demand, ending idle battery drain
  • Chart downsampling is cached per channel and recomputed only when the viewport changes, instead of every channel every frame
  • Scatter heatmaps are built once per axis selection rather than rebuilt per frame

Features

  • Settings persistence — unit preferences, font scale, colorblind mode, field normalization, cursor tracking, auto-update preference, and custom channel mappings now survive restarts
  • Esc stops playback and Cmd/Ctrl+E exports the current view as PNG

Under the hood

  • The meval formula dependency was replaced with a built-in expression engine. meval was unmaintained and its transitive nom 1.2.4 dependency is rejected by future Rust versions. Formula behavior is unchanged; formulas now compile once and evaluate with no parsing or allocation per record.

UltraLog v2.10.1

macOS installs are now signed & notarized by Apple

The biggest change in this release: macOS builds are now signed with a Developer ID certificate, notarized by Apple, and stapled. The "Apple cannot check it for malicious software" warning is gone — UltraLog opens normally on first launch, even offline.

If you previously worked around the warning, no action is needed; just download the new DMG and drag it to Applications.

Security & dependency updates

  • rustls-webpki 0.103.9 → 0.103.13 — pulls in upstream security advisory fixes (CRL parsing panic + name-constraint enforcement)
  • tar 0.4.44 → 0.4.45
  • grid 1.0.0 → 1.0.1

Housekeeping

  • Corrected version metadata across the site and structured data
  • Updated install instructions to reflect notarized builds

v2.10.0 — Woolich Racing Tuned support

Adds full support for Woolich Racing Tuned (WRT) CSV log files, for Yamaha/Kawasaki/Suzuki/Honda/BMW sportbike ECUs flashed and logged through the WRT datalogger.

  • Parses the Log Time (HH:MM:SS.mmm) timestamp column, normalized to relative seconds
  • Boolean channels (e.g. Clutch In True/False) charted as 1/0
  • Trailing-comma handling and name-based unit inference (IAP→kPa, temps→°C, TPS→%, AFR)
  • UTF-8 BOM tolerant; handles wall-clock midnight wrap-around
  • Auto-detected — just open the .csv

--

New ECU Support: Motorsport Electronics (ME221 / ME442)

UltraLog now parses ME Tuner CSV exports from Motorsport Electronics ECUs — popular in turbo and supercharged MX-5, Ford Focus ST150, Honda S2000, Toyota Starlet, and Mitsubishi Evo builds.

Bug Fix: ME221 Time Scaling

Before this release, importing an ME221 CSV produced a log with the time axis compressed by roughly 1000x — a 111-second log would render as 0.111 seconds, making the data effectively unreadable.

The root cause was that both ME Tuner and RomRaider CSV exports start with a Time, header, and RomRaider's format detection was permissive enough to claim ME221 files. The RomRaider parser then divided the Time column by 1000 on the assumption it was milliseconds, while ME Tuner actually exports Time in seconds.

The fix adds a dedicated Motorsport Electronics parser with strict detection (exact Time first column plus ME221-specific fingerprint columns like Sync status, Injector duty, WBO2 Curr. AFR, and DBW Status), dispatched before RomRaider so it correctly claims ME Tuner exports.

What Works

  • Detection of ME221 and ME442 logs without collisions against other Time,-prefixed CSV formats
  • Time axis rendered in real seconds, normalized so logs start at t = 0
  • Automatic unit inference from channel names (RPM, kPa, %, °C, V, etc.) since ME Tuner does not embed units in headers
  • Trailing Dummy column silently stripped

Testing

  • Comprehensive unit tests cover detection, RomRaider rejection, generic CSV rejection, time-seconds scaling, first-timestamp normalization, and unit inference
  • Integration tests parse two bundled real ME221 example logs and assert the time range is in seconds

Bug Fix

Corrected Link ECU binary parsing across all format variants (.llg, .llg5, .llgx)

The previous Link parser used a byte-scan heuristic for channel discovery that had several critical issues:

  • Produced false-positive channel detections
  • Read each 8-byte data pair as (value, time) when the actual format is (time, value)
  • Silently skipped the first 8 bytes of every channel's data section
  • Filtered out pre-trigger samples with negative times
  • Resulted in ~24-hour time ranges and all-zero values on every file

The parser has been rewritten around proper block-based parsing, walking the file's <3-byte marker> block framing to correctly identify channel definitions and read data streams.

Before: Time range 0–89,477s (24.8 hours), all-zero values on every file. After: Physically plausible time ranges (21–52s) with real RPM, MAP, lambda, and other channel values.

Testing

  • Added plausibility checks for Link timing and channel values to catch regressions
  • Verified against all example Link files in the repo and additional .llgx files from real G4X hardware

What's New in v2.8.0

Stackable Log Viewer

The most requested visualization feature is here — stacked plot areas let you split your chart into multiple independent panels, each with its own Y-axis and channel set. No more struggling to compare RPM (0–8000) and Lambda (0.7–1.3) on the same scale.

  • Toggle stacked mode from the view options to split your chart into separate vertically-stacked panels
  • Up to 10 plot areas — create named panels like "Engine", "Fuel", "Temps" and assign channels to each
  • Drag to resize — adjust the height of each plot area by dragging the dividers between them
  • Collapse panels — minimize plot areas you don't need right now without losing your channel assignments
  • Per-plot channel management — add and remove channels from individual plots, or move channels between plots
  • Shared timeline — all stacked plots share the same time axis, cursor position, and playback controls, so everything stays synchronized as you scrub through the log
  • Works with all tools — stacked mode integrates with the existing channel selection, color assignment, min/max legends, and cursor value readouts

When you disable stacked mode, all channels consolidate back to a single chart — nothing is lost.

MCP Server — Claude Desktop Integration

UltraLog now embeds a Model Context Protocol (MCP) server that lets Claude Desktop (or any MCP-compatible AI client) control the application in real time. When UltraLog launches, it starts an MCP endpoint at http://localhost:52453/mcp that exposes 23 tools for AI-assisted log analysis:

  • File management — Load, close, and inspect ECU log files
  • Channel operations — List channels, select/deselect channels for display, get time-series data and statistics (min, max, mean, std dev, median)
  • Computed channels — Create, delete, and list computed channels from mathematical formulas
  • Formula evaluation — Evaluate arbitrary formulas against log data without creating permanent channels
  • Playback control — Play, pause, stop, set cursor position, and set visible time range
  • Analysis tools — Find peaks in channel data, compute Pearson correlation between channels
  • View switching — Switch between time-series chart, scatter plot, and histogram views

To connect Claude Desktop, add UltraLog as a Streamable HTTP MCP server pointing to http://localhost:52453/mcp.

New ECU Format: BlueDriver OBD-II

Added support for BlueDriver OBD-II diagnostic scanner log files (.csv). BlueDriver is a popular Bluetooth OBD-II scanner used for reading live data from any OBD-II compliant vehicle.

AFR/Lambda Unit Preference

Added a new unit preference for Air-Fuel Ratio (AFR) and Lambda display, letting you switch between AFR and Lambda units across all channels that report mixture data.

UI Polish

  • Improved histogram and scatter plot tool properties panels with better layout and controls
  • Refined tool properties panel styling
  • Cursor tracking now defaults to on for a better out-of-the-box experience

Under the Hood

  • Rust toolchain updated from 1.92.0 to 1.94.1
  • egui ecosystem upgraded to eframe 0.34.1, egui_plot 0.35.0, egui_extras 0.34.1
  • Dependency updates: zip 8.5, printpdf 0.9 (complete PDF export rewrite), strum 0.28, dirs 6.0, ureq 3.3, serde_yml (replacing deprecated serde_yaml), chrono 0.4.44
  • OpenECU Alliance API — Fixed spec refresh parsing for the updated API response format; added Diagnostics channel category
  • PDF export rewritten to use printpdf 0.9's Op-based API

UltraLog v2.0.0 Release Notes

Major Release - Complete UI Overhaul & Professional Analysis Tools

This is a major release featuring a completely redesigned user interface, powerful new analysis tools, and significant accessibility improvements.


New Features

Complete UI Redesign

  • VS Code-style Activity Bar - New vertical navigation with icon-based panel switching for Files, Channels, Tools, and Settings
  • Reorganized Panel Layout - Cleaner, more intuitive organization with dedicated panels for each function
  • Improved Tool Switcher - Pill-style tabs for switching between Log Viewer, Scatter Plot, and Histogram views
  • Consolidated Settings Panel - All display, unit, normalization, and update settings in one accessible location

Histogram / 2D Heatmap View

  • New Visualization Tool - Analyze channel relationships as a 2D heatmap grid
  • Configurable Grid Sizes - Choose between 16x16 or 32x32 grid resolution
  • Dual Display Modes - View average Z-value or hit count per cell
  • Interactive Selection - Click cells to inspect detailed statistics
  • Cursor Tracking - Real-time crosshair follows playback position
  • WCAG-Compliant Colors - Dynamic text coloring for AAA accessibility compliance
  • Heat Gradient Legend - Blue-to-red color scale with value range display

Professional Analysis Framework

A comprehensive suite of 14 analysis algorithms organized into four categories:

AFR Analysis
  • Fuel Trim Drift Detection (CUSUM) - Detects systematic drift in AFR using Cumulative Sum algorithm
  • Rich/Lean Zone Detection - Identifies and highlights rich and lean operating regions
  • AFR Deviation Analysis - Measures deviation from stoichiometric with configurable targets
Derived Calculations
  • Volumetric Efficiency - Estimates VE from MAP, RPM, and IAT using speed-density equations
  • Injector Duty Cycle - Calculates IDC from pulse width, RPM, and injector flow rate
  • Lambda Calculator - Converts between AFR and Lambda with fuel type support
Signal Filters
  • Moving Average - Simple N-sample averaging for noise reduction
  • Exponential Moving Average (EMA) - Weighted averaging with configurable smoothing factor
  • Median Filter - Robust outlier rejection filter
  • Butterworth Lowpass - Professional-grade IIR filter with configurable cutoff and order (1-8)
  • Butterworth Highpass - High-frequency pass filter with SOS implementation
Statistics
  • Descriptive Statistics - Mean, median, std dev, min, max, range, and coefficient of variation
  • Correlation Analysis - Pearson correlation coefficient between any two channels
  • Rate of Change - First derivative calculation with smoothing options
Analysis Tool Features
  • Channel Selection Dropdowns - Tooltips show common ECU channel names for each analyzer type
  • Results Display - Results prominently displayed at top of Analysis Tools panel
  • Run & Chart Button - One-click analysis execution with automatic chart addition
  • Min/Max Jump Buttons - Quick navigation to peak values for computed channels
  • Computed Channel Indicator (ƒ) - Visual distinction between formula-based and raw channels

Accessibility Improvements

  • Font Scaling - Four size options: Small (0.85x), Medium (1.0x), Large (1.15x), and Extra Large (1.3x)
  • Scalable UI Elements - All interface elements respect font size preference
  • Improved Readability - Enhanced text contrast and sizing throughout the application

New ECU Support

  • Emerald ECU Parser - Full support for Emerald K6/M3D ECU log files
    • Parses .lg1 (binary data) and .lg2 (channel definition) file pairs
    • Supports 40+ channel types including TPS, MAP, Lambda, temperatures, pressures, and more
    • Automatic OLE timestamp conversion for accurate time synchronization
    • Proper scaling and unit conversion for all channel types

Bug Fixes

  • Linux Scaling Issues - Fixed DPI scaling problems on Linux systems (Issue #32)
  • Windows Build - Fixed winresource compilation for paths containing spaces
  • Visual Polish - Numerous small visual bug fixes and UI refinements
  • Analysis Tool Stability - Bug fixes for analysis algorithms and test corrections

Technical Changes

  • New Module Structure - Added src/analysis/ module with sub-modules for each algorithm category
  • New UI Components - Added activity bar, side panel, files panel, channels panel, tools panel, settings panel, and analysis panel
  • Extended State Management - New state types for histogram, font scaling, active panel tracking
  • Test Coverage - Added comprehensive tests for Emerald parser (878 lines of tests)
  • Code Stats - 12,605 lines added, 966 lines removed across 55 files

Supported ECU Systems

UltraLog now supports 8 ECU systems:

  • Haltech (NSP CSV export)
  • ECUMaster EMU Pro (CSV export)
  • RomRaider (Subaru ECUs)
  • Speeduino (MLG binary)
  • rusEFI (MLG binary)
  • AiM (XRK/DRK binary)
  • Link ECU (LLG binary)
  • NEW: Emerald K6/M3D (LG1/LG2 binary)

Contributors

Thanks to everyone who contributed to this release!