diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 812dd86..e5c464c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -2,7 +2,6 @@ name: CI on: push: - pull_request: jobs: run_tests: @@ -15,6 +14,13 @@ jobs: fail-fast: false matrix: os: [ ubuntu-latest, windows-latest, macos-latest ] + isMainBranch: + - ${{ contains(github.ref, 'main') }} # Check if the branch is main + exclude: + - isMainBranch: false + os: windows-latest # Exclude Windows for non-main branches + - isMainBranch: false + os: macos-latest # Exclude macOS for non-main branches steps: - name: Checkout repository uses: actions/checkout@v4.2.2 diff --git a/.gitignore b/.gitignore index b39262e..21b87b7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ __pycache__/ # Example output -examples/output +data/example/output # Temporary files ~$*.xlsx diff --git a/CaseStudy.py b/CaseStudy.py index 835a22e..25407c6 100644 --- a/CaseStudy.py +++ b/CaseStudy.py @@ -10,7 +10,10 @@ class CaseStudy: - def __init__(self, data_folder: str, do_not_merge_single_node_buses: bool = False, + def __init__(self, + data_folder: str, + do_not_scale_units: bool = False, + do_not_merge_single_node_buses: bool = False, global_parameters_file: str = "Global_Parameters.xlsx", dGlobal_Parameters: pd.DataFrame = None, global_scenarios_file: str = "Global_Scenarios.xlsx", dGlobal_Scenarios: pd.DataFrame = None, power_parameters_file: str = "Power_Parameters.xlsx", dPower_Parameters: pd.DataFrame = None, @@ -29,6 +32,7 @@ def __init__(self, data_folder: str, do_not_merge_single_node_buses: bool = Fals power_impexphubs_file: str = "Power_ImpExpHubs.xlsx", dPower_ImpExpHubs: pd.DataFrame = None, power_impexpprofiles_file: str = "Power_ImpExpProfiles.xlsx", dPower_ImpExpProfiles: pd.DataFrame = None): self.data_folder = data_folder if data_folder.endswith("/") else data_folder + "/" + self.do_not_scale_units = do_not_scale_units self.do_not_merge_single_node_buses = do_not_merge_single_node_buses if dGlobal_Parameters is not None: @@ -146,15 +150,132 @@ def __init__(self, data_folder: str, do_not_merge_single_node_buses: bool = Fals if not do_not_merge_single_node_buses: self.merge_single_node_buses() + self.power_scaling_factor = self.dGlobal_Parameters["pPowerScalingFactor"] + self.cost_scaling_factor = self.dGlobal_Parameters["pCostScalingFactor"] + self.angle_to_rad_scaling_factor = np.pi / 180 + + if not do_not_scale_units: + self.scale_CaseStudy() + def copy(self): return copy.deepcopy(self) + def scale_CaseStudy(self): + self.scale_dPower_Parameters() + self.scale_dPower_Network() + self.scale_dPower_Demand() + + if self.dPower_Parameters["pEnableThermalGen"]: + self.scale_dPower_ThermalGen() + + if self.dPower_Parameters["pEnableRoR"]: + self.scale_dPower_RoR() + self.scale_dPower_Inflows() + + if self.dPower_Parameters["pEnableVRES"]: + self.scale_dPower_VRES() + + if self.dPower_Parameters["pEnableStorage"]: + self.scale_dPower_Storage() + + if self.dPower_Parameters["pEnablePowerImportExport"]: + self.scale_dPower_ImpExpHubs() + self.scale_dPower_ImpExpProfiles() + + def remove_scaling(self): + self.power_scaling_factor = 1 / self.power_scaling_factor + self.cost_scaling_factor = 1 / self.cost_scaling_factor + self.angle_to_rad_scaling_factor = 1 / self.angle_to_rad_scaling_factor + + self.scale_CaseStudy() + + self.power_scaling_factor = 1 / self.power_scaling_factor + self.cost_scaling_factor = 1 / self.cost_scaling_factor + self.angle_to_rad_scaling_factor = 1 / self.angle_to_rad_scaling_factor + + def scale_dPower_Parameters(self): + self.dPower_Parameters["pSBase"] *= self.power_scaling_factor + self.dPower_Parameters["pENSCost"] *= self.cost_scaling_factor / self.power_scaling_factor + self.dPower_Parameters["pLOLCost"] *= self.cost_scaling_factor / self.power_scaling_factor + + self.dPower_Parameters["pMaxAngleDCOPF"] *= self.angle_to_rad_scaling_factor # Convert angle from degrees to radians + + def scale_dPower_Network(self): + self.dPower_Network["pInvestCost"] = self.dPower_Network["pInvestCost"].fillna(0) + self.dPower_Network["pPmax"] *= self.power_scaling_factor + + 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 + + # Only FuelCost is adjusted by efficiency (OMVarCost is not), then both are scaled by the cost_scaling_factor / power_scaling_factor + self.dPower_ThermalGen['pSlopeVarCostEUR'] = (self.dPower_ThermalGen['OMVarCost'] + self.dPower_ThermalGen['FuelCost'] / self.dPower_ThermalGen['Efficiency']) * (self.cost_scaling_factor / self.power_scaling_factor) + + # Calculate interVar- and startup-costs in EUR, and then scale by cost_scaling_factor + self.dPower_ThermalGen['pInterVarCostEUR'] = self.dPower_ThermalGen['CommitConsumption'] * self.dPower_ThermalGen['FuelCost'] * self.cost_scaling_factor + self.dPower_ThermalGen['pStartupCostEUR'] = self.dPower_ThermalGen['StartupConsumption'] * self.dPower_ThermalGen['FuelCost'] * self.cost_scaling_factor + + self.dPower_ThermalGen['MaxInvest'] = self.dPower_ThermalGen.apply(lambda x: 1 if x['EnableInvest'] == 1 and x['ExisUnits'] == 0 else 0, axis=1) + self.dPower_ThermalGen['RampUp'] *= self.power_scaling_factor + self.dPower_ThermalGen['RampDw'] *= self.power_scaling_factor + self.dPower_ThermalGen['MaxProd'] *= self.power_scaling_factor * (1 - self.dPower_ThermalGen['EFOR']) + self.dPower_ThermalGen['MinProd'] *= self.power_scaling_factor * (1 - self.dPower_ThermalGen['EFOR']) + self.dPower_ThermalGen['InvestCostEUR'] = self.dPower_ThermalGen['InvestCost'] * (self.cost_scaling_factor / self.power_scaling_factor) * self.dPower_ThermalGen['MaxProd'] # InvestCost is scaled here, scaling of MaxProd happens above + + # Fill NaN values with 0 for MinUpTime and MinDownTime + self.dPower_ThermalGen['MinUpTime'] = self.dPower_ThermalGen['MinUpTime'].fillna(0) + self.dPower_ThermalGen['MinDownTime'] = self.dPower_ThermalGen['MinDownTime'].fillna(0) + + # Check that both MinUpTime and MinDownTime are integers and raise error if not + if not self.dPower_ThermalGen.MinUpTime.dtype == np.int64: + raise ValueError("MinUpTime must be an integer for all entries.") + if not self.dPower_ThermalGen.MinDownTime.dtype == np.int64: + raise ValueError("MinDownTime must be an integer for all entries.") + self.dPower_ThermalGen['MinUpTime'] = self.dPower_ThermalGen['MinUpTime'].astype('int64') + self.dPower_ThermalGen['MinDownTime'] = self.dPower_ThermalGen['MinDownTime'].astype('int64') + + 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 + + def scale_dPower_Inflows(self): + self.dPower_Inflows["Inflow"] *= self.power_scaling_factor + + def scale_dPower_VRES(self): + if "MinProd" not in self.dPower_VRES.columns: + self.dPower_VRES['MinProd'] = 0 + + self.dPower_VRES['InvestCostEUR'] = self.dPower_VRES['InvestCost'] * (self.cost_scaling_factor / self.power_scaling_factor) * self.dPower_VRES['MaxProd'] * self.power_scaling_factor + self.dPower_VRES['MaxProd'] *= self.power_scaling_factor + self.dPower_VRES['OMVarCost'] *= (self.cost_scaling_factor / self.power_scaling_factor) + + def scale_dPower_Storage(self): + 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) + self.dPower_Storage['pOMVarCostEUR'] = self.dPower_Storage['OMVarCost'] * (self.cost_scaling_factor / self.power_scaling_factor) + self.dPower_Storage['InvestCostEUR'] = self.dPower_Storage['MaxProd'] * self.power_scaling_factor * (self.dPower_Storage['InvestCostPerMW'] + self.dPower_Storage['InvestCostPerMWh'] * self.dPower_Storage['Ene2PowRatio']) * (self.cost_scaling_factor / self.power_scaling_factor) + self.dPower_Storage['MaxProd'] *= self.power_scaling_factor + self.dPower_Storage['MaxCons'] *= self.power_scaling_factor + + def scale_dPower_ImpExpHubs(self): + self.dPower_ImpExpHubs["Pmax Import"] *= self.power_scaling_factor + self.dPower_ImpExpHubs["Pmax Export"] *= self.power_scaling_factor + + def scale_dPower_ImpExpProfiles(self): + self.dPower_ImpExpProfiles["ImpExp"] *= self.power_scaling_factor + def get_dGlobal_Parameters(self): dGlobal_Parameters = pd.read_excel(self.data_folder + self.global_parameters_file, skiprows=[0, 1]) dGlobal_Parameters = dGlobal_Parameters.drop(dGlobal_Parameters.columns[0], axis=1) - dGlobal_Parameters = dGlobal_Parameters.set_index('Sectors') + dGlobal_Parameters = dGlobal_Parameters.set_index('Solver Options') - self.yesNo_to_bool(dGlobal_Parameters, ['pEnablePower', 'pEnableGas', 'pEnableHeat', 'pEnableH2', 'pEnableRMIP']) + self.yesNo_to_bool(dGlobal_Parameters, ['pEnableRMIP']) # Transform to make it easier to access values dGlobal_Parameters = dGlobal_Parameters.drop(dGlobal_Parameters.columns[1:], axis=1) # Drop all columns but "Value" (rest is just for information in the Excel) @@ -174,12 +295,6 @@ def get_dPower_Parameters(self): dPower_Parameters = dPower_Parameters.drop(dPower_Parameters.columns[1:], axis=1) # Drop all columns but "Value" (rest is just for information in the Excel) dPower_Parameters = dict({(parameter_name, parameter_value["Value"]) for parameter_name, parameter_value in dPower_Parameters.iterrows()}) # Transform into dictionary - # Value adjustments - dPower_Parameters["pMaxAngleDCOPF"] = dPower_Parameters["pMaxAngleDCOPF"] * np.pi / 180 # Convert angle from degrees to radians - dPower_Parameters["pSBase"] *= 1e-3 - dPower_Parameters["pENSCost"] *= 1e-3 - dPower_Parameters["pLOLCost"] *= 1e-3 - return dPower_Parameters @staticmethod @@ -197,9 +312,6 @@ def yesNo_to_bool(df: pd.DataFrame, columns_to_be_changed: list[str]): def get_dPower_RoR(self): dPower_RoR = self.read_generator_data(self.data_folder + self.power_ror_file) - dPower_RoR['InvestCostEUR'] = dPower_RoR['MaxProd'] * 1e-3 * (dPower_RoR['InvestCostPerMW'] * 1e-3 + dPower_RoR['InvestCostPerMWh'] * 1e-3 * dPower_RoR['Ene2PowRatio']) - dPower_RoR['MaxProd'] *= 1e-3 - # 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 @@ -207,13 +319,6 @@ def get_dPower_RoR(self): def get_dPower_Storage(self): dPower_Storage = self.read_generator_data(self.data_folder + self.power_storage_file) - dPower_Storage['pOMVarCostEUR'] = dPower_Storage['OMVarCost'] * 1e-3 - dPower_Storage['IniReserve'] = dPower_Storage['IniReserve'].fillna(0) - dPower_Storage['MinReserve'] = dPower_Storage['MinReserve'].fillna(0) - dPower_Storage['MinProd'] = dPower_Storage["MinProd"].fillna(0) - dPower_Storage['InvestCostEUR'] = dPower_Storage['MaxProd'] * 1e-3 * (dPower_Storage['InvestCostPerMW'] * 1e-3 + dPower_Storage['InvestCostPerMWh'] * 1e-3 * dPower_Storage['Ene2PowRatio']) - dPower_Storage['MaxProd'] *= 1e-3 - dPower_Storage['MaxCons'] *= 1e-3 # If column 'scenario' is not present, add it if 'scenario' not in dPower_Storage.columns: @@ -227,7 +332,9 @@ def get_dPower_Inflows(self): dPower_Inflows = dPower_Inflows.melt(id_vars=['rp', 'g'], var_name='k', value_name='Inflow') dPower_Inflows = dPower_Inflows.set_index(['rp', 'g', 'k']) - dPower_Inflows['scenario'] = 'ScenarioA' # TODO: Fill this dynamically, once the Excel file is updated + # 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): @@ -249,14 +356,9 @@ def get_dPower_ImpExpHubs(self): if len(errors) > 0: raise ValueError(f"Each hub must have the same Import Type (Fix or Max) and the same Export Type (Fix or Max) for each connection. Please check: \n{errors.index}\n") - # Adjust values - dPower_ImpExpHubs["Pmax Import"] *= 1e-3 - dPower_ImpExpHubs["Pmax Export"] *= 1e-3 - # If column 'scenario' is not present, add it if 'scenario' not in dPower_ImpExpHubs.columns: dPower_ImpExpHubs['scenario'] = 'ScenarioA' # TODO: Fill this dynamically, once the Excel file is updated - return dPower_ImpExpHubs def get_dPower_ImpExpProfiles(self): @@ -280,9 +382,6 @@ def get_dPower_ImpExpProfiles(self): dPower_ImpExpProfiles = dPower_ImpExpProfiles.pivot(columns="Type", values="Value") dPower_ImpExpProfiles.columns.name = None # Fix name of columns/indices (which are altered through pivot) - # Adjust values - dPower_ImpExpProfiles["ImpExp"] *= 1e-3 - # Check that Pmax of ImpExpConnections can handle the maximum import and export (for those connections that are ImpFix or ExpFix) max_import = dPower_ImpExpProfiles[dPower_ImpExpProfiles["ImpExp"] >= 0]["ImpExp"].groupby("hub").max() max_export = -dPower_ImpExpProfiles[dPower_ImpExpProfiles["ImpExp"] <= 0]["ImpExp"].groupby("hub").min() @@ -295,20 +394,17 @@ def get_dPower_ImpExpProfiles(self): error_information = pd.concat([import_violations, pmax_sum_by_hub['Pmax Import']], axis=1) # Concat Pmax information and maximum import error_information = error_information[error_information["ImpExp"].notna()] # Only show rows where there is a violation error_information = error_information.rename(columns={"ImpExp": "Max Import from Profiles", "Pmax Import": "Sum of Pmax Import from Hub Definition"}) # Rename columns for readability - error_information *= 1e3 # Convert back to input format raise ValueError(f"At least one hub has ImpFix imports which exceed the sum of Pmax of all connections. Please check: \n{error_information}\n") if not export_violations.empty: error_information = pd.concat([export_violations, pmax_sum_by_hub['Pmax Export']], axis=1) # Concat Pmax information and maximum export error_information = error_information[error_information["ImpExp"].notna()] # Only show rows where there is a violation error_information = error_information.rename(columns={"ImpExp": "Max Export from Profiles", "Pmax Export": "Sum of Pmax Export from Hub Definition"}) # Rename columns for readability - error_information *= 1e3 # Convert back to input format raise ValueError(f"At least one hub has ExpFix exports which exceed the sum of Pmax of all connections. Please check: \n{error_information}\n") # If column 'scenario' is not present, add it if 'scenario' not in dPower_ImpExpProfiles.columns: dPower_ImpExpProfiles['scenario'] = "ScenarioA" # TODO: Fill this dynamically, once the Excel file is updated - return dPower_ImpExpProfiles @staticmethod diff --git a/ExcelReader.py b/ExcelReader.py index 543f906..e753250 100644 --- a/ExcelReader.py +++ b/ExcelReader.py @@ -1,6 +1,5 @@ import time -import numpy as np import openpyxl import pandas as pd from openpyxl import load_workbook @@ -158,10 +157,6 @@ def get_dPower_Network(excel_file_path: str, keep_excluded_entries: bool = False """ dPower_Network = __read_non_pivoted_file(excel_file_path, "v0.1.1", ["i", "j", "c"], True, keep_excluded_entries) - if not do_not_convert_values: - dPower_Network["pInvestCost"] = dPower_Network["pInvestCost"].fillna(0) - dPower_Network["pPmax"] *= 1e-3 - return dPower_Network @@ -179,9 +174,6 @@ def get_dPower_Demand(excel_file_path: str, keep_excluded_entries: bool = 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.") - if not do_not_convert_values: - dPower_Demand["value"] = dPower_Demand["value"] * 1e-3 - return dPower_Demand @@ -195,35 +187,6 @@ def get_dPower_ThermalGen(excel_file_path: str, keep_excluded_entries: bool = Fa """ dPower_ThermalGen = __read_non_pivoted_file(excel_file_path, "v0.1.1", ["g"], True, keep_excluded_entries) - if not do_not_convert_values: - dPower_ThermalGen = dPower_ThermalGen[(dPower_ThermalGen["ExisUnits"] > 0) | (dPower_ThermalGen["EnableInvest"] > 0)] # Filter out all generators that are not existing and not investable - - dPower_ThermalGen['EFOR'] = dPower_ThermalGen['EFOR'].fillna(0) # Fill NaN values with 0 for EFOR - - dPower_ThermalGen['pSlopeVarCostEUR'] = (dPower_ThermalGen['OMVarCost'] * 1e-3 + - dPower_ThermalGen['FuelCost']) / dPower_ThermalGen['Efficiency'] * 1e-3 - - dPower_ThermalGen['pInterVarCostEUR'] = dPower_ThermalGen['CommitConsumption'] * 1e-6 * dPower_ThermalGen['FuelCost'] - dPower_ThermalGen['pStartupCostEUR'] = dPower_ThermalGen['StartupConsumption'] * 1e-6 * dPower_ThermalGen['FuelCost'] - dPower_ThermalGen['MaxInvest'] = dPower_ThermalGen.apply(lambda x: 1 if x['EnableInvest'] == 1 and x['ExisUnits'] == 0 else 0, axis=1) - dPower_ThermalGen['RampUp'] *= 1e-3 - dPower_ThermalGen['RampDw'] *= 1e-3 - dPower_ThermalGen['MaxProd'] *= 1e-3 * (1 - dPower_ThermalGen['EFOR']) - dPower_ThermalGen['MinProd'] *= 1e-3 * (1 - dPower_ThermalGen['EFOR']) - dPower_ThermalGen['InvestCostEUR'] = dPower_ThermalGen['InvestCost'] * 1e-3 * dPower_ThermalGen['MaxProd'] # InvestCost is scaled here (1e-3), scaling of MaxProd happens above - - # Fill NaN values with 0 for MinUpTime and MinDownTime - dPower_ThermalGen['MinUpTime'] = dPower_ThermalGen['MinUpTime'].fillna(0) - dPower_ThermalGen['MinDownTime'] = dPower_ThermalGen['MinDownTime'].fillna(0) - - # Check that both MinUpTime and MinDownTime are integers and raise error if not - if not dPower_ThermalGen.MinUpTime.dtype == np.int64: - raise ValueError("MinUpTime must be an integer for all entries.") - if not dPower_ThermalGen.MinDownTime.dtype == np.int64: - raise ValueError("MinDownTime must be an integer for all entries.") - dPower_ThermalGen['MinUpTime'] = dPower_ThermalGen['MinUpTime'].astype(int) - dPower_ThermalGen['MinDownTime'] = dPower_ThermalGen['MinDownTime'].astype(int) - return dPower_ThermalGen @@ -237,13 +200,6 @@ def get_dPower_VRES(excel_file_path: str, keep_excluded_entries: bool = False, d """ dPower_VRES = __read_non_pivoted_file(excel_file_path, "v0.1.0", ["g"], True, keep_excluded_entries) - if not do_not_convert_values: - if "MinProd" not in dPower_VRES.columns: - dPower_VRES['MinProd'] = 0 - - dPower_VRES['InvestCostEUR'] = dPower_VRES['InvestCost'] * 1e-3 * dPower_VRES['MaxProd'] * 1e-3 - dPower_VRES['MaxProd'] *= 1e-3 - dPower_VRES['OMVarCost'] *= 1e-3 return dPower_VRES diff --git a/SQLiteWriter.py b/SQLiteWriter.py index 70e1918..7816821 100644 --- a/SQLiteWriter.py +++ b/SQLiteWriter.py @@ -41,7 +41,7 @@ def model_to_sqlite(model: pyo.base.Model, filename: str) -> None: case pyomo.core.base.constraint.ConstraintList | pyomo.core.base.constraint.IndexedConstraint | pyomo.core.base.expression.IndexedExpression: # Those will not be saved on purpose continue case _: - printer.error(f"Pyomo-Type {type(o)} not implemented, {o.name} will not be saved to SQLite") + printer.warning(f"Pyomo-Type {type(o)} not implemented, {o.name} will not be saved to SQLite") continue df.to_sql(o.name, cnx, if_exists='replace') cnx.commit() diff --git a/examples/Data_Packages.xlsx b/data/example/Data_Packages.xlsx similarity index 100% rename from examples/Data_Packages.xlsx rename to data/example/Data_Packages.xlsx diff --git a/examples/Data_Sources.xlsx b/data/example/Data_Sources.xlsx similarity index 100% rename from examples/Data_Sources.xlsx rename to data/example/Data_Sources.xlsx diff --git a/examples/Global_Scenarios.xlsx b/data/example/Global_Scenarios.xlsx similarity index 100% rename from examples/Global_Scenarios.xlsx rename to data/example/Global_Scenarios.xlsx diff --git a/examples/Power_BusInfo.xlsx b/data/example/Power_BusInfo.xlsx similarity index 100% rename from examples/Power_BusInfo.xlsx rename to data/example/Power_BusInfo.xlsx diff --git a/examples/Power_Demand.xlsx b/data/example/Power_Demand.xlsx similarity index 100% rename from examples/Power_Demand.xlsx rename to data/example/Power_Demand.xlsx diff --git a/examples/Power_Hindex.xlsx b/data/example/Power_Hindex.xlsx similarity index 100% rename from examples/Power_Hindex.xlsx rename to data/example/Power_Hindex.xlsx diff --git a/examples/Power_Network.xlsx b/data/example/Power_Network.xlsx similarity index 100% rename from examples/Power_Network.xlsx rename to data/example/Power_Network.xlsx diff --git a/examples/Power_ThermalGen.xlsx b/data/example/Power_ThermalGen.xlsx similarity index 100% rename from examples/Power_ThermalGen.xlsx rename to data/example/Power_ThermalGen.xlsx diff --git a/examples/Power_VRES.xlsx b/data/example/Power_VRES.xlsx similarity index 100% rename from examples/Power_VRES.xlsx rename to data/example/Power_VRES.xlsx diff --git a/examples/Power_VRESProfiles.xlsx b/data/example/Power_VRESProfiles.xlsx similarity index 100% rename from examples/Power_VRESProfiles.xlsx rename to data/example/Power_VRESProfiles.xlsx diff --git a/examples/Power_WeightsK.xlsx b/data/example/Power_WeightsK.xlsx similarity index 100% rename from examples/Power_WeightsK.xlsx rename to data/example/Power_WeightsK.xlsx diff --git a/examples/Power_WeightsRP.xlsx b/data/example/Power_WeightsRP.xlsx similarity index 100% rename from examples/Power_WeightsRP.xlsx rename to data/example/Power_WeightsRP.xlsx diff --git a/environment.yml b/environment.yml index a76f37c..73f27c9 100644 --- a/environment.yml +++ b/environment.yml @@ -6,6 +6,7 @@ dependencies: - openpyxl=3.1.5 - pandas=2.2.3 - pip=24.0 + - pyomo=6.9.2 - pytest=8.4.0 - python=3.12.2 - rich=13.7.1 diff --git a/tests/test_ExcelReaderWriter.py b/tests/test_ExcelReaderWriter.py index ff95402..cbbd61e 100644 --- a/tests/test_ExcelReaderWriter.py +++ b/tests/test_ExcelReaderWriter.py @@ -6,7 +6,7 @@ printer = Printer.getInstance() -case_study_folder = "examples/" +case_study_folder = "data/example/" ew = ExcelWriter() combinations = [ ("Global_Scenarios", f"{case_study_folder}Global_Scenarios.xlsx", ExcelReader.get_dGlobal_Scenarios, ew.write_dGlobal_Scenarios),