server: replace carconnectivity with volkswagencarnet

Switches the VW API backend from carconnectivity + connector-volkswagen
to volkswagencarnet (local fork with the cariad-hybrid-auth-fix patch
applied), fixing authentication against the current CARIAD BFF endpoints.

- requirements.txt: point at local volkswagencarnet git repo via
  git+file:// URL (editable path no longer needed now the patch is
  committed there)
- we_connect.py: rewrite around the async volkswagencarnet Connection
  class; a persistent asyncio event loop held in _Session lets the rest
  of the code stay synchronous
- data_model.py: remap all extractors to volkswagencarnet Vehicle
  properties and Paths constants; output shape preserved so
  apply_procedural and the GUI client continue to work unchanged
- collect.py: swap carconnectivity error import, drop
  TemporaryAuthenticationError (no equivalent), fix vehicle.vin.value →
  vehicle.vin

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-28 22:50:57 +02:00
co-authored by Claude Sonnet 4.6
parent 63e807bdb0
commit bc424310b5
4 changed files with 223 additions and 148 deletions
+5 -5
View File
@@ -10,7 +10,7 @@ from .data_model import ALL_DOMAINS, collect_snapshot, apply_procedural
from .storage_helpers import auto_out_path, load_last_24h_records, load_store, save_store
from jaydiff.diff import diff_full as jay_diff_full
from carconnectivity.errors import AuthenticationError, TemporaryAuthenticationError
from volkswagencarnet.vw_exceptions import AuthenticationError
log = logging.getLogger(__name__)
@@ -26,18 +26,18 @@ def run(args: argparse.Namespace) -> None:
sys.exit(1)
if args.dry:
log.info("Dry-run mode — skipping CarConnectivity login")
log.info("Dry-run mode — skipping volkswagencarnet login")
wc = None
vehicle = None
vin = args.vin or "UNKNOWN"
else:
log.info("Connecting via CarConnectivity")
log.info("Connecting via volkswagencarnet")
wc = we_connect.connect(args.username, args.password)
vehicle, err = we_connect.select_vehicle(wc, args.vin)
if err:
log.error(err)
sys.exit(1)
vin = vehicle.vin.value
vin = vehicle.vin
log.info("Vehicle: %s", vin)
@@ -98,7 +98,7 @@ def run(args: argparse.Namespace) -> None:
log.info("Record #%d saved at %s", len(store["records"]), snapshot["ts"])
except KeyboardInterrupt:
raise
except (AuthenticationError, TemporaryAuthenticationError):
except AuthenticationError:
log.warning("Authentication error — will retry at next interval")
except Exception:
log.exception("Collection failed — will retry at next interval")