Time condition can also accept an input_datetime Entity ID (#39676)

This commit is contained in:
Franck Nijhof 2020-09-06 16:06:09 +02:00 committed by GitHub
parent f298281ec4
commit da9b077c11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 124 additions and 13 deletions

View File

@ -437,8 +437,9 @@ def async_template_from_config(
def time(
before: Optional[dt_util.dt.time] = None,
after: Optional[dt_util.dt.time] = None,
hass: HomeAssistant,
before: Optional[Union[dt_util.dt.time, str]] = None,
after: Optional[Union[dt_util.dt.time, str]] = None,
weekday: Union[None, str, Container[str]] = None,
) -> bool:
"""Test if local time condition matches.
@ -453,8 +454,28 @@ def time(
if after is None:
after = dt_util.dt.time(0)
elif isinstance(after, str):
after_entity = hass.states.get(after)
if not after_entity:
return False
after = dt_util.dt.time(
after_entity.attributes.get("hour", 23),
after_entity.attributes.get("minute", 59),
after_entity.attributes.get("second", 59),
)
if before is None:
before = dt_util.dt.time(23, 59, 59, 999999)
elif isinstance(before, str):
before_entity = hass.states.get(before)
if not before_entity:
return False
before = dt_util.dt.time(
before_entity.attributes.get("hour", 23),
before_entity.attributes.get("minute", 59),
before_entity.attributes.get("second", 59),
999999,
)
if after < before:
if not after <= now_time < before:
@ -488,7 +509,7 @@ def time_from_config(
def time_if(hass: HomeAssistant, variables: TemplateVarsType = None) -> bool:
"""Validate time based if-condition."""
return time(before, after, weekday)
return time(hass, before, after, weekday)
return time_if

View File

@ -956,8 +956,8 @@ TIME_CONDITION_SCHEMA = vol.All(
vol.Schema(
{
vol.Required(CONF_CONDITION): "time",
"before": time,
"after": time,
"before": vol.Any(time, vol.All(str, entity_domain("input_datetime"))),
"after": vol.Any(time, vol.All(str, entity_domain("input_datetime"))),
"weekday": weekdays,
}
),

View File

@ -5,6 +5,7 @@ import pytest
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import condition
from homeassistant.setup import async_setup_component
from homeassistant.util import dt
from tests.async_mock import patch
@ -226,29 +227,118 @@ async def test_time_window(hass):
"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)
assert not condition.time(hass, after=sixam, before=sixpm)
assert condition.time(hass, 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)
assert condition.time(hass, after=sixam, before=sixpm)
assert not condition.time(hass, 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)
assert condition.time(hass, after=sixam, before=sixpm)
assert not condition.time(hass, 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)
assert not condition.time(hass, after=sixam, before=sixpm)
assert condition.time(hass, after=sixpm, before=sixam)
async def test_time_using_input_datetime(hass):
"""Test time conditions using input_datetime entities."""
await async_setup_component(
hass,
"input_datetime",
{
"input_datetime": {
"am": {"has_date": True, "has_time": True},
"pm": {"has_date": True, "has_time": True},
}
},
)
await hass.services.async_call(
"input_datetime",
"set_datetime",
{
"entity_id": "input_datetime.am",
"datetime": str(
dt.now()
.replace(hour=6, minute=0, second=0, microsecond=0)
.replace(tzinfo=None)
),
},
blocking=True,
)
await hass.services.async_call(
"input_datetime",
"set_datetime",
{
"entity_id": "input_datetime.pm",
"datetime": str(
dt.now()
.replace(hour=18, minute=0, second=0, microsecond=0)
.replace(tzinfo=None)
),
},
blocking=True,
)
with patch(
"homeassistant.helpers.condition.dt_util.now",
return_value=dt.now().replace(hour=3),
):
assert not condition.time(
hass, after="input_datetime.am", before="input_datetime.pm"
)
assert condition.time(
hass, after="input_datetime.pm", before="input_datetime.am"
)
with patch(
"homeassistant.helpers.condition.dt_util.now",
return_value=dt.now().replace(hour=9),
):
assert condition.time(
hass, after="input_datetime.am", before="input_datetime.pm"
)
assert not condition.time(
hass, after="input_datetime.pm", before="input_datetime.am"
)
with patch(
"homeassistant.helpers.condition.dt_util.now",
return_value=dt.now().replace(hour=15),
):
assert condition.time(
hass, after="input_datetime.am", before="input_datetime.pm"
)
assert not condition.time(
hass, after="input_datetime.pm", before="input_datetime.am"
)
with patch(
"homeassistant.helpers.condition.dt_util.now",
return_value=dt.now().replace(hour=21),
):
assert not condition.time(
hass, after="input_datetime.am", before="input_datetime.pm"
)
assert condition.time(
hass, after="input_datetime.pm", before="input_datetime.am"
)
assert not condition.time(hass, after="input_datetime.not_existing")
assert not condition.time(hass, before="input_datetime.not_existing")
async def test_if_numeric_state_not_raise_on_unavailable(hass):