181 lines
5.9 KiB
Python
181 lines
5.9 KiB
Python
|
"""Support for AdGuard Home."""
|
||
|
import logging
|
||
|
from typing import Any, Dict
|
||
|
|
||
|
from adguardhome import AdGuardHome, AdGuardHomeError
|
||
|
import voluptuous as vol
|
||
|
|
||
|
from homeassistant.components.adguard.const import (
|
||
|
CONF_FORCE, DATA_ADGUARD_CLIENT, DATA_ADGUARD_VERION, DOMAIN,
|
||
|
SERVICE_ADD_URL, SERVICE_DISABLE_URL, SERVICE_ENABLE_URL, SERVICE_REFRESH,
|
||
|
SERVICE_REMOVE_URL)
|
||
|
from homeassistant.config_entries import ConfigEntry
|
||
|
from homeassistant.const import (
|
||
|
CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_PORT, CONF_SSL, CONF_URL,
|
||
|
CONF_USERNAME, CONF_VERIFY_SSL)
|
||
|
from homeassistant.helpers import config_validation as cv
|
||
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||
|
from homeassistant.helpers.entity import Entity
|
||
|
from homeassistant.helpers.typing import ConfigType, HomeAssistantType
|
||
|
|
||
|
_LOGGER = logging.getLogger(__name__)
|
||
|
|
||
|
SERVICE_URL_SCHEMA = vol.Schema({vol.Required(CONF_URL): cv.url})
|
||
|
SERVICE_ADD_URL_SCHEMA = vol.Schema(
|
||
|
{vol.Required(CONF_NAME): cv.string, vol.Required(CONF_URL): cv.url}
|
||
|
)
|
||
|
SERVICE_REFRESH_SCHEMA = vol.Schema(
|
||
|
{vol.Optional(CONF_FORCE, default=False): cv.boolean}
|
||
|
)
|
||
|
|
||
|
|
||
|
async def async_setup(hass: HomeAssistantType, config: ConfigType) -> bool:
|
||
|
"""Set up the AdGuard Home components."""
|
||
|
return True
|
||
|
|
||
|
|
||
|
async def async_setup_entry(
|
||
|
hass: HomeAssistantType, entry: ConfigEntry
|
||
|
) -> bool:
|
||
|
"""Set up AdGuard Home from a config entry."""
|
||
|
session = async_get_clientsession(hass, entry.data[CONF_VERIFY_SSL])
|
||
|
adguard = AdGuardHome(
|
||
|
entry.data[CONF_HOST],
|
||
|
port=entry.data[CONF_PORT],
|
||
|
username=entry.data[CONF_USERNAME],
|
||
|
password=entry.data[CONF_PASSWORD],
|
||
|
tls=entry.data[CONF_SSL],
|
||
|
verify_ssl=entry.data[CONF_VERIFY_SSL],
|
||
|
loop=hass.loop,
|
||
|
session=session,
|
||
|
)
|
||
|
|
||
|
hass.data.setdefault(DOMAIN, {})[DATA_ADGUARD_CLIENT] = adguard
|
||
|
|
||
|
for component in 'sensor', 'switch':
|
||
|
hass.async_create_task(
|
||
|
hass.config_entries.async_forward_entry_setup(entry, component)
|
||
|
)
|
||
|
|
||
|
async def add_url(call) -> None:
|
||
|
"""Service call to add a new filter subscription to AdGuard Home."""
|
||
|
await adguard.filtering.add_url(
|
||
|
call.data.get(CONF_NAME), call.data.get(CONF_URL)
|
||
|
)
|
||
|
|
||
|
async def remove_url(call) -> None:
|
||
|
"""Service call to remove a filter subscription from AdGuard Home."""
|
||
|
await adguard.filtering.remove_url(call.data.get(CONF_URL))
|
||
|
|
||
|
async def enable_url(call) -> None:
|
||
|
"""Service call to enable a filter subscription in AdGuard Home."""
|
||
|
await adguard.filtering.enable_url(call.data.get(CONF_URL))
|
||
|
|
||
|
async def disable_url(call) -> None:
|
||
|
"""Service call to disable a filter subscription in AdGuard Home."""
|
||
|
await adguard.filtering.disable_url(call.data.get(CONF_URL))
|
||
|
|
||
|
async def refresh(call) -> None:
|
||
|
"""Service call to refresh the filter subscriptions in AdGuard Home."""
|
||
|
await adguard.filtering.refresh(call.data.get(CONF_FORCE))
|
||
|
|
||
|
hass.services.async_register(
|
||
|
DOMAIN, SERVICE_ADD_URL, add_url, schema=SERVICE_ADD_URL_SCHEMA
|
||
|
)
|
||
|
hass.services.async_register(
|
||
|
DOMAIN, SERVICE_REMOVE_URL, remove_url, schema=SERVICE_URL_SCHEMA
|
||
|
)
|
||
|
hass.services.async_register(
|
||
|
DOMAIN, SERVICE_ENABLE_URL, enable_url, schema=SERVICE_URL_SCHEMA
|
||
|
)
|
||
|
hass.services.async_register(
|
||
|
DOMAIN, SERVICE_DISABLE_URL, disable_url, schema=SERVICE_URL_SCHEMA
|
||
|
)
|
||
|
hass.services.async_register(
|
||
|
DOMAIN, SERVICE_REFRESH, refresh, schema=SERVICE_REFRESH_SCHEMA
|
||
|
)
|
||
|
|
||
|
return True
|
||
|
|
||
|
|
||
|
async def async_unload_entry(
|
||
|
hass: HomeAssistantType, entry: ConfigType
|
||
|
) -> bool:
|
||
|
"""Unload AdGuard Home config entry."""
|
||
|
hass.services.async_remove(DOMAIN, SERVICE_ADD_URL)
|
||
|
hass.services.async_remove(DOMAIN, SERVICE_REMOVE_URL)
|
||
|
hass.services.async_remove(DOMAIN, SERVICE_ENABLE_URL)
|
||
|
hass.services.async_remove(DOMAIN, SERVICE_DISABLE_URL)
|
||
|
hass.services.async_remove(DOMAIN, SERVICE_REFRESH)
|
||
|
|
||
|
for component in 'sensor', 'switch':
|
||
|
await hass.config_entries.async_forward_entry_unload(entry, component)
|
||
|
|
||
|
del hass.data[DOMAIN]
|
||
|
|
||
|
return True
|
||
|
|
||
|
|
||
|
class AdGuardHomeEntity(Entity):
|
||
|
"""Defines a base AdGuard Home entity."""
|
||
|
|
||
|
def __init__(self, adguard, name: str, icon: str) -> None:
|
||
|
"""Initialize the AdGuard Home entity."""
|
||
|
self._name = name
|
||
|
self._icon = icon
|
||
|
self._available = True
|
||
|
self.adguard = adguard
|
||
|
|
||
|
@property
|
||
|
def name(self) -> str:
|
||
|
"""Return the name of the entity."""
|
||
|
return self._name
|
||
|
|
||
|
@property
|
||
|
def icon(self) -> str:
|
||
|
"""Return the mdi icon of the entity."""
|
||
|
return self._icon
|
||
|
|
||
|
@property
|
||
|
def available(self) -> bool:
|
||
|
"""Return True if entity is available."""
|
||
|
return self._available
|
||
|
|
||
|
async def async_update(self) -> None:
|
||
|
"""Update AdGuard Home entity."""
|
||
|
try:
|
||
|
await self._adguard_update()
|
||
|
self._available = True
|
||
|
except AdGuardHomeError:
|
||
|
if self._available:
|
||
|
_LOGGER.debug(
|
||
|
"An error occurred while updating AdGuard Home sensor.",
|
||
|
exc_info=True,
|
||
|
)
|
||
|
self._available = False
|
||
|
|
||
|
async def _adguard_update(self) -> None:
|
||
|
"""Update AdGuard Home entity."""
|
||
|
raise NotImplementedError()
|
||
|
|
||
|
|
||
|
class AdGuardHomeDeviceEntity(AdGuardHomeEntity):
|
||
|
"""Defines a AdGuard Home device entity."""
|
||
|
|
||
|
@property
|
||
|
def device_info(self) -> Dict[str, Any]:
|
||
|
"""Return device information about this AdGuard Home instance."""
|
||
|
return {
|
||
|
'identifiers': {
|
||
|
(
|
||
|
DOMAIN,
|
||
|
self.adguard.host,
|
||
|
self.adguard.port,
|
||
|
self.adguard.base_path,
|
||
|
)
|
||
|
},
|
||
|
'name': 'AdGuard Home',
|
||
|
'manufacturer': 'AdGuard Team',
|
||
|
'sw_version': self.hass.data[DOMAIN].get(DATA_ADGUARD_VERION),
|
||
|
}
|