diff --git a/CaseStudy.py b/CaseStudy.py index 3d57f26..ae0aa4f 100644 --- a/CaseStudy.py +++ b/CaseStudy.py @@ -1,4 +1,5 @@ import copy +import os import warnings from typing import Optional, Self @@ -20,7 +21,6 @@ def __init__(self, power_businfo_file: str = "Power_BusInfo.xlsx", dPower_BusInfo: pd.DataFrame = None, power_network_file: str = "Power_Network.xlsx", dPower_Network: pd.DataFrame = None, power_thermalgen_file: str = "Power_ThermalGen.xlsx", dPower_ThermalGen: pd.DataFrame = None, - power_ror_file: str = "Power_RoR.xlsx", dPower_RoR: pd.DataFrame = None, power_vres_file: str = "Power_VRES.xlsx", dPower_VRES: pd.DataFrame = None, power_demand_file: str = "Power_Demand.xlsx", dPower_Demand: pd.DataFrame = None, power_inflows_file: str = "Power_Inflows.xlsx", dPower_Inflows: pd.DataFrame = None, @@ -98,19 +98,6 @@ def __init__(self, self.power_thermalgen_file = power_thermalgen_file self.dPower_ThermalGen = ExcelReader.get_dPower_ThermalGen(self.data_folder + self.power_thermalgen_file) - if self.dPower_Parameters["pEnableRoR"]: - if dPower_RoR is not None: - self.dPower_RoR = dPower_RoR - else: - self.power_ror_file = power_ror_file - self.dPower_RoR = self.get_dPower_RoR() - - if dPower_Inflows is not None: - self.dPower_Inflows = dPower_Inflows - else: - self.power_inflows_file = power_inflows_file - self.dPower_Inflows = self.get_dPower_Inflows() - if self.dPower_Parameters["pEnableVRES"]: if dPower_VRES is not None: self.dPower_VRES = dPower_VRES @@ -120,7 +107,7 @@ def __init__(self, if dPower_VRESProfiles is not None: self.dPower_VRESProfiles = dPower_VRESProfiles - else: + elif os.path.isfile(self.data_folder + power_vresprofiles_file): self.power_vresprofiles_file = power_vresprofiles_file self.dPower_VRESProfiles = ExcelReader.get_dPower_VRESProfiles(self.data_folder + self.power_vresprofiles_file) @@ -129,7 +116,14 @@ def __init__(self, self.dPower_Storage = dPower_Storage else: self.power_storage_file = power_storage_file - self.dPower_Storage = self.get_dPower_Storage() + self.dPower_Storage = ExcelReader.get_dPower_Storage(self.data_folder + self.power_storage_file) + + if self.dPower_Parameters["pEnableVRES"] or self.dPower_Parameters["pEnableStorage"]: + if dPower_Inflows is not None: + self.dPower_Inflows = dPower_Inflows + elif os.path.isfile(self.data_folder + power_inflows_file): + self.power_inflows_file = power_inflows_file + self.dPower_Inflows = ExcelReader.get_dPower_Inflows(self.data_folder + self.power_inflows_file) if self.dPower_Parameters["pEnablePowerImportExport"]: if dPower_ImpExpHubs is not None: @@ -169,8 +163,7 @@ def scale_CaseStudy(self): if self.dPower_Parameters["pEnableThermalGen"]: self.scale_dPower_ThermalGen() - if self.dPower_Parameters["pEnableRoR"]: - self.scale_dPower_RoR() + if self.dPower_Inflows is not None: self.scale_dPower_Inflows() if self.dPower_Parameters["pEnableVRES"]: @@ -209,7 +202,6 @@ def scale_dPower_Demand(self): self.dPower_Demand["value"] *= self.power_scaling_factor def scale_dPower_ThermalGen(self): - self.dPower_ThermalGen = self.dPower_ThermalGen[self.dPower_ThermalGen["excl"].isnull()] # Only keep rows that are not excluded (i.e., have no value in the "Excl." column) self.dPower_ThermalGen = self.dPower_ThermalGen[(self.dPower_ThermalGen["ExisUnits"] > 0) | (self.dPower_ThermalGen["EnableInvest"] > 0)] # Filter out all generators that are not existing and not investable self.dPower_ThermalGen['EFOR'] = self.dPower_ThermalGen['EFOR'].fillna(0) # Fill NaN values with 0 for EFOR @@ -243,17 +235,11 @@ def scale_dPower_ThermalGen(self): self.dPower_ThermalGen['Qmin'] = self.dPower_ThermalGen['Qmin'].fillna(0) * self.reactive_power_scaling_factor self.dPower_ThermalGen['Qmax'] = self.dPower_ThermalGen['Qmax'].fillna(0) * self.reactive_power_scaling_factor - def scale_dPower_RoR(self): - self.dPower_RoR['InvestCostEUR'] = self.dPower_RoR['MaxProd'] * self.power_scaling_factor * (self.dPower_RoR['InvestCostPerMW'] + self.dPower_RoR['InvestCostPerMWh'] * self.dPower_RoR['Ene2PowRatio']) * (self.cost_scaling_factor / self.power_scaling_factor) - self.dPower_RoR['MaxProd'] *= self.power_scaling_factor - - self.dPower_RoR['Qmin'] = self.dPower_RoR['Qmin'].fillna(0) * self.reactive_power_scaling_factor - self.dPower_RoR['Qmax'] = self.dPower_RoR['Qmax'].fillna(0) * self.reactive_power_scaling_factor - def scale_dPower_Inflows(self): - self.dPower_Inflows["Inflow"] *= self.power_scaling_factor + self.dPower_Inflows["value"] *= self.power_scaling_factor def scale_dPower_VRES(self): + self.dPower_VRES = self.dPower_VRES[(self.dPower_VRES["ExisUnits"] > 0) | ((self.dPower_VRES["EnableInvest"] > 0) & (self.dPower_VRES["MaxInvest"] > 0))] # Filter out all generators that are not existing and not investable if "MinProd" not in self.dPower_VRES.columns: self.dPower_VRES['MinProd'] = 0 @@ -265,6 +251,7 @@ def scale_dPower_VRES(self): self.dPower_VRES['Qmax'] = self.dPower_VRES['Qmax'].fillna(0) * self.reactive_power_scaling_factor def scale_dPower_Storage(self): + self.dPower_Storage = self.dPower_Storage[(self.dPower_Storage["ExisUnits"] > 0) | ((self.dPower_Storage["EnableInvest"] > 0) & (self.dPower_Storage["MaxInvest"] > 0))] # Filter out all generators that are not existing and not investable self.dPower_Storage['IniReserve'] = self.dPower_Storage['IniReserve'].fillna(0) self.dPower_Storage['MinReserve'] = self.dPower_Storage['MinReserve'].fillna(0) self.dPower_Storage['MinProd'] = self.dPower_Storage["MinProd"].fillna(0) @@ -276,6 +263,10 @@ def scale_dPower_Storage(self): self.dPower_Storage['Qmin'] = self.dPower_Storage['Qmin'].fillna(0) * self.reactive_power_scaling_factor self.dPower_Storage['Qmax'] = self.dPower_Storage['Qmax'].fillna(0) * self.reactive_power_scaling_factor + # Check if any DisEffic or ChEffic is nan, if so, raise an error + if self.dPower_Storage['DisEffic'].isna().any() or self.dPower_Storage['ChEffic'].isna().any(): + raise ValueError("DisEffic and ChEffic in 'Power_Storage.xlsx' must not contain NaN values. Please check the data.") + def scale_dPower_ImpExpHubs(self): self.dPower_ImpExpHubs["Pmax Import"] *= self.power_scaling_factor self.dPower_ImpExpHubs["Pmax Export"] *= self.power_scaling_factor @@ -302,7 +293,7 @@ def get_dPower_Parameters(self): dPower_Parameters = dPower_Parameters.dropna(how="all") dPower_Parameters = dPower_Parameters.set_index('General') - self.yesNo_to_bool(dPower_Parameters, ['pEnableChDisPower', 'pFixStInterResToIniReserve', 'pEnableSoftLineLoadLimits', 'pEnableThermalGen', 'pEnableRoR', 'pEnableVRES', 'pEnableStorage', 'pEnablePowerImportExport', 'pEnableSOCP']) + self.yesNo_to_bool(dPower_Parameters, ['pEnableChDisPower', 'pFixStInterResToIniReserve', 'pEnableSoftLineLoadLimits', 'pEnableThermalGen', 'pEnableVRES', 'pEnableStorage', 'pEnablePowerImportExport', 'pEnableSOCP']) # Transform to make it easier to access values dPower_Parameters = dPower_Parameters.drop(dPower_Parameters.columns[1:], axis=1) # Drop all columns but "Value" (rest is just for information in the Excel) @@ -322,34 +313,6 @@ def yesNo_to_bool(df: pd.DataFrame, columns_to_be_changed: list[str]): raise ValueError(f"Value for {column} must be either 'Yes' or 'No'.") return df - def get_dPower_RoR(self): - dPower_RoR = self.read_generator_data(self.data_folder + self.power_ror_file) - - # If column 'scenario' is not present, add it - if 'scenario' not in dPower_RoR.columns: - dPower_RoR['scenario'] = 'ScenarioA' # TODO: Fill this dynamically, once the Excel file is updated - return dPower_RoR - - def get_dPower_Storage(self): - dPower_Storage = self.read_generator_data(self.data_folder + self.power_storage_file) - - # If column 'scenario' is not present, add it - if 'scenario' not in dPower_Storage.columns: - dPower_Storage['scenario'] = 'ScenarioA' # TODO: Fill this dynamically, once the Excel file is updated - return dPower_Storage - - def get_dPower_Inflows(self): - dPower_Inflows = pd.read_excel(self.data_folder + self.power_inflows_file, skiprows=[0, 1, 3, 4, 5]) - dPower_Inflows = dPower_Inflows.drop(dPower_Inflows.columns[0], axis=1) - dPower_Inflows = dPower_Inflows.rename(columns={dPower_Inflows.columns[0]: "rp", dPower_Inflows.columns[1]: "g"}) - dPower_Inflows = dPower_Inflows.melt(id_vars=['rp', 'g'], var_name='k', value_name='Inflow') - dPower_Inflows = dPower_Inflows.set_index(['rp', 'g', 'k']) - - # If column 'scenario' is not present, add it - if 'scenario' not in dPower_Inflows.columns: - dPower_Inflows['scenario'] = 'ScenarioA' # TODO: Fill this dynamically, once the Excel file is updated - return dPower_Inflows - def get_dPower_ImpExpHubs(self): dPower_ImpExpHubs = pd.read_excel(self.data_folder + self.power_impexphubs_file, skiprows=[0, 1, 3, 4, 5]) dPower_ImpExpHubs = dPower_ImpExpHubs.drop(dPower_ImpExpHubs.columns[0], axis=1) @@ -531,12 +494,6 @@ def merge_single_node_buses(self): row['i'] = new_bus_name self.dPower_ThermalGen.loc[i] = row - # Adapt dPower_RoR - for i, row in self.dPower_RoR.iterrows(): - if row['i'] in connected_buses: - row['i'] = new_bus_name - self.dPower_RoR.loc[i] = row - # Adapt dPower_VRES for i, row in self.dPower_VRES.iterrows(): if row['i'] in connected_buses: @@ -567,16 +524,6 @@ def merge_single_node_buses(self): self.dPower_VRESProfiles = self.dPower_VRESProfiles.groupby(['rp', 'i', 'k', 'tec']).mean() # TODO: Aggregate using more complex method (capacity * productionCapacity * ... * / Total Production Capacity) self.dPower_VRESProfiles.sort_index(inplace=True) - # Function to read generator data - @staticmethod - def read_generator_data(file_path): - d_generator = pd.read_excel(file_path, skiprows=[0, 1, 3, 4, 5]) - d_generator = d_generator.drop(d_generator.columns[0], axis=1) - d_generator = d_generator[(d_generator["ExisUnits"] > 0) | (d_generator["EnableInvest"] > 0)] # Filter out all generators that are not existing and not investable - d_generator = d_generator.rename(columns={d_generator.columns[0]: "g", d_generator.columns[1]: "tec", d_generator.columns[2]: "i"}) - d_generator = d_generator.set_index('g') - return d_generator - # Create transition matrix from Hindex def get_rpTransitionMatrices(self): rps = sorted(self.dPower_Hindex.index.get_level_values('rp').unique().tolist()) @@ -689,8 +636,7 @@ def filter_scenario(self, scenario_name) -> Self: if hasattr(caseStudy, "dPower_ThermalGen"): caseStudy._filter_dataframe("dPower_ThermalGen", scenario_name) - if hasattr(caseStudy, "dPower_RoR") and len(caseStudy.dPower_RoR) > 0: - caseStudy._filter_dataframe("dPower_RoR", scenario_name) + if hasattr(caseStudy, "dPower_Inflows"): caseStudy._filter_dataframe("dPower_Inflows", scenario_name) if hasattr(caseStudy, "dPower_VRES"): caseStudy._filter_dataframe("dPower_VRES", scenario_name) diff --git a/ExcelReader.py b/ExcelReader.py index e753250..fa209b8 100644 --- a/ExcelReader.py +++ b/ExcelReader.py @@ -9,27 +9,40 @@ printer = Printer.getInstance() -def __check_LEGOExcel_version(excel_file_path: str, version_specifier: str): +def __check_LEGOExcel_version(excel_file_path: str, version_specifier: str, fail_on_wrong_version: bool = False): + """ + Check if the Excel file has the correct version specifier. + :param excel_file_path: Path to the Excel file + :param version_specifier: Expected version specifier (e.g., "v0.1.0") + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version + :return: None + :raises ValueError: If the version specifier does not match and fail_on_wrong_version + """ # Check if the file has the correct version specifier wb = openpyxl.load_workbook(excel_file_path) for sheet in wb.sheetnames: if wb[sheet].cell(row=2, column=3).value != version_specifier: - printer.error(f"Excel file '{excel_file_path}' does not have the correct version specifier in sheet '{sheet}'. Expected '{version_specifier}' but got '{wb[sheet].cell(row=2, column=3).value}'.") - printer.error(f"Trying to work with it any way, but this can have unintended consequences!") + if fail_on_wrong_version: + raise ValueError(f"Excel file '{excel_file_path}' does not have the correct version specifier. Expected '{version_specifier}' but got '{wb[sheet].cell(row=2, column=3).value}'.") + else: + printer.error(f"Excel file '{excel_file_path}' does not have the correct version specifier in sheet '{sheet}'. Expected '{version_specifier}' but got '{wb[sheet].cell(row=2, column=3).value}'.") + printer.error(f"Trying to work with it any way, but this can have unintended consequences!") pass -# Function to read generator data -def __read_generator_data(file_path): - d_generator = pd.read_excel(file_path, skiprows=[0, 1, 2, 4, 5, 6]) - d_generator = d_generator[d_generator["excl"].isnull()] # Only keep rows that are not excluded (i.e., have no value in the "Excl." column) - d_generator = d_generator[(d_generator["ExisUnits"] > 0) | (d_generator["EnableInvest"] > 0)] # Filter out all generators that are not existing and not invest-able - d_generator = d_generator.set_index('g') - return d_generator - - -def __read_non_pivoted_file(excel_file_path: str, version_specifier: str, indices: list[str], has_excl_column: bool, keep_excl_columns: bool = False) -> pd.DataFrame: - __check_LEGOExcel_version(excel_file_path, version_specifier) +def __read_non_pivoted_file(excel_file_path: str, version_specifier: str, indices: list[str], has_excl_column: bool, + keep_excl_columns: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: + """ + Read a non-pivoted Excel file and return the data as a DataFrame. + :param excel_file_path: Path to the Excel file + :param version_specifier: Version specifier to check against the Excel file + :param indices: List of columns to set as index in the DataFrame + :param has_excl_column: If True, the DataFrame has an "Excl." column that indicates whether a row should be excluded + :param keep_excl_columns: If True, keep the "Excl." column in the DataFrame + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version + :return: DataFrame containing the data from the Excel file + """ + __check_LEGOExcel_version(excel_file_path, version_specifier, fail_on_wrong_version) xls = pd.ExcelFile(excel_file_path) data = pd.DataFrame() @@ -48,26 +61,68 @@ def __read_non_pivoted_file(excel_file_path: str, version_specifier: str, indice return data -def __read_pivoted_file(excel_file_path: str, version_specifier: str, indices: list[str], pivoted_variable_name: str, melt_indices: list[str], has_excl_column: bool, keep_excluded_columns: bool = False) -> pd.DataFrame: - df = __read_non_pivoted_file(excel_file_path, version_specifier, [], has_excl_column, keep_excluded_columns) +def __read_pivoted_file(excel_file_path: str, version_specifier: str, indices: list[str], pivoted_variable_name: str, melt_indices: list[str], has_excl_column: bool, + keep_excluded_columns: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: + """ + Read a pivoted Excel file and return the data as a DataFrame. + :param excel_file_path: Path to the Excel file + :param version_specifier: Version specifier to check against the Excel file + :param indices: List of columns to set as index in the DataFrame + :param pivoted_variable_name: Name of the variable that was pivoted in the Excel + :param melt_indices: List of columns to keep as identifiers when melting the DataFrame + :param has_excl_column: If True, the DataFrame has an "Excl." column that indicates whether a row should be excluded + :param keep_excluded_columns: If True, keep the "Excl." column in the DataFrame + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version + :return: DataFrame containing the data from the Excel file + """ + df = __read_non_pivoted_file(excel_file_path, version_specifier, [], has_excl_column, keep_excluded_columns, fail_on_wrong_version) df = df.melt(id_vars=melt_indices + ["scenario"], var_name=pivoted_variable_name, value_name="value") df = df.set_index(indices) return df -def get_dGlobal_Scenarios(excel_file_path: str, keep_excluded_entries: bool = False, do_not_convert_values: bool = False) -> pd.DataFrame: +def get_dData_Packages(excel_file_path: str, keep_excluded_entries: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: """ - Read the dGlobal_Scenarios data from the Excel file. + Read the dData_Packages data from the Excel file. :param excel_file_path: Path to the Excel file :param keep_excluded_entries: Unused but kept for compatibility with other functions - :param do_not_convert_values: Unused but kept for compatibility with other functions - :return: dGlobal_Scenarios + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version + :return: dData_Packages + """ + dData_Packages = __read_non_pivoted_file(excel_file_path, "v0.1.0", ["dataPackage"], False, False, fail_on_wrong_version) + + if keep_excluded_entries: + printer.warning("'keep_excluded_entries' is set for 'get_dData_Packages', although nothing is excluded anyway - please check if this is intended.") + + return dData_Packages + + +def get_dData_Sources(excel_file_path: str, keep_excluded_entries: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: + """ + Read the dData_Sources data from the Excel file. + :param excel_file_path: Path to the Excel file + :param keep_excluded_entries: Unused but kept for compatibility with other functions + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version + :return: dData_Sources """ - dGlobal_Scenarios = __read_non_pivoted_file(excel_file_path, "v0.1.0", ["scenarioID"], True, keep_excluded_entries) + dData_Sources = __read_non_pivoted_file(excel_file_path, "v0.1.0", ["dataSource"], False, False, fail_on_wrong_version) - if do_not_convert_values: - printer.warning("'do_not_convert_values' is set for 'get_dGlobal_Scenarios', although no values are converted anyway - please check if this is intended.") + if keep_excluded_entries: + printer.warning("'keep_excluded_entries' is set for 'get_dData_Sources', although nothing is excluded anyway - please check if this is intended.") + + return dData_Sources + + +def get_dGlobal_Scenarios(excel_file_path: str, keep_excluded_entries: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: + """ + Read the dGlobal_Scenarios data from the Excel file. + :param excel_file_path: Path to the Excel file + :param keep_excluded_entries: Do not exclude any entries which are marked to be excluded in the Excel file + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version + :return: dGlobal_Scenarios + """ + dGlobal_Scenarios = __read_non_pivoted_file(excel_file_path, "v0.1.0", ["scenarioID"], True, keep_excluded_entries, fail_on_wrong_version) # Check that there is only one sheet with the name 'Scenario' check = dGlobal_Scenarios["scenario"].to_numpy() @@ -77,184 +132,165 @@ def get_dGlobal_Scenarios(excel_file_path: str, keep_excluded_entries: bool = Fa return dGlobal_Scenarios -def get_dPower_Hindex(excel_file_path: str, keep_excluded_entries: bool = False, do_not_convert_values: bool = False) -> pd.DataFrame: +def get_dPower_BusInfo(excel_file_path: str, keep_excluded_entries: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: """ - Read the dPower_Hindex data from the Excel file. + Read the dPower_BusInfo data from the Excel file. :param excel_file_path: Path to the Excel file - :param keep_excluded_entries: Unused but kept for compatibility with other functions - :param do_not_convert_values: Unused but kept for compatibility with other functions - :return: dPower_Hindex + :param keep_excluded_entries: Do not exclude any entries which are marked to be excluded in the Excel file + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version + :return: dPower_BusInfo """ - dPower_Hindex = __read_non_pivoted_file(excel_file_path, "v0.1.2", ["p", "rp", "k"], False, False) - - if keep_excluded_entries: - printer.warning("'keep_excluded_entries' is set for 'get_dPower_Hindex', although nothing is excluded anyway - please check if this is intended.") - if do_not_convert_values: - printer.warning("'do_not_convert_values' is set for 'get_dPower_Hindex', although no values are converted anyway - please check if this is intended.") + dPower_BusInfo = __read_non_pivoted_file(excel_file_path, "v0.1.2", ["i"], True, keep_excluded_entries, fail_on_wrong_version) - return dPower_Hindex + return dPower_BusInfo -def get_dPower_WeightsRP(excel_file_path: str, keep_excluded_entries: bool = False, do_not_convert_values: bool = False) -> pd.DataFrame: +def get_dPower_Demand(excel_file_path: str, keep_excluded_entries: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: """ - Read the dPower_WeightsRP data from the Excel file. + Read the dPower_Demand data from the Excel file. :param excel_file_path: Path to the Excel file :param keep_excluded_entries: Unused but kept for compatibility with other functions - :param do_not_convert_values: Unused but kept for compatibility with other functions - :return: dPower_WeightsRP + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version + :return: dPower_Demand """ - dPower_WeightsRP = __read_non_pivoted_file(excel_file_path, "v0.1.3", ["rp"], False, False) + dPower_Demand = __read_pivoted_file(excel_file_path, "v0.1.2", ['rp', 'k', 'i'], 'k', ['rp', 'i', 'dataPackage', 'dataSource', 'id'], False, False, fail_on_wrong_version) if keep_excluded_entries: - printer.warning("'keep_excluded_entries' is set for 'get_dPower_WeightsRP', although nothing is excluded anyway - please check if this is intended.") - if do_not_convert_values: - printer.warning("'do_not_convert_values' is set for 'get_dPower_WeightsRP', although no values are converted anyway - please check if this is intended.") + printer.warning("'keep_excluded_entries' is set for 'get_dPower_Demand', although nothing is excluded anyway - please check if this is intended.") - return dPower_WeightsRP + return dPower_Demand -def get_dPower_WeightsK(excel_file_path: str, keep_excluded_entries: bool = False, do_not_convert_values: bool = False) -> pd.DataFrame: +def get_dPower_Hindex(excel_file_path: str, keep_excluded_entries: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: """ - Read the dPower_WeightsK data from the Excel file. + Read the dPower_Hindex data from the Excel file. :param excel_file_path: Path to the Excel file :param keep_excluded_entries: Unused but kept for compatibility with other functions - :param do_not_convert_values: Unused but kept for compatibility with other functions - :return: dPower_WeightsK + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version + :return: dPower_Hindex """ - dPower_WeightsK = __read_non_pivoted_file(excel_file_path, "v0.1.3", ["k"], False, False) + dPower_Hindex = __read_non_pivoted_file(excel_file_path, "v0.1.2", ["p", "rp", "k"], False, False, fail_on_wrong_version) if keep_excluded_entries: - printer.warning("'keep_excluded_entries' is set for 'get_dPower_WeightsK', although nothing is excluded anyway - please check if this is intended.") - if do_not_convert_values: - printer.warning("'do_not_convert_values' is set for 'get_dPower_WeightsK', although no values are converted anyway - please check if this is intended.") + printer.warning("'keep_excluded_entries' is set for 'get_dPower_Hindex', although nothing is excluded anyway - please check if this is intended.") - return dPower_WeightsK + return dPower_Hindex -def get_dPower_BusInfo(excel_file_path: str, keep_excluded_entries: bool = False, do_not_convert_values: bool = False) -> pd.DataFrame: +def get_dPower_Inflows(excel_file_path: str, keep_excluded_entries: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: """ - Read the dPower_BusInfo data from the Excel file. + Read the dPower_Inflows data from the Excel file. :param excel_file_path: Path to the Excel file - :param keep_excluded_entries: Do not exclude any entries which are marked to be excluded in the Excel file - :param do_not_convert_values: Unused but kept for compatibility with other functions - :return: dPower_BusInfo + :param keep_excluded_entries: Unused but kept for compatibility with other functions + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version + :return: dPower_Inflows """ - dPower_BusInfo = __read_non_pivoted_file(excel_file_path, "v0.1.2", ["i"], True, keep_excluded_entries) + dPower_Inflows = __read_pivoted_file(excel_file_path, "v0.0.1", ['rp', 'k', 'g'], 'k', ['rp', 'g', 'dataPackage', 'dataSource', 'id'], False, False, fail_on_wrong_version) - if do_not_convert_values: - printer.warning("'do_not_convert_values' is set for 'get_dPower_BusInfo', although no values are converted anyway - please check if this is intended.") + if keep_excluded_entries: + printer.warning("'keep_excluded_entries' is set for 'get_dPower_Inflows', although nothing is excluded anyway - please check if this is intended.") - return dPower_BusInfo + return dPower_Inflows -def get_dPower_Network(excel_file_path: str, keep_excluded_entries: bool = False, do_not_convert_values: bool = False) -> pd.DataFrame: +def get_dPower_Network(excel_file_path: str, keep_excluded_entries: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: """ Read the dPower_Network data from the Excel file. :param excel_file_path: Path to the Excel file :param keep_excluded_entries: Do not exclude any entries which are marked to be excluded in the Excel file - :param do_not_convert_values: Unused but kept for compatibility with other functions + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version :return: dPower_Network """ - dPower_Network = __read_non_pivoted_file(excel_file_path, "v0.1.1", ["i", "j", "c"], True, keep_excluded_entries) + dPower_Network = __read_non_pivoted_file(excel_file_path, "v0.1.2", ["i", "j", "c"], True, keep_excluded_entries, fail_on_wrong_version) return dPower_Network -def get_dPower_Demand(excel_file_path: str, keep_excluded_entries: bool = False, do_not_convert_values: bool = False) -> pd.DataFrame: +def get_dPower_Storage(excel_file_path: str, keep_excluded_entries: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: """ - Read the dPower_Demand data from the Excel file. + Read the dPower_Storage data from the Excel file. :param excel_file_path: Path to the Excel file - :param keep_excluded_entries: Unused but kept for compatibility with other functions - :param do_not_convert_values: Skip the conversion of values - :return: dPower_Demand + :param keep_excluded_entries: Do not exclude any entries which are marked to be excluded in the Excel file + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version + :return: dPower_Storage """ + dPower_Storage = __read_non_pivoted_file(excel_file_path, "v0.0.1", ["g"], True, keep_excluded_entries, fail_on_wrong_version) - dPower_Demand = __read_pivoted_file(excel_file_path, "v0.1.2", ['rp', 'k', 'i'], 'k', ['rp', 'i', 'dataPackage', 'dataSource', 'id'], False, False) - - if keep_excluded_entries: - printer.warning("'keep_excluded_entries' is set for 'get_dPower_Demand', although nothing is excluded anyway - please check if this is intended.") - - return dPower_Demand + return dPower_Storage -def get_dPower_ThermalGen(excel_file_path: str, keep_excluded_entries: bool = False, do_not_convert_values: bool = False) -> pd.DataFrame: +def get_dPower_ThermalGen(excel_file_path: str, keep_excluded_entries: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: """ Read the dPower_ThermalGen data from the Excel file. :param excel_file_path: Path to the Excel file :param keep_excluded_entries: Do not exclude any entries which are marked to be excluded in the Excel file - :param do_not_convert_values: Skip the conversion of values + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version :return: dPower_thermalGen """ - dPower_ThermalGen = __read_non_pivoted_file(excel_file_path, "v0.1.1", ["g"], True, keep_excluded_entries) + dPower_ThermalGen = __read_non_pivoted_file(excel_file_path, "v0.1.1", ["g"], True, keep_excluded_entries, fail_on_wrong_version) return dPower_ThermalGen -def get_dPower_VRES(excel_file_path: str, keep_excluded_entries: bool = False, do_not_convert_values: bool = False) -> pd.DataFrame: +def get_dPower_VRES(excel_file_path: str, keep_excluded_entries: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: """ Read the dPower_VRES data from the Excel file. :param excel_file_path: Path to the Excel file :param keep_excluded_entries: Do not exclude any entries which are marked to be excluded in the Excel file - :param do_not_convert_values: Skip the conversion of values + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version :return: dPower_VRES """ - dPower_VRES = __read_non_pivoted_file(excel_file_path, "v0.1.0", ["g"], True, keep_excluded_entries) + dPower_VRES = __read_non_pivoted_file(excel_file_path, "v0.1.0", ["g"], True, keep_excluded_entries, fail_on_wrong_version) return dPower_VRES -def get_dPower_VRESProfiles(excel_file_path: str, keep_excluded_entries: bool = False, do_not_convert_values: bool = False) -> pd.DataFrame: +def get_dPower_VRESProfiles(excel_file_path: str, keep_excluded_entries: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: """ Read the dPower_VRESProfiles data from the Excel file. :param excel_file_path: Path to the Excel file :param keep_excluded_entries: Unused but kept for compatibility with other functions - :param do_not_convert_values: Unused but kept for compatibility with other functions + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version :return: dPower_VRES """ - dPower_VRESProfiles = __read_pivoted_file(excel_file_path, "v0.1.0", ['rp', 'k', 'g'], 'k', ['rp', 'g', 'dataPackage', 'dataSource', 'id'], False, False) + dPower_VRESProfiles = __read_pivoted_file(excel_file_path, "v0.1.0", ['rp', 'k', 'g'], 'k', ['rp', 'g', 'dataPackage', 'dataSource', 'id'], False, False, fail_on_wrong_version) if keep_excluded_entries: - printer.warning("'keep_excluded_entries' is set for 'get_dPower_WeightsK', although nothing is excluded anyway - please check if this is intended.") - if do_not_convert_values: - printer.warning("'do_not_convert_values' is set for 'get_dPower_WeightsK', although no values are converted anyway - please check if this is intended.") + printer.warning("'keep_excluded_entries' is set for 'get_dPower_VRESProfiles', although nothing is excluded anyway - please check if this is intended.") return dPower_VRESProfiles -def get_dData_Sources(excel_file_path: str, keep_excluded_entries: bool = False, do_not_convert_values: bool = False) -> pd.DataFrame: +def get_dPower_WeightsK(excel_file_path: str, keep_excluded_entries: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: """ - Read the dData_Sources data from the Excel file. + Read the dPower_WeightsK data from the Excel file. :param excel_file_path: Path to the Excel file :param keep_excluded_entries: Unused but kept for compatibility with other functions - :param do_not_convert_values: Unused but kept for compatibility with other functions - :return: dData_Sources + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version + :return: dPower_WeightsK """ - dData_Sources = __read_non_pivoted_file(excel_file_path, "v0.1.0", ["dataSource"], False, False) + dPower_WeightsK = __read_non_pivoted_file(excel_file_path, "v0.1.3", ["k"], False, False, fail_on_wrong_version) if keep_excluded_entries: - printer.warning("'keep_excluded_entries' is set for 'get_dData_Sources', although nothing is excluded anyway - please check if this is intended.") - if do_not_convert_values: - printer.warning("'do_not_convert_values' is set for 'get_dData_Sources', although no values are converted anyway - please check if this is intended.") + printer.warning("'keep_excluded_entries' is set for 'get_dPower_WeightsK', although nothing is excluded anyway - please check if this is intended.") - return dData_Sources + return dPower_WeightsK -def get_dData_Packages(excel_file_path: str, keep_excluded_entries: bool = False, do_not_convert_values: bool = False) -> pd.DataFrame: +def get_dPower_WeightsRP(excel_file_path: str, keep_excluded_entries: bool = False, fail_on_wrong_version: bool = False) -> pd.DataFrame: """ - Read the dData_Packages data from the Excel file. + Read the dPower_WeightsRP data from the Excel file. :param excel_file_path: Path to the Excel file :param keep_excluded_entries: Unused but kept for compatibility with other functions - :param do_not_convert_values: Unused but kept for compatibility with other functions - :return: dData_Packages + :param fail_on_wrong_version: If True, raise an error if the version of the Excel file does not match the expected version + :return: dPower_WeightsRP """ - dData_Packages = __read_non_pivoted_file(excel_file_path, "v0.1.0", ["dataPackage"], False, False) + dPower_WeightsRP = __read_non_pivoted_file(excel_file_path, "v0.1.3", ["rp"], False, False, fail_on_wrong_version) if keep_excluded_entries: - printer.warning("'keep_excluded_entries' is set for 'get_dData_Packages', although nothing is excluded anyway - please check if this is intended.") - if do_not_convert_values: - printer.warning("'do_not_convert_values' is set for 'get_dData_Packages', although no values are converted anyway - please check if this is intended.") + printer.warning("'keep_excluded_entries' is set for 'get_dPower_WeightsRP', although nothing is excluded anyway - please check if this is intended.") - return dData_Packages + return dPower_WeightsRP def compare_Excels(source_path: str, target_path: str, dont_check_formatting: bool = False) -> bool: diff --git a/ExcelWriter.py b/ExcelWriter.py index 319fbe0..1c8f020 100644 --- a/ExcelWriter.py +++ b/ExcelWriter.py @@ -194,50 +194,69 @@ def _write_Excel_from_definition(self, data: pd.DataFrame, folder_path: str, exc wb.save(path) printer.information(f"Saved Excel file to '{path}' after {time.time() - start_time:.2f} seconds") - def write_dGlobal_Scenarios(self, dGlobal_Scenarios: pd.DataFrame, folder_path: str) -> None: + def write_dData_Packages(self, dData_Packages: pd.DataFrame, folder_path: str) -> None: """ - Write the dGlobal_Scenarios DataFrame to an Excel file in LEGO format. - :param dGlobal_Scenarios: DataFrame containing the dGlobal_Scenarios data. + Write the dData_Packages DataFrame to an Excel file in LEGO format. + :param dData_Packages: DataFrame containing the dData_Packages data. :param folder_path: Path to the folder where the Excel file will be saved. :return: None """ - self._write_Excel_from_definition(dGlobal_Scenarios, folder_path, "Global_Scenarios") + self._write_Excel_from_definition(dData_Packages, folder_path, "Data_Packages") - def write_dPower_Hindex(self, dPower_Hindex: pd.DataFrame, folder_path: str) -> None: + def write_dData_Sources(self, dData_Sources: pd.DataFrame, folder_path: str) -> None: """ - Write the dPower_Hindex DataFrame to an Excel file in LEGO format. - :param dPower_Hindex: DataFrame containing the dPower_Hindex data. + Write the dData_Sources DataFrame to an Excel file in LEGO format. + :param dData_Sources: DataFrame containing the dData_Sources data. :param folder_path: Path to the folder where the Excel file will be saved. :return: None """ - self._write_Excel_from_definition(dPower_Hindex, folder_path, "Power_Hindex") + self._write_Excel_from_definition(dData_Sources, folder_path, "Data_Sources") - def write_dPower_WeightsRP(self, dPower_WeightsRP: pd.DataFrame, folder_path: str) -> None: + def write_dPower_BusInfo(self, dPower_BusInfo: pd.DataFrame, folder_path: str) -> None: """ - Write the dPower_WeightsRP DataFrame to an Excel file in LEGO format. - :param dPower_WeightsRP: DataFrame containing the dPower_WeightsRP data. + Write the dPower_BusInfo DataFrame to an Excel file in LEGO format. + :param dPower_BusInfo: DataFrame containing the dPower_BusInfo data. :param folder_path: Path to the folder where the Excel file will be saved. :return: None """ - self._write_Excel_from_definition(dPower_WeightsRP, folder_path, "Power_WeightsRP") + self._write_Excel_from_definition(dPower_BusInfo, folder_path, "Power_BusInfo") - def write_dPower_WeightsK(self, dPower_WeightsK: pd.DataFrame, folder_path: str) -> None: + def write_dGlobal_Scenarios(self, dGlobal_Scenarios: pd.DataFrame, folder_path: str) -> None: """ - Write the dPower_WeightsK DataFrame to an Excel file in LEGO format. - :param dPower_WeightsK: DataFrame containing the dPower_WeightsK data. + Write the dGlobal_Scenarios DataFrame to an Excel file in LEGO format. + :param dGlobal_Scenarios: DataFrame containing the dGlobal_Scenarios data. :param folder_path: Path to the folder where the Excel file will be saved. :return: None """ - self._write_Excel_from_definition(dPower_WeightsK, folder_path, "Power_WeightsK") + self._write_Excel_from_definition(dGlobal_Scenarios, folder_path, "Global_Scenarios") - def write_dPower_BusInfo(self, dPower_BusInfo: pd.DataFrame, folder_path: str) -> None: + def write_dPower_Demand(self, dPower_Demand: pd.DataFrame, folder_path: str) -> None: """ - Write the dPower_BusInfo DataFrame to an Excel file in LEGO format. - :param dPower_BusInfo: DataFrame containing the dPower_BusInfo data. + Write the dPower_Demand DataFrame to an Excel file in LEGO format. + :param dPower_Demand: DataFrame containing the dPower_Demand data. :param folder_path: Path to the folder where the Excel file will be saved. :return: None """ - self._write_Excel_from_definition(dPower_BusInfo, folder_path, "Power_BusInfo") + + self._write_Excel_from_definition(dPower_Demand, folder_path, "Power_Demand") + + def write_dPower_Hindex(self, dPower_Hindex: pd.DataFrame, folder_path: str) -> None: + """ + Write the dPower_Hindex DataFrame to an Excel file in LEGO format. + :param dPower_Hindex: DataFrame containing the dPower_Hindex data. + :param folder_path: Path to the folder where the Excel file will be saved. + :return: None + """ + self._write_Excel_from_definition(dPower_Hindex, folder_path, "Power_Hindex") + + def write_dPower_Inflows(self, dPower_Inflows: pd.DataFrame, folder_path: str) -> None: + """ + Write the dPower_Inflows DataFrame to an Excel file in LEGO format. + :param dPower_Inflows: DataFrame containing the dPower_Inflows data. + :param folder_path: Path to the folder where the Excel file will be saved. + :return: None + """ + self._write_Excel_from_definition(dPower_Inflows, folder_path, "Power_Inflows") def write_dPower_Network(self, dPower_Network: pd.DataFrame, folder_path: str) -> None: """ @@ -248,15 +267,14 @@ def write_dPower_Network(self, dPower_Network: pd.DataFrame, folder_path: str) - """ self._write_Excel_from_definition(dPower_Network, folder_path, "Power_Network") - def write_dPower_Demand(self, dPower_Demand: pd.DataFrame, folder_path: str) -> None: + def write_dPower_Storage(self, dPower_Storage: pd.DataFrame, folder_path: str) -> None: """ - Write the dPower_Demand DataFrame to an Excel file in LEGO format. - :param dPower_Demand: DataFrame containing the dPower_Demand data. + Write the dPower_Storage DataFrame to an Excel file in LEGO format. + :param dPower_Storage: DataFrame containing the dPower_Storage data. :param folder_path: Path to the folder where the Excel file will be saved. :return: None """ - - self._write_Excel_from_definition(dPower_Demand, folder_path, "Power_Demand") + self._write_Excel_from_definition(dPower_Storage, folder_path, "Power_Storage") def write_dPower_ThermalGen(self, dPower_ThermalGen: pd.DataFrame, folder_path: str) -> None: """ @@ -285,23 +303,23 @@ def write_VRESProfiles(self, dPower_VRESProfiles: pd.DataFrame, folder_path: str """ self._write_Excel_from_definition(dPower_VRESProfiles, folder_path, "Power_VRESProfiles") - def write_dData_Sources(self, dData_Sources: pd.DataFrame, folder_path: str) -> None: + def write_dPower_WeightsK(self, dPower_WeightsK: pd.DataFrame, folder_path: str) -> None: """ - Write the dData_Sources DataFrame to an Excel file in LEGO format. - :param dData_Sources: DataFrame containing the dData_Sources data. + Write the dPower_WeightsK DataFrame to an Excel file in LEGO format. + :param dPower_WeightsK: DataFrame containing the dPower_WeightsK data. :param folder_path: Path to the folder where the Excel file will be saved. :return: None """ - self._write_Excel_from_definition(dData_Sources, folder_path, "Data_Sources") + self._write_Excel_from_definition(dPower_WeightsK, folder_path, "Power_WeightsK") - def write_dData_Packages(self, dData_Packages: pd.DataFrame, folder_path: str) -> None: + def write_dPower_WeightsRP(self, dPower_WeightsRP: pd.DataFrame, folder_path: str) -> None: """ - Write the dData_Packages DataFrame to an Excel file in LEGO format. - :param dData_Packages: DataFrame containing the dData_Packages data. + Write the dPower_WeightsRP DataFrame to an Excel file in LEGO format. + :param dPower_WeightsRP: DataFrame containing the dPower_WeightsRP data. :param folder_path: Path to the folder where the Excel file will be saved. :return: None """ - self._write_Excel_from_definition(dData_Packages, folder_path, "Data_Packages") + self._write_Excel_from_definition(dPower_WeightsRP, folder_path, "Power_WeightsRP") def model_to_excel(model: pyomo.core.Model, target_path: str) -> None: @@ -356,18 +374,20 @@ def model_to_excel(model: pyomo.core.Model, target_path: str) -> None: printer.separator() combinations = [ + ("Data_Packages", f"{args.caseStudyFolder}Data_Packages.xlsx", ExcelReader.get_dData_Packages, ew.write_dData_Packages), + ("Data_Sources", f"{args.caseStudyFolder}Data_Sources.xlsx", ExcelReader.get_dData_Sources, ew.write_dData_Sources), ("Global_Scenarios", f"{args.caseStudyFolder}Global_Scenarios.xlsx", ExcelReader.get_dGlobal_Scenarios, ew.write_dGlobal_Scenarios), - ("Power_Hindex", f"{args.caseStudyFolder}Power_Hindex.xlsx", ExcelReader.get_dPower_Hindex, ew.write_dPower_Hindex), - ("Power_WeightsRP", f"{args.caseStudyFolder}Power_WeightsRP.xlsx", ExcelReader.get_dPower_WeightsRP, ew.write_dPower_WeightsRP), - ("Power_WeightsK", f"{args.caseStudyFolder}Power_WeightsK.xlsx", ExcelReader.get_dPower_WeightsK, ew.write_dPower_WeightsK), ("Power_BusInfo", f"{args.caseStudyFolder}Power_BusInfo.xlsx", ExcelReader.get_dPower_BusInfo, ew.write_dPower_BusInfo), - ("Power_Network", f"{args.caseStudyFolder}Power_Network.xlsx", ExcelReader.get_dPower_Network, ew.write_dPower_Network), ("Power_Demand", f"{args.caseStudyFolder}Power_Demand.xlsx", ExcelReader.get_dPower_Demand, ew.write_dPower_Demand), + ("Power_Hindex", f"{args.caseStudyFolder}Power_Hindex.xlsx", ExcelReader.get_dPower_Hindex, ew.write_dPower_Hindex), + ("Power_Inflows", f"{args.caseStudyFolder}Power_Inflows.xlsx", ExcelReader.get_dPower_Inflows, ew.write_dPower_Inflows), + ("Power_Network", f"{args.caseStudyFolder}Power_Network.xlsx", ExcelReader.get_dPower_Network, ew.write_dPower_Network), + ("Power_Storage", f"{args.caseStudyFolder}Power_Storage.xlsx", ExcelReader.get_dPower_Storage, ew.write_dPower_Storage), ("Power_ThermalGen", f"{args.caseStudyFolder}Power_ThermalGen.xlsx", ExcelReader.get_dPower_ThermalGen, ew.write_dPower_ThermalGen), ("Power_VRES", f"{args.caseStudyFolder}Power_VRES.xlsx", ExcelReader.get_dPower_VRES, ew.write_VRES), ("Power_VRESProfiles", f"{args.caseStudyFolder}Power_VRESProfiles.xlsx", ExcelReader.get_dPower_VRESProfiles, ew.write_VRESProfiles), - ("Data_Sources", f"{args.caseStudyFolder}Data_Sources.xlsx", ExcelReader.get_dData_Sources, ew.write_dData_Sources), - ("Data_Packages", f"{args.caseStudyFolder}Data_Packages.xlsx", ExcelReader.get_dData_Packages, ew.write_dData_Packages), + ("Power_WeightsK", f"{args.caseStudyFolder}Power_WeightsK.xlsx", ExcelReader.get_dPower_WeightsK, ew.write_dPower_WeightsK), + ("Power_WeightsRP", f"{args.caseStudyFolder}Power_WeightsRP.xlsx", ExcelReader.get_dPower_WeightsRP, ew.write_dPower_WeightsRP), ] for excel_definition_id, file_path, read, write in combinations: diff --git a/TableDefinitions.xml b/TableDefinitions.xml index 5497860..487d494 100644 --- a/TableDefinitions.xml +++ b/TableDefinitions.xml @@ -1,6 +1,31 @@ - + + + v0.1.0 + Data Packages + 45.0 + + + + + + + + + v0.1.0 + Data Sources + 45.0 + + + + + + + + + + v0.1.0 Global - Scenarios and Probabilities @@ -13,72 +38,74 @@ - + v0.1.2 - Power - Relation among periods and representative periods - 30.0 + Power - Bus information + 45.0 - + - - - + + + + + + + + + + + + + - - v0.1.3 - Power - Weights of representative periods + + v0.1.2 + Power - Demand 30.0 - + + - - v0.1.3 - Power - Weights of representative hours + + v0.1.2 + Power - Relation among periods and representative periods 30.0 - - + + + - - v0.1.2 - Power - Bus information - 45.0 + + v0.0.1 + Power - Inflows + 60.0 - + - - - - - - - - - - - - - + + + - v0.1.1 + v0.1.2 Power - Network 45.0 @@ -103,18 +130,41 @@ - - v0.1.2 - Power - Demand - 30.0 + + v0.0.1 + Power - Storage + 60.0 - + - + + + + + + + + + + + + + + + + + + + + + + + + + - @@ -197,29 +247,30 @@ - - v0.1.0 - Data Sources - 45.0 + + v0.1.3 + Power - Weights of representative hours + 30.0 - - - - - - + + + + + - - v0.1.0 - Data Packages - 45.0 + + v0.1.3 + Power - Weights of representative periods + 30.0 - - - + + + + + @@ -232,6 +283,13 @@ 15.0 general + + Charge Efficiency + Efficiency of charging the storage unit + [%, 0-1] + 21.0 + rightFloat2 + CO2Emis Specific CO2 emissions of the unit @@ -267,6 +325,13 @@ 23.86 general + + Discharge Efficiency + Efficiency of discharging the storage unit + [%, 0-1] + 21.0 + rightFloat2 + Efficiency Efficiency calculated as 1/input for 1 MWh, i.e. 0.5 (or 50%) if 2 MWh fuel are required for 1 MWh electricity @@ -288,6 +353,13 @@ 15.0 rightInt + + Energy to Power Ratio + Energy to power ratio of the storage unit + [h] + 22.0 + rightFloat1 + Excl. @@ -344,6 +416,13 @@ 15.0 rightFloat1 + + Initial Reserve + Initial reserve of the storage unit + [%, 0-1] + 15.0 + rightFloat2 + InvestCost Annualized investment cost per MW @@ -351,6 +430,27 @@ 15.0 rightFloat2 + + InvestCostPerMW + Annualized investment cost per MW of MaxProd + [€/MW] + 20.0 + rightFloat2 + + + InvestCostPerMWh + Annualized investment cost per MWh of storage capacity + [€/MWh] + 20.0 + rightFloat2 + + + IsLDS + Whether the storage unit is a long-duration storage (1) or not (0) + [0, 1] + 20.0 + rightInt + To Node To which node @@ -393,6 +493,13 @@ 15.0 rightFloat4 + + MaxCons + Maximum consumption of the unit + [MW] + 15.0 + rightFloat1 + MaxInvest Maximum number of units that can be invested in @@ -421,6 +528,13 @@ 15.0 rightFloat1 + + MinReserve + Minimum reserve of the storage unit + [%, 0-1] + 15.0 + rightFloat2 + MinUpTime Minimum time the unit has to be on after a startup @@ -557,7 +671,7 @@ Technical Representation Technical representation of line in model - [DC-OPF,TP,SN] + [SOCP,DC-OPF,TP,SN] 26.0 general @@ -631,6 +745,13 @@ 41.0 general + + Self Discharge + Self discharge of the storage unit + [%, 0-1] + 20.0 + rightFloat2 + Source(s) List of used sources (detailing which values are from where) @@ -699,6 +820,14 @@ 10.57 rightInt + + + k + Inflow for each unit at this k + [MWh] + 10.57 + rightFloat2 + diff --git a/changelog-LEGOExcels.md b/changelog-LEGOExcels.md index bbdf67c..e84ef1d 100644 --- a/changelog-LEGOExcels.md +++ b/changelog-LEGOExcels.md @@ -1,61 +1,22 @@ -# Global_Scenarios - -## v0.1.0 - -Very first version. - -# Power_Hindex - -## v0.1.1 → v0.1.2 - -Adjust column widths. - -## v0.1.0 → v0.1.1 - -Fix description for columns 'rp' and 'k' to be more general. +# Data_Packages -## v0.0.2r → v0.1.0 +## v0.0.2 → v0.1.0 Switching to "scripted" method when writing Excel-File (instead of copying from template), thus slight changes in -formatting and description texts. - -# Power_WeightsRP - -## v0.1.2 → v0.1.3 - -Adjust column widths and number formatting of weights. - -## v0.1.1 → v0.1.2 - -Fix formatting of pWeight_rp column. - -## v0.1.0 → v0.1.1 +formatting and description texts. Change of identifier from 'packageName' to 'dataPackage'. -Fix description for column 'rp' to be more general. +# Data_Sources ## v0.0.2 → v0.1.0 Switching to "scripted" method when writing Excel-File (instead of copying from template), thus slight changes in -formatting and description texts. - -# Power_WeightsK - -## v0.1.2 → v0.1.3 - -Adjust column widths. - -## v0.1.1 → v0.1.2 - -Fix formatting of pWeight_k column. - -## v0.1.0 → v0.1.1 +formatting and description texts. Change of identifier from 'sourceName' to 'dataSource'. -Fix description for column 'k' to be more general. +# Global_Scenarios -## v0.0.2r → v0.1.0 +## v0.1.0 -Switching to "scripted" method when writing Excel-File (instead of copying from template), thus slight changes in -formatting and description texts. +Very first version. # Power_BusInfo @@ -109,17 +70,6 @@ formatting and description texts. | Power_BusInfo | O8 (and others) | 'Yes' | '1' | Entered Value Changed. | | Power_BusInfo | A4 | 'Background color: Color [Window], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | 'Background color: Color [A=255, R=216, G=216, B=216], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | Cell Formatting Changed | -# Power_Network - -## v0.1.0 → v0.1.1 - -Fix comment in 'excl' column, adjust columnd widths. - -## v0.0.4r → v0.1.0 - -Switching to "scripted" method when writing Excel-File (instead of copying from template), thus slight changes in -formatting and description texts. - # Power_Demand ## v0.1.1 → v0.1.2 @@ -168,6 +118,44 @@ formatting and description texts. | Power_Network | L8 (and others) | 'No' | '0' | Entered Value Changed. | | Power_Network | A4 | 'Background color: Color [Window], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | 'Background color: Color [A=255, R=216, G=216, B=216], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | Cell Formatting Changed | +# Power_Hindex + +## v0.1.1 → v0.1.2 + +Adjust column widths. + +## v0.1.0 → v0.1.1 + +Fix description for columns 'rp' and 'k' to be more general. + +## v0.0.2r → v0.1.0 + +Switching to "scripted" method when writing Excel-File (instead of copying from template), thus slight changes in +formatting and description texts. + +# Power_Inflows + +Please see git history of `TabbleDefinitions.xml`. + +# Power_Network + +## \>v0.1.1 + +Please see git history of `TabbleDefinitions.xml`. + +## v0.1.0 → v0.1.1 + +Fix comment in 'excl' column, adjust columnd widths. + +## v0.0.4r → v0.1.0 + +Switching to "scripted" method when writing Excel-File (instead of copying from template), thus slight changes in +formatting and description texts. + +# Power_Storage + +Please see git history of `TabbleDefinitions.xml`. + # Power_ThermalGen ## v0.1.0 → v0.1.1 @@ -313,16 +301,40 @@ formatting and description texts. Switching to "scripted" method when writing Excel-File (instead of copying from template), thus slight changes in formatting and description texts. -# Data_Sources +# Power_WeightsK -## v0.0.2 → v0.1.0 +## v0.1.2 → v0.1.3 + +Adjust column widths. + +## v0.1.1 → v0.1.2 + +Fix formatting of pWeight_k column. + +## v0.1.0 → v0.1.1 + +Fix description for column 'k' to be more general. + +## v0.0.2r → v0.1.0 Switching to "scripted" method when writing Excel-File (instead of copying from template), thus slight changes in -formatting and description texts. Change of identifier from 'sourceName' to 'dataSource'. +formatting and description texts. -# Data_Packages +# Power_WeightsRP + +## v0.1.2 → v0.1.3 + +Adjust column widths and number formatting of weights. + +## v0.1.1 → v0.1.2 + +Fix formatting of pWeight_rp column. + +## v0.1.0 → v0.1.1 + +Fix description for column 'rp' to be more general. ## v0.0.2 → v0.1.0 Switching to "scripted" method when writing Excel-File (instead of copying from template), thus slight changes in -formatting and description texts. Change of identifier from 'packageName' to 'dataPackage'. +formatting and description texts. diff --git a/data/example/Power_Inflows.xlsx b/data/example/Power_Inflows.xlsx new file mode 100644 index 0000000..c58dab2 Binary files /dev/null and b/data/example/Power_Inflows.xlsx differ diff --git a/data/example/Power_Network.xlsx b/data/example/Power_Network.xlsx index e0bf995..d2c543f 100644 Binary files a/data/example/Power_Network.xlsx and b/data/example/Power_Network.xlsx differ diff --git a/data/example/Power_Storage.xlsx b/data/example/Power_Storage.xlsx new file mode 100644 index 0000000..007ded9 Binary files /dev/null and b/data/example/Power_Storage.xlsx differ diff --git a/tests/test_ExcelReaderWriter.py b/tests/test_ExcelReaderWriter.py index cbbd61e..cc0d7ac 100644 --- a/tests/test_ExcelReaderWriter.py +++ b/tests/test_ExcelReaderWriter.py @@ -9,18 +9,20 @@ case_study_folder = "data/example/" ew = ExcelWriter() combinations = [ + ("Data_Packages", f"{case_study_folder}Data_Packages.xlsx", ExcelReader.get_dData_Packages, ew.write_dData_Packages), + ("Data_Sources", f"{case_study_folder}Data_Sources.xlsx", ExcelReader.get_dData_Sources, ew.write_dData_Sources), ("Global_Scenarios", f"{case_study_folder}Global_Scenarios.xlsx", ExcelReader.get_dGlobal_Scenarios, ew.write_dGlobal_Scenarios), - ("Power_Hindex", f"{case_study_folder}Power_Hindex.xlsx", ExcelReader.get_dPower_Hindex, ew.write_dPower_Hindex), - ("Power_WeightsRP", f"{case_study_folder}Power_WeightsRP.xlsx", ExcelReader.get_dPower_WeightsRP, ew.write_dPower_WeightsRP), - ("Power_WeightsK", f"{case_study_folder}Power_WeightsK.xlsx", ExcelReader.get_dPower_WeightsK, ew.write_dPower_WeightsK), ("Power_BusInfo", f"{case_study_folder}Power_BusInfo.xlsx", ExcelReader.get_dPower_BusInfo, ew.write_dPower_BusInfo), - ("Power_Network", f"{case_study_folder}Power_Network.xlsx", ExcelReader.get_dPower_Network, ew.write_dPower_Network), ("Power_Demand", f"{case_study_folder}Power_Demand.xlsx", ExcelReader.get_dPower_Demand, ew.write_dPower_Demand), + ("Power_Hindex", f"{case_study_folder}Power_Hindex.xlsx", ExcelReader.get_dPower_Hindex, ew.write_dPower_Hindex), + ("Power_Inflows", f"{case_study_folder}Power_Inflows.xlsx", ExcelReader.get_dPower_Inflows, ew.write_dPower_Inflows), + ("Power_Network", f"{case_study_folder}Power_Network.xlsx", ExcelReader.get_dPower_Network, ew.write_dPower_Network), + ("Power_Storage", f"{case_study_folder}Power_Storage.xlsx", ExcelReader.get_dPower_Storage, ew.write_dPower_Storage), ("Power_ThermalGen", f"{case_study_folder}Power_ThermalGen.xlsx", ExcelReader.get_dPower_ThermalGen, ew.write_dPower_ThermalGen), ("Power_VRES", f"{case_study_folder}Power_VRES.xlsx", ExcelReader.get_dPower_VRES, ew.write_VRES), ("Power_VRESProfiles", f"{case_study_folder}Power_VRESProfiles.xlsx", ExcelReader.get_dPower_VRESProfiles, ew.write_VRESProfiles), - ("Data_Sources", f"{case_study_folder}Data_Sources.xlsx", ExcelReader.get_dData_Sources, ew.write_dData_Sources), - ("Data_Packages", f"{case_study_folder}Data_Packages.xlsx", ExcelReader.get_dData_Packages, ew.write_dData_Packages), + ("Power_WeightsK", f"{case_study_folder}Power_WeightsK.xlsx", ExcelReader.get_dPower_WeightsK, ew.write_dPower_WeightsK), + ("Power_WeightsRP", f"{case_study_folder}Power_WeightsRP.xlsx", ExcelReader.get_dPower_WeightsRP, ew.write_dPower_WeightsRP), ]