|
7 | 7 | from enum import IntEnum
|
8 | 8 | from functools import partial
|
9 | 9 | from math import floor, log10
|
10 |
| -from time import monotonic |
11 | 10 | from typing import Any, cast
|
12 | 11 |
|
13 | 12 | from aiolifx.aiolifx import (
|
@@ -83,7 +82,8 @@ def __init__(
|
83 | 82 | self._update_rssi: bool = False
|
84 | 83 | self._rssi: int = 0
|
85 | 84 | self.last_used_theme: str = ""
|
86 |
| - self._timeouts = 0 |
| 85 | + self._timeouts = MAX_TIMEOUTS_TO_DECLARE_UPDATE_FAILED |
| 86 | + self._updated: bool = False |
87 | 87 | self._offline_time: float = 0.0
|
88 | 88 |
|
89 | 89 | super().__init__(
|
@@ -192,69 +192,60 @@ def async_get_entity_id(self, platform: Platform, key: str) -> str | None:
|
192 | 192 | async def _async_update_data(self) -> None:
|
193 | 193 | """Fetch all device data from the api."""
|
194 | 194 |
|
195 |
| - try: |
196 |
| - tasks: list[Awaitable] = [async_execute_lifx(self.device.get_color)] |
197 |
| - |
198 |
| - if self.device.host_firmware_version is None: |
199 |
| - tasks.append(async_execute_lifx(self.device.get_hostfirmware)) |
200 |
| - if self.device.product is None: |
201 |
| - tasks.append(async_execute_lifx(self.device.get_version)) |
202 |
| - if self.device.group is None: |
203 |
| - tasks.append(async_execute_lifx(self.device.get_group)) |
204 |
| - |
205 |
| - await asyncio.gather(*tasks) |
206 |
| - |
207 |
| - while len(self.device.message) > 0: |
208 |
| - # let the loop run until all messages have replies or aiolifx times out waiting for them |
209 |
| - await asyncio.sleep(0) # pragma: no cover |
| 195 | + for _ in range(MAX_TIMEOUTS_TO_DECLARE_UPDATE_FAILED - 1): |
| 196 | + try: |
| 197 | + tasks: list[Awaitable] = [async_execute_lifx(self.device.get_color)] |
210 | 198 |
|
211 |
| - if self._update_rssi is True: |
212 |
| - await self.async_update_rssi() |
| 199 | + if self.device.host_firmware_version is None: |
| 200 | + tasks.append(async_execute_lifx(self.device.get_hostfirmware)) |
| 201 | + if self.device.product is None: |
| 202 | + tasks.append(async_execute_lifx(self.device.get_version)) |
| 203 | + if self.device.group is None: |
| 204 | + tasks.append(async_execute_lifx(self.device.get_group)) |
213 | 205 |
|
214 |
| - # Update extended multizone devices |
215 |
| - if lifx_features(self.device)["extended_multizone"]: |
216 |
| - await async_execute_lifx(self.device.get_extended_color_zones) |
217 |
| - await self.async_get_multizone_effect() |
218 |
| - # use legacy methods for older devices |
219 |
| - elif lifx_features(self.device)["multizone"]: |
220 |
| - await self.async_get_color_zones() |
221 |
| - await self.async_get_multizone_effect() |
| 206 | + await asyncio.gather(*tasks) |
222 | 207 |
|
223 |
| - if lifx_features(self.device)["hev"]: |
224 |
| - await self.async_get_hev_cycle() |
| 208 | + while len(self.device.message) > 0: |
| 209 | + # let the loop run until all messages have replies or aiolifx times out waiting for them |
| 210 | + await asyncio.sleep(0) # pragma: no cover |
225 | 211 |
|
226 |
| - if lifx_features(self.device)["infrared"]: |
227 |
| - await async_execute_lifx(self.device.get_infrared) |
| 212 | + if self._update_rssi is True: |
| 213 | + await self.async_update_rssi() |
228 | 214 |
|
229 |
| - except asyncio.TimeoutError as ex: |
230 |
| - if self._timeouts == 0: |
231 |
| - self._offline_time = monotonic() |
232 |
| - |
233 |
| - self._timeouts += 1 |
| 215 | + # Update extended multizone devices |
| 216 | + if lifx_features(self.device)["extended_multizone"]: |
| 217 | + await async_execute_lifx(self.device.get_extended_color_zones) |
| 218 | + await self.async_get_multizone_effect() |
| 219 | + # use legacy methods for older devices |
| 220 | + elif lifx_features(self.device)["multizone"]: |
| 221 | + await self.async_get_color_zones() |
| 222 | + await self.async_get_multizone_effect() |
234 | 223 |
|
235 |
| - if self._timeouts >= MAX_TIMEOUTS_TO_DECLARE_UPDATE_FAILED: |
236 |
| - raise UpdateFailed( |
237 |
| - f"The device failed to respond after {MAX_TIMEOUTS_TO_DECLARE_UPDATE_FAILED} attempts" |
238 |
| - ) from ex |
| 224 | + if lifx_features(self.device)["hev"]: |
| 225 | + await self.async_get_hev_cycle() |
239 | 226 |
|
240 |
| - _LOGGER.debug( |
241 |
| - "Incrementing timeout counter to %s after no reply from %s (%s)", |
242 |
| - self._timeouts, |
243 |
| - self.device.label, |
244 |
| - self.device.ip_addr, |
245 |
| - ) |
| 227 | + if lifx_features(self.device)["infrared"]: |
| 228 | + await async_execute_lifx(self.device.get_infrared) |
246 | 229 |
|
247 |
| - await self._async_update_data() |
| 230 | + break |
248 | 231 |
|
249 |
| - else: |
250 |
| - if self._timeouts > 0: |
| 232 | + except asyncio.TimeoutError: |
251 | 233 | _LOGGER.debug(
|
252 |
| - "Resetting timeout to 0 for %s (%s) after being offline for %.2f seconds", |
| 234 | + "Time out updating %s (%s): retrying", |
253 | 235 | self.device.label or self.device.ip_addr,
|
254 | 236 | self.device.mac_addr,
|
255 |
| - monotonic() - self._offline_time, |
256 | 237 | )
|
257 |
| - self._timeouts = 0 |
| 238 | + |
| 239 | + else: |
| 240 | + _LOGGER.debug( |
| 241 | + "Marking %s (%s) as offline after three failed update attempts", |
| 242 | + self.device.label or self.device.ip_addr, |
| 243 | + self.device.mac_addr, |
| 244 | + ) |
| 245 | + |
| 246 | + raise UpdateFailed( |
| 247 | + f"The device failed to respond after {MAX_TIMEOUTS_TO_DECLARE_UPDATE_FAILED} attempts" |
| 248 | + ) |
258 | 249 |
|
259 | 250 | async def async_get_color_zones(self) -> None:
|
260 | 251 | """Get updated color information for each zone."""
|
|
0 commit comments