Handle ConditionError with multiple entity_id for state/numeric_state (#46855)

This commit is contained in:
Anders Melchiorsen 2021-02-22 08:11:59 +01:00 committed by GitHub
parent 75b37b4c2a
commit d61d39de08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 33 deletions

View File

@ -85,7 +85,7 @@ class ConditionErrorIndex(ConditionError):
@attr.s
class ConditionErrorContainer(ConditionError):
"""Condition error with index."""
"""Condition error with subconditions."""
# List of ConditionErrors that this error wraps
errors: Sequence[ConditionError] = attr.ib()

View File

@ -342,12 +342,25 @@ def async_numeric_state_from_config(
if value_template is not None:
value_template.hass = hass
return all(
async_numeric_state(
hass, entity_id, below, above, value_template, variables, attribute
)
for entity_id in entity_ids
)
errors = []
for index, entity_id in enumerate(entity_ids):
try:
if not async_numeric_state(
hass, entity_id, below, above, value_template, variables, attribute
):
return False
except ConditionError as ex:
errors.append(
ConditionErrorIndex(
"numeric_state", index=index, total=len(entity_ids), error=ex
)
)
# Raise the errors if no check was false
if errors:
raise ConditionErrorContainer("numeric_state", errors=errors)
return True
return if_numeric_state
@ -429,10 +442,23 @@ def state_from_config(
def if_state(hass: HomeAssistant, variables: TemplateVarsType = None) -> bool:
"""Test if condition."""
return all(
state(hass, entity_id, req_states, for_period, attribute)
for entity_id in entity_ids
)
errors = []
for index, entity_id in enumerate(entity_ids):
try:
if not state(hass, entity_id, req_states, for_period, attribute):
return False
except ConditionError as ex:
errors.append(
ConditionErrorIndex(
"state", index=index, total=len(entity_ids), error=ex
)
)
# Raise the errors if no check was false
if errors:
raise ConditionErrorContainer("state", errors=errors)
return True
return if_state

View File

@ -390,17 +390,18 @@ async def test_state_raises(hass):
with pytest.raises(ConditionError, match="no entity"):
condition.state(hass, entity=None, req_state="missing")
# Unknown entity_id
with pytest.raises(ConditionError, match="unknown entity"):
test = await condition.async_from_config(
hass,
{
"condition": "state",
"entity_id": "sensor.door_unknown",
"state": "open",
},
)
# Unknown entities
test = await condition.async_from_config(
hass,
{
"condition": "state",
"entity_id": ["sensor.door_unknown", "sensor.window_unknown"],
"state": "open",
},
)
with pytest.raises(ConditionError, match="unknown entity.*door"):
test(hass)
with pytest.raises(ConditionError, match="unknown entity.*window"):
test(hass)
# Unknown attribute
@ -632,17 +633,18 @@ async def test_state_using_input_entities(hass):
async def test_numeric_state_raises(hass):
"""Test that numeric_state raises ConditionError on errors."""
# Unknown entity_id
with pytest.raises(ConditionError, match="unknown entity"):
test = await condition.async_from_config(
hass,
{
"condition": "numeric_state",
"entity_id": "sensor.temperature_unknown",
"above": 0,
},
)
# Unknown entities
test = await condition.async_from_config(
hass,
{
"condition": "numeric_state",
"entity_id": ["sensor.temperature_unknown", "sensor.humidity_unknown"],
"above": 0,
},
)
with pytest.raises(ConditionError, match="unknown entity.*temperature"):
test(hass)
with pytest.raises(ConditionError, match="unknown entity.*humidity"):
test(hass)
# Unknown attribute