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