Commit Graph
12 Commits
Author SHA1 Message Date
jensandClaude Sonnet 4.6 2f6556116e Replace utils/jay_diff.py with jaydiff package from jayfield/jaypy
Remove the local copy of jay_diff and its tests/data; switch all four
import sites to `jaydiff.diff.diff_full` / `jaydiff.merge.merge_full`
from the shared Gitea package (http://192.168.22.90:3001/jayfield/jaypy).
Add the package as a VCS dependency in requirements.txt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 13:56:45 +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 bf33737654 data_model: redesign domain extractors for CarConnectivity object model
Flatten the snapshot structure so each domain maps directly to its
fields rather than mirroring the old WeConnect status-object nesting.
New domains: electric_drive (range, battery/SOC/temps, odometer),
connectivity, vehicle, position, doors — replacing the old readiness,
parking, access, and measurements domains.  Update apply_procedural
paths and collect.py defaults accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 09:01:15 +02:00
jensandClaude Sonnet 4.6 f050de7001 collect: migrate from weconnect to CarConnectivity + VW connector
Replace the weconnect library with carconnectivity and
carconnectivity-connector-volkswagen.  The connector is configured via
a dict passed to CarConnectivity(); startup()/fetch_all() replace
login()/update().  All domain extractors in data_model.py are rewritten
for the new object model (vehicle.charging.*, vehicle.get_electric_drive(),
vehicle.climatization.*, etc.).  Remaining time fields are now derived
from estimated_date_reached DateAttributes.  Battery temperatures are
read directly in °C (no Kelvin conversion).  Auth error handling drops
the manual re-login since the connector manages token refresh internally.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 08:02:34 +02:00
jensandClaude Sonnet 4.6 cdc01aaa76 data_model: implement range_at_100 procedural field
Compute estimated full-charge range from totalRange and current SOC.
Guard against None values (_get returns None for missing keys) and
SOC = 0 to avoid TypeError / ZeroDivisionError on incomplete records.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 17:49:12 +02:00
jensandClaude Sonnet 4.6 2756c6a49b Add procedural field post-processing to snapshots
server/data_model.py:
- apply_procedural(record) — stub function; add computed fields to the
  proc dict inside and they appear under record['procedural'] in every
  record stored and broadcast.
- _get(data, *keys) — safe nested dict accessor for use inside
  apply_procedural.

collect.py:
- New snapshots: apply_procedural() called after collect_snapshot(),
  before appending to the store and broadcasting.
- Preloaded 24-h history: guarded apply (skip if 'procedural' already
  present) applied after load_last_24h_records().
- Current-day store loaded from disk: same guarded apply after
  load_store(), so legacy records sent to clients are enriched on the fly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 17:35:10 +02:00
jensandClaude Sonnet 4.6 ca5b284e9a Remove _diff marker: use self-describing jay_diff protocol
Server (network.py): send every record in diff mode starting from
prev={}, including the first — fixes history drop on new client connect.

Collect (collect.py): remove payload["_diff"] = True from live broadcast.

GUI client (gui_client.py): always call jay_merge_full in diff mode;
drop the _diff key check that gated reconstruction.

CLI client (client.py): fix `args.diff or True` guard that made --diff
irrelevant.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 16:08: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 b57e2a9cc2 collect: send last 24 h of history on client connect (not same-day only)
Replace load_today_records with load_last_24h_records which computes a
rolling 24 h cutoff, globs log files for both the current and previous
calendar day, and filters records by timestamp — so clients always
receive a full 24 h window regardless of when midnight falls.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 13:20:41 +02:00
jensandClaude Sonnet 4.6 04578781af Eagerly pre-load today's disk records into push_store_ref at startup
Previously load_today() was only called if in-memory records were empty,
which was never true once the first WeConnect poll had completed.
Now disk records are loaded unconditionally at startup and merged with
live in-memory records (dedup by ts) when a client connects.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 21:39:22 +02:00
jensandClaude Sonnet 4.6 9d2d742368 Fall back to disk when in-memory store is empty on client connect
storage_helpers: load_today_records() scans logs/ for all files
matching today's UTC date and VIN, merges and sorts their records.

network: _accept_loop receives an optional load_today callable;
if store_ref["current"] has no records it calls load_today() to
replay the day's history from disk before adding the client.

collect: passes a load_today lambda (None when -o is used).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 21:21:17 +02:00
jensandClaude Sonnet 4.6 7774f4842e Move server modules into server/ package
data_model, log_config, network, storage_helpers, we_connect are now
under server/. collect.py stays in the project root and imports via
the server package.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 20:16:46 +02:00