From caf5ee2fabdce28502c427ffb81bd2933e28d98a Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Sun, 28 Nov 2021 14:54:07 +0100 Subject: [PATCH] Remove optional validation when creating conditions (#60481) --- .../alarm_control_panel/device_condition.py | 6 +- .../components/automation/__init__.py | 2 +- .../binary_sensor/device_condition.py | 7 +- .../components/climate/device_condition.py | 7 +- .../components/cover/device_condition.py | 7 +- .../device_automation/toggle_entity.py | 1 + .../device_tracker/device_condition.py | 7 +- .../components/fan/device_condition.py | 6 +- .../components/humidifier/device_condition.py | 7 +- .../components/light/device_condition.py | 6 +- .../components/lock/device_condition.py | 6 +- .../media_player/device_condition.py | 6 +- .../components/remote/device_condition.py | 6 +- .../components/select/device_condition.py | 6 +- .../components/sensor/device_condition.py | 7 +- .../components/switch/device_condition.py | 6 +- .../components/vacuum/device_condition.py | 6 +- .../components/websocket_api/commands.py | 6 +- .../components/zwave_js/device_condition.py | 7 +- homeassistant/helpers/condition.py | 77 +- homeassistant/helpers/script.py | 2 +- .../integration/device_condition.py | 6 +- .../zwave_js/test_device_condition.py | 2 +- tests/helpers/test_condition.py | 867 +++++++++--------- 24 files changed, 486 insertions(+), 580 deletions(-) diff --git a/homeassistant/components/alarm_control_panel/device_condition.py b/homeassistant/components/alarm_control_panel/device_condition.py index 9367ef8f811..6eb0144a4b4 100644 --- a/homeassistant/components/alarm_control_panel/device_condition.py +++ b/homeassistant/components/alarm_control_panel/device_condition.py @@ -104,12 +104,8 @@ async def async_get_conditions( return conditions -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> condition.ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> condition.ConditionCheckerType: """Create a function to test a device condition.""" - if config_validation: - config = CONDITION_SCHEMA(config) if config[CONF_TYPE] == CONDITION_TRIGGERED: state = STATE_ALARM_TRIGGERED elif config[CONF_TYPE] == CONDITION_DISARMED: diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index 699fdc8745b..64c6b335fbd 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -714,7 +714,7 @@ async def _async_process_if(hass, name, config, p_config): checks = [] for if_config in if_configs: try: - checks.append(await condition.async_from_config(hass, if_config, False)) + checks.append(await condition.async_from_config(hass, if_config)) except HomeAssistantError as ex: LOGGER.warning("Invalid condition: %s", ex) return None diff --git a/homeassistant/components/binary_sensor/device_condition.py b/homeassistant/components/binary_sensor/device_condition.py index 8351234182d..e6202ef66a4 100644 --- a/homeassistant/components/binary_sensor/device_condition.py +++ b/homeassistant/components/binary_sensor/device_condition.py @@ -264,12 +264,8 @@ async def async_get_conditions( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> condition.ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> condition.ConditionCheckerType: """Evaluate state based on configuration.""" - if config_validation: - config = CONDITION_SCHEMA(config) condition_type = config[CONF_TYPE] if condition_type in IS_ON: stat = "on" @@ -282,6 +278,7 @@ def async_condition_from_config( } if CONF_FOR in config: state_config[CONF_FOR] = config[CONF_FOR] + state_config = cv.STATE_CONDITION_SCHEMA(state_config) return condition.state_from_config(state_config) diff --git a/homeassistant/components/climate/device_condition.py b/homeassistant/components/climate/device_condition.py index 97bb4515f14..03e456965fe 100644 --- a/homeassistant/components/climate/device_condition.py +++ b/homeassistant/components/climate/device_condition.py @@ -70,13 +70,8 @@ async def async_get_conditions( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> condition.ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> condition.ConditionCheckerType: """Create a function to test a device condition.""" - if config_validation: - config = CONDITION_SCHEMA(config) - if config[CONF_TYPE] == "is_hvac_mode": attribute = const.ATTR_HVAC_MODE else: diff --git a/homeassistant/components/cover/device_condition.py b/homeassistant/components/cover/device_condition.py index 28a057cb17f..d719c4835e2 100644 --- a/homeassistant/components/cover/device_condition.py +++ b/homeassistant/components/cover/device_condition.py @@ -119,13 +119,8 @@ async def async_get_condition_capabilities( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> condition.ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> condition.ConditionCheckerType: """Create a function to test a device condition.""" - if config_validation: - config = CONDITION_SCHEMA(config) - if config[CONF_TYPE] in STATE_CONDITION_TYPES: if config[CONF_TYPE] == "is_open": state = STATE_OPEN diff --git a/homeassistant/components/device_automation/toggle_entity.py b/homeassistant/components/device_automation/toggle_entity.py index 99473777658..a1ee84da2fb 100644 --- a/homeassistant/components/device_automation/toggle_entity.py +++ b/homeassistant/components/device_automation/toggle_entity.py @@ -141,6 +141,7 @@ def async_condition_from_config(config: ConfigType) -> condition.ConditionChecke if CONF_FOR in config: state_config[CONF_FOR] = config[CONF_FOR] + state_config = cv.STATE_CONDITION_SCHEMA(state_config) return condition.state_from_config(state_config) diff --git a/homeassistant/components/device_tracker/device_condition.py b/homeassistant/components/device_tracker/device_condition.py index afa899444f6..78cedd6e900 100644 --- a/homeassistant/components/device_tracker/device_condition.py +++ b/homeassistant/components/device_tracker/device_condition.py @@ -55,13 +55,8 @@ async def async_get_conditions( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> condition.ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> condition.ConditionCheckerType: """Create a function to test a device condition.""" - if config_validation: - config = CONDITION_SCHEMA(config) - reverse = config[CONF_TYPE] == "is_not_home" @callback diff --git a/homeassistant/components/fan/device_condition.py b/homeassistant/components/fan/device_condition.py index 56d9208b2d2..4e3aed026dc 100644 --- a/homeassistant/components/fan/device_condition.py +++ b/homeassistant/components/fan/device_condition.py @@ -55,12 +55,8 @@ async def async_get_conditions( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> condition.ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> condition.ConditionCheckerType: """Create a function to test a device condition.""" - if config_validation: - config = CONDITION_SCHEMA(config) if config[CONF_TYPE] == "is_on": state = STATE_ON else: diff --git a/homeassistant/components/humidifier/device_condition.py b/homeassistant/components/humidifier/device_condition.py index f2bf032b195..28d74d1efff 100644 --- a/homeassistant/components/humidifier/device_condition.py +++ b/homeassistant/components/humidifier/device_condition.py @@ -65,13 +65,8 @@ async def async_get_conditions( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> condition.ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> condition.ConditionCheckerType: """Create a function to test a device condition.""" - if config_validation: - config = CONDITION_SCHEMA(config) - if config[CONF_TYPE] == "is_mode": attribute = ATTR_MODE else: diff --git a/homeassistant/components/light/device_condition.py b/homeassistant/components/light/device_condition.py index e5ff8a83ba3..908af72ecfd 100644 --- a/homeassistant/components/light/device_condition.py +++ b/homeassistant/components/light/device_condition.py @@ -19,12 +19,8 @@ CONDITION_SCHEMA = toggle_entity.CONDITION_SCHEMA.extend( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> ConditionCheckerType: """Evaluate state based on configuration.""" - if config_validation: - config = CONDITION_SCHEMA(config) return toggle_entity.async_condition_from_config(config) diff --git a/homeassistant/components/lock/device_condition.py b/homeassistant/components/lock/device_condition.py index 74b55a1a89c..b3fe4ffcfe1 100644 --- a/homeassistant/components/lock/device_condition.py +++ b/homeassistant/components/lock/device_condition.py @@ -67,12 +67,8 @@ async def async_get_conditions( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> condition.ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> condition.ConditionCheckerType: """Create a function to test a device condition.""" - if config_validation: - config = CONDITION_SCHEMA(config) if config[CONF_TYPE] == "is_jammed": state = STATE_JAMMED elif config[CONF_TYPE] == "is_locking": diff --git a/homeassistant/components/media_player/device_condition.py b/homeassistant/components/media_player/device_condition.py index e392c274f33..41034bbe870 100644 --- a/homeassistant/components/media_player/device_condition.py +++ b/homeassistant/components/media_player/device_condition.py @@ -59,12 +59,8 @@ async def async_get_conditions( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> condition.ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> condition.ConditionCheckerType: """Create a function to test a device condition.""" - if config_validation: - config = CONDITION_SCHEMA(config) if config[CONF_TYPE] == "is_playing": state = STATE_PLAYING elif config[CONF_TYPE] == "is_idle": diff --git a/homeassistant/components/remote/device_condition.py b/homeassistant/components/remote/device_condition.py index 02e6ea6bd23..ffbfc1c1061 100644 --- a/homeassistant/components/remote/device_condition.py +++ b/homeassistant/components/remote/device_condition.py @@ -19,12 +19,8 @@ CONDITION_SCHEMA = toggle_entity.CONDITION_SCHEMA.extend( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> ConditionCheckerType: """Evaluate state based on configuration.""" - if config_validation: - config = CONDITION_SCHEMA(config) return toggle_entity.async_condition_from_config(config) diff --git a/homeassistant/components/select/device_condition.py b/homeassistant/components/select/device_condition.py index 4f650ddadda..eadfebbc711 100644 --- a/homeassistant/components/select/device_condition.py +++ b/homeassistant/components/select/device_condition.py @@ -52,12 +52,8 @@ async def async_get_conditions( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> condition.ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> condition.ConditionCheckerType: """Create a function to test a device condition.""" - if config_validation: - config = CONDITION_SCHEMA(config) @callback def test_is_state(hass: HomeAssistant, variables: TemplateVarsType) -> bool: diff --git a/homeassistant/components/sensor/device_condition.py b/homeassistant/components/sensor/device_condition.py index 224ca26d28d..6444f58a1de 100644 --- a/homeassistant/components/sensor/device_condition.py +++ b/homeassistant/components/sensor/device_condition.py @@ -186,12 +186,8 @@ async def async_get_conditions( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> condition.ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> condition.ConditionCheckerType: """Evaluate state based on configuration.""" - if config_validation: - config = CONDITION_SCHEMA(config) numeric_state_config = { condition.CONF_CONDITION: "numeric_state", condition.CONF_ENTITY_ID: config[CONF_ENTITY_ID], @@ -201,6 +197,7 @@ def async_condition_from_config( if CONF_BELOW in config: numeric_state_config[condition.CONF_BELOW] = config[CONF_BELOW] + numeric_state_config = cv.NUMERIC_STATE_CONDITION_SCHEMA(numeric_state_config) return condition.async_numeric_state_from_config(numeric_state_config) diff --git a/homeassistant/components/switch/device_condition.py b/homeassistant/components/switch/device_condition.py index b59e533375c..94469275ab3 100644 --- a/homeassistant/components/switch/device_condition.py +++ b/homeassistant/components/switch/device_condition.py @@ -19,12 +19,8 @@ CONDITION_SCHEMA = toggle_entity.CONDITION_SCHEMA.extend( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> ConditionCheckerType: """Evaluate state based on configuration.""" - if config_validation: - config = CONDITION_SCHEMA(config) return toggle_entity.async_condition_from_config(config) diff --git a/homeassistant/components/vacuum/device_condition.py b/homeassistant/components/vacuum/device_condition.py index a66df1323f7..1c7b0c93332 100644 --- a/homeassistant/components/vacuum/device_condition.py +++ b/homeassistant/components/vacuum/device_condition.py @@ -53,12 +53,8 @@ async def async_get_conditions( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> condition.ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> condition.ConditionCheckerType: """Create a function to test a device condition.""" - if config_validation: - config = CONDITION_SCHEMA(config) if config[CONF_TYPE] == "is_docked": test_states = [STATE_DOCKED] else: diff --git a/homeassistant/components/websocket_api/commands.py b/homeassistant/components/websocket_api/commands.py index 4216eae5a09..a4abbd30dff 100644 --- a/homeassistant/components/websocket_api/commands.py +++ b/homeassistant/components/websocket_api/commands.py @@ -495,7 +495,11 @@ async def handle_test_condition( # pylint: disable=import-outside-toplevel from homeassistant.helpers import condition - check_condition = await condition.async_from_config(hass, msg["condition"]) + # Do static + dynamic validation of the condition + config = cv.CONDITION_SCHEMA(msg["condition"]) + config = await condition.async_validate_condition_config(hass, config) + # Test the condition + check_condition = await condition.async_from_config(hass, config) connection.send_result( msg["id"], {"result": check_condition(hass, msg.get("variables"))} ) diff --git a/homeassistant/components/zwave_js/device_condition.py b/homeassistant/components/zwave_js/device_condition.py index 6694d88a135..4258a0b0892 100644 --- a/homeassistant/components/zwave_js/device_condition.py +++ b/homeassistant/components/zwave_js/device_condition.py @@ -147,13 +147,8 @@ async def async_get_conditions( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> condition.ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> condition.ConditionCheckerType: """Create a function to test a device condition.""" - if config_validation: - config = CONDITION_SCHEMA(config) - condition_type = config[CONF_TYPE] device_id = config[CONF_DEVICE_ID] diff --git a/homeassistant/helpers/condition.py b/homeassistant/helpers/condition.py index 5608e61a07f..a4c62709778 100644 --- a/homeassistant/helpers/condition.py +++ b/homeassistant/helpers/condition.py @@ -152,7 +152,6 @@ def trace_condition_function(condition: ConditionCheckerType) -> ConditionChecke async def async_from_config( hass: HomeAssistant, config: ConfigType | Template, - config_validation: bool = True, ) -> ConditionCheckerType: """Turn a condition configuration into a method. @@ -181,21 +180,15 @@ async def async_from_config( check_factory = check_factory.func if asyncio.iscoroutinefunction(check_factory): - return cast( - ConditionCheckerType, await factory(hass, config, config_validation) - ) - return cast(ConditionCheckerType, factory(config, config_validation)) + return cast(ConditionCheckerType, await factory(hass, config)) + return cast(ConditionCheckerType, factory(config)) async def async_and_from_config( - hass: HomeAssistant, config: ConfigType, config_validation: bool = True + hass: HomeAssistant, config: ConfigType ) -> ConditionCheckerType: """Create multi condition matcher using 'AND'.""" - if config_validation: - config = cv.AND_CONDITION_SCHEMA(config) - checks = [ - await async_from_config(hass, entry, False) for entry in config["conditions"] - ] + checks = [await async_from_config(hass, entry) for entry in config["conditions"]] @trace_condition_function def if_and_condition( @@ -223,14 +216,10 @@ async def async_and_from_config( async def async_or_from_config( - hass: HomeAssistant, config: ConfigType, config_validation: bool = True + hass: HomeAssistant, config: ConfigType ) -> ConditionCheckerType: """Create multi condition matcher using 'OR'.""" - if config_validation: - config = cv.OR_CONDITION_SCHEMA(config) - checks = [ - await async_from_config(hass, entry, False) for entry in config["conditions"] - ] + checks = [await async_from_config(hass, entry) for entry in config["conditions"]] @trace_condition_function def if_or_condition( @@ -258,14 +247,10 @@ async def async_or_from_config( async def async_not_from_config( - hass: HomeAssistant, config: ConfigType, config_validation: bool = True + hass: HomeAssistant, config: ConfigType ) -> ConditionCheckerType: """Create multi condition matcher using 'NOT'.""" - if config_validation: - config = cv.NOT_CONDITION_SCHEMA(config) - checks = [ - await async_from_config(hass, entry, False) for entry in config["conditions"] - ] + checks = [await async_from_config(hass, entry) for entry in config["conditions"]] @trace_condition_function def if_not_condition( @@ -433,12 +418,8 @@ def async_numeric_state( # noqa: C901 return True -def async_numeric_state_from_config( - config: ConfigType, config_validation: bool = True -) -> ConditionCheckerType: +def async_numeric_state_from_config(config: ConfigType) -> ConditionCheckerType: """Wrap action method with state based condition.""" - if config_validation: - config = cv.NUMERIC_STATE_CONDITION_SCHEMA(config) entity_ids = config.get(CONF_ENTITY_ID, []) attribute = config.get(CONF_ATTRIBUTE) below = config.get(CONF_BELOW) @@ -548,12 +529,8 @@ def state( return duration_ok -def state_from_config( - config: ConfigType, config_validation: bool = True -) -> ConditionCheckerType: +def state_from_config(config: ConfigType) -> ConditionCheckerType: """Wrap action method with state based condition.""" - if config_validation: - config = cv.STATE_CONDITION_SCHEMA(config) entity_ids = config.get(CONF_ENTITY_ID, []) req_states: str | list[str] = config.get(CONF_STATE, []) for_period = config.get("for") @@ -656,12 +633,8 @@ def sun( return True -def sun_from_config( - config: ConfigType, config_validation: bool = True -) -> ConditionCheckerType: +def sun_from_config(config: ConfigType) -> ConditionCheckerType: """Wrap action method with sun based condition.""" - if config_validation: - config = cv.SUN_CONDITION_SCHEMA(config) before = config.get("before") after = config.get("after") before_offset = config.get("before_offset") @@ -703,12 +676,8 @@ def async_template( return result -def async_template_from_config( - config: ConfigType, config_validation: bool = True -) -> ConditionCheckerType: +def async_template_from_config(config: ConfigType) -> ConditionCheckerType: """Wrap action method with state based condition.""" - if config_validation: - config = cv.TEMPLATE_CONDITION_SCHEMA(config) value_template = cast(Template, config.get(CONF_VALUE_TEMPLATE)) @trace_condition_function @@ -808,12 +777,8 @@ def time( return True -def time_from_config( - config: ConfigType, config_validation: bool = True -) -> ConditionCheckerType: +def time_from_config(config: ConfigType) -> ConditionCheckerType: """Wrap action method with time based condition.""" - if config_validation: - config = cv.TIME_CONDITION_SCHEMA(config) before = config.get(CONF_BEFORE) after = config.get(CONF_AFTER) weekday = config.get(CONF_WEEKDAY) @@ -873,12 +838,8 @@ def zone( ) -def zone_from_config( - config: ConfigType, config_validation: bool = True -) -> ConditionCheckerType: +def zone_from_config(config: ConfigType) -> ConditionCheckerType: """Wrap action method with zone based condition.""" - if config_validation: - config = cv.ZONE_CONDITION_SCHEMA(config) entity_ids = config.get(CONF_ENTITY_ID, []) zone_entity_ids = config.get(CONF_ZONE, []) @@ -915,28 +876,24 @@ def zone_from_config( async def async_device_from_config( - hass: HomeAssistant, config: ConfigType, config_validation: bool = True + hass: HomeAssistant, config: ConfigType ) -> ConditionCheckerType: """Test a device condition.""" - if config_validation: - config = cv.DEVICE_CONDITION_SCHEMA(config) platform = await async_get_device_automation_platform( hass, config[CONF_DOMAIN], "condition" ) return trace_condition_function( cast( ConditionCheckerType, - platform.async_condition_from_config(config, config_validation), # type: ignore + platform.async_condition_from_config(config), # type: ignore ) ) async def async_trigger_from_config( - hass: HomeAssistant, config: ConfigType, config_validation: bool = True + hass: HomeAssistant, config: ConfigType ) -> ConditionCheckerType: """Test a trigger condition.""" - if config_validation: - config = cv.TRIGGER_CONDITION_SCHEMA(config) trigger_id = config[CONF_ID] @trace_condition_function diff --git a/homeassistant/helpers/script.py b/homeassistant/helpers/script.py index 293a8a9455f..933b44d9ec9 100644 --- a/homeassistant/helpers/script.py +++ b/homeassistant/helpers/script.py @@ -1275,7 +1275,7 @@ class Script: else: config_cache_key = frozenset((k, str(v)) for k, v in config.items()) if not (cond := self._config_cache.get(config_cache_key)): - cond = await condition.async_from_config(self._hass, config, False) + cond = await condition.async_from_config(self._hass, config) self._config_cache[config_cache_key] = cond return cond diff --git a/script/scaffold/templates/device_condition/integration/device_condition.py b/script/scaffold/templates/device_condition/integration/device_condition.py index 4180f81b3ff..ca0eda163b8 100644 --- a/script/scaffold/templates/device_condition/integration/device_condition.py +++ b/script/scaffold/templates/device_condition/integration/device_condition.py @@ -58,12 +58,8 @@ async def async_get_conditions( @callback -def async_condition_from_config( - config: ConfigType, config_validation: bool -) -> condition.ConditionCheckerType: +def async_condition_from_config(config: ConfigType) -> condition.ConditionCheckerType: """Create a function to test a device condition.""" - if config_validation: - config = CONDITION_SCHEMA(config) if config[CONF_TYPE] == "is_on": state = STATE_ON else: diff --git a/tests/components/zwave_js/test_device_condition.py b/tests/components/zwave_js/test_device_condition.py index dfdbb16c8e8..1f6a9d9ca90 100644 --- a/tests/components/zwave_js/test_device_condition.py +++ b/tests/components/zwave_js/test_device_condition.py @@ -552,7 +552,7 @@ async def test_failure_scenarios(hass, client, hank_binary_switch, integration): with pytest.raises(HomeAssistantError): await device_condition.async_condition_from_config( - {"type": "failed.test", "device_id": device.id}, False + {"type": "failed.test", "device_id": device.id} ) with patch( diff --git a/tests/helpers/test_condition.py b/tests/helpers/test_condition.py index cd355129770..92bad8777bd 100644 --- a/tests/helpers/test_condition.py +++ b/tests/helpers/test_condition.py @@ -16,7 +16,7 @@ from homeassistant.const import ( SUN_EVENT_SUNSET, ) from homeassistant.exceptions import ConditionError, HomeAssistantError -from homeassistant.helpers import condition, trace +from homeassistant.helpers import condition, config_validation as cv, trace from homeassistant.helpers.template import Template from homeassistant.setup import async_setup_component import homeassistant.util.dt as dt_util @@ -106,25 +106,25 @@ async def test_invalid_condition(hass): async def test_and_condition(hass): """Test the 'and' condition.""" - test = await condition.async_from_config( - hass, - { - "alias": "And Condition", - "condition": "and", - "conditions": [ - { - "condition": "state", - "entity_id": "sensor.temperature", - "state": "100", - }, - { - "condition": "numeric_state", - "entity_id": "sensor.temperature", - "below": 110, - }, - ], - }, - ) + config = { + "alias": "And Condition", + "condition": "and", + "conditions": [ + { + "condition": "state", + "entity_id": "sensor.temperature", + "state": "100", + }, + { + "condition": "numeric_state", + "entity_id": "sensor.temperature", + "below": 110, + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) with pytest.raises(ConditionError): test(hass) @@ -179,25 +179,25 @@ async def test_and_condition(hass): async def test_and_condition_raises(hass): """Test the 'and' condition.""" - test = await condition.async_from_config( - hass, - { - "alias": "And Condition", - "condition": "and", - "conditions": [ - { - "condition": "state", - "entity_id": "sensor.temperature", - "state": "100", - }, - { - "condition": "numeric_state", - "entity_id": "sensor.temperature2", - "above": 110, - }, - ], - }, - ) + config = { + "alias": "And Condition", + "condition": "and", + "conditions": [ + { + "condition": "state", + "entity_id": "sensor.temperature", + "state": "100", + }, + { + "condition": "numeric_state", + "entity_id": "sensor.temperature2", + "above": 110, + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) # All subconditions raise, the AND-condition should raise with pytest.raises(ConditionError): @@ -252,24 +252,24 @@ async def test_and_condition_raises(hass): async def test_and_condition_with_template(hass): """Test the 'and' condition.""" - test = await condition.async_from_config( - hass, - { - "condition": "and", - "conditions": [ - { - "alias": "Template Condition", - "condition": "template", - "value_template": '{{ states.sensor.temperature.state == "100" }}', - }, - { - "condition": "numeric_state", - "entity_id": "sensor.temperature", - "below": 110, - }, - ], - }, - ) + config = { + "condition": "and", + "conditions": [ + { + "alias": "Template Condition", + "condition": "template", + "value_template": '{{ states.sensor.temperature.state == "100" }}', + }, + { + "condition": "numeric_state", + "entity_id": "sensor.temperature", + "below": 110, + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.temperature", 120) assert not test(hass) @@ -291,25 +291,25 @@ async def test_and_condition_with_template(hass): async def test_or_condition(hass): """Test the 'or' condition.""" - test = await condition.async_from_config( - hass, - { - "alias": "Or Condition", - "condition": "or", - "conditions": [ - { - "condition": "state", - "entity_id": "sensor.temperature", - "state": "100", - }, - { - "condition": "numeric_state", - "entity_id": "sensor.temperature", - "below": 110, - }, - ], - }, - ) + config = { + "alias": "Or Condition", + "condition": "or", + "conditions": [ + { + "condition": "state", + "entity_id": "sensor.temperature", + "state": "100", + }, + { + "condition": "numeric_state", + "entity_id": "sensor.temperature", + "below": 110, + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) with pytest.raises(ConditionError): test(hass) @@ -374,25 +374,25 @@ async def test_or_condition(hass): async def test_or_condition_raises(hass): """Test the 'or' condition.""" - test = await condition.async_from_config( - hass, - { - "alias": "Or Condition", - "condition": "or", - "conditions": [ - { - "condition": "state", - "entity_id": "sensor.temperature", - "state": "100", - }, - { - "condition": "numeric_state", - "entity_id": "sensor.temperature2", - "above": 110, - }, - ], - }, - ) + config = { + "alias": "Or Condition", + "condition": "or", + "conditions": [ + { + "condition": "state", + "entity_id": "sensor.temperature", + "state": "100", + }, + { + "condition": "numeric_state", + "entity_id": "sensor.temperature2", + "above": 110, + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) # All subconditions raise, the OR-condition should raise with pytest.raises(ConditionError): @@ -447,20 +447,20 @@ async def test_or_condition_raises(hass): async def test_or_condition_with_template(hass): """Test the 'or' condition.""" - test = await condition.async_from_config( - hass, - { - "condition": "or", - "conditions": [ - {'{{ states.sensor.temperature.state == "100" }}'}, - { - "condition": "numeric_state", - "entity_id": "sensor.temperature", - "below": 110, - }, - ], - }, - ) + config = { + "condition": "or", + "conditions": [ + {'{{ states.sensor.temperature.state == "100" }}'}, + { + "condition": "numeric_state", + "entity_id": "sensor.temperature", + "below": 110, + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.temperature", 120) assert not test(hass) @@ -474,25 +474,25 @@ async def test_or_condition_with_template(hass): async def test_not_condition(hass): """Test the 'not' condition.""" - test = await condition.async_from_config( - hass, - { - "alias": "Not Condition", - "condition": "not", - "conditions": [ - { - "condition": "state", - "entity_id": "sensor.temperature", - "state": "100", - }, - { - "condition": "numeric_state", - "entity_id": "sensor.temperature", - "below": 50, - }, - ], - }, - ) + config = { + "alias": "Not Condition", + "condition": "not", + "conditions": [ + { + "condition": "state", + "entity_id": "sensor.temperature", + "state": "100", + }, + { + "condition": "numeric_state", + "entity_id": "sensor.temperature", + "below": 50, + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) with pytest.raises(ConditionError): test(hass) @@ -573,25 +573,25 @@ async def test_not_condition(hass): async def test_not_condition_raises(hass): """Test the 'and' condition.""" - test = await condition.async_from_config( - hass, - { - "alias": "Not Condition", - "condition": "not", - "conditions": [ - { - "condition": "state", - "entity_id": "sensor.temperature", - "state": "100", - }, - { - "condition": "numeric_state", - "entity_id": "sensor.temperature2", - "below": 50, - }, - ], - }, - ) + config = { + "alias": "Not Condition", + "condition": "not", + "conditions": [ + { + "condition": "state", + "entity_id": "sensor.temperature", + "state": "100", + }, + { + "condition": "numeric_state", + "entity_id": "sensor.temperature2", + "below": 50, + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) # All subconditions raise, the NOT-condition should raise with pytest.raises(ConditionError): @@ -640,23 +640,23 @@ async def test_not_condition_raises(hass): async def test_not_condition_with_template(hass): """Test the 'or' condition.""" - test = await condition.async_from_config( - hass, - { - "condition": "not", - "conditions": [ - { - "condition": "template", - "value_template": '{{ states.sensor.temperature.state == "100" }}', - }, - { - "condition": "numeric_state", - "entity_id": "sensor.temperature", - "below": 50, - }, - ], - }, - ) + config = { + "condition": "not", + "conditions": [ + { + "condition": "template", + "value_template": '{{ states.sensor.temperature.state == "100" }}', + }, + { + "condition": "numeric_state", + "entity_id": "sensor.temperature", + "below": 50, + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.temperature", 101) assert test(hass) @@ -676,14 +676,24 @@ async def test_time_window(hass): sixam = "06:00:00" sixpm = "18:00:00" - test1 = await condition.async_from_config( - hass, - {"alias": "Time Cond", "condition": "time", "after": sixam, "before": sixpm}, - ) - test2 = await condition.async_from_config( - hass, - {"alias": "Time Cond", "condition": "time", "after": sixpm, "before": sixam}, - ) + config1 = { + "alias": "Time Cond", + "condition": "time", + "after": sixam, + "before": sixpm, + } + config1 = cv.CONDITION_SCHEMA(config1) + config1 = await condition.async_validate_condition_config(hass, config1) + config2 = { + "alias": "Time Cond", + "condition": "time", + "after": sixpm, + "before": sixam, + } + config2 = cv.CONDITION_SCHEMA(config2) + config2 = await condition.async_validate_condition_config(hass, config2) + test1 = await condition.async_from_config(hass, config1) + test2 = await condition.async_from_config(hass, config2) with patch( "homeassistant.helpers.condition.dt_util.now", @@ -925,14 +935,14 @@ async def test_state_raises(hass): condition.state(hass, entity=None, req_state="missing") # Unknown entities - test = await condition.async_from_config( - hass, - { - "condition": "state", - "entity_id": ["sensor.door_unknown", "sensor.window_unknown"], - "state": "open", - }, - ) + config = { + "condition": "state", + "entity_id": ["sensor.door_unknown", "sensor.window_unknown"], + "state": "open", + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) with pytest.raises(ConditionError, match="unknown entity.*door"): test(hass) with pytest.raises(ConditionError, match="unknown entity.*window"): @@ -940,14 +950,14 @@ async def test_state_raises(hass): # Unknown state entity with pytest.raises(ConditionError, match="input_text.missing"): - test = await condition.async_from_config( - hass, - { - "condition": "state", - "entity_id": "sensor.door", - "state": "input_text.missing", - }, - ) + config = { + "condition": "state", + "entity_id": "sensor.door", + "state": "input_text.missing", + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.door", "open") test(hass) @@ -956,15 +966,15 @@ async def test_state_raises(hass): async def test_state_unknown_attribute(hass): """Test that state returns False on unknown attribute.""" # Unknown attribute - test = await condition.async_from_config( - hass, - { - "condition": "state", - "entity_id": "sensor.door", - "attribute": "model", - "state": "acme", - }, - ) + config = { + "condition": "state", + "entity_id": "sensor.door", + "attribute": "model", + "state": "acme", + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.door", "open") assert not test(hass) @@ -985,19 +995,19 @@ async def test_state_unknown_attribute(hass): async def test_state_multiple_entities(hass): """Test with multiple entities in condition.""" - test = await condition.async_from_config( - hass, - { - "condition": "and", - "conditions": [ - { - "condition": "state", - "entity_id": ["sensor.temperature_1", "sensor.temperature_2"], - "state": "100", - }, - ], - }, - ) + config = { + "condition": "and", + "conditions": [ + { + "condition": "state", + "entity_id": ["sensor.temperature_1", "sensor.temperature_2"], + "state": "100", + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.temperature_1", 100) hass.states.async_set("sensor.temperature_2", 100) @@ -1014,20 +1024,20 @@ async def test_state_multiple_entities(hass): async def test_multiple_states(hass): """Test with multiple states in condition.""" - test = await condition.async_from_config( - hass, - { - "condition": "and", - "conditions": [ - { - "alias": "State Condition", - "condition": "state", - "entity_id": "sensor.temperature", - "state": ["100", "200"], - }, - ], - }, - ) + config = { + "condition": "and", + "conditions": [ + { + "alias": "State Condition", + "condition": "state", + "entity_id": "sensor.temperature", + "state": ["100", "200"], + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.temperature", 100) assert test(hass) @@ -1041,20 +1051,20 @@ async def test_multiple_states(hass): async def test_state_attribute(hass): """Test with state attribute in condition.""" - test = await condition.async_from_config( - hass, - { - "condition": "and", - "conditions": [ - { - "condition": "state", - "entity_id": "sensor.temperature", - "attribute": "attribute1", - "state": 200, - }, - ], - }, - ) + config = { + "condition": "and", + "conditions": [ + { + "condition": "state", + "entity_id": "sensor.temperature", + "attribute": "attribute1", + "state": 200, + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.temperature", 100, {"unknown_attr": 200}) assert not test(hass) @@ -1074,15 +1084,15 @@ async def test_state_attribute(hass): async def test_state_attribute_boolean(hass): """Test with boolean state attribute in condition.""" - test = await condition.async_from_config( - hass, - { - "condition": "state", - "entity_id": "sensor.temperature", - "attribute": "happening", - "state": False, - }, - ) + config = { + "condition": "state", + "entity_id": "sensor.temperature", + "attribute": "happening", + "state": False, + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.temperature", 100, {"happening": 200}) assert not test(hass) @@ -1119,23 +1129,23 @@ async def test_state_using_input_entities(hass): }, ) - test = await condition.async_from_config( - hass, - { - "condition": "and", - "conditions": [ - { - "condition": "state", - "entity_id": "sensor.salut", - "state": [ - "input_text.hello", - "input_select.hello", - "salut", - ], - }, - ], - }, - ) + config = { + "condition": "and", + "conditions": [ + { + "condition": "state", + "entity_id": "sensor.salut", + "state": [ + "input_text.hello", + "input_select.hello", + "salut", + ], + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.salut", "goodbye") assert test(hass) @@ -1181,14 +1191,14 @@ async def test_state_using_input_entities(hass): async def test_numeric_state_known_non_matching(hass): """Test that numeric_state doesn't match on known non-matching states.""" hass.states.async_set("sensor.temperature", "unavailable") - test = await condition.async_from_config( - hass, - { - "condition": "numeric_state", - "entity_id": "sensor.temperature", - "above": 0, - }, - ) + config = { + "condition": "numeric_state", + "entity_id": "sensor.temperature", + "above": 0, + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) # Unavailable state assert not test(hass) @@ -1229,14 +1239,14 @@ async def test_numeric_state_known_non_matching(hass): async def test_numeric_state_raises(hass): """Test that numeric_state raises ConditionError on errors.""" # Unknown entities - test = await condition.async_from_config( - hass, - { - "condition": "numeric_state", - "entity_id": ["sensor.temperature_unknown", "sensor.humidity_unknown"], - "above": 0, - }, - ) + config = { + "condition": "numeric_state", + "entity_id": ["sensor.temperature_unknown", "sensor.humidity_unknown"], + "above": 0, + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) with pytest.raises(ConditionError, match="unknown entity.*temperature"): test(hass) with pytest.raises(ConditionError, match="unknown entity.*humidity"): @@ -1244,43 +1254,43 @@ async def test_numeric_state_raises(hass): # Template error with pytest.raises(ConditionError, match="ZeroDivisionError"): - test = await condition.async_from_config( - hass, - { - "condition": "numeric_state", - "entity_id": "sensor.temperature", - "value_template": "{{ 1 / 0 }}", - "above": 0, - }, - ) + config = { + "condition": "numeric_state", + "entity_id": "sensor.temperature", + "value_template": "{{ 1 / 0 }}", + "above": 0, + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.temperature", 50) test(hass) # Bad number with pytest.raises(ConditionError, match="cannot be processed as a number"): - test = await condition.async_from_config( - hass, - { - "condition": "numeric_state", - "entity_id": "sensor.temperature", - "above": 0, - }, - ) + config = { + "condition": "numeric_state", + "entity_id": "sensor.temperature", + "above": 0, + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.temperature", "fifty") test(hass) # Below entity missing with pytest.raises(ConditionError, match="'below' entity"): - test = await condition.async_from_config( - hass, - { - "condition": "numeric_state", - "entity_id": "sensor.temperature", - "below": "input_number.missing", - }, - ) + config = { + "condition": "numeric_state", + "entity_id": "sensor.temperature", + "below": "input_number.missing", + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.temperature", 50) test(hass) @@ -1295,14 +1305,14 @@ async def test_numeric_state_raises(hass): # Above entity missing with pytest.raises(ConditionError, match="'above' entity"): - test = await condition.async_from_config( - hass, - { - "condition": "numeric_state", - "entity_id": "sensor.temperature", - "above": "input_number.missing", - }, - ) + config = { + "condition": "numeric_state", + "entity_id": "sensor.temperature", + "above": "input_number.missing", + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.temperature", 50) test(hass) @@ -1319,15 +1329,15 @@ async def test_numeric_state_raises(hass): async def test_numeric_state_unknown_attribute(hass): """Test that numeric_state returns False on unknown attribute.""" # Unknown attribute - test = await condition.async_from_config( - hass, - { - "condition": "numeric_state", - "entity_id": "sensor.temperature", - "attribute": "temperature", - "above": 0, - }, - ) + config = { + "condition": "numeric_state", + "entity_id": "sensor.temperature", + "attribute": "temperature", + "above": 0, + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.temperature", 50) assert not test(hass) @@ -1348,20 +1358,20 @@ async def test_numeric_state_unknown_attribute(hass): async def test_numeric_state_multiple_entities(hass): """Test with multiple entities in condition.""" - test = await condition.async_from_config( - hass, - { - "condition": "and", - "conditions": [ - { - "alias": "Numeric State Condition", - "condition": "numeric_state", - "entity_id": ["sensor.temperature_1", "sensor.temperature_2"], - "below": 50, - }, - ], - }, - ) + config = { + "condition": "and", + "conditions": [ + { + "alias": "Numeric State Condition", + "condition": "numeric_state", + "entity_id": ["sensor.temperature_1", "sensor.temperature_2"], + "below": 50, + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.temperature_1", 49) hass.states.async_set("sensor.temperature_2", 49) @@ -1378,20 +1388,20 @@ async def test_numeric_state_multiple_entities(hass): async def test_numeric_state_attribute(hass): """Test with numeric state attribute in condition.""" - test = await condition.async_from_config( - hass, - { - "condition": "and", - "conditions": [ - { - "condition": "numeric_state", - "entity_id": "sensor.temperature", - "attribute": "attribute1", - "below": 50, - }, - ], - }, - ) + config = { + "condition": "and", + "conditions": [ + { + "condition": "numeric_state", + "entity_id": "sensor.temperature", + "attribute": "attribute1", + "below": 50, + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.temperature", 100, {"unknown_attr": 10}) assert not test(hass) @@ -1422,20 +1432,20 @@ async def test_numeric_state_using_input_number(hass): }, ) - test = await condition.async_from_config( - hass, - { - "condition": "and", - "conditions": [ - { - "condition": "numeric_state", - "entity_id": "sensor.temperature", - "below": "input_number.high", - "above": "number.low", - }, - ], - }, - ) + config = { + "condition": "and", + "conditions": [ + { + "condition": "numeric_state", + "entity_id": "sensor.temperature", + "below": "input_number.high", + "above": "number.low", + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set("sensor.temperature", 42) assert test(hass) @@ -1481,14 +1491,14 @@ async def test_numeric_state_using_input_number(hass): async def test_zone_raises(hass): """Test that zone raises ConditionError on errors.""" - test = await condition.async_from_config( - hass, - { - "condition": "zone", - "entity_id": "device_tracker.cat", - "zone": "zone.home", - }, - ) + config = { + "condition": "zone", + "entity_id": "device_tracker.cat", + "zone": "zone.home", + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) with pytest.raises(ConditionError, match="no zone"): condition.zone(hass, zone_ent=None, entity="sensor.any") @@ -1535,14 +1545,14 @@ async def test_zone_raises(hass): # All okay, now test multiple failed conditions assert test(hass) - test = await condition.async_from_config( - hass, - { - "condition": "zone", - "entity_id": ["device_tracker.cat", "device_tracker.dog"], - "zone": ["zone.home", "zone.work"], - }, - ) + config = { + "condition": "zone", + "entity_id": ["device_tracker.cat", "device_tracker.dog"], + "zone": ["zone.home", "zone.work"], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) with pytest.raises(ConditionError, match="dog"): test(hass) @@ -1567,20 +1577,20 @@ async def test_zone_raises(hass): async def test_zone_multiple_entities(hass): """Test with multiple entities in condition.""" - test = await condition.async_from_config( - hass, - { - "condition": "and", - "conditions": [ - { - "alias": "Zone Condition", - "condition": "zone", - "entity_id": ["device_tracker.person_1", "device_tracker.person_2"], - "zone": "zone.home", - }, - ], - }, - ) + config = { + "condition": "and", + "conditions": [ + { + "alias": "Zone Condition", + "condition": "zone", + "entity_id": ["device_tracker.person_1", "device_tracker.person_2"], + "zone": "zone.home", + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set( "zone.home", @@ -1627,19 +1637,19 @@ async def test_zone_multiple_entities(hass): async def test_multiple_zones(hass): """Test with multiple entities in condition.""" - test = await condition.async_from_config( - hass, - { - "condition": "and", - "conditions": [ - { - "condition": "zone", - "entity_id": "device_tracker.person", - "zone": ["zone.home", "zone.work"], - }, - ], - }, - ) + config = { + "condition": "and", + "conditions": [ + { + "condition": "zone", + "entity_id": "device_tracker.person", + "zone": ["zone.home", "zone.work"], + }, + ], + } + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) hass.states.async_set( "zone.home", @@ -1801,9 +1811,10 @@ async def test_extract_devices(): async def test_condition_template_error(hass): """Test invalid template.""" - test = await condition.async_from_config( - hass, {"condition": "template", "value_template": "{{ undefined.state }}"} - ) + config = {"condition": "template", "value_template": "{{ undefined.state }}"} + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) with pytest.raises(ConditionError, match="template"): test(hass) @@ -1811,24 +1822,28 @@ async def test_condition_template_error(hass): async def test_condition_template_invalid_results(hass): """Test template condition render false with invalid results.""" - test = await condition.async_from_config( - hass, {"condition": "template", "value_template": "{{ 'string' }}"} - ) + config = {"condition": "template", "value_template": "{{ 'string' }}"} + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) assert not test(hass) - test = await condition.async_from_config( - hass, {"condition": "template", "value_template": "{{ 10.1 }}"} - ) + config = {"condition": "template", "value_template": "{{ 10.1 }}"} + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) assert not test(hass) - test = await condition.async_from_config( - hass, {"condition": "template", "value_template": "{{ 42 }}"} - ) + config = {"condition": "template", "value_template": "{{ 42 }}"} + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) assert not test(hass) - test = await condition.async_from_config( - hass, {"condition": "template", "value_template": "{{ [1, 2, 3] }}"} - ) + config = {"condition": "template", "value_template": "{{ [1, 2, 3] }}"} + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) assert not test(hass) @@ -2894,10 +2909,10 @@ async def test_if_action_after_sunset_no_offset_kotzebue(hass, hass_ws_client, c async def test_trigger(hass): """Test trigger condition.""" - test = await condition.async_from_config( - hass, - {"alias": "Trigger Cond", "condition": "trigger", "id": "123456"}, - ) + config = {"alias": "Trigger Cond", "condition": "trigger", "id": "123456"} + config = cv.CONDITION_SCHEMA(config) + config = await condition.async_validate_condition_config(hass, config) + test = await condition.async_from_config(hass, config) assert not test(hass) assert not test(hass, {})