tesla-fleet-api 0.9.10__py3-none-any.whl → 1.0.1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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)