carconnectivity-connector-seatcupra 0.2a4__py3-none-any.whl → 0.3__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.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: carconnectivity-connector-seatcupra
3
- Version: 0.2a4
3
+ Version: 0.3
4
4
  Summary: CarConnectivity connector for Seat and Cupra services
5
5
  Author: Till Steinbach
6
6
  License: MIT License
@@ -37,10 +37,11 @@ Classifier: Topic :: Software Development :: Libraries
37
37
  Requires-Python: >=3.9
38
38
  Description-Content-Type: text/markdown
39
39
  License-File: LICENSE
40
- Requires-Dist: carconnectivity>=0.5a4
40
+ Requires-Dist: carconnectivity>=0.6
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
+ Dynamic: license-file
44
45
 
45
46
 
46
47
 
@@ -0,0 +1,21 @@
1
+ carconnectivity_connector_seatcupra-0.3.dist-info/licenses/LICENSE,sha256=PIwI1alwDyOfvEQHdGCm2u9uf_mGE8030xZDfun0xTo,1071
2
+ carconnectivity_connectors/seatcupra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ carconnectivity_connectors/seatcupra/_version.py,sha256=hptOGIBLOnpzA-fkbjoP65wPqWhg_6jCYYIUObQw6xc,506
4
+ carconnectivity_connectors/seatcupra/capability.py,sha256=936V06hOX8AuAMxL_S9wVyVa36Xw1bo9081X0xf5f94,5064
5
+ carconnectivity_connectors/seatcupra/charging.py,sha256=mayvseay5x2r2qjWqol0ijlgoBL2L2A0A96T44FOiHg,4076
6
+ carconnectivity_connectors/seatcupra/climatization.py,sha256=0xxWlxrheAPzkVT8WRQtbm6ExZmVdgW7lUdOXyS_qWY,1695
7
+ carconnectivity_connectors/seatcupra/command_impl.py,sha256=wUmf4IRo4HxzeiS6LKfQzUZBwPO6Gm8GQmVJM9sH1Tk,3226
8
+ carconnectivity_connectors/seatcupra/connector.py,sha256=5bLClhgEyL1R12Ooa3UanRNx0Ke5yrvYp_5qF82hnD4,130762
9
+ carconnectivity_connectors/seatcupra/vehicle.py,sha256=LHkAlVD_C8xOX81wCGFZbZqyhctpKx-CN0T3NZJ2jFk,3946
10
+ carconnectivity_connectors/seatcupra/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ carconnectivity_connectors/seatcupra/auth/auth_util.py,sha256=Y81h8fGOMSMgPtE4wI_TI9WgE_s43uaPjRLBBINhj4g,4433
12
+ carconnectivity_connectors/seatcupra/auth/my_cupra_session.py,sha256=VF_9U8fESLkndVaPn2W1ZxZwNr9-ndeaegeTVT5FyYk,13904
13
+ carconnectivity_connectors/seatcupra/auth/openid_session.py,sha256=pGdTSt2zMtPWD4EY8MoZTj8lT6_krfa1Xt3Fyh877FA,16972
14
+ carconnectivity_connectors/seatcupra/auth/session_manager.py,sha256=ZIDvC848T3fy6PgGqCl8A2SzaNhu2YG19Xam5kgp7SA,5635
15
+ carconnectivity_connectors/seatcupra/auth/vw_web_session.py,sha256=CcI6m68IyRs6WsMDu-IsW3Dj85vyGiMmxvFqNETMHO0,10929
16
+ carconnectivity_connectors/seatcupra/auth/helpers/blacklist_retry.py,sha256=f3wsiY5bpHDBxp7Va1Mv9nKJ4u3qnCHZZmDu78_AhMk,1251
17
+ carconnectivity_connectors/seatcupra/ui/connector_ui.py,sha256=UXDWnMAyTrm0UReTP2WamorrPE5kAJ5oxOjCp-MrZ-c,1414
18
+ carconnectivity_connector_seatcupra-0.3.dist-info/METADATA,sha256=TAUEL6c8a4npLNiH2ltogQLIBT6D4LysUhLU3wxbHc0,5491
19
+ carconnectivity_connector_seatcupra-0.3.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
20
+ carconnectivity_connector_seatcupra-0.3.dist-info/top_level.txt,sha256=KqA8GviZsDH4PtmnwSQsz0HB_w-TWkeEHLIRNo5dTaI,27
21
+ carconnectivity_connector_seatcupra-0.3.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.2a4'
21
- __version_tuple__ = version_tuple = (0, 2)
20
+ __version__ = version = '0.3'
21
+ __version_tuple__ = version_tuple = (0, 3)
@@ -12,6 +12,8 @@ from carconnectivity.vehicle import ElectricVehicle
12
12
  if TYPE_CHECKING:
13
13
  from typing import Optional, Dict
14
14
 
15
+ from carconnectivity.objects import GenericObject
16
+
15
17
 
16
18
  class SeatCupraCharging(Charging): # pylint: disable=too-many-instance-attributes
17
19
  """
@@ -22,9 +24,22 @@ class SeatCupraCharging(Charging): # pylint: disable=too-many-instance-attribut
22
24
  """
23
25
  def __init__(self, vehicle: ElectricVehicle | None = None, origin: Optional[Charging] = None) -> None:
24
26
  if origin is not None:
25
- super().__init__(origin=origin)
27
+ super().__init__(vehicle=vehicle, origin=origin)
28
+ self.settings = SeatCupraCharging.Settings(parent=self, origin=origin.settings)
26
29
  else:
27
30
  super().__init__(vehicle=vehicle)
31
+ self.settings = SeatCupraCharging.Settings(parent=self, origin=self.settings)
32
+
33
+ class Settings(Charging.Settings):
34
+ """
35
+ This class represents the settings for car volkswagen car charging.
36
+ """
37
+ def __init__(self, parent: Optional[GenericObject] = None, origin: Optional[Charging.Settings] = None) -> None:
38
+ if origin is not None:
39
+ super().__init__(parent=parent, origin=origin)
40
+ else:
41
+ super().__init__(parent=parent)
42
+ self.max_current_in_ampere: Optional[bool] = None
28
43
 
29
44
  class SeatCupraChargingState(Enum,):
30
45
  """
@@ -33,7 +33,11 @@ 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))
@@ -22,7 +22,8 @@ from carconnectivity.windows import Windows
22
22
  from carconnectivity.lights import Lights
23
23
  from carconnectivity.drive import GenericDrive, ElectricDrive, CombustionDrive, DieselDrive
24
24
  from carconnectivity.vehicle import GenericVehicle, ElectricVehicle
25
- from carconnectivity.attributes import BooleanAttribute, DurationAttribute, GenericAttribute, TemperatureAttribute, EnumAttribute
25
+ from carconnectivity.attributes import BooleanAttribute, DurationAttribute, GenericAttribute, TemperatureAttribute, EnumAttribute, CurrentAttribute, \
26
+ LevelAttribute
26
27
  from carconnectivity.units import Temperature
27
28
  from carconnectivity.command_impl import ClimatizationStartStopCommand, WakeSleepCommand, HonkAndFlashCommand, LockUnlockCommand, ChargingStartStopCommand, \
28
29
  WindowHeatingStartStopCommand
@@ -335,6 +336,9 @@ class Connector(BaseConnector):
335
336
  if 'vehicles' in data and data['vehicles'] is not None:
336
337
  for vehicle_dict in data['vehicles']:
337
338
  if 'vin' in vehicle_dict and vehicle_dict['vin'] is not None:
339
+ if vehicle_dict['vin'] in self.active_config['hide_vins']:
340
+ LOG.info('Vehicle %s filtered out due to configuration', vehicle_dict['vin'])
341
+ continue
338
342
  vin: str = vehicle_dict['vin']
339
343
  seen_vehicle_vins.add(vin)
340
344
  vehicle: Optional[GenericVehicle] = garage.get_vehicle(vin) # pyright: ignore[reportAssignmentType]
@@ -1132,22 +1136,84 @@ class Connector(BaseConnector):
1132
1136
  log_extra_keys(LOG_API, f'https://ola.prod.code.seat.cloud.vwgroup.com/v1/vehicles/{vin}/charging/status', data,
1133
1137
  {'state', 'battery', 'charging', 'plug'})
1134
1138
 
1135
- url = f'https://ola.prod.code.seat.cloud.vwgroup.com/v1/vehicles/{vin}/charging/settings'
1139
+ url = f'https://ola.prod.code.seat.cloud.vwgroup.com/vehicles/{vin}/charging/settings'
1136
1140
  data: Dict[str, Any] | None = self._fetch_data(url=url, session=self.session, no_cache=no_cache)
1137
1141
  if data is not None:
1138
- if 'maxChargeCurrentAc' in data and data['maxChargeCurrentAc'] is not None:
1139
- if data['maxChargeCurrentAc']:
1140
- vehicle.charging.settings.maximum_current._set_value(value=16, # pylint: disable=protected-access
1141
- unit=Current.A)
1142
+ # {'settings': {'maxChargeCurrentAC': 'reduced', 'carCapturedTimestamp': '2025-03-18T16:50:33Z', 'autoUnlockPlugWhenCharged': None, 'targetSoc_pct': 100, 'batteryCareTargetSocPercentage': 80}}
1143
+ if 'settings' in data and data['settings'] is not None:
1144
+ if 'carCapturedTimestamp' not in data['settings'] or data['settings']['carCapturedTimestamp'] is None:
1145
+ raise APIError('Could not fetch vehicle status, carCapturedTimestamp missing')
1146
+ captured_at: datetime = robust_time_parse(data['settings']['carCapturedTimestamp'])
1147
+ if 'maxChargeCurrentAC_A' in data['settings'] and data['settings']['maxChargeCurrentAC_A'] is not None:
1148
+ if isinstance(vehicle.charging.settings, SeatCupraCharging.Settings):
1149
+ vehicle.charging.settings.max_current_in_ampere = True
1150
+ else:
1151
+ raise ValueError('Charging settings not of type VolkswagenCharging.Settings')
1152
+ vehicle.charging.settings.maximum_current.minimum = 6.0
1153
+ vehicle.charging.settings.maximum_current.maximum = 16.0
1154
+ vehicle.charging.settings.maximum_current.precision = 1.0
1155
+ # pylint: disable-next=protected-access
1156
+ vehicle.charging.settings.maximum_current._add_on_set_hook(self.__on_charging_settings_change)
1157
+ vehicle.charging.settings.maximum_current._is_changeable = True # pylint: disable=protected-access
1158
+ vehicle.charging.settings.maximum_current._set_value(data['settings']['maxChargeCurrentAC_A'], # pylint: disable=protected-access
1159
+ measured=captured_at)
1160
+ elif 'maxChargeCurrentAC' in data['settings'] and data['settings']['maxChargeCurrentAC'] is not None:
1161
+ if isinstance(vehicle.charging.settings, SeatCupraCharging.Settings):
1162
+ vehicle.charging.settings.max_current_in_ampere = False
1163
+ else:
1164
+ raise ValueError('Charging settings not of type VolkswagenCharging.Settings')
1165
+ vehicle.charging.settings.maximum_current.minimum = 6.0
1166
+ vehicle.charging.settings.maximum_current.maximum = 16.0
1167
+ vehicle.charging.settings.maximum_current.precision = 1.0
1168
+ # pylint: disable-next=protected-access
1169
+ vehicle.charging.settings.maximum_current._add_on_set_hook(self.__on_charging_settings_change)
1170
+ vehicle.charging.settings.maximum_current._is_changeable = True # pylint: disable=protected-access
1171
+ if data['settings']['maxChargeCurrentAC'] == 'maximum':
1172
+ vehicle.charging.settings.maximum_current._set_value(16.0, # pylint: disable=protected-access
1173
+ measured=captured_at)
1174
+ elif data['settings']['maxChargeCurrentAC'] == 'reduced':
1175
+ vehicle.charging.settings.maximum_current._set_value(6.0, # pylint: disable=protected-access
1176
+ measured=captured_at)
1177
+ else:
1178
+ LOG_API.info('Unknown max charge current %s', data['settings']['maxChargeCurrentAC'])
1179
+ vehicle.charging.settings.maximum_current._set_value(None, measured=captured_at) # pylint: disable=protected-access
1142
1180
  else:
1143
- vehicle.charging.settings.maximum_current._set_value(value=6, # pylint: disable=protected-access
1144
- unit=Current.A)
1145
- else:
1146
- vehicle.charging.settings.maximum_current._set_value(None) # pylint: disable=protected-access
1147
- if 'defaultMaxTargetSocPercentage' in data and data['defaultMaxTargetSocPercentage'] is not None:
1148
- vehicle.charging.settings.target_level._set_value(data['defaultMaxTargetSocPercentage']) # pylint: disable=protected-access
1149
- else:
1150
- vehicle.charging.settings.target_level._set_value(None) # pylint: disable=protected-access
1181
+ vehicle.charging.settings.maximum_current._set_value(None, measured=captured_at) # pylint: disable=protected-access
1182
+ if 'autoUnlockPlugWhenCharged' in data['settings'] and data['settings']['autoUnlockPlugWhenCharged'] is not None:
1183
+ # pylint: disable-next=protected-access
1184
+ vehicle.charging.settings.auto_unlock._add_on_set_hook(self.__on_charging_settings_change)
1185
+ vehicle.charging.settings.auto_unlock._is_changeable = True # pylint: disable=protected-access
1186
+ if data['settings']['autoUnlockPlugWhenCharged'] == 'on':
1187
+ vehicle.charging.settings.auto_unlock._set_value(True, # pylint: disable=protected-access
1188
+ measured=captured_at)
1189
+ elif data['settings']['autoUnlockPlugWhenCharged'] == 'off':
1190
+ vehicle.charging.settings.auto_unlock._set_value(False, # pylint: disable=protected-access
1191
+ measured=captured_at)
1192
+ else:
1193
+ LOG_API.info('Unknown auto unlock plug when charged %s', data['settings']['autoUnlockPlugWhenCharged'])
1194
+ vehicle.charging.settings.auto_unlock._set_value(None, measured=captured_at) # pylint: disable=protected-access
1195
+ else:
1196
+ vehicle.charging.settings.auto_unlock._set_value(None, measured=captured_at) # pylint: disable=protected-access
1197
+ if 'targetSoc_pct' in data['settings'] and data['settings']['targetSoc_pct'] is not None:
1198
+ charging_capability: Optional[Capability] = vehicle.capabilities.get_capability('charging')
1199
+ if charging_capability is not None and ('supportsTargetStateOfCharge' not in charging_capability.parameters
1200
+ or charging_capability.parameters['supportsTargetStateOfCharge'] != 'false'):
1201
+ vehicle.charging.settings.target_level.minimum = 50.0
1202
+ vehicle.charging.settings.target_level.maximum = 100.0
1203
+ vehicle.charging.settings.target_level.precision = 10.0
1204
+ # pylint: disable-next=protected-access
1205
+ vehicle.charging.settings.target_level._add_on_set_hook(self.__on_charging_settings_change)
1206
+ vehicle.charging.settings.target_level._is_changeable = True # pylint: disable=protected-access
1207
+ vehicle.charging.settings.target_level._set_value(data['settings']['targetSoc_pct'], # pylint: disable=protected-access
1208
+ measured=captured_at)
1209
+ else:
1210
+ vehicle.charging.settings.target_level._set_value(None, measured=captured_at) # pylint: disable=protected-access
1211
+ log_extra_keys(LOG_API, 'chargingSettings', data['settings'], {'carCapturedTimestamp', 'maxChargeCurrentAC_A', 'maxChargeCurrentAC',
1212
+ 'autoUnlockPlugWhenCharged', 'targetSoc_pct'})
1213
+ else:
1214
+ vehicle.charging.settings.maximum_current._set_value(None) # pylint: disable=protected-access
1215
+ vehicle.charging.settings.auto_unlock._set_value(None) # pylint: disable=protected-access
1216
+ vehicle.charging.settings.target_level._set_value(None) # pylint: disable=protected-access
1151
1217
  return vehicle
1152
1218
 
1153
1219
  def fetch_image(self, vehicle: SeatCupraVehicle, no_cache: bool = False) -> SeatCupraVehicle:
@@ -1453,7 +1519,7 @@ class Connector(BaseConnector):
1453
1519
 
1454
1520
  try:
1455
1521
  command_response: requests.Response = self.session.post(url, data='{}', allow_redirects=True)
1456
- if command_response.status_code not in (requests.codes['ok'], requests.codes['no_content']):
1522
+ if command_response.status_code not in (requests.codes['ok'], requests.codes['no_content'], requests.codes['created']):
1457
1523
  LOG.error('Could not execute wake command (%s: %s)', command_response.status_code, command_response.text)
1458
1524
  raise CommandError(f'Could not execute wake command ({command_response.status_code}: {command_response.text})')
1459
1525
  except requests.exceptions.ConnectionError as connection_error:
@@ -1502,7 +1568,7 @@ class Connector(BaseConnector):
1502
1568
  url = f'https://ola.prod.code.seat.cloud.vwgroup.com/v1/vehicles/{vin}/honk-and-flash'
1503
1569
  try:
1504
1570
  command_response: requests.Response = self.session.post(url, data=json.dumps(command_dict), allow_redirects=True)
1505
- if command_response.status_code not in (requests.codes['ok'], requests.codes['no_content']):
1571
+ if command_response.status_code not in (requests.codes['ok'], requests.codes['no_content'], requests.codes['created']):
1506
1572
  LOG.error('Could not execute honk or flash command (%s: %s)', command_response.status_code, command_response.text)
1507
1573
  raise CommandError(f'Could not execute honk or flash command ({command_response.status_code}: {command_response.text})')
1508
1574
  except requests.exceptions.ConnectionError as connection_error:
@@ -1594,10 +1660,13 @@ class Connector(BaseConnector):
1594
1660
  setting_dict['targetTemperatureUnit'] = 'farenheit'
1595
1661
  else:
1596
1662
  setting_dict['targetTemperatureUnit'] = 'celsius'
1597
- if isinstance(attribute, BooleanAttribute) and attribute.id == 'climatisation_without_external_power':
1598
- setting_dict['climatisationWithoutExternalPower'] = value
1599
- elif settings.climatization_without_external_power.enabled and settings.climatization_without_external_power.value is not None:
1600
- setting_dict['climatisationWithoutExternalPower'] = settings.climatization_without_external_power.value
1663
+ climatization_capability: Optional[Capability] = vehicle.capabilities.get_capability('climatisation')
1664
+ if climatization_capability is not None and ('supportsOffGridClimatisation' not in climatization_capability.parameters
1665
+ or climatization_capability.parameters['supportsOffGridClimatisation'] != 'false'):
1666
+ if isinstance(attribute, BooleanAttribute) and attribute.id == 'climatisation_without_external_power':
1667
+ setting_dict['climatisationWithoutExternalPower'] = value
1668
+ elif settings.climatization_without_external_power.enabled and settings.climatization_without_external_power.value is not None:
1669
+ setting_dict['climatisationWithoutExternalPower'] = settings.climatization_without_external_power.value
1601
1670
 
1602
1671
  url: str = f'https://ola.prod.code.seat.cloud.vwgroup.com/v2/vehicles/{vin}/climatisation/settings'
1603
1672
  try:
@@ -1653,6 +1722,77 @@ class Connector(BaseConnector):
1653
1722
  raise CommandError(f'Retrying failed: {retry_error}') from retry_error
1654
1723
  return command_arguments
1655
1724
 
1725
+ def __on_charging_settings_change(self, attribute: GenericAttribute, value: Any) -> Any:
1726
+ """
1727
+ Callback for the charging setting change.
1728
+ """
1729
+ if attribute.parent is None or not isinstance(attribute.parent, SeatCupraCharging.Settings) \
1730
+ or attribute.parent.parent is None \
1731
+ or attribute.parent.parent.parent is None or not isinstance(attribute.parent.parent.parent, SeatCupraVehicle):
1732
+ raise SetterError('Object hierarchy is not as expected')
1733
+ settings: SeatCupraCharging.Settings = attribute.parent
1734
+ vehicle: SeatCupraVehicle = attribute.parent.parent.parent
1735
+ vin: Optional[str] = vehicle.vin.value
1736
+ if vin is None:
1737
+ raise SetterError('VIN in object hierarchy missing')
1738
+ setting_dict = {}
1739
+ precision: float = settings.maximum_current.precision if settings.maximum_current.precision is not None else 1.0
1740
+ if isinstance(attribute, CurrentAttribute) and attribute.id == 'maximum_current':
1741
+ value = round(value / precision) * precision
1742
+ if settings.max_current_in_ampere:
1743
+ setting_dict['maxChargeCurrentAcInAmperes'] = value
1744
+ else:
1745
+ if value < 6:
1746
+ raise SetterError('Maximum current must be greater than 6 amps')
1747
+ if value < 16:
1748
+ setting_dict['maxChargeCurrentAc'] = 'reduced'
1749
+ value = 6.0
1750
+ else:
1751
+ setting_dict['maxChargeCurrentAc'] = 'maximum'
1752
+ value = 16.0
1753
+ elif settings.maximum_current.enabled and settings.maximum_current.value is not None:
1754
+ if settings.max_current_in_ampere:
1755
+ setting_dict['maxChargeCurrentAc_A'] = round(settings.maximum_current.value / precision) * precision
1756
+ else:
1757
+ if settings.maximum_current.value < 6:
1758
+ raise SetterError('Maximum current must be greater than 6 amps')
1759
+ if settings.maximum_current.value < 16:
1760
+ setting_dict['maxChargeCurrentAc'] = 'reduced'
1761
+ settings.maximum_current.value = 6.0
1762
+ else:
1763
+ setting_dict['maxChargeCurrentAc'] = 'maximum'
1764
+ settings.maximum_current.value = 16.0
1765
+ if isinstance(attribute, BooleanAttribute) and attribute.id == 'auto_unlock':
1766
+ setting_dict['autoUnlockPlugWhenChargedAc'] = 'on' if value else 'off'
1767
+ elif settings.auto_unlock.enabled and settings.auto_unlock.value is not None:
1768
+ setting_dict['autoUnlockPlugWhenChargedAc'] = 'on' if settings.auto_unlock.value else 'off'
1769
+ charging_capability: Optional[Capability] = vehicle.capabilities.get_capability('charging')
1770
+ if charging_capability is not None and ('supportsTargetStateOfCharge' not in charging_capability.parameters
1771
+ or charging_capability.parameters['supportsTargetStateOfCharge'] != 'false'):
1772
+ precision: float = settings.target_level.precision if settings.target_level.precision is not None else 10.0
1773
+ if isinstance(attribute, LevelAttribute) and attribute.id == 'target_level':
1774
+ value = round(value / precision) * precision
1775
+ setting_dict['targetSoc'] = value
1776
+ elif settings.target_level.enabled and settings.target_level.value is not None:
1777
+ setting_dict['targetSoc'] = round(settings.target_level.value / precision) * precision
1778
+
1779
+ url: str = f'https://ola.prod.code.seat.cloud.vwgroup.com/v1/vehicles/{vin}/charging/settings'
1780
+ try:
1781
+ settings_response: requests.Response = self.session.post(url, data=json.dumps(setting_dict), allow_redirects=True)
1782
+ if settings_response.status_code not in [requests.codes['ok'], requests.codes['created']]:
1783
+ LOG.error('Could not set charging settings (%s)', settings_response.status_code)
1784
+ raise SetterError(f'Could not set value ({settings_response.status_code})')
1785
+ except requests.exceptions.ConnectionError as connection_error:
1786
+ raise SetterError(f'Connection error: {connection_error}.'
1787
+ ' If this happens frequently, please check if other applications communicate with the Volkswagen server.') from connection_error
1788
+ except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
1789
+ raise SetterError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
1790
+ except requests.exceptions.ReadTimeout as timeout_error:
1791
+ raise SetterError(f'Timeout during read: {timeout_error}') from timeout_error
1792
+ except requests.exceptions.RetryError as retry_error:
1793
+ raise SetterError(f'Retrying failed: {retry_error}') from retry_error
1794
+ return value
1795
+
1656
1796
  def get_version(self) -> str:
1657
1797
  return __version__
1658
1798
 
@@ -19,8 +19,8 @@ class ConnectorUI(BaseConnectorUI):
19
19
  A user interface class for the Seat/Cupra connector in the Car Connectivity application.
20
20
  """
21
21
  def __init__(self, connector: BaseConnector):
22
- blueprint: Optional[flask.Blueprint] = flask.Blueprint(name='seatcupra', import_name='carconnectivity-connector-seatcupra', url_prefix='/seatcupra',
23
- template_folder=os.path.dirname(__file__) + '/templates')
22
+ blueprint: Optional[flask.Blueprint] = flask.Blueprint(name=connector.id, import_name='carconnectivity-connector-seatcupra', 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]]]:
@@ -6,6 +6,7 @@ from carconnectivity.vehicle import GenericVehicle, ElectricVehicle, CombustionV
6
6
 
7
7
  from carconnectivity_connectors.seatcupra.capability import Capabilities
8
8
  from carconnectivity_connectors.seatcupra.climatization import SeatCupraClimatization
9
+ from carconnectivity_connectors.seatcupra.charging import SeatCupraCharging
9
10
 
10
11
  SUPPORT_IMAGES = False
11
12
  try:
@@ -17,6 +18,8 @@ except ImportError:
17
18
  if TYPE_CHECKING:
18
19
  from typing import Optional, Dict
19
20
  from carconnectivity.garage import Garage
21
+ from carconnectivity.charging import Charging
22
+
20
23
  from carconnectivity_connectors.base.connector import BaseConnector
21
24
 
22
25
 
@@ -55,8 +58,13 @@ class SeatCupraElectricVehicle(ElectricVehicle, SeatCupraVehicle):
55
58
  origin: Optional[SeatCupraVehicle] = None) -> None:
56
59
  if origin is not None:
57
60
  super().__init__(garage=garage, origin=origin)
61
+ if isinstance(origin, ElectricVehicle):
62
+ self.charging: Charging = SeatCupraCharging(vehicle=self, origin=origin.charging)
63
+ else:
64
+ self.charging: Charging = SeatCupraCharging(vehicle=self, origin=self.charging)
58
65
  else:
59
66
  super().__init__(vin=vin, garage=garage, managing_connector=managing_connector)
67
+ self.charging: Charging = SeatCupraCharging(vehicle=self, origin=self.charging)
60
68
 
61
69
 
62
70
  class SeatCupraCombustionVehicle(CombustionVehicle, SeatCupraVehicle):
@@ -1,21 +0,0 @@
1
- carconnectivity_connectors/seatcupra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- carconnectivity_connectors/seatcupra/_version.py,sha256=tfKjOgkysWzsCAchrdls12fBGPdso8aTKDZv71JrhH4,508
3
- carconnectivity_connectors/seatcupra/capability.py,sha256=936V06hOX8AuAMxL_S9wVyVa36Xw1bo9081X0xf5f94,5064
4
- carconnectivity_connectors/seatcupra/charging.py,sha256=BJe_5GEB0JkP78tpU6kyKpwuwjDZHvm-kt3PTlpQHeU,3336
5
- carconnectivity_connectors/seatcupra/climatization.py,sha256=0xxWlxrheAPzkVT8WRQtbm6ExZmVdgW7lUdOXyS_qWY,1695
6
- carconnectivity_connectors/seatcupra/command_impl.py,sha256=LmBOCWGZPfJCG_4-5449xvO6NAvnPDsAWEBKlsG4WoI,3051
7
- carconnectivity_connectors/seatcupra/connector.py,sha256=PoTAAWKbToQ_a7VTLnfS2vDyxdj_mZ_dNZjs0YK7xYk,118807
8
- carconnectivity_connectors/seatcupra/vehicle.py,sha256=-M_d1Boly5DLJSQT_Zc8R3JJ7Csi_M4kktgGqjTrPAQ,3463
9
- carconnectivity_connectors/seatcupra/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- carconnectivity_connectors/seatcupra/auth/auth_util.py,sha256=Y81h8fGOMSMgPtE4wI_TI9WgE_s43uaPjRLBBINhj4g,4433
11
- carconnectivity_connectors/seatcupra/auth/my_cupra_session.py,sha256=VF_9U8fESLkndVaPn2W1ZxZwNr9-ndeaegeTVT5FyYk,13904
12
- carconnectivity_connectors/seatcupra/auth/openid_session.py,sha256=pGdTSt2zMtPWD4EY8MoZTj8lT6_krfa1Xt3Fyh877FA,16972
13
- carconnectivity_connectors/seatcupra/auth/session_manager.py,sha256=ZIDvC848T3fy6PgGqCl8A2SzaNhu2YG19Xam5kgp7SA,5635
14
- carconnectivity_connectors/seatcupra/auth/vw_web_session.py,sha256=CcI6m68IyRs6WsMDu-IsW3Dj85vyGiMmxvFqNETMHO0,10929
15
- carconnectivity_connectors/seatcupra/auth/helpers/blacklist_retry.py,sha256=f3wsiY5bpHDBxp7Va1Mv9nKJ4u3qnCHZZmDu78_AhMk,1251
16
- carconnectivity_connectors/seatcupra/ui/connector_ui.py,sha256=SNYnlcGJpbWhuLiIHD2l6H9IfSiMz3IgmvXsdossDnE,1412
17
- carconnectivity_connector_seatcupra-0.2a4.dist-info/LICENSE,sha256=PIwI1alwDyOfvEQHdGCm2u9uf_mGE8030xZDfun0xTo,1071
18
- carconnectivity_connector_seatcupra-0.2a4.dist-info/METADATA,sha256=6DlLIQCvCZlpR_8QEC6_ksBczkiLvjIUm_097x-95mY,5473
19
- carconnectivity_connector_seatcupra-0.2a4.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
20
- carconnectivity_connector_seatcupra-0.2a4.dist-info/top_level.txt,sha256=KqA8GviZsDH4PtmnwSQsz0HB_w-TWkeEHLIRNo5dTaI,27
21
- carconnectivity_connector_seatcupra-0.2a4.dist-info/RECORD,,