diff --git a/homeassistant/components/homeassistant/triggers/state.py b/homeassistant/components/homeassistant/triggers/state.py index dad7314f4fa..0fa7a98b562 100644 --- a/homeassistant/components/homeassistant/triggers/state.py +++ b/homeassistant/components/homeassistant/triggers/state.py @@ -25,22 +25,16 @@ CONF_ENTITY_ID = "entity_id" CONF_FROM = "from" CONF_TO = "to" -TRIGGER_SCHEMA = vol.All( - vol.Schema( - { - vol.Required(CONF_PLATFORM): "state", - vol.Required(CONF_ENTITY_ID): cv.entity_ids, - # These are str on purpose. Want to catch YAML conversions - vol.Optional(CONF_FROM): vol.Any(str, [str]), - vol.Optional(CONF_TO): vol.Any(str, [str]), - vol.Optional(CONF_FOR): cv.positive_time_period_template, - vol.Optional(CONF_ATTRIBUTE): cv.match_all, - } - ), - vol.Any( - cv.key_dependency(CONF_FOR, CONF_TO), - cv.key_dependency(CONF_FOR, CONF_FROM), - ), +TRIGGER_SCHEMA = vol.Schema( + { + vol.Required(CONF_PLATFORM): "state", + vol.Required(CONF_ENTITY_ID): cv.entity_ids, + # These are str on purpose. Want to catch YAML conversions + vol.Optional(CONF_FROM): vol.Any(str, [str]), + vol.Optional(CONF_TO): vol.Any(str, [str]), + vol.Optional(CONF_FOR): cv.positive_time_period_template, + vol.Optional(CONF_ATTRIBUTE): cv.match_all, + } ) diff --git a/tests/components/homeassistant/triggers/test_state.py b/tests/components/homeassistant/triggers/test_state.py index 0ae7c340ea8..68ce907bdae 100644 --- a/tests/components/homeassistant/triggers/test_state.py +++ b/tests/components/homeassistant/triggers/test_state.py @@ -334,25 +334,6 @@ async def test_if_fails_setup_bad_for(hass, calls): assert mock_logger.error.called -async def test_if_fails_setup_for_without_to(hass, calls): - """Test for setup failures for missing to.""" - with assert_setup_component(0, automation.DOMAIN): - assert await async_setup_component( - hass, - automation.DOMAIN, - { - automation.DOMAIN: { - "trigger": { - "platform": "state", - "entity_id": "test.entity", - "for": {"seconds": 5}, - }, - "action": {"service": "homeassistant.turn_on"}, - } - }, - ) - - async def test_if_not_fires_on_entity_change_with_for(hass, calls): """Test for not firing on entity change with for.""" assert await async_setup_component( @@ -520,6 +501,43 @@ async def test_if_fires_on_entity_change_with_for(hass, calls): assert 1 == len(calls) +async def test_if_fires_on_entity_change_with_for_without_to(hass, calls): + """Test for firing on entity change with for.""" + assert await async_setup_component( + hass, + automation.DOMAIN, + { + automation.DOMAIN: { + "trigger": { + "platform": "state", + "entity_id": "test.entity", + "for": {"seconds": 5}, + }, + "action": {"service": "test.automation"}, + } + }, + ) + await hass.async_block_till_done() + + hass.states.async_set("test.entity", "hello") + await hass.async_block_till_done() + + async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=2)) + await hass.async_block_till_done() + assert len(calls) == 0 + + hass.states.async_set("test.entity", "world") + await hass.async_block_till_done() + + async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=4)) + await hass.async_block_till_done() + assert len(calls) == 0 + + async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=10)) + await hass.async_block_till_done() + assert len(calls) == 1 + + async def test_if_fires_on_entity_creation_and_removal(hass, calls): """Test for firing on entity creation and removal, with to/from constraints.""" # set automations for multiple combinations to/from