Exclude sun attributes from being recorded in the database (#68887)

This commit is contained in:
J. Nick Koston 2022-03-29 23:03:08 -10:00 committed by GitHub
parent ecd43f391f
commit bbcefd6fec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 125 additions and 15 deletions

View File

@ -5,11 +5,12 @@ import logging
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
CONF_ELEVATION, CONF_ELEVATION,
EVENT_COMPONENT_LOADED,
EVENT_CORE_CONFIG_UPDATE, EVENT_CORE_CONFIG_UPDATE,
SUN_EVENT_SUNRISE, SUN_EVENT_SUNRISE,
SUN_EVENT_SUNSET, SUN_EVENT_SUNSET,
) )
from homeassistant.core import HomeAssistant, callback from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.helpers import event from homeassistant.helpers import event
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.sun import ( from homeassistant.helpers.sun import (
@ -17,6 +18,7 @@ from homeassistant.helpers.sun import (
get_location_astral_event_next, get_location_astral_event_next,
) )
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from homeassistant.setup import ATTR_COMPONENT
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
from .const import DOMAIN from .const import DOMAIN
@ -124,26 +126,43 @@ class Sun(Entity):
self._config_listener = None self._config_listener = None
self._update_events_listener = None self._update_events_listener = None
self._update_sun_position_listener = None self._update_sun_position_listener = None
self._loaded_listener = None
@callback
def update_location(_event):
location, elevation = get_astral_location(self.hass)
if location == self.location:
return
self.location = location
self.elevation = elevation
if self._update_events_listener:
self._update_events_listener()
self.update_events()
update_location(None)
self._config_listener = self.hass.bus.async_listen( self._config_listener = self.hass.bus.async_listen(
EVENT_CORE_CONFIG_UPDATE, update_location EVENT_CORE_CONFIG_UPDATE, self.update_location
) )
self._loaded_listener = self.hass.bus.async_listen(
EVENT_COMPONENT_LOADED, self.loading_complete
)
@callback
def loading_complete(self, event_: Event) -> None:
"""Update location when loading is complete."""
if event_.data[ATTR_COMPONENT] == DOMAIN:
self.update_location()
self._remove_loaded_listener()
@callback
def update_location(self, *_):
"""Update location."""
location, elevation = get_astral_location(self.hass)
if location == self.location:
return
self.location = location
self.elevation = elevation
if self._update_events_listener:
self._update_events_listener()
self.update_events()
@callback
def _remove_loaded_listener(self):
"""Remove the loaded listener."""
if self._loaded_listener:
self._loaded_listener()
@callback @callback
def remove_listeners(self): def remove_listeners(self):
"""Remove listeners.""" """Remove listeners."""
self._remove_loaded_listener()
if self._config_listener: if self._config_listener:
self._config_listener() self._config_listener()
if self._update_events_listener: if self._update_events_listener:

View File

@ -0,0 +1,32 @@
"""Integration platform for recorder."""
from __future__ import annotations
from homeassistant.core import HomeAssistant, callback
from . import (
STATE_ATTR_AZIMUTH,
STATE_ATTR_ELEVATION,
STATE_ATTR_NEXT_DAWN,
STATE_ATTR_NEXT_DUSK,
STATE_ATTR_NEXT_MIDNIGHT,
STATE_ATTR_NEXT_NOON,
STATE_ATTR_NEXT_RISING,
STATE_ATTR_NEXT_SETTING,
STATE_ATTR_RISING,
)
@callback
def exclude_attributes(hass: HomeAssistant) -> set[str]:
"""Exclude sun attributes from being recorded in the database."""
return {
STATE_ATTR_AZIMUTH,
STATE_ATTR_ELEVATION,
STATE_ATTR_RISING,
STATE_ATTR_NEXT_DAWN,
STATE_ATTR_NEXT_DUSK,
STATE_ATTR_NEXT_MIDNIGHT,
STATE_ATTR_NEXT_NOON,
STATE_ATTR_NEXT_RISING,
STATE_ATTR_NEXT_SETTING,
}

View File

@ -0,0 +1,59 @@
"""The tests for sun recorder."""
from __future__ import annotations
from datetime import timedelta
from homeassistant.components.recorder.models import StateAttributes, States
from homeassistant.components.recorder.util import session_scope
from homeassistant.components.sun import (
DOMAIN,
STATE_ATTR_AZIMUTH,
STATE_ATTR_ELEVATION,
STATE_ATTR_NEXT_DAWN,
STATE_ATTR_NEXT_DUSK,
STATE_ATTR_NEXT_MIDNIGHT,
STATE_ATTR_NEXT_NOON,
STATE_ATTR_NEXT_RISING,
STATE_ATTR_NEXT_SETTING,
STATE_ATTR_RISING,
)
from homeassistant.const import ATTR_FRIENDLY_NAME
from homeassistant.core import State
from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util
from tests.common import async_fire_time_changed, async_init_recorder_component
from tests.components.recorder.common import async_wait_recording_done_without_instance
async def test_exclude_attributes(hass):
"""Test sun attributes to be excluded."""
await async_init_recorder_component(hass)
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=5))
await hass.async_block_till_done()
await async_wait_recording_done_without_instance(hass)
def _fetch_sun_states() -> list[State]:
with session_scope(hass=hass) as session:
native_states = []
for db_state, db_state_attributes in session.query(States, StateAttributes):
state = db_state.to_native()
state.attributes = db_state_attributes.to_native()
native_states.append(state)
return native_states
states: list[State] = await hass.async_add_executor_job(_fetch_sun_states)
assert len(states) > 1
for state in states:
assert STATE_ATTR_AZIMUTH not in state.attributes
assert STATE_ATTR_ELEVATION not in state.attributes
assert STATE_ATTR_NEXT_DAWN not in state.attributes
assert STATE_ATTR_NEXT_DUSK not in state.attributes
assert STATE_ATTR_NEXT_MIDNIGHT not in state.attributes
assert STATE_ATTR_NEXT_NOON not in state.attributes
assert STATE_ATTR_NEXT_RISING not in state.attributes
assert STATE_ATTR_NEXT_SETTING not in state.attributes
assert STATE_ATTR_RISING not in state.attributes
assert ATTR_FRIENDLY_NAME in state.attributes