honeybee-energy 1.116.106__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. honeybee_energy/__init__.py +24 -0
  2. honeybee_energy/__main__.py +4 -0
  3. honeybee_energy/_extend_honeybee.py +145 -0
  4. honeybee_energy/altnumber.py +21 -0
  5. honeybee_energy/baseline/__init__.py +2 -0
  6. honeybee_energy/baseline/create.py +608 -0
  7. honeybee_energy/baseline/data/__init__.py +1 -0
  8. honeybee_energy/baseline/data/constructions.csv +64 -0
  9. honeybee_energy/baseline/data/fen_ratios.csv +15 -0
  10. honeybee_energy/baseline/data/lpd_building.csv +21 -0
  11. honeybee_energy/baseline/data/pci_2016.csv +22 -0
  12. honeybee_energy/baseline/data/pci_2019.csv +22 -0
  13. honeybee_energy/baseline/data/pci_2022.csv +22 -0
  14. honeybee_energy/baseline/data/shw.csv +21 -0
  15. honeybee_energy/baseline/pci.py +512 -0
  16. honeybee_energy/baseline/result.py +371 -0
  17. honeybee_energy/boundarycondition.py +128 -0
  18. honeybee_energy/cli/__init__.py +69 -0
  19. honeybee_energy/cli/baseline.py +475 -0
  20. honeybee_energy/cli/edit.py +327 -0
  21. honeybee_energy/cli/lib.py +1154 -0
  22. honeybee_energy/cli/result.py +810 -0
  23. honeybee_energy/cli/setconfig.py +124 -0
  24. honeybee_energy/cli/settings.py +569 -0
  25. honeybee_energy/cli/simulate.py +380 -0
  26. honeybee_energy/cli/translate.py +1714 -0
  27. honeybee_energy/cli/validate.py +224 -0
  28. honeybee_energy/config.json +11 -0
  29. honeybee_energy/config.py +842 -0
  30. honeybee_energy/construction/__init__.py +1 -0
  31. honeybee_energy/construction/_base.py +374 -0
  32. honeybee_energy/construction/air.py +325 -0
  33. honeybee_energy/construction/dictutil.py +89 -0
  34. honeybee_energy/construction/dynamic.py +607 -0
  35. honeybee_energy/construction/opaque.py +460 -0
  36. honeybee_energy/construction/shade.py +319 -0
  37. honeybee_energy/construction/window.py +1096 -0
  38. honeybee_energy/construction/windowshade.py +847 -0
  39. honeybee_energy/constructionset.py +1655 -0
  40. honeybee_energy/dictutil.py +56 -0
  41. honeybee_energy/generator/__init__.py +5 -0
  42. honeybee_energy/generator/loadcenter.py +204 -0
  43. honeybee_energy/generator/pv.py +535 -0
  44. honeybee_energy/hvac/__init__.py +21 -0
  45. honeybee_energy/hvac/_base.py +124 -0
  46. honeybee_energy/hvac/_template.py +270 -0
  47. honeybee_energy/hvac/allair/__init__.py +22 -0
  48. honeybee_energy/hvac/allair/_base.py +349 -0
  49. honeybee_energy/hvac/allair/furnace.py +168 -0
  50. honeybee_energy/hvac/allair/psz.py +131 -0
  51. honeybee_energy/hvac/allair/ptac.py +163 -0
  52. honeybee_energy/hvac/allair/pvav.py +109 -0
  53. honeybee_energy/hvac/allair/vav.py +128 -0
  54. honeybee_energy/hvac/detailed.py +337 -0
  55. honeybee_energy/hvac/doas/__init__.py +28 -0
  56. honeybee_energy/hvac/doas/_base.py +345 -0
  57. honeybee_energy/hvac/doas/fcu.py +127 -0
  58. honeybee_energy/hvac/doas/radiant.py +329 -0
  59. honeybee_energy/hvac/doas/vrf.py +81 -0
  60. honeybee_energy/hvac/doas/wshp.py +91 -0
  61. honeybee_energy/hvac/heatcool/__init__.py +23 -0
  62. honeybee_energy/hvac/heatcool/_base.py +177 -0
  63. honeybee_energy/hvac/heatcool/baseboard.py +61 -0
  64. honeybee_energy/hvac/heatcool/evapcool.py +72 -0
  65. honeybee_energy/hvac/heatcool/fcu.py +92 -0
  66. honeybee_energy/hvac/heatcool/gasunit.py +53 -0
  67. honeybee_energy/hvac/heatcool/radiant.py +269 -0
  68. honeybee_energy/hvac/heatcool/residential.py +77 -0
  69. honeybee_energy/hvac/heatcool/vrf.py +54 -0
  70. honeybee_energy/hvac/heatcool/windowac.py +70 -0
  71. honeybee_energy/hvac/heatcool/wshp.py +62 -0
  72. honeybee_energy/hvac/idealair.py +699 -0
  73. honeybee_energy/internalmass.py +310 -0
  74. honeybee_energy/lib/__init__.py +1 -0
  75. honeybee_energy/lib/_loadconstructions.py +194 -0
  76. honeybee_energy/lib/_loadconstructionsets.py +117 -0
  77. honeybee_energy/lib/_loadmaterials.py +83 -0
  78. honeybee_energy/lib/_loadprogramtypes.py +125 -0
  79. honeybee_energy/lib/_loadschedules.py +87 -0
  80. honeybee_energy/lib/_loadtypelimits.py +64 -0
  81. honeybee_energy/lib/constructions.py +207 -0
  82. honeybee_energy/lib/constructionsets.py +95 -0
  83. honeybee_energy/lib/materials.py +67 -0
  84. honeybee_energy/lib/programtypes.py +125 -0
  85. honeybee_energy/lib/schedules.py +61 -0
  86. honeybee_energy/lib/scheduletypelimits.py +31 -0
  87. honeybee_energy/load/__init__.py +1 -0
  88. honeybee_energy/load/_base.py +190 -0
  89. honeybee_energy/load/daylight.py +397 -0
  90. honeybee_energy/load/dictutil.py +47 -0
  91. honeybee_energy/load/equipment.py +771 -0
  92. honeybee_energy/load/hotwater.py +543 -0
  93. honeybee_energy/load/infiltration.py +460 -0
  94. honeybee_energy/load/lighting.py +480 -0
  95. honeybee_energy/load/people.py +497 -0
  96. honeybee_energy/load/process.py +472 -0
  97. honeybee_energy/load/setpoint.py +816 -0
  98. honeybee_energy/load/ventilation.py +550 -0
  99. honeybee_energy/material/__init__.py +1 -0
  100. honeybee_energy/material/_base.py +166 -0
  101. honeybee_energy/material/dictutil.py +59 -0
  102. honeybee_energy/material/frame.py +367 -0
  103. honeybee_energy/material/gas.py +1087 -0
  104. honeybee_energy/material/glazing.py +854 -0
  105. honeybee_energy/material/opaque.py +1351 -0
  106. honeybee_energy/material/shade.py +1360 -0
  107. honeybee_energy/measure.py +472 -0
  108. honeybee_energy/programtype.py +723 -0
  109. honeybee_energy/properties/__init__.py +1 -0
  110. honeybee_energy/properties/aperture.py +333 -0
  111. honeybee_energy/properties/door.py +342 -0
  112. honeybee_energy/properties/extension.py +244 -0
  113. honeybee_energy/properties/face.py +274 -0
  114. honeybee_energy/properties/model.py +2640 -0
  115. honeybee_energy/properties/room.py +1747 -0
  116. honeybee_energy/properties/shade.py +314 -0
  117. honeybee_energy/properties/shademesh.py +262 -0
  118. honeybee_energy/reader.py +48 -0
  119. honeybee_energy/result/__init__.py +1 -0
  120. honeybee_energy/result/colorobj.py +648 -0
  121. honeybee_energy/result/emissions.py +290 -0
  122. honeybee_energy/result/err.py +101 -0
  123. honeybee_energy/result/eui.py +100 -0
  124. honeybee_energy/result/generation.py +160 -0
  125. honeybee_energy/result/loadbalance.py +890 -0
  126. honeybee_energy/result/match.py +202 -0
  127. honeybee_energy/result/osw.py +90 -0
  128. honeybee_energy/result/rdd.py +59 -0
  129. honeybee_energy/result/zsz.py +190 -0
  130. honeybee_energy/run.py +1577 -0
  131. honeybee_energy/schedule/__init__.py +1 -0
  132. honeybee_energy/schedule/day.py +626 -0
  133. honeybee_energy/schedule/dictutil.py +59 -0
  134. honeybee_energy/schedule/fixedinterval.py +1012 -0
  135. honeybee_energy/schedule/rule.py +619 -0
  136. honeybee_energy/schedule/ruleset.py +1867 -0
  137. honeybee_energy/schedule/typelimit.py +310 -0
  138. honeybee_energy/shw.py +315 -0
  139. honeybee_energy/simulation/__init__.py +1 -0
  140. honeybee_energy/simulation/control.py +214 -0
  141. honeybee_energy/simulation/daylightsaving.py +185 -0
  142. honeybee_energy/simulation/dictutil.py +51 -0
  143. honeybee_energy/simulation/output.py +646 -0
  144. honeybee_energy/simulation/parameter.py +606 -0
  145. honeybee_energy/simulation/runperiod.py +443 -0
  146. honeybee_energy/simulation/shadowcalculation.py +295 -0
  147. honeybee_energy/simulation/sizing.py +546 -0
  148. honeybee_energy/ventcool/__init__.py +5 -0
  149. honeybee_energy/ventcool/_crack_data.py +91 -0
  150. honeybee_energy/ventcool/afn.py +289 -0
  151. honeybee_energy/ventcool/control.py +269 -0
  152. honeybee_energy/ventcool/crack.py +126 -0
  153. honeybee_energy/ventcool/fan.py +493 -0
  154. honeybee_energy/ventcool/opening.py +365 -0
  155. honeybee_energy/ventcool/simulation.py +314 -0
  156. honeybee_energy/writer.py +1078 -0
  157. honeybee_energy-1.116.106.dist-info/METADATA +113 -0
  158. honeybee_energy-1.116.106.dist-info/RECORD +162 -0
  159. honeybee_energy-1.116.106.dist-info/WHEEL +5 -0
  160. honeybee_energy-1.116.106.dist-info/entry_points.txt +2 -0
  161. honeybee_energy-1.116.106.dist-info/licenses/LICENSE +661 -0
  162. honeybee_energy-1.116.106.dist-info/top_level.txt +1 -0
@@ -0,0 +1,128 @@
1
+ # coding=utf-8
2
+ """Variable Air Volume (VAV) HVAC system."""
3
+ from __future__ import division
4
+
5
+ from ._base import _AllAirBase
6
+
7
+ from honeybee._lockable import lockable
8
+
9
+
10
+ @lockable
11
+ class VAV(_AllAirBase):
12
+ """Variable Air Volume (VAV) HVAC system (aka. System 7 or 8).
13
+
14
+ All rooms/zones are connected to a central air loop that is kept at a constant
15
+ central temperature of 12.8C (55F). The central temperature is maintained by a
16
+ cooling coil, which runs whenever the combination of return air and fresh outdoor
17
+ air is greater than 12.8C, as well as a heating coil, which runs whenever
18
+ the combination of return air and fresh outdoor air is less than 12.8C.
19
+
20
+ Each air terminal for the connected rooms/zones contains its own reheat coil,
21
+ which runs whenever the room is not in need of the cooling supplied by the 12.8C
22
+ central air.
23
+
24
+ The central cooling coil is always a chilled water coil, which is connected to a
25
+ chilled water loop operating at 6.7C (44F). All heating coils are hot water coils
26
+ except when Gas Coil equipment_type is used (in which case coils are gas)
27
+ or when Parallel Fan-Powered (PFP) boxes equipment_type is used (in which case
28
+ coils are electric resistance). Hot water temperature is 82C (180F) for
29
+ boiler/district heating and 49C (120F) when ASHP is used.
30
+
31
+ VAV systems are the traditional baseline system for commercial buildings
32
+ taller than 5 stories or larger than 14,000 m2 (150,000 ft2) of floor area.
33
+
34
+ Args:
35
+ identifier: Text string for system identifier. Must be < 100 characters
36
+ and not contain any EnergyPlus special characters. This will be used to
37
+ identify the object across a model and in the exported IDF.
38
+ vintage: Text for the vintage of the template system. This will be used
39
+ to set efficiencies for various pieces of equipment within the system.
40
+ Choose from the following.
41
+
42
+ * DOE_Ref_Pre_1980
43
+ * DOE_Ref_1980_2004
44
+ * ASHRAE_2004
45
+ * ASHRAE_2007
46
+ * ASHRAE_2010
47
+ * ASHRAE_2013
48
+ * ASHRAE_2016
49
+ * ASHRAE_2019
50
+
51
+ equipment_type: Text for the specific type of the system and equipment. (Default:
52
+ the first option below) Choose from.
53
+
54
+ * VAV_Chiller_Boiler
55
+ * VAV_Chiller_ASHP
56
+ * VAV_Chiller_DHW
57
+ * VAV_Chiller_PFP
58
+ * VAV_Chiller_GasCoil
59
+ * VAV_ACChiller_Boiler
60
+ * VAV_ACChiller_ASHP
61
+ * VAV_ACChiller_DHW
62
+ * VAV_ACChiller_PFP
63
+ * VAV_ACChiller_GasCoil
64
+ * VAV_DCW_Boiler
65
+ * VAV_DCW_ASHP
66
+ * VAV_DCW_DHW
67
+ * VAV_DCW_PFP
68
+ * VAV_DCW_GasCoil
69
+
70
+ economizer_type: Text to indicate the type of air-side economizer used on
71
+ the system. (Default: NoEconomizer). Choose from the following.
72
+
73
+ * NoEconomizer
74
+ * DifferentialDryBulb
75
+ * DifferentialEnthalpy
76
+ * DifferentialDryBulbAndEnthalpy
77
+ * FixedDryBulb
78
+ * FixedEnthalpy
79
+ * ElectronicEnthalpy
80
+
81
+ sensible_heat_recovery: A number between 0 and 1 for the effectiveness
82
+ of sensible heat recovery within the system. (Default: 0).
83
+ latent_heat_recovery: A number between 0 and 1 for the effectiveness
84
+ of latent heat recovery within the system. (Default: 0).
85
+ demand_controlled_ventilation: Boolean to note whether demand controlled
86
+ ventilation should be used on the system, which will vary the amount
87
+ of ventilation air according to the occupancy schedule of the
88
+ Rooms. (Default: False).
89
+
90
+ Properties:
91
+ * identifier
92
+ * display_name
93
+ * vintage
94
+ * equipment_type
95
+ * economizer_type
96
+ * sensible_heat_recovery
97
+ * latent_heat_recovery
98
+ * demand_controlled_ventilation
99
+ * schedules
100
+ * has_district_heating
101
+ * has_district_cooling
102
+ * user_data
103
+ * properties
104
+
105
+ Note:
106
+ [1] American Society of Heating, Refrigerating and Air-Conditioning Engineers,
107
+ Inc. (2007). Ashrae standard 90.1. Atlanta, GA. https://www.ashrae.org/\
108
+ technical-resources/standards-and-guidelines/read-only-versions-of-ashrae-standards
109
+ """
110
+ __slots__ = ()
111
+
112
+ EQUIPMENT_TYPES = (
113
+ 'VAV_Chiller_Boiler',
114
+ 'VAV_Chiller_ASHP',
115
+ 'VAV_Chiller_DHW',
116
+ 'VAV_Chiller_PFP',
117
+ 'VAV_Chiller_GasCoil',
118
+ 'VAV_ACChiller_Boiler',
119
+ 'VAV_ACChiller_ASHP',
120
+ 'VAV_ACChiller_DHW',
121
+ 'VAV_ACChiller_PFP',
122
+ 'VAV_ACChiller_GasCoil',
123
+ 'VAV_DCW_Boiler',
124
+ 'VAV_DCW_ASHP',
125
+ 'VAV_DCW_DHW',
126
+ 'VAV_DCW_PFP',
127
+ 'VAV_DCW_GasCoil'
128
+ )
@@ -0,0 +1,337 @@
1
+ # coding=utf-8
2
+ """Detailed HVAC system object defined using IronBug or OpenStudio .NET bindings."""
3
+ from __future__ import division
4
+
5
+ from honeybee._lockable import lockable
6
+
7
+ from ._base import _HVACSystem
8
+ from .idealair import IdealAirSystem
9
+
10
+
11
+ @lockable
12
+ class DetailedHVAC(_HVACSystem):
13
+ """Detailed HVAC system object defined using IronBug or OpenStudio .NET bindings.
14
+
15
+ Args:
16
+ identifier: Text string for detailed system identifier. Must be < 100 characters
17
+ and not contain any EnergyPlus special characters.
18
+ specification: A JSON-serializable dictionary representing the full
19
+ specification of the detailed system. This can be obtained by calling
20
+ the ToJson() method on any IronBug HVAC system and then serializing
21
+ the resulting JSON string into a Python dictionary using the native
22
+ Python json package. Note that the Rooms that the HVAC is assigned to
23
+ must be specified as ThermalZones under this specification in order
24
+ for the resulting Model this HVAC is a part of to be valid.
25
+
26
+ Properties:
27
+ * identifier
28
+ * specification
29
+ * thermal_zones
30
+ * design_type
31
+ * air_loop_count
32
+ * economizer_type
33
+ * sensible_heat_recovery
34
+ * latent_heat_recovery
35
+ * display_name
36
+ * user_data
37
+ """
38
+ NO_AIR_LOOP = 'Ironbug.HVAC.IB_NoAirLoop'
39
+ AIR_LOOP = 'Ironbug.HVAC.IB_AirLoopHVAC'
40
+ BRANCHES = 'Ironbug.HVAC.IB_AirLoopBranches'
41
+ OA_SYSTEM = 'Ironbug.HVAC.IB_OutdoorAirSystem'
42
+ OA_CONTROLLER = 'Ironbug.HVAC.IB_ControllerOutdoorAir'
43
+ HEAT_RECOVERY = 'Ironbug.HVAC.IB_HeatExchangerAirToAirSensibleAndLatent'
44
+ HR_SENSIBLE = (
45
+ 'SensibleEffectivenessat75CoolingAirFlow',
46
+ 'SensibleEffectivenessat75HeatingAirFlow'
47
+ )
48
+ HR_LATENT = (
49
+ 'LatentEffectivenessat75CoolingAirFlow',
50
+ 'LatentEffectivenessat75HeatingAirFlow'
51
+ )
52
+ ECONOMIZER_TYPES = ('NoEconomizer', 'DifferentialDryBulb', 'DifferentialEnthalpy',
53
+ 'DifferentialDryBulbAndEnthalpy', 'FixedDryBulb',
54
+ 'FixedEnthalpy', 'ElectronicEnthalpy')
55
+
56
+ __slots__ = ('_specification', '_thermal_zones', '_design_type', '_air_loop_count',
57
+ '_economizer_type', '_sensible_heat_recovery', '_latent_heat_recovery')
58
+
59
+ def __init__(self, identifier, specification):
60
+ """Initialize DetailedHVAC."""
61
+ # initialize base HVAC system properties
62
+ _HVACSystem.__init__(self, identifier)
63
+ self.specification = specification
64
+
65
+ @property
66
+ def specification(self):
67
+ """Get or set a dictionary for the full specification of this HVAC.
68
+
69
+ This can be obtained by calling the SaveAsJson() method on any IronBug HVAC
70
+ system and then serializing the resulting JSON string into a Python dictionary
71
+ using the native Python json package.
72
+ """
73
+ return self._specification
74
+
75
+ @specification.setter
76
+ def specification(self, value):
77
+ assert isinstance(value, dict), 'Expected dictionary for DetailedHVAC' \
78
+ 'object specification. Got {}.'.format(type(value))
79
+ thermal_zones, design_type, air_loop_count = [], 'HeatCool', 0
80
+ econ_type, sensible_hr, latent_hr = 'NoEconomizer', 0, 0
81
+ try:
82
+ for a_loop in value['AirLoops']:
83
+ if a_loop['$type'].startswith(self.NO_AIR_LOOP):
84
+ # get all of the zones on the demand side
85
+ for zone in a_loop['ThermalZones']:
86
+ for z_attr in zone['CustomAttributes']:
87
+ if z_attr['Field']['FullName'] == 'Name':
88
+ thermal_zones.append(z_attr['Value'])
89
+ elif a_loop['$type'].startswith(self.AIR_LOOP):
90
+ # determine whether it's an AllAir system or DOAS system
91
+ air_loop_count += 1
92
+ design_type = 'AllAir'
93
+ if 'SizingSystem' in a_loop and \
94
+ 'CustomAttributes' in a_loop['SizingSystem']:
95
+ for sz_attr in a_loop['SizingSystem']['CustomAttributes']:
96
+ if sz_attr['Field']['FullName'] == 'TypeofLoadtoSizeOn':
97
+ if sz_attr['Value'] == 'VentilationRequirement':
98
+ design_type = 'DOAS'
99
+ # determine the type of economizer or heat recovery
100
+ for comp in a_loop['SupplyComponents']:
101
+ if comp['$type'].startswith(self.OA_SYSTEM):
102
+ for child in comp['Children']:
103
+ if child['$type'].startswith(self.OA_CONTROLLER):
104
+ if 'CustomAttributes' in child:
105
+ for attr in child['CustomAttributes']:
106
+ f_name = attr['Field']['FullName']
107
+ if f_name == 'EconomizerControlType':
108
+ econ_type = self._f_econ(attr['Value'])
109
+ if 'IBProperties' in comp and \
110
+ 'OAStreamObjs' in comp['IBProperties']:
111
+ for oa_comp in comp['IBProperties']['OAStreamObjs']:
112
+ if oa_comp['$type'].startswith(self.HEAT_RECOVERY):
113
+ if 'CustomAttributes' in oa_comp:
114
+ for oa_attr in oa_comp['CustomAttributes']:
115
+ f_name = oa_attr['Field']['FullName']
116
+ if f_name in self.HR_SENSIBLE:
117
+ sensible_hr = oa_attr['Value']
118
+ if f_name in self.HR_LATENT:
119
+ latent_hr = oa_attr['Value']
120
+ # get all of the zones on the demand side
121
+ for comp in a_loop['DemandComponents']:
122
+ if comp['$type'].startswith(self.BRANCHES):
123
+ for branch in comp['Branches']:
124
+ for z_attr in branch[0]['CustomAttributes']:
125
+ if z_attr['Field']['FullName'] == 'Name':
126
+ thermal_zones.append(z_attr['Value'])
127
+ else:
128
+ raise ValueError('DetailedHVAC specification does not contain '
129
+ 'any ThermalZones that can be matched to Rooms.')
130
+ except KeyError as e:
131
+ raise ValueError('DetailedHVAC specification is not valid:\n{}'.format(e))
132
+ self._thermal_zones = tuple(thermal_zones)
133
+ self._design_type = design_type
134
+ self._air_loop_count = air_loop_count
135
+ self._economizer_type = econ_type
136
+ self._sensible_heat_recovery = sensible_hr
137
+ self._latent_heat_recovery = latent_hr
138
+ self._specification = value
139
+
140
+ @property
141
+ def thermal_zones(self):
142
+ """Get a tuple of strings for the Rooms/Zones to which the HVAC is assigned."""
143
+ return self._thermal_zones
144
+
145
+ @property
146
+ def design_type(self):
147
+ """Text for the structure of the system. It will be one of the following.
148
+
149
+ * AllAir
150
+ * DOAS
151
+ * HeatCool
152
+ """
153
+ return self._design_type
154
+
155
+ @property
156
+ def air_loop_count(self):
157
+ """Get an integer for the number of air loops in the system."""
158
+ return self._air_loop_count
159
+
160
+ @property
161
+ def economizer_type(self):
162
+ """Get text to indicate the type of air-side economizer.
163
+
164
+ Choose from the following options.
165
+
166
+ * NoEconomizer
167
+ * DifferentialDryBulb
168
+ * DifferentialEnthalpy
169
+ * DifferentialDryBulbAndEnthalpy
170
+ * FixedDryBulb
171
+ * FixedEnthalpy
172
+ * ElectronicEnthalpy
173
+ """
174
+ return self._economizer_type
175
+
176
+ @property
177
+ def sensible_heat_recovery(self):
178
+ """Get a number for the effectiveness of sensible heat recovery."""
179
+ return self._sensible_heat_recovery
180
+
181
+ @property
182
+ def latent_heat_recovery(self):
183
+ """Get a number for the effectiveness of latent heat recovery."""
184
+ return self._latent_heat_recovery
185
+
186
+ def sync_room_ids(self, room_map):
187
+ """Sync this DetailedHVAC with Rooms that had their IDs changed.
188
+
189
+ This is useful after running the Model.reset_ids() command to ensure that
190
+ the bi-directional Room references between DetailedHVAC and Honeybee Rooms
191
+ is correct.
192
+
193
+ Args:
194
+ room_map: A dictionary that relates the original Rooms identifiers (keys)
195
+ to the new identifiers (values) of the Rooms in the Model.
196
+ """
197
+ thermal_zones, air_loop_count = [], 0
198
+ hvac_spec = self._specification
199
+ for a_loop in hvac_spec['AirLoops']:
200
+ if a_loop['$type'].startswith(self.NO_AIR_LOOP):
201
+ for zone in a_loop['ThermalZones']:
202
+ for z_attr in zone['CustomAttributes']:
203
+ if z_attr['Field']['FullName'] == 'Name':
204
+ z_attr['Value'] = room_map[z_attr['Value']]
205
+ thermal_zones.append(z_attr['Value'])
206
+ elif a_loop['$type'].startswith(self.AIR_LOOP):
207
+ air_loop_count += 1
208
+ for comp in a_loop['DemandComponents']:
209
+ if comp['$type'].startswith(self.BRANCHES):
210
+ for branch in comp['Branches']:
211
+ for z_attr in branch[0]['CustomAttributes']:
212
+ if z_attr['Field']['FullName'] == 'Name':
213
+ z_attr['Value'] = room_map[z_attr['Value']]
214
+ thermal_zones.append(z_attr['Value'])
215
+ # unlock object and set attributes
216
+ was_locked = False
217
+ if self._locked:
218
+ was_locked = True
219
+ self.unlock()
220
+ self._air_loop_count = air_loop_count
221
+ self._thermal_zones = tuple(thermal_zones)
222
+ self._specification = hvac_spec
223
+ if was_locked: # set the object back to being locked
224
+ self.lock()
225
+
226
+ def to_ideal_air_equivalent(self):
227
+ """This method is NOT YET IMPLEMENTED."""
228
+ econ_typ = self.economizer_type
229
+ if econ_typ not in self.ECONOMIZER_TYPES[:3]:
230
+ enth_types = ('FixedEnthalpy', 'ElectronicEnthalpy')
231
+ econ_typ = 'DifferentialEnthalpy' if econ_typ in enth_types \
232
+ else 'DifferentialDryBulb'
233
+ i_sys = IdealAirSystem(
234
+ self.identifier, economizer_type=econ_typ,
235
+ sensible_heat_recovery=self.sensible_heat_recovery,
236
+ latent_heat_recovery=self.latent_heat_recovery)
237
+ i_sys._display_name = self._display_name
238
+ return i_sys
239
+
240
+ @classmethod
241
+ def from_dict(cls, data):
242
+ """Create a HVAC object from a dictionary.
243
+
244
+ Args:
245
+ data: A HVAC dictionary in following the format below.
246
+
247
+ .. code-block:: python
248
+
249
+ {
250
+ "type": "DetailedHVAC",
251
+ "identifier": "Classroom1_System", # identifier for the HVAC
252
+ "display_name": "Custom VAV System", # name for the HVAC
253
+ "specification": {} # dictionary for the full HVAC specification
254
+ }
255
+ """
256
+ assert data['type'] == 'DetailedHVAC', \
257
+ 'Expected {} dictionary. Got {}.'.format('DetailedHVAC', data['type'])
258
+ new_obj = cls(data['identifier'], data['specification'])
259
+ if 'display_name' in data and data['display_name'] is not None:
260
+ new_obj.display_name = data['display_name']
261
+ if 'user_data' in data and data['user_data'] is not None:
262
+ new_obj.user_data = data['user_data']
263
+ return new_obj
264
+
265
+ @classmethod
266
+ def from_dict_abridged(cls, data, schedule_dict):
267
+ """Create a HVAC object from an abridged dictionary.
268
+
269
+ Args:
270
+ data: An abridged dictionary in following the format below.
271
+ schedule_dict: A dictionary with schedule identifiers as keys and honeybee
272
+ schedule objects as values.
273
+
274
+ .. code-block:: python
275
+
276
+ {
277
+ "type": "DetailedHVAC",
278
+ "identifier": "Classroom1_System", # identifier for the HVAC
279
+ "display_name": "Custom VAV System", # name for the HVAC
280
+ "specification": {} # dictionary for the full HVAC specification
281
+ }
282
+ """
283
+ # this is the same as the from_dict method for as long as there are not schedules
284
+ return cls.from_dict(data)
285
+
286
+ def to_dict(self, abridged=False):
287
+ """DetailedHVAC dictionary representation.
288
+
289
+ Args:
290
+ abridged: Boolean to note whether the full dictionary describing the
291
+ object should be returned (False) or just an abridged version (True).
292
+ This input currently has no effect but may eventually have one if
293
+ schedule-type properties are exposed on this object.
294
+ """
295
+ base = {'type': 'DetailedHVAC'}
296
+ base['identifier'] = self.identifier
297
+ base['specification'] = self.specification
298
+ if self._display_name is not None:
299
+ base['display_name'] = self.display_name
300
+ if self._user_data is not None:
301
+ base['user_data'] = self.user_data
302
+ return base
303
+
304
+ def _f_econ(self, value):
305
+ clean_input = value.lower()
306
+ for key in self.ECONOMIZER_TYPES:
307
+ if key.lower() == clean_input:
308
+ value = key
309
+ break
310
+ else:
311
+ raise ValueError(
312
+ 'economizer_type {} is not recognized.\nChoose from the '
313
+ 'following:\n{}'.format(value, self.ECONOMIZER_TYPES))
314
+ return value
315
+
316
+ def __copy__(self):
317
+ new_obj = self.__class__(self.identifier, self.specification.copy())
318
+ new_obj._display_name = self._display_name
319
+ new_obj._user_data = None if self._user_data is None else self._user_data.copy()
320
+ return new_obj
321
+
322
+ def __key(self):
323
+ """A tuple based on the object properties, useful for hashing."""
324
+ return (self._identifier, self._air_loop_count) + self._thermal_zones
325
+
326
+ def __hash__(self):
327
+ return hash(self.__key())
328
+
329
+ def __eq__(self, other):
330
+ return isinstance(other, self.__class__) and self.__key() == other.__key()
331
+
332
+ def __ne__(self, other):
333
+ return not self.__eq__(other)
334
+
335
+ def __repr__(self):
336
+ return 'DetailedHVAC: {} [air loops: {}] [zones: {}]'.format(
337
+ self.display_name, self.air_loop_count, len(self.thermal_zones))
@@ -0,0 +1,28 @@
1
+ """Template Dedicated Outdoor Air System (DOAS) HVAC definitions.
2
+
3
+ DOAS systems separate minimum ventilation supply from the satisfaction of heating
4
+ + cooling demand. Ventilation air tends to be supplied at neutral temperatures
5
+ (close to room air temperature) and heating / cooling loads are met with additional
6
+ pieces of zone equipment (eg. Fan Coil Units (FCUs)).
7
+
8
+ Because DOAS systems only have to cool down and re-heat the minimum ventilation air,
9
+ they tend to use less energy than all-air systems. They also tend to use less energy
10
+ to distribute heating + cooling by pumping around hot/cold water or refrigerant
11
+ instead of blowing hot/cold air. However, they do not provide as good of control
12
+ over humidity and so they may not be appropriate for rooms with high latent loads
13
+ like auditoriums, kitchens, laundromats, etc.
14
+
15
+ Properties:
16
+ * HVAC_TYPES_DICT: A dictionary containing pointers to the classes of each
17
+ HVAC system. The keys of this dictionary are the names of the HVAC
18
+ classes (eg. 'FCU').
19
+ * EQUIPMENT_TYPES_DICT: A dictionary containing pointers to the classes of
20
+ the HVAC systems. The keys of this dictionary are the names of the HVAC
21
+ systems as they appear in the OpenStudio standards gem and include the
22
+ specific equipment in the system (eg. 'DOAS with fan coil chiller with boiler').
23
+ """
24
+ from ._base import _DOASEnumeration
25
+
26
+ _doas_types = _DOASEnumeration(import_modules=True)
27
+ HVAC_TYPES_DICT = _doas_types.types_dict
28
+ EQUIPMENT_TYPES_DICT = _doas_types.equipment_types_dict