tesla-fleet-api 1.0.3__py3-none-any.whl → 1.0.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tesla_fleet_api/const.py +1 -1
- tesla_fleet_api/exceptions.py +0 -1
- tesla_fleet_api/tesla/bluetooth.py +9 -0
- tesla_fleet_api/tesla/energysite.py +2 -1
- tesla_fleet_api/tesla/vehicle/bluetooth.py +60 -45
- tesla_fleet_api/tesla/vehicle/signed.py +0 -11
- tesla_fleet_api/tesla/vehicle/vehicle.py +17 -3
- tesla_fleet_api/tesla/vehicle/vehicles.py +6 -3
- {tesla_fleet_api-1.0.3.dist-info → tesla_fleet_api-1.0.5.dist-info}/METADATA +5 -3
- {tesla_fleet_api-1.0.3.dist-info → tesla_fleet_api-1.0.5.dist-info}/RECORD +13 -13
- {tesla_fleet_api-1.0.3.dist-info → tesla_fleet_api-1.0.5.dist-info}/WHEEL +1 -1
- {tesla_fleet_api-1.0.3.dist-info → tesla_fleet_api-1.0.5.dist-info}/LICENSE +0 -0
- {tesla_fleet_api-1.0.3.dist-info → tesla_fleet_api-1.0.5.dist-info}/top_level.txt +0 -0
tesla_fleet_api/const.py
CHANGED
tesla_fleet_api/exceptions.py
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
import hashlib
|
4
4
|
import re
|
5
|
+
from google.protobuf.json_format import MessageToJson, MessageToDict
|
5
6
|
from bleak.backends.device import BLEDevice
|
6
7
|
from cryptography.hazmat.primitives.asymmetric import ec
|
7
8
|
|
@@ -43,3 +44,11 @@ class Vehicles(dict[str, VehicleBluetooth]):
|
|
43
44
|
vehicle = VehicleBluetooth(self._parent, vin, key, device)
|
44
45
|
self[vin] = vehicle
|
45
46
|
return vehicle
|
47
|
+
|
48
|
+
def toJson(message) -> str:
|
49
|
+
"""Convert a protobuf message to JSON."""
|
50
|
+
return MessageToJson(message, preserving_proto_field_name=True)
|
51
|
+
|
52
|
+
def toDict(message) -> dict:
|
53
|
+
"""Convert a protobuf message to a dictionary."""
|
54
|
+
return MessageToDict(message, preserving_proto_field_name=True)
|
@@ -159,11 +159,12 @@ class EnergySites(dict[int, EnergySite]):
|
|
159
159
|
"""Class describing the Tesla Fleet API partner endpoints"""
|
160
160
|
|
161
161
|
_parent: TeslaFleetApi
|
162
|
+
Site = EnergySite
|
162
163
|
|
163
164
|
def __init__(self, parent: TeslaFleetApi):
|
164
165
|
self._parent = parent
|
165
166
|
|
166
167
|
def create(self, energy_site_id: int) -> EnergySite:
|
167
168
|
"""Create a specific energy site."""
|
168
|
-
self[energy_site_id] =
|
169
|
+
self[energy_site_id] = self.Site(self._parent, energy_site_id)
|
169
170
|
return self[energy_site_id]
|
@@ -4,7 +4,7 @@ import hashlib
|
|
4
4
|
import asyncio
|
5
5
|
from typing import TYPE_CHECKING
|
6
6
|
from google.protobuf.message import DecodeError
|
7
|
-
|
7
|
+
from bleak_retry_connector import establish_connection, MAX_CONNECT_ATTEMPTS
|
8
8
|
from bleak import BleakClient, BleakScanner
|
9
9
|
from bleak.backends.characteristic import BleakGATTCharacteristic
|
10
10
|
from bleak.backends.device import BLEDevice
|
@@ -19,17 +19,14 @@ from tesla_fleet_api.const import (
|
|
19
19
|
BluetoothVehicleData
|
20
20
|
)
|
21
21
|
from tesla_fleet_api.exceptions import (
|
22
|
-
MESSAGE_FAULTS,
|
23
22
|
WHITELIST_OPERATION_STATUS,
|
24
23
|
WhitelistOperationStatus,
|
25
|
-
NotOnWhitelistFault,
|
26
24
|
)
|
27
25
|
|
28
26
|
# Protocol
|
29
27
|
from tesla_fleet_api.tesla.vehicle.proto.car_server_pb2 import (
|
30
28
|
Action,
|
31
29
|
VehicleAction,
|
32
|
-
Response,
|
33
30
|
GetVehicleData,
|
34
31
|
GetChargeState,
|
35
32
|
GetClimateState,
|
@@ -44,10 +41,6 @@ from tesla_fleet_api.tesla.vehicle.proto.car_server_pb2 import (
|
|
44
41
|
GetSoftwareUpdateState,
|
45
42
|
GetParentalControlsState,
|
46
43
|
)
|
47
|
-
from tesla_fleet_api.tesla.vehicle.proto.signatures_pb2 import (
|
48
|
-
SessionInfo,
|
49
|
-
Session_Info_Status
|
50
|
-
)
|
51
44
|
from tesla_fleet_api.tesla.vehicle.proto.universal_message_pb2 import (
|
52
45
|
Destination,
|
53
46
|
Domain,
|
@@ -84,6 +77,7 @@ class VehicleBluetooth(Commands):
|
|
84
77
|
"""Class describing the Tesla Fleet API vehicle endpoints and commands for a specific vehicle with command signing."""
|
85
78
|
|
86
79
|
ble_name: str
|
80
|
+
device: BLEDevice
|
87
81
|
client: BleakClient
|
88
82
|
_queues: dict[Domain, asyncio.Queue]
|
89
83
|
_ekey: ec.EllipticCurvePublicKey
|
@@ -103,26 +97,38 @@ class VehicleBluetooth(Commands):
|
|
103
97
|
if device is not None:
|
104
98
|
self.client = BleakClient(device, services=[SERVICE_UUID])
|
105
99
|
|
106
|
-
async def
|
100
|
+
async def find_vehicle(self, name: str | None = None, address: str | None = None, scanner: BleakScanner = BleakScanner()) -> BLEDevice:
|
107
101
|
"""Find the Tesla BLE device."""
|
108
|
-
|
109
|
-
|
102
|
+
if name is not None:
|
103
|
+
device = await scanner.find_device_by_name(name)
|
104
|
+
elif address is not None:
|
105
|
+
device = await scanner.find_device_by_address(address)
|
106
|
+
else:
|
107
|
+
device = await scanner.find_device_by_name(self.ble_name)
|
110
108
|
if not device:
|
111
109
|
raise ValueError(f"Device {self.ble_name} not found")
|
112
|
-
self.
|
113
|
-
|
114
|
-
|
110
|
+
self.device = device
|
111
|
+
return self.device
|
112
|
+
|
113
|
+
def set_device(self, device: BLEDevice) -> None:
|
114
|
+
self.device = device
|
115
115
|
|
116
|
-
def
|
117
|
-
|
118
|
-
self.client = BleakClient(device, services=[SERVICE_UUID])
|
119
|
-
return self.client
|
116
|
+
def get_device(self) -> BLEDevice:
|
117
|
+
return self.device
|
120
118
|
|
121
|
-
async def connect(self, device:
|
119
|
+
async def connect(self, device: BLEDevice | None = None, max_attempts: int = MAX_CONNECT_ATTEMPTS) -> None:
|
122
120
|
"""Connect to the Tesla BLE device."""
|
123
|
-
if device
|
124
|
-
self.
|
125
|
-
|
121
|
+
if device:
|
122
|
+
self.device = device
|
123
|
+
if not self.device:
|
124
|
+
raise ValueError(f"Device {self.ble_name} not found")
|
125
|
+
self.client = await establish_connection(
|
126
|
+
BleakClient,
|
127
|
+
self.device,
|
128
|
+
self.vin,
|
129
|
+
max_attempts=max_attempts,
|
130
|
+
ble_device_callback=self.get_device
|
131
|
+
)
|
126
132
|
await self.client.start_notify(READ_UUID, self._on_notify)
|
127
133
|
|
128
134
|
async def disconnect(self) -> bool:
|
@@ -144,34 +150,43 @@ class VehicleBluetooth(Commands):
|
|
144
150
|
self._recv += data
|
145
151
|
else:
|
146
152
|
self._recv_len = int.from_bytes(data[:2], 'big')
|
153
|
+
if self._recv_len > 1024:
|
154
|
+
LOGGER.error("Parsed very large message length")
|
155
|
+
self._recv = bytearray()
|
156
|
+
self._recv_len = 0
|
157
|
+
return
|
147
158
|
self._recv = data[2:]
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
if len(self._recv)
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
159
|
+
#while len(self._recv) > self._recv_len:
|
160
|
+
#
|
161
|
+
# # Maybe this needs to trigger a reset
|
162
|
+
# await self._on_message(bytes(self._recv[:self._recv_len]))
|
163
|
+
# self._recv_len = int.from_bytes(self._recv[self._recv_len:self._recv_len+2], 'big')
|
164
|
+
# self._recv = self._recv[self._recv_len+2:]
|
165
|
+
# continue
|
166
|
+
if len(self._recv) >= self._recv_len:
|
167
|
+
if len(self._recv) > self._recv_len:
|
168
|
+
LOGGER.debug(f"Received more data than expected: {len(self._recv)} > {self._recv_len}")
|
169
|
+
try:
|
170
|
+
msg = RoutableMessage.FromString(bytes(self._recv[:self._recv_len]))
|
171
|
+
await self._on_message(msg)
|
172
|
+
self._recv = bytearray()
|
173
|
+
self._recv_len = 0
|
174
|
+
except DecodeError:
|
175
|
+
# Attempt parsing the whole payload
|
176
|
+
msg = RoutableMessage.FromString(bytes(self._recv))
|
177
|
+
LOGGER.warn(f"Parsed more data than length: {len(self._recv)} > {self._recv_len}")
|
178
|
+
await self._on_message(msg)
|
179
|
+
self._recv = bytearray()
|
180
|
+
self._recv_len = 0
|
181
|
+
|
182
|
+
async def _on_message(self, msg: RoutableMessage) -> None:
|
161
183
|
"""Receive messages from the Tesla BLE data."""
|
162
|
-
try:
|
163
|
-
msg = RoutableMessage.FromString(data)
|
164
|
-
except DecodeError as e:
|
165
|
-
LOGGER.error(f"Error parsing message: {e}")
|
166
|
-
self._recv = bytearray()
|
167
|
-
self._recv_len = 0
|
168
|
-
return
|
169
184
|
|
170
185
|
if(msg.to_destination.routing_address != self._from_destination):
|
171
186
|
# Ignore ephemeral key broadcasts
|
172
187
|
return
|
173
188
|
|
174
|
-
LOGGER.
|
189
|
+
LOGGER.debug(f"Received response: {msg}")
|
175
190
|
await self._queues[msg.from_destination.domain].put(msg)
|
176
191
|
|
177
192
|
async def _send(self, msg: RoutableMessage, requires: str) -> RoutableMessage:
|
@@ -188,7 +203,7 @@ class VehicleBluetooth(Commands):
|
|
188
203
|
await self.client.write_gatt_char(WRITE_UUID, payload, True)
|
189
204
|
|
190
205
|
# Process the response
|
191
|
-
async with asyncio.timeout(
|
206
|
+
async with asyncio.timeout(2):
|
192
207
|
while True:
|
193
208
|
resp = await self._queues[domain].get()
|
194
209
|
LOGGER.debug(f"Received message {resp}")
|
@@ -221,7 +236,7 @@ class VehicleBluetooth(Commands):
|
|
221
236
|
),
|
222
237
|
protobuf_message_as_bytes=request.SerializeToString(),
|
223
238
|
)
|
224
|
-
resp = await self._send(msg)
|
239
|
+
resp = await self._send(msg, "protobuf_message_as_bytes")
|
225
240
|
respMsg = FromVCSECMessage.FromString(resp.protobuf_message_as_bytes)
|
226
241
|
if(respMsg.commandStatus.whitelistOperationStatus.whitelistOperationInformation):
|
227
242
|
if(respMsg.commandStatus.whitelistOperationStatus.whitelistOperationInformation < len(WHITELIST_OPERATION_STATUS)):
|
@@ -5,14 +5,6 @@ from typing import TYPE_CHECKING
|
|
5
5
|
|
6
6
|
from tesla_fleet_api.tesla.vehicle.fleet import VehicleFleet
|
7
7
|
from tesla_fleet_api.tesla.vehicle.commands import Commands
|
8
|
-
from tesla_fleet_api.exceptions import (
|
9
|
-
MESSAGE_FAULTS,
|
10
|
-
NotOnWhitelistFault,
|
11
|
-
)
|
12
|
-
from tesla_fleet_api.tesla.vehicle.proto.signatures_pb2 import (
|
13
|
-
Session_Info_Status,
|
14
|
-
SessionInfo,
|
15
|
-
)
|
16
8
|
from tesla_fleet_api.tesla.vehicle.proto.universal_message_pb2 import (
|
17
9
|
RoutableMessage,
|
18
10
|
)
|
@@ -41,9 +33,6 @@ class VehicleSigned(VehicleFleet, Commands):
|
|
41
33
|
json = await self.signed_command(
|
42
34
|
base64.b64encode(msg.SerializeToString()).decode()
|
43
35
|
)
|
44
|
-
|
45
36
|
resp = RoutableMessage.FromString(base64.b64decode(json["response"]))
|
46
|
-
|
47
37
|
self.validate_msg(resp)
|
48
|
-
|
49
38
|
return resp
|
@@ -1,10 +1,18 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
from typing import TYPE_CHECKING
|
3
3
|
|
4
|
-
|
5
4
|
if TYPE_CHECKING:
|
6
5
|
from tesla_fleet_api.tesla.tesla import Tesla
|
7
6
|
|
7
|
+
MODELS = {
|
8
|
+
"S": "Model S",
|
9
|
+
"X": "Model X",
|
10
|
+
"3": "Model 3",
|
11
|
+
"Y": "Model Y",
|
12
|
+
"C": "Cybertruck",
|
13
|
+
"R": "Roadster",
|
14
|
+
"T": "Semi",
|
15
|
+
}
|
8
16
|
|
9
17
|
class Vehicle:
|
10
18
|
"""Base class describing a Tesla vehicle."""
|
@@ -14,6 +22,12 @@ class Vehicle:
|
|
14
22
|
def __init__(self, parent: Tesla, vin: str):
|
15
23
|
self.vin = vin
|
16
24
|
|
17
|
-
|
25
|
+
|
26
|
+
def pre2021(self) -> bool:
|
18
27
|
"""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']))
|
28
|
+
return self.vin[3] in ["S", "X"] and (self.vin[9] <= "L" or (self.vin[9] == "M" and self.vin[7] in ['1', '2', '3', '4']))
|
29
|
+
|
30
|
+
@property
|
31
|
+
def model(self) -> str:
|
32
|
+
"""Returns the model of the vehicle."""
|
33
|
+
return MODELS.get(self.vin[3], "Unknown")
|
@@ -15,25 +15,28 @@ class Vehicles(dict[str, Vehicle]):
|
|
15
15
|
"""Class containing and creating vehicles."""
|
16
16
|
|
17
17
|
_parent: TeslaFleetApi
|
18
|
+
Fleet = VehicleFleet
|
19
|
+
Signed = VehicleSigned
|
20
|
+
Bluetooth = VehicleBluetooth
|
18
21
|
|
19
22
|
def __init__(self, parent: TeslaFleetApi):
|
20
23
|
self._parent = parent
|
21
24
|
|
22
25
|
def createFleet(self, vin: str) -> VehicleFleet:
|
23
26
|
"""Creates a Fleet API vehicle."""
|
24
|
-
vehicle =
|
27
|
+
vehicle = self.Fleet(self._parent, vin)
|
25
28
|
self[vin] = vehicle
|
26
29
|
return vehicle
|
27
30
|
|
28
31
|
def createSigned(self, vin: str) -> VehicleSigned:
|
29
32
|
"""Creates a Fleet API vehicle that uses command protocol."""
|
30
|
-
vehicle =
|
33
|
+
vehicle = self.Signed(self._parent, vin)
|
31
34
|
self[vin] = vehicle
|
32
35
|
return vehicle
|
33
36
|
|
34
37
|
def createBluetooth(self, vin: str):
|
35
38
|
"""Creates a bluetooth vehicle that uses command protocol."""
|
36
|
-
vehicle =
|
39
|
+
vehicle = self.Bluetooth(self._parent, vin)
|
37
40
|
self[vin] = vehicle
|
38
41
|
return vehicle
|
39
42
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: tesla_fleet_api
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.5
|
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
|
@@ -18,6 +18,7 @@ Requires-Dist: aiolimiter
|
|
18
18
|
Requires-Dist: cryptography
|
19
19
|
Requires-Dist: protobuf
|
20
20
|
Requires-Dist: bleak
|
21
|
+
Requires-Dist: bleak-retry-connector
|
21
22
|
Dynamic: author
|
22
23
|
Dynamic: author-email
|
23
24
|
Dynamic: classifier
|
@@ -29,10 +30,11 @@ Dynamic: requires-python
|
|
29
30
|
Dynamic: summary
|
30
31
|
|
31
32
|
# Tesla Fleet Api
|
32
|
-
Python library for Tesla Fleet API and Teslemetry.
|
33
|
+
Python library for Tesla Fleet API and Tesla Command Protocol, including signed commands and encrypted local Bluetooth (BLE). Also provides interfaces for Teslemetry and Tessie.
|
33
34
|
|
34
|
-
Based on [Tesla Developer documentation](https://developer.tesla.com/docs/fleet-api).
|
35
|
+
Based on [Tesla Developer documentation](https://developer.tesla.com/docs/fleet-api) and [Tesla Command Protocol](https://github.com/teslamotors/vehicle-command/blob/main/pkg/protocol/protocol.md)
|
35
36
|
|
37
|
+
**Documentation is currently outdated for V1.0.X**
|
36
38
|
|
37
39
|
## TeslaFleetApi
|
38
40
|
This is the base class, however can also be used directly if you have a valid user access_token.
|
@@ -1,23 +1,23 @@
|
|
1
1
|
tesla_fleet_api/__init__.py,sha256=3DZMoZ-5srW-7SooAjqcRubQDuZPY8rMKH7eqIp4qtg,392
|
2
|
-
tesla_fleet_api/const.py,sha256=
|
3
|
-
tesla_fleet_api/exceptions.py,sha256=
|
2
|
+
tesla_fleet_api/const.py,sha256=1GEFPEYxka-ADBs_MWNaxdr2FPH7ObxaKRX2NvFrGaY,3748
|
3
|
+
tesla_fleet_api/exceptions.py,sha256=iZJv_6YJO6wK_lYvR18SugpNk-ZTzElmcsOqNqd05M0,35495
|
4
4
|
tesla_fleet_api/ratecalculator.py,sha256=4lz8yruUeouHXh_3ezsXX-CTpIegp1T1J4VuRV_qdHA,1791
|
5
5
|
tesla_fleet_api/tesla/__init__.py,sha256=Cvpqu8OaOFmbuwu9KjgYrje8eVluDp2IU_zwdtXbmO0,282
|
6
|
-
tesla_fleet_api/tesla/bluetooth.py,sha256=
|
6
|
+
tesla_fleet_api/tesla/bluetooth.py,sha256=WhDo66OEwCGhvsGskvWcGUiNv6eyFsdEiQdIm571jQM,1835
|
7
7
|
tesla_fleet_api/tesla/charging.py,sha256=D7I7cAf-3-95sIjyP6wpVqCq9Cppj6U-VPFQGpQQ8bs,1704
|
8
|
-
tesla_fleet_api/tesla/energysite.py,sha256=
|
8
|
+
tesla_fleet_api/tesla/energysite.py,sha256=vStffklBQfQNAO_1wrHLFu7BlBCTVVbLh7_IrAUL3wg,6131
|
9
9
|
tesla_fleet_api/tesla/fleet.py,sha256=X74tzwGO9w65j9YUGuW04CwG7Bx6biEHwxIjWGCzB4c,5670
|
10
10
|
tesla_fleet_api/tesla/oauth.py,sha256=aWBsWmnM-QxzaU8W9TXVNxGsYn_LraXnpexwdE8wOqo,4104
|
11
11
|
tesla_fleet_api/tesla/partner.py,sha256=e-l6sEP6-IupjFEQieSUjhhvRXF3aL4ebPNahcGFRCE,1238
|
12
12
|
tesla_fleet_api/tesla/tesla.py,sha256=Jlz90-fM0nJbhnQN0k3ukNv59-9KqZZbyQ91IiLIbfo,2010
|
13
13
|
tesla_fleet_api/tesla/user.py,sha256=w8rwiAOIFjuDus8M0RpZ0wucJtw8kYFKtJfYVk7Ekr0,1194
|
14
14
|
tesla_fleet_api/tesla/vehicle/__init__.py,sha256=3A5_wTQHofRShof4pUNOtF78-7lUh62uz2jq2ecnmRY,381
|
15
|
-
tesla_fleet_api/tesla/vehicle/bluetooth.py,sha256=
|
15
|
+
tesla_fleet_api/tesla/vehicle/bluetooth.py,sha256=25UlaAatKxu_NzbG5te5sKHeM9jAufj42LjGJaIKNHg,16476
|
16
16
|
tesla_fleet_api/tesla/vehicle/commands.py,sha256=zgfc2yo1UxEh8ePqSb-4h0UTK0RmpCG_9LZX44CES2c,51268
|
17
17
|
tesla_fleet_api/tesla/vehicle/fleet.py,sha256=K9BVZj6CChJSDSMFroa7Cz0KrsYWj32ILtQumarkLaU,32080
|
18
|
-
tesla_fleet_api/tesla/vehicle/signed.py,sha256=
|
19
|
-
tesla_fleet_api/tesla/vehicle/vehicle.py,sha256=
|
20
|
-
tesla_fleet_api/tesla/vehicle/vehicles.py,sha256=
|
18
|
+
tesla_fleet_api/tesla/vehicle/signed.py,sha256=RUzVnZIfykz3YZW2gaxd1iaN1i8LkLaEoiXrbqZn9kg,1339
|
19
|
+
tesla_fleet_api/tesla/vehicle/vehicle.py,sha256=nIhfn2hGuHJoAj-LiipcZdS4abdrWI6yST2cuE-w23s,810
|
20
|
+
tesla_fleet_api/tesla/vehicle/vehicles.py,sha256=axiH33YRnkYcbQmolbL85PF69SRI_5FA5T10v-cMmBc,1644
|
21
21
|
tesla_fleet_api/tesla/vehicle/proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
22
|
tesla_fleet_api/tesla/vehicle/proto/__init__.pyi,sha256=qFXWNIgl71wB260u-XPzaAwWAHL6krw21q-aXnBtop0,252
|
23
23
|
tesla_fleet_api/tesla/vehicle/proto/car_server_pb2.py,sha256=v_eb4NDIkx_ZYPYW29_EFRky5vQ4b2q14gwuQSbouYw,29202
|
@@ -44,8 +44,8 @@ tesla_fleet_api/teslemetry/vehicle.py,sha256=9_2N1iNNDouqfb6YBBWAFjnlzVRTf5frhXi
|
|
44
44
|
tesla_fleet_api/tessie/__init__.py,sha256=9lhQJaB6X4PObUL9QdaaZYqs2BxiTidu3zmHcBESLVw,78
|
45
45
|
tesla_fleet_api/tessie/tessie.py,sha256=qdMZ61TcQi5JRuv2qaxuLHtOuy8WZJ1WNqWg5WDAwwU,2615
|
46
46
|
tesla_fleet_api/tessie/vehicle.py,sha256=9khv4oCkGGLxHzQ2FYhDPH7wczxEDiUppsDXalawarE,1125
|
47
|
-
tesla_fleet_api-1.0.
|
48
|
-
tesla_fleet_api-1.0.
|
49
|
-
tesla_fleet_api-1.0.
|
50
|
-
tesla_fleet_api-1.0.
|
51
|
-
tesla_fleet_api-1.0.
|
47
|
+
tesla_fleet_api-1.0.5.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
48
|
+
tesla_fleet_api-1.0.5.dist-info/METADATA,sha256=nL7RUQYO8-i8R0-zkSQBNvJD7BtruTEkNxywMB5lsT4,4382
|
49
|
+
tesla_fleet_api-1.0.5.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
50
|
+
tesla_fleet_api-1.0.5.dist-info/top_level.txt,sha256=jeNbog_1saXBFrGpom9WyPWmilxsyP3szL_G7JLWQfM,16
|
51
|
+
tesla_fleet_api-1.0.5.dist-info/RECORD,,
|
File without changes
|
File without changes
|