Some checks failed
Code Quality Check / Code Formatting (push) Failing after 21s
Code Quality Check / Security Analysis (push) Failing after 20s
Integration Testing / Integration Tests (2024.12.0, 3.13) (push) Failing after 1m32s
Integration Testing / Integration Tests (2025.9.4, 3.13) (push) Failing after 20s
Signed-off-by: Rafal Zielinski <sq4ind@gmail.com>
195 lines
7.0 KiB
Python
195 lines
7.0 KiB
Python
"""AdGuard Control Hub binary sensor platform."""
|
|
import logging
|
|
from typing import Any, Dict, List, Optional
|
|
|
|
from homeassistant.components.binary_sensor import (
|
|
BinarySensorEntity,
|
|
BinarySensorDeviceClass,
|
|
)
|
|
from homeassistant.config_entries import ConfigEntry
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
|
from homeassistant.helpers.entity import DeviceInfo, EntityCategory
|
|
|
|
from .api import AdGuardHomeAPI
|
|
from .const import DOMAIN, MANUFACTURER
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
config_entry: ConfigEntry,
|
|
async_add_entities: AddEntitiesCallback,
|
|
) -> None:
|
|
"""Set up AdGuard Control Hub binary sensor platform."""
|
|
coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"]
|
|
api = hass.data[DOMAIN][config_entry.entry_id]["api"]
|
|
|
|
entities: List[BinarySensorEntity] = []
|
|
|
|
# Add main binary sensors
|
|
entities.extend([
|
|
AdGuardProtectionBinarySensor(coordinator, api),
|
|
AdGuardServerRunningBinarySensor(coordinator, api),
|
|
AdGuardSafeBrowsingBinarySensor(coordinator, api),
|
|
AdGuardParentalControlBinarySensor(coordinator, api),
|
|
AdGuardSafeSearchBinarySensor(coordinator, api),
|
|
])
|
|
|
|
# Add client-specific binary sensors
|
|
for client_name in coordinator.clients:
|
|
entities.extend([
|
|
AdGuardClientFilteringBinarySensor(coordinator, api, client_name),
|
|
])
|
|
|
|
async_add_entities(entities)
|
|
|
|
|
|
class AdGuardBaseBinarySensor(CoordinatorEntity, BinarySensorEntity):
|
|
"""Base AdGuard binary sensor."""
|
|
|
|
def __init__(self, coordinator, api: AdGuardHomeAPI) -> None:
|
|
"""Initialize the binary sensor."""
|
|
super().__init__(coordinator)
|
|
self.api = api
|
|
|
|
@property
|
|
def device_info(self) -> DeviceInfo:
|
|
"""Return device info."""
|
|
return DeviceInfo(
|
|
identifiers={(DOMAIN, "adguard_home")},
|
|
name="AdGuard Home",
|
|
manufacturer=MANUFACTURER,
|
|
model="AdGuard Home",
|
|
configuration_url=self.api.base_url,
|
|
)
|
|
|
|
|
|
class AdGuardProtectionBinarySensor(AdGuardBaseBinarySensor):
|
|
"""AdGuard protection status binary sensor."""
|
|
|
|
def __init__(self, coordinator, api: AdGuardHomeAPI) -> None:
|
|
"""Initialize the binary sensor."""
|
|
super().__init__(coordinator, api)
|
|
self._attr_name = "AdGuard Protection Status"
|
|
self._attr_unique_id = f"{DOMAIN}_protection_status"
|
|
self._attr_device_class = BinarySensorDeviceClass.SAFETY
|
|
self._attr_icon = "mdi:shield-check"
|
|
|
|
@property
|
|
def is_on(self) -> bool:
|
|
"""Return true if protection is enabled."""
|
|
return self.coordinator.protection_status.get("protection_enabled", False)
|
|
|
|
|
|
class AdGuardServerRunningBinarySensor(AdGuardBaseBinarySensor):
|
|
"""AdGuard server running binary sensor."""
|
|
|
|
def __init__(self, coordinator, api: AdGuardHomeAPI) -> None:
|
|
"""Initialize the binary sensor."""
|
|
super().__init__(coordinator, api)
|
|
self._attr_name = "AdGuard Server Running"
|
|
self._attr_unique_id = f"{DOMAIN}_server_running"
|
|
self._attr_device_class = BinarySensorDeviceClass.RUNNING
|
|
self._attr_icon = "mdi:server"
|
|
self._attr_entity_category = EntityCategory.DIAGNOSTIC
|
|
|
|
@property
|
|
def is_on(self) -> bool:
|
|
"""Return true if server is running."""
|
|
return self.coordinator.protection_status.get("running", False)
|
|
|
|
@property
|
|
def available(self) -> bool:
|
|
"""Return if entity is available."""
|
|
return bool(self.coordinator.protection_status)
|
|
|
|
|
|
class AdGuardSafeBrowsingBinarySensor(AdGuardBaseBinarySensor):
|
|
"""AdGuard safe browsing binary sensor."""
|
|
|
|
def __init__(self, coordinator, api: AdGuardHomeAPI) -> None:
|
|
"""Initialize the binary sensor."""
|
|
super().__init__(coordinator, api)
|
|
self._attr_name = "AdGuard Safe Browsing"
|
|
self._attr_unique_id = f"{DOMAIN}_safe_browsing"
|
|
self._attr_device_class = BinarySensorDeviceClass.SAFETY
|
|
self._attr_icon = "mdi:web-check"
|
|
|
|
@property
|
|
def is_on(self) -> bool:
|
|
"""Return true if safe browsing is enabled."""
|
|
return self.coordinator.protection_status.get("safebrowsing_enabled", False)
|
|
|
|
|
|
class AdGuardParentalControlBinarySensor(AdGuardBaseBinarySensor):
|
|
"""AdGuard parental control binary sensor."""
|
|
|
|
def __init__(self, coordinator, api: AdGuardHomeAPI) -> None:
|
|
"""Initialize the binary sensor."""
|
|
super().__init__(coordinator, api)
|
|
self._attr_name = "AdGuard Parental Control"
|
|
self._attr_unique_id = f"{DOMAIN}_parental_control"
|
|
self._attr_device_class = BinarySensorDeviceClass.SAFETY
|
|
self._attr_icon = "mdi:account-child"
|
|
|
|
@property
|
|
def is_on(self) -> bool:
|
|
"""Return true if parental control is enabled."""
|
|
return self.coordinator.protection_status.get("parental_enabled", False)
|
|
|
|
|
|
class AdGuardSafeSearchBinarySensor(AdGuardBaseBinarySensor):
|
|
"""AdGuard safe search binary sensor."""
|
|
|
|
def __init__(self, coordinator, api: AdGuardHomeAPI) -> None:
|
|
"""Initialize the binary sensor."""
|
|
super().__init__(coordinator, api)
|
|
self._attr_name = "AdGuard Safe Search"
|
|
self._attr_unique_id = f"{DOMAIN}_safe_search"
|
|
self._attr_device_class = BinarySensorDeviceClass.SAFETY
|
|
self._attr_icon = "mdi:magnify-scan"
|
|
|
|
@property
|
|
def is_on(self) -> bool:
|
|
"""Return true if safe search is enabled."""
|
|
return self.coordinator.protection_status.get("safesearch_enabled", False)
|
|
|
|
|
|
class AdGuardClientFilteringBinarySensor(CoordinatorEntity, BinarySensorEntity):
|
|
"""AdGuard client filtering binary sensor."""
|
|
|
|
def __init__(self, coordinator, api: AdGuardHomeAPI, client_name: str) -> None:
|
|
"""Initialize the binary sensor."""
|
|
super().__init__(coordinator)
|
|
self.api = api
|
|
self._client_name = client_name
|
|
self._attr_name = f"AdGuard {client_name} Filtering"
|
|
self._attr_unique_id = f"{DOMAIN}_{client_name.lower().replace(' ', '_')}_filtering"
|
|
self._attr_device_class = BinarySensorDeviceClass.SAFETY
|
|
self._attr_icon = "mdi:filter-check"
|
|
|
|
@property
|
|
def device_info(self) -> DeviceInfo:
|
|
"""Return device info."""
|
|
return DeviceInfo(
|
|
identifiers={(DOMAIN, f"client_{self._client_name}")},
|
|
name=f"AdGuard Client: {self._client_name}",
|
|
manufacturer=MANUFACTURER,
|
|
model="AdGuard Client",
|
|
via_device=(DOMAIN, "adguard_home"),
|
|
)
|
|
|
|
@property
|
|
def is_on(self) -> bool:
|
|
"""Return true if client filtering is enabled."""
|
|
client = self.coordinator.clients.get(self._client_name, {})
|
|
return client.get("filtering_enabled", True)
|
|
|
|
@property
|
|
def available(self) -> bool:
|
|
"""Return if entity is available."""
|
|
return self._client_name in self.coordinator.clients
|