Coverage for bim2sim/tasks/hvac/export.py: 75%

48 statements  

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

1from datetime import datetime 

2 

3from bim2sim.elements import hvac_elements as hvac 

4from bim2sim.elements.base_elements import ProductBased 

5from bim2sim.elements.graphs.hvac_graph import HvacGraph 

6from bim2sim.export import modelica 

7from bim2sim.export.modelica import ModelicaParameter 

8from bim2sim.tasks.base import ITask 

9 

10 

11class Export(ITask): 

12 """Export to Dymola/Modelica""" 

13 

14 reads = ('libraries', 'graph') 

15 touches = ('modelica_model',) 

16 final = True 

17 

18 def run(self, libraries: tuple, graph: HvacGraph): 

19 """Export HVAC graph to Modelica code. 

20 

21 This method performs the following steps: 

22 1. Initializes the Modelica instance factory with the specified 

23 libraries. 

24 2. Creates Modelica instances for each HVAC element in the graph. 

25 3. Collects and exports parameters for each Modelica instance. 

26 4. Creates connections between Modelica instances based on the HVAC 

27 graph. 

28 5. Creates a Modelica model with the exported elements and connections. 

29 6. Saves the Modelica model to the specified export path. 

30 

31 Args: 

32 libraries: Tuple of libraries to be used in Modelica. 

33 graph: The HVAC graph to be exported. 

34 """ 

35 

36 self.logger.info("Export to Modelica code") 

37 elements = graph.elements 

38 

39 connections = graph.get_connections() 

40 

41 modelica.ModelicaElement.init_factory(libraries) 

42 export_elements = {inst: modelica.ModelicaElement.factory(inst) 

43 for inst in elements} 

44 

45 # Perform decisions for requested but not existing attributes 

46 yield from ProductBased.get_pending_attribute_decisions(elements) 

47 yield from ModelicaParameter.get_pending_parameter_decisions() 

48 

49 # All parameters are checked against the specified check function and 

50 # exported with the correct unit 

51 for instance in export_elements.values(): 

52 instance.collect_params() 

53 

54 connection_port_names = self.create_connections(graph, export_elements) 

55 

56 self.logger.info( 

57 "Creating Modelica model with %d model elements " 

58 "and %d connections.", 

59 len(export_elements), len(connection_port_names)) 

60 

61 modelica_model = modelica.ModelicaModel( 

62 name="bim2sim_"+self.prj_name, 

63 comment=f"Autogenerated by BIM2SIM on " 

64 f"{datetime.now():%Y-%m-%d %H:%M:%S%z}", 

65 modelica_elements=list(export_elements.values()), 

66 connections=connection_port_names, 

67 ) 

68 modelica_model.save(self.paths.export) 

69 return modelica_model, 

70 

71 @staticmethod 

72 def create_connections(graph: HvacGraph, export_elements: dict) -> list: 

73 """Creates a list of connections for the corresponding Modelica model. 

74 

75 This method iterates over the edges of the HVAC graph and creates a 

76 list of connections for the corresponding Modelica model. 

77 It considers distributors and adjusts port names accordingly. 

78 

79 Args: 

80 graph: the HVAC graph 

81 export_elements: the Modelica elements 

82 

83 Returns: 

84 connection_port_names: list of tuple of port names that are 

85 connected. 

86 """ 

87 connection_port_names = [] 

88 distributors_n = {} 

89 distributors_ports = {} 

90 for port_a, port_b in graph.edges: 

91 if port_a.parent is port_b.parent: 

92 # ignore inner connections 

93 continue 

94 elements = {'a': export_elements[port_a.parent], 

95 'b': export_elements[port_b.parent]} 

96 ports_name = {'a': elements['a'].get_full_port_name(port_a), 

97 'b': elements['b'].get_full_port_name(port_b)} 

98 if any(isinstance(e.element, hvac.Distributor) 

99 for e in elements.values()): 

100 for key, inst in elements.items(): 

101 if type(inst.element) is hvac.Distributor: 

102 distributor = (key, inst) 

103 distributor_port = ports_name[key] 

104 else: 

105 other_inst = inst 

106 other_port = ports_name[key] 

107 

108 ports_name[distributor[0]] = distributor[1].get_new_port_name( 

109 distributor[1], other_inst, distributor_port, other_port, 

110 distributors_n, distributors_ports) 

111 

112 connection_port_names.append((ports_name['a'], ports_name['b'])) 

113 

114 for distributor in distributors_n: 

115 distributor.export_parameters['n'] = int(distributors_n[distributor] / 2 - 1) 

116 

117 return connection_port_names