Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 0 additions & 33 deletions packages/modules/vehicles/vwid/api.py

This file was deleted.

156 changes: 83 additions & 73 deletions packages/modules/vehicles/vwid/libvwid.py
Original file line number Diff line number Diff line change
Expand Up @@ -1391,10 +1391,14 @@ async def validate_login(self):
return True


class vwid:
class vwid():

connection = {}

def __init__(self, session):
self.session = session
self.log = logging.getLogger(__name__)
# self.log = logging.getLogger(__name__)
# self.connection = {}

def set_vin(self, vin):
self.vin = vin
Expand All @@ -1407,75 +1411,81 @@ def set_jobs(self, jobs):
self.jobs_string = ','.join(jobs)

async def get_status(self):
global connection
async with aiohttp.ClientSession(headers={'Connection': 'keep-alive'}) as session:
_now = datetime.now(UTC).strftime('%Y-%m-%dT%H:%M:%SZ')
data = {}
data['charging'] = {}
data['charging']['batteryStatus'] = {}
data['charging']['batteryStatus']['value'] = {}
data['charging']['batteryStatus']['value']['currentSOC_pct'] = str(0)
data['charging']['batteryStatus']['value']['cruisingRangeElectric_km'] = str(0)
data['charging']['batteryStatus']['value']['carCapturedTimestamp'] = _now

if 'connection' not in globals() or connection is None:
connection = {}
if self.username not in connection or connection[self.username] != self.username:
_LOGGER.debug("create new connection")
connection[self.username] = Connection(session, self.username, self.password)
connection[self.username]._session_tokens['identity'] = {}
connection[self.username]._session_tokens['Legacy'] = {}
for token in self.tokens:
connection[self.username]._session_tokens['identity'][token] = self.tokens[token]
connection[self.username]._session_tokens['Legacy'][token] = self.tokens[token]
_conn_reuse = False
else:
_LOGGER.debug("reuse existing connection")
connection[self.username]._session = session
_conn_reuse = True
try:
if not _conn_reuse:
_doLogin_result = await connection[self.username].doLogin()
_LOGGER.debug("after 1st doLogin, result=" + str(_doLogin_result))
if _doLogin_result:
_update_result = True
else:
_update_result = await connection[self.username].update()
_LOGGER.debug("after 1st connection.update without doLogin, result=" + str(_update_result))
if not _update_result:
_doLogin_result = await connection[self.username].doLogin()
_LOGGER.debug("after 2nd doLogin, result=" + str(_doLogin_result))
try:
async with aiohttp.ClientSession(headers={'Connection': 'keep-alive'}) as session:
_now = datetime.now(UTC).strftime('%Y-%m-%dT%H:%M:%SZ')
data = {}
data['charging'] = {}
data['charging']['batteryStatus'] = {}
data['charging']['batteryStatus']['value'] = {}
data['charging']['batteryStatus']['value']['currentSOC_pct'] = str(0)
data['charging']['batteryStatus']['value']['cruisingRangeElectric_km'] = str(0)
data['charging']['batteryStatus']['value']['carCapturedTimestamp'] = _now

try:
_k = str(vwid.connection.keys())
_LOGGER.info(f"libvwid.get_status connections at entry: vwid.connections.keys={_k}")
if self.username not in vwid.connection:
_LOGGER.info(f"create new connection, key={self.username}")
vwid.connection[self.username] = Connection(session, self.username, self.password)
self._connection = vwid.connection[self.username]
vwid.connection[self.username]._session_tokens['identity'] = {}
vwid.connection[self.username]._session_tokens['Legacy'] = {}
for token in self.tokens:
vwid.connection[self.username]._session_tokens['identity'][token] = self.tokens[token]
vwid.connection[self.username]._session_tokens['Legacy'][token] = self.tokens[token]
_conn_reuse = False
else:
_LOGGER.info(f"reuse existing connection, key={self.username}")
vwid.connection[self.username]._session = session
_conn_reuse = True
if not _conn_reuse:
_doLogin_result = await vwid.connection[self.username].doLogin()
_LOGGER.debug("after 1st doLogin, result=" + str(_doLogin_result))
if _doLogin_result:
_update_result = await connection[self.username].update()
_LOGGER.debug("after 2nd connection.update, result=" + str(_update_result))
else:
_LOGGER.debug("retry doLogin failed, exit")
return data
if _update_result:
_LOGGER.debug("update/doLogin look OK, get results")
for vehicle in connection[self.username].vehicles:
_LOGGER.debug("vehicle loop: " + str(vehicle) + ", self.vin=" + str(self.vin))
if str(vehicle) == str(self.vin):
_LOGGER.debug("vehicle loop match: " + str(vehicle) + ", self.vin=" + str(self.vin))
soc = vehicle._states['charging']['batteryStatus']['value']['currentSOC_pct']
range = vehicle._states['charging']['batteryStatus']['value']['cruisingRangeElectric_km']
ts = vehicle._states['charging']['batteryStatus']['value']['carCapturedTimestamp']
_LOGGER.debug("vehicle =" + str(vehicle))
_LOGGER.debug("soc =" + str(soc))
_LOGGER.debug("range =" + str(range))
_LOGGER.debug("timestamp=" + str(ts))
tsxx = ts.strftime('%Y-%m-%dT%H:%M:%SZ')
_LOGGER.debug("timestampxx=" + str(tsxx))
data['charging']['batteryStatus']['value']['currentSOC_pct'] = str(soc)
data['charging']['batteryStatus']['value']['cruisingRangeElectric_km'] = str(range)
data['charging']['batteryStatus']['value']['carCapturedTimestamp'] = str(tsxx)
_LOGGER.debug("return data =" + to_json(data, indent=4))
for token in connection[self.username]._session_tokens['identity']:
self.tokens[token] = connection[self.username]._session_tokens['identity'][token]
return data
else:
_LOGGER.warning("get_status rsp. update failed, return soc 0")
return data
except Exception as error:
_LOGGER.exception("get_status failed, return soc 0, exception=" + str(error))
return data
_update_result = True
else:
_update_result = await vwid.connection[self.username].update()
_LOGGER.debug("after 1st connection.update without doLogin, result=" + str(_update_result))
if not _update_result:
_doLogin_result = await vwid.connection[self.username].doLogin()
_LOGGER.debug("after 2nd doLogin, result=" + str(_doLogin_result))
if _doLogin_result:
_update_result = await vwid.connection[self.username].update()
_LOGGER.debug("after 2nd connection.update, result=" + str(_update_result))
else:
_LOGGER.error("retry doLogin failed, exit")
raise Exception("Login failed")
if _update_result:
_LOGGER.debug("update/doLogin look OK, get results")
for vehicle in vwid.connection[self.username].vehicles:
_LOGGER.debug("vehicle loop: " + str(vehicle) + ", self.vin=" + str(self.vin))
if str(vehicle) == str(self.vin):
_LOGGER.debug("vehicle loop match: " + str(vehicle) + ", self.vin=" + str(self.vin))
soc = vehicle._states['charging']['batteryStatus']['value']['currentSOC_pct']
range =\
vehicle._states['charging']['batteryStatus']['value']['cruisingRangeElectric_km']
ts = vehicle._states['charging']['batteryStatus']['value']['carCapturedTimestamp']
_LOGGER.debug("vehicle =" + str(vehicle))
_LOGGER.debug("soc =" + str(soc))
_LOGGER.debug("range =" + str(range))
_LOGGER.debug("timestamp=" + str(ts))
tsxx = ts.strftime('%Y-%m-%dT%H:%M:%SZ')
_LOGGER.debug("timestampxx=" + str(tsxx))
data['charging']['batteryStatus']['value']['currentSOC_pct'] = str(soc)
data['charging']['batteryStatus']['value']['cruisingRangeElectric_km'] = str(range)
data['charging']['batteryStatus']['value']['carCapturedTimestamp'] = str(tsxx)
_LOGGER.debug("return data =" + to_json(data, indent=4))
for token in vwid.connection[self.username]._session_tokens['identity']:
self.tokens[token] =\
vwid.connection[self.username]._session_tokens['identity'][token]
return data
else:
_LOGGER.error("get_status rsp. update failed, raise exception")
raise Exception("get_status: keine Daten empfangen")
except Exception as error:
_LOGGER.exception("get_status failed 1, raise exception, exception=" + str(error))
raise Exception(error)
except Exception as error:
_LOGGER.exception("get_status failed 0, raise exception=" + str(error))
raise Exception(error)
44 changes: 21 additions & 23 deletions packages/modules/vehicles/vwid/soc.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,41 @@
from typing import List

import aiohttp
import logging
from asyncio import new_event_loop, set_event_loop
from typing import Union

from helpermodules.cli import run_using_positional_cli_args
from modules.common import store
from modules.common.abstract_device import DeviceDescriptor
from modules.common.abstract_vehicle import VehicleUpdateData
from modules.common.component_state import CarState
from modules.common.configurable_vehicle import ConfigurableVehicle
from modules.vehicles.vwid import api
from modules.vehicles.vwid.config import VWId, VWIdConfiguration

from modules.vehicles.vwid.config import VWId
from modules.vehicles.vwid import libvwid
from modules.vehicles.vwgroup.vwgroup import VwGroup

log = logging.getLogger(__name__)


def fetch(vehicle_update_data: VehicleUpdateData, config: VWId, vehicle: int) -> CarState:
soc, range, soc_ts, soc_tsX = api.fetch_soc(config, vehicle)
log.info("Result: soc=" + str(soc)+", range=" + str(range) + "@" + soc_ts)
return CarState(soc=soc, range=range, soc_timestamp=soc_tsX)
def create_vehicle(vehicle_config: VWId, vehicle: int):
def fetch() -> CarState:
nonlocal vw_group

# async method, called from sync fetch_soc, required because libvwid expect async environment
async def _fetch_soc() -> Union[int, float, str]:
async with aiohttp.ClientSession() as session:
return await vw_group.request_data(libvwid.vwid(session))

loop = new_event_loop()
set_event_loop(loop)
soc, range, soc_ts, soc_tsX = loop.run_until_complete(_fetch_soc())
return CarState(soc=soc, range=range, soc_timestamp=soc_tsX)

vw_group = VwGroup(vehicle_config, vehicle)

def create_vehicle(vehicle_config: VWId, vehicle: int):
def updater(vehicle_update_data: VehicleUpdateData) -> CarState:
return fetch(vehicle_update_data, vehicle_config, vehicle)
return fetch()
return ConfigurableVehicle(vehicle_config=vehicle_config,
component_updater=updater,
vehicle=vehicle,
calc_while_charging=vehicle_config.configuration.calculate_soc)


def vwid_update(user_id: str, password: str, vin: str, refreshToken: str, charge_point: int):
log.debug("vwid: user_id="+user_id+"vin="+vin+"charge_point="+str(charge_point))
store.get_car_value_store(charge_point).store.set(
fetch(None, VWId(configuration=VWIdConfiguration(user_id, password, vin, refreshToken)), charge_point))


def main(argv: List[str]):
run_using_positional_cli_args(vwid_update, argv)


device_descriptor = DeviceDescriptor(configuration_factory=VWId)