carconnectivity-connector-skoda 0.5a2__py3-none-any.whl → 0.7__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.

Potentially problematic release.


This version of carconnectivity-connector-skoda might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: carconnectivity-connector-skoda
3
- Version: 0.5a2
3
+ Version: 0.7
4
4
  Summary: CarConnectivity connector for Skoda services
5
5
  Author: Till Steinbach
6
6
  License: MIT License
@@ -37,11 +37,12 @@ Classifier: Topic :: Software Development :: Libraries
37
37
  Requires-Python: >=3.8
38
38
  Description-Content-Type: text/markdown
39
39
  License-File: LICENSE
40
- Requires-Dist: carconnectivity>=0.5a4
40
+ Requires-Dist: carconnectivity>=0.7
41
41
  Requires-Dist: oauthlib~=3.2.2
42
42
  Requires-Dist: requests~=2.32.3
43
43
  Requires-Dist: jwt~=1.3.1
44
44
  Requires-Dist: paho-mqtt~=2.1.0
45
+ Dynamic: license-file
45
46
 
46
47
 
47
48
 
@@ -1,12 +1,13 @@
1
+ carconnectivity_connector_skoda-0.7.dist-info/licenses/LICENSE,sha256=PIwI1alwDyOfvEQHdGCm2u9uf_mGE8030xZDfun0xTo,1071
1
2
  carconnectivity_connectors/skoda/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- carconnectivity_connectors/skoda/_version.py,sha256=FnsAkPBiQBLIp2akvad-n95m_ffJpDdufPzILnmfCFo,508
3
+ carconnectivity_connectors/skoda/_version.py,sha256=pz35JP40uhhjvpunO5XmeQhmrllFsoC46JzXGE2quqw,506
3
4
  carconnectivity_connectors/skoda/capability.py,sha256=wH563-XUb_TnT8di1qDjnj-cY-cNHcAT6z7mx21LhSQ,4770
4
5
  carconnectivity_connectors/skoda/charging.py,sha256=7DPNiTWFhxiiEFKVnbIIU2TCmkpmcMWx_zsHXGXFpAQ,6856
5
6
  carconnectivity_connectors/skoda/climatization.py,sha256=Jut468SkxjPBDTqroWFvDifVPfJBxGjsFed5pc4kZkg,1768
6
- carconnectivity_connectors/skoda/command_impl.py,sha256=vgno5Qb5To0hCHOEBWSG8UOwCY9kT5fz1e2y0b6zF7U,3047
7
- carconnectivity_connectors/skoda/connector.py,sha256=wp3GXooqn1-O-TR4PxUdNR846EKrghBPCp3lN_5_UeE,144975
7
+ carconnectivity_connectors/skoda/command_impl.py,sha256=wDCI3Bka5pXlbyI4yVFS353TgFGyiBHBkERpP2g0A9w,3230
8
+ carconnectivity_connectors/skoda/connector.py,sha256=Lgg-_ySEgtvjGEFNTa5215ZJa8OYVEyGFolgPhV8mMA,146134
8
9
  carconnectivity_connectors/skoda/error.py,sha256=ffxzvjmci7vtp9Q1K4DR1kBF0kTJxN5Gluci3kDBkEI,2459
9
- carconnectivity_connectors/skoda/mqtt_client.py,sha256=RkZ43NG1Z_TUmc2hUZS0yYUfwewzfut63zZUhQR1xug,39101
10
+ carconnectivity_connectors/skoda/mqtt_client.py,sha256=D9_e_Bz842ULYKlRWd4JmosalhTtYr9DtCuvWrT3WQw,39126
10
11
  carconnectivity_connectors/skoda/vehicle.py,sha256=q5gwe-_yPfE_-aEc17UQ-Q0Z46IN7PCpNG5jLw5PZl0,3981
11
12
  carconnectivity_connectors/skoda/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
13
  carconnectivity_connectors/skoda/auth/auth_util.py,sha256=dGLUbUre0HBsTg_Ii5vW34f8DLrCykYJYCyzEvUBBEE,4434
@@ -15,9 +16,8 @@ carconnectivity_connectors/skoda/auth/openid_session.py,sha256=5JfR-gS1uKpE8DD-s
15
16
  carconnectivity_connectors/skoda/auth/session_manager.py,sha256=Uf1vujuDBYUCAXhYToOsZkgbTtfmY3Qe0ICTfwomBpI,2899
16
17
  carconnectivity_connectors/skoda/auth/skoda_web_session.py,sha256=tapjCRRPBu3tHrDoKmtuAlQhgxktib3oWTB8MHEzZTY,10816
17
18
  carconnectivity_connectors/skoda/auth/helpers/blacklist_retry.py,sha256=f3wsiY5bpHDBxp7Va1Mv9nKJ4u3qnCHZZmDu78_AhMk,1251
18
- carconnectivity_connectors/skoda/ui/connector_ui.py,sha256=2Gywhyki52IxIZXV6DhWhzrBLn2293LlUMhK1Rxnw9w,1376
19
- carconnectivity_connector_skoda-0.5a2.dist-info/LICENSE,sha256=PIwI1alwDyOfvEQHdGCm2u9uf_mGE8030xZDfun0xTo,1071
20
- carconnectivity_connector_skoda-0.5a2.dist-info/METADATA,sha256=9poMLd4wkqQ22Sj1NQCFVeMIPBYD7bIUMQ8qkHB5e1U,5360
21
- carconnectivity_connector_skoda-0.5a2.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
22
- carconnectivity_connector_skoda-0.5a2.dist-info/top_level.txt,sha256=KqA8GviZsDH4PtmnwSQsz0HB_w-TWkeEHLIRNo5dTaI,27
23
- carconnectivity_connector_skoda-0.5a2.dist-info/RECORD,,
19
+ carconnectivity_connectors/skoda/ui/connector_ui.py,sha256=lLjwoakRaU0S80hAVwVi4JA1wtHycGHcoM2-7S9qsqI,1386
20
+ carconnectivity_connector_skoda-0.7.dist-info/METADATA,sha256=l43xSHbtcW1miuJdp7el4wdFpyaGKc_vaggWQI5eNH4,5378
21
+ carconnectivity_connector_skoda-0.7.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
22
+ carconnectivity_connector_skoda-0.7.dist-info/top_level.txt,sha256=KqA8GviZsDH4PtmnwSQsz0HB_w-TWkeEHLIRNo5dTaI,27
23
+ carconnectivity_connector_skoda-0.7.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (76.0.0)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.5a2'
21
- __version_tuple__ = version_tuple = (0, 5)
20
+ __version__ = version = '0.7'
21
+ __version_tuple__ = version_tuple = (0, 7)
@@ -33,14 +33,18 @@ class SpinCommand(GenericCommand):
33
33
  def value(self, new_value: Optional[Union[str, Dict]]) -> None:
34
34
  # Execute early hooks before parsing the value
35
35
  new_value = self._execute_on_set_hook(new_value, early_hook=True)
36
- if isinstance(new_value, str):
36
+ if isinstance(new_value, SpinCommand.Command):
37
+ newvalue_dict = {}
38
+ newvalue_dict['command'] = new_value
39
+ new_value = newvalue_dict
40
+ elif isinstance(new_value, str):
37
41
  parser = ThrowingArgumentParser(prog='', add_help=False, exit_on_error=False)
38
42
  parser.add_argument('command', help='Command to execute', type=SpinCommand.Command,
39
43
  choices=list(SpinCommand.Command))
40
44
  parser.add_argument('--spin', dest='spin', help='Spin to be used instead of spin from config or .netrc', type=str, required=False,
41
45
  default=None)
42
46
  try:
43
- args = parser.parse_args(new_value.split(sep=' '))
47
+ args = parser.parse_args(new_value.strip().split(sep=' '))
44
48
  except argparse.ArgumentError as e:
45
49
  raise SetterError(f'Invalid format for SpinCommand: {e.message} {parser.format_usage()}') from e
46
50
 
@@ -328,6 +328,9 @@ class Connector(BaseConnector):
328
328
  if 'vehicles' in data and data['vehicles'] is not None:
329
329
  for vehicle_dict in data['vehicles']:
330
330
  if 'vin' in vehicle_dict and vehicle_dict['vin'] is not None:
331
+ if vehicle_dict['vin'] in self.active_config['hide_vins']:
332
+ LOG.info('Vehicle %s filtered out due to configuration', vehicle_dict['vin'])
333
+ continue
331
334
  seen_vehicle_vins.add(vehicle_dict['vin'])
332
335
  vehicle: Optional[SkodaVehicle] = garage.get_vehicle(vehicle_dict['vin']) # pyright: ignore[reportAssignmentType]
333
336
  if not vehicle:
@@ -374,8 +377,9 @@ class Connector(BaseConnector):
374
377
  vehicle_to_update: Optional[GenericVehicle] = garage.get_vehicle(vin)
375
378
  if vehicle_to_update is not None and isinstance(vehicle_to_update, SkodaVehicle) and vehicle_to_update.is_managed_by_connector(self):
376
379
  vehicle_to_update = self.fetch_vehicle_status(vehicle_to_update)
377
- vehicle_to_update = self.fetch_driving_range(vehicle_to_update)
378
380
  if vehicle_to_update.capabilities is not None and vehicle_to_update.capabilities.enabled:
381
+ if vehicle_to_update.capabilities.has_capability('MEASUREMENTS', check_status_ok=True):
382
+ vehicle_to_update = self.fetch_driving_range(vehicle_to_update)
379
383
  if vehicle_to_update.capabilities.has_capability('READINESS', check_status_ok=True):
380
384
  vehicle_to_update = self.fetch_connection_status(vehicle_to_update)
381
385
  if vehicle_to_update.capabilities.has_capability('PARKING_POSITION', check_status_ok=True):
@@ -400,13 +404,16 @@ class Connector(BaseConnector):
400
404
  SkodaVehicle: The Skoda vehicle object with the updated state.
401
405
  """
402
406
  if vehicle is not None:
403
- if vehicle.in_motion is not None and vehicle.in_motion.enabled and vehicle.in_motion.value:
407
+ if vehicle.connection_state is not None and vehicle.connection_state.enabled \
408
+ and vehicle.connection_state.value == GenericVehicle.ConnectionState.OFFLINE:
409
+ vehicle.state._set_value(GenericVehicle.State.OFFLINE)
410
+ elif vehicle.in_motion is not None and vehicle.in_motion.enabled and vehicle.in_motion.value:
404
411
  vehicle.state._set_value(GenericVehicle.State.IGNITION_ON) # pylint: disable=protected-access
405
412
  elif vehicle.position is not None and vehicle.position.enabled and vehicle.position.position_type is not None \
406
413
  and vehicle.position.position_type.enabled and vehicle.position.position_type.value == Position.PositionType.PARKING:
407
414
  vehicle.state._set_value(GenericVehicle.State.PARKED) # pylint: disable=protected-access
408
415
  else:
409
- vehicle.state._set_value(None) # pylint: disable=protected-access
416
+ vehicle.state._set_value(GenericVehicle.State.UNKNOWN) # pylint: disable=protected-access
410
417
  return vehicle
411
418
 
412
419
  def fetch_charging(self, vehicle: SkodaElectricVehicle, no_cache: bool = False) -> SkodaElectricVehicle:
@@ -494,10 +501,12 @@ class Connector(BaseConnector):
494
501
  cruising_range_in_km: float = data['status']['battery']['remainingCruisingRangeInMeters'] / 1000
495
502
  # pylint: disable-next=protected-access
496
503
  drive.range._set_value(value=cruising_range_in_km, measured=captured_at, unit=Length.KM)
504
+ drive.range.precision = 1
497
505
  if 'stateOfChargeInPercent' in data['status']['battery'] \
498
506
  and data['status']['battery']['stateOfChargeInPercent'] is not None:
499
507
  # pylint: disable-next=protected-access
500
508
  drive.level._set_value(value=data['status']['battery']['stateOfChargeInPercent'], measured=captured_at)
509
+ drive.level.precision = 1
501
510
  log_extra_keys(LOG_API, 'status', data['status']['battery'], {'remainingCruisingRangeInMeters',
502
511
  'stateOfChargeInPercent'})
503
512
  break
@@ -699,7 +708,9 @@ class Connector(BaseConnector):
699
708
  else:
700
709
  longitude = None
701
710
  vehicle.position.latitude._set_value(latitude) # pylint: disable=protected-access
711
+ vehicle.position.latitude.precision = 0.000001
702
712
  vehicle.position.longitude._set_value(longitude) # pylint: disable=protected-access
713
+ vehicle.position.longitude.precision = 0.000001
703
714
  vehicle.position.position_type._set_value(Position.PositionType.PARKING) # pylint: disable=protected-access
704
715
  else:
705
716
  vehicle.position.latitude._set_value(None) # pylint: disable=protected-access
@@ -752,6 +763,7 @@ class Connector(BaseConnector):
752
763
  raise APIError('Could not fetch maintenance, capturedAt missing')
753
764
  if 'mileageInKm' in data and data['mileageInKm'] is not None:
754
765
  vehicle.odometer._set_value(value=data['mileageInKm'], measured=captured_at, unit=Length.KM) # pylint: disable=protected-access
766
+ vehicle.odometer.precision = 1
755
767
  else:
756
768
  vehicle.odometer._set_value(None) # pylint: disable=protected-access
757
769
  if 'inspectionDueInDays' in data and data['inspectionDueInDays'] is not None:
@@ -1270,6 +1282,7 @@ class Connector(BaseConnector):
1270
1282
  if 'totalRangeInKm' in range_data and range_data['totalRangeInKm'] is not None:
1271
1283
  # pylint: disable-next=protected-access
1272
1284
  vehicle.drives.total_range._set_value(value=range_data['totalRangeInKm'], measured=captured_at, unit=Length.KM)
1285
+ vehicle.drives.total_range.precision = 1
1273
1286
  else:
1274
1287
  vehicle.drives.total_range._set_value(None, measured=captured_at, unit=Length.KM) # pylint: disable=protected-access
1275
1288
 
@@ -1302,15 +1315,18 @@ class Connector(BaseConnector):
1302
1315
  and range_data[f'{drive_id}EngineRange']['currentSoCInPercent'] is not None:
1303
1316
  # pylint: disable-next=protected-access
1304
1317
  drive.level._set_value(value=range_data[f'{drive_id}EngineRange']['currentSoCInPercent'], measured=captured_at)
1318
+ drive.level.precision = 1
1305
1319
  elif 'currentFuelLevelInPercent' in range_data[f'{drive_id}EngineRange'] \
1306
1320
  and range_data[f'{drive_id}EngineRange']['currentFuelLevelInPercent'] is not None:
1307
1321
  # pylint: disable-next=protected-access
1308
1322
  drive.level._set_value(value=range_data[f'{drive_id}EngineRange']['currentFuelLevelInPercent'], measured=captured_at)
1323
+ drive.level.precision = 1
1309
1324
  else:
1310
1325
  drive.level._set_value(None, measured=captured_at) # pylint: disable=protected-access
1311
1326
  if 'remainingRangeInKm' in range_data[f'{drive_id}EngineRange'] and range_data[f'{drive_id}EngineRange']['remainingRangeInKm'] is not None:
1312
1327
  # pylint: disable-next=protected-access
1313
1328
  drive.range._set_value(value=range_data[f'{drive_id}EngineRange']['remainingRangeInKm'], measured=captured_at, unit=Length.KM)
1329
+ drive.range.precision = 1
1314
1330
  else:
1315
1331
  drive.range._set_value(None, measured=captured_at, unit=Length.KM) # pylint: disable=protected-access
1316
1332
 
@@ -1464,7 +1480,7 @@ class Connector(BaseConnector):
1464
1480
  elif not allow_http_error or (allowed_errors is not None and status_response.status_code not in allowed_errors):
1465
1481
  raise RetrievalError(f'Could not fetch data even after re-authorization. Status Code was: {status_response.status_code}')
1466
1482
  elif not allow_http_error or (allowed_errors is not None and status_response.status_code not in allowed_errors):
1467
- raise RetrievalError(f'Could not fetch data. Status Code was: {status_response.status_code}')
1483
+ raise RetrievalError(f'Could not fetch data for {url}. Status Code was: {status_response.status_code}')
1468
1484
  except requests.exceptions.ConnectionError as connection_error:
1469
1485
  raise RetrievalError(f'Connection error: {connection_error}.'
1470
1486
  ' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
@@ -480,7 +480,7 @@ class SkodaMQTTClient(Client): # pylint: disable=too-many-instance-attributes
480
480
  old_charging_state: Optional[Charging.ChargingState] = charging_state
481
481
  if 'mode' in data['data'] and data['data']['mode'] is not None \
482
482
  and vehicle.charging is not None and isinstance(vehicle.charging.settings, SkodaCharging.Settings):
483
- if data['data']['mode'] in SkodaCharging.SkodaChargeMode:
483
+ if data['data']['mode'] in [item.value for item in SkodaCharging.SkodaChargeMode]:
484
484
  skoda_charging_mode = SkodaCharging.SkodaChargeMode(data['data']['mode'])
485
485
  else:
486
486
  LOG_API.info('Unkown charging mode %s not in %s', data['data']['mode'], str(SkodaCharging.SkodaChargeMode))
@@ -19,8 +19,8 @@ class ConnectorUI(BaseConnectorUI):
19
19
  A user interface class for the Skoda connector in the Car Connectivity application.
20
20
  """
21
21
  def __init__(self, connector: BaseConnector):
22
- blueprint: Optional[flask.Blueprint] = flask.Blueprint(name='skoda', import_name='carconnectivity-connector-skoda', url_prefix='/skoda',
23
- template_folder=os.path.dirname(__file__) + '/templates')
22
+ blueprint: Optional[flask.Blueprint] = flask.Blueprint(name=connector.id, import_name='carconnectivity-connector-skoda', url_prefix=f'/{connector.id}',
23
+ template_folder=os.path.dirname(__file__) + '/templates')
24
24
  super().__init__(connector, blueprint=blueprint)
25
25
 
26
26
  def get_nav_items(self) -> List[Dict[Literal['text', 'url', 'sublinks', 'divider'], Union[str, List]]]: