carconnectivity-connector-seatcupra 0.1a15__py3-none-any.whl → 0.1a17__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
1
  Metadata-Version: 2.2
2
2
  Name: carconnectivity-connector-seatcupra
3
- Version: 0.1a15
3
+ Version: 0.1a17
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.4a8
40
+ Requires-Dist: carconnectivity>=0.4a11
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,10 +1,10 @@
1
1
  carconnectivity_connectors/seatcupra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- carconnectivity_connectors/seatcupra/_version.py,sha256=C1vm3bxABjgmaD2Hpd79Ue7W_YMKggXDlANMpHBdVTI,509
2
+ carconnectivity_connectors/seatcupra/_version.py,sha256=h6qKff23EXoCChHlB_Nct7DIvHThmGCDSsQuZQK2zzA,509
3
3
  carconnectivity_connectors/seatcupra/capability.py,sha256=Oe9tC_u69bj6VmOuNJ21RKoETe2j3QyZCoz-VgcZPQ0,4523
4
4
  carconnectivity_connectors/seatcupra/charging.py,sha256=BJe_5GEB0JkP78tpU6kyKpwuwjDZHvm-kt3PTlpQHeU,3336
5
5
  carconnectivity_connectors/seatcupra/climatization.py,sha256=0xxWlxrheAPzkVT8WRQtbm6ExZmVdgW7lUdOXyS_qWY,1695
6
- carconnectivity_connectors/seatcupra/command_impl.py,sha256=mtw8ZwJLmf79fPDZ1N3ImLfB8Gt9JPbzjMuIo2y5v3M,2879
7
- carconnectivity_connectors/seatcupra/connector.py,sha256=ACP_TJitI1nQqxDzsiMn0HGdRAvoyY3NAZhpm8BltN4,101979
6
+ carconnectivity_connectors/seatcupra/command_impl.py,sha256=LmBOCWGZPfJCG_4-5449xvO6NAvnPDsAWEBKlsG4WoI,3051
7
+ carconnectivity_connectors/seatcupra/connector.py,sha256=cOuQOlnImZlVMOjHbRrm2vo02zlNB4m87uO88subqZk,102253
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.1a15.dist-info/LICENSE,sha256=PIwI1alwDyOfvEQHdGCm2u9uf_mGE8030xZDfun0xTo,1071
18
- carconnectivity_connector_seatcupra-0.1a15.dist-info/METADATA,sha256=O10hztHSKmJMu8BqxiB6qh1isOsQv7gfOnU9M7vVffw,5641
19
- carconnectivity_connector_seatcupra-0.1a15.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
20
- carconnectivity_connector_seatcupra-0.1a15.dist-info/top_level.txt,sha256=KqA8GviZsDH4PtmnwSQsz0HB_w-TWkeEHLIRNo5dTaI,27
21
- carconnectivity_connector_seatcupra-0.1a15.dist-info/RECORD,,
17
+ carconnectivity_connector_seatcupra-0.1a17.dist-info/LICENSE,sha256=PIwI1alwDyOfvEQHdGCm2u9uf_mGE8030xZDfun0xTo,1071
18
+ carconnectivity_connector_seatcupra-0.1a17.dist-info/METADATA,sha256=Dat_Q7Tw4hiyrVptq1LiL5xLSAGzj2RH56jSJFyxR0c,5642
19
+ carconnectivity_connector_seatcupra-0.1a17.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
20
+ carconnectivity_connector_seatcupra-0.1a17.dist-info/top_level.txt,sha256=KqA8GviZsDH4PtmnwSQsz0HB_w-TWkeEHLIRNo5dTaI,27
21
+ carconnectivity_connector_seatcupra-0.1a17.dist-info/RECORD,,
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.1a15'
20
+ __version__ = version = '0.1a17'
21
21
  __version_tuple__ = version_tuple = (0, 1)
@@ -31,6 +31,8 @@ class SpinCommand(GenericCommand):
31
31
 
32
32
  @value.setter
33
33
  def value(self, new_value: Optional[Union[str, Dict]]) -> None:
34
+ # Execute early hooks before parsing the value
35
+ new_value = self._execute_on_set_hook(new_value, early_hook=True)
34
36
  if isinstance(new_value, str):
35
37
  parser = ThrowingArgumentParser(prog='', add_help=False, exit_on_error=False)
36
38
  parser.add_argument('command', help='Command to execute', type=SpinCommand.Command,
@@ -55,8 +57,8 @@ class SpinCommand(GenericCommand):
55
57
  raise ValueError('Invalid value for SpinCommand. '
56
58
  f'Command must be one of {SpinCommand.Command}')
57
59
  if self._is_changeable:
58
- for hook in self._on_set_hooks:
59
- new_value = hook(self, new_value)
60
+ # Execute late hooks before setting the value
61
+ new_value = self._execute_on_set_hook(new_value, early_hook=False)
60
62
  self._set_value(new_value)
61
63
  else:
62
64
  raise TypeError('You cannot set this attribute. Attribute is not mutable.')
@@ -22,7 +22,7 @@ from carconnectivity.windows import Windows
22
22
  from carconnectivity.lights import Lights
23
23
  from carconnectivity.drive import GenericDrive, ElectricDrive, CombustionDrive
24
24
  from carconnectivity.vehicle import GenericVehicle, ElectricVehicle
25
- from carconnectivity.attributes import BooleanAttribute, DurationAttribute, GenericAttribute, TemperatureAttribute
25
+ from carconnectivity.attributes import BooleanAttribute, DurationAttribute, GenericAttribute, TemperatureAttribute, EnumAttribute
26
26
  from carconnectivity.units import Temperature
27
27
  from carconnectivity.command_impl import ClimatizationStartStopCommand, WakeSleepCommand, HonkAndFlashCommand, LockUnlockCommand, ChargingStartStopCommand
28
28
  from carconnectivity.climatization import Climatization
@@ -30,6 +30,7 @@ from carconnectivity.commands import Commands
30
30
  from carconnectivity.charging import Charging
31
31
  from carconnectivity.charging_connector import ChargingConnector
32
32
  from carconnectivity.position import Position
33
+ from carconnectivity.enums import ConnectionState
33
34
 
34
35
  from carconnectivity_connectors.base.connector import BaseConnector
35
36
  from carconnectivity_connectors.seatcupra.auth.session_manager import SessionManager, SessionUser, Service
@@ -76,18 +77,11 @@ class Connector(BaseConnector):
76
77
  self._background_thread: Optional[threading.Thread] = None
77
78
  self._stop_event = threading.Event()
78
79
 
79
- self.connected: BooleanAttribute = BooleanAttribute(name="connected", parent=self, tags={'connector_custom'})
80
+ self.connection_state: EnumAttribute = EnumAttribute(name="connection_state", parent=self, value_type=ConnectionState,
81
+ value=ConnectionState.DISCONNECTED, tags={'connector_custom'})
80
82
  self.interval: DurationAttribute = DurationAttribute(name="interval", parent=self, tags={'connector_custom'})
81
-
82
- def __check_interval(attribute: GenericAttribute, value: Any) -> Any:
83
- del attribute
84
- if value is not None and value < timedelta(seconds=180):
85
- raise ValueError('Intervall must be at least 180 seconds')
86
- return value
87
- self._healthy = False
88
-
83
+ self.interval.minimum = timedelta(seconds=180)
89
84
  self.interval._is_changeable = True # pylint: disable=protected-access
90
- self.interval._add_on_set_hook(__check_interval) # pylint: disable=protected-access
91
85
 
92
86
  self.commands: Commands = Commands(parent=self)
93
87
 
@@ -173,11 +167,12 @@ class Connector(BaseConnector):
173
167
  self._background_thread = threading.Thread(target=self._background_loop, daemon=False)
174
168
  self._background_thread.name = 'carconnectivity.connectors.seatcupra-background'
175
169
  self._background_thread.start()
176
- self._healthy = True
170
+ self.healthy._set_value(value=True) # pylint: disable=protected-access
177
171
 
178
172
  def _background_loop(self) -> None:
179
173
  self._stop_event.clear()
180
174
  fetch: bool = True
175
+ self.connection_state._set_value(value=ConnectionState.CONNECTING) # pylint: disable=protected-access
181
176
  while not self._stop_event.is_set():
182
177
  interval = 300
183
178
  try:
@@ -211,7 +206,7 @@ class Connector(BaseConnector):
211
206
  self._stop_event.wait(interval)
212
207
  except Exception as err:
213
208
  LOG.critical('Critical error during update: %s', traceback.format_exc())
214
- self._healthy = False
209
+ self.healthy._set_value(value=False) # pylint: disable=protected-access
215
210
  raise err
216
211
  else:
217
212
  self._stop_event.wait(interval)
@@ -292,6 +287,7 @@ class Connector(BaseConnector):
292
287
  vehicle_to_update = self.fetch_parking_position(vehicle_to_update)
293
288
  if vehicle_to_update.capabilities.has_capability('vehicleHealthInspection'):
294
289
  vehicle_to_update = self.fetch_maintenance(vehicle_to_update)
290
+ self.car_connectivity.transaction_end()
295
291
 
296
292
  def fetch_vehicles(self) -> None:
297
293
  """
@@ -725,7 +721,7 @@ class Connector(BaseConnector):
725
721
  if vehicle.position is None:
726
722
  raise ValueError('Vehicle has no position object')
727
723
  url = f'https://ola.prod.code.seat.cloud.vwgroup.com/v1/vehicles/{vin}/parkingposition'
728
- data: Dict[str, Any] | None = self._fetch_data(url=url, session=self.session, no_cache=no_cache)
724
+ data: Dict[str, Any] | None = self._fetch_data(url=url, session=self.session, no_cache=no_cache, allow_empty=True)
729
725
  if data is not None:
730
726
  if 'lat' in data and data['lat'] is not None:
731
727
  latitude: Optional[float] = data['lat']
@@ -847,7 +843,7 @@ class Connector(BaseConnector):
847
843
  vehicle.climatization.state._set_value(value=climatization_state, measured=captured_at) # pylint: disable=protected-access
848
844
  else:
849
845
  vehicle.climatization.state._set_value(None) # pylint: disable=protected-access
850
- log_extra_keys(LOG_API, 'climatisation', data, {'carCapturedTimestamp', 'climatisationState'})
846
+ log_extra_keys(LOG_API, 'climatisationStatus', data['climatisationStatus'], {'carCapturedTimestamp', 'climatisationState'})
851
847
  else:
852
848
  vehicle.climatization.state._set_value(None) # pylint: disable=protected-access
853
849
  log_extra_keys(LOG_API, 'climatisation', data, {'climatisationStatus'})
@@ -1087,6 +1083,8 @@ class Connector(BaseConnector):
1087
1083
  data = status_response.json()
1088
1084
  if session.cache is not None:
1089
1085
  session.cache[url] = (data, str(datetime.utcnow()))
1086
+ elif status_response.status_code == requests.codes['no_content'] and allow_empty:
1087
+ data = None
1090
1088
  elif status_response.status_code == requests.codes['too_many_requests']:
1091
1089
  raise TooManyRequestsError('Could not fetch data due to too many requests from your account. '
1092
1090
  f'Status Code was: {status_response.status_code}')
@@ -1459,5 +1457,5 @@ class Connector(BaseConnector):
1459
1457
  def get_type(self) -> str:
1460
1458
  return "carconnectivity-connector-seatcupra"
1461
1459
 
1462
- def is_healthy(self) -> bool:
1463
- return self._healthy and super().is_healthy()
1460
+ def get_name(self) -> str:
1461
+ return "Seat/Cupra Connector"