From 78337a99d266655e7c57c6ea8ae07bbd0cdec9c0 Mon Sep 17 00:00:00 2001 From: Honey Date: Sat, 25 Jul 2026 00:33:19 +0200 Subject: [PATCH] Fix forecast showing yesterday's days for a while after midnight Weather's daily forecast starts with "today" as of when check() last ran -- correct at fetch time, but that cached state sits until the next poll (up to update_minutes later, 30 min by default). Right after local midnight, that means the forecast keeps showing the old day first (e.g. Fr Sa So Mo Di at 00:30 Saturday) until the next scheduled poll happens to land after the rollover. ScreenCache now also tracks the calendar date it was last checked on and treats itself as stale on a date change, independent of poll_interval -- so the very next tick after midnight re-checks weather (and any other date-sensitive screen) immediately instead of waiting out the rest of the interval. Verified with a unit test simulating a cache populated "yesterday". --- scheduler.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scheduler.py b/scheduler.py index e81fb38..fb93aa9 100644 --- a/scheduler.py +++ b/scheduler.py @@ -15,6 +15,7 @@ import hashlib import logging import threading import time +from datetime import date from pathlib import Path from PIL import Image @@ -32,8 +33,17 @@ class ScreenCache: def __init__(self): self.state = None self.checked_at: float = 0.0 + self.checked_date: date | None = None def is_stale(self, poll_interval: int) -> bool: + # Also stale across a local-midnight rollover, independent of + # poll_interval -- otherwise a screen whose data is inherently + # date-bound (weather's daily forecast labels, its "today" hourly + # graph) keeps showing yesterday's data for up to poll_interval + # after midnight, since the cached state was genuinely correct + # when fetched, just not anymore now that the date has turned over. + if self.checked_date != date.today(): + return True return (time.time() - self.checked_at) >= poll_interval @@ -197,6 +207,7 @@ class Scheduler: if cache.is_stale(screen.get_poll_interval(settings)): cache.state = self._check(screen_id) cache.checked_at = time.time() + cache.checked_date = date.today() checked = True return screen_id, cache.state, checked