mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 17:27:52 +00:00
Fix AVM Fritz!Tools update entity (#100151)
* move update entity to coordinator * fix tests
This commit is contained in:
parent
15b9963a24
commit
3d28c6d636
@ -1096,7 +1096,7 @@ class FritzBoxBaseEntity:
|
||||
class FritzRequireKeysMixin:
|
||||
"""Fritz entity description mix in."""
|
||||
|
||||
value_fn: Callable[[FritzStatus, Any], Any]
|
||||
value_fn: Callable[[FritzStatus, Any], Any] | None
|
||||
|
||||
|
||||
@dataclass
|
||||
@ -1118,9 +1118,12 @@ class FritzBoxBaseCoordinatorEntity(update_coordinator.CoordinatorEntity[AvmWrap
|
||||
) -> None:
|
||||
"""Init device info class."""
|
||||
super().__init__(avm_wrapper)
|
||||
self.async_on_remove(
|
||||
avm_wrapper.register_entity_updates(description.key, description.value_fn)
|
||||
)
|
||||
if description.value_fn is not None:
|
||||
self.async_on_remove(
|
||||
avm_wrapper.register_entity_updates(
|
||||
description.key, description.value_fn
|
||||
)
|
||||
)
|
||||
self.entity_description = description
|
||||
self._device_name = device_name
|
||||
self._attr_unique_id = f"{avm_wrapper.unique_id}-{description.key}"
|
||||
|
@ -1,20 +1,31 @@
|
||||
"""Support for AVM FRITZ!Box update platform."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.update import UpdateEntity, UpdateEntityFeature
|
||||
from homeassistant.components.update import (
|
||||
UpdateEntity,
|
||||
UpdateEntityDescription,
|
||||
UpdateEntityFeature,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EntityCategory
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .common import AvmWrapper, FritzBoxBaseEntity
|
||||
from .common import AvmWrapper, FritzBoxBaseCoordinatorEntity, FritzEntityDescription
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@dataclass
|
||||
class FritzUpdateEntityDescription(UpdateEntityDescription, FritzEntityDescription):
|
||||
"""Describes Fritz update entity."""
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
) -> None:
|
||||
@ -27,11 +38,13 @@ async def async_setup_entry(
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class FritzBoxUpdateEntity(FritzBoxBaseEntity, UpdateEntity):
|
||||
class FritzBoxUpdateEntity(FritzBoxBaseCoordinatorEntity, UpdateEntity):
|
||||
"""Mixin for update entity specific attributes."""
|
||||
|
||||
_attr_entity_category = EntityCategory.CONFIG
|
||||
_attr_supported_features = UpdateEntityFeature.INSTALL
|
||||
_attr_title = "FRITZ!OS"
|
||||
entity_description: FritzUpdateEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@ -39,29 +52,30 @@ class FritzBoxUpdateEntity(FritzBoxBaseEntity, UpdateEntity):
|
||||
device_friendly_name: str,
|
||||
) -> None:
|
||||
"""Init FRITZ!Box connectivity class."""
|
||||
self._attr_name = f"{device_friendly_name} FRITZ!OS"
|
||||
self._attr_unique_id = f"{avm_wrapper.unique_id}-update"
|
||||
super().__init__(avm_wrapper, device_friendly_name)
|
||||
description = FritzUpdateEntityDescription(
|
||||
key="update", name="FRITZ!OS", value_fn=None
|
||||
)
|
||||
super().__init__(avm_wrapper, device_friendly_name, description)
|
||||
|
||||
@property
|
||||
def installed_version(self) -> str | None:
|
||||
"""Version currently in use."""
|
||||
return self._avm_wrapper.current_firmware
|
||||
return self.coordinator.current_firmware
|
||||
|
||||
@property
|
||||
def latest_version(self) -> str | None:
|
||||
"""Latest version available for install."""
|
||||
if self._avm_wrapper.update_available:
|
||||
return self._avm_wrapper.latest_firmware
|
||||
return self._avm_wrapper.current_firmware
|
||||
if self.coordinator.update_available:
|
||||
return self.coordinator.latest_firmware
|
||||
return self.coordinator.current_firmware
|
||||
|
||||
@property
|
||||
def release_url(self) -> str | None:
|
||||
"""URL to the full release notes of the latest version available."""
|
||||
return self._avm_wrapper.release_url
|
||||
return self.coordinator.release_url
|
||||
|
||||
async def async_install(
|
||||
self, version: str | None, backup: bool, **kwargs: Any
|
||||
) -> None:
|
||||
"""Install an update."""
|
||||
await self._avm_wrapper.async_trigger_firmware_update()
|
||||
await self.coordinator.async_trigger_firmware_update()
|
||||
|
@ -8,11 +8,25 @@ from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from .const import MOCK_FIRMWARE_AVAILABLE, MOCK_FIRMWARE_RELEASE_URL, MOCK_USER_DATA
|
||||
from .const import (
|
||||
MOCK_FB_SERVICES,
|
||||
MOCK_FIRMWARE_AVAILABLE,
|
||||
MOCK_FIRMWARE_RELEASE_URL,
|
||||
MOCK_USER_DATA,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.typing import ClientSessionGenerator
|
||||
|
||||
AVAILABLE_UPDATE = {
|
||||
"UserInterface1": {
|
||||
"GetInfo": {
|
||||
"NewX_AVM-DE_Version": MOCK_FIRMWARE_AVAILABLE,
|
||||
"NewX_AVM-DE_InfoURL": MOCK_FIRMWARE_RELEASE_URL,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async def test_update_entities_initialized(
|
||||
hass: HomeAssistant,
|
||||
@ -41,23 +55,21 @@ async def test_update_available(
|
||||
) -> None:
|
||||
"""Test update entities."""
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.fritz.common.FritzBoxTools._update_device_info",
|
||||
return_value=(True, MOCK_FIRMWARE_AVAILABLE, MOCK_FIRMWARE_RELEASE_URL),
|
||||
):
|
||||
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
|
||||
entry.add_to_hass(hass)
|
||||
fc_class_mock().override_services({**MOCK_FB_SERVICES, **AVAILABLE_UPDATE})
|
||||
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
assert entry.state == ConfigEntryState.LOADED
|
||||
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
update = hass.states.get("update.mock_title_fritz_os")
|
||||
assert update is not None
|
||||
assert update.state == "on"
|
||||
assert update.attributes.get("installed_version") == "7.29"
|
||||
assert update.attributes.get("latest_version") == MOCK_FIRMWARE_AVAILABLE
|
||||
assert update.attributes.get("release_url") == MOCK_FIRMWARE_RELEASE_URL
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
assert entry.state == ConfigEntryState.LOADED
|
||||
|
||||
update = hass.states.get("update.mock_title_fritz_os")
|
||||
assert update is not None
|
||||
assert update.state == "on"
|
||||
assert update.attributes.get("installed_version") == "7.29"
|
||||
assert update.attributes.get("latest_version") == MOCK_FIRMWARE_AVAILABLE
|
||||
assert update.attributes.get("release_url") == MOCK_FIRMWARE_RELEASE_URL
|
||||
|
||||
|
||||
async def test_no_update_available(
|
||||
@ -90,10 +102,9 @@ async def test_available_update_can_be_installed(
|
||||
) -> None:
|
||||
"""Test update entities."""
|
||||
|
||||
fc_class_mock().override_services({**MOCK_FB_SERVICES, **AVAILABLE_UPDATE})
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.fritz.common.FritzBoxTools._update_device_info",
|
||||
return_value=(True, MOCK_FIRMWARE_AVAILABLE, MOCK_FIRMWARE_RELEASE_URL),
|
||||
), patch(
|
||||
"homeassistant.components.fritz.common.FritzBoxTools.async_trigger_firmware_update",
|
||||
return_value=True,
|
||||
) as mocked_update_call:
|
||||
|
Loading…
x
Reference in New Issue
Block a user