core/tests/components/sun/test_init.py

197 lines
6.0 KiB
Python
Raw Normal View History

2016-03-09 09:25:50 +00:00
"""The tests for the Sun component."""
from datetime import datetime, timedelta
2021-01-01 21:31:56 +00:00
from unittest.mock import patch
2014-11-25 07:15:14 +00:00
from pytest import mark
import homeassistant.components.sun as sun
from homeassistant.const import EVENT_STATE_CHANGED
import homeassistant.core as ha
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
async def test_setting_rising(hass, legacy_patchable_time):
"""Test retrieving sun setting and rising."""
utc_now = datetime(2016, 11, 1, 8, 0, 0, tzinfo=dt_util.UTC)
2019-07-31 19:25:30 +00:00
with patch("homeassistant.helpers.condition.dt_util.utcnow", return_value=utc_now):
await async_setup_component(
hass, sun.DOMAIN, {sun.DOMAIN: {sun.CONF_ELEVATION: 0}}
)
await hass.async_block_till_done()
state = hass.states.get(sun.ENTITY_ID)
2021-04-01 22:29:08 +00:00
from astral import LocationInfo
import astral.sun
utc_today = utc_now.date()
2021-04-01 22:29:08 +00:00
location = LocationInfo(
latitude=hass.config.latitude, longitude=hass.config.longitude
)
mod = -1
while True:
2021-04-01 22:29:08 +00:00
next_dawn = astral.sun.dawn(
location.observer, date=utc_today + timedelta(days=mod)
2019-07-31 19:25:30 +00:00
)
if next_dawn > utc_now:
break
mod += 1
mod = -1
while True:
2021-04-01 22:29:08 +00:00
next_dusk = astral.sun.dusk(
location.observer, date=utc_today + timedelta(days=mod)
2019-07-31 19:25:30 +00:00
)
if next_dusk > utc_now:
break
mod += 1
mod = -1
while True:
2021-04-01 22:29:08 +00:00
next_midnight = astral.sun.midnight(
location.observer, date=utc_today + timedelta(days=mod)
2019-07-31 19:25:30 +00:00
)
if next_midnight > utc_now:
break
mod += 1
mod = -1
while True:
2021-04-01 22:29:08 +00:00
next_noon = astral.sun.noon(
location.observer, date=utc_today + timedelta(days=mod)
)
if next_noon > utc_now:
break
mod += 1
mod = -1
while True:
2021-04-01 22:29:08 +00:00
next_rising = astral.sun.sunrise(
location.observer, date=utc_today + timedelta(days=mod)
2019-07-31 19:25:30 +00:00
)
if next_rising > utc_now:
break
mod += 1
mod = -1
while True:
2021-04-01 22:29:08 +00:00
next_setting = astral.sun.sunset(
location.observer, date=utc_today + timedelta(days=mod)
2019-07-31 19:25:30 +00:00
)
if next_setting > utc_now:
break
mod += 1
assert next_dawn == dt_util.parse_datetime(
2019-07-31 19:25:30 +00:00
state.attributes[sun.STATE_ATTR_NEXT_DAWN]
)
assert next_dusk == dt_util.parse_datetime(
2019-07-31 19:25:30 +00:00
state.attributes[sun.STATE_ATTR_NEXT_DUSK]
)
assert next_midnight == dt_util.parse_datetime(
2019-07-31 19:25:30 +00:00
state.attributes[sun.STATE_ATTR_NEXT_MIDNIGHT]
)
assert next_noon == dt_util.parse_datetime(
2019-07-31 19:25:30 +00:00
state.attributes[sun.STATE_ATTR_NEXT_NOON]
)
assert next_rising == dt_util.parse_datetime(
2019-07-31 19:25:30 +00:00
state.attributes[sun.STATE_ATTR_NEXT_RISING]
)
assert next_setting == dt_util.parse_datetime(
2019-07-31 19:25:30 +00:00
state.attributes[sun.STATE_ATTR_NEXT_SETTING]
)
async def test_state_change(hass, legacy_patchable_time):
"""Test if the state changes at next setting/rising."""
now = datetime(2016, 6, 1, 8, 0, 0, tzinfo=dt_util.UTC)
2019-07-31 19:25:30 +00:00
with patch("homeassistant.helpers.condition.dt_util.utcnow", return_value=now):
await async_setup_component(
hass, sun.DOMAIN, {sun.DOMAIN: {sun.CONF_ELEVATION: 0}}
)
await hass.async_block_till_done()
test_time = dt_util.parse_datetime(
2019-07-31 19:25:30 +00:00
hass.states.get(sun.ENTITY_ID).attributes[sun.STATE_ATTR_NEXT_RISING]
)
assert test_time is not None
2019-07-31 19:25:30 +00:00
assert sun.STATE_BELOW_HORIZON == hass.states.get(sun.ENTITY_ID).state
patched_time = test_time + timedelta(seconds=5)
with patch(
"homeassistant.helpers.condition.dt_util.utcnow", return_value=patched_time
):
hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: patched_time})
await hass.async_block_till_done()
2019-07-31 19:25:30 +00:00
assert sun.STATE_ABOVE_HORIZON == hass.states.get(sun.ENTITY_ID).state
2019-07-31 19:25:30 +00:00
with patch("homeassistant.helpers.condition.dt_util.utcnow", return_value=now):
await hass.config.async_update(longitude=hass.config.longitude + 90)
2019-06-08 06:21:41 +00:00
await hass.async_block_till_done()
2019-07-31 19:25:30 +00:00
assert sun.STATE_ABOVE_HORIZON == hass.states.get(sun.ENTITY_ID).state
2019-06-08 06:21:41 +00:00
async def test_norway_in_june(hass):
"""Test location in Norway where the sun doesn't set in summer."""
hass.config.latitude = 69.6
hass.config.longitude = 18.8
june = datetime(2016, 6, 1, tzinfo=dt_util.UTC)
2019-07-31 19:25:30 +00:00
with patch("homeassistant.helpers.condition.dt_util.utcnow", return_value=june):
assert await async_setup_component(
hass, sun.DOMAIN, {sun.DOMAIN: {sun.CONF_ELEVATION: 0}}
)
state = hass.states.get(sun.ENTITY_ID)
assert state is not None
assert dt_util.parse_datetime(
2019-07-31 19:25:30 +00:00
state.attributes[sun.STATE_ATTR_NEXT_RISING]
2021-04-01 22:29:08 +00:00
) == datetime(2016, 7, 24, 22, 59, 45, 689645, tzinfo=dt_util.UTC)
assert dt_util.parse_datetime(
2019-07-31 19:25:30 +00:00
state.attributes[sun.STATE_ATTR_NEXT_SETTING]
2021-04-01 22:29:08 +00:00
) == datetime(2016, 7, 25, 22, 17, 13, 503932, tzinfo=dt_util.UTC)
2019-06-08 06:21:41 +00:00
assert state.state == sun.STATE_ABOVE_HORIZON
@mark.skip
async def test_state_change_count(hass):
"""Count the number of state change events in a location."""
# Skipped because it's a bit slow. Has been validated with
# multiple lattitudes and dates
hass.config.latitude = 10
hass.config.longitude = 0
now = datetime(2016, 6, 1, tzinfo=dt_util.UTC)
2019-07-31 19:25:30 +00:00
with patch("homeassistant.helpers.condition.dt_util.utcnow", return_value=now):
assert await async_setup_component(
hass, sun.DOMAIN, {sun.DOMAIN: {sun.CONF_ELEVATION: 0}}
)
events = []
2019-07-31 19:25:30 +00:00
@ha.callback
def state_change_listener(event):
2019-07-31 19:25:30 +00:00
if event.data.get("entity_id") == "sun.sun":
events.append(event)
2019-07-31 19:25:30 +00:00
hass.bus.async_listen(EVENT_STATE_CHANGED, state_change_listener)
await hass.async_block_till_done()
2019-07-31 19:25:30 +00:00
for _ in range(24 * 60 * 60):
now += timedelta(seconds=1)
2019-07-31 19:25:30 +00:00
hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: now})
await hass.async_block_till_done()
assert len(events) < 721