From 3bdb727fb47a4607e012004696a81d46b200caf4 Mon Sep 17 00:00:00 2001 From: Kilian Helfenbein Date: Mon, 17 Feb 2025 12:01:44 +0100 Subject: [PATCH 1/5] Fix missing timeindex in set_time_series_active_power_predefined - Automatically set `EDisGo.TimeSeries.timeindex` to the default year of the database if it is empty. # - Added a logger warning to inform users about the default behavior and recommend setting the `timeindex` explicitly using `EDisGo.set_timeindex()`. # On branch feature/#456-feature-set-default-timeindex-in-edisgoset_time_series_active_power_predefined --- doc/whatsnew/v0-3-0.rst | 1 + edisgo/edisgo.py | 29 +++++++++++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/doc/whatsnew/v0-3-0.rst b/doc/whatsnew/v0-3-0.rst index 1335a26c7..cc0cae1fa 100644 --- a/doc/whatsnew/v0-3-0.rst +++ b/doc/whatsnew/v0-3-0.rst @@ -29,3 +29,4 @@ Changes * Added a storage operation strategy where the storage is charged when PV feed-in is higher than electricity demand of the household and discharged when electricity demand exceeds PV generation `#386 `_ * Added an estimation of the voltage deviation over a cable when selecting a suitable cable to connect a new component `#411 `_ * Added clipping of heat pump electrical power at its maximum value #428 +* Loading predefined time series now automatically sets the timeindex to the default year of the database if it is empty. `#457 `_ diff --git a/edisgo/edisgo.py b/edisgo/edisgo.py index 4fda72aa2..07ca92d0a 100755 --- a/edisgo/edisgo.py +++ b/edisgo/edisgo.py @@ -41,6 +41,7 @@ ) from edisgo.io.heat_pump_import import oedb as import_heat_pumps_oedb from edisgo.io.storage_import import home_batteries_oedb +from edisgo.io.timeseries_import import _timeindex_helper_func from edisgo.network import timeseries from edisgo.network.dsm import DSM from edisgo.network.electromobility import Electromobility @@ -558,12 +559,22 @@ def set_time_series_active_power_predefined( """ if self.timeseries.timeindex.empty: logger.warning( - "When setting time series using predefined profiles it is better to " - "set a time index as all data in TimeSeries class is indexed by the" - "time index. You can set the time index upon initialisation of " - "the EDisGo object by providing the input parameter 'timeindex' or by " - "using the function EDisGo.set_timeindex()." + "The EDisGo.TimeSeries.timeindex is empty. By default, this function " + "will set the timeindex to the default year of the provided database " + "connection or, if specified, to the given timeindex. To ensure " + "expected behavior, consider setting the timeindex explicitly before " + "running this function using EDisGo.set_timeindex()." ) + + timeindex = kwargs.get("timeindex", None) + + if timeindex is None: + timeindex, _ = _timeindex_helper_func( + self, timeindex, allow_leap_year=True + ) + + self.set_timeindex(timeindex) + if fluctuating_generators_ts is not None: self.timeseries.predefined_fluctuating_generators_by_technology( self, @@ -1846,9 +1857,11 @@ def _aggregate_time_series(attribute, groups, naming): [ pd.DataFrame( { - naming.format("_".join(k)) - if isinstance(k, tuple) - else naming.format(k): getattr(self.timeseries, attribute) + ( + naming.format("_".join(k)) + if isinstance(k, tuple) + else naming.format(k) + ): getattr(self.timeseries, attribute) .loc[:, v] .sum(axis=1) } From bb1f3b4a77a124a4f7a5bb011724050d85ea8bec Mon Sep 17 00:00:00 2001 From: Kilian Helfenbein Date: Mon, 17 Feb 2025 16:02:57 +0100 Subject: [PATCH 2/5] Overwrite timeindex if given timeindex differs from existing timeindex in set_time_series_active_power_predefined --- edisgo/edisgo.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/edisgo/edisgo.py b/edisgo/edisgo.py index 07ca92d0a..80ed8c35c 100755 --- a/edisgo/edisgo.py +++ b/edisgo/edisgo.py @@ -557,22 +557,38 @@ def set_time_series_active_power_predefined( is indexed using a default year and set for the whole year. """ - if self.timeseries.timeindex.empty: + + timeindex = kwargs.get("timeindex", None) + set_timeindex = False + + if (timeindex is not None) and not timeindex.equals(self.timeseries.timeindex): + logger.warning( + "The given timeindex is different from the EDisGo.TimeSeries.timeindex." + " Therefore the EDisGo.TimeSeries.timeindex will be overwritten by the " + "given timeindex." + ) + + set_timeindex = True + + elif self.timeseries.timeindex.empty: logger.warning( "The EDisGo.TimeSeries.timeindex is empty. By default, this function " "will set the timeindex to the default year of the provided database " - "connection or, if specified, to the given timeindex. To ensure " - "expected behavior, consider setting the timeindex explicitly before " - "running this function using EDisGo.set_timeindex()." + "connection. To ensure expected behavior, consider setting the " + "timeindex explicitly before running this function using " + "EDisGo.set_timeindex()." ) - timeindex = kwargs.get("timeindex", None) + set_timeindex = True + if set_timeindex: if timeindex is None: timeindex, _ = _timeindex_helper_func( self, timeindex, allow_leap_year=True ) + logger.warning(f"Setting EDisGo.TimeSeries.timeindex to {timeindex}.") + self.set_timeindex(timeindex) if fluctuating_generators_ts is not None: From aa075cc6aa9382ff37ce3f085fa9e594b5752858 Mon Sep 17 00:00:00 2001 From: Kilian Helfenbein Date: Mon, 17 Feb 2025 16:40:47 +0100 Subject: [PATCH 3/5] add logging and correct timeindex variable handling --- edisgo/edisgo.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/edisgo/edisgo.py b/edisgo/edisgo.py index 80ed8c35c..8f98e4796 100755 --- a/edisgo/edisgo.py +++ b/edisgo/edisgo.py @@ -591,13 +591,17 @@ def set_time_series_active_power_predefined( self.set_timeindex(timeindex) + logger.info( + f"Trying to set predefined timeseries for {self.timeseries.timeindex}" + ) + if fluctuating_generators_ts is not None: self.timeseries.predefined_fluctuating_generators_by_technology( self, fluctuating_generators_ts, fluctuating_generators_names, engine=kwargs.get("engine", toep_engine()), - timeindex=kwargs.get("timeindex", None), + timeindex=timeindex, ) if dispatchable_generators_ts is not None: self.timeseries.predefined_dispatchable_generators_by_technology( @@ -612,7 +616,7 @@ def set_time_series_active_power_predefined( edisgo_obj=self, scenario=kwargs.get("scenario"), engine=kwargs.get("engine", toep_engine()), - timeindex=kwargs.get("timeindex", None), + timeindex=timeindex, load_names=conventional_loads_names, ) # concat new time series with existing ones and drop any duplicate From f4253bf3aa8c1e35246020cb1db31010e582717a Mon Sep 17 00:00:00 2001 From: Jonas Danke Date: Tue, 18 Feb 2025 09:02:36 +0100 Subject: [PATCH 4/5] Refactor test cases for improved readability and consistency --- tests/test_edisgo.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/test_edisgo.py b/tests/test_edisgo.py index a4d20407a..f6c67283f 100755 --- a/tests/test_edisgo.py +++ b/tests/test_edisgo.py @@ -934,9 +934,9 @@ def test_aggregate_components(self): # ##### test without any aggregation - self.edisgo.topology._loads_df.at[ - "Load_residential_LVGrid_1_4", "bus" - ] = "Bus_BranchTee_LVGrid_1_10" + self.edisgo.topology._loads_df.at["Load_residential_LVGrid_1_4", "bus"] = ( + "Bus_BranchTee_LVGrid_1_10" + ) # save original values number_gens_before = len(self.edisgo.topology.generators_df) @@ -1054,9 +1054,9 @@ def test_aggregate_components(self): ) # manipulate grid so that more than one load of the same sector is # connected at the same bus - self.edisgo.topology._loads_df.at[ - "Load_residential_LVGrid_1_4", "bus" - ] = "Bus_BranchTee_LVGrid_1_10" + self.edisgo.topology._loads_df.at["Load_residential_LVGrid_1_4", "bus"] = ( + "Bus_BranchTee_LVGrid_1_10" + ) # save original values (only loads, as generators did not change) loads_p_set_before = self.edisgo.topology.loads_df.p_set.sum() @@ -1136,9 +1136,9 @@ def test_aggregate_components(self): # manipulate grid so that two generators of different types are # connected at the same bus - self.edisgo.topology._generators_df.at[ - "GeneratorFluctuating_13", "type" - ] = "misc" + self.edisgo.topology._generators_df.at["GeneratorFluctuating_13", "type"] = ( + "misc" + ) # save original values (values of loads were changed in previous aggregation) loads_p_set_before = self.edisgo.topology.loads_df.p_set.sum() From fa7ff54fb69a296d86dcfa083fdb36f040795fa4 Mon Sep 17 00:00:00 2001 From: Jonas Danke Date: Tue, 18 Feb 2025 09:02:47 +0100 Subject: [PATCH 5/5] updated tests with new warning text --- tests/test_edisgo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_edisgo.py b/tests/test_edisgo.py index f6c67283f..cc6f346d4 100755 --- a/tests/test_edisgo.py +++ b/tests/test_edisgo.py @@ -207,7 +207,7 @@ def test_set_time_series_active_power_predefined(self, caplog): # check warning self.edisgo.set_time_series_active_power_predefined() assert ( - "When setting time series using predefined profiles it is better" + "The EDisGo.TimeSeries.timeindex is empty. By default, this function" in caplog.text )