Bump zwave_js lib to 0.43.0 and fix multi-file firmware updates (#79342)
parent
2b27cfdabb
commit
27413cee19
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
|||
from collections.abc import Callable
|
||||
import dataclasses
|
||||
from functools import partial, wraps
|
||||
from typing import Any, Literal, cast
|
||||
from typing import Any, Literal
|
||||
|
||||
from aiohttp import web, web_exceptions, web_request
|
||||
import voluptuous as vol
|
||||
|
@ -27,7 +27,7 @@ from zwave_js_server.exceptions import (
|
|||
NotFoundError,
|
||||
SetValueFailed,
|
||||
)
|
||||
from zwave_js_server.firmware import begin_firmware_update
|
||||
from zwave_js_server.firmware import update_firmware
|
||||
from zwave_js_server.model.controller import (
|
||||
ControllerStatistics,
|
||||
InclusionGrant,
|
||||
|
@ -36,8 +36,9 @@ from zwave_js_server.model.controller import (
|
|||
)
|
||||
from zwave_js_server.model.driver import Driver
|
||||
from zwave_js_server.model.firmware import (
|
||||
FirmwareUpdateFinished,
|
||||
FirmwareUpdateData,
|
||||
FirmwareUpdateProgress,
|
||||
FirmwareUpdateResult,
|
||||
)
|
||||
from zwave_js_server.model.log_config import LogConfig
|
||||
from zwave_js_server.model.log_message import LogMessage
|
||||
|
@ -1897,11 +1898,14 @@ async def websocket_is_node_firmware_update_in_progress(
|
|||
|
||||
def _get_firmware_update_progress_dict(
|
||||
progress: FirmwareUpdateProgress,
|
||||
) -> dict[str, int]:
|
||||
) -> dict[str, int | float]:
|
||||
"""Get a dictionary of firmware update progress."""
|
||||
return {
|
||||
"current_file": progress.current_file,
|
||||
"total_files": progress.total_files,
|
||||
"sent_fragments": progress.sent_fragments,
|
||||
"total_fragments": progress.total_fragments,
|
||||
"progress": progress.progress,
|
||||
}
|
||||
|
||||
|
||||
|
@ -1943,14 +1947,16 @@ async def websocket_subscribe_firmware_update_status(
|
|||
|
||||
@callback
|
||||
def forward_finished(event: dict) -> None:
|
||||
finished: FirmwareUpdateFinished = event["firmware_update_finished"]
|
||||
finished: FirmwareUpdateResult = event["firmware_update_finished"]
|
||||
connection.send_message(
|
||||
websocket_api.event_message(
|
||||
msg[ID],
|
||||
{
|
||||
"event": event["event"],
|
||||
"status": finished.status,
|
||||
"success": finished.success,
|
||||
"wait_time": finished.wait_time,
|
||||
"reinterview": finished.reinterview,
|
||||
},
|
||||
)
|
||||
)
|
||||
|
@ -2052,21 +2058,20 @@ class FirmwareUploadView(HomeAssistantView):
|
|||
if "file" not in data or not isinstance(data["file"], web_request.FileField):
|
||||
raise web_exceptions.HTTPBadRequest
|
||||
|
||||
target = None
|
||||
if "target" in data:
|
||||
target = int(cast(str, data["target"]))
|
||||
|
||||
uploaded_file: web_request.FileField = data["file"]
|
||||
|
||||
try:
|
||||
await begin_firmware_update(
|
||||
await update_firmware(
|
||||
node.client.ws_server_url,
|
||||
node,
|
||||
uploaded_file.filename,
|
||||
await hass.async_add_executor_job(uploaded_file.file.read),
|
||||
[
|
||||
FirmwareUpdateData(
|
||||
uploaded_file.filename,
|
||||
await hass.async_add_executor_job(uploaded_file.file.read),
|
||||
)
|
||||
],
|
||||
async_get_clientsession(hass),
|
||||
additional_user_agent_components=USER_AGENT,
|
||||
target=target,
|
||||
)
|
||||
except BaseZwaveJSServerError as err:
|
||||
raise web_exceptions.HTTPBadRequest(reason=str(err)) from err
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Z-Wave",
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/zwave_js",
|
||||
"requirements": ["pyserial==3.5", "zwave-js-server-python==0.42.0"],
|
||||
"requirements": ["pyserial==3.5", "zwave-js-server-python==0.43.0"],
|
||||
"codeowners": ["@home-assistant/z-wave"],
|
||||
"dependencies": ["usb", "http", "websocket_api"],
|
||||
"iot_class": "local_push",
|
||||
|
|
|
@ -4,7 +4,6 @@ from __future__ import annotations
|
|||
import asyncio
|
||||
from collections.abc import Callable
|
||||
from datetime import datetime, timedelta
|
||||
from math import floor
|
||||
from typing import Any
|
||||
|
||||
from awesomeversion import AwesomeVersion
|
||||
|
@ -13,10 +12,9 @@ from zwave_js_server.const import NodeStatus
|
|||
from zwave_js_server.exceptions import BaseZwaveJSServerError, FailedZWaveCommand
|
||||
from zwave_js_server.model.driver import Driver
|
||||
from zwave_js_server.model.firmware import (
|
||||
FirmwareUpdateFinished,
|
||||
FirmwareUpdateInfo,
|
||||
FirmwareUpdateProgress,
|
||||
FirmwareUpdateStatus,
|
||||
FirmwareUpdateResult,
|
||||
)
|
||||
from zwave_js_server.model.node import Node as ZwaveNode
|
||||
|
||||
|
@ -91,9 +89,8 @@ class ZWaveNodeFirmwareUpdate(UpdateEntity):
|
|||
self._poll_unsub: Callable[[], None] | None = None
|
||||
self._progress_unsub: Callable[[], None] | None = None
|
||||
self._finished_unsub: Callable[[], None] | None = None
|
||||
self._num_files_installed: int = 0
|
||||
self._finished_event = asyncio.Event()
|
||||
self._finished_status: FirmwareUpdateStatus | None = None
|
||||
self._result: FirmwareUpdateResult | None = None
|
||||
|
||||
# Entity class attributes
|
||||
self._attr_name = "Firmware"
|
||||
|
@ -115,25 +112,14 @@ class ZWaveNodeFirmwareUpdate(UpdateEntity):
|
|||
progress: FirmwareUpdateProgress = event["firmware_update_progress"]
|
||||
if not self._latest_version_firmware:
|
||||
return
|
||||
# We will assume that each file in the firmware update represents an equal
|
||||
# percentage of the overall progress. This is likely not true because each file
|
||||
# may be a different size, but it's the best we can do since we don't know the
|
||||
# total number of fragments across all files.
|
||||
self._attr_in_progress = floor(
|
||||
100
|
||||
* (
|
||||
self._num_files_installed
|
||||
+ (progress.sent_fragments / progress.total_fragments)
|
||||
)
|
||||
/ len(self._latest_version_firmware.files)
|
||||
)
|
||||
self._attr_in_progress = int(progress.progress)
|
||||
self.async_write_ha_state()
|
||||
|
||||
@callback
|
||||
def _update_finished(self, event: dict[str, Any]) -> None:
|
||||
"""Update install progress on event."""
|
||||
finished: FirmwareUpdateFinished = event["firmware_update_finished"]
|
||||
self._finished_status = finished.status
|
||||
result: FirmwareUpdateResult = event["firmware_update_finished"]
|
||||
self._result = result
|
||||
self._finished_event.set()
|
||||
|
||||
@callback
|
||||
|
@ -149,10 +135,9 @@ class ZWaveNodeFirmwareUpdate(UpdateEntity):
|
|||
self._finished_unsub()
|
||||
self._finished_unsub = None
|
||||
|
||||
self._finished_status = None
|
||||
self._result = None
|
||||
self._finished_event.clear()
|
||||
self._num_files_installed = 0
|
||||
self._attr_in_progress = 0
|
||||
self._attr_in_progress = False
|
||||
if write_state:
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
@ -235,41 +220,23 @@ class ZWaveNodeFirmwareUpdate(UpdateEntity):
|
|||
"firmware update finished", self._update_finished
|
||||
)
|
||||
|
||||
for file in firmware.files:
|
||||
try:
|
||||
await self.driver.controller.async_begin_ota_firmware_update(
|
||||
self.node, file
|
||||
)
|
||||
except BaseZwaveJSServerError as err:
|
||||
self._unsub_firmware_events_and_reset_progress()
|
||||
raise HomeAssistantError(err) from err
|
||||
|
||||
# We need to block until we receive the `firmware update finished` event
|
||||
await self._finished_event.wait()
|
||||
# Clear the event so that a second firmware update blocks again
|
||||
self._finished_event.clear()
|
||||
assert self._finished_status is not None
|
||||
|
||||
# If status is not OK, we should throw an error to let the user know
|
||||
if self._finished_status not in (
|
||||
FirmwareUpdateStatus.OK_NO_RESTART,
|
||||
FirmwareUpdateStatus.OK_RESTART_PENDING,
|
||||
FirmwareUpdateStatus.OK_WAITING_FOR_ACTIVATION,
|
||||
):
|
||||
status = self._finished_status
|
||||
self._unsub_firmware_events_and_reset_progress()
|
||||
raise HomeAssistantError(status.name.replace("_", " ").title())
|
||||
|
||||
# If we get here, the firmware installation was successful and we need to
|
||||
# update progress accordingly
|
||||
self._num_files_installed += 1
|
||||
self._attr_in_progress = floor(
|
||||
100 * self._num_files_installed / len(firmware.files)
|
||||
try:
|
||||
await self.driver.controller.async_firmware_update_ota(
|
||||
self.node, firmware.files
|
||||
)
|
||||
except BaseZwaveJSServerError as err:
|
||||
self._unsub_firmware_events_and_reset_progress()
|
||||
raise HomeAssistantError(err) from err
|
||||
|
||||
# Clear the status so we can get a new one
|
||||
self._finished_status = None
|
||||
self.async_write_ha_state()
|
||||
# We need to block until we receive the `firmware update finished` event
|
||||
await self._finished_event.wait()
|
||||
assert self._result is not None
|
||||
|
||||
# If the update was not successful, we should throw an error to let the user know
|
||||
if not self._result.success:
|
||||
error_msg = self._result.status.name.replace("_", " ").title()
|
||||
self._unsub_firmware_events_and_reset_progress()
|
||||
raise HomeAssistantError(error_msg)
|
||||
|
||||
# If we get here, all files were installed successfully
|
||||
self._attr_installed_version = self._attr_latest_version = firmware.version
|
||||
|
|
|
@ -2622,7 +2622,7 @@ zigpy==0.51.1
|
|||
zm-py==0.5.2
|
||||
|
||||
# homeassistant.components.zwave_js
|
||||
zwave-js-server-python==0.42.0
|
||||
zwave-js-server-python==0.43.0
|
||||
|
||||
# homeassistant.components.zwave_me
|
||||
zwave_me_ws==0.2.6
|
||||
|
|
|
@ -1814,7 +1814,7 @@ zigpy-znp==0.9.0
|
|||
zigpy==0.51.1
|
||||
|
||||
# homeassistant.components.zwave_js
|
||||
zwave-js-server-python==0.42.0
|
||||
zwave-js-server-python==0.43.0
|
||||
|
||||
# homeassistant.components.zwave_me
|
||||
zwave_me_ws==0.2.6
|
||||
|
|
|
@ -28,6 +28,7 @@ from zwave_js_server.model.controller import (
|
|||
ProvisioningEntry,
|
||||
QRProvisioningInformation,
|
||||
)
|
||||
from zwave_js_server.model.firmware import FirmwareUpdateData
|
||||
from zwave_js_server.model.node import Node
|
||||
|
||||
from homeassistant.components.websocket_api import ERR_INVALID_FORMAT, ERR_NOT_FOUND
|
||||
|
@ -2815,18 +2816,20 @@ async def test_firmware_upload_view(
|
|||
client = await hass_client()
|
||||
device = get_device(hass, multisensor_6)
|
||||
with patch(
|
||||
"homeassistant.components.zwave_js.api.begin_firmware_update",
|
||||
"homeassistant.components.zwave_js.api.update_firmware",
|
||||
) as mock_cmd, patch.dict(
|
||||
"homeassistant.components.zwave_js.api.USER_AGENT",
|
||||
{"HomeAssistant": "0.0.0"},
|
||||
):
|
||||
resp = await client.post(
|
||||
f"/api/zwave_js/firmware/upload/{device.id}",
|
||||
data={"file": firmware_file, "target": "15"},
|
||||
data={"file": firmware_file},
|
||||
)
|
||||
assert mock_cmd.call_args[0][1:3] == (
|
||||
multisensor_6,
|
||||
[FirmwareUpdateData("file", bytes(10))],
|
||||
)
|
||||
assert mock_cmd.call_args[0][1:4] == (multisensor_6, "file", bytes(10))
|
||||
assert mock_cmd.call_args[1] == {
|
||||
"target": 15,
|
||||
"additional_user_agent_components": {"HomeAssistant": "0.0.0"},
|
||||
}
|
||||
assert json.loads(await resp.text()) is None
|
||||
|
@ -2839,7 +2842,7 @@ async def test_firmware_upload_view_failed_command(
|
|||
client = await hass_client()
|
||||
device = get_device(hass, multisensor_6)
|
||||
with patch(
|
||||
"homeassistant.components.zwave_js.api.begin_firmware_update",
|
||||
"homeassistant.components.zwave_js.api.update_firmware",
|
||||
side_effect=FailedCommand("test", "test"),
|
||||
):
|
||||
resp = await client.post(
|
||||
|
@ -3502,8 +3505,13 @@ async def test_subscribe_firmware_update_status(
|
|||
"source": "node",
|
||||
"event": "firmware update progress",
|
||||
"nodeId": multisensor_6.node_id,
|
||||
"sentFragments": 1,
|
||||
"totalFragments": 10,
|
||||
"progress": {
|
||||
"currentFile": 1,
|
||||
"totalFiles": 1,
|
||||
"sentFragments": 1,
|
||||
"totalFragments": 10,
|
||||
"progress": 10.0,
|
||||
},
|
||||
},
|
||||
)
|
||||
multisensor_6.receive_event(event)
|
||||
|
@ -3511,8 +3519,11 @@ async def test_subscribe_firmware_update_status(
|
|||
msg = await ws_client.receive_json()
|
||||
assert msg["event"] == {
|
||||
"event": "firmware update progress",
|
||||
"current_file": 1,
|
||||
"total_files": 1,
|
||||
"sent_fragments": 1,
|
||||
"total_fragments": 10,
|
||||
"progress": 10.0,
|
||||
}
|
||||
|
||||
event = Event(
|
||||
|
@ -3521,8 +3532,12 @@ async def test_subscribe_firmware_update_status(
|
|||
"source": "node",
|
||||
"event": "firmware update finished",
|
||||
"nodeId": multisensor_6.node_id,
|
||||
"status": 255,
|
||||
"waitTime": 10,
|
||||
"result": {
|
||||
"status": 255,
|
||||
"success": True,
|
||||
"waitTime": 10,
|
||||
"reInterview": False,
|
||||
},
|
||||
},
|
||||
)
|
||||
multisensor_6.receive_event(event)
|
||||
|
@ -3531,7 +3546,9 @@ async def test_subscribe_firmware_update_status(
|
|||
assert msg["event"] == {
|
||||
"event": "firmware update finished",
|
||||
"status": 255,
|
||||
"success": True,
|
||||
"wait_time": 10,
|
||||
"reinterview": False,
|
||||
}
|
||||
|
||||
|
||||
|
@ -3551,8 +3568,13 @@ async def test_subscribe_firmware_update_status_initial_value(
|
|||
"source": "node",
|
||||
"event": "firmware update progress",
|
||||
"nodeId": multisensor_6.node_id,
|
||||
"sentFragments": 1,
|
||||
"totalFragments": 10,
|
||||
"progress": {
|
||||
"currentFile": 1,
|
||||
"totalFiles": 1,
|
||||
"sentFragments": 1,
|
||||
"totalFragments": 10,
|
||||
"progress": 10.0,
|
||||
},
|
||||
},
|
||||
)
|
||||
multisensor_6.receive_event(event)
|
||||
|
@ -3574,8 +3596,11 @@ async def test_subscribe_firmware_update_status_initial_value(
|
|||
msg = await ws_client.receive_json()
|
||||
assert msg["event"] == {
|
||||
"event": "firmware update progress",
|
||||
"current_file": 1,
|
||||
"total_files": 1,
|
||||
"sent_fragments": 1,
|
||||
"total_fragments": 10,
|
||||
"progress": 10.0,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -324,7 +324,7 @@ async def test_update_entity_progress(
|
|||
assert attrs[ATTR_LATEST_VERSION] == "11.2.4"
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command.return_value = None
|
||||
client.async_send_command.return_value = {"success": False}
|
||||
|
||||
# Test successful install call without a version
|
||||
install_task = hass.async_create_task(
|
||||
|
@ -352,8 +352,13 @@ async def test_update_entity_progress(
|
|||
"source": "node",
|
||||
"event": "firmware update progress",
|
||||
"nodeId": node.node_id,
|
||||
"sentFragments": 1,
|
||||
"totalFragments": 20,
|
||||
"progress": {
|
||||
"currentFile": 1,
|
||||
"totalFiles": 1,
|
||||
"sentFragments": 1,
|
||||
"totalFragments": 20,
|
||||
"progress": 5.0,
|
||||
},
|
||||
},
|
||||
)
|
||||
node.receive_event(event)
|
||||
|
@ -370,7 +375,11 @@ async def test_update_entity_progress(
|
|||
"source": "node",
|
||||
"event": "firmware update finished",
|
||||
"nodeId": node.node_id,
|
||||
"status": FirmwareUpdateStatus.OK_NO_RESTART,
|
||||
"result": {
|
||||
"status": FirmwareUpdateStatus.OK_NO_RESTART,
|
||||
"success": True,
|
||||
"reInterview": False,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -381,142 +390,7 @@ async def test_update_entity_progress(
|
|||
state = hass.states.get(UPDATE_ENTITY)
|
||||
assert state
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_IN_PROGRESS] == 0
|
||||
assert attrs[ATTR_INSTALLED_VERSION] == "11.2.4"
|
||||
assert attrs[ATTR_LATEST_VERSION] == "11.2.4"
|
||||
assert state.state == STATE_OFF
|
||||
|
||||
await install_task
|
||||
|
||||
|
||||
async def test_update_entity_progress_multiple(
|
||||
hass,
|
||||
client,
|
||||
climate_radio_thermostat_ct100_plus_different_endpoints,
|
||||
integration,
|
||||
):
|
||||
"""Test update entity progress with multiple files."""
|
||||
node = climate_radio_thermostat_ct100_plus_different_endpoints
|
||||
client.async_send_command.return_value = FIRMWARE_UPDATE_MULTIPLE_FILES
|
||||
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(days=1))
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(UPDATE_ENTITY)
|
||||
assert state
|
||||
assert state.state == STATE_ON
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_INSTALLED_VERSION] == "10.7"
|
||||
assert attrs[ATTR_LATEST_VERSION] == "11.2.4"
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command.return_value = None
|
||||
|
||||
# Test successful install call without a version
|
||||
install_task = hass.async_create_task(
|
||||
hass.services.async_call(
|
||||
UPDATE_DOMAIN,
|
||||
SERVICE_INSTALL,
|
||||
{
|
||||
ATTR_ENTITY_ID: UPDATE_ENTITY,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
)
|
||||
|
||||
# Sleep so that task starts
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
state = hass.states.get(UPDATE_ENTITY)
|
||||
assert state
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_IN_PROGRESS] is True
|
||||
|
||||
node.receive_event(
|
||||
Event(
|
||||
type="firmware update progress",
|
||||
data={
|
||||
"source": "node",
|
||||
"event": "firmware update progress",
|
||||
"nodeId": node.node_id,
|
||||
"sentFragments": 1,
|
||||
"totalFragments": 20,
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
# Block so HA can do its thing
|
||||
await asyncio.sleep(0)
|
||||
|
||||
# Validate that the progress is updated (two files means progress is 50% of 5)
|
||||
state = hass.states.get(UPDATE_ENTITY)
|
||||
assert state
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_IN_PROGRESS] == 2
|
||||
|
||||
node.receive_event(
|
||||
Event(
|
||||
type="firmware update finished",
|
||||
data={
|
||||
"source": "node",
|
||||
"event": "firmware update finished",
|
||||
"nodeId": node.node_id,
|
||||
"status": FirmwareUpdateStatus.OK_NO_RESTART,
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
# Block so HA can do its thing
|
||||
await asyncio.sleep(0)
|
||||
|
||||
# One file done, progress should be 50%
|
||||
state = hass.states.get(UPDATE_ENTITY)
|
||||
assert state
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_IN_PROGRESS] == 50
|
||||
|
||||
node.receive_event(
|
||||
Event(
|
||||
type="firmware update progress",
|
||||
data={
|
||||
"source": "node",
|
||||
"event": "firmware update progress",
|
||||
"nodeId": node.node_id,
|
||||
"sentFragments": 1,
|
||||
"totalFragments": 20,
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
# Block so HA can do its thing
|
||||
await asyncio.sleep(0)
|
||||
|
||||
# Validate that the progress is updated (50% + 50% of 5)
|
||||
state = hass.states.get(UPDATE_ENTITY)
|
||||
assert state
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_IN_PROGRESS] == 52
|
||||
|
||||
node.receive_event(
|
||||
Event(
|
||||
type="firmware update finished",
|
||||
data={
|
||||
"source": "node",
|
||||
"event": "firmware update finished",
|
||||
"nodeId": node.node_id,
|
||||
"status": FirmwareUpdateStatus.OK_NO_RESTART,
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
# Block so HA can do its thing
|
||||
await asyncio.sleep(0)
|
||||
|
||||
# Validate that progress is reset and entity reflects new version
|
||||
state = hass.states.get(UPDATE_ENTITY)
|
||||
assert state
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_IN_PROGRESS] == 0
|
||||
assert attrs[ATTR_IN_PROGRESS] is False
|
||||
assert attrs[ATTR_INSTALLED_VERSION] == "11.2.4"
|
||||
assert attrs[ATTR_LATEST_VERSION] == "11.2.4"
|
||||
assert state.state == STATE_OFF
|
||||
|
@ -546,10 +420,11 @@ async def test_update_entity_install_failed(
|
|||
assert attrs[ATTR_LATEST_VERSION] == "11.2.4"
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command.return_value = None
|
||||
client.async_send_command.return_value = {"success": False}
|
||||
|
||||
async def call_install():
|
||||
await hass.services.async_call(
|
||||
# Test install call - we expect it to finish fail
|
||||
install_task = hass.async_create_task(
|
||||
hass.services.async_call(
|
||||
UPDATE_DOMAIN,
|
||||
SERVICE_INSTALL,
|
||||
{
|
||||
|
@ -557,9 +432,7 @@ async def test_update_entity_install_failed(
|
|||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
# Test install call - we expect it to raise
|
||||
install_task = hass.async_create_task(call_install())
|
||||
)
|
||||
|
||||
# Sleep so that task starts
|
||||
await asyncio.sleep(0.1)
|
||||
|
@ -570,8 +443,13 @@ async def test_update_entity_install_failed(
|
|||
"source": "node",
|
||||
"event": "firmware update progress",
|
||||
"nodeId": node.node_id,
|
||||
"sentFragments": 1,
|
||||
"totalFragments": 20,
|
||||
"progress": {
|
||||
"currentFile": 1,
|
||||
"totalFiles": 1,
|
||||
"sentFragments": 1,
|
||||
"totalFragments": 20,
|
||||
"progress": 5.0,
|
||||
},
|
||||
},
|
||||
)
|
||||
node.receive_event(event)
|
||||
|
@ -588,7 +466,11 @@ async def test_update_entity_install_failed(
|
|||
"source": "node",
|
||||
"event": "firmware update finished",
|
||||
"nodeId": node.node_id,
|
||||
"status": FirmwareUpdateStatus.ERROR_TIMEOUT,
|
||||
"result": {
|
||||
"status": FirmwareUpdateStatus.ERROR_TIMEOUT,
|
||||
"success": False,
|
||||
"reInterview": False,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -599,7 +481,7 @@ async def test_update_entity_install_failed(
|
|||
state = hass.states.get(UPDATE_ENTITY)
|
||||
assert state
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_IN_PROGRESS] == 0
|
||||
assert attrs[ATTR_IN_PROGRESS] is False
|
||||
assert attrs[ATTR_INSTALLED_VERSION] == "10.7"
|
||||
assert attrs[ATTR_LATEST_VERSION] == "11.2.4"
|
||||
assert state.state == STATE_ON
|
||||
|
|
Loading…
Reference in New Issue