Fix openweathermap forecast sensors (#74513)

pull/74522/head
Erik Montnemery 2022-07-06 17:49:06 +02:00 committed by Franck Nijhof
parent 519d15428c
commit 9d3dde60ff
No known key found for this signature in database
GPG Key ID: D62583BA8AB11CA3
3 changed files with 74 additions and 39 deletions

View File

@ -21,9 +21,6 @@ from homeassistant.components.weather import (
ATTR_CONDITION_SUNNY, ATTR_CONDITION_SUNNY,
ATTR_CONDITION_WINDY, ATTR_CONDITION_WINDY,
ATTR_CONDITION_WINDY_VARIANT, ATTR_CONDITION_WINDY_VARIANT,
ATTR_FORECAST_CONDITION,
ATTR_FORECAST_PRECIPITATION_PROBABILITY,
ATTR_FORECAST_TIME,
) )
from homeassistant.const import ( from homeassistant.const import (
DEGREE, DEGREE,
@ -68,10 +65,15 @@ ATTR_API_FORECAST = "forecast"
UPDATE_LISTENER = "update_listener" UPDATE_LISTENER = "update_listener"
PLATFORMS = [Platform.SENSOR, Platform.WEATHER] PLATFORMS = [Platform.SENSOR, Platform.WEATHER]
ATTR_FORECAST_PRECIPITATION = "precipitation" ATTR_API_FORECAST_CONDITION = "condition"
ATTR_FORECAST_PRESSURE = "pressure" ATTR_API_FORECAST_PRECIPITATION = "precipitation"
ATTR_FORECAST_TEMP = "temperature" ATTR_API_FORECAST_PRECIPITATION_PROBABILITY = "precipitation_probability"
ATTR_FORECAST_TEMP_LOW = "templow" ATTR_API_FORECAST_PRESSURE = "pressure"
ATTR_API_FORECAST_TEMP = "temperature"
ATTR_API_FORECAST_TEMP_LOW = "templow"
ATTR_API_FORECAST_TIME = "datetime"
ATTR_API_FORECAST_WIND_BEARING = "wind_bearing"
ATTR_API_FORECAST_WIND_SPEED = "wind_speed"
FORECAST_MODE_HOURLY = "hourly" FORECAST_MODE_HOURLY = "hourly"
FORECAST_MODE_DAILY = "daily" FORECAST_MODE_DAILY = "daily"
@ -263,39 +265,39 @@ WEATHER_SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
) )
FORECAST_SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( FORECAST_SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
SensorEntityDescription( SensorEntityDescription(
key=ATTR_FORECAST_CONDITION, key=ATTR_API_FORECAST_CONDITION,
name="Condition", name="Condition",
), ),
SensorEntityDescription( SensorEntityDescription(
key=ATTR_FORECAST_PRECIPITATION, key=ATTR_API_FORECAST_PRECIPITATION,
name="Precipitation", name="Precipitation",
native_unit_of_measurement=LENGTH_MILLIMETERS, native_unit_of_measurement=LENGTH_MILLIMETERS,
), ),
SensorEntityDescription( SensorEntityDescription(
key=ATTR_FORECAST_PRECIPITATION_PROBABILITY, key=ATTR_API_FORECAST_PRECIPITATION_PROBABILITY,
name="Precipitation probability", name="Precipitation probability",
native_unit_of_measurement=PERCENTAGE, native_unit_of_measurement=PERCENTAGE,
), ),
SensorEntityDescription( SensorEntityDescription(
key=ATTR_FORECAST_PRESSURE, key=ATTR_API_FORECAST_PRESSURE,
name="Pressure", name="Pressure",
native_unit_of_measurement=PRESSURE_HPA, native_unit_of_measurement=PRESSURE_HPA,
device_class=SensorDeviceClass.PRESSURE, device_class=SensorDeviceClass.PRESSURE,
), ),
SensorEntityDescription( SensorEntityDescription(
key=ATTR_FORECAST_TEMP, key=ATTR_API_FORECAST_TEMP,
name="Temperature", name="Temperature",
native_unit_of_measurement=TEMP_CELSIUS, native_unit_of_measurement=TEMP_CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
), ),
SensorEntityDescription( SensorEntityDescription(
key=ATTR_FORECAST_TEMP_LOW, key=ATTR_API_FORECAST_TEMP_LOW,
name="Temperature Low", name="Temperature Low",
native_unit_of_measurement=TEMP_CELSIUS, native_unit_of_measurement=TEMP_CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
), ),
SensorEntityDescription( SensorEntityDescription(
key=ATTR_FORECAST_TIME, key=ATTR_API_FORECAST_TIME,
name="Time", name="Time",
device_class=SensorDeviceClass.TIMESTAMP, device_class=SensorDeviceClass.TIMESTAMP,
), ),

View File

@ -1,7 +1,20 @@
"""Support for the OpenWeatherMap (OWM) service.""" """Support for the OpenWeatherMap (OWM) service."""
from __future__ import annotations from __future__ import annotations
from homeassistant.components.weather import Forecast, WeatherEntity from typing import cast
from homeassistant.components.weather import (
ATTR_FORECAST_CONDITION,
ATTR_FORECAST_NATIVE_PRECIPITATION,
ATTR_FORECAST_NATIVE_TEMP,
ATTR_FORECAST_NATIVE_TEMP_LOW,
ATTR_FORECAST_NATIVE_WIND_SPEED,
ATTR_FORECAST_PRECIPITATION_PROBABILITY,
ATTR_FORECAST_TIME,
ATTR_FORECAST_WIND_BEARING,
Forecast,
WeatherEntity,
)
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
LENGTH_MILLIMETERS, LENGTH_MILLIMETERS,
@ -17,6 +30,14 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import ( from .const import (
ATTR_API_CONDITION, ATTR_API_CONDITION,
ATTR_API_FORECAST, ATTR_API_FORECAST,
ATTR_API_FORECAST_CONDITION,
ATTR_API_FORECAST_PRECIPITATION,
ATTR_API_FORECAST_PRECIPITATION_PROBABILITY,
ATTR_API_FORECAST_TEMP,
ATTR_API_FORECAST_TEMP_LOW,
ATTR_API_FORECAST_TIME,
ATTR_API_FORECAST_WIND_BEARING,
ATTR_API_FORECAST_WIND_SPEED,
ATTR_API_HUMIDITY, ATTR_API_HUMIDITY,
ATTR_API_PRESSURE, ATTR_API_PRESSURE,
ATTR_API_TEMPERATURE, ATTR_API_TEMPERATURE,
@ -31,6 +52,17 @@ from .const import (
) )
from .weather_update_coordinator import WeatherUpdateCoordinator from .weather_update_coordinator import WeatherUpdateCoordinator
FORECAST_MAP = {
ATTR_API_FORECAST_CONDITION: ATTR_FORECAST_CONDITION,
ATTR_API_FORECAST_PRECIPITATION: ATTR_FORECAST_NATIVE_PRECIPITATION,
ATTR_API_FORECAST_PRECIPITATION_PROBABILITY: ATTR_FORECAST_PRECIPITATION_PROBABILITY,
ATTR_API_FORECAST_TEMP_LOW: ATTR_FORECAST_NATIVE_TEMP_LOW,
ATTR_API_FORECAST_TEMP: ATTR_FORECAST_NATIVE_TEMP,
ATTR_API_FORECAST_TIME: ATTR_FORECAST_TIME,
ATTR_API_FORECAST_WIND_BEARING: ATTR_FORECAST_WIND_BEARING,
ATTR_API_FORECAST_WIND_SPEED: ATTR_FORECAST_NATIVE_WIND_SPEED,
}
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
@ -109,7 +141,12 @@ class OpenWeatherMapWeather(WeatherEntity):
@property @property
def forecast(self) -> list[Forecast] | None: def forecast(self) -> list[Forecast] | None:
"""Return the forecast array.""" """Return the forecast array."""
return self._weather_coordinator.data[ATTR_API_FORECAST] api_forecasts = self._weather_coordinator.data[ATTR_API_FORECAST]
forecasts = [
{ha_key: forecast[api_key] for api_key, ha_key in FORECAST_MAP.items()}
for forecast in api_forecasts
]
return cast(list[Forecast], forecasts)
@property @property
def available(self) -> bool: def available(self) -> bool:

View File

@ -8,15 +8,6 @@ from pyowm.commons.exceptions import APIRequestError, UnauthorizedError
from homeassistant.components.weather import ( from homeassistant.components.weather import (
ATTR_CONDITION_CLEAR_NIGHT, ATTR_CONDITION_CLEAR_NIGHT,
ATTR_CONDITION_SUNNY, ATTR_CONDITION_SUNNY,
ATTR_FORECAST_CONDITION,
ATTR_FORECAST_NATIVE_PRECIPITATION,
ATTR_FORECAST_NATIVE_PRESSURE,
ATTR_FORECAST_NATIVE_TEMP,
ATTR_FORECAST_NATIVE_TEMP_LOW,
ATTR_FORECAST_NATIVE_WIND_SPEED,
ATTR_FORECAST_PRECIPITATION_PROBABILITY,
ATTR_FORECAST_TIME,
ATTR_FORECAST_WIND_BEARING,
) )
from homeassistant.helpers import sun from homeassistant.helpers import sun
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
@ -29,6 +20,15 @@ from .const import (
ATTR_API_DEW_POINT, ATTR_API_DEW_POINT,
ATTR_API_FEELS_LIKE_TEMPERATURE, ATTR_API_FEELS_LIKE_TEMPERATURE,
ATTR_API_FORECAST, ATTR_API_FORECAST,
ATTR_API_FORECAST_CONDITION,
ATTR_API_FORECAST_PRECIPITATION,
ATTR_API_FORECAST_PRECIPITATION_PROBABILITY,
ATTR_API_FORECAST_PRESSURE,
ATTR_API_FORECAST_TEMP,
ATTR_API_FORECAST_TEMP_LOW,
ATTR_API_FORECAST_TIME,
ATTR_API_FORECAST_WIND_BEARING,
ATTR_API_FORECAST_WIND_SPEED,
ATTR_API_HUMIDITY, ATTR_API_HUMIDITY,
ATTR_API_PRECIPITATION_KIND, ATTR_API_PRECIPITATION_KIND,
ATTR_API_PRESSURE, ATTR_API_PRESSURE,
@ -158,19 +158,19 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator):
def _convert_forecast(self, entry): def _convert_forecast(self, entry):
"""Convert the forecast data.""" """Convert the forecast data."""
forecast = { forecast = {
ATTR_FORECAST_TIME: dt.utc_from_timestamp( ATTR_API_FORECAST_TIME: dt.utc_from_timestamp(
entry.reference_time("unix") entry.reference_time("unix")
).isoformat(), ).isoformat(),
ATTR_FORECAST_NATIVE_PRECIPITATION: self._calc_precipitation( ATTR_API_FORECAST_PRECIPITATION: self._calc_precipitation(
entry.rain, entry.snow entry.rain, entry.snow
), ),
ATTR_FORECAST_PRECIPITATION_PROBABILITY: ( ATTR_API_FORECAST_PRECIPITATION_PROBABILITY: (
round(entry.precipitation_probability * 100) round(entry.precipitation_probability * 100)
), ),
ATTR_FORECAST_NATIVE_PRESSURE: entry.pressure.get("press"), ATTR_API_FORECAST_PRESSURE: entry.pressure.get("press"),
ATTR_FORECAST_NATIVE_WIND_SPEED: entry.wind().get("speed"), ATTR_API_FORECAST_WIND_SPEED: entry.wind().get("speed"),
ATTR_FORECAST_WIND_BEARING: entry.wind().get("deg"), ATTR_API_FORECAST_WIND_BEARING: entry.wind().get("deg"),
ATTR_FORECAST_CONDITION: self._get_condition( ATTR_API_FORECAST_CONDITION: self._get_condition(
entry.weather_code, entry.reference_time("unix") entry.weather_code, entry.reference_time("unix")
), ),
ATTR_API_CLOUDS: entry.clouds, ATTR_API_CLOUDS: entry.clouds,
@ -178,16 +178,12 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator):
temperature_dict = entry.temperature("celsius") temperature_dict = entry.temperature("celsius")
if "max" in temperature_dict and "min" in temperature_dict: if "max" in temperature_dict and "min" in temperature_dict:
forecast[ATTR_FORECAST_NATIVE_TEMP] = entry.temperature("celsius").get( forecast[ATTR_API_FORECAST_TEMP] = entry.temperature("celsius").get("max")
"max" forecast[ATTR_API_FORECAST_TEMP_LOW] = entry.temperature("celsius").get(
)
forecast[ATTR_FORECAST_NATIVE_TEMP_LOW] = entry.temperature("celsius").get(
"min" "min"
) )
else: else:
forecast[ATTR_FORECAST_NATIVE_TEMP] = entry.temperature("celsius").get( forecast[ATTR_API_FORECAST_TEMP] = entry.temperature("celsius").get("temp")
"temp"
)
return forecast return forecast