From ec9d774a00330b0bb5dc2301f2f0280a4eb1a6d8 Mon Sep 17 00:00:00 2001 From: Guy Khmelnitsky <3136012+GuyKh@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:32:13 +0300 Subject: [PATCH] fix: Weather forecast with correct timezone (#113) * fix: Minor style fixes * fix: Weather forecast with correct timezone * Align changes from version 0.34.0 --- custom_components/ims/__init__.py | 6 +++--- custom_components/ims/manifest.json | 4 ++-- custom_components/ims/sensor.py | 3 +-- custom_components/ims/weather.py | 7 ++++--- custom_components/ims/weather_update_coordinator.py | 10 ++++++---- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/custom_components/ims/__init__.py b/custom_components/ims/__init__.py index a27b74b..7a637ac 100644 --- a/custom_components/ims/__init__.py +++ b/custom_components/ims/__init__.py @@ -95,13 +95,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: if (IMS_PLATFORMS[0] in ims_entity_platform) and ( IMS_PLATFORMS[1] in ims_entity_platform ): - await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) + hass.async_create_task(hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)) # If only sensor elif IMS_PLATFORMS[0] in ims_entity_platform: - await hass.config_entries.async_forward_entry_setups(entry, [PLATFORMS[0], PLATFORMS[2]]) + hass.async_create_task(hass.config_entries.async_forward_entry_setups(entry, [PLATFORMS[0], PLATFORMS[2]])) # If only weather elif IMS_PLATFORMS[1] in ims_entity_platform: - await hass.config_entries.async_forward_entry_setup(entry, [PLATFORMS[1]]) + hass.async_create_task(hass.config_entries.async_forward_entry_setup(entry, [PLATFORMS[1]])) update_listener = entry.add_update_listener(async_update_options) hass.data[DOMAIN][entry.entry_id][UPDATE_LISTENER] = update_listener diff --git a/custom_components/ims/manifest.json b/custom_components/ims/manifest.json index e330f02..e3b946a 100644 --- a/custom_components/ims/manifest.json +++ b/custom_components/ims/manifest.json @@ -6,6 +6,6 @@ "documentation": "https://github.com/GuyKh/ims-custom-component", "iot_class": "cloud_polling", "issue_tracker": "https://github.com/GuyKh/ims-custom-component/issues", - "requirements": ["weatheril>=0.33.0"], - "version": "0.1.28" + "requirements": ["weatheril>=0.34.0"], + "version": "0.1.29" } diff --git a/custom_components/ims/sensor.py b/custom_components/ims/sensor.py index 91d4d34..220848b 100644 --- a/custom_components/ims/sensor.py +++ b/custom_components/ims/sensor.py @@ -18,6 +18,7 @@ from . import ImsEntity, ImsSensorEntityDescription from .const import ( DOMAIN, + PLATFORMS, IMS_PLATFORMS, IMS_PLATFORM, ENTRY_WEATHER_COORDINATOR, @@ -203,7 +204,6 @@ SENSOR_DESCRIPTIONS_KEYS = [desc.key for desc in SENSOR_DESCRIPTIONS] weather = None -timezone = dt_util.get_time_zone('Asia/Jerusalem') async def async_setup_platform(hass, config_entry, async_add_entities, discovery_info=None): _LOGGER.warning( @@ -292,7 +292,6 @@ def generate_forecast_extra_state_attributes(daily_forecast): return attributes - class ImsSensor(ImsEntity, SensorEntity): """Representation of an IMS sensor.""" diff --git a/custom_components/ims/weather.py b/custom_components/ims/weather.py index 18a8ef9..20c55e1 100644 --- a/custom_components/ims/weather.py +++ b/custom_components/ims/weather.py @@ -1,6 +1,7 @@ from __future__ import annotations import logging +import homeassistant.util.dt as dt_util import pytz from homeassistant.helpers.entity_platform import AddEntitiesCallback @@ -8,6 +9,7 @@ from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry from homeassistant.core import HomeAssistant, callback + from homeassistant.components.weather import ( # PLATFORM_SCHEMA, Forecast, @@ -103,7 +105,6 @@ def round_if_needed(value: int | float, output_round: bool): else: return round(value, 2) - class IMSWeather(WeatherEntity): """Implementation of an IMSWeather sensor.""" @@ -240,7 +241,7 @@ def _forecast(self, hourly: bool) -> list[Forecast]: data = [ Forecast( condition=WEATHER_CODE_TO_CONDITION[daily_forecast.weather_code], - datetime=daily_forecast.date.astimezone(pytz.UTC).isoformat(), + datetime=daily_forecast.date.isoformat(), native_temperature=daily_forecast.maximum_temperature, native_templow=daily_forecast.minimum_temperature ) for daily_forecast in self._weather_coordinator.data.forecast.days @@ -259,7 +260,7 @@ def _forecast(self, hourly: bool) -> list[Forecast]: data.append( Forecast( condition=WEATHER_CODE_TO_CONDITION[hourly_weather_code], - datetime=hourly_forecast.forecast_time.astimezone(pytz.UTC).isoformat(), + datetime=hourly_forecast.forecast_time.isoformat(), native_temperature=hourly_forecast.precise_temperature, native_templow=daily_forecast.minimum_temperature, native_precipitation=hourly_forecast.rain, diff --git a/custom_components/ims/weather_update_coordinator.py b/custom_components/ims/weather_update_coordinator.py index 71aeca9..c5a148b 100644 --- a/custom_components/ims/weather_update_coordinator.py +++ b/custom_components/ims/weather_update_coordinator.py @@ -1,7 +1,8 @@ """Weather data coordinator for the OpenWeatherMap (OWM) service.""" import asyncio +import datetime import logging -from datetime import timedelta, date, datetime +import homeassistant.util.dt as dt_util from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from weatheril import WeatherIL @@ -14,6 +15,7 @@ ATTRIBUTION = "Powered by IMS Weather" +timezone = dt_util.get_time_zone("Asia/Jerusalem") class WeatherUpdateCoordinator(DataUpdateCoordinator): """Weather data update coordinator.""" @@ -64,14 +66,14 @@ async def _get_ims_weather(self): @staticmethod def _filter_future_forecast(weather_forecast): """ Filter Forecast to include only future dates """ - today_datetime = datetime.fromordinal(date.today().toordinal()) + today_datetime = dt_util.as_local(datetime.datetime.combine(dt_util.now(timezone).date(), datetime.time())) filtered_day_list = list(filter(lambda daily: daily.date >= today_datetime, weather_forecast.days)) for daily_forecast in filtered_day_list: filtered_hours = [] for hourly_forecast in daily_forecast.hours: - forecast_datetime = daily_forecast.date + timedelta(hours=int(hourly_forecast.hour.split(":")[0])) - if datetime.now() <= forecast_datetime: + forecast_datetime = daily_forecast.date + datetime.timedelta(hours=int(hourly_forecast.hour.split(":")[0])) + if dt_util.now(timezone) <= forecast_datetime: filtered_hours.append(hourly_forecast) daily_forecast.hours = filtered_hours