"""Support for update entities of a Pi-hole system.""" from __future__ import annotations from collections.abc import Callable from dataclasses import dataclass from hole import Hole from homeassistant.components.update import UpdateEntity, UpdateEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from . import PiHoleEntity from .const import DATA_KEY_API, DATA_KEY_COORDINATOR, DOMAIN @dataclass class PiHoleUpdateEntityDescription(UpdateEntityDescription): """Describes PiHole update entity.""" installed_version: Callable[[dict], str | None] = lambda api: None latest_version: Callable[[dict], str | None] = lambda api: None release_base_url: str | None = None title: str | None = None UPDATE_ENTITY_TYPES: tuple[PiHoleUpdateEntityDescription, ...] = ( PiHoleUpdateEntityDescription( key="core_update_available", name="Core Update Available", title="Pi-hole Core", entity_category=EntityCategory.DIAGNOSTIC, installed_version=lambda versions: versions.get("core_current"), latest_version=lambda versions: versions.get("core_latest"), release_base_url="https://github.com/pi-hole/pi-hole/releases/tag", ), PiHoleUpdateEntityDescription( key="web_update_available", name="Web Update Available", title="Pi-hole Web interface", entity_category=EntityCategory.DIAGNOSTIC, installed_version=lambda versions: versions.get("web_current"), latest_version=lambda versions: versions.get("web_latest"), release_base_url="https://github.com/pi-hole/AdminLTE/releases/tag", ), PiHoleUpdateEntityDescription( key="ftl_update_available", name="FTL Update Available", title="Pi-hole FTL DNS", entity_category=EntityCategory.DIAGNOSTIC, installed_version=lambda versions: versions.get("FTL_current"), latest_version=lambda versions: versions.get("FTL_latest"), release_base_url="https://github.com/pi-hole/FTL/releases/tag", ), ) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up the Pi-hole update entities.""" name = entry.data[CONF_NAME] hole_data = hass.data[DOMAIN][entry.entry_id] async_add_entities( PiHoleUpdateEntity( hole_data[DATA_KEY_API], hole_data[DATA_KEY_COORDINATOR], name, entry.entry_id, description, ) for description in UPDATE_ENTITY_TYPES ) class PiHoleUpdateEntity(PiHoleEntity, UpdateEntity): """Representation of a Pi-hole update entity.""" entity_description: PiHoleUpdateEntityDescription def __init__( self, api: Hole, coordinator: DataUpdateCoordinator, name: str, server_unique_id: str, description: PiHoleUpdateEntityDescription, ) -> None: """Initialize a Pi-hole update entity.""" super().__init__(api, coordinator, name, server_unique_id) self.entity_description = description self._attr_name = f"{name} {description.name}" self._attr_unique_id = f"{self._server_unique_id}/{description.name}" self._attr_title = description.title @property def installed_version(self) -> str | None: """Version installed and in use.""" if isinstance(self.api.versions, dict): return self.entity_description.installed_version(self.api.versions) return None @property def latest_version(self) -> str | None: """Latest version available for install.""" if isinstance(self.api.versions, dict): return self.entity_description.latest_version(self.api.versions) return None @property def release_url(self) -> str | None: """URL to the full release notes of the latest version available.""" if self.latest_version: return f"{self.entity_description.release_base_url}/{self.latest_version}" return None