carconnectivity-connector-seatcupra 0.1a18__py3-none-any.whl → 0.1.1__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.1a18.dist-info → carconnectivity_connector_seatcupra-0.1.1.dist-info}/METADATA +2 -5
- {carconnectivity_connector_seatcupra-0.1a18.dist-info → carconnectivity_connector_seatcupra-0.1.1.dist-info}/RECORD +8 -8
- carconnectivity_connectors/seatcupra/_version.py +2 -2
- carconnectivity_connectors/seatcupra/capability.py +11 -4
- carconnectivity_connectors/seatcupra/connector.py +75 -9
- {carconnectivity_connector_seatcupra-0.1a18.dist-info → carconnectivity_connector_seatcupra-0.1.1.dist-info}/LICENSE +0 -0
- {carconnectivity_connector_seatcupra-0.1a18.dist-info → carconnectivity_connector_seatcupra-0.1.1.dist-info}/WHEEL +0 -0
- {carconnectivity_connector_seatcupra-0.1a18.dist-info → carconnectivity_connector_seatcupra-0.1.1.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: carconnectivity-connector-seatcupra
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.1.1
|
4
4
|
Summary: CarConnectivity connector for Seat and Cupra 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.9
|
38
38
|
Description-Content-Type: text/markdown
|
39
39
|
License-File: LICENSE
|
40
|
-
Requires-Dist: carconnectivity>=0.
|
40
|
+
Requires-Dist: carconnectivity>=0.4
|
41
41
|
Requires-Dist: oauthlib~=3.2.2
|
42
42
|
Requires-Dist: requests~=2.32.3
|
43
43
|
Requires-Dist: jwt~=1.3.1
|
@@ -54,9 +54,6 @@ Requires-Dist: jwt~=1.3.1
|
|
54
54
|
[](https://www.paypal.com/donate?hosted_button_id=2BVFF5GJ9SXAJ)
|
55
55
|
[](https://github.com/sponsors/tillsteinbach)
|
56
56
|
|
57
|
-
|
58
|
-
## Due to lack of access to a Cupra car the development of this conenctor is currently stuck. If you want to help me with access to your account, please contact me!
|
59
|
-
|
60
57
|
[CarConnectivity](https://github.com/tillsteinbach/CarConnectivity) is a python API to connect to various car services. This connector enables the integration of seat and cupra vehicles through the MyCupra API. Look at [CarConnectivity](https://github.com/tillsteinbach/CarConnectivity) for other supported brands.
|
61
58
|
|
62
59
|
## Configuration
|
@@ -1,10 +1,10 @@
|
|
1
1
|
carconnectivity_connectors/seatcupra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
carconnectivity_connectors/seatcupra/_version.py,sha256=
|
3
|
-
carconnectivity_connectors/seatcupra/capability.py,sha256=
|
2
|
+
carconnectivity_connectors/seatcupra/_version.py,sha256=Mmxse1R0ki5tjz9qzU8AQyqUsLt8nTyCAbYQp8R87PU,511
|
3
|
+
carconnectivity_connectors/seatcupra/capability.py,sha256=936V06hOX8AuAMxL_S9wVyVa36Xw1bo9081X0xf5f94,5064
|
4
4
|
carconnectivity_connectors/seatcupra/charging.py,sha256=BJe_5GEB0JkP78tpU6kyKpwuwjDZHvm-kt3PTlpQHeU,3336
|
5
5
|
carconnectivity_connectors/seatcupra/climatization.py,sha256=0xxWlxrheAPzkVT8WRQtbm6ExZmVdgW7lUdOXyS_qWY,1695
|
6
6
|
carconnectivity_connectors/seatcupra/command_impl.py,sha256=LmBOCWGZPfJCG_4-5449xvO6NAvnPDsAWEBKlsG4WoI,3051
|
7
|
-
carconnectivity_connectors/seatcupra/connector.py,sha256=
|
7
|
+
carconnectivity_connectors/seatcupra/connector.py,sha256=llxFhVdpnL5MxmHbOej1wMio5tareY3zha0qaFhnPgs,107680
|
8
8
|
carconnectivity_connectors/seatcupra/vehicle.py,sha256=s0G-HqG5qcwStDxD3649KgLMa3lKPZ4TOGWRJEuQzsQ,3403
|
9
9
|
carconnectivity_connectors/seatcupra/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
carconnectivity_connectors/seatcupra/auth/auth_util.py,sha256=Y81h8fGOMSMgPtE4wI_TI9WgE_s43uaPjRLBBINhj4g,4433
|
@@ -14,8 +14,8 @@ carconnectivity_connectors/seatcupra/auth/session_manager.py,sha256=ZIDvC848T3fy
|
|
14
14
|
carconnectivity_connectors/seatcupra/auth/vw_web_session.py,sha256=CcI6m68IyRs6WsMDu-IsW3Dj85vyGiMmxvFqNETMHO0,10929
|
15
15
|
carconnectivity_connectors/seatcupra/auth/helpers/blacklist_retry.py,sha256=f3wsiY5bpHDBxp7Va1Mv9nKJ4u3qnCHZZmDu78_AhMk,1251
|
16
16
|
carconnectivity_connectors/seatcupra/ui/connector_ui.py,sha256=SNYnlcGJpbWhuLiIHD2l6H9IfSiMz3IgmvXsdossDnE,1412
|
17
|
-
carconnectivity_connector_seatcupra-0.
|
18
|
-
carconnectivity_connector_seatcupra-0.
|
19
|
-
carconnectivity_connector_seatcupra-0.
|
20
|
-
carconnectivity_connector_seatcupra-0.
|
21
|
-
carconnectivity_connector_seatcupra-0.
|
17
|
+
carconnectivity_connector_seatcupra-0.1.1.dist-info/LICENSE,sha256=PIwI1alwDyOfvEQHdGCm2u9uf_mGE8030xZDfun0xTo,1071
|
18
|
+
carconnectivity_connector_seatcupra-0.1.1.dist-info/METADATA,sha256=Vh1baAcurqTyzfkXNO_Ts4GNO8nbFwXgpDS3r8kK2xs,5471
|
19
|
+
carconnectivity_connector_seatcupra-0.1.1.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
20
|
+
carconnectivity_connector_seatcupra-0.1.1.dist-info/top_level.txt,sha256=KqA8GviZsDH4PtmnwSQsz0HB_w-TWkeEHLIRNo5dTaI,27
|
21
|
+
carconnectivity_connector_seatcupra-0.1.1.dist-info/RECORD,,
|
@@ -5,7 +5,7 @@ from typing import TYPE_CHECKING
|
|
5
5
|
from enum import IntEnum
|
6
6
|
|
7
7
|
from carconnectivity.objects import GenericObject
|
8
|
-
from carconnectivity.attributes import StringAttribute, BooleanAttribute, DateAttribute
|
8
|
+
from carconnectivity.attributes import StringAttribute, BooleanAttribute, DateAttribute, GenericAttribute
|
9
9
|
|
10
10
|
if TYPE_CHECKING:
|
11
11
|
from typing import Dict, Optional, List
|
@@ -77,7 +77,7 @@ class Capabilities(GenericObject):
|
|
77
77
|
"""
|
78
78
|
return self.__capabilities.get(capability_id)
|
79
79
|
|
80
|
-
def has_capability(self, capability_id: str) -> bool:
|
80
|
+
def has_capability(self, capability_id: str, check_status_ok=False) -> bool:
|
81
81
|
"""
|
82
82
|
Check if the Capabilities contains a capability with the specified ID.
|
83
83
|
|
@@ -87,7 +87,14 @@ class Capabilities(GenericObject):
|
|
87
87
|
Returns:
|
88
88
|
bool: True if the capability exists, otherwise False.
|
89
89
|
"""
|
90
|
-
|
90
|
+
if check_status_ok:
|
91
|
+
if capability_id in self.__capabilities and self.__capabilities[capability_id].enabled:
|
92
|
+
capability: Capability = self.__capabilities[capability_id]
|
93
|
+
if capability.status.enabled and capability.status.value is not None and len(capability.status.value) > 0:
|
94
|
+
return False
|
95
|
+
return True
|
96
|
+
return False
|
97
|
+
return capability_id in self.__capabilities and self.__capabilities[capability_id].enabled
|
91
98
|
|
92
99
|
|
93
100
|
class Capability(GenericObject):
|
@@ -105,7 +112,7 @@ class Capability(GenericObject):
|
|
105
112
|
self.capability_id = StringAttribute("id", self, capability_id, tags={'connector_custom'})
|
106
113
|
self.expiration_date = DateAttribute("expiration_date", self, tags={'connector_custom'})
|
107
114
|
self.editable = BooleanAttribute("editable", self, tags={'connector_custom'})
|
108
|
-
self.
|
115
|
+
self.status = GenericAttribute("status", self, value=[], tags={'connector_custom'})
|
109
116
|
self.parameters: Dict[str, bool] = {}
|
110
117
|
self.enabled = True
|
111
118
|
self.delay_notifications = False
|
@@ -288,16 +288,32 @@ class Connector(BaseConnector):
|
|
288
288
|
vehicle_to_update = self.fetch_vehicle_status(vehicle_to_update)
|
289
289
|
vehicle_to_update = self.fetch_vehicle_mycar_status(vehicle_to_update)
|
290
290
|
vehicle_to_update = self.fetch_mileage(vehicle_to_update)
|
291
|
-
if vehicle_to_update.capabilities.has_capability('climatisation'):
|
291
|
+
if vehicle_to_update.capabilities.has_capability('climatisation', check_status_ok=True):
|
292
292
|
vehicle_to_update = self.fetch_climatisation(vehicle_to_update)
|
293
|
-
if vehicle_to_update.capabilities.has_capability('charging'):
|
293
|
+
if vehicle_to_update.capabilities.has_capability('charging', check_status_ok=True):
|
294
294
|
vehicle_to_update = self.fetch_charging(vehicle_to_update)
|
295
|
-
if vehicle_to_update.capabilities.has_capability('parkingPosition'):
|
295
|
+
if vehicle_to_update.capabilities.has_capability('parkingPosition', check_status_ok=True):
|
296
296
|
vehicle_to_update = self.fetch_parking_position(vehicle_to_update)
|
297
|
-
if vehicle_to_update.capabilities.has_capability('vehicleHealthInspection'):
|
297
|
+
if vehicle_to_update.capabilities.has_capability('vehicleHealthInspection', check_status_ok=True):
|
298
298
|
vehicle_to_update = self.fetch_maintenance(vehicle_to_update)
|
299
|
+
vehicle_to_update = self.fetch_connection_status(vehicle_to_update)
|
300
|
+
self.decide_state(vehicle_to_update)
|
299
301
|
self.car_connectivity.transaction_end()
|
300
302
|
|
303
|
+
def decide_state(self, vehicle: SeatCupraVehicle) -> None:
|
304
|
+
"""
|
305
|
+
Decides the state of the vehicle based on the current data.
|
306
|
+
|
307
|
+
Args:
|
308
|
+
vehicle (SeatCupraVehicle): The SeatCupra vehicle object.
|
309
|
+
"""
|
310
|
+
if vehicle is not None:
|
311
|
+
if vehicle.position is not None and vehicle.position.enabled and vehicle.position.position_type is not None \
|
312
|
+
and vehicle.position.position_type.enabled and vehicle.position.position_type.value == Position.PositionType.PARKING:
|
313
|
+
vehicle.state._set_value(GenericVehicle.State.PARKED) # pylint: disable=protected-access
|
314
|
+
else:
|
315
|
+
vehicle.state._set_value(None) # pylint: disable=protected-access
|
316
|
+
|
301
317
|
def fetch_vehicles(self) -> None:
|
302
318
|
"""
|
303
319
|
Fetches the list of vehicles from the Seat/Cupra Connect API and updates the garage with new vehicles.
|
@@ -369,6 +385,19 @@ class Connector(BaseConnector):
|
|
369
385
|
else:
|
370
386
|
capability = Capability(capability_id=capability_id, capabilities=vehicle.capabilities)
|
371
387
|
vehicle.capabilities.add_capability(capability_id, capability)
|
388
|
+
if 'status' in capability_dict and capability_dict['status'] is not None:
|
389
|
+
statuses = capability_dict['status']
|
390
|
+
if isinstance(statuses, list):
|
391
|
+
for status in statuses:
|
392
|
+
if status in [item.value for item in Capability.Status]:
|
393
|
+
capability.status.value.append(Capability.Status(status))
|
394
|
+
else:
|
395
|
+
LOG_API.warning('Capability status unkown %s', status)
|
396
|
+
capability.status.value.append(Capability.Status.UNKNOWN)
|
397
|
+
else:
|
398
|
+
LOG_API.warning('Capability status not a list in %s', statuses)
|
399
|
+
else:
|
400
|
+
capability.status.value.clear()
|
372
401
|
if 'expirationDate' in capability_dict and capability_dict['expirationDate'] is not None \
|
373
402
|
and capability_dict['expirationDate'] != '':
|
374
403
|
expiration_date: datetime = robust_time_parse(capability_dict['expirationDate'])
|
@@ -390,7 +419,7 @@ class Connector(BaseConnector):
|
|
390
419
|
for capability_id in vehicle.capabilities.capabilities.keys() - found_capabilities:
|
391
420
|
vehicle.capabilities.remove_capability(capability_id)
|
392
421
|
|
393
|
-
if vehicle.capabilities.has_capability('charging'):
|
422
|
+
if vehicle.capabilities.has_capability('charging', check_status_ok=True):
|
394
423
|
if not isinstance(vehicle, SeatCupraElectricVehicle):
|
395
424
|
LOG.debug('Promoting %s to SeatCupraElectricVehicle object for %s', vehicle.__class__.__name__, vin)
|
396
425
|
vehicle = SeatCupraElectricVehicle(origin=vehicle)
|
@@ -401,7 +430,7 @@ class Connector(BaseConnector):
|
|
401
430
|
charging_start_stop_command.enabled = True
|
402
431
|
vehicle.charging.commands.add_command(charging_start_stop_command)
|
403
432
|
|
404
|
-
if vehicle.capabilities.has_capability('climatisation'):
|
433
|
+
if vehicle.capabilities.has_capability('climatisation', check_status_ok=True):
|
405
434
|
if vehicle.climatization is not None and vehicle.climatization.commands is not None \
|
406
435
|
and not vehicle.climatization.commands.contains_command('start-stop'):
|
407
436
|
climatisation_start_stop_command: ClimatizationStartStopCommand = \
|
@@ -411,7 +440,7 @@ class Connector(BaseConnector):
|
|
411
440
|
climatisation_start_stop_command.enabled = True
|
412
441
|
vehicle.climatization.commands.add_command(climatisation_start_stop_command)
|
413
442
|
|
414
|
-
if vehicle.capabilities.has_capability('vehicleWakeUpTrigger'):
|
443
|
+
if vehicle.capabilities.has_capability('vehicleWakeUpTrigger', check_status_ok=True):
|
415
444
|
if vehicle.commands is not None and vehicle.commands.commands is not None \
|
416
445
|
and not vehicle.commands.contains_command('wake-sleep'):
|
417
446
|
wake_sleep_command = WakeSleepCommand(parent=vehicle.commands)
|
@@ -420,7 +449,7 @@ class Connector(BaseConnector):
|
|
420
449
|
vehicle.commands.add_command(wake_sleep_command)
|
421
450
|
|
422
451
|
# Add honkAndFlash command if necessary capabilities are available
|
423
|
-
if vehicle.capabilities.has_capability('honkAndFlash'):
|
452
|
+
if vehicle.capabilities.has_capability('honkAndFlash', check_status_ok=True):
|
424
453
|
if vehicle.commands is not None and vehicle.commands.commands is not None \
|
425
454
|
and not vehicle.commands.contains_command('honk-flash'):
|
426
455
|
honk_flash_command = HonkAndFlashCommand(parent=vehicle.commands, with_duration=True)
|
@@ -429,7 +458,7 @@ class Connector(BaseConnector):
|
|
429
458
|
vehicle.commands.add_command(honk_flash_command)
|
430
459
|
|
431
460
|
# Add lock and unlock command
|
432
|
-
if vehicle.capabilities.has_capability('access'):
|
461
|
+
if vehicle.capabilities.has_capability('access', check_status_ok=True):
|
433
462
|
if vehicle.doors is not None and vehicle.doors.commands is not None and vehicle.doors.commands.commands is not None \
|
434
463
|
and not vehicle.doors.commands.contains_command('lock-unlock'):
|
435
464
|
lock_unlock_command = LockUnlockCommand(parent=vehicle.doors.commands)
|
@@ -710,6 +739,43 @@ class Connector(BaseConnector):
|
|
710
739
|
'remainingTime'})
|
711
740
|
return vehicle
|
712
741
|
|
742
|
+
def fetch_connection_status(self, vehicle: SeatCupraVehicle, no_cache: bool = False) -> SeatCupraVehicle:
|
743
|
+
"""
|
744
|
+
Fetches the connection status of the given Seat/Cupra vehicle and updates its connection attributes.
|
745
|
+
|
746
|
+
Args:
|
747
|
+
vehicle (SeatCupraVehicle): The Seat/Cupra vehicle object containing the VIN and connection attributes.
|
748
|
+
|
749
|
+
Returns:
|
750
|
+
SeatCupraVehicle: The updated Seat/Cupra vehicle object with the fetched connection data.
|
751
|
+
|
752
|
+
Raises:
|
753
|
+
APIError: If the VIN is missing.
|
754
|
+
ValueError: If the vehicle has no connection object.
|
755
|
+
"""
|
756
|
+
vin = vehicle.vin.value
|
757
|
+
if vin is None:
|
758
|
+
raise APIError('VIN is missing')
|
759
|
+
url = f'https://ola.prod.code.seat.cloud.vwgroup.com/vehicles/{vin}/connection'
|
760
|
+
data: Dict[str, Any] | None = self._fetch_data(url=url, session=self.session, no_cache=no_cache)
|
761
|
+
# {'connection': {'mode': 'online'}
|
762
|
+
if data is not None:
|
763
|
+
if 'connection' in data and data['connection'] is not None:
|
764
|
+
if 'mode' in data['connection'] and data['connection']['mode'] is not None:
|
765
|
+
if data['connection']['mode'] in [item.value for item in GenericVehicle.ConnectionState]:
|
766
|
+
connection_state: GenericVehicle.ConnectionState = GenericVehicle.ConnectionState(data['connection']['mode'])
|
767
|
+
vehicle.connection_state._set_value(connection_state) # pylint: disable=protected-access
|
768
|
+
else:
|
769
|
+
vehicle.connection_state._set_value(GenericVehicle.ConnectionState.UNKNOWN) # pylint: disable=protected-access
|
770
|
+
LOG_API.info('Unknown connection state %s', data['connection']['mode'])
|
771
|
+
else:
|
772
|
+
vehicle.connection_state._set_value(None) # pylint: disable=protected-access
|
773
|
+
log_extra_keys(LOG_API, 'connection status', data['connection'], {'mode'})
|
774
|
+
else:
|
775
|
+
vehicle.connection_state._set_value(None) # pylint: disable=protected-access
|
776
|
+
log_extra_keys(LOG_API, 'connection status', data, {'connection'})
|
777
|
+
return vehicle
|
778
|
+
|
713
779
|
def fetch_parking_position(self, vehicle: SeatCupraVehicle, no_cache: bool = False) -> SeatCupraVehicle:
|
714
780
|
"""
|
715
781
|
Fetches the position of the given vehicle and updates its position attributes.
|
File without changes
|
File without changes
|