carconnectivity-connector-seatcupra 0.2a5__py3-none-any.whl → 0.4__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.2a5.dist-info → carconnectivity_connector_seatcupra-0.4.dist-info}/METADATA +2 -2
- {carconnectivity_connector_seatcupra-0.2a5.dist-info → carconnectivity_connector_seatcupra-0.4.dist-info}/RECORD +9 -9
- {carconnectivity_connector_seatcupra-0.2a5.dist-info → carconnectivity_connector_seatcupra-0.4.dist-info}/WHEEL +1 -1
- carconnectivity_connectors/seatcupra/_version.py +2 -2
- carconnectivity_connectors/seatcupra/command_impl.py +6 -2
- carconnectivity_connectors/seatcupra/connector.py +20 -4
- carconnectivity_connectors/seatcupra/ui/connector_ui.py +2 -2
- {carconnectivity_connector_seatcupra-0.2a5.dist-info → carconnectivity_connector_seatcupra-0.4.dist-info}/licenses/LICENSE +0 -0
- {carconnectivity_connector_seatcupra-0.2a5.dist-info → carconnectivity_connector_seatcupra-0.4.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: carconnectivity-connector-seatcupra
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.4
|
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.7
|
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,11 +1,11 @@
|
|
1
|
-
carconnectivity_connector_seatcupra-0.
|
1
|
+
carconnectivity_connector_seatcupra-0.4.dist-info/licenses/LICENSE,sha256=PIwI1alwDyOfvEQHdGCm2u9uf_mGE8030xZDfun0xTo,1071
|
2
2
|
carconnectivity_connectors/seatcupra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
-
carconnectivity_connectors/seatcupra/_version.py,sha256=
|
3
|
+
carconnectivity_connectors/seatcupra/_version.py,sha256=z4A7Ai6QyXWBOpaj5g4Fi0n9CYi27WfJ6gm02OiXBxE,506
|
4
4
|
carconnectivity_connectors/seatcupra/capability.py,sha256=936V06hOX8AuAMxL_S9wVyVa36Xw1bo9081X0xf5f94,5064
|
5
5
|
carconnectivity_connectors/seatcupra/charging.py,sha256=mayvseay5x2r2qjWqol0ijlgoBL2L2A0A96T44FOiHg,4076
|
6
6
|
carconnectivity_connectors/seatcupra/climatization.py,sha256=0xxWlxrheAPzkVT8WRQtbm6ExZmVdgW7lUdOXyS_qWY,1695
|
7
|
-
carconnectivity_connectors/seatcupra/command_impl.py,sha256=
|
8
|
-
carconnectivity_connectors/seatcupra/connector.py,sha256=
|
7
|
+
carconnectivity_connectors/seatcupra/command_impl.py,sha256=5kIzMWhabUTtLVcrWQuu2Xp78NnF96G3Fr-nt9h6IA0,3234
|
8
|
+
carconnectivity_connectors/seatcupra/connector.py,sha256=N8LhUSgy6zK4rjtLuLgI1xPwYqPmFzqaZ4gczaXy2tE,131556
|
9
9
|
carconnectivity_connectors/seatcupra/vehicle.py,sha256=LHkAlVD_C8xOX81wCGFZbZqyhctpKx-CN0T3NZJ2jFk,3946
|
10
10
|
carconnectivity_connectors/seatcupra/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
11
|
carconnectivity_connectors/seatcupra/auth/auth_util.py,sha256=Y81h8fGOMSMgPtE4wI_TI9WgE_s43uaPjRLBBINhj4g,4433
|
@@ -14,8 +14,8 @@ carconnectivity_connectors/seatcupra/auth/openid_session.py,sha256=pGdTSt2zMtPWD
|
|
14
14
|
carconnectivity_connectors/seatcupra/auth/session_manager.py,sha256=ZIDvC848T3fy6PgGqCl8A2SzaNhu2YG19Xam5kgp7SA,5635
|
15
15
|
carconnectivity_connectors/seatcupra/auth/vw_web_session.py,sha256=CcI6m68IyRs6WsMDu-IsW3Dj85vyGiMmxvFqNETMHO0,10929
|
16
16
|
carconnectivity_connectors/seatcupra/auth/helpers/blacklist_retry.py,sha256=f3wsiY5bpHDBxp7Va1Mv9nKJ4u3qnCHZZmDu78_AhMk,1251
|
17
|
-
carconnectivity_connectors/seatcupra/ui/connector_ui.py,sha256=
|
18
|
-
carconnectivity_connector_seatcupra-0.
|
19
|
-
carconnectivity_connector_seatcupra-0.
|
20
|
-
carconnectivity_connector_seatcupra-0.
|
21
|
-
carconnectivity_connector_seatcupra-0.
|
17
|
+
carconnectivity_connectors/seatcupra/ui/connector_ui.py,sha256=UXDWnMAyTrm0UReTP2WamorrPE5kAJ5oxOjCp-MrZ-c,1414
|
18
|
+
carconnectivity_connector_seatcupra-0.4.dist-info/METADATA,sha256=ptD-uU_NM7mKuk29cunDIkPyVHWmmiXkb4-ynFmGYag,5491
|
19
|
+
carconnectivity_connector_seatcupra-0.4.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
20
|
+
carconnectivity_connector_seatcupra-0.4.dist-info/top_level.txt,sha256=KqA8GviZsDH4PtmnwSQsz0HB_w-TWkeEHLIRNo5dTaI,27
|
21
|
+
carconnectivity_connector_seatcupra-0.4.dist-info/RECORD,,
|
@@ -33,14 +33,18 @@ 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))
|
40
44
|
parser.add_argument('--spin', dest='spin', help='Spin to be used instead of spin from config or .netrc', type=str, required=False,
|
41
45
|
default=None)
|
42
46
|
try:
|
43
|
-
args = parser.parse_args(new_value.split(sep=' '))
|
47
|
+
args = parser.parse_args(new_value.strip().split(sep=' '))
|
44
48
|
except argparse.ArgumentError as e:
|
45
49
|
raise SetterError(f'Invalid format for SpinCommand: {e.message} {parser.format_usage()}') from e
|
46
50
|
|
@@ -316,7 +316,7 @@ class Connector(BaseConnector):
|
|
316
316
|
and vehicle.position.position_type.enabled and vehicle.position.position_type.value == Position.PositionType.PARKING:
|
317
317
|
vehicle.state._set_value(GenericVehicle.State.PARKED) # pylint: disable=protected-access
|
318
318
|
else:
|
319
|
-
vehicle.state._set_value(
|
319
|
+
vehicle.state._set_value(GenericVehicle.State.UNKNOWN) # pylint: disable=protected-access
|
320
320
|
|
321
321
|
def fetch_vehicles(self) -> None:
|
322
322
|
"""
|
@@ -336,6 +336,9 @@ class Connector(BaseConnector):
|
|
336
336
|
if 'vehicles' in data and data['vehicles'] is not None:
|
337
337
|
for vehicle_dict in data['vehicles']:
|
338
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
|
339
342
|
vin: str = vehicle_dict['vin']
|
340
343
|
seen_vehicle_vins.add(vin)
|
341
344
|
vehicle: Optional[GenericVehicle] = garage.get_vehicle(vin) # pyright: ignore[reportAssignmentType]
|
@@ -666,11 +669,13 @@ class Connector(BaseConnector):
|
|
666
669
|
if 'levelPct' in vehicle_status_data['engines'][drive_id] and vehicle_status_data['engines'][drive_id]['levelPct'] is not None:
|
667
670
|
# pylint: disable-next=protected-access
|
668
671
|
drive.level._set_value(value=vehicle_status_data['engines'][drive_id]['levelPct'])
|
672
|
+
drive.level.precision = 1
|
669
673
|
else:
|
670
674
|
drive.level._set_value(None) # pylint: disable=protected-access
|
671
675
|
if 'rangeKm' in vehicle_status_data['engines'][drive_id] and vehicle_status_data['engines'][drive_id]['rangeKm'] is not None:
|
672
676
|
# pylint: disable-next=protected-access
|
673
677
|
drive.range._set_value(value=vehicle_status_data['engines'][drive_id]['rangeKm'], unit=Length.KM)
|
678
|
+
drive.range.precision = 1
|
674
679
|
total_range += vehicle_status_data['engines'][drive_id]['rangeKm']
|
675
680
|
else:
|
676
681
|
drive.range._set_value(None, unit=Length.KM) # pylint: disable=protected-access
|
@@ -678,6 +683,7 @@ class Connector(BaseConnector):
|
|
678
683
|
'levelPct',
|
679
684
|
'rangeKm'})
|
680
685
|
vehicle.drives.total_range._set_value(total_range, unit=Length.KM) # pylint: disable=protected-access
|
686
|
+
vehicle.drives.total_range.precision = 1
|
681
687
|
else:
|
682
688
|
vehicle.drives.enabled = False
|
683
689
|
if len(vehicle.drives.drives) > 0:
|
@@ -813,7 +819,9 @@ class Connector(BaseConnector):
|
|
813
819
|
else:
|
814
820
|
longitude = None
|
815
821
|
vehicle.position.latitude._set_value(latitude) # pylint: disable=protected-access
|
822
|
+
vehicle.position.latitude.precision = 0.000001
|
816
823
|
vehicle.position.longitude._set_value(longitude) # pylint: disable=protected-access
|
824
|
+
vehicle.position.longitude.precision = 0.000001
|
817
825
|
vehicle.position.position_type._set_value(Position.PositionType.PARKING) # pylint: disable=protected-access
|
818
826
|
log_extra_keys(LOG_API, 'parkingposition', data, {'lat', 'lon'})
|
819
827
|
else:
|
@@ -844,6 +852,7 @@ class Connector(BaseConnector):
|
|
844
852
|
if data is not None:
|
845
853
|
if 'mileageKm' in data and data['mileageKm'] is not None:
|
846
854
|
vehicle.odometer._set_value(data['mileageKm'], unit=Length.KM) # pylint: disable=protected-access
|
855
|
+
vehicle.odometer.precision = 1
|
847
856
|
else:
|
848
857
|
vehicle.odometer._set_value(None) # pylint: disable=protected-access
|
849
858
|
log_extra_keys(LOG_API, f'https://ola.prod.code.seat.cloud.vwgroup.com/v1/vehicles/{vin}/mileage', data, {'mileageKm'})
|
@@ -866,22 +875,26 @@ class Connector(BaseConnector):
|
|
866
875
|
if 'rangeName' in range_dict and range_dict['rangeName'] is not None and range_dict['rangeName'] == 'electricRangeKm' \
|
867
876
|
and 'value' in range_dict and range_dict['value'] is not None:
|
868
877
|
drive.range._set_value(range_dict['value'], unit=Length.KM) # pylint: disable=protected-access
|
878
|
+
drive.range.precision = 1
|
869
879
|
break
|
870
880
|
elif drive.type.enabled and drive.type.value == GenericDrive.Type.GASOLINE:
|
871
881
|
for range_dict in data['ranges']:
|
872
882
|
if 'rangeName' in range_dict and range_dict['rangeName'] is not None and range_dict['rangeName'] == 'gasolineRangeKm' \
|
873
883
|
and 'value' in range_dict and range_dict['value'] is not None:
|
874
884
|
drive.range._set_value(range_dict['value'], unit=Length.KM) # pylint: disable=protected-access
|
885
|
+
drive.range.precision = 1
|
875
886
|
break
|
876
887
|
elif drive.type.enabled and drive.type.value == GenericDrive.Type.DIESEL:
|
877
888
|
for range_dict in data['ranges']:
|
878
889
|
if 'rangeName' in range_dict and range_dict['rangeName'] is not None and range_dict['rangeName'] == 'dieselRangeKm' \
|
879
890
|
and 'value' in range_dict and range_dict['value'] is not None:
|
880
891
|
drive.range._set_value(range_dict['value'], unit=Length.KM) # pylint: disable=protected-access
|
892
|
+
drive.range.precision = 1
|
881
893
|
elif 'rangeName' in range_dict and range_dict['rangeName'] is not None and range_dict['rangeName'] == 'adBlueKm' \
|
882
894
|
and 'value' in range_dict and range_dict['value'] is not None:
|
883
895
|
if isinstance(drive, DieselDrive):
|
884
896
|
drive.adblue_range._set_value(range_dict['value'], unit=Length.KM) # pylint: disable=protected-access
|
897
|
+
drive.adblue_range.precision = 1
|
885
898
|
log_extra_keys(LOG_API, f'https://ola.prod.code.seat.cloud.vwgroup.com/v1/vehicles/{vin}/ranges', data, {'ranges'})
|
886
899
|
return vehicle
|
887
900
|
|
@@ -902,6 +915,7 @@ class Connector(BaseConnector):
|
|
902
915
|
vehicle.maintenance.inspection_due_at._set_value(None) # pylint: disable=protected-access
|
903
916
|
if 'inspectionDueKm' in data and data['inspectionDueKm'] is not None:
|
904
917
|
vehicle.maintenance.inspection_due_after._set_value(data['inspectionDueKm'], unit=Length.KM) # pylint: disable=protected-access
|
918
|
+
vehicle.maintenance.inspection_due_after.precision = 1
|
905
919
|
else:
|
906
920
|
vehicle.maintenance.inspection_due_after._set_value(None) # pylint: disable=protected-access
|
907
921
|
if 'oilServiceDueDays' in data and data['oilServiceDueDays'] is not None:
|
@@ -914,11 +928,13 @@ class Connector(BaseConnector):
|
|
914
928
|
vehicle.maintenance.oil_service_due_at._set_value(None) # pylint: disable=protected-access
|
915
929
|
if 'oilServiceDueKm' in data and data['oilServiceDueKm'] is not None:
|
916
930
|
vehicle.maintenance.oil_service_due_after._set_value(data['oilServiceDueKm'], unit=Length.KM) # pylint: disable=protected-access
|
931
|
+
vehicle.maintenance.oil_service_due_after.precision = 1
|
917
932
|
else:
|
918
933
|
vehicle.maintenance.oil_service_due_after._set_value(None) # pylint: disable=protected-access
|
919
934
|
log_extra_keys(LOG_API, f'/v1/vehicles/{vin}/maintenance', data, {'inspectionDueDays', 'inspectionDueKm', 'oilServiceDueDays', 'oilServiceDueKm'})
|
920
935
|
else:
|
921
936
|
vehicle.odometer._set_value(None) # pylint: disable=protected-access
|
937
|
+
vehicle.odometer.precision = 1
|
922
938
|
return vehicle
|
923
939
|
|
924
940
|
def fetch_climatisation(self, vehicle: SeatCupraVehicle, no_cache: bool = False) -> SeatCupraVehicle:
|
@@ -1327,7 +1343,7 @@ class Connector(BaseConnector):
|
|
1327
1343
|
elif not allow_http_error or (allowed_errors is not None and status_response.status_code not in allowed_errors):
|
1328
1344
|
raise RetrievalError(f'Could not fetch data even after re-authorization. Status Code was: {status_response.status_code}')
|
1329
1345
|
elif not allow_http_error or (allowed_errors is not None and status_response.status_code not in allowed_errors):
|
1330
|
-
raise RetrievalError(f'Could not fetch data. Status Code was: {status_response.status_code}')
|
1346
|
+
raise RetrievalError(f'Could not fetch data for {url}. Status Code was: {status_response.status_code}')
|
1331
1347
|
except requests.exceptions.ConnectionError as connection_error:
|
1332
1348
|
raise RetrievalError(f'Connection error: {connection_error}.'
|
1333
1349
|
' If this happens frequently, please check if other applications communicate with the Seat/Cupra server.') from connection_error
|
@@ -1516,7 +1532,7 @@ class Connector(BaseConnector):
|
|
1516
1532
|
|
1517
1533
|
try:
|
1518
1534
|
command_response: requests.Response = self.session.post(url, data='{}', allow_redirects=True)
|
1519
|
-
if command_response.status_code not in (requests.codes['ok'], requests.codes['no_content']):
|
1535
|
+
if command_response.status_code not in (requests.codes['ok'], requests.codes['no_content'], requests.codes['created']):
|
1520
1536
|
LOG.error('Could not execute wake command (%s: %s)', command_response.status_code, command_response.text)
|
1521
1537
|
raise CommandError(f'Could not execute wake command ({command_response.status_code}: {command_response.text})')
|
1522
1538
|
except requests.exceptions.ConnectionError as connection_error:
|
@@ -1565,7 +1581,7 @@ class Connector(BaseConnector):
|
|
1565
1581
|
url = f'https://ola.prod.code.seat.cloud.vwgroup.com/v1/vehicles/{vin}/honk-and-flash'
|
1566
1582
|
try:
|
1567
1583
|
command_response: requests.Response = self.session.post(url, data=json.dumps(command_dict), allow_redirects=True)
|
1568
|
-
if command_response.status_code not in (requests.codes['ok'], requests.codes['no_content']):
|
1584
|
+
if command_response.status_code not in (requests.codes['ok'], requests.codes['no_content'], requests.codes['created']):
|
1569
1585
|
LOG.error('Could not execute honk or flash command (%s: %s)', command_response.status_code, command_response.text)
|
1570
1586
|
raise CommandError(f'Could not execute honk or flash command ({command_response.status_code}: {command_response.text})')
|
1571
1587
|
except requests.exceptions.ConnectionError as connection_error:
|
@@ -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]]]:
|
File without changes
|