Coverage for agentlib_flexquant/data_structures/mpcs.py: 100%
68 statements
« prev ^ index » next coverage.py v7.4.4, created at 2025-08-01 15:10 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2025-08-01 15:10 +0000
1import pydantic
2from pydantic import ConfigDict, model_validator
3from typing import List, Optional
4from agentlib_mpc.data_structures.mpc_datamodels import MPCVariable
5import agentlib_flexquant.data_structures.globals as glbs
6import agentlib_flexquant.utils.config_management as cmng
9class BaseMPCData(pydantic.BaseModel):
10 """Base class containing necessary data for the code creation of the different mpcs"""
12 # files and paths
13 created_flex_mpcs_file: str = "flex_agents.py"
14 name_of_created_file: str
15 results_suffix: str
16 # modules
17 module_types: dict
18 class_name: str
19 module_id: str
20 # variables
21 power_alias: str
22 stored_energy_alias: str
23 config_inputs_appendix: List[MPCVariable] = []
24 config_parameters_appendix: List[MPCVariable] = []
25 weights: List[MPCVariable] = pydantic.Field(
26 default=[],
27 description="Name and value of weights",
28 )
29 model_config = ConfigDict(json_encoders={MPCVariable: lambda v: v.dict()})
32class BaselineMPCData(BaseMPCData):
33 """Data class for Baseline MPC"""
35 # files and paths
36 results_suffix: str = "_base.csv"
37 name_of_created_file: str = "baseline.json"
38 # modules
39 module_types: dict = cmng.BASELINE_MODULE_TYPE_DICT
40 class_name: str = "BaselineMPCModel"
41 module_id: str = "Baseline"
42 # variables
43 power_alias: str = glbs.POWER_ALIAS_BASE
44 stored_energy_alias: str = glbs.STORED_ENERGY_ALIAS_BASE
45 power_variable: str = pydantic.Field(
46 default="P_el",
47 description="Name of the variable representing the electrical power in the baseline config",
48 )
49 profile_deviation_weight: float = pydantic.Field(
50 default=0,
51 description="Weight of soft constraint for deviation from accepted flexible profile",
52 )
53 power_unit: str = pydantic.Field(
54 default="kW",
55 description="Unit of the power variable"
56 )
57 comfort_variable: str = pydantic.Field(
58 default=None,
59 description="Name of the slack variable representing the thermal comfort in the baseline config",
60 )
61 profile_comfort_weight: float = pydantic.Field(
62 default=1,
63 description="Weight of soft constraint for discomfort",
64 )
65 config_inputs_appendix: List[MPCVariable] = [
66 MPCVariable(name="_P_external", value=0, unit="W"),
67 MPCVariable(name="in_provision", value=False),
68 MPCVariable(name="rel_start", value=0, unit="s"),
69 MPCVariable(name="rel_end", value=0, unit="s"),
70 ]
71 config_parameters_appendix: List[MPCVariable] = []
72 weights: List[MPCVariable] = pydantic.Field(
73 default=[],
74 description="Name and value of weights",
75 )
76 model_config = ConfigDict(json_encoders={MPCVariable: lambda v: v.dict()})
78 @model_validator(mode='after')
79 def update_config_parameters_appendix(self) -> 'BaselineMPCData':
80 self.config_parameters_appendix = [
81 MPCVariable(
82 name=glbs.PROFILE_DEVIATION_WEIGHT,
83 value=self.profile_deviation_weight,
84 unit="-",
85 description="Weight of soft constraint for deviation from accepted flexible profile"
86 )
87 ]
88 if self.comfort_variable:
89 self.config_parameters_appendix.append(MPCVariable(
90 name=glbs.PROFILE_COMFORT_WEIGHT,
91 value=self.profile_comfort_weight,
92 unit="-",
93 description="Weight of soft constraint for discomfort"
94 ))
95 return self
98class PFMPCData(BaseMPCData):
99 """Data class for PF-MPC"""
101 # files and paths
102 results_suffix: str = "_pos_flex.csv"
103 name_of_created_file: str = "pos_flex.json"
104 # modules
105 module_types: dict = cmng.SHADOW_MODULE_TYPE_DICT
106 class_name: str = "PosFlexModel"
107 module_id: str = "PosFlexMPC"
108 # variables
109 power_alias: str = glbs.POWER_ALIAS_POS
110 stored_energy_alias: str = glbs.STORED_ENERGY_ALIAS_POS
111 flex_cost_function: str = pydantic.Field(
112 default=None,
113 description="Cost function of the PF-MPC",
114 )
115 # initialize market parameters with dummy values (0)
116 config_parameters_appendix: List[MPCVariable] = [
117 MPCVariable(name=glbs.PREP_TIME, value=0, unit="s"),
118 MPCVariable(name=glbs.MARKET_TIME, value=0, unit="s"),
119 MPCVariable(name=glbs.FLEX_EVENT_DURATION, value=0, unit="s"),
120 ]
121 config_inputs_appendix: List[MPCVariable] = [
122 MPCVariable(name="in_provision", value=False),
123 ]
124 weights: List[MPCVariable] = pydantic.Field(
125 default=[],
126 description="Name and value of weights",
127 )
128 model_config = ConfigDict(json_encoders={MPCVariable: lambda v: v.dict()})
131class NFMPCData(BaseMPCData):
132 """Data class for PF-MPC"""
134 # files and paths
135 results_suffix: str = "_neg_flex.csv"
136 name_of_created_file: str = "neg_flex.json"
137 # modules
138 module_types: dict = cmng.SHADOW_MODULE_TYPE_DICT
139 class_name: str = "NegFlexModel"
140 module_id: str = "NegFlexMPC"
141 # variables
142 power_alias: str = glbs.POWER_ALIAS_NEG
143 stored_energy_alias: str = glbs.STORED_ENERGY_ALIAS_NEG
144 flex_cost_function: str = pydantic.Field(
145 default=None,
146 description="Cost function of the NF-MPC",
147 )
148 # initialize market parameters with dummy values (0)
149 config_parameters_appendix: List[MPCVariable] = [
150 MPCVariable(name=glbs.PREP_TIME, value=0, unit="s"),
151 MPCVariable(name=glbs.MARKET_TIME, value=0, unit="s"),
152 MPCVariable(name=glbs.FLEX_EVENT_DURATION, value=0, unit="s"),
153 ]
154 config_inputs_appendix: List[MPCVariable] = [
155 MPCVariable(name="in_provision", value=False),
156 ]
157 weights: List[MPCVariable] = pydantic.Field(
158 default=[],
159 description="Name and value of weights",
160 )
161 model_config = ConfigDict(json_encoders={MPCVariable: lambda v: v.dict()})