carconnectivity-connector-skoda 0.4a1__tar.gz → 0.4a3__tar.gz

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.

Files changed (41) hide show
  1. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/PKG-INFO +2 -2
  2. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/pyproject.toml +1 -1
  3. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connector_skoda.egg-info/PKG-INFO +2 -2
  4. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connector_skoda.egg-info/requires.txt +1 -1
  5. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/_version.py +1 -1
  6. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/connector.py +220 -80
  7. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/.flake8 +0 -0
  8. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  9. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  10. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/.github/dependabot.yml +0 -0
  11. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/.github/workflows/build.yml +0 -0
  12. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/.github/workflows/build_and_publish.yml +0 -0
  13. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/.github/workflows/codeql-analysis.yml +0 -0
  14. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/.gitignore +0 -0
  15. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/CHANGELOG.md +0 -0
  16. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/LICENSE +0 -0
  17. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/Makefile +0 -0
  18. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/README.md +0 -0
  19. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/doc/Config.md +0 -0
  20. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/setup.cfg +0 -0
  21. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/setup_requirements.txt +0 -0
  22. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connector_skoda.egg-info/SOURCES.txt +0 -0
  23. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connector_skoda.egg-info/dependency_links.txt +0 -0
  24. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connector_skoda.egg-info/top_level.txt +0 -0
  25. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/__init__.py +0 -0
  26. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/auth/__init__.py +0 -0
  27. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/auth/auth_util.py +0 -0
  28. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/auth/helpers/blacklist_retry.py +0 -0
  29. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/auth/my_skoda_session.py +0 -0
  30. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/auth/openid_session.py +0 -0
  31. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/auth/session_manager.py +0 -0
  32. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/auth/skoda_web_session.py +0 -0
  33. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/capability.py +0 -0
  34. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/charging.py +0 -0
  35. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/climatization.py +0 -0
  36. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/command_impl.py +0 -0
  37. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/error.py +0 -0
  38. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/mqtt_client.py +0 -0
  39. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/ui/connector_ui.py +0 -0
  40. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/src/carconnectivity_connectors/skoda/vehicle.py +0 -0
  41. {carconnectivity_connector_skoda-0.4a1 → carconnectivity_connector_skoda-0.4a3}/test/integration_test/carConnectivity.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: carconnectivity-connector-skoda
3
- Version: 0.4a1
3
+ Version: 0.4a3
4
4
  Summary: CarConnectivity connector for Skoda services
5
5
  Author: Till Steinbach
6
6
  License: MIT License
@@ -37,7 +37,7 @@ 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.4a3
40
+ Requires-Dist: carconnectivity>=0.4a4
41
41
  Requires-Dist: oauthlib~=3.2.2
42
42
  Requires-Dist: requests~=2.32.3
43
43
  Requires-Dist: jwt~=1.3.1
@@ -14,7 +14,7 @@ authors = [
14
14
  { name = "Till Steinbach" }
15
15
  ]
16
16
  dependencies = [
17
- "carconnectivity>=0.4a3",
17
+ "carconnectivity>=0.4a4",
18
18
  "oauthlib~=3.2.2",
19
19
  "requests~=2.32.3",
20
20
  "jwt~=1.3.1",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: carconnectivity-connector-skoda
3
- Version: 0.4a1
3
+ Version: 0.4a3
4
4
  Summary: CarConnectivity connector for Skoda services
5
5
  Author: Till Steinbach
6
6
  License: MIT License
@@ -37,7 +37,7 @@ 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.4a3
40
+ Requires-Dist: carconnectivity>=0.4a4
41
41
  Requires-Dist: oauthlib~=3.2.2
42
42
  Requires-Dist: requests~=2.32.3
43
43
  Requires-Dist: jwt~=1.3.1
@@ -1,4 +1,4 @@
1
- carconnectivity>=0.4a3
1
+ carconnectivity>=0.4a4
2
2
  oauthlib~=3.2.2
3
3
  requests~=2.32.3
4
4
  jwt~=1.3.1
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.4a1'
20
+ __version__ = version = '0.4a3'
21
21
  __version_tuple__ = version_tuple = (0, 4)
@@ -345,6 +345,8 @@ class Connector(BaseConnector):
345
345
  vehicle_to_update = self.fetch_charging(vehicle_to_update)
346
346
  if vehicle_to_update.capabilities.has_capability('AIR_CONDITIONING'):
347
347
  vehicle_to_update = self.fetch_air_conditioning(vehicle_to_update)
348
+ if vehicle_to_update.capabilities.has_capability('VEHICLE_HEALTH_INSPECTION'):
349
+ vehicle_to_update = self.fetch_maintenance(vehicle_to_update)
348
350
 
349
351
  def fetch_charging(self, vehicle: SkodaElectricVehicle, no_cache: bool = False) -> SkodaElectricVehicle:
350
352
  """
@@ -608,6 +610,53 @@ class Connector(BaseConnector):
608
610
  vehicle.position.position_type._set_value(None) # pylint: disable=protected-access
609
611
  return vehicle
610
612
 
613
+ def fetch_maintenance(self, vehicle: SkodaVehicle, no_cache: bool = False) -> SkodaVehicle:
614
+ """
615
+ Fetches the maintenance information for a given Skoda vehicle.
616
+
617
+ Args:
618
+ vehicle (SkodaVehicle): The vehicle object for which maintenance information is to be fetched.
619
+ no_cache (bool, optional): If True, bypasses the cache and fetches fresh data. Defaults to False.
620
+
621
+ Returns:
622
+ SkodaVehicle: The vehicle object with updated maintenance information.
623
+
624
+ Raises:
625
+ APIError: If the VIN is missing or if the 'capturedAt' field is missing in the fetched data.
626
+ ValueError: If the vehicle has no charging object.
627
+ """
628
+ vin = vehicle.vin.value
629
+ if vin is None:
630
+ raise APIError('VIN is missing')
631
+ if vehicle.position is None:
632
+ raise ValueError('Vehicle has no charging object')
633
+ url = f'https://mysmob.api.connect.skoda-auto.cz/api/v3/vehicle-maintenance/vehicles/{vin}/report'
634
+ data: Dict[str, Any] | None = self._fetch_data(url=url, session=self.session, no_cache=no_cache)
635
+ #{'capturedAt': '2025-02-24T19:54:32.728Z', 'inspectionDueInDays': 620, 'mileageInKm': 2512}
636
+ if data is not None:
637
+ if 'capturedAt' in data and data['capturedAt'] is not None:
638
+ captured_at: datetime = robust_time_parse(data['capturedAt'])
639
+ else:
640
+ raise APIError('Could not fetch maintenance, capturedAt missing')
641
+ if 'mileageInKm' in data and data['mileageInKm'] is not None:
642
+ vehicle.odometer._set_value(value=data['mileageInKm'], measured=captured_at, unit=Length.KM) # pylint: disable=protected-access
643
+ else:
644
+ vehicle.odometer._set_value(None) # pylint: disable=protected-access
645
+ if 'inspectionDueInDays' in data and data['inspectionDueInDays'] is not None:
646
+ inspection_due: timedelta = timedelta(days=data['inspectionDueInDays'])
647
+ inspection_date: datetime = captured_at + inspection_due
648
+ inspection_date = inspection_date.replace(hour=0, minute=0, second=0, microsecond=0)
649
+ # pylint: disable-next=protected-access
650
+ vehicle.maintenance.inspection_due_at._set_value(value=inspection_date, measured=captured_at)
651
+ else:
652
+ vehicle.maintenance.inspection_due_at._set_value(None) # pylint: disable=protected-access
653
+ log_extra_keys(LOG_API, 'maintenance', data, {'capturedAt', 'mileageInKm', 'inspectionDueInDays'})
654
+
655
+ #url = f'https://mysmob.api.connect.skoda-auto.cz/api/v1/vehicle-health-report/warning-lights/{vin}'
656
+ #data: Dict[str, Any] | None = self._fetch_data(url=url, session=self.session, no_cache=no_cache)
657
+ #{'capturedAt': '2025-02-24T15:32:35.032Z', 'mileageInKm': 2512, 'warningLights': [{'category': 'ASSISTANCE', 'defects': []}, {'category': 'COMFORT', 'defects': []}, {'category': 'BRAKE', 'defects': []}, {'category': 'ELECTRIC_ENGINE', 'defects': []}, {'category': 'LIGHTING', 'defects': []}, {'category': 'TIRE', 'defects': []}, {'category': 'OTHER', 'defects': []}]}
658
+ return vehicle
659
+
611
660
  def fetch_air_conditioning(self, vehicle: SkodaVehicle, no_cache: bool = False) -> SkodaVehicle:
612
661
  """
613
662
  Fetches the air conditioning data for a given Skoda vehicle and updates the vehicle object with the retrieved data.
@@ -1287,10 +1336,20 @@ class Connector(BaseConnector):
1287
1336
  raise SetterError(f'Unknown temperature unit {temperature_attribute.unit}')
1288
1337
 
1289
1338
  url = f'https://mysmob.api.connect.skoda-auto.cz/api/v2/air-conditioning/{vin}/settings/target-temperature'
1290
- settings_response: requests.Response = self.session.post(url, data=json.dumps(setting_dict), allow_redirects=True)
1291
- if settings_response.status_code != requests.codes['accepted']:
1292
- LOG.error('Could not set target temperature (%s)', settings_response.status_code)
1293
- raise SetterError(f'Could not set value ({settings_response.status_code})')
1339
+ try:
1340
+ settings_response: requests.Response = self.session.post(url, data=json.dumps(setting_dict), allow_redirects=True)
1341
+ if settings_response.status_code != requests.codes['accepted']:
1342
+ LOG.error('Could not set target temperature (%s)', settings_response.status_code)
1343
+ raise SetterError(f'Could not set value ({settings_response.status_code})')
1344
+ except requests.exceptions.ConnectionError as connection_error:
1345
+ raise SetterError(f'Connection error: {connection_error}.'
1346
+ ' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
1347
+ except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
1348
+ raise SetterError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
1349
+ except requests.exceptions.ReadTimeout as timeout_error:
1350
+ raise SetterError(f'Timeout during read: {timeout_error}') from timeout_error
1351
+ except requests.exceptions.RetryError as retry_error:
1352
+ raise SetterError(f'Retrying failed: {retry_error}') from retry_error
1294
1353
  return target_temperature
1295
1354
 
1296
1355
  def __on_air_conditioning_at_unlock_change(self, at_unlock_attribute: BooleanAttribute, at_unlock_value: bool) -> bool:
@@ -1306,10 +1365,20 @@ class Connector(BaseConnector):
1306
1365
  setting_dict['airConditioningAtUnlockEnabled'] = at_unlock_value
1307
1366
 
1308
1367
  url = f'https://mysmob.api.connect.skoda-auto.cz/api/v2/air-conditioning/{vin}/settings/ac-at-unlock'
1309
- settings_response: requests.Response = self.session.post(url, data=json.dumps(setting_dict), allow_redirects=True)
1310
- if settings_response.status_code != requests.codes['accepted']:
1311
- LOG.error('Could not set air conditioning at unlock (%s)', settings_response.status_code)
1312
- raise SetterError(f'Could not set value ({settings_response.status_code})')
1368
+ try:
1369
+ settings_response: requests.Response = self.session.post(url, data=json.dumps(setting_dict), allow_redirects=True)
1370
+ if settings_response.status_code != requests.codes['accepted']:
1371
+ LOG.error('Could not set air conditioning at unlock (%s)', settings_response.status_code)
1372
+ raise SetterError(f'Could not set value ({settings_response.status_code})')
1373
+ except requests.exceptions.ConnectionError as connection_error:
1374
+ raise SetterError(f'Connection error: {connection_error}.'
1375
+ ' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
1376
+ except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
1377
+ raise SetterError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
1378
+ except requests.exceptions.ReadTimeout as timeout_error:
1379
+ raise SetterError(f'Timeout during read: {timeout_error}') from timeout_error
1380
+ except requests.exceptions.RetryError as retry_error:
1381
+ raise SetterError(f'Retrying failed: {retry_error}') from retry_error
1313
1382
  return at_unlock_value
1314
1383
 
1315
1384
  def __on_air_conditioning_window_heating_change(self, window_heating_attribute: BooleanAttribute, window_heating_value: bool) -> bool:
@@ -1325,10 +1394,20 @@ class Connector(BaseConnector):
1325
1394
  setting_dict['windowHeatingEnabled'] = window_heating_value
1326
1395
 
1327
1396
  url = f'https://mysmob.api.connect.skoda-auto.cz/api/v2/air-conditioning/{vin}/settings/ac-at-unlock'
1328
- settings_response: requests.Response = self.session.post(url, data=json.dumps(setting_dict), allow_redirects=True)
1329
- if settings_response.status_code != requests.codes['accepted']:
1330
- LOG.error('Could not set air conditioning window heating (%s)', settings_response.status_code)
1331
- raise SetterError(f'Could not set value ({settings_response.status_code})')
1397
+ try:
1398
+ settings_response: requests.Response = self.session.post(url, data=json.dumps(setting_dict), allow_redirects=True)
1399
+ if settings_response.status_code != requests.codes['accepted']:
1400
+ LOG.error('Could not set air conditioning window heating (%s)', settings_response.status_code)
1401
+ raise SetterError(f'Could not set value ({settings_response.status_code})')
1402
+ except requests.exceptions.ConnectionError as connection_error:
1403
+ raise SetterError(f'Connection error: {connection_error}.'
1404
+ ' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
1405
+ except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
1406
+ raise SetterError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
1407
+ except requests.exceptions.ReadTimeout as timeout_error:
1408
+ raise SetterError(f'Timeout during read: {timeout_error}') from timeout_error
1409
+ except requests.exceptions.RetryError as retry_error:
1410
+ raise SetterError(f'Retrying failed: {retry_error}') from retry_error
1332
1411
  return window_heating_value
1333
1412
 
1334
1413
  def __on_air_conditioning_start_stop(self, start_stop_command: ClimatizationStartStopCommand, command_arguments: Union[str, Dict[str, Any]]) \
@@ -1345,53 +1424,63 @@ class Connector(BaseConnector):
1345
1424
  if 'command' not in command_arguments:
1346
1425
  raise CommandError('Command argument missing')
1347
1426
  command_dict = {}
1348
- if command_arguments['command'] == ClimatizationStartStopCommand.Command.START:
1349
- command_dict['heaterSource'] = 'ELECTRIC'
1350
- command_dict['targetTemperature'] = {}
1351
- if 'target_temperature' in command_arguments:
1352
- # Round target temperature to nearest 0.5
1353
- command_dict['targetTemperature']['temperatureValue'] = round(command_arguments['target_temperature'] * 2) / 2
1354
- if 'target_temperature_unit' in command_arguments:
1355
- if not isinstance(command_arguments['target_temperature_unit'], Temperature):
1356
- raise CommandError('Temperature unit is not of type Temperature')
1357
- if command_arguments['target_temperature_unit'] == Temperature.C:
1427
+ try:
1428
+ if command_arguments['command'] == ClimatizationStartStopCommand.Command.START:
1429
+ command_dict['heaterSource'] = 'ELECTRIC'
1430
+ command_dict['targetTemperature'] = {}
1431
+ if 'target_temperature' in command_arguments:
1432
+ # Round target temperature to nearest 0.5
1433
+ command_dict['targetTemperature']['temperatureValue'] = round(command_arguments['target_temperature'] * 2) / 2
1434
+ if 'target_temperature_unit' in command_arguments:
1435
+ if not isinstance(command_arguments['target_temperature_unit'], Temperature):
1436
+ raise CommandError('Temperature unit is not of type Temperature')
1437
+ if command_arguments['target_temperature_unit'] == Temperature.C:
1438
+ command_dict['targetTemperature']['unitInCar'] = 'CELSIUS'
1439
+ elif command_arguments['target_temperature_unit'] == Temperature.F:
1440
+ command_dict['targetTemperature']['unitInCar'] = 'FAHRENHEIT'
1441
+ elif command_arguments['target_temperature_unit'] == Temperature.K:
1442
+ command_dict['targetTemperature']['unitInCar'] = 'KELVIN'
1443
+ else:
1444
+ raise CommandError(f'Unknown temperature unit {command_arguments["target_temperature_unit"]}')
1445
+ else:
1446
+ command_dict['targetTemperature']['unitInCar'] = 'CELSIUS'
1447
+ elif start_stop_command.parent is not None and (climatization := start_stop_command.parent.parent) is not None \
1448
+ and isinstance(climatization, Climatization) and climatization.settings is not None \
1449
+ and climatization.settings.target_temperature is not None and climatization.settings.target_temperature.enabled \
1450
+ and climatization.settings.target_temperature.value is not None: # pylint: disable=too-many-boolean-expressions
1451
+ # Round target temperature to nearest 0.5
1452
+ command_dict['targetTemperature']['temperatureValue'] = round(climatization.settings.target_temperature.value * 2) / 2
1453
+ if climatization.settings.target_temperature.unit == Temperature.C:
1358
1454
  command_dict['targetTemperature']['unitInCar'] = 'CELSIUS'
1359
- elif command_arguments['target_temperature_unit'] == Temperature.F:
1455
+ elif climatization.settings.target_temperature.unit == Temperature.F:
1360
1456
  command_dict['targetTemperature']['unitInCar'] = 'FAHRENHEIT'
1361
- elif command_arguments['target_temperature_unit'] == Temperature.K:
1457
+ elif climatization.settings.target_temperature.unit == Temperature.K:
1362
1458
  command_dict['targetTemperature']['unitInCar'] = 'KELVIN'
1363
1459
  else:
1364
- raise CommandError(f'Unknown temperature unit {command_arguments["target_temperature_unit"]}')
1460
+ raise CommandError(f'Unknown temperature unit {climatization.settings.target_temperature.unit}')
1365
1461
  else:
1462
+ command_dict['targetTemperature']['temperatureValue'] = 25.0
1366
1463
  command_dict['targetTemperature']['unitInCar'] = 'CELSIUS'
1367
- elif start_stop_command.parent is not None and (climatization := start_stop_command.parent.parent) is not None \
1368
- and isinstance(climatization, Climatization) and climatization.settings is not None \
1369
- and climatization.settings.target_temperature is not None and climatization.settings.target_temperature.enabled \
1370
- and climatization.settings.target_temperature.value is not None: # pylint: disable=too-many-boolean-expressions
1371
- # Round target temperature to nearest 0.5
1372
- command_dict['targetTemperature']['temperatureValue'] = round(climatization.settings.target_temperature.value * 2) / 2
1373
- if climatization.settings.target_temperature.unit == Temperature.C:
1374
- command_dict['targetTemperature']['unitInCar'] = 'CELSIUS'
1375
- elif climatization.settings.target_temperature.unit == Temperature.F:
1376
- command_dict['targetTemperature']['unitInCar'] = 'FAHRENHEIT'
1377
- elif climatization.settings.target_temperature.unit == Temperature.K:
1378
- command_dict['targetTemperature']['unitInCar'] = 'KELVIN'
1379
- else:
1380
- raise CommandError(f'Unknown temperature unit {climatization.settings.target_temperature.unit}')
1464
+ url = f'https://mysmob.api.connect.skoda-auto.cz/api/v2/air-conditioning/{vin}/start'
1465
+ command_response: requests.Response = self.session.post(url, data=json.dumps(command_dict), allow_redirects=True)
1466
+ elif command_arguments['command'] == ClimatizationStartStopCommand.Command.STOP:
1467
+ url = f'https://mysmob.api.connect.skoda-auto.cz/api/v2/air-conditioning/{vin}/stop'
1468
+ command_response: requests.Response = self.session.post(url, allow_redirects=True)
1381
1469
  else:
1382
- command_dict['targetTemperature']['temperatureValue'] = 25.0
1383
- command_dict['targetTemperature']['unitInCar'] = 'CELSIUS'
1384
- url = f'https://mysmob.api.connect.skoda-auto.cz/api/v2/air-conditioning/{vin}/start'
1385
- command_response: requests.Response = self.session.post(url, data=json.dumps(command_dict), allow_redirects=True)
1386
- elif command_arguments['command'] == ClimatizationStartStopCommand.Command.STOP:
1387
- url = f'https://mysmob.api.connect.skoda-auto.cz/api/v2/air-conditioning/{vin}/stop'
1388
- command_response: requests.Response = self.session.post(url, allow_redirects=True)
1389
- else:
1390
- raise CommandError(f'Unknown command {command_arguments["command"]}')
1470
+ raise CommandError(f'Unknown command {command_arguments["command"]}')
1391
1471
 
1392
- if command_response.status_code != requests.codes['accepted']:
1393
- LOG.error('Could not start/stop air conditioning (%s: %s)', command_response.status_code, command_response.text)
1394
- raise CommandError(f'Could not start/stop air conditioning ({command_response.status_code}: {command_response.text})')
1472
+ if command_response.status_code != requests.codes['accepted']:
1473
+ LOG.error('Could not start/stop air conditioning (%s: %s)', command_response.status_code, command_response.text)
1474
+ raise CommandError(f'Could not start/stop air conditioning ({command_response.status_code}: {command_response.text})')
1475
+ except requests.exceptions.ConnectionError as connection_error:
1476
+ raise CommandError(f'Connection error: {connection_error}.'
1477
+ ' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
1478
+ except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
1479
+ raise CommandError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
1480
+ except requests.exceptions.ReadTimeout as timeout_error:
1481
+ raise CommandError(f'Timeout during read: {timeout_error}') from timeout_error
1482
+ except requests.exceptions.RetryError as retry_error:
1483
+ raise CommandError(f'Retrying failed: {retry_error}') from retry_error
1395
1484
  return command_arguments
1396
1485
 
1397
1486
  def __on_charging_start_stop(self, start_stop_command: ChargingStartStopCommand, command_arguments: Union[str, Dict[str, Any]]) \
@@ -1407,18 +1496,29 @@ class Connector(BaseConnector):
1407
1496
  raise CommandError('VIN in object hierarchy missing')
1408
1497
  if 'command' not in command_arguments:
1409
1498
  raise CommandError('Command argument missing')
1410
- if command_arguments['command'] == ChargingStartStopCommand.Command.START:
1411
- url = f'https://mysmob.api.connect.skoda-auto.cz/api/v1/charging/{vin}/start'
1412
- command_response: requests.Response = self.session.post(url, allow_redirects=True)
1413
- elif command_arguments['command'] == ChargingStartStopCommand.Command.STOP:
1414
- url = f'https://mysmob.api.connect.skoda-auto.cz/api/v1/charging/{vin}/stop'
1415
- command_response: requests.Response = self.session.post(url, allow_redirects=True)
1416
- else:
1417
- raise CommandError(f'Unknown command {command_arguments["command"]}')
1499
+ try:
1500
+ if command_arguments['command'] == ChargingStartStopCommand.Command.START:
1501
+ url = f'https://mysmob.api.connect.skoda-auto.cz/api/v1/charging/{vin}/start'
1502
+ command_response: requests.Response = self.session.post(url, allow_redirects=True)
1503
+ elif command_arguments['command'] == ChargingStartStopCommand.Command.STOP:
1504
+ url = f'https://mysmob.api.connect.skoda-auto.cz/api/v1/charging/{vin}/stop'
1505
+
1506
+ command_response: requests.Response = self.session.post(url, allow_redirects=True)
1507
+ else:
1508
+ raise CommandError(f'Unknown command {command_arguments["command"]}')
1418
1509
 
1419
- if command_response.status_code != requests.codes['accepted']:
1420
- LOG.error('Could not start/stop charging (%s: %s)', command_response.status_code, command_response.text)
1421
- raise CommandError(f'Could not start/stop charging ({command_response.status_code}: {command_response.text})')
1510
+ if command_response.status_code != requests.codes['accepted']:
1511
+ LOG.error('Could not start/stop charging (%s: %s)', command_response.status_code, command_response.text)
1512
+ raise CommandError(f'Could not start/stop charging ({command_response.status_code}: {command_response.text})')
1513
+ except requests.exceptions.ConnectionError as connection_error:
1514
+ raise CommandError(f'Connection error: {connection_error}.'
1515
+ ' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
1516
+ except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
1517
+ raise CommandError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
1518
+ except requests.exceptions.ReadTimeout as timeout_error:
1519
+ raise CommandError(f'Timeout during read: {timeout_error}') from timeout_error
1520
+ except requests.exceptions.RetryError as retry_error:
1521
+ raise CommandError(f'Retrying failed: {retry_error}') from retry_error
1422
1522
  return command_arguments
1423
1523
 
1424
1524
  def __on_honk_flash(self, honk_flash_command: HonkAndFlashCommand, command_arguments: Union[str, Dict[str, Any]]) \
@@ -1448,10 +1548,20 @@ class Connector(BaseConnector):
1448
1548
  command_dict['vehiclePosition']['longitude'] = vehicle.position.longitude.value
1449
1549
 
1450
1550
  url = f'https://mysmob.api.connect.skoda-auto.cz/api/v1/vehicle-access/{vin}/honk-and-flash'
1451
- command_response: requests.Response = self.session.post(url, data=json.dumps(command_dict), allow_redirects=True)
1452
- if command_response.status_code != requests.codes['accepted']:
1453
- LOG.error('Could not execute honk or flash command (%s: %s)', command_response.status_code, command_response.text)
1454
- raise CommandError(f'Could not execute honk or flash command ({command_response.status_code}: {command_response.text})')
1551
+ try:
1552
+ command_response: requests.Response = self.session.post(url, data=json.dumps(command_dict), allow_redirects=True)
1553
+ if command_response.status_code != requests.codes['accepted']:
1554
+ LOG.error('Could not execute honk or flash command (%s: %s)', command_response.status_code, command_response.text)
1555
+ raise CommandError(f'Could not execute honk or flash command ({command_response.status_code}: {command_response.text})')
1556
+ except requests.exceptions.ConnectionError as connection_error:
1557
+ raise CommandError(f'Connection error: {connection_error}.'
1558
+ ' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
1559
+ except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
1560
+ raise SetterError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
1561
+ except requests.exceptions.ReadTimeout as timeout_error:
1562
+ raise CommandError(f'Timeout during read: {timeout_error}') from timeout_error
1563
+ except requests.exceptions.RetryError as retry_error:
1564
+ raise CommandError(f'Retrying failed: {retry_error}') from retry_error
1455
1565
  else:
1456
1566
  raise CommandError(f'Unknown command {command_arguments["command"]}')
1457
1567
  return command_arguments
@@ -1482,10 +1592,20 @@ class Connector(BaseConnector):
1482
1592
  url = f'https://mysmob.api.connect.skoda-auto.cz/api/v1/vehicle-access/{vin}/unlock'
1483
1593
  else:
1484
1594
  raise CommandError(f'Unknown command {command_arguments["command"]}')
1485
- command_response: requests.Response = self.session.post(url, data=json.dumps(command_dict), allow_redirects=True)
1486
- if command_response.status_code != requests.codes['accepted']:
1487
- LOG.error('Could not execute locking command (%s: %s)', command_response.status_code, command_response.text)
1488
- raise CommandError(f'Could not execute locking command ({command_response.status_code}: {command_response.text})')
1595
+ try:
1596
+ command_response: requests.Response = self.session.post(url, data=json.dumps(command_dict), allow_redirects=True)
1597
+ if command_response.status_code != requests.codes['accepted']:
1598
+ LOG.error('Could not execute locking command (%s: %s)', command_response.status_code, command_response.text)
1599
+ raise CommandError(f'Could not execute locking command ({command_response.status_code}: {command_response.text})')
1600
+ except requests.exceptions.ConnectionError as connection_error:
1601
+ raise CommandError(f'Connection error: {connection_error}.'
1602
+ ' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
1603
+ except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
1604
+ raise CommandError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
1605
+ except requests.exceptions.ReadTimeout as timeout_error:
1606
+ raise CommandError(f'Timeout during read: {timeout_error}') from timeout_error
1607
+ except requests.exceptions.RetryError as retry_error:
1608
+ raise CommandError(f'Retrying failed: {retry_error}') from retry_error
1489
1609
  return command_arguments
1490
1610
 
1491
1611
  def __on_wake_sleep(self, wake_sleep_command: WakeSleepCommand, command_arguments: Union[str, Dict[str, Any]]) \
@@ -1504,10 +1624,20 @@ class Connector(BaseConnector):
1504
1624
  if command_arguments['command'] == WakeSleepCommand.Command.WAKE:
1505
1625
  url = f'https://mysmob.api.connect.skoda-auto.cz/api/v1/vehicle-wakeup/{vin}?applyRequestLimiter=true'
1506
1626
 
1507
- command_response: requests.Response = self.session.post(url, data='{}', allow_redirects=True)
1508
- if command_response.status_code != requests.codes['accepted']:
1509
- LOG.error('Could not execute wake command (%s: %s)', command_response.status_code, command_response.text)
1510
- raise CommandError(f'Could not execute wake command ({command_response.status_code}: {command_response.text})')
1627
+ try:
1628
+ command_response: requests.Response = self.session.post(url, data='{}', allow_redirects=True)
1629
+ if command_response.status_code != requests.codes['accepted']:
1630
+ LOG.error('Could not execute wake command (%s: %s)', command_response.status_code, command_response.text)
1631
+ raise CommandError(f'Could not execute wake command ({command_response.status_code}: {command_response.text})')
1632
+ except requests.exceptions.ConnectionError as connection_error:
1633
+ raise CommandError(f'Connection error: {connection_error}.'
1634
+ ' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
1635
+ except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
1636
+ raise CommandError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
1637
+ except requests.exceptions.ReadTimeout as timeout_error:
1638
+ raise CommandError(f'Timeout during read: {timeout_error}') from timeout_error
1639
+ except requests.exceptions.RetryError as retry_error:
1640
+ raise CommandError(f'Retrying failed: {retry_error}') from retry_error
1511
1641
  elif command_arguments['command'] == WakeSleepCommand.Command.SLEEP:
1512
1642
  raise CommandError('Sleep command not supported by vehicle. Vehicle will put itself to sleep')
1513
1643
  else:
@@ -1534,10 +1664,20 @@ class Connector(BaseConnector):
1534
1664
  url = 'https://mysmob.api.connect.skoda-auto.cz/api/v1/spin/verify'
1535
1665
  else:
1536
1666
  raise CommandError(f'Unknown command {command_arguments["command"]}')
1537
- command_response: requests.Response = self.session.post(url, data=json.dumps(command_dict), allow_redirects=True)
1538
- if command_response.status_code != requests.codes['ok']:
1539
- LOG.error('Could not execute spin command (%s: %s)', command_response.status_code, command_response.text)
1540
- raise CommandError(f'Could not execute spin command ({command_response.status_code}: {command_response.text})')
1541
- else:
1542
- LOG.info('Spin verify command executed successfully')
1667
+ try:
1668
+ command_response: requests.Response = self.session.post(url, data=json.dumps(command_dict), allow_redirects=True)
1669
+ if command_response.status_code != requests.codes['ok']:
1670
+ LOG.error('Could not execute spin command (%s: %s)', command_response.status_code, command_response.text)
1671
+ raise CommandError(f'Could not execute spin command ({command_response.status_code}: {command_response.text})')
1672
+ else:
1673
+ LOG.info('Spin verify command executed successfully')
1674
+ except requests.exceptions.ConnectionError as connection_error:
1675
+ raise CommandError(f'Connection error: {connection_error}.'
1676
+ ' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
1677
+ except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
1678
+ raise CommandError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
1679
+ except requests.exceptions.ReadTimeout as timeout_error:
1680
+ raise CommandError(f'Timeout during read: {timeout_error}') from timeout_error
1681
+ except requests.exceptions.RetryError as retry_error:
1682
+ raise CommandError(f'Retrying failed: {retry_error}') from retry_error
1543
1683
  return command_arguments