core/tests/components/sun/test_sensor.py

228 lines
8.0 KiB
Python

"""The tests for the Sun sensor platform."""
from datetime import datetime, timedelta
from astral import LocationInfo
import astral.sun
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components import sun
from homeassistant.config_entries import RELOAD_AFTER_UPDATE_DELAY
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er, issue_registry as ir
from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util
from tests.common import async_fire_time_changed
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_setting_rising(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test retrieving sun setting and rising."""
utc_now = datetime(2016, 11, 1, 8, 0, 0, tzinfo=dt_util.UTC)
freezer.move_to(utc_now)
await async_setup_component(hass, sun.DOMAIN, {sun.DOMAIN: {}})
await hass.async_block_till_done()
utc_today = utc_now.date()
location = LocationInfo(
latitude=hass.config.latitude, longitude=hass.config.longitude
)
mod = -1
while True:
next_dawn = astral.sun.dawn(
location.observer, date=utc_today + timedelta(days=mod)
)
if next_dawn > utc_now:
break
mod += 1
mod = -1
while True:
next_dusk = astral.sun.dusk(
location.observer, date=utc_today + timedelta(days=mod)
)
if next_dusk > utc_now:
break
mod += 1
mod = -1
while True:
next_midnight = astral.sun.midnight(
location.observer, date=utc_today + timedelta(days=mod)
)
if next_midnight > utc_now:
break
mod += 1
mod = -1
while True:
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:
next_rising = astral.sun.sunrise(
location.observer, date=utc_today + timedelta(days=mod)
)
if next_rising > utc_now:
break
mod += 1
mod = -1
while True:
next_setting = astral.sun.sunset(
location.observer, date=utc_today + timedelta(days=mod)
)
if next_setting > utc_now:
break
mod += 1
expected_solar_elevation = astral.sun.elevation(location.observer, utc_now)
expected_solar_azimuth = astral.sun.azimuth(location.observer, utc_now)
state1 = hass.states.get("sensor.sun_next_dawn")
state2 = hass.states.get("sensor.sun_next_dusk")
state3 = hass.states.get("sensor.sun_next_midnight")
state4 = hass.states.get("sensor.sun_next_noon")
state5 = hass.states.get("sensor.sun_next_rising")
state6 = hass.states.get("sensor.sun_next_setting")
assert next_dawn.replace(microsecond=0) == dt_util.parse_datetime(state1.state)
assert next_dusk.replace(microsecond=0) == dt_util.parse_datetime(state2.state)
assert next_midnight.replace(microsecond=0) == dt_util.parse_datetime(state3.state)
assert next_noon.replace(microsecond=0) == dt_util.parse_datetime(state4.state)
assert next_rising.replace(microsecond=0) == dt_util.parse_datetime(state5.state)
assert next_setting.replace(microsecond=0) == dt_util.parse_datetime(state6.state)
solar_elevation_state = hass.states.get("sensor.sun_solar_elevation")
assert float(solar_elevation_state.state) == pytest.approx(
expected_solar_elevation, 0.1
)
solar_azimuth_state = hass.states.get("sensor.sun_solar_azimuth")
assert float(solar_azimuth_state.state) == pytest.approx(
expected_solar_azimuth, 0.1
)
entry_ids = hass.config_entries.async_entries("sun")
entity = entity_registry.async_get("sensor.sun_next_dawn")
assert entity
assert entity.entity_category is EntityCategory.DIAGNOSTIC
assert entity.unique_id == f"{entry_ids[0].entry_id}-next_dawn"
freezer.tick(timedelta(hours=24))
# Block once for Sun to update
await hass.async_block_till_done()
# Block another time for the sensors to update
await hass.async_block_till_done()
# Make sure all the signals work
assert state1.state != hass.states.get("sensor.sun_next_dawn").state
assert state2.state != hass.states.get("sensor.sun_next_dusk").state
assert state3.state != hass.states.get("sensor.sun_next_midnight").state
assert state4.state != hass.states.get("sensor.sun_next_noon").state
assert state5.state != hass.states.get("sensor.sun_next_rising").state
assert state6.state != hass.states.get("sensor.sun_next_setting").state
assert (
solar_elevation_state.state
!= hass.states.get("sensor.sun_solar_elevation").state
)
assert (
solar_azimuth_state.state != hass.states.get("sensor.sun_solar_azimuth").state
)
entity = entity_registry.async_get("sensor.sun_next_dusk")
assert entity
assert entity.entity_category is EntityCategory.DIAGNOSTIC
assert entity.unique_id == f"{entry_ids[0].entry_id}-next_dusk"
entity = entity_registry.async_get("sensor.sun_next_midnight")
assert entity
assert entity.entity_category is EntityCategory.DIAGNOSTIC
assert entity.unique_id == f"{entry_ids[0].entry_id}-next_midnight"
entity = entity_registry.async_get("sensor.sun_next_noon")
assert entity
assert entity.entity_category is EntityCategory.DIAGNOSTIC
assert entity.unique_id == f"{entry_ids[0].entry_id}-next_noon"
entity = entity_registry.async_get("sensor.sun_next_rising")
assert entity
assert entity.entity_category is EntityCategory.DIAGNOSTIC
assert entity.unique_id == f"{entry_ids[0].entry_id}-next_rising"
entity = entity_registry.async_get("sensor.sun_next_setting")
assert entity
assert entity.entity_category is EntityCategory.DIAGNOSTIC
assert entity.unique_id == f"{entry_ids[0].entry_id}-next_setting"
entity = entity_registry.async_get("sensor.sun_solar_elevation")
assert entity
assert entity.entity_category is EntityCategory.DIAGNOSTIC
assert entity.unique_id == f"{entry_ids[0].entry_id}-solar_elevation"
entity = entity_registry.async_get("sensor.sun_solar_azimuth")
assert entity
assert entity.entity_category is EntityCategory.DIAGNOSTIC
assert entity.unique_id == f"{entry_ids[0].entry_id}-solar_azimuth"
entity = entity_registry.async_get("sensor.sun_solar_rising")
assert entity
assert entity.entity_category is EntityCategory.DIAGNOSTIC
assert entity.unique_id == f"{entry_ids[0].entry_id}-solar_rising"
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_deprecation(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
issue_registry: ir.IssueRegistry,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test sensor.sun_solar_rising deprecation."""
utc_now = datetime(2016, 11, 1, 8, 0, 0, tzinfo=dt_util.UTC)
freezer.move_to(utc_now)
await async_setup_component(hass, sun.DOMAIN, {sun.DOMAIN: {}})
await hass.async_block_till_done()
assert issue_registry.async_get_issue(
domain="sun",
issue_id="deprecated_sun_solar_rising",
)
assert len(issue_registry.issues) == 1
entity_registry.async_update_entity(
"sensor.sun_solar_rising", disabled_by=er.RegistryEntryDisabler.USER
)
await hass.async_block_till_done()
assert not issue_registry.async_get_issue(
domain="sun",
issue_id="deprecated_sun_solar_rising",
)
assert len(issue_registry.issues) == 0
entity_registry.async_update_entity("sensor.sun_solar_rising", disabled_by=None)
await hass.async_block_till_done()
freezer.tick(delta=RELOAD_AFTER_UPDATE_DELAY)
async_fire_time_changed(hass)
await hass.async_block_till_done()
assert issue_registry.async_get_issue(
domain="sun",
issue_id="deprecated_sun_solar_rising",
)
assert len(issue_registry.issues) == 1