Improve sun typing (#78298)

This commit is contained in:
epenet 2022-09-12 21:34:35 +02:00 committed by GitHub
parent 3be9bee61e
commit 19bee11a01
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 33 deletions

View file

@ -1,6 +1,11 @@
"""Support for functionality to keep track of the sun."""
from datetime import timedelta
from __future__ import annotations
from datetime import datetime, timedelta
import logging
from typing import Any
from astral.location import Elevation, Location
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import (
@ -9,7 +14,7 @@ from homeassistant.const import (
SUN_EVENT_SUNRISE,
SUN_EVENT_SUNSET,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.core import CALLBACK_TYPE, Event, HomeAssistant, callback
from homeassistant.helpers import event
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.integration_platform import (
@ -24,8 +29,6 @@ from homeassistant.util import dt as dt_util
from .const import DOMAIN
# mypy: allow-untyped-calls, allow-untyped-defs, no-check-untyped-defs
_LOGGER = logging.getLogger(__name__)
ENTITY_ID = "sun.sun"
@ -114,32 +117,40 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
class Sun(Entity):
"""Representation of the Sun."""
_attr_name = "Sun"
entity_id = ENTITY_ID
def __init__(self, hass):
location: Location
elevation: Elevation
next_rising: datetime
next_setting: datetime
next_dawn: datetime
next_dusk: datetime
next_midnight: datetime
next_noon: datetime
solar_elevation: float
solar_azimuth: float
rising: bool
_next_change: datetime
def __init__(self, hass: HomeAssistant) -> None:
"""Initialize the sun."""
self.hass = hass
self.location = None
self.elevation = 0.0
self._state = self.next_rising = self.next_setting = None
self.next_dawn = self.next_dusk = None
self.next_midnight = self.next_noon = None
self.solar_elevation = self.solar_azimuth = None
self.rising = self.phase = None
self._next_change = None
self._config_listener = None
self._update_events_listener = None
self._update_sun_position_listener = None
self.phase: str | None = None
self._config_listener: CALLBACK_TYPE | None = None
self._update_events_listener: CALLBACK_TYPE | None = None
self._update_sun_position_listener: CALLBACK_TYPE | None = None
self._config_listener = self.hass.bus.async_listen(
EVENT_CORE_CONFIG_UPDATE, self.update_location
)
self.update_location()
self.update_location(initial=True)
@callback
def update_location(self, *_):
def update_location(self, _: Event | None = None, initial: bool = False) -> None:
"""Update location."""
location, elevation = get_astral_location(self.hass)
if location == self.location:
if not initial and location == self.location:
return
self.location = location
self.elevation = elevation
@ -148,7 +159,7 @@ class Sun(Entity):
self.update_events()
@callback
def remove_listeners(self):
def remove_listeners(self) -> None:
"""Remove listeners."""
if self._config_listener:
self._config_listener()
@ -158,12 +169,7 @@ class Sun(Entity):
self._update_sun_position_listener()
@property
def name(self):
"""Return the name."""
return "Sun"
@property
def state(self):
def state(self) -> str:
"""Return the state of the sun."""
# 0.8333 is the same value as astral uses
if self.solar_elevation > -0.833:
@ -172,7 +178,7 @@ class Sun(Entity):
return STATE_BELOW_HORIZON
@property
def extra_state_attributes(self):
def extra_state_attributes(self) -> dict[str, Any]:
"""Return the state attributes of the sun."""
return {
STATE_ATTR_NEXT_DAWN: self.next_dawn.isoformat(),
@ -186,7 +192,9 @@ class Sun(Entity):
STATE_ATTR_RISING: self.rising,
}
def _check_event(self, utc_point_in_time, sun_event, before):
def _check_event(
self, utc_point_in_time: datetime, sun_event: str, before: str | None
) -> datetime:
next_utc = get_location_astral_event_next(
self.location, self.elevation, sun_event, utc_point_in_time
)
@ -196,7 +204,7 @@ class Sun(Entity):
return next_utc
@callback
def update_events(self, now=None):
def update_events(self, now: datetime | None = None) -> None:
"""Update the attributes containing solar events."""
# Grab current time in case system clock changed since last time we ran.
utc_point_in_time = dt_util.utcnow()
@ -266,7 +274,7 @@ class Sun(Entity):
_LOGGER.debug("next time: %s", self._next_change.isoformat())
@callback
def update_sun_position(self, now=None):
def update_sun_position(self, now: datetime | None = None) -> None:
"""Calculate the position of the sun."""
# Grab current time in case system clock changed since last time we ran.
utc_point_in_time = dt_util.utcnow()
@ -286,6 +294,7 @@ class Sun(Entity):
self.async_write_ha_state()
# Next update as per the current phase
assert self.phase
delta = _PHASE_UPDATES[self.phase]
# if the next update is within 1.25 of the next
# position update just drop it

View file

@ -15,8 +15,6 @@ from homeassistant.helpers.event import async_track_sunrise, async_track_sunset
from homeassistant.helpers.trigger import TriggerActionType, TriggerInfo
from homeassistant.helpers.typing import ConfigType
# mypy: allow-untyped-defs, no-check-untyped-defs
TRIGGER_SCHEMA = cv.TRIGGER_BASE_SCHEMA.extend(
{
vol.Required(CONF_PLATFORM): "sun",
@ -42,7 +40,7 @@ async def async_attach_trigger(
job = HassJob(action)
@callback
def call_action():
def call_action() -> None:
"""Call action with right context."""
hass.async_run_hass_job(
job,