From 76a257e7a7d159e1680d5ff62e2526df714d0d6c Mon Sep 17 00:00:00 2001 From: Chuck Date: Thu, 2 Apr 2026 20:05:50 -0400 Subject: [PATCH 1/2] fix(weather): prevent radar from showing stale frames when tile CDN is unreachable When all RainViewer tile downloads failed, _last_fetch was still updated to the current time, delaying retry for the full 5-minute interval. Old frames stayed in memory indefinitely, causing radar to show hours-old data. Now retries after 60s when no tiles are fetched. Co-Authored-By: Claude Opus 4.6 (1M context) --- plugins.json | 6 +++--- plugins/ledmatrix-weather/manifest.json | 2 +- plugins/ledmatrix-weather/radar.py | 9 ++++++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/plugins.json b/plugins.json index 58a4e79d..f19e67d9 100644 --- a/plugins.json +++ b/plugins.json @@ -1,6 +1,6 @@ { "version": "1.0.0", - "last_updated": "2026-03-30", + "last_updated": "2026-04-02", "plugins": [ { "id": "hello-world", @@ -59,10 +59,10 @@ "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", "branch": "main", "plugin_path": "plugins/ledmatrix-weather", - "latest_version": "2.2.0", + "latest_version": "2.2.1", "stars": 0, "downloads": 0, - "last_updated": "2026-03-30", + "last_updated": "2026-04-02", "verified": true, "screenshot": "" }, diff --git a/plugins/ledmatrix-weather/manifest.json b/plugins/ledmatrix-weather/manifest.json index 8b156859..575b2f67 100644 --- a/plugins/ledmatrix-weather/manifest.json +++ b/plugins/ledmatrix-weather/manifest.json @@ -1,7 +1,7 @@ { "id": "ledmatrix-weather", "name": "Weather Display", - "version": "2.2.0", + "version": "2.2.1", "author": "ChuckBuilds", "class_name": "WeatherPlugin", "description": "Comprehensive weather display with current conditions, hourly forecast, daily forecast, almanac (sunrise/sunset, moon phase), precipitation radar, weather alerts, UV index, wind direction, and weather icons. Powered by OpenWeatherMap + RainViewer APIs.", diff --git a/plugins/ledmatrix-weather/radar.py b/plugins/ledmatrix-weather/radar.py index 1fed15d7..a59547b3 100644 --- a/plugins/ledmatrix-weather/radar.py +++ b/plugins/ledmatrix-weather/radar.py @@ -309,13 +309,16 @@ def refresh_data(self, width: int, height: int) -> None: self._radar_frames = new_frames self._frame_timestamps = new_timestamps self._frame_index = 0 + self._last_fetch = time.time() logger.info(f"[Radar] Loaded {len(new_frames)} radar frames") if failed: logger.warning(f"[Radar] {failed}/{len(frames_to_fetch)} tile(s) failed to load") else: - logger.error(f"[Radar] All {len(frames_to_fetch)} radar tile(s) failed to load") - - self._last_fetch = time.time() + # Don't update _last_fetch to full interval — retry in 60s + # instead of waiting the full 300s. Prevents stale frames + # persisting when tile CDN is temporarily unreachable. + self._last_fetch = time.time() - 240 + logger.error(f"[Radar] All {len(frames_to_fetch)} radar tile(s) failed to load, retrying in 60s") def needs_refresh(self, interval: int = 300) -> bool: """Return True when radar data is stale and should be refreshed.""" From cb8ceabf1c170a6aaa215fed2ee367f5828b6ea1 Mon Sep 17 00:00:00 2001 From: Chuck Date: Thu, 2 Apr 2026 21:02:51 -0400 Subject: [PATCH 2/2] fix(weather): reprocess hourly forecast during API failures to drop past hours When the OpenWeatherMap API is down, _process_forecast_data() was never re-called, so self.hourly_forecast kept displaying hours that had already passed (e.g., showing "2:00 PM" at 6pm). Now reprocess existing forecast data during error backoff so the time filter stays current even without fresh API data. Co-Authored-By: Claude Opus 4.6 (1M context) --- plugins.json | 2 +- plugins/ledmatrix-weather/manager.py | 8 ++++++++ plugins/ledmatrix-weather/manifest.json | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/plugins.json b/plugins.json index f19e67d9..8b683abe 100644 --- a/plugins.json +++ b/plugins.json @@ -59,7 +59,7 @@ "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", "branch": "main", "plugin_path": "plugins/ledmatrix-weather", - "latest_version": "2.2.1", + "latest_version": "2.2.2", "stars": 0, "downloads": 0, "last_updated": "2026-04-02", diff --git a/plugins/ledmatrix-weather/manager.py b/plugins/ledmatrix-weather/manager.py index cb7ce3cf..8ac01fbb 100644 --- a/plugins/ledmatrix-weather/manager.py +++ b/plugins/ledmatrix-weather/manager.py @@ -328,6 +328,9 @@ def update(self) -> None: if self.consecutive_errors >= self.max_consecutive_errors: if current_time - self.last_error_time < self.error_backoff_time: self.logger.debug(f"In error backoff period, retrying in {self.error_backoff_time - (current_time - self.last_error_time):.0f}s") + # Still reprocess forecast so past hours drop off the display + if self.forecast_data: + self._process_forecast_data(self.forecast_data) return else: # Reset error count after backoff @@ -361,6 +364,11 @@ def update(self) -> None: self.logger.error(f"Weather API disabled for {self.error_backoff_time} seconds due to repeated failures") self.last_error_log_time = current_time + # Re-filter existing forecast data so past hours drop off the + # hourly display even when API calls are failing. + if self.forecast_data: + self._process_forecast_data(self.forecast_data) + def _update_radar(self) -> None: """Refresh radar data in the update loop so display() never blocks on HTTP.""" if not self.show_radar: diff --git a/plugins/ledmatrix-weather/manifest.json b/plugins/ledmatrix-weather/manifest.json index 575b2f67..564f0f48 100644 --- a/plugins/ledmatrix-weather/manifest.json +++ b/plugins/ledmatrix-weather/manifest.json @@ -1,7 +1,7 @@ { "id": "ledmatrix-weather", "name": "Weather Display", - "version": "2.2.1", + "version": "2.2.2", "author": "ChuckBuilds", "class_name": "WeatherPlugin", "description": "Comprehensive weather display with current conditions, hourly forecast, daily forecast, almanac (sunrise/sunset, moon phase), precipitation radar, weather alerts, UV index, wind direction, and weather icons. Powered by OpenWeatherMap + RainViewer APIs.",