Update DeviceInfo.sw_version value for Shelly Gen2 sleeping devices (#101338)

* Update device info for gen2 sleeping devices

* Add test

* Update sw_version only if the firmware_version value has changed

* Rename device_update_info() to update_device_fw_info()

* Remove duplicate comparison
This commit is contained in:
Maciej Bieniek 2023-10-04 09:00:17 +00:00 committed by GitHub
parent d3c5b9777b
commit 3aa6771835
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 11 deletions

View file

@ -58,7 +58,7 @@ from .const import (
UPDATE_PERIOD_MULTIPLIER,
BLEScannerMode,
)
from .utils import device_update_info, get_rpc_device_wakeup_period
from .utils import get_rpc_device_wakeup_period, update_device_fw_info
_DeviceT = TypeVar("_DeviceT", bound="BlockDevice|RpcDevice")
@ -374,16 +374,13 @@ class ShellyRestCoordinator(ShellyCoordinatorBase[BlockDevice]):
if self.device.status["uptime"] > 2 * REST_SENSORS_UPDATE_INTERVAL:
return
old_firmware = self.device.firmware_version
await self.device.update_shelly()
if self.device.firmware_version == old_firmware:
return
except DeviceConnectionError as err:
raise UpdateFailed(f"Error fetching data: {repr(err)}") from err
except InvalidAuthError:
self.entry.async_start_reauth(self.hass)
else:
device_update_info(self.hass, self.device, self.entry)
update_device_fw_info(self.hass, self.device, self.entry)
class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]):
@ -531,7 +528,7 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]):
LOGGER.debug("Reconnecting to Shelly RPC Device - %s", self.name)
try:
await self.device.initialize()
device_update_info(self.hass, self.device, self.entry)
update_device_fw_info(self.hass, self.device, self.entry)
except DeviceConnectionError as err:
raise UpdateFailed(f"Device disconnected: {repr(err)}") from err
except InvalidAuthError:
@ -617,6 +614,8 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]):
self.hass.async_create_task(self._async_disconnected())
elif update_type is RpcUpdateType.STATUS:
self.async_set_updated_data(None)
if self.sleep_period:
update_device_fw_info(self.hass, self.device, self.entry)
elif update_type is RpcUpdateType.EVENT and (event := self.device.event):
self._async_device_event_handler(event)

View file

@ -375,13 +375,10 @@ def get_rpc_input_triggers(device: RpcDevice) -> list[tuple[str, str]]:
@callback
def device_update_info(
def update_device_fw_info(
hass: HomeAssistant, shellydevice: BlockDevice | RpcDevice, entry: ConfigEntry
) -> None:
"""Update device registry info."""
LOGGER.debug("Updating device registry info for %s", entry.title)
"""Update the firmware version information in the device registry."""
assert entry.unique_id
dev_reg = dr_async_get(hass)
@ -389,6 +386,11 @@ def device_update_info(
identifiers={(DOMAIN, entry.entry_id)},
connections={(CONNECTION_NETWORK_MAC, format_mac(entry.unique_id))},
):
if device.sw_version == shellydevice.firmware_version:
return
LOGGER.debug("Updating device registry info for %s", entry.title)
dev_reg.async_update_device(device.id, sw_version=shellydevice.firmware_version)

View file

@ -23,8 +23,10 @@ from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
from homeassistant.const import ATTR_DEVICE_ID, STATE_ON, STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import (
CONNECTION_NETWORK_MAC,
async_entries_for_config_entry,
async_get as async_get_dev_reg,
format_mac,
)
import homeassistant.helpers.issue_registry as ir
@ -632,3 +634,34 @@ async def test_rpc_polling_disconnected(
await mock_polling_rpc_update(hass, freezer)
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE
async def test_rpc_update_entry_fw_ver(
hass: HomeAssistant, mock_rpc_device, monkeypatch
) -> None:
"""Test RPC update entry firmware version."""
entry = await init_integration(hass, 2, sleep_period=600)
dev_reg = async_get_dev_reg(hass)
# Make device online
mock_rpc_device.mock_update()
await hass.async_block_till_done()
device = dev_reg.async_get_device(
identifiers={(DOMAIN, entry.entry_id)},
connections={(CONNECTION_NETWORK_MAC, format_mac(entry.unique_id))},
)
assert device.sw_version == "some fw string"
monkeypatch.setattr(mock_rpc_device, "firmware_version", "99.0.0")
mock_rpc_device.mock_update()
await hass.async_block_till_done()
device = dev_reg.async_get_device(
identifiers={(DOMAIN, entry.entry_id)},
connections={(CONNECTION_NETWORK_MAC, format_mac(entry.unique_id))},
)
assert device.sw_version == "99.0.0"