Do not trigger when numeric_state is true at startup (#46424)

This commit is contained in:
Anders Melchiorsen 2021-02-20 09:11:36 +01:00 committed by GitHub
parent b775a0d796
commit 26ce316c18
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 175 additions and 33 deletions

View file

@ -10,7 +10,12 @@ import homeassistant.components.automation as automation
from homeassistant.components.homeassistant.triggers import (
numeric_state as numeric_state_trigger,
)
from homeassistant.const import ATTR_ENTITY_ID, ENTITY_MATCH_ALL, SERVICE_TURN_OFF
from homeassistant.const import (
ATTR_ENTITY_ID,
ENTITY_MATCH_ALL,
SERVICE_TURN_OFF,
STATE_UNAVAILABLE,
)
from homeassistant.core import Context
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
@ -241,7 +246,7 @@ async def test_if_not_below_fires_on_entity_change_to_equal(hass, calls, below):
@pytest.mark.parametrize("below", (10, "input_number.value_10"))
async def test_if_fires_on_initial_entity_below(hass, calls, below):
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)
await hass.async_block_till_done()
@ -261,14 +266,14 @@ async def test_if_fires_on_initial_entity_below(hass, calls, below):
},
)
# Fire on first update even if initial state was already below
# Do not fire on first update when initial state was already below
hass.states.async_set("test.entity", 8)
await hass.async_block_till_done()
assert len(calls) == 1
assert len(calls) == 0
@pytest.mark.parametrize("above", (10, "input_number.value_10"))
async def test_if_fires_on_initial_entity_above(hass, calls, above):
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)
await hass.async_block_till_done()
@ -288,10 +293,10 @@ async def test_if_fires_on_initial_entity_above(hass, calls, above):
},
)
# Fire on first update even if initial state was already above
# Do not fire on first update when initial state was already above
hass.states.async_set("test.entity", 12)
await hass.async_block_till_done()
assert len(calls) == 1
assert len(calls) == 0
@pytest.mark.parametrize("above", (10, "input_number.value_10"))
@ -320,6 +325,74 @@ async def test_if_fires_on_entity_change_above(hass, calls, above):
assert len(calls) == 1
async def test_if_fires_on_entity_unavailable_at_startup(hass, calls):
"""Test the firing with changed entity at startup."""
assert await async_setup_component(
hass,
automation.DOMAIN,
{
automation.DOMAIN: {
"trigger": {
"platform": "numeric_state",
"entity_id": "test.entity",
"above": 10,
},
"action": {"service": "test.automation"},
}
},
)
# 11 is above 10
hass.states.async_set("test.entity", 11)
await hass.async_block_till_done()
assert len(calls) == 0
async def test_if_not_fires_on_entity_unavailable(hass, calls):
"""Test the firing with entity changing to unavailable."""
# set initial state
hass.states.async_set("test.entity", 9)
await hass.async_block_till_done()
assert await async_setup_component(
hass,
automation.DOMAIN,
{
automation.DOMAIN: {
"trigger": {
"platform": "numeric_state",
"entity_id": "test.entity",
"above": 10,
},
"action": {"service": "test.automation"},
}
},
)
# 11 is above 10
hass.states.async_set("test.entity", 11)
await hass.async_block_till_done()
assert len(calls) == 1
# Going to unavailable and back should not fire
hass.states.async_set("test.entity", STATE_UNAVAILABLE)
await hass.async_block_till_done()
assert len(calls) == 1
hass.states.async_set("test.entity", 11)
await hass.async_block_till_done()
assert len(calls) == 1
# Crossing threshold via unavailable should fire
hass.states.async_set("test.entity", 9)
await hass.async_block_till_done()
assert len(calls) == 1
hass.states.async_set("test.entity", STATE_UNAVAILABLE)
await hass.async_block_till_done()
assert len(calls) == 1
hass.states.async_set("test.entity", 11)
await hass.async_block_till_done()
assert len(calls) == 2
@pytest.mark.parametrize("above", (10, "input_number.value_10"))
async def test_if_fires_on_entity_change_below_to_above(hass, calls, above):
"""Test the firing with changed entity."""
@ -1449,6 +1522,48 @@ async def test_if_fires_on_change_with_for_template_3(hass, calls, above, below)
assert len(calls) == 1
async def test_if_not_fires_on_error_with_for_template(hass, caplog, calls):
"""Test for not firing on error with for template."""
hass.states.async_set("test.entity", 0)
await hass.async_block_till_done()
assert await async_setup_component(
hass,
automation.DOMAIN,
{
automation.DOMAIN: {
"trigger": {
"platform": "numeric_state",
"entity_id": "test.entity",
"above": 100,
"for": "00:00:05",
},
"action": {"service": "test.automation"},
}
},
)
hass.states.async_set("test.entity", 101)
await hass.async_block_till_done()
assert len(calls) == 0
caplog.clear()
caplog.set_level(logging.WARNING)
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=3))
hass.states.async_set("test.entity", "unavailable")
await hass.async_block_till_done()
assert len(calls) == 0
assert len(caplog.record_tuples) == 1
assert caplog.record_tuples[0][1] == logging.WARNING
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=3))
hass.states.async_set("test.entity", 101)
await hass.async_block_till_done()
assert len(calls) == 0
@pytest.mark.parametrize(
"above, below",
(