mirror of
https://github.com/jdejaegh/irm-kmi-ha.git
synced 2025-06-27 03:35:56 +02:00
Compare commits
6 commits
fbab30e33f
...
fee2a10f5e
Author | SHA1 | Date | |
---|---|---|---|
fee2a10f5e | |||
18040eb577 | |||
be0a7425d4 | |||
1844d02639 | |||
ca98e12e88 | |||
fb59936c79 |
17 changed files with 404 additions and 42 deletions
|
@ -1,6 +1,7 @@
|
|||
"""Constants for the IRM KMI integration."""
|
||||
from typing import Final
|
||||
|
||||
from homeassistant.components.sensor import SensorDeviceClass
|
||||
from homeassistant.components.weather import (ATTR_CONDITION_CLEAR_NIGHT,
|
||||
ATTR_CONDITION_CLOUDY,
|
||||
ATTR_CONDITION_FOG,
|
||||
|
@ -11,7 +12,7 @@ from homeassistant.components.weather import (ATTR_CONDITION_CLEAR_NIGHT,
|
|||
ATTR_CONDITION_SNOWY,
|
||||
ATTR_CONDITION_SNOWY_RAINY,
|
||||
ATTR_CONDITION_SUNNY)
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.const import Platform, UnitOfPressure, UnitOfSpeed, UnitOfTemperature, DEGREE
|
||||
|
||||
DOMAIN: Final = 'irm_kmi'
|
||||
PLATFORMS: Final = [Platform.WEATHER, Platform.CAMERA, Platform.BINARY_SENSOR, Platform.SENSOR]
|
||||
|
@ -160,4 +161,29 @@ IRM_KMI_NAME: Final = {
|
|||
|
||||
WEEKDAYS = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
|
||||
|
||||
USER_AGENT: Final = 'github.com/jdejaegh/irm-kmi-ha 0.2.29'
|
||||
USER_AGENT: Final = 'github.com/jdejaegh/irm-kmi-ha 0.2.30'
|
||||
|
||||
CURRENT_WEATHER_SENSORS: Final = {'temperature', 'wind_speed', 'wind_gust_speed', 'wind_bearing', 'uv_index',
|
||||
'pressure'}
|
||||
|
||||
CURRENT_WEATHER_SENSOR_UNITS: Final = {'temperature': UnitOfTemperature.CELSIUS,
|
||||
'wind_speed': UnitOfSpeed.KILOMETERS_PER_HOUR,
|
||||
'wind_gust_speed': UnitOfSpeed.KILOMETERS_PER_HOUR,
|
||||
'wind_bearing': DEGREE,
|
||||
'uv_index': None,
|
||||
'pressure': UnitOfPressure.HPA}
|
||||
|
||||
CURRENT_WEATHER_SENSOR_CLASS: Final = {'temperature': SensorDeviceClass.TEMPERATURE,
|
||||
'wind_speed': SensorDeviceClass.WIND_SPEED,
|
||||
'wind_gust_speed': SensorDeviceClass.WIND_SPEED,
|
||||
'wind_bearing': None,
|
||||
'uv_index': None,
|
||||
'pressure': SensorDeviceClass.ATMOSPHERIC_PRESSURE}
|
||||
|
||||
# Leave None when we want the default icon to be shown
|
||||
CURRENT_WEATHER_SENSOR_ICON: Final = {'temperature': None,
|
||||
'wind_speed': None,
|
||||
'wind_gust_speed': None,
|
||||
'wind_bearing': 'mdi:compass',
|
||||
'uv_index': 'mdi:sun-wireless',
|
||||
'pressure': None}
|
||||
|
|
|
@ -327,6 +327,7 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator):
|
|||
if data is None:
|
||||
return None
|
||||
sequence = data.get("sequence", [])
|
||||
unit = data.get("unit", {}).get("en", None)
|
||||
ratios = [f['value'] / f['position'] for f in sequence if f['position'] > 0]
|
||||
|
||||
if len(ratios) > 0:
|
||||
|
@ -342,7 +343,8 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator):
|
|||
native_precipitation=f.get('value'),
|
||||
rain_forecast_max=round(f.get('positionHigher') * ratio, 2),
|
||||
rain_forecast_min=round(f.get('positionLower') * ratio, 2),
|
||||
might_rain=f.get('positionHigher') > 0
|
||||
might_rain=f.get('positionHigher') > 0,
|
||||
unit=unit
|
||||
)
|
||||
)
|
||||
return forecast
|
||||
|
|
|
@ -12,5 +12,5 @@
|
|||
"svgwrite==1.4.3",
|
||||
"aiofile==3.9.0"
|
||||
],
|
||||
"version": "0.2.29"
|
||||
"version": "0.2.30"
|
||||
}
|
|
@ -11,6 +11,7 @@ class IrmKmiRadarForecast(Forecast):
|
|||
rain_forecast_max: float
|
||||
rain_forecast_min: float
|
||||
might_rain: bool
|
||||
unit: str | None
|
||||
|
||||
|
||||
class AnimationFrameData(TypedDict, total=False):
|
||||
|
|
|
@ -11,9 +11,11 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
|||
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.const import POLLEN_NAMES, POLLEN_TO_ICON_MAP, CURRENT_WEATHER_SENSOR_UNITS, \
|
||||
CURRENT_WEATHER_SENSOR_CLASS, CURRENT_WEATHER_SENSORS, CURRENT_WEATHER_SENSOR_ICON
|
||||
from custom_components.irm_kmi.data import IrmKmiForecast
|
||||
from custom_components.irm_kmi.pollen import PollenParser
|
||||
from custom_components.irm_kmi.radar_data import IrmKmiRadarForecast
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -22,7 +24,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_e
|
|||
"""Set up the sensor platform"""
|
||||
coordinator = hass.data[DOMAIN][entry.entry_id]
|
||||
async_add_entities([IrmKmiPollen(coordinator, entry, pollen.lower()) for pollen in POLLEN_NAMES])
|
||||
async_add_entities([IrmKmiNextWarning(coordinator, entry),])
|
||||
async_add_entities([IrmKmiCurrentWeather(coordinator, entry, name) for name in CURRENT_WEATHER_SENSORS])
|
||||
async_add_entities([IrmKmiNextWarning(coordinator, entry),
|
||||
IrmKmiCurrentRainfall(coordinator, entry)])
|
||||
|
||||
if coordinator.data.get('country') != 'NL':
|
||||
async_add_entities([IrmKmiNextSunMove(coordinator, entry, move) for move in ['sunset', 'sunrise']])
|
||||
|
@ -135,3 +139,91 @@ class IrmKmiNextSunMove(CoordinatorEntity, SensorEntity):
|
|||
if len(upcoming) > 0:
|
||||
return upcoming[0]
|
||||
return None
|
||||
|
||||
|
||||
class IrmKmiCurrentWeather(CoordinatorEntity, SensorEntity):
|
||||
"""Representation of a current weather sensor"""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
_attr_attribution = "Weather data from the Royal Meteorological Institute of Belgium meteo.be"
|
||||
|
||||
def __init__(self,
|
||||
coordinator: IrmKmiCoordinator,
|
||||
entry: ConfigEntry,
|
||||
sensor_name: str) -> None:
|
||||
super().__init__(coordinator)
|
||||
SensorEntity.__init__(self)
|
||||
self._attr_unique_id = f"{entry.entry_id}-current-{sensor_name}"
|
||||
self.entity_id = sensor.ENTITY_ID_FORMAT.format(f"{str(entry.title).lower()}_current_{sensor_name}")
|
||||
self._attr_device_info = coordinator.shared_device_info
|
||||
self._attr_translation_key = f"current_{sensor_name}"
|
||||
self._sensor_name: str = sensor_name
|
||||
|
||||
@property
|
||||
def native_value(self) -> float | None:
|
||||
"""Return the current value of the sensor"""
|
||||
return self.coordinator.data.get('current_weather', {}).get(self._sensor_name, None)
|
||||
|
||||
@property
|
||||
def native_unit_of_measurement(self) -> str | None:
|
||||
return CURRENT_WEATHER_SENSOR_UNITS[self._sensor_name]
|
||||
|
||||
@property
|
||||
def device_class(self) -> SensorDeviceClass | None:
|
||||
return CURRENT_WEATHER_SENSOR_CLASS[self._sensor_name]
|
||||
|
||||
@property
|
||||
def icon(self) -> str | None:
|
||||
return CURRENT_WEATHER_SENSOR_ICON[self._sensor_name]
|
||||
|
||||
|
||||
class IrmKmiCurrentRainfall(CoordinatorEntity, SensorEntity):
|
||||
"""Representation of a current rainfall sensor"""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
_attr_attribution = "Weather data from the Royal Meteorological Institute of Belgium meteo.be"
|
||||
|
||||
def __init__(self,
|
||||
coordinator: IrmKmiCoordinator,
|
||||
entry: ConfigEntry) -> None:
|
||||
super().__init__(coordinator)
|
||||
SensorEntity.__init__(self)
|
||||
self._attr_unique_id = f"{entry.entry_id}-current-rainfall"
|
||||
self.entity_id = sensor.ENTITY_ID_FORMAT.format(f"{str(entry.title).lower()}_current_rainfall")
|
||||
self._attr_device_info = coordinator.shared_device_info
|
||||
self._attr_translation_key = "current_rainfall"
|
||||
self._attr_icon = 'mdi:weather-pouring'
|
||||
|
||||
def _current_forecast(self) -> IrmKmiRadarForecast | None:
|
||||
now = dt.now()
|
||||
forecasts = self.coordinator.data.get('radar_forecast', None)
|
||||
|
||||
if forecasts is None:
|
||||
return None
|
||||
|
||||
prev = forecasts[0]
|
||||
for f in forecasts:
|
||||
if datetime.fromisoformat(f.get('datetime')) > now:
|
||||
return prev
|
||||
prev = f
|
||||
|
||||
return forecasts[-1]
|
||||
|
||||
@property
|
||||
def native_value(self) -> float | None:
|
||||
"""Return the current value of the sensor"""
|
||||
current = self._current_forecast()
|
||||
|
||||
if current is None:
|
||||
return None
|
||||
|
||||
return current.get('native_precipitation', None)
|
||||
|
||||
@property
|
||||
def native_unit_of_measurement(self) -> str | None:
|
||||
current = self._current_forecast()
|
||||
|
||||
if current is None:
|
||||
return None
|
||||
|
||||
return current.get('unit', None)
|
|
@ -182,6 +182,27 @@
|
|||
"purple": "Purple",
|
||||
"none": "None"
|
||||
}
|
||||
},
|
||||
"current_temperature": {
|
||||
"name": "Temperature"
|
||||
},
|
||||
"current_wind_speed": {
|
||||
"name": "Wind speed"
|
||||
},
|
||||
"current_wind_gust_speed": {
|
||||
"name": "Wind gust speed"
|
||||
},
|
||||
"current_wind_bearing": {
|
||||
"name": "Wind bearing"
|
||||
},
|
||||
"current_uv_index": {
|
||||
"name": "UV index"
|
||||
},
|
||||
"current_pressure": {
|
||||
"name": "Atmospheric pressure"
|
||||
},
|
||||
"current_rainfall": {
|
||||
"name": "Rainfall"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -182,6 +182,27 @@
|
|||
"purple": "Violet",
|
||||
"none": "Aucun"
|
||||
}
|
||||
},
|
||||
"current_temperature": {
|
||||
"name": "Température"
|
||||
},
|
||||
"current_wind_speed": {
|
||||
"name": "Vitesse du vent"
|
||||
},
|
||||
"current_wind_gust_speed": {
|
||||
"name": "Vitesse des rafales de vent"
|
||||
},
|
||||
"current_wind_bearing": {
|
||||
"name": "Direction du vent"
|
||||
},
|
||||
"current_uv_index": {
|
||||
"name": "Index UV"
|
||||
},
|
||||
"current_pressure": {
|
||||
"name": "Pression atmosphérique"
|
||||
},
|
||||
"current_rainfall": {
|
||||
"name": "Precipitation"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -182,6 +182,27 @@
|
|||
"purple": "Paars",
|
||||
"none": "Geen"
|
||||
}
|
||||
},
|
||||
"current_temperature": {
|
||||
"name": "Temperatuur"
|
||||
},
|
||||
"current_wind_speed": {
|
||||
"name": "Windsnelheid"
|
||||
},
|
||||
"current_wind_gust_speed": {
|
||||
"name": "Snelheid windvlaag"
|
||||
},
|
||||
"current_wind_bearing": {
|
||||
"name": "Windrichting"
|
||||
},
|
||||
"current_uv_index": {
|
||||
"name": "UV-index"
|
||||
},
|
||||
"current_pressure": {
|
||||
"name": "Luchtdruk"
|
||||
},
|
||||
"current_rainfall": {
|
||||
"name": "Neerslag"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -182,6 +182,27 @@
|
|||
"purple": "Roxo",
|
||||
"none": "Nenhum"
|
||||
}
|
||||
},
|
||||
"current_temperature": {
|
||||
"name": "Temperatura"
|
||||
},
|
||||
"current_wind_speed": {
|
||||
"name": "Velocidade do vento"
|
||||
},
|
||||
"current_wind_gust_speed": {
|
||||
"name": "Velocidade da rajada de vento"
|
||||
},
|
||||
"current_wind_bearing": {
|
||||
"name": "Direção do vento"
|
||||
},
|
||||
"current_uv_index": {
|
||||
"name": "Índice UV"
|
||||
},
|
||||
"current_pressure": {
|
||||
"name": "Pressão atmosférica"
|
||||
},
|
||||
"current_rainfall": {
|
||||
"name": "Precipitação"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[tool.bumpver]
|
||||
current_version = "0.2.29"
|
||||
current_version = "0.2.30"
|
||||
version_pattern = "MAJOR.MINOR.PATCH"
|
||||
commit_message = "bump version {old_version} -> {new_version}"
|
||||
tag_message = "{new_version}"
|
||||
|
|
2
tests/fixtures/be_forecast_warning.json
vendored
2
tests/fixtures/be_forecast_warning.json
vendored
|
@ -1474,7 +1474,7 @@
|
|||
{
|
||||
"time": "2024-01-12T10:10:00+01:00",
|
||||
"uri": "https:\/\/app.meteo.be\/services\/appv4\/?s=getIncaImage&i=202401120920&f=2&k=2160a92594985471351907ee5cc75d1f&d=202401120900",
|
||||
"value": 0,
|
||||
"value": 0.42,
|
||||
"position": 0,
|
||||
"positionLower": 0,
|
||||
"positionHigher": 0
|
||||
|
|
2
tests/fixtures/forecast_ams_no_ww.json
vendored
2
tests/fixtures/forecast_ams_no_ww.json
vendored
|
@ -1642,7 +1642,7 @@
|
|||
{
|
||||
"time": "2024-06-09T13:40:00+00:00",
|
||||
"uri": "https:\/\/cdn.knmi.nl\/knmi\/map\/page\/weer\/actueel-weer\/neerslagradar\/weerapp\/RAD_NL25_PCP_CM_202406091340_640.png",
|
||||
"value": 0,
|
||||
"value": 0.1341,
|
||||
"position": 0,
|
||||
"positionLower": 0,
|
||||
"positionHigher": 0
|
||||
|
|
4
tests/fixtures/forecast_nl.json
vendored
4
tests/fixtures/forecast_nl.json
vendored
|
@ -6,7 +6,7 @@
|
|||
"municipality_code": "0995",
|
||||
"temp": 11,
|
||||
"windSpeedKm": 40,
|
||||
"timestamp": "2023-12-28T14:20:00+00:00",
|
||||
"timestamp": "2023-12-28T14:30:00+00:00",
|
||||
"windDirection": 45,
|
||||
"municipality": "Lelystad",
|
||||
"windDirectionText": {
|
||||
|
@ -1337,7 +1337,7 @@
|
|||
{
|
||||
"time": "2023-12-28T14:25:00+00:00",
|
||||
"uri": "https:\/\/cdn.knmi.nl\/knmi\/map\/page\/weer\/actueel-weer\/neerslagradar\/weerapp\/RAD_NL25_PCP_CM_202312281425_640.png",
|
||||
"value": 0,
|
||||
"value": 0.15,
|
||||
"position": 0,
|
||||
"positionLower": 0,
|
||||
"positionHigher": 0
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import zoneinfo
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from freezegun import freeze_time
|
||||
|
@ -12,9 +11,8 @@ from custom_components.irm_kmi.const import CONF_LANGUAGE_OVERRIDE
|
|||
from custom_components.irm_kmi.coordinator import IrmKmiCoordinator
|
||||
from custom_components.irm_kmi.data import (CurrentWeatherData, IrmKmiForecast,
|
||||
ProcessedCoordinatorData)
|
||||
from custom_components.irm_kmi.radar_data import IrmKmiRadarForecast, RadarAnimationData
|
||||
from custom_components.irm_kmi.pollen import PollenParser
|
||||
from custom_components.irm_kmi.rain_graph import RainGraph
|
||||
from custom_components.irm_kmi.radar_data import IrmKmiRadarForecast
|
||||
from tests.conftest import get_api_data
|
||||
|
||||
|
||||
|
@ -267,27 +265,27 @@ def test_radar_forecast() -> None:
|
|||
|
||||
expected = [
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T17:00:00+01:00", native_precipitation=0, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T17:10:00+01:00", native_precipitation=0, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T17:20:00+01:00", native_precipitation=0, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T17:30:00+01:00", native_precipitation=0, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T17:40:00+01:00", native_precipitation=0.1, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T17:50:00+01:00", native_precipitation=0.01, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T18:00:00+01:00", native_precipitation=0.12, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T18:10:00+01:00", native_precipitation=1.2, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T18:20:00+01:00", native_precipitation=2, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T18:30:00+01:00", native_precipitation=0, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T18:40:00+01:00", native_precipitation=0, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0)
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min')
|
||||
]
|
||||
|
||||
assert expected == result
|
||||
|
@ -302,7 +300,8 @@ def test_radar_forecast_rain_interval() -> None:
|
|||
native_precipitation=0.89,
|
||||
might_rain=True,
|
||||
rain_forecast_max=1.12,
|
||||
rain_forecast_min=0.50
|
||||
rain_forecast_min=0.50,
|
||||
unit='mm/10min'
|
||||
)
|
||||
|
||||
_13 = IrmKmiRadarForecast(
|
||||
|
@ -310,7 +309,8 @@ def test_radar_forecast_rain_interval() -> None:
|
|||
native_precipitation=0.83,
|
||||
might_rain=True,
|
||||
rain_forecast_max=1.09,
|
||||
rain_forecast_min=0.64
|
||||
rain_forecast_min=0.64,
|
||||
unit='mm/10min'
|
||||
)
|
||||
|
||||
assert result[12] == _12
|
||||
|
|
159
tests/test_current_weather_sensors.py
Normal file
159
tests/test_current_weather_sensors.py
Normal file
|
@ -0,0 +1,159 @@
|
|||
import inspect
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import pytest
|
||||
from freezegun import freeze_time
|
||||
from homeassistant.core import HomeAssistant
|
||||
from pytest_homeassistant_custom_component.common import MockConfigEntry
|
||||
|
||||
from custom_components.irm_kmi import IrmKmiCoordinator
|
||||
from custom_components.irm_kmi.const import CURRENT_WEATHER_SENSORS, CURRENT_WEATHER_SENSOR_UNITS, \
|
||||
CURRENT_WEATHER_SENSOR_CLASS
|
||||
from custom_components.irm_kmi.data import CurrentWeatherData, ProcessedCoordinatorData
|
||||
from custom_components.irm_kmi.sensor import IrmKmiCurrentWeather, IrmKmiCurrentRainfall
|
||||
from tests.conftest import get_api_data
|
||||
|
||||
|
||||
def test_sensors_in_current_weather_data():
|
||||
weather_data_keys = inspect.get_annotations(CurrentWeatherData).keys()
|
||||
|
||||
for sensor in CURRENT_WEATHER_SENSORS:
|
||||
assert sensor in weather_data_keys
|
||||
|
||||
def test_sensors_have_unit():
|
||||
weather_sensor_units_keys = CURRENT_WEATHER_SENSOR_UNITS.keys()
|
||||
|
||||
for sensor in CURRENT_WEATHER_SENSORS:
|
||||
assert sensor in weather_sensor_units_keys
|
||||
|
||||
def test_sensors_have_class():
|
||||
weather_sensor_class_keys = CURRENT_WEATHER_SENSOR_CLASS.keys()
|
||||
|
||||
for sensor in CURRENT_WEATHER_SENSORS:
|
||||
assert sensor in weather_sensor_class_keys
|
||||
|
||||
|
||||
@pytest.mark.parametrize("sensor,expected,filename",
|
||||
[
|
||||
('temperature', -2, 'be_forecast_warning.json'),
|
||||
('temperature', 7, 'forecast.json'),
|
||||
('temperature', 15, 'forecast_ams_no_ww.json'),
|
||||
('temperature', 9, 'forecast_out_of_benelux.json'),
|
||||
('temperature', 13, 'forecast_with_rain_on_radar.json'),
|
||||
('temperature', 4, 'high_low_temp.json'),
|
||||
('temperature', 14, 'midnight-bug-31-05-2024T00-13.json'),
|
||||
('temperature', 13, 'no-midnight-bug-31-05-2024T01-55.json'),
|
||||
|
||||
('wind_speed', 10, 'be_forecast_warning.json'),
|
||||
('wind_speed', 5, 'forecast.json'),
|
||||
('wind_speed', 26, 'forecast_ams_no_ww.json'),
|
||||
('wind_speed', 25, 'forecast_out_of_benelux.json'),
|
||||
('wind_speed', 15, 'forecast_with_rain_on_radar.json'),
|
||||
('wind_speed', 30, 'high_low_temp.json'),
|
||||
('wind_speed', 10, 'midnight-bug-31-05-2024T00-13.json'),
|
||||
('wind_speed', 15, 'no-midnight-bug-31-05-2024T01-55.json'),
|
||||
|
||||
('wind_gust_speed', None, 'be_forecast_warning.json'),
|
||||
('wind_gust_speed', None, 'forecast.json'),
|
||||
('wind_gust_speed', None, 'forecast_ams_no_ww.json'),
|
||||
('wind_gust_speed', None, 'forecast_out_of_benelux.json'),
|
||||
('wind_gust_speed', None, 'forecast_with_rain_on_radar.json'),
|
||||
('wind_gust_speed', 50, 'high_low_temp.json'),
|
||||
('wind_gust_speed', None, 'midnight-bug-31-05-2024T00-13.json'),
|
||||
('wind_gust_speed', None, 'no-midnight-bug-31-05-2024T01-55.json'),
|
||||
|
||||
('wind_bearing', 23, 'be_forecast_warning.json'),
|
||||
('wind_bearing', 248, 'forecast.json'),
|
||||
('wind_bearing', 270, 'forecast_ams_no_ww.json'),
|
||||
('wind_bearing', 180, 'forecast_out_of_benelux.json'),
|
||||
('wind_bearing', 293, 'forecast_with_rain_on_radar.json'),
|
||||
('wind_bearing', 180, 'high_low_temp.json'),
|
||||
('wind_bearing', 293, 'midnight-bug-31-05-2024T00-13.json'),
|
||||
('wind_bearing', 270, 'no-midnight-bug-31-05-2024T01-55.json'),
|
||||
|
||||
('uv_index', 0.7, 'be_forecast_warning.json'),
|
||||
('uv_index', 0.7, 'forecast.json'),
|
||||
('uv_index', 6, 'forecast_ams_no_ww.json'),
|
||||
('uv_index', 0.6, 'forecast_out_of_benelux.json'),
|
||||
('uv_index', None, 'forecast_with_rain_on_radar.json'),
|
||||
('uv_index', 0.7, 'high_low_temp.json'),
|
||||
('uv_index', 5.6, 'midnight-bug-31-05-2024T00-13.json'),
|
||||
('uv_index', 5.6, 'no-midnight-bug-31-05-2024T01-55.json'),
|
||||
|
||||
('pressure', 1034, 'be_forecast_warning.json'),
|
||||
('pressure', 1020, 'forecast.json'),
|
||||
('pressure', 1010, 'forecast_ams_no_ww.json'),
|
||||
('pressure', 1013, 'forecast_out_of_benelux.json'),
|
||||
('pressure', 1006, 'forecast_with_rain_on_radar.json'),
|
||||
('pressure', 1022, 'high_low_temp.json'),
|
||||
('pressure', 1010, 'midnight-bug-31-05-2024T00-13.json'),
|
||||
('pressure', 1010, 'no-midnight-bug-31-05-2024T01-55.json'),
|
||||
|
||||
('rainfall', 0.42, 'be_forecast_warning.json'),
|
||||
('rainfall', 0.15, 'forecast_nl.json'),
|
||||
('rainfall', 0, 'forecast.json'),
|
||||
('rainfall', 0.1341, 'forecast_ams_no_ww.json'),
|
||||
('rainfall', 0, 'forecast_out_of_benelux.json'),
|
||||
('rainfall', 0.33, 'forecast_with_rain_on_radar.json'),
|
||||
('rainfall', 0, 'high_low_temp.json'),
|
||||
('rainfall', 0, 'midnight-bug-31-05-2024T00-13.json'),
|
||||
('rainfall', 0, 'no-midnight-bug-31-05-2024T01-55.json'),
|
||||
])
|
||||
async def test_current_weather_sensors(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
sensor,
|
||||
expected,
|
||||
filename
|
||||
) -> None:
|
||||
hass.config.time_zone = 'Europe/Brussels'
|
||||
|
||||
api_data = get_api_data(filename)
|
||||
time = api_data.get('obs').get('timestamp')
|
||||
|
||||
@freeze_time(datetime.fromisoformat(time) + timedelta(seconds=45, minutes=1))
|
||||
async def run(mock_config_entry_, sensor_, expected_):
|
||||
coordinator = IrmKmiCoordinator(hass, mock_config_entry_)
|
||||
coordinator.data = ProcessedCoordinatorData(
|
||||
current_weather=await IrmKmiCoordinator.current_weather_from_data(api_data),
|
||||
hourly_forecast=await IrmKmiCoordinator.hourly_list_to_forecast(api_data.get('for', {}).get('hourly')),
|
||||
radar_forecast=IrmKmiCoordinator.radar_list_to_forecast(api_data.get('animation', {})),
|
||||
country=api_data.get('country')
|
||||
)
|
||||
|
||||
if sensor_ == 'rainfall':
|
||||
s = IrmKmiCurrentRainfall(coordinator, mock_config_entry_)
|
||||
else:
|
||||
s = IrmKmiCurrentWeather(coordinator, mock_config_entry_, sensor_)
|
||||
|
||||
assert s.native_value == expected_
|
||||
|
||||
await run(mock_config_entry, sensor, expected)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("expected,filename",
|
||||
[
|
||||
('mm/h', 'forecast_ams_no_ww.json'),
|
||||
('mm/10min', 'forecast_out_of_benelux.json'),
|
||||
('mm/10min', 'forecast_with_rain_on_radar.json'),
|
||||
])
|
||||
async def test_current_rainfall_unit(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
expected,
|
||||
filename
|
||||
) -> None:
|
||||
hass.config.time_zone = 'Europe/Brussels'
|
||||
coordinator = IrmKmiCoordinator(hass, mock_config_entry)
|
||||
api_data = get_api_data(filename)
|
||||
|
||||
coordinator.data = ProcessedCoordinatorData(
|
||||
current_weather=await IrmKmiCoordinator.current_weather_from_data(api_data),
|
||||
hourly_forecast=await IrmKmiCoordinator.hourly_list_to_forecast(api_data.get('for', {}).get('hourly')),
|
||||
radar_forecast=IrmKmiCoordinator.radar_list_to_forecast(api_data.get('animation', {})),
|
||||
country=api_data.get('country')
|
||||
)
|
||||
|
||||
s = IrmKmiCurrentRainfall(coordinator, mock_config_entry)
|
||||
|
||||
assert s.native_unit_of_measurement == expected
|
|
@ -7,8 +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 (IrmKmiNextSunMove,
|
||||
IrmKmiNextWarning)
|
||||
from custom_components.irm_kmi.sensor import IrmKmiNextSunMove, IrmKmiNextWarning
|
||||
from tests.conftest import get_api_data
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ from unittest.mock import AsyncMock
|
|||
|
||||
from freezegun import freeze_time
|
||||
from homeassistant.components.weather import Forecast
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.core import HomeAssistant
|
||||
from pytest_homeassistant_custom_component.common import MockConfigEntry
|
||||
|
||||
|
@ -30,7 +29,7 @@ async def test_weather_nl(
|
|||
|
||||
coordinator = IrmKmiCoordinator(hass, mock_config_entry)
|
||||
await coordinator.async_refresh()
|
||||
|
||||
print(coordinator.data)
|
||||
weather = IrmKmiWeather(coordinator, mock_config_entry)
|
||||
result = await weather.async_forecast_daily()
|
||||
|
||||
|
@ -118,27 +117,27 @@ async def test_radar_forecast_service(
|
|||
|
||||
expected = [
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T17:00:00+01:00", native_precipitation=0, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T17:10:00+01:00", native_precipitation=0, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T17:20:00+01:00", native_precipitation=0, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T17:30:00+01:00", native_precipitation=0, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T17:40:00+01:00", native_precipitation=0.1, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T17:50:00+01:00", native_precipitation=0.01, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T18:00:00+01:00", native_precipitation=0.12, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T18:10:00+01:00", native_precipitation=1.2, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T18:20:00+01:00", native_precipitation=2, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T18:30:00+01:00", native_precipitation=0, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0),
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min'),
|
||||
IrmKmiRadarForecast(datetime="2023-12-26T18:40:00+01:00", native_precipitation=0, might_rain=False,
|
||||
rain_forecast_max=0, rain_forecast_min=0)
|
||||
rain_forecast_max=0, rain_forecast_min=0, unit='mm/10min')
|
||||
]
|
||||
|
||||
assert result_service == expected[5:]
|
||||
|
|
Loading…
Add table
Reference in a new issue