pycupra 0.1.13__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.
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
- return False
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
- return False
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
- return False
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
- return False
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
- return False
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
- return False
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
- return False
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
- return False
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
- return False
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 None
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
- data = {}
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
- else:
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
- last_connected = datetime.strptime(last_connected_utc,'%Y-%m-%dT%H:%M:%SZ').replace(tzinfo=timezone.utc).astimezone(tz=None)
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
- else:
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
- else:
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
- return True
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=None, updateCallback=None):
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 False
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 False
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: