Skip to content

Commit 0a94d55

Browse files
authored
Decimal OTA progress (#288)
* Allow non-integer OTA progress percentage * Update unit tests * Revert debouncer, progress is naturally limited to roughly 1/200ms * Rename `progress` to `update_percentage`
1 parent 701f575 commit 0a94d55

File tree

2 files changed

+15
-15
lines changed

2 files changed

+15
-15
lines changed

tests/test_update.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
ATTR_IN_PROGRESS,
3030
ATTR_INSTALLED_VERSION,
3131
ATTR_LATEST_VERSION,
32-
ATTR_PROGRESS,
32+
ATTR_UPDATE_PERCENTAGE,
3333
)
3434
from zha.exceptions import ZHAException
3535

@@ -309,7 +309,9 @@ async def endpoint_reply(cluster, sequence, data, **kwargs):
309309
== f"0x{installed_fw_version:08x}"
310310
)
311311
assert entity.state[ATTR_IN_PROGRESS] is True
312-
assert entity.state[ATTR_PROGRESS] == 57
312+
assert entity.state[ATTR_UPDATE_PERCENTAGE] == pytest.approx(
313+
100 * (40 / 70)
314+
)
313315
assert (
314316
entity.state[ATTR_LATEST_VERSION]
315317
== f"0x{fw_image.firmware.header.file_version:08x}"

zha/application/platforms/update.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,10 @@ class UpdateEntityFeature(IntFlag):
5151
RELEASE_NOTES = 16
5252

5353

54-
SERVICE_INSTALL: Final = "install"
55-
5654
ATTR_BACKUP: Final = "backup"
5755
ATTR_INSTALLED_VERSION: Final = "installed_version"
5856
ATTR_IN_PROGRESS: Final = "in_progress"
59-
ATTR_PROGRESS: Final = "progress"
57+
ATTR_UPDATE_PERCENTAGE: Final = "update_percentage"
6058
ATTR_LATEST_VERSION: Final = "latest_version"
6159
ATTR_RELEASE_SUMMARY: Final = "release_summary"
6260
ATTR_RELEASE_NOTES: Final = "release_notes"
@@ -89,7 +87,7 @@ class FirmwareUpdateEntity(PlatformEntity):
8987
)
9088
_attr_installed_version: str | None = None
9189
_attr_in_progress: bool = False
92-
_attr_progress: int = 0
90+
_attr_update_percentage: float | None = None
9391
_attr_latest_version: str | None = None
9492
_attr_release_summary: str | None = None
9593
_attr_release_notes: str | None = None
@@ -152,14 +150,13 @@ def in_progress(self) -> bool | None:
152150
return self._attr_in_progress
153151

154152
@property
155-
def progress(self) -> int | None:
153+
def update_percentage(self) -> float | None:
156154
"""Update installation progress.
157155
158-
Needs UpdateEntityFeature.PROGRESS flag to be set for it to be used.
159-
160-
Returns an integer indicating the progress from 0 to 100%.
156+
Returns a number indicating the progress from 0 to 100%. If an update's progress
157+
is indeterminate, this will return None.
161158
"""
162-
return self._attr_progress
159+
return self._attr_update_percentage
163160

164161
@property
165162
def latest_version(self) -> str | None:
@@ -200,7 +197,7 @@ def state_attributes(self) -> dict[str, Any] | None:
200197
return {
201198
ATTR_INSTALLED_VERSION: self.installed_version,
202199
ATTR_IN_PROGRESS: self.in_progress,
203-
ATTR_PROGRESS: self.progress,
200+
ATTR_UPDATE_PERCENTAGE: self.update_percentage,
204201
ATTR_LATEST_VERSION: self.latest_version,
205202
ATTR_RELEASE_SUMMARY: release_summary,
206203
ATTR_RELEASE_NOTES: self.release_notes,
@@ -260,7 +257,7 @@ def _update_progress(self, current: int, total: int, progress: float) -> None:
260257
if not self._attr_in_progress:
261258
return
262259

263-
self._attr_progress = int(progress)
260+
self._attr_update_percentage = progress
264261
self.maybe_emit_state_changed_event()
265262

266263
async def async_install(self, version: str | None) -> None:
@@ -284,7 +281,7 @@ async def async_install(self, version: str | None) -> None:
284281
raise ZHAException(f"Version {version!r} is not available")
285282

286283
self._attr_in_progress = True
287-
self._attr_progress = 0
284+
self._attr_update_percentage = None
288285
self.maybe_emit_state_changed_event()
289286

290287
try:
@@ -309,5 +306,6 @@ async def async_install(self, version: str | None) -> None:
309306

310307
async def on_remove(self) -> None:
311308
"""Call when entity will be removed."""
312-
await super().on_remove()
313309
self._attr_in_progress = False
310+
self.device.device.remove_listener(self)
311+
await super().on_remove()

0 commit comments

Comments
 (0)