tesla-fleet-api 0.5.5__py3-none-any.whl → 0.5.7__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/__init__.py +15 -0
- tesla_fleet_api/const.py +1 -1
- tesla_fleet_api/energy.py +1 -1
- tesla_fleet_api/exceptions.py +1 -0
- tesla_fleet_api/teslafleetapi.py +12 -10
- tesla_fleet_api/teslafleetoauth.py +9 -7
- tesla_fleet_api/teslemetry.py +5 -4
- tesla_fleet_api/tessie.py +1 -2
- tesla_fleet_api/vehicle.py +25 -6
- tesla_fleet_api/vehiclespecific.py +25 -3
- {tesla_fleet_api-0.5.5.dist-info → tesla_fleet_api-0.5.7.dist-info}/METADATA +1 -1
- tesla_fleet_api-0.5.7.dist-info/RECORD +19 -0
- tesla_fleet_api-0.5.5.dist-info/RECORD +0 -19
- {tesla_fleet_api-0.5.5.dist-info → tesla_fleet_api-0.5.7.dist-info}/LICENSE +0 -0
- {tesla_fleet_api-0.5.5.dist-info → tesla_fleet_api-0.5.7.dist-info}/WHEEL +0 -0
- {tesla_fleet_api-0.5.5.dist-info → tesla_fleet_api-0.5.7.dist-info}/top_level.txt +0 -0
tesla_fleet_api/__init__.py
CHANGED
@@ -9,3 +9,18 @@ from .partner import Partner
|
|
9
9
|
from .user import User
|
10
10
|
from .vehicle import Vehicle
|
11
11
|
from .vehiclespecific import VehicleSpecific
|
12
|
+
|
13
|
+
|
14
|
+
__all__ = [
|
15
|
+
"TeslaFleetApi",
|
16
|
+
"TeslaFleetOAuth",
|
17
|
+
"Teslemetry",
|
18
|
+
"Tessie",
|
19
|
+
"Charging",
|
20
|
+
"Energy",
|
21
|
+
"EnergySpecific",
|
22
|
+
"Partner",
|
23
|
+
"User",
|
24
|
+
"Vehicle",
|
25
|
+
"VehicleSpecific",
|
26
|
+
]
|
tesla_fleet_api/const.py
CHANGED
tesla_fleet_api/energy.py
CHANGED
@@ -91,7 +91,7 @@ class Energy:
|
|
91
91
|
self,
|
92
92
|
energy_site_id: int,
|
93
93
|
disallow_charge_from_grid_with_solar_installed: bool | None = None,
|
94
|
-
customer_preferred_export_rule: EnergyExportMode|str | None = None,
|
94
|
+
customer_preferred_export_rule: EnergyExportMode | str | None = None,
|
95
95
|
) -> dict[str, Any]:
|
96
96
|
"""Allow/disallow charging from the grid and exporting energy to the grid."""
|
97
97
|
return await self._request(
|
tesla_fleet_api/exceptions.py
CHANGED
tesla_fleet_api/teslafleetapi.py
CHANGED
@@ -15,7 +15,7 @@ from .vehicle import Vehicle
|
|
15
15
|
class TeslaFleetApi:
|
16
16
|
"""Class describing the Tesla Fleet API."""
|
17
17
|
|
18
|
-
server: str
|
18
|
+
server: str | None = None
|
19
19
|
session: aiohttp.ClientSession
|
20
20
|
headers: dict[str, str]
|
21
21
|
raise_for_status: bool
|
@@ -23,7 +23,7 @@ class TeslaFleetApi:
|
|
23
23
|
def __init__(
|
24
24
|
self,
|
25
25
|
session: aiohttp.ClientSession,
|
26
|
-
access_token: str,
|
26
|
+
access_token: str | None = None,
|
27
27
|
region: str | None = None,
|
28
28
|
server: str | None = None,
|
29
29
|
raise_for_status: bool = True,
|
@@ -38,9 +38,10 @@ class TeslaFleetApi:
|
|
38
38
|
self.session = session
|
39
39
|
self.access_token = access_token
|
40
40
|
|
41
|
-
if region
|
42
|
-
|
43
|
-
|
41
|
+
if region is not None:
|
42
|
+
if not server and region not in SERVERS:
|
43
|
+
raise ValueError(f"Region must be one of {', '.join(SERVERS.keys())}")
|
44
|
+
self.server = server or SERVERS.get(region)
|
44
45
|
self.raise_for_status = raise_for_status
|
45
46
|
|
46
47
|
LOGGER.debug("Using server %s", self.server)
|
@@ -61,7 +62,8 @@ class TeslaFleetApi:
|
|
61
62
|
for server in SERVERS.values():
|
62
63
|
self.server = server
|
63
64
|
try:
|
64
|
-
|
65
|
+
region_response = await self.user.region()
|
66
|
+
response = region_response.get("response")
|
65
67
|
if response:
|
66
68
|
self.server = response["fleet_api_base_url"]
|
67
69
|
LOGGER.debug("Using server %s", self.server)
|
@@ -74,9 +76,9 @@ class TeslaFleetApi:
|
|
74
76
|
self,
|
75
77
|
method: Method,
|
76
78
|
path: str,
|
77
|
-
params: dict[str
|
78
|
-
json: dict[str
|
79
|
-
):
|
79
|
+
params: dict[str, Any] | None = None,
|
80
|
+
json: dict[str, Any] | None = None,
|
81
|
+
) -> dict[str, Any] | str:
|
80
82
|
"""Send a request to the Tesla Fleet API."""
|
81
83
|
|
82
84
|
if not self.server:
|
@@ -125,7 +127,7 @@ class TeslaFleetApi:
|
|
125
127
|
LOGGER.debug("Response Text: %s", data)
|
126
128
|
return data
|
127
129
|
|
128
|
-
async def status(self):
|
130
|
+
async def status(self) -> str:
|
129
131
|
"""This endpoint returns the string "ok" if the API is operating normally. No HTTP headers are required."""
|
130
132
|
if not self.server:
|
131
133
|
raise ValueError("Server was not set at init. Call find_server() first.")
|
@@ -42,7 +42,9 @@ class TeslaFleetOAuth(TeslaFleetApi):
|
|
42
42
|
"""Get the login URL."""
|
43
43
|
return f"https://auth.tesla.com/oauth2/v3/authorize?response_type=code&client_id={self.client_id}&redirect_uri={redirect_uri}&scope={' '.join(scopes)}&state={state}"
|
44
44
|
|
45
|
-
async def get_refresh_token(
|
45
|
+
async def get_refresh_token(
|
46
|
+
self, client_secret: str, code: str, redirect_uri: str
|
47
|
+
) -> None:
|
46
48
|
"""Get the refresh token."""
|
47
49
|
async with self.session.post(
|
48
50
|
"https://auth.tesla.com/oauth2/v3/token",
|
@@ -63,13 +65,13 @@ class TeslaFleetOAuth(TeslaFleetApi):
|
|
63
65
|
region = code.split("_")[0].lower()
|
64
66
|
self.server = SERVERS.get(region)
|
65
67
|
|
66
|
-
async def check_access_token(self) -> str | None:
|
68
|
+
async def check_access_token(self) -> dict[str, Any] | None:
|
67
69
|
"""Get the access token."""
|
68
70
|
if self.access_token and self.expires > time.time():
|
69
|
-
return
|
71
|
+
return None
|
70
72
|
return await self.refresh_access_token()
|
71
73
|
|
72
|
-
async def refresh_access_token(self) -> str:
|
74
|
+
async def refresh_access_token(self) -> dict[str, Any]:
|
73
75
|
"""Refresh the access token."""
|
74
76
|
if not self.refresh_token:
|
75
77
|
raise ValueError("Refresh token is missing")
|
@@ -93,9 +95,9 @@ class TeslaFleetOAuth(TeslaFleetApi):
|
|
93
95
|
self,
|
94
96
|
method: Method,
|
95
97
|
path: str,
|
96
|
-
params: dict | None = None,
|
97
|
-
data: dict | None = None,
|
98
|
-
):
|
98
|
+
params: dict[str, Any] | None = None,
|
99
|
+
data: dict[str, Any] | None = None,
|
100
|
+
) -> str | dict[str, Any]:
|
99
101
|
"""Send a request to the Tesla Fleet API."""
|
100
102
|
await self.check_access_token()
|
101
103
|
return await super()._request(method, path, params, data)
|
tesla_fleet_api/teslemetry.py
CHANGED
@@ -52,7 +52,8 @@ class Teslemetry(TeslaFleetApi):
|
|
52
52
|
LOGGER.debug("Using server %s", self.server)
|
53
53
|
return resp
|
54
54
|
|
55
|
-
|
55
|
+
# TODO: type this properly, it probably should return something
|
56
|
+
async def find_server(self) -> None:
|
56
57
|
"""Find the server URL for the Tesla Fleet API."""
|
57
58
|
await self.metadata(True)
|
58
59
|
|
@@ -60,9 +61,9 @@ class Teslemetry(TeslaFleetApi):
|
|
60
61
|
self,
|
61
62
|
method: Method,
|
62
63
|
path: str,
|
63
|
-
params: dict[str
|
64
|
-
json: dict[str
|
65
|
-
):
|
64
|
+
params: dict[str, Any] | None = None,
|
65
|
+
json: dict[str, Any] | None = None,
|
66
|
+
) -> str | dict[str, Any]:
|
66
67
|
"""Send a request to the Teslemetry API."""
|
67
68
|
async with rate_limit:
|
68
69
|
return await super()._request(method, path, params, json)
|
tesla_fleet_api/tessie.py
CHANGED
@@ -2,7 +2,6 @@ import aiohttp
|
|
2
2
|
from typing import Any
|
3
3
|
from .teslafleetapi import TeslaFleetApi
|
4
4
|
from .const import Method
|
5
|
-
from .vehiclespecific import VehicleSpecific
|
6
5
|
|
7
6
|
|
8
7
|
class Tessie(TeslaFleetApi):
|
@@ -23,7 +22,7 @@ class Tessie(TeslaFleetApi):
|
|
23
22
|
energy_scope=False,
|
24
23
|
)
|
25
24
|
|
26
|
-
async def find_server(self):
|
25
|
+
async def find_server(self) -> str:
|
27
26
|
"""Find the server URL for the Tesla Fleet API."""
|
28
27
|
raise NotImplementedError("Do not use this function for Tessie.")
|
29
28
|
|
tesla_fleet_api/vehicle.py
CHANGED
@@ -24,6 +24,10 @@ class Vehicle:
|
|
24
24
|
def specific(self, vehicle_tag: str | int) -> VehicleSpecific:
|
25
25
|
"""Creates a class for each vehicle."""
|
26
26
|
return VehicleSpecific(self, vehicle_tag)
|
27
|
+
|
28
|
+
def pre2021(self, vin: str) -> bool:
|
29
|
+
"""Checks if a vehicle is pre-2021."""
|
30
|
+
return vin[9] <= "L"
|
27
31
|
|
28
32
|
async def actuate_trunk(
|
29
33
|
self, vehicle_tag: str | int, which_trunk: Trunk | str
|
@@ -426,13 +430,29 @@ class Vehicle:
|
|
426
430
|
)
|
427
431
|
|
428
432
|
async def set_scheduled_departure(
|
429
|
-
self,
|
433
|
+
self,
|
434
|
+
vehicle_tag: str | int,
|
435
|
+
enable: bool = True,
|
436
|
+
preconditioning_enabled: bool = False,
|
437
|
+
preconditioning_weekdays_only: bool = False,
|
438
|
+
departure_time: int = 0,
|
439
|
+
off_peak_charging_enabled: bool = False,
|
440
|
+
off_peak_charging_weekdays_only: bool = False,
|
441
|
+
end_off_peak_time: int = 0,
|
430
442
|
) -> dict[str, Any]:
|
431
443
|
"""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)."""
|
432
444
|
return await self._request(
|
433
445
|
Method.POST,
|
434
446
|
f"api/1/vehicles/{vehicle_tag}/command/set_scheduled_departure",
|
435
|
-
json={
|
447
|
+
json={
|
448
|
+
"enable": enable,
|
449
|
+
"preconditioning_enabled": preconditioning_enabled,
|
450
|
+
"preconditioning_weekdays_only": preconditioning_weekdays_only,
|
451
|
+
"departure_time": departure_time,
|
452
|
+
"off_peak_charging_enabled": off_peak_charging_enabled,
|
453
|
+
"off_peak_charging_weekdays_only": off_peak_charging_weekdays_only,
|
454
|
+
"end_off_peak_time": end_off_peak_time,
|
455
|
+
},
|
436
456
|
)
|
437
457
|
|
438
458
|
async def set_sentry_mode(self, vehicle_tag: str | int, on: bool) -> dict[str, Any]:
|
@@ -551,7 +571,7 @@ class Vehicle:
|
|
551
571
|
lon: float | None = None,
|
552
572
|
) -> dict[str, Any]:
|
553
573
|
"""Turns on HomeLink (used to open and close garage doors)."""
|
554
|
-
data = {}
|
574
|
+
data: dict[str, str | float] = {}
|
555
575
|
if token:
|
556
576
|
data["token"] = token
|
557
577
|
if lat and lon:
|
@@ -726,12 +746,11 @@ class Vehicle:
|
|
726
746
|
endpoints: List[VehicleDataEndpoint] | List[str] | None = None,
|
727
747
|
) -> dict[str, Any]:
|
728
748
|
"""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."""
|
729
|
-
|
730
|
-
endpoints = ";".join(endpoints)
|
749
|
+
endpoint_payload = ";".join(endpoints) if endpoints else None
|
731
750
|
return await self._request(
|
732
751
|
Method.GET,
|
733
752
|
f"api/1/vehicles/{vehicle_tag}/vehicle_data",
|
734
|
-
{"endpoints":
|
753
|
+
{"endpoints": endpoint_payload},
|
735
754
|
)
|
736
755
|
|
737
756
|
async def vehicle_subscriptions(
|
@@ -13,10 +13,14 @@ from .const import (
|
|
13
13
|
class VehicleSpecific:
|
14
14
|
"""Class describing the Tesla Fleet API vehicle endpoints and commands for a specific vehicle."""
|
15
15
|
|
16
|
-
def __init__(self, parent, vin: str | None = None):
|
16
|
+
def __init__(self, parent, vin: str | int | None = None):
|
17
17
|
self._parent = parent
|
18
18
|
self.vin = vin
|
19
19
|
|
20
|
+
def pre2021(self) -> bool:
|
21
|
+
"""Checks if a vehicle is pre-2021."""
|
22
|
+
return self._parent.pre2021(self.vin)
|
23
|
+
|
20
24
|
async def actuate_trunk(self, which_trunk: Trunk | str) -> dict[str, Any]:
|
21
25
|
"""Controls the front or rear trunk."""
|
22
26
|
return await self._parent.actuate_trunk(self.vin, which_trunk)
|
@@ -243,9 +247,27 @@ class VehicleSpecific:
|
|
243
247
|
"""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)."""
|
244
248
|
return await self._parent.set_scheduled_charging(self.vin, enable, time)
|
245
249
|
|
246
|
-
async def set_scheduled_departure(
|
250
|
+
async def set_scheduled_departure(
|
251
|
+
self,
|
252
|
+
enable: bool = True,
|
253
|
+
preconditioning_enabled: bool = False,
|
254
|
+
preconditioning_weekdays_only: bool = False,
|
255
|
+
departure_time: int = 0,
|
256
|
+
off_peak_charging_enabled: bool = False,
|
257
|
+
off_peak_charging_weekdays_only: bool = False,
|
258
|
+
end_off_peak_time: int = 0,
|
259
|
+
) -> dict[str, Any]:
|
247
260
|
"""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)."""
|
248
|
-
return await self._parent.set_scheduled_departure(
|
261
|
+
return await self._parent.set_scheduled_departure(
|
262
|
+
self.vin,
|
263
|
+
enable,
|
264
|
+
preconditioning_enabled,
|
265
|
+
preconditioning_weekdays_only,
|
266
|
+
departure_time,
|
267
|
+
off_peak_charging_enabled,
|
268
|
+
off_peak_charging_weekdays_only,
|
269
|
+
end_off_peak_time,
|
270
|
+
)
|
249
271
|
|
250
272
|
async def set_sentry_mode(self, on: bool) -> dict[str, Any]:
|
251
273
|
"""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."""
|
@@ -0,0 +1,19 @@
|
|
1
|
+
tesla_fleet_api/__init__.py,sha256=0MON9vh3AShIiX16FZ6NU3yZ7kyXFh5GxA0rY8CzVRM,584
|
2
|
+
tesla_fleet_api/charging.py,sha256=N_mc8axrXj3iduqLj_jCt4Vx86tHqe3xqQT4R1R7HvU,1689
|
3
|
+
tesla_fleet_api/const.py,sha256=cxe_D2pfWT6REocIZEGfC-COOiXZrCcqGGKkYOs6MxM,9277
|
4
|
+
tesla_fleet_api/energy.py,sha256=kE-HDupzhgatIsizJoer1MAALP-wH6jjjGliiRQN0Os,5285
|
5
|
+
tesla_fleet_api/energyspecific.py,sha256=kICxdeDoWR9JHlgjHvnmjJ1ErLOWJT8bCSESoXo9axU,3732
|
6
|
+
tesla_fleet_api/exceptions.py,sha256=Wh9roGPYB9oBGgEEfxMDay5A7RkPy8JFKloKPStGQ2Y,9211
|
7
|
+
tesla_fleet_api/partner.py,sha256=1vIBUaxKLIfqcC0X6VXZN0dMAzj_CLNPUMjA6QVqZ1k,1223
|
8
|
+
tesla_fleet_api/teslafleetapi.py,sha256=3-gGx-RxOD92Ul0lNCEsCwVBsYunKsO2Sr5rYH0YtIg,5070
|
9
|
+
tesla_fleet_api/teslafleetoauth.py,sha256=FfLnuqZMxF2HsZ5miLNtm3pRwKDoQKi2GD-oXgKxZgA,3594
|
10
|
+
tesla_fleet_api/teslemetry.py,sha256=XOqm7SaakooJSNXEasJI_tRoCIyiFCD6n_PCx9U_D9g,2107
|
11
|
+
tesla_fleet_api/tessie.py,sha256=ZttWuDdQOuTFO4k-BMq7fXKP3Nb4Dsxk3gFJprHHsco,2214
|
12
|
+
tesla_fleet_api/user.py,sha256=TZE2oh-n5zrhKXmGRuiNL9voKVODD7rBhGE_IObYVGA,1179
|
13
|
+
tesla_fleet_api/vehicle.py,sha256=3MF8KN3BjY2dQxmu6-hrrVxrXxI8iQF-rBS8v89ruUw,32835
|
14
|
+
tesla_fleet_api/vehiclespecific.py,sha256=yq1S1rXNUJegG_AIcreoplzznIVDcwviYRvWH2Z5CEI,21492
|
15
|
+
tesla_fleet_api-0.5.7.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
16
|
+
tesla_fleet_api-0.5.7.dist-info/METADATA,sha256=YqHUJyTAqgr0WIiXOtOtc3adsNyrBatwTNnjKsyWloc,3961
|
17
|
+
tesla_fleet_api-0.5.7.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
18
|
+
tesla_fleet_api-0.5.7.dist-info/top_level.txt,sha256=jeNbog_1saXBFrGpom9WyPWmilxsyP3szL_G7JLWQfM,16
|
19
|
+
tesla_fleet_api-0.5.7.dist-info/RECORD,,
|
@@ -1,19 +0,0 @@
|
|
1
|
-
tesla_fleet_api/__init__.py,sha256=RL9KGtDjYwbBa5i6Lagzrya-yjvEE1EVfyge2lV49iI,375
|
2
|
-
tesla_fleet_api/charging.py,sha256=N_mc8axrXj3iduqLj_jCt4Vx86tHqe3xqQT4R1R7HvU,1689
|
3
|
-
tesla_fleet_api/const.py,sha256=uzb_5f14m5lrcySlHWVL-_JM48HubpWmqL5fXy0kyrw,9277
|
4
|
-
tesla_fleet_api/energy.py,sha256=Fgg4pdYc226WNOXHUnzBHbZoZ3jYLfN3GgjprazYLZA,5283
|
5
|
-
tesla_fleet_api/energyspecific.py,sha256=kICxdeDoWR9JHlgjHvnmjJ1ErLOWJT8bCSESoXo9axU,3732
|
6
|
-
tesla_fleet_api/exceptions.py,sha256=c6i_AegrLzlfrHxht_Z_xLl_kmxcd3DDJaSIcldcUo8,9171
|
7
|
-
tesla_fleet_api/partner.py,sha256=1vIBUaxKLIfqcC0X6VXZN0dMAzj_CLNPUMjA6QVqZ1k,1223
|
8
|
-
tesla_fleet_api/teslafleetapi.py,sha256=ErPfOz4M4WERrOlo_a_1ssVPcOIGeiBpbxd4vFJH_x4,4929
|
9
|
-
tesla_fleet_api/teslafleetoauth.py,sha256=BmRAuwcgFMBo2_3AJzS3QTBm_cP9xt4yoz4vKjwgmsw,3501
|
10
|
-
tesla_fleet_api/teslemetry.py,sha256=jB2OlYAjjl98mW4p2-VGTVl5lpG1Qox57mXgsdrF1vg,2005
|
11
|
-
tesla_fleet_api/tessie.py,sha256=3ScOi8RaxHdvp6s5ZdSWYXwHZdey6IkX9SF1oohtSWk,2252
|
12
|
-
tesla_fleet_api/user.py,sha256=TZE2oh-n5zrhKXmGRuiNL9voKVODD7rBhGE_IObYVGA,1179
|
13
|
-
tesla_fleet_api/vehicle.py,sha256=wER3UQIccxN-cUxSkOD1oPQrQ33GoZikmE9yQnEJ7Sk,32010
|
14
|
-
tesla_fleet_api/vehiclespecific.py,sha256=C9gCPGZphzcnDPwyX5HR1ZCEC4IWqdv5ATccHqvFryQ,20817
|
15
|
-
tesla_fleet_api-0.5.5.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
16
|
-
tesla_fleet_api-0.5.5.dist-info/METADATA,sha256=HMQhlZJBUjSNZUN7LqTggG6b2b_MsN3BBrDxgKAidww,3961
|
17
|
-
tesla_fleet_api-0.5.5.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
18
|
-
tesla_fleet_api-0.5.5.dist-info/top_level.txt,sha256=jeNbog_1saXBFrGpom9WyPWmilxsyP3szL_G7JLWQfM,16
|
19
|
-
tesla_fleet_api-0.5.5.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|