Skip to content

Commit

Permalink
fix(weather): repair forecasts in HA 2023.8
Browse files Browse the repository at this point in the history
Fix #82
  • Loading branch information
IATkachenko committed Aug 6, 2023
1 parent 742dad4 commit 66162fd
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 21 deletions.
2 changes: 2 additions & 0 deletions custom_components/yandex_weather/updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from homeassistant.components.weather import (
ATTR_FORECAST,
ATTR_FORECAST_CONDITION,
ATTR_FORECAST_IS_DAYTIME,
ATTR_FORECAST_NATIVE_PRECIPITATION,
ATTR_FORECAST_NATIVE_PRESSURE,
ATTR_FORECAST_NATIVE_TEMP,
Expand Down Expand Up @@ -266,6 +267,7 @@ async def update(self):
f_datetime += timedelta(hours=24 / 4)
forecast = Forecast(datetime=f_datetime.isoformat())
self.process_data(forecast, f, FORECAST_ATTRIBUTE_TRANSLATION)
forecast[ATTR_FORECAST_IS_DAYTIME] = f["daytime"] == "d"
result[ATTR_FORECAST].append(forecast)
result[ATTR_API_FORECAST_ICONS].append(f.get("icon", "no_image"))

Expand Down
67 changes: 46 additions & 21 deletions custom_components/yandex_weather/weather.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@

from homeassistant.components.weather import (
ATTR_FORECAST,
ATTR_FORECAST_IS_DAYTIME,
ATTR_WEATHER_PRECIPITATION_UNIT,
ATTR_WEATHER_PRESSURE_UNIT,
ATTR_WEATHER_TEMPERATURE_UNIT,
ATTR_WEATHER_WIND_SPEED_UNIT,
UNIT_CONVERSIONS,
Forecast,
WeatherEntity,
WeatherEntityFeature,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
Expand Down Expand Up @@ -76,6 +79,7 @@ class YandexWeather(WeatherEntity, CoordinatorEntity, RestoreEntity):
_attr_native_pressure_unit = PRESSURE_HPA
_attr_native_temperature_unit = TEMP_CELSIUS
_attr_native_precipitation_unit = LENGTH_MILLIMETERS
_twice_daily_forecast: list[Forecast] | None
coordinator: WeatherUpdater

def __init__(
Expand All @@ -95,6 +99,7 @@ def __init__(
self._attr_condition = None
self._attr_unique_id = config_entry.unique_id
self._attr_device_info = self.coordinator.device_info
self._attr_supported_features = WeatherEntityFeature.FORECAST_TWICE_DAILY
self._image_source = get_value(config_entry, CONF_IMAGE_SOURCE, "Yandex")

async def async_added_to_hass(self) -> None:
Expand All @@ -120,24 +125,27 @@ async def async_added_to_hass(self) -> None:
("pressure", UNIT_CONVERSIONS[ATTR_WEATHER_PRESSURE_UNIT]),
("wind_speed", UNIT_CONVERSIONS[ATTR_WEATHER_WIND_SPEED_UNIT]),
]:
setattr(
self,
f"_attr_native_{attribute}",
converter(
state.attributes.get(attribute),
state.attributes.get(
f"_{attribute}_unit",
try:
setattr(
self,
f"_attr_native_{attribute}",
converter(
state.attributes.get(attribute),
state.attributes.get(
f"_{attribute}_unit",
getattr(self, f"_attr_native_{attribute}_unit"),
),
getattr(self, f"_attr_native_{attribute}_unit"),
),
getattr(self, f"_attr_native_{attribute}_unit"),
),
)
)
except TypeError:
pass

self._attr_humidity = state.attributes.get("humidity")
self._attr_wind_bearing = state.attributes.get("wind_bearing")
self._attr_entity_picture = state.attributes.get("entity_picture")
self._attr_forecast = state.attributes.get(ATTR_FORECAST)
for f in self._attr_forecast:
self._twice_daily_forecast = state.attributes.get(ATTR_FORECAST, [])
for f in self._twice_daily_forecast:
for (attribute, converter) in [
("temperature", UNIT_CONVERSIONS[ATTR_WEATHER_TEMPERATURE_UNIT]),
("pressure", UNIT_CONVERSIONS[ATTR_WEATHER_PRESSURE_UNIT]),
Expand All @@ -147,15 +155,19 @@ async def async_added_to_hass(self) -> None:
UNIT_CONVERSIONS[ATTR_WEATHER_PRECIPITATION_UNIT],
),
]:
f[attribute] = converter(
f.get(attribute),
getattr(
self,
f"_{attribute}_unit",
try:
f[attribute] = converter(
f.get(attribute),
getattr(
self,
f"_{attribute}_unit",
getattr(self, f"_attr_native_{attribute}_unit"),
),
getattr(self, f"_attr_native_{attribute}_unit"),
),
getattr(self, f"_attr_native_{attribute}_unit"),
)
)
except TypeError:
pass
self._attr_forecast = self._twice_daily_forecast # backward compatibility
self._attr_extra_state_attributes = {}
for attribute in [
"feels_like",
Expand Down Expand Up @@ -193,7 +205,8 @@ def _handle_coordinator_update(self) -> None:
is_day=self.coordinator.data.get("daytime") == "d",
image=self.coordinator.data.get(ATTR_API_IMAGE),
)
self._attr_forecast = self.coordinator.data.get(ATTR_FORECAST)
self._twice_daily_forecast = self.coordinator.data.get(ATTR_FORECAST, [])
self._attr_forecast = self._twice_daily_forecast # backward compatibility
self._attr_humidity = self.coordinator.data.get(ATTR_API_HUMIDITY)
self._attr_native_pressure = self.coordinator.data.get(ATTR_API_PRESSURE)
self._attr_native_temperature = self.coordinator.data.get(ATTR_API_TEMPERATURE)
Expand Down Expand Up @@ -231,3 +244,15 @@ def condition(self, new_condition: str):
)

self._attr_condition = new_condition

async def async_forecast_twice_daily(self) -> list[Forecast] | None:
"""Return the daily forecast in native units."""
_LOGGER.debug(f"async_forecast_twice_daily: {self._twice_daily_forecast=}")
# we must return at least three elements in forecast
# https://github.com/home-assistant/frontend/blob/dev/src/data/weather.ts#L548
if len(result := self._twice_daily_forecast) < 3:
_LOGGER.debug(
"Have not enough forecast data. Adding empty element to forecast..."
)
result.append({ATTR_FORECAST_IS_DAYTIME: False})
return result

0 comments on commit 66162fd

Please sign in to comment.