From 3c44ddf5c43cb66bb42e9cceb95ecae642a362c1 Mon Sep 17 00:00:00 2001 From: smartie2076 Date: Tue, 4 May 2021 16:02:02 +0200 Subject: [PATCH] Implement new KPI: `GENSET_HOURS_OF_OPERATION` - Add `GENSET_HOURS_OF_OPERATION` to `constants.py` and in `C1.overall_results_title` - Add function `G3.get_hours_of_operation()` for generator evaluation, including pytests --- src/C_sensitivity_experiments.py | 2 ++ src/G3_oemof_evaluate.py | 30 ++++++++++++++++++++++++++++++ src/constants.py | 1 + tests/test_G3_oemof_evaluation.py | 28 ++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 tests/test_G3_oemof_evaluation.py diff --git a/src/C_sensitivity_experiments.py b/src/C_sensitivity_experiments.py index 7d74c47c..a6fc14af 100644 --- a/src/C_sensitivity_experiments.py +++ b/src/C_sensitivity_experiments.py @@ -132,6 +132,7 @@ TOTAL_WIND_GENERATION_KWH, TOTAL_GENSET_GENERATION_KWH, CONSUMPTION_FUEL_ANNUAL_L, + GENSET_HOURS_OF_OPERATION, CONSUMPTION_MAIN_GRID_MG_SIDE_ANNUAL_KWH, FEEDIN_MAIN_GRID_MG_SIDE_ANNUAL_KWH, RESULTS_ANNUITIES, @@ -1308,6 +1309,7 @@ def overall_results_title(settings, number_of_project_sites, sensitivity_array_d TOTAL_GENSET_GENERATION_KWH, CONSUMPTION_FUEL_ANNUAL_KWH, CONSUMPTION_FUEL_ANNUAL_L, + GENSET_HOURS_OF_OPERATION, CONSUMPTION_MAIN_GRID_MG_SIDE_ANNUAL_KWH, FEEDIN_MAIN_GRID_MG_SIDE_ANNUAL_KWH, ] diff --git a/src/G3_oemof_evaluate.py b/src/G3_oemof_evaluate.py index 27ede4bb..8af664aa 100644 --- a/src/G3_oemof_evaluate.py +++ b/src/G3_oemof_evaluate.py @@ -117,6 +117,7 @@ FEED_INTO_MAIN_GRID_MG_SIDE, DEMAND_AC, DEMAND_DC, + GENSET_HOURS_OF_OPERATION, ) @@ -496,9 +497,38 @@ def get_genset(case_dict, oemof_results, electricity_bus_ac, e_flows_df): oemof_results.update({CAPACITY_GENSET_KW: case_dict[GENSET_FIXED_CAPACITY]}) elif case_dict[GENSET_FIXED_CAPACITY] == None: oemof_results.update({CAPACITY_GENSET_KW: 0}) + + # Get hours of operation: + if case_dict[GENSET_FIXED_CAPACITY] != None: + get_hours_of_operation(oemof_results, case_dict, e_flows_df[GENSET_GENERATION]) + else: + oemof_results.update({GENSET_HOURS_OF_OPERATION: 0}) return e_flows_df +def get_hours_of_operation(oemof_results, case_dict, genset_generation_total): + """ + Calculates the total hours of genset generation (aggregated generation) of the evaluated timeframe. + + Parameters + ---------- + oemof_results: dict + Dict of all results of the simulation + + genset_generation_total: pd.Series + Dispatch of the gensets, aggregated + + Returns + ------- + Updates oemof_results with annual value of the GENSET_HOURS_OF_OPERATION. + """ + operation_boolean = genset_generation_total.where( + genset_generation_total == 0, other=1 + ) + annual_value(GENSET_HOURS_OF_OPERATION, operation_boolean, oemof_results, case_dict) + return operation_boolean + + def get_fuel(case_dict, oemof_results, results): logging.debug("Evaluate flow: fuel") if case_dict[GENSET_FIXED_CAPACITY] != None: diff --git a/src/constants.py b/src/constants.py index 7fb00167..f76cce09 100644 --- a/src/constants.py +++ b/src/constants.py @@ -194,6 +194,7 @@ TOTAL_GENSET_GENERATION_KWH = "total_genset_generation_kWh" CONSUMPTION_FUEL_ANNUAL_L = "consumption_fuel_annual_l" CONSUMPTION_MAIN_GRID_MG_SIDE_ANNUAL_KWH = "consumption_main_grid_mg_side_annual_kWh" +GENSET_HOURS_OF_OPERATION = "generator_operation_hours" FEEDIN_MAIN_GRID_MG_SIDE_ANNUAL_KWH = "feedin_main_grid_mg_side_annual_kWh" RESULTS_ANNUITIES = "results_annuities" ANNUITY_PV = "annuity_pv" diff --git a/tests/test_G3_oemof_evaluation.py b/tests/test_G3_oemof_evaluation.py new file mode 100644 index 00000000..75dd7a74 --- /dev/null +++ b/tests/test_G3_oemof_evaluation.py @@ -0,0 +1,28 @@ +import pandas as pd +import numpy as np +from pandas.util.testing import assert_series_equal + +import src.G3_oemof_evaluate as G3 +from src.constants import EVALUATED_DAYS, GENSET_HOURS_OF_OPERATION + + +def test_get_hours_of_operation(): + genset_generation = pd.Series([0, 0, 0, 0.5, 2]) + oemof_results = {} + case_dict = {EVALUATED_DAYS: 5} + operation_boolean = G3.get_hours_of_operation( + oemof_results, case_dict, genset_generation + ) + exp = pd.Series([0, 0, 0, 1, 1]) + assert ( + operation_boolean.sum() == 2 + ), f"It was expected that the number of operation hours in the evaluated timeframe was 2, but it is {operation_boolean.sum()}." + assert_series_equal( + genset_generation.astype(np.float64), exp(np.float64), check_names=False, + ), f"The operational hours pd.Series should be the same when calculated with the function to the expected series." + assert ( + GENSET_HOURS_OF_OPERATION in oemof_results + ), f"Parameter {GENSET_HOURS_OF_OPERATION} is not in the oemof_results, but was expected." + assert oemof_results[GENSET_HOURS_OF_OPERATION] == 2 * ( + 365 / 5 + ), f"Parameter {GENSET_HOURS_OF_OPERATION} is not of expected annual value {2*365/5}, but {oemof_results[GENSET_HOURS_OF_OPERATION]}."