Skip to content

Commit 4b3146d

Browse files
committed
Use bleak retry
1 parent 0180406 commit 4b3146d

File tree

3 files changed

+28
-22
lines changed

3 files changed

+28
-22
lines changed

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ cryptography==43.*
44
protobuf==5.*
55
aiofiles==24.*
66
bleak==0.22.*
7+
bleak-retry-connector==3.9.*

tesla_fleet_api/tesla/bluetooth.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import hashlib
44
import re
5+
from google.protobuf.json_format import MessageToJson, MessageToDict
56
from bleak.backends.device import BLEDevice
67
from cryptography.hazmat.primitives.asymmetric import ec
78

@@ -43,3 +44,11 @@ def createBluetooth(self, vin: str, key: ec.EllipticCurvePrivateKey | None = Non
4344
vehicle = VehicleBluetooth(self._parent, vin, key, device)
4445
self[vin] = vehicle
4546
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)

tesla_fleet_api/tesla/vehicle/bluetooth.py

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import asyncio
55
from typing import TYPE_CHECKING
66
from google.protobuf.message import DecodeError
7-
7+
from bleak_retry_connector import establish_connection, MAX_CONNECT_ATTEMPTS
88
from bleak import BleakClient, BleakScanner
99
from bleak.backends.characteristic import BleakGATTCharacteristic
1010
from bleak.backends.device import BLEDevice
@@ -19,17 +19,14 @@
1919
BluetoothVehicleData
2020
)
2121
from tesla_fleet_api.exceptions import (
22-
MESSAGE_FAULTS,
2322
WHITELIST_OPERATION_STATUS,
2423
WhitelistOperationStatus,
25-
NotOnWhitelistFault,
2624
)
2725

2826
# Protocol
2927
from tesla_fleet_api.tesla.vehicle.proto.car_server_pb2 import (
3028
Action,
3129
VehicleAction,
32-
Response,
3330
GetVehicleData,
3431
GetChargeState,
3532
GetClimateState,
@@ -44,10 +41,6 @@
4441
GetSoftwareUpdateState,
4542
GetParentalControlsState,
4643
)
47-
from tesla_fleet_api.tesla.vehicle.proto.signatures_pb2 import (
48-
SessionInfo,
49-
Session_Info_Status
50-
)
5144
from tesla_fleet_api.tesla.vehicle.proto.universal_message_pb2 import (
5245
Destination,
5346
Domain,
@@ -84,6 +77,7 @@ class VehicleBluetooth(Commands):
8477
"""Class describing the Tesla Fleet API vehicle endpoints and commands for a specific vehicle with command signing."""
8578

8679
ble_name: str
80+
device: BLEDevice
8781
client: BleakClient
8882
_queues: dict[Domain, asyncio.Queue]
8983
_ekey: ec.EllipticCurvePublicKey
@@ -103,26 +97,28 @@ def __init__(
10397
if device is not None:
10498
self.client = BleakClient(device, services=[SERVICE_UUID])
10599

106-
async def find_client(self, scanner: BleakScanner = BleakScanner()) -> BleakClient:
100+
async def find_vehicle(self, name: str | None = None, address: str | None = None, scanner: BleakScanner = BleakScanner()) -> BLEDevice:
107101
"""Find the Tesla BLE device."""
108-
109-
device = await scanner.find_device_by_name(self.ble_name)
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)
110108
if not device:
111109
raise ValueError(f"Device {self.ble_name} not found")
112-
self.client = BleakClient(device, services=[SERVICE_UUID])
113-
LOGGER.debug(f"Discovered device {device.name} {device.address}")
114-
return self.client
110+
self.device = device
111+
return self.device
112+
113+
def set_device(self, device: BLEDevice) -> None:
114+
self.device = device
115115

116-
def create_client(self, device: str|BLEDevice) -> BleakClient:
117-
"""Create a client using a MAC address or Bleak Device."""
118-
self.client = BleakClient(device, services=[SERVICE_UUID])
119-
return self.client
116+
def get_device(self) -> BLEDevice:
117+
return self.device
120118

121-
async def connect(self, device: str|BLEDevice | None = None) -> None:
119+
async def connect(self, device: BLEDevice | None = None, max_attempts: int = MAX_CONNECT_ATTEMPTS) -> None:
122120
"""Connect to the Tesla BLE device."""
123-
if device is not None:
124-
self.create_client(device)
125-
await self.client.connect()
121+
self.client = await establish_connection(BleakClient, self.device, self.vin, max_attempts=max_attempts, ble_device_callback=self.get_device)
126122
await self.client.start_notify(READ_UUID, self._on_notify)
127123

128124
async def disconnect(self) -> bool:

0 commit comments

Comments
 (0)