From d6f2e7165f4501e4ee9edfe0c7bd4521917ab3f5 Mon Sep 17 00:00:00 2001 From: Magnus <34011212+MagMar94@users.noreply.github.com> Date: Mon, 27 Jan 2025 22:41:51 +0100 Subject: [PATCH] Fix frozen Yr weather-module (#3706) Fixes #3296 The problem was that the fetch-methods threw errors when something went wrong instead of calling `updateAvailable()`. `updateAvailable()` must be called in order to schedule the next update. I added some filtering for the hourly forecast that removes hours in the past. If the API call fails we use the cached data, but we should only display hours in the future. --- CHANGELOG.md | 2 ++ modules/default/weather/providers/yr.js | 25 +++++++++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d1a004c..1e02f2dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ planned for 2025-04-01 - [core] Optimize systeminformation calls and output (#3689) - [core] Add issue templates for feature requests and bug reports (#3695) - [core] Adapt `start:x11:dev` script +- [weather/yr] The Yr weather provider now enforces a minimum `updateInterval` of 600 000 ms (10 minutes) to comply with the terms of service. If a lower value is set, it will be automatically increased to this minimum. ### Removed @@ -36,6 +37,7 @@ planned for 2025-04-01 - [weather] Fix wrong weatherCondition name in openmeteo provider which lead to n/a icon (#3691) - [core] Fix wrong port in log message when starting server only (#3696) - [calendar] NewYork event processed on system in Central timezone shows wrong time #3701 +- [weather/yr] The Yr weather provider is now able to recover from bad API resposes instead of freezing (#3296) ## [2.30.0] - 2025-01-01 diff --git a/modules/default/weather/providers/yr.js b/modules/default/weather/providers/yr.js index f305a1c0..a89dacd8 100644 --- a/modules/default/weather/providers/yr.js +++ b/modules/default/weather/providers/yr.js @@ -23,6 +23,10 @@ WeatherProvider.register("yr", { Log.error("The Yr weather provider requires local storage."); throw new Error("Local storage not available"); } + if (this.config.updateInterval < 600000) { + Log.warn("The Yr weather provider requires a minimum update interval of 10 minutes (600 000 ms). The configuration has been adjusted to meet this requirement."); + this.delegate.config.updateInterval = 600000; + } Log.info(`Weather provider: ${this.providerName} started.`); }, @@ -34,7 +38,7 @@ WeatherProvider.register("yr", { }) .catch((error) => { Log.error(error); - throw new Error(error); + this.updateAvailable(); }); }, @@ -119,7 +123,12 @@ WeatherProvider.register("yr", { }) .catch((err) => { Log.error(err); - reject("Unable to get weather data from Yr."); + if (weatherData) { + Log.warn("Using outdated cached weather data."); + resolve(weatherData); + } else { + reject("Unable to get weather data from Yr."); + } }) .finally(() => { localStorage.removeItem("yrIsFetchingWeatherData"); @@ -497,7 +506,7 @@ WeatherProvider.register("yr", { }) .catch((error) => { Log.error(error); - throw new Error(error); + this.updateAvailable(); }); }, @@ -530,7 +539,15 @@ WeatherProvider.register("yr", { getHourlyForecastFrom (weatherData) { const series = []; + const now = moment({ + year: moment().year(), + month: moment().month(), + day: moment().date(), + hour: moment().hour() + }); for (const forecast of weatherData.properties.timeseries) { + if (now.isAfter(moment(forecast.time))) continue; + forecast.symbol = forecast.data.next_1_hours?.summary?.symbol_code; forecast.precipitationAmount = forecast.data.next_1_hours?.details?.precipitation_amount; forecast.precipitationProbability = forecast.data.next_1_hours?.details?.probability_of_precipitation; @@ -600,7 +617,7 @@ WeatherProvider.register("yr", { }) .catch((error) => { Log.error(error); - throw new Error(error); + this.updateAvailable(); }); } });