Fix openweathermap forecast sensors (#74513)
parent
519d15428c
commit
9d3dde60ff
|
@ -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,
|
||||||
),
|
),
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue