carconnectivity-connector-seatcupra 0.1a6__py3-none-any.whl → 0.1a8__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.1a6.dist-info → carconnectivity_connector_seatcupra-0.1a8.dist-info}/METADATA +4 -1
- {carconnectivity_connector_seatcupra-0.1a6.dist-info → carconnectivity_connector_seatcupra-0.1a8.dist-info}/RECORD +10 -10
- {carconnectivity_connector_seatcupra-0.1a6.dist-info → carconnectivity_connector_seatcupra-0.1a8.dist-info}/WHEEL +1 -1
- carconnectivity_connectors/seatcupra/_version.py +1 -1
- carconnectivity_connectors/seatcupra/auth/my_cupra_session.py +58 -28
- carconnectivity_connectors/seatcupra/auth/session_manager.py +5 -1
- carconnectivity_connectors/seatcupra/auth/vw_web_session.py +3 -0
- carconnectivity_connectors/seatcupra/connector.py +132 -49
- {carconnectivity_connector_seatcupra-0.1a6.dist-info → carconnectivity_connector_seatcupra-0.1a8.dist-info}/LICENSE +0 -0
- {carconnectivity_connector_seatcupra-0.1a6.dist-info → carconnectivity_connector_seatcupra-0.1a8.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.1a8
|
4
4
|
Summary: CarConnectivity connector for Seat and Cupra services
|
5
5
|
Author: Till Steinbach
|
6
6
|
License: MIT License
|
@@ -68,6 +68,7 @@ In your carconnectivity.json configuration add a section for the seatcupra conne
|
|
68
68
|
{
|
69
69
|
"type": "seatcupra",
|
70
70
|
"config": {
|
71
|
+
"brand": "cupra",
|
71
72
|
"username": "test@test.de",
|
72
73
|
"password": "testpassword123"
|
73
74
|
}
|
@@ -76,6 +77,8 @@ In your carconnectivity.json configuration add a section for the seatcupra conne
|
|
76
77
|
}
|
77
78
|
}
|
78
79
|
```
|
80
|
+
`brand` (`seat` or `cupra`) defines what login is used. MyCupra or MySeat account. Your credentials will work with both, but you may need to consent again to the terms and conditions when you use the "wrong" brand.
|
81
|
+
|
79
82
|
### Credentials
|
80
83
|
If you do not want to provide your username or password inside the configuration you have to create a ".netrc" file at the appropriate location (usually this is your home folder):
|
81
84
|
```
|
@@ -1,21 +1,21 @@
|
|
1
1
|
carconnectivity_connectors/seatcupra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
carconnectivity_connectors/seatcupra/_version.py,sha256=
|
2
|
+
carconnectivity_connectors/seatcupra/_version.py,sha256=8cqHsmeL27BhXP-5TXDRomSBRkxC7CZnFEC8NypOGaI,508
|
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
6
|
carconnectivity_connectors/seatcupra/command_impl.py,sha256=mtw8ZwJLmf79fPDZ1N3ImLfB8Gt9JPbzjMuIo2y5v3M,2879
|
7
|
-
carconnectivity_connectors/seatcupra/connector.py,sha256=
|
7
|
+
carconnectivity_connectors/seatcupra/connector.py,sha256=MQ5zGNO051feTZUt23J-TJLQUKdOlzG3pYyeOVAGsaw,99318
|
8
8
|
carconnectivity_connectors/seatcupra/vehicle.py,sha256=kiFVbJgq5VQOzf-vSli_2NsMgY0x4pwvJsjPWLGdr1g,3404
|
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
|
11
|
-
carconnectivity_connectors/seatcupra/auth/my_cupra_session.py,sha256=
|
11
|
+
carconnectivity_connectors/seatcupra/auth/my_cupra_session.py,sha256=ybBZ2y7-kUdo5MJ9Zin8UYViC0y3H43H3yOQcDGtWUo,12767
|
12
12
|
carconnectivity_connectors/seatcupra/auth/openid_session.py,sha256=dA0vE2YuckkMPeqJo2dEI0h8_XfohdCgdGkTyshPF7Q,16858
|
13
|
-
carconnectivity_connectors/seatcupra/auth/session_manager.py,sha256=
|
14
|
-
carconnectivity_connectors/seatcupra/auth/vw_web_session.py,sha256=
|
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
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.1a8.dist-info/LICENSE,sha256=PIwI1alwDyOfvEQHdGCm2u9uf_mGE8030xZDfun0xTo,1071
|
18
|
+
carconnectivity_connector_seatcupra-0.1a8.dist-info/METADATA,sha256=OcY0IeJGVQIRGNGjdTUJ32jwKBA77KB_BNed0XxmTEg,5640
|
19
|
+
carconnectivity_connector_seatcupra-0.1a8.dist-info/WHEEL,sha256=nn6H5-ilmfVryoAQl3ZQ2l8SH5imPWFpm1A5FgEuFV4,91
|
20
|
+
carconnectivity_connector_seatcupra-0.1a8.dist-info/top_level.txt,sha256=KqA8GviZsDH4PtmnwSQsz0HB_w-TWkeEHLIRNo5dTaI,27
|
21
|
+
carconnectivity_connector_seatcupra-0.1a8.dist-info/RECORD,,
|
@@ -23,7 +23,7 @@ from carconnectivity_connectors.seatcupra.auth.openid_session import AccessType
|
|
23
23
|
from carconnectivity_connectors.seatcupra.auth.vw_web_session import VWWebSession
|
24
24
|
|
25
25
|
if TYPE_CHECKING:
|
26
|
-
from typing import Tuple, Dict
|
26
|
+
from typing import Tuple, Dict, Any
|
27
27
|
|
28
28
|
|
29
29
|
LOG: logging.Logger = logging.getLogger("carconnectivity.connectors.seatcupra.auth")
|
@@ -33,22 +33,40 @@ class MyCupraSession(VWWebSession):
|
|
33
33
|
"""
|
34
34
|
MyCupraSession class handles the authentication and session management for Cupras's MyCupra service.
|
35
35
|
"""
|
36
|
-
def __init__(self, session_user, **kwargs) -> None:
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
36
|
+
def __init__(self, session_user, is_seat: bool, **kwargs) -> None:
|
37
|
+
self.is_seat: bool = is_seat
|
38
|
+
if self.is_seat:
|
39
|
+
super(MyCupraSession, self).__init__(client_id='99a5b77d-bd88-4d53-b4e5-a539c60694a3@apps_vw-dilab_com',
|
40
|
+
refresh_url='https://identity.vwgroup.io/oidc/v1/token',
|
41
|
+
scope='openid profile nickname birthdate phone',
|
42
|
+
redirect_uri='seat://oauth-callback',
|
43
|
+
state=None,
|
44
|
+
session_user=session_user,
|
45
|
+
**kwargs)
|
46
|
+
|
47
|
+
self.headers = CaseInsensitiveDict({
|
48
|
+
'accept': '*/*',
|
49
|
+
'content-type': 'application/json',
|
50
|
+
'user-agent': 'SEATApp/2.5.0 (com.seat.myseat.ola; build:202410171614; iOS 15.8.3) Alamofire/5.7.0 Mobile',
|
51
|
+
'accept-language': 'de-de',
|
52
|
+
'accept-encoding': 'gzip, deflate, br'
|
53
|
+
})
|
54
|
+
else:
|
55
|
+
super(MyCupraSession, self).__init__(client_id='3c756d46-f1ba-4d78-9f9a-cff0d5292d51@apps_vw-dilab_com',
|
56
|
+
refresh_url='https://identity.vwgroup.io/oidc/v1/token',
|
57
|
+
scope='openid profile nickname birthdate phone',
|
58
|
+
redirect_uri='cupra://oauth-callback',
|
59
|
+
state=None,
|
60
|
+
session_user=session_user,
|
61
|
+
**kwargs)
|
62
|
+
|
63
|
+
self.headers = CaseInsensitiveDict({
|
64
|
+
'accept': '*/*',
|
65
|
+
'content-type': 'application/json',
|
66
|
+
'user-agent': 'CUPRAApp%20-%20Store/20220503 CFNetwork/1333.0.4 Darwin/21.5.0',
|
67
|
+
'accept-language': 'de-de',
|
68
|
+
'accept-encoding': 'gzip, deflate, br'
|
69
|
+
})
|
52
70
|
|
53
71
|
def login(self):
|
54
72
|
super(MyCupraSession, self).login()
|
@@ -57,8 +75,12 @@ class MyCupraSession(VWWebSession):
|
|
57
75
|
# perform web authentication
|
58
76
|
response = self.do_web_auth(authorization_url_str)
|
59
77
|
# fetch tokens from web authentication response
|
60
|
-
self.
|
61
|
-
|
78
|
+
if self.is_seat:
|
79
|
+
return self.fetch_tokens('https://ola.prod.code.seat.cloud.vwgroup.com/authorization/api/v1/token',
|
80
|
+
authorization_response=response)
|
81
|
+
else:
|
82
|
+
self.fetch_tokens('https://identity.vwgroup.io/oidc/v1/token',
|
83
|
+
authorization_response=response)
|
62
84
|
|
63
85
|
def refresh(self) -> None:
|
64
86
|
# refresh tokens from refresh endpoint
|
@@ -92,15 +114,23 @@ class MyCupraSession(VWWebSession):
|
|
92
114
|
|
93
115
|
if self.token is not None and all(key in self.token for key in ('state', 'id_token', 'access_token', 'code')):
|
94
116
|
# Generate json body for token request
|
95
|
-
|
96
|
-
'state': self.token['state'],
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
117
|
+
if self.is_seat:
|
118
|
+
body: Dict[str, Any] = {'state': self.token['state'],
|
119
|
+
'id_token': self.token['id_token'],
|
120
|
+
'redirect_uri': self.redirect_uri,
|
121
|
+
'client_id': self.client_id,
|
122
|
+
'code': self.token['code'],
|
123
|
+
'grant_type': 'authorization_code'
|
124
|
+
}
|
125
|
+
else:
|
126
|
+
body: Dict[str, Any] = {'state': self.token['state'],
|
127
|
+
'id_token': self.token['id_token'],
|
128
|
+
'redirect_uri': self.redirect_uri,
|
129
|
+
'client_id': self.client_id,
|
130
|
+
'client_secret': 'eb8814e641c81a2640ad62eeccec11c98effc9bccd4269ab7af338b50a94b3a2',
|
131
|
+
'code': self.token['code'],
|
132
|
+
'grant_type': 'authorization_code'
|
133
|
+
}
|
104
134
|
|
105
135
|
request_headers: CaseInsensitiveDict = dict(self.headers) # pyright: ignore reportAssignmentType
|
106
136
|
request_headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8'
|
@@ -47,11 +47,13 @@ class Service(Enum):
|
|
47
47
|
|
48
48
|
Attributes:
|
49
49
|
MY_CUPRA (str): Represents the 'MyCupra' service.
|
50
|
+
MY_SEAT (str): Represents the 'MySeat' service.
|
50
51
|
|
51
52
|
Methods:
|
52
53
|
__str__() -> str: Returns the string representation of the service.
|
53
54
|
"""
|
54
55
|
MY_CUPRA = 'MyCupra'
|
56
|
+
MY_SEAT = 'MySeat'
|
55
57
|
|
56
58
|
def __str__(self) -> str:
|
57
59
|
return self.value
|
@@ -127,7 +129,9 @@ class SessionManager():
|
|
127
129
|
cache = self.cache[identifier]
|
128
130
|
|
129
131
|
if service == Service.MY_CUPRA:
|
130
|
-
session = MyCupraSession(session_user=session_user, token=token, metadata=metadata, cache=cache)
|
132
|
+
session = MyCupraSession(session_user=session_user, is_seat=False, token=token, metadata=metadata, cache=cache)
|
133
|
+
elif service == Service.MY_SEAT:
|
134
|
+
session = MyCupraSession(session_user=session_user, is_seat=True, token=token, metadata=metadata, cache=cache)
|
131
135
|
else:
|
132
136
|
raise ValueError(f"Unsupported service: {service}")
|
133
137
|
|
@@ -121,6 +121,9 @@ class VWWebSession(OpenIDSession):
|
|
121
121
|
raise RetrievalError('Temporary server error during login')
|
122
122
|
|
123
123
|
if 'Location' not in response.headers:
|
124
|
+
if 'consent' in url:
|
125
|
+
raise AuthenticationError('Could not find Location in headers, probably due to missing consent. '
|
126
|
+
'Check that you configured the correct brand or try visiting: ' + url)
|
124
127
|
raise APICompatibilityError('Forwarding without Location in headers')
|
125
128
|
|
126
129
|
url = response.headers['Location']
|
@@ -129,17 +129,30 @@ class Connector(BaseConnector):
|
|
129
129
|
self.active_config['max_age'] = config['max_age']
|
130
130
|
self.interval._set_value(timedelta(seconds=self.active_config['interval'])) # pylint: disable=protected-access
|
131
131
|
|
132
|
+
if 'brand' in config:
|
133
|
+
if config['brand'] not in ['seat', 'cupra']:
|
134
|
+
raise ValueError('Brand must be either "seat" or "cupra"')
|
135
|
+
self.active_config['brand'] = config['brand']
|
136
|
+
else:
|
137
|
+
self.active_config['brand'] = 'cupra'
|
138
|
+
|
132
139
|
if self.active_config['username'] is None or self.active_config['password'] is None:
|
133
140
|
raise AuthenticationError('Username or password not provided')
|
134
141
|
|
142
|
+
if self.active_config['brand'] == 'cupra':
|
143
|
+
service = Service.MY_CUPRA
|
144
|
+
elif self.active_config['brand'] == 'seat':
|
145
|
+
service = Service.MY_SEAT
|
146
|
+
else:
|
147
|
+
raise ValueError('Brand must be either "seat" or "cupra"')
|
135
148
|
self._manager: SessionManager = SessionManager(tokenstore=car_connectivity.get_tokenstore(), cache=car_connectivity.get_cache())
|
136
|
-
session: requests.Session = self._manager.get_session(
|
137
|
-
|
149
|
+
session: requests.Session = self._manager.get_session(service, SessionUser(username=self.active_config['username'],
|
150
|
+
password=self.active_config['password']))
|
138
151
|
if not isinstance(session, MyCupraSession):
|
139
152
|
raise AuthenticationError('Could not create session')
|
140
153
|
self.session: MyCupraSession = session
|
141
154
|
self.session.retries = 3
|
142
|
-
self.session.timeout =
|
155
|
+
self.session.timeout = 30
|
143
156
|
self.session.refresh()
|
144
157
|
|
145
158
|
self._elapsed: List[timedelta] = []
|
@@ -1089,27 +1102,37 @@ class Connector(BaseConnector):
|
|
1089
1102
|
if 'command' not in command_arguments:
|
1090
1103
|
raise CommandError('Command argument missing')
|
1091
1104
|
command_dict: Dict = {}
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1105
|
+
try:
|
1106
|
+
if command_arguments['command'] == ChargingStartStopCommand.Command.START:
|
1107
|
+
url = f'https://ola.prod.code.seat.cloud.vwgroup.com/vehicles/{vin}/charging/requests/start'
|
1108
|
+
if isinstance(vehicle, SeatCupraElectricVehicle) and vehicle.charging is not None and vehicle.charging.settings is not None \
|
1109
|
+
and vehicle.charging.settings.maximum_current is not None and vehicle.charging.settings.maximum_current.enabled \
|
1110
|
+
and vehicle.charging.settings.maximum_current.value is not None:
|
1111
|
+
if vehicle.charging.settings.maximum_current.value <= 6:
|
1112
|
+
command_dict['maxChargeCurrentAC'] = 'reduced'
|
1113
|
+
else:
|
1114
|
+
command_dict['maxChargeCurrentAC'] = 'maximum'
|
1099
1115
|
else:
|
1100
1116
|
command_dict['maxChargeCurrentAC'] = 'maximum'
|
1117
|
+
command_response: requests.Response = self.session.post(url, json=command_dict, allow_redirects=True)
|
1118
|
+
elif command_arguments['command'] == ChargingStartStopCommand.Command.STOP:
|
1119
|
+
url = f'https://ola.prod.code.seat.cloud.vwgroup.com/vehicles/{vin}/charging/requests/stop'
|
1120
|
+
command_response: requests.Response = self.session.post(url, data='{}', allow_redirects=True)
|
1101
1121
|
else:
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
raise CommandError(f'
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1122
|
+
raise CommandError(f'Unknown command {command_arguments["command"]}')
|
1123
|
+
|
1124
|
+
if command_response.status_code not in [requests.codes['ok'], requests.codes['created']]:
|
1125
|
+
LOG.error('Could not start/stop charging (%s: %s)', command_response.status_code, command_response.text)
|
1126
|
+
raise CommandError(f'Could not start/stop charging ({command_response.status_code}: {command_response.text})')
|
1127
|
+
except requests.exceptions.ConnectionError as connection_error:
|
1128
|
+
raise CommandError(f'Connection error: {connection_error}.'
|
1129
|
+
' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
|
1130
|
+
except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
|
1131
|
+
raise CommandError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
|
1132
|
+
except requests.exceptions.ReadTimeout as timeout_error:
|
1133
|
+
raise CommandError(f'Timeout during read: {timeout_error}') from timeout_error
|
1134
|
+
except requests.exceptions.RetryError as retry_error:
|
1135
|
+
raise CommandError(f'Retrying failed: {retry_error}') from retry_error
|
1113
1136
|
return command_arguments
|
1114
1137
|
|
1115
1138
|
def __on_air_conditioning_start_stop(self, start_stop_command: ClimatizationStartStopCommand, command_arguments: Union[str, Dict[str, Any]]) \
|
@@ -1155,10 +1178,20 @@ class Connector(BaseConnector):
|
|
1155
1178
|
url: str = f'https://ola.prod.code.seat.cloud.vwgroup.com/vehicles/{vin}/climatisation/requests/stop'
|
1156
1179
|
else:
|
1157
1180
|
raise CommandError(f'Unknown command {command_arguments["command"]}')
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1181
|
+
try:
|
1182
|
+
command_response: requests.Response = self.session.post(url, data=json.dumps(command_dict), allow_redirects=True)
|
1183
|
+
if command_response.status_code not in [requests.codes['ok'], requests.codes['created']]:
|
1184
|
+
LOG.error('Could not start/stop air conditioning (%s: %s)', command_response.status_code, command_response.text)
|
1185
|
+
raise CommandError(f'Could not start/stop air conditioning ({command_response.status_code}: {command_response.text})')
|
1186
|
+
except requests.exceptions.ConnectionError as connection_error:
|
1187
|
+
raise CommandError(f'Connection error: {connection_error}.'
|
1188
|
+
' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
|
1189
|
+
except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
|
1190
|
+
raise CommandError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
|
1191
|
+
except requests.exceptions.ReadTimeout as timeout_error:
|
1192
|
+
raise CommandError(f'Timeout during read: {timeout_error}') from timeout_error
|
1193
|
+
except requests.exceptions.RetryError as retry_error:
|
1194
|
+
raise CommandError(f'Retrying failed: {retry_error}') from retry_error
|
1162
1195
|
return command_arguments
|
1163
1196
|
|
1164
1197
|
def __on_spin(self, spin_command: SpinCommand, command_arguments: Union[str, Dict[str, Any]]) \
|
@@ -1181,12 +1214,22 @@ class Connector(BaseConnector):
|
|
1181
1214
|
url = f'https://ola.prod.code.seat.cloud.vwgroup.com/v2/users/{self.session.user_id}/spin/verify'
|
1182
1215
|
else:
|
1183
1216
|
raise CommandError(f'Unknown command {command_arguments["command"]}')
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1217
|
+
try:
|
1218
|
+
command_response: requests.Response = self.session.post(url, data=json.dumps(command_dict), allow_redirects=True)
|
1219
|
+
if command_response.status_code != requests.codes['ok']:
|
1220
|
+
LOG.error('Could not execute spin command (%s: %s)', command_response.status_code, command_response.text)
|
1221
|
+
raise CommandError(f'Could not execute spin command ({command_response.status_code}: {command_response.text})')
|
1222
|
+
else:
|
1223
|
+
LOG.info('Spin verify command executed successfully')
|
1224
|
+
except requests.exceptions.ConnectionError as connection_error:
|
1225
|
+
raise CommandError(f'Connection error: {connection_error}.'
|
1226
|
+
' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
|
1227
|
+
except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
|
1228
|
+
raise CommandError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
|
1229
|
+
except requests.exceptions.ReadTimeout as timeout_error:
|
1230
|
+
raise CommandError(f'Timeout during read: {timeout_error}') from timeout_error
|
1231
|
+
except requests.exceptions.RetryError as retry_error:
|
1232
|
+
raise CommandError(f'Retrying failed: {retry_error}') from retry_error
|
1190
1233
|
return command_arguments
|
1191
1234
|
|
1192
1235
|
def __on_wake_sleep(self, wake_sleep_command: WakeSleepCommand, command_arguments: Union[str, Dict[str, Any]]) \
|
@@ -1205,10 +1248,20 @@ class Connector(BaseConnector):
|
|
1205
1248
|
if command_arguments['command'] == WakeSleepCommand.Command.WAKE:
|
1206
1249
|
url = f'https://ola.prod.code.seat.cloud.vwgroup.com/v1/vehicles/{vin}/vehicle-wakeup/request'
|
1207
1250
|
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1251
|
+
try:
|
1252
|
+
command_response: requests.Response = self.session.post(url, data='{}', allow_redirects=True)
|
1253
|
+
if command_response.status_code not in (requests.codes['ok'], requests.codes['no_content']):
|
1254
|
+
LOG.error('Could not execute wake command (%s: %s)', command_response.status_code, command_response.text)
|
1255
|
+
raise CommandError(f'Could not execute wake command ({command_response.status_code}: {command_response.text})')
|
1256
|
+
except requests.exceptions.ConnectionError as connection_error:
|
1257
|
+
raise CommandError(f'Connection error: {connection_error}.'
|
1258
|
+
' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
|
1259
|
+
except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
|
1260
|
+
raise CommandError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
|
1261
|
+
except requests.exceptions.ReadTimeout as timeout_error:
|
1262
|
+
raise CommandError(f'Timeout during read: {timeout_error}') from timeout_error
|
1263
|
+
except requests.exceptions.RetryError as retry_error:
|
1264
|
+
raise CommandError(f'Retrying failed: {retry_error}') from retry_error
|
1212
1265
|
elif command_arguments['command'] == WakeSleepCommand.Command.SLEEP:
|
1213
1266
|
raise CommandError('Sleep command not supported by vehicle. Vehicle will put itself to sleep')
|
1214
1267
|
else:
|
@@ -1244,12 +1297,22 @@ class Connector(BaseConnector):
|
|
1244
1297
|
command_dict['userPosition']['longitude'] = vehicle.position.longitude.value
|
1245
1298
|
|
1246
1299
|
url = f'https://ola.prod.code.seat.cloud.vwgroup.com/v1/vehicles/{vin}/honk-and-flash'
|
1247
|
-
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1300
|
+
try:
|
1301
|
+
command_response: requests.Response = self.session.post(url, data=json.dumps(command_dict), allow_redirects=True)
|
1302
|
+
if command_response.status_code not in (requests.codes['ok'], requests.codes['no_content']):
|
1303
|
+
LOG.error('Could not execute honk or flash command (%s: %s)', command_response.status_code, command_response.text)
|
1304
|
+
raise CommandError(f'Could not execute honk or flash command ({command_response.status_code}: {command_response.text})')
|
1305
|
+
except requests.exceptions.ConnectionError as connection_error:
|
1306
|
+
raise CommandError(f'Connection error: {connection_error}.'
|
1307
|
+
' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
|
1308
|
+
except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
|
1309
|
+
raise CommandError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
|
1310
|
+
except requests.exceptions.ReadTimeout as timeout_error:
|
1311
|
+
raise CommandError(f'Timeout during read: {timeout_error}') from timeout_error
|
1312
|
+
except requests.exceptions.RetryError as retry_error:
|
1313
|
+
raise CommandError(f'Retrying failed: {retry_error}') from retry_error
|
1314
|
+
else:
|
1315
|
+
raise CommandError(f'Unknown command {command_arguments["command"]}')
|
1253
1316
|
return command_arguments
|
1254
1317
|
|
1255
1318
|
def __on_lock_unlock(self, lock_unlock_command: LockUnlockCommand, command_arguments: Union[str, Dict[str, Any]]) \
|
@@ -1278,10 +1341,20 @@ class Connector(BaseConnector):
|
|
1278
1341
|
url = f'https://ola.prod.code.seat.cloud.vwgroup.com/v1/vehicles/{vin}/access/unlock'
|
1279
1342
|
else:
|
1280
1343
|
raise CommandError(f'Unknown command {command_arguments["command"]}')
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1344
|
+
try:
|
1345
|
+
command_response: requests.Response = self.session.post(url, data=json.dumps(command_dict), allow_redirects=True)
|
1346
|
+
if command_response.status_code != requests.codes['ok']:
|
1347
|
+
LOG.error('Could not execute locking command (%s: %s)', command_response.status_code, command_response.text)
|
1348
|
+
raise CommandError(f'Could not execute locking command ({command_response.status_code}: {command_response.text})')
|
1349
|
+
except requests.exceptions.ConnectionError as connection_error:
|
1350
|
+
raise CommandError(f'Connection error: {connection_error}.'
|
1351
|
+
' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
|
1352
|
+
except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
|
1353
|
+
raise CommandError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
|
1354
|
+
except requests.exceptions.ReadTimeout as timeout_error:
|
1355
|
+
raise CommandError(f'Timeout during read: {timeout_error}') from timeout_error
|
1356
|
+
except requests.exceptions.RetryError as retry_error:
|
1357
|
+
raise CommandError(f'Retrying failed: {retry_error}') from retry_error
|
1285
1358
|
return command_arguments
|
1286
1359
|
|
1287
1360
|
def __on_air_conditioning_settings_change(self, attribute: GenericAttribute, value: Any) -> Any:
|
@@ -1317,10 +1390,20 @@ class Connector(BaseConnector):
|
|
1317
1390
|
setting_dict['climatisationWithoutExternalPower'] = settings.climatization_without_external_power.value
|
1318
1391
|
|
1319
1392
|
url: str = f'https://ola.prod.code.seat.cloud.vwgroup.com/v2/vehicles/{vin}/climatisation/settings'
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1393
|
+
try:
|
1394
|
+
settings_response: requests.Response = self.session.post(url, data=json.dumps(setting_dict), allow_redirects=True)
|
1395
|
+
if settings_response.status_code not in [requests.codes['ok'], requests.codes['created']]:
|
1396
|
+
LOG.error('Could not set climatization settings (%s) %s', settings_response.status_code, settings_response.text)
|
1397
|
+
raise SetterError(f'Could not set value ({settings_response.status_code}): {settings_response.text}')
|
1398
|
+
except requests.exceptions.ConnectionError as connection_error:
|
1399
|
+
raise SetterError(f'Connection error: {connection_error}.'
|
1400
|
+
' If this happens frequently, please check if other applications communicate with the Skoda server.') from connection_error
|
1401
|
+
except requests.exceptions.ChunkedEncodingError as chunked_encoding_error:
|
1402
|
+
raise SetterError(f'Error: {chunked_encoding_error}') from chunked_encoding_error
|
1403
|
+
except requests.exceptions.ReadTimeout as timeout_error:
|
1404
|
+
raise SetterError(f'Timeout during read: {timeout_error}') from timeout_error
|
1405
|
+
except requests.exceptions.RetryError as retry_error:
|
1406
|
+
raise SetterError(f'Retrying failed: {retry_error}') from retry_error
|
1324
1407
|
return value
|
1325
1408
|
|
1326
1409
|
def get_version(self) -> str:
|
File without changes
|