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
13 changes: 12 additions & 1 deletion dao/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
# Changelog 刀 DAO
# Day Ahead Optimizer
# 2025.12.1
# 2026.01.0
With this new stable release comes a second optional method for predicting the porduction of your solar-devices.
This if fully documented in the wiki: https://github.com/corneel27/day-ahead/wiki/2.-Installatie-en-basis-configuratie#pv-productie-voorspellen <br>
This module is developed by @simnet and implemented by @corneel27/kc27.
Other changes and fixes:
- Updated several used python packages
- charge and discharge of the battery is now fully calculated with "specializes order set" (sos).
This gives always the "optimal" (=most efficient) level voor charging and discharging.
- Update README.md, link to wiki: https://github.com/corneel27/day-ahead/wiki (thanks @Torch1969)
- From now on new features will only be documented in the wiki, in the future DOCS.md will become deprecated.

# 2025.12.1
- Fix error calculating number of heat-blocks heatpump (on/off, reported by @sailor_dg)

# 2025.12.0
Expand Down
2 changes: 1 addition & 1 deletion dao/config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: 刀 Day Ahead Optimizer
version: 2025.12.1
version: 2026.01.0
slug: day_ahead_opt
description: Home Assistant Community Add-ons for day ahead optimizations
url: https://github.com/corneel27/day-ahead
Expand Down
Binary file modified dao/images/solar_graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified dao/images/solar_table.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 34 additions & 3 deletions dao/prog/da_meteo.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def get_dif_rad_factor(self, utc_time):
return value

@staticmethod
def is_aws(station:int):
def is_aws(station: int):
"""
station :code van een knmi station
:return: boolean
Expand All @@ -199,8 +199,39 @@ def is_aws(station:int):
"""
# onderstaande lijst is gegenereerd met prof/tst.py/generate_list_knmi-aws.py
# beter bij iedere nieuwe versie autoamtisch checken en vernieuwen op github
list_aws = [215, 235, 240, 249, 251, 257, 260, 267, 269, 270, 273, 275, 277, 278, 279, 280,
283, 286, 290, 310, 319, 323, 330, 344, 348, 350, 356, 370, 375, 377, 380]
list_aws = [
215,
235,
240,
249,
251,
257,
260,
267,
269,
270,
273,
275,
277,
278,
279,
280,
283,
286,
290,
310,
319,
323,
330,
344,
348,
350,
356,
370,
375,
377,
380,
]
return station in list_aws

def which_station(self) -> str:
Expand Down
15 changes: 10 additions & 5 deletions dao/prog/da_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -1145,15 +1145,19 @@ def add_col_df(
except ValueError:
org_value = 0
if pd.notna(row[col_index]):
add_to.at[row.tijd, col_name_to] = org_value + factor * row[col_index]
add_to.at[row.tijd, col_name_to] = (
org_value + factor * row[col_index]
)
else:
for row in add_from.itertuples():
# add_from.at[row.tijd, col_name_from])
if row.time in add_to.index:
org_value = add_to.at[row.tijd, col_name_to]
if pd.isna(org_value):
org_value = 0
add_to.at[row.time, col_name_to] = org_value + factor * row[col_index]
add_to.at[row.time, col_name_to] = (
org_value + factor * row[col_index]
)
return add_to

def get_latest_present(self, code: str) -> datetime.datetime:
Expand Down Expand Up @@ -2998,7 +3002,7 @@ def calc_solar_data(self, device: dict, day: datetime.date, active_view: str):

# prognose straling
rad_prog = self.get_da_data("gr", start, end, "uur", "uur", "prognoses")
result["prognose_straling"] =rad_prog["gr"]
result["prognose_straling"] = rad_prog["gr"]

# gemeten straling
rad_real = self.get_da_data("gr", start, end, "uur", "uur", "values")
Expand All @@ -3017,7 +3021,7 @@ def calc_solar_data(self, device: dict, day: datetime.date, active_view: str):
self.add_col_df(df_sensor, df_solar, "gemeten")
count += 1
result["gemeten_prod"] = pd.NA
self.add_col_df(df_solar, result, "gemeten", "gemeten_prod" )
self.add_col_df(df_solar, result, "gemeten", "gemeten_prod")

# voorspelling DAO
pred_dao = []
Expand All @@ -3039,12 +3043,13 @@ def calc_solar_data(self, device: dict, day: datetime.date, active_view: str):

# voorspelling ML
from dao.prog.solar_predictor import SolarPredictor

solar_predictor = SolarPredictor()
solar_prog = solar_predictor.predict_solar_device(device, start, end)
solar_prog["tijd"] = solar_prog["date_time"].dt.tz_localize(None)
solar_prog.index = solar_prog["tijd"]
result["prognose_ml"] = pd.NA
self.add_col_df(solar_prog, result, "prediction","prognose_ml")
self.add_col_df(solar_prog, result, "prediction", "prognose_ml")
# result["prognose_ml"] = solar_prog["prediction"]

result.drop(columns=["tijd"], inplace=True)
Expand Down
78 changes: 41 additions & 37 deletions dao/prog/day_ahead.py
Original file line number Diff line number Diff line change
Expand Up @@ -709,12 +709,7 @@ def calc_optimum(

# vanaf hier declaraties ontladen met sos ###############################################
ac_from_dc_samples = [
[
(
discharge_stages[b][ds]["power"]
/ 1000
)
for ds in range(DS[b])]
[(discharge_stages[b][ds]["power"] / 1000) for ds in range(DS[b])]
for b in range(B)
]
dc_to_ac_samples = [
Expand Down Expand Up @@ -3192,21 +3187,29 @@ def calc_optimum(
if self.log_level == logging.INFO:
# debug laden
if ac_to_dc[b][u].x > 0.0:
logging.info(f"Laad volume in uur {u} {uur[u]} "
f"{ac_from_dc[b][u].x*hour_fraction[u]} kWh")
logging.info(
f"Laad volume in uur {u} {uur[u]} "
f"{ac_from_dc[b][u].x * hour_fraction[u]} kWh"
)
for cs in range(CS[b]):
if ac_to_dc_w[b][u][cs].x > 0:
logging.info(f"{cs} {ac_to_dc_w[b][u][cs].x} "
f"{ac_to_dc_samples[b][cs]}")
logging.info(
f"{cs} {ac_to_dc_w[b][u][cs].x} "
f"{ac_to_dc_samples[b][cs]}"
)

# debug ontladen
if ac_from_dc[b][u].x > 0.0:
logging.info(f"Ontlaad volume in uur {u} {uur[u]} "
f"{ac_from_dc[b][u].x*hour_fraction[u]} kWh")
logging.info(
f"Ontlaad volume in uur {u} {uur[u]} "
f"{ac_from_dc[b][u].x * hour_fraction[u]} kWh"
)
for ds in range(DS[b]):
if ac_from_dc_w[b][u][ds].x > 0:
logging.info(f"{ds} {ac_from_dc_w[b][u][ds].x} "
f"{ac_from_dc_samples[b][ds]}")
logging.info(
f"{ds} {ac_from_dc_w[b][u][ds].x} "
f"{ac_from_dc_samples[b][ds]}"
)

row = [
str(uur[u]),
Expand Down Expand Up @@ -3727,7 +3730,7 @@ def calc_optimum(
netto_vermogen_bat = -minimum_power
elif ac_to_dc[b][0].x > 0.0: # laden met optimaal vermogen
sum_weight_factor = 0
sum_power = 0 # in W
sum_power = 0 # in W
for cs in range(CS[b]):
wf = ac_to_dc_w[b][0][cs].x
if wf > 0:
Expand All @@ -3736,36 +3739,37 @@ def calc_optimum(
if sum_weight_factor < 0.95:
new_state = battery_state_on_value
balance = False
netto_vermogen_bat = round(sum_power/sum_weight_factor)
netto_vermogen_bat = round(sum_power / sum_weight_factor)
new_ts = (
start_dt.timestamp() + self.interval_s * sum_weight_factor * interval_fraction[0]
start_dt.timestamp()
+ self.interval_s * sum_weight_factor * interval_fraction[0]
)
stop_omvormer = dt.datetime.fromtimestamp(int(new_ts))
else:
new_state = battery_state_on_value
balance = False
stop_omvormer = None
elif ac_from_dc[b][0].x > 0.0: # ontladen met optimaal vermogen
sum_weight_factor = 0
sum_power = 0 # in W
for ds in range(DS[b]):
wf = ac_from_dc_w[b][0][ds].x
if wf > 0:
sum_weight_factor += wf
sum_power += wf * discharge_stages[b][ds]["power"]
if sum_weight_factor < 0.95:
new_state = battery_state_on_value
balance = False
netto_vermogen_bat = - round(sum_power / sum_weight_factor)
new_ts = (
start_dt.timestamp() + self.interval_s * sum_weight_factor *
interval_fraction[0]
)
stop_omvormer = dt.datetime.fromtimestamp(int(new_ts))
else:
new_state = battery_state_on_value
balance = False
stop_omvormer = None
sum_weight_factor = 0
sum_power = 0 # in W
for ds in range(DS[b]):
wf = ac_from_dc_w[b][0][ds].x
if wf > 0:
sum_weight_factor += wf
sum_power += wf * discharge_stages[b][ds]["power"]
if sum_weight_factor < 0.95:
new_state = battery_state_on_value
balance = False
netto_vermogen_bat = -round(sum_power / sum_weight_factor)
new_ts = (
start_dt.timestamp()
+ self.interval_s * sum_weight_factor * interval_fraction[0]
)
stop_omvormer = dt.datetime.fromtimestamp(int(new_ts))
else:
new_state = battery_state_on_value
balance = False
stop_omvormer = None
else:
new_state = battery_state_on_value
balance = False
Expand Down
2 changes: 1 addition & 1 deletion dao/prog/solar_predictor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ def predict_solar_device(
f"Er is geen model aanwezig voor {self.solar_name},svp eerst trainen."
)
latest_dt = self.db_da.get_time_border_record("gr", latest=True)
prognose = (latest_dt < end)
prognose = latest_dt < end
weather_data = self.get_weatherdata(start, end, prognose=prognose)
prediction = self.predict(weather_data)
logging.info(f"ML prediction {self.solar_name}\n{prediction}")
Expand Down
7 changes: 5 additions & 2 deletions release-testing/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog 刀 DAO
# Day Ahead Optimizer
# 2026.01.0.rc9
This version is identical to stable version 2026.01.0

# 2026.01.0.rc8
Fixed error check AWS (reported by @Kees Schilder)

Expand Down Expand Up @@ -135,9 +138,9 @@ When you activate this rule: for devices with ml_prediction = True there will be
9. In the dashboard is an extra-menu-option available: **Solar**
Here you can view the effectivity of your calculated model:<br>
In text:<br>
![solar_table.png](images/solar_table.png)<br>
![solar_table.png](https://github.com/corneel27/day-ahead/raw/main/dao/images/solar_table.png)<br>
With a graph:<br>
![solar_graph.png](/images/solar_graph.png)
![solar_graph.png](https://github.com/corneel27/day-ahead/raw/main/dao//images/solar_graph.png)

# 2025.12.1.rc1
- Fix error calculating number of heat-blocks heatpump (on/off, reported by @sailor_dg)
Expand Down
2 changes: 1 addition & 1 deletion release-testing/config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: 刀 Day Ahead Optimizer (TESTING)
version: 2026.01.0.rc8
version: 2026.01.0.rc9
stage: experimental
slug: day_ahead_opt-testing
description: Beta version of DAO. Use only for testing!
Expand Down