tesla-fleet-api 0.0.3__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.
@@ -1,12 +1,17 @@
1
1
  import aiohttp
2
2
  from .exceptions import raise_for_status, InvalidRegion, LibraryError
3
3
  from typing import Any
4
- from enum import StrEnum, IntEnum
5
- from .const import SERVERS
6
-
7
- GET = "GET"
8
- POST = "POST"
9
- DELETE = "DELETE"
4
+ from .const import (
5
+ SERVERS,
6
+ Methods,
7
+ Trunks,
8
+ ClimateKeeperMode,
9
+ CabinOverheatProtectionTemps,
10
+ VehicleDataEndpoints,
11
+ SunRoofCommands,
12
+ WindowCommands,
13
+ DeviceTypes,
14
+ )
10
15
 
11
16
 
12
17
  # Based on https://developer.tesla.com/docs/fleet-api
@@ -56,23 +61,26 @@ class TeslaFleetApi:
56
61
 
57
62
  async def _request(
58
63
  self,
59
- method: str,
64
+ method: Methods,
60
65
  path: str,
66
+ params: dict[str:Any] | None = None,
61
67
  data: dict[str:Any] | None = None,
62
68
  json: dict[str:Any] | None = None,
63
- params: dict[str:Any] | None = None,
64
69
  ):
65
70
  """Send a request to the Tesla Fleet API."""
66
71
 
67
72
  if not self.server:
68
73
  raise ValueError("Server was not set at init. Call find_server() first.")
69
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}
70
80
  if data:
71
81
  data = {k: v for k, v in data.items() if v is not None}
72
82
  if json:
73
83
  json = {k: v for k, v in json.items() if v is not None}
74
- if params:
75
- params = {k: v for k, v in params.items() if v is not None}
76
84
 
77
85
  async with self.session.request(
78
86
  method,
@@ -114,7 +122,7 @@ class TeslaFleetApi:
114
122
  ) -> dict[str, Any]:
115
123
  """Returns the paginated charging history."""
116
124
  return await self._request(
117
- GET,
125
+ Methods.GET,
118
126
  "api/1/dx/charging/history",
119
127
  {
120
128
  vin: vin,
@@ -137,7 +145,7 @@ class TeslaFleetApi:
137
145
  ) -> dict[str, Any]:
138
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."""
139
147
  return await self._request(
140
- GET,
148
+ Methods.GET,
141
149
  "api/1/dx/charging/sessions",
142
150
  {
143
151
  vin: vin,
@@ -157,13 +165,13 @@ class TeslaFleetApi:
157
165
  async def public_key(self, domain: str | None = None) -> dict[str, Any]:
158
166
  """Returns the public key associated with a domain. It can be used to ensure the registration was successful."""
159
167
  return await self._request(
160
- GET, "api/1/partner_accounts/public_key", data={domain: domain}
168
+ Methods.GET, "api/1/partner_accounts/public_key", data={domain: domain}
161
169
  )
162
170
 
163
171
  async def register(self, domain: str) -> dict[str, Any]:
164
172
  """Registers an existing account before it can be used for general API access. Each application from developer.tesla.com must complete this step."""
165
173
  return await self._request(
166
- POST, "api/1/partner_accounts", data={domain: domain}
174
+ Methods.POST, "api/1/partner_accounts", data={domain: domain}
167
175
  )
168
176
 
169
177
  class User:
@@ -174,45 +182,40 @@ class TeslaFleetApi:
174
182
 
175
183
  async def backup_key(self) -> dict[str, Any]:
176
184
  """Returns the public key associated with the user."""
177
- return await self._request(GET, "api/1/users/backup_key")
185
+ return await self._request(Methods.GET, "api/1/users/backup_key")
178
186
 
179
187
  async def feature_config(self) -> dict[str, Any]:
180
188
  """Returns any custom feature flag applied to a user."""
181
- return await self._request(GET, "api/1/users/feature_config")
189
+ return await self._request(Methods.GET, "api/1/users/feature_config")
182
190
 
183
191
  async def me(self) -> dict[str, Any]:
184
192
  """Returns a summary of a user's account."""
185
- return await self._request(GET, "api/1/users/me")
193
+ return await self._request(Methods.GET, "api/1/users/me")
186
194
 
187
195
  async def orders(self) -> dict[str, Any]:
188
196
  """Returns the active orders for a user."""
189
- return await self._request(GET, "api/1/users/orders")
197
+ return await self._request(Methods.GET, "api/1/users/orders")
190
198
 
191
199
  async def region(self) -> dict[str, Any]:
192
200
  """Returns a user's region and appropriate fleet-api base URL. Accepts no parameters, response is based on the authentication token subject."""
193
- return await self._request(GET, "api/1/users/region")
201
+ return await self._request(Methods.GET, "api/1/users/region")
194
202
 
195
203
  class Vehicle:
196
204
  """Class describing the Tesla Fleet API vehicle endpoints and commands."""
197
205
 
198
206
  def __init__(self, parent):
207
+ self._parent = parent
199
208
  self._request = parent._request
200
209
  self.use_command_protocol = parent.use_command_protocol
201
210
 
202
- class Trunk(StrEnum):
203
- """Trunk options"""
204
-
205
- FRONT: "front"
206
- REAR: "rear"
207
-
208
211
  async def actuate_trunk(
209
- self, vehicle_tag: str | int, which_trunk: Trunk | str
212
+ self, vehicle_tag: str | int, which_trunk: Trunks | str
210
213
  ) -> dict[str, Any]:
211
214
  """Controls the front or rear trunk."""
212
215
  if self.use_command_protocol:
213
216
  raise NotImplementedError("Command Protocol not implemented")
214
217
  return await self._request(
215
- POST,
218
+ Methods.POST,
216
219
  f"api/1/vehicles/{vehicle_tag}/command/actuate_trunk",
217
220
  json={which_trunk: which_trunk},
218
221
  )
@@ -226,7 +229,7 @@ class TeslaFleetApi:
226
229
  if volume < 0.0 or volume > 11.0:
227
230
  raise ValueError("Volume must a number from 0.0 to 11.0")
228
231
  return await self._request(
229
- POST,
232
+ Methods.POST,
230
233
  f"api/1/vehicles/{vehicle_tag}/command/adjust_volume",
231
234
  json={volume: volume},
232
235
  )
@@ -238,7 +241,8 @@ class TeslaFleetApi:
238
241
  if self.use_command_protocol:
239
242
  raise NotImplementedError("Command Protocol not implemented")
240
243
  return await self._request(
241
- POST, f"api/1/vehicles/{vehicle_tag}/command/auto_conditioning_start"
244
+ Methods.POST,
245
+ f"api/1/vehicles/{vehicle_tag}/command/auto_conditioning_start",
242
246
  )
243
247
 
244
248
  async def auto_conditioning_stop(
@@ -248,7 +252,8 @@ class TeslaFleetApi:
248
252
  if self.use_command_protocol:
249
253
  raise NotImplementedError("Command Protocol not implemented")
250
254
  return await self._request(
251
- POST, f"api/1/vehicles/{vehicle_tag}/command/auto_conditioning_stop"
255
+ Methods.POST,
256
+ f"api/1/vehicles/{vehicle_tag}/command/auto_conditioning_stop",
252
257
  )
253
258
 
254
259
  async def cancel_software_update(
@@ -258,7 +263,8 @@ class TeslaFleetApi:
258
263
  if self.use_command_protocol:
259
264
  raise NotImplementedError("Command Protocol not implemented")
260
265
  return await self._request(
261
- POST, f"api/1/vehicles/{vehicle_tag}/command/cancel_software_update"
266
+ Methods.POST,
267
+ f"api/1/vehicles/{vehicle_tag}/command/cancel_software_update",
262
268
  )
263
269
 
264
270
  async def charge_max_range(self, vehicle_tag: str | int) -> dict[str, Any]:
@@ -266,7 +272,7 @@ class TeslaFleetApi:
266
272
  if self.use_command_protocol:
267
273
  raise NotImplementedError("Command Protocol not implemented")
268
274
  return await self._request(
269
- POST, f"api/1/vehicles/{vehicle_tag}/command/charge_max_range"
275
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/charge_max_range"
270
276
  )
271
277
 
272
278
  async def charge_port_door_close(
@@ -276,7 +282,8 @@ class TeslaFleetApi:
276
282
  if self.use_command_protocol:
277
283
  raise NotImplementedError("Command Protocol not implemented")
278
284
  return await self._request(
279
- POST, f"api/1/vehicles/{vehicle_tag}/command/charge_port_door_close"
285
+ Methods.POST,
286
+ f"api/1/vehicles/{vehicle_tag}/command/charge_port_door_close",
280
287
  )
281
288
 
282
289
  async def charge_port_door_open(self, vehicle_tag: str | int) -> dict[str, Any]:
@@ -284,7 +291,8 @@ class TeslaFleetApi:
284
291
  if self.use_command_protocol:
285
292
  raise NotImplementedError("Command Protocol not implemented")
286
293
  return await self._request(
287
- POST, f"api/1/vehicles/{vehicle_tag}/command/charge_port_door_open"
294
+ Methods.POST,
295
+ f"api/1/vehicles/{vehicle_tag}/command/charge_port_door_open",
288
296
  )
289
297
 
290
298
  async def charge_standard(self, vehicle_tag: str | int) -> dict[str, Any]:
@@ -292,7 +300,7 @@ class TeslaFleetApi:
292
300
  if self.use_command_protocol:
293
301
  raise NotImplementedError("Command Protocol not implemented")
294
302
  return await self._request(
295
- POST, f"api/1/vehicles/{vehicle_tag}/command/charge_standard"
303
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/charge_standard"
296
304
  )
297
305
 
298
306
  async def charge_start(self, vehicle_tag: str | int) -> dict[str, Any]:
@@ -300,7 +308,7 @@ class TeslaFleetApi:
300
308
  if self.use_command_protocol:
301
309
  raise NotImplementedError("Command Protocol not implemented")
302
310
  return await self._request(
303
- POST, f"api/1/vehicles/{vehicle_tag}/command/charge_start"
311
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/charge_start"
304
312
  )
305
313
 
306
314
  async def charge_stop(self, vehicle_tag: str | int) -> dict[str, Any]:
@@ -308,13 +316,14 @@ class TeslaFleetApi:
308
316
  if self.use_command_protocol:
309
317
  raise NotImplementedError("Command Protocol not implemented")
310
318
  return await self._request(
311
- POST, f"api/1/vehicles/{vehicle_tag}/command/charge_stop"
319
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/charge_stop"
312
320
  )
313
321
 
314
322
  async def clear_pin_to_drive_admin(self, vehicle_tag: str | int):
315
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."""
316
324
  return await self._request(
317
- POST, f"api/1/vehicles/{vehicle_tag}/command/clear_pin_to_drive_admin"
325
+ Methods.POST,
326
+ f"api/1/vehicles/{vehicle_tag}/command/clear_pin_to_drive_admin",
318
327
  )
319
328
 
320
329
  async def door_lock(self, vehicle_tag: str | int) -> dict[str, Any]:
@@ -322,7 +331,7 @@ class TeslaFleetApi:
322
331
  if self.use_command_protocol:
323
332
  raise NotImplementedError("Command Protocol not implemented")
324
333
  return await self._request(
325
- POST, f"api/1/vehicles/{vehicle_tag}/command/door_lock"
334
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/door_lock"
326
335
  )
327
336
 
328
337
  async def door_unlock(self, vehicle_tag: str | int) -> dict[str, Any]:
@@ -330,13 +339,13 @@ class TeslaFleetApi:
330
339
  if self.use_command_protocol:
331
340
  raise NotImplementedError("Command Protocol not implemented")
332
341
  return await self._request(
333
- POST, f"api/1/vehicles/{vehicle_tag}/command/door_unlock"
342
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/door_unlock"
334
343
  )
335
344
 
336
345
  async def erase_user_data(self, vehicle_tag: str | int) -> dict[str, Any]:
337
346
  """Erases user's data from the user interface. Requires the vehicle to be in park."""
338
347
  return await self._request(
339
- POST, f"api/1/vehicles/{vehicle_tag}/command/erase_user_data"
348
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/erase_user_data"
340
349
  )
341
350
 
342
351
  async def flash_lights(self, vehicle_tag: str | int) -> dict[str, Any]:
@@ -344,7 +353,7 @@ class TeslaFleetApi:
344
353
  if self.use_command_protocol:
345
354
  raise NotImplementedError("Command Protocol not implemented")
346
355
  return await self._request(
347
- POST, f"api/1/vehicles/{vehicle_tag}/command/flash_lights"
356
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/flash_lights"
348
357
  )
349
358
 
350
359
  async def guest_mode(
@@ -354,7 +363,7 @@ class TeslaFleetApi:
354
363
  if self.use_command_protocol:
355
364
  raise NotImplementedError("Command Protocol not implemented")
356
365
  return await self._request(
357
- POST,
366
+ Methods.POST,
358
367
  f"api/1/vehicles/{vehicle_tag}/command/guest_mode",
359
368
  json={enable: enable},
360
369
  )
@@ -364,43 +373,44 @@ class TeslaFleetApi:
364
373
  if self.use_command_protocol:
365
374
  raise NotImplementedError("Command Protocol not implemented")
366
375
  return await self._request(
367
- POST, f"api/1/vehicles/{vehicle_tag}/command/honk_horn"
376
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/honk_horn"
368
377
  )
369
378
 
370
379
  async def media_next_fav(self, vehicle_tag: str | int) -> dict[str, Any]:
371
380
  """Advances media player to next favorite track."""
372
381
  return await self._request(
373
- POST, f"api/1/vehicles/{vehicle_tag}/command/media_next_fav"
382
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/media_next_fav"
374
383
  )
375
384
 
376
385
  async def media_next_track(self, vehicle_tag: str | int) -> dict[str, Any]:
377
386
  """Advances media player to next track."""
378
387
  return await self._request(
379
- POST, f"api/1/vehicles/{vehicle_tag}/command/media_next_track"
388
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/media_next_track"
380
389
  )
381
390
 
382
391
  async def media_prev_fav(self, vehicle_tag: str | int) -> dict[str, Any]:
383
392
  """Advances media player to previous favorite track."""
384
393
  return await self._request(
385
- POST, f"api/1/vehicles/{vehicle_tag}/command/media_prev_fav"
394
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/media_prev_fav"
386
395
  )
387
396
 
388
397
  async def media_prev_track(self, vehicle_tag: str | int) -> dict[str, Any]:
389
398
  """Advances media player to previous track."""
390
399
  return await self._request(
391
- POST, f"api/1/vehicles/{vehicle_tag}/command/media_prev_track"
400
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/media_prev_track"
392
401
  )
393
402
 
394
403
  async def media_toggle_playback(self, vehicle_tag: str | int) -> dict[str, Any]:
395
404
  """Toggles current play/pause state."""
396
405
  return await self._request(
397
- POST, f"api/1/vehicles/{vehicle_tag}/command/media_toggle_playback"
406
+ Methods.POST,
407
+ f"api/1/vehicles/{vehicle_tag}/command/media_toggle_playback",
398
408
  )
399
409
 
400
410
  async def media_volume_down(self, vehicle_tag: str | int) -> dict[str, Any]:
401
411
  """Turns the volume down by one."""
402
412
  return await self._request(
403
- POST, f"api/1/vehicles/{vehicle_tag}/command/media_volume_down"
413
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/media_volume_down"
404
414
  )
405
415
 
406
416
  async def navigation_gps_request(
@@ -410,7 +420,7 @@ class TeslaFleetApi:
410
420
  if self.use_command_protocol:
411
421
  raise NotImplementedError("Command Protocol not implemented")
412
422
  return await self._request(
413
- POST,
423
+ Methods.POST,
414
424
  f"api/1/vehicles/{vehicle_tag}/command/navigation_gps_request",
415
425
  json={lat: lat, lon: lon, order: order},
416
426
  )
@@ -420,7 +430,7 @@ class TeslaFleetApi:
420
430
  ) -> dict[str, Any]:
421
431
  """Sends a location to the in-vehicle navigation system."""
422
432
  return await self._request(
423
- POST,
433
+ Methods.POST,
424
434
  f"api/1/vehicles/{vehicle_tag}/command/navigation_request",
425
435
  json={type: type, locale: locale, timestamp_ms: timestamp_ms},
426
436
  )
@@ -430,7 +440,7 @@ class TeslaFleetApi:
430
440
  ) -> dict[str, Any]:
431
441
  """Sends a location to the in-vehicle navigation system."""
432
442
  return await self._request(
433
- POST,
443
+ Methods.POST,
434
444
  f"api/1/vehicles/{vehicle_tag}/command/navigation_sc_request",
435
445
  json={type: type, id: id, order: order},
436
446
  )
@@ -442,7 +452,7 @@ class TeslaFleetApi:
442
452
  if self.use_command_protocol:
443
453
  raise NotImplementedError("Command Protocol not implemented")
444
454
  return await self._request(
445
- POST,
455
+ Methods.POST,
446
456
  f"api/1/vehicles/{vehicle_tag}/command/remote_auto_seat_climate_request",
447
457
  json={
448
458
  auto_seat_position: auto_seat_position,
@@ -455,7 +465,7 @@ class TeslaFleetApi:
455
465
  ) -> dict[str, Any]:
456
466
  """Sets automatic steering wheel heating on/off."""
457
467
  return await self._request(
458
- POST,
468
+ Methods.POST,
459
469
  f"api/1/vehicles/{vehicle_tag}/command/remote_auto_steering_wheel_heat_climate_request",
460
470
  json={on: on},
461
471
  )
@@ -465,7 +475,7 @@ class TeslaFleetApi:
465
475
  ) -> dict[str, Any]:
466
476
  """Plays a sound through the vehicle external speaker."""
467
477
  return await self._request(
468
- POST,
478
+ Methods.POST,
469
479
  f"api/1/vehicles/{vehicle_tag}/command/remote_boombox",
470
480
  json={sound: sound},
471
481
  )
@@ -477,7 +487,7 @@ class TeslaFleetApi:
477
487
  if self.use_command_protocol:
478
488
  raise NotImplementedError("Command Protocol not implemented")
479
489
  return await self._request(
480
- POST,
490
+ Methods.POST,
481
491
  f"api/1/vehicles/{vehicle_tag}/command/remote_seat_cooler_request",
482
492
  json={
483
493
  seat_position: seat_position,
@@ -492,7 +502,7 @@ class TeslaFleetApi:
492
502
  if self.use_command_protocol:
493
503
  raise NotImplementedError("Command Protocol not implemented")
494
504
  return await self._request(
495
- POST,
505
+ Methods.POST,
496
506
  f"api/1/vehicles/{vehicle_tag}/command/remote_seat_heater_request",
497
507
  )
498
508
 
@@ -501,7 +511,7 @@ class TeslaFleetApi:
501
511
  if self.use_command_protocol:
502
512
  raise NotImplementedError("Command Protocol not implemented")
503
513
  return await self._request(
504
- POST, f"api/1/vehicles/{vehicle_tag}/command/remote_start_drive"
514
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/remote_start_drive"
505
515
  )
506
516
 
507
517
  async def remote_steering_wheel_heat_level_request(
@@ -511,7 +521,7 @@ class TeslaFleetApi:
511
521
  if self.use_command_protocol:
512
522
  raise NotImplementedError("Command Protocol not implemented")
513
523
  return await self._request(
514
- POST,
524
+ Methods.POST,
515
525
  f"api/1/vehicles/{vehicle_tag}/command/remote_steering_wheel_heat_level_request",
516
526
  json={level: level},
517
527
  )
@@ -523,7 +533,7 @@ class TeslaFleetApi:
523
533
  if self.use_command_protocol:
524
534
  raise NotImplementedError("Command Protocol not implemented")
525
535
  return await self._request(
526
- POST,
536
+ Methods.POST,
527
537
  f"api/1/vehicles/{vehicle_tag}/command/remote_steering_wheel_heater_request",
528
538
  json={on: on},
529
539
  )
@@ -535,7 +545,8 @@ class TeslaFleetApi:
535
545
  if self.use_command_protocol:
536
546
  raise NotImplementedError("Command Protocol not implemented")
537
547
  return await self._request(
538
- POST, f"api/1/vehicles/{vehicle_tag}/command/reset_pin_to_drive_pin"
548
+ Methods.POST,
549
+ f"api/1/vehicles/{vehicle_tag}/command/reset_pin_to_drive_pin",
539
550
  )
540
551
 
541
552
  async def reset_valet_pin(self, vehicle_tag: str | int) -> dict[str, Any]:
@@ -543,7 +554,7 @@ class TeslaFleetApi:
543
554
  if self.use_command_protocol:
544
555
  raise NotImplementedError("Command Protocol not implemented")
545
556
  return await self._request(
546
- POST, f"api/1/vehicles/{vehicle_tag}/command/reset_valet_pin"
557
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/command/reset_valet_pin"
547
558
  )
548
559
 
549
560
  async def schedule_software_update(
@@ -553,7 +564,7 @@ class TeslaFleetApi:
553
564
  if self.use_command_protocol:
554
565
  raise NotImplementedError("Command Protocol not implemented")
555
566
  return await self._request(
556
- POST,
567
+ Methods.POST,
557
568
  f"api/1/vehicles/{vehicle_tag}/command/schedule_software_update",
558
569
  json={offset_sec: offset_sec},
559
570
  )
@@ -565,7 +576,7 @@ class TeslaFleetApi:
565
576
  if self.use_command_protocol:
566
577
  raise NotImplementedError("Command Protocol not implemented")
567
578
  return await self._request(
568
- POST,
579
+ Methods.POST,
569
580
  f"api/1/vehicles/{vehicle_tag}/command/set_bioweapon_mode",
570
581
  json={on: on, manual_override: manual_override},
571
582
  )
@@ -577,7 +588,7 @@ class TeslaFleetApi:
577
588
  if self.use_command_protocol:
578
589
  raise NotImplementedError("Command Protocol not implemented")
579
590
  return await self._request(
580
- POST,
591
+ Methods.POST,
581
592
  f"api/1/vehicles/{vehicle_tag}/command/set_cabin_overheat_protection",
582
593
  json={on: on, fan_only: fan_only},
583
594
  )
@@ -589,7 +600,7 @@ class TeslaFleetApi:
589
600
  if self.use_command_protocol:
590
601
  raise NotImplementedError("Command Protocol not implemented")
591
602
  return await self._request(
592
- POST,
603
+ Methods.POST,
593
604
  f"api/1/vehicles/{vehicle_tag}/command/set_charge_limit",
594
605
  json={percent: percent},
595
606
  )
@@ -601,19 +612,11 @@ class TeslaFleetApi:
601
612
  if self.use_command_protocol:
602
613
  raise NotImplementedError("Command Protocol not implemented")
603
614
  return await self._request(
604
- POST,
615
+ Methods.POST,
605
616
  f"api/1/vehicles/{vehicle_tag}/command/set_charging_amps",
606
617
  json={charging_amps: charging_amps},
607
618
  )
608
619
 
609
- class ClimateKeeperMode(IntEnum):
610
- """Climate Keeper Mode options"""
611
-
612
- OFF = 0
613
- KEEP_MODE = 1
614
- DOG_MODE = 2
615
- CAMP_MODE = 3
616
-
617
620
  async def set_climate_keeper_mode(
618
621
  self, vehicle_tag: str | int, climate_keeper_mode: ClimateKeeperMode | int
619
622
  ) -> dict[str, Any]:
@@ -621,26 +624,19 @@ class TeslaFleetApi:
621
624
  if self.use_command_protocol:
622
625
  raise NotImplementedError("Command Protocol not implemented")
623
626
  return await self._request(
624
- POST,
627
+ Methods.POST,
625
628
  f"api/1/vehicles/{vehicle_tag}/command/set_climate_keeper_mode",
626
629
  json={climate_keeper_mode: climate_keeper_mode},
627
630
  )
628
631
 
629
- class CopTemp(IntEnum):
630
- """COP Temp options"""
631
-
632
- LOW = 0 # 30C 90F
633
- MEDIUM = 1 # 35C 95F
634
- HIGH = 2 # 40C 100F
635
-
636
632
  async def set_cop_temp(
637
- self, vehicle_tag: str | int, cop_temp: CopTemp | int
633
+ self, vehicle_tag: str | int, cop_temp: CabinOverheatProtectionTemps | int
638
634
  ) -> dict[str, Any]:
639
635
  """Adjusts the Cabin Overheat Protection temperature (COP)."""
640
636
  if self.use_command_protocol:
641
637
  raise NotImplementedError("Command Protocol not implemented")
642
638
  return await self._request(
643
- POST,
639
+ Methods.POST,
644
640
  f"api/1/vehicles/{vehicle_tag}/command/set_cop_temp",
645
641
  json={cop_temp: cop_temp},
646
642
  )
@@ -652,7 +648,7 @@ class TeslaFleetApi:
652
648
  if self.use_command_protocol:
653
649
  raise NotImplementedError("Command Protocol not implemented")
654
650
  return await self._request(
655
- POST,
651
+ Methods.POST,
656
652
  f"api/1/vehicles/{vehicle_tag}/command/set_pin_to_drive",
657
653
  json={on: on, password: str(password)},
658
654
  )
@@ -664,7 +660,7 @@ class TeslaFleetApi:
664
660
  if self.use_command_protocol:
665
661
  raise NotImplementedError("Command Protocol not implemented")
666
662
  return await self._request(
667
- POST,
663
+ Methods.POST,
668
664
  f"api/1/vehicles/{vehicle_tag}/command/set_preconditioning_max",
669
665
  json={on: on, manual_override: manual_override},
670
666
  )
@@ -676,7 +672,7 @@ class TeslaFleetApi:
676
672
  if self.use_command_protocol:
677
673
  raise NotImplementedError("Command Protocol not implemented")
678
674
  return await self._request(
679
- POST,
675
+ Methods.POST,
680
676
  f"api/1/vehicles/{vehicle_tag}/command/set_scheduled_charging",
681
677
  json={enable: enable, time: time},
682
678
  )
@@ -688,7 +684,7 @@ class TeslaFleetApi:
688
684
  if self.use_command_protocol:
689
685
  raise NotImplementedError("Command Protocol not implemented")
690
686
  return await self._request(
691
- POST,
687
+ Methods.POST,
692
688
  f"api/1/vehicles/{vehicle_tag}/command/set_scheduled_departure",
693
689
  json={enable: enable, time: time},
694
690
  )
@@ -700,7 +696,7 @@ class TeslaFleetApi:
700
696
  if self.use_command_protocol:
701
697
  raise NotImplementedError("Command Protocol not implemented")
702
698
  return await self._request(
703
- POST,
699
+ Methods.POST,
704
700
  f"api/1/vehicles/{vehicle_tag}/command/set_sentry_mode",
705
701
  json={on: on},
706
702
  )
@@ -712,7 +708,7 @@ class TeslaFleetApi:
712
708
  if self.use_command_protocol:
713
709
  raise NotImplementedError("Command Protocol not implemented")
714
710
  return await self._request(
715
- POST,
711
+ Methods.POST,
716
712
  f"api/1/vehicles/{vehicle_tag}/command/set_temps",
717
713
  json={driver_temp: driver_temp, passenger_temp: passenger_temp},
718
714
  )
@@ -724,7 +720,7 @@ class TeslaFleetApi:
724
720
  if self.use_command_protocol:
725
721
  raise NotImplementedError("Command Protocol not implemented")
726
722
  return await self._request(
727
- POST,
723
+ Methods.POST,
728
724
  f"api/1/vehicles/{vehicle_tag}/command/set_valet_mode",
729
725
  json={on: on, password: str(password)},
730
726
  )
@@ -736,7 +732,7 @@ class TeslaFleetApi:
736
732
  if self.use_command_protocol:
737
733
  raise NotImplementedError("Command Protocol not implemented")
738
734
  return await self._request(
739
- POST,
735
+ Methods.POST,
740
736
  f"api/1/vehicles/{vehicle_tag}/command/set_vehicle_name",
741
737
  json={vehicle_name: vehicle_name},
742
738
  )
@@ -748,7 +744,7 @@ class TeslaFleetApi:
748
744
  if self.use_command_protocol:
749
745
  raise NotImplementedError("Command Protocol not implemented")
750
746
  return await self._request(
751
- POST,
747
+ Methods.POST,
752
748
  f"api/1/vehicles/{vehicle_tag}/command/speed_limit_activate",
753
749
  json={pin: str(pin)},
754
750
  )
@@ -760,7 +756,7 @@ class TeslaFleetApi:
760
756
  if self.use_command_protocol:
761
757
  raise NotImplementedError("Command Protocol not implemented")
762
758
  return await self._request(
763
- POST,
759
+ Methods.POST,
764
760
  f"api/1/vehicles/{vehicle_tag}/command/speed_limit_clear_pin",
765
761
  json={pin: str(pin)},
766
762
  )
@@ -770,7 +766,7 @@ class TeslaFleetApi:
770
766
  ) -> dict[str, Any]:
771
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."""
772
768
  return await self._request(
773
- POST,
769
+ Methods.POST,
774
770
  f"api/1/vehicles/{vehicle_tag}/command/speed_limit_clear_pin_admin",
775
771
  )
776
772
 
@@ -781,7 +777,7 @@ class TeslaFleetApi:
781
777
  if self.use_command_protocol:
782
778
  raise NotImplementedError("Command Protocol not implemented")
783
779
  return await self._request(
784
- POST,
780
+ Methods.POST,
785
781
  f"api/1/vehicles/{vehicle_tag}/command/speed_limit_deactivate",
786
782
  json={pin: str(pin)},
787
783
  )
@@ -793,24 +789,17 @@ class TeslaFleetApi:
793
789
  if self.use_command_protocol:
794
790
  raise NotImplementedError("Command Protocol not implemented")
795
791
  return await self._request(
796
- POST,
792
+ Methods.POST,
797
793
  f"api/1/vehicles/{vehicle_tag}/command/speed_limit_set_limit",
798
794
  json={limit_mph: limit_mph},
799
795
  )
800
796
 
801
- class SunRoof(StrEnum):
802
- """Sunroof options"""
803
-
804
- STOP = "stop"
805
- CLOSE = "close"
806
- VENT = "vent"
807
-
808
797
  async def sun_roof_control(
809
- self, vehicle_tag: str | int, state: str | SunRoof
798
+ self, vehicle_tag: str | int, state: str | SunRoofCommands
810
799
  ) -> dict[str, Any]:
811
800
  """Controls the panoramic sunroof on the Model S."""
812
801
  return await self._request(
813
- POST,
802
+ Methods.POST,
814
803
  f"api/1/vehicles/{vehicle_tag}/command/sun_roof_control",
815
804
  {state: state},
816
805
  )
@@ -820,7 +809,7 @@ class TeslaFleetApi:
820
809
  ) -> dict[str, Any]:
821
810
  """Records a drive note. The note parameter is truncated to 80 characters in length."""
822
811
  return await self._request(
823
- POST,
812
+ Methods.POST,
824
813
  f"api/1/vehicles/{vehicle_tag}/command/take_drivenote",
825
814
  {note: note},
826
815
  )
@@ -832,7 +821,7 @@ class TeslaFleetApi:
832
821
  if self.use_command_protocol:
833
822
  raise NotImplementedError("Command Protocol not implemented")
834
823
  return await self._request(
835
- POST,
824
+ Methods.POST,
836
825
  f"api/1/vehicles/{vehicle_tag}/command/trigger_homelink",
837
826
  {lat: lat, lon: lon, token: token},
838
827
  )
@@ -842,41 +831,37 @@ class TeslaFleetApi:
842
831
  ) -> dict[str, Any]:
843
832
  """Upcoming calendar entries stored on the vehicle."""
844
833
  return await self._request(
845
- POST,
834
+ Methods.POST,
846
835
  f"api/1/vehicles/{vehicle_tag}/command/upcoming_calendar_entries",
847
836
  {calendar_data: calendar_data},
848
837
  )
849
838
 
850
- class WindowControl(StrEnum):
851
- """Window Control options"""
852
-
853
- VENT = "vent"
854
- CLOSE = "close"
855
-
856
839
  async def window_control(
857
840
  self,
858
841
  vehicle_tag: str | int,
859
842
  lat: float,
860
843
  lon: float,
861
- command: str | WindowControl,
844
+ command: str | WindowCommands,
862
845
  ) -> dict[str, Any]:
863
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)."""
864
847
  return await self._request(
865
- POST,
848
+ Methods.POST,
866
849
  f"api/1/vehicles/{vehicle_tag}/command/window_control",
867
850
  {lat: lat, lon: lon, command: command},
868
851
  )
869
852
 
870
853
  async def drivers(self, vehicle_tag: str | int) -> dict[str, Any]:
871
854
  """Returns all allowed drivers for a vehicle. This endpoint is only available for the vehicle owner."""
872
- return await self._request(GET, f"api/1/vehicles/{vehicle_tag}/drivers")
855
+ return await self._request(
856
+ Methods.GET, f"api/1/vehicles/{vehicle_tag}/drivers"
857
+ )
873
858
 
874
859
  async def drivers_remove(
875
860
  self, vehicle_tag: str | int, share_user_id: str | int | None = None
876
861
  ) -> dict[str, Any]:
877
862
  """Removes driver access from a vehicle. Share users can only remove their own access. Owners can remove share access or their own."""
878
863
  return await self._request(
879
- DELETE,
864
+ Methods.DELETE,
880
865
  f"api/1/vehicles/{vehicle_tag}/drivers",
881
866
  {share_user_id: share_user_id},
882
867
  )
@@ -886,13 +871,13 @@ class TeslaFleetApi:
886
871
  ) -> dict[str, Any]:
887
872
  """Returns vehicles belonging to the account."""
888
873
  return await self._request(
889
- GET, "api/1/vehicles", {page: page, per_page: per_page}
874
+ Methods.GET, "api/1/vehicles", {page: page, per_page: per_page}
890
875
  )
891
876
 
892
877
  async def mobile_enabled(self, vehicle_tag: str | int) -> dict[str, Any]:
893
878
  """Returns whether or not mobile access is enabled for the vehicle."""
894
879
  return await self._request(
895
- GET, f"api/1/vehicles/{vehicle_tag}/mobile_enabled"
880
+ Methods.GET, f"api/1/vehicles/{vehicle_tag}/mobile_enabled"
896
881
  )
897
882
 
898
883
  async def nearby_charging_sites(
@@ -904,19 +889,21 @@ class TeslaFleetApi:
904
889
  ) -> dict[str, Any]:
905
890
  """Returns the charging sites near the current location of the vehicle."""
906
891
  return await self._request(
907
- GET,
892
+ Methods.GET,
908
893
  f"api/1/vehicles/{vehicle_tag}/nearby_charging_sites",
909
894
  {count: count, radius: radius, detail: detail},
910
895
  )
911
896
 
912
897
  async def options(self, vin: str) -> dict[str, Any]:
913
898
  """Returns vehicle option details."""
914
- return await self._request(GET, "api/1/dx/vehicles/options", {vin: vin})
899
+ return await self._request(
900
+ Methods.GET, "api/1/dx/vehicles/options", {vin: vin}
901
+ )
915
902
 
916
903
  async def recent_alerts(self, vehicle_tag: str | int) -> dict[str, Any]:
917
904
  """List of recent alerts"""
918
905
  return await self._request(
919
- GET, f"api/1/vehicles/{vehicle_tag}/recent_alerts"
906
+ Methods.GET, f"api/1/vehicles/{vehicle_tag}/recent_alerts"
920
907
  )
921
908
 
922
909
  async def release_notes(
@@ -927,7 +914,7 @@ class TeslaFleetApi:
927
914
  ) -> dict[str, Any]:
928
915
  """Returns firmware release notes."""
929
916
  return await self._request(
930
- GET,
917
+ Methods.GET,
931
918
  f"api/1/vehicles/{vehicle_tag}/release_notes",
932
919
  {staged: staged, language: language},
933
920
  )
@@ -935,29 +922,33 @@ class TeslaFleetApi:
935
922
  async def service_data(self, vehicle_tag: str | int) -> dict[str, Any]:
936
923
  """Returns service data."""
937
924
  return await self._request(
938
- GET, f"api/1/vehicles/{vehicle_tag}/service_data"
925
+ Methods.GET, f"api/1/vehicles/{vehicle_tag}/service_data"
939
926
  )
940
927
 
941
928
  async def share_invites(self, vehicle_tag: str | int) -> dict[str, Any]:
942
929
  """Returns the share invites for a vehicle."""
943
- return await self._request(GET, f"api/1/vehicles/{vehicle_tag}/invitations")
930
+ return await self._request(
931
+ Methods.GET, f"api/1/vehicles/{vehicle_tag}/invitations"
932
+ )
944
933
 
945
934
  async def share_invites_create(self, vehicle_tag: str | int) -> dict[str, Any]:
946
935
  """Creates a share invite for a vehicle."""
947
936
  return await self._request(
948
- POST, f"api/1/vehicles/{vehicle_tag}/invitations"
937
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/invitations"
949
938
  )
950
939
 
951
940
  async def share_invites_redeem(self, code: str) -> dict[str, Any]:
952
941
  """Redeems a share invite."""
953
- return await self._request(POST, "api/1/invitations/redeem", {code: code})
942
+ return await self._request(
943
+ Methods.POST, "api/1/invitations/redeem", {code: code}
944
+ )
954
945
 
955
946
  async def share_invites_revoke(
956
947
  self, vehicle_tag: str | int, id: str
957
948
  ) -> dict[str, Any]:
958
949
  """Revokes a share invite."""
959
950
  return await self._request(
960
- POST, f"api/1/vehicles/{vehicle_tag}/invitations/{id}/revoke"
951
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/invitations/{id}/revoke"
961
952
  )
962
953
 
963
954
  async def signed_command(
@@ -965,7 +956,7 @@ class TeslaFleetApi:
965
956
  ) -> dict[str, Any]:
966
957
  """Signed Commands is a generic endpoint replacing legacy commands."""
967
958
  return await self._request(
968
- POST,
959
+ Methods.POST,
969
960
  f"api/1/vehicles/{vehicle_tag}/signed_command",
970
961
  {routable_message: routable_message},
971
962
  )
@@ -975,7 +966,7 @@ class TeslaFleetApi:
975
966
  ) -> dict[str, Any]:
976
967
  """Returns the list of vehicles for which this mobile device currently subscribes to push notifications."""
977
968
  return await self._request(
978
- GET,
969
+ Methods.GET,
979
970
  "api/1/subscriptions",
980
971
  query={device_token: device_token, device_type: device_type},
981
972
  )
@@ -985,81 +976,515 @@ class TeslaFleetApi:
985
976
  ) -> dict[str, Any]:
986
977
  """Allows a mobile device to specify which vehicles to receive push notifications from."""
987
978
  return await self._request(
988
- POST,
979
+ Methods.POST,
989
980
  "api/1/subscriptions",
990
981
  query={device_token: device_token, device_type: device_type},
991
982
  )
992
983
 
993
984
  async def vehicle(self, vehicle_tag: str | int) -> dict[str, Any]:
994
985
  """Returns information about a vehicle."""
995
- return await self._request(GET, f"api/1/vehicles/{vehicle_tag}")
996
-
997
- class Endpoints(StrEnum):
998
- """Endpoints options"""
999
-
1000
- CHARGE_STATE = "charge_state"
1001
- CLIMATE_STATE = "climate_state"
1002
- CLOSURES_STATE = "closures_state"
1003
- DRIVE_STATE = "drive_state"
1004
- GUI_SETTINGS = "gui_settings"
1005
- LOCATION_DATA = "location_data"
1006
- VEHICLE_CONFIG = "vehicle_config"
1007
- VEHICLE_STATE = "vehicle_state"
1008
- VEHICLE_DATA_COMBO = "vehicle_data_combo"
986
+ return await self._request(Methods.GET, f"api/1/vehicles/{vehicle_tag}")
1009
987
 
1010
988
  async def vehicle_data(
1011
989
  self,
1012
990
  vehicle_tag: str | int,
1013
- endpoints: Endpoints | str | None = None,
991
+ endpoints: VehicleDataEndpoints | str | None = None,
1014
992
  ) -> dict[str, Any]:
1015
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."""
1016
994
  return await self._request(
1017
- GET,
995
+ Methods.GET,
1018
996
  f"api/1/vehicles/{vehicle_tag}/vehicle_data",
1019
997
  {endpoints: endpoints},
1020
998
  )
1021
999
 
1022
- class DeviceType(StrEnum):
1023
- """Device Type options"""
1024
-
1025
- ANDROID = "android"
1026
- IOS_DEVELOPMENT = "ios-development"
1027
- IOS_ENTERPRISE = "ios-enterprise"
1028
- IOS_BETA = "ios-beta"
1029
- IOS_PRODUCTION = "ios-production"
1030
-
1031
1000
  async def vehicle_subscriptions(
1032
- self, device_token: str, device_type: DeviceType | str
1001
+ self, device_token: str, device_type: DeviceTypes | str
1033
1002
  ) -> dict[str, Any]:
1034
1003
  """Returns the list of vehicles for which this mobile device currently subscribes to push notifications."""
1035
1004
  return await self._request(
1036
- GET,
1005
+ Methods.GET,
1037
1006
  "api/1/vehicle_subscriptions",
1038
1007
  {device_token: device_token, device_type: device_type},
1039
1008
  )
1040
1009
 
1041
1010
  async def vehicle_subscriptions_set(
1042
- self, device_token: str, device_type: DeviceType | str
1011
+ self, device_token: str, device_type: DeviceTypes | str
1043
1012
  ) -> dict[str, Any]:
1044
1013
  """Allows a mobile device to specify which vehicles to receive push notifications from."""
1045
1014
  return await self._request(
1046
- POST,
1015
+ Methods.POST,
1047
1016
  "api/1/vehicle_subscriptions",
1048
1017
  params={device_token: device_token, device_type: device_type},
1049
1018
  )
1050
1019
 
1051
1020
  async def wake_up(self, vehicle_tag: str | int) -> dict[str, Any]:
1052
1021
  """Wakes the vehicle from sleep, which is a state to minimize idle energy consumption."""
1053
- return await self._request(POST, f"api/1/vehicles/{vehicle_tag}/wake_up")
1022
+ return await self._request(
1023
+ Methods.POST, f"api/1/vehicles/{vehicle_tag}/wake_up"
1024
+ )
1054
1025
 
1055
1026
  async def warranty_details(self, vin: str | None) -> dict[str, Any]:
1056
1027
  """Returns warranty details."""
1057
- return await self._request(GET, "api/1/dx/warranty/details", {vin: vin})
1028
+ return await self._request(
1029
+ Methods.GET, "api/1/dx/warranty/details", {vin: vin}
1030
+ )
1058
1031
 
1059
1032
  async def fleet_telemetry_config(
1060
1033
  self, config: dict[str, Any]
1061
1034
  ) -> dict[str, Any]:
1062
1035
  """Configures fleet telemetry."""
1063
1036
  return await self._request(
1064
- POST, "api/1/vehicles/fleet_telemetry_config", json=config
1037
+ Methods.POST, "api/1/vehicles/fleet_telemetry_config", json=config
1065
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"]]