From c708e1e2d5e1637e1fe49a6900c1ed88f3a505e2 Mon Sep 17 00:00:00 2001 From: Santiago Patterson Date: Thu, 11 Jun 2026 17:24:55 +0200 Subject: [PATCH 1/8] Started the implementation of the assets. --- .../adapter/transforms/esdl_asset_mapper.py | 1 + .../esdl_asset_mappers/producer_mapper.py | 32 ++++++- .../adapter/transforms/string_to_esdl.py | 4 + .../entities/assets/elec_boiler.py | 90 ++++++++++++++++++ .../entities/assets/gas_heater.py | 93 +++++++++++++++++++ 5 files changed, 215 insertions(+), 5 deletions(-) create mode 100644 src/omotes_simulator_core/entities/assets/elec_boiler.py create mode 100644 src/omotes_simulator_core/entities/assets/gas_heater.py diff --git a/src/omotes_simulator_core/adapter/transforms/esdl_asset_mapper.py b/src/omotes_simulator_core/adapter/transforms/esdl_asset_mapper.py index bda33c94..d0ba11b2 100644 --- a/src/omotes_simulator_core/adapter/transforms/esdl_asset_mapper.py +++ b/src/omotes_simulator_core/adapter/transforms/esdl_asset_mapper.py @@ -47,6 +47,7 @@ esdl.ResidualHeatSource: EsdlAssetProducerMapper, esdl.SolarCollector: EsdlAssetProducerMapper, esdl.GasHeater: EsdlAssetProducerMapper, + esdl.ElectricBoiler: EsdlAssetProducerMapper, esdl.Consumer: EsdlAssetConsumerMapper, esdl.GenericConsumer: EsdlAssetConsumerMapper, esdl.HeatingDemand: EsdlAssetConsumerMapper, diff --git a/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py b/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py index c365deea..1b483bb9 100644 --- a/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py +++ b/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py @@ -15,7 +15,10 @@ """Module containing the Esdl to Producer asset mapper class.""" +import esdl + from omotes_simulator_core.entities.assets.asset_abstract import AssetAbstract +from omotes_simulator_core.entities.assets.elec_boiler import ElecBoiler from omotes_simulator_core.entities.assets.esdl_asset_object import EsdlAssetObject from omotes_simulator_core.entities.assets.production_cluster import ProductionCluster from omotes_simulator_core.simulation.mappers.mappers import EsdlMapperAbstract @@ -34,10 +37,29 @@ def to_entity(self, esdl_asset: EsdlAssetObject) -> AssetAbstract: :param EsdlAssetObject esdl_asset: Object to be converted to a producer entity. :return: Producer object. """ - producer_entity = ProductionCluster( - asset_name=esdl_asset.esdl_asset.name, - asset_id=esdl_asset.esdl_asset.id, - port_ids=esdl_asset.get_port_ids(), - ) + + if type(esdl_asset.esdl_asset) == esdl.ElectricBoiler: + producer_entity = ElecBoiler( + asset_name=esdl_asset.esdl_asset.name, + asset_id=esdl_asset.esdl_asset.id, + port_ids=esdl_asset.get_port_ids(), + ) + + elif type(esdl_asset.esdl_asset) == esdl.GasHeater: + # producer_entity = ElecBoiler( # type:ignore + # asset_name=esdl_asset.esdl_asset.name, + # asset_id=esdl_asset.esdl_asset.id, + # port_ids=esdl_asset.get_port_ids(), + # ) + pass # TODO: create and link the gas heater mapper here. + + else: + producer_entity = ProductionCluster( + asset_name=esdl_asset.esdl_asset.name, + asset_id=esdl_asset.esdl_asset.id, + port_ids=esdl_asset.get_port_ids(), + ) + + # TODO: call eboiler or gas heater entities from here. return producer_entity diff --git a/src/omotes_simulator_core/adapter/transforms/string_to_esdl.py b/src/omotes_simulator_core/adapter/transforms/string_to_esdl.py index 83b3519e..72abf9ac 100644 --- a/src/omotes_simulator_core/adapter/transforms/string_to_esdl.py +++ b/src/omotes_simulator_core/adapter/transforms/string_to_esdl.py @@ -34,6 +34,8 @@ class OmotesAssetLabels(str, Enum): ATES = "ates" HEAT_PUMP = "heat_pump" HEAT_EXCHANGER = "heat_exchanger" + ELECTRIC_BOILER = "electric_boiler" + GAS_HEATER = "gas_heater" class StringEsdlAssetMapper: @@ -69,6 +71,8 @@ def __init__(self) -> None: OmotesAssetLabels.ATES: [esdl.ATES], OmotesAssetLabels.HEAT_PUMP: [esdl.HeatPump], OmotesAssetLabels.HEAT_EXCHANGER: [esdl.HeatExchange], + OmotesAssetLabels.ELECTRIC_BOILER: [esdl.ElectricBoiler], + OmotesAssetLabels.GAS_HEATER: [esdl.GasHeater], } self.type_to_label_map: dict[Type[esdl.Asset], OmotesAssetLabels] = { diff --git a/src/omotes_simulator_core/entities/assets/elec_boiler.py b/src/omotes_simulator_core/entities/assets/elec_boiler.py new file mode 100644 index 00000000..3dcb03d2 --- /dev/null +++ b/src/omotes_simulator_core/entities/assets/elec_boiler.py @@ -0,0 +1,90 @@ +# Copyright (c) 2026. Deltares & TNO +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +"""ElecBoiler class.""" +import logging + +from omotes_simulator_core.entities.assets.asset_defaults import ( + PROPERTY_ELECTRICITY_CONSUMPTION, + PROPERTY_HEAT_SUPPLIED, + PROPERTY_HEAT_SUPPLY_SET_POINT, + HeatPumpDefaults, +) +from omotes_simulator_core.entities.assets.production_cluster import ProductionCluster +from omotes_simulator_core.solver.network.assets.production_asset import HeatBoundary + +logger = logging.getLogger(__name__) + + +class ElecBoiler(ProductionCluster): + """An electric boiler asset. + + It represents a two port electric boiler that adds heat to the network by consuming electricity. + """ + + efficiency: float + """The efficiency of the electric boiler [-].""" + + def __init__( + self, + asset_name: str, + asset_id: str, + port_ids: list[str], + efficiency: float = HeatPumpDefaults.coefficient_of_performance, #TODO: Make sure this takes a default of 1.0. + ) -> None: + """ + Initialize the ElecBoiler asset. + + :param str asset_name: The name of the asset. + :param str asset_id: The unique identifier of the asset. + :param List[str] port_ids: List of ids of the connected ports. + """ + super().__init__( + asset_name=asset_name, + asset_id=asset_id, + port_ids=port_ids, + ) + self.efficiency = efficiency + self.solver_asset = HeatBoundary( + name=self.name, + _id=self.asset_id, + pre_scribe_mass_flow=False, + set_pressure=self.pressure_supply, + ) + + def get_electric_power_consumption(self) -> float: + """Calculate the electric power consumption of the electric boiler. + + The electric power consumption is calculated as the ratio between the heat + supplied by the boiler to the network and the efficiency of the boiler. + + :return: float + The electric power consumption of the electric boiler. + """ + + return abs(self.get_actual_heat_supplied()) / self.efficiency + + def write_to_output(self) -> None: + """Method to write time step results to the output dict. + + The output list is a list of dictionaries, where each dictionary + represents the output of the asset for a specific timestep. + """ + output_dict_temp = { + PROPERTY_HEAT_SUPPLY_SET_POINT: self.heat_demand_set_point, + PROPERTY_HEAT_SUPPLIED: self.get_actual_heat_supplied(), + PROPERTY_ELECTRICITY_CONSUMPTION: (self.get_electric_power_consumption()), + } + self.outputs[1][-1].update(output_dict_temp) # Outputs appended to the out port. \ No newline at end of file diff --git a/src/omotes_simulator_core/entities/assets/gas_heater.py b/src/omotes_simulator_core/entities/assets/gas_heater.py new file mode 100644 index 00000000..d69e68d5 --- /dev/null +++ b/src/omotes_simulator_core/entities/assets/gas_heater.py @@ -0,0 +1,93 @@ +# Copyright (c) 2026. Deltares & TNO +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +"""GasHeater class.""" +import logging + +from omotes_simulator_core.entities.assets.asset_defaults import ( + PROPERTY_ELECTRICITY_CONSUMPTION, + PROPERTY_HEAT_SUPPLIED, + PROPERTY_HEAT_SUPPLY_SET_POINT, + HeatPumpDefaults, +) +from omotes_simulator_core.entities.assets.production_cluster import ProductionCluster +from omotes_simulator_core.solver.network.assets.production_asset import HeatBoundary + +logger = logging.getLogger(__name__) + + +class GasHeater(ProductionCluster): + """A gas heater asset. + + It represents a two port gas heater that adds heat to the network by consuming gas. + """ + + efficiency: float + """The efficiency of the gas heater [-].""" + + def __init__( + self, + asset_name: str, + asset_id: str, + port_ids: list[str], + efficiency: float = HeatPumpDefaults.coefficient_of_performance, #TODO: Make sure this takes a default of 1.0. + ) -> None: + """ + Initialize the GasHeater asset. + + :param str asset_name: The name of the asset. + :param str asset_id: The unique identifier of the asset. + :param List[str] port_ids: List of ids of the connected ports. + """ + super().__init__( + asset_name=asset_name, + asset_id=asset_id, + port_ids=port_ids, + ) + self.efficiency = efficiency + self.solver_asset = HeatBoundary( + name=self.name, + _id=self.asset_id, + pre_scribe_mass_flow=False, + set_pressure=self.pressure_supply, + ) + + def get_gas_consumption(self) -> float: + """Calculate the gas power consumption of the gas heater. + + The gas power consumption is calculated as the ratio between the heat + supplied by the heater to the network and the efficiency of the heater. + + :return: float + The gas power consumption of the gas heater. + """ + + # self.Gas_demand_mass_flow / 1000.0 * self.energy_content * self.efficiency + # - self.Heat_source + + return 1.0 # TODO: Fix this, it needs a gas energy content value. Check if it is already used somewhere else. + + def write_to_output(self) -> None: + """Method to write time step results to the output dict. + + The output list is a list of dictionaries, where each dictionary + represents the output of the asset for a specific timestep. + """ + output_dict_temp = { + PROPERTY_HEAT_SUPPLY_SET_POINT: self.heat_demand_set_point, + PROPERTY_HEAT_SUPPLIED: self.get_actual_heat_supplied(), + PROPERTY_ELECTRICITY_CONSUMPTION: (self.get_gas_consumption()), + } + self.outputs[1][-1].update(output_dict_temp) # Outputs appended to the out port. \ No newline at end of file From 42d2e0df8faa87aab4e599ae0138d78552b535ee Mon Sep 17 00:00:00 2001 From: Santiago Patterson Date: Fri, 26 Jun 2026 16:47:54 +0200 Subject: [PATCH 2/8] Fixed issue with the controller and the temperature setting. Simulation can now run the eboiler. --- .../adapter/transforms/controller_mapper.py | 9 ++++ .../entities/assets/esdl_asset_object.py | 10 ++++ testdata/test1_eboiler.esdl | 49 +++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 testdata/test1_eboiler.esdl diff --git a/src/omotes_simulator_core/adapter/transforms/controller_mapper.py b/src/omotes_simulator_core/adapter/transforms/controller_mapper.py index 672e6550..9abd1ee7 100644 --- a/src/omotes_simulator_core/adapter/transforms/controller_mapper.py +++ b/src/omotes_simulator_core/adapter/transforms/controller_mapper.py @@ -121,8 +121,17 @@ def to_entity( ControllerProducerMapper().to_entity(esdl_asset=esdl_asset) for esdl_asset in esdl_object.get_all_assets_of_type(OmotesAssetLabels.HEAT_PUMP) if esdl_asset.get_number_of_ports() == 2 + ] + [ + ControllerProducerMapper().to_entity(esdl_asset=esdl_asset) + for esdl_asset in esdl_object.get_all_assets_of_type(OmotesAssetLabels.GAS_HEATER) + ] + [ + ControllerProducerMapper().to_entity(esdl_asset=esdl_asset) + for esdl_asset in esdl_object.get_all_assets_of_type(OmotesAssetLabels.ELECTRIC_BOILER) ] + # ELECTRIC_BOILER = "electric_boiler" + # GAS_HEATER = "gas_heater" + storages = self.convert_heat_storages_and_ates(esdl_object) # if there are no heat transfer assets, all assets can be stored into one network. diff --git a/src/omotes_simulator_core/entities/assets/esdl_asset_object.py b/src/omotes_simulator_core/entities/assets/esdl_asset_object.py index f1d1902b..8a3019ad 100644 --- a/src/omotes_simulator_core/entities/assets/esdl_asset_object.py +++ b/src/omotes_simulator_core/entities/assets/esdl_asset_object.py @@ -186,6 +186,16 @@ def get_temperatures_asset(self, side: str | None = None) -> Temperatures: in_flow=self.get_temperature("In", "Return"), out_flow=self.get_temperature("Out", "Supply"), ) + elif self.get_esdl_type() == OmotesAssetLabels.GAS_HEATER: + temperatures = Temperatures( + in_flow=self.get_temperature("In", "Return"), + out_flow=self.get_temperature("Out", "Supply"), + ) + elif self.get_esdl_type() == OmotesAssetLabels.ELECTRIC_BOILER: + temperatures = Temperatures( + in_flow=self.get_temperature("In", "Return"), + out_flow=self.get_temperature("Out", "Supply"), + ) elif (self.get_esdl_type() == OmotesAssetLabels.ATES) | ( self.get_esdl_type() == OmotesAssetLabels.STORAGE ): diff --git a/testdata/test1_eboiler.esdl b/testdata/test1_eboiler.esdl new file mode 100644 index 00000000..bb6a587a --- /dev/null +++ b/testdata/test1_eboiler.esdl @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 46326061d6ef984522f190b6c98628f54d72d36d Mon Sep 17 00:00:00 2001 From: Santiago Patterson Date: Wed, 8 Jul 2026 17:21:10 +0200 Subject: [PATCH 3/8] Final parts of the code. Needs testing, write tests and cleaning up. --- .../esdl_asset_mappers/producer_mapper.py | 15 +++++------ .../entities/assets/asset_defaults.py | 2 ++ .../entities/assets/elec_boiler.py | 11 +------- .../entities/assets/gas_heater.py | 25 +++++++------------ 4 files changed, 18 insertions(+), 35 deletions(-) diff --git a/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py b/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py index 1b483bb9..d87a7621 100644 --- a/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py +++ b/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py @@ -19,6 +19,7 @@ from omotes_simulator_core.entities.assets.asset_abstract import AssetAbstract from omotes_simulator_core.entities.assets.elec_boiler import ElecBoiler +from omotes_simulator_core.entities.assets.gas_heater import GasHeater from omotes_simulator_core.entities.assets.esdl_asset_object import EsdlAssetObject from omotes_simulator_core.entities.assets.production_cluster import ProductionCluster from omotes_simulator_core.simulation.mappers.mappers import EsdlMapperAbstract @@ -46,13 +47,11 @@ def to_entity(self, esdl_asset: EsdlAssetObject) -> AssetAbstract: ) elif type(esdl_asset.esdl_asset) == esdl.GasHeater: - # producer_entity = ElecBoiler( # type:ignore - # asset_name=esdl_asset.esdl_asset.name, - # asset_id=esdl_asset.esdl_asset.id, - # port_ids=esdl_asset.get_port_ids(), - # ) - pass # TODO: create and link the gas heater mapper here. - + producer_entity = GasHeater( + asset_name=esdl_asset.esdl_asset.name, + asset_id=esdl_asset.esdl_asset.id, + port_ids=esdl_asset.get_port_ids(), + ) else: producer_entity = ProductionCluster( asset_name=esdl_asset.esdl_asset.name, @@ -60,6 +59,4 @@ def to_entity(self, esdl_asset: EsdlAssetObject) -> AssetAbstract: port_ids=esdl_asset.get_port_ids(), ) - # TODO: call eboiler or gas heater entities from here. - return producer_entity diff --git a/src/omotes_simulator_core/entities/assets/asset_defaults.py b/src/omotes_simulator_core/entities/assets/asset_defaults.py index 264fe722..b2d5f6be 100644 --- a/src/omotes_simulator_core/entities/assets/asset_defaults.py +++ b/src/omotes_simulator_core/entities/assets/asset_defaults.py @@ -28,6 +28,7 @@ DEFAULT_POWER = 500000.0 # [W] DEFAULT_MISSING_VALUE = -9999.99 # [-] DEFAULT_ROUGHNESS = 1e-3 # [m] +DEFAULT_GAS_ENERGY_CONTENT = 31.68 * 10.0**6 # [J/Nm3] @dataclass @@ -147,6 +148,7 @@ class HeatBufferDefaults: PROPERTY_HEAT_POWER_PRIMARY = "heat_power_primary" PROPERTY_HEAT_POWER_SECONDARY = "heat_power_secondary" PROPERTY_ELECTRICITY_CONSUMPTION = "electricity_consumption" +PROPERTY_GAS_CONSUMPTION = "gas_consumption" PROPERTY_VOLUME = "volume" PROPERTY_FILL_LEVEL = "fill_level" PROPERTY_TIMESTEP = "time_step" diff --git a/src/omotes_simulator_core/entities/assets/elec_boiler.py b/src/omotes_simulator_core/entities/assets/elec_boiler.py index 3dcb03d2..090f00cb 100644 --- a/src/omotes_simulator_core/entities/assets/elec_boiler.py +++ b/src/omotes_simulator_core/entities/assets/elec_boiler.py @@ -20,10 +20,8 @@ PROPERTY_ELECTRICITY_CONSUMPTION, PROPERTY_HEAT_SUPPLIED, PROPERTY_HEAT_SUPPLY_SET_POINT, - HeatPumpDefaults, ) from omotes_simulator_core.entities.assets.production_cluster import ProductionCluster -from omotes_simulator_core.solver.network.assets.production_asset import HeatBoundary logger = logging.getLogger(__name__) @@ -35,14 +33,13 @@ class ElecBoiler(ProductionCluster): """ efficiency: float - """The efficiency of the electric boiler [-].""" def __init__( self, asset_name: str, asset_id: str, port_ids: list[str], - efficiency: float = HeatPumpDefaults.coefficient_of_performance, #TODO: Make sure this takes a default of 1.0. + efficiency: float = 1.0 ) -> None: """ Initialize the ElecBoiler asset. @@ -57,12 +54,6 @@ def __init__( port_ids=port_ids, ) self.efficiency = efficiency - self.solver_asset = HeatBoundary( - name=self.name, - _id=self.asset_id, - pre_scribe_mass_flow=False, - set_pressure=self.pressure_supply, - ) def get_electric_power_consumption(self) -> float: """Calculate the electric power consumption of the electric boiler. diff --git a/src/omotes_simulator_core/entities/assets/gas_heater.py b/src/omotes_simulator_core/entities/assets/gas_heater.py index d69e68d5..c3b73fae 100644 --- a/src/omotes_simulator_core/entities/assets/gas_heater.py +++ b/src/omotes_simulator_core/entities/assets/gas_heater.py @@ -17,13 +17,12 @@ import logging from omotes_simulator_core.entities.assets.asset_defaults import ( - PROPERTY_ELECTRICITY_CONSUMPTION, PROPERTY_HEAT_SUPPLIED, PROPERTY_HEAT_SUPPLY_SET_POINT, - HeatPumpDefaults, + PROPERTY_GAS_CONSUMPTION, + DEFAULT_GAS_ENERGY_CONTENT, ) from omotes_simulator_core.entities.assets.production_cluster import ProductionCluster -from omotes_simulator_core.solver.network.assets.production_asset import HeatBoundary logger = logging.getLogger(__name__) @@ -35,14 +34,13 @@ class GasHeater(ProductionCluster): """ efficiency: float - """The efficiency of the gas heater [-].""" def __init__( self, asset_name: str, asset_id: str, port_ids: list[str], - efficiency: float = HeatPumpDefaults.coefficient_of_performance, #TODO: Make sure this takes a default of 1.0. + efficiency: float = 1.0, ) -> None: """ Initialize the GasHeater asset. @@ -51,18 +49,15 @@ def __init__( :param str asset_id: The unique identifier of the asset. :param List[str] port_ids: List of ids of the connected ports. """ + + self.efficiency = efficiency + self.gas_energy_content = DEFAULT_GAS_ENERGY_CONTENT + super().__init__( asset_name=asset_name, asset_id=asset_id, port_ids=port_ids, ) - self.efficiency = efficiency - self.solver_asset = HeatBoundary( - name=self.name, - _id=self.asset_id, - pre_scribe_mass_flow=False, - set_pressure=self.pressure_supply, - ) def get_gas_consumption(self) -> float: """Calculate the gas power consumption of the gas heater. @@ -74,10 +69,8 @@ def get_gas_consumption(self) -> float: The gas power consumption of the gas heater. """ - # self.Gas_demand_mass_flow / 1000.0 * self.energy_content * self.efficiency - # - self.Heat_source - return 1.0 # TODO: Fix this, it needs a gas energy content value. Check if it is already used somewhere else. + return abs(self.get_actual_heat_supplied()) / self.gas_energy_content / self.efficiency def write_to_output(self) -> None: """Method to write time step results to the output dict. @@ -88,6 +81,6 @@ def write_to_output(self) -> None: output_dict_temp = { PROPERTY_HEAT_SUPPLY_SET_POINT: self.heat_demand_set_point, PROPERTY_HEAT_SUPPLIED: self.get_actual_heat_supplied(), - PROPERTY_ELECTRICITY_CONSUMPTION: (self.get_gas_consumption()), + PROPERTY_GAS_CONSUMPTION: self.get_gas_consumption(), } self.outputs[1][-1].update(output_dict_temp) # Outputs appended to the out port. \ No newline at end of file From 534966ccdbc87529c38d07516ff5829dc023c2d7 Mon Sep 17 00:00:00 2001 From: Santiago Patterson Date: Wed, 15 Jul 2026 14:07:48 +0200 Subject: [PATCH 4/8] Fixed issue with efficiency assignment --- .../transforms/esdl_asset_mappers/producer_mapper.py | 2 ++ src/omotes_simulator_core/entities/assets/elec_boiler.py | 9 ++++++++- src/omotes_simulator_core/entities/assets/gas_heater.py | 9 ++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py b/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py index d87a7621..708dfe49 100644 --- a/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py +++ b/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py @@ -44,6 +44,7 @@ def to_entity(self, esdl_asset: EsdlAssetObject) -> AssetAbstract: asset_name=esdl_asset.esdl_asset.name, asset_id=esdl_asset.esdl_asset.id, port_ids=esdl_asset.get_port_ids(), + efficiency=esdl_asset.esdl_asset.efficiency ) elif type(esdl_asset.esdl_asset) == esdl.GasHeater: @@ -51,6 +52,7 @@ def to_entity(self, esdl_asset: EsdlAssetObject) -> AssetAbstract: asset_name=esdl_asset.esdl_asset.name, asset_id=esdl_asset.esdl_asset.id, port_ids=esdl_asset.get_port_ids(), + efficiency=esdl_asset.esdl_asset.efficiency ) else: producer_entity = ProductionCluster( diff --git a/src/omotes_simulator_core/entities/assets/elec_boiler.py b/src/omotes_simulator_core/entities/assets/elec_boiler.py index 090f00cb..88be98b7 100644 --- a/src/omotes_simulator_core/entities/assets/elec_boiler.py +++ b/src/omotes_simulator_core/entities/assets/elec_boiler.py @@ -53,7 +53,14 @@ def __init__( asset_id=asset_id, port_ids=port_ids, ) - self.efficiency = efficiency + if efficiency == 0 or efficiency > 1.0: + logger.warning( + f"Efficiency of {asset_name} is set to an invalid value of {efficiency}. " + f"Setting efficiency of {asset_name} to 1.0." + ) + self.efficiency = 1.0 + else: + self.efficiency = efficiency def get_electric_power_consumption(self) -> float: """Calculate the electric power consumption of the electric boiler. diff --git a/src/omotes_simulator_core/entities/assets/gas_heater.py b/src/omotes_simulator_core/entities/assets/gas_heater.py index c3b73fae..dd308156 100644 --- a/src/omotes_simulator_core/entities/assets/gas_heater.py +++ b/src/omotes_simulator_core/entities/assets/gas_heater.py @@ -49,8 +49,15 @@ def __init__( :param str asset_id: The unique identifier of the asset. :param List[str] port_ids: List of ids of the connected ports. """ + if efficiency == 0 or efficiency > 1.0: + logger.warning( + f"Efficiency of {asset_name} is set to an invalid value of {efficiency}. " + f"Setting efficiency of {asset_name} to 1.0." + ) + self.efficiency = 1.0 + else: + self.efficiency = efficiency - self.efficiency = efficiency self.gas_energy_content = DEFAULT_GAS_ENERGY_CONTENT super().__init__( From f3094dda8ed663d0090c1edf8e2897c547936313 Mon Sep 17 00:00:00 2001 From: Santiago Patterson Date: Wed, 15 Jul 2026 15:53:36 +0200 Subject: [PATCH 5/8] Tests added for gas heater and eboiler. --- unit_test/entities/test_elec_boiler.py | 101 ++++++++++++++++++++++++ unit_test/entities/test_gas_heater.py | 102 +++++++++++++++++++++++++ 2 files changed, 203 insertions(+) create mode 100644 unit_test/entities/test_elec_boiler.py create mode 100644 unit_test/entities/test_gas_heater.py diff --git a/unit_test/entities/test_elec_boiler.py b/unit_test/entities/test_elec_boiler.py new file mode 100644 index 00000000..0ac9ed5c --- /dev/null +++ b/unit_test/entities/test_elec_boiler.py @@ -0,0 +1,101 @@ +# Copyright (c) 2026. Deltares & TNO +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +"""Test ElecBoiler entities.""" +import unittest +from unittest.mock import patch + +from omotes_simulator_core.entities.assets.asset_defaults import ( + PROPERTY_ELECTRICITY_CONSUMPTION, + PROPERTY_HEAT_SUPPLIED, + PROPERTY_HEAT_SUPPLY_SET_POINT, +) +from omotes_simulator_core.entities.assets.elec_boiler import ElecBoiler + + +class ElecBoilerTest(unittest.TestCase): + """Testcase for ElecBoiler class.""" + + def setUp(self) -> None: + """Set up test case.""" + self.elec_boiler = ElecBoiler( + asset_name="elec_boiler", + asset_id="elec_boiler_id", + port_ids=["test1", "test2"], + efficiency=0.8, + ) + + def test_elec_boiler_create(self) -> None: + """Evaluate the creation of an electric boiler object.""" + self.assertIsInstance(self.elec_boiler, ElecBoiler) + self.assertEqual(self.elec_boiler.name, "elec_boiler") + self.assertEqual(self.elec_boiler.asset_id, "elec_boiler_id") + self.assertEqual(self.elec_boiler.connected_ports, ["test1", "test2"]) + self.assertEqual(self.elec_boiler.efficiency, 0.8) + + def test_elec_boiler_invalid_efficiency_defaults_to_one(self) -> None: + """Test invalid efficiency values are reset to 1.0.""" + elec_boiler_zero = ElecBoiler( + asset_name="elec_boiler_zero", + asset_id="elec_boiler_zero_id", + port_ids=["test1", "test2"], + efficiency=0.0, + ) + elec_boiler_above_one = ElecBoiler( + asset_name="elec_boiler_above_one", + asset_id="elec_boiler_above_one_id", + port_ids=["test1", "test2"], + efficiency=1.2, + ) + + self.assertEqual(elec_boiler_zero.efficiency, 1.0) + self.assertEqual(elec_boiler_above_one.efficiency, 1.0) + + def test_get_electric_power_consumption(self) -> None: + """Test getting electric power consumption of an electric boiler.""" + with patch.object(self.elec_boiler, "get_actual_heat_supplied", return_value=-2000.0): + power_consumption = self.elec_boiler.get_electric_power_consumption() + + expected_power_consumption = abs(-2000.0) / 0.8 + self.assertEqual(power_consumption, expected_power_consumption) + + def test_write_to_output(self) -> None: + """Test writing output of an electric boiler.""" + with ( + patch.object(self.elec_boiler.solver_asset, "get_mass_flow_rate") as get_mass_flow_rate, + patch.object(self.elec_boiler.solver_asset, "get_pressure") as get_pressure, + patch.object(self.elec_boiler.solver_asset, "get_temperature") as get_temperature, + patch.object(self.elec_boiler, "get_volume_flow_rate") as get_volume_flow_rate, + ): + get_mass_flow_rate.return_value = 1e6 + get_pressure.return_value = 2e5 + get_temperature.return_value = 333.15 + get_volume_flow_rate.return_value = 100.0 + + self.elec_boiler.write_standard_output() + + self.elec_boiler.heat_demand_set_point = -4000.0 + with ( + patch.object(self.elec_boiler, "get_actual_heat_supplied", return_value=3500.0), + patch.object(self.elec_boiler, "get_electric_power_consumption", return_value=4375.0), + ): + self.elec_boiler.write_to_output() + + self.assertEqual(self.elec_boiler.outputs[1][-1][PROPERTY_HEAT_SUPPLY_SET_POINT], -4000.0) + self.assertEqual(self.elec_boiler.outputs[1][-1][PROPERTY_HEAT_SUPPLIED], 3500.0) + self.assertEqual( + self.elec_boiler.outputs[1][-1][PROPERTY_ELECTRICITY_CONSUMPTION], + 4375.0, + ) diff --git a/unit_test/entities/test_gas_heater.py b/unit_test/entities/test_gas_heater.py new file mode 100644 index 00000000..2202446e --- /dev/null +++ b/unit_test/entities/test_gas_heater.py @@ -0,0 +1,102 @@ +# Copyright (c) 2026. Deltares & TNO +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +"""Test GasHeater entities.""" +import unittest +from unittest.mock import patch + +from omotes_simulator_core.entities.assets.asset_defaults import ( + DEFAULT_GAS_ENERGY_CONTENT, + PROPERTY_GAS_CONSUMPTION, + PROPERTY_HEAT_SUPPLIED, + PROPERTY_HEAT_SUPPLY_SET_POINT, +) +from omotes_simulator_core.entities.assets.gas_heater import GasHeater + + +class GasHeaterTest(unittest.TestCase): + """Testcase for GasHeater class.""" + + def setUp(self) -> None: + """Set up test case.""" + self.gas_heater = GasHeater( + asset_name="gas_heater", + asset_id="gas_heater_id", + port_ids=["test1", "test2"], + efficiency=0.9, + ) + + def test_gas_heater_create(self) -> None: + """Evaluate the creation of a gas heater object.""" + self.assertIsInstance(self.gas_heater, GasHeater) + self.assertEqual(self.gas_heater.name, "gas_heater") + self.assertEqual(self.gas_heater.asset_id, "gas_heater_id") + self.assertEqual(self.gas_heater.connected_ports, ["test1", "test2"]) + self.assertEqual(self.gas_heater.efficiency, 0.9) + + def test_gas_heater_invalid_efficiency_defaults_to_one(self) -> None: + """Test invalid efficiency values are reset to 1.0.""" + gas_heater_zero = GasHeater( + asset_name="gas_heater_zero", + asset_id="gas_heater_zero_id", + port_ids=["test1", "test2"], + efficiency=0.0, + ) + gas_heater_above_one = GasHeater( + asset_name="gas_heater_above_one", + asset_id="gas_heater_above_one_id", + port_ids=["test1", "test2"], + efficiency=1.1, + ) + + self.assertEqual(gas_heater_zero.efficiency, 1.0) + self.assertEqual(gas_heater_above_one.efficiency, 1.0) + + def test_get_gas_consumption(self) -> None: + """Test getting gas consumption of a gas heater.""" + with patch.object(self.gas_heater, "get_actual_heat_supplied", return_value=-1.0e6): + gas_consumption = self.gas_heater.get_gas_consumption() + + expected_gas_consumption = abs(-1.0e6) / DEFAULT_GAS_ENERGY_CONTENT / 0.9 + self.assertEqual(gas_consumption, expected_gas_consumption) + + def test_write_to_output(self) -> None: + """Test writing output of a gas heater.""" + with ( + patch.object(self.gas_heater.solver_asset, "get_mass_flow_rate") as get_mass_flow_rate, + patch.object(self.gas_heater.solver_asset, "get_pressure") as get_pressure, + patch.object(self.gas_heater.solver_asset, "get_temperature") as get_temperature, + patch.object(self.gas_heater, "get_volume_flow_rate") as get_volume_flow_rate, + ): + get_mass_flow_rate.return_value = 1e6 + get_pressure.return_value = 2e5 + get_temperature.return_value = 333.15 + get_volume_flow_rate.return_value = 100.0 + + self.gas_heater.write_standard_output() + + self.gas_heater.heat_demand_set_point = -2.5e6 + with ( + patch.object(self.gas_heater, "get_actual_heat_supplied", return_value=2.0e6), + patch.object(self.gas_heater, "get_gas_consumption", return_value=0.1), + ): + self.gas_heater.write_to_output() + + self.assertEqual( + self.gas_heater.outputs[1][-1][PROPERTY_HEAT_SUPPLY_SET_POINT], + -2.5e6, + ) + self.assertEqual(self.gas_heater.outputs[1][-1][PROPERTY_HEAT_SUPPLIED], 2.0e6) + self.assertEqual(self.gas_heater.outputs[1][-1][PROPERTY_GAS_CONSUMPTION], 0.1) From fcc2d17cd0093cda49dd6f57c5e189c898932765 Mon Sep 17 00:00:00 2001 From: Santiago Patterson Date: Wed, 15 Jul 2026 16:39:33 +0200 Subject: [PATCH 6/8] Linting and formatting. --- .../adapter/transforms/controller_mapper.py | 35 +++++++++++-------- .../esdl_asset_mappers/producer_mapper.py | 17 +++++---- .../entities/assets/asset_defaults.py | 2 +- .../entities/assets/elec_boiler.py | 15 +++----- .../entities/assets/gas_heater.py | 14 ++++---- .../entities/utility/influxdb_reader.py | 7 ++-- 6 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/omotes_simulator_core/adapter/transforms/controller_mapper.py b/src/omotes_simulator_core/adapter/transforms/controller_mapper.py index 9abd1ee7..03cc1ede 100644 --- a/src/omotes_simulator_core/adapter/transforms/controller_mapper.py +++ b/src/omotes_simulator_core/adapter/transforms/controller_mapper.py @@ -114,20 +114,27 @@ def to_entity( ControllerConsumerMapper().to_entity(esdl_asset=esdl_asset, timestep=timestep) for esdl_asset in esdl_object.get_all_assets_of_type(OmotesAssetLabels.CONSUMER) ] - producers = [ - ControllerProducerMapper().to_entity(esdl_asset=esdl_asset) - for esdl_asset in esdl_object.get_all_assets_of_type(OmotesAssetLabels.PRODUCER) - ] + [ - ControllerProducerMapper().to_entity(esdl_asset=esdl_asset) - for esdl_asset in esdl_object.get_all_assets_of_type(OmotesAssetLabels.HEAT_PUMP) - if esdl_asset.get_number_of_ports() == 2 - ] + [ - ControllerProducerMapper().to_entity(esdl_asset=esdl_asset) - for esdl_asset in esdl_object.get_all_assets_of_type(OmotesAssetLabels.GAS_HEATER) - ] + [ - ControllerProducerMapper().to_entity(esdl_asset=esdl_asset) - for esdl_asset in esdl_object.get_all_assets_of_type(OmotesAssetLabels.ELECTRIC_BOILER) - ] + producers = ( + [ + ControllerProducerMapper().to_entity(esdl_asset=esdl_asset) + for esdl_asset in esdl_object.get_all_assets_of_type(OmotesAssetLabels.PRODUCER) + ] + + [ + ControllerProducerMapper().to_entity(esdl_asset=esdl_asset) + for esdl_asset in esdl_object.get_all_assets_of_type(OmotesAssetLabels.HEAT_PUMP) + if esdl_asset.get_number_of_ports() == 2 + ] + + [ + ControllerProducerMapper().to_entity(esdl_asset=esdl_asset) + for esdl_asset in esdl_object.get_all_assets_of_type(OmotesAssetLabels.GAS_HEATER) + ] + + [ + ControllerProducerMapper().to_entity(esdl_asset=esdl_asset) + for esdl_asset in esdl_object.get_all_assets_of_type( + OmotesAssetLabels.ELECTRIC_BOILER + ) + ] + ) # ELECTRIC_BOILER = "electric_boiler" # GAS_HEATER = "gas_heater" diff --git a/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py b/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py index 708dfe49..58806b52 100644 --- a/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py +++ b/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py @@ -19,8 +19,8 @@ from omotes_simulator_core.entities.assets.asset_abstract import AssetAbstract from omotes_simulator_core.entities.assets.elec_boiler import ElecBoiler -from omotes_simulator_core.entities.assets.gas_heater import GasHeater from omotes_simulator_core.entities.assets.esdl_asset_object import EsdlAssetObject +from omotes_simulator_core.entities.assets.gas_heater import GasHeater from omotes_simulator_core.entities.assets.production_cluster import ProductionCluster from omotes_simulator_core.simulation.mappers.mappers import EsdlMapperAbstract @@ -38,21 +38,20 @@ def to_entity(self, esdl_asset: EsdlAssetObject) -> AssetAbstract: :param EsdlAssetObject esdl_asset: Object to be converted to a producer entity. :return: Producer object. """ - - if type(esdl_asset.esdl_asset) == esdl.ElectricBoiler: - producer_entity = ElecBoiler( + if isinstance(esdl_asset.esdl_asset, esdl.ElectricBoiler): + producer_entity = ElecBoiler( asset_name=esdl_asset.esdl_asset.name, asset_id=esdl_asset.esdl_asset.id, port_ids=esdl_asset.get_port_ids(), - efficiency=esdl_asset.esdl_asset.efficiency + efficiency=esdl_asset.esdl_asset.efficiency, ) - - elif type(esdl_asset.esdl_asset) == esdl.GasHeater: - producer_entity = GasHeater( + + elif isinstance(esdl_asset.esdl_asset, esdl.GasHeater): + producer_entity = GasHeater( asset_name=esdl_asset.esdl_asset.name, asset_id=esdl_asset.esdl_asset.id, port_ids=esdl_asset.get_port_ids(), - efficiency=esdl_asset.esdl_asset.efficiency + efficiency=esdl_asset.esdl_asset.efficiency, ) else: producer_entity = ProductionCluster( diff --git a/src/omotes_simulator_core/entities/assets/asset_defaults.py b/src/omotes_simulator_core/entities/assets/asset_defaults.py index b2d5f6be..2c0b9be7 100644 --- a/src/omotes_simulator_core/entities/assets/asset_defaults.py +++ b/src/omotes_simulator_core/entities/assets/asset_defaults.py @@ -28,7 +28,7 @@ DEFAULT_POWER = 500000.0 # [W] DEFAULT_MISSING_VALUE = -9999.99 # [-] DEFAULT_ROUGHNESS = 1e-3 # [m] -DEFAULT_GAS_ENERGY_CONTENT = 31.68 * 10.0**6 # [J/Nm3] +DEFAULT_GAS_ENERGY_CONTENT = 31.68 * 10.0**6 # [J/Nm3] @dataclass diff --git a/src/omotes_simulator_core/entities/assets/elec_boiler.py b/src/omotes_simulator_core/entities/assets/elec_boiler.py index 88be98b7..7e164371 100644 --- a/src/omotes_simulator_core/entities/assets/elec_boiler.py +++ b/src/omotes_simulator_core/entities/assets/elec_boiler.py @@ -35,11 +35,7 @@ class ElecBoiler(ProductionCluster): efficiency: float def __init__( - self, - asset_name: str, - asset_id: str, - port_ids: list[str], - efficiency: float = 1.0 + self, asset_name: str, asset_id: str, port_ids: list[str], efficiency: float = 1.0 ) -> None: """ Initialize the ElecBoiler asset. @@ -55,9 +51,9 @@ def __init__( ) if efficiency == 0 or efficiency > 1.0: logger.warning( - f"Efficiency of {asset_name} is set to an invalid value of {efficiency}. " - f"Setting efficiency of {asset_name} to 1.0." - ) + f"Efficiency of {asset_name} is set to an invalid value of {efficiency}. " + f"Setting efficiency of {asset_name} to 1.0." + ) self.efficiency = 1.0 else: self.efficiency = efficiency @@ -71,7 +67,6 @@ def get_electric_power_consumption(self) -> float: :return: float The electric power consumption of the electric boiler. """ - return abs(self.get_actual_heat_supplied()) / self.efficiency def write_to_output(self) -> None: @@ -85,4 +80,4 @@ def write_to_output(self) -> None: PROPERTY_HEAT_SUPPLIED: self.get_actual_heat_supplied(), PROPERTY_ELECTRICITY_CONSUMPTION: (self.get_electric_power_consumption()), } - self.outputs[1][-1].update(output_dict_temp) # Outputs appended to the out port. \ No newline at end of file + self.outputs[1][-1].update(output_dict_temp) # Outputs appended to the out port. diff --git a/src/omotes_simulator_core/entities/assets/gas_heater.py b/src/omotes_simulator_core/entities/assets/gas_heater.py index dd308156..903b786b 100644 --- a/src/omotes_simulator_core/entities/assets/gas_heater.py +++ b/src/omotes_simulator_core/entities/assets/gas_heater.py @@ -17,10 +17,10 @@ import logging from omotes_simulator_core.entities.assets.asset_defaults import ( + DEFAULT_GAS_ENERGY_CONTENT, + PROPERTY_GAS_CONSUMPTION, PROPERTY_HEAT_SUPPLIED, PROPERTY_HEAT_SUPPLY_SET_POINT, - PROPERTY_GAS_CONSUMPTION, - DEFAULT_GAS_ENERGY_CONTENT, ) from omotes_simulator_core.entities.assets.production_cluster import ProductionCluster @@ -51,9 +51,9 @@ def __init__( """ if efficiency == 0 or efficiency > 1.0: logger.warning( - f"Efficiency of {asset_name} is set to an invalid value of {efficiency}. " - f"Setting efficiency of {asset_name} to 1.0." - ) + f"Efficiency of {asset_name} is set to an invalid value of {efficiency}. " + f"Setting efficiency of {asset_name} to 1.0." + ) self.efficiency = 1.0 else: self.efficiency = efficiency @@ -75,8 +75,6 @@ def get_gas_consumption(self) -> float: :return: float The gas power consumption of the gas heater. """ - - return abs(self.get_actual_heat_supplied()) / self.gas_energy_content / self.efficiency def write_to_output(self) -> None: @@ -90,4 +88,4 @@ def write_to_output(self) -> None: PROPERTY_HEAT_SUPPLIED: self.get_actual_heat_supplied(), PROPERTY_GAS_CONSUMPTION: self.get_gas_consumption(), } - self.outputs[1][-1].update(output_dict_temp) # Outputs appended to the out port. \ No newline at end of file + self.outputs[1][-1].update(output_dict_temp) # Outputs appended to the out port. diff --git a/src/omotes_simulator_core/entities/utility/influxdb_reader.py b/src/omotes_simulator_core/entities/utility/influxdb_reader.py index c225c738..6bd8bb37 100644 --- a/src/omotes_simulator_core/entities/utility/influxdb_reader.py +++ b/src/omotes_simulator_core/entities/utility/influxdb_reader.py @@ -43,7 +43,7 @@ def _normalize_influx_filters(filters: str | None) -> list[dict[str, str]]: normalized_filters.append( { "tag": str(tag), - "value": str(value).strip().strip("\"").strip("'"), + "value": str(value).strip().strip('"').strip("'"), } ) return normalized_filters @@ -108,8 +108,9 @@ def get_data_from_profile(esdl_profile: esdl.InfluxDBProfile) -> pd.DataFrame: fields=[profile_field], from_datetime=cast(datetime, esdl_profile.startDate), to_datetime=cast(datetime, esdl_profile.endDate), - filters=_normalize_influx_filters(str(esdl_profile.filters) - if esdl_profile.filters else None), + filters=_normalize_influx_filters( + str(esdl_profile.filters) if esdl_profile.filters else None + ), ) # Error check start and end dates of profiles From f8527a7a744ca63ac75073c299ca1283041649bb Mon Sep 17 00:00:00 2001 From: Santiago Patterson Date: Wed, 15 Jul 2026 16:46:20 +0200 Subject: [PATCH 7/8] Fixed typecheck --- .../adapter/transforms/esdl_asset_mappers/producer_mapper.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py b/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py index 58806b52..a3cc269d 100644 --- a/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py +++ b/src/omotes_simulator_core/adapter/transforms/esdl_asset_mappers/producer_mapper.py @@ -38,6 +38,7 @@ def to_entity(self, esdl_asset: EsdlAssetObject) -> AssetAbstract: :param EsdlAssetObject esdl_asset: Object to be converted to a producer entity. :return: Producer object. """ + producer_entity: AssetAbstract if isinstance(esdl_asset.esdl_asset, esdl.ElectricBoiler): producer_entity = ElecBoiler( asset_name=esdl_asset.esdl_asset.name, From 39a7c7424710d2f3afad39627e3e4c944f900c49 Mon Sep 17 00:00:00 2001 From: Santiago Patterson Date: Thu, 16 Jul 2026 16:49:44 +0200 Subject: [PATCH 8/8] Deleted file. --- testdata/test1_eboiler.esdl | 49 ------------------------------------- 1 file changed, 49 deletions(-) delete mode 100644 testdata/test1_eboiler.esdl diff --git a/testdata/test1_eboiler.esdl b/testdata/test1_eboiler.esdl deleted file mode 100644 index bb6a587a..00000000 --- a/testdata/test1_eboiler.esdl +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -