Fix loop in tod binary sensor (#51491)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
parent
a383198c0c
commit
a3146ad150
2 changed files with 237 additions and 4 deletions
|
@ -156,6 +156,26 @@ class TodSensor(BinarySensorEntity):
|
||||||
self._time_after += self._after_offset
|
self._time_after += self._after_offset
|
||||||
self._time_before += self._before_offset
|
self._time_before += self._before_offset
|
||||||
|
|
||||||
|
def _turn_to_next_day(self):
|
||||||
|
"""Turn to to the next day."""
|
||||||
|
if is_sun_event(self._after):
|
||||||
|
self._time_after = get_astral_event_next(
|
||||||
|
self.hass, self._after, self._time_after - self._after_offset
|
||||||
|
)
|
||||||
|
self._time_after += self._after_offset
|
||||||
|
else:
|
||||||
|
# Offset is already there
|
||||||
|
self._time_after += timedelta(days=1)
|
||||||
|
|
||||||
|
if is_sun_event(self._before):
|
||||||
|
self._time_before = get_astral_event_next(
|
||||||
|
self.hass, self._before, self._time_before - self._before_offset
|
||||||
|
)
|
||||||
|
self._time_before += self._before_offset
|
||||||
|
else:
|
||||||
|
# Offset is already there
|
||||||
|
self._time_before += timedelta(days=1)
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
async def async_added_to_hass(self):
|
||||||
"""Call when entity about to be added to Home Assistant."""
|
"""Call when entity about to be added to Home Assistant."""
|
||||||
self._calculate_boudary_time()
|
self._calculate_boudary_time()
|
||||||
|
@ -182,7 +202,7 @@ class TodSensor(BinarySensorEntity):
|
||||||
if now < self._time_before:
|
if now < self._time_before:
|
||||||
self._next_update = self._time_before
|
self._next_update = self._time_before
|
||||||
return
|
return
|
||||||
self._calculate_boudary_time()
|
self._turn_to_next_day()
|
||||||
self._next_update = self._time_after
|
self._next_update = self._time_after
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
|
|
|
@ -12,6 +12,8 @@ import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
from tests.common import assert_setup_component
|
from tests.common import assert_setup_component
|
||||||
|
|
||||||
|
ORIG_TIMEZONE = dt_util.DEFAULT_TIME_ZONE
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def mock_legacy_time(legacy_patchable_time):
|
def mock_legacy_time(legacy_patchable_time):
|
||||||
|
@ -26,6 +28,13 @@ def setup_fixture(hass):
|
||||||
hass.config.longitude = 18.98583
|
hass.config.longitude = 18.98583
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def restore_timezone(hass):
|
||||||
|
"""Make sure we change timezone."""
|
||||||
|
yield
|
||||||
|
dt_util.set_default_time_zone(ORIG_TIMEZONE)
|
||||||
|
|
||||||
|
|
||||||
async def test_setup(hass):
|
async def test_setup(hass):
|
||||||
"""Test the setup."""
|
"""Test the setup."""
|
||||||
config = {
|
config = {
|
||||||
|
@ -863,6 +872,7 @@ async def test_sun_offset(hass):
|
||||||
async def test_dst(hass):
|
async def test_dst(hass):
|
||||||
"""Test sun event with offset."""
|
"""Test sun event with offset."""
|
||||||
hass.config.time_zone = "CET"
|
hass.config.time_zone = "CET"
|
||||||
|
dt_util.set_default_time_zone(dt_util.get_time_zone("CET"))
|
||||||
test_time = datetime(2019, 3, 30, 3, 0, 0, tzinfo=dt_util.UTC)
|
test_time = datetime(2019, 3, 30, 3, 0, 0, tzinfo=dt_util.UTC)
|
||||||
config = {
|
config = {
|
||||||
"binary_sensor": [
|
"binary_sensor": [
|
||||||
|
@ -882,7 +892,210 @@ async def test_dst(hass):
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state.attributes["after"] == "2019-03-30T03:30:00+01:00"
|
assert state.attributes["after"] == "2019-03-31T03:30:00+02:00"
|
||||||
assert state.attributes["before"] == "2019-03-30T03:40:00+01:00"
|
assert state.attributes["before"] == "2019-03-31T03:40:00+02:00"
|
||||||
assert state.attributes["next_update"] == "2019-03-30T03:30:00+01:00"
|
assert state.attributes["next_update"] == "2019-03-31T03:30:00+02:00"
|
||||||
assert state.state == STATE_OFF
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
|
||||||
|
async def test_simple_before_after_does_not_loop_utc_not_in_range(hass):
|
||||||
|
"""Test simple before after."""
|
||||||
|
hass.config.time_zone = "UTC"
|
||||||
|
dt_util.set_default_time_zone(dt_util.UTC)
|
||||||
|
test_time = datetime(2019, 1, 10, 18, 43, 0, tzinfo=dt_util.UTC)
|
||||||
|
config = {
|
||||||
|
"binary_sensor": [
|
||||||
|
{
|
||||||
|
"platform": "tod",
|
||||||
|
"name": "Night",
|
||||||
|
"before": "06:00",
|
||||||
|
"after": "22:00",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.tod.binary_sensor.dt_util.utcnow",
|
||||||
|
return_value=test_time,
|
||||||
|
):
|
||||||
|
await async_setup_component(hass, "binary_sensor", config)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("binary_sensor.night")
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
assert state.attributes["after"] == "2019-01-10T22:00:00+00:00"
|
||||||
|
assert state.attributes["before"] == "2019-01-11T06:00:00+00:00"
|
||||||
|
assert state.attributes["next_update"] == "2019-01-10T22:00:00+00:00"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_simple_before_after_does_not_loop_utc_in_range(hass):
|
||||||
|
"""Test simple before after."""
|
||||||
|
hass.config.time_zone = "UTC"
|
||||||
|
dt_util.set_default_time_zone(dt_util.UTC)
|
||||||
|
test_time = datetime(2019, 1, 10, 22, 43, 0, tzinfo=dt_util.UTC)
|
||||||
|
config = {
|
||||||
|
"binary_sensor": [
|
||||||
|
{
|
||||||
|
"platform": "tod",
|
||||||
|
"name": "Night",
|
||||||
|
"before": "06:00",
|
||||||
|
"after": "22:00",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.tod.binary_sensor.dt_util.utcnow",
|
||||||
|
return_value=test_time,
|
||||||
|
):
|
||||||
|
await async_setup_component(hass, "binary_sensor", config)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("binary_sensor.night")
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
assert state.attributes["after"] == "2019-01-10T22:00:00+00:00"
|
||||||
|
assert state.attributes["before"] == "2019-01-11T06:00:00+00:00"
|
||||||
|
assert state.attributes["next_update"] == "2019-01-11T06:00:00+00:00"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_simple_before_after_does_not_loop_utc_fire_at_before(hass):
|
||||||
|
"""Test simple before after."""
|
||||||
|
hass.config.time_zone = "UTC"
|
||||||
|
dt_util.set_default_time_zone(dt_util.UTC)
|
||||||
|
test_time = datetime(2019, 1, 11, 6, 0, 0, tzinfo=dt_util.UTC)
|
||||||
|
config = {
|
||||||
|
"binary_sensor": [
|
||||||
|
{
|
||||||
|
"platform": "tod",
|
||||||
|
"name": "Night",
|
||||||
|
"before": "06:00",
|
||||||
|
"after": "22:00",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.tod.binary_sensor.dt_util.utcnow",
|
||||||
|
return_value=test_time,
|
||||||
|
):
|
||||||
|
await async_setup_component(hass, "binary_sensor", config)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("binary_sensor.night")
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
assert state.attributes["after"] == "2019-01-11T22:00:00+00:00"
|
||||||
|
assert state.attributes["before"] == "2019-01-12T06:00:00+00:00"
|
||||||
|
assert state.attributes["next_update"] == "2019-01-11T22:00:00+00:00"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_simple_before_after_does_not_loop_utc_fire_at_after(hass):
|
||||||
|
"""Test simple before after."""
|
||||||
|
hass.config.time_zone = "UTC"
|
||||||
|
dt_util.set_default_time_zone(dt_util.UTC)
|
||||||
|
test_time = datetime(2019, 1, 10, 22, 0, 0, tzinfo=dt_util.UTC)
|
||||||
|
config = {
|
||||||
|
"binary_sensor": [
|
||||||
|
{
|
||||||
|
"platform": "tod",
|
||||||
|
"name": "Night",
|
||||||
|
"before": "06:00",
|
||||||
|
"after": "22:00",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.tod.binary_sensor.dt_util.utcnow",
|
||||||
|
return_value=test_time,
|
||||||
|
):
|
||||||
|
await async_setup_component(hass, "binary_sensor", config)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("binary_sensor.night")
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
assert state.attributes["after"] == "2019-01-10T22:00:00+00:00"
|
||||||
|
assert state.attributes["before"] == "2019-01-11T06:00:00+00:00"
|
||||||
|
assert state.attributes["next_update"] == "2019-01-11T06:00:00+00:00"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_simple_before_after_does_not_loop_utc_both_before_now(hass):
|
||||||
|
"""Test simple before after."""
|
||||||
|
hass.config.time_zone = "UTC"
|
||||||
|
dt_util.set_default_time_zone(dt_util.UTC)
|
||||||
|
test_time = datetime(2019, 1, 10, 22, 0, 0, tzinfo=dt_util.UTC)
|
||||||
|
config = {
|
||||||
|
"binary_sensor": [
|
||||||
|
{
|
||||||
|
"platform": "tod",
|
||||||
|
"name": "Morning",
|
||||||
|
"before": "08:00",
|
||||||
|
"after": "00:00",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.tod.binary_sensor.dt_util.utcnow",
|
||||||
|
return_value=test_time,
|
||||||
|
):
|
||||||
|
await async_setup_component(hass, "binary_sensor", config)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("binary_sensor.morning")
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
assert state.attributes["after"] == "2019-01-11T00:00:00+00:00"
|
||||||
|
assert state.attributes["before"] == "2019-01-11T08:00:00+00:00"
|
||||||
|
assert state.attributes["next_update"] == "2019-01-11T00:00:00+00:00"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_simple_before_after_does_not_loop_berlin_not_in_range(hass):
|
||||||
|
"""Test simple before after."""
|
||||||
|
hass.config.time_zone = "Europe/Berlin"
|
||||||
|
dt_util.set_default_time_zone(dt_util.get_time_zone("Europe/Berlin"))
|
||||||
|
test_time = datetime(2019, 1, 10, 18, 43, 0, tzinfo=dt_util.UTC)
|
||||||
|
config = {
|
||||||
|
"binary_sensor": [
|
||||||
|
{
|
||||||
|
"platform": "tod",
|
||||||
|
"name": "Dark",
|
||||||
|
"before": "06:00",
|
||||||
|
"after": "00:00",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.tod.binary_sensor.dt_util.utcnow",
|
||||||
|
return_value=test_time,
|
||||||
|
):
|
||||||
|
await async_setup_component(hass, "binary_sensor", config)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("binary_sensor.dark")
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
assert state.attributes["after"] == "2019-01-11T00:00:00+01:00"
|
||||||
|
assert state.attributes["before"] == "2019-01-11T06:00:00+01:00"
|
||||||
|
assert state.attributes["next_update"] == "2019-01-11T00:00:00+01:00"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_simple_before_after_does_not_loop_berlin_in_range(hass):
|
||||||
|
"""Test simple before after."""
|
||||||
|
hass.config.time_zone = "Europe/Berlin"
|
||||||
|
dt_util.set_default_time_zone(dt_util.get_time_zone("Europe/Berlin"))
|
||||||
|
test_time = datetime(2019, 1, 10, 23, 43, 0, tzinfo=dt_util.UTC)
|
||||||
|
config = {
|
||||||
|
"binary_sensor": [
|
||||||
|
{
|
||||||
|
"platform": "tod",
|
||||||
|
"name": "Dark",
|
||||||
|
"before": "06:00",
|
||||||
|
"after": "00:00",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.tod.binary_sensor.dt_util.utcnow",
|
||||||
|
return_value=test_time,
|
||||||
|
):
|
||||||
|
await async_setup_component(hass, "binary_sensor", config)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("binary_sensor.dark")
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
assert state.attributes["after"] == "2019-01-11T00:00:00+01:00"
|
||||||
|
assert state.attributes["before"] == "2019-01-11T06:00:00+01:00"
|
||||||
|
assert state.attributes["next_update"] == "2019-01-11T06:00:00+01:00"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue