Skip to content

Commit 8a2589d

Browse files
committed
Fixes and improvements
1 parent 318f6a8 commit 8a2589d

File tree

5 files changed

+55
-9
lines changed

5 files changed

+55
-9
lines changed

tesla_fleet_api/tesla/bluetooth.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Bluetooth only interface."""
22

3+
import hashlib
34
import re
45
from .tesla import Tesla
56
from .vehicle.bluetooth import VehicleBluetooth
@@ -16,7 +17,11 @@ def __init__(
1617

1718
def valid_name(self, name: str) -> bool:
1819
"""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+
return bool(re.match("^S[a-f0-9]{16}[CDRP]$", name))
21+
22+
def get_name(self, vin: str) -> str:
23+
"""Get the name of a vehicle."""
24+
return "S" + hashlib.sha1(vin.encode('utf-8')).hexdigest()[:16] + "C"
2025

2126
class Vehicles(dict[str, VehicleBluetooth]):
2227
"""Class containing and creating vehicles."""
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""Tesla Fleet API classes."""
2+
3+
from .vehicles import Vehicles
4+
from .fleet import VehicleFleet
5+
from .bluetooth import VehicleBluetooth
6+
from .signed import VehicleSigned
7+
8+
__all__ = [
9+
"Vehicles",
10+
"VehicleFleet",
11+
"VehicleBluetooth",
12+
"VehicleSigned",
13+
]

tesla_fleet_api/tesla/vehicle/bluetooth.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,20 +84,34 @@ async def discover(self, scanner: BleakScanner = BleakScanner()) -> BleakClient:
8484
raise ValueError(f"Device {self.ble_name} not found")
8585
self._device = device
8686
self.client = BleakClient(self._device, services=[SERVICE_UUID])
87-
LOGGER.info(f"Discovered device {self._device.name} {self._device.address}")
87+
LOGGER.debug(f"Discovered device {self._device.name} {self._device.address}")
88+
return self.client
89+
90+
def create_client(self, mac:str):
91+
"""Create a client with a MAC."""
92+
self.client = BleakClient(mac, services=[SERVICE_UUID])
8893
return self.client
8994

9095
async def connect(self, mac:str | None = None) -> None:
9196
"""Connect to the Tesla BLE device."""
9297
if mac is not None:
93-
self.client = BleakClient(mac, services=[SERVICE_UUID])
98+
self.create_client(mac)
9499
await self.client.connect()
95100
await self.client.start_notify(READ_UUID, self._on_notify)
96101

97102
async def disconnect(self) -> bool:
98103
"""Disconnect from the Tesla BLE device."""
99104
return await self.client.disconnect()
100105

106+
async def __aenter__(self) -> VehicleBluetooth:
107+
"""Enter the async context."""
108+
await self.connect()
109+
return self
110+
111+
async def __aexit__(self, exc_type, exc_val, exc_tb):
112+
"""Exit the async context."""
113+
await self.disconnect()
114+
101115
def _on_notify(self,sender: BleakGATTCharacteristic,data : bytearray):
102116
"""Receive data from the Tesla BLE device."""
103117
if self._recv_len:
@@ -157,15 +171,14 @@ async def _send(self, msg: RoutableMessage) -> RoutableMessage:
157171
"""Serialize a message and send to the vehicle and wait for a response."""
158172
domain = msg.to_destination.domain
159173
async with self._sessions[domain].lock:
160-
LOGGER.info(f"Sending message {msg}")
174+
LOGGER.debug(f"Sending message {msg}")
161175
future = await self._create_future(domain)
162176
payload = prependLength(msg.SerializeToString())
163-
LOGGER.info(f"Payload: {payload}")
164177

165178
await self.client.write_gatt_char(WRITE_UUID, payload, True)
166179

167180
resp = await future
168-
LOGGER.info(f"Received message {resp}")
181+
LOGGER.debug(f"Received message {resp}")
169182

170183
if resp.signedMessageStatus.signed_message_fault:
171184
raise MESSAGE_FAULTS[resp.signedMessageStatus.signed_message_fault]

tesla_fleet_api/tesla/vehicle/commands.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,13 @@ async def _sendInfotainment(self, command: Action) -> dict[str, Any]:
458458
"""Sign and send a message to Infotainment computer."""
459459
return await self._command(Domain.DOMAIN_INFOTAINMENT, command.SerializeToString())
460460

461+
async def handshakeVehicleSecurity(self) -> None:
462+
"""Perform a handshake with the vehicle security domain."""
463+
await self._handshake(Domain.DOMAIN_VEHICLE_SECURITY)
464+
465+
async def handshakeInfotainment(self) -> None:
466+
"""Perform a handshake with the infotainment domain."""
467+
await self._handshake(Domain.DOMAIN_INFOTAINMENT)
461468

462469
async def _handshake(self, domain: Domain) -> None:
463470
"""Perform a handshake with the vehicle."""

tesla_fleet_api/tesla/vehicle/vehicles.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,27 @@ def __init__(self, parent: TeslaFleetApi):
2020
self._parent = parent
2121

2222
def createFleet(self, vin: str) -> VehicleFleet:
23-
"""Creates a specific vehicle."""
23+
"""Creates a Fleet API vehicle."""
2424
vehicle = VehicleFleet(self._parent, vin)
2525
self[vin] = vehicle
2626
return vehicle
2727

2828
def createSigned(self, vin: str) -> VehicleSigned:
29-
"""Creates a specific vehicle."""
29+
"""Creates a Fleet API vehicle that uses command protocol."""
3030
vehicle = VehicleSigned(self._parent, vin)
3131
self[vin] = vehicle
3232
return vehicle
3333

3434
def createBluetooth(self, vin: str) -> VehicleBluetooth:
35-
"""Creates a specific vehicle."""
35+
"""Creates a bluetooth vehicle that uses command protocol."""
3636
vehicle = VehicleBluetooth(self._parent, vin)
3737
self[vin] = vehicle
3838
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 commit comments

Comments
 (0)