Commit Graph
6 Commits
Author SHA1 Message Date
jensandClaude Sonnet 4.6 c8de234423 jay_diff: fix two correctness bugs + add real-data round-trip tests
Bug 1 (crash): jay_merge_delete iterated _new.items() while _old (which
aliases _new sub-dicts due to jay_diff_rev's side-effect writes) was being
mutated.  Fixed by snapshotting with list(_new.items()) before iteration.

Bug 2 (wrong round-trip): When new has an empty dict {} at a location where
old had a non-empty dict, jay_merge_delete incorrectly pruned the now-empty
parent key.  Root cause: jay_diff_del stored the full old sub-dict in the
delete delta for both "key absent from new" and "key present but empty in
new", making them indistinguishable at merge time.

Fix: jay_diff_del is now a standalone recursive function that stores None
for dict keys entirely absent from new (sentinel for "delete entire key")
vs a sub-dict of specific sub-keys for partial deletions.  jay_merge_delete
no longer prunes empty dicts; None (or any non-dict value) in the delta is
the explicit signal to remove the parent key.

Also adds:
- tests/data/  — copy of 25 real JSON log files for integration testing
- tests/test_jay_diff_real_data.py — 2028 parametrised round-trip tests
  over 675 real vehicle snapshots; exposed and confirmed both bugs above

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 12:25:35 +02:00
jensandClaude Sonnet 4.6 5ef7f13118 tests: add test suite for jay_diff; fix two bugs found
Move the inline assertions from jay_diff.py into tests/test_jay_diff.py
as proper pytest functions, grouped by function under test.  Add corner
cases for numeric/bool/None/list values, completely different structures,
empty containers, deep nesting, type changes (dict↔scalar), and
parametrised round-trip tests (diff→merge produces new).

Two bugs fixed during the exercise:
- jay_diff_rev: guard against _old being a non-dict (type change from
  dict to scalar caused TypeError on item assignment)
- jay_merge_delete / jay_merge_update: already fixed in previous commit;
  covered by new tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 11:54:57 +02:00
jensandClaude Sonnet 4.6 4492692786 Update clients, docs, and install for CarConnectivity migration
- gui_client: update _TRACE_LABELS paths to new flat snapshot structure
- README: update library name, pip command, domain list, credentials
  template, output example, and module reference
- install.sh: update credentials template and systemd service description
- client.py: update docstring
- data_model: Kelvin→Celsius conversion for battery temps (CarConnectivity
  returns Kelvin); round range_estimated_full to 1 decimal
- jay_diff: fix merge when old value is not a dict; skip empty-dict
  branches in delete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 11:43:41 +02:00
jensandClaude Sonnet 4.6 620d22d2e4 jay_merge_full: handle non-jaydiff input (full snapshot passthrough)
When _diff contains none of the jaydiff keys (update, update_add, add,
delete) and _old is empty, return _diff directly. This lets callers pass
a raw snapshot into jay_merge_full without needing a separate code path
for the initial-state bootstrap case.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 16:16:33 +02:00
jensandClaude Sonnet 4.6 56ed4ac265 Add opt-in diff mode for network transmission (--diff / Diff mode checkbox)
Server (collect.py --diff):
- History burst: first record sent full, subsequent as jay_diff_full diffs
- Live broadcast: each snapshot diffed against the previous one
- Diff payloads tagged with "_diff": true

Client (client.py --diff):
- Reconstructs full state via jay_merge_full before printing

GUI (Connector tab "Diff mode" checkbox):
- TcpReader.connect_to() accepts diff_mode; maintains _state dict
- Merges incoming diffs before emitting to Dashboard/Plot
- Checkbox state persisted to plot_settings.json

Both sides default to off; must be enabled consistently on server and client.
utils/__init__.py added so utils.jay_diff is importable as a package.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 14:34:34 +02:00
jensandClaude Sonnet 4.6 02e8d71569 Initial commit: WeConnect data collector
Adds collect.py with CLI flags for credentials (-u/-p), credential
JSON file (-c), VIN, domains (-d), interval, output file, and
--list-domains.  Credentials file supports domains as array or string.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 18:40:01 +02:00