Skip to content

Commit ce70444

Browse files
authored
Merge branch 'davidusb-geek:master' into weather
2 parents da5a2f5 + bdcac6d commit ce70444

5 files changed

Lines changed: 29 additions & 9 deletions

File tree

pyproject.toml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ build-backend = "hatchling.build"
77
[tool.uv.workspace]
88
members = ["emhass"]
99

10-
[tool.hatch.build.targets.wheel]
11-
packages = ["src/emhass"]
10+
[tool.uv]
11+
default-groups = "all"
1212

1313
[project]
1414
name = "emhass"
15-
version = "0.13.0"
15+
version = "0.13.0.post1"
1616
description = "An Energy Management System for Home Assistant"
1717
readme = "README.md"
1818
requires-python = ">=3.10, <3.13"
@@ -51,6 +51,9 @@ docs = ["sphinx", "sphinx-rtd-theme", "myst-parser"]
5151
# can add "mypy"
5252
test = ["requests_mock", "pytest", "coverage", "snakeviz", "ruff", "tabulate", "hatchling"]
5353

54+
[tool.hatch.build.targets.wheel]
55+
packages = ["src/emhass"]
56+
5457
[tool.hatch.build.targets.sdist]
5558
packages = ["src/emhass"]
5659
include = [

src/emhass/command_line.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ def retrieve_home_assistant_data(
6969
var_list = [retrieve_hass_conf["sensor_power_load_no_var_loads"]]
7070
if optim_conf.get("set_use_pv", True):
7171
var_list.append(retrieve_hass_conf["sensor_power_photovoltaics"])
72+
var_list.append(retrieve_hass_conf["sensor_power_photovoltaics_forecast"])
7273
if not rh.get_data(days_list, var_list, minimal_response=False, significant_changes_only=False):
7374
return False, None, days_list
7475
rh.prepare_data(

src/emhass/data/cec_inverters.pbz2

-25 Bytes
Binary file not shown.

src/emhass/data/cec_modules.pbz2

-268 Bytes
Binary file not shown.

src/emhass/forecast.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ def __init__(
154154
self.timeStep = self.freq.seconds / 3600 # in hours
155155
self.time_delta = pd.to_timedelta(opt_time_delta, "hours")
156156
self.var_PV = self.retrieve_hass_conf["sensor_power_photovoltaics"]
157+
self.var_PV_forecast = self.retrieve_hass_conf["sensor_power_photovoltaics_forecast"]
157158
self.var_load = self.retrieve_hass_conf["sensor_power_load_no_var_loads"]
158159
self.var_load_new = self.var_load + "_positive"
159160
self.lat = self.retrieve_hass_conf["Latitude"]
@@ -811,8 +812,11 @@ def adjust_pv_forecast_data_prep(
811812
:type data: pd.DataFrame
812813
"""
813814
# Extract target and predictor
814-
P_PV = data["sensor.power_photovoltaics"] # Actual PV production
815-
P_PV_forecast = data["sensor.p_pv_forecast"] # Forecasted PV production
815+
self.logger.debug("adjust_pv_forecast_data_prep using data:\n%s", data)
816+
if self.logger.isEnabledFor(logging.DEBUG):
817+
data.to_csv(self.emhass_conf["data_path"] / 'debug-adjust-pv-forecast-data-prep-input-data.csv')
818+
P_PV = data[self.var_PV] # Actual PV production
819+
P_PV_forecast = data[self.var_PV_forecast] # Forecasted PV production
816820
# Define time ranges
817821
last_day = data.index.max().normalize() # Last available day
818822
three_months_ago = last_day - pd.DateOffset(days=self.retrieve_hass_conf["historic_days_to_retrieve"])
@@ -832,6 +836,9 @@ def adjust_pv_forecast_data_prep(
832836
# Features (X) and target (y)
833837
self.X_adjust_pv = self.data_adjust_pv.drop(columns=["actual"]) # Predictors
834838
self.y_adjust_pv = self.data_adjust_pv["actual"] # Target: actual PV production
839+
self.logger.debug("adjust_pv_forecast_data_prep output data:\n%s", self.data_adjust_pv)
840+
if self.logger.isEnabledFor(logging.DEBUG):
841+
self.data_adjust_pv.to_csv(self.emhass_conf["data_path"] / 'debug-adjust-pv-forecast-data-prep-output-data.csv')
835842

836843
def adjust_pv_forecast_fit(
837844
self, n_splits: int = 5, regression_model: str = "LassoRegression",
@@ -935,6 +942,9 @@ def apply_weighting(row):
935942
self.validation_r2 = r2_score(y_true, y_pred)
936943
# Log the validation metrics
937944
self.logger.info(f"PV adjust Validation metrics: RMSE = {self.validation_rmse}, R2 = {self.validation_r2}")
945+
self.logger.debug("adjust_pv_forecast_predict forecast data:\n%s", forecast_data)
946+
if self.logger.isEnabledFor(logging.DEBUG):
947+
forecast_data.to_csv(self.emhass_conf["data_path"] / 'debug-adjust-pv-forecast-predict-forecast-data.csv')
938948
# Return the DataFrame with the adjusted forecast
939949
return forecast_data
940950

@@ -1482,8 +1492,11 @@ def get_load_cost_forecast(
14821492
# Ensure correct length
14831493
if not list_and_perfect:
14841494
forecast_out = forecast_out[0 : len(self.forecast_dates)]
1485-
df_final = df_final[0 : len(self.forecast_dates)]
1486-
df_final.loc[:,self.var_load_cost] = forecast_out.values
1495+
df_final = df_final[0 : len(self.forecast_dates)].copy()
1496+
# Convert to Series if needed and align index
1497+
if not isinstance(forecast_out, pd.Series):
1498+
forecast_out = pd.Series(np.ravel(forecast_out), index=df_final.index)
1499+
df_final.loc[:, self.var_load_cost] = forecast_out
14871500
elif method == "list": # reading a list of values
14881501
# Loading data from passed list
14891502
data_list = self.params["passed_data"]["load_cost_forecast"]
@@ -1554,8 +1567,11 @@ def get_prod_price_forecast(
15541567
# Ensure correct length
15551568
if not list_and_perfect:
15561569
forecast_out = forecast_out[0 : len(self.forecast_dates)]
1557-
df_final = df_final[0 : len(self.forecast_dates)]
1558-
df_final.loc[:,self.var_prod_price] = forecast_out.values
1570+
df_final = df_final[0 : len(self.forecast_dates)].copy()
1571+
# Convert to Series if needed and align index
1572+
if not isinstance(forecast_out, pd.Series):
1573+
forecast_out = pd.Series(np.ravel(forecast_out), index=df_final.index)
1574+
df_final.loc[:, self.var_prod_price] = forecast_out
15591575
elif method == "list": # reading a list of values
15601576
# Loading data from passed list
15611577
data_list = self.params["passed_data"]["prod_price_forecast"]

0 commit comments

Comments
 (0)