"""Support for AdGuard Home sensors.""" from __future__ import annotations from collections.abc import Callable, Coroutine from dataclasses import dataclass from datetime import timedelta from typing import Any from adguardhome import AdGuardHome from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.const import PERCENTAGE, UnitOfTime from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from . import AdGuardConfigEntry, AdGuardData from .const import DOMAIN from .entity import AdGuardHomeEntity SCAN_INTERVAL = timedelta(seconds=300) PARALLEL_UPDATES = 4 @dataclass(frozen=True, kw_only=True) class AdGuardHomeEntityDescription(SensorEntityDescription): """Describes AdGuard Home sensor entity.""" value_fn: Callable[[AdGuardHome], Coroutine[Any, Any, int | float]] SENSORS: tuple[AdGuardHomeEntityDescription, ...] = ( AdGuardHomeEntityDescription( key="dns_queries", translation_key="dns_queries", native_unit_of_measurement="queries", value_fn=lambda adguard: adguard.stats.dns_queries(), ), AdGuardHomeEntityDescription( key="blocked_filtering", translation_key="dns_queries_blocked", native_unit_of_measurement="queries", value_fn=lambda adguard: adguard.stats.blocked_filtering(), ), AdGuardHomeEntityDescription( key="blocked_percentage", translation_key="dns_queries_blocked_ratio", native_unit_of_measurement=PERCENTAGE, value_fn=lambda adguard: adguard.stats.blocked_percentage(), ), AdGuardHomeEntityDescription( key="blocked_parental", translation_key="parental_control_blocked", native_unit_of_measurement="requests", value_fn=lambda adguard: adguard.stats.replaced_parental(), ), AdGuardHomeEntityDescription( key="blocked_safebrowsing", translation_key="safe_browsing_blocked", native_unit_of_measurement="requests", value_fn=lambda adguard: adguard.stats.replaced_safebrowsing(), ), AdGuardHomeEntityDescription( key="enforced_safesearch", translation_key="safe_searches_enforced", native_unit_of_measurement="requests", value_fn=lambda adguard: adguard.stats.replaced_safesearch(), ), AdGuardHomeEntityDescription( key="average_speed", translation_key="average_processing_speed", native_unit_of_measurement=UnitOfTime.MILLISECONDS, value_fn=lambda adguard: adguard.stats.avg_processing_time(), ), AdGuardHomeEntityDescription( key="rules_count", translation_key="rules_count", native_unit_of_measurement="rules", value_fn=lambda adguard: adguard.filtering.rules_count(allowlist=False), entity_registry_enabled_default=False, ), ) async def async_setup_entry( hass: HomeAssistant, entry: AdGuardConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up AdGuard Home sensor based on a config entry.""" data = entry.runtime_data async_add_entities( [AdGuardHomeSensor(data, entry, description) for description in SENSORS], True, ) class AdGuardHomeSensor(AdGuardHomeEntity, SensorEntity): """Defines a AdGuard Home sensor.""" entity_description: AdGuardHomeEntityDescription def __init__( self, data: AdGuardData, entry: AdGuardConfigEntry, description: AdGuardHomeEntityDescription, ) -> None: """Initialize AdGuard Home sensor.""" super().__init__(data, entry) self.entity_description = description self._attr_unique_id = "_".join( [ DOMAIN, self.adguard.host, str(self.adguard.port), "sensor", description.key, ] ) async def _adguard_update(self) -> None: """Update AdGuard Home entity.""" value = await self.entity_description.value_fn(self.adguard) self._attr_native_value = value if isinstance(value, float): self._attr_native_value = f"{value:.2f}"