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

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 

6 

7 

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

28 

29 

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

74 

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 

93 

94 

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

125 

126 

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