|
10 | 10 | import async_timeout |
11 | 11 | import bleak |
12 | 12 | from bleak.backends.device import BLEDevice |
13 | | -from bleak_retry_connector import BleakClient, establish_connection |
| 13 | +from bleak.backends.service import BleakGATTServiceCollection |
| 14 | +from bleak_retry_connector import ( |
| 15 | + BleakClientWithServiceCache, |
| 16 | + ble_device_has_changed, |
| 17 | + establish_connection, |
| 18 | +) |
14 | 19 |
|
15 | 20 | from ..const import DEFAULT_RETRY_COUNT, DEFAULT_SCAN_TIMEOUT |
16 | 21 | from ..discovery import GetSwitchbotDevices |
@@ -61,6 +66,7 @@ def __init__( |
61 | 66 | self._password_encoded = "%08x" % ( |
62 | 67 | binascii.crc32(password.encode("ascii")) & 0xFFFFFFFF |
63 | 68 | ) |
| 69 | + self._cached_services: BleakGATTServiceCollection | None = None |
64 | 70 |
|
65 | 71 | def _commandkey(self, key: str) -> str: |
66 | 72 | """Add password to key if set.""" |
@@ -98,12 +104,17 @@ def name(self) -> str: |
98 | 104 |
|
99 | 105 | async def _send_command_locked(self, key: str, command: bytes) -> bytes: |
100 | 106 | """Send command to device and read response.""" |
101 | | - client: BleakClient | None = None |
| 107 | + client: BleakClientWithServiceCache | None = None |
102 | 108 | try: |
103 | 109 | _LOGGER.debug("%s: Connnecting to switchbot", self.name) |
104 | 110 | client = await establish_connection( |
105 | | - BleakClient, self._device, self.name, max_attempts=1 |
| 111 | + BleakClientWithServiceCache, |
| 112 | + self._device, |
| 113 | + self.name, |
| 114 | + max_attempts=1, |
| 115 | + cached_services=self._cached_services, |
106 | 116 | ) |
| 117 | + self._cached_services = client.services |
107 | 118 | _LOGGER.debug( |
108 | 119 | "%s: Connnected to switchbot: %s", self.name, client.is_connected |
109 | 120 | ) |
@@ -158,6 +169,8 @@ def get_battery_percent(self) -> Any: |
158 | 169 | def update_from_advertisement(self, advertisement: SwitchBotAdvertisement) -> None: |
159 | 170 | """Update device data from advertisement.""" |
160 | 171 | self._sb_adv_data = advertisement |
| 172 | + if self._device and ble_device_has_changed(self._device, advertisement.device): |
| 173 | + self._cached_services = None |
161 | 174 | self._device = advertisement.device |
162 | 175 |
|
163 | 176 | async def get_device_data( |
|
0 commit comments