Skip to content

Commit e3b0632

Browse files
committed
Refactor retry logic again
1 parent 0ec8871 commit e3b0632

File tree

1 file changed

+66
-55
lines changed

1 file changed

+66
-55
lines changed

custom_components/eurotronic_cometblue/coordinator.py

Lines changed: 66 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -63,71 +63,82 @@ async def send_command(
6363
"""Send command to device."""
6464

6565
LOGGER.debug("Updating device with '%s' from '%s'", caller_entity_id, payload)
66-
try:
67-
async with self.device:
68-
if not self.device.connected:
69-
raise ConfigEntryNotReady(
70-
f"Failed to connect to '{self.device.device.address}'"
71-
)
72-
retry_count = 0
73-
while retry_count < RETRY_COUNT:
74-
try:
75-
return await getattr(self.device, function)(**payload)
76-
except (InvalidByteValueError, TimeoutError) as ex: # noqa: PERF203
77-
retry_count += 1
78-
LOGGER.info(
79-
"Retrying command '%s' to '%s' after %s (%s)",
80-
payload,
81-
caller_entity_id,
82-
type(ex).__name__,
83-
ex,
66+
retry_count = 0
67+
while retry_count < RETRY_COUNT:
68+
try:
69+
async with self.device:
70+
if not self.device.connected:
71+
raise ConfigEntryNotReady(
72+
f"Failed to connect to '{self.device.device.address}'"
8473
)
85-
except ValueError as err:
86-
raise ServiceValidationError(
87-
f"Invalid payload '{payload}' for '{caller_entity_id}': {err}"
88-
) from err
89-
except (BleakError, TimeoutError) as err:
90-
raise HomeAssistantError(
91-
f"Error sending command '{payload}' to '{caller_entity_id}': {err}"
92-
) from err
74+
return await getattr(self.device, function)(**payload)
75+
except (InvalidByteValueError, TimeoutError, BleakError) as ex: # noqa: PERF203
76+
retry_count += 1
77+
if retry_count >= RETRY_COUNT:
78+
raise HomeAssistantError(
79+
f"Error sending command '{payload}' to '{caller_entity_id}': {ex}"
80+
) from ex
81+
LOGGER.info(
82+
"Retrying command '%s' to '%s' after %s (%s)",
83+
payload,
84+
caller_entity_id,
85+
type(ex).__name__,
86+
ex,
87+
)
88+
except ValueError as ex:
89+
raise ServiceValidationError(
90+
f"Invalid payload '{payload}' for '{caller_entity_id}': {ex}"
91+
) from ex
9392

9493
async def _async_update_data(self) -> dict[str, bytes]:
9594
"""Poll the device."""
9695
data: dict = {}
9796

98-
try:
99-
async with self.device:
100-
if not self.device.connected:
101-
raise ConfigEntryNotReady(
102-
f"Failed to connect to '{self.device.device.address}'"
103-
)
104-
retrieved_temperatures = await self.device.get_temperature_async()
105-
data = {
106-
"battery": await self.device.get_battery_async(),
107-
"holiday": await self.device.get_holiday_async(1),
108-
# If one value was not retrieved correctly, keep the old value
109-
**{
110-
k: retrieved_temperatures.get(k) or self.data.get(k)
111-
for k in CONF_ALL_TEMPERATURES
112-
},
113-
}
114-
# Reset failed update count if all values were retrieved correctly
115-
self.failed_update_count = 0
116-
except (InvalidByteValueError, TimeoutError) as ex:
117-
# allow invalid bytes until RETRY_COUNT is reached
118-
if self.failed_update_count < RETRY_COUNT and self.data:
119-
self.failed_update_count += 1
97+
retry_count = 0
98+
retrieved_temperatures = {}
99+
battery = 0
100+
holiday = {}
101+
102+
while retry_count < RETRY_COUNT:
103+
try:
104+
async with self.device:
105+
if not self.device.connected:
106+
raise ConfigEntryNotReady(
107+
f"Failed to connect to '{self.device.device.address}'"
108+
)
109+
# temperatures are required and must trigger a retry if not available
110+
retrieved_temperatures = await self.device.get_temperature_async()
111+
# battery and holiday are optional and should not trigger a retry
112+
try:
113+
battery = await self.device.get_battery_async()
114+
holiday = await self.device.get_holiday_async(1)
115+
except InvalidByteValueError as ex:
116+
LOGGER.warning(
117+
"Failed to retrieve optional data: %s (%s)",
118+
type(ex).__name__,
119+
ex,
120+
)
121+
except (InvalidByteValueError, TimeoutError, BleakError) as ex: # noqa: PERF203
122+
retry_count += 1
123+
if retry_count >= RETRY_COUNT:
124+
raise UpdateFailed(f"Error retrieving data: {ex}") from ex
120125
LOGGER.info(
121-
"Returning old data for '%s' after %s (%s)",
122-
self.device.device.address,
126+
"Retrying after %s (%s)",
123127
type(ex).__name__,
124128
ex,
125129
)
126-
return self.data
127-
raise UpdateFailed(f"Error in device response: {ex}") from ex
128-
except Exception as ex:
129-
self.failed_update_count += 1
130-
raise UpdateFailed(f"({type(ex).__name__}) {ex}") from ex
130+
except Exception as ex:
131+
raise UpdateFailed(f"({type(ex).__name__}) {ex}") from ex
132+
133+
# If one value was not retrieved correctly, keep the old value
134+
data = {
135+
"battery": battery or self.data.get("battery"),
136+
"holiday": holiday or self.data.get("holiday"),
137+
**{
138+
k: retrieved_temperatures.get(k) or self.data.get(k)
139+
for k in CONF_ALL_TEMPERATURES
140+
},
141+
}
131142
LOGGER.debug("Received data: %s", data)
132143
return data
133144

0 commit comments

Comments
 (0)