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.
- {carconnectivity_connector_seatcupra-0.2a4.dist-info → carconnectivity_connector_seatcupra-0.3.dist-info}/METADATA +4 -3
- carconnectivity_connector_seatcupra-0.3.dist-info/RECORD +21 -0
- {carconnectivity_connector_seatcupra-0.2a4.dist-info → carconnectivity_connector_seatcupra-0.3.dist-info}/WHEEL +1 -1
- carconnectivity_connectors/seatcupra/_version.py +2 -2
- carconnectivity_connectors/seatcupra/charging.py +16 -1
- carconnectivity_connectors/seatcupra/command_impl.py +5 -1
- carconnectivity_connectors/seatcupra/connector.py +160 -20
- carconnectivity_connectors/seatcupra/ui/connector_ui.py +2 -2
- carconnectivity_connectors/seatcupra/vehicle.py +8 -0
- carconnectivity_connector_seatcupra-0.2a4.dist-info/RECORD +0 -21
- {carconnectivity_connector_seatcupra-0.2a4.dist-info → carconnectivity_connector_seatcupra-0.3.dist-info/licenses}/LICENSE +0 -0
- {carconnectivity_connector_seatcupra-0.2a4.dist-info → carconnectivity_connector_seatcupra-0.3.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: carconnectivity-connector-seatcupra
|
3
|
-
Version: 0.
|
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.
|
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,,
|
@@ -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,
|
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/
|
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
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
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(
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
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
|
-
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
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=
|
23
|
-
|
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,,
|
File without changes
|