mirror of
https://github.com/home-assistant/core.git
synced 2025-07-10 14:57:09 +00:00
Add NOT condition helper (#34624)
This commit is contained in:
parent
6404882ec4
commit
c93c6a66e8
@ -54,6 +54,7 @@ CONF_SKIP_CONDITION = "skip_condition"
|
|||||||
|
|
||||||
CONDITION_USE_TRIGGER_VALUES = "use_trigger_values"
|
CONDITION_USE_TRIGGER_VALUES = "use_trigger_values"
|
||||||
CONDITION_TYPE_AND = "and"
|
CONDITION_TYPE_AND = "and"
|
||||||
|
CONDITION_TYPE_NOT = "not"
|
||||||
CONDITION_TYPE_OR = "or"
|
CONDITION_TYPE_OR = "or"
|
||||||
|
|
||||||
DEFAULT_CONDITION_TYPE = CONDITION_TYPE_AND
|
DEFAULT_CONDITION_TYPE = CONDITION_TYPE_AND
|
||||||
|
@ -137,6 +137,32 @@ async def async_or_from_config(
|
|||||||
return if_or_condition
|
return if_or_condition
|
||||||
|
|
||||||
|
|
||||||
|
async def async_not_from_config(
|
||||||
|
hass: HomeAssistant, config: ConfigType, config_validation: bool = True
|
||||||
|
) -> 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"]
|
||||||
|
]
|
||||||
|
|
||||||
|
def if_not_condition(
|
||||||
|
hass: HomeAssistant, variables: TemplateVarsType = None
|
||||||
|
) -> bool:
|
||||||
|
"""Test not condition."""
|
||||||
|
try:
|
||||||
|
for check in checks:
|
||||||
|
if check(hass, variables):
|
||||||
|
return False
|
||||||
|
except Exception as ex: # pylint: disable=broad-except
|
||||||
|
_LOGGER.warning("Error during not-condition: %s", ex)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
return if_not_condition
|
||||||
|
|
||||||
|
|
||||||
def numeric_state(
|
def numeric_state(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
entity: Union[None, str, State],
|
entity: Union[None, str, State],
|
||||||
|
@ -924,6 +924,17 @@ OR_CONDITION_SCHEMA = vol.Schema(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
NOT_CONDITION_SCHEMA = vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(CONF_CONDITION): "not",
|
||||||
|
vol.Required("conditions"): vol.All(
|
||||||
|
ensure_list,
|
||||||
|
# pylint: disable=unnecessary-lambda
|
||||||
|
[lambda value: CONDITION_SCHEMA(value)],
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
DEVICE_CONDITION_BASE_SCHEMA = vol.Schema(
|
DEVICE_CONDITION_BASE_SCHEMA = vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Required(CONF_CONDITION): "device",
|
vol.Required(CONF_CONDITION): "device",
|
||||||
@ -945,6 +956,7 @@ CONDITION_SCHEMA: vol.Schema = key_value_schemas(
|
|||||||
"zone": ZONE_CONDITION_SCHEMA,
|
"zone": ZONE_CONDITION_SCHEMA,
|
||||||
"and": AND_CONDITION_SCHEMA,
|
"and": AND_CONDITION_SCHEMA,
|
||||||
"or": OR_CONDITION_SCHEMA,
|
"or": OR_CONDITION_SCHEMA,
|
||||||
|
"not": NOT_CONDITION_SCHEMA,
|
||||||
"device": DEVICE_CONDITION_SCHEMA,
|
"device": DEVICE_CONDITION_SCHEMA,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -127,6 +127,73 @@ async def test_or_condition_with_template(hass):
|
|||||||
assert test(hass)
|
assert test(hass)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_not_condition(hass):
|
||||||
|
"""Test the 'not' condition."""
|
||||||
|
test = await condition.async_from_config(
|
||||||
|
hass,
|
||||||
|
{
|
||||||
|
"condition": "not",
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"condition": "state",
|
||||||
|
"entity_id": "sensor.temperature",
|
||||||
|
"state": "100",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"condition": "numeric_state",
|
||||||
|
"entity_id": "sensor.temperature",
|
||||||
|
"below": 50,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
hass.states.async_set("sensor.temperature", 101)
|
||||||
|
assert test(hass)
|
||||||
|
|
||||||
|
hass.states.async_set("sensor.temperature", 50)
|
||||||
|
assert test(hass)
|
||||||
|
|
||||||
|
hass.states.async_set("sensor.temperature", 49)
|
||||||
|
assert not test(hass)
|
||||||
|
|
||||||
|
hass.states.async_set("sensor.temperature", 100)
|
||||||
|
assert not test(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,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
hass.states.async_set("sensor.temperature", 101)
|
||||||
|
assert test(hass)
|
||||||
|
|
||||||
|
hass.states.async_set("sensor.temperature", 50)
|
||||||
|
assert test(hass)
|
||||||
|
|
||||||
|
hass.states.async_set("sensor.temperature", 49)
|
||||||
|
assert not test(hass)
|
||||||
|
|
||||||
|
hass.states.async_set("sensor.temperature", 100)
|
||||||
|
assert not test(hass)
|
||||||
|
|
||||||
|
|
||||||
async def test_time_window(hass):
|
async def test_time_window(hass):
|
||||||
"""Test time condition windows."""
|
"""Test time condition windows."""
|
||||||
sixam = dt.parse_time("06:00:00")
|
sixam = dt.parse_time("06:00:00")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user