Files
adguard-control-hub/custom_components/adguard_hub/switch.py
2025-10-02 12:46:59 +01:00

146 lines
5.3 KiB
Python

"""AdGuard Control Hub switch platform."""
import logging
from typing import Any, Dict, List, Optional
from homeassistant.components.switch import SwitchEntity
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
from .api import AdGuardHomeAPI, AdGuardConnectionError
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 switch platform."""
coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"]
api = hass.data[DOMAIN][config_entry.entry_id]["api"]
entities: List[SwitchEntity] = []
# Add main protection switch
entities.append(AdGuardProtectionSwitch(coordinator, api))
# Add client switches
for client_name in coordinator.clients:
entities.append(AdGuardClientSwitch(coordinator, api, client_name))
async_add_entities(entities)
class AdGuardProtectionSwitch(CoordinatorEntity, SwitchEntity):
"""AdGuard Home protection switch."""
def __init__(self, coordinator, api: AdGuardHomeAPI) -> None:
"""Initialize the switch."""
super().__init__(coordinator)
self.api = api
self._attr_name = "AdGuard Protection"
self._attr_unique_id = f"{DOMAIN}_protection"
@property
def device_info(self) -> DeviceInfo:
"""Return device info."""
return DeviceInfo(
identifiers={(DOMAIN, "adguard_home")},
name="AdGuard Home",
manufacturer=MANUFACTURER, # FIXED: Now uses imported MANUFACTURER
model="AdGuard Home",
configuration_url=self.api.base_url,
)
@property
def is_on(self) -> bool:
"""Return true if protection is enabled."""
return self.coordinator.protection_status.get("protection_enabled", False)
@property
def icon(self) -> str:
"""Return the icon."""
return "mdi:shield-check" if self.is_on else "mdi:shield-off"
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on protection."""
try:
await self.api.set_protection(True)
await self.coordinator.async_request_refresh()
except AdGuardConnectionError as err:
_LOGGER.error("Failed to turn on protection: %s", err)
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off protection."""
try:
await self.api.set_protection(False)
await self.coordinator.async_request_refresh()
except AdGuardConnectionError as err:
_LOGGER.error("Failed to turn off protection: %s", err)
class AdGuardClientSwitch(CoordinatorEntity, SwitchEntity):
"""AdGuard Home client switch."""
def __init__(self, coordinator, api: AdGuardHomeAPI, client_name: str) -> None:
"""Initialize the client switch."""
super().__init__(coordinator)
self.api = api
self._client_name = client_name
self._attr_name = f"AdGuard {client_name}"
self._attr_unique_id = f"{DOMAIN}_{client_name.lower().replace(' ', '_')}"
@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 not client.get("filtering_enabled", True) is False
@property
def icon(self) -> str:
"""Return the icon."""
return "mdi:devices" if self.is_on else "mdi:devices-off"
@property
def available(self) -> bool:
"""Return if entity is available."""
return self._client_name in self.coordinator.clients
async def async_turn_on(self, **kwargs: Any) -> None:
"""Enable filtering for client."""
try:
client = await self.api.get_client_by_name(self._client_name)
if client:
client["filtering_enabled"] = True
await self.api._request("POST", "/control/clients/update", json=client)
await self.coordinator.async_request_refresh()
except AdGuardConnectionError as err:
_LOGGER.error("Failed to enable filtering for %s: %s", self._client_name, err)
async def async_turn_off(self, **kwargs: Any) -> None:
"""Disable filtering for client."""
try:
client = await self.api.get_client_by_name(self._client_name)
if client:
client["filtering_enabled"] = False
await self.api._request("POST", "/control/clients/update", json=client)
await self.coordinator.async_request_refresh()
except AdGuardConnectionError as err:
_LOGGER.error("Failed to disable filtering for %s: %s", self._client_name, err)