Support time entities in time conditions (#124575)

Co-authored-by: Mark Bergsma <mark@wikked.net>
This commit is contained in:
Simon Lamon 2024-11-26 15:37:31 +01:00 committed by GitHub
parent 147679f803
commit ee74a35417
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 99 additions and 8 deletions

View File

@ -821,9 +821,15 @@ def time(
after_entity.attributes.get("minute", 59),
after_entity.attributes.get("second", 59),
)
elif after_entity.attributes.get(
ATTR_DEVICE_CLASS
) == SensorDeviceClass.TIMESTAMP and after_entity.state not in (
elif after_entity.domain == "time" and after_entity.state not in (
STATE_UNAVAILABLE,
STATE_UNKNOWN,
):
after = datetime.strptime(after_entity.state, "%H:%M:%S").time()
elif (
after_entity.attributes.get(ATTR_DEVICE_CLASS)
== SensorDeviceClass.TIMESTAMP
) and after_entity.state not in (
STATE_UNAVAILABLE,
STATE_UNKNOWN,
):
@ -845,9 +851,15 @@ def time(
before_entity.attributes.get("minute", 59),
before_entity.attributes.get("second", 59),
)
elif before_entity.attributes.get(
ATTR_DEVICE_CLASS
) == SensorDeviceClass.TIMESTAMP and before_entity.state not in (
elif before_entity.domain == "time":
try:
before = datetime.strptime(before_entity.state, "%H:%M:%S").time()
except ValueError:
return False
elif (
before_entity.attributes.get(ATTR_DEVICE_CLASS)
== SensorDeviceClass.TIMESTAMP
) and before_entity.state not in (
STATE_UNAVAILABLE,
STATE_UNKNOWN,
):

View File

@ -1574,10 +1574,10 @@ TIME_CONDITION_SCHEMA = vol.All(
**CONDITION_BASE_SCHEMA,
vol.Required(CONF_CONDITION): "time",
vol.Optional("before"): vol.Any(
time, vol.All(str, entity_domain(["input_datetime", "sensor"]))
time, vol.All(str, entity_domain(["input_datetime", "time", "sensor"]))
),
vol.Optional("after"): vol.Any(
time, vol.All(str, entity_domain(["input_datetime", "sensor"]))
time, vol.All(str, entity_domain(["input_datetime", "time", "sensor"]))
),
vol.Optional("weekday"): weekdays,
}

View File

@ -15,6 +15,8 @@ from homeassistant.const import (
CONF_CONDITION,
CONF_DEVICE_ID,
CONF_DOMAIN,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
SUN_EVENT_SUNRISE,
SUN_EVENT_SUNSET,
)
@ -992,6 +994,83 @@ async def test_time_using_input_datetime(hass: HomeAssistant) -> None:
condition.time(hass, before="input_datetime.not_existing")
async def test_time_using_time(hass: HomeAssistant) -> None:
"""Test time conditions using time entities."""
hass.states.async_set(
"time.am",
"06:00:00", # 6 am local time
)
hass.states.async_set(
"time.pm",
"18:00:00", # 6 pm local time
)
hass.states.async_set(
"time.unknown_state",
STATE_UNKNOWN,
)
hass.states.async_set(
"time.unavailable_state",
STATE_UNAVAILABLE,
)
with patch(
"homeassistant.helpers.condition.dt_util.now",
return_value=dt_util.now().replace(hour=3),
):
assert not condition.time(hass, after="time.am", before="time.pm")
assert condition.time(hass, after="time.pm", before="time.am")
with patch(
"homeassistant.helpers.condition.dt_util.now",
return_value=dt_util.now().replace(hour=9),
):
assert condition.time(hass, after="time.am", before="time.pm")
assert not condition.time(hass, after="time.pm", before="time.am")
with patch(
"homeassistant.helpers.condition.dt_util.now",
return_value=dt_util.now().replace(hour=15),
):
assert condition.time(hass, after="time.am", before="time.pm")
assert not condition.time(hass, after="time.pm", before="time.am")
with patch(
"homeassistant.helpers.condition.dt_util.now",
return_value=dt_util.now().replace(hour=21),
):
assert not condition.time(hass, after="time.am", before="time.pm")
assert condition.time(hass, after="time.pm", before="time.am")
# Trigger on PM time
with patch(
"homeassistant.helpers.condition.dt_util.now",
return_value=dt_util.now().replace(hour=18, minute=0, second=0),
):
assert condition.time(hass, after="time.pm", before="time.am")
assert not condition.time(hass, after="time.am", before="time.pm")
assert condition.time(hass, after="time.pm")
assert not condition.time(hass, before="time.pm")
# Trigger on AM time
with patch(
"homeassistant.helpers.condition.dt_util.now",
return_value=dt_util.now().replace(hour=6, minute=0, second=0),
):
assert not condition.time(hass, after="time.pm", before="time.am")
assert condition.time(hass, after="time.am", before="time.pm")
assert condition.time(hass, after="time.am")
assert not condition.time(hass, before="time.am")
assert not condition.time(hass, after="time.unknown_state")
assert not condition.time(hass, before="time.unavailable_state")
with pytest.raises(ConditionError):
condition.time(hass, after="time.not_existing")
with pytest.raises(ConditionError):
condition.time(hass, before="time.not_existing")
async def test_time_using_sensor(hass: HomeAssistant) -> None:
"""Test time conditions using sensor entities."""
hass.states.async_set(