Skip to content

Commit d8c49a0

Browse files
authored
Merge branch 'davidusb-geek:master' into weather
2 parents ce70444 + 97150db commit d8c49a0

6 files changed

Lines changed: 60 additions & 8 deletions

File tree

src/emhass/command_line.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def retrieve_home_assistant_data(
4141
if get_data_from_file:
4242
with open(emhass_conf["data_path"] / test_df_literal, "rb") as inp:
4343
rh.df_final, days_list, var_list, rh.ha_config = pickle.load(inp)
44+
rh.var_list = var_list
4445
# Assign variables based on set_type
4546
retrieve_hass_conf["sensor_power_load_no_var_loads"] = str(var_list[0])
4647
if optim_conf.get("set_use_pv", True):

src/emhass/forecast.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,6 +1279,7 @@ def get_load_forecast(
12791279
)
12801280
var_interp = [var_list[0]]
12811281
self.var_list = [var_list[0]]
1282+
rh.var_list = self.var_list
12821283
self.var_load_new = self.var_load + "_positive"
12831284
else:
12841285
days_list = get_days_list(days_min_load_forecast)

src/emhass/retrieve_hass.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,12 @@ def prepare_data(
328328
:rtype: pandas.DataFrame
329329
330330
"""
331+
self.logger.debug("prepare_data self.var_list=%s", self.var_list)
332+
self.logger.debug("prepare_data var_load=%s", var_load)
333+
self.logger.debug("prepare_data load_negative=%s", load_negative)
334+
self.logger.debug("prepare_data set_zero_min=%s", set_zero_min)
335+
self.logger.debug("prepare_data var_replace_zero=%s", var_replace_zero)
336+
self.logger.debug("prepare_data var_interp=%s", var_interp)
331337
try:
332338
if load_negative: # Apply the correct sign to load power
333339
self.df_final[var_load + "_positive"] = -self.df_final[var_load]
@@ -347,16 +353,22 @@ def prepare_data(
347353
)
348354
return False
349355
# Confirm var_replace_zero & var_interp contain only sensors contained in var_list
350-
if isinstance(var_replace_zero, list) and all(
351-
item in var_replace_zero for item in self.var_list
352-
):
353-
pass
356+
if isinstance(var_replace_zero, list):
357+
original_list = var_replace_zero[:]
358+
var_replace_zero = [item for item in var_replace_zero if item in self.var_list]
359+
removed = set(original_list) - set(var_replace_zero)
360+
for item in removed:
361+
self.logger.warning(
362+
f"Sensor '{item}' in var_replace_zero not found in self.var_list and has been removed.")
354363
else:
355364
var_replace_zero = []
356-
if isinstance(var_interp, list) and all(
357-
item in var_interp for item in self.var_list
358-
):
359-
pass
365+
if isinstance(var_interp, list):
366+
original_list = var_interp[:]
367+
var_interp = [item for item in var_interp if item in self.var_list]
368+
removed = set(original_list) - set(var_interp)
369+
for item in removed:
370+
self.logger.warning(
371+
f"Sensor '{item}' in var_interp not found in self.var_list and has been removed.")
360372
else:
361373
var_interp = []
362374
# Apply minimum values

tests/test_forecast.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ def setUp(self):
7979
self.rh.df_final, self.days_list, self.var_list, self.rh.ha_config = (
8080
pickle.load(inp)
8181
)
82+
self.rh.var_list = self.var_list
8283
self.retrieve_hass_conf["sensor_power_load_no_var_loads"] = str(
8384
self.var_list[0]
8485
)
@@ -561,6 +562,7 @@ def test_get_forecasts_with_lists(self):
561562
if self.get_data_from_file:
562563
with open(emhass_conf["data_path"] / "test_df_final.pkl", "rb") as inp:
563564
rh.df_final, days_list, var_list, rh.ha_config = pickle.load(inp)
565+
rh.var_list = var_list
564566
retrieve_hass_conf["sensor_power_load_no_var_loads"] = str(self.var_list[0])
565567
retrieve_hass_conf["sensor_power_photovoltaics"] = str(self.var_list[1])
566568
retrieve_hass_conf["sensor_linear_interp"] = [
@@ -801,6 +803,7 @@ def test_get_forecasts_with_lists_special_case(self):
801803
if self.get_data_from_file:
802804
with open(emhass_conf["data_path"] / "test_df_final.pkl", "rb") as inp:
803805
rh.df_final, days_list, var_list, rh.ha_config = pickle.load(inp)
806+
rh.var_list = var_list
804807
retrieve_hass_conf["sensor_power_load_no_var_loads"] = str(self.var_list[0])
805808
retrieve_hass_conf["sensor_power_photovoltaics"] = str(self.var_list[1])
806809
retrieve_hass_conf["sensor_linear_interp"] = [

tests/test_optimization.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ def setUp(self):
7777
self.rh.df_final, self.days_list, self.var_list, self.rh.ha_config = (
7878
pickle.load(inp)
7979
)
80+
self.rh.var_list = self.var_list
8081
self.retrieve_hass_conf["sensor_power_load_no_var_loads"] = str(
8182
self.var_list[0]
8283
)

tests/test_retrieve_hass.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ def setUp(self):
101101
self.rh.df_final, self.days_list, self.var_list, self.rh.ha_config = (
102102
pickle.load(inp)
103103
)
104+
self.rh.var_list = self.var_list
104105
# Else obtain sensor values from HA
105106
else:
106107
if model_type == "long_train_data":
@@ -287,6 +288,39 @@ def test_prepare_data_negative_load(self):
287288
self.rh.df_final.index.tz, self.retrieve_hass_conf["time_zone"]
288289
)
289290

291+
# Tests that the prepare_data method does convert missing PV values to zero
292+
# and also ignores any missing sensor columns.
293+
def test_prepare_data_missing_pv(self):
294+
load_sensor = self.retrieve_hass_conf["sensor_power_load_no_var_loads"]
295+
actual_pv_sensor = self.retrieve_hass_conf["sensor_power_photovoltaics"]
296+
forecast_pv_sensor = self.retrieve_hass_conf["sensor_power_photovoltaics_forecast"]
297+
var_replace_zero = [actual_pv_sensor, forecast_pv_sensor, 'sensor.missing1']
298+
var_interp = [actual_pv_sensor, load_sensor, 'sensor.missing2']
299+
# Replace actual and forecast PV zero values with NaN's (to test they get replaced back)
300+
self.rh.df_final[actual_pv_sensor] = self.rh.df_final[actual_pv_sensor].replace(0, np.nan)
301+
self.rh.df_final[forecast_pv_sensor] = self.rh.df_final[forecast_pv_sensor].replace(0, np.nan)
302+
# Verify a non-zero number of missing values in the actual and forecast PV columns before prepare_data
303+
self.assertTrue(self.rh.df_final[actual_pv_sensor].isna().sum() > 0)
304+
self.assertTrue(self.rh.df_final[forecast_pv_sensor].isna().sum() > 0)
305+
self.rh.prepare_data(
306+
load_sensor,
307+
load_negative=False,
308+
set_zero_min=True,
309+
var_replace_zero=var_replace_zero,
310+
var_interp=var_interp
311+
)
312+
self.assertIsInstance(self.rh.df_final, type(pd.DataFrame()))
313+
self.assertEqual(
314+
self.rh.df_final.index.isin(self.days_list).sum(),
315+
self.df_raw.index.isin(self.days_list).sum(),
316+
)
317+
# Check the before and after actual and forecast PV columns have the same number of values
318+
self.assertEqual(len(self.df_raw[actual_pv_sensor]), len(self.rh.df_final[actual_pv_sensor]))
319+
self.assertEqual(len(self.df_raw[forecast_pv_sensor]), len(self.rh.df_final[forecast_pv_sensor]))
320+
# Verify no missing values in the actual and forecast PV columns after prepare_data
321+
self.assertTrue(self.rh.df_final[actual_pv_sensor].isna().sum() == 0)
322+
self.assertTrue(self.rh.df_final[forecast_pv_sensor].isna().sum() == 0)
323+
290324
# Test publish data
291325
def test_publish_data(self):
292326
response, data = self.rh.post_data(

0 commit comments

Comments
 (0)