Coverage for bim2sim/plugins/PluginHKESim/bim2sim_hkesim/models/__init__.py: 0%
170 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-12 17:09 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-12 17:09 +0000
1"""Package for Python representations of HKESim models"""
3from bim2sim.elements.aggregation import hvac_aggregations
4from bim2sim.export import modelica
5from bim2sim.elements import hvac_elements as hvac
6from bim2sim.elements.mapping.units import ureg
7from bim2sim.export.modelica import check_numeric
9MEDIUM_WATER = 'Modelica.Media.Water.ConstantPropertyLiquidWater'
12class HKESim(modelica.ModelicaElement):
13 library = "HKESim"
16class Boiler(HKESim):
17 path = "HKESim.Heating.Boilers.Boiler"
18 represents = [hvac.Boiler]
20 def __init__(self, element):
21 super().__init__(element)
22 self._set_parameter(name='redeclare package Medium',
23 unit=None,
24 required=False,
25 value=MEDIUM_WATER)
26 self._set_parameter(name="Q_nom",
27 unit=ureg.watt,
28 required=True,
29 attributes=['rated_power'])
30 self._set_parameter(name='T_set',
31 unit=ureg.kelvin,
32 required=True,
33 attributes=['return_temperature'])
35 def get_port_name(self, port):
36 if port.verbose_flow_direction == 'SINK':
37 return 'port_a'
38 if port.verbose_flow_direction == 'SOURCE':
39 return 'port_b'
40 else:
41 return super().get_port_name(port)
42 # TODO: Gas and electric connection see
43 # https://github.com/BIM2SIM/bim2sim/issues/80
46class Radiator(HKESim):
47 path = "HKESim.Heating.Consumers.Consumer"
48 represents = [hvac.SpaceHeater, hvac_aggregations.Consumer]
50 def __init__(self, element):
51 super().__init__(element)
52 self._set_parameter(name='redeclare package Medium',
53 unit=None,
54 required=False,
55 value=MEDIUM_WATER)
56 self._set_parameter(name="Q_flow_nominal",
57 unit=ureg.watt,
58 required=False,
59 attributes=['rated_power'])
60 self._set_parameter(name="Tout_max",
61 unit=ureg.kelvin,
62 required=False,
63 attributes=['return_temperature'])
65 def get_port_name(self, port):
66 if port.verbose_flow_direction == 'SINK':
67 return 'port_a'
68 if port.verbose_flow_direction == 'SOURCE':
69 return 'port_b'
70 else:
71 return super().get_port_name(port)
74class Pump(HKESim):
75 path = "HKESim.Heating.Pumps.Pump"
76 represents = [hvac.Pump]
78 def __init__(self, element):
79 super().__init__(element)
80 self._set_parameter(name='redeclare package Medium',
81 unit=None,
82 required=False,
83 value=MEDIUM_WATER)
84 self._set_parameter(name="head_set",
85 unit=ureg.meter,
86 required=True,
87 attributes=['rated_height'],
88 check=check_numeric(min_value=0 * ureg.meter))
89 self._set_parameter(name="Vflow_set",
90 unit=ureg.meter ** 3 / ureg.hour,
91 required=True,
92 attributes=['rated_volume_flow'],
93 check=check_numeric(
94 min_value=0 * ureg.meter ** 3 / ureg.hour))
95 self._set_parameter(name="P_nom",
96 unit=ureg.watt,
97 required=True,
98 attributes=['rated_power'],
99 check=check_numeric(min_value=0 * ureg.watt))
101 def get_port_name(self, port):
102 if port.verbose_flow_direction == 'SINK':
103 return 'port_a'
104 if port.verbose_flow_direction == 'SOURCE':
105 return 'port_b'
106 else:
107 return super().get_port_name(port)
110class ThreeWayValve(HKESim):
111 path = "HKESim.Heating.Hydraulics.Valves.ThreeWayValveControlled"
112 represents = [hvac.ThreeWayValve]
114 def __init__(self, element):
115 super().__init__(element)
116 self._set_parameter(name='redeclare package Medium',
117 unit=None,
118 required=False,
119 value=MEDIUM_WATER)
121 def get_port_name(self, port):
122 try:
123 index = self.element.ports.index(port)
124 except ValueError:
125 # unknown port
126 index = -1
127 if index == 0:
128 return "port_a"
129 elif index == 1:
130 return "port_b"
131 elif index == 2:
132 return "port_c"
133 else:
134 return super().get_port_name(port)
137class ConsumerHeatingDistributorModule(HKESim):
138 path = "SystemModules.HeatingSystemModules.ConsumerHeatingDistributorModule"
139 represents = [hvac_aggregations.ConsumerHeatingDistributorModule]
141 def __init__(self, element):
142 super().__init__(element)
143 self._set_parameter(name='redeclare package Medium_heating',
144 unit=None,
145 required=False,
146 value= MEDIUM_WATER)
147 self._set_parameter(name='Tconsumer',
148 unit=ureg.kelvin,
149 required=False,
150 function=lambda flow_temperature,
151 return_temperature:
152 (flow_temperature[0], return_temperature[0]))
153 self._set_parameter(name='useHydraulicSeparator',
154 unit=None,
155 required=False,
156 attributes=['use_hydraulic_separator'])
157 self._set_parameter(name='V',
158 unit=ureg.meter ** 3,
159 required=False,
160 attributes=['hydraulic_separator_volume'])
161 for index, consumer in enumerate(self.element.consumers):
162 self._set_parameter(name=f"c{index + 1}Qflow_nom",
163 unit=ureg.watt,
164 required=False,
165 value=getattr(consumer, 'rated_power'))
166 self._set_parameter(name=f"Tconsumer{index + 1}",
167 unit=ureg.kelvin,
168 required=False,
169 value=(getattr(consumer, 'flow_temperature'),
170 getattr(consumer, 'return_temperature')))
171 self._set_parameter(name=f"c{index+1}OpenEnd",
172 unit=None,
173 required=False,
174 value=False)
175 self._set_parameter(name=f"c{index + 1}TControl",
176 unit=None,
177 required=False,
178 value=getattr(consumer, 't_control'))
179 if index > 0:
180 self._set_parameter(name=f"isConsumer{index + 1}",
181 unit=None,
182 required=False,
183 value=True)
185 def get_port_name(self, port):
186 try:
187 index = self.element.ports.index(port)
188 except ValueError:
189 # unknown port
190 index = -1
191 if port.verbose_flow_direction == 'SINK':
192 return "port_a_consumer"
193 elif port.verbose_flow_direction == 'SOURCE':
194 return "port_b_consumer"
195 elif (index % 2) == 0:
196 return "port_a_consumer{}".format(
197 len(self.element.consumers) + index - 1)
198 elif (index % 2) == 1:
199 return "port_b_consumer{}".format(
200 len(self.element.consumers) + index - 2)
201 else:
202 return super().get_port_name(port)
205class BoilerModule(HKESim):
206 path = "SystemModules.HeatingSystemModules.BoilerModule"
207 represents = [hvac_aggregations.GeneratorOneFluid]
209 def __init__(self, element):
210 super().__init__(element)
211 self._set_parameter(name='redeclare package Medium_heating',
212 unit=None,
213 required=False,
214 value=MEDIUM_WATER)
215 self._set_parameter(name='Qflow_nom',
216 unit=ureg.watt,
217 required=True,
218 check=check_numeric(min_value=0 * ureg.watt),
219 attributes=['rated_power'])
220 self._set_parameter(name='Theating',
221 unit=ureg.kelvin,
222 required=True,
223 function=lambda flow_temperature,
224 return_temperature:
225 (flow_temperature, return_temperature))
226 self._set_parameter(name='boilerPump',
227 unit=None,
228 required=False,
229 attributes=['has_pump'])
230 self._set_parameter(name='returnTempControl',
231 unit=None,
232 required=False,
233 attributes=['has_bypass'])
235 def get_port_name(self, port):
236 if port.verbose_flow_direction == 'SINK':
237 return 'port_a'
238 if port.verbose_flow_direction == 'SOURCE':
239 return 'port_b'
240 else:
241 return super().get_port_name(port)
244class HeatPump(HKESim):
245 path = 'HKESim.Heating.HeatPumps.HeatPump'
246 represents = [hvac.HeatPump]
248 def __init__(self, element):
249 super().__init__(element)
250 self._set_parameter(name='redeclare package Medium_con',
251 unit=None,
252 required=False,
253 value=MEDIUM_WATER)
254 self._set_parameter(name='redeclare package Medium_ev',
255 unit=None,
256 required=False,
257 value=MEDIUM_WATER)
258 self._set_parameter(name='Qcon_nom',
259 unit=ureg.watt,
260 required=True,
261 check=check_numeric(min_value=0 * ureg.watt),
262 attributes=['rated_power'])
264 def get_port_name(self, port):
265 # TODO: heat pump might have 4 ports (if source is modeled in BIM)
266 if port.verbose_flow_direction == 'SINK':
267 return 'port_a_con'
268 if port.verbose_flow_direction == 'SOURCE':
269 return 'port_b_con'
270 else:
271 return super().get_port_name(port)
274class Chiller(HKESim):
275 path = 'HKESim.Heating.Chillers.CompressionChiller'
276 represents = [hvac.Chiller]
278 def __init__(self, element):
279 super().__init__(element)
280 self._set_parameter(name='redeclare package Medium_con',
281 unit=None,
282 required=False,
283 value= MEDIUM_WATER)
284 self._set_parameter(name='redeclare package Medium_ev',
285 unit=None,
286 required=False,
287 value=MEDIUM_WATER)
288 self._set_parameter(name='EER_nom',
289 unit=ureg.dimensionless,
290 check=check_numeric(
291 min_value=0 * ureg.dimensionless),
292 required=True,
293 attributes=['nominal_COP'])
294 self._set_parameter(name='Qev_nom',
295 unit=ureg.watt,
296 required=True,
297 check=check_numeric(min_value=0 * ureg.watt),
298 attributes=['rated_power'])
300 def get_port_name(self, port):
301 # TODO: chiller might have 4 ports (if source is modeled in BIM)
302 if port.verbose_flow_direction == 'SINK':
303 return 'port_a_con'
304 if port.verbose_flow_direction == 'SOURCE':
305 return 'port_b_con'
306 else:
307 return super().get_port_name(port)
310class CHP(HKESim):
311 path = "HKESim.Heating.CHPs.CHP"
312 represents = [hvac.CHP]
314 def __init__(self, element):
315 super().__init__(element)
316 self._set_parameter(name='redeclare package Medium',
317 unit=None,
318 required=False,
319 value=MEDIUM_WATER)
320 self._set_parameter(name='P_nom',
321 unit=ureg.watt,
322 required=True,
323 check=check_numeric(min_value=0 * ureg.watt),
324 attributes=['rated_power'])
326 def get_port_name(self, port):
327 if port.verbose_flow_direction == 'SINK':
328 return 'port_a'
329 if port.verbose_flow_direction == 'SOURCE':
330 return 'port_b'
331 else:
332 return super().get_port_name(port)
335class CoolingTower(HKESim):
336 path = 'HKESim.Heating.CoolingTowers.CoolingTower'
337 represents = [hvac.CoolingTower]
339 def __init__(self, element):
340 super().__init__(element)
341 self._set_parameter(name='redeclare package Medium',
342 unit=None,
343 required=False,
344 value=MEDIUM_WATER)
345 self._set_parameter(name='Qflow_nom',
346 unit=ureg.watt,
347 required=True,
348 check=check_numeric(min_value=0 * ureg.watt),
349 attributes=['rated_power'])
351 def get_port_name(self, port):
352 if port.verbose_flow_direction == 'SINK':
353 return 'port_a'
354 if port.verbose_flow_direction == 'SOURCE':
355 return 'port_b'
356 else:
357 return super().get_port_name(port)