2016-04-28 10:03:57 +00:00
|
|
|
"""Test the condition helper."""
|
2020-08-16 00:53:03 +00:00
|
|
|
from logging import ERROR
|
|
|
|
|
2020-04-30 22:15:53 +00:00
|
|
|
import pytest
|
|
|
|
|
|
|
|
from homeassistant.exceptions import HomeAssistantError
|
2016-04-28 10:03:57 +00:00
|
|
|
from homeassistant.helpers import condition
|
2016-05-29 21:32:32 +00:00
|
|
|
from homeassistant.util import dt
|
2016-04-28 10:03:57 +00:00
|
|
|
|
2020-05-03 18:27:19 +00:00
|
|
|
from tests.async_mock import patch
|
|
|
|
|
2019-09-05 14:49:32 +00:00
|
|
|
|
2020-04-30 22:15:53 +00:00
|
|
|
async def test_invalid_condition(hass):
|
|
|
|
"""Test if invalid condition raises."""
|
|
|
|
with pytest.raises(HomeAssistantError):
|
|
|
|
await condition.async_from_config(
|
|
|
|
hass,
|
|
|
|
{
|
|
|
|
"condition": "invalid",
|
|
|
|
"conditions": [
|
|
|
|
{
|
|
|
|
"condition": "state",
|
|
|
|
"entity_id": "sensor.temperature",
|
|
|
|
"state": "100",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2019-09-05 14:49:32 +00:00
|
|
|
async def test_and_condition(hass):
|
|
|
|
"""Test the 'and' condition."""
|
|
|
|
test = await condition.async_from_config(
|
|
|
|
hass,
|
|
|
|
{
|
|
|
|
"condition": "and",
|
|
|
|
"conditions": [
|
|
|
|
{
|
|
|
|
"condition": "state",
|
|
|
|
"entity_id": "sensor.temperature",
|
|
|
|
"state": "100",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"condition": "numeric_state",
|
|
|
|
"entity_id": "sensor.temperature",
|
|
|
|
"below": 110,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 120)
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 105)
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 100)
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
|
|
|
|
async def test_and_condition_with_template(hass):
|
|
|
|
"""Test the 'and' condition."""
|
|
|
|
test = await condition.async_from_config(
|
|
|
|
hass,
|
|
|
|
{
|
|
|
|
"condition": "and",
|
|
|
|
"conditions": [
|
|
|
|
{
|
|
|
|
"condition": "template",
|
|
|
|
"value_template": '{{ states.sensor.temperature.state == "100" }}',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"condition": "numeric_state",
|
|
|
|
"entity_id": "sensor.temperature",
|
|
|
|
"below": 110,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 120)
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 105)
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 100)
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
|
|
|
|
async def test_or_condition(hass):
|
|
|
|
"""Test the 'or' condition."""
|
|
|
|
test = await condition.async_from_config(
|
|
|
|
hass,
|
|
|
|
{
|
|
|
|
"condition": "or",
|
|
|
|
"conditions": [
|
|
|
|
{
|
|
|
|
"condition": "state",
|
|
|
|
"entity_id": "sensor.temperature",
|
|
|
|
"state": "100",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"condition": "numeric_state",
|
|
|
|
"entity_id": "sensor.temperature",
|
|
|
|
"below": 110,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 120)
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 105)
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 100)
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
|
|
|
|
async def test_or_condition_with_template(hass):
|
|
|
|
"""Test the 'or' condition."""
|
|
|
|
test = await condition.async_from_config(
|
|
|
|
hass,
|
|
|
|
{
|
|
|
|
"condition": "or",
|
|
|
|
"conditions": [
|
|
|
|
{
|
|
|
|
"condition": "template",
|
|
|
|
"value_template": '{{ states.sensor.temperature.state == "100" }}',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"condition": "numeric_state",
|
|
|
|
"entity_id": "sensor.temperature",
|
|
|
|
"below": 110,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 120)
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 105)
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 100)
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
|
2020-04-24 16:40:23 +00:00
|
|
|
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)
|
|
|
|
|
|
|
|
|
2019-09-05 14:49:32 +00:00
|
|
|
async def test_time_window(hass):
|
|
|
|
"""Test time condition windows."""
|
|
|
|
sixam = dt.parse_time("06:00:00")
|
|
|
|
sixpm = dt.parse_time("18:00:00")
|
|
|
|
|
|
|
|
with patch(
|
|
|
|
"homeassistant.helpers.condition.dt_util.now",
|
|
|
|
return_value=dt.now().replace(hour=3),
|
|
|
|
):
|
|
|
|
assert not condition.time(after=sixam, before=sixpm)
|
|
|
|
assert condition.time(after=sixpm, before=sixam)
|
|
|
|
|
|
|
|
with patch(
|
|
|
|
"homeassistant.helpers.condition.dt_util.now",
|
|
|
|
return_value=dt.now().replace(hour=9),
|
|
|
|
):
|
|
|
|
assert condition.time(after=sixam, before=sixpm)
|
|
|
|
assert not condition.time(after=sixpm, before=sixam)
|
|
|
|
|
|
|
|
with patch(
|
|
|
|
"homeassistant.helpers.condition.dt_util.now",
|
|
|
|
return_value=dt.now().replace(hour=15),
|
|
|
|
):
|
|
|
|
assert condition.time(after=sixam, before=sixpm)
|
|
|
|
assert not condition.time(after=sixpm, before=sixam)
|
|
|
|
|
|
|
|
with patch(
|
|
|
|
"homeassistant.helpers.condition.dt_util.now",
|
|
|
|
return_value=dt.now().replace(hour=21),
|
|
|
|
):
|
|
|
|
assert not condition.time(after=sixam, before=sixpm)
|
|
|
|
assert condition.time(after=sixpm, before=sixam)
|
|
|
|
|
|
|
|
|
|
|
|
async def test_if_numeric_state_not_raise_on_unavailable(hass):
|
|
|
|
"""Test numeric_state doesn't raise on unavailable/unknown state."""
|
|
|
|
test = await condition.async_from_config(
|
|
|
|
hass,
|
|
|
|
{"condition": "numeric_state", "entity_id": "sensor.temperature", "below": 42},
|
|
|
|
)
|
|
|
|
|
|
|
|
with patch("homeassistant.helpers.condition._LOGGER.warning") as logwarn:
|
|
|
|
hass.states.async_set("sensor.temperature", "unavailable")
|
|
|
|
assert not test(hass)
|
|
|
|
assert len(logwarn.mock_calls) == 0
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", "unknown")
|
|
|
|
assert not test(hass)
|
|
|
|
assert len(logwarn.mock_calls) == 0
|
2020-01-30 00:19:13 +00:00
|
|
|
|
|
|
|
|
2020-06-15 20:54:19 +00:00
|
|
|
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",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature_1", 100)
|
|
|
|
hass.states.async_set("sensor.temperature_2", 100)
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature_1", 101)
|
|
|
|
hass.states.async_set("sensor.temperature_2", 100)
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature_1", 100)
|
|
|
|
hass.states.async_set("sensor.temperature_2", 101)
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
|
2020-06-15 22:53:13 +00:00
|
|
|
async def test_multiple_states(hass):
|
|
|
|
"""Test with multiple states in condition."""
|
|
|
|
test = await condition.async_from_config(
|
|
|
|
hass,
|
|
|
|
{
|
|
|
|
"condition": "and",
|
|
|
|
"conditions": [
|
|
|
|
{
|
|
|
|
"condition": "state",
|
|
|
|
"entity_id": "sensor.temperature",
|
|
|
|
"state": ["100", "200"],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 100)
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 200)
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 42)
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
|
2020-08-19 18:01:27 +00:00
|
|
|
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",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 100, {"unkown_attr": 200})
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 100, {"attribute1": 200})
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 100, {"attribute1": "200"})
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 100, {"attribute1": 201})
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 100, {"attribute1": None})
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
|
2020-06-15 20:54:19 +00:00
|
|
|
async def test_numeric_state_multiple_entities(hass):
|
|
|
|
"""Test with multiple entities in condition."""
|
|
|
|
test = await condition.async_from_config(
|
|
|
|
hass,
|
|
|
|
{
|
|
|
|
"condition": "and",
|
|
|
|
"conditions": [
|
|
|
|
{
|
|
|
|
"condition": "numeric_state",
|
|
|
|
"entity_id": ["sensor.temperature_1", "sensor.temperature_2"],
|
|
|
|
"below": 50,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature_1", 49)
|
|
|
|
hass.states.async_set("sensor.temperature_2", 49)
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature_1", 50)
|
|
|
|
hass.states.async_set("sensor.temperature_2", 49)
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature_1", 49)
|
|
|
|
hass.states.async_set("sensor.temperature_2", 50)
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
|
2020-08-19 18:01:27 +00:00
|
|
|
async def test_numberic_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,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 100, {"unkown_attr": 10})
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 100, {"attribute1": 49})
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 100, {"attribute1": "49"})
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 100, {"attribute1": 51})
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set("sensor.temperature", 100, {"attribute1": None})
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
|
2020-06-15 20:54:19 +00:00
|
|
|
async def test_zone_multiple_entities(hass):
|
|
|
|
"""Test with multiple entities in condition."""
|
|
|
|
test = await condition.async_from_config(
|
|
|
|
hass,
|
|
|
|
{
|
|
|
|
"condition": "and",
|
|
|
|
"conditions": [
|
|
|
|
{
|
|
|
|
"condition": "zone",
|
|
|
|
"entity_id": ["device_tracker.person_1", "device_tracker.person_2"],
|
|
|
|
"zone": "zone.home",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
hass.states.async_set(
|
|
|
|
"zone.home",
|
|
|
|
"zoning",
|
|
|
|
{"name": "home", "latitude": 2.1, "longitude": 1.1, "radius": 10},
|
|
|
|
)
|
|
|
|
|
|
|
|
hass.states.async_set(
|
|
|
|
"device_tracker.person_1",
|
|
|
|
"home",
|
|
|
|
{"friendly_name": "person_1", "latitude": 2.1, "longitude": 1.1},
|
|
|
|
)
|
|
|
|
hass.states.async_set(
|
|
|
|
"device_tracker.person_2",
|
|
|
|
"home",
|
|
|
|
{"friendly_name": "person_2", "latitude": 2.1, "longitude": 1.1},
|
|
|
|
)
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set(
|
|
|
|
"device_tracker.person_1",
|
|
|
|
"home",
|
|
|
|
{"friendly_name": "person_1", "latitude": 20.1, "longitude": 10.1},
|
|
|
|
)
|
|
|
|
hass.states.async_set(
|
|
|
|
"device_tracker.person_2",
|
|
|
|
"home",
|
|
|
|
{"friendly_name": "person_2", "latitude": 2.1, "longitude": 1.1},
|
|
|
|
)
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set(
|
|
|
|
"device_tracker.person_1",
|
|
|
|
"home",
|
|
|
|
{"friendly_name": "person_1", "latitude": 2.1, "longitude": 1.1},
|
|
|
|
)
|
|
|
|
hass.states.async_set(
|
|
|
|
"device_tracker.person_2",
|
|
|
|
"home",
|
|
|
|
{"friendly_name": "person_2", "latitude": 20.1, "longitude": 10.1},
|
|
|
|
)
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
|
2020-06-15 22:53:13 +00:00
|
|
|
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"],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
hass.states.async_set(
|
|
|
|
"zone.home",
|
|
|
|
"zoning",
|
|
|
|
{"name": "home", "latitude": 2.1, "longitude": 1.1, "radius": 10},
|
|
|
|
)
|
|
|
|
hass.states.async_set(
|
|
|
|
"zone.work",
|
|
|
|
"zoning",
|
|
|
|
{"name": "work", "latitude": 20.1, "longitude": 10.1, "radius": 10},
|
|
|
|
)
|
|
|
|
|
|
|
|
hass.states.async_set(
|
|
|
|
"device_tracker.person",
|
|
|
|
"home",
|
|
|
|
{"friendly_name": "person", "latitude": 2.1, "longitude": 1.1},
|
|
|
|
)
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set(
|
|
|
|
"device_tracker.person",
|
|
|
|
"home",
|
|
|
|
{"friendly_name": "person", "latitude": 20.1, "longitude": 10.1},
|
|
|
|
)
|
|
|
|
assert test(hass)
|
|
|
|
|
|
|
|
hass.states.async_set(
|
|
|
|
"device_tracker.person",
|
|
|
|
"home",
|
|
|
|
{"friendly_name": "person", "latitude": 50.1, "longitude": 20.1},
|
|
|
|
)
|
|
|
|
assert not test(hass)
|
|
|
|
|
|
|
|
|
2020-01-30 00:19:13 +00:00
|
|
|
async def test_extract_entities():
|
|
|
|
"""Test extracting entities."""
|
2020-04-06 10:51:48 +00:00
|
|
|
assert condition.async_extract_entities(
|
2020-01-30 00:19:13 +00:00
|
|
|
{
|
|
|
|
"condition": "and",
|
|
|
|
"conditions": [
|
|
|
|
{
|
|
|
|
"condition": "state",
|
|
|
|
"entity_id": "sensor.temperature",
|
|
|
|
"state": "100",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"condition": "numeric_state",
|
|
|
|
"entity_id": "sensor.temperature_2",
|
|
|
|
"below": 110,
|
|
|
|
},
|
2020-04-30 22:15:53 +00:00
|
|
|
{
|
|
|
|
"condition": "not",
|
|
|
|
"conditions": [
|
|
|
|
{
|
|
|
|
"condition": "state",
|
|
|
|
"entity_id": "sensor.temperature_3",
|
|
|
|
"state": "100",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"condition": "numeric_state",
|
|
|
|
"entity_id": "sensor.temperature_4",
|
|
|
|
"below": 110,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"condition": "or",
|
|
|
|
"conditions": [
|
|
|
|
{
|
|
|
|
"condition": "state",
|
|
|
|
"entity_id": "sensor.temperature_5",
|
|
|
|
"state": "100",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"condition": "numeric_state",
|
|
|
|
"entity_id": "sensor.temperature_6",
|
|
|
|
"below": 110,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
2020-06-15 20:54:19 +00:00
|
|
|
{
|
|
|
|
"condition": "state",
|
|
|
|
"entity_id": ["sensor.temperature_7", "sensor.temperature_8"],
|
|
|
|
"state": "100",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"condition": "numeric_state",
|
|
|
|
"entity_id": ["sensor.temperature_9", "sensor.temperature_10"],
|
|
|
|
"below": 110,
|
|
|
|
},
|
2020-01-30 00:19:13 +00:00
|
|
|
],
|
|
|
|
}
|
2020-04-30 22:15:53 +00:00
|
|
|
) == {
|
|
|
|
"sensor.temperature",
|
|
|
|
"sensor.temperature_2",
|
|
|
|
"sensor.temperature_3",
|
|
|
|
"sensor.temperature_4",
|
|
|
|
"sensor.temperature_5",
|
|
|
|
"sensor.temperature_6",
|
2020-06-15 20:54:19 +00:00
|
|
|
"sensor.temperature_7",
|
|
|
|
"sensor.temperature_8",
|
|
|
|
"sensor.temperature_9",
|
|
|
|
"sensor.temperature_10",
|
2020-04-30 22:15:53 +00:00
|
|
|
}
|
2020-01-30 00:19:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def test_extract_devices():
|
|
|
|
"""Test extracting devices."""
|
2020-08-27 11:56:20 +00:00
|
|
|
assert (
|
|
|
|
condition.async_extract_devices(
|
|
|
|
{
|
|
|
|
"condition": "and",
|
|
|
|
"conditions": [
|
|
|
|
{"condition": "device", "device_id": "abcd", "domain": "light"},
|
|
|
|
{"condition": "device", "device_id": "qwer", "domain": "switch"},
|
|
|
|
{
|
|
|
|
"condition": "state",
|
|
|
|
"entity_id": "sensor.not_a_device",
|
|
|
|
"state": "100",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"condition": "not",
|
|
|
|
"conditions": [
|
|
|
|
{
|
|
|
|
"condition": "device",
|
|
|
|
"device_id": "abcd_not",
|
|
|
|
"domain": "light",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"condition": "device",
|
|
|
|
"device_id": "qwer_not",
|
|
|
|
"domain": "switch",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"condition": "or",
|
|
|
|
"conditions": [
|
|
|
|
{
|
|
|
|
"condition": "device",
|
|
|
|
"device_id": "abcd_or",
|
|
|
|
"domain": "light",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"condition": "device",
|
|
|
|
"device_id": "qwer_or",
|
|
|
|
"domain": "switch",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}
|
|
|
|
)
|
|
|
|
== {"abcd", "qwer", "abcd_not", "qwer_not", "abcd_or", "qwer_or"}
|
|
|
|
)
|
2020-08-16 00:53:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def test_condition_template_error(hass, caplog):
|
|
|
|
"""Test invalid template."""
|
|
|
|
caplog.set_level(ERROR)
|
|
|
|
|
|
|
|
test = await condition.async_from_config(
|
|
|
|
hass, {"condition": "template", "value_template": "{{ undefined.state }}"}
|
|
|
|
)
|
|
|
|
|
|
|
|
assert not test(hass)
|
|
|
|
assert len(caplog.records) == 1
|
|
|
|
assert caplog.records[0].message.startswith(
|
|
|
|
"Error during template condition: UndefinedError:"
|
|
|
|
)
|