State condition can also accept an input_* Entity ID as state value (#39691)
parent
165dd351b7
commit
1ec3446c56
|
@ -4,6 +4,7 @@ from collections import deque
|
|||
from datetime import datetime, timedelta
|
||||
import functools as ft
|
||||
import logging
|
||||
import re
|
||||
import sys
|
||||
from typing import Any, Callable, Container, List, Optional, Set, Union, cast
|
||||
|
||||
|
@ -48,6 +49,10 @@ ASYNC_FROM_CONFIG_FORMAT = "async_{}_from_config"
|
|||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
INPUT_ENTITY_ID = re.compile(
|
||||
r"^input_(?:select|text|number|boolean|datetime)\.(?!.+__)(?!_)[\da-z_]+(?<!_)$"
|
||||
)
|
||||
|
||||
ConditionCheckerType = Callable[[HomeAssistant, TemplateVarsType], bool]
|
||||
|
||||
|
||||
|
@ -308,13 +313,25 @@ def state(
|
|||
|
||||
assert isinstance(entity, State)
|
||||
|
||||
if attribute is None:
|
||||
value = entity.state
|
||||
else:
|
||||
value = str(entity.attributes.get(attribute))
|
||||
|
||||
if isinstance(req_state, str):
|
||||
req_state = [req_state]
|
||||
|
||||
if attribute is None:
|
||||
is_state = entity.state in req_state
|
||||
else:
|
||||
is_state = str(entity.attributes.get(attribute)) in req_state
|
||||
is_state = False
|
||||
for req_state_value in req_state:
|
||||
state_value = req_state_value
|
||||
if INPUT_ENTITY_ID.match(req_state_value) is not None:
|
||||
state_entity = hass.states.get(req_state_value)
|
||||
if not state_entity:
|
||||
continue
|
||||
state_value = state_entity.state
|
||||
is_state = value == state_value
|
||||
if is_state:
|
||||
break
|
||||
|
||||
if for_period is None or not is_state:
|
||||
return is_state
|
||||
|
|
|
@ -443,6 +443,88 @@ async def test_state_attribute(hass):
|
|||
assert not test(hass)
|
||||
|
||||
|
||||
async def test_state_using_input_entities(hass):
|
||||
"""Test state conditions using input_* entities."""
|
||||
await async_setup_component(
|
||||
hass,
|
||||
"input_text",
|
||||
{
|
||||
"input_text": {
|
||||
"hello": {"initial": "goodbye"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
await async_setup_component(
|
||||
hass,
|
||||
"input_select",
|
||||
{
|
||||
"input_select": {
|
||||
"hello": {"options": ["cya", "goodbye", "welcome"], "initial": "cya"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
test = await condition.async_from_config(
|
||||
hass,
|
||||
{
|
||||
"condition": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "state",
|
||||
"entity_id": "sensor.salut",
|
||||
"state": [
|
||||
"input_text.hello",
|
||||
"input_select.hello",
|
||||
"input_number.not_exist",
|
||||
"salut",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
hass.states.async_set("sensor.salut", "goodbye")
|
||||
assert test(hass)
|
||||
|
||||
hass.states.async_set("sensor.salut", "salut")
|
||||
assert test(hass)
|
||||
|
||||
hass.states.async_set("sensor.salut", "hello")
|
||||
assert not test(hass)
|
||||
|
||||
await hass.services.async_call(
|
||||
"input_text",
|
||||
"set_value",
|
||||
{
|
||||
"entity_id": "input_text.hello",
|
||||
"value": "hi",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
assert not test(hass)
|
||||
|
||||
hass.states.async_set("sensor.salut", "hi")
|
||||
assert test(hass)
|
||||
|
||||
hass.states.async_set("sensor.salut", "cya")
|
||||
assert test(hass)
|
||||
|
||||
await hass.services.async_call(
|
||||
"input_select",
|
||||
"select_option",
|
||||
{
|
||||
"entity_id": "input_select.hello",
|
||||
"option": "welcome",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
assert not test(hass)
|
||||
|
||||
hass.states.async_set("sensor.salut", "welcome")
|
||||
assert test(hass)
|
||||
|
||||
|
||||
async def test_numeric_state_multiple_entities(hass):
|
||||
"""Test with multiple entities in condition."""
|
||||
test = await condition.async_from_config(
|
||||
|
|
Loading…
Reference in New Issue