tesla-fleet-api 0.0.1__py3-none-any.whl → 0.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.
- tesla_fleet_api/TeslaFleetApi.py +715 -271
- tesla_fleet_api/TeslaFleetOAuth.py +50 -4
- tesla_fleet_api/Teslemetry.py +25 -0
- tesla_fleet_api/__init__.py +0 -1
- tesla_fleet_api/const.py +236 -2
- tesla_fleet_api/exceptions.py +180 -122
- {tesla_fleet_api-0.0.1.dist-info → tesla_fleet_api-0.0.4.dist-info}/METADATA +37 -3
- tesla_fleet_api-0.0.4.dist-info/RECORD +11 -0
- tesla_fleet_api-0.0.1.dist-info/RECORD +0 -11
- {tesla_fleet_api-0.0.1.dist-info → tesla_fleet_api-0.0.4.dist-info}/LICENSE +0 -0
- {tesla_fleet_api-0.0.1.dist-info → tesla_fleet_api-0.0.4.dist-info}/WHEEL +0 -0
- {tesla_fleet_api-0.0.1.dist-info → tesla_fleet_api-0.0.4.dist-info}/top_level.txt +0 -0
tesla_fleet_api/TeslaFleetApi.py
CHANGED
@@ -1,8 +1,17 @@
|
|
1
1
|
import aiohttp
|
2
|
-
from .exceptions import raise_for_status,
|
2
|
+
from .exceptions import raise_for_status, InvalidRegion, LibraryError
|
3
3
|
from typing import Any
|
4
|
-
from
|
5
|
-
|
4
|
+
from .const import (
|
5
|
+
SERVERS,
|
6
|
+
Methods,
|
7
|
+
Trunks,
|
8
|
+
ClimateKeeperMode,
|
9
|
+
CabinOverheatProtectionTemps,
|
10
|
+
VehicleDataEndpoints,
|
11
|
+
SunRoofCommands,
|
12
|
+
WindowCommands,
|
13
|
+
DeviceTypes,
|
14
|
+
)
|
6
15
|
|
7
16
|
|
8
17
|
# Based on https://developer.tesla.com/docs/fleet-api
|
@@ -26,6 +35,7 @@ class TeslaFleetApi:
|
|
26
35
|
"""Initialize the Tesla Fleet API."""
|
27
36
|
|
28
37
|
self.session = session
|
38
|
+
self.access_token = access_token
|
29
39
|
self.use_command_protocol = use_command_protocol
|
30
40
|
|
31
41
|
if region and not server and region not in SERVERS:
|
@@ -33,11 +43,6 @@ class TeslaFleetApi:
|
|
33
43
|
self.server = server or SERVERS.get(region)
|
34
44
|
self.raise_for_status = raise_for_status
|
35
45
|
|
36
|
-
self.headers = {
|
37
|
-
"Authorization": f"Bearer {access_token}",
|
38
|
-
"Content-Type": "application/json",
|
39
|
-
}
|
40
|
-
|
41
46
|
self.user = self.User(self)
|
42
47
|
self.charging = self.Charging(self)
|
43
48
|
self.partner = self.Partner(self)
|
@@ -50,35 +55,40 @@ class TeslaFleetApi:
|
|
50
55
|
try:
|
51
56
|
await self.user.region()
|
52
57
|
return
|
53
|
-
except
|
54
|
-
print(f"not {server}")
|
58
|
+
except InvalidRegion:
|
55
59
|
continue
|
56
|
-
raise
|
60
|
+
raise LibraryError("Could not find a valid Tesla API server.")
|
57
61
|
|
58
62
|
async def _request(
|
59
63
|
self,
|
60
|
-
method:
|
64
|
+
method: Methods,
|
61
65
|
path: str,
|
66
|
+
params: dict[str:Any] | None = None,
|
62
67
|
data: dict[str:Any] | None = None,
|
63
68
|
json: dict[str:Any] | None = None,
|
64
|
-
params: dict[str:Any] | None = None,
|
65
69
|
):
|
66
|
-
"""
|
70
|
+
"""Send a request to the Tesla Fleet API."""
|
67
71
|
|
68
72
|
if not self.server:
|
69
73
|
raise ValueError("Server was not set at init. Call find_server() first.")
|
70
74
|
|
75
|
+
if method == Methods.GET and (data is not None or json is not None):
|
76
|
+
raise ValueError("GET requests cannot have data or json parameters.")
|
77
|
+
|
78
|
+
if params:
|
79
|
+
params = {k: v for k, v in params.items() if v is not None}
|
71
80
|
if data:
|
72
81
|
data = {k: v for k, v in data.items() if v is not None}
|
73
82
|
if json:
|
74
83
|
json = {k: v for k, v in json.items() if v is not None}
|
75
|
-
if params:
|
76
|
-
params = {k: v for k, v in params.items() if v is not None}
|
77
84
|
|
78
85
|
async with self.session.request(
|
79
86
|
method,
|
80
87
|
f"{self.server}/{path}",
|
81
|
-
headers=
|
88
|
+
headers={
|
89
|
+
"Authorization": f"Bearer {self.access_token}",
|
90
|
+
"Content-Type": "application/json",
|
91
|
+
},
|
82
92
|
data=data,
|
83
93
|
json=json,
|
84
94
|
params=params,
|
@@ -87,70 +97,10 @@ class TeslaFleetApi:
|
|
87
97
|
await raise_for_status(resp)
|
88
98
|
return await resp.json()
|
89
99
|
|
90
|
-
async def _get(self, path, params: dict[str:Any] | None = None):
|
91
|
-
"""Get data from the Tesla Fleet API."""
|
92
|
-
|
93
|
-
if not self.server:
|
94
|
-
raise ValueError("Server was not set at init. Call find_server() first.")
|
95
|
-
|
96
|
-
if params:
|
97
|
-
params = {k: v for k, v in params.items() if v is not None}
|
98
|
-
|
99
|
-
async with self.session.get(
|
100
|
-
f"{self.server}/{path}",
|
101
|
-
params=params,
|
102
|
-
headers=self.headers,
|
103
|
-
) as resp:
|
104
|
-
if self.raise_for_status:
|
105
|
-
await raise_for_status(resp)
|
106
|
-
return await resp.json()
|
107
|
-
|
108
|
-
async def _post(
|
109
|
-
self,
|
110
|
-
path,
|
111
|
-
data: dict[str:Any] | None = None,
|
112
|
-
json: dict[str:Any] | None = None,
|
113
|
-
params: dict[str:Any] | None = None,
|
114
|
-
):
|
115
|
-
"""Post data to the Tesla Fleet API with URL encoded data."""
|
116
|
-
|
117
|
-
if not self.server:
|
118
|
-
raise ValueError("Server was not set at init. Call find_server() first.")
|
119
|
-
|
120
|
-
if params:
|
121
|
-
params = {k: v for k, v in params.items() if v is not None}
|
122
|
-
|
123
|
-
async with self.session.post(
|
124
|
-
f"{self.server}/{path}",
|
125
|
-
headers=self.headers,
|
126
|
-
data=data,
|
127
|
-
json=json,
|
128
|
-
params=params,
|
129
|
-
) as resp:
|
130
|
-
if self.raise_for_status:
|
131
|
-
await raise_for_status(resp)
|
132
|
-
return await resp.json()
|
133
|
-
|
134
|
-
async def _delete(self, path, params: dict[str:Any] | None = None):
|
135
|
-
"""Delete data from the Tesla Fleet API."""
|
136
|
-
|
137
|
-
if not self.server:
|
138
|
-
raise ValueError("Server was not set at init. Call find_server() first.")
|
139
|
-
|
140
|
-
if params:
|
141
|
-
params = {k: v for k, v in params.items() if v is not None}
|
142
|
-
|
143
|
-
async with self.session.delete(
|
144
|
-
f"{self.server}/{path}",
|
145
|
-
headers=self.headers,
|
146
|
-
params=params,
|
147
|
-
) as resp:
|
148
|
-
if self.raise_for_status:
|
149
|
-
await raise_for_status(resp)
|
150
|
-
return await resp.json()
|
151
|
-
|
152
100
|
async def status(self):
|
153
101
|
"""This endpoint returns the string "ok" if the API is operating normally. No HTTP headers are required."""
|
102
|
+
if not self.server:
|
103
|
+
raise ValueError("Server was not set at init. Call find_server() first.")
|
154
104
|
async with self.session.get(f"{self.server}/status") as resp:
|
155
105
|
return await resp.text()
|
156
106
|
|
@@ -158,8 +108,7 @@ class TeslaFleetApi:
|
|
158
108
|
"""Class describing the Tesla Fleet API charging endpoints."""
|
159
109
|
|
160
110
|
def __init__(self, parent):
|
161
|
-
self.
|
162
|
-
self._post = parent._post
|
111
|
+
self._request = parent._request
|
163
112
|
|
164
113
|
async def history(
|
165
114
|
self,
|
@@ -172,7 +121,8 @@ class TeslaFleetApi:
|
|
172
121
|
sortOrder: str | None = None,
|
173
122
|
) -> dict[str, Any]:
|
174
123
|
"""Returns the paginated charging history."""
|
175
|
-
return await self.
|
124
|
+
return await self._request(
|
125
|
+
Methods.GET,
|
176
126
|
"api/1/dx/charging/history",
|
177
127
|
{
|
178
128
|
vin: vin,
|
@@ -194,7 +144,8 @@ class TeslaFleetApi:
|
|
194
144
|
offset: int | None = None,
|
195
145
|
) -> dict[str, Any]:
|
196
146
|
"""Returns the charging session information including pricing and energy data. This endpoint is only available for business accounts that own a fleet of vehicles."""
|
197
|
-
return await self.
|
147
|
+
return await self._request(
|
148
|
+
Methods.GET,
|
198
149
|
"api/1/dx/charging/sessions",
|
199
150
|
{
|
200
151
|
vin: vin,
|
@@ -209,67 +160,62 @@ class TeslaFleetApi:
|
|
209
160
|
"""Class describing the Tesla Fleet API partner endpoints"""
|
210
161
|
|
211
162
|
def __init__(self, parent):
|
212
|
-
self.
|
213
|
-
self._post = parent._post
|
163
|
+
self._request = parent._request
|
214
164
|
|
215
165
|
async def public_key(self, domain: str | None = None) -> dict[str, Any]:
|
216
166
|
"""Returns the public key associated with a domain. It can be used to ensure the registration was successful."""
|
217
|
-
return await self.
|
218
|
-
"api/1/partner_accounts/public_key", data={domain: domain}
|
167
|
+
return await self._request(
|
168
|
+
Methods.GET, "api/1/partner_accounts/public_key", data={domain: domain}
|
219
169
|
)
|
220
170
|
|
221
171
|
async def register(self, domain: str) -> dict[str, Any]:
|
222
172
|
"""Registers an existing account before it can be used for general API access. Each application from developer.tesla.com must complete this step."""
|
223
|
-
return await self.
|
173
|
+
return await self._request(
|
174
|
+
Methods.POST, "api/1/partner_accounts", data={domain: domain}
|
175
|
+
)
|
224
176
|
|
225
177
|
class User:
|
226
178
|
"""Class describing the Tesla Fleet API user endpoints"""
|
227
179
|
|
228
180
|
def __init__(self, parent):
|
229
|
-
self.
|
181
|
+
self._request = parent._request
|
230
182
|
|
231
183
|
async def backup_key(self) -> dict[str, Any]:
|
232
184
|
"""Returns the public key associated with the user."""
|
233
|
-
return await self.
|
185
|
+
return await self._request(Methods.GET, "api/1/users/backup_key")
|
234
186
|
|
235
187
|
async def feature_config(self) -> dict[str, Any]:
|
236
188
|
"""Returns any custom feature flag applied to a user."""
|
237
|
-
return await self.
|
189
|
+
return await self._request(Methods.GET, "api/1/users/feature_config")
|
238
190
|
|
239
191
|
async def me(self) -> dict[str, Any]:
|
240
192
|
"""Returns a summary of a user's account."""
|
241
|
-
return await self.
|
193
|
+
return await self._request(Methods.GET, "api/1/users/me")
|
242
194
|
|
243
195
|
async def orders(self) -> dict[str, Any]:
|
244
196
|
"""Returns the active orders for a user."""
|
245
|
-
return await self.
|
197
|
+
return await self._request(Methods.GET, "api/1/users/orders")
|
246
198
|
|
247
199
|
async def region(self) -> dict[str, Any]:
|
248
200
|
"""Returns a user's region and appropriate fleet-api base URL. Accepts no parameters, response is based on the authentication token subject."""
|
249
|
-
return await self.
|
201
|
+
return await self._request(Methods.GET, "api/1/users/region")
|
250
202
|
|
251
203
|
class Vehicle:
|
252
204
|
"""Class describing the Tesla Fleet API vehicle endpoints and commands."""
|
253
205
|
|
254
206
|
def __init__(self, parent):
|
255
|
-
self.
|
256
|
-
self.
|
257
|
-
self._delete = parent._delete
|
207
|
+
self._parent = parent
|
208
|
+
self._request = parent._request
|
258
209
|
self.use_command_protocol = parent.use_command_protocol
|
259
210
|
|
260
|
-
class Trunk(StrEnum):
|
261
|
-
"""Trunk options"""
|
262
|
-
|
263
|
-
FRONT: "front"
|
264
|
-
REAR: "rear"
|
265
|
-
|
266
211
|
async def actuate_trunk(
|
267
|
-
self, vehicle_tag: str | int, which_trunk:
|
212
|
+
self, vehicle_tag: str | int, which_trunk: Trunks | str
|
268
213
|
) -> dict[str, Any]:
|
269
214
|
"""Controls the front or rear trunk."""
|
270
215
|
if self.use_command_protocol:
|
271
216
|
raise NotImplementedError("Command Protocol not implemented")
|
272
|
-
return await self.
|
217
|
+
return await self._request(
|
218
|
+
Methods.POST,
|
273
219
|
f"api/1/vehicles/{vehicle_tag}/command/actuate_trunk",
|
274
220
|
json={which_trunk: which_trunk},
|
275
221
|
)
|
@@ -282,7 +228,8 @@ class TeslaFleetApi:
|
|
282
228
|
raise NotImplementedError("Command Protocol not implemented")
|
283
229
|
if volume < 0.0 or volume > 11.0:
|
284
230
|
raise ValueError("Volume must a number from 0.0 to 11.0")
|
285
|
-
return await self.
|
231
|
+
return await self._request(
|
232
|
+
Methods.POST,
|
286
233
|
f"api/1/vehicles/{vehicle_tag}/command/adjust_volume",
|
287
234
|
json={volume: volume},
|
288
235
|
)
|
@@ -293,8 +240,9 @@ class TeslaFleetApi:
|
|
293
240
|
"""Starts climate preconditioning."""
|
294
241
|
if self.use_command_protocol:
|
295
242
|
raise NotImplementedError("Command Protocol not implemented")
|
296
|
-
return await self.
|
297
|
-
|
243
|
+
return await self._request(
|
244
|
+
Methods.POST,
|
245
|
+
f"api/1/vehicles/{vehicle_tag}/command/auto_conditioning_start",
|
298
246
|
)
|
299
247
|
|
300
248
|
async def auto_conditioning_stop(
|
@@ -303,8 +251,9 @@ class TeslaFleetApi:
|
|
303
251
|
"""Stops climate preconditioning."""
|
304
252
|
if self.use_command_protocol:
|
305
253
|
raise NotImplementedError("Command Protocol not implemented")
|
306
|
-
return await self.
|
307
|
-
|
254
|
+
return await self._request(
|
255
|
+
Methods.POST,
|
256
|
+
f"api/1/vehicles/{vehicle_tag}/command/auto_conditioning_stop",
|
308
257
|
)
|
309
258
|
|
310
259
|
async def cancel_software_update(
|
@@ -313,16 +262,17 @@ class TeslaFleetApi:
|
|
313
262
|
"""Cancels the countdown to install the vehicle software update."""
|
314
263
|
if self.use_command_protocol:
|
315
264
|
raise NotImplementedError("Command Protocol not implemented")
|
316
|
-
return await self.
|
317
|
-
|
265
|
+
return await self._request(
|
266
|
+
Methods.POST,
|
267
|
+
f"api/1/vehicles/{vehicle_tag}/command/cancel_software_update",
|
318
268
|
)
|
319
269
|
|
320
270
|
async def charge_max_range(self, vehicle_tag: str | int) -> dict[str, Any]:
|
321
271
|
"""Charges in max range mode -- we recommend limiting the use of this mode to long trips."""
|
322
272
|
if self.use_command_protocol:
|
323
273
|
raise NotImplementedError("Command Protocol not implemented")
|
324
|
-
return await self.
|
325
|
-
f"api/1/vehicles/{vehicle_tag}/command/charge_max_range"
|
274
|
+
return await self._request(
|
275
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/charge_max_range"
|
326
276
|
)
|
327
277
|
|
328
278
|
async def charge_port_door_close(
|
@@ -331,70 +281,79 @@ class TeslaFleetApi:
|
|
331
281
|
"""Closes the charge port door."""
|
332
282
|
if self.use_command_protocol:
|
333
283
|
raise NotImplementedError("Command Protocol not implemented")
|
334
|
-
return await self.
|
335
|
-
|
284
|
+
return await self._request(
|
285
|
+
Methods.POST,
|
286
|
+
f"api/1/vehicles/{vehicle_tag}/command/charge_port_door_close",
|
336
287
|
)
|
337
288
|
|
338
289
|
async def charge_port_door_open(self, vehicle_tag: str | int) -> dict[str, Any]:
|
339
290
|
"""Opens the charge port door."""
|
340
291
|
if self.use_command_protocol:
|
341
292
|
raise NotImplementedError("Command Protocol not implemented")
|
342
|
-
return await self.
|
343
|
-
|
293
|
+
return await self._request(
|
294
|
+
Methods.POST,
|
295
|
+
f"api/1/vehicles/{vehicle_tag}/command/charge_port_door_open",
|
344
296
|
)
|
345
297
|
|
346
298
|
async def charge_standard(self, vehicle_tag: str | int) -> dict[str, Any]:
|
347
299
|
"""Charges in Standard mode."""
|
348
300
|
if self.use_command_protocol:
|
349
301
|
raise NotImplementedError("Command Protocol not implemented")
|
350
|
-
return await self.
|
351
|
-
f"api/1/vehicles/{vehicle_tag}/command/charge_standard"
|
302
|
+
return await self._request(
|
303
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/charge_standard"
|
352
304
|
)
|
353
305
|
|
354
306
|
async def charge_start(self, vehicle_tag: str | int) -> dict[str, Any]:
|
355
307
|
"""Starts charging the vehicle."""
|
356
308
|
if self.use_command_protocol:
|
357
309
|
raise NotImplementedError("Command Protocol not implemented")
|
358
|
-
return await self.
|
359
|
-
f"api/1/vehicles/{vehicle_tag}/command/charge_start"
|
310
|
+
return await self._request(
|
311
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/charge_start"
|
360
312
|
)
|
361
313
|
|
362
314
|
async def charge_stop(self, vehicle_tag: str | int) -> dict[str, Any]:
|
363
315
|
"""Stops charging the vehicle."""
|
364
316
|
if self.use_command_protocol:
|
365
317
|
raise NotImplementedError("Command Protocol not implemented")
|
366
|
-
return await self.
|
318
|
+
return await self._request(
|
319
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/charge_stop"
|
320
|
+
)
|
367
321
|
|
368
322
|
async def clear_pin_to_drive_admin(self, vehicle_tag: str | int):
|
369
323
|
"""Deactivates PIN to Drive and resets the associated PIN for vehicles running firmware versions 2023.44+. This command is only accessible to fleet managers or owners."""
|
370
|
-
return await self.
|
371
|
-
|
324
|
+
return await self._request(
|
325
|
+
Methods.POST,
|
326
|
+
f"api/1/vehicles/{vehicle_tag}/command/clear_pin_to_drive_admin",
|
372
327
|
)
|
373
328
|
|
374
329
|
async def door_lock(self, vehicle_tag: str | int) -> dict[str, Any]:
|
375
330
|
"""Locks the vehicle."""
|
376
331
|
if self.use_command_protocol:
|
377
332
|
raise NotImplementedError("Command Protocol not implemented")
|
378
|
-
return await self.
|
333
|
+
return await self._request(
|
334
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/door_lock"
|
335
|
+
)
|
379
336
|
|
380
337
|
async def door_unlock(self, vehicle_tag: str | int) -> dict[str, Any]:
|
381
338
|
"""Unlocks the vehicle."""
|
382
339
|
if self.use_command_protocol:
|
383
340
|
raise NotImplementedError("Command Protocol not implemented")
|
384
|
-
return await self.
|
341
|
+
return await self._request(
|
342
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/door_unlock"
|
343
|
+
)
|
385
344
|
|
386
345
|
async def erase_user_data(self, vehicle_tag: str | int) -> dict[str, Any]:
|
387
346
|
"""Erases user's data from the user interface. Requires the vehicle to be in park."""
|
388
|
-
return await self.
|
389
|
-
f"api/1/vehicles/{vehicle_tag}/command/erase_user_data"
|
347
|
+
return await self._request(
|
348
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/erase_user_data"
|
390
349
|
)
|
391
350
|
|
392
351
|
async def flash_lights(self, vehicle_tag: str | int) -> dict[str, Any]:
|
393
352
|
"""Briefly flashes the vehicle headlights. Requires the vehicle to be in park."""
|
394
353
|
if self.use_command_protocol:
|
395
354
|
raise NotImplementedError("Command Protocol not implemented")
|
396
|
-
return await self.
|
397
|
-
f"api/1/vehicles/{vehicle_tag}/command/flash_lights"
|
355
|
+
return await self._request(
|
356
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/flash_lights"
|
398
357
|
)
|
399
358
|
|
400
359
|
async def guest_mode(
|
@@ -403,7 +362,8 @@ class TeslaFleetApi:
|
|
403
362
|
"""Restricts certain vehicle UI functionality from guest users"""
|
404
363
|
if self.use_command_protocol:
|
405
364
|
raise NotImplementedError("Command Protocol not implemented")
|
406
|
-
return await self.
|
365
|
+
return await self._request(
|
366
|
+
Methods.POST,
|
407
367
|
f"api/1/vehicles/{vehicle_tag}/command/guest_mode",
|
408
368
|
json={enable: enable},
|
409
369
|
)
|
@@ -412,42 +372,45 @@ class TeslaFleetApi:
|
|
412
372
|
"""Honks the vehicle horn. Requires the vehicle to be in park."""
|
413
373
|
if self.use_command_protocol:
|
414
374
|
raise NotImplementedError("Command Protocol not implemented")
|
415
|
-
return await self.
|
375
|
+
return await self._request(
|
376
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/honk_horn"
|
377
|
+
)
|
416
378
|
|
417
379
|
async def media_next_fav(self, vehicle_tag: str | int) -> dict[str, Any]:
|
418
380
|
"""Advances media player to next favorite track."""
|
419
|
-
return await self.
|
420
|
-
f"api/1/vehicles/{vehicle_tag}/command/media_next_fav"
|
381
|
+
return await self._request(
|
382
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/media_next_fav"
|
421
383
|
)
|
422
384
|
|
423
385
|
async def media_next_track(self, vehicle_tag: str | int) -> dict[str, Any]:
|
424
386
|
"""Advances media player to next track."""
|
425
|
-
return await self.
|
426
|
-
f"api/1/vehicles/{vehicle_tag}/command/media_next_track"
|
387
|
+
return await self._request(
|
388
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/media_next_track"
|
427
389
|
)
|
428
390
|
|
429
391
|
async def media_prev_fav(self, vehicle_tag: str | int) -> dict[str, Any]:
|
430
392
|
"""Advances media player to previous favorite track."""
|
431
|
-
return await self.
|
432
|
-
f"api/1/vehicles/{vehicle_tag}/command/media_prev_fav"
|
393
|
+
return await self._request(
|
394
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/media_prev_fav"
|
433
395
|
)
|
434
396
|
|
435
397
|
async def media_prev_track(self, vehicle_tag: str | int) -> dict[str, Any]:
|
436
398
|
"""Advances media player to previous track."""
|
437
|
-
return await self.
|
438
|
-
f"api/1/vehicles/{vehicle_tag}/command/media_prev_track"
|
399
|
+
return await self._request(
|
400
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/media_prev_track"
|
439
401
|
)
|
440
402
|
|
441
403
|
async def media_toggle_playback(self, vehicle_tag: str | int) -> dict[str, Any]:
|
442
404
|
"""Toggles current play/pause state."""
|
443
|
-
return await self.
|
444
|
-
|
405
|
+
return await self._request(
|
406
|
+
Methods.POST,
|
407
|
+
f"api/1/vehicles/{vehicle_tag}/command/media_toggle_playback",
|
445
408
|
)
|
446
409
|
|
447
410
|
async def media_volume_down(self, vehicle_tag: str | int) -> dict[str, Any]:
|
448
411
|
"""Turns the volume down by one."""
|
449
|
-
return await self.
|
450
|
-
f"api/1/vehicles/{vehicle_tag}/command/media_volume_down"
|
412
|
+
return await self._request(
|
413
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/media_volume_down"
|
451
414
|
)
|
452
415
|
|
453
416
|
async def navigation_gps_request(
|
@@ -456,7 +419,8 @@ class TeslaFleetApi:
|
|
456
419
|
"""Start navigation to given coordinates. Order can be used to specify order of multiple stops."""
|
457
420
|
if self.use_command_protocol:
|
458
421
|
raise NotImplementedError("Command Protocol not implemented")
|
459
|
-
return await self.
|
422
|
+
return await self._request(
|
423
|
+
Methods.POST,
|
460
424
|
f"api/1/vehicles/{vehicle_tag}/command/navigation_gps_request",
|
461
425
|
json={lat: lat, lon: lon, order: order},
|
462
426
|
)
|
@@ -465,7 +429,8 @@ class TeslaFleetApi:
|
|
465
429
|
self, vehicle_tag: str | int, type: str, locale: str, timestamp_ms: str
|
466
430
|
) -> dict[str, Any]:
|
467
431
|
"""Sends a location to the in-vehicle navigation system."""
|
468
|
-
return await self.
|
432
|
+
return await self._request(
|
433
|
+
Methods.POST,
|
469
434
|
f"api/1/vehicles/{vehicle_tag}/command/navigation_request",
|
470
435
|
json={type: type, locale: locale, timestamp_ms: timestamp_ms},
|
471
436
|
)
|
@@ -474,7 +439,8 @@ class TeslaFleetApi:
|
|
474
439
|
self, vehicle_tag: str | int, id: int, order: int
|
475
440
|
) -> dict[str, Any]:
|
476
441
|
"""Sends a location to the in-vehicle navigation system."""
|
477
|
-
return await self.
|
442
|
+
return await self._request(
|
443
|
+
Methods.POST,
|
478
444
|
f"api/1/vehicles/{vehicle_tag}/command/navigation_sc_request",
|
479
445
|
json={type: type, id: id, order: order},
|
480
446
|
)
|
@@ -485,7 +451,8 @@ class TeslaFleetApi:
|
|
485
451
|
"""Sets automatic seat heating and cooling."""
|
486
452
|
if self.use_command_protocol:
|
487
453
|
raise NotImplementedError("Command Protocol not implemented")
|
488
|
-
return await self.
|
454
|
+
return await self._request(
|
455
|
+
Methods.POST,
|
489
456
|
f"api/1/vehicles/{vehicle_tag}/command/remote_auto_seat_climate_request",
|
490
457
|
json={
|
491
458
|
auto_seat_position: auto_seat_position,
|
@@ -497,7 +464,8 @@ class TeslaFleetApi:
|
|
497
464
|
self, vehicle_tag: str | int, on: bool
|
498
465
|
) -> dict[str, Any]:
|
499
466
|
"""Sets automatic steering wheel heating on/off."""
|
500
|
-
return await self.
|
467
|
+
return await self._request(
|
468
|
+
Methods.POST,
|
501
469
|
f"api/1/vehicles/{vehicle_tag}/command/remote_auto_steering_wheel_heat_climate_request",
|
502
470
|
json={on: on},
|
503
471
|
)
|
@@ -506,7 +474,8 @@ class TeslaFleetApi:
|
|
506
474
|
self, vehicle_tag: str | int, sound: int
|
507
475
|
) -> dict[str, Any]:
|
508
476
|
"""Plays a sound through the vehicle external speaker."""
|
509
|
-
return await self.
|
477
|
+
return await self._request(
|
478
|
+
Methods.POST,
|
510
479
|
f"api/1/vehicles/{vehicle_tag}/command/remote_boombox",
|
511
480
|
json={sound: sound},
|
512
481
|
)
|
@@ -517,7 +486,8 @@ class TeslaFleetApi:
|
|
517
486
|
"""Sets seat cooling."""
|
518
487
|
if self.use_command_protocol:
|
519
488
|
raise NotImplementedError("Command Protocol not implemented")
|
520
|
-
return await self.
|
489
|
+
return await self._request(
|
490
|
+
Methods.POST,
|
521
491
|
f"api/1/vehicles/{vehicle_tag}/command/remote_seat_cooler_request",
|
522
492
|
json={
|
523
493
|
seat_position: seat_position,
|
@@ -531,16 +501,17 @@ class TeslaFleetApi:
|
|
531
501
|
"""Sets seat heating."""
|
532
502
|
if self.use_command_protocol:
|
533
503
|
raise NotImplementedError("Command Protocol not implemented")
|
534
|
-
return await self.
|
535
|
-
|
504
|
+
return await self._request(
|
505
|
+
Methods.POST,
|
506
|
+
f"api/1/vehicles/{vehicle_tag}/command/remote_seat_heater_request",
|
536
507
|
)
|
537
508
|
|
538
509
|
async def remote_start_drive(self, vehicle_tag: str | int) -> dict[str, Any]:
|
539
510
|
"""Starts the vehicle remotely. Requires keyless driving to be enabled."""
|
540
511
|
if self.use_command_protocol:
|
541
512
|
raise NotImplementedError("Command Protocol not implemented")
|
542
|
-
return await self.
|
543
|
-
f"api/1/vehicles/{vehicle_tag}/command/remote_start_drive"
|
513
|
+
return await self._request(
|
514
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/remote_start_drive"
|
544
515
|
)
|
545
516
|
|
546
517
|
async def remote_steering_wheel_heat_level_request(
|
@@ -549,7 +520,8 @@ class TeslaFleetApi:
|
|
549
520
|
"""Sets steering wheel heat level."""
|
550
521
|
if self.use_command_protocol:
|
551
522
|
raise NotImplementedError("Command Protocol not implemented")
|
552
|
-
return await self.
|
523
|
+
return await self._request(
|
524
|
+
Methods.POST,
|
553
525
|
f"api/1/vehicles/{vehicle_tag}/command/remote_steering_wheel_heat_level_request",
|
554
526
|
json={level: level},
|
555
527
|
)
|
@@ -560,7 +532,8 @@ class TeslaFleetApi:
|
|
560
532
|
"""Sets steering wheel heating on/off. For vehicles that do not support auto steering wheel heat."""
|
561
533
|
if self.use_command_protocol:
|
562
534
|
raise NotImplementedError("Command Protocol not implemented")
|
563
|
-
return await self.
|
535
|
+
return await self._request(
|
536
|
+
Methods.POST,
|
564
537
|
f"api/1/vehicles/{vehicle_tag}/command/remote_steering_wheel_heater_request",
|
565
538
|
json={on: on},
|
566
539
|
)
|
@@ -571,16 +544,17 @@ class TeslaFleetApi:
|
|
571
544
|
"""Removes PIN to Drive. Requires the car to be in Pin to Drive mode and not in Valet mode. Note that this only works if PIN to Drive is not active. This command also requires the Tesla Vehicle Command Protocol - for more information, please see refer to the documentation here."""
|
572
545
|
if self.use_command_protocol:
|
573
546
|
raise NotImplementedError("Command Protocol not implemented")
|
574
|
-
return await self.
|
575
|
-
|
547
|
+
return await self._request(
|
548
|
+
Methods.POST,
|
549
|
+
f"api/1/vehicles/{vehicle_tag}/command/reset_pin_to_drive_pin",
|
576
550
|
)
|
577
551
|
|
578
552
|
async def reset_valet_pin(self, vehicle_tag: str | int) -> dict[str, Any]:
|
579
553
|
"""Removes PIN for Valet Mode."""
|
580
554
|
if self.use_command_protocol:
|
581
555
|
raise NotImplementedError("Command Protocol not implemented")
|
582
|
-
return await self.
|
583
|
-
f"api/1/vehicles/{vehicle_tag}/command/reset_valet_pin"
|
556
|
+
return await self._request(
|
557
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/reset_valet_pin"
|
584
558
|
)
|
585
559
|
|
586
560
|
async def schedule_software_update(
|
@@ -589,7 +563,8 @@ class TeslaFleetApi:
|
|
589
563
|
"""Schedules a vehicle software update (over the air "OTA") to be installed in the future."""
|
590
564
|
if self.use_command_protocol:
|
591
565
|
raise NotImplementedError("Command Protocol not implemented")
|
592
|
-
return await self.
|
566
|
+
return await self._request(
|
567
|
+
Methods.POST,
|
593
568
|
f"api/1/vehicles/{vehicle_tag}/command/schedule_software_update",
|
594
569
|
json={offset_sec: offset_sec},
|
595
570
|
)
|
@@ -600,7 +575,8 @@ class TeslaFleetApi:
|
|
600
575
|
"""Turns Bioweapon Defense Mode on and off."""
|
601
576
|
if self.use_command_protocol:
|
602
577
|
raise NotImplementedError("Command Protocol not implemented")
|
603
|
-
return await self.
|
578
|
+
return await self._request(
|
579
|
+
Methods.POST,
|
604
580
|
f"api/1/vehicles/{vehicle_tag}/command/set_bioweapon_mode",
|
605
581
|
json={on: on, manual_override: manual_override},
|
606
582
|
)
|
@@ -611,7 +587,8 @@ class TeslaFleetApi:
|
|
611
587
|
"""Sets the vehicle overheat protection."""
|
612
588
|
if self.use_command_protocol:
|
613
589
|
raise NotImplementedError("Command Protocol not implemented")
|
614
|
-
return await self.
|
590
|
+
return await self._request(
|
591
|
+
Methods.POST,
|
615
592
|
f"api/1/vehicles/{vehicle_tag}/command/set_cabin_overheat_protection",
|
616
593
|
json={on: on, fan_only: fan_only},
|
617
594
|
)
|
@@ -622,7 +599,8 @@ class TeslaFleetApi:
|
|
622
599
|
"""Sets the vehicle charge limit."""
|
623
600
|
if self.use_command_protocol:
|
624
601
|
raise NotImplementedError("Command Protocol not implemented")
|
625
|
-
return await self.
|
602
|
+
return await self._request(
|
603
|
+
Methods.POST,
|
626
604
|
f"api/1/vehicles/{vehicle_tag}/command/set_charge_limit",
|
627
605
|
json={percent: percent},
|
628
606
|
)
|
@@ -633,44 +611,32 @@ class TeslaFleetApi:
|
|
633
611
|
"""Sets the vehicle charging amps."""
|
634
612
|
if self.use_command_protocol:
|
635
613
|
raise NotImplementedError("Command Protocol not implemented")
|
636
|
-
return await self.
|
614
|
+
return await self._request(
|
615
|
+
Methods.POST,
|
637
616
|
f"api/1/vehicles/{vehicle_tag}/command/set_charging_amps",
|
638
617
|
json={charging_amps: charging_amps},
|
639
618
|
)
|
640
619
|
|
641
|
-
class ClimateKeeperMode(IntEnum):
|
642
|
-
"""Climate Keeper Mode options"""
|
643
|
-
|
644
|
-
OFF = 0
|
645
|
-
KEEP_MODE = 1
|
646
|
-
DOG_MODE = 2
|
647
|
-
CAMP_MODE = 3
|
648
|
-
|
649
620
|
async def set_climate_keeper_mode(
|
650
621
|
self, vehicle_tag: str | int, climate_keeper_mode: ClimateKeeperMode | int
|
651
622
|
) -> dict[str, Any]:
|
652
623
|
"""Enables climate keeper mode."""
|
653
624
|
if self.use_command_protocol:
|
654
625
|
raise NotImplementedError("Command Protocol not implemented")
|
655
|
-
return await self.
|
626
|
+
return await self._request(
|
627
|
+
Methods.POST,
|
656
628
|
f"api/1/vehicles/{vehicle_tag}/command/set_climate_keeper_mode",
|
657
629
|
json={climate_keeper_mode: climate_keeper_mode},
|
658
630
|
)
|
659
631
|
|
660
|
-
class CopTemp(IntEnum):
|
661
|
-
"""COP Temp options"""
|
662
|
-
|
663
|
-
LOW = 0 # 30C 90F
|
664
|
-
MEDIUM = 1 # 35C 95F
|
665
|
-
HIGH = 2 # 40C 100F
|
666
|
-
|
667
632
|
async def set_cop_temp(
|
668
|
-
self, vehicle_tag: str | int, cop_temp:
|
633
|
+
self, vehicle_tag: str | int, cop_temp: CabinOverheatProtectionTemps | int
|
669
634
|
) -> dict[str, Any]:
|
670
635
|
"""Adjusts the Cabin Overheat Protection temperature (COP)."""
|
671
636
|
if self.use_command_protocol:
|
672
637
|
raise NotImplementedError("Command Protocol not implemented")
|
673
|
-
return await self.
|
638
|
+
return await self._request(
|
639
|
+
Methods.POST,
|
674
640
|
f"api/1/vehicles/{vehicle_tag}/command/set_cop_temp",
|
675
641
|
json={cop_temp: cop_temp},
|
676
642
|
)
|
@@ -681,7 +647,8 @@ class TeslaFleetApi:
|
|
681
647
|
"""Sets a four-digit passcode for PIN to Drive. This PIN must then be entered before the vehicle can be driven."""
|
682
648
|
if self.use_command_protocol:
|
683
649
|
raise NotImplementedError("Command Protocol not implemented")
|
684
|
-
return await self.
|
650
|
+
return await self._request(
|
651
|
+
Methods.POST,
|
685
652
|
f"api/1/vehicles/{vehicle_tag}/command/set_pin_to_drive",
|
686
653
|
json={on: on, password: str(password)},
|
687
654
|
)
|
@@ -692,7 +659,8 @@ class TeslaFleetApi:
|
|
692
659
|
"""Sets an override for preconditioning — it should default to empty if no override is used."""
|
693
660
|
if self.use_command_protocol:
|
694
661
|
raise NotImplementedError("Command Protocol not implemented")
|
695
|
-
return await self.
|
662
|
+
return await self._request(
|
663
|
+
Methods.POST,
|
696
664
|
f"api/1/vehicles/{vehicle_tag}/command/set_preconditioning_max",
|
697
665
|
json={on: on, manual_override: manual_override},
|
698
666
|
)
|
@@ -703,7 +671,8 @@ class TeslaFleetApi:
|
|
703
671
|
"""Sets a time at which charging should be completed. The time parameter is minutes after midnight (e.g: time=120 schedules charging for 2:00am vehicle local time)."""
|
704
672
|
if self.use_command_protocol:
|
705
673
|
raise NotImplementedError("Command Protocol not implemented")
|
706
|
-
return await self.
|
674
|
+
return await self._request(
|
675
|
+
Methods.POST,
|
707
676
|
f"api/1/vehicles/{vehicle_tag}/command/set_scheduled_charging",
|
708
677
|
json={enable: enable, time: time},
|
709
678
|
)
|
@@ -714,7 +683,8 @@ class TeslaFleetApi:
|
|
714
683
|
"""Sets a time at which departure should be completed. The time parameter is minutes after midnight (e.g: time=120 schedules departure for 2:00am vehicle local time)."""
|
715
684
|
if self.use_command_protocol:
|
716
685
|
raise NotImplementedError("Command Protocol not implemented")
|
717
|
-
return await self.
|
686
|
+
return await self._request(
|
687
|
+
Methods.POST,
|
718
688
|
f"api/1/vehicles/{vehicle_tag}/command/set_scheduled_departure",
|
719
689
|
json={enable: enable, time: time},
|
720
690
|
)
|
@@ -725,8 +695,10 @@ class TeslaFleetApi:
|
|
725
695
|
"""Enables and disables Sentry Mode. Sentry Mode allows customers to watch the vehicle cameras live from the mobile app, as well as record sentry events."""
|
726
696
|
if self.use_command_protocol:
|
727
697
|
raise NotImplementedError("Command Protocol not implemented")
|
728
|
-
return await self.
|
729
|
-
|
698
|
+
return await self._request(
|
699
|
+
Methods.POST,
|
700
|
+
f"api/1/vehicles/{vehicle_tag}/command/set_sentry_mode",
|
701
|
+
json={on: on},
|
730
702
|
)
|
731
703
|
|
732
704
|
async def set_temps(
|
@@ -735,7 +707,8 @@ class TeslaFleetApi:
|
|
735
707
|
"""Sets the driver and/or passenger-side cabin temperature (and other zones if sync is enabled)."""
|
736
708
|
if self.use_command_protocol:
|
737
709
|
raise NotImplementedError("Command Protocol not implemented")
|
738
|
-
return await self.
|
710
|
+
return await self._request(
|
711
|
+
Methods.POST,
|
739
712
|
f"api/1/vehicles/{vehicle_tag}/command/set_temps",
|
740
713
|
json={driver_temp: driver_temp, passenger_temp: passenger_temp},
|
741
714
|
)
|
@@ -746,7 +719,8 @@ class TeslaFleetApi:
|
|
746
719
|
"""Turns on Valet Mode and sets a four-digit passcode that must then be entered to disable Valet Mode."""
|
747
720
|
if self.use_command_protocol:
|
748
721
|
raise NotImplementedError("Command Protocol not implemented")
|
749
|
-
return await self.
|
722
|
+
return await self._request(
|
723
|
+
Methods.POST,
|
750
724
|
f"api/1/vehicles/{vehicle_tag}/command/set_valet_mode",
|
751
725
|
json={on: on, password: str(password)},
|
752
726
|
)
|
@@ -757,7 +731,8 @@ class TeslaFleetApi:
|
|
757
731
|
"""Changes the name of a vehicle. This command also requires the Tesla Vehicle Command Protocol - for more information, please see refer to the documentation here."""
|
758
732
|
if self.use_command_protocol:
|
759
733
|
raise NotImplementedError("Command Protocol not implemented")
|
760
|
-
return await self.
|
734
|
+
return await self._request(
|
735
|
+
Methods.POST,
|
761
736
|
f"api/1/vehicles/{vehicle_tag}/command/set_vehicle_name",
|
762
737
|
json={vehicle_name: vehicle_name},
|
763
738
|
)
|
@@ -768,7 +743,8 @@ class TeslaFleetApi:
|
|
768
743
|
"""Activates Speed Limit Mode with a four-digit PIN."""
|
769
744
|
if self.use_command_protocol:
|
770
745
|
raise NotImplementedError("Command Protocol not implemented")
|
771
|
-
return await self.
|
746
|
+
return await self._request(
|
747
|
+
Methods.POST,
|
772
748
|
f"api/1/vehicles/{vehicle_tag}/command/speed_limit_activate",
|
773
749
|
json={pin: str(pin)},
|
774
750
|
)
|
@@ -779,7 +755,8 @@ class TeslaFleetApi:
|
|
779
755
|
"""Deactivates Speed Limit Mode and resets the associated PIN."""
|
780
756
|
if self.use_command_protocol:
|
781
757
|
raise NotImplementedError("Command Protocol not implemented")
|
782
|
-
return await self.
|
758
|
+
return await self._request(
|
759
|
+
Methods.POST,
|
783
760
|
f"api/1/vehicles/{vehicle_tag}/command/speed_limit_clear_pin",
|
784
761
|
json={pin: str(pin)},
|
785
762
|
)
|
@@ -788,8 +765,9 @@ class TeslaFleetApi:
|
|
788
765
|
self, vehicle_tag: str | int
|
789
766
|
) -> dict[str, Any]:
|
790
767
|
"""Deactivates Speed Limit Mode and resets the associated PIN for vehicles running firmware versions 2023.38+. This command is only accessible to fleet managers or owners."""
|
791
|
-
return await self.
|
792
|
-
|
768
|
+
return await self._request(
|
769
|
+
Methods.POST,
|
770
|
+
f"api/1/vehicles/{vehicle_tag}/command/speed_limit_clear_pin_admin",
|
793
771
|
)
|
794
772
|
|
795
773
|
async def speed_limit_deactivate(
|
@@ -798,7 +776,8 @@ class TeslaFleetApi:
|
|
798
776
|
"""Deactivates Speed Limit Mode."""
|
799
777
|
if self.use_command_protocol:
|
800
778
|
raise NotImplementedError("Command Protocol not implemented")
|
801
|
-
return await self.
|
779
|
+
return await self._request(
|
780
|
+
Methods.POST,
|
802
781
|
f"api/1/vehicles/{vehicle_tag}/command/speed_limit_deactivate",
|
803
782
|
json={pin: str(pin)},
|
804
783
|
)
|
@@ -809,23 +788,18 @@ class TeslaFleetApi:
|
|
809
788
|
"""Sets the maximum speed allowed when Speed Limit Mode is active."""
|
810
789
|
if self.use_command_protocol:
|
811
790
|
raise NotImplementedError("Command Protocol not implemented")
|
812
|
-
return await self.
|
791
|
+
return await self._request(
|
792
|
+
Methods.POST,
|
813
793
|
f"api/1/vehicles/{vehicle_tag}/command/speed_limit_set_limit",
|
814
794
|
json={limit_mph: limit_mph},
|
815
795
|
)
|
816
796
|
|
817
|
-
class SunRoof(StrEnum):
|
818
|
-
"""Sunroof options"""
|
819
|
-
|
820
|
-
STOP = "stop"
|
821
|
-
CLOSE = "close"
|
822
|
-
VENT = "vent"
|
823
|
-
|
824
797
|
async def sun_roof_control(
|
825
|
-
self, vehicle_tag: str | int, state: str |
|
798
|
+
self, vehicle_tag: str | int, state: str | SunRoofCommands
|
826
799
|
) -> dict[str, Any]:
|
827
800
|
"""Controls the panoramic sunroof on the Model S."""
|
828
|
-
return await self.
|
801
|
+
return await self._request(
|
802
|
+
Methods.POST,
|
829
803
|
f"api/1/vehicles/{vehicle_tag}/command/sun_roof_control",
|
830
804
|
{state: state},
|
831
805
|
)
|
@@ -834,8 +808,10 @@ class TeslaFleetApi:
|
|
834
808
|
self, vehicle_tag: str | int, note: str
|
835
809
|
) -> dict[str, Any]:
|
836
810
|
"""Records a drive note. The note parameter is truncated to 80 characters in length."""
|
837
|
-
return await self.
|
838
|
-
|
811
|
+
return await self._request(
|
812
|
+
Methods.POST,
|
813
|
+
f"api/1/vehicles/{vehicle_tag}/command/take_drivenote",
|
814
|
+
{note: note},
|
839
815
|
)
|
840
816
|
|
841
817
|
async def trigger_homelink(
|
@@ -844,7 +820,8 @@ class TeslaFleetApi:
|
|
844
820
|
"""Turns on HomeLink (used to open and close garage doors)."""
|
845
821
|
if self.use_command_protocol:
|
846
822
|
raise NotImplementedError("Command Protocol not implemented")
|
847
|
-
return await self.
|
823
|
+
return await self._request(
|
824
|
+
Methods.POST,
|
848
825
|
f"api/1/vehicles/{vehicle_tag}/command/trigger_homelink",
|
849
826
|
{lat: lat, lon: lon, token: token},
|
850
827
|
)
|
@@ -853,51 +830,55 @@ class TeslaFleetApi:
|
|
853
830
|
self, vehicle_tag: str | int, calendar_data: str
|
854
831
|
) -> dict[str, Any]:
|
855
832
|
"""Upcoming calendar entries stored on the vehicle."""
|
856
|
-
return await self.
|
833
|
+
return await self._request(
|
834
|
+
Methods.POST,
|
857
835
|
f"api/1/vehicles/{vehicle_tag}/command/upcoming_calendar_entries",
|
858
836
|
{calendar_data: calendar_data},
|
859
837
|
)
|
860
838
|
|
861
|
-
class WindowControl(StrEnum):
|
862
|
-
"""Window Control options"""
|
863
|
-
|
864
|
-
VENT = "vent"
|
865
|
-
CLOSE = "close"
|
866
|
-
|
867
839
|
async def window_control(
|
868
840
|
self,
|
869
841
|
vehicle_tag: str | int,
|
870
842
|
lat: float,
|
871
843
|
lon: float,
|
872
|
-
command: str |
|
844
|
+
command: str | WindowCommands,
|
873
845
|
) -> dict[str, Any]:
|
874
846
|
"""Control the windows of a parked vehicle. Supported commands: vent and close. When closing, specify lat and lon of user to ensure they are within range of vehicle (unless this is an M3 platform vehicle)."""
|
875
|
-
return await self.
|
847
|
+
return await self._request(
|
848
|
+
Methods.POST,
|
876
849
|
f"api/1/vehicles/{vehicle_tag}/command/window_control",
|
877
850
|
{lat: lat, lon: lon, command: command},
|
878
851
|
)
|
879
852
|
|
880
853
|
async def drivers(self, vehicle_tag: str | int) -> dict[str, Any]:
|
881
854
|
"""Returns all allowed drivers for a vehicle. This endpoint is only available for the vehicle owner."""
|
882
|
-
return await self.
|
855
|
+
return await self._request(
|
856
|
+
Methods.GET, f"api/1/vehicles/{vehicle_tag}/drivers"
|
857
|
+
)
|
883
858
|
|
884
859
|
async def drivers_remove(
|
885
860
|
self, vehicle_tag: str | int, share_user_id: str | int | None = None
|
886
861
|
) -> dict[str, Any]:
|
887
862
|
"""Removes driver access from a vehicle. Share users can only remove their own access. Owners can remove share access or their own."""
|
888
|
-
return await self.
|
889
|
-
|
863
|
+
return await self._request(
|
864
|
+
Methods.DELETE,
|
865
|
+
f"api/1/vehicles/{vehicle_tag}/drivers",
|
866
|
+
{share_user_id: share_user_id},
|
890
867
|
)
|
891
868
|
|
892
869
|
async def list(
|
893
870
|
self, page: int | None = None, per_page: int | None = None
|
894
871
|
) -> dict[str, Any]:
|
895
872
|
"""Returns vehicles belonging to the account."""
|
896
|
-
return await self.
|
873
|
+
return await self._request(
|
874
|
+
Methods.GET, "api/1/vehicles", {page: page, per_page: per_page}
|
875
|
+
)
|
897
876
|
|
898
877
|
async def mobile_enabled(self, vehicle_tag: str | int) -> dict[str, Any]:
|
899
878
|
"""Returns whether or not mobile access is enabled for the vehicle."""
|
900
|
-
return await self.
|
879
|
+
return await self._request(
|
880
|
+
Methods.GET, f"api/1/vehicles/{vehicle_tag}/mobile_enabled"
|
881
|
+
)
|
901
882
|
|
902
883
|
async def nearby_charging_sites(
|
903
884
|
self,
|
@@ -907,18 +888,23 @@ class TeslaFleetApi:
|
|
907
888
|
detail: bool | None = None,
|
908
889
|
) -> dict[str, Any]:
|
909
890
|
"""Returns the charging sites near the current location of the vehicle."""
|
910
|
-
return await self.
|
891
|
+
return await self._request(
|
892
|
+
Methods.GET,
|
911
893
|
f"api/1/vehicles/{vehicle_tag}/nearby_charging_sites",
|
912
894
|
{count: count, radius: radius, detail: detail},
|
913
895
|
)
|
914
896
|
|
915
897
|
async def options(self, vin: str) -> dict[str, Any]:
|
916
898
|
"""Returns vehicle option details."""
|
917
|
-
return await self.
|
899
|
+
return await self._request(
|
900
|
+
Methods.GET, "api/1/dx/vehicles/options", {vin: vin}
|
901
|
+
)
|
918
902
|
|
919
903
|
async def recent_alerts(self, vehicle_tag: str | int) -> dict[str, Any]:
|
920
904
|
"""List of recent alerts"""
|
921
|
-
return await self.
|
905
|
+
return await self._request(
|
906
|
+
Methods.GET, f"api/1/vehicles/{vehicle_tag}/recent_alerts"
|
907
|
+
)
|
922
908
|
|
923
909
|
async def release_notes(
|
924
910
|
self,
|
@@ -927,40 +913,50 @@ class TeslaFleetApi:
|
|
927
913
|
language: int | None = None,
|
928
914
|
) -> dict[str, Any]:
|
929
915
|
"""Returns firmware release notes."""
|
930
|
-
return await self.
|
916
|
+
return await self._request(
|
917
|
+
Methods.GET,
|
931
918
|
f"api/1/vehicles/{vehicle_tag}/release_notes",
|
932
919
|
{staged: staged, language: language},
|
933
920
|
)
|
934
921
|
|
935
922
|
async def service_data(self, vehicle_tag: str | int) -> dict[str, Any]:
|
936
923
|
"""Returns service data."""
|
937
|
-
return await self.
|
924
|
+
return await self._request(
|
925
|
+
Methods.GET, f"api/1/vehicles/{vehicle_tag}/service_data"
|
926
|
+
)
|
938
927
|
|
939
928
|
async def share_invites(self, vehicle_tag: str | int) -> dict[str, Any]:
|
940
929
|
"""Returns the share invites for a vehicle."""
|
941
|
-
return await self.
|
930
|
+
return await self._request(
|
931
|
+
Methods.GET, f"api/1/vehicles/{vehicle_tag}/invitations"
|
932
|
+
)
|
942
933
|
|
943
934
|
async def share_invites_create(self, vehicle_tag: str | int) -> dict[str, Any]:
|
944
935
|
"""Creates a share invite for a vehicle."""
|
945
|
-
return await self.
|
936
|
+
return await self._request(
|
937
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/invitations"
|
938
|
+
)
|
946
939
|
|
947
940
|
async def share_invites_redeem(self, code: str) -> dict[str, Any]:
|
948
941
|
"""Redeems a share invite."""
|
949
|
-
return await self.
|
942
|
+
return await self._request(
|
943
|
+
Methods.POST, "api/1/invitations/redeem", {code: code}
|
944
|
+
)
|
950
945
|
|
951
946
|
async def share_invites_revoke(
|
952
947
|
self, vehicle_tag: str | int, id: str
|
953
948
|
) -> dict[str, Any]:
|
954
949
|
"""Revokes a share invite."""
|
955
|
-
return await self.
|
956
|
-
f"api/1/vehicles/{vehicle_tag}/invitations/{id}/revoke"
|
950
|
+
return await self._request(
|
951
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/invitations/{id}/revoke"
|
957
952
|
)
|
958
953
|
|
959
954
|
async def signed_command(
|
960
955
|
self, vehicle_tag: str | int, routable_message: str
|
961
956
|
) -> dict[str, Any]:
|
962
957
|
"""Signed Commands is a generic endpoint replacing legacy commands."""
|
963
|
-
return await self.
|
958
|
+
return await self._request(
|
959
|
+
Methods.POST,
|
964
960
|
f"api/1/vehicles/{vehicle_tag}/signed_command",
|
965
961
|
{routable_message: routable_message},
|
966
962
|
)
|
@@ -969,7 +965,8 @@ class TeslaFleetApi:
|
|
969
965
|
self, device_token: str, device_type: str
|
970
966
|
) -> dict[str, Any]:
|
971
967
|
"""Returns the list of vehicles for which this mobile device currently subscribes to push notifications."""
|
972
|
-
return await self.
|
968
|
+
return await self._request(
|
969
|
+
Methods.GET,
|
973
970
|
"api/1/subscriptions",
|
974
971
|
query={device_token: device_token, device_type: device_type},
|
975
972
|
)
|
@@ -978,69 +975,516 @@ class TeslaFleetApi:
|
|
978
975
|
self, device_token: str, device_type: str
|
979
976
|
) -> dict[str, Any]:
|
980
977
|
"""Allows a mobile device to specify which vehicles to receive push notifications from."""
|
981
|
-
return await self.
|
978
|
+
return await self._request(
|
979
|
+
Methods.POST,
|
982
980
|
"api/1/subscriptions",
|
983
981
|
query={device_token: device_token, device_type: device_type},
|
984
982
|
)
|
985
983
|
|
986
984
|
async def vehicle(self, vehicle_tag: str | int) -> dict[str, Any]:
|
987
985
|
"""Returns information about a vehicle."""
|
988
|
-
return await self.
|
989
|
-
|
990
|
-
class Endpoints(StrEnum):
|
991
|
-
"""Endpoints options"""
|
992
|
-
|
993
|
-
CHARGE_STATE = "charge_state"
|
994
|
-
CLIMATE_STATE = "climate_state"
|
995
|
-
CLOSURES_STATE = "closures_state"
|
996
|
-
DRIVE_STATE = "drive_state"
|
997
|
-
GUI_SETTINGS = "gui_settings"
|
998
|
-
LOCATION_DATA = "location_data"
|
999
|
-
VEHICLE_CONFIG = "vehicle_config"
|
1000
|
-
VEHICLE_STATE = "vehicle_state"
|
1001
|
-
VEHICLE_DATA_COMBO = "vehicle_data_combo"
|
986
|
+
return await self._request(Methods.GET, f"api/1/vehicles/{vehicle_tag}")
|
1002
987
|
|
1003
988
|
async def vehicle_data(
|
1004
989
|
self,
|
1005
990
|
vehicle_tag: str | int,
|
1006
|
-
endpoints:
|
991
|
+
endpoints: VehicleDataEndpoints | str | None = None,
|
1007
992
|
) -> dict[str, Any]:
|
1008
993
|
"""Makes a live call to the vehicle. This may return cached data if the vehicle is offline. For vehicles running firmware versions 2023.38+, location_data is required to fetch vehicle location. This will result in a location sharing icon to show on the vehicle UI."""
|
1009
|
-
return await self.
|
1010
|
-
|
994
|
+
return await self._request(
|
995
|
+
Methods.GET,
|
996
|
+
f"api/1/vehicles/{vehicle_tag}/vehicle_data",
|
997
|
+
{endpoints: endpoints},
|
1011
998
|
)
|
1012
999
|
|
1013
|
-
class DeviceType(StrEnum):
|
1014
|
-
"""Device Type options"""
|
1015
|
-
|
1016
|
-
ANDROID = "android"
|
1017
|
-
IOS_DEVELOPMENT = "ios-development"
|
1018
|
-
IOS_ENTERPRISE = "ios-enterprise"
|
1019
|
-
IOS_BETA = "ios-beta"
|
1020
|
-
IOS_PRODUCTION = "ios-production"
|
1021
|
-
|
1022
1000
|
async def vehicle_subscriptions(
|
1023
|
-
self, device_token: str, device_type:
|
1001
|
+
self, device_token: str, device_type: DeviceTypes | str
|
1024
1002
|
) -> dict[str, Any]:
|
1025
1003
|
"""Returns the list of vehicles for which this mobile device currently subscribes to push notifications."""
|
1026
|
-
return await self.
|
1004
|
+
return await self._request(
|
1005
|
+
Methods.GET,
|
1027
1006
|
"api/1/vehicle_subscriptions",
|
1028
1007
|
{device_token: device_token, device_type: device_type},
|
1029
1008
|
)
|
1030
1009
|
|
1031
1010
|
async def vehicle_subscriptions_set(
|
1032
|
-
self, device_token: str, device_type:
|
1011
|
+
self, device_token: str, device_type: DeviceTypes | str
|
1033
1012
|
) -> dict[str, Any]:
|
1034
1013
|
"""Allows a mobile device to specify which vehicles to receive push notifications from."""
|
1035
|
-
return await self.
|
1014
|
+
return await self._request(
|
1015
|
+
Methods.POST,
|
1036
1016
|
"api/1/vehicle_subscriptions",
|
1037
1017
|
params={device_token: device_token, device_type: device_type},
|
1038
1018
|
)
|
1039
1019
|
|
1040
1020
|
async def wake_up(self, vehicle_tag: str | int) -> dict[str, Any]:
|
1041
1021
|
"""Wakes the vehicle from sleep, which is a state to minimize idle energy consumption."""
|
1042
|
-
return await self.
|
1022
|
+
return await self._request(
|
1023
|
+
Methods.POST, f"api/1/vehicles/{vehicle_tag}/wake_up"
|
1024
|
+
)
|
1043
1025
|
|
1044
1026
|
async def warranty_details(self, vin: str | None) -> dict[str, Any]:
|
1045
1027
|
"""Returns warranty details."""
|
1046
|
-
return await self.
|
1028
|
+
return await self._request(
|
1029
|
+
Methods.GET, "api/1/dx/warranty/details", {vin: vin}
|
1030
|
+
)
|
1031
|
+
|
1032
|
+
async def fleet_telemetry_config(
|
1033
|
+
self, config: dict[str, Any]
|
1034
|
+
) -> dict[str, Any]:
|
1035
|
+
"""Configures fleet telemetry."""
|
1036
|
+
return await self._request(
|
1037
|
+
Methods.POST, "api/1/vehicles/fleet_telemetry_config", json=config
|
1038
|
+
)
|
1039
|
+
|
1040
|
+
class Specific:
|
1041
|
+
"""Class describing the Tesla Fleet API vehicle endpoints and commands for a specific vehicle."""
|
1042
|
+
|
1043
|
+
def __init__(self, parent, vin: str | None = None):
|
1044
|
+
self.parent = parent
|
1045
|
+
self.vin = vin
|
1046
|
+
|
1047
|
+
async def actuate_trunk(self, which_trunk: Trunks | str) -> dict[str, Any]:
|
1048
|
+
"""Controls the front or rear trunk."""
|
1049
|
+
return await self.parent.actuate_trunk(self.vin, which_trunk)
|
1050
|
+
|
1051
|
+
async def adjust_volume(self, volume: float) -> dict[str, Any]:
|
1052
|
+
"""Adjusts vehicle media playback volume."""
|
1053
|
+
return await self.parent.adjust_volume(self.vin, volume)
|
1054
|
+
|
1055
|
+
async def auto_conditioning_start(self) -> dict[str, Any]:
|
1056
|
+
"""Starts climate preconditioning."""
|
1057
|
+
return await self.parent.auto_conditioning_start(self.vin)
|
1058
|
+
|
1059
|
+
async def auto_conditioning_stop(self) -> dict[str, Any]:
|
1060
|
+
"""Stops climate preconditioning."""
|
1061
|
+
return await self.parent.auto_conditioning_stop(self.vin)
|
1062
|
+
|
1063
|
+
async def cancel_software_update(self) -> dict[str, Any]:
|
1064
|
+
"""Cancels the countdown to install the vehicle software update."""
|
1065
|
+
return await self.parent.cancel_software_update(self.vin)
|
1066
|
+
|
1067
|
+
async def charge_max_range(self) -> dict[str, Any]:
|
1068
|
+
"""Charges in max range mode -- we recommend limiting the use of this mode to long trips."""
|
1069
|
+
return await self.parent.charge_max_range(self.vin)
|
1070
|
+
|
1071
|
+
async def charge_port_door_close(self) -> dict[str, Any]:
|
1072
|
+
"""Closes the charge port door."""
|
1073
|
+
return await self.parent.charge_port_door_close(self.vin)
|
1074
|
+
|
1075
|
+
async def charge_port_door_open(self) -> dict[str, Any]:
|
1076
|
+
"""Opens the charge port door."""
|
1077
|
+
return await self.parent.charge_port_door_open(self.vin)
|
1078
|
+
|
1079
|
+
async def charge_standard(self) -> dict[str, Any]:
|
1080
|
+
"""Charges in Standard mode."""
|
1081
|
+
return await self.parent.charge_standard(self.vin)
|
1082
|
+
|
1083
|
+
async def charge_start(self) -> dict[str, Any]:
|
1084
|
+
"""Starts charging the vehicle."""
|
1085
|
+
return await self.parent.charge_start(self.vin)
|
1086
|
+
|
1087
|
+
async def charge_stop(self) -> dict[str, Any]:
|
1088
|
+
"""Stops charging the vehicle."""
|
1089
|
+
return await self.parent.charge_stop(self.vin)
|
1090
|
+
|
1091
|
+
async def clear_pin_to_drive_admin(self):
|
1092
|
+
"""Deactivates PIN to Drive and resets the associated PIN for vehicles running firmware versions 2023.44+. This command is only accessible to fleet managers or owners."""
|
1093
|
+
return await self.parent.clear_pin_to_drive_admin(self.vin)
|
1094
|
+
|
1095
|
+
async def door_lock(self) -> dict[str, Any]:
|
1096
|
+
"""Locks the vehicle."""
|
1097
|
+
return await self.parent.door_lock(self.vin)
|
1098
|
+
|
1099
|
+
async def door_unlock(self) -> dict[str, Any]:
|
1100
|
+
"""Unlocks the vehicle."""
|
1101
|
+
return await self.parent.door_unlock(self.vin)
|
1102
|
+
|
1103
|
+
async def erase_user_data(self) -> dict[str, Any]:
|
1104
|
+
"""Erases user's data from the user interface. Requires the vehicle to be in park."""
|
1105
|
+
return await self.parent.erase_user_data(self.vin)
|
1106
|
+
|
1107
|
+
async def flash_lights(self) -> dict[str, Any]:
|
1108
|
+
"""Briefly flashes the vehicle headlights. Requires the vehicle to be in park."""
|
1109
|
+
return await self.parent.flash_lights(self.vin)
|
1110
|
+
|
1111
|
+
async def guest_mode(self, enable: bool) -> dict[str, Any]:
|
1112
|
+
"""Restricts certain vehicle UI functionality from guest users"""
|
1113
|
+
return await self.parent.guest_mode(self.vin, enable)
|
1114
|
+
|
1115
|
+
async def honk_horn(self) -> dict[str, Any]:
|
1116
|
+
"""Honks the vehicle horn. Requires the vehicle to be in park."""
|
1117
|
+
return await self.parent.honk_horn(self.vin)
|
1118
|
+
|
1119
|
+
async def media_next_fav(self) -> dict[str, Any]:
|
1120
|
+
"""Advances media player to next favorite track."""
|
1121
|
+
return await self.parent.media_next_fav(self.vin)
|
1122
|
+
|
1123
|
+
async def media_next_track(self) -> dict[str, Any]:
|
1124
|
+
"""Advances media player to next track."""
|
1125
|
+
return await self.parent.media_next_track(self.vin)
|
1126
|
+
|
1127
|
+
async def media_prev_fav(self) -> dict[str, Any]:
|
1128
|
+
"""Advances media player to previous favorite track."""
|
1129
|
+
return await self.parent.media_prev_fav(self.vin)
|
1130
|
+
|
1131
|
+
async def media_prev_track(self) -> dict[str, Any]:
|
1132
|
+
"""Advances media player to previous track."""
|
1133
|
+
return await self.parent.media_prev_track(self.vin)
|
1134
|
+
|
1135
|
+
async def media_toggle_playback(self) -> dict[str, Any]:
|
1136
|
+
"""Toggles current play/pause state."""
|
1137
|
+
return await self.parent.media_toggle_playback(self.vin)
|
1138
|
+
|
1139
|
+
async def media_volume_down(self) -> dict[str, Any]:
|
1140
|
+
"""Turns the volume down by one."""
|
1141
|
+
return await self.parent.media_volume_down(self.vin)
|
1142
|
+
|
1143
|
+
async def navigation_gps_request(
|
1144
|
+
self, lat: float, lon: float, order: int
|
1145
|
+
) -> dict[str, Any]:
|
1146
|
+
"""Start navigation to given coordinates. Order can be used to specify order of multiple stops."""
|
1147
|
+
self.parent.navigation_gps_request(self.vin, lat, lon, order)
|
1148
|
+
|
1149
|
+
async def navigation_request(
|
1150
|
+
self, type: str, locale: str, timestamp_ms: str
|
1151
|
+
) -> dict[str, Any]:
|
1152
|
+
"""Sends a location to the in-vehicle navigation system."""
|
1153
|
+
return await self.parent.navigation_request(
|
1154
|
+
self.vin, type, locale, timestamp_ms
|
1155
|
+
)
|
1156
|
+
|
1157
|
+
async def navigation_sc_request(
|
1158
|
+
self, id: int, order: int
|
1159
|
+
) -> dict[str, Any]:
|
1160
|
+
"""Sends a location to the in-vehicle navigation system."""
|
1161
|
+
return await self.parent.navigation_sc_request(self.vin, id, order)
|
1162
|
+
|
1163
|
+
async def remote_auto_seat_climate_request(
|
1164
|
+
self, auto_seat_position: int, auto_climate_on: bool
|
1165
|
+
) -> dict[str, Any]:
|
1166
|
+
"""Sets automatic seat heating and cooling."""
|
1167
|
+
return await self.parent.remote_auto_seat_climate_request(
|
1168
|
+
self.vin, auto_seat_position, auto_climate_on
|
1169
|
+
)
|
1170
|
+
|
1171
|
+
async def remote_auto_steering_wheel_heat_climate_request(
|
1172
|
+
self, on: bool
|
1173
|
+
) -> dict[str, Any]:
|
1174
|
+
"""Sets automatic steering wheel heating on/off."""
|
1175
|
+
return (
|
1176
|
+
await self.parent.remote_auto_steering_wheel_heat_climate_request(
|
1177
|
+
self.vin, on
|
1178
|
+
)
|
1179
|
+
)
|
1180
|
+
|
1181
|
+
async def remote_boombox(self, sound: int) -> dict[str, Any]:
|
1182
|
+
"""Plays a sound through the vehicle external speaker."""
|
1183
|
+
return await self.parent.remote_boombox(self.vin, sound)
|
1184
|
+
|
1185
|
+
async def remote_seat_cooler_request(
|
1186
|
+
self, seat_position: int, seat_cooler_level: int
|
1187
|
+
) -> dict[str, Any]:
|
1188
|
+
"""Sets seat cooling."""
|
1189
|
+
return await self.parent.remote_seat_cooler_request(
|
1190
|
+
self.vin, seat_position, seat_cooler_level
|
1191
|
+
)
|
1192
|
+
|
1193
|
+
async def remote_seat_heater_request(self) -> dict[str, Any]:
|
1194
|
+
"""Sets seat heating."""
|
1195
|
+
return await self.parent.remote_seat_heater_request(self.vin)
|
1196
|
+
|
1197
|
+
async def remote_start_drive(self) -> dict[str, Any]:
|
1198
|
+
"""Starts the vehicle remotely. Requires keyless driving to be enabled."""
|
1199
|
+
return await self.parent.remote_start_drive(self.vin)
|
1200
|
+
|
1201
|
+
async def remote_steering_wheel_heat_level_request(
|
1202
|
+
self, level: int
|
1203
|
+
) -> dict[str, Any]:
|
1204
|
+
"""Sets steering wheel heat level."""
|
1205
|
+
return await self.parent.remote_steering_wheel_heat_level_request(
|
1206
|
+
self.vin, level
|
1207
|
+
)
|
1208
|
+
|
1209
|
+
async def remote_steering_wheel_heater_request(
|
1210
|
+
self, on: bool
|
1211
|
+
) -> dict[str, Any]:
|
1212
|
+
"""Sets steering wheel heating on/off. For vehicles that do not support auto steering wheel heat."""
|
1213
|
+
return await self.parent.remote_steering_wheel_heater_request(
|
1214
|
+
self.vin, on
|
1215
|
+
)
|
1216
|
+
|
1217
|
+
async def reset_pin_to_drive_pin(self) -> dict[str, Any]:
|
1218
|
+
"""Removes PIN to Drive. Requires the car to be in Pin to Drive mode and not in Valet mode. Note that this only works if PIN to Drive is not active. This command also requires the Tesla Vehicle Command Protocol - for more information, please see refer to the documentation here."""
|
1219
|
+
return await self.parent.reset_pin_to_drive_pin(self.vin)
|
1220
|
+
|
1221
|
+
async def reset_valet_pin(self) -> dict[str, Any]:
|
1222
|
+
"""Removes PIN for Valet Mode."""
|
1223
|
+
return await self.parent.reset_valet_pin(self.vin)
|
1224
|
+
|
1225
|
+
async def schedule_software_update(self, offset_sec: int) -> dict[str, Any]:
|
1226
|
+
"""Schedules a vehicle software update (over the air "OTA") to be installed in the future."""
|
1227
|
+
return await self.parent.schedule_software_update(self.vin, offset_sec)
|
1228
|
+
|
1229
|
+
async def set_bioweapon_mode(
|
1230
|
+
self, on: bool, manual_override: bool
|
1231
|
+
) -> dict[str, Any]:
|
1232
|
+
"""Turns Bioweapon Defense Mode on and off."""
|
1233
|
+
return await self.parent.set_bioweapon_mode(
|
1234
|
+
self.vin, on, manual_override
|
1235
|
+
)
|
1236
|
+
|
1237
|
+
async def set_cabin_overheat_protection(
|
1238
|
+
self, on: bool, fan_only: bool
|
1239
|
+
) -> dict[str, Any]:
|
1240
|
+
"""Sets the vehicle overheat protection."""
|
1241
|
+
return await self.parent.set_cabin_overheat_protection(
|
1242
|
+
self.vin, on, fan_only
|
1243
|
+
)
|
1244
|
+
|
1245
|
+
async def set_charge_limit(self, percent: int) -> dict[str, Any]:
|
1246
|
+
"""Sets the vehicle charge limit."""
|
1247
|
+
return await self.parent.set_charge_limit(self.vin, percent)
|
1248
|
+
|
1249
|
+
async def set_charging_amps(self, charging_amps: int) -> dict[str, Any]:
|
1250
|
+
"""Sets the vehicle charging amps."""
|
1251
|
+
return await self.parent.set_charging_amps(self.vin, charging_amps)
|
1252
|
+
|
1253
|
+
async def set_climate_keeper_mode(
|
1254
|
+
self, climate_keeper_mode: ClimateKeeperMode | int
|
1255
|
+
) -> dict[str, Any]:
|
1256
|
+
"""Enables climate keeper mode."""
|
1257
|
+
return await self.parent.set_climate_keeper_mode(
|
1258
|
+
self.vin, climate_keeper_mode
|
1259
|
+
)
|
1260
|
+
|
1261
|
+
async def set_cop_temp(
|
1262
|
+
self, cop_temp: CabinOverheatProtectionTemps | int
|
1263
|
+
) -> dict[str, Any]:
|
1264
|
+
"""Adjusts the Cabin Overheat Protection temperature (COP)."""
|
1265
|
+
return await self.parent.set_cop_temp(self.vin, cop_temp)
|
1266
|
+
|
1267
|
+
async def set_pin_to_drive(
|
1268
|
+
self, on: bool, password: str | int
|
1269
|
+
) -> dict[str, Any]:
|
1270
|
+
"""Sets a four-digit passcode for PIN to Drive. This PIN must then be entered before the vehicle can be driven."""
|
1271
|
+
return await self.parent.set_pin_to_drive(self.vin, on, password)
|
1272
|
+
|
1273
|
+
async def set_preconditioning_max(
|
1274
|
+
self, on: bool, manual_override: bool
|
1275
|
+
) -> dict[str, Any]:
|
1276
|
+
"""Sets an override for preconditioning — it should default to empty if no override is used."""
|
1277
|
+
return await self.parent.set_preconditioning_max(
|
1278
|
+
self.vin, on, manual_override
|
1279
|
+
)
|
1280
|
+
|
1281
|
+
async def set_scheduled_charging(
|
1282
|
+
self, enable: bool, time: int
|
1283
|
+
) -> dict[str, Any]:
|
1284
|
+
"""Sets a time at which charging should be completed. The time parameter is minutes after midnight (e.g: time=120 schedules charging for 2:00am vehicle local time)."""
|
1285
|
+
return await self.parent.set_scheduled_charging(self.vin, enable, time)
|
1286
|
+
|
1287
|
+
async def set_scheduled_departure(
|
1288
|
+
self, enable: bool, time: int
|
1289
|
+
) -> dict[str, Any]:
|
1290
|
+
"""Sets a time at which departure should be completed. The time parameter is minutes after midnight (e.g: time=120 schedules departure for 2:00am vehicle local time)."""
|
1291
|
+
return await self.parent.set_scheduled_departure(self.vin, enable, time)
|
1292
|
+
|
1293
|
+
async def set_sentry_mode(self, on: bool) -> dict[str, Any]:
|
1294
|
+
"""Enables and disables Sentry Mode. Sentry Mode allows customers to watch the vehicle cameras live from the mobile app, as well as record sentry events."""
|
1295
|
+
return await self.parent.set_sentry_mode(self.vin, on)
|
1296
|
+
|
1297
|
+
async def set_temps(
|
1298
|
+
self, driver_temp: int, passenger_temp: int
|
1299
|
+
) -> dict[str, Any]:
|
1300
|
+
"""Sets the driver and/or passenger-side cabin temperature (and other zones if sync is enabled)."""
|
1301
|
+
return await self.parent.set_temps(
|
1302
|
+
self.vin, driver_temp, passenger_temp
|
1303
|
+
)
|
1304
|
+
|
1305
|
+
async def set_valet_mode(
|
1306
|
+
self, on: bool, password: str | int
|
1307
|
+
) -> dict[str, Any]:
|
1308
|
+
"""Turns on Valet Mode and sets a four-digit passcode that must then be entered to disable Valet Mode."""
|
1309
|
+
return await self.parent.set_valet_mode(self.vin, on, password)
|
1310
|
+
|
1311
|
+
async def set_vehicle_name(self, vehicle_name: str) -> dict[str, Any]:
|
1312
|
+
"""Changes the name of a vehicle. This command also requires the Tesla Vehicle Command Protocol - for more information, please see refer to the documentation here."""
|
1313
|
+
return await self.parent.set_vehicle_name(self.vin, vehicle_name)
|
1314
|
+
|
1315
|
+
async def speed_limit_activate(self, pin: str | int) -> dict[str, Any]:
|
1316
|
+
"""Activates Speed Limit Mode with a four-digit PIN."""
|
1317
|
+
return await self.parent.speed_limit_activate(self.vin, pin)
|
1318
|
+
|
1319
|
+
async def speed_limit_clear_pin(self, pin: str | int) -> dict[str, Any]:
|
1320
|
+
"""Deactivates Speed Limit Mode and resets the associated PIN."""
|
1321
|
+
return await self.parent.speed_limit_clear_pin(self.vin, pin)
|
1322
|
+
|
1323
|
+
async def speed_limit_clear_pin_admin(self) -> dict[str, Any]:
|
1324
|
+
"""Deactivates Speed Limit Mode and resets the associated PIN for vehicles running firmware versions 2023.38+. This command is only accessible to fleet managers or owners."""
|
1325
|
+
return await self.parent.speed_limit_clear_pin_admin(self.vin)
|
1326
|
+
|
1327
|
+
async def speed_limit_deactivate(self, pin: str | int) -> dict[str, Any]:
|
1328
|
+
"""Deactivates Speed Limit Mode."""
|
1329
|
+
return await self.parent.speed_limit_deactivate(self.vin, pin)
|
1330
|
+
|
1331
|
+
async def speed_limit_set_limit(self, limit_mph: int) -> dict[str, Any]:
|
1332
|
+
"""Sets the maximum speed allowed when Speed Limit Mode is active."""
|
1333
|
+
return await self.parent.speed_limit_set_limit(self.vin, limit_mph)
|
1334
|
+
|
1335
|
+
async def sun_roof_control(
|
1336
|
+
self, state: str | SunRoofCommands
|
1337
|
+
) -> dict[str, Any]:
|
1338
|
+
"""Controls the panoramic sunroof on the Model S."""
|
1339
|
+
return await self.parent.sun_roof_control(self.vin, state)
|
1340
|
+
|
1341
|
+
async def take_drivenote(self, note: str) -> dict[str, Any]:
|
1342
|
+
"""Records a drive note. The note parameter is truncated to 80 characters in length."""
|
1343
|
+
return await self.parent.take_drivenote(self.vin, note)
|
1344
|
+
|
1345
|
+
async def trigger_homelink(
|
1346
|
+
self, lat: float, lon: float, token: str
|
1347
|
+
) -> dict[str, Any]:
|
1348
|
+
"""Turns on HomeLink (used to open and close garage doors)."""
|
1349
|
+
return await self.parent.trigger_homelink(self.vin, lat, lon, token)
|
1350
|
+
|
1351
|
+
async def upcoming_calendar_entries(
|
1352
|
+
self, calendar_data: str
|
1353
|
+
) -> dict[str, Any]:
|
1354
|
+
"""Upcoming calendar entries stored on the vehicle."""
|
1355
|
+
return await self.parent.upcoming_calendar_entries(
|
1356
|
+
self.vin, calendar_data
|
1357
|
+
)
|
1358
|
+
|
1359
|
+
async def window_control(
|
1360
|
+
self,
|
1361
|
+
vehicle_tag: str | int,
|
1362
|
+
lat: float,
|
1363
|
+
lon: float,
|
1364
|
+
command: str | WindowCommands,
|
1365
|
+
) -> dict[str, Any]:
|
1366
|
+
"""Control the windows of a parked vehicle. Supported commands: vent and close. When closing, specify lat and lon of user to ensure they are within range of vehicle (unless this is an M3 platform vehicle)."""
|
1367
|
+
return await self.parent.window_control(self.vin, lat, lon, command)
|
1368
|
+
|
1369
|
+
async def drivers(self) -> dict[str, Any]:
|
1370
|
+
"""Returns all allowed drivers for a vehicle. This endpoint is only available for the vehicle owner."""
|
1371
|
+
return await self.parent.drivers(self.vin)
|
1372
|
+
|
1373
|
+
async def drivers_remove(
|
1374
|
+
self, share_user_id: str | int | None = None
|
1375
|
+
) -> dict[str, Any]:
|
1376
|
+
"""Removes driver access from a vehicle. Share users can only remove their own access. Owners can remove share access or their own."""
|
1377
|
+
return await self.parent.drivers_remove(self.vin, share_user_id)
|
1378
|
+
|
1379
|
+
async def mobile_enabled(self) -> dict[str, Any]:
|
1380
|
+
"""Returns whether or not mobile access is enabled for the vehicle."""
|
1381
|
+
return await self.parent.mobile_enabled(self.vin)
|
1382
|
+
|
1383
|
+
async def nearby_charging_sites(
|
1384
|
+
self,
|
1385
|
+
vehicle_tag: str | int,
|
1386
|
+
count: int | None = None,
|
1387
|
+
radius: int | None = None,
|
1388
|
+
detail: bool | None = None,
|
1389
|
+
) -> dict[str, Any]:
|
1390
|
+
"""Returns the charging sites near the current location of the vehicle."""
|
1391
|
+
return await self.parent.nearby_charging_sites(
|
1392
|
+
self.vin, count, radius, detail
|
1393
|
+
)
|
1394
|
+
|
1395
|
+
async def options(self, vin: str) -> dict[str, Any]:
|
1396
|
+
"""Returns vehicle option details."""
|
1397
|
+
return await self.parent.options(self.vin)
|
1398
|
+
|
1399
|
+
async def recent_alerts(self) -> dict[str, Any]:
|
1400
|
+
"""List of recent alerts"""
|
1401
|
+
return await self.parent.recent_alerts(self.vin)
|
1402
|
+
|
1403
|
+
async def release_notes(
|
1404
|
+
self,
|
1405
|
+
vehicle_tag: str | int,
|
1406
|
+
staged: bool | None = None,
|
1407
|
+
language: int | None = None,
|
1408
|
+
) -> dict[str, Any]:
|
1409
|
+
"""Returns firmware release notes."""
|
1410
|
+
return await self.parent.release_notes(self.vin, staged, language)
|
1411
|
+
|
1412
|
+
async def service_data(self) -> dict[str, Any]:
|
1413
|
+
"""Returns service data."""
|
1414
|
+
return await self.parent.service_data(self.vin)
|
1415
|
+
|
1416
|
+
async def share_invites(self) -> dict[str, Any]:
|
1417
|
+
"""Returns the share invites for a vehicle."""
|
1418
|
+
return await self.parent.share_invites(self.vin)
|
1419
|
+
|
1420
|
+
async def share_invites_create(self) -> dict[str, Any]:
|
1421
|
+
"""Creates a share invite for a vehicle."""
|
1422
|
+
return await self.parent.share_invites_create(self.vin)
|
1423
|
+
|
1424
|
+
async def share_invites_redeem(self, code: str) -> dict[str, Any]:
|
1425
|
+
"""Redeems a share invite."""
|
1426
|
+
return await self.parent.share_invites_redeem(code)
|
1427
|
+
|
1428
|
+
async def share_invites_revoke(self, id: str) -> dict[str, Any]:
|
1429
|
+
"""Revokes a share invite."""
|
1430
|
+
return await self.parent.share_invites_revoke(self.vin, id)
|
1431
|
+
|
1432
|
+
async def signed_command(self, routable_message: str) -> dict[str, Any]:
|
1433
|
+
"""Signed Commands is a generic endpoint replacing legacy commands."""
|
1434
|
+
return await self.parent.signed_command(self.vin, routable_message)
|
1435
|
+
|
1436
|
+
async def subscriptions(
|
1437
|
+
self, device_token: str, device_type: str
|
1438
|
+
) -> dict[str, Any]:
|
1439
|
+
"""Returns the list of vehicles for which this mobile device currently subscribes to push notifications."""
|
1440
|
+
return await self.parent.subscriptions(
|
1441
|
+
self.vin, device_token, device_type
|
1442
|
+
)
|
1443
|
+
|
1444
|
+
async def subscriptions_set(
|
1445
|
+
self, device_token: str, device_type: str
|
1446
|
+
) -> dict[str, Any]:
|
1447
|
+
"""Allows a mobile device to specify which vehicles to receive push notifications from."""
|
1448
|
+
return await self.parent.subscriptions_set(
|
1449
|
+
self.vin, device_token, device_type
|
1450
|
+
)
|
1451
|
+
|
1452
|
+
async def vehicle(self) -> dict[str, Any]:
|
1453
|
+
"""Returns information about a vehicle."""
|
1454
|
+
return await self.parent.vehicle(self.vin)
|
1455
|
+
|
1456
|
+
async def vehicle_data(
|
1457
|
+
self,
|
1458
|
+
endpoints: VehicleDataEndpoints | str | None = None,
|
1459
|
+
) -> dict[str, Any]:
|
1460
|
+
"""Makes a live call to the vehicle. This may return cached data if the vehicle is offline. For vehicles running firmware versions 2023.38+, location_data is required to fetch vehicle location. This will result in a location sharing icon to show on the vehicle UI."""
|
1461
|
+
return await self.parent.vehicle_data(self.vin, endpoints)
|
1462
|
+
|
1463
|
+
async def vehicle_subscriptions(
|
1464
|
+
self, device_token: str, device_type: DeviceTypes | str
|
1465
|
+
) -> dict[str, Any]:
|
1466
|
+
"""Returns the list of vehicles for which this mobile device currently subscribes to push notifications."""
|
1467
|
+
return await self.parent.vehicle_subscriptions(
|
1468
|
+
self.vin, device_token, device_type
|
1469
|
+
)
|
1470
|
+
|
1471
|
+
async def vehicle_subscriptions_set(
|
1472
|
+
self, device_token: str, device_type: DeviceTypes | str
|
1473
|
+
) -> dict[str, Any]:
|
1474
|
+
"""Allows a mobile device to specify which vehicles to receive push notifications from."""
|
1475
|
+
return await self.parent.vehicle_subscriptions_set(
|
1476
|
+
self.vin, device_token, device_type
|
1477
|
+
)
|
1478
|
+
|
1479
|
+
async def wake_up(self) -> dict[str, Any]:
|
1480
|
+
"""Wakes the vehicle from sleep, which is a state to minimize idle energy consumption."""
|
1481
|
+
return await self.parent.wake_up(self.vin)
|
1482
|
+
|
1483
|
+
async def warranty_details(self) -> dict[str, Any]:
|
1484
|
+
"""Returns warranty details."""
|
1485
|
+
return await self.parent.warranty_details(self.vin)
|
1486
|
+
|
1487
|
+
async def create(self) -> [Specific]:
|
1488
|
+
"""Creates a class for each vehicle."""
|
1489
|
+
list = await self.list()
|
1490
|
+
return [self.Specific(self, x["vin"]) for x in list["response"]]
|