tesla-fleet-api 0.9.9__tar.gz → 1.0.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {tesla_fleet_api-0.9.9/tesla_fleet_api.egg-info → tesla_fleet_api-1.0.0}/PKG-INFO +3 -2
- tesla_fleet_api-1.0.0/pyproject.toml +2 -0
- {tesla_fleet_api-0.9.9 → tesla_fleet_api-1.0.0}/setup.py +3 -3
- tesla_fleet_api-1.0.0/tesla_fleet_api/__init__.py +15 -0
- tesla_fleet_api-1.0.0/tesla_fleet_api/const.py +161 -0
- {tesla_fleet_api-0.9.9 → tesla_fleet_api-1.0.0}/tesla_fleet_api/exceptions.py +117 -0
- tesla_fleet_api-1.0.0/tesla_fleet_api/tesla/__init__.py +11 -0
- tesla_fleet_api-1.0.0/tesla_fleet_api/tesla/bluetooth.py +33 -0
- {tesla_fleet_api-0.9.9/tesla_fleet_api → tesla_fleet_api-1.0.0/tesla_fleet_api/tesla}/charging.py +1 -1
- tesla_fleet_api-0.9.9/tesla_fleet_api/energy.py → tesla_fleet_api-1.0.0/tesla_fleet_api/tesla/energysite.py +41 -33
- tesla_fleet_api-0.9.9/tesla_fleet_api/teslafleetapi.py → tesla_fleet_api-1.0.0/tesla_fleet_api/tesla/fleet.py +8 -53
- tesla_fleet_api-0.9.9/tesla_fleet_api/teslafleetoauth.py → tesla_fleet_api-1.0.0/tesla_fleet_api/tesla/oauth.py +3 -4
- {tesla_fleet_api-0.9.9/tesla_fleet_api → tesla_fleet_api-1.0.0/tesla_fleet_api/tesla}/partner.py +1 -1
- tesla_fleet_api-1.0.0/tesla_fleet_api/tesla/tesla.py +52 -0
- {tesla_fleet_api-0.9.9/tesla_fleet_api → tesla_fleet_api-1.0.0/tesla_fleet_api/tesla}/user.py +1 -1
- tesla_fleet_api-1.0.0/tesla_fleet_api/teslemetry/__init__.py +5 -0
- {tesla_fleet_api-0.9.9/tesla_fleet_api → tesla_fleet_api-1.0.0/tesla_fleet_api/teslemetry}/teslemetry.py +16 -25
- tesla_fleet_api-1.0.0/tesla_fleet_api/teslemetry/vehicle.py +73 -0
- tesla_fleet_api-1.0.0/tesla_fleet_api/tessie/__init__.py +5 -0
- {tesla_fleet_api-0.9.9/tesla_fleet_api → tesla_fleet_api-1.0.0/tesla_fleet_api/tessie}/tessie.py +17 -9
- tesla_fleet_api-1.0.0/tesla_fleet_api/tessie/vehicle.py +41 -0
- {tesla_fleet_api-0.9.9 → tesla_fleet_api-1.0.0/tesla_fleet_api.egg-info}/PKG-INFO +3 -2
- tesla_fleet_api-1.0.0/tesla_fleet_api.egg-info/SOURCES.txt +28 -0
- {tesla_fleet_api-0.9.9 → tesla_fleet_api-1.0.0}/tesla_fleet_api.egg-info/requires.txt +1 -0
- tesla_fleet_api-0.9.9/tesla_fleet_api/__init__.py +0 -30
- tesla_fleet_api-0.9.9/tesla_fleet_api/const.py +0 -385
- tesla_fleet_api-0.9.9/tesla_fleet_api/energyspecific.py +0 -125
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/__init__.py +0 -0
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/__init__.pyi +0 -9
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/car_server_pb2.py +0 -175
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/car_server_pb2.pyi +0 -904
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/common_pb2.py +0 -33
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/common_pb2.pyi +0 -130
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/errors_pb2.py +0 -17
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/errors_pb2.pyi +0 -32
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/keys_pb2.py +0 -15
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/keys_pb2.pyi +0 -21
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/managed_charging_pb2.py +0 -15
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/managed_charging_pb2.pyi +0 -17
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/signatures_pb2.py +0 -35
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/signatures_pb2.pyi +0 -152
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/universal_message_pb2.py +0 -30
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/universal_message_pb2.pyi +0 -148
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/vcsec_pb2.py +0 -79
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/vcsec_pb2.pyi +0 -482
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/vehicle_pb2.py +0 -125
- tesla_fleet_api-0.9.9/tesla_fleet_api/pb2/vehicle_pb2.pyi +0 -1183
- tesla_fleet_api-0.9.9/tesla_fleet_api/teslafleetopensource.py +0 -61
- tesla_fleet_api-0.9.9/tesla_fleet_api/vehicle.py +0 -878
- tesla_fleet_api-0.9.9/tesla_fleet_api/vehiclesigned.py +0 -1127
- tesla_fleet_api-0.9.9/tesla_fleet_api/vehiclespecific.py +0 -505
- tesla_fleet_api-0.9.9/tesla_fleet_api.egg-info/SOURCES.txt +0 -45
- {tesla_fleet_api-0.9.9 → tesla_fleet_api-1.0.0}/LICENSE +0 -0
- {tesla_fleet_api-0.9.9 → tesla_fleet_api-1.0.0}/README.md +0 -0
- {tesla_fleet_api-0.9.9 → tesla_fleet_api-1.0.0}/setup.cfg +0 -0
- {tesla_fleet_api-0.9.9 → tesla_fleet_api-1.0.0}/tesla_fleet_api/ratecalculator.py +0 -0
- {tesla_fleet_api-0.9.9 → tesla_fleet_api-1.0.0}/tesla_fleet_api.egg-info/dependency_links.txt +0 -0
- {tesla_fleet_api-0.9.9 → tesla_fleet_api-1.0.0}/tesla_fleet_api.egg-info/top_level.txt +0 -0
@@ -1,11 +1,11 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: tesla_fleet_api
|
3
|
-
Version: 0.
|
3
|
+
Version: 1.0.0
|
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 ::
|
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
|
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
|
5
5
|
|
6
6
|
setuptools.setup(
|
7
7
|
name="tesla_fleet_api",
|
8
|
-
version="0.
|
8
|
+
version="1.0.0",
|
9
9
|
author="Brett Adams",
|
10
10
|
author_email="hello@teslemetry.com",
|
11
11
|
description="Tesla Fleet API library for Python",
|
@@ -14,11 +14,11 @@ setuptools.setup(
|
|
14
14
|
url="https://github.com/Teslemetry/python-tesla-fleet-api",
|
15
15
|
packages=setuptools.find_packages(),
|
16
16
|
classifiers=[
|
17
|
-
"Development Status ::
|
17
|
+
"Development Status :: 5 - Production/Stable",
|
18
18
|
"Programming Language :: Python :: 3",
|
19
19
|
"License :: OSI Approved :: Apache Software License",
|
20
20
|
"Operating System :: OS Independent",
|
21
21
|
],
|
22
22
|
python_requires=">=3.10",
|
23
|
-
install_requires=["aiohttp", "aiofiles", "aiolimiter", "cryptography", "protobuf"],
|
23
|
+
install_requires=["aiohttp", "aiofiles", "aiolimiter", "cryptography", "protobuf", "bleak"],
|
24
24
|
)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
from .tesla.fleet import TeslaFleetApi
|
2
|
+
from .tesla.bluetooth import TeslaBluetooth
|
3
|
+
from .tesla.oauth import TeslaFleetOAuth
|
4
|
+
from .tesla.opensource import TeslaFleetOpenSource
|
5
|
+
from .teslemetry.teslemetry import Teslemetry
|
6
|
+
from .tessie.tessie import Tessie
|
7
|
+
|
8
|
+
__all__ = [
|
9
|
+
"TeslaFleetApi",
|
10
|
+
"TeslaBluetooth",
|
11
|
+
"TeslaFleetOAuth",
|
12
|
+
"TeslaFleetOpenSource",
|
13
|
+
"Teslemetry",
|
14
|
+
"Tessie",
|
15
|
+
]
|
@@ -0,0 +1,161 @@
|
|
1
|
+
"""Tesla Fleet API constants."""
|
2
|
+
|
3
|
+
from enum import Enum
|
4
|
+
import logging
|
5
|
+
|
6
|
+
VERSION = "1.0.0"
|
7
|
+
LOGGER = logging.getLogger(__package__)
|
8
|
+
SERVERS = {
|
9
|
+
"na": "https://fleet-api.prd.na.vn.cloud.tesla.com",
|
10
|
+
"eu": "https://fleet-api.prd.eu.vn.cloud.tesla.com",
|
11
|
+
"cn": "https://fleet-api.prd.cn.vn.cloud.tesla.cn",
|
12
|
+
}
|
13
|
+
|
14
|
+
|
15
|
+
class IntEnum(int, Enum):
|
16
|
+
"""Integer Enum."""
|
17
|
+
|
18
|
+
def __str__(self) -> str:
|
19
|
+
return str(self.value)
|
20
|
+
|
21
|
+
|
22
|
+
class StrEnum(str, Enum):
|
23
|
+
"""String Enum."""
|
24
|
+
|
25
|
+
def __str__(self) -> str:
|
26
|
+
return self.value
|
27
|
+
|
28
|
+
|
29
|
+
class Method(StrEnum):
|
30
|
+
"""HTTP Methods."""
|
31
|
+
|
32
|
+
GET = "GET"
|
33
|
+
POST = "POST"
|
34
|
+
DELETE = "DELETE"
|
35
|
+
|
36
|
+
|
37
|
+
class Trunk(StrEnum):
|
38
|
+
"""Trunk options"""
|
39
|
+
|
40
|
+
FRONT = "front"
|
41
|
+
REAR = "rear"
|
42
|
+
|
43
|
+
|
44
|
+
class Seat(IntEnum):
|
45
|
+
"""Seat positions"""
|
46
|
+
|
47
|
+
FRONT_LEFT = 0
|
48
|
+
FRONT_RIGHT = 1
|
49
|
+
REAR_LEFT = 2
|
50
|
+
REAR_CENTER = 4
|
51
|
+
REAR_RIGHT = 5
|
52
|
+
THIRD_LEFT = 6
|
53
|
+
THIRD_RIGHT = 7
|
54
|
+
|
55
|
+
|
56
|
+
class Level(IntEnum):
|
57
|
+
"""Level options"""
|
58
|
+
|
59
|
+
OFF = 0
|
60
|
+
LOW = 1
|
61
|
+
MEDIUM = 2
|
62
|
+
HIGH = 3
|
63
|
+
|
64
|
+
|
65
|
+
class ClimateKeeperMode(IntEnum):
|
66
|
+
"""Climate Keeper Mode options"""
|
67
|
+
|
68
|
+
OFF = 0
|
69
|
+
KEEP_MODE = 1
|
70
|
+
DOG_MODE = 2
|
71
|
+
CAMP_MODE = 3
|
72
|
+
|
73
|
+
|
74
|
+
class CabinOverheatProtectionTemp(IntEnum):
|
75
|
+
"""COP Temp options"""
|
76
|
+
|
77
|
+
LOW = 0 # 30C 90F
|
78
|
+
MEDIUM = 1 # 35C 95F
|
79
|
+
HIGH = 2 # 40C 100F
|
80
|
+
|
81
|
+
|
82
|
+
class VehicleDataEndpoint(StrEnum):
|
83
|
+
"""Endpoints options"""
|
84
|
+
|
85
|
+
CHARGE_STATE = "charge_state"
|
86
|
+
CLIMATE_STATE = "climate_state"
|
87
|
+
CLOSURES_STATE = "closures_state"
|
88
|
+
DRIVE_STATE = "drive_state"
|
89
|
+
GUI_SETTINGS = "gui_settings"
|
90
|
+
LOCATION_DATA = "location_data"
|
91
|
+
CHARGE_SCHEDULE_DATA = "charge_schedule_data"
|
92
|
+
PRECONDITIONING_SCHEDULE_DATA = "preconditioning_schedule_data"
|
93
|
+
VEHICLE_CONFIG = "vehicle_config"
|
94
|
+
VEHICLE_STATE = "vehicle_state"
|
95
|
+
VEHICLE_DATA_COMBO = "vehicle_data_combo"
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
class SunRoofCommand(StrEnum):
|
100
|
+
"""Sunroof options"""
|
101
|
+
|
102
|
+
STOP = "stop"
|
103
|
+
CLOSE = "close"
|
104
|
+
VENT = "vent"
|
105
|
+
|
106
|
+
|
107
|
+
class WindowCommand(StrEnum):
|
108
|
+
"""Window Control options"""
|
109
|
+
|
110
|
+
VENT = "vent"
|
111
|
+
CLOSE = "close"
|
112
|
+
|
113
|
+
|
114
|
+
class DeviceType(StrEnum):
|
115
|
+
"""Device Type options"""
|
116
|
+
|
117
|
+
ANDROID = "android"
|
118
|
+
IOS_DEVELOPMENT = "ios-development"
|
119
|
+
IOS_ENTERPRISE = "ios-enterprise"
|
120
|
+
IOS_BETA = "ios-beta"
|
121
|
+
IOS_PRODUCTION = "ios-production"
|
122
|
+
|
123
|
+
|
124
|
+
class Scope(StrEnum):
|
125
|
+
"""Fleet API Scope"""
|
126
|
+
|
127
|
+
OPENID = "openid"
|
128
|
+
OFFLINE_ACCESS = "offline_access"
|
129
|
+
USER_DATA = "user_data"
|
130
|
+
VEHICLE_DEVICE_DATA = "vehicle_device_data"
|
131
|
+
VEHICLE_LOCATION = "vehicle_location"
|
132
|
+
VEHICLE_CMDS = "vehicle_cmds"
|
133
|
+
VEHICLE_CHARGING_CMDS = "vehicle_charging_cmds"
|
134
|
+
ENERGY_DEVICE_DATA = "energy_device_data"
|
135
|
+
ENERGY_CMDS = "energy_cmds"
|
136
|
+
|
137
|
+
|
138
|
+
class EnergyOperationMode(StrEnum):
|
139
|
+
"""Energy Operation Mode options"""
|
140
|
+
|
141
|
+
AUTONOMOUS = "autonomous"
|
142
|
+
SELF_CONSUMPTION = "self_consumption"
|
143
|
+
BACKUP = "backup"
|
144
|
+
|
145
|
+
|
146
|
+
class EnergyExportMode(StrEnum):
|
147
|
+
"""Energy Export Mode options"""
|
148
|
+
|
149
|
+
BATTERY_OK = "battery_ok"
|
150
|
+
PV_ONLY = "pv_only"
|
151
|
+
NEVER = "never"
|
152
|
+
|
153
|
+
|
154
|
+
class TeslaEnergyPeriod(StrEnum):
|
155
|
+
"""Period for history for energy sites"""
|
156
|
+
|
157
|
+
DAY = "day"
|
158
|
+
WEEK = "week"
|
159
|
+
MONTH = "month"
|
160
|
+
YEAR = "year"
|
161
|
+
LIFETIME = "lifetime"
|
@@ -853,6 +853,123 @@ SIGNED_MESSAGE_INFORMATION_FAULTS = [
|
|
853
853
|
SignedMessageInformationFaultCouldNotHashMetadata,
|
854
854
|
]
|
855
855
|
|
856
|
+
class WhitelistOperationStatus(TeslaFleetError):
|
857
|
+
message = "Whitelist operation failed"
|
858
|
+
|
859
|
+
class WhitelistOperationUndocumentedError(WhitelistOperationStatus):
|
860
|
+
message = "Undocumented whitelist operation error"
|
861
|
+
code = 1
|
862
|
+
|
863
|
+
class WhitelistOperationNoPermissionToRemoveOneself(WhitelistOperationStatus):
|
864
|
+
message = "No permission to remove oneself from whitelist"
|
865
|
+
code = 2
|
866
|
+
|
867
|
+
class WhitelistOperationKeyfobSlotsFull(WhitelistOperationStatus):
|
868
|
+
message = "Keyfob slots are full"
|
869
|
+
code = 3
|
870
|
+
|
871
|
+
class WhitelistOperationWhitelistFull(WhitelistOperationStatus):
|
872
|
+
message = "Whitelist is full"
|
873
|
+
code = 4
|
874
|
+
|
875
|
+
class WhitelistOperationNoPermissionToAdd(WhitelistOperationStatus):
|
876
|
+
message = "No permission to add to whitelist"
|
877
|
+
code = 5
|
878
|
+
|
879
|
+
class WhitelistOperationInvalidPublicKey(WhitelistOperationStatus):
|
880
|
+
message = "Invalid public key"
|
881
|
+
code = 6
|
882
|
+
|
883
|
+
class WhitelistOperationNoPermissionToRemove(WhitelistOperationStatus):
|
884
|
+
message = "No permission to remove from whitelist"
|
885
|
+
code = 7
|
886
|
+
|
887
|
+
class WhitelistOperationNoPermissionToChangePermissions(WhitelistOperationStatus):
|
888
|
+
message = "No permission to change permissions"
|
889
|
+
code = 8
|
890
|
+
|
891
|
+
class WhitelistOperationAttemptingToElevateOthersAboveOneself(WhitelistOperationStatus):
|
892
|
+
message = "Attempting to elevate others above oneself"
|
893
|
+
code = 9
|
894
|
+
|
895
|
+
class WhitelistOperationAttemptingToDemoteSuperiorToOneself(WhitelistOperationStatus):
|
896
|
+
message = "Attempting to demote superior to oneself"
|
897
|
+
code = 10
|
898
|
+
|
899
|
+
class WhitelistOperationAttemptingToRemoveOwnPermissions(WhitelistOperationStatus):
|
900
|
+
message = "Attempting to remove own permissions"
|
901
|
+
code = 11
|
902
|
+
|
903
|
+
class WhitelistOperationPublicKeyNotOnWhitelist(WhitelistOperationStatus):
|
904
|
+
message = "Public key not on whitelist"
|
905
|
+
code = 12
|
906
|
+
|
907
|
+
class WhitelistOperationAttemptingToAddExistingKey(WhitelistOperationStatus):
|
908
|
+
message = "Attempting to add key that is already on the whitelist"
|
909
|
+
code = 13
|
910
|
+
|
911
|
+
class WhitelistOperationNotAllowedToAddUnlessOnReader(WhitelistOperationStatus):
|
912
|
+
message = "Not allowed to add unless on reader"
|
913
|
+
code = 14
|
914
|
+
|
915
|
+
class WhitelistOperationFMModifyingOutsideOfFMode(WhitelistOperationStatus):
|
916
|
+
message = "FM modifying outside of F mode"
|
917
|
+
code = 15
|
918
|
+
|
919
|
+
class WhitelistOperationFMAttemptingToAddPermanentKey(WhitelistOperationStatus):
|
920
|
+
message = "FM attempting to add permanent key"
|
921
|
+
code = 16
|
922
|
+
|
923
|
+
class WhitelistOperationFMAttemptingToRemovePermanentKey(WhitelistOperationStatus):
|
924
|
+
message = "FM attempting to remove permanent key"
|
925
|
+
code = 17
|
926
|
+
|
927
|
+
class WhitelistOperationKeychainWhileFSFull(WhitelistOperationStatus):
|
928
|
+
message = "Keychain while FS full"
|
929
|
+
code = 18
|
930
|
+
|
931
|
+
class WhitelistOperationAttemptingToAddKeyWithoutRole(WhitelistOperationStatus):
|
932
|
+
message = "Attempting to add key without role"
|
933
|
+
code = 19
|
934
|
+
|
935
|
+
class WhitelistOperationAttemptingToAddKeyWithServiceRole(WhitelistOperationStatus):
|
936
|
+
message = "Attempting to add key with service role"
|
937
|
+
code = 20
|
938
|
+
|
939
|
+
class WhitelistOperationNonServiceKeyAttemptingToAddServiceTech(WhitelistOperationStatus):
|
940
|
+
message = "Non-service key attempting to add service tech"
|
941
|
+
code = 21
|
942
|
+
|
943
|
+
class WhitelistOperationServiceKeyAttemptingToAddServiceTechOutsideServiceMode(WhitelistOperationStatus):
|
944
|
+
message = "Service key attempting to add service tech outside service mode"
|
945
|
+
code = 22
|
946
|
+
|
947
|
+
WHITELIST_OPERATION_STATUS = [
|
948
|
+
None,
|
949
|
+
WhitelistOperationUndocumentedError,
|
950
|
+
WhitelistOperationNoPermissionToRemoveOneself,
|
951
|
+
WhitelistOperationKeyfobSlotsFull,
|
952
|
+
WhitelistOperationWhitelistFull,
|
953
|
+
WhitelistOperationNoPermissionToAdd,
|
954
|
+
WhitelistOperationInvalidPublicKey,
|
955
|
+
WhitelistOperationNoPermissionToRemove,
|
956
|
+
WhitelistOperationNoPermissionToChangePermissions,
|
957
|
+
WhitelistOperationAttemptingToElevateOthersAboveOneself,
|
958
|
+
WhitelistOperationAttemptingToDemoteSuperiorToOneself,
|
959
|
+
WhitelistOperationAttemptingToRemoveOwnPermissions,
|
960
|
+
WhitelistOperationPublicKeyNotOnWhitelist,
|
961
|
+
WhitelistOperationAttemptingToAddExistingKey,
|
962
|
+
WhitelistOperationNotAllowedToAddUnlessOnReader,
|
963
|
+
WhitelistOperationFMModifyingOutsideOfFMode,
|
964
|
+
WhitelistOperationFMAttemptingToAddPermanentKey,
|
965
|
+
WhitelistOperationFMAttemptingToRemovePermanentKey,
|
966
|
+
WhitelistOperationKeychainWhileFSFull,
|
967
|
+
WhitelistOperationAttemptingToAddKeyWithoutRole,
|
968
|
+
WhitelistOperationAttemptingToAddKeyWithServiceRole,
|
969
|
+
WhitelistOperationNonServiceKeyAttemptingToAddServiceTech,
|
970
|
+
WhitelistOperationServiceKeyAttemptingToAddServiceTechOutsideServiceMode
|
971
|
+
]
|
972
|
+
|
856
973
|
|
857
974
|
async def raise_for_status(resp: aiohttp.ClientResponse) -> None:
|
858
975
|
"""Raise an exception if the response status code is >=400."""
|
@@ -0,0 +1,33 @@
|
|
1
|
+
"""Bluetooth only interface."""
|
2
|
+
|
3
|
+
import re
|
4
|
+
from .tesla import Tesla
|
5
|
+
from .vehicle.bluetooth import VehicleBluetooth
|
6
|
+
|
7
|
+
class TeslaBluetooth(Tesla):
|
8
|
+
"""Class describing a Tesla Bluetooth connection."""
|
9
|
+
|
10
|
+
def __init__(
|
11
|
+
self,
|
12
|
+
):
|
13
|
+
"""Initialize the Tesla Fleet API."""
|
14
|
+
|
15
|
+
self.vehicles = Vehicles(self)
|
16
|
+
|
17
|
+
def valid_name(self, name: str) -> bool:
|
18
|
+
"""Check if a BLE device name is a valid Tesla vehicle."""
|
19
|
+
return bool(re.match("^S[a-f0-9]{16}[A-F]$", name))
|
20
|
+
|
21
|
+
class Vehicles(dict[str, VehicleBluetooth]):
|
22
|
+
"""Class containing and creating vehicles."""
|
23
|
+
|
24
|
+
_parent: TeslaBluetooth
|
25
|
+
|
26
|
+
def __init__(self, parent: TeslaBluetooth):
|
27
|
+
self._parent = parent
|
28
|
+
|
29
|
+
def createBluetooth(self, vin: str) -> VehicleBluetooth:
|
30
|
+
"""Creates a specific vehicle."""
|
31
|
+
vehicle = VehicleBluetooth(self._parent, vin)
|
32
|
+
self[vin] = vehicle
|
33
|
+
return vehicle
|
@@ -1,37 +1,35 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
from typing import Any, TYPE_CHECKING
|
3
|
-
from
|
4
|
-
from .energyspecific import EnergySpecific
|
3
|
+
from ..const import Method, EnergyOperationMode, EnergyExportMode, TeslaEnergyPeriod
|
5
4
|
|
6
5
|
if TYPE_CHECKING:
|
7
|
-
from .
|
6
|
+
from . import TeslaFleetApi
|
8
7
|
|
9
|
-
|
10
|
-
class Energy:
|
8
|
+
class EnergySite:
|
11
9
|
"""Class describing the Tesla Fleet API partner endpoints"""
|
12
10
|
|
13
|
-
|
11
|
+
energy_site_id: int
|
14
12
|
|
15
|
-
def __init__(
|
13
|
+
def __init__(
|
14
|
+
self,
|
15
|
+
parent: TeslaFleetApi,
|
16
|
+
energy_site_id: int
|
17
|
+
):
|
16
18
|
self._request = parent._request
|
17
|
-
|
18
|
-
def specific(self, energy_site_id: int) -> EnergySpecific:
|
19
|
-
"""Create a specific energy site."""
|
20
|
-
return EnergySpecific(self, energy_site_id)
|
19
|
+
self.energy_site_id = energy_site_id
|
21
20
|
|
22
21
|
async def backup(
|
23
|
-
self,
|
22
|
+
self, backup_reserve_percent: int
|
24
23
|
) -> dict[str, Any]:
|
25
24
|
"""Adjust the site's backup reserve."""
|
26
25
|
return await self._request(
|
27
26
|
Method.POST,
|
28
|
-
f"api/1/energy_sites/{energy_site_id}/backup",
|
27
|
+
f"api/1/energy_sites/{self.energy_site_id}/backup",
|
29
28
|
json={"backup_reserve_percent": backup_reserve_percent},
|
30
29
|
)
|
31
30
|
|
32
31
|
async def backup_history(
|
33
32
|
self,
|
34
|
-
energy_site_id: int,
|
35
33
|
period: TeslaEnergyPeriod | str | None,
|
36
34
|
start_date: str | None = None,
|
37
35
|
end_date: str | None = None,
|
@@ -40,7 +38,7 @@ class Energy:
|
|
40
38
|
"""Returns the backup (off-grid) event history of the site in duration of seconds."""
|
41
39
|
return await self._request(
|
42
40
|
Method.GET,
|
43
|
-
f"api/1/energy_sites/{energy_site_id}/calendar_history",
|
41
|
+
f"api/1/energy_sites/{self.energy_site_id}/calendar_history",
|
44
42
|
params={
|
45
43
|
"kind": "backup",
|
46
44
|
"start_date": start_date,
|
@@ -52,7 +50,6 @@ class Energy:
|
|
52
50
|
|
53
51
|
async def charge_history(
|
54
52
|
self,
|
55
|
-
energy_site_id: int,
|
56
53
|
start_date: str,
|
57
54
|
end_date: str,
|
58
55
|
time_zone: str | None = None,
|
@@ -60,7 +57,7 @@ class Energy:
|
|
60
57
|
"""Returns the charging history of a wall connector."""
|
61
58
|
return await self._request(
|
62
59
|
Method.GET,
|
63
|
-
f"api/1/energy_sites/{energy_site_id}/telemetry_history",
|
60
|
+
f"api/1/energy_sites/{self.energy_site_id}/telemetry_history",
|
64
61
|
params={
|
65
62
|
"kind": "charge",
|
66
63
|
"start_date": start_date,
|
@@ -71,7 +68,6 @@ class Energy:
|
|
71
68
|
|
72
69
|
async def energy_history(
|
73
70
|
self,
|
74
|
-
energy_site_id: int,
|
75
71
|
period: TeslaEnergyPeriod | str | None,
|
76
72
|
start_date: str | None = None,
|
77
73
|
end_date: str | None = None,
|
@@ -80,7 +76,7 @@ class Energy:
|
|
80
76
|
"""Returns the energy measurements of the site, aggregated to the requested period."""
|
81
77
|
return await self._request(
|
82
78
|
Method.GET,
|
83
|
-
f"api/1/energy_sites/{energy_site_id}/calendar_history",
|
79
|
+
f"api/1/energy_sites/{self.energy_site_id}/calendar_history",
|
84
80
|
params={
|
85
81
|
"kind": "energy",
|
86
82
|
"start_date": start_date,
|
@@ -92,70 +88,82 @@ class Energy:
|
|
92
88
|
|
93
89
|
async def grid_import_export(
|
94
90
|
self,
|
95
|
-
energy_site_id: int,
|
96
91
|
disallow_charge_from_grid_with_solar_installed: bool | None = None,
|
97
92
|
customer_preferred_export_rule: EnergyExportMode | str | None = None,
|
98
93
|
) -> dict[str, Any]:
|
99
94
|
"""Allow/disallow charging from the grid and exporting energy to the grid."""
|
100
95
|
return await self._request(
|
101
96
|
Method.POST,
|
102
|
-
f"api/1/energy_sites/{energy_site_id}/grid_import_export",
|
97
|
+
f"api/1/energy_sites/{self.energy_site_id}/grid_import_export",
|
103
98
|
json={
|
104
99
|
"disallow_charge_from_grid_with_solar_installed": disallow_charge_from_grid_with_solar_installed,
|
105
100
|
"customer_preferred_export_rule": customer_preferred_export_rule,
|
106
101
|
},
|
107
102
|
)
|
108
103
|
|
109
|
-
async def live_status(self
|
104
|
+
async def live_status(self) -> dict[str, Any]:
|
110
105
|
"""Returns the live status of the site (power, state of energy, grid status, storm mode)."""
|
111
106
|
return await self._request(
|
112
107
|
Method.GET,
|
113
|
-
f"api/1/energy_sites/{energy_site_id}/live_status",
|
108
|
+
f"api/1/energy_sites/{self.energy_site_id}/live_status",
|
114
109
|
)
|
115
110
|
|
116
111
|
async def off_grid_vehicle_charging_reserve(
|
117
|
-
self,
|
112
|
+
self, off_grid_vehicle_charging_reserve_percent: int
|
118
113
|
) -> dict[str, Any]:
|
119
114
|
"""Adjust the site's off-grid vehicle charging backup reserve."""
|
120
115
|
return await self._request(
|
121
116
|
Method.POST,
|
122
|
-
f"api/1/energy_sites/{energy_site_id}/off_grid_vehicle_charging_reserve",
|
117
|
+
f"api/1/energy_sites/{self.energy_site_id}/off_grid_vehicle_charging_reserve",
|
123
118
|
json={
|
124
119
|
"off_grid_vehicle_charging_reserve_percent": off_grid_vehicle_charging_reserve_percent
|
125
120
|
},
|
126
121
|
)
|
127
122
|
|
128
123
|
async def operation(
|
129
|
-
self,
|
124
|
+
self, default_real_mode: EnergyOperationMode | str
|
130
125
|
) -> dict[str, Any]:
|
131
126
|
"""Set the site's mode."""
|
132
127
|
return await self._request(
|
133
128
|
Method.POST,
|
134
|
-
f"api/1/energy_sites/{energy_site_id}/operation",
|
129
|
+
f"api/1/energy_sites/{self.energy_site_id}/operation",
|
135
130
|
json={"default_real_mode": default_real_mode},
|
136
131
|
)
|
137
132
|
|
138
|
-
async def site_info(self
|
133
|
+
async def site_info(self) -> dict[str, Any]:
|
139
134
|
"""Returns information about the site. Things like assets (has solar, etc), settings (backup reserve, etc), and features (storm_mode_capable, etc)."""
|
140
135
|
return await self._request(
|
141
136
|
Method.GET,
|
142
|
-
f"api/1/energy_sites/{energy_site_id}/site_info",
|
137
|
+
f"api/1/energy_sites/{self.energy_site_id}/site_info",
|
143
138
|
)
|
144
139
|
|
145
|
-
async def storm_mode(self,
|
140
|
+
async def storm_mode(self, enabled: bool) -> dict[str, Any]:
|
146
141
|
"""Update storm watch participation."""
|
147
142
|
return await self._request(
|
148
143
|
Method.POST,
|
149
|
-
f"api/1/energy_sites/{energy_site_id}/storm_mode",
|
144
|
+
f"api/1/energy_sites/{self.energy_site_id}/storm_mode",
|
150
145
|
json={"enabled": enabled},
|
151
146
|
)
|
152
147
|
|
153
148
|
async def time_of_use_settings(
|
154
|
-
self,
|
149
|
+
self, settings: dict[str, Any]
|
155
150
|
) -> dict[str, Any]:
|
156
151
|
"""Update the time of use settings for the energy site."""
|
157
152
|
return await self._request(
|
158
153
|
Method.POST,
|
159
|
-
f"api/1/energy_sites/{energy_site_id}/time_of_use_settings",
|
154
|
+
f"api/1/energy_sites/{self.energy_site_id}/time_of_use_settings",
|
160
155
|
json={"tou_settings": {"tariff_content_v2": settings}},
|
161
156
|
)
|
157
|
+
|
158
|
+
class EnergySites(dict[int, EnergySite]):
|
159
|
+
"""Class describing the Tesla Fleet API partner endpoints"""
|
160
|
+
|
161
|
+
_parent: TeslaFleetApi
|
162
|
+
|
163
|
+
def __init__(self, parent: TeslaFleetApi):
|
164
|
+
self._parent = parent
|
165
|
+
|
166
|
+
def create(self, energy_site_id: int) -> EnergySite:
|
167
|
+
"""Create a specific energy site."""
|
168
|
+
self[energy_site_id] = EnergySite(self._parent, energy_site_id)
|
169
|
+
return self[energy_site_id]
|