"""Validate device conditions.""" from __future__ import annotations from typing import TYPE_CHECKING, Any, Protocol import voluptuous as vol from homeassistant.const import CONF_DOMAIN, CONF_OPTIONS from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv from homeassistant.helpers.condition import ( Condition, ConditionCheckerType, ConditionConfig, trace_condition_function, ) from homeassistant.helpers.typing import ConfigType from . import DeviceAutomationType, async_get_device_automation_platform from .helpers import async_validate_device_automation_config if TYPE_CHECKING: from homeassistant.helpers import condition class DeviceAutomationConditionProtocol(Protocol): """Define the format of device_condition modules. Each module must define either CONDITION_SCHEMA or async_validate_condition_config. """ CONDITION_SCHEMA: vol.Schema async def async_validate_condition_config( self, hass: HomeAssistant, config: ConfigType ) -> ConfigType: """Validate config.""" def async_condition_from_config( self, hass: HomeAssistant, config: ConfigType ) -> ConditionCheckerType: """Evaluate state based on configuration.""" async def async_get_condition_capabilities( self, hass: HomeAssistant, config: ConfigType ) -> dict[str, vol.Schema]: """List condition capabilities.""" async def async_get_conditions( self, hass: HomeAssistant, device_id: str ) -> list[dict[str, Any]]: """List conditions.""" class DeviceCondition(Condition): """Device condition.""" _hass: HomeAssistant _config: ConfigType @classmethod async def async_validate_complete_config( cls, hass: HomeAssistant, complete_config: ConfigType ) -> ConfigType: """Validate complete config.""" complete_config = await async_validate_device_automation_config( hass, complete_config, cv.DEVICE_CONDITION_SCHEMA, DeviceAutomationType.CONDITION, ) # Since we don't want to migrate device conditions to a new format # we just pass the entire config as options. complete_config[CONF_OPTIONS] = complete_config.copy() return complete_config @classmethod async def async_validate_config( cls, hass: HomeAssistant, config: ConfigType ) -> ConfigType: """Validate config. This is here just to satisfy the abstract class interface. It is never called. """ raise NotImplementedError def __init__(self, hass: HomeAssistant, config: ConditionConfig) -> None: """Initialize condition.""" self._hass = hass assert config.options is not None self._config = config.options async def async_get_checker(self) -> condition.ConditionCheckerType: """Test a device condition.""" platform = await async_get_device_automation_platform( self._hass, self._config[CONF_DOMAIN], DeviceAutomationType.CONDITION ) return trace_condition_function( platform.async_condition_from_config(self._hass, self._config) ) CONDITIONS: dict[str, type[Condition]] = { "_device": DeviceCondition, } async def async_get_conditions(hass: HomeAssistant) -> dict[str, type[Condition]]: """Return the sun conditions.""" return CONDITIONS