Skip to content

Fix truncation of last character of VIN by modifying decode_encoded_string() - #276

Open
gwillgues wants to merge 5 commits into
brendan-w:masterfrom
gwillgues:master
Open

Fix truncation of last character of VIN by modifying decode_encoded_string()#276
gwillgues wants to merge 5 commits into
brendan-w:masterfrom
gwillgues:master

Conversation

@gwillgues

@gwillgues gwillgues commented May 4, 2024

Copy link
Copy Markdown

When retrieving VIN via the following example code, I received 16 characters instead of the proper 17, and the trailing "0" in my VIN was truncated.

connection = obd.OBD()

cmd = obd.commands.VIN
response = connection.query(cmd)
print(response.value)

I modified decode_encoded_string() in decoders.py to use the .replace() function instead of .strip() to remove '\x00', '\x01', and '\x02', which resolved the issue in my testing.

gwillgues added 5 commits May 4, 2024 14:42
…coded_string function to use .replace() instead of .strip()
…ecode_encoded_string function to use .replace() instead of .strip()"

This reverts commit 090b66a.
…ifying decode_encoded_string function to use .replace() instead of .strip()""

This reverts commit a10a12c.
@gwillgues gwillgues changed the title Fix truncation of last character of VIN by modifying decode_encoded_string(), add DEBUG env var support Fix truncation of last character of VIN by modifying decode_encoded_string() May 4, 2024
@gwillgues

Copy link
Copy Markdown
Author

@brendan-w Did you have a chance to review this?

@gwillgues

Copy link
Copy Markdown
Author

@brendan-w Did you have a chance to review this?

bkonick added a commit to WOT-Lemons/Lemongrass that referenced this pull request Aug 7, 2026
VINs read over OBD-II were truncated before being used to tag telemetry.

python-obd 0.7.3 decodes Mode 09 strings with (obd/decoders.py:508):

    d.strip().strip(b'\x00' b'\x01' b'\x02' b'\\x00' b'\\x01' b'\\x02')

Adjacent bytes literals concatenate, and the last three are the characters
backslash, x, 0, 1 and 2 rather than escapes, so the effective strip set is
{0x00, 0x01, 0x02, '0', '1', '2', '\', 'x'} -- applied to both ends. Any VIN
beginning or ending in 0, 1 or 2 was silently shortened, and one ending in
several such digits could lose them all. Confirmed against the ELM327
emulator, whose WP0ZZZ99ZTS390000 arrives as WP0ZZZ99ZTS39. The upstream fix
has been open as brendan-w/python-OBD#276 since May 2024 with no release
since, so this does not wait on it.

_decode_vin now reads the VIN from the raw response messages rather than
response.value, stripping only the control-byte padding, and scans every
message so a multi-ECU reply resolves to whichever yields a valid VIN.
_resolve_vin accepts an OBD-derived VIN only when it is a complete 17
alphanumeric characters, so a fragment can never become a tag and collide
with another car's prefix; anything shorter is discarded with a warning and
the configured telem.vin is used instead. A configured VIN is trusted as
given, and OBD remains the source of truth ahead of config.

The vin tag changes for any car whose VIN was being truncated, so its
telemetry appears under a new tag from the first run after deploying and
Grafana lists the old and new values as separate cars until the history is
reconciled.

Two emulator-backed integration tests (four cases, deselected by default)
exercise the real OBD path. The emulator serves a different sample VIN per
query, so they are parametrized across several rather than pinned to one and
assert the decoded value is a complete VIN strictly longer than the
library's.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant