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

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

29 

30 

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

75 

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 

94 

95 

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

126 

127 

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