Fix time trigger based on entities ignoring entities if initially in the past (#43431)

pull/43439/head
Paulus Schoutsen 2020-11-20 15:43:28 +01:00 committed by GitHub
parent 82b7cc8ac7
commit bbb82ded68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 96 additions and 3 deletions

View File

@ -143,9 +143,12 @@ async def async_attach_trigger(hass, config, action, automation_info):
if remove:
entities[entity_id] = remove
to_track = []
for at_time in config[CONF_AT]:
if isinstance(at_time, str):
# entity
to_track.append(at_time)
update_entity_trigger(at_time, new_state=hass.states.get(at_time))
else:
# datetime.time
@ -161,9 +164,7 @@ async def async_attach_trigger(hass, config, action, automation_info):
# Track state changes of any entities.
removes.append(
async_track_state_change_event(
hass, list(entities), update_entity_trigger_event
)
async_track_state_change_event(hass, to_track, update_entity_trigger_event)
)
@callback

View File

@ -2,8 +2,10 @@
from datetime import timedelta
import pytest
import voluptuous as vol
from homeassistant.components import automation, sensor
from homeassistant.components.homeassistant.triggers import time
from homeassistant.const import ATTR_DEVICE_CLASS, ATTR_ENTITY_ID, SERVICE_TURN_OFF
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
@ -492,3 +494,93 @@ async def test_if_fires_using_at_sensor(hass, calls):
# We should not have listened to anything
assert len(calls) == 2
@pytest.mark.parametrize(
"conf",
[
{"platform": "time", "at": "input_datetime.bla"},
{"platform": "time", "at": "sensor.bla"},
{"platform": "time", "at": "12:34"},
],
)
def test_schema_valid(conf):
"""Make sure we don't accept number for 'at' value."""
time.TRIGGER_SCHEMA(conf)
@pytest.mark.parametrize(
"conf",
[
{"platform": "time", "at": "binary_sensor.bla"},
{"platform": "time", "at": 745},
{"platform": "time", "at": "25:00"},
],
)
def test_schema_invalid(conf):
"""Make sure we don't accept number for 'at' value."""
with pytest.raises(vol.Invalid):
time.TRIGGER_SCHEMA(conf)
async def test_datetime_in_past_on_load(hass, calls):
"""Test time trigger works if input_datetime is in past."""
await async_setup_component(
hass,
"input_datetime",
{"input_datetime": {"my_trigger": {"has_date": True, "has_time": True}}},
)
now = dt_util.now()
past = now - timedelta(days=2)
future = now + timedelta(days=1)
await hass.services.async_call(
"input_datetime",
"set_datetime",
{
ATTR_ENTITY_ID: "input_datetime.my_trigger",
"datetime": str(past.replace(tzinfo=None)),
},
blocking=True,
)
assert await async_setup_component(
hass,
automation.DOMAIN,
{
automation.DOMAIN: {
"trigger": {"platform": "time", "at": "input_datetime.my_trigger"},
"action": {
"service": "test.automation",
"data_template": {
"some": "{{ trigger.platform }}-{{ trigger.now.day }}-{{ trigger.now.hour }}-{{trigger.entity_id}}"
},
},
}
},
)
async_fire_time_changed(hass, now)
await hass.async_block_till_done()
assert len(calls) == 0
await hass.services.async_call(
"input_datetime",
"set_datetime",
{
ATTR_ENTITY_ID: "input_datetime.my_trigger",
"datetime": str(future.replace(tzinfo=None)),
},
blocking=True,
)
async_fire_time_changed(hass, future + timedelta(seconds=1))
await hass.async_block_till_done()
assert len(calls) == 1
assert (
calls[0].data["some"]
== f"time-{future.day}-{future.hour}-input_datetime.my_trigger"
)