pycupra 0.1.12__py3-none-any.whl → 0.1.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- example/PyCupra.py +611 -0
- example/PyCupra_ExportDrivingData.py +113 -0
- pycupra/connection.py +78 -68
- pycupra/dashboard.py +36 -36
- pycupra/firebase.py +11 -8
- pycupra/firebase_messaging/android_checkin_pb2.pyi +257 -257
- pycupra/firebase_messaging/fcmpushclient.py +8 -7
- pycupra/firebase_messaging/fcmregister.py +3 -3
- pycupra/utilities.py +2 -26
- pycupra/vehicle.py +299 -226
- pycupra-0.1.14.dist-info/METADATA +63 -0
- {pycupra-0.1.12.dist-info → pycupra-0.1.14.dist-info}/RECORD +15 -14
- pycupra-0.1.14.dist-info/top_level.txt +3 -0
- pycupra/__version__.py +0 -6
- pycupra-0.1.12.dist-info/METADATA +0 -13
- pycupra-0.1.12.dist-info/top_level.txt +0 -1
- {pycupra-0.1.12.dist-info → pycupra-0.1.14.dist-info}/WHEEL +0 -0
- {pycupra-0.1.12.dist-info → pycupra-0.1.14.dist-info}/licenses/LICENSE +0 -0
pycupra/vehicle.py
CHANGED
@@ -5,6 +5,7 @@ import re
|
|
5
5
|
import logging
|
6
6
|
import asyncio
|
7
7
|
import json
|
8
|
+
from typing import Any
|
8
9
|
|
9
10
|
from copy import deepcopy
|
10
11
|
from datetime import datetime, timedelta, timezone
|
@@ -100,7 +101,7 @@ class Vehicle:
|
|
100
101
|
|
101
102
|
#### API get and set functions ####
|
102
103
|
# Init and update vehicle data
|
103
|
-
async def discover(self):
|
104
|
+
async def discover(self) -> None:
|
104
105
|
"""Discover vehicle and initial data."""
|
105
106
|
#await asyncio.gather(
|
106
107
|
# self.get_basiccardata(),
|
@@ -133,9 +134,6 @@ class Vehicle:
|
|
133
134
|
self._relevantCapabilties[id].update(data)
|
134
135
|
else:
|
135
136
|
_LOGGER.warning(f"No capabilities information stored for vehicle with VIN {self.vin}")
|
136
|
-
|
137
|
-
|
138
|
-
|
139
137
|
|
140
138
|
# Get URLs for model image
|
141
139
|
self._modelimages = await self.get_modelimageurl()
|
@@ -260,7 +258,7 @@ class Vehicle:
|
|
260
258
|
"""Fetch the URL for model image."""
|
261
259
|
return await self._connection.getModelImageURL(self.vin, self._apibase)
|
262
260
|
|
263
|
-
async def get_basiccardata(self):
|
261
|
+
async def get_basiccardata(self) -> bool:
|
264
262
|
"""Fetch basic car data."""
|
265
263
|
data = await self._connection.getBasicCarData(self.vin, self._apibase)
|
266
264
|
if data:
|
@@ -270,7 +268,7 @@ class Vehicle:
|
|
270
268
|
_LOGGER.debug('Could not fetch basic car data')
|
271
269
|
return False
|
272
270
|
|
273
|
-
async def get_mileage(self):
|
271
|
+
async def get_mileage(self) -> bool:
|
274
272
|
"""Fetch basic car data."""
|
275
273
|
data = await self._connection.getMileage(self.vin, self._apibase)
|
276
274
|
if data:
|
@@ -281,7 +279,7 @@ class Vehicle:
|
|
281
279
|
_LOGGER.debug('Could not fetch mileage data')
|
282
280
|
return False
|
283
281
|
|
284
|
-
async def get_preheater(self):
|
282
|
+
async def get_preheater(self) -> None:
|
285
283
|
"""Fetch pre-heater data if function is enabled."""
|
286
284
|
_LOGGER.info('get_preheater() not implemented yet')
|
287
285
|
#if self._relevantCapabilties.get('#dont know the name for the preheater capability', {}).get('active', False):
|
@@ -294,7 +292,7 @@ class Vehicle:
|
|
294
292
|
#else:
|
295
293
|
# self._requests.pop('preheater', None)
|
296
294
|
|
297
|
-
async def get_climater(self):
|
295
|
+
async def get_climater(self) -> bool:
|
298
296
|
"""Fetch climater data if function is enabled."""
|
299
297
|
if self._relevantCapabilties.get('climatisation', {}).get('active', False):
|
300
298
|
data = await self._connection.getClimater(self.vin, self._apibase, deepcopy(self.attrs.get('climater',{})))
|
@@ -304,11 +302,11 @@ class Vehicle:
|
|
304
302
|
return True
|
305
303
|
else:
|
306
304
|
_LOGGER.debug('Could not fetch climater data')
|
307
|
-
|
305
|
+
return False
|
308
306
|
#else:
|
309
307
|
# self._requests.pop('climatisation', None)
|
310
308
|
|
311
|
-
async def get_trip_statistic(self):
|
309
|
+
async def get_trip_statistic(self) -> bool:
|
312
310
|
"""Fetch trip data if function is enabled."""
|
313
311
|
if self._relevantCapabilties.get('tripStatistics', {}).get('active', False):
|
314
312
|
data = await self._connection.getTripStatistics(self.vin, self._apibase, self._relevantCapabilties['tripStatistics'].get('supportsCyclicTrips', False))
|
@@ -317,9 +315,9 @@ class Vehicle:
|
|
317
315
|
return True
|
318
316
|
else:
|
319
317
|
_LOGGER.debug('Could not fetch trip statistics')
|
320
|
-
|
318
|
+
return False
|
321
319
|
|
322
|
-
async def get_position(self):
|
320
|
+
async def get_position(self) -> bool:
|
323
321
|
"""Fetch position data if function is enabled."""
|
324
322
|
if self._relevantCapabilties.get('parkingPosition', {}).get('active', False):
|
325
323
|
data = await self._connection.getPosition(self.vin, self._apibase)
|
@@ -338,9 +336,9 @@ class Vehicle:
|
|
338
336
|
return True
|
339
337
|
else:
|
340
338
|
_LOGGER.debug('Could not fetch any positional data')
|
341
|
-
|
339
|
+
return False
|
342
340
|
|
343
|
-
async def get_vehicleHealthWarnings(self):
|
341
|
+
async def get_vehicleHealthWarnings(self) -> bool:
|
344
342
|
if self._relevantCapabilties.get('vehicleHealthWarnings', {}).get('active', False):
|
345
343
|
data = await self._connection.getVehicleHealthWarnings(self.vin, self._apibase)
|
346
344
|
if data:
|
@@ -348,9 +346,9 @@ class Vehicle:
|
|
348
346
|
return True
|
349
347
|
else:
|
350
348
|
_LOGGER.debug('Could not fetch vehicle health warnings')
|
351
|
-
|
349
|
+
return False
|
352
350
|
|
353
|
-
async def get_statusreport(self):
|
351
|
+
async def get_statusreport(self) -> bool:
|
354
352
|
"""Fetch status data if function is enabled."""
|
355
353
|
if self._relevantCapabilties.get('state', {}).get('active', False):
|
356
354
|
data = await self._connection.getVehicleStatusReport(self.vin, self._apibase)
|
@@ -360,9 +358,9 @@ class Vehicle:
|
|
360
358
|
return True
|
361
359
|
else:
|
362
360
|
_LOGGER.debug('Could not fetch status report')
|
363
|
-
|
361
|
+
return False
|
364
362
|
|
365
|
-
async def get_maintenance(self):
|
363
|
+
async def get_maintenance(self) -> bool:
|
366
364
|
"""Fetch maintenance data if function is enabled."""
|
367
365
|
if self._relevantCapabilties.get('vehicleHealthInspection', {}).get('active', False):
|
368
366
|
data = await self._connection.getMaintenance(self.vin, self._apibase)
|
@@ -371,9 +369,9 @@ class Vehicle:
|
|
371
369
|
return True
|
372
370
|
else:
|
373
371
|
_LOGGER.debug('Could not fetch status report')
|
374
|
-
|
372
|
+
return False
|
375
373
|
|
376
|
-
async def get_charger(self):
|
374
|
+
async def get_charger(self) -> bool:
|
377
375
|
"""Fetch charger data if function is enabled."""
|
378
376
|
if self._relevantCapabilties.get('charging', {}).get('active', False):
|
379
377
|
data = await self._connection.getCharger(self.vin, self._apibase, deepcopy(self.attrs.get('charging',{})))
|
@@ -383,9 +381,9 @@ class Vehicle:
|
|
383
381
|
return True
|
384
382
|
else:
|
385
383
|
_LOGGER.debug('Could not fetch charger data')
|
386
|
-
|
384
|
+
return False
|
387
385
|
|
388
|
-
async def get_departure_timers(self):
|
386
|
+
async def get_departure_timers(self) -> bool:
|
389
387
|
"""Fetch timer data if function is enabled."""
|
390
388
|
if self._relevantCapabilties.get('departureTimers', {}).get('active', False):
|
391
389
|
data = await self._connection.getDeparturetimer(self.vin, self._apibase)
|
@@ -395,9 +393,9 @@ class Vehicle:
|
|
395
393
|
return True
|
396
394
|
else:
|
397
395
|
_LOGGER.debug('Could not fetch timers')
|
398
|
-
|
396
|
+
return False
|
399
397
|
|
400
|
-
async def get_departure_profiles(self):
|
398
|
+
async def get_departure_profiles(self) -> bool:
|
401
399
|
"""Fetch timer data if function is enabled."""
|
402
400
|
if self._relevantCapabilties.get('departureProfiles', {}).get('active', False):
|
403
401
|
data = await self._connection.getDepartureprofiles(self.vin, self._apibase)
|
@@ -407,7 +405,7 @@ class Vehicle:
|
|
407
405
|
return True
|
408
406
|
else:
|
409
407
|
_LOGGER.debug('Could not fetch timers')
|
410
|
-
|
408
|
+
return False
|
411
409
|
|
412
410
|
#async def wait_for_request(self, section, request, retryCount=36):
|
413
411
|
"""Update status of outstanding requests."""
|
@@ -431,9 +429,10 @@ class Vehicle:
|
|
431
429
|
|
432
430
|
# Data set functions
|
433
431
|
# API endpoint charging
|
434
|
-
async def set_charger_current(self, value):
|
432
|
+
async def set_charger_current(self, value) -> bool:
|
435
433
|
"""Set charger current"""
|
436
434
|
if self.is_charging_supported:
|
435
|
+
data: dict[str, Any] = {}
|
437
436
|
# Set charger max ampere to integer value
|
438
437
|
if isinstance(value, int):
|
439
438
|
if 1 <= int(value) <= 255:
|
@@ -467,7 +466,7 @@ class Vehicle:
|
|
467
466
|
_LOGGER.error('No charger support.')
|
468
467
|
raise SeatInvalidRequestException('No charger support.')
|
469
468
|
|
470
|
-
async def set_charger_target_soc(self, value):
|
469
|
+
async def set_charger_target_soc(self, value) -> bool:
|
471
470
|
"""Set target state of charge"""
|
472
471
|
if self.is_charging_supported:
|
473
472
|
if isinstance(value, int):
|
@@ -494,7 +493,7 @@ class Vehicle:
|
|
494
493
|
_LOGGER.error('No charger support.')
|
495
494
|
raise SeatInvalidRequestException('No charger support.')
|
496
495
|
|
497
|
-
async def set_charger(self, action, data=None):
|
496
|
+
async def set_charger(self, action, data=None) -> bool:
|
498
497
|
"""Charging actions."""
|
499
498
|
if not self._relevantCapabilties.get('charging', {}).get('active', False):
|
500
499
|
_LOGGER.info('Remote start/stop of charger is not supported.')
|
@@ -572,7 +571,7 @@ class Vehicle:
|
|
572
571
|
raise SeatException(f'Failed to execute set charger - {error}')
|
573
572
|
|
574
573
|
# API endpoint departuretimer
|
575
|
-
async def set_charge_limit(self, limit=50):
|
574
|
+
async def set_charge_limit(self, limit=50) -> bool:
|
576
575
|
""" Set minimum state of charge limit for departure timers or departure profiles. """
|
577
576
|
if (not self._relevantCapabilties.get('departureTimers', {}).get('active', False) and
|
578
577
|
not self._relevantCapabilties.get('departureProfiles', {}).get('active', False) and
|
@@ -601,10 +600,11 @@ class Vehicle:
|
|
601
600
|
else:
|
602
601
|
raise SeatInvalidRequestException(f'Charge limit "{limit}" is not supported.')
|
603
602
|
return await self._set_departure_profiles(data, action='minSocPercentage')
|
603
|
+
return False
|
604
604
|
|
605
|
-
async def set_timer_active(self, id=1, action='off'):
|
605
|
+
async def set_timer_active(self, id=1, action='off') -> bool:
|
606
606
|
""" Activate/deactivate departure timers. """
|
607
|
-
data = {}
|
607
|
+
data: dict[str, Any] = {}
|
608
608
|
supported = "is_departure" + str(id) + "_supported"
|
609
609
|
if getattr(self, supported) is not True:
|
610
610
|
raise SeatConfigException(f'This vehicle does not support timer id {id}.')
|
@@ -629,9 +629,9 @@ class Vehicle:
|
|
629
629
|
else:
|
630
630
|
raise SeatInvalidRequestException('Departure timers are not supported.')
|
631
631
|
|
632
|
-
async def set_timer_schedule(self, id, schedule={}):
|
632
|
+
async def set_timer_schedule(self, id, schedule={}) -> bool:
|
633
633
|
""" Set departure timer schedule. """
|
634
|
-
data = {}
|
634
|
+
data: dict[str, Any] = {}
|
635
635
|
# Validate required user inputs
|
636
636
|
supported = "is_departure" + str(id) + "_supported"
|
637
637
|
if getattr(self, supported) is not True:
|
@@ -758,7 +758,7 @@ class Vehicle:
|
|
758
758
|
_LOGGER.info('Departure timers are not supported.')
|
759
759
|
raise SeatInvalidRequestException('Departure timers are not supported.')
|
760
760
|
|
761
|
-
async def _set_timers(self, data=None):
|
761
|
+
async def _set_timers(self, data=None) -> bool:
|
762
762
|
""" Set departure timers. """
|
763
763
|
if not self._relevantCapabilties.get('departureTimers', {}).get('active', False):
|
764
764
|
raise SeatInvalidRequestException('Departure timers are not supported.')
|
@@ -829,7 +829,7 @@ class Vehicle:
|
|
829
829
|
self._requests['departuretimer'] = {'status': 'Exception'}
|
830
830
|
raise SeatException('Failed to set departure timer schedule')
|
831
831
|
|
832
|
-
async def set_departure_profile_schedule(self, id, schedule={}):
|
832
|
+
async def set_departure_profile_schedule(self, id, schedule={}) -> bool:
|
833
833
|
""" Set departure profile schedule. """
|
834
834
|
data = {}
|
835
835
|
# Validate required user inputs
|
@@ -921,7 +921,7 @@ class Vehicle:
|
|
921
921
|
_LOGGER.info('Departure profiles are not supported.')
|
922
922
|
raise SeatInvalidRequestException('Departure profiles are not supported.')
|
923
923
|
|
924
|
-
async def set_departure_profile_active(self, id=1, action='off'):
|
924
|
+
async def set_departure_profile_active(self, id=1, action='off') -> bool:
|
925
925
|
""" Activate/deactivate departure profiles. """
|
926
926
|
data = {}
|
927
927
|
supported = "is_departure_profile" + str(id) + "_supported"
|
@@ -950,7 +950,7 @@ class Vehicle:
|
|
950
950
|
else:
|
951
951
|
raise SeatInvalidRequestException('Departure profiles are not supported.')
|
952
952
|
|
953
|
-
async def _set_departure_profiles(self, data=None, action=None):
|
953
|
+
async def _set_departure_profiles(self, data=None, action=None) -> bool:
|
954
954
|
""" Set departure profiles. """
|
955
955
|
if not self._relevantCapabilties.get('departureProfiles', {}).get('active', False):
|
956
956
|
raise SeatInvalidRequestException('Departure profiles are not supported.')
|
@@ -1014,7 +1014,7 @@ class Vehicle:
|
|
1014
1014
|
|
1015
1015
|
|
1016
1016
|
# Send a destination to vehicle
|
1017
|
-
async def send_destination(self, destination=None):
|
1017
|
+
async def send_destination(self, destination=None) -> bool:
|
1018
1018
|
""" Send destination to vehicle. """
|
1019
1019
|
|
1020
1020
|
if destination==None:
|
@@ -1037,7 +1037,7 @@ class Vehicle:
|
|
1037
1037
|
raise SeatException('Failed to send destination to vehicle')
|
1038
1038
|
|
1039
1039
|
# Climatisation electric/auxiliary/windows (CLIMATISATION)
|
1040
|
-
async def set_climatisation_temp(self, temperature=20):
|
1040
|
+
async def set_climatisation_temp(self, temperature=20) -> bool:
|
1041
1041
|
"""Set climatisation target temp."""
|
1042
1042
|
if self.is_electric_climatisation_supported or self.is_auxiliary_climatisation_supported:
|
1043
1043
|
if 16 <= float(temperature) <= 30:
|
@@ -1055,7 +1055,7 @@ class Vehicle:
|
|
1055
1055
|
_LOGGER.error('No climatisation support.')
|
1056
1056
|
raise SeatInvalidRequestException('No climatisation support.')
|
1057
1057
|
|
1058
|
-
async def set_window_heating(self, action = 'stop'):
|
1058
|
+
async def set_window_heating(self, action = 'stop') -> bool:
|
1059
1059
|
"""Turn on/off window heater."""
|
1060
1060
|
if self.is_window_heater_supported:
|
1061
1061
|
if action in ['start', 'stop']:
|
@@ -1068,7 +1068,7 @@ class Vehicle:
|
|
1068
1068
|
_LOGGER.error('No climatisation support.')
|
1069
1069
|
raise SeatInvalidRequestException('No climatisation support.')
|
1070
1070
|
|
1071
|
-
async def set_battery_climatisation(self, mode = False):
|
1071
|
+
async def set_battery_climatisation(self, mode = False) -> bool:
|
1072
1072
|
"""Turn on/off electric climatisation from battery."""
|
1073
1073
|
if self.is_electric_climatisation_supported:
|
1074
1074
|
if mode in [True, False]:
|
@@ -1086,7 +1086,7 @@ class Vehicle:
|
|
1086
1086
|
_LOGGER.error('No climatisation support.')
|
1087
1087
|
raise SeatInvalidRequestException('No climatisation support.')
|
1088
1088
|
|
1089
|
-
async def set_climatisation(self, mode = 'off', temp = None, hvpower = None, spin = None):
|
1089
|
+
async def set_climatisation(self, mode = 'off', temp = None, hvpower = None, spin = None) -> bool:
|
1090
1090
|
"""Turn on/off climatisation with electric/auxiliary heater."""
|
1091
1091
|
data = {}
|
1092
1092
|
# Validate user input
|
@@ -1128,12 +1128,12 @@ class Vehicle:
|
|
1128
1128
|
return await self._set_climater(mode, data, spin)
|
1129
1129
|
else:
|
1130
1130
|
_LOGGER.error('Can not stop climatisation because no running request was found')
|
1131
|
-
return
|
1131
|
+
return False
|
1132
1132
|
else:
|
1133
1133
|
_LOGGER.error('No climatisation support.')
|
1134
1134
|
raise SeatInvalidRequestException('No climatisation support.')
|
1135
1135
|
|
1136
|
-
async def _set_climater(self, mode, data, spin = False):
|
1136
|
+
async def _set_climater(self, mode, data, spin = False) -> bool:
|
1137
1137
|
"""Climater actions."""
|
1138
1138
|
if not self._relevantCapabilties.get('climatisation', {}).get('active', False):
|
1139
1139
|
_LOGGER.info('Remote control of climatisation functions is not supported.')
|
@@ -1202,7 +1202,7 @@ class Vehicle:
|
|
1202
1202
|
raise SeatException('Climatisation action failed')
|
1203
1203
|
|
1204
1204
|
# Parking heater heating/ventilation (RS)
|
1205
|
-
async def set_pheater(self, mode, spin):
|
1205
|
+
async def set_pheater(self, mode, spin) -> bool:
|
1206
1206
|
"""Set the mode for the parking heater."""
|
1207
1207
|
if not self.is_pheater_heating_supported:
|
1208
1208
|
_LOGGER.error('No parking heater support.')
|
@@ -1245,7 +1245,7 @@ class Vehicle:
|
|
1245
1245
|
raise SeatException('Pre-heater action failed')
|
1246
1246
|
|
1247
1247
|
# Lock
|
1248
|
-
async def set_lock(self, action, spin):
|
1248
|
+
async def set_lock(self, action, spin) -> bool:
|
1249
1249
|
"""Remote lock and unlock actions."""
|
1250
1250
|
#if not self._services.get('rlu_v1', False):
|
1251
1251
|
if not self._relevantCapabilties.get('transactionHistoryLockUnlock', {}).get('active', False):
|
@@ -1263,8 +1263,7 @@ class Vehicle:
|
|
1263
1263
|
raise SeatInvalidRequestException(f'Invalid lock action: {action}')
|
1264
1264
|
try:
|
1265
1265
|
self._requests['latest'] = 'Lock'
|
1266
|
-
|
1267
|
-
response = await self._connection.setLock(self.vin, self._apibase, action, data, spin)
|
1266
|
+
response = await self._connection.setLock(self.vin, self._apibase, action, spin)
|
1268
1267
|
if not response:
|
1269
1268
|
self._requests['lock'] = {'status': 'Failed'}
|
1270
1269
|
_LOGGER.error(f'Failed to {action} vehicle')
|
@@ -1307,7 +1306,7 @@ class Vehicle:
|
|
1307
1306
|
raise SeatException('Lock action failed')
|
1308
1307
|
|
1309
1308
|
# Honk and flash (RHF)
|
1310
|
-
async def set_honkandflash(self, action, lat=None, lng=None):
|
1309
|
+
async def set_honkandflash(self, action, lat=None, lng=None) -> bool:
|
1311
1310
|
"""Turn on/off honk and flash."""
|
1312
1311
|
if not self._relevantCapabilties.get('honkAndFlash', {}).get('active', False):
|
1313
1312
|
_LOGGER.info('Remote honk and flash is not supported.')
|
@@ -1364,7 +1363,7 @@ class Vehicle:
|
|
1364
1363
|
raise SeatException('Honk and flash action failed')
|
1365
1364
|
|
1366
1365
|
# Refresh vehicle data (VSR)
|
1367
|
-
async def set_refresh(self):
|
1366
|
+
async def set_refresh(self) -> bool:
|
1368
1367
|
"""Wake up vehicle and update status data."""
|
1369
1368
|
if not self._relevantCapabilties.get('state', {}).get('active', False):
|
1370
1369
|
_LOGGER.info('Data refresh is not supported.')
|
@@ -1443,12 +1442,14 @@ class Vehicle:
|
|
1443
1442
|
return self._properties.get('vehicleNickname', '')
|
1444
1443
|
|
1445
1444
|
@property
|
1446
|
-
def is_nickname_supported(self):
|
1445
|
+
def is_nickname_supported(self) -> bool:
|
1447
1446
|
if self._properties.get('vehicleNickname', False):
|
1448
1447
|
return True
|
1448
|
+
else:
|
1449
|
+
return False
|
1449
1450
|
|
1450
1451
|
@property
|
1451
|
-
def deactivated(self):
|
1452
|
+
def deactivated(self) -> bool:
|
1452
1453
|
if 'mode' in self._connectivities:
|
1453
1454
|
if self._connectivities.get('mode','')=='online':
|
1454
1455
|
return False
|
@@ -1458,7 +1459,7 @@ class Vehicle:
|
|
1458
1459
|
# return car.get('deactivated', False)
|
1459
1460
|
|
1460
1461
|
@property
|
1461
|
-
def is_deactivated_supported(self):
|
1462
|
+
def is_deactivated_supported(self) -> bool:
|
1462
1463
|
if 'mode' in self._connectivities:
|
1463
1464
|
return True
|
1464
1465
|
return False
|
@@ -1473,10 +1474,12 @@ class Vehicle:
|
|
1473
1474
|
return self._specification.get('factoryModel', False).get('vehicleBrand', 'Unknown')
|
1474
1475
|
|
1475
1476
|
@property
|
1476
|
-
def is_brand_supported(self):
|
1477
|
+
def is_brand_supported(self) -> bool:
|
1477
1478
|
"""Return true if brand is supported."""
|
1478
1479
|
if self._specification.get('factoryModel', False).get('vehicleBrand', False):
|
1479
1480
|
return True
|
1481
|
+
else:
|
1482
|
+
return False
|
1480
1483
|
|
1481
1484
|
@property
|
1482
1485
|
def model(self):
|
@@ -1487,10 +1490,12 @@ class Vehicle:
|
|
1487
1490
|
return self._specification.get('factoryModel', False).get('vehicleModel', 'Unknown')
|
1488
1491
|
|
1489
1492
|
@property
|
1490
|
-
def is_model_supported(self):
|
1493
|
+
def is_model_supported(self) -> bool:
|
1491
1494
|
"""Return true if model is supported."""
|
1492
1495
|
if self._specification.get('factoryModel', False).get('vehicleModel', False):
|
1493
1496
|
return True
|
1497
|
+
else:
|
1498
|
+
return False
|
1494
1499
|
|
1495
1500
|
@property
|
1496
1501
|
def model_year(self):
|
@@ -1498,10 +1503,12 @@ class Vehicle:
|
|
1498
1503
|
return self._specification.get('factoryModel', False).get('modYear', 'Unknown')
|
1499
1504
|
|
1500
1505
|
@property
|
1501
|
-
def is_model_year_supported(self):
|
1506
|
+
def is_model_year_supported(self) -> bool:
|
1502
1507
|
"""Return true if model year is supported."""
|
1503
1508
|
if self._specification.get('factoryModel', False).get('modYear', False):
|
1504
1509
|
return True
|
1510
|
+
else:
|
1511
|
+
return False
|
1505
1512
|
|
1506
1513
|
@property
|
1507
1514
|
def model_image_small(self):
|
@@ -1509,11 +1516,12 @@ class Vehicle:
|
|
1509
1516
|
return self._modelimages.get('images','').get('front_cropped','')
|
1510
1517
|
|
1511
1518
|
@property
|
1512
|
-
def is_model_image_small_supported(self):
|
1519
|
+
def is_model_image_small_supported(self) -> bool:
|
1513
1520
|
"""Return true if model image url is not None."""
|
1514
1521
|
if self._modelimages is not None:
|
1515
1522
|
if self._modelimages.get('images','').get('front_cropped','')!='':
|
1516
1523
|
return True
|
1524
|
+
return False
|
1517
1525
|
|
1518
1526
|
@property
|
1519
1527
|
def model_image_large(self):
|
@@ -1521,14 +1529,16 @@ class Vehicle:
|
|
1521
1529
|
return self._modelimages.get('images','').get('front', '')
|
1522
1530
|
|
1523
1531
|
@property
|
1524
|
-
def is_model_image_large_supported(self):
|
1532
|
+
def is_model_image_large_supported(self) -> bool:
|
1525
1533
|
"""Return true if model image url is not None."""
|
1526
1534
|
if self._modelimages is not None:
|
1527
1535
|
return True
|
1536
|
+
else:
|
1537
|
+
return False
|
1528
1538
|
|
1529
1539
|
# Lights
|
1530
1540
|
@property
|
1531
|
-
def parking_light(self):
|
1541
|
+
def parking_light(self) -> bool:
|
1532
1542
|
"""Return true if parking light is on"""
|
1533
1543
|
response = self.attrs.get('status').get('lights', 0)
|
1534
1544
|
if response == 'on':
|
@@ -1537,30 +1547,34 @@ class Vehicle:
|
|
1537
1547
|
return False
|
1538
1548
|
|
1539
1549
|
@property
|
1540
|
-
def is_parking_light_supported(self):
|
1550
|
+
def is_parking_light_supported(self) -> bool:
|
1541
1551
|
"""Return true if parking light is supported"""
|
1542
1552
|
if self.attrs.get('status', False):
|
1543
1553
|
if 'lights' in self.attrs.get('status'):
|
1544
1554
|
return True
|
1545
|
-
|
1546
|
-
return False
|
1555
|
+
return False
|
1547
1556
|
|
1548
1557
|
# Connection status
|
1549
1558
|
@property
|
1550
|
-
def last_connected(self):
|
1559
|
+
def last_connected(self) -> datetime:
|
1551
1560
|
"""Return when vehicle was last connected to connect servers."""
|
1552
1561
|
last_connected_utc = self.attrs.get('status').get('updatedAt','')
|
1553
1562
|
if isinstance(last_connected_utc, datetime):
|
1554
1563
|
last_connected = last_connected_utc.replace(tzinfo=timezone.utc).astimezone(tz=None)
|
1555
1564
|
else:
|
1556
|
-
|
1565
|
+
# it seems, that last_connected_utc was provided as a string. If the string contains a '.', then the timestamp was provided with milliseconds
|
1566
|
+
if '.' in last_connected_utc:
|
1567
|
+
last_connected = datetime.strptime(last_connected_utc,'%Y-%m-%dT%H:%M:%S.%fZ').replace(tzinfo=timezone.utc).astimezone(tz=None)
|
1568
|
+
else:
|
1569
|
+
last_connected = datetime.strptime(last_connected_utc,'%Y-%m-%dT%H:%M:%SZ').replace(tzinfo=timezone.utc).astimezone(tz=None)
|
1557
1570
|
return last_connected #.strftime('%Y-%m-%d %H:%M:%S')
|
1558
1571
|
|
1559
1572
|
@property
|
1560
|
-
def is_last_connected_supported(self):
|
1573
|
+
def is_last_connected_supported(self) -> bool:
|
1561
1574
|
"""Return when vehicle was last connected to connect servers."""
|
1562
1575
|
if 'updatedAt' in self.attrs.get('status', {}):
|
1563
1576
|
return True
|
1577
|
+
return False
|
1564
1578
|
|
1565
1579
|
# Update status
|
1566
1580
|
@property
|
@@ -1569,20 +1583,21 @@ class Vehicle:
|
|
1569
1583
|
return self._last_full_update.astimezone(tz=None)
|
1570
1584
|
|
1571
1585
|
@property
|
1572
|
-
def is_last_full_update_supported(self):
|
1586
|
+
def is_last_full_update_supported(self) -> bool:
|
1573
1587
|
"""Return when last full update for vehicle took place."""
|
1574
1588
|
if hasattr(self,'_last_full_update'):
|
1575
1589
|
return True
|
1590
|
+
return False
|
1576
1591
|
|
1577
1592
|
# Service information
|
1578
1593
|
@property
|
1579
|
-
def distance(self):
|
1594
|
+
def distance(self) -> int:
|
1580
1595
|
"""Return vehicle odometer."""
|
1581
1596
|
value = self.attrs.get('mileage').get('mileageKm', 0)
|
1582
1597
|
return int(value)
|
1583
1598
|
|
1584
1599
|
@property
|
1585
|
-
def is_distance_supported(self):
|
1600
|
+
def is_distance_supported(self) -> bool:
|
1586
1601
|
"""Return true if odometer is supported"""
|
1587
1602
|
if self.attrs.get('mileage', False):
|
1588
1603
|
if 'mileageKm' in self.attrs.get('mileage'):
|
@@ -1590,42 +1605,42 @@ class Vehicle:
|
|
1590
1605
|
return False
|
1591
1606
|
|
1592
1607
|
@property
|
1593
|
-
def service_inspection(self):
|
1608
|
+
def service_inspection(self) -> int:
|
1594
1609
|
"""Return time left until service inspection"""
|
1595
1610
|
value = -1
|
1596
1611
|
value = int(self.attrs.get('maintenance', {}).get('inspectionDueDays', 0))
|
1597
1612
|
return int(value)
|
1598
1613
|
|
1599
1614
|
@property
|
1600
|
-
def is_service_inspection_supported(self):
|
1615
|
+
def is_service_inspection_supported(self) -> bool:
|
1601
1616
|
if self.attrs.get('maintenance', False):
|
1602
1617
|
if 'inspectionDueDays' in self.attrs.get('maintenance'):
|
1603
1618
|
return True
|
1604
1619
|
return False
|
1605
1620
|
|
1606
1621
|
@property
|
1607
|
-
def service_inspection_distance(self):
|
1622
|
+
def service_inspection_distance(self) -> int:
|
1608
1623
|
"""Return time left until service inspection"""
|
1609
1624
|
value = -1
|
1610
1625
|
value = int(self.attrs.get('maintenance').get('inspectionDueKm', 0))
|
1611
1626
|
return int(value)
|
1612
1627
|
|
1613
1628
|
@property
|
1614
|
-
def is_service_inspection_distance_supported(self):
|
1629
|
+
def is_service_inspection_distance_supported(self) -> bool:
|
1615
1630
|
if self.attrs.get('maintenance', False):
|
1616
1631
|
if 'inspectionDueKm' in self.attrs.get('maintenance'):
|
1617
1632
|
return True
|
1618
1633
|
return False
|
1619
1634
|
|
1620
1635
|
@property
|
1621
|
-
def oil_inspection(self):
|
1636
|
+
def oil_inspection(self) -> int:
|
1622
1637
|
"""Return time left until oil inspection"""
|
1623
1638
|
value = -1
|
1624
1639
|
value = int(self.attrs.get('maintenance', {}).get('oilServiceDueDays', 0))
|
1625
1640
|
return int(value)
|
1626
1641
|
|
1627
1642
|
@property
|
1628
|
-
def is_oil_inspection_supported(self):
|
1643
|
+
def is_oil_inspection_supported(self) -> bool:
|
1629
1644
|
if self.attrs.get('maintenance', False):
|
1630
1645
|
if 'oilServiceDueDays' in self.attrs.get('maintenance'):
|
1631
1646
|
if self.attrs.get('maintenance').get('oilServiceDueDays', None) is not None:
|
@@ -1633,14 +1648,14 @@ class Vehicle:
|
|
1633
1648
|
return False
|
1634
1649
|
|
1635
1650
|
@property
|
1636
|
-
def oil_inspection_distance(self):
|
1651
|
+
def oil_inspection_distance(self) -> int:
|
1637
1652
|
"""Return distance left until oil inspection"""
|
1638
1653
|
value = -1
|
1639
1654
|
value = int(self.attrs.get('maintenance').get('oilServiceDueKm', 0))
|
1640
1655
|
return int(value)
|
1641
1656
|
|
1642
1657
|
@property
|
1643
|
-
def is_oil_inspection_distance_supported(self):
|
1658
|
+
def is_oil_inspection_distance_supported(self) -> bool:
|
1644
1659
|
if self.attrs.get('maintenance', False):
|
1645
1660
|
if 'oilServiceDueKm' in self.attrs.get('maintenance'):
|
1646
1661
|
if self.attrs.get('maintenance').get('oilServiceDueKm', None) is not None:
|
@@ -1648,12 +1663,12 @@ class Vehicle:
|
|
1648
1663
|
return False
|
1649
1664
|
|
1650
1665
|
@property
|
1651
|
-
def adblue_level(self):
|
1666
|
+
def adblue_level(self) -> int:
|
1652
1667
|
"""Return adblue level."""
|
1653
1668
|
return int(self.attrs.get('maintenance', {}).get('0x02040C0001', {}).get('value', 0))
|
1654
1669
|
|
1655
1670
|
@property
|
1656
|
-
def is_adblue_level_supported(self):
|
1671
|
+
def is_adblue_level_supported(self) -> bool:
|
1657
1672
|
"""Return true if adblue level is supported."""
|
1658
1673
|
if self.attrs.get('maintenance', False):
|
1659
1674
|
if '0x02040C0001' in self.attrs.get('maintenance'):
|
@@ -1664,14 +1679,14 @@ class Vehicle:
|
|
1664
1679
|
|
1665
1680
|
# Charger related states for EV and PHEV
|
1666
1681
|
@property
|
1667
|
-
def charging(self):
|
1682
|
+
def charging(self) -> int:
|
1668
1683
|
"""Return battery level"""
|
1669
1684
|
#cstate = self.attrs.get('charging').get('status').get('charging').get('state','')
|
1670
1685
|
cstate = self.attrs.get('mycar',{}).get('services',{}).get('charging',{}).get('status','')
|
1671
1686
|
return 1 if cstate in ['charging', 'Charging'] else 0
|
1672
1687
|
|
1673
1688
|
@property
|
1674
|
-
def is_charging_supported(self):
|
1689
|
+
def is_charging_supported(self) -> bool:
|
1675
1690
|
"""Return true if charging is supported"""
|
1676
1691
|
#if self.attrs.get('charging', False):
|
1677
1692
|
# if 'status' in self.attrs.get('charging', {}):
|
@@ -1694,14 +1709,14 @@ class Vehicle:
|
|
1694
1709
|
return 0
|
1695
1710
|
|
1696
1711
|
@property
|
1697
|
-
def is_min_charge_level_supported(self):
|
1712
|
+
def is_min_charge_level_supported(self) -> bool:
|
1698
1713
|
"""Return true if car supports setting the min charge level"""
|
1699
1714
|
if self.attrs.get('departuretimers', {}).get('minSocPercentage', False):
|
1700
1715
|
return True
|
1701
1716
|
return False
|
1702
1717
|
|
1703
1718
|
@property
|
1704
|
-
def battery_level(self):
|
1719
|
+
def battery_level(self) -> int:
|
1705
1720
|
"""Return battery level"""
|
1706
1721
|
#if self.attrs.get('charging', False):
|
1707
1722
|
# return int(self.attrs.get('charging').get('status', {}).get('battery', {}).get('currentSocPercentage', 0))
|
@@ -1711,7 +1726,7 @@ class Vehicle:
|
|
1711
1726
|
return 0
|
1712
1727
|
|
1713
1728
|
@property
|
1714
|
-
def is_battery_level_supported(self):
|
1729
|
+
def is_battery_level_supported(self) -> bool:
|
1715
1730
|
"""Return true if battery level is supported"""
|
1716
1731
|
#if self.attrs.get('charging', False):
|
1717
1732
|
# if 'status' in self.attrs.get('charging'):
|
@@ -1736,7 +1751,7 @@ class Vehicle:
|
|
1736
1751
|
return 0
|
1737
1752
|
|
1738
1753
|
@property
|
1739
|
-
def is_charge_max_ampere_supported(self):
|
1754
|
+
def is_charge_max_ampere_supported(self) -> bool:
|
1740
1755
|
"""Return true if Charger Max Ampere is supported"""
|
1741
1756
|
if self.attrs.get('charging', False):
|
1742
1757
|
if 'info' in self.attrs.get('charging', {}):
|
@@ -1746,14 +1761,14 @@ class Vehicle:
|
|
1746
1761
|
return False
|
1747
1762
|
|
1748
1763
|
@property
|
1749
|
-
def slow_charge(self):
|
1764
|
+
def slow_charge(self) -> bool:
|
1750
1765
|
"""Return charger max ampere setting."""
|
1751
1766
|
if self.charge_max_ampere=='reduced':
|
1752
1767
|
return True
|
1753
1768
|
return False
|
1754
1769
|
|
1755
1770
|
@property
|
1756
|
-
def is_slow_charge_supported(self):
|
1771
|
+
def is_slow_charge_supported(self) -> bool:
|
1757
1772
|
"""Return true if Slow Charge is supported"""
|
1758
1773
|
if self.is_charge_max_ampere_supported:
|
1759
1774
|
if self.charge_max_ampere in ('reduced', 'maximum'):
|
@@ -1761,7 +1776,7 @@ class Vehicle:
|
|
1761
1776
|
return False
|
1762
1777
|
|
1763
1778
|
@property
|
1764
|
-
def charging_cable_locked(self):
|
1779
|
+
def charging_cable_locked(self) -> bool:
|
1765
1780
|
"""Return plug locked state"""
|
1766
1781
|
response = ''
|
1767
1782
|
if self.attrs.get('charging', False):
|
@@ -1769,7 +1784,7 @@ class Vehicle:
|
|
1769
1784
|
return True if response in ['Locked', 'locked'] else False
|
1770
1785
|
|
1771
1786
|
@property
|
1772
|
-
def is_charging_cable_locked_supported(self):
|
1787
|
+
def is_charging_cable_locked_supported(self) -> bool:
|
1773
1788
|
"""Return true if plug locked state is supported"""
|
1774
1789
|
if self.attrs.get('charging', False):
|
1775
1790
|
if 'status' in self.attrs.get('charging'):
|
@@ -1779,7 +1794,7 @@ class Vehicle:
|
|
1779
1794
|
return False
|
1780
1795
|
|
1781
1796
|
@property
|
1782
|
-
def charging_cable_connected(self):
|
1797
|
+
def charging_cable_connected(self) -> bool:
|
1783
1798
|
"""Return plug locked state"""
|
1784
1799
|
response = ''
|
1785
1800
|
if self.attrs.get('charging', False):
|
@@ -1787,7 +1802,7 @@ class Vehicle:
|
|
1787
1802
|
return True if response in ['Connected', 'connected'] else False
|
1788
1803
|
|
1789
1804
|
@property
|
1790
|
-
def is_charging_cable_connected_supported(self):
|
1805
|
+
def is_charging_cable_connected_supported(self) -> bool:
|
1791
1806
|
"""Return true if charging cable connected is supported"""
|
1792
1807
|
if self.attrs.get('charging', False):
|
1793
1808
|
if 'status' in self.attrs.get('charging', {}):
|
@@ -1818,12 +1833,12 @@ class Vehicle:
|
|
1818
1833
|
return 0
|
1819
1834
|
|
1820
1835
|
@property
|
1821
|
-
def is_charging_time_left_supported(self):
|
1836
|
+
def is_charging_time_left_supported(self) -> bool:
|
1822
1837
|
"""Return true if charging is supported"""
|
1823
1838
|
return self.is_charging_supported
|
1824
1839
|
|
1825
1840
|
@property
|
1826
|
-
def charging_power(self):
|
1841
|
+
def charging_power(self) -> int:
|
1827
1842
|
"""Return charging power in watts."""
|
1828
1843
|
if self.attrs.get('charging', False):
|
1829
1844
|
return int(self.attrs.get('charging', {}).get('chargingPowerInWatts', 0))
|
@@ -1831,7 +1846,7 @@ class Vehicle:
|
|
1831
1846
|
return 0
|
1832
1847
|
|
1833
1848
|
@property
|
1834
|
-
def is_charging_power_supported(self):
|
1849
|
+
def is_charging_power_supported(self) -> bool:
|
1835
1850
|
"""Return true if charging power is supported."""
|
1836
1851
|
if self.attrs.get('charging', False):
|
1837
1852
|
if self.attrs.get('charging', {}).get('chargingPowerInWatts', False) is not False:
|
@@ -1839,7 +1854,7 @@ class Vehicle:
|
|
1839
1854
|
return False
|
1840
1855
|
|
1841
1856
|
@property
|
1842
|
-
def charge_rate(self):
|
1857
|
+
def charge_rate(self) -> int:
|
1843
1858
|
"""Return charge rate in km per h."""
|
1844
1859
|
if self.attrs.get('charging', False):
|
1845
1860
|
return int(self.attrs.get('charging', {}).get('chargingRateInKilometersPerHour', 0))
|
@@ -1847,7 +1862,7 @@ class Vehicle:
|
|
1847
1862
|
return 0
|
1848
1863
|
|
1849
1864
|
@property
|
1850
|
-
def is_charge_rate_supported(self):
|
1865
|
+
def is_charge_rate_supported(self) -> bool:
|
1851
1866
|
"""Return true if charge rate is supported."""
|
1852
1867
|
if self.attrs.get('charging', False):
|
1853
1868
|
if self.attrs.get('charging', {}).get('chargingRateInKilometersPerHour', False) is not False:
|
@@ -1865,10 +1880,12 @@ class Vehicle:
|
|
1865
1880
|
return True if response in ['stationConnected', 'available', 'Charging', 'ready'] else False
|
1866
1881
|
|
1867
1882
|
@property
|
1868
|
-
def is_external_power_supported(self):
|
1883
|
+
def is_external_power_supported(self) -> bool:
|
1869
1884
|
"""External power supported."""
|
1870
1885
|
if self.attrs.get('charging', {}).get('status', {}).get('plug, {}').get('externalPower', False):
|
1871
1886
|
return True
|
1887
|
+
else:
|
1888
|
+
return False
|
1872
1889
|
|
1873
1890
|
@property
|
1874
1891
|
def charging_state(self):
|
@@ -1881,7 +1898,7 @@ class Vehicle:
|
|
1881
1898
|
return False
|
1882
1899
|
|
1883
1900
|
@property
|
1884
|
-
def is_charging_state_supported(self):
|
1901
|
+
def is_charging_state_supported(self) -> bool:
|
1885
1902
|
"""Charging state supported."""
|
1886
1903
|
#if self.attrs.get('charging', {}).get('status', {}).get('state', False):
|
1887
1904
|
# return True
|
@@ -1890,6 +1907,7 @@ class Vehicle:
|
|
1890
1907
|
if 'charging' in self.attrs.get('mycar')['services']:
|
1891
1908
|
if 'status' in self.attrs.get('mycar')['services']['charging']:
|
1892
1909
|
return True
|
1910
|
+
return False
|
1893
1911
|
|
1894
1912
|
@property
|
1895
1913
|
def energy_flow(self):
|
@@ -1905,10 +1923,12 @@ class Vehicle:
|
|
1905
1923
|
return False
|
1906
1924
|
|
1907
1925
|
@property
|
1908
|
-
def is_energy_flow_supported(self):
|
1926
|
+
def is_energy_flow_supported(self) -> bool:
|
1909
1927
|
"""Energy flow supported."""
|
1910
1928
|
if self.is_charging_state_supported:
|
1911
1929
|
return True
|
1930
|
+
else:
|
1931
|
+
return False
|
1912
1932
|
|
1913
1933
|
@property
|
1914
1934
|
def target_soc(self):
|
@@ -1916,10 +1936,12 @@ class Vehicle:
|
|
1916
1936
|
return self.attrs.get('charging', {}).get('info', {}).get('settings', {}).get('targetSoc', 0)
|
1917
1937
|
|
1918
1938
|
@property
|
1919
|
-
def is_target_soc_supported(self):
|
1939
|
+
def is_target_soc_supported(self) -> bool:
|
1920
1940
|
"""Target state of charge supported."""
|
1921
1941
|
if self.attrs.get('charging', {}).get('info', {}).get('settings', {}).get('targetSoc', False):
|
1922
1942
|
return True
|
1943
|
+
else:
|
1944
|
+
return False
|
1923
1945
|
|
1924
1946
|
# Vehicle location states
|
1925
1947
|
@property
|
@@ -1954,26 +1976,29 @@ class Vehicle:
|
|
1954
1976
|
return output
|
1955
1977
|
|
1956
1978
|
@property
|
1957
|
-
def is_position_supported(self):
|
1979
|
+
def is_position_supported(self) -> bool:
|
1958
1980
|
"""Return true if carfinder_v1 service is active."""
|
1959
1981
|
if self.attrs.get('findCarResponse', {}).get('lat', False):
|
1960
1982
|
return True
|
1961
1983
|
elif self.attrs.get('isMoving', False):
|
1962
1984
|
return True
|
1985
|
+
return False
|
1963
1986
|
|
1964
1987
|
@property
|
1965
|
-
def vehicle_moving(self):
|
1988
|
+
def vehicle_moving(self) -> bool:
|
1966
1989
|
"""Return true if vehicle is moving."""
|
1967
1990
|
return self.attrs.get('isMoving', False)
|
1968
1991
|
|
1969
1992
|
@property
|
1970
|
-
def is_vehicle_moving_supported(self):
|
1993
|
+
def is_vehicle_moving_supported(self) -> bool:
|
1971
1994
|
"""Return true if vehicle supports position."""
|
1972
1995
|
if self.is_position_supported:
|
1973
1996
|
return True
|
1997
|
+
else:
|
1998
|
+
return False
|
1974
1999
|
|
1975
2000
|
@property
|
1976
|
-
def parking_time(self):
|
2001
|
+
def parking_time(self) -> str:
|
1977
2002
|
"""Return timestamp of last parking time."""
|
1978
2003
|
parkTime_utc = self.attrs.get('findCarResponse', {}).get('parkingTimeUTC', 'Unknown')
|
1979
2004
|
if isinstance(parkTime_utc, datetime):
|
@@ -1983,10 +2008,12 @@ class Vehicle:
|
|
1983
2008
|
return parkTime.strftime('%Y-%m-%d %H:%M:%S')
|
1984
2009
|
|
1985
2010
|
@property
|
1986
|
-
def is_parking_time_supported(self):
|
2011
|
+
def is_parking_time_supported(self) -> bool:
|
1987
2012
|
"""Return true if vehicle parking timestamp is supported."""
|
1988
2013
|
if 'parkingTimeUTC' in self.attrs.get('findCarResponse', {}):
|
1989
2014
|
return True
|
2015
|
+
else:
|
2016
|
+
return False
|
1990
2017
|
|
1991
2018
|
# Vehicle fuel level and range
|
1992
2019
|
@property
|
@@ -1997,7 +2024,7 @@ class Vehicle:
|
|
1997
2024
|
return int(value)
|
1998
2025
|
|
1999
2026
|
@property
|
2000
|
-
def is_primary_range_supported(self):
|
2027
|
+
def is_primary_range_supported(self) -> bool:
|
2001
2028
|
if self.attrs.get('mycar', False):
|
2002
2029
|
if 'engines' in self.attrs.get('mycar', {}):
|
2003
2030
|
if 'primary' in self.attrs.get('mycar')['engines']:
|
@@ -2013,7 +2040,7 @@ class Vehicle:
|
|
2013
2040
|
return value
|
2014
2041
|
|
2015
2042
|
@property
|
2016
|
-
def is_primary_drive_supported(self):
|
2043
|
+
def is_primary_drive_supported(self) -> bool:
|
2017
2044
|
if self.attrs.get('mycar', False):
|
2018
2045
|
if 'engines' in self.attrs.get('mycar', {}):
|
2019
2046
|
if 'primary' in self.attrs.get('mycar')['engines']:
|
@@ -2029,7 +2056,7 @@ class Vehicle:
|
|
2029
2056
|
return int(value)
|
2030
2057
|
|
2031
2058
|
@property
|
2032
|
-
def is_secondary_range_supported(self):
|
2059
|
+
def is_secondary_range_supported(self) -> bool:
|
2033
2060
|
if self.attrs.get('mycar', False):
|
2034
2061
|
if 'engines' in self.attrs.get('mycar', {}):
|
2035
2062
|
if 'secondary' in self.attrs.get('mycar')['engines']:
|
@@ -2045,7 +2072,7 @@ class Vehicle:
|
|
2045
2072
|
return value
|
2046
2073
|
|
2047
2074
|
@property
|
2048
|
-
def is_secondary_drive_supported(self):
|
2075
|
+
def is_secondary_drive_supported(self) -> bool:
|
2049
2076
|
if self.attrs.get('mycar', False):
|
2050
2077
|
if 'engines' in self.attrs.get('mycar', {}):
|
2051
2078
|
if 'secondary' in self.attrs.get('mycar')['engines']:
|
@@ -2065,7 +2092,7 @@ class Vehicle:
|
|
2065
2092
|
return -1
|
2066
2093
|
|
2067
2094
|
@property
|
2068
|
-
def is_electric_range_supported(self):
|
2095
|
+
def is_electric_range_supported(self) -> bool:
|
2069
2096
|
if self.is_secondary_drive_supported:
|
2070
2097
|
if self.secondary_drive == 'electric':
|
2071
2098
|
return self.is_secondary_range_supported
|
@@ -2086,7 +2113,7 @@ class Vehicle:
|
|
2086
2113
|
return -1
|
2087
2114
|
|
2088
2115
|
@property
|
2089
|
-
def is_combustion_range_supported(self):
|
2116
|
+
def is_combustion_range_supported(self) -> bool:
|
2090
2117
|
if self.is_primary_drive_supported:
|
2091
2118
|
if not self.primary_drive == 'electric':
|
2092
2119
|
return self.is_primary_range_supported
|
@@ -2096,17 +2123,17 @@ class Vehicle:
|
|
2096
2123
|
return False
|
2097
2124
|
|
2098
2125
|
@property
|
2099
|
-
def combined_range(self):
|
2126
|
+
def combined_range(self) -> int:
|
2100
2127
|
return int(self.combustion_range)+int(self.electric_range)
|
2101
2128
|
|
2102
2129
|
@property
|
2103
|
-
def is_combined_range_supported(self):
|
2130
|
+
def is_combined_range_supported(self) -> bool:
|
2104
2131
|
if self.is_combustion_range_supported and self.is_electric_range_supported:
|
2105
2132
|
return True
|
2106
2133
|
return False
|
2107
2134
|
|
2108
2135
|
@property
|
2109
|
-
def fuel_level(self):
|
2136
|
+
def fuel_level(self) -> int:
|
2110
2137
|
value = -1
|
2111
2138
|
if self.is_fuel_level_supported:
|
2112
2139
|
if not self.primary_drive == 'electric':
|
@@ -2116,7 +2143,7 @@ class Vehicle:
|
|
2116
2143
|
return int(value)
|
2117
2144
|
|
2118
2145
|
@property
|
2119
|
-
def is_fuel_level_supported(self):
|
2146
|
+
def is_fuel_level_supported(self) -> bool:
|
2120
2147
|
if self.is_primary_drive_supported:
|
2121
2148
|
if not self.primary_drive == 'electric':
|
2122
2149
|
if "levelPct" in self.attrs.get('mycar')['engines']['primary']:
|
@@ -2137,7 +2164,7 @@ class Vehicle:
|
|
2137
2164
|
return False
|
2138
2165
|
|
2139
2166
|
@property
|
2140
|
-
def is_climatisation_target_temperature_supported(self):
|
2167
|
+
def is_climatisation_target_temperature_supported(self) -> bool:
|
2141
2168
|
"""Return true if climatisation target temperature is supported."""
|
2142
2169
|
if self.attrs.get('climater', False):
|
2143
2170
|
if 'settings' in self.attrs.get('climater', {}):
|
@@ -2159,7 +2186,7 @@ class Vehicle:
|
|
2159
2186
|
return "00:00"
|
2160
2187
|
|
2161
2188
|
@property
|
2162
|
-
def is_climatisation_time_left_supported(self):
|
2189
|
+
def is_climatisation_time_left_supported(self) -> bool:
|
2163
2190
|
"""Return true if remainingTimeToReachTargetTemperatureInSeconds is supported."""
|
2164
2191
|
if self.attrs.get('airConditioning', {}).get('remainingTimeToReachTargetTemperatureInSeconds', False):
|
2165
2192
|
return True
|
@@ -2171,14 +2198,13 @@ class Vehicle:
|
|
2171
2198
|
return self.attrs.get('climater').get('settings').get('climatisationWithoutExternalPower', False)
|
2172
2199
|
|
2173
2200
|
@property
|
2174
|
-
def is_climatisation_without_external_power_supported(self):
|
2201
|
+
def is_climatisation_without_external_power_supported(self) -> bool:
|
2175
2202
|
"""Return true if climatisation on battery power is supported."""
|
2176
2203
|
if self.attrs.get('climater', False):
|
2177
2204
|
if 'settings' in self.attrs.get('climater', {}):
|
2178
2205
|
if 'climatisationWithoutExternalPower' in self.attrs.get('climater', {})['settings']:
|
2179
2206
|
return True
|
2180
|
-
|
2181
|
-
return False
|
2207
|
+
return False
|
2182
2208
|
|
2183
2209
|
@property
|
2184
2210
|
def outside_temperature(self):
|
@@ -2190,16 +2216,13 @@ class Vehicle:
|
|
2190
2216
|
return False
|
2191
2217
|
|
2192
2218
|
@property
|
2193
|
-
def is_outside_temperature_supported(self):
|
2219
|
+
def is_outside_temperature_supported(self) -> bool:
|
2194
2220
|
"""Return true if outside temp is supported"""
|
2195
2221
|
if self.attrs.get('StoredVehicleDataResponseParsed', False):
|
2196
2222
|
if '0x0301020001' in self.attrs.get('StoredVehicleDataResponseParsed'):
|
2197
2223
|
if "value" in self.attrs.get('StoredVehicleDataResponseParsed')['0x0301020001']:
|
2198
2224
|
return True
|
2199
|
-
|
2200
|
-
return False
|
2201
|
-
else:
|
2202
|
-
return False
|
2225
|
+
return False
|
2203
2226
|
|
2204
2227
|
# Climatisation, electric
|
2205
2228
|
@property
|
@@ -2212,12 +2235,12 @@ class Vehicle:
|
|
2212
2235
|
return data
|
2213
2236
|
|
2214
2237
|
@property
|
2215
|
-
def is_electric_climatisation_attributes_supported(self):
|
2238
|
+
def is_electric_climatisation_attributes_supported(self) -> bool:
|
2216
2239
|
"""Return true if vehichle has climater."""
|
2217
2240
|
return self.is_climatisation_supported
|
2218
2241
|
|
2219
2242
|
@property
|
2220
|
-
def electric_climatisation(self):
|
2243
|
+
def electric_climatisation(self) -> bool:
|
2221
2244
|
"""Return status of climatisation."""
|
2222
2245
|
if self.attrs.get('climater', {}).get('status', {}).get('climatisationStatus', {}).get('climatisationState', False):
|
2223
2246
|
climatisation_type = self.attrs.get('climater', {}).get('settings', {}).get('heaterSource', '')
|
@@ -2227,12 +2250,12 @@ class Vehicle:
|
|
2227
2250
|
return False
|
2228
2251
|
|
2229
2252
|
@property
|
2230
|
-
def is_electric_climatisation_supported(self):
|
2253
|
+
def is_electric_climatisation_supported(self) -> bool:
|
2231
2254
|
"""Return true if vehichle has climater."""
|
2232
2255
|
return self.is_climatisation_supported
|
2233
2256
|
|
2234
2257
|
@property
|
2235
|
-
def auxiliary_climatisation(self):
|
2258
|
+
def auxiliary_climatisation(self) -> bool:
|
2236
2259
|
"""Return status of auxiliary climatisation."""
|
2237
2260
|
climatisation_type = self.attrs.get('climater', {}).get('settings', {}).get('heaterSource', {}).get('content', '')
|
2238
2261
|
status = self.attrs.get('climater', {}).get('status', {}).get('climatisationStatus', {}).get('climatisationState', '')
|
@@ -2244,26 +2267,26 @@ class Vehicle:
|
|
2244
2267
|
return False
|
2245
2268
|
|
2246
2269
|
@property
|
2247
|
-
def is_auxiliary_climatisation_supported(self):
|
2270
|
+
def is_auxiliary_climatisation_supported(self) -> bool:
|
2248
2271
|
"""Return true if vehicle has auxiliary climatisation."""
|
2249
2272
|
#if self._services.get('rclima_v1', False):
|
2250
|
-
if self._relevantCapabilties.get('climatisation', {}).get('active', False):
|
2251
|
-
functions = self._services.get('rclima_v1', {}).get('operations', [])
|
2273
|
+
#if self._relevantCapabilties.get('climatisation', {}).get('active', False):
|
2274
|
+
#functions = self._services.get('rclima_v1', {}).get('operations', [])
|
2252
2275
|
#for operation in functions:
|
2253
2276
|
# if operation['id'] == 'P_START_CLIMA_AU':
|
2254
|
-
if 'P_START_CLIMA_AU' in functions:
|
2255
|
-
|
2277
|
+
#if 'P_START_CLIMA_AU' in functions:
|
2278
|
+
# return True
|
2256
2279
|
return False
|
2257
2280
|
|
2258
2281
|
@property
|
2259
|
-
def is_climatisation_supported(self):
|
2282
|
+
def is_climatisation_supported(self) -> bool:
|
2260
2283
|
"""Return true if climatisation has State."""
|
2261
2284
|
if self.attrs.get('climater', {}).get('status', {}).get('climatisationStatus', {}).get('climatisationState', False):
|
2262
2285
|
return True
|
2263
2286
|
return False
|
2264
2287
|
|
2265
2288
|
@property
|
2266
|
-
def window_heater(self):
|
2289
|
+
def window_heater(self) -> bool:
|
2267
2290
|
"""Return status of window heater."""
|
2268
2291
|
if self.attrs.get('climater', False):
|
2269
2292
|
for elem in self.attrs.get('climater', {}).get('status', {}).get('windowHeatingStatus', {}).get('windowHeatingStatus', []):
|
@@ -2272,7 +2295,7 @@ class Vehicle:
|
|
2272
2295
|
return False
|
2273
2296
|
|
2274
2297
|
@property
|
2275
|
-
def is_window_heater_supported(self):
|
2298
|
+
def is_window_heater_supported(self) -> bool:
|
2276
2299
|
"""Return true if vehichle has heater."""
|
2277
2300
|
if self.is_electric_climatisation_supported:
|
2278
2301
|
if self.attrs.get('climater', False):
|
@@ -2282,7 +2305,7 @@ class Vehicle:
|
|
2282
2305
|
return False
|
2283
2306
|
|
2284
2307
|
@property
|
2285
|
-
def seat_heating(self):
|
2308
|
+
def seat_heating(self) -> bool:
|
2286
2309
|
"""Return status of seat heating."""
|
2287
2310
|
if self.attrs.get('airConditioning', {}).get('seatHeatingSupport', False):
|
2288
2311
|
for element in self.attrs.get('airConditioning', {}).get('seatHeatingSupport', {}):
|
@@ -2291,19 +2314,19 @@ class Vehicle:
|
|
2291
2314
|
return False
|
2292
2315
|
|
2293
2316
|
@property
|
2294
|
-
def is_seat_heating_supported(self):
|
2317
|
+
def is_seat_heating_supported(self) -> bool:
|
2295
2318
|
"""Return true if vehichle has seat heating."""
|
2296
2319
|
if self.attrs.get('airConditioning', {}).get('seatHeatingSupport', False):
|
2297
2320
|
return True
|
2298
2321
|
return False
|
2299
2322
|
|
2300
2323
|
@property
|
2301
|
-
def warnings(self):
|
2324
|
+
def warnings(self) -> int:
|
2302
2325
|
"""Return warnings."""
|
2303
2326
|
return len(self.attrs.get('warninglights', {}).get('statuses',[]))
|
2304
2327
|
|
2305
2328
|
@property
|
2306
|
-
def is_warnings_supported(self):
|
2329
|
+
def is_warnings_supported(self) -> bool:
|
2307
2330
|
"""Return true if vehichle has warnings."""
|
2308
2331
|
if self.attrs.get('warninglights', False):
|
2309
2332
|
return True
|
@@ -2322,7 +2345,7 @@ class Vehicle:
|
|
2322
2345
|
_LOGGER.warning(f'Invalid value for duration: {value}')
|
2323
2346
|
|
2324
2347
|
@property
|
2325
|
-
def is_pheater_duration_supported(self):
|
2348
|
+
def is_pheater_duration_supported(self) -> bool:
|
2326
2349
|
return self.is_pheater_heating_supported
|
2327
2350
|
|
2328
2351
|
@property
|
@@ -2331,7 +2354,7 @@ class Vehicle:
|
|
2331
2354
|
return self.attrs.get('heating', {}).get('climatisationStateReport', {}).get('climatisationState', False) == 'ventilation'
|
2332
2355
|
|
2333
2356
|
@property
|
2334
|
-
def is_pheater_ventilation_supported(self):
|
2357
|
+
def is_pheater_ventilation_supported(self) -> bool:
|
2335
2358
|
"""Return true if vehichle has combustion climatisation."""
|
2336
2359
|
return self.is_pheater_heating_supported
|
2337
2360
|
|
@@ -2341,10 +2364,12 @@ class Vehicle:
|
|
2341
2364
|
return self.attrs.get('heating', {}).get('climatisationStateReport', {}).get('climatisationState', False) == 'heating'
|
2342
2365
|
|
2343
2366
|
@property
|
2344
|
-
def is_pheater_heating_supported(self):
|
2367
|
+
def is_pheater_heating_supported(self) -> bool:
|
2345
2368
|
"""Return true if vehichle has combustion engine heating."""
|
2346
2369
|
if self.attrs.get('heating', {}).get('climatisationStateReport', {}).get('climatisationState', False):
|
2347
2370
|
return True
|
2371
|
+
else:
|
2372
|
+
return False
|
2348
2373
|
|
2349
2374
|
@property
|
2350
2375
|
def pheater_status(self):
|
@@ -2352,18 +2377,20 @@ class Vehicle:
|
|
2352
2377
|
return self.attrs.get('heating', {}).get('climatisationStateReport', {}).get('climatisationState', 'Unknown')
|
2353
2378
|
|
2354
2379
|
@property
|
2355
|
-
def is_pheater_status_supported(self):
|
2380
|
+
def is_pheater_status_supported(self) -> bool:
|
2356
2381
|
"""Return true if vehichle has combustion engine heating/ventilation."""
|
2357
2382
|
if self.attrs.get('heating', {}).get('climatisationStateReport', {}).get('climatisationState', False):
|
2358
2383
|
return True
|
2384
|
+
else:
|
2385
|
+
return False
|
2359
2386
|
|
2360
2387
|
# Windows
|
2361
2388
|
@property
|
2362
|
-
def windows_closed(self):
|
2389
|
+
def windows_closed(self) -> bool:
|
2363
2390
|
return (self.window_closed_left_front and self.window_closed_left_back and self.window_closed_right_front and self.window_closed_right_back)
|
2364
2391
|
|
2365
2392
|
@property
|
2366
|
-
def is_windows_closed_supported(self):
|
2393
|
+
def is_windows_closed_supported(self) -> bool:
|
2367
2394
|
"""Return true if window state is supported"""
|
2368
2395
|
response = ""
|
2369
2396
|
if self.attrs.get('status', False):
|
@@ -2380,7 +2407,7 @@ class Vehicle:
|
|
2380
2407
|
return False
|
2381
2408
|
|
2382
2409
|
@property
|
2383
|
-
def is_window_closed_left_front_supported(self):
|
2410
|
+
def is_window_closed_left_front_supported(self) -> bool:
|
2384
2411
|
"""Return true if window state is supported"""
|
2385
2412
|
response = ""
|
2386
2413
|
if self.attrs.get('status', False):
|
@@ -2389,7 +2416,7 @@ class Vehicle:
|
|
2389
2416
|
return True if response != "" else False
|
2390
2417
|
|
2391
2418
|
@property
|
2392
|
-
def window_closed_right_front(self):
|
2419
|
+
def window_closed_right_front(self) -> bool:
|
2393
2420
|
response = self.attrs.get('status')['windows'].get('frontRight', '')
|
2394
2421
|
if response == 'closed':
|
2395
2422
|
return True
|
@@ -2397,7 +2424,7 @@ class Vehicle:
|
|
2397
2424
|
return False
|
2398
2425
|
|
2399
2426
|
@property
|
2400
|
-
def is_window_closed_right_front_supported(self):
|
2427
|
+
def is_window_closed_right_front_supported(self) -> bool:
|
2401
2428
|
"""Return true if window state is supported"""
|
2402
2429
|
response = ""
|
2403
2430
|
if self.attrs.get('status', False):
|
@@ -2406,7 +2433,7 @@ class Vehicle:
|
|
2406
2433
|
return True if response != "" else False
|
2407
2434
|
|
2408
2435
|
@property
|
2409
|
-
def window_closed_left_back(self):
|
2436
|
+
def window_closed_left_back(self) -> bool:
|
2410
2437
|
response = self.attrs.get('status')['windows'].get('rearLeft', '')
|
2411
2438
|
if response == 'closed':
|
2412
2439
|
return True
|
@@ -2414,7 +2441,7 @@ class Vehicle:
|
|
2414
2441
|
return False
|
2415
2442
|
|
2416
2443
|
@property
|
2417
|
-
def is_window_closed_left_back_supported(self):
|
2444
|
+
def is_window_closed_left_back_supported(self) -> bool:
|
2418
2445
|
"""Return true if window state is supported"""
|
2419
2446
|
response = ""
|
2420
2447
|
if self.attrs.get('status', False):
|
@@ -2423,7 +2450,7 @@ class Vehicle:
|
|
2423
2450
|
return True if response != "" else False
|
2424
2451
|
|
2425
2452
|
@property
|
2426
|
-
def window_closed_right_back(self):
|
2453
|
+
def window_closed_right_back(self) -> bool:
|
2427
2454
|
response = self.attrs.get('status')['windows'].get('rearRight', '')
|
2428
2455
|
if response == 'closed':
|
2429
2456
|
return True
|
@@ -2431,7 +2458,7 @@ class Vehicle:
|
|
2431
2458
|
return False
|
2432
2459
|
|
2433
2460
|
@property
|
2434
|
-
def is_window_closed_right_back_supported(self):
|
2461
|
+
def is_window_closed_right_back_supported(self) -> bool:
|
2435
2462
|
"""Return true if window state is supported"""
|
2436
2463
|
response = ""
|
2437
2464
|
if self.attrs.get('status', False):
|
@@ -2440,7 +2467,7 @@ class Vehicle:
|
|
2440
2467
|
return True if response != "" else False
|
2441
2468
|
|
2442
2469
|
@property
|
2443
|
-
def sunroof_closed(self):
|
2470
|
+
def sunroof_closed(self) -> bool:
|
2444
2471
|
# Due to missing test objects, it is yet unclear, if 'sunroof' is direct subentry of 'status' or a subentry of 'windows'. So both are checked.
|
2445
2472
|
response = ""
|
2446
2473
|
if 'sunRoof' in self.attrs.get('status'):
|
@@ -2453,7 +2480,7 @@ class Vehicle:
|
|
2453
2480
|
return False
|
2454
2481
|
|
2455
2482
|
@property
|
2456
|
-
def is_sunroof_closed_supported(self):
|
2483
|
+
def is_sunroof_closed_supported(self) -> bool:
|
2457
2484
|
"""Return true if sunroof state is supported"""
|
2458
2485
|
# Due to missing test objects, it is yet unclear, if 'sunroof' is direct subentry of 'status' or a subentry of 'windows'. So both are checked.
|
2459
2486
|
response = ""
|
@@ -2466,7 +2493,7 @@ class Vehicle:
|
|
2466
2493
|
|
2467
2494
|
# Locks
|
2468
2495
|
@property
|
2469
|
-
def door_locked(self):
|
2496
|
+
def door_locked(self) -> bool:
|
2470
2497
|
# LEFT FRONT
|
2471
2498
|
response = self.attrs.get('status')['doors']['frontLeft'].get('locked', 'false')
|
2472
2499
|
if response != 'true':
|
@@ -2487,7 +2514,7 @@ class Vehicle:
|
|
2487
2514
|
return True
|
2488
2515
|
|
2489
2516
|
@property
|
2490
|
-
def is_door_locked_supported(self):
|
2517
|
+
def is_door_locked_supported(self) -> bool:
|
2491
2518
|
response = 0
|
2492
2519
|
if self.attrs.get('status', False):
|
2493
2520
|
if 'doors' in self.attrs.get('status'):
|
@@ -2500,7 +2527,7 @@ class Vehicle:
|
|
2500
2527
|
return True if locked == 'true' else False
|
2501
2528
|
|
2502
2529
|
@property
|
2503
|
-
def is_trunk_locked_supported(self):
|
2530
|
+
def is_trunk_locked_supported(self) -> bool:
|
2504
2531
|
if self.attrs.get('status', False):
|
2505
2532
|
if 'trunk' in self.attrs.get('status'):
|
2506
2533
|
if 'locked' in self.attrs.get('status').get('trunk'):
|
@@ -2515,7 +2542,7 @@ class Vehicle:
|
|
2515
2542
|
return True if open == 'false' else False
|
2516
2543
|
|
2517
2544
|
@property
|
2518
|
-
def is_hood_closed_supported(self):
|
2545
|
+
def is_hood_closed_supported(self) -> bool:
|
2519
2546
|
"""Return true if hood state is supported"""
|
2520
2547
|
response = 0
|
2521
2548
|
if self.attrs.get('status', False):
|
@@ -2529,7 +2556,7 @@ class Vehicle:
|
|
2529
2556
|
return True if open == 'false' else False
|
2530
2557
|
|
2531
2558
|
@property
|
2532
|
-
def is_door_closed_left_front_supported(self):
|
2559
|
+
def is_door_closed_left_front_supported(self) -> bool:
|
2533
2560
|
"""Return true if window state is supported"""
|
2534
2561
|
if self.attrs.get('status', False):
|
2535
2562
|
if 'doors' in self.attrs.get('status'):
|
@@ -2543,7 +2570,7 @@ class Vehicle:
|
|
2543
2570
|
return True if open == 'false' else False
|
2544
2571
|
|
2545
2572
|
@property
|
2546
|
-
def is_door_closed_right_front_supported(self):
|
2573
|
+
def is_door_closed_right_front_supported(self) -> bool:
|
2547
2574
|
"""Return true if window state is supported"""
|
2548
2575
|
if self.attrs.get('status', False):
|
2549
2576
|
if 'doors' in self.attrs.get('status'):
|
@@ -2557,7 +2584,7 @@ class Vehicle:
|
|
2557
2584
|
return True if open == 'false' else False
|
2558
2585
|
|
2559
2586
|
@property
|
2560
|
-
def is_door_closed_left_back_supported(self):
|
2587
|
+
def is_door_closed_left_back_supported(self) -> bool:
|
2561
2588
|
if self.attrs.get('status', False):
|
2562
2589
|
if 'doors' in self.attrs.get('status'):
|
2563
2590
|
if 'rearLeft' in self.attrs.get('status').get('doors', {}):
|
@@ -2570,7 +2597,7 @@ class Vehicle:
|
|
2570
2597
|
return True if open == 'false' else False
|
2571
2598
|
|
2572
2599
|
@property
|
2573
|
-
def is_door_closed_right_back_supported(self):
|
2600
|
+
def is_door_closed_right_back_supported(self) -> bool:
|
2574
2601
|
"""Return true if window state is supported"""
|
2575
2602
|
if self.attrs.get('status', False):
|
2576
2603
|
if 'doors' in self.attrs.get('status'):
|
@@ -2584,7 +2611,7 @@ class Vehicle:
|
|
2584
2611
|
return True if open == 'false' else False
|
2585
2612
|
|
2586
2613
|
@property
|
2587
|
-
def is_trunk_closed_supported(self):
|
2614
|
+
def is_trunk_closed_supported(self) -> bool:
|
2588
2615
|
"""Return true if window state is supported"""
|
2589
2616
|
response = 0
|
2590
2617
|
if self.attrs.get('status', False):
|
@@ -2622,7 +2649,7 @@ class Vehicle:
|
|
2622
2649
|
return None
|
2623
2650
|
|
2624
2651
|
@property
|
2625
|
-
def is_departure1_supported(self):
|
2652
|
+
def is_departure1_supported(self) -> bool:
|
2626
2653
|
"""Return true if timer 1 is supported."""
|
2627
2654
|
if len(self.attrs.get('departureTimers', {}).get('timers', [])) >= 1:
|
2628
2655
|
return True
|
@@ -2659,7 +2686,7 @@ class Vehicle:
|
|
2659
2686
|
return None
|
2660
2687
|
|
2661
2688
|
@property
|
2662
|
-
def is_departure2_supported(self):
|
2689
|
+
def is_departure2_supported(self) -> bool:
|
2663
2690
|
"""Return true if timer 2 is supported."""
|
2664
2691
|
if len(self.attrs.get('departureTimers', {}).get('timers', [])) >= 2:
|
2665
2692
|
return True
|
@@ -2696,7 +2723,7 @@ class Vehicle:
|
|
2696
2723
|
return None
|
2697
2724
|
|
2698
2725
|
@property
|
2699
|
-
def is_departure3_supported(self):
|
2726
|
+
def is_departure3_supported(self) -> bool:
|
2700
2727
|
"""Return true if timer 3 is supported."""
|
2701
2728
|
if len(self.attrs.get('departureTimers', {}).get('timers', [])) >= 3:
|
2702
2729
|
return True
|
@@ -2723,7 +2750,7 @@ class Vehicle:
|
|
2723
2750
|
return None
|
2724
2751
|
|
2725
2752
|
@property
|
2726
|
-
def is_departure_profile1_supported(self):
|
2753
|
+
def is_departure_profile1_supported(self) -> bool:
|
2727
2754
|
"""Return true if profile 1 is supported."""
|
2728
2755
|
if len(self.attrs.get('departureProfiles', {}).get('timers', [])) >= 1:
|
2729
2756
|
return True
|
@@ -2747,7 +2774,7 @@ class Vehicle:
|
|
2747
2774
|
return None
|
2748
2775
|
|
2749
2776
|
@property
|
2750
|
-
def is_departure_profile2_supported(self):
|
2777
|
+
def is_departure_profile2_supported(self) -> bool:
|
2751
2778
|
"""Return true if profile 2 is supported."""
|
2752
2779
|
if len(self.attrs.get('departureProfiles', {}).get('timers', [])) >= 2:
|
2753
2780
|
return True
|
@@ -2771,7 +2798,7 @@ class Vehicle:
|
|
2771
2798
|
return None
|
2772
2799
|
|
2773
2800
|
@property
|
2774
|
-
def is_departure_profile3_supported(self):
|
2801
|
+
def is_departure_profile3_supported(self) -> bool:
|
2775
2802
|
"""Return true if profile 3 is supported."""
|
2776
2803
|
if len(self.attrs.get('departureProfiles', {}).get('timers', [])) >= 3:
|
2777
2804
|
return True
|
@@ -2787,40 +2814,48 @@ class Vehicle:
|
|
2787
2814
|
return self.trip_last_entry.get('averageSpeedKmph')
|
2788
2815
|
|
2789
2816
|
@property
|
2790
|
-
def is_trip_last_average_speed_supported(self):
|
2817
|
+
def is_trip_last_average_speed_supported(self) -> bool:
|
2791
2818
|
response = self.trip_last_entry
|
2792
2819
|
if response and type(response.get('averageSpeedKmph', None)) in (float, int):
|
2793
2820
|
return True
|
2821
|
+
else:
|
2822
|
+
return False
|
2794
2823
|
|
2795
2824
|
@property
|
2796
2825
|
def trip_last_average_electric_consumption(self):
|
2797
2826
|
return self.trip_last_entry.get('averageElectricConsumption')
|
2798
2827
|
|
2799
2828
|
@property
|
2800
|
-
def is_trip_last_average_electric_consumption_supported(self):
|
2829
|
+
def is_trip_last_average_electric_consumption_supported(self) -> bool:
|
2801
2830
|
response = self.trip_last_entry
|
2802
2831
|
if response and type(response.get('averageElectricConsumption', None)) in (float, int):
|
2803
2832
|
return True
|
2833
|
+
else:
|
2834
|
+
return False
|
2804
2835
|
|
2805
2836
|
@property
|
2806
2837
|
def trip_last_average_fuel_consumption(self):
|
2807
2838
|
return self.trip_last_entry.get('averageFuelConsumption')
|
2808
2839
|
|
2809
2840
|
@property
|
2810
|
-
def is_trip_last_average_fuel_consumption_supported(self):
|
2841
|
+
def is_trip_last_average_fuel_consumption_supported(self) -> bool:
|
2811
2842
|
response = self.trip_last_entry
|
2812
2843
|
if response and type(response.get('averageFuelConsumption', None)) in (float, int):
|
2813
2844
|
return True
|
2845
|
+
else:
|
2846
|
+
return False
|
2814
2847
|
|
2815
2848
|
@property
|
2816
2849
|
def trip_last_average_auxillary_consumption(self):
|
2817
2850
|
return self.trip_last_entry.get('averageAuxConsumption')
|
2818
2851
|
|
2819
2852
|
@property
|
2820
|
-
def is_trip_last_average_auxillary_consumption_supported(self):
|
2853
|
+
def is_trip_last_average_auxillary_consumption_supported(self) -> bool:
|
2821
2854
|
response = self.trip_last_entry
|
2822
2855
|
if response and type(response.get('averageAuxConsumption', None)) in (float, int):
|
2823
2856
|
return True
|
2857
|
+
else:
|
2858
|
+
return False
|
2824
2859
|
|
2825
2860
|
@property
|
2826
2861
|
def trip_last_average_aux_consumer_consumption(self):
|
@@ -2828,30 +2863,36 @@ class Vehicle:
|
|
2828
2863
|
return value
|
2829
2864
|
|
2830
2865
|
@property
|
2831
|
-
def is_trip_last_average_aux_consumer_consumption_supported(self):
|
2866
|
+
def is_trip_last_average_aux_consumer_consumption_supported(self) -> bool:
|
2832
2867
|
response = self.trip_last_entry
|
2833
2868
|
if response and type(response.get('averageAuxConsumerConsumption', None)) in (float, int):
|
2834
2869
|
return True
|
2870
|
+
else:
|
2871
|
+
return False
|
2835
2872
|
|
2836
2873
|
@property
|
2837
2874
|
def trip_last_duration(self):
|
2838
2875
|
return self.trip_last_entry.get('travelTime')
|
2839
2876
|
|
2840
2877
|
@property
|
2841
|
-
def is_trip_last_duration_supported(self):
|
2878
|
+
def is_trip_last_duration_supported(self) -> bool:
|
2842
2879
|
response = self.trip_last_entry
|
2843
2880
|
if response and type(response.get('travelTime', None)) in (float, int):
|
2844
2881
|
return True
|
2882
|
+
else:
|
2883
|
+
return False
|
2845
2884
|
|
2846
2885
|
@property
|
2847
2886
|
def trip_last_length(self):
|
2848
2887
|
return self.trip_last_entry.get('mileageKm')
|
2849
2888
|
|
2850
2889
|
@property
|
2851
|
-
def is_trip_last_length_supported(self):
|
2890
|
+
def is_trip_last_length_supported(self) -> bool:
|
2852
2891
|
response = self.trip_last_entry
|
2853
2892
|
if response and type(response.get('mileageKm', None)) in (float, int):
|
2854
2893
|
return True
|
2894
|
+
else:
|
2895
|
+
return False
|
2855
2896
|
|
2856
2897
|
@property
|
2857
2898
|
def trip_last_recuperation(self):
|
@@ -2859,11 +2900,13 @@ class Vehicle:
|
|
2859
2900
|
return self.trip_last_entry.get('recuperation')
|
2860
2901
|
|
2861
2902
|
@property
|
2862
|
-
def is_trip_last_recuperation_supported(self):
|
2903
|
+
def is_trip_last_recuperation_supported(self) -> bool:
|
2863
2904
|
#Not implemented
|
2864
2905
|
response = self.trip_last_entry
|
2865
2906
|
if response and type(response.get('recuperation', None)) in (float, int):
|
2866
2907
|
return True
|
2908
|
+
else:
|
2909
|
+
return False
|
2867
2910
|
|
2868
2911
|
@property
|
2869
2912
|
def trip_last_average_recuperation(self):
|
@@ -2872,11 +2915,13 @@ class Vehicle:
|
|
2872
2915
|
return value
|
2873
2916
|
|
2874
2917
|
@property
|
2875
|
-
def is_trip_last_average_recuperation_supported(self):
|
2918
|
+
def is_trip_last_average_recuperation_supported(self) -> bool:
|
2876
2919
|
#Not implemented
|
2877
2920
|
response = self.trip_last_entry
|
2878
2921
|
if response and type(response.get('averageRecuperation', None)) in (float, int):
|
2879
2922
|
return True
|
2923
|
+
else:
|
2924
|
+
return False
|
2880
2925
|
|
2881
2926
|
@property
|
2882
2927
|
def trip_last_total_electric_consumption(self):
|
@@ -2884,11 +2929,13 @@ class Vehicle:
|
|
2884
2929
|
return self.trip_last_entry.get('totalElectricConsumption')
|
2885
2930
|
|
2886
2931
|
@property
|
2887
|
-
def is_trip_last_total_electric_consumption_supported(self):
|
2932
|
+
def is_trip_last_total_electric_consumption_supported(self) -> bool:
|
2888
2933
|
#Not implemented
|
2889
2934
|
response = self.trip_last_entry
|
2890
2935
|
if response and type(response.get('totalElectricConsumption', None)) in (float, int):
|
2891
2936
|
return True
|
2937
|
+
else:
|
2938
|
+
return False
|
2892
2939
|
|
2893
2940
|
@property
|
2894
2941
|
def trip_last_cycle_entry(self):
|
@@ -2899,40 +2946,48 @@ class Vehicle:
|
|
2899
2946
|
return self.trip_last_cycle_entry.get('averageSpeedKmph')
|
2900
2947
|
|
2901
2948
|
@property
|
2902
|
-
def is_trip_last_cycle_average_speed_supported(self):
|
2949
|
+
def is_trip_last_cycle_average_speed_supported(self) -> bool:
|
2903
2950
|
response = self.trip_last_cycle_entry
|
2904
2951
|
if response and type(response.get('averageSpeedKmph', None)) in (float, int):
|
2905
2952
|
return True
|
2953
|
+
else:
|
2954
|
+
return False
|
2906
2955
|
|
2907
2956
|
@property
|
2908
2957
|
def trip_last_cycle_average_electric_consumption(self):
|
2909
2958
|
return self.trip_last_cycle_entry.get('averageElectricConsumption')
|
2910
2959
|
|
2911
2960
|
@property
|
2912
|
-
def is_trip_last_cycle_average_electric_consumption_supported(self):
|
2961
|
+
def is_trip_last_cycle_average_electric_consumption_supported(self) -> bool:
|
2913
2962
|
response = self.trip_last_cycle_entry
|
2914
2963
|
if response and type(response.get('averageElectricConsumption', None)) in (float, int):
|
2915
2964
|
return True
|
2965
|
+
else:
|
2966
|
+
return False
|
2916
2967
|
|
2917
2968
|
@property
|
2918
2969
|
def trip_last_cycle_average_fuel_consumption(self):
|
2919
2970
|
return self.trip_last_cycle_entry.get('averageFuelConsumption')
|
2920
2971
|
|
2921
2972
|
@property
|
2922
|
-
def is_trip_last_cycle_average_fuel_consumption_supported(self):
|
2973
|
+
def is_trip_last_cycle_average_fuel_consumption_supported(self) -> bool:
|
2923
2974
|
response = self.trip_last_cycle_entry
|
2924
2975
|
if response and type(response.get('averageFuelConsumption', None)) in (float, int):
|
2925
2976
|
return True
|
2977
|
+
else:
|
2978
|
+
return False
|
2926
2979
|
|
2927
2980
|
@property
|
2928
2981
|
def trip_last_cycle_average_auxillary_consumption(self):
|
2929
2982
|
return self.trip_last_cycle_entry.get('averageAuxConsumption')
|
2930
2983
|
|
2931
2984
|
@property
|
2932
|
-
def is_trip_last_cycle_average_auxillary_consumption_supported(self):
|
2985
|
+
def is_trip_last_cycle_average_auxillary_consumption_supported(self) -> bool:
|
2933
2986
|
response = self.trip_last_cycle_entry
|
2934
2987
|
if response and type(response.get('averageAuxConsumption', None)) in (float, int):
|
2935
2988
|
return True
|
2989
|
+
else:
|
2990
|
+
return False
|
2936
2991
|
|
2937
2992
|
@property
|
2938
2993
|
def trip_last_cycle_average_aux_consumer_consumption(self):
|
@@ -2940,71 +2995,83 @@ class Vehicle:
|
|
2940
2995
|
return value
|
2941
2996
|
|
2942
2997
|
@property
|
2943
|
-
def is_trip_last_cycle_average_aux_consumer_consumption_supported(self):
|
2998
|
+
def is_trip_last_cycle_average_aux_consumer_consumption_supported(self) -> bool:
|
2944
2999
|
response = self.trip_last_cycle_entry
|
2945
3000
|
if response and type(response.get('averageAuxConsumerConsumption', None)) in (float, int):
|
2946
3001
|
return True
|
3002
|
+
else:
|
3003
|
+
return False
|
2947
3004
|
|
2948
3005
|
@property
|
2949
3006
|
def trip_last_cycle_duration(self):
|
2950
3007
|
return self.trip_last_cycle_entry.get('travelTime')
|
2951
3008
|
|
2952
3009
|
@property
|
2953
|
-
def is_trip_last_cycle_duration_supported(self):
|
3010
|
+
def is_trip_last_cycle_duration_supported(self) -> bool:
|
2954
3011
|
response = self.trip_last_cycle_entry
|
2955
3012
|
if response and type(response.get('travelTime', None)) in (float, int):
|
2956
3013
|
return True
|
3014
|
+
else:
|
3015
|
+
return False
|
2957
3016
|
|
2958
3017
|
@property
|
2959
|
-
def trip_last_cycle_length(self):
|
3018
|
+
def trip_last_cycle_length(self) -> int:
|
2960
3019
|
return self.trip_last_cycle_entry.get('mileageKm')
|
2961
3020
|
|
2962
3021
|
@property
|
2963
|
-
def is_trip_last_cycle_length_supported(self):
|
3022
|
+
def is_trip_last_cycle_length_supported(self) -> bool:
|
2964
3023
|
response = self.trip_last_cycle_entry
|
2965
3024
|
if response and type(response.get('mileageKm', None)) in (float, int):
|
2966
3025
|
return True
|
3026
|
+
else:
|
3027
|
+
return False
|
2967
3028
|
|
2968
3029
|
@property
|
2969
|
-
def trip_last_cycle_recuperation(self):
|
3030
|
+
def trip_last_cycle_recuperation(self) -> float:
|
2970
3031
|
#Not implemented
|
2971
3032
|
return self.trip_last_cycle_entry.get('recuperation')
|
2972
3033
|
|
2973
3034
|
@property
|
2974
|
-
def is_trip_last_cycle_recuperation_supported(self):
|
3035
|
+
def is_trip_last_cycle_recuperation_supported(self) -> bool:
|
2975
3036
|
#Not implemented
|
2976
3037
|
response = self.trip_last_cycle_entry
|
2977
3038
|
if response and type(response.get('recuperation', None)) in (float, int):
|
2978
3039
|
return True
|
3040
|
+
else:
|
3041
|
+
return False
|
2979
3042
|
|
2980
3043
|
@property
|
2981
|
-
def trip_last_cycle_average_recuperation(self):
|
3044
|
+
def trip_last_cycle_average_recuperation(self) -> float:
|
2982
3045
|
#Not implemented
|
2983
3046
|
value = self.trip_last_cycle_entry.get('averageRecuperation')
|
2984
3047
|
return value
|
2985
3048
|
|
2986
3049
|
@property
|
2987
|
-
def is_trip_last_cycle_average_recuperation_supported(self):
|
3050
|
+
def is_trip_last_cycle_average_recuperation_supported(self) -> bool:
|
2988
3051
|
#Not implemented
|
2989
3052
|
response = self.trip_last_cycle_entry
|
2990
3053
|
if response and type(response.get('averageRecuperation', None)) in (float, int):
|
2991
3054
|
return True
|
3055
|
+
else:
|
3056
|
+
return False
|
2992
3057
|
|
2993
3058
|
@property
|
2994
|
-
def trip_last_cycle_total_electric_consumption(self):
|
3059
|
+
def trip_last_cycle_total_electric_consumption(self) -> float:
|
2995
3060
|
#Not implemented
|
2996
3061
|
return self.trip_last_cycle_entry.get('totalElectricConsumption')
|
2997
3062
|
|
2998
3063
|
@property
|
2999
|
-
def is_trip_last_cycle_total_electric_consumption_supported(self):
|
3064
|
+
def is_trip_last_cycle_total_electric_consumption_supported(self) -> bool:
|
3000
3065
|
#Not implemented
|
3001
3066
|
response = self.trip_last_cycle_entry
|
3002
3067
|
if response and type(response.get('totalElectricConsumption', None)) in (float, int):
|
3003
3068
|
return True
|
3069
|
+
else:
|
3070
|
+
return False
|
3004
3071
|
|
3005
3072
|
# Area alarm
|
3006
3073
|
@property
|
3007
|
-
def area_alarm(self):
|
3074
|
+
def area_alarm(self) -> bool:
|
3008
3075
|
"""Return True, if attribute areaAlarm is not {}"""
|
3009
3076
|
alarmPresent = self.attrs.get('areaAlarm', {})
|
3010
3077
|
if alarmPresent !={}:
|
@@ -3016,7 +3083,7 @@ class Vehicle:
|
|
3016
3083
|
return False if alarmPresent == {} else True
|
3017
3084
|
|
3018
3085
|
@property
|
3019
|
-
def is_area_alarm_supported(self):
|
3086
|
+
def is_area_alarm_supported(self) -> bool:
|
3020
3087
|
"""Return True, if vehicle supports area alarm (always True at the moment)"""
|
3021
3088
|
# Always True at the moment. Have to check, if the geofence capability is a necessary condition
|
3022
3089
|
return True
|
@@ -3028,7 +3095,7 @@ class Vehicle:
|
|
3028
3095
|
return self._requests.get('refresh', {}).get('status', 'None')
|
3029
3096
|
|
3030
3097
|
@property
|
3031
|
-
def refresh_action_timestamp(self):
|
3098
|
+
def refresh_action_timestamp(self) -> str:
|
3032
3099
|
"""Return timestamp of latest data refresh request."""
|
3033
3100
|
timestamp = self._requests.get('refresh', {}).get('timestamp', DATEZERO)
|
3034
3101
|
return timestamp.strftime("%Y-%m-%d %H:%M:%S")
|
@@ -3039,7 +3106,7 @@ class Vehicle:
|
|
3039
3106
|
return self._requests.get('batterycharge', {}).get('status', 'None')
|
3040
3107
|
|
3041
3108
|
@property
|
3042
|
-
def charger_action_timestamp(self):
|
3109
|
+
def charger_action_timestamp(self) -> str:
|
3043
3110
|
"""Return timestamp of latest charger request."""
|
3044
3111
|
timestamp = self._requests.get('charger', {}).get('timestamp', DATEZERO)
|
3045
3112
|
return timestamp.strftime("%Y-%m-%d %H:%M:%S")
|
@@ -3050,7 +3117,7 @@ class Vehicle:
|
|
3050
3117
|
return self._requests.get('climatisation', {}).get('status', 'None')
|
3051
3118
|
|
3052
3119
|
@property
|
3053
|
-
def climater_action_timestamp(self):
|
3120
|
+
def climater_action_timestamp(self) -> str:
|
3054
3121
|
"""Return timestamp of latest climater request."""
|
3055
3122
|
timestamp = self._requests.get('climatisation', {}).get('timestamp', DATEZERO)
|
3056
3123
|
return timestamp.strftime("%Y-%m-%d %H:%M:%S")
|
@@ -3061,7 +3128,7 @@ class Vehicle:
|
|
3061
3128
|
return self._requests.get('preheater', {}).get('status', 'None')
|
3062
3129
|
|
3063
3130
|
@property
|
3064
|
-
def pheater_action_timestamp(self):
|
3131
|
+
def pheater_action_timestamp(self) -> str:
|
3065
3132
|
"""Return timestamp of latest parking heater request."""
|
3066
3133
|
timestamp = self._requests.get('preheater', {}).get('timestamp', DATEZERO)
|
3067
3134
|
return timestamp.strftime("%Y-%m-%d %H:%M:%S")
|
@@ -3072,7 +3139,7 @@ class Vehicle:
|
|
3072
3139
|
return self._requests.get('honkandflash', {}).get('status', 'None')
|
3073
3140
|
|
3074
3141
|
@property
|
3075
|
-
def honkandflash_action_timestamp(self):
|
3142
|
+
def honkandflash_action_timestamp(self) -> str:
|
3076
3143
|
"""Return timestamp of latest honk and flash request."""
|
3077
3144
|
timestamp = self._requests.get('honkandflash', {}).get('timestamp', DATEZERO)
|
3078
3145
|
return timestamp.strftime("%Y-%m-%d %H:%M:%S")
|
@@ -3083,7 +3150,7 @@ class Vehicle:
|
|
3083
3150
|
return self._requests.get('lock', {}).get('status', 'None')
|
3084
3151
|
|
3085
3152
|
@property
|
3086
|
-
def lock_action_timestamp(self):
|
3153
|
+
def lock_action_timestamp(self) -> str:
|
3087
3154
|
"""Return timestamp of latest lock action request."""
|
3088
3155
|
timestamp = self._requests.get('lock', {}).get('timestamp', DATEZERO)
|
3089
3156
|
return timestamp.strftime("%Y-%m-%d %H:%M:%S")
|
@@ -3094,13 +3161,13 @@ class Vehicle:
|
|
3094
3161
|
return self._requests.get('departuretimer', {}).get('status', 'None')
|
3095
3162
|
|
3096
3163
|
@property
|
3097
|
-
def timer_action_timestamp(self):
|
3164
|
+
def timer_action_timestamp(self) -> str:
|
3098
3165
|
"""Return timestamp of latest departure timer request."""
|
3099
3166
|
timestamp = self._requests.get('departuretimer', {}).get('timestamp', DATEZERO)
|
3100
3167
|
return timestamp.strftime("%Y-%m-%d %H:%M:%S")
|
3101
3168
|
|
3102
3169
|
@property
|
3103
|
-
def refresh_data(self):
|
3170
|
+
def refresh_data(self) -> bool:
|
3104
3171
|
"""Get state of data refresh"""
|
3105
3172
|
#if self._requests.get('refresh', {}).get('id', False):
|
3106
3173
|
# timestamp = self._requests.get('refresh', {}).get('timestamp', DATEZERO)
|
@@ -3111,47 +3178,53 @@ class Vehicle:
|
|
3111
3178
|
return False
|
3112
3179
|
|
3113
3180
|
@property
|
3114
|
-
def is_refresh_data_supported(self):
|
3181
|
+
def is_refresh_data_supported(self) -> bool:
|
3115
3182
|
"""Data refresh is supported."""
|
3116
3183
|
if self._connectivities.get('mode', '') == 'online':
|
3117
3184
|
return True
|
3185
|
+
else:
|
3186
|
+
return False
|
3118
3187
|
|
3119
3188
|
@property
|
3120
|
-
def update_data(self):
|
3189
|
+
def update_data(self) -> bool:
|
3121
3190
|
"""Get state of data update"""
|
3122
3191
|
return False
|
3123
3192
|
|
3124
3193
|
@property
|
3125
|
-
def is_update_data_supported(self):
|
3194
|
+
def is_update_data_supported(self) -> bool:
|
3126
3195
|
"""Data update is supported."""
|
3127
3196
|
return True
|
3128
3197
|
|
3129
3198
|
# Honk and flash
|
3130
3199
|
@property
|
3131
|
-
def request_honkandflash(self):
|
3200
|
+
def request_honkandflash(self) -> bool:
|
3132
3201
|
"""State is always False"""
|
3133
3202
|
return False
|
3134
3203
|
|
3135
3204
|
@property
|
3136
|
-
def is_request_honkandflash_supported(self):
|
3205
|
+
def is_request_honkandflash_supported(self) -> bool:
|
3137
3206
|
"""Honk and flash is supported if service is enabled."""
|
3138
3207
|
if self._relevantCapabilties.get('honkAndFlash', {}).get('active', False):
|
3139
3208
|
return True
|
3209
|
+
else:
|
3210
|
+
return False
|
3140
3211
|
|
3141
3212
|
@property
|
3142
|
-
def request_flash(self):
|
3213
|
+
def request_flash(self) -> bool:
|
3143
3214
|
"""State is always False"""
|
3144
3215
|
return False
|
3145
3216
|
|
3146
3217
|
@property
|
3147
|
-
def is_request_flash_supported(self):
|
3218
|
+
def is_request_flash_supported(self) -> bool:
|
3148
3219
|
"""Honk and flash is supported if service is enabled."""
|
3149
3220
|
if self._relevantCapabilties.get('honkAndFlash', {}).get('active', False):
|
3150
3221
|
return True
|
3222
|
+
else:
|
3223
|
+
return False
|
3151
3224
|
|
3152
3225
|
# Requests data
|
3153
3226
|
@property
|
3154
|
-
def request_in_progress(self):
|
3227
|
+
def request_in_progress(self) -> bool:
|
3155
3228
|
"""Request in progress is always supported."""
|
3156
3229
|
try:
|
3157
3230
|
for section in self._requests:
|
@@ -3162,12 +3235,12 @@ class Vehicle:
|
|
3162
3235
|
return False
|
3163
3236
|
|
3164
3237
|
@property
|
3165
|
-
def is_request_in_progress_supported(self):
|
3238
|
+
def is_request_in_progress_supported(self) -> bool:
|
3166
3239
|
"""Request in progress is always supported."""
|
3167
3240
|
return False
|
3168
3241
|
|
3169
3242
|
@property
|
3170
|
-
def request_results(self):
|
3243
|
+
def request_results(self) -> dict:
|
3171
3244
|
"""Get last request result."""
|
3172
3245
|
data = {
|
3173
3246
|
'latest': self._requests.get('latest', 'N/A'),
|
@@ -3181,13 +3254,13 @@ class Vehicle:
|
|
3181
3254
|
return data
|
3182
3255
|
|
3183
3256
|
@property
|
3184
|
-
def is_request_results_supported(self):
|
3257
|
+
def is_request_results_supported(self) -> bool:
|
3185
3258
|
"""Request results is supported if in progress is supported."""
|
3186
3259
|
return False # deactivated because it provides no usefull information
|
3187
3260
|
#return self.is_request_in_progress_supported
|
3188
3261
|
|
3189
3262
|
@property
|
3190
|
-
def requests_remaining(self):
|
3263
|
+
def requests_remaining(self) -> int:
|
3191
3264
|
"""Get remaining requests before throttled."""
|
3192
3265
|
if self.attrs.get('rate_limit_remaining', False):
|
3193
3266
|
self.requests_remaining = self.attrs.get('rate_limit_remaining')
|
@@ -3195,21 +3268,21 @@ class Vehicle:
|
|
3195
3268
|
return self._requests['remaining']
|
3196
3269
|
|
3197
3270
|
@requests_remaining.setter
|
3198
|
-
def requests_remaining(self, value):
|
3271
|
+
def requests_remaining(self, value) -> None:
|
3199
3272
|
self._requests['remaining'] = value
|
3200
3273
|
|
3201
3274
|
@property
|
3202
|
-
def is_requests_remaining_supported(self):
|
3275
|
+
def is_requests_remaining_supported(self) -> bool:
|
3203
3276
|
return False # deactivated because it provides no usefull information
|
3204
3277
|
#if self.is_request_in_progress_supported:
|
3205
3278
|
# return True if self._requests.get('remaining', False) else False
|
3206
3279
|
|
3207
3280
|
#### Helper functions ####
|
3208
|
-
def __str__(self):
|
3281
|
+
def __str__(self) -> str:
|
3209
3282
|
return self.vin
|
3210
3283
|
|
3211
3284
|
@property
|
3212
|
-
def json(self):
|
3285
|
+
def json(self) -> str:
|
3213
3286
|
def serialize(obj):
|
3214
3287
|
if isinstance(obj, datetime):
|
3215
3288
|
return obj.isoformat()
|
@@ -3221,7 +3294,7 @@ class Vehicle:
|
|
3221
3294
|
)
|
3222
3295
|
|
3223
3296
|
|
3224
|
-
async def stopFirebase(self):
|
3297
|
+
async def stopFirebase(self) -> int:
|
3225
3298
|
# Check if firebase is activated
|
3226
3299
|
if self.firebaseStatus not in (FIREBASE_STATUS_ACTIVATED, FIREBASE_STATUS_ACTIVATION_STOPPED):
|
3227
3300
|
_LOGGER.info(f'No need to stop firebase. Firebase status={self.firebaseStatus}')
|
@@ -3242,7 +3315,7 @@ class Vehicle:
|
|
3242
3315
|
_LOGGER.info('Stopping of firebase messaging was successful.')
|
3243
3316
|
return self.firebaseStatus
|
3244
3317
|
|
3245
|
-
async def initialiseFirebase(self, firebaseCredentialsFileName=
|
3318
|
+
async def initialiseFirebase(self, firebaseCredentialsFileName='', updateCallback=None) -> int:
|
3246
3319
|
# Check if firebase shall be used
|
3247
3320
|
if firebaseCredentialsFileName == None:
|
3248
3321
|
_LOGGER.debug('No use of firebase wanted.')
|
@@ -3297,7 +3370,7 @@ class Vehicle:
|
|
3297
3370
|
|
3298
3371
|
|
3299
3372
|
|
3300
|
-
async def onNotification(self, obj, notification, data_message):
|
3373
|
+
async def onNotification(self, obj: Any, notification: str, data_message: Any) -> None:
|
3301
3374
|
# Do something with the notification
|
3302
3375
|
_LOGGER.debug(f'Received push notification: notification id={notification}, type={obj.get('data',{}).get('type','')}, requestId={obj.get('data',{}).get('requestId','[None]')}')
|
3303
3376
|
_LOGGER.debug(f' data_message={data_message}, payload={obj.get('data',{}).get('payload','[None]')}')
|
@@ -3306,7 +3379,7 @@ class Vehicle:
|
|
3306
3379
|
if self.firebaseStatus != FIREBASE_STATUS_ACTIVATION_STOPPED:
|
3307
3380
|
_LOGGER.info(f'While firebase is not fully activated, received notifications are just acknowledged.')
|
3308
3381
|
# As long as the firebase status is not set to activated, ignore the notifications
|
3309
|
-
return
|
3382
|
+
return
|
3310
3383
|
else:
|
3311
3384
|
# It seems that the firebase connection still works although fcmpushclient.is_started() returned False some time ago
|
3312
3385
|
_LOGGER.info(f'Firebase status={self.firebaseStatus}, but PyCupra still receives push notifications.')
|
@@ -3325,7 +3398,7 @@ class Vehicle:
|
|
3325
3398
|
|
3326
3399
|
if notification == self._firebaseLastMessageId:
|
3327
3400
|
_LOGGER.info(f'Received notification {notification} again. Just acknoledging it, nothing to do.')
|
3328
|
-
return
|
3401
|
+
return
|
3329
3402
|
|
3330
3403
|
self._firebaseLastMessageId = notification # save the id of the last notification
|
3331
3404
|
if type in ('vehicle-access-locked-successful', 'vehicle-access-unlocked-successful'): # vehicle was locked/unlocked
|
@@ -3388,7 +3461,7 @@ class Vehicle:
|
|
3388
3461
|
_LOGGER.debug(f'It is now {datetime.now(tz=None)}. Last get_charger was at {self._last_get_charger}. So no need to update.')
|
3389
3462
|
# Wait 5 seconds
|
3390
3463
|
await asyncio.sleep(5)
|
3391
|
-
elif type in ('climatisation-status-changed','climatisation-started', 'climatisation-stopped', 'climatisation-settings-updated'):
|
3464
|
+
elif type in ('climatisation-status-changed','climatisation-started', 'climatisation-stopped', 'climatisation-settings-updated', 'climatisation-error-fail'):
|
3392
3465
|
if self._requests.get('climatisation', {}).get('id', None):
|
3393
3466
|
openRequest= self._requests.get('climatisation', {}).get('id', None)
|
3394
3467
|
if openRequest == requestId:
|