v0.1.10-alpha
🎉 v0.1.10 – “String-Safe Signal Filtering” 🎉
The latest patch finally slays the dreaded unhashable-type errors by coercing every signal identifier to a string before any set-based filtering—and while we were at it, we made the filtering code bullet-proof and polished up the error messages.
✨ What’s New in v0.1.10
🛠 Bug Fixes & Edge-Case Handling
Unhashable-safe filtering
All expected_signals and filter_signals entries are now normalized via str() before building any set(), eliminating errors when passing cantools’ NameSignalValue or other custom objects.
Graceful skip of bad entries
If a signal name can’t be stringified, it’s simply omitted—no exceptions, no crashes.
🎨 Usability & API Tweaks
Zero impact on public API
No function signatures changed—just improved internals.
Clearer warnings & errors
Attempting to supply duplicate signal names still raises early ValueError, and any chunk-decode failures turn into concise, logged ValueErrors.
🔧 Quickstart
pip install canml==0.1.8from canml.canmlio import (
load_dbc_files, load_blf, to_csv, to_parquet, CanmlConfig
)
# 1️⃣ Merge & cache your DBC(s) safely
db = load_dbc_files(["vehicle.dbc", "chassis.dbc"], prefix_signals=True)
# 2️⃣ Configure BLF loading once
cfg = CanmlConfig(
chunk_size=5000,
progress_bar=True,
force_uniform_timing=True,
interval_seconds=0.02,
interpolate_missing=True,
dtype_map={"Engine_RPM": "int32"}
)
# 3️⃣ Full‐file decode with filters, injection, and enums
df = load_blf(
blf_path="drive.blf",
db=db,
config=cfg,
message_ids={0x100, 0x200},
expected_signals=["Engine_RPM", "Brake_Active"]
)
print(df.head())
# timestamp Engine_RPM Brake_Active raw_timestamp
# 0 0.00 8000 0 162523.1
# 1 0.02 8050 0 162523.3
# 4️⃣ Export with metadata side-dump
to_csv(df, "drive_data.csv", metadata_path="drive_data_meta.json")
to_parquet(df, "drive_data.parquet", metadata_path="drive_data_meta.json")Massive thanks to all contributors and issue reporters—enjoy the smoother, smarter CAN-ML! 🎉🎉