Coverage for test/unit/tasks/hvac/test_export.py: 100%

96 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-12 17:09 +0000

1import tempfile 

2import unittest 

3from pathlib import Path 

4from typing import List, Tuple 

5from unittest import mock 

6 

7from bim2sim.elements.graphs.hvac_graph import HvacGraph 

8from bim2sim.elements.hvac_elements import HVACProduct, Pump 

9from bim2sim.elements.mapping.units import ureg 

10 

11from bim2sim.export.modelica import ModelicaElement, ModelicaParameter, \ 

12 parse_to_modelica 

13from bim2sim.kernel.decision.decisionhandler import DebugDecisionHandler 

14from bim2sim.sim_settings import PlantSimSettings 

15from bim2sim.tasks.hvac import Export, LoadLibrariesStandardLibrary 

16from test.unit.elements.helper import SetupHelperHVAC 

17from test.unit.tasks import TestTask 

18 

19 

20class TestStandardLibraryExports(TestTask): 

21 @classmethod 

22 def simSettingsClass(cls): 

23 return PlantSimSettings() 

24 

25 @classmethod 

26 def testTask(cls): 

27 return Export(cls.playground) 

28 

29 @classmethod 

30 def helper(cls): 

31 return SetupHelperHVAC() 

32 

33 @classmethod 

34 def setUpClass(cls) -> None: 

35 super().setUpClass() 

36 # Load libraries as these are required for export 

37 lib_msl = LoadLibrariesStandardLibrary(cls.playground) 

38 cls.loaded_libs = lib_msl.run()[0] 

39 

40 

41 def run_parameter_test(self, graph: HvacGraph, modelica_model: list, 

42 parameters: List[Tuple[str, str]], 

43 expected_units: list): 

44 """ 

45 Runs a parameter test on an element exported to Modelica code. 

46 

47 This method checks that the specified attributes in the element are 

48 converted to the expected units and correctly appear in the Modelica 

49 model's code. 

50 

51 Args: 

52 graph: The HvacGraph containing the element to be tested. 

53 modelica_model: A list containing the modelica model instances. 

54 parameters: A list of tuples where each tuple contains the name of 

55 the element attribute and the corresponding modelica parameter. 

56 The attribute name comes first. 

57 expected_units: A list of expected units of the parameter in 

58 Modelica. 

59 """ 

60 element = graph.elements[0] 

61 values = [ 

62 element.attributes[param[0]][0].to(expected_units[index]).magnitude 

63 for index, param in enumerate(parameters)] 

64 expected_strings = [f'{param[1]}={values[index]}' 

65 for index, param in enumerate(parameters)] 

66 for expected_string in expected_strings: 

67 self.assertIn(expected_string, modelica_model[0].code()) 

68 

69 def test_to_modelica(self): 

70 element = HVACProduct() 

71 modelica_instance = ModelicaElement(element) 

72 # True boolean 

73 self.assertEqual('a=true', 

74 parse_to_modelica('a', True)) 

75 # False boolean 

76 self.assertEqual('a=false', 

77 parse_to_modelica('a', False)) 

78 # Quantity with unit 

79 self.assertEqual('a=1', 

80 parse_to_modelica('a', 1 * ureg.m)) 

81 # Integer 

82 self.assertEqual('a=1', 

83 parse_to_modelica('a', int(1))) 

84 # Float 

85 self.assertEqual('a=1.1', 

86 parse_to_modelica('a', float(1.1))) 

87 # String 

88 self.assertEqual('a="a"', 

89 parse_to_modelica('a', '"a"')) 

90 # List 

91 self.assertEqual('a={1,1.1}', 

92 parse_to_modelica( 

93 'a', [int(1), float(1.1)])) 

94 # Tuple 

95 self.assertEqual('a={1,1.1}', 

96 parse_to_modelica( 

97 'a', (int(1), float(1.1)))) 

98 # Set 

99 self.assertEqual('a={1,1.1}', 

100 parse_to_modelica( 

101 'a', {int(1), float(1.1)})) 

102 # Dict 

103 self.assertEqual('a(b=1.1)', 

104 parse_to_modelica( 

105 'a', {'b': 1.1})) 

106 self.assertEqual('per(pressure(V_flow={1,2},dp={1,2}))', 

107 parse_to_modelica( 

108 'per', 

109 {'pressure': {'V_flow': [1, 2], 'dp': [1, 2]}})) 

110 # Path 

111 self.assertEqual( 

112 'Modelica.Utilities.Files.loadResource("C:\\\\Users")', 

113 parse_to_modelica(None, Path(r'C:\Users'))) 

114 

115 def test_missing_required_parameter(self): 

116 """ Test if an AssertionError is raised if a required parameter is not 

117 provided.""" 

118 graph, pipe = self.helper.get_simple_pipe() 

119 answers = () 

120 with self.assertRaises(AssertionError): 

121 DebugDecisionHandler(answers).handle( 

122 self.test_task.run(self.loaded_libs, graph)) 

123 

124 def test_check_function(self): 

125 """ Test if the check function for a parameter works. The exported 

126 parameter 'diameter' should be None since it is set to a negative 

127 value. 

128 """ 

129 graph, pipe = self.helper.get_simple_pipe() 

130 pipe.diameter = -1 * ureg.meter 

131 answers = () 

132 reads = (self.loaded_libs, graph) 

133 modelica_model = self.run_task(answers, reads) 

134 self.assertIsNone( 

135 modelica_model[0].modelica_elements[0].parameters['diameter'].value) 

136 self.assertIsNotNone( 

137 modelica_model[0].modelica_elements[0].parameters['length'].value) 

138 

139 def test_pipe_export(self): 

140 graph, pipe = self.helper.get_simple_pipe() 

141 pipe.diameter = 0.2 * ureg.meter 

142 answers = () 

143 reads = (self.loaded_libs, graph) 

144 modelica_model = self.run_task(answers, reads) 

145 # Test for expected and exported parameters 

146 parameters = [('diameter', 'diameter'), ('length', 'length')] 

147 expected_units = [ureg.m, ureg.m] 

148 self.run_parameter_test(graph, modelica_model, parameters, 

149 expected_units) 

150 

151 def test_valve_export(self): 

152 graph = self.helper.get_simple_valve() 

153 answers = (1 * ureg.kg / ureg.h,) 

154 reads = (self.loaded_libs, graph) 

155 modelica_model = self.run_task(answers, reads) 

156 parameters = [('nominal_pressure_difference', 'dp_nominal'), 

157 ('nominal_mass_flow_rate', 'm_flow_nominal')] 

158 expected_units = [ureg.bar, ureg.kg / ureg.s] 

159 self.run_parameter_test(graph, modelica_model, parameters, 

160 expected_units) 

161 

162 def test_junction_export(self): 

163 graph = self.helper.get_simple_junction() 

164 answers = () 

165 reads = (self.loaded_libs, graph) 

166 modelica_model = self.run_task(answers, reads) 

167 # Test for expected and exported parameters 

168 parameters = [('volume', 'V')] 

169 expected_units = [ureg.m ** 3] 

170 self.run_parameter_test(graph, modelica_model, parameters, 

171 expected_units) 

172 

173 def test_storage_export(self): 

174 graph = self.helper.get_simple_storage() 

175 answers = () 

176 reads = (self.loaded_libs, graph) 

177 modelica_model = self.run_task(answers, reads) 

178 # Test for expected and exported parameters 

179 parameters = [('volume', 'V')] 

180 expected_units = [ureg.m ** 3] 

181 self.run_parameter_test(graph, modelica_model, parameters, 

182 expected_units)