React on changed firmware version in devolo_home_network (#101513)

This commit is contained in:
Guido Schmitz 2023-10-06 13:37:48 +02:00 committed by GitHub
parent 1c590f8d0e
commit 3cd4d26eb9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 2 deletions

View file

@ -28,6 +28,7 @@ from homeassistant.const import (
)
from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.httpx_client import get_async_client
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
@ -54,6 +55,7 @@ async def async_setup_entry( # noqa: C901
hass.data.setdefault(DOMAIN, {})
zeroconf_instance = await zeroconf.async_get_async_instance(hass)
async_client = get_async_client(hass)
device_registry = dr.async_get(hass)
try:
device = Device(
@ -73,6 +75,7 @@ async def async_setup_entry( # noqa: C901
async def async_update_firmware_available() -> UpdateFirmwareCheck:
"""Fetch data from API endpoint."""
assert device.device
update_sw_version(device_registry, device)
try:
return await device.device.async_check_firmware_available()
except DeviceUnavailable as err:
@ -81,6 +84,7 @@ async def async_setup_entry( # noqa: C901
async def async_update_connected_plc_devices() -> LogicalNetwork:
"""Fetch data from API endpoint."""
assert device.plcnet
update_sw_version(device_registry, device)
try:
return await device.plcnet.async_get_network_overview()
except DeviceUnavailable as err:
@ -89,6 +93,7 @@ async def async_setup_entry( # noqa: C901
async def async_update_guest_wifi_status() -> WifiGuestAccessGet:
"""Fetch data from API endpoint."""
assert device.device
update_sw_version(device_registry, device)
try:
return await device.device.async_get_wifi_guest_access()
except DeviceUnavailable as err:
@ -99,6 +104,7 @@ async def async_setup_entry( # noqa: C901
async def async_update_led_status() -> bool:
"""Fetch data from API endpoint."""
assert device.device
update_sw_version(device_registry, device)
try:
return await device.device.async_get_led_setting()
except DeviceUnavailable as err:
@ -107,6 +113,7 @@ async def async_setup_entry( # noqa: C901
async def async_update_wifi_connected_station() -> list[ConnectedStationInfo]:
"""Fetch data from API endpoint."""
assert device.device
update_sw_version(device_registry, device)
try:
return await device.device.async_get_wifi_connected_station()
except DeviceUnavailable as err:
@ -115,6 +122,7 @@ async def async_setup_entry( # noqa: C901
async def async_update_wifi_neighbor_access_points() -> list[NeighborAPInfo]:
"""Fetch data from API endpoint."""
assert device.device
update_sw_version(device_registry, device)
try:
return await device.device.async_get_wifi_neighbor_access_points()
except DeviceUnavailable as err:
@ -211,3 +219,16 @@ def platforms(device: Device) -> set[Platform]:
if device.device and "update" in device.device.features:
supported_platforms.add(Platform.UPDATE)
return supported_platforms
@callback
def update_sw_version(device_registry: dr.DeviceRegistry, device: Device) -> None:
"""Update device registry with new firmware version."""
if (
device_entry := device_registry.async_get_device(
identifiers={(DOMAIN, str(device.serial_number))}
)
) and device_entry.sw_version != device.firmware_version:
device_registry.async_update_device(
device_id=device_entry.id, sw_version=device.firmware_version
)

View file

@ -31,12 +31,18 @@ class MockDevice(Device):
) -> None:
"""Bring mock in a well defined state."""
super().__init__(ip, zeroconf_instance)
self._firmware_version = DISCOVERY_INFO.properties["FirmwareVersion"]
self.reset()
@property
def firmware_version(self) -> str:
"""Mock firmware version currently installed."""
return DISCOVERY_INFO.properties["FirmwareVersion"]
return self._firmware_version
@firmware_version.setter
def firmware_version(self, version: str) -> None:
"""Mock firmware version currently installed."""
self._firmware_version = version
async def async_connect(
self, session_instance: httpx.AsyncClient | None = None
@ -49,6 +55,7 @@ class MockDevice(Device):
def reset(self):
"""Reset mock to starting point."""
self._firmware_version = DISCOVERY_INFO.properties["FirmwareVersion"]
self.async_disconnect = AsyncMock()
self.device = DeviceApi(IP, None, DISCOVERY_INFO)
self.device.async_check_firmware_available = AsyncMock(

View file

@ -14,9 +14,10 @@ from homeassistant.config_entries import SOURCE_REAUTH
from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers import device_registry as dr, entity_registry as er
from . import configure_integration
from .const import FIRMWARE_UPDATE_AVAILABLE
from .mock import MockDevice
from tests.common import async_fire_time_changed
@ -38,6 +39,7 @@ async def test_update_setup(hass: HomeAssistant) -> None:
async def test_update_firmware(
hass: HomeAssistant,
mock_device: MockDevice,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
freezer: FrozenDateTimeFactory,
snapshot: SnapshotAssertion,
@ -62,6 +64,9 @@ async def test_update_firmware(
assert mock_device.device.async_start_firmware_update.call_count == 1
# Emulate state change
mock_device.firmware_version = FIRMWARE_UPDATE_AVAILABLE.new_firmware_version.split(
"_"
)[0]
mock_device.device.async_check_firmware_available.return_value = (
UpdateFirmwareCheck(result=UPDATE_NOT_AVAILABLE)
)
@ -73,6 +78,12 @@ async def test_update_firmware(
assert state is not None
assert state.state == STATE_OFF
device_info = device_registry.async_get_device(
{(DOMAIN, mock_device.serial_number)}
)
assert device_info is not None
assert device_info.sw_version == mock_device.firmware_version
await hass.config_entries.async_unload(entry.entry_id)