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