Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/predbat/predbat.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import requests
import asyncio

THIS_VERSION = "v8.37.10"
THIS_VERSION = "v8.38.0"

from download import predbat_update_move, predbat_update_download, check_install, resolve_predbat_repository, DEFAULT_PREDBAT_REPOSITORY
from const import MINUTE_WATT
Expand Down
4 changes: 4 additions & 0 deletions apps/predbat/solcast.py
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,7 @@ def publish_pv_stats(self, pv_forecast_data, divide_by, period):
"remainingCL": dp2(total_left_todayCL),
"detailedForecast": forecast_day[day],
},
app="solar",
)
self.dashboard_item(
"sensor." + self.prefix + "_pv_forecast_h0",
Expand All @@ -856,6 +857,7 @@ def publish_pv_stats(self, pv_forecast_data, divide_by, period):
"now90": dp2(power_now90),
"nowCL": dp2(power_nowCL),
},
app="solar",
)
else:
day_name = "tomorrow" if day == 1 else "d{}".format(day)
Expand All @@ -877,6 +879,7 @@ def publish_pv_stats(self, pv_forecast_data, divide_by, period):
"totalCL": dp2(total_dayCL[day]),
"detailedForecast": forecast_day[day],
},
app="solar",
)

def pv_calibration(self, pv_forecast_minute, pv_forecast_minute10, pv_forecast_data, create_pv10, divide_by, max_kwh, forecast_days, period=None):
Expand Down Expand Up @@ -1167,6 +1170,7 @@ def pack_and_store_forecast(self, pv_forecast_minute, pv_forecast_minute10):
"device_class": "power",
"state_class": "measurement",
},
app="solar",
)

async def fetch_pv_forecast(self):
Expand Down
20 changes: 20 additions & 0 deletions apps/predbat/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -2958,6 +2958,25 @@ def get_chart(self, chart):
{"name": "Forecast CL", "data": pv_today_forecastCL, "opacity": "0.3", "stroke_width": "2", "stroke_curve": "smooth", "chart_type": "area", "color": "#e90a0a"},
]
text += self.render_chart(series_data, "kW", "Solar Forecast", now_str)
elif chart == "PVAccuracy":
# Get pv_today history once and extract total and remaining attributes per timestamp
pv_today_hist = self.get_history_wrapper("sensor." + self.prefix + "_pv_today", 7, required=False)
pv_total_raw = history_attribute(pv_today_hist, attributes=True, state_key="total")
pv_remaining_raw = history_attribute(pv_today_hist, attributes=True, state_key="remaining")
# Compute forecast so far = total - remaining per timestamp
pv_forecast_sofar_raw = {}
for ts, total_val in pv_total_raw.items():
remaining_val = pv_remaining_raw.get(ts, 0)
pv_forecast_sofar_raw[ts] = dp2(max(total_val - remaining_val, 0))
pv_forecast_sofar = prune_today(pv_forecast_sofar_raw, self.now_utc, self.midnight_utc, prune=False)
# Get actual PV energy over time
pv_actual_hist = history_attribute(self.get_history_wrapper(self.prefix + ".pv_energy_h0", 7, required=False))
pv_actual = prune_today(pv_actual_hist, self.now_utc, self.midnight_utc, prune=False)
series_data = [
{"name": "PV Forecast (so far)", "data": pv_forecast_sofar, "opacity": "1.0", "stroke_width": "2", "stroke_curve": "smooth", "color": "#a8a8a7"},
{"name": "PV Actual", "data": pv_actual, "opacity": "1.0", "stroke_width": "3", "stroke_curve": "smooth", "color": "#f5c43d"},
]
text += self.render_chart(series_data, "kWh", "PV Forecast vs Actual", now_str)
elif chart == "LoadML":
load_today_history = self.get_history_with_now_attrs("sensor." + self.prefix + "_load_ml_stats", 7)
# Get historical load data for last 24 hours
Expand Down Expand Up @@ -3195,6 +3214,7 @@ async def html_charts(self, request):
text += f'<a href="./charts?chart=InDay" class="{"active" if chart == "InDay" else ""}">InDay</a>'
text += f'<a href="./charts?chart=PV" class="{"active" if chart == "PV" else ""}">PV</a>'
text += f'<a href="./charts?chart=PV7" class="{"active" if chart == "PV7" else ""}">PV7</a>'
text += f'<a href="./charts?chart=PVAccuracy" class="{"active" if chart == "PVAccuracy" else ""}">PVAccuracy</a>'
text += f'<a href="./charts?chart=Savings" class="{"active" if chart == "Savings" else ""}">Savings</a>'
text += f'<a href="./charts?chart=MarginalCosts" class="{"active" if chart == "MarginalCosts" else ""}">MarginalCosts</a>'
# Only show LoadML chart if ML is enabled
Expand Down
Loading