"""Support for AdGuard Home sensors.""" from datetime import timedelta from adguardhome import AdGuardHomeConnectionError from homeassistant.components.adguard import AdGuardHomeDeviceEntity from homeassistant.components.adguard.const import ( DATA_ADGUARD_CLIENT, DATA_ADGUARD_VERION, DOMAIN, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, TIME_MILLISECONDS from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers.typing import HomeAssistantType SCAN_INTERVAL = timedelta(seconds=300) PARALLEL_UPDATES = 4 async def async_setup_entry( hass: HomeAssistantType, entry: ConfigEntry, async_add_entities ) -> None: """Set up AdGuard Home sensor based on a config entry.""" adguard = hass.data[DOMAIN][DATA_ADGUARD_CLIENT] try: version = await adguard.version() except AdGuardHomeConnectionError as exception: raise PlatformNotReady from exception hass.data[DOMAIN][DATA_ADGUARD_VERION] = version sensors = [ AdGuardHomeDNSQueriesSensor(adguard), AdGuardHomeBlockedFilteringSensor(adguard), AdGuardHomePercentageBlockedSensor(adguard), AdGuardHomeReplacedParentalSensor(adguard), AdGuardHomeReplacedSafeBrowsingSensor(adguard), AdGuardHomeReplacedSafeSearchSensor(adguard), AdGuardHomeAverageProcessingTimeSensor(adguard), AdGuardHomeRulesCountSensor(adguard), ] async_add_entities(sensors, True) class AdGuardHomeSensor(AdGuardHomeDeviceEntity): """Defines a AdGuard Home sensor.""" def __init__( self, adguard, name: str, icon: str, measurement: str, unit_of_measurement: str, enabled_default: bool = True, ) -> None: """Initialize AdGuard Home sensor.""" self._state = None self._unit_of_measurement = unit_of_measurement self.measurement = measurement super().__init__(adguard, name, icon, enabled_default) @property def unique_id(self) -> str: """Return the unique ID for this sensor.""" return "_".join( [ DOMAIN, self.adguard.host, str(self.adguard.port), "sensor", self.measurement, ] ) @property def state(self): """Return the state of the sensor.""" return self._state @property def unit_of_measurement(self) -> str: """Return the unit this state is expressed in.""" return self._unit_of_measurement class AdGuardHomeDNSQueriesSensor(AdGuardHomeSensor): """Defines a AdGuard Home DNS Queries sensor.""" def __init__(self, adguard): """Initialize AdGuard Home sensor.""" super().__init__( adguard, "AdGuard DNS Queries", "mdi:magnify", "dns_queries", "queries" ) async def _adguard_update(self) -> None: """Update AdGuard Home entity.""" self._state = await self.adguard.stats.dns_queries() class AdGuardHomeBlockedFilteringSensor(AdGuardHomeSensor): """Defines a AdGuard Home blocked by filtering sensor.""" def __init__(self, adguard): """Initialize AdGuard Home sensor.""" super().__init__( adguard, "AdGuard DNS Queries Blocked", "mdi:magnify-close", "blocked_filtering", "queries", enabled_default=False, ) async def _adguard_update(self) -> None: """Update AdGuard Home entity.""" self._state = await self.adguard.stats.blocked_filtering() class AdGuardHomePercentageBlockedSensor(AdGuardHomeSensor): """Defines a AdGuard Home blocked percentage sensor.""" def __init__(self, adguard): """Initialize AdGuard Home sensor.""" super().__init__( adguard, "AdGuard DNS Queries Blocked Ratio", "mdi:magnify-close", "blocked_percentage", PERCENTAGE, ) async def _adguard_update(self) -> None: """Update AdGuard Home entity.""" percentage = await self.adguard.stats.blocked_percentage() self._state = f"{percentage:.2f}" class AdGuardHomeReplacedParentalSensor(AdGuardHomeSensor): """Defines a AdGuard Home replaced by parental control sensor.""" def __init__(self, adguard): """Initialize AdGuard Home sensor.""" super().__init__( adguard, "AdGuard Parental Control Blocked", "mdi:human-male-girl", "blocked_parental", "requests", ) async def _adguard_update(self) -> None: """Update AdGuard Home entity.""" self._state = await self.adguard.stats.replaced_parental() class AdGuardHomeReplacedSafeBrowsingSensor(AdGuardHomeSensor): """Defines a AdGuard Home replaced by safe browsing sensor.""" def __init__(self, adguard): """Initialize AdGuard Home sensor.""" super().__init__( adguard, "AdGuard Safe Browsing Blocked", "mdi:shield-half-full", "blocked_safebrowsing", "requests", ) async def _adguard_update(self) -> None: """Update AdGuard Home entity.""" self._state = await self.adguard.stats.replaced_safebrowsing() class AdGuardHomeReplacedSafeSearchSensor(AdGuardHomeSensor): """Defines a AdGuard Home replaced by safe search sensor.""" def __init__(self, adguard): """Initialize AdGuard Home sensor.""" super().__init__( adguard, "AdGuard Safe Searches Enforced", "mdi:shield-search", "enforced_safesearch", "requests", ) async def _adguard_update(self) -> None: """Update AdGuard Home entity.""" self._state = await self.adguard.stats.replaced_safesearch() class AdGuardHomeAverageProcessingTimeSensor(AdGuardHomeSensor): """Defines a AdGuard Home average processing time sensor.""" def __init__(self, adguard): """Initialize AdGuard Home sensor.""" super().__init__( adguard, "AdGuard Average Processing Speed", "mdi:speedometer", "average_speed", TIME_MILLISECONDS, ) async def _adguard_update(self) -> None: """Update AdGuard Home entity.""" average = await self.adguard.stats.avg_processing_time() self._state = f"{average:.2f}" class AdGuardHomeRulesCountSensor(AdGuardHomeSensor): """Defines a AdGuard Home rules count sensor.""" def __init__(self, adguard): """Initialize AdGuard Home sensor.""" super().__init__( adguard, "AdGuard Rules Count", "mdi:counter", "rules_count", "rules", enabled_default=False, ) async def _adguard_update(self) -> None: """Update AdGuard Home entity.""" self._state = await self.adguard.filtering.rules_count()