Files
we_monitor/server/we_connect.py
T
jensandClaude Sonnet 4.6 bc424310b5 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>
2026-05-28 22:50:57 +02:00

65 lines
1.8 KiB
Python

import asyncio
import logging
import aiohttp
from volkswagencarnet.vw_connection import Connection
from volkswagencarnet.vw_exceptions import AuthenticationError # noqa: F401 — re-exported for collect.py
log = logging.getLogger(__name__)
class _Session:
"""Holds the asyncio event loop, aiohttp session, and Connection together."""
def __init__(
self,
loop: asyncio.AbstractEventLoop,
session: aiohttp.ClientSession,
connection: Connection,
) -> None:
self._loop = loop
self._http_session = session
self.connection = connection
def run(self, coro):
return self._loop.run_until_complete(coro)
@property
def vehicles(self):
return self.connection.vehicles
def connect(username: str, password: str) -> _Session:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
async def _do():
session = aiohttp.ClientSession(headers={"Connection": "keep-alive"})
conn = Connection(session, username, password)
ok = await conn.doLogin()
if not ok:
await session.close()
raise AuthenticationError("Login failed")
return session, conn
session, conn = loop.run_until_complete(_do())
return _Session(loop, session, conn)
def select_vehicle(wc: _Session, vin: str | None):
"""Return (vehicle, error_message). error_message is None on success."""
vehicles = wc.vehicles
if not vehicles:
return None, "No vehicles found in this account"
if vin:
vehicle = next((v for v in vehicles if v.vin == vin), None)
if not vehicle:
available = [v.vin for v in vehicles]
return None, f"VIN {vin} not found. Available: {available}"
return vehicle, None
return vehicles[0], None
def update(wc: _Session) -> None:
wc.run(wc.connection.update())