mirror of
https://github.com/jdejaegh/irm-kmi-ha.git
synced 2025-06-27 03:35:56 +02:00
Add next sunset sunrise sensors
This commit is contained in:
parent
0059b2f78f
commit
f1e7c267e6
7 changed files with 100 additions and 2 deletions
|
@ -176,7 +176,8 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator):
|
|||
radar_forecast=IrmKmiCoordinator.radar_list_to_forecast(api_data.get('animation', {})),
|
||||
animation=await self._async_animation_data(api_data=api_data),
|
||||
warnings=self.warnings_from_data(api_data.get('for', {}).get('warning')),
|
||||
pollen=await self._async_pollen_data(api_data=api_data)
|
||||
pollen=await self._async_pollen_data(api_data=api_data),
|
||||
country=api_data.get('country')
|
||||
)
|
||||
|
||||
async def download_images_from_api(self,
|
||||
|
|
|
@ -73,3 +73,4 @@ class ProcessedCoordinatorData(TypedDict, total=False):
|
|||
animation: RadarAnimationData
|
||||
warnings: List[WarningData]
|
||||
pollen: dict
|
||||
country: str
|
||||
|
|
|
@ -12,6 +12,7 @@ from homeassistant.util import dt
|
|||
|
||||
from custom_components.irm_kmi import DOMAIN, IrmKmiCoordinator
|
||||
from custom_components.irm_kmi.const import POLLEN_NAMES, POLLEN_TO_ICON_MAP
|
||||
from custom_components.irm_kmi.data import IrmKmiForecast
|
||||
from custom_components.irm_kmi.pollen import PollenParser
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -23,6 +24,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_e
|
|||
async_add_entities([IrmKmiPollen(coordinator, entry, pollen.lower()) for pollen in POLLEN_NAMES])
|
||||
async_add_entities([IrmKmiNextWarning(coordinator, entry),])
|
||||
|
||||
if coordinator.data.get('country') != 'NL':
|
||||
async_add_entities([IrmKmiNextSunMove(coordinator, entry, move) for move in ['sunset', 'sunrise']])
|
||||
|
||||
|
||||
class IrmKmiPollen(CoordinatorEntity, SensorEntity):
|
||||
"""Representation of a pollen sensor"""
|
||||
|
@ -96,3 +100,37 @@ class IrmKmiNextWarning(CoordinatorEntity, SensorEntity):
|
|||
[warning['friendly_name'] for warning in attrs['next_warnings'] if warning['friendly_name'] != ''])
|
||||
|
||||
return attrs
|
||||
|
||||
|
||||
class IrmKmiNextSunMove(CoordinatorEntity, SensorEntity):
|
||||
"""Representation of the next sunrise or sunset"""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
_attr_device_class = SensorDeviceClass.TIMESTAMP
|
||||
_attr_attribution = "Weather data from the Royal Meteorological Institute of Belgium meteo.be"
|
||||
|
||||
def __init__(self,
|
||||
coordinator: IrmKmiCoordinator,
|
||||
entry: ConfigEntry,
|
||||
move: str) -> None:
|
||||
assert move in ['sunset', 'sunrise']
|
||||
super().__init__(coordinator)
|
||||
SensorEntity.__init__(self)
|
||||
self._attr_unique_id = f"{entry.entry_id}-next-{move}"
|
||||
self.entity_id = sensor.ENTITY_ID_FORMAT.format(f"{str(entry.title).lower()}_next_{move}")
|
||||
self._attr_device_info = coordinator.shared_device_info
|
||||
self._attr_translation_key = f"next_{move}"
|
||||
self._move: str = move
|
||||
self._attr_icon = 'mdi:weather-sunset-down' if move == 'sunset' else 'mdi:weather-sunset-up'
|
||||
|
||||
@property
|
||||
def native_value(self) -> datetime.datetime | None:
|
||||
"""Return the timestamp for the next sunrise or sunset"""
|
||||
now = dt.now()
|
||||
data: list[IrmKmiForecast] = self.coordinator.data.get('daily_forecast')
|
||||
|
||||
upcoming = [f.get(self._move) for f in data if f.get(self._move) >= now]
|
||||
|
||||
if len(upcoming) > 0:
|
||||
return upcoming[0]
|
||||
return None
|
||||
|
|
|
@ -93,6 +93,12 @@
|
|||
"next_warning": {
|
||||
"name": "Next warning"
|
||||
},
|
||||
"next_sunrise": {
|
||||
"name": "Next sunrise"
|
||||
},
|
||||
"next_sunset": {
|
||||
"name": "Next sunset"
|
||||
},
|
||||
"pollen_alder": {
|
||||
"name": "Alder pollen",
|
||||
"state": {
|
||||
|
|
|
@ -93,6 +93,12 @@
|
|||
"next_warning": {
|
||||
"name": "Prochain avertissement"
|
||||
},
|
||||
"next_sunrise": {
|
||||
"name": "Prochain lever de soleil"
|
||||
},
|
||||
"next_sunset": {
|
||||
"name": "Prochain coucher de soleil"
|
||||
},
|
||||
"pollen_alder": {
|
||||
"name": "Pollen d'aulne",
|
||||
"state": {
|
||||
|
|
|
@ -93,6 +93,12 @@
|
|||
"next_warning": {
|
||||
"name": "Volgende waarschuwing"
|
||||
},
|
||||
"next_sunrise": {
|
||||
"name": "Volgende zonsopkomst"
|
||||
},
|
||||
"next_sunset": {
|
||||
"name": "Volgende zonsondergang"
|
||||
},
|
||||
"pollen_alder": {
|
||||
"name": "Elzenpollen",
|
||||
"state": {
|
||||
|
|
|
@ -7,7 +7,7 @@ from pytest_homeassistant_custom_component.common import MockConfigEntry
|
|||
from custom_components.irm_kmi import IrmKmiCoordinator
|
||||
from custom_components.irm_kmi.binary_sensor import IrmKmiWarning
|
||||
from custom_components.irm_kmi.const import CONF_LANGUAGE_OVERRIDE
|
||||
from custom_components.irm_kmi.sensor import IrmKmiNextWarning
|
||||
from custom_components.irm_kmi.sensor import IrmKmiNextWarning, IrmKmiNextSunMove
|
||||
from tests.conftest import get_api_data
|
||||
|
||||
|
||||
|
@ -126,3 +126,43 @@ async def test_next_warning_none_when_no_warnings(
|
|||
assert len(warning.extra_state_attributes['next_warnings']) == 0
|
||||
|
||||
assert warning.extra_state_attributes['next_warnings_friendly_names'] == ""
|
||||
|
||||
|
||||
@freeze_time(datetime.fromisoformat('2023-12-26T18:30:00+01:00'))
|
||||
async def test_next_sunrise_sunset(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry
|
||||
) -> None:
|
||||
api_data = get_api_data("forecast.json")
|
||||
|
||||
coordinator = IrmKmiCoordinator(hass, mock_config_entry)
|
||||
|
||||
result = await coordinator.daily_list_to_forecast(api_data.get('for', {}).get('daily'))
|
||||
|
||||
coordinator.data = {'daily_forecast': result}
|
||||
|
||||
sunset = IrmKmiNextSunMove(coordinator, mock_config_entry, 'sunset')
|
||||
sunrise = IrmKmiNextSunMove(coordinator, mock_config_entry, 'sunrise')
|
||||
|
||||
assert datetime.fromisoformat(sunrise.state) == datetime.fromisoformat('2023-12-27T08:44:00+01:00')
|
||||
assert datetime.fromisoformat(sunset.state) == datetime.fromisoformat('2023-12-27T16:43:00+01:00')
|
||||
|
||||
|
||||
@freeze_time(datetime.fromisoformat('2023-12-26T15:30:00+01:00'))
|
||||
async def test_next_sunrise_sunset_bis(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry
|
||||
) -> None:
|
||||
api_data = get_api_data("forecast.json")
|
||||
|
||||
coordinator = IrmKmiCoordinator(hass, mock_config_entry)
|
||||
|
||||
result = await coordinator.daily_list_to_forecast(api_data.get('for', {}).get('daily'))
|
||||
|
||||
coordinator.data = {'daily_forecast': result}
|
||||
|
||||
sunset = IrmKmiNextSunMove(coordinator, mock_config_entry, 'sunset')
|
||||
sunrise = IrmKmiNextSunMove(coordinator, mock_config_entry, 'sunrise')
|
||||
|
||||
assert datetime.fromisoformat(sunrise.state) == datetime.fromisoformat('2023-12-27T08:44:00+01:00')
|
||||
assert datetime.fromisoformat(sunset.state) == datetime.fromisoformat('2023-12-26T16:42:00+01:00')
|
Loading…
Add table
Reference in a new issue