tesla-fleet-api 0.9.10__py3-none-any.whl → 1.0.1__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.
Files changed (54) hide show
  1. tesla_fleet_api/__init__.py +7 -22
  2. tesla_fleet_api/const.py +1 -225
  3. tesla_fleet_api/exceptions.py +117 -0
  4. tesla_fleet_api/tesla/__init__.py +11 -0
  5. tesla_fleet_api/tesla/bluetooth.py +38 -0
  6. tesla_fleet_api/{charging.py → tesla/charging.py} +1 -1
  7. tesla_fleet_api/{energy.py → tesla/energysite.py} +41 -33
  8. tesla_fleet_api/{teslafleetapi.py → tesla/fleet.py} +8 -53
  9. tesla_fleet_api/{teslafleetoauth.py → tesla/oauth.py} +3 -4
  10. tesla_fleet_api/{partner.py → tesla/partner.py} +1 -1
  11. tesla_fleet_api/tesla/tesla.py +52 -0
  12. tesla_fleet_api/{user.py → tesla/user.py} +1 -1
  13. tesla_fleet_api/tesla/vehicle/__init__.py +13 -0
  14. tesla_fleet_api/tesla/vehicle/bluetooth.py +219 -0
  15. tesla_fleet_api/{vehiclesigned.py → tesla/vehicle/commands.py} +321 -164
  16. tesla_fleet_api/{vehicle.py → tesla/vehicle/fleet.py} +173 -206
  17. tesla_fleet_api/tesla/vehicle/signed.py +56 -0
  18. tesla_fleet_api/tesla/vehicle/vehicle.py +19 -0
  19. tesla_fleet_api/tesla/vehicle/vehicles.py +46 -0
  20. tesla_fleet_api/teslemetry/__init__.py +5 -0
  21. tesla_fleet_api/{teslemetry.py → teslemetry/teslemetry.py} +16 -25
  22. tesla_fleet_api/teslemetry/vehicle.py +73 -0
  23. tesla_fleet_api/tessie/__init__.py +5 -0
  24. tesla_fleet_api/{tessie.py → tessie/tessie.py} +17 -9
  25. tesla_fleet_api/tessie/vehicle.py +41 -0
  26. {tesla_fleet_api-0.9.10.dist-info → tesla_fleet_api-1.0.1.dist-info}/METADATA +3 -2
  27. tesla_fleet_api-1.0.1.dist-info/RECORD +51 -0
  28. tesla_fleet_api/energyspecific.py +0 -125
  29. tesla_fleet_api/teslafleetopensource.py +0 -61
  30. tesla_fleet_api/vehiclespecific.py +0 -509
  31. tesla_fleet_api-0.9.10.dist-info/RECORD +0 -42
  32. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/__init__.py +0 -0
  33. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/__init__.pyi +0 -0
  34. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/car_server_pb2.py +0 -0
  35. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/car_server_pb2.pyi +0 -0
  36. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/common_pb2.py +0 -0
  37. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/common_pb2.pyi +0 -0
  38. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/errors_pb2.py +0 -0
  39. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/errors_pb2.pyi +0 -0
  40. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/keys_pb2.py +0 -0
  41. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/keys_pb2.pyi +0 -0
  42. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/managed_charging_pb2.py +0 -0
  43. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/managed_charging_pb2.pyi +0 -0
  44. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/signatures_pb2.py +0 -0
  45. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/signatures_pb2.pyi +0 -0
  46. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/universal_message_pb2.py +0 -0
  47. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/universal_message_pb2.pyi +0 -0
  48. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/vcsec_pb2.py +0 -0
  49. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/vcsec_pb2.pyi +0 -0
  50. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/vehicle_pb2.py +0 -0
  51. /tesla_fleet_api/{pb2 → tesla/vehicle/proto}/vehicle_pb2.pyi +0 -0
  52. {tesla_fleet_api-0.9.10.dist-info → tesla_fleet_api-1.0.1.dist-info}/LICENSE +0 -0
  53. {tesla_fleet_api-0.9.10.dist-info → tesla_fleet_api-1.0.1.dist-info}/WHEEL +0 -0
  54. {tesla_fleet_api-0.9.10.dist-info → tesla_fleet_api-1.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,56 @@
1
+ from __future__ import annotations
2
+
3
+ import base64
4
+ from typing import TYPE_CHECKING
5
+
6
+ from .fleet import VehicleFleet
7
+ from .commands import Commands
8
+
9
+ from ...exceptions import (
10
+ MESSAGE_FAULTS,
11
+ )
12
+ from .proto.signatures_pb2 import (
13
+ SessionInfo,
14
+ )
15
+ from .proto.universal_message_pb2 import (
16
+ RoutableMessage,
17
+ )
18
+
19
+ if TYPE_CHECKING:
20
+ from ..fleet import TeslaFleetApi
21
+
22
+
23
+ class VehicleSigned(VehicleFleet, Commands):
24
+ """Class describing the Tesla Fleet API vehicle endpoints and commands for a specific vehicle with command signing."""
25
+
26
+
27
+ _auth_method = "hmac"
28
+
29
+ def __init__(self, parent: TeslaFleetApi, vin: str):
30
+ """Initialize the VehicleSigned class."""
31
+ super().__init__(parent, vin)
32
+ super(Commands, self).__init__(parent, vin)
33
+
34
+
35
+ async def _send(self, msg: RoutableMessage) -> RoutableMessage:
36
+ """Serialize a message and send to the signed command endpoint."""
37
+
38
+ async with self._sessions[msg.to_destination.domain].lock:
39
+ resp = await self.signed_command(
40
+ base64.b64encode(msg.SerializeToString()).decode()
41
+ )
42
+
43
+ resp_msg = RoutableMessage.FromString(base64.b64decode(resp["response"]))
44
+
45
+ # Check UUID?
46
+ # Check RoutingAdress?
47
+
48
+ if resp_msg.session_info:
49
+ self._sessions[resp_msg.from_destination.domain].update(
50
+ SessionInfo.FromString(resp_msg.session_info), self.private_key
51
+ )
52
+
53
+ if resp_msg.signedMessageStatus.signed_message_fault:
54
+ raise MESSAGE_FAULTS[resp_msg.signedMessageStatus.signed_message_fault]
55
+
56
+ return resp_msg
@@ -0,0 +1,19 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+
4
+
5
+ if TYPE_CHECKING:
6
+ from ..tesla import Tesla
7
+
8
+
9
+ class Vehicle:
10
+ """Base class describing a Tesla vehicle."""
11
+
12
+ vin: str
13
+
14
+ def __init__(self, parent: Tesla, vin: str):
15
+ self.vin = vin
16
+
17
+ def pre2021(self, vin: str) -> bool:
18
+ """Checks if a vehicle is a pre-2021 model S or X."""
19
+ return vin[3] in ["S", "X"] and (vin[9] <= "L" or (vin[9] == "M" and vin[7] in ['1', '2', '3', '4']))
@@ -0,0 +1,46 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+
4
+ from .signed import VehicleSigned
5
+ from .bluetooth import VehicleBluetooth
6
+ from .fleet import VehicleFleet
7
+ from .vehicle import Vehicle
8
+
9
+ if TYPE_CHECKING:
10
+ from ..fleet import TeslaFleetApi
11
+
12
+
13
+
14
+ class Vehicles(dict[str, Vehicle]):
15
+ """Class containing and creating vehicles."""
16
+
17
+ _parent: TeslaFleetApi
18
+
19
+ def __init__(self, parent: TeslaFleetApi):
20
+ self._parent = parent
21
+
22
+ def createFleet(self, vin: str) -> VehicleFleet:
23
+ """Creates a Fleet API vehicle."""
24
+ vehicle = VehicleFleet(self._parent, vin)
25
+ self[vin] = vehicle
26
+ return vehicle
27
+
28
+ def createSigned(self, vin: str) -> VehicleSigned:
29
+ """Creates a Fleet API vehicle that uses command protocol."""
30
+ vehicle = VehicleSigned(self._parent, vin)
31
+ self[vin] = vehicle
32
+ return vehicle
33
+
34
+ def createBluetooth(self, vin: str) -> VehicleBluetooth:
35
+ """Creates a bluetooth vehicle that uses command protocol."""
36
+ vehicle = VehicleBluetooth(self._parent, vin)
37
+ self[vin] = vehicle
38
+ return vehicle
39
+
40
+ def specific(self, vin: str) -> Vehicle:
41
+ """Legacy method for creating a Fleet API vehicle."""
42
+ return self.createFleet(vin)
43
+
44
+ def specificSigned(self, vin: str) -> VehicleSigned:
45
+ """Legacy method for creating a Fleet API vehicle that uses command protocol."""
46
+ return self.createSigned(vin)
@@ -0,0 +1,5 @@
1
+ from .teslemetry import Teslemetry
2
+
3
+ __all__ = [
4
+ "Teslemetry",
5
+ ]
@@ -1,30 +1,32 @@
1
1
  from typing import Any
2
2
 
3
3
  import aiohttp
4
- from aiolimiter import AsyncLimiter
5
4
 
6
- from .const import LOGGER, Method
7
- from .teslafleetapi import TeslaFleetApi
5
+ from ..tesla.charging import Charging
6
+ from ..tesla.energysite import EnergySites
7
+ from ..tesla.user import User
8
+ from .vehicle import TeslemetryVehicles
9
+ from ..const import LOGGER, Method
10
+ from ..tesla import TeslaFleetApi
8
11
 
9
- # Rate limit should be global, even if multiple instances are created
10
- rate_limit = AsyncLimiter(5, 10)
12
+ class Teslemetry(TeslaFleetApi):
11
13
 
14
+ server = "https://api.teslemetry.com"
12
15
 
13
- class Teslemetry(TeslaFleetApi):
14
16
  def __init__(
15
17
  self,
16
18
  session: aiohttp.ClientSession,
17
19
  access_token: str,
18
20
  ):
19
21
  """Initialize the Teslemetry API."""
20
- super().__init__(
21
- session=session,
22
- access_token=access_token,
23
- server="https://api.teslemetry.com",
24
- user_scope=False,
25
- partner_scope=False,
26
- )
27
- self.rate_limit = rate_limit
22
+
23
+ self.session = session
24
+ self.access_token = access_token
25
+
26
+ self.charging = Charging(self)
27
+ self.energySites = EnergySites(self)
28
+ self.user = User(self)
29
+ self.vehicle = TeslemetryVehicles(self)
28
30
 
29
31
  async def ping(self) -> dict[str, bool]:
30
32
  """Send a ping."""
@@ -102,14 +104,3 @@ class Teslemetry(TeslaFleetApi):
102
104
  Method.GET,
103
105
  f"api/refresh/{vin}",
104
106
  )
105
-
106
- async def _request(
107
- self,
108
- method: Method,
109
- path: str,
110
- params: dict[str, Any] | None = None,
111
- json: dict[str, Any] | None = None,
112
- ) -> dict[str, Any]:
113
- """Send a request to the Teslemetry API."""
114
- async with rate_limit:
115
- return await super()._request(method, path, params, json)
@@ -0,0 +1,73 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING, Any
3
+
4
+ from ..const import Method
5
+ from ..tesla.vehicle.proto.universal_message_pb2 import Domain
6
+ from ..tesla.vehicle.vehicle import Vehicle
7
+ from ..tesla.vehicle.vehicles import Vehicles
8
+ from ..tesla.vehicle.bluetooth import VehicleBluetooth
9
+ from ..tesla.vehicle.fleet import VehicleFleet
10
+
11
+ if TYPE_CHECKING:
12
+ from .teslemetry import Teslemetry
13
+
14
+ class TeslemetryVehicle(Vehicle):
15
+ """Teslemetry specific base vehicle."""
16
+ pass
17
+
18
+ class TeslemetryVehicleFleet(VehicleFleet):
19
+ """Teslemetry specific API vehicle."""
20
+
21
+ async def server_side_polling(
22
+ self, value: bool | None = None
23
+ ) -> bool | None:
24
+ """Get or set Auto mode."""
25
+ if value is True:
26
+ return (
27
+ await self._request(
28
+ Method.POST,
29
+ f"api/auto/{self.vin}",
30
+ )
31
+ ).get("response")
32
+ if value is False:
33
+ return (
34
+ await self._request(
35
+ Method.DELETE,
36
+ f"api/auto/{self.vin}",
37
+ )
38
+ ).get("response")
39
+ return (
40
+ await self._request(
41
+ Method.GET,
42
+ f"api/auto/{self.vin}",
43
+ )
44
+ ).get("response")
45
+
46
+ async def data_refresh(self) -> dict[str, Any]:
47
+ """Force a refresh of the vehicle data."""
48
+ return await self._request(
49
+ Method.GET,
50
+ f"api/refresh/{self.vin}",
51
+ )
52
+
53
+
54
+ class TeslemetryVehicles(Vehicles):
55
+ """Class containing and creating vehicles."""
56
+
57
+ def create(self, vin: str) -> TeslemetryVehicleFleet:
58
+ """Creates a specific vehicle."""
59
+ return self.createFleet(vin)
60
+
61
+ def createFleet(self, vin: str) -> TeslemetryVehicleFleet:
62
+ """Creates a specific vehicle."""
63
+ vehicle = TeslemetryVehicleFleet(self._parent, vin)
64
+ self[vin] = vehicle
65
+ return vehicle
66
+
67
+ def createSigned(self, vin: str):
68
+ """Creates a specific vehicle."""
69
+ raise NotImplementedError("Signing is handled by Teslemetry server-side")
70
+
71
+ def createBluetooth(self, vin: str):
72
+ """Creates a specific vehicle."""
73
+ raise NotImplementedError("Bluetooth is only handled locally")
@@ -0,0 +1,5 @@
1
+ from .tessie import Tessie
2
+
3
+ __all__ = [
4
+ "Tessie",
5
+ ]
@@ -1,23 +1,31 @@
1
1
  import aiohttp
2
2
  from typing import Any
3
- from .teslafleetapi import TeslaFleetApi
4
- from .const import Method
5
3
 
4
+ from ..tesla.charging import Charging
5
+ from ..tesla.energysite import EnergySites
6
+ from ..tesla.user import User
7
+ from ..tesla import TeslaFleetApi
8
+ from ..const import Method
9
+ from .vehicle import TessieVehicles
6
10
 
7
11
  class Tessie(TeslaFleetApi):
12
+
13
+ server="https://api.tessie.com"
14
+
8
15
  def __init__(
9
16
  self,
10
17
  session: aiohttp.ClientSession,
11
18
  access_token: str,
12
19
  ):
13
20
  """Initialize the Tessie API."""
14
- super().__init__(
15
- session,
16
- access_token,
17
- server="https://api.tessie.com",
18
- partner_scope=False,
19
- user_scope=False,
20
- )
21
+
22
+ self.session = session
23
+ self.access_token = access_token
24
+
25
+ self.charging = Charging(self)
26
+ self.energySites = EnergySites(self)
27
+ self.user = User(self)
28
+ self.vehicle = TessieVehicles(self)
21
29
 
22
30
  async def scopes(self) -> list[str]:
23
31
  """Get user scopes."""
@@ -0,0 +1,41 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING, Any
3
+
4
+ from ..const import Method
5
+ from ..tesla.vehicle.proto.universal_message_pb2 import Domain
6
+ from ..tesla.vehicle.vehicle import Vehicle
7
+ from ..tesla.vehicle.vehicles import Vehicles
8
+ from ..tesla.vehicle.bluetooth import VehicleBluetooth
9
+ from ..tesla.vehicle.fleet import VehicleFleet
10
+
11
+ if TYPE_CHECKING:
12
+ from .tessie import Tessie
13
+
14
+ class TessieVehicle(Vehicle):
15
+ """Tessie specific base vehicle."""
16
+ pass
17
+
18
+ class TessieVehicleFleet(VehicleFleet):
19
+ """Tessie specific API vehicle."""
20
+ pass
21
+
22
+ class TessieVehicles(Vehicles):
23
+ """Class containing and creating vehicles."""
24
+
25
+ def create(self, vin: str) -> TessieVehicleFleet:
26
+ """Creates a specific vehicle."""
27
+ return self.createFleet(vin)
28
+
29
+ def createFleet(self, vin: str) -> TessieVehicleFleet:
30
+ """Creates a specific vehicle."""
31
+ vehicle = TessieVehicleFleet(self._parent, vin)
32
+ self[vin] = vehicle
33
+ return vehicle
34
+
35
+ def createSigned(self, vin: str):
36
+ """Creates a specific vehicle."""
37
+ raise NotImplementedError("Signing is handled by Tessie server-side")
38
+
39
+ def createBluetooth(self, vin: str):
40
+ """Creates a specific vehicle."""
41
+ raise NotImplementedError("Bluetooth is only handled locally")
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tesla_fleet_api
3
- Version: 0.9.10
3
+ Version: 1.0.1
4
4
  Summary: Tesla Fleet API library for Python
5
5
  Home-page: https://github.com/Teslemetry/python-tesla-fleet-api
6
6
  Author: Brett Adams
7
7
  Author-email: hello@teslemetry.com
8
- Classifier: Development Status :: 4 - Beta
8
+ Classifier: Development Status :: 5 - Production/Stable
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Classifier: License :: OSI Approved :: Apache Software License
11
11
  Classifier: Operating System :: OS Independent
@@ -17,6 +17,7 @@ Requires-Dist: aiofiles
17
17
  Requires-Dist: aiolimiter
18
18
  Requires-Dist: cryptography
19
19
  Requires-Dist: protobuf
20
+ Requires-Dist: bleak
20
21
  Dynamic: author
21
22
  Dynamic: author-email
22
23
  Dynamic: classifier
@@ -0,0 +1,51 @@
1
+ tesla_fleet_api/__init__.py,sha256=FewtEncMLxOZa3dVA3SsT3tY--RMNF9-GXIpOTkbXvk,396
2
+ tesla_fleet_api/const.py,sha256=8KPO_bQbwwspp1Gm-DrHt4EsuQQSFsp1n9yMk0b2hZA,3158
3
+ tesla_fleet_api/exceptions.py,sha256=nTo9MIJrAxL-UxzbrMrr00QhSvrLaSc6ee00Ko9pB1Q,34213
4
+ tesla_fleet_api/ratecalculator.py,sha256=4lz8yruUeouHXh_3ezsXX-CTpIegp1T1J4VuRV_qdHA,1791
5
+ tesla_fleet_api/tesla/__init__.py,sha256=sWIkVh4lesdp5eGQPC9Hjk_eoyN1_g9zz7vpMsJzTgo,219
6
+ tesla_fleet_api/tesla/bluetooth.py,sha256=7L6U8_xr2JiAX2YJOCLcsCOD7NkGdLLSf3-qnopHQtg,1092
7
+ tesla_fleet_api/tesla/charging.py,sha256=9zNSFi9vo8v03KQRKyosO5me49_tDrg3_25BRZibfQ0,1690
8
+ tesla_fleet_api/tesla/energysite.py,sha256=jauUrh14LL-EaMruxhye1YsNHjtTMmgCl1HCf_8mBeI,6070
9
+ tesla_fleet_api/tesla/fleet.py,sha256=NCkHLd-ddpa0wkSu_CEOG7ru9ea5HTLXud4lvkh3DWM,5516
10
+ tesla_fleet_api/tesla/oauth.py,sha256=pFGtIcERjsNKrO5VUEHm8WsNo1xF4DVbx3Yt2MhlGPQ,4070
11
+ tesla_fleet_api/tesla/partner.py,sha256=TU3Xg18x2w3PHv6Dy3Mo40pb417pp5lqnF0c1vDCt6g,1224
12
+ tesla_fleet_api/tesla/tesla.py,sha256=Jlz90-fM0nJbhnQN0k3ukNv59-9KqZZbyQ91IiLIbfo,2010
13
+ tesla_fleet_api/tesla/user.py,sha256=1LVwarEU-wmkqkPw0LGvNiPRy6uGRZkYL-vr17sz51M,1180
14
+ tesla_fleet_api/tesla/vehicle/__init__.py,sha256=luJKFuTGxmo4ef4tURaZgYwdkmWqCQrjxKogQzlFBtI,265
15
+ tesla_fleet_api/tesla/vehicle/bluetooth.py,sha256=QjnFT4UYNsS4UWD_Spq-2T6Qlh4HnVCX_1ZCS18XjT8,8153
16
+ tesla_fleet_api/tesla/vehicle/commands.py,sha256=INHps_29kPjblFSFJdQCrf2Ob3tURy6J9pO85NbGDVU,46874
17
+ tesla_fleet_api/tesla/vehicle/fleet.py,sha256=j9jGE6kGUnmlO6kvB2CBJcwaEPaJ-CGxP7Cgv2AI9AU,32018
18
+ tesla_fleet_api/tesla/vehicle/signed.py,sha256=lhf_zzMc9xL9P2S8GC7IQC-CEVkQNUIrT_gR8AvODCc,1659
19
+ tesla_fleet_api/tesla/vehicle/vehicle.py,sha256=kbL6o-doro5wD-pMBbFcphfSUz1jNApfAUDEZmleKNs,485
20
+ tesla_fleet_api/tesla/vehicle/vehicles.py,sha256=gG7I9tCr3-fag5DSLK2lXayBpjbgEpE61DeDzJZs4f8,1449
21
+ tesla_fleet_api/tesla/vehicle/proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ tesla_fleet_api/tesla/vehicle/proto/__init__.pyi,sha256=qFXWNIgl71wB260u-XPzaAwWAHL6krw21q-aXnBtop0,252
23
+ tesla_fleet_api/tesla/vehicle/proto/car_server_pb2.py,sha256=v_eb4NDIkx_ZYPYW29_EFRky5vQ4b2q14gwuQSbouYw,29202
24
+ tesla_fleet_api/tesla/vehicle/proto/car_server_pb2.pyi,sha256=qkig9HEsOE4Dk2-r38BAWOyALqt7CtUnlirgSVt_oa8,46334
25
+ tesla_fleet_api/tesla/vehicle/proto/common_pb2.py,sha256=C5O6BBTckU3F-XItLfivaPG_XVCnzF_JX4mpVfM_jFk,3931
26
+ tesla_fleet_api/tesla/vehicle/proto/common_pb2.pyi,sha256=8aZiigp74MfSOMpHtMw0D9Jj0kwPz1zV_BIZfVWhh_0,5012
27
+ tesla_fleet_api/tesla/vehicle/proto/errors_pb2.py,sha256=nfOvriyjVgVxnJZIAYNRHiBa1_14dOXhC9Pokc5anV8,1631
28
+ tesla_fleet_api/tesla/vehicle/proto/errors_pb2.pyi,sha256=CNsAR7Oe6wavnqjzhInEyAFxMio6TtXfaNT0DUztn6o,1478
29
+ tesla_fleet_api/tesla/vehicle/proto/keys_pb2.py,sha256=-hyVP9-W1DypTYLaWwkOSUzgia6l9R3M9wUIgvNs-T0,1252
30
+ tesla_fleet_api/tesla/vehicle/proto/keys_pb2.pyi,sha256=HH-TfhE5ihwmoPCGdiVnZ5B7KkaMJglEpusgLc1J02M,676
31
+ tesla_fleet_api/tesla/vehicle/proto/managed_charging_pb2.py,sha256=4crkLo6uC0YPkgw90jRjAqlGMFnRze_koUt2-pw14m4,1430
32
+ tesla_fleet_api/tesla/vehicle/proto/managed_charging_pb2.pyi,sha256=SqEmrfknTfzYTUYHtsoCpt1Fw2YpU3OyQllX247UfyQ,1227
33
+ tesla_fleet_api/tesla/vehicle/proto/signatures_pb2.py,sha256=TRaJ6lzmJtryhhmBC_PbYzftc-pqCmwC6wuBCXHeuTg,4734
34
+ tesla_fleet_api/tesla/vehicle/proto/signatures_pb2.pyi,sha256=-OGm9ctBnEJiXk-3nkFCPRTxKgFiqFgMbKeq3x2zGGM,6101
35
+ tesla_fleet_api/tesla/vehicle/proto/universal_message_pb2.py,sha256=UklH73qoYsqxylie6IK8iIcw2tmykSqDiaBKSWz66OQ,5093
36
+ tesla_fleet_api/tesla/vehicle/proto/universal_message_pb2.pyi,sha256=a_RygTJL26v0rA7QuUwsxiG1_ZBcliwXCqOAqTIJ6UE,7647
37
+ tesla_fleet_api/tesla/vehicle/proto/vcsec_pb2.py,sha256=PDv9TfiXnNs6sQ0D5vBrsSSPinSqu3eBUwvTcG8xMWo,15919
38
+ tesla_fleet_api/tesla/vehicle/proto/vcsec_pb2.pyi,sha256=cyK1uyRtDjRVqVlyl5uRQYY1RhFlWSJheLg3PGfs-_s,28524
39
+ tesla_fleet_api/tesla/vehicle/proto/vehicle_pb2.py,sha256=bqyFJM-1qZ7W9XKREINhYZx8yXAudmq6W8_Pdfkhbkk,44711
40
+ tesla_fleet_api/tesla/vehicle/proto/vehicle_pb2.pyi,sha256=sAUW_9aVB8NqJCnhZjXMLfqfePLVZv_7PfSKZKEBaQA,74251
41
+ tesla_fleet_api/teslemetry/__init__.py,sha256=OnHrZEkPGVFrziwMA-vArvh5vgBn6vT_nMbIhjN49V0,68
42
+ tesla_fleet_api/teslemetry/teslemetry.py,sha256=BtV__OSenTg_dwM0aovbL--mv3HhIIWtoWHQp58sViQ,2990
43
+ tesla_fleet_api/teslemetry/vehicle.py,sha256=aCe4Vhs4WHd6OQ-gzdxsPubKF_C5aLBoHrDvzyVgucI,2277
44
+ tesla_fleet_api/tessie/__init__.py,sha256=UNsWgx5w0DJSIFcMd7jBBdSxklF3Vhubq9tSL8vfegg,56
45
+ tesla_fleet_api/tessie/tessie.py,sha256=Z6t-ulDL7zfBIAJ6L7EBUMux2iawWjR1cR4jvYIhVFg,2523
46
+ tesla_fleet_api/tessie/vehicle.py,sha256=C2Q0en3Uo3xtI2sU9jSHXUtYhgBrNJYYhl8gP2zVmfQ,1315
47
+ tesla_fleet_api-1.0.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
48
+ tesla_fleet_api-1.0.1.dist-info/METADATA,sha256=6wVdb-DMTVaAa9hKPrYQNjphXXMbE6Rabxf003sDSB8,4056
49
+ tesla_fleet_api-1.0.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
50
+ tesla_fleet_api-1.0.1.dist-info/top_level.txt,sha256=jeNbog_1saXBFrGpom9WyPWmilxsyP3szL_G7JLWQfM,16
51
+ tesla_fleet_api-1.0.1.dist-info/RECORD,,
@@ -1,125 +0,0 @@
1
- from __future__ import annotations
2
- from typing import Any, TYPE_CHECKING
3
- from .const import EnergyExportMode, EnergyOperationMode, TeslaEnergyPeriod
4
-
5
- if TYPE_CHECKING:
6
- from .energy import Energy
7
-
8
-
9
- class EnergySpecific:
10
- """Class describing the Tesla Fleet API partner endpoints"""
11
-
12
- _parent: Energy
13
- energy_site_id: int
14
-
15
- def __init__(
16
- self,
17
- parent: Energy,
18
- energy_site_id: int,
19
- ):
20
- self._parent = parent
21
- self.energy_site_id = energy_site_id
22
-
23
- async def backup(self, backup_reserve_percent: int) -> dict[str, Any]:
24
- """Adjust the site's backup reserve."""
25
- return await self._parent.backup(
26
- self.energy_site_id,
27
- backup_reserve_percent,
28
- )
29
-
30
- async def backup_history(
31
- self,
32
- period: TeslaEnergyPeriod | str,
33
- start_date: str | None = None,
34
- end_date: str | None = None,
35
- time_zone: str | None = None,
36
- ) -> dict[str, Any]:
37
- """Returns the backup (off-grid) event history of the site in duration of seconds."""
38
- return await self._parent.backup_history(
39
- self.energy_site_id,
40
- period,
41
- start_date,
42
- end_date,
43
- time_zone,
44
- )
45
-
46
- async def charge_history(
47
- self,
48
- start_date: str,
49
- end_date: str,
50
- time_zone: str | None = None,
51
- ) -> dict[str, Any]:
52
- """Returns the charging history of a wall connector."""
53
- return await self._parent.charge_history(
54
- self.energy_site_id,
55
- start_date,
56
- end_date,
57
- time_zone,
58
- )
59
-
60
- async def energy_history(
61
- self,
62
- period: TeslaEnergyPeriod | str,
63
- start_date: str | None = None,
64
- end_date: str | None = None,
65
- time_zone: str | None = None,
66
- ) -> dict[str, Any]:
67
- """Returns the energy measurements of the site, aggregated to the requested period."""
68
- return await self._parent.energy_history(
69
- self.energy_site_id,
70
- period,
71
- start_date,
72
- end_date,
73
- time_zone,
74
- )
75
-
76
- async def grid_import_export(
77
- self,
78
- disallow_charge_from_grid_with_solar_installed: bool | None = None,
79
- customer_preferred_export_rule: EnergyExportMode | str | None = None,
80
- ) -> dict[str, Any]:
81
- """Allow/disallow charging from the grid and exporting energy to the grid."""
82
- return await self._parent.grid_import_export(
83
- self.energy_site_id,
84
- disallow_charge_from_grid_with_solar_installed,
85
- customer_preferred_export_rule,
86
- )
87
-
88
- async def live_status(self) -> dict[str, Any]:
89
- """Returns the live status of the site (power, state of energy, grid status, storm mode)."""
90
- return await self._parent.live_status(self.energy_site_id)
91
-
92
- async def off_grid_vehicle_charging_reserve(
93
- self, off_grid_vehicle_charging_reserve_percent: int
94
- ) -> dict[str, Any]:
95
- """Adjust the site's off-grid vehicle charging backup reserve."""
96
- return await self._parent.off_grid_vehicle_charging_reserve(
97
- self.energy_site_id, off_grid_vehicle_charging_reserve_percent
98
- )
99
-
100
- async def operation(
101
- self, default_real_mode: EnergyOperationMode | str
102
- ) -> dict[str, Any]:
103
- """Set the site's mode."""
104
- return await self._parent.operation(
105
- self.energy_site_id,
106
- default_real_mode,
107
- )
108
-
109
- async def site_info(self) -> dict[str, Any]:
110
- """Returns information about the site. Things like assets (has solar, etc), settings (backup reserve, etc), and features (storm_mode_capable, etc)."""
111
- return await self._parent.site_info(self.energy_site_id)
112
-
113
- async def storm_mode(self, enabled: bool) -> dict[str, Any]:
114
- """Update storm watch participation."""
115
- return await self._parent.storm_mode(
116
- self.energy_site_id,
117
- enabled,
118
- )
119
-
120
- async def time_of_use_settings(self, settings: dict[str, Any]) -> dict[str, Any]:
121
- """Update the site's time of use settings."""
122
- return await self._parent.time_of_use_settings(
123
- self.energy_site_id,
124
- settings,
125
- )
@@ -1,61 +0,0 @@
1
- import aiohttp
2
- import time
3
- import secrets
4
- import hashlib
5
- import base64
6
-
7
- from .teslafleetoauth import TeslaFleetOAuth
8
- from .const import Scope, SERVERS
9
-
10
-
11
- class TeslaFleetOpenSource(TeslaFleetOAuth):
12
- """Tesla Fleet Open Source OAuth API."""
13
-
14
- code_verifier: str
15
- code_challenge: str
16
-
17
- def __init__(
18
- self,
19
- session: aiohttp.ClientSession,
20
- client_id: str,
21
- redirect_uri: str,
22
- ):
23
- self.code_verifier = secrets.token_urlsafe(32)
24
-
25
- # Hash the code_verifier using SHA-256
26
- hashed_verifier = hashlib.sha256(self.code_verifier.encode()).digest()
27
- # Encode the hash using URL-safe Base64 encoding, without padding
28
- self.code_challenge = (
29
- base64.urlsafe_b64encode(hashed_verifier).decode().replace("=", "")
30
- )
31
-
32
- super().__init__(session, client_id, redirect_uri=redirect_uri)
33
-
34
- def get_login_url(self, scopes: list[Scope], state: str = "login") -> str:
35
- """Get the login URL without a client secret."""
36
-
37
- return (
38
- super().get_login_url(scopes, state)
39
- + f"&code_challenge={self.code_challenge}"
40
- )
41
-
42
- async def get_refresh_token(self, code: str) -> None:
43
- """Get the refresh token."""
44
- async with self.session.post(
45
- "https://auth.tesla.com/oauth2/v3/token",
46
- data={
47
- "grant_type": "authorization_code",
48
- "client_id": self.client_id,
49
- "code": code,
50
- "audience": self.server,
51
- "redirect_uri": self.redirect_uri,
52
- "code_verifier": self.code_verifier,
53
- },
54
- ) as resp:
55
- if resp.ok:
56
- data = await resp.json()
57
- self.refresh_token = data["refresh_token"]
58
- self.access_token = data["access_token"]
59
- self.expires = int(time.time()) + data["expires_in"]
60
- region = code.split("_")[0].lower()
61
- self.server = SERVERS.get(region)