Skip to content

Ensure solar data updates at midnight#3331

Merged
springfall2008 merged 9 commits intomainfrom
fixes3
Feb 8, 2026
Merged

Ensure solar data updates at midnight#3331
springfall2008 merged 9 commits intomainfrom
fixes3

Conversation

@springfall2008
Copy link
Owner

@springfall2008 springfall2008 commented Feb 8, 2026

@springfall2008 springfall2008 marked this pull request as ready for review February 8, 2026 10:50
Copilot AI review requested due to automatic review settings February 8, 2026 10:50
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Addresses issue #3330 by attempting to refresh Solcast/solar forecast data promptly after a day rollover (midnight) so plans calculated shortly after midnight don’t use stale “yesterday” values.

Changes:

  • Add day-rollover / age-based logic in SolarAPI.run() to trigger fetch_pv_forecast() outside the existing plan-interval cadence.
  • Track last_fetched_timestamp after forecast fetch attempts.
  • Update chart pruning behavior and series colors in the web charts UI.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
apps/predbat/solcast.py Adds “new day or older than 60 minutes” fetch logic and tracks last fetch time to improve solar forecast freshness around midnight.
apps/predbat/web.py Adjusts LoadMLPower chart history pruning and updates several chart series colors.

Comment on lines +65 to +74
fetch_age = 9999
same_day = False
if self.last_fetched_timestamp:
fetch_age = (self.now_utc_exact - self.last_fetched_timestamp).total_seconds() / 60
same_day = self.last_fetched_timestamp.date() == self.now_utc_exact.date()

if seconds % (self.plan_interval_minutes * 60) == 0: # Every plan_interval_minutes
await self.fetch_pv_forecast()
elif not same_day or (fetch_age > 60): # If data is older than 60 minutes or it's a new day, fetch new data
await self.fetch_pv_forecast()
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.last_fetched_timestamp is set using self.now_utc_exact (timezone-aware), but run() compares it to datetime.now() (naive). Subtracting/comparing these will raise a TypeError at runtime. Use a consistent, tz-aware clock for both values (e.g., now = self.now_utc_exact or datetime.now(self.local_tz)), and avoid mixing naive/aware datetimes.

Copilot uses AI. Check for mistakes.
Comment on lines 61 to 75
async def run(self, seconds, first):
"""
Run the Solar API
"""
fetch_age = 9999
same_day = False
if self.last_fetched_timestamp:
fetch_age = (self.now_utc_exact - self.last_fetched_timestamp).total_seconds() / 60
same_day = self.last_fetched_timestamp.date() == self.now_utc_exact.date()

if seconds % (self.plan_interval_minutes * 60) == 0: # Every plan_interval_minutes
await self.fetch_pv_forecast()
elif not same_day or (fetch_age > 60): # If data is older than 60 minutes or it's a new day, fetch new data
await self.fetch_pv_forecast()
return True
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new midnight/age-based refresh logic in run() is not covered by existing tests (current tests exercise fetch_pv_forecast() directly but not the scheduler behavior). Add a unit test that simulates a day rollover and verifies run() triggers a fetch shortly after midnight (and does not refetch every minute once updated). This will also prevent regressions around timezone handling.

Copilot uses AI. Check for mistakes.
Comment on lines 2615 to 2667
@@ -2659,12 +2659,12 @@ def get_chart(self, chart):
{"name": "Load Power (Actual)", "data": load_power, "opacity": "1.0", "stroke_width": "3", "stroke_curve": "smooth", "color": "#3291a8", "unit": "kW"},
{"name": "Load Power (ML Predicted Future)", "data": load_ml_forecast_power, "opacity": "0.5", "stroke_width": "3", "chart_type": "area", "stroke_curve": "smooth", "color": "#eb2323", "unit": "kW"},
{"name": "Load Power (Used)", "data": load_power_best, "opacity": "1.0", "stroke_width": "2", "stroke_curve": "smooth", "unit": "kW"},
{"name": "Load Power ML History", "data": power_today, "opacity": "1.0", "stroke_width": "2", "stroke_curve": "smooth", "unit": "kW"},
{"name": "Load Power ML History +1h", "data": power_today_h1, "opacity": "1.0", "stroke_width": "2", "stroke_curve": "smooth", "unit": "kW"},
{"name": "Load Power ML History +8h", "data": power_today_h8, "opacity": "1.0", "stroke_width": "2", "stroke_curve": "smooth", "unit": "kW"},
{"name": "Load Power ML History", "data": power_today, "opacity": "1.0", "stroke_width": "2", "stroke_curve": "smooth", "unit": "kW", "color": "#eb2323"},
{"name": "Load Power ML History +1h", "data": power_today_h1, "opacity": "1.0", "stroke_width": "2", "stroke_curve": "smooth", "unit": "kW", "color": "#716d63"},
{"name": "Load Power ML History +8h", "data": power_today_h8, "opacity": "1.0", "stroke_width": "2", "stroke_curve": "smooth", "unit": "kW", "color": "#a6a5a3"},
{"name": "PV Power (Actual)", "data": pv_power, "opacity": "1.0", "stroke_width": "3", "stroke_curve": "smooth", "color": "#f5c43d", "unit": "kW"},
{"name": "PV Power (Predicted)", "data": pv_power_best, "opacity": "0.7", "stroke_width": "2", "stroke_curve": "smooth", "chart_type": "area", "color": "#ffa500", "unit": "kW"},
{"name": "Temperature", "data": temperature_forecast, "opacity": "1.0", "stroke_width": "2", "stroke_curve": "smooth", "color": "#ff6b6b", "unit": "°C"},
{"name": "Temperature", "data": temperature_forecast, "opacity": "1.0", "stroke_width": "2", "stroke_curve": "smooth", "color": "#75ff6b", "unit": "°C"},
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is titled/described as fixing Solcast updates at midnight, but this hunk also changes LoadMLPower chart data pruning and several chart colors. If these UI/graph changes are intentional, please link them to the issue or split them into a separate PR so the bugfix can be reviewed/reverted independently.

Copilot uses AI. Check for mistakes.
@springfall2008 springfall2008 merged commit f8abd45 into main Feb 8, 2026
1 check passed
@springfall2008 springfall2008 deleted the fixes3 branch February 8, 2026 11:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant