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,608 @@
1
+ """Module for creating baseline buildings conforming to standards."""
2
+ import os
3
+
4
+ from ladybug.futil import csv_to_matrix
5
+ from honeybee.boundarycondition import Outdoors
6
+ from honeybee.facetype import Wall, RoofCeiling
7
+
8
+ from ..material.glazing import EnergyWindowMaterialSimpleGlazSys
9
+ from ..construction.window import WindowConstruction
10
+ from ..lib.constructionsets import construction_set_by_identifier
11
+ from ..lib.programtypes import program_type_by_identifier
12
+ from ..hvac._template import _TemplateSystem
13
+ from ..hvac.heatcool._base import _HeatCoolBase
14
+ from ..hvac.allair.vav import VAV
15
+ from ..hvac.allair.pvav import PVAV
16
+ from ..hvac.allair.psz import PSZ
17
+ from ..hvac.allair.ptac import PTAC
18
+ from ..hvac.allair.furnace import ForcedAirFurnace
19
+ from ..hvac.doas.fcu import FCUwithDOAS
20
+ from ..shw import SHWSystem
21
+
22
+
23
+ def model_to_baseline(model, climate_zone, building_type='NonResidential',
24
+ floor_area=None, story_count=None, lighting_by_building=False):
25
+ """Convert a Model to be conformant with ASHRAE 90.1 appendix G.
26
+
27
+ This includes running all other functions contained within this group to adjust
28
+ the geometry, constructions, lighting, HVAC, SHW, and remove any clearly-defined
29
+ energy conservation measures like daylight controls. Note that all schedules
30
+ are essentially unchanged, meaning that additional post-processing of setpoints
31
+ may be necessary to account for energy conservation strategies like expanded
32
+ comfort ranges, ceiling fans, and personal thermal comfort devices. It may
33
+ also be necessary to adjust electric equipment loads in cases where such
34
+ equipment qualifies as an energy conservation strategy or hot water loads in
35
+ cases where low-flow fixtures are implemented.
36
+
37
+ Note that not all versions of ASHRAE 90.1 use this exact definition of a
38
+ baseline model but version 2016 and onward conform to it. It is essentially
39
+ an adjusted version of the 90.1-2004 methods.
40
+
41
+ Args:
42
+ model: A Honeybee Model that will be converted to conform to the ASHRAE 90.1
43
+ appendix G baseline.
44
+ climate_zone: Text indicating the ASHRAE climate zone. This can be a single
45
+ integer (in which case it is interpreted as A) or it can include the
46
+ A, B, or C qualifier (eg. 3C).
47
+ building_type: Text for the building type that the Model represents. This is
48
+ used to determine the baseline window-to-wall ratio and HVAC system. If
49
+ the type is not recognized or is "Unknown", it will be assumed that the
50
+ building is a generic NonResidential. The following have specified
51
+ meaning per the standard.
52
+
53
+ * NonResidential
54
+ * Residential
55
+ * MidriseApartment
56
+ * HighriseApartment
57
+ * LargeOffice
58
+ * MediumOffice
59
+ * SmallOffice
60
+ * Retail
61
+ * StripMall
62
+ * PrimarySchool
63
+ * SecondarySchool
64
+ * SmallHotel
65
+ * LargeHotel
66
+ * Hospital
67
+ * Outpatient
68
+ * Warehouse
69
+ * SuperMarket
70
+ * FullServiceRestaurant
71
+ * QuickServiceRestaurant
72
+ * Laboratory
73
+ * Courthouse
74
+
75
+ floor_area: A number for the floor area of the building that the model is a part
76
+ of in m2. If None, the model floor area will be used. (Default: None).
77
+ story_count: An integer for the number of stories of the building that the
78
+ model is a part of. If None, the model stories will be used. (Default: None).
79
+ lighting_by_building: A boolean to note whether the building_type should
80
+ be used to assign the baseline lighting power density (True), which will
81
+ use the same value for all Rooms in the model, or a space-by-space method
82
+ should be used (False). To use the space-by-space method, the model should
83
+ either be built with the programs that ship with Ladybug Tools in
84
+ honeybee-energy-standards or the baseline_watts_per_area should be correctly
85
+ assigned for all Rooms. (Default: False).
86
+ """
87
+ model_geometry_to_baseline(model, building_type)
88
+ model_constructions_to_baseline(model, climate_zone)
89
+ if lighting_by_building:
90
+ model_lighting_to_baseline_building(model, building_type)
91
+ else:
92
+ model_lighting_to_baseline(model)
93
+ model_hvac_to_baseline(model, climate_zone, building_type, floor_area, story_count)
94
+ model_shw_to_baseline(model, building_type)
95
+ model_remove_ecms(model)
96
+
97
+
98
+ def model_geometry_to_baseline(model, building_type='NonResidential'):
99
+ """Convert a Model's geometry to be conformant with ASHRAE 90.1 appendix G.
100
+
101
+ This includes stripping out all attached shades (leaving detached shade as
102
+ context), reducing the vertical glazing ratio to a level conformant to the
103
+ building_type (or 40% if the building type is unknown and the model is above
104
+ this value), and reducing the skylight ratio to 3% if it's above this value.
105
+
106
+ Note that not all versions of ASHRAE 90.1 use this exact definition of
107
+ baseline geometry but version 2016 and onward conform to it. It is
108
+ essentially an adjusted version of the 90.1-2004 methods.
109
+
110
+ Args:
111
+ model: A Honeybee Model that will have its geometry adjusted to
112
+ conform to the baseline.
113
+ building_type: Text for the building type that the Model represents.
114
+ This is used to set the maximum window ratio for the model. If the
115
+ type is not recognized or is "Unknown", a maximum of 40% shall
116
+ be used. The following have specified ratios per the standard.
117
+
118
+ * LargeOffice
119
+ * MediumOffice
120
+ * SmallOffice
121
+ * Retail
122
+ * StripMall
123
+ * PrimarySchool
124
+ * SecondarySchool
125
+ * SmallHotel
126
+ * LargeHotel
127
+ * Hospital
128
+ * Outpatient
129
+ * Warehouse
130
+ * SuperMarket
131
+ * FullServiceRestaurant
132
+ * QuickServiceRestaurant
133
+
134
+ """
135
+ # remove all non-context shade
136
+ model.remove_assigned_shades() # remove all of the child shades
137
+ or_shades = [shd for shd in model.orphaned_shades if shd.is_detached]
138
+ model.remove_shades()
139
+ for shd in or_shades:
140
+ model.add_shade(shd)
141
+
142
+ # determine the maximum glazing ratio using the building type
143
+ ratio_file = os.path.join(os.path.dirname(__file__), 'data', 'fen_ratios.csv')
144
+ ratio_data = csv_to_matrix(ratio_file)
145
+ max_ratio = 0.4
146
+ for row in ratio_data:
147
+ if row[0] == building_type:
148
+ max_ratio = float(row[1])
149
+ break
150
+
151
+ # compute the window and skylight ratios
152
+ w_area = model.exterior_wall_area
153
+ r_area = model.exterior_roof_area
154
+ wa_area = model.exterior_wall_aperture_area
155
+ ra_area = model.exterior_skylight_aperture_area
156
+ wr = wa_area / w_area if w_area != 0 else 0
157
+ sr = ra_area / r_area if r_area != 0 else 0
158
+
159
+ # if the window or skylight ratio is greater than max permitted, set it to max
160
+ if wr > max_ratio: # set all walls to have the maximum ratio
161
+ adjust_factor = max_ratio / wr
162
+ for room in model.rooms:
163
+ for face in room.faces:
164
+ if isinstance(face.boundary_condition, Outdoors) and \
165
+ isinstance(face.type, Wall):
166
+ new_ratio = face.aperture_ratio * adjust_factor
167
+ face.apertures_by_ratio(new_ratio, model.tolerance)
168
+ if sr > 0.03: # reduce all skylights by the amount needed for 5%
169
+ red_fract = 0.03 / sr # scale factor for all of the skylights
170
+ for room in model.rooms:
171
+ for face in room.faces:
172
+ if isinstance(face.boundary_condition, Outdoors) and \
173
+ isinstance(face.type, RoofCeiling) and \
174
+ len(face._apertures) > 0:
175
+ new_ratio = face.aperture_ratio * red_fract
176
+ face.apertures_by_ratio(new_ratio)
177
+
178
+
179
+ def model_constructions_to_baseline(model, climate_zone):
180
+ """Convert a Model's constructions to be conformant with ASHRAE 90.1 appendix G.
181
+
182
+ This includes assigning a ConstructionSet that is compliant with Table G3.4
183
+ to all rooms in the model, accounting for the fenestration ratios in the process.
184
+
185
+ Note that not all versions of ASHRAE 90.1 use this exact definition of
186
+ baseline constructions but version 2016 and onward conform to it. It is
187
+ essentially an adjusted version of the 90.1-2004 methods.
188
+
189
+ Args:
190
+ model: A Honeybee Model that will have its constructions adjusted to
191
+ conform to the baseline.
192
+ climate_zone: Text indicating the ASHRAE climate zone. This can be a single
193
+ integer (in which case it is interpreted as A) or it can include the
194
+ A, B, or C qualifier (eg. 3C).
195
+ """
196
+ # compute the fenestration ratios across the model
197
+ w_area = model.exterior_wall_area
198
+ r_area = model.exterior_roof_area
199
+ wr = model.exterior_wall_aperture_area / w_area if w_area != 0 else 0
200
+ sr = model.exterior_skylight_aperture_area / r_area if r_area != 0 else 0
201
+
202
+ # get the base ConstructionSet from the standards library
203
+ clean_cz = str(climate_zone)[0]
204
+ constr_set_id = '2004::ClimateZone{}::SteelFramed'.format(clean_cz)
205
+ base_set = construction_set_by_identifier(constr_set_id)
206
+
207
+ # parse the CSV file with exceptions to the base construction set
208
+ ex_file = os.path.join(os.path.dirname(__file__), 'data', 'constructions.csv')
209
+ ex_data = csv_to_matrix(ex_file)
210
+ ex_cz = clean_cz if climate_zone != '3C' else climate_zone
211
+ ex_ratio = '100'
212
+ for ratio in (40, 30, 20, 10):
213
+ if wr < ratio / 100 + 0.001:
214
+ ex_ratio = str(ratio)
215
+ for row in ex_data:
216
+ if row[0] == ex_cz and row[1] == ex_ratio:
217
+ vert_except = [float(val) for val in row[2:]]
218
+ break
219
+
220
+ # change the constructions for fixed and operable windows
221
+ si_ip_u = 5.678263337
222
+ fixed_id = 'U {} SHGC {} Fixed Glz'.format(vert_except[0], vert_except[2])
223
+ fixed_mat = EnergyWindowMaterialSimpleGlazSys(
224
+ fixed_id, vert_except[0] * si_ip_u, vert_except[2])
225
+ fixed_constr = WindowConstruction(fixed_id.replace('Glz', 'Window'), [fixed_mat])
226
+ oper_id = 'U {} SHGC {} Operable Glz'.format(vert_except[1], vert_except[2])
227
+ oper_mat = EnergyWindowMaterialSimpleGlazSys(
228
+ oper_id, vert_except[1] * si_ip_u, vert_except[2])
229
+ oper_constr = WindowConstruction(oper_id.replace('Glz', 'Window'), [oper_mat])
230
+ base_set.aperture_set.window_construction = fixed_constr
231
+ base_set.aperture_set.operable_construction = oper_constr
232
+
233
+ # change the construction for skylights if the ratio is greater than 2%
234
+ if sr > 0.021:
235
+ for row in ex_data:
236
+ if row[0] == ex_cz and row[1] == 'sky_5':
237
+ sky_except = [float(row[2]), float(row[4])]
238
+ break
239
+ sky_id = 'U {} SHGC {} Skylight Glz'.format(sky_except[0], sky_except[1])
240
+ sky_mat = EnergyWindowMaterialSimpleGlazSys(
241
+ sky_id, sky_except[0] * si_ip_u, sky_except[1])
242
+ sky_constr = WindowConstruction(sky_id.replace('Glz', 'Window'), [sky_mat])
243
+ base_set.aperture_set.skylight_construction = sky_constr
244
+
245
+ # remove child constructions ans assign the construction set to all rooms
246
+ model.properties.energy.remove_child_constructions()
247
+ for room in model.rooms:
248
+ room.properties.energy.construction_set = base_set
249
+
250
+
251
+ def model_lighting_to_baseline(model):
252
+ """Convert a Model's lighting to be conformant with ASHRAE 90.1-2004 appendix G.
253
+
254
+ This includes determining whether an ASHRAE 2004 equivalent exists for each
255
+ program type in the model. If none is found, the baseline_watts_per_area on
256
+ the room's program's lighting will be used, which will default to a typical
257
+ office if none has been specified.
258
+
259
+ Args:
260
+ model: A Honeybee Model that will have its lighting power adjusted to
261
+ conform to the baseline.
262
+ """
263
+ # loop through the rooms and try to find equivalent programs in 2004
264
+ for room in model.rooms:
265
+ if room.properties.energy.lighting is None or \
266
+ room.properties.energy.lighting.watts_per_area == 0:
267
+ continue
268
+ prog_name = room.properties.energy.program_type.identifier.split('::')
269
+ prog_2004 = None
270
+ if len(prog_name) >= 3:
271
+ new_prog_name = '2004::{}::{}'.format(prog_name[1], prog_name[2])
272
+ try:
273
+ prog_2004 = program_type_by_identifier(new_prog_name)
274
+ except ValueError: # no equivalent program in ASHRAE 2004
275
+ pass
276
+ # if program was found, use it to assign the LPD
277
+ if prog_2004 is not None and prog_2004.lighting is not None:
278
+ dup_light = room.properties.energy.lighting.duplicate()
279
+ dup_light.watts_per_area = prog_2004.lighting.watts_per_area
280
+ elif room.properties.energy.program_type.lighting is not None:
281
+ dup_light = room.properties.energy.program_type.lighting.duplicate()
282
+ dup_light.watts_per_area = dup_light.baseline_watts_per_area
283
+ else:
284
+ dup_light = room.properties.energy.lighting.duplicate()
285
+ dup_light.watts_per_area = dup_light.baseline_watts_per_area
286
+ dup_light.identifier = '{}_Lighting'.format(room.identifier)
287
+ room.properties.energy.lighting = dup_light
288
+
289
+
290
+ def model_lighting_to_baseline_building(model, building_type='NonResidential'):
291
+ """Convert a Model's lighting to be conformant with ASHRAE 90.1-2004 appendix G.
292
+
293
+ This includes looking up the building type's average lighting power density
294
+ and assigning it to all Rooms in the model.
295
+
296
+ Args:
297
+ model: A Honeybee Model that will have its lighting power adjusted to
298
+ conform to the baseline.
299
+ building_type: Text for the building type that the Model represents. If
300
+ the type is not recognized or is "Unknown", it will be assumed that the
301
+ building is a generic NonResidential (aka. an office). The following
302
+ have specified meaning per the standard.
303
+
304
+ * NonResidential
305
+ * Residential
306
+ * MidriseApartment
307
+ * HighriseApartment
308
+ * LargeOffice
309
+ * MediumOffice
310
+ * SmallOffice
311
+ * Retail
312
+ * StripMall
313
+ * PrimarySchool
314
+ * SecondarySchool
315
+ * SmallHotel
316
+ * LargeHotel
317
+ * Hospital
318
+ * Outpatient
319
+ * Warehouse
320
+ * SuperMarket
321
+ * FullServiceRestaurant
322
+ * QuickServiceRestaurant
323
+ * Laboratory
324
+ * Courthouse
325
+ """
326
+ # determine the lighting power density using the building type
327
+ lpd_file = os.path.join(os.path.dirname(__file__), 'data', 'lpd_building.csv')
328
+ lpd_data = csv_to_matrix(lpd_file)
329
+ lpd = 1.0
330
+ for row in lpd_data:
331
+ if row[0] == building_type:
332
+ lpd = float(row[1])
333
+ break
334
+ lpd = lpd * 10.7639 # convert to W/m2 from W/ft2
335
+
336
+ # assign the lighting power density to all rooms in the model
337
+ for room in model.rooms:
338
+ if room.properties.energy.lighting is None or \
339
+ room.properties.energy.lighting.watts_per_area == 0:
340
+ continue
341
+ dup_light = room.properties.energy.lighting.duplicate()
342
+ dup_light.watts_per_area = lpd
343
+ dup_light.identifier = '{}_Lighting'.format(room.identifier)
344
+ room.properties.energy.lighting = dup_light
345
+
346
+
347
+ def model_hvac_to_baseline(model, climate_zone, building_type='NonResidential',
348
+ floor_area=None, story_count=None):
349
+ """Convert a Model's HVAC to be conformant with ASHRAE 90.1 appendix G.
350
+
351
+ This includes the selection of the correct Appendix G template HVAC based on
352
+ the inputs and the application of this HVAC to all conditioned spaces in
353
+ the model.
354
+
355
+ Note that not all versions of ASHRAE 90.1 use this exact definition of
356
+ baseline HVAC but version 2016 and onward conform to it. It is
357
+ essentially an adjusted version of the 90.1-2004 methods.
358
+
359
+ Args:
360
+ model: A Honeybee Model that will have its HVAC adjusted to conform to
361
+ the baseline.
362
+ climate_zone: Text indicating the ASHRAE climate zone. This can be a single
363
+ integer (in which case it is interpreted as A) or it can include the
364
+ A, B, or C qualifier (eg. 3C).
365
+ building_type: Text for the building type that the Model represents. This is
366
+ used to determine the baseline system. If the type is not recognized or
367
+ is "Unknown", it will be assumed that the building is a generic
368
+ NonResidential. The following have specified systems per the standard.
369
+
370
+ * NonResidential
371
+ * Residential
372
+ * MidriseApartment
373
+ * HighriseApartment
374
+ * LargeOffice
375
+ * MediumOffice
376
+ * SmallOffice
377
+ * Retail
378
+ * StripMall
379
+ * PrimarySchool
380
+ * SecondarySchool
381
+ * SmallHotel
382
+ * LargeHotel
383
+ * Hospital
384
+ * Outpatient
385
+ * Warehouse
386
+ * SuperMarket
387
+ * FullServiceRestaurant
388
+ * QuickServiceRestaurant
389
+ * Laboratory
390
+
391
+ floor_area: A number for the floor area of the building that the model is a part
392
+ of in m2. If None, the model floor area will be used. (Default: None).
393
+ story_count: An integer for the number of stories of the building that the
394
+ model is a part of. If None, the model stories will be used. (Default: None).
395
+ """
396
+ # set the standard to be used and the climate zone
397
+ std = 'ASHRAE_2004'
398
+ if len(climate_zone) == 1:
399
+ climate_zone = '{}A'.format(climate_zone)
400
+
401
+ # determine whether the system uses fuel or electricity from the climate zone
402
+ fuel = climate_zone not in ('0A', '0B', '1A', '1B', '2A', '2B', '3A')
403
+
404
+ # determine whether the building type is residential or it's heated-only storage
405
+ res_types = ('Residential', 'MidriseApartment', 'HighriseApartment'
406
+ 'SmallHotel', 'LargeHotel')
407
+ residential = building_type in res_types
408
+ heat_only = False
409
+ if building_type == 'Warehouse':
410
+ for hvac in model.properties.energy.hvacs:
411
+ if isinstance(hvac, _HeatCoolBase) and \
412
+ hvac.equipment_type in hvac.HEAT_ONLY_TYPES:
413
+ heat_only = True
414
+ break
415
+ elif isinstance(hvac, ForcedAirFurnace):
416
+ heat_only = True
417
+ break
418
+
419
+ # determine the HVAC template from the input criteria
420
+ if residential:
421
+ hvac_id = 'Baseline PT Residential HVAC'
422
+ hvac_sys = PTAC(hvac_id, std, 'PTAC_BoilerBaseboard') \
423
+ if fuel else PTAC(hvac_id, std, 'PTHP')
424
+ elif heat_only:
425
+ hvac_id = 'Baseline Warm Air Furnace HVAC'
426
+ hvac_sys = ForcedAirFurnace(hvac_id, std, 'Furnace') \
427
+ if fuel else ForcedAirFurnace(hvac_id, std, 'Furnace_Electric')
428
+ else:
429
+ # determine the floor area if it is not input
430
+ if floor_area == 0 or floor_area is None:
431
+ floor_area = model.floor_area
432
+ floor_area = floor_area if model.units == 'Meters' else \
433
+ floor_area * model.conversion_factor_to_meters(model.units)
434
+ # determine the number of stories if it is not input
435
+ if story_count == 0 or story_count is None:
436
+ story_count = len(model.stories)
437
+ # determine the HVAC from the floor area and stories
438
+ hvac_temp = 'Baseline {} HVAC'
439
+ if building_type in ('Retail, StripMall') and story_count <= 2:
440
+ hvac_id = hvac_temp.format('PSZ')
441
+ hvac_sys = PSZ(hvac_id, std, 'PSZAC_Boiler') \
442
+ if fuel else PSZ(hvac_id, std, 'PSZHP')
443
+ elif story_count > 5 or floor_area > 13935.5: # more than 150,000 ft2
444
+ hvac_id = hvac_temp.format('VAV')
445
+ hvac_sys = VAV(hvac_id, std, 'VAV_Chiller_Boiler') \
446
+ if fuel else VAV(hvac_id, std, 'VAV_Chiller_PFP')
447
+ elif story_count > 3 or floor_area > 2322.6: # more than 25,000 ft2
448
+ hvac_id = hvac_temp.format('PVAV')
449
+ hvac_sys = PVAV(hvac_id, std, 'PVAV_Boiler') \
450
+ if fuel else PVAV(hvac_id, std, 'PVAV_PFP')
451
+ elif building_type in ('Hospital', 'Laboratory'):
452
+ hvac_id = hvac_temp.format('PVAV')
453
+ hvac_sys = PVAV(hvac_id, std, 'PVAV_Boiler') \
454
+ if fuel else PVAV(hvac_id, std, 'PVAV_PFP')
455
+ else:
456
+ hvac_id = hvac_temp.format('PSZ')
457
+ hvac_sys = PSZ(hvac_id, std, 'PSZAC_Boiler') \
458
+ if fuel else PSZ(hvac_id, std, 'PSZHP')
459
+ if climate_zone not in ('0A', '0B', '1A', '1B', '2A', '3A', '4A'):
460
+ hvac_sys.economizer_type = 'DifferentialDryBulb'
461
+
462
+ # apply the HVAC template to all conditioned rooms in the model
463
+ dhw_only, dch_only, dhw_dcw = [], [], []
464
+ for room in model.rooms:
465
+ r_hvac = room.properties.energy.hvac
466
+ if r_hvac is not None:
467
+ if isinstance(r_hvac, _TemplateSystem):
468
+ if not r_hvac.has_district_heating and not r_hvac.has_district_cooling:
469
+ room.properties.energy.hvac = hvac_sys
470
+ elif r_hvac.has_district_heating and r_hvac.has_district_cooling:
471
+ dhw_dcw.append(room)
472
+ elif r_hvac.has_district_heating:
473
+ dhw_only.append(room)
474
+ else:
475
+ dch_only.append(room)
476
+ else:
477
+ room.properties.energy.hvac = hvac_sys
478
+
479
+ # if there were any rooms with district heating or cooling, substitute the system
480
+ if len(dhw_dcw) != 0:
481
+ if isinstance(hvac_sys, (VAV, PVAV)):
482
+ hvac_id = hvac_temp.format('VAV') + ' DHW DCW'
483
+ new_hvac_sys = VAV(hvac_id, std, 'VAV_DCW_DHW')
484
+ new_hvac_sys.economizer_type = hvac_sys.economizer_type
485
+ elif isinstance(hvac_sys, PSZ):
486
+ hvac_id = hvac_temp.format('PSZ') + ' DHW DCW'
487
+ new_hvac_sys = PSZ(hvac_id, std, 'PSZAC_DCW_DHW')
488
+ new_hvac_sys.economizer_type = hvac_sys.economizer_type
489
+ elif isinstance(hvac_sys, PTAC):
490
+ hvac_id = 'Baseline FCU Residential HVAC DHW DCW'
491
+ new_hvac_sys = FCUwithDOAS(hvac_id, std, 'DOAS_FCU_DCW_DHW')
492
+ else:
493
+ new_hvac_sys = hvac_sys
494
+ for room in dhw_dcw:
495
+ room.properties.energy.hvac = new_hvac_sys
496
+ if len(dch_only) != 0:
497
+ if isinstance(hvac_sys, (VAV, PVAV)):
498
+ hvac_id = hvac_temp.format('VAV') + ' DCW'
499
+ new_hvac_sys = VAV(hvac_id, std, 'VAV_DCW_Boiler') \
500
+ if fuel else PVAV(hvac_id, std, 'VAV_DCW_PFP')
501
+ new_hvac_sys.economizer_type = hvac_sys.economizer_type
502
+ elif isinstance(hvac_sys, PSZ):
503
+ hvac_id = hvac_temp.format('PSZ') + ' DCW'
504
+ new_hvac_sys = PSZ(hvac_id, std, 'PSZAC_DCW_Boiler')
505
+ new_hvac_sys.economizer_type = hvac_sys.economizer_type
506
+ elif isinstance(hvac_sys, PTAC):
507
+ hvac_id = 'Baseline FCU Residential HVAC DCW'
508
+ new_hvac_sys = FCUwithDOAS(hvac_id, std, 'DOAS_FCU_DCW_Boiler')
509
+ else:
510
+ new_hvac_sys = hvac_sys
511
+ for room in dch_only:
512
+ room.properties.energy.hvac = new_hvac_sys
513
+ if len(dhw_only) != 0:
514
+ if isinstance(hvac_sys, VAV):
515
+ hvac_id = hvac_temp.format('VAV') + ' DHW'
516
+ new_hvac_sys = VAV(hvac_id, std, 'VAV_Chiller_DHW')
517
+ new_hvac_sys.economizer_type = hvac_sys.economizer_type
518
+ elif isinstance(hvac_sys, PVAV):
519
+ hvac_id = hvac_temp.format('PVAV') + ' DHW'
520
+ new_hvac_sys = PVAV(hvac_id, std, 'PVAV_DHW')
521
+ new_hvac_sys.economizer_type = hvac_sys.economizer_type
522
+ elif isinstance(hvac_sys, PSZ):
523
+ hvac_id = hvac_temp.format('PSZ') + ' DHW'
524
+ new_hvac_sys = PSZ(hvac_id, std, 'PSZAC_DHW')
525
+ new_hvac_sys.economizer_type = hvac_sys.economizer_type
526
+ elif isinstance(hvac_sys, PTAC):
527
+ hvac_id = 'Baseline PT Residential HVAC DHW'
528
+ hvac_sys = PTAC(hvac_id, std, 'PTAC_DHW')
529
+ else:
530
+ new_hvac_sys = hvac_sys
531
+ for room in dhw_only:
532
+ room.properties.energy.hvac = new_hvac_sys
533
+
534
+
535
+ def model_shw_to_baseline(model, building_type='NonResidential'):
536
+ """Convert a Model's SHW systems to be conformant with ASHRAE 90.1-2004 appendix G.
537
+
538
+ This includes looking up the building type's baseline heating method and
539
+ assigning it to all Rooms with a SHW system in the model.
540
+
541
+ Args:
542
+ model: A Honeybee Model that will have its Service Hot Water (SHW) systems
543
+ adjusted to conform to the baseline.
544
+ building_type: Text for the building type that the Model represents. If
545
+ the type is not recognized or is "Unknown", it will be assumed that
546
+ the building is a generic NonResidential (aka. an office). The following
547
+ have specified meaning per the standard.
548
+
549
+ * NonResidential
550
+ * Residential
551
+ * MidriseApartment
552
+ * HighriseApartment
553
+ * LargeOffice
554
+ * MediumOffice
555
+ * SmallOffice
556
+ * Retail
557
+ * StripMall
558
+ * PrimarySchool
559
+ * SecondarySchool
560
+ * SmallHotel
561
+ * LargeHotel
562
+ * Hospital
563
+ * Outpatient
564
+ * Warehouse
565
+ * SuperMarket
566
+ * FullServiceRestaurant
567
+ * QuickServiceRestaurant
568
+ * Laboratory
569
+ * Courthouse
570
+ """
571
+ # determine the service hot water system using the building type
572
+ shw_file = os.path.join(os.path.dirname(__file__), 'data', 'shw.csv')
573
+ shw_data = csv_to_matrix(shw_file)
574
+ shw_t = 'Gas'
575
+ for row in shw_data:
576
+ if row[0] == building_type:
577
+ shw_t = row[1]
578
+ break
579
+ shw_sys = SHWSystem('Baseline Gas SHW System', 'Gas_WaterHeater') if shw_t == 'Gas' \
580
+ else SHWSystem('Baseline Electric Resistance SHW System', 'Electric_WaterHeater')
581
+
582
+ # assign the SHW system to all relevant rooms in the model
583
+ for room in model.rooms:
584
+ if room.properties.energy.shw is None:
585
+ continue
586
+ room.properties.energy.shw = shw_sys
587
+
588
+
589
+ def model_remove_ecms(model):
590
+ """Remove energy conservation strategies (ECMs) not associated with baseline models.
591
+
592
+ This includes removing the opening behavior of all operable windows, daylight
593
+ controls, etc.
594
+
595
+ Args:
596
+ model: A Honeybee Model that will have its lighting power adjusted to
597
+ conform to the baseline.
598
+ """
599
+ # loop through the rooms and remove daylight controls
600
+ for room in model.rooms:
601
+ room.properties.energy.daylighting_control = None
602
+ # loop through the rooms and remove operable windows
603
+ for room in model.rooms:
604
+ room.properties.energy.window_vent_control = None
605
+ room.properties.energy.remove_ventilation_opening()
606
+ for face in room.faces:
607
+ for ap in face.apertures:
608
+ ap.is_operable = False
@@ -0,0 +1 @@
1
+ """Data that is used by the baseline subpackage."""
@@ -0,0 +1,64 @@
1
+ climate_zone,max_percent,u_fixed,u_oper,shgc_all,shgc_north
2
+ 1,10,1.22,1.27,0.25,0.61
3
+ 1,20,1.22,1.27,0.25,0.61
4
+ 1,30,1.22,1.27,0.25,0.61
5
+ 1,40,1.22,1.27,0.25,0.44
6
+ 1,100,1.22,1.27,0.19,0.33
7
+ 1,sky_2,1.98,,0.36,
8
+ 1,sky_5,1.98,,0.19,
9
+ 2,10,1.22,1.27,0.25,0.61
10
+ 2,20,1.22,1.27,0.25,0.61
11
+ 2,30,1.22,1.27,0.25,0.61
12
+ 2,40,1.22,1.27,0.25,0.61
13
+ 2,100,1.22,1.27,0.17,0.44
14
+ 2,sky_2,1.98,,0.36,
15
+ 2,sky_5,1.98,,0.19,
16
+ 3,10,0.57,0.67,0.39,0.49
17
+ 3,20,0.57,0.67,0.25,0.49
18
+ 3,30,0.57,0.67,0.25,0.39
19
+ 3,40,0.57,0.67,0.25,0.39
20
+ 3,100,0.46,0.47,0.19,0.26
21
+ 3,sky_2,1.17,,0.39,
22
+ 3,sky_5,1.17,,0.19,
23
+ 3C,10,1.22,1.27,0.61,0.82
24
+ 3C,20,1.22,1.27,0.39,0.61
25
+ 3C,30,1.22,1.27,0.39,0.61
26
+ 3C,40,1.22,1.27,0.34,0.61
27
+ 3C,100,1.22,1.27,0.2,0.3
28
+ 3C,sky_2,1.98,,0.61,
29
+ 3C,sky_5,1.98,,0.39,
30
+ 4,10,0.57,0.67,0.39,0.49
31
+ 4,20,0.57,0.67,0.39,0.49
32
+ 4,30,0.57,0.67,0.39,0.49
33
+ 4,40,0.57,0.67,0.39,0.49
34
+ 4,100,0.46,0.47,0.25,0.36
35
+ 4,sky_2,1.17,,0.49,
36
+ 4,sky_5,1.17,,0.39,
37
+ 5,10,0.57,0.67,0.49,0.49
38
+ 5,20,0.57,0.67,0.39,0.49
39
+ 5,30,0.57,0.67,0.39,0.49
40
+ 5,40,0.57,0.67,0.39,0.49
41
+ 5,100,0.46,0.47,0.26,0.36
42
+ 5,sky_2,1.17,,0.49,
43
+ 5,sky_5,1.17,,0.39,
44
+ 6,10,0.57,0.67,0.49,0.49
45
+ 6,20,0.57,0.67,0.39,0.49
46
+ 6,30,0.57,0.67,0.39,0.49
47
+ 6,40,0.57,0.67,0.39,0.49
48
+ 6,100,0.46,0.47,0.26,0.49
49
+ 6,sky_2,1.17,,0.49,
50
+ 6,sky_5,1.17,,0.49,
51
+ 7,10,0.57,0.67,0.49,0.64
52
+ 7,20,0.57,0.67,0.49,0.64
53
+ 7,30,0.57,0.67,0.49,0.64
54
+ 7,40,0.57,0.67,0.49,0.64
55
+ 7,100,0.46,0.47,0.36,0.64
56
+ 7,sky_2,1.17,,0.68,
57
+ 7,sky_5,1.17,,0.64,
58
+ 8,10,0.46,0.47,0.45,0.45
59
+ 8,20,0.46,0.47,0.45,0.45
60
+ 8,30,0.46,0.47,0.45,0.45
61
+ 8,40,0.46,0.47,0.45,0.45
62
+ 8,100,0.35,0.39,0.45,0.45
63
+ 8,sky_2,0.98,,0.45,
64
+ 8,sky_5,0.98,,0.45,
@@ -0,0 +1,15 @@
1
+ LargeOffice,0.40
2
+ MediumOffice,0.31
3
+ SmallOffice,0.19
4
+ Retail,0.11
5
+ StripMall,0.20
6
+ PrimarySchool,0.22
7
+ SecondarySchool,0.22
8
+ SmallHotel,0.24
9
+ LargeHotel,0.34
10
+ Hospital,0.27
11
+ Outpatient,0.21
12
+ Warehouse,0.06
13
+ SuperMarket,0.07
14
+ FullServiceRestaurant,0.24
15
+ QuickServiceRestaurant,0.34