From b57c4baec5f0eff01a5b07dfdd72f2c7fc64a155 Mon Sep 17 00:00:00 2001 From: Femke Janssen Date: Thu, 19 Feb 2026 16:44:13 +0100 Subject: [PATCH 1/2] first work on eliminating asset names and utilizing asset ids --- src/mesido/asset_sizing_mixin.py | 8 +- src/mesido/esdl/esdl_additional_vars_mixin.py | 4 +- src/mesido/esdl/esdl_mixin.py | 15 +- src/mesido/esdl/esdl_model_base.py | 16 +- src/mesido/esdl/profile_parser.py | 9 +- src/mesido/workflows/io/write_output.py | 193 +++++++++--------- 6 files changed, 125 insertions(+), 120 deletions(-) diff --git a/src/mesido/asset_sizing_mixin.py b/src/mesido/asset_sizing_mixin.py index 709c15040..7ffe0967c 100644 --- a/src/mesido/asset_sizing_mixin.py +++ b/src/mesido/asset_sizing_mixin.py @@ -801,9 +801,7 @@ def _make_max_size_var(name, lb, ub, nominal): ub = bounds[f"{asset_name}.Heat_source"][1] # Update bound to account for profile constraint being used instead of 1 value - esdl_asset_attributes = self.esdl_assets[ - self.esdl_asset_name_to_id_map[asset_name] - ].attributes["constraint"] + esdl_asset_attributes = self.esdl_assets[asset_name].attributes["constraint"] if ( len(esdl_asset_attributes) > 0 and hasattr(esdl_asset_attributes.items[0], "maximum") @@ -1927,9 +1925,7 @@ def __max_size_constraints(self, ensemble_member): # Cap the heat produced via a profile. Two profile options below. # Option 1: Profile specified in absolute values [W] via a ProfileConstraint - esdl_asset_attributes = self.esdl_assets[ - self.esdl_asset_name_to_id_map[s] - ].attributes["constraint"] + esdl_asset_attributes = self.esdl_assets[s].attributes["constraint"] if ( len(esdl_asset_attributes) > 0 and hasattr(esdl_asset_attributes.items[0], "maximum") diff --git a/src/mesido/esdl/esdl_additional_vars_mixin.py b/src/mesido/esdl/esdl_additional_vars_mixin.py index 926d43d8f..06fea946c 100644 --- a/src/mesido/esdl/esdl_additional_vars_mixin.py +++ b/src/mesido/esdl/esdl_additional_vars_mixin.py @@ -177,7 +177,7 @@ def __limit_list_available_heat_pipe_classes_max_power( *self.energy_system_components.get("heat_buffer", []), *self.energy_system_components.get("heat_pump", []), ]: - esdl_asset = self.esdl_assets[self.esdl_asset_name_to_id_map[asset]] + esdl_asset = self.esdl_assets[asset] for constraint in esdl_asset.attributes.get("constraint", []): if constraint.name == "setpointconstraint": time_unit = constraint.range.profileQuantityAndUnit.perTimeUnit @@ -252,7 +252,7 @@ def temperature_regimes(self, carrier): *self.energy_system_components.get("heat_exchanger", []), *self.energy_system_components.get("heat_demand", []), ]: - esdl_asset = self.esdl_assets[self.esdl_asset_name_to_id_map[asset]] + esdl_asset = self.esdl_assets[asset] parameters = self.parameters(0) for i in range(len(esdl_asset.attributes["constraint"].items)): constraint = esdl_asset.attributes["constraint"].items[i] diff --git a/src/mesido/esdl/esdl_mixin.py b/src/mesido/esdl/esdl_mixin.py index 208a9f378..bc4f8e909 100644 --- a/src/mesido/esdl/esdl_mixin.py +++ b/src/mesido/esdl/esdl_mixin.py @@ -629,23 +629,26 @@ def hot_cold_pipe_relations(self): self.__unrelated_pipes.append(asset.name) else: pipes = self.energy_system_components.get("heat_pipe", []) - for pipe in pipes: + for pipe_id in pipes: related = False # test if hot_pipe + pipe = self.esdl_asset_id_to_name_map[pipe_id] if not pipe.endswith("_ret"): cold_pipe = f"{pipe}_ret" - if cold_pipe in pipes: + cold_pipe_id = self.esdl_asset_name_to_id_map[cold_pipe] + if cold_pipe_id in pipes: related = True if pipe not in self.__hot_cold_pipe_relations.keys(): - self.__hot_cold_pipe_relations[pipe] = cold_pipe + self.__hot_cold_pipe_relations[pipe_id] = cold_pipe_id elif pipe.endswith("_ret"): hot_pipe = pipe[:-4] - if hot_pipe in pipes: + hot_pipe_id = self.esdl_asset_name_to_id_map[hot_pipe] + if hot_pipe_id in pipes: related = True if hot_pipe not in self.__hot_cold_pipe_relations.keys(): - self.__hot_cold_pipe_relations[hot_pipe] = pipe + self.__hot_cold_pipe_relations[hot_pipe_id] = pipe_id if not related and pipe not in self.__unrelated_pipes: - self.__unrelated_pipes.append(pipe) + self.__unrelated_pipes.append(pipe_id) @property def hot_to_cold_pipe_map(self) -> Dict: diff --git a/src/mesido/esdl/esdl_model_base.py b/src/mesido/esdl/esdl_model_base.py index 66b06d94f..b32bb0933 100644 --- a/src/mesido/esdl/esdl_model_base.py +++ b/src/mesido/esdl/esdl_model_base.py @@ -66,7 +66,7 @@ def _esdl_convert( for asset in list(assets_sorted.values()): pycml_type, modifiers = converter.convert(asset) - self.add_variable(pycml_type, asset.name, **modifiers) + self.add_variable(pycml_type, asset.id, **modifiers) in_suf = "HeatIn" out_suf = "HeatOut" @@ -136,7 +136,7 @@ def __set_primary_secondary_heat_ports(): port_map[p.id] = getattr(component.Secondary, out_suf) for asset in non_node_assets: - component = getattr(self, asset.name) + component = getattr(self, asset.id) # We assume that every component has 2 ports. Essentially meaning that we are dealing # with a single commodity for a component. Exceptions, assets that deal with multiple # have to be specifically specified what port configuration is expected in the model. @@ -322,9 +322,9 @@ def __set_pipe_port_connections( type_node_assets: list of node assets of a specific commodity. """ if connected_to.id in list(port_map.keys()) and ( - assets[name_to_id_map[port_map[connected_to.id].name.split(".")[0]]].asset_type + assets[port_map[connected_to.id].name.split(".")[0]].asset_type == "Pipe" - or assets[name_to_id_map[port_map[connected_to.id].name.split(".")[0]]].asset_type + or assets[port_map[connected_to.id].name.split(".")[0]].asset_type == "ElectricityCable" ): self.connect(getattr(component, node_suffixes)[i], port_map[connected_to.id]) @@ -347,7 +347,7 @@ def __set_pipe_port_connections( count += 1 self.connect_logical_links( getattr(component, node_suffixes)[i], - getattr(getattr(self, connected_node_asset.name), node_suffixes)[idx], + getattr(getattr(self, connected_node_asset.id), node_suffixes)[idx], ) else: # If the Connected asset is not of type pipe, there might be @@ -358,7 +358,7 @@ def __set_pipe_port_connections( connections.add(conn) for asset in [*node_assets, *bus_assets, *gas_node_assets]: - component = getattr(self, asset.name) + component = getattr(self, asset.id) i = 1 if len(asset.in_ports) != 1 or len(asset.out_ports) != 1: @@ -432,11 +432,11 @@ def __set_pipe_port_connections( asset.asset_type == "Pipe" or asset.asset_type == "ElectricityCable" or assets[ - name_to_id_map[port_map[connected_to.id].name.split(".")[0]] + port_map[connected_to.id].name.split(".")[0] ].asset_type == "Pipe" or assets[ - name_to_id_map[port_map[connected_to.id].name.split(".")[0]] + port_map[connected_to.id].name.split(".")[0] ].asset_type == "ElectricityCable" ): diff --git a/src/mesido/esdl/profile_parser.py b/src/mesido/esdl/profile_parser.py index d8da97366..362bb202d 100644 --- a/src/mesido/esdl/profile_parser.py +++ b/src/mesido/esdl/profile_parser.py @@ -108,7 +108,7 @@ def read_profiles( for component_type, var_name in self.component_type_to_var_name_map.items(): for component in energy_system_components.get(component_type, []): profile = self._profiles[ensemble_member].get(component + var_name, None) - asset_power = esdl_assets[esdl_asset_names_to_ids[component]].attributes[ + asset_power = esdl_assets[component].attributes[ "power" ] if profile is not None: @@ -626,6 +626,7 @@ def _load_profiles_from_source( elif self._file_path.suffix == ".csv": self._load_csv( energy_system_components=energy_system_components, + esdl_asset_id_to_name_map=esdl_asset_id_to_name_map, carrier_properties=carrier_properties, ensemble_size=ensemble_size, ) @@ -637,6 +638,7 @@ def _load_profiles_from_source( def _load_csv( self, energy_system_components: Dict[str, Set[str]], + esdl_asset_id_to_name_map, carrier_properties: Dict[str, Dict], ensemble_size: int, ) -> None: @@ -681,7 +683,8 @@ def _load_csv( for component_type, var_name in self.component_type_to_var_name_map.items(): for component_name in energy_system_components.get(component_type, []): try: - column_name = f"{component_name.replace(' ', '')}" + asset_name = esdl_asset_id_to_name_map[component_name] + column_name = f"{asset_name.replace(' ', '')}" values = data[column_name].to_numpy() if np.isnan(values).any(): raise Exception( @@ -759,7 +762,7 @@ def variable(self, pi_header): location_id = pi_header.find("pi:locationId", self.ns).text try: - component_name = self.__id_map[location_id] + component_name = location_id except KeyError: parameter_id = pi_header.find("pi:parameterId", self.ns).text qualifiers = pi_header.findall("pi:qualifierId", self.ns) diff --git a/src/mesido/workflows/io/write_output.py b/src/mesido/workflows/io/write_output.py index e87336b6c..2023e7bdc 100644 --- a/src/mesido/workflows/io/write_output.py +++ b/src/mesido/workflows/io/write_output.py @@ -356,102 +356,103 @@ def _add_kpis_to_energy_system(self, energy_system, optimizer_sim: bool = False) logger.error("Variable optimizer_sim has not been set") for _key, asset in self.esdl_assets.items(): - asset_placement_var = self._asset_aggregation_count_var_map[asset.name] + asset_id = asset.id + asset_placement_var = self._asset_aggregation_count_var_map[asset_id] placed = np.round(results[asset_placement_var][0]) >= 1.0 cost_type_prefix = "" if not discounted_annualized_cost: - if np.isnan(parameters[f"{asset.name}.technical_life"]) or np.isclose( - parameters[f"{asset.name}.technical_life"], 0.0 + if np.isnan(parameters[f"{asset_id}.technical_life"]) or np.isclose( + parameters[f"{asset_id}.technical_life"], 0.0 ): capex_factor = 1.0 else: - capex_factor = optim_time_horizon / parameters[f"{asset.name}.technical_life"] + capex_factor = optim_time_horizon / parameters[f"{asset.id}.technical_life"] if capex_factor < 1.0: capex_factor = 1.0 else: cost_type_prefix = "EAC - " - asset_life_years = parameters[f"{asset.name}.technical_life"] - discount_rate = parameters[f"{asset.name}.discount_rate"] / 100.0 + asset_life_years = parameters[f"{asset_id}.technical_life"] + discount_rate = parameters[f"{asset_id}.discount_rate"] / 100.0 capex_factor = calculate_annuity_factor(discount_rate, asset_life_years) if placed: try: asset_timehorizon_capex_breakdown[asset.asset_type] += ( - results[f"{asset.name}__installation_cost"][0] - + results[f"{asset.name}__investment_cost"][0] + results[f"{asset_id}__installation_cost"][0] + + results[f"{asset_id}__investment_cost"][0] ) * capex_factor tot_timehorizon_install_cost_euro += ( - results[f"{asset.name}__installation_cost"][0] + results[f"{asset_id}__installation_cost"][0] ) * capex_factor tot_timehorizon_invest_cost_euro += ( - results[f"{asset.name}__investment_cost"][0] + results[f"{asset_id}__investment_cost"][0] ) * capex_factor if ( - results[f"{asset.name}__variable_operational_cost"][0] > 0.0 - or results[f"{asset.name}__fixed_operational_cost"][0] > 0.0 + results[f"{asset_id}__variable_operational_cost"][0] > 0.0 + or results[f"{asset_id}__fixed_operational_cost"][0] > 0.0 ): asset_opex_breakdown[asset.asset_type] += ( - results[f"{asset.name}__variable_operational_cost"][0] - + results[f"{asset.name}__fixed_operational_cost"][0] + results[f"{asset_id}__variable_operational_cost"][0] + + results[f"{asset_id}__fixed_operational_cost"][0] ) asset_timehorizon_opex_breakdown[asset.asset_type] += ( - results[f"{asset.name}__variable_operational_cost"][0] - + results[f"{asset.name}__fixed_operational_cost"][0] + results[f"{asset_id}__variable_operational_cost"][0] + + results[f"{asset_id}__fixed_operational_cost"][0] ) * optim_time_horizon tot_variable_opex_cost_euro += results[ - f"{asset.name}__variable_operational_cost" + f"{asset_id}__variable_operational_cost" ][0] tot_fixed_opex_cost_euro += results[ - f"{asset.name}__fixed_operational_cost" + f"{asset_id}__fixed_operational_cost" ][0] tot_timehorizon_variable_opex_cost_euro += ( - results[f"{asset.name}__variable_operational_cost"][0] + results[f"{asset_id}__variable_operational_cost"][0] * optim_time_horizon ) tot_timehorizon_fixed_opex_cost_euro += ( - results[f"{asset.name}__fixed_operational_cost"][0] * optim_time_horizon + results[f"{asset_id}__fixed_operational_cost"][0] * optim_time_horizon ) except KeyError: try: asset_timehorizon_capex_breakdown[asset.asset_type] = ( - results[f"{asset.name}__installation_cost"][0] - + results[f"{asset.name}__investment_cost"][0] + results[f"{asset_id}__installation_cost"][0] + + results[f"{asset_id}__investment_cost"][0] ) * capex_factor tot_timehorizon_install_cost_euro += ( - results[f"{asset.name}__installation_cost"][0] + results[f"{asset_id}__installation_cost"][0] ) * capex_factor tot_timehorizon_invest_cost_euro += ( - results[f"{asset.name}__investment_cost"][0] + results[f"{asset_id}__investment_cost"][0] ) * capex_factor if ( - results[f"{asset.name}__variable_operational_cost"][0] > 0.0 - or results[f"{asset.name}__fixed_operational_cost"][0] > 0.0 + results[f"{asset_id}__variable_operational_cost"][0] > 0.0 + or results[f"{asset_id}__fixed_operational_cost"][0] > 0.0 ): asset_opex_breakdown[asset.asset_type] = ( - results[f"{asset.name}__variable_operational_cost"][0] - + results[f"{asset.name}__fixed_operational_cost"][0] + results[f"{asset_id}__variable_operational_cost"][0] + + results[f"{asset_id}__fixed_operational_cost"][0] ) asset_timehorizon_opex_breakdown[asset.asset_type] = ( asset_opex_breakdown[asset.asset_type] * optim_time_horizon ) tot_variable_opex_cost_euro += results[ - f"{asset.name}__variable_operational_cost" + f"{asset_id}__variable_operational_cost" ][0] tot_fixed_opex_cost_euro += results[ - f"{asset.name}__fixed_operational_cost" + f"{asset_id}__fixed_operational_cost" ][0] tot_timehorizon_variable_opex_cost_euro += ( - results[f"{asset.name}__variable_operational_cost"][0] + results[f"{asset_id}__variable_operational_cost"][0] * optim_time_horizon ) tot_timehorizon_fixed_opex_cost_euro += ( - results[f"{asset.name}__fixed_operational_cost"][0] + results[f"{asset_id}__fixed_operational_cost"][0] * optim_time_horizon ) @@ -469,8 +470,8 @@ def _add_kpis_to_energy_system(self, energy_system, optimizer_sim: bool = False) or asset.asset_type == "ResidualHeatSource" or asset.asset_type == "GasHeater" ): - heat_source_energy_wh[asset.name] = np.sum( - results[f"{asset.name}.Heat_source"][1:] * diff_times / 3600 + heat_source_energy_wh[asset_id] = np.sum( + results[f"{asset_id}.Heat_source"][1:] * diff_times / 3600 ) # TODO: ATES, HEAT pump show Secondary_heat and Primary_heat and tank storage # elif ATES: @@ -478,8 +479,8 @@ def _add_kpis_to_energy_system(self, energy_system, optimizer_sim: bool = False) # summed_discharge = np.abs(np.sum(np.clip(heat_ates, -np.inf, 0.0))) # elif Heat pump # elif asset.asset_type == "HeatStorage": # Heat discharged - # heat_source_energy_wh[asset.name] = np.sum( - # np.clip(results[f"{asset.name}.Heat_buffer"][1:], -np.inf, 0.0) + # heat_source_energy_wh[asset_id] = np.sum( + # np.clip(results[f"{asset_id}.Heat_buffer"][1:], -np.inf, 0.0) # * diff_times # / 3600 # ) @@ -679,45 +680,45 @@ def _add_kpis_to_energy_system(self, energy_system, optimizer_sim: bool = False) # part of the subarea. energy_breakdown = {} for asset in subarea.asset: - asset_name = asset.name - asset_type = self.get_asset_from_asset_name(asset_name).asset_type + asset_id = asset.id + asset_type = asset.asset_type - asset_placement_var = self._asset_aggregation_count_var_map[asset.name] + asset_placement_var = self._asset_aggregation_count_var_map[asset_id] placed = np.round(results[asset_placement_var][0]) >= 1.0 if placed: if asset_type == "Joint": continue try: - energy_breakdown[asset_type] += np.sum(results[f"{asset_name}.Heat_source"]) + energy_breakdown[asset_type] += np.sum(results[f"{asset_id}.Heat_source"]) except KeyError: try: energy_breakdown[asset_type] = np.sum( - results[f"{asset_name}.Heat_source"] + results[f"{asset_id}.Heat_source"] ) except KeyError: try: energy_breakdown[asset_type] += np.sum( - results[f"{asset_name}.Secondary_heat"] + results[f"{asset_id}.Secondary_heat"] ) except KeyError: try: energy_breakdown[asset_type] = np.sum( - results[f"{asset_name}.Secondary_heat"] + results[f"{asset_id}.Secondary_heat"] ) except KeyError: pass # Create KPIs by using applicable costs for the specific asset - area_investment_cost += results[self._asset_investment_cost_map[asset_name]][0] + area_investment_cost += results[self._asset_investment_cost_map[asset_id]][0] area_installation_cost += results[ - self._asset_installation_cost_map[asset_name] + self._asset_installation_cost_map[asset_id] ][0] area_variable_opex_cost += results[ - self._asset_variable_operational_cost_map[asset_name] + self._asset_variable_operational_cost_map[asset_id] ][0] area_fixed_opex_cost += results[ - self._asset_fixed_operational_cost_map[asset_name] + self._asset_fixed_operational_cost_map[asset_id] ][0] if discounted_annualized_cost: @@ -727,27 +728,27 @@ def _add_kpis_to_energy_system(self, energy_system, optimizer_sim: bool = False) # Calculate the total energy [Wh] consumed/produced in an are. # Note: milp losses of buffers, ATES' and pipes are included in the area energy # consumption - if asset_name in self.energy_system_components.get("heat_source", []): + if asset_id in self.energy_system_components.get("heat_source", []): try: total_energy_produced_locally_wh[subarea.name] += np.sum( - results[f"{asset_name}.Heat_source"][1:] * diff_times / 3600.0 + results[f"{asset_id}.Heat_source"][1:] * diff_times / 3600.0 ) except KeyError: total_energy_produced_locally_wh[subarea.name] = np.sum( - results[f"{asset_name}.Heat_source"][1:] * diff_times / 3600.0 + results[f"{asset_id}.Heat_source"][1:] * diff_times / 3600.0 ) - if asset_name in self.energy_system_components.get("heat_demand", []): - flow_variable = results[f"{asset_name}.Heat_demand"][1:] - elif asset_name in self.energy_system_components.get("heat_buffer", []): - flow_variable = results[f"{asset_name}.Heat_buffer"][1:] - elif asset_name in [ + if asset_id in self.energy_system_components.get("heat_demand", []): + flow_variable = results[f"{asset_id}.Heat_demand"][1:] + elif asset_id in self.energy_system_components.get("heat_buffer", []): + flow_variable = results[f"{asset_id}.Heat_buffer"][1:] + elif asset_id in [ *self.energy_system_components.get("ates", []), *self.energy_system_components.get("low_temperature_ates", []), ]: - flow_variable = results[f"{asset_name}.Heat_ates"][1:] - elif asset_name in self.energy_system_components.get("heat_pipe", []): + flow_variable = results[f"{asset_id}.Heat_ates"][1:] + elif asset_id in self.energy_system_components.get("heat_pipe", []): flow_variable = ( - np.ones(len(self.times())) * results[f"{asset_name}__hn_heat_loss"] + np.ones(len(self.times())) * results[f"{asset_id}__hn_heat_loss"] ) else: flow_variable = np.array([]) @@ -952,9 +953,9 @@ def _add_kpis_to_energy_system(self, energy_system, optimizer_sim: bool = False) # end KPIs - def _name_to_asset(self, energy_system, name): + def _id_to_asset(self, energy_system, id): return next( - (x for x in energy_system.eAllContents() if hasattr(x, "name") and x.name == name) + (x for x in energy_system.eAllContents() if hasattr(x, "id") and x.id == id) ) def _remove_result_profiles( @@ -971,7 +972,7 @@ def _remove_result_profiles( *self.energy_system_components.get("heat_exchanger", []), *self.energy_system_components.get("heat_pump", []), ]: - asset = self._name_to_asset(energy_system, asset_name) + asset = self._id_to_asset(energy_system, asset_name) for iport in range(len(asset.port)): if isinstance(asset.port[iport], esdl.OutPort) or isinstance( asset.port[iport], esdl.InPort @@ -1023,8 +1024,9 @@ def _write_updated_esdl( # Placement heat_pipes = set(self.energy_system_components.get("heat_pipe", [])) for _, attributes in self.esdl_assets.items(): - name = attributes.name - if name in [ + asset_id = attributes.id + asset_name = attributes.name + if asset_id in [ *self.energy_system_components.get("heat_source", []), *self.energy_system_components.get("ates", []), *self.energy_system_components.get("low_temperature_ates", []), @@ -1033,41 +1035,41 @@ def _write_updated_esdl( *self.energy_system_components.get("airco", []), *self.energy_system_components.get("heat_exchanger", []), ]: - asset = self._name_to_asset(energy_system, name) - asset_placement_var = self._asset_aggregation_count_var_map[name] + asset = self._id_to_asset(energy_system, asset_id) + asset_placement_var = self._asset_aggregation_count_var_map[asset_id] placed = np.round(results[asset_placement_var][0]) >= 1.0 - max_size = results[self._asset_max_size_map[name]][0] + max_size = results[self._asset_max_size_map[asset_id]][0] - if asset.name in [ + if asset_id in [ *self.energy_system_components.get("ates", []), *self.energy_system_components.get("low_temperature_ates", []), ]: - asset.maxChargeRate = results[f"{name}__max_size"][0] - asset.maxDischargeRate = results[f"{name}__max_size"][0] - elif asset.name in self.energy_system_components.get("heat_buffer", []): + asset.maxChargeRate = results[f"{asset_id}__max_size"][0] + asset.maxDischargeRate = results[f"{asset_id}__max_size"][0] + elif asset_id in self.energy_system_components.get("heat_buffer", []): asset.capacity = max_size asset.volume = max_size / ( - parameters[f"{name}.cp"] - * parameters[f"{name}.rho"] - * parameters[f"{name}.dT"] + parameters[f"{asset_id}.cp"] + * parameters[f"{asset_id}.rho"] + * parameters[f"{asset_id}.dT"] ) - elif asset.name in self.energy_system_components.get("heat_exchanger", []): + elif asset_id in self.energy_system_components.get("heat_exchanger", []): asset.capacity = max_size - elif asset.name in [ + elif asset_id in [ *self.energy_system_components.get("heat_pump", []), *self.energy_system_components.get("airco", []), ]: # Note: The heat capacity and not the electrical capacity # TODO: in the future we need to cater for varying COP as well - asset.power = results[f"{name}__max_size"][0] + asset.power = results[f"{asset_id}__max_size"][0] else: asset.power = max_size if not placed: asset.delete(recursive=True) else: asset.state = esdl.AssetStateEnum.ENABLED - elif name not in heat_pipes: # because heat pipes are updated below - logger.warning(f"ESDL update: asset {name} has not been updated") + elif asset_id not in heat_pipes: # because heat pipes are updated below + logger.warning(f"ESDL update: asset {asset_id} has not been updated") # Pipes: edr_pipe_properties_to_copy = ["innerDiameter", "outerDiameter", "diameter", "material"] @@ -1100,7 +1102,7 @@ def _write_updated_esdl( assert isinstance(pipe_class, EDRPipeClass) asset_edr = esh_edr.load_from_string(pipe_class.xml_string) - asset = self._name_to_asset(energy_system, pipe) + asset = self._id_to_asset(energy_system, pipe) asset.state = esdl.AssetStateEnum.ENABLED try: @@ -1116,7 +1118,7 @@ def _write_updated_esdl( for prop in edr_pipe_properties_to_copy: setattr(asset, prop, getattr(asset_edr, prop)) else: - asset = self._name_to_asset(energy_system, pipe) + asset = self._id_to_asset(energy_system, pipe) asset.delete(recursive=True) # ------------------------------------------------------------------------------------------ @@ -1157,7 +1159,7 @@ def _write_updated_esdl( esdl.Storage, ] - for asset_name in [ + for asset_id in [ *self.energy_system_components.get("heat_source", []), *self.energy_system_components.get("heat_demand", []), *self.energy_system_components.get("heat_pipe", []), @@ -1170,9 +1172,9 @@ def _write_updated_esdl( ]: try: # If the asset has been placed - asset = self._name_to_asset(energy_system, asset_name) + asset = self._id_to_asset(energy_system, asset_id) asset_class = asset.__class__.__name__ - asset_id = asset.id + asset_name = asset.name capability = [c for c in capabilities if c in asset.__class__.__mro__][ 0 ].__name__ @@ -1230,7 +1232,7 @@ def _write_updated_esdl( # These variables exist for all the assets. Variables that only exist for # specific # assets are only added later, like Pump_power - commodity = self.energy_system_components_commodity.get(asset_name) + commodity = self.energy_system_components_commodity.get(asset_id) variables_one_hydraulic_system = [f"{commodity}In.Q"] variables_two_hydraulic_system = [ @@ -1254,7 +1256,7 @@ def _write_updated_esdl( variables_one_hydraulic_system.append(f"{commodity}In.H") variables_two_hydraulic_system.append(f"Primary.{commodity}In.H") variables_two_hydraulic_system.append(f"Secondary.{commodity}In.H") - if asset_name in [ + if asset_id in [ *self.energy_system_components.get("heat_source", []), *self.energy_system_components.get("heat_buffer", []), *self.energy_system_components.get("ates", []), @@ -1265,10 +1267,10 @@ def _write_updated_esdl( ]: variables_one_hydraulic_system.append("Pump_power") variables_two_hydraulic_system.append("Pump_power") - elif asset_name in [*self.energy_system_components.get("pump", [])]: + elif asset_id in [*self.energy_system_components.get("pump", [])]: variables_one_hydraulic_system = ["Pump_power"] variables_two_hydraulic_system = ["Pump_power"] - if asset_name in [ + if asset_id in [ *self.energy_system_components.get("heat_pipe", []), *self.energy_system_components.get("gas_pipe", []), ]: @@ -1276,13 +1278,13 @@ def _write_updated_esdl( variables_two_hydraulic_system.append("PostProc.Velocity") # Velocity at the pipe outlet [m/s] post_processed["PostProc.Velocity"] = pipe_velocity( - asset_name, commodity, results, parameters + asset_id, commodity, results, parameters ) variables_one_hydraulic_system.append("PostProc.Pressure") # TODO: seems unnecessary, pipes always only have 1 hydraulic system variables_two_hydraulic_system.append("PostProc.Pressure") post_processed["PostProc.Pressure"] = pipe_pressure( - asset_name, commodity, results, parameters + asset_id, commodity, results, parameters ) # Pa # Depending on the port set, different carriers are assigned @@ -1354,7 +1356,7 @@ def _write_updated_esdl( try: # For all components dealing with one hydraulic system if isinstance( - results[f"{asset_name}." + variables_one_hydraulic_system[0]][ + results[f"{asset_id}." + variables_one_hydraulic_system[0]][ ii ], numbers.Number, @@ -1363,7 +1365,7 @@ def _write_updated_esdl( except KeyError: # For all components dealing with two hydraulic system if isinstance( - results[f"{asset_name}." + variables_two_hydraulic_system[0]][ + results[f"{asset_id}." + variables_two_hydraulic_system[0]][ ii ], numbers.Number, @@ -1371,7 +1373,8 @@ def _write_updated_esdl( variables_names = variables_two_hydraulic_system except Exception: logger.error( - f"During the influxDB profile writing for asset: {asset_name}," + f"During the influxDB profile writing for asset: " + f"{asset_name}," f" the following error occured:" ) traceback.print_exc() @@ -1458,7 +1461,7 @@ def _write_updated_esdl( else: logger.warning( f"No profile units will be written to the ESDL for: " - f"{asset_name}. + {variable}" + f"{asset_id}. + {variable}" ) # Write result OUTPUT profiles on the optimized esdl @@ -1476,7 +1479,7 @@ def _write_updated_esdl( conversion_factor = 1.0 if variable not in ["PostProc.Velocity", "PostProc.Pressure"]: data_row.append( - results[f"{asset_name}." + variable][ii] * conversion_factor + results[f"{asset_id}." + variable][ii] * conversion_factor ) # The variable evaluation below seems unnecessary, but it would be # used we expand the list of post process type variables @@ -1497,7 +1500,7 @@ def _write_updated_esdl( "simulationRun": simulation_id, "simulation_type": type(self).__name__, "assetId": asset_id, - "assetName": asset_name, + "assetName": asset.name, "assetClass": asset_class, "capability": capability, } From 27e9f38d921d002da3ca2855e04eab06c6e0277a Mon Sep 17 00:00:00 2001 From: Femke Janssen Date: Thu, 19 Feb 2026 17:05:58 +0100 Subject: [PATCH 2/2] updating first tests with checks where asset name is replaced with id --- src/mesido/workflows/io/write_output.py | 2 +- .../electrolyzer/src/example.py | 4 +- tests/test_asset_is_realized.py | 36 +++++++++------- tests/test_ates.py | 10 +++-- tests/test_cable_topology_optimization.py | 6 ++- tests/test_cold_demand.py | 19 ++++---- tests/test_elec_boiler.py | 43 +++++++++++-------- tests/test_end_scenario_sizing.py | 9 ++-- tests/test_profile_parsing.py | 11 +++-- tests/test_warmingup_unit_cases.py | 8 ++-- 10 files changed, 89 insertions(+), 59 deletions(-) diff --git a/src/mesido/workflows/io/write_output.py b/src/mesido/workflows/io/write_output.py index 2023e7bdc..e5f35a878 100644 --- a/src/mesido/workflows/io/write_output.py +++ b/src/mesido/workflows/io/write_output.py @@ -681,7 +681,7 @@ def _add_kpis_to_energy_system(self, energy_system, optimizer_sim: bool = False) energy_breakdown = {} for asset in subarea.asset: asset_id = asset.id - asset_type = asset.asset_type + asset_type = self.esdl_assets[asset_id].asset_type asset_placement_var = self._asset_aggregation_count_var_map[asset_id] placed = np.round(results[asset_placement_var][0]) >= 1.0 diff --git a/tests/models/unit_cases_electricity/electrolyzer/src/example.py b/tests/models/unit_cases_electricity/electrolyzer/src/example.py index 4d88de903..e273570c8 100644 --- a/tests/models/unit_cases_electricity/electrolyzer/src/example.py +++ b/tests/models/unit_cases_electricity/electrolyzer/src/example.py @@ -66,7 +66,7 @@ def goals(self): # TODO: these goals should incorperate the timestep for demand in self.energy_system_components.get("electricity_demand", []): carrier_name = ( - self.esdl_assets[self.esdl_asset_name_to_id_map[demand]].in_ports[0].carrier.name + self.esdl_assets[demand].in_ports[0].carrier.name ) price_profile = f"{carrier_name}.price_profile" # price_profile = f"{demand}.electricity_price" @@ -80,7 +80,7 @@ def goals(self): for demand in self.energy_system_components.get("gas_demand", []): # Code below: When profile is assigned to carrier instead of using .csv file carrier_name = ( - self.esdl_assets[self.esdl_asset_name_to_id_map[demand]].in_ports[0].carrier.name + self.esdl_assets[demand].in_ports[0].carrier.name ) price_profile = f"{carrier_name}.price_profile" # price_profile = f"{demand}.gas_price" diff --git a/tests/test_asset_is_realized.py b/tests/test_asset_is_realized.py index a32e5fc52..b33dae618 100644 --- a/tests/test_asset_is_realized.py +++ b/tests/test_asset_is_realized.py @@ -45,52 +45,56 @@ def test_asset_is_realized(self): ) results = solution.extract_results() + name_to_id_map = solution.esdl_asset_name_to_id_map + + prod_1_id = name_to_id_map["HeatProducer_1"] + prod_2_id = name_to_id_map["HeatProducer_2"] # First we test whether the investments made are below cap cap = 2.5e5 + 1.0e-3 # some small tolerance, CBC... np.testing.assert_allclose( - True, np.diff(results["HeatProducer_1__cumulative_investments_made_in_eur"]) <= cap + True, np.diff(results[f"{prod_1_id}__cumulative_investments_made_in_eur"]) <= cap ) np.testing.assert_allclose( - True, np.diff(results["HeatProducer_2__cumulative_investments_made_in_eur"]) <= cap + True, np.diff(results[f"{prod_2_id}__cumulative_investments_made_in_eur"]) <= cap ) # Now we test if the investments made are greater then the needed investments once the # asset is realized - inds_1 = np.where(np.round(results["HeatProducer_1__asset_is_realized"]) == 1) + inds_1 = np.where(np.round(results[f"{prod_1_id}__asset_is_realized"]) == 1) np.testing.assert_allclose( True, ( - results["HeatProducer_1__cumulative_investments_made_in_eur"][inds_1] - >= results["HeatProducer_1__investment_cost"] - + results["HeatProducer_1__installation_cost"] + results[f"{prod_1_id}__cumulative_investments_made_in_eur"][inds_1] + >= results[f"{prod_1_id}__investment_cost"] + + results[f"{prod_1_id}__installation_cost"] - 1.0e-3 ), ) - inds_2 = np.where(np.round(results["HeatProducer_2__asset_is_realized"]) == 1) + inds_2 = np.where(np.round(results[f"{prod_2_id}__asset_is_realized"]) == 1) np.testing.assert_allclose( True, ( - results["HeatProducer_2__cumulative_investments_made_in_eur"][inds_2] - >= results["HeatProducer_2__investment_cost"] - + results["HeatProducer_2__installation_cost"] + results[f"{prod_2_id}__cumulative_investments_made_in_eur"][inds_2] + >= results[f"{prod_2_id}__investment_cost"] + + results[f"{prod_2_id}__installation_cost"] - 1.0e-3 ), ) # Here we test that the asset is not used until it is actually realized - inds_not_1 = np.where(np.round(results["HeatProducer_1__asset_is_realized"]) == 0) + inds_not_1 = np.where(np.round(results[f"{prod_1_id}__asset_is_realized"]) == 0) np.testing.assert_allclose( - results["HeatProducer_1.Heat_source"][inds_not_1], 0.0, atol=1e-6 + results[f"{prod_1_id}.Heat_source"][inds_not_1], 0.0, atol=1e-6 ) - inds_not_2 = np.where(np.round(results["HeatProducer_2__asset_is_realized"]) == 0) + inds_not_2 = np.where(np.round(results[f"{prod_2_id}__asset_is_realized"]) == 0) np.testing.assert_allclose( - results["HeatProducer_1.Heat_source"][inds_not_2], 0.0, atol=1e-6 + results[f"{prod_1_id}.Heat_source"][inds_not_2], 0.0, atol=1e-6 ) # Here we test that the asset is actually used once it is realized - np.testing.assert_allclose(results["HeatProducer_1.Heat_source"][inds_1] > 0.0, True) - np.testing.assert_allclose(results["HeatProducer_2.Heat_source"][inds_2] > 0.0, True) + np.testing.assert_allclose(results[f"{prod_1_id}.Heat_source"][inds_1] > 0.0, True) + np.testing.assert_allclose(results[f"{prod_2_id}.Heat_source"][inds_2] > 0.0, True) if __name__ == "__main__": diff --git a/tests/test_ates.py b/tests/test_ates.py index 150960447..1e6b6a76b 100644 --- a/tests/test_ates.py +++ b/tests/test_ates.py @@ -42,15 +42,17 @@ def test_ates(self): ) results = solution.extract_results() + name_to_id_map = solution.esdl_asset_name_to_id_map - stored_heat = results["ATES_033c.Stored_heat"] - heat_loss = results["ATES_033c.Heat_loss"] - heat_ates = results["ATES_033c.Heat_ates"] + ates_id = name_to_id_map["ATES_033c"] + stored_heat = results[f"{ates_id}.Stored_heat"] + heat_loss = results[f"{ates_id}.Heat_loss"] + heat_ates = results[f"{ates_id}.Heat_ates"] summed_charge = np.sum(np.clip(heat_ates, 0.0, np.inf)) summed_discharge = np.abs(np.sum(np.clip(heat_ates, -np.inf, 0.0))) # Test if the milp loss is as expected - coeff = solution.parameters(0)["ATES_033c.heat_loss_coeff"] + coeff = solution.parameters(0)[f"{ates_id}.heat_loss_coeff"] np.testing.assert_allclose(heat_loss, coeff * stored_heat) np.testing.assert_array_less(summed_discharge, summed_charge) diff --git a/tests/test_cable_topology_optimization.py b/tests/test_cable_topology_optimization.py index 6363d9421..c0ae7cf53 100644 --- a/tests/test_cable_topology_optimization.py +++ b/tests/test_cable_topology_optimization.py @@ -34,6 +34,7 @@ def test_electricity_network_topology(self): ) results = heat_problem.extract_results() + name_to_id_map = heat_problem.esdl_asset_name_to_id_map for demand in heat_problem.energy_system_components.get("electricity_demand", []): target = heat_problem.get_timeseries(f"{demand}.target_electricity_demand").values @@ -47,5 +48,6 @@ def test_electricity_network_topology(self): ] for cable in removed_cables: - np.testing.assert_allclose(results[f"{cable}__investment_cost"], 0.0) - np.testing.assert_allclose(results[f"{cable}__en_max_current"], 0.0) + cable_id = name_to_id_map[cable] + np.testing.assert_allclose(results[f"{cable_id}__investment_cost"], 0.0) + np.testing.assert_allclose(results[f"{cable_id}__en_max_current"], 0.0) diff --git a/tests/test_cold_demand.py b/tests/test_cold_demand.py index 2013d485a..6da1ca395 100644 --- a/tests/test_cold_demand.py +++ b/tests/test_cold_demand.py @@ -128,6 +128,7 @@ def test_airco(self): ) results = heat_problem.extract_results() parameters = heat_problem.parameters(0) + name_to_id_map = heat_problem.esdl_asset_name_to_id_map demand_matching_test(heat_problem, results) energy_conservation_test(heat_problem, results) @@ -136,9 +137,9 @@ def test_airco(self): # Check how variable operation cost is calculated np.testing.assert_allclose( parameters["HeatPump_b97e.variable_operational_cost_coefficient"] - * sum(results["HeatPump_b97e.Heat_source"][1:]) + * sum(results[f"{name_to_id_map['HeatPump_b97e']}.Heat_source"][1:]) / parameters["HeatPump_b97e.cop"], - results["HeatPump_b97e__variable_operational_cost"], + results[f"{name_to_id_map['HeatPump_b97e']}__variable_operational_cost"], ) def test_wko(self): @@ -219,6 +220,7 @@ def constraints(self, ensemble_member): input_timeseries_file="timeseries_2.csv", ) results = heat_problem.extract_results() + name_to_id_map = heat_problem.esdl_asset_name_to_id_map demand_matching_test(heat_problem, results) energy_conservation_test(heat_problem, results) @@ -226,15 +228,15 @@ def constraints(self, ensemble_member): # Check cyclic constraint np.testing.assert_allclose( - results["ATES_226d.Stored_heat"][0], results["ATES_226d.Stored_heat"][-1] + results[f"{name_to_id_map['ATES_226d']}.Stored_heat"][0], results[f"{name_to_id_map['ATES_226d']}.Stored_heat"][-1] ) # Check heat loss and gain tol_value = 1.0e-6 np.testing.assert_array_less( - 0.0, results["Pipe1.HeatIn.Heat"] - results["Pipe1.HeatOut.Heat"] + tol_value + 0.0, results[f"{name_to_id_map['Pipe1']}.HeatIn.Heat"] - results[f"{name_to_id_map['Pipe1']}.HeatOut.Heat"] + tol_value ) np.testing.assert_array_less( - results["Pipe1_ret.HeatIn.Heat"] - results["Pipe1_ret.HeatOut.Heat"] - tol_value, 0.0 + results[f"{name_to_id_map['Pipe1_ret']}.HeatIn.Heat"] - results[f"{name_to_id_map['Pipe1_ret']}.HeatOut.Heat"] - tol_value, 0.0 ) # ------------------------------------------------------------------------------------------ @@ -254,6 +256,7 @@ def energy_system_options(self): input_timeseries_file="timeseries_2.csv", ) results = heat_problem.extract_results() + name_to_id_map = heat_problem.esdl_asset_name_to_id_map demand_matching_test(heat_problem, results) energy_conservation_test(heat_problem, results) @@ -261,15 +264,15 @@ def energy_system_options(self): # Check cyclic constraint np.testing.assert_allclose( - results["ATES_226d.Stored_heat"][0], results["ATES_226d.Stored_heat"][-1] + results[f"{name_to_id_map['ATES_226d']}.Stored_heat"][0], results[f"{name_to_id_map['ATES_226d']}.Stored_heat"][-1] ) # Check heat loss and gain tol_value = 1.0e-6 np.testing.assert_allclose( - 0.0, results["Pipe1.HeatIn.Heat"] - results["Pipe1.HeatOut.Heat"], atol=1e-6 + 0.0, results[f"{name_to_id_map['Pipe1']}.HeatIn.Heat"] - results[f"{name_to_id_map['Pipe1']}.HeatOut.Heat"], atol=1e-6 ) np.testing.assert_allclose( - 0.0, results["Pipe1_ret.HeatIn.Heat"] - results["Pipe1_ret.HeatOut.Heat"], atol=1e-6 + 0.0, results[f"{name_to_id_map['Pipe1_ret']}.HeatIn.Heat"] - results[f"{name_to_id_map['Pipe1_ret']}.HeatOut.Heat"], atol=1e-6 ) # ------------------------------------------------------------------------------------------ diff --git a/tests/test_elec_boiler.py b/tests/test_elec_boiler.py index 802bb8ca5..e49df7244 100644 --- a/tests/test_elec_boiler.py +++ b/tests/test_elec_boiler.py @@ -78,18 +78,22 @@ def test_elec_heat_source_elec(self): ) results = heat_problem.extract_results() parameters = heat_problem.parameters(0) + name_to_id_map = heat_problem.esdl_asset_name_to_id_map demand_matching_test(heat_problem, results) energy_conservation_test(heat_problem, results) heat_to_discharge_test(heat_problem, results) electric_power_conservation_test(heat_problem, results) - np.testing.assert_array_less(0.0, results["ElectricBoiler_9aab.Heat_source"]) - np.testing.assert_array_less(0.0, results["ElectricityProducer_4dde.ElectricityOut.Power"]) + e_boiler_id = name_to_id_map["ElectricBoiler_9aab"] + + np.testing.assert_array_less(0.0, results[f"{e_boiler_id}.Heat_source"]) + np.testing.assert_array_less(0.0, results[f"" + f"{name_to_id_map['ElectricityProducer_4dde']}.ElectricityOut.Power"]) np.testing.assert_allclose( - parameters["ElectricBoiler_9aab.efficiency"] - * results["ElectricBoiler_9aab.Power_consumed"], - results["ElectricBoiler_9aab.Heat_source"], + parameters[f"{e_boiler_id}.efficiency"] + * results[f"{e_boiler_id}.Power_consumed"], + results[f"{e_boiler_id}.Heat_source"], ) # Check the cost components of ElectricBoiler @@ -122,16 +126,19 @@ def test_heat_source_elec(self): ) results = heat_problem.extract_results() parameters = heat_problem.parameters(0) + name_to_id_map = heat_problem.esdl_asset_name_to_id_map demand_matching_test(heat_problem, results) energy_conservation_test(heat_problem, results) heat_to_discharge_test(heat_problem, results) - np.testing.assert_array_less(0.0, results["ElectricBoiler_9aab.Heat_source"]) + e_boiler_id = name_to_id_map["ElectricBoiler_9aab"] + + np.testing.assert_array_less(0.0, results[f"{e_boiler_id}.Heat_source"]) np.testing.assert_allclose( - parameters["ElectricBoiler_9aab.efficiency"] - * results["ElectricBoiler_9aab.Power_consumed"], - results["ElectricBoiler_9aab.Heat_source"], + parameters[f"{e_boiler_id}.efficiency"] + * results[f"{e_boiler_id}.Power_consumed"], + results[f"{e_boiler_id}.Heat_source"], ) # Check the cost components of ElectricBoiler @@ -163,25 +170,27 @@ def test_air_water_hp_elec(self): ) results = heat_problem.extract_results() parameters = heat_problem.parameters(0) + name_to_id_map = heat_problem.esdl_asset_name_to_id_map demand_matching_test(heat_problem, results) energy_conservation_test(heat_problem, results) heat_to_discharge_test(heat_problem, results) electric_power_conservation_test(heat_problem, results) - np.testing.assert_array_less(0.0, results["HeatPump_d8fd.Heat_source"]) - np.testing.assert_array_less(0.0, results["ElectricityProducer_4dde.ElectricityOut.Power"]) + hp_id = name_to_id_map["HeatPump_d8fd"] + np.testing.assert_array_less(0.0, results[f"{hp_id}.Heat_source"]) + np.testing.assert_array_less(0.0, results[f"{name_to_id_map['ElectricityProducer_4dde']}.ElectricityOut.Power"]) np.testing.assert_array_less( - parameters["HeatPump_d8fd.cop"] * results["HeatPump_d8fd.Power_elec"], - results["HeatPump_d8fd.Heat_source"] + 1.0e-6, + parameters[f"{hp_id}.cop"] * results[f"{hp_id}.Power_elec"], + results[f"{hp_id}.Heat_source"] + 1.0e-6, ) # Check how variable operation cost is calculated np.testing.assert_allclose( - parameters["HeatPump_d8fd.variable_operational_cost_coefficient"] - * sum(results["HeatPump_d8fd.Heat_source"][1:]) - / parameters["HeatPump_d8fd.cop"], - results["HeatPump_d8fd__variable_operational_cost"], + parameters[f"{hp_id}.variable_operational_cost_coefficient"] + * sum(results[f"{hp_id}.Heat_source"][1:]) + / parameters[f"{hp_id}.cop"], + results[f"{hp_id}__variable_operational_cost"], ) diff --git a/tests/test_end_scenario_sizing.py b/tests/test_end_scenario_sizing.py index 719e8d6a6..292594951 100644 --- a/tests/test_end_scenario_sizing.py +++ b/tests/test_end_scenario_sizing.py @@ -45,21 +45,24 @@ def test_heat_exchanger_sizing(self): esdl_parser=ESDLFileParser, ) results = solution.extract_results() + name_to_id_map = solution.esdl_asset_name_to_id_map # Check heat exchanger is sized np.testing.assert_allclose( - max(results["HeatExchange_39ed.Secondary_heat"]), results["HeatExchange_39ed__max_size"] + max(results[f"{name_to_id_map['HeatExchange_39ed']}.Secondary_heat"]), results[ + f"{name_to_id_map['HeatExchange_39ed']}__max_size"] ) # Check heat exchanger state attribute is changed from OPTIONAL # to ENABLED after the optimization energy_system = solution._ESDLMixin__energy_system_handler.energy_system - asset = solution._name_to_asset(energy_system, "HeatExchange_39ed") + asset = solution._id_to_asset(energy_system, name_to_id_map['HeatExchange_39ed']) np.testing.assert_equal(esdl.AssetStateEnum.ENABLED, asset.state) # Check heat exchanger capacity attribute is updated # with max_size variable after the optimization - np.testing.assert_allclose(results["HeatExchange_39ed__max_size"], asset.capacity) + np.testing.assert_allclose(results[f"{name_to_id_map['HeatExchange_39ed']}__max_size"], + asset.capacity) @classmethod def setUpClass(cls) -> None: diff --git a/tests/test_profile_parsing.py b/tests/test_profile_parsing.py index fd7439185..e9fd8f7b5 100644 --- a/tests/test_profile_parsing.py +++ b/tests/test_profile_parsing.py @@ -161,12 +161,14 @@ def test_loading_from_influx(self): input_timeseries_file="influx_mock.csv", ) problem.pre() + name_to_id_map = problem.esdl_asset_name_to_id_map np.testing.assert_equal(problem.io.reference_datetime.tzinfo, datetime.timezone.utc) # the three demands in the test ESDL for demand_name in ["HeatingDemand_2ab9", "HeatingDemand_6662", "HeatingDemand_506c"]: - profile_values = problem.get_timeseries(f"{demand_name}.target_heat_demand").values + demand_id = name_to_id_map[demand_name] + profile_values = problem.get_timeseries(f"{demand_id}.target_heat_demand").values self.assertEqual(profile_values[0], profile_values[1]) self.assertEqual(len(profile_values), 26) @@ -197,12 +199,14 @@ def test_loading_from_csv(self): ) problem.pre() + name_to_id_map = problem.esdl_asset_name_to_id_map + np.testing.assert_equal(problem.io.reference_datetime.tzinfo, datetime.timezone.utc) expected_array = np.array([1.0e8] * 3) np.testing.assert_equal( expected_array, - problem.get_timeseries("WindPark_7f14.maximum_electricity_source").values, + problem.get_timeseries(f"{name_to_id_map['WindPark_7f14']}.maximum_electricity_source").values, ) expected_array = np.array([1.0] * 3) @@ -235,12 +239,13 @@ def test_loading_from_xml(self): input_timeseries_file="timeseries.xml", ) problem.pre() + name_to_id_map = problem.esdl_asset_name_to_id_map np.testing.assert_equal(problem.io.reference_datetime.tzinfo, datetime.timezone.utc) expected_array = np.array([1.5e5] * 16 + [1.0e5] * 13 + [0.5e5] * 16) np.testing.assert_equal( - expected_array, problem.get_timeseries("demand.target_heat_demand").values + expected_array, problem.get_timeseries(f"{name_to_id_map['demand']}.target_heat_demand").values ) def test_loading_from_csv_with_influx_profiles_given(self): diff --git a/tests/test_warmingup_unit_cases.py b/tests/test_warmingup_unit_cases.py index 3a53f1665..b6b5d0294 100644 --- a/tests/test_warmingup_unit_cases.py +++ b/tests/test_warmingup_unit_cases.py @@ -151,15 +151,17 @@ def test_3a(self): parameters = heat_problem.parameters(0) bounds = heat_problem.bounds() + name_to_id_map = heat_problem.esdl_asset_name_to_id_map + demand_matching_test(heat_problem, results) energy_conservation_test(heat_problem, results) heat_to_discharge_test(heat_problem, results) # We only check the flow directions for the time-steps that there is flow in the pipe. - inds = np.round(1 - results["Pipe_e53a__is_disconnected"]).astype(bool) + inds = np.round(1 - results[f"{name_to_id_map['Pipe_e53a']}__is_disconnected"]).astype(bool) np.testing.assert_allclose( - np.round(results["Pipe_e53a__flow_direct_var"][inds]) * 2.0 - 1.0, - np.sign(results["Pipe_e53a.Q"][inds]), + np.round(results[f"{name_to_id_map['Pipe_e53a']}__flow_direct_var"][inds]) * 2.0 - 1.0, + np.sign(results[f"{name_to_id_map['Pipe_e53a']}.Q"][inds]), ) for buffer in heat_problem.energy_system_components.get("heat_buffer", []):