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

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 

7 

8 

9class BaseMPCData(pydantic.BaseModel): 

10 """Base class containing necessary data for the code creation of the different mpcs""" 

11 

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()}) 

30 

31 

32class BaselineMPCData(BaseMPCData): 

33 """Data class for Baseline MPC""" 

34 

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()}) 

77 

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 

96 

97 

98class PFMPCData(BaseMPCData): 

99 """Data class for PF-MPC""" 

100 

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()}) 

129 

130 

131class NFMPCData(BaseMPCData): 

132 """Data class for PF-MPC""" 

133 

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()})