From 05241a7a682e1ff43785833cf370d06e450945f5 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Fri, 4 Jun 2021 18:14:48 +0200 Subject: [PATCH] Allow number/sensor entities in numeric state conditions/triggers (#51439) --- homeassistant/helpers/config_validation.py | 2 +- .../triggers/test_numeric_state.py | 42 ++++++++++++++----- tests/helpers/test_condition.py | 8 ++-- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index 40457ef92c8..88f38f0a688 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -926,7 +926,7 @@ SERVICE_SCHEMA = vol.All( ) NUMERIC_STATE_THRESHOLD_SCHEMA = vol.Any( - vol.Coerce(float), vol.All(str, entity_domain("input_number")) + vol.Coerce(float), vol.All(str, entity_domain(["input_number", "number", "sensor"])) ) CONDITION_BASE_SCHEMA = {vol.Optional(CONF_ALIAS): string} diff --git a/tests/components/homeassistant/triggers/test_numeric_state.py b/tests/components/homeassistant/triggers/test_numeric_state.py index 38372d09825..0e71594937f 100644 --- a/tests/components/homeassistant/triggers/test_numeric_state.py +++ b/tests/components/homeassistant/triggers/test_numeric_state.py @@ -47,9 +47,13 @@ async def setup_comp(hass): } }, ) + hass.states.async_set("number.value_10", 10) + hass.states.async_set("sensor.value_10", 10) -@pytest.mark.parametrize("below", (10, "input_number.value_10")) +@pytest.mark.parametrize( + "below", (10, "input_number.value_10", "number.value_10", "sensor.value_10") +) async def test_if_not_fires_on_entity_removal(hass, calls, below): """Test the firing with removed entity.""" hass.states.async_set("test.entity", 11) @@ -75,7 +79,9 @@ async def test_if_not_fires_on_entity_removal(hass, calls, below): assert len(calls) == 0 -@pytest.mark.parametrize("below", (10, "input_number.value_10")) +@pytest.mark.parametrize( + "below", (10, "input_number.value_10", "number.value_10", "sensor.value_10") +) async def test_if_fires_on_entity_change_below(hass, calls, below): """Test the firing with changed entity.""" hass.states.async_set("test.entity", 11) @@ -120,7 +126,9 @@ async def test_if_fires_on_entity_change_below(hass, calls, below): assert calls[0].data["id"] == 0 -@pytest.mark.parametrize("below", (10, "input_number.value_10")) +@pytest.mark.parametrize( + "below", (10, "input_number.value_10", "number.value_10", "sensor.value_10") +) async def test_if_fires_on_entity_change_over_to_below(hass, calls, below): """Test the firing with changed entity.""" hass.states.async_set("test.entity", 11) @@ -147,7 +155,9 @@ async def test_if_fires_on_entity_change_over_to_below(hass, calls, below): assert len(calls) == 1 -@pytest.mark.parametrize("below", (10, "input_number.value_10")) +@pytest.mark.parametrize( + "below", (10, "input_number.value_10", "number.value_10", "sensor.value_10") +) async def test_if_fires_on_entities_change_over_to_below(hass, calls, below): """Test the firing with changed entities.""" hass.states.async_set("test.entity_1", 11) @@ -178,7 +188,9 @@ async def test_if_fires_on_entities_change_over_to_below(hass, calls, below): assert len(calls) == 2 -@pytest.mark.parametrize("below", (10, "input_number.value_10")) +@pytest.mark.parametrize( + "below", (10, "input_number.value_10", "number.value_10", "sensor.value_10") +) async def test_if_not_fires_on_entity_change_below_to_below(hass, calls, below): """Test the firing with changed entity.""" context = Context() @@ -217,7 +229,9 @@ async def test_if_not_fires_on_entity_change_below_to_below(hass, calls, below): assert len(calls) == 1 -@pytest.mark.parametrize("below", (10, "input_number.value_10")) +@pytest.mark.parametrize( + "below", (10, "input_number.value_10", "number.value_10", "sensor.value_10") +) async def test_if_not_below_fires_on_entity_change_to_equal(hass, calls, below): """Test the firing with changed entity.""" hass.states.async_set("test.entity", 11) @@ -244,7 +258,9 @@ async def test_if_not_below_fires_on_entity_change_to_equal(hass, calls, below): assert len(calls) == 0 -@pytest.mark.parametrize("below", (10, "input_number.value_10")) +@pytest.mark.parametrize( + "below", (10, "input_number.value_10", "number.value_10", "sensor.value_10") +) async def test_if_not_fires_on_initial_entity_below(hass, calls, below): """Test the firing when starting with a match.""" hass.states.async_set("test.entity", 9) @@ -271,7 +287,9 @@ async def test_if_not_fires_on_initial_entity_below(hass, calls, below): assert len(calls) == 0 -@pytest.mark.parametrize("above", (10, "input_number.value_10")) +@pytest.mark.parametrize( + "above", (10, "input_number.value_10", "number.value_10", "sensor.value_10") +) async def test_if_not_fires_on_initial_entity_above(hass, calls, above): """Test the firing when starting with a match.""" hass.states.async_set("test.entity", 11) @@ -298,7 +316,9 @@ async def test_if_not_fires_on_initial_entity_above(hass, calls, above): assert len(calls) == 0 -@pytest.mark.parametrize("above", (10, "input_number.value_10")) +@pytest.mark.parametrize( + "above", (10, "input_number.value_10", "number.value_10", "sensor.value_10") +) async def test_if_fires_on_entity_change_above(hass, calls, above): """Test the firing with changed entity.""" hass.states.async_set("test.entity", 9) @@ -1632,8 +1652,8 @@ def test_below_above(): ) -def test_schema_input_number(): - """Test input_number only is accepted for above/below.""" +def test_schema_unacceptable_entities(): + """Test input_number, number & sensor only is accepted for above/below.""" with pytest.raises(vol.Invalid): numeric_state_trigger.TRIGGER_SCHEMA( { diff --git a/tests/helpers/test_condition.py b/tests/helpers/test_condition.py index 2290ce9f679..973196d29f8 100644 --- a/tests/helpers/test_condition.py +++ b/tests/helpers/test_condition.py @@ -1265,12 +1265,12 @@ async def test_numeric_state_attribute(hass): async def test_numeric_state_using_input_number(hass): """Test numeric_state conditions using input_number entities.""" + hass.states.async_set("number.low", 10) await async_setup_component( hass, "input_number", { "input_number": { - "low": {"min": 0, "max": 255, "initial": 10}, "high": {"min": 0, "max": 255, "initial": 100}, } }, @@ -1285,7 +1285,7 @@ async def test_numeric_state_using_input_number(hass): "condition": "numeric_state", "entity_id": "sensor.temperature", "below": "input_number.high", - "above": "input_number.low", + "above": "number.low", }, ], }, @@ -1317,10 +1317,10 @@ async def test_numeric_state_using_input_number(hass): ) assert test(hass) - hass.states.async_set("input_number.low", "unknown") + hass.states.async_set("number.low", "unknown") assert not test(hass) - hass.states.async_set("input_number.low", "unavailable") + hass.states.async_set("number.low", "unavailable") assert not test(hass) with pytest.raises(ConditionError):