Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# [Unreleased-main] - 2026-02-25
# [Unreleased-main] - 2026-03-10

## Added
- Parsing of ensemble profiles when using input profiles from csv.
- Maximum profile constraint for PV asset is considered in PV sizing
- Cater for input via esdl constraints to specify the upper limit for OPTIONAL assets in DTK

## Changed
- Speed-up timeseries check in from InfluxDB
Expand Down
Empty file removed heat_producer)
Empty file.
1 change: 1 addition & 0 deletions manual_run/testing_bugs/src/run_grow.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
base_folder = Path(__file__).resolve().parent.parent

kwargs = {
"use_esdl_ranged_constraint": True, # default value in the code is set to False
"database_connections": [
{
"access_type": DBAccessType.READ, # or DBAccessType.WRITE or DBAccessType.READ_WRITE
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
# < 81.0.0 needed for pandapipes (still to be removed)
# < 82.0.0 needed for pkg_resources (used in rtctools)
"setuptools <= 80.9.0",
"pyesdl == 25.7",
"pyesdl == 26.2",
"pandas >= 1.3.1, < 2.0",
"casadi-gil-comp == 3.6.7",
"StrEnum == 0.4.15",
Expand Down
51 changes: 27 additions & 24 deletions src/mesido/asset_sizing_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from mesido.base_component_type_mixin import BaseComponentTypeMixin
from mesido.demand_insulation_class import DemandInsulationClass
from mesido.esdl.asset_to_component_base import AssetStateEnum
from mesido.esdl.common import Asset
from mesido.esdl.esdl_additional_vars_mixin import get_asset_contraints
from mesido.head_loss_class import HeadLossOption
from mesido.network_common import NetworkSettings
from mesido.pipe_class import CableClass, GasPipeClass, PipeClass
Expand Down Expand Up @@ -801,13 +803,14 @@ 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"]
asset = self.esdl_assets[self.esdl_asset_name_to_id_map[asset_name]]
asset_profile_constraints, qty_asset_profile_constraints = get_asset_contraints(
self, asset, esdl.ProfileConstraint
)
if (
len(esdl_asset_attributes) > 0
and hasattr(esdl_asset_attributes.items[0], "maximum")
and esdl_asset_attributes.items[0].maximum.profileQuantityAndUnit.reference.unit
qty_asset_profile_constraints > 0
and hasattr(asset_profile_constraints[0], "maximum")
and asset_profile_constraints[0].maximum.profileQuantityAndUnit.reference.unit
== esdl.UnitEnum.WATT
and parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL # Optional asset
):
Expand Down Expand Up @@ -1859,7 +1862,7 @@ def __electricity_cable_topology_path_constraints(self, ensemble_member):

def __producer_constraints(
self,
asset: str,
asset: Asset,
variable_suffix: str,
source: ca.MX,
max_power: ca.MX,
Expand All @@ -1875,7 +1878,7 @@ def __producer_constraints(

Parameters
----------
asset : Name of the asset.
asset : Asset object.
variable_suffix : Timeseries suffix indicating the maximum production profile
(e.g., "maximum_heat_source", "maximum_electricity_source").
source : Vector of path_variables of produced energy to be constrained.
Expand All @@ -1888,8 +1891,8 @@ def __producer_constraints(
constraints : The function returns a list of profile‑based capacity constraints.
"""
constraints = []
if f"{asset}.{variable_suffix}" in self.io.get_timeseries_names():
timeseries = self.get_timeseries(f"{asset}.{variable_suffix}")
if f"{asset.name}.{variable_suffix}" in self.io.get_timeseries_names():
timeseries = self.get_timeseries(f"{asset.name}.{variable_suffix}")
if len(self.times()) < len(timeseries.times):
idx_start = np.where(timeseries.times == self.times()[0])[0][0]
idx_end = np.where(timeseries.times == self.times()[-1])[0][0]
Expand All @@ -1901,17 +1904,17 @@ def __producer_constraints(

# Cap the energy 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[asset]
].attributes["constraint"]
asset_profile_constraints, qty_asset_profile_constraints = get_asset_contraints(
self, asset, esdl.ProfileConstraint
)
if (
len(esdl_asset_attributes) > 0
and hasattr(esdl_asset_attributes.items[0], "maximum")
and esdl_asset_attributes.items[0].maximum.profileQuantityAndUnit.reference.unit
qty_asset_profile_constraints > 0
and hasattr(asset_profile_constraints[0], "maximum")
and asset_profile_constraints[0].maximum.profileQuantityAndUnit.reference.unit
== esdl.UnitEnum.WATT
):
parameters = self.parameters(ensemble_member)
asset_state = parameters[f"{asset}.state"]
asset_state = parameters[f"{asset.name}.state"]

if asset_state == AssetStateEnum.ENABLED: # Enabled asset
constraints.append(
Expand Down Expand Up @@ -1946,16 +1949,16 @@ def __producer_constraints(
# installed capacity
elif (
# profile is specified without units (xlm/csv)
len(esdl_asset_attributes) == 0
qty_asset_profile_constraints == 0
or (
esdl_asset_attributes.items[
asset_profile_constraints[
0
].maximum.profileQuantityAndUnit.reference.physicalQuantity
== esdl.PhysicalQuantityEnum.COEFFICIENT
and (
esdl_asset_attributes.items[0].maximum.profileQuantityAndUnit.reference.unit
asset_profile_constraints[0].maximum.profileQuantityAndUnit.reference.unit
== esdl.UnitEnum.PERCENT
or esdl_asset_attributes.items[
or asset_profile_constraints[
0
].maximum.profileQuantityAndUnit.reference.unit
== esdl.UnitEnum.NONE
Expand All @@ -1973,7 +1976,7 @@ def __producer_constraints(
)
)
else:
RuntimeError(f"{asset}: Unforeseen error in adding a profile constraint")
RuntimeError(f"{asset.name}: Unforeseen error in adding a profile constraint")
else:
constraints.append(
(
Expand Down Expand Up @@ -2048,7 +2051,7 @@ def __max_size_constraints(self, ensemble_member):
constraint_nominal = self.variable_nominal(f"{s}.Heat_source")
constraints.extend(
self.__producer_constraints(
s,
self.esdl_assets[self.esdl_asset_name_to_id_map[s]],
"maximum_heat_source",
heat_source,
max_heat,
Expand Down Expand Up @@ -2192,7 +2195,7 @@ def __max_size_constraints(self, ensemble_member):
constraint_nominal = self.variable_nominal(f"{d}.Electricity_source")
constraints.extend(
self.__producer_constraints(
d,
self.esdl_assets[self.esdl_asset_name_to_id_map[d]],
"maximum_electricity_source",
electricity_source,
max_power,
Expand Down
6 changes: 4 additions & 2 deletions src/mesido/esdl/asset_to_component_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ def get_density(
# pressure and temperature.
if carrier is None:
logger.warning(
f"Neither gas/hydrogen/heat was used in the carrier at asset named {asset_name}."
f"Neither gas/hydrogen/heat was specified at asset named {asset_name}. "
"Gas properties will be used."
)
density = cP.CoolProp.PropsSI(
"D",
Expand Down Expand Up @@ -201,7 +202,8 @@ def get_density(
)
else:
logger.warning(
f"Neither gas/hydrogen/heat was used in the carrier at asset named {asset_name}."
f"Neither gas/hydrogen/heat was specified in the carrier at asset named {asset_name}. "
"Gas properties will be used."
)
density = 6.2 # natural gas at about 8 bar

Expand Down
25 changes: 24 additions & 1 deletion src/mesido/esdl/esdl_additional_vars_mixin.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import logging
from typing import List
from typing import List, Union

import esdl

from mesido.esdl.common import Asset
from mesido.network_common import NetworkSettings
from mesido.pipe_class import PipeClass

Expand Down Expand Up @@ -285,3 +286,25 @@ def temperature_regimes(self, carrier):
self.__temperature_options[carrier] = temperature_options

return temperature_options


def get_asset_contraints(
self, asset: Asset, constraint_type: esdl.Constraint
) -> Union[List[esdl.Constraint], int]:
"""
Get the contraints at an asset and the qty thereof.

Arg:
asset: mesido common asset with all attributes
constraint type: the type of contraint specified (e.g. esdl.RangedConstraint,
esdl.ProfileConstraint)

Returns:
- Contraints of a specific type
- Number of constraints of specific type that exists
"""

asset_constraints = [
cnst for cnst in asset.attributes["constraint"] if isinstance(cnst, constraint_type)
]
return asset_constraints, len(asset_constraints)
Loading