mirror of
https://github.com/jdejaegh/irm-kmi-ha.git
synced 2025-06-27 03:35:56 +02:00
Add rainfall sensor and tests
This commit is contained in:
parent
1844d02639
commit
be0a7425d4
15 changed files with 242 additions and 40 deletions
|
@ -185,5 +185,5 @@ CURRENT_WEATHER_SENSOR_ICON: Final = {'temperature': None,
|
||||||
'wind_speed': None,
|
'wind_speed': None,
|
||||||
'wind_gust_speed': None,
|
'wind_gust_speed': None,
|
||||||
'wind_bearing': 'mdi:compass',
|
'wind_bearing': 'mdi:compass',
|
||||||
'uv_index': None,
|
'uv_index': 'mdi:sun-wireless',
|
||||||
'pressure': None}
|
'pressure': None}
|
||||||
|
|
|
@ -327,6 +327,7 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator):
|
||||||
if data is None:
|
if data is None:
|
||||||
return None
|
return None
|
||||||
sequence = data.get("sequence", [])
|
sequence = data.get("sequence", [])
|
||||||
|
unit = data.get("unit", {}).get("en", None)
|
||||||
ratios = [f['value'] / f['position'] for f in sequence if f['position'] > 0]
|
ratios = [f['value'] / f['position'] for f in sequence if f['position'] > 0]
|
||||||
|
|
||||||
if len(ratios) > 0:
|
if len(ratios) > 0:
|
||||||
|
@ -342,7 +343,8 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator):
|
||||||
native_precipitation=f.get('value'),
|
native_precipitation=f.get('value'),
|
||||||
rain_forecast_max=round(f.get('positionHigher') * ratio, 2),
|
rain_forecast_max=round(f.get('positionHigher') * ratio, 2),
|
||||||
rain_forecast_min=round(f.get('positionLower') * 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
|
return forecast
|
||||||
|
|
|
@ -11,6 +11,7 @@ class IrmKmiRadarForecast(Forecast):
|
||||||
rain_forecast_max: float
|
rain_forecast_max: float
|
||||||
rain_forecast_min: float
|
rain_forecast_min: float
|
||||||
might_rain: bool
|
might_rain: bool
|
||||||
|
unit: str | None
|
||||||
|
|
||||||
|
|
||||||
class AnimationFrameData(TypedDict, total=False):
|
class AnimationFrameData(TypedDict, total=False):
|
||||||
|
|
|
@ -15,6 +15,7 @@ from custom_components.irm_kmi.const import POLLEN_NAMES, POLLEN_TO_ICON_MAP, CU
|
||||||
CURRENT_WEATHER_SENSOR_CLASS, CURRENT_WEATHER_SENSORS, CURRENT_WEATHER_SENSOR_ICON
|
CURRENT_WEATHER_SENSOR_CLASS, CURRENT_WEATHER_SENSORS, CURRENT_WEATHER_SENSOR_ICON
|
||||||
from custom_components.irm_kmi.data import IrmKmiForecast
|
from custom_components.irm_kmi.data import IrmKmiForecast
|
||||||
from custom_components.irm_kmi.pollen import PollenParser
|
from custom_components.irm_kmi.pollen import PollenParser
|
||||||
|
from custom_components.irm_kmi.radar_data import IrmKmiRadarForecast
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -24,7 +25,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_e
|
||||||
coordinator = hass.data[DOMAIN][entry.entry_id]
|
coordinator = hass.data[DOMAIN][entry.entry_id]
|
||||||
async_add_entities([IrmKmiPollen(coordinator, entry, pollen.lower()) for pollen in POLLEN_NAMES])
|
async_add_entities([IrmKmiPollen(coordinator, entry, pollen.lower()) for pollen in POLLEN_NAMES])
|
||||||
async_add_entities([IrmKmiCurrentWeather(coordinator, entry, name) for name in CURRENT_WEATHER_SENSORS])
|
async_add_entities([IrmKmiCurrentWeather(coordinator, entry, name) for name in CURRENT_WEATHER_SENSORS])
|
||||||
async_add_entities([IrmKmiNextWarning(coordinator, entry),])
|
async_add_entities([IrmKmiNextWarning(coordinator, entry),
|
||||||
|
IrmKmiCurrentRainfall(coordinator, entry)])
|
||||||
|
|
||||||
if coordinator.data.get('country') != 'NL':
|
if coordinator.data.get('country') != 'NL':
|
||||||
async_add_entities([IrmKmiNextSunMove(coordinator, entry, move) for move in ['sunset', 'sunrise']])
|
async_add_entities([IrmKmiNextSunMove(coordinator, entry, move) for move in ['sunset', 'sunrise']])
|
||||||
|
@ -152,7 +154,7 @@ class IrmKmiCurrentWeather(CoordinatorEntity, SensorEntity):
|
||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
SensorEntity.__init__(self)
|
SensorEntity.__init__(self)
|
||||||
self._attr_unique_id = f"{entry.entry_id}-current-{sensor_name}"
|
self._attr_unique_id = f"{entry.entry_id}-current-{sensor_name}"
|
||||||
self.entity_id = sensor.ENTITY_ID_FORMAT.format(f"{str(entry.title).lower()}_next_{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_device_info = coordinator.shared_device_info
|
||||||
self._attr_translation_key = f"current_{sensor_name}"
|
self._attr_translation_key = f"current_{sensor_name}"
|
||||||
self._sensor_name: str = sensor_name
|
self._sensor_name: str = sensor_name
|
||||||
|
@ -173,3 +175,55 @@ class IrmKmiCurrentWeather(CoordinatorEntity, SensorEntity):
|
||||||
@property
|
@property
|
||||||
def icon(self) -> str | None:
|
def icon(self) -> str | None:
|
||||||
return CURRENT_WEATHER_SENSOR_ICON[self._sensor_name]
|
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)
|
|
@ -200,6 +200,9 @@
|
||||||
},
|
},
|
||||||
"current_pressure": {
|
"current_pressure": {
|
||||||
"name": "Atmospheric pressure"
|
"name": "Atmospheric pressure"
|
||||||
|
},
|
||||||
|
"current_rainfall": {
|
||||||
|
"name": "Rainfall"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -200,6 +200,9 @@
|
||||||
},
|
},
|
||||||
"current_pressure": {
|
"current_pressure": {
|
||||||
"name": "Pression atmosphérique"
|
"name": "Pression atmosphérique"
|
||||||
|
},
|
||||||
|
"current_rainfall": {
|
||||||
|
"name": "Precipitation"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -200,6 +200,9 @@
|
||||||
},
|
},
|
||||||
"current_pressure": {
|
"current_pressure": {
|
||||||
"name": "Luchtdruk"
|
"name": "Luchtdruk"
|
||||||
|
},
|
||||||
|
"current_rainfall": {
|
||||||
|
"name": "Neerslag"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -200,6 +200,9 @@
|
||||||
},
|
},
|
||||||
"current_pressure": {
|
"current_pressure": {
|
||||||
"name": "Pressão atmosférica"
|
"name": "Pressão atmosférica"
|
||||||
|
},
|
||||||
|
"current_rainfall": {
|
||||||
|
"name": "Precipitação"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
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",
|
"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",
|
"uri": "https:\/\/app.meteo.be\/services\/appv4\/?s=getIncaImage&i=202401120920&f=2&k=2160a92594985471351907ee5cc75d1f&d=202401120900",
|
||||||
"value": 0,
|
"value": 0.42,
|
||||||
"position": 0,
|
"position": 0,
|
||||||
"positionLower": 0,
|
"positionLower": 0,
|
||||||
"positionHigher": 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",
|
"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",
|
"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,
|
"position": 0,
|
||||||
"positionLower": 0,
|
"positionLower": 0,
|
||||||
"positionHigher": 0
|
"positionHigher": 0
|
||||||
|
|
4
tests/fixtures/forecast_nl.json
vendored
4
tests/fixtures/forecast_nl.json
vendored
|
@ -6,7 +6,7 @@
|
||||||
"municipality_code": "0995",
|
"municipality_code": "0995",
|
||||||
"temp": 11,
|
"temp": 11,
|
||||||
"windSpeedKm": 40,
|
"windSpeedKm": 40,
|
||||||
"timestamp": "2023-12-28T14:20:00+00:00",
|
"timestamp": "2023-12-28T14:30:00+00:00",
|
||||||
"windDirection": 45,
|
"windDirection": 45,
|
||||||
"municipality": "Lelystad",
|
"municipality": "Lelystad",
|
||||||
"windDirectionText": {
|
"windDirectionText": {
|
||||||
|
@ -1337,7 +1337,7 @@
|
||||||
{
|
{
|
||||||
"time": "2023-12-28T14:25:00+00:00",
|
"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",
|
"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,
|
"position": 0,
|
||||||
"positionLower": 0,
|
"positionLower": 0,
|
||||||
"positionHigher": 0
|
"positionHigher": 0
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import zoneinfo
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from freezegun import freeze_time
|
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.coordinator import IrmKmiCoordinator
|
||||||
from custom_components.irm_kmi.data import (CurrentWeatherData, IrmKmiForecast,
|
from custom_components.irm_kmi.data import (CurrentWeatherData, IrmKmiForecast,
|
||||||
ProcessedCoordinatorData)
|
ProcessedCoordinatorData)
|
||||||
from custom_components.irm_kmi.radar_data import IrmKmiRadarForecast, RadarAnimationData
|
|
||||||
from custom_components.irm_kmi.pollen import PollenParser
|
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
|
from tests.conftest import get_api_data
|
||||||
|
|
||||||
|
|
||||||
|
@ -267,27 +265,27 @@ def test_radar_forecast() -> None:
|
||||||
|
|
||||||
expected = [
|
expected = [
|
||||||
IrmKmiRadarForecast(datetime="2023-12-26T17:00:00+01:00", native_precipitation=0, might_rain=False,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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
|
assert expected == result
|
||||||
|
@ -302,7 +300,8 @@ def test_radar_forecast_rain_interval() -> None:
|
||||||
native_precipitation=0.89,
|
native_precipitation=0.89,
|
||||||
might_rain=True,
|
might_rain=True,
|
||||||
rain_forecast_max=1.12,
|
rain_forecast_max=1.12,
|
||||||
rain_forecast_min=0.50
|
rain_forecast_min=0.50,
|
||||||
|
unit='mm/10min'
|
||||||
)
|
)
|
||||||
|
|
||||||
_13 = IrmKmiRadarForecast(
|
_13 = IrmKmiRadarForecast(
|
||||||
|
@ -310,7 +309,8 @@ def test_radar_forecast_rain_interval() -> None:
|
||||||
native_precipitation=0.83,
|
native_precipitation=0.83,
|
||||||
might_rain=True,
|
might_rain=True,
|
||||||
rain_forecast_max=1.09,
|
rain_forecast_max=1.09,
|
||||||
rain_forecast_min=0.64
|
rain_forecast_min=0.64,
|
||||||
|
unit='mm/10min'
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result[12] == _12
|
assert result[12] == _12
|
||||||
|
|
|
@ -1,8 +1,18 @@
|
||||||
import inspect
|
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, \
|
from custom_components.irm_kmi.const import CURRENT_WEATHER_SENSORS, CURRENT_WEATHER_SENSOR_UNITS, \
|
||||||
CURRENT_WEATHER_SENSOR_CLASS
|
CURRENT_WEATHER_SENSOR_CLASS
|
||||||
from custom_components.irm_kmi.data import CurrentWeatherData
|
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():
|
def test_sensors_in_current_weather_data():
|
||||||
weather_data_keys = inspect.get_annotations(CurrentWeatherData).keys()
|
weather_data_keys = inspect.get_annotations(CurrentWeatherData).keys()
|
||||||
|
@ -22,3 +32,128 @@ def test_sensors_have_class():
|
||||||
for sensor in CURRENT_WEATHER_SENSORS:
|
for sensor in CURRENT_WEATHER_SENSORS:
|
||||||
assert sensor in weather_sensor_class_keys
|
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 import IrmKmiCoordinator
|
||||||
from custom_components.irm_kmi.binary_sensor import IrmKmiWarning
|
from custom_components.irm_kmi.binary_sensor import IrmKmiWarning
|
||||||
from custom_components.irm_kmi.const import CONF_LANGUAGE_OVERRIDE
|
from custom_components.irm_kmi.const import CONF_LANGUAGE_OVERRIDE
|
||||||
from custom_components.irm_kmi.sensor import (IrmKmiNextSunMove,
|
from custom_components.irm_kmi.sensor import IrmKmiNextSunMove, IrmKmiNextWarning
|
||||||
IrmKmiNextWarning)
|
|
||||||
from tests.conftest import get_api_data
|
from tests.conftest import get_api_data
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ from unittest.mock import AsyncMock
|
||||||
|
|
||||||
from freezegun import freeze_time
|
from freezegun import freeze_time
|
||||||
from homeassistant.components.weather import Forecast
|
from homeassistant.components.weather import Forecast
|
||||||
from homeassistant.config_entries import ConfigEntryState
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from pytest_homeassistant_custom_component.common import MockConfigEntry
|
from pytest_homeassistant_custom_component.common import MockConfigEntry
|
||||||
|
|
||||||
|
@ -30,7 +29,7 @@ async def test_weather_nl(
|
||||||
|
|
||||||
coordinator = IrmKmiCoordinator(hass, mock_config_entry)
|
coordinator = IrmKmiCoordinator(hass, mock_config_entry)
|
||||||
await coordinator.async_refresh()
|
await coordinator.async_refresh()
|
||||||
|
print(coordinator.data)
|
||||||
weather = IrmKmiWeather(coordinator, mock_config_entry)
|
weather = IrmKmiWeather(coordinator, mock_config_entry)
|
||||||
result = await weather.async_forecast_daily()
|
result = await weather.async_forecast_daily()
|
||||||
|
|
||||||
|
@ -118,27 +117,27 @@ async def test_radar_forecast_service(
|
||||||
|
|
||||||
expected = [
|
expected = [
|
||||||
IrmKmiRadarForecast(datetime="2023-12-26T17:00:00+01:00", native_precipitation=0, might_rain=False,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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:]
|
assert result_service == expected[5:]
|
||||||
|
|
Loading…
Add table
Reference in a new issue