tesla-fleet-api 0.3.2__py3-none-any.whl → 0.4.0__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,7 +1,5 @@
1
1
  from typing import Any
2
- from .const import (
3
- Methods,
4
- )
2
+ from .const import Method
5
3
 
6
4
 
7
5
  class Charging:
@@ -22,7 +20,7 @@ class Charging:
22
20
  ) -> dict[str, Any]:
23
21
  """Returns the paginated charging history."""
24
22
  return await self._request(
25
- Methods.GET,
23
+ Method.GET,
26
24
  "api/1/dx/charging/history",
27
25
  {
28
26
  "vin": vin,
@@ -45,7 +43,7 @@ class Charging:
45
43
  ) -> dict[str, Any]:
46
44
  """Returns the charging session information including pricing and energy data. This endpoint is only available for business accounts that own a fleet of vehicles."""
47
45
  return await self._request(
48
- Methods.GET,
46
+ Method.GET,
49
47
  "api/1/dx/charging/sessions",
50
48
  {
51
49
  "vin": vin,
tesla_fleet_api/const.py CHANGED
@@ -3,22 +3,22 @@ from enum import Enum
3
3
 
4
4
 
5
5
  class IntEnum(int, Enum):
6
- pass
6
+ """Integer Enum."""
7
7
 
8
8
 
9
9
  class StrEnum(str, Enum):
10
- pass
10
+ """String Enum."""
11
11
 
12
12
 
13
- class Methods(StrEnum):
14
- """HTTP methods."""
13
+ class Method(StrEnum):
14
+ """HTTP Methods."""
15
15
 
16
16
  GET = "GET"
17
17
  POST = "POST"
18
18
  DELETE = "DELETE"
19
19
 
20
20
 
21
- class Errors(StrEnum):
21
+ class Error(StrEnum):
22
22
  """Tesla Fleet API error codes."""
23
23
 
24
24
  INVALID_COMMAND = "invalid_command"
@@ -39,13 +39,32 @@ SERVERS = {
39
39
  }
40
40
 
41
41
 
42
- class Trunks(StrEnum):
42
+ class Trunk(StrEnum):
43
43
  """Trunk options"""
44
44
 
45
45
  FRONT: "front"
46
46
  REAR: "rear"
47
47
 
48
48
 
49
+ class Seat(IntEnum):
50
+ """Seat positions"""
51
+
52
+ FRONT_LEFT = 0
53
+ FRONT_RIGHT = 1
54
+ REAR_LEFT = 2
55
+ REAR_CENTER = 4
56
+ REAR_RIGHT = 5
57
+
58
+
59
+ class Level(IntEnum):
60
+ """Level options"""
61
+
62
+ OFF = 0
63
+ LOW = 1
64
+ MEDIUM = 2
65
+ HIGH = 3
66
+
67
+
49
68
  class ClimateKeeperMode(IntEnum):
50
69
  """Climate Keeper Mode options"""
51
70
 
@@ -55,7 +74,7 @@ class ClimateKeeperMode(IntEnum):
55
74
  CAMP_MODE = 3
56
75
 
57
76
 
58
- class CabinOverheatProtectionTemps(IntEnum):
77
+ class CabinOverheatProtectionTemp(IntEnum):
59
78
  """COP Temp options"""
60
79
 
61
80
  LOW = 0 # 30C 90F
@@ -63,7 +82,7 @@ class CabinOverheatProtectionTemps(IntEnum):
63
82
  HIGH = 2 # 40C 100F
64
83
 
65
84
 
66
- class VehicleDataEndpoints(StrEnum):
85
+ class VehicleDataEndpoint(StrEnum):
67
86
  """Endpoints options"""
68
87
 
69
88
  CHARGE_STATE = "charge_state"
@@ -77,7 +96,7 @@ class VehicleDataEndpoints(StrEnum):
77
96
  VEHICLE_DATA_COMBO = "vehicle_data_combo"
78
97
 
79
98
 
80
- class SunRoofCommands(StrEnum):
99
+ class SunRoofCommand(StrEnum):
81
100
  """Sunroof options"""
82
101
 
83
102
  STOP = "stop"
@@ -85,14 +104,14 @@ class SunRoofCommands(StrEnum):
85
104
  VENT = "vent"
86
105
 
87
106
 
88
- class WindowCommands(StrEnum):
107
+ class WindowCommand(StrEnum):
89
108
  """Window Control options"""
90
109
 
91
110
  VENT = "vent"
92
111
  CLOSE = "close"
93
112
 
94
113
 
95
- class DeviceTypes(StrEnum):
114
+ class DeviceType(StrEnum):
96
115
  """Device Type options"""
97
116
 
98
117
  ANDROID = "android"
@@ -102,8 +121,8 @@ class DeviceTypes(StrEnum):
102
121
  IOS_PRODUCTION = "ios-production"
103
122
 
104
123
 
105
- class Scopes(StrEnum):
106
- """Fleet API Scopes"""
124
+ class Scope(StrEnum):
125
+ """Fleet API Scope"""
107
126
 
108
127
  OPENID = "openid"
109
128
  OFFLINE_ACCESS = "offline_access"
@@ -115,7 +134,7 @@ class Scopes(StrEnum):
115
134
  ENERGY_CMDS = "energy_cmds"
116
135
 
117
136
 
118
- class TelemetryFields(StrEnum):
137
+ class TelemetryField(StrEnum):
119
138
  """Fields available in telemetry streams"""
120
139
 
121
140
  AC_CHARGING_ENERGY_IN = "ACChargingEnergyIn"
@@ -270,7 +289,7 @@ class TelemetryFields(StrEnum):
270
289
  VERSION = "Version"
271
290
 
272
291
 
273
- class TelemetryAlerts(StrEnum):
292
+ class TelemetryAlert(StrEnum):
274
293
  """Alerts available in telemetry streams"""
275
294
 
276
295
  CUSTOMER = "Customer"
tesla_fleet_api/energy.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from typing import Any
2
- from .const import Methods
2
+ from .const import Method
3
3
  from .energyspecific import EnergySpecific
4
4
 
5
5
 
@@ -18,7 +18,7 @@ class Energy:
18
18
  ) -> dict[str, Any]:
19
19
  """Adjust the site's backup reserve."""
20
20
  return await self._request(
21
- Methods.POST,
21
+ Method.POST,
22
22
  f"api/1/energy_sites/{energy_site_id}/backup",
23
23
  json={"backup_reserve_percent": backup_reserve_percent},
24
24
  )
@@ -34,7 +34,7 @@ class Energy:
34
34
  ) -> dict[str, Any]:
35
35
  """Returns the backup (off-grid) event history of the site in duration of seconds."""
36
36
  return await self._request(
37
- Methods.GET,
37
+ Method.GET,
38
38
  f"api/1/energy_sites/{energy_site_id}/calendar_history",
39
39
  json={
40
40
  "kind": kind,
@@ -55,7 +55,7 @@ class Energy:
55
55
  ) -> dict[str, Any]:
56
56
  """Returns the charging history of a wall connector."""
57
57
  return await self._request(
58
- Methods.GET,
58
+ Method.GET,
59
59
  f"api/1/energy_sites/{energy_site_id}/telemetry_history",
60
60
  query={
61
61
  "kind": kind,
@@ -76,7 +76,7 @@ class Energy:
76
76
  ) -> dict[str, Any]:
77
77
  """Returns the energy measurements of the site, aggregated to the requested period."""
78
78
  return await self._request(
79
- Methods.GET,
79
+ Method.GET,
80
80
  f"api/1/energy_sites/{energy_site_id}/calendar_history",
81
81
  query={
82
82
  "kind": kind,
@@ -106,7 +106,7 @@ class Energy:
106
106
  "At least one of disallow_charge_from_grid_with_solar_installed or customer_preferred_export_rule must be set."
107
107
  )
108
108
  return await self._request(
109
- Methods.POST,
109
+ Method.POST,
110
110
  f"api/1/energy_sites/{energy_site_id}/grid_import_export",
111
111
  json=data,
112
112
  )
@@ -114,7 +114,7 @@ class Energy:
114
114
  async def live_status(self, energy_site_id: int) -> dict[str, Any]:
115
115
  """Returns the live status of the site (power, state of energy, grid status, storm mode)."""
116
116
  return await self._request(
117
- Methods.GET,
117
+ Method.GET,
118
118
  f"api/1/energy_sites/{energy_site_id}/live_status",
119
119
  )
120
120
 
@@ -123,7 +123,7 @@ class Energy:
123
123
  ) -> dict[str, Any]:
124
124
  """Adjust the site's off-grid vehicle charging backup reserve."""
125
125
  return await self._request(
126
- Methods.POST,
126
+ Method.POST,
127
127
  f"api/1/energy_sites/{energy_site_id}/off_grid_vehicle_charging_reserve",
128
128
  json={
129
129
  "off_grid_vehicle_charging_reserve_percent": off_grid_vehicle_charging_reserve_percent
@@ -135,7 +135,7 @@ class Energy:
135
135
  ) -> dict[str, Any]:
136
136
  """Set the site's mode."""
137
137
  return await self._request(
138
- Methods.POST,
138
+ Method.POST,
139
139
  f"api/1/energy_sites/{energy_site_id}/operation",
140
140
  json={"default_real_mode": default_real_mode},
141
141
  )
@@ -143,14 +143,14 @@ class Energy:
143
143
  async def site_info(self, energy_site_id: int) -> dict[str, Any]:
144
144
  """Returns information about the site. Things like assets (has solar, etc), settings (backup reserve, etc), and features (storm_mode_capable, etc)."""
145
145
  return await self._request(
146
- Methods.GET,
146
+ Method.GET,
147
147
  f"api/1/energy_sites/{energy_site_id}/site_info",
148
148
  )
149
149
 
150
150
  async def storm_mode(self, energy_site_id: int, enabled: bool) -> dict[str, Any]:
151
151
  """Update storm watch participation."""
152
152
  return await self._request(
153
- Methods.POST,
153
+ Method.POST,
154
154
  f"api/1/energy_sites/{energy_site_id}/storm_mode",
155
155
  json={"enabled": enabled},
156
156
  )
@@ -1,5 +1,5 @@
1
1
  import aiohttp
2
- from .const import Errors
2
+ from .const import Error
3
3
 
4
4
 
5
5
  class TeslaFleetError(BaseException):
@@ -87,9 +87,9 @@ class PaymentRequired(TeslaFleetError):
87
87
 
88
88
 
89
89
  class Forbidden(TeslaFleetError):
90
- """Access to this resource is not authorized, developers should check required scopes."""
90
+ """Access to this resource is not authorized, developers should check required Scope."""
91
91
 
92
- message = "Access to this resource is not authorized, developers should check required scopes."
92
+ message = "Access to this resource is not authorized, developers should check required Scope."
93
93
  status = 403
94
94
 
95
95
 
@@ -232,25 +232,25 @@ async def raise_for_status(resp: aiohttp.ClientResponse) -> None:
232
232
  except aiohttp.ClientResponseError as e:
233
233
  if resp.status == 400:
234
234
  error = data.get("error")
235
- if error == Errors.INVALID_COMMAND:
235
+ if error == Error.INVALID_COMMAND:
236
236
  raise InvalidCommand(data) from e
237
- elif error == Errors.INVALID_FIELD:
237
+ elif error == Error.INVALID_FIELD:
238
238
  raise InvalidField(data) from e
239
- elif error == Errors.INVALID_REQUEST:
239
+ elif error == Error.INVALID_REQUEST:
240
240
  raise InvalidRequest(data) from e
241
- elif error == Errors.INVALID_AUTH_CODE:
241
+ elif error == Error.INVALID_AUTH_CODE:
242
242
  raise InvalidAuthCode(data) from e
243
- elif error == Errors.INVALID_REDIRECT_URL:
243
+ elif error == Error.INVALID_REDIRECT_URL:
244
244
  raise InvalidRedirectUrl(data) from e
245
- elif error == Errors.UNAUTHORIZED_CLIENT:
245
+ elif error == Error.UNAUTHORIZED_CLIENT:
246
246
  raise UnauthorizedClient(data) from e
247
247
  else:
248
248
  raise TeslaFleetError(data) from e
249
249
  elif resp.status == 401:
250
250
  error = data.get("error")
251
- if error == Errors.TOKEN_EXPIRED:
251
+ if error == Error.TOKEN_EXPIRED:
252
252
  raise OAuthExpired(data) from e
253
- elif error == Errors.MOBILE_ACCESS_DISABLED:
253
+ elif error == Error.MOBILE_ACCESS_DISABLED:
254
254
  raise MobileAccessDisabled(data) from e
255
255
  else:
256
256
  raise InvalidToken(data) from e
@@ -1,5 +1,5 @@
1
1
  from typing import Any
2
- from .const import Methods
2
+ from .const import Method
3
3
 
4
4
 
5
5
  class Partner:
@@ -11,17 +11,17 @@ class Partner:
11
11
  async def public_key(self, domain: str | None = None) -> dict[str, Any]:
12
12
  """Returns the public key associated with a domain. It can be used to ensure the registration was successful."""
13
13
  return await self._request(
14
- Methods.GET, "api/1/partner_accounts/public_key", params={"domain": domain}
14
+ Method.GET, "api/1/partner_accounts/public_key", params={"domain": domain}
15
15
  )
16
16
 
17
17
  async def register(self, domain: str) -> dict[str, Any]:
18
18
  """Registers an existing account before it can be used for general API access. Each application from developer.tesla.com must complete this step."""
19
19
  return await self._request(
20
- Methods.POST, "api/1/partner_accounts", json={"domain": domain}
20
+ Method.POST, "api/1/partner_accounts", json={"domain": domain}
21
21
  )
22
22
 
23
23
  async def fleet_telemetry_errors(self) -> dict[str, Any]:
24
24
  """Returns recent fleet telemetry errors reported by vehicles after receiving the config."""
25
25
  return await self._request(
26
- Methods.GET, "api/1/fleet_telemetry/fleet_telemetry_errors"
26
+ Method.GET, "api/1/fleet_telemetry/fleet_telemetry_errors"
27
27
  )
@@ -1,7 +1,7 @@
1
1
  import aiohttp
2
2
  from .exceptions import raise_for_status, InvalidRegion, LibraryError
3
3
  from typing import Any
4
- from .const import SERVERS, Methods, Errors
4
+ from .const import SERVERS, Method, Error
5
5
  from .charging import Charging
6
6
  from .energy import Energy
7
7
  from .partner import Partner
@@ -67,7 +67,7 @@ class TeslaFleetApi:
67
67
 
68
68
  async def _request(
69
69
  self,
70
- method: Methods,
70
+ method: Method,
71
71
  path: str,
72
72
  params: dict[str:Any] | None = None,
73
73
  json: dict[str:Any] | None = None,
@@ -77,7 +77,7 @@ class TeslaFleetApi:
77
77
  if not self.server:
78
78
  raise ValueError("Server was not set at init. Call find_server() first.")
79
79
 
80
- if method == Methods.GET and json is not None:
80
+ if method == Method.GET and json is not None:
81
81
  raise ValueError("GET requests cannot have a body.")
82
82
 
83
83
  if params:
@@ -101,7 +101,7 @@ class TeslaFleetApi:
101
101
  # Manufacture a response since Tesla doesn't provide a body for token expiration.
102
102
  return {
103
103
  "response": None,
104
- "error": Errors.INVALID_TOKEN,
104
+ "error": Error.INVALID_TOKEN,
105
105
  "error_message": "The OAuth token has expired.",
106
106
  }
107
107
  if resp.content_type == "application/json":
@@ -118,6 +118,6 @@ class TeslaFleetApi:
118
118
  async def products(self) -> dict[str, Any]:
119
119
  """Returns products mapped to user."""
120
120
  return await self._request(
121
- Methods.GET,
121
+ Method.GET,
122
122
  "api/1/products",
123
123
  )
@@ -2,9 +2,9 @@ from typing import Any
2
2
  import aiohttp
3
3
  import time
4
4
 
5
- from tesla_fleet_api.const import Methods
5
+ from tesla_fleet_api.const import Method
6
6
  from .teslafleetapi import TeslaFleetApi
7
- from .const import Scopes, SERVERS
7
+ from .const import Scope, SERVERS
8
8
 
9
9
 
10
10
  class TeslaFleetOAuth(TeslaFleetApi):
@@ -37,10 +37,10 @@ class TeslaFleetOAuth(TeslaFleetApi):
37
37
  )
38
38
 
39
39
  def get_login_url(
40
- self, redirect_uri: str, scopes: [Scopes], state: str = "login"
40
+ self, redirect_uri: str, Scope: [Scope], state: str = "login"
41
41
  ) -> str:
42
42
  """Get the login URL."""
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}"
43
+ return f"https://auth.tesla.com/oauth2/v3/authorize?response_type=code&client_id={self.client_id}&redirect_uri={redirect_uri}&scope={' '.join(Scope)}&state={state}"
44
44
 
45
45
  async def get_refresh_token(self, client_secret: str, code: str, redirect_uri: str):
46
46
  """Get the refresh token."""
@@ -91,7 +91,7 @@ class TeslaFleetOAuth(TeslaFleetApi):
91
91
 
92
92
  async def _request(
93
93
  self,
94
- method: Methods,
94
+ method: Method,
95
95
  path: str,
96
96
  params: dict | None = None,
97
97
  data: dict | None = None,
@@ -1,6 +1,6 @@
1
1
  import aiohttp
2
2
  from .teslafleetapi import TeslaFleetApi
3
- from .const import Methods
3
+ from .const import Method
4
4
 
5
5
 
6
6
  class Teslemetry(TeslaFleetApi):
@@ -23,21 +23,21 @@ class Teslemetry(TeslaFleetApi):
23
23
  async def ping(self) -> bool:
24
24
  """Send a ping."""
25
25
  return await self._request(
26
- Methods.GET,
26
+ Method.GET,
27
27
  "api/ping",
28
28
  )
29
29
 
30
30
  async def test(self) -> bool:
31
31
  """Test API Authentication."""
32
32
  return await self._request(
33
- Methods.GET,
33
+ Method.GET,
34
34
  "api/test",
35
35
  )
36
36
 
37
37
  async def metadata(self) -> bool:
38
38
  """Test API Authentication."""
39
39
  return await self._request(
40
- Methods.GET,
40
+ Method.GET,
41
41
  "api/metadata",
42
42
  )
43
43
 
tesla_fleet_api/user.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from typing import Any
2
- from .const import Methods
2
+ from .const import Method
3
3
 
4
4
 
5
5
  class User:
@@ -10,20 +10,20 @@ class User:
10
10
 
11
11
  async def backup_key(self) -> dict[str, Any]:
12
12
  """Returns the public key associated with the user."""
13
- return await self._request(Methods.GET, "api/1/users/backup_key")
13
+ return await self._request(Method.GET, "api/1/users/backup_key")
14
14
 
15
15
  async def feature_config(self) -> dict[str, Any]:
16
16
  """Returns any custom feature flag applied to a user."""
17
- return await self._request(Methods.GET, "api/1/users/feature_config")
17
+ return await self._request(Method.GET, "api/1/users/feature_config")
18
18
 
19
19
  async def me(self) -> dict[str, Any]:
20
20
  """Returns a summary of a user's account."""
21
- return await self._request(Methods.GET, "api/1/users/me")
21
+ return await self._request(Method.GET, "api/1/users/me")
22
22
 
23
23
  async def orders(self) -> dict[str, Any]:
24
24
  """Returns the active orders for a user."""
25
- return await self._request(Methods.GET, "api/1/users/orders")
25
+ return await self._request(Method.GET, "api/1/users/orders")
26
26
 
27
27
  async def region(self) -> dict[str, Any]:
28
28
  """Returns a user's region and appropriate fleet-api base URL. Accepts no parameters, response is based on the authentication token subject."""
29
- return await self._request(Methods.GET, "api/1/users/region")
29
+ return await self._request(Method.GET, "api/1/users/region")