mirror of
https://github.com/home-assistant/core.git
synced 2026-09-24 15:31:52 -05:00
Check for Z-Wave firmware updates of sleeping devices (#150123)
This commit is contained in:
@@ -10,7 +10,6 @@ from datetime import datetime, timedelta
|
||||
from typing import Any, Final, cast
|
||||
|
||||
from awesomeversion import AwesomeVersion
|
||||
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 (
|
||||
@@ -192,7 +191,6 @@ class ZWaveFirmwareUpdateEntity(UpdateEntity):
|
||||
self.entity_description = entity_description
|
||||
self.node = node
|
||||
self._latest_version_firmware: FirmwareUpdateInfo | None = None
|
||||
self._status_unsub: Callable[[], None] | None = None
|
||||
self._poll_unsub: Callable[[], None] | None = None
|
||||
self._progress_unsub: Callable[[], None] | None = None
|
||||
self._finished_unsub: Callable[[], None] | None = None
|
||||
@@ -213,12 +211,6 @@ class ZWaveFirmwareUpdateEntity(UpdateEntity):
|
||||
"""Return ZWave Node Firmware Update specific state data to be restored."""
|
||||
return ZWaveFirmwareUpdateExtraStoredData(self._latest_version_firmware)
|
||||
|
||||
@callback
|
||||
def _update_on_status_change(self, _: dict[str, Any]) -> None:
|
||||
"""Update the entity when node is awake."""
|
||||
self._status_unsub = None
|
||||
self.hass.async_create_task(self._async_update())
|
||||
|
||||
@callback
|
||||
def update_progress(self, event: dict[str, Any]) -> None:
|
||||
"""Update install progress on event."""
|
||||
@@ -270,14 +262,6 @@ class ZWaveFirmwareUpdateEntity(UpdateEntity):
|
||||
)
|
||||
return
|
||||
|
||||
# If device is asleep, wait for it to wake up before attempting an update
|
||||
if self.node.status == NodeStatus.ASLEEP:
|
||||
if not self._status_unsub:
|
||||
self._status_unsub = self.node.once(
|
||||
"wake up", self._update_on_status_change
|
||||
)
|
||||
return
|
||||
|
||||
try:
|
||||
# Retrieve all firmware updates including non-stable ones but filter
|
||||
# non-stable channels out
|
||||
@@ -436,10 +420,6 @@ class ZWaveFirmwareUpdateEntity(UpdateEntity):
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Call when entity will be removed."""
|
||||
if self._status_unsub:
|
||||
self._status_unsub()
|
||||
self._status_unsub = None
|
||||
|
||||
if self._poll_unsub:
|
||||
self._poll_unsub()
|
||||
self._poll_unsub = None
|
||||
|
||||
@@ -269,7 +269,7 @@ async def test_update_entity_sleep(
|
||||
zen_31: Node,
|
||||
integration: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test update occurs when device is asleep after it wakes up."""
|
||||
"""Test update occurs when device is asleep."""
|
||||
event = Event(
|
||||
"sleep",
|
||||
data={"source": "node", "event": "sleep", "nodeId": zen_31.node_id},
|
||||
@@ -283,29 +283,13 @@ async def test_update_entity_sleep(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Two nodes in total, the controller node and the zen_31 node.
|
||||
# The zen_31 node is asleep,
|
||||
# so we should only check for updates for the controller node.
|
||||
assert client.async_send_command.call_count == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert args["command"] == "controller.get_available_firmware_updates"
|
||||
assert args["nodeId"] == 1
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
|
||||
event = Event(
|
||||
"wake up",
|
||||
data={"source": "node", "event": "wake up", "nodeId": zen_31.node_id},
|
||||
)
|
||||
zen_31.receive_event(event)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Now that the zen_31 node is awake we can check for updates for it.
|
||||
# The controller node has already been checked,
|
||||
# so won't get another check now.
|
||||
assert client.async_send_command.call_count == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert args["command"] == "controller.get_available_firmware_updates"
|
||||
assert args["nodeId"] == 94
|
||||
# We should check for updates for both nodes, including the sleeping one
|
||||
# since the firmware check no longer requires device communication first.
|
||||
assert client.async_send_command.call_count == 2
|
||||
# Check calls were made for both nodes
|
||||
call_args = [call[0][0] for call in client.async_send_command.call_args_list]
|
||||
assert any(args["nodeId"] == 1 for args in call_args) # Controller node
|
||||
assert any(args["nodeId"] == 94 for args in call_args) # zen_31 node
|
||||
|
||||
|
||||
async def test_update_entity_dead(
|
||||
@@ -1158,28 +1142,3 @@ async def test_update_entity_no_latest_version(
|
||||
assert state.state == STATE_OFF
|
||||
assert state.attributes[ATTR_SKIPPED_VERSION] is None
|
||||
assert state.attributes[ATTR_LATEST_VERSION] == latest_version
|
||||
|
||||
|
||||
async def test_update_entity_unload_asleep_node(
|
||||
hass: HomeAssistant,
|
||||
client: MagicMock,
|
||||
wallmote_central_scene: Node,
|
||||
integration: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test unloading config entry after attempting an update for an asleep node."""
|
||||
config_entry = integration
|
||||
assert client.async_send_command.call_count == 0
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command.return_value = {"updates": []}
|
||||
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=5, days=1))
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Once call completed for the (awake) controller node.
|
||||
assert client.async_send_command.call_count == 1
|
||||
assert len(wallmote_central_scene._listeners["wake up"]) == 1
|
||||
|
||||
await hass.config_entries.async_unload(config_entry.entry_id)
|
||||
assert client.async_send_command.call_count == 1
|
||||
assert len(wallmote_central_scene._listeners["wake up"]) == 0
|
||||
|
||||
Reference in New Issue
Block a user