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,475 @@
1
+ """honeybee energy commands for creating baseline buildings conforming to standards."""
2
+ import click
3
+ import sys
4
+ import logging
5
+ import json
6
+
7
+ from honeybee.model import Model
8
+
9
+ from honeybee_energy.baseline.create import model_to_baseline, \
10
+ model_geometry_to_baseline, model_constructions_to_baseline, \
11
+ model_lighting_to_baseline, model_hvac_to_baseline, model_shw_to_baseline, \
12
+ model_remove_ecms
13
+ from honeybee_energy.baseline.result import appendix_g_summary, leed_v4_summary
14
+
15
+ _logger = logging.getLogger(__name__)
16
+
17
+
18
+ @click.group(help='Commands for creating baseline buildings conforming to standards.')
19
+ def baseline():
20
+ pass
21
+
22
+
23
+ @baseline.command('create')
24
+ @click.argument('model-file', type=click.Path(
25
+ exists=True, file_okay=True, dir_okay=False, resolve_path=True))
26
+ @click.argument('climate-zone', type=str)
27
+ @click.option(
28
+ '--building-type', '-b', help='Text for the building type that the Model represents.'
29
+ ' This is used to determine the baseline window-to-wall ratio and HVAC system. If '
30
+ 'the type is not recognized or is "Unknown", it will be assumed that the building is'
31
+ ' a generic NonResidential. The following have specified systems per the standard: '
32
+ 'Residential, NonResidential, MidriseApartment, HighriseApartment, LargeOffice, '
33
+ 'MediumOffice, SmallOffice, Retail, StripMall, PrimarySchool, SecondarySchool, '
34
+ 'SmallHotel, LargeHotel, Hospital, Outpatient, Warehouse, SuperMarket, '
35
+ 'FullServiceRestaurant, QuickServiceRestaurant, Laboratory',
36
+ type=str, default='NonResidential', show_default=True)
37
+ @click.option(
38
+ '--floor-area', '-a', help='A number for the floor area of the building'
39
+ ' that the model is a part of in m2. If None or 0, the model floor area '
40
+ 'will be used.', type=float, default=0, show_default=True)
41
+ @click.option(
42
+ '--story-count', '-s', help='An integer for the number of stories of '
43
+ 'the building that the model is a part of. If None or 0, the model stories '
44
+ 'will be used.', type=int, default=0, show_default=True)
45
+ @click.option(
46
+ '--lighting-by-space/--lighting-by-building', ' /-lb', help='Flag to note whether '
47
+ 'the building-type should be used to assign the baseline lighting power density, '
48
+ 'which will use the same value for all Rooms in the model, or a space-by-space '
49
+ 'method should be used. To use the space-by-space method, the model should '
50
+ 'either be built with the programs that ship with Ladybug Tools in '
51
+ 'honeybee-energy-standards or the baseline_watts_per_area should be correctly '
52
+ 'assigned for all Rooms.', default=True)
53
+ @click.option(
54
+ '--output-file', '-f', help='Optional hbjson file to output the JSON '
55
+ 'string of the converted model. By default this will be printed out '
56
+ 'to stdout', type=click.File('w'), default='-', show_default=True)
57
+ def create_baseline(model_file, climate_zone, building_type, floor_area,
58
+ story_count, lighting_by_space, output_file):
59
+ """Convert a Model to be conformant with ASHRAE 90.1 appendix G.
60
+
61
+ This includes running all other functions contained within this group to adjust
62
+ the geometry, constructions, lighting, HVAC, SHW, and remove any clearly-defined
63
+ energy conservation measures like daylight controls. Note that all schedules
64
+ are essentially unchanged, meaning that additional post-processing of setpoints
65
+ may be necessary to account for energy conservation strategies like expanded
66
+ comfort ranges, ceiling fans, and personal thermal comfort devices. It may
67
+ also be necessary to adjust electric equipment loads in cases where such
68
+ equipment qualifies as an energy conservation strategy or hot water loads in
69
+ cases where low-flow fixtures are implemented.
70
+
71
+ Note that not all versions of ASHRAE 90.1 use this exact definition of a
72
+ baseline model but version 2016 and onward conform to it. It is essentially
73
+ an adjusted version of the 90.1-2004 methods.
74
+
75
+ \b
76
+ Args:
77
+ model_file: Full path to a Honeybee Model file.
78
+ climate_zone: Text indicating the ASHRAE climate zone. This can be a single
79
+ integer (in which case it is interpreted as A) or it can include the
80
+ A, B, or C qualifier (eg. 3C).
81
+ """
82
+ try:
83
+ lighting_by_building = not lighting_by_space
84
+ model = Model.from_file(model_file)
85
+ model_to_baseline(
86
+ model, climate_zone, building_type, floor_area, story_count,
87
+ lighting_by_building)
88
+ output_file.write(json.dumps(model.to_dict()))
89
+ except Exception as e:
90
+ _logger.exception('Model baseline HVAC creation failed.\n{}'.format(e))
91
+ sys.exit(1)
92
+ else:
93
+ sys.exit(0)
94
+
95
+
96
+ @baseline.command('geometry')
97
+ @click.argument('model-file', type=click.Path(
98
+ exists=True, file_okay=True, dir_okay=False, resolve_path=True))
99
+ @click.option(
100
+ '--building-type', '-b', help='Text for the building type that the '
101
+ 'Model represents. This is used to set the maximum window ratio for the '
102
+ 'model. If the type is not recognized or is "Unknown", a maximum of 0.4 '
103
+ 'shall be used. The following have specified ratios per the standard: '
104
+ 'LargeOffice, MediumOffice, SmallOffice, Retail, StripMall, PrimarySchool, '
105
+ 'SecondarySchool, SmallHotel, LargeHotel, Hospital, Outpatient, Warehouse, '
106
+ 'SuperMarket, FullServiceRestaurant, QuickServiceRestaurant',
107
+ type=str, default='NonResidential', show_default=True)
108
+ @click.option('--output-file', '-f', help='Optional hbjson file to output the JSON '
109
+ 'string of the converted model. By default this will be printed out to '
110
+ 'stdout', type=click.File('w'), default='-', show_default=True)
111
+ def baseline_geometry(model_file, building_type, output_file):
112
+ """Convert a Model's geometry to be conformant with ASHRAE 90.1-2004 appendix G.
113
+
114
+ This includes stripping out all attached shades (leaving detached shade as context),
115
+ reducing the vertical glazing ratio to 40% it it's above this value, and
116
+ reducing the skylight ratio to 5% if it's above this value.
117
+
118
+ \b
119
+ Args:
120
+ model_file: Path to a Honeybee Model file.
121
+ """
122
+ try:
123
+ model = Model.from_file(model_file)
124
+ model_geometry_to_baseline(model, building_type)
125
+ output_file.write(json.dumps(model.to_dict()))
126
+ except Exception as e:
127
+ _logger.exception('Model baseline geometry creation failed.\n{}'.format(e))
128
+ sys.exit(1)
129
+ else:
130
+ sys.exit(0)
131
+
132
+
133
+ @baseline.command('constructions')
134
+ @click.argument('model-file', type=click.Path(
135
+ exists=True, file_okay=True, dir_okay=False, resolve_path=True))
136
+ @click.argument('climate-zone', type=str)
137
+ @click.option('--output-file', '-f', help='Optional hbjson file to output the JSON '
138
+ 'string of the converted model. By default this will be printed out '
139
+ 'to stdout', type=click.File('w'), default='-', show_default=True)
140
+ def baseline_constructions(model_file, climate_zone, output_file):
141
+ """Convert a Model's constructions to be conformant with ASHRAE 90.1-2004 appendix G.
142
+
143
+ This includes assigning a ConstructionSet that is compliant with Table 5.5 to
144
+ all rooms in the model.
145
+
146
+ \b
147
+ Args:
148
+ model_file: Full path to a Honeybee Model file.
149
+ climate_zone: Text indicating the ASHRAE climate zone. This can be a single
150
+ integer (in which case it is interpreted as A) or it can include the
151
+ A, B, or C qualifier (eg. 3C).
152
+ """
153
+ try:
154
+ model = Model.from_file(model_file)
155
+ model_constructions_to_baseline(model, climate_zone)
156
+ output_file.write(json.dumps(model.to_dict()))
157
+ except Exception as e:
158
+ _logger.exception('Model baseline construction assignment failed.\n{}'.format(e))
159
+ sys.exit(1)
160
+ else:
161
+ sys.exit(0)
162
+
163
+
164
+ @baseline.command('lighting')
165
+ @click.argument('model-file', type=click.Path(
166
+ exists=True, file_okay=True, dir_okay=False, resolve_path=True))
167
+ @click.option('--output-file', '-f', help='Optional hbjson file to output the JSON '
168
+ 'string of the converted model. By default this will be printed out '
169
+ 'to stdout', type=click.File('w'), default='-', show_default=True)
170
+ def baseline_lighting(model_file, output_file):
171
+ """Convert a Model's lighting to be conformant with ASHRAE 90.1-2004 appendix G.
172
+
173
+ This includes determining whether an ASHRAE 2004 equivalent exists for each
174
+ program type in the model. If none is found, the baseline_watts_per_area on
175
+ the room's program's lighting will be used, which will default to a typical
176
+ office if none has been specified.
177
+
178
+ \b
179
+ Args:
180
+ model_file: Full path to a Honeybee Model file.
181
+ """
182
+ try:
183
+ model = Model.from_file(model_file)
184
+ model_lighting_to_baseline(model)
185
+ output_file.write(json.dumps(model.to_dict()))
186
+ except Exception as e:
187
+ _logger.exception('Model baseline lighting assignment failed.\n{}'.format(e))
188
+ sys.exit(1)
189
+ else:
190
+ sys.exit(0)
191
+
192
+
193
+ @baseline.command('hvac')
194
+ @click.argument('model-file', type=click.Path(
195
+ exists=True, file_okay=True, dir_okay=False, resolve_path=True))
196
+ @click.argument('climate-zone', type=str)
197
+ @click.option(
198
+ '--building-type', '-b', help='Text for the building type that the '
199
+ 'Model represents. This is used to determine the baseline system. If the type '
200
+ 'is not recognized or is "Unknown", it will be assumed that the building is '
201
+ 'a generic NonResidential. The following have specified systems per the standard: '
202
+ 'Residential, NonResidential, MidriseApartment, HighriseApartment, LargeOffice, '
203
+ 'MediumOffice, SmallOffice, Retail, StripMall, PrimarySchool, SecondarySchool, '
204
+ 'SmallHotel, LargeHotel, Hospital, Outpatient, Warehouse, SuperMarket, '
205
+ 'FullServiceRestaurant, QuickServiceRestaurant, Laboratory',
206
+ type=str, default='NonResidential', show_default=True)
207
+ @click.option(
208
+ '--floor-area', '-a', help='A number for the floor area of the building'
209
+ ' that the model is a part of in m2. If None or 0, the model floor area '
210
+ 'will be used.', type=float, default=0, show_default=True)
211
+ @click.option(
212
+ '--story-count', '-s', help='An integer for the number of stories of '
213
+ 'the building that the model is a part of. If None or 0, the model stories '
214
+ 'will be used.', type=int, default=0, show_default=True)
215
+ @click.option(
216
+ '--output-file', '-f', help='Optional hbjson file to output the JSON '
217
+ 'string of the converted model. By default this will be printed out '
218
+ 'to stdout', type=click.File('w'), default='-', show_default=True)
219
+ def baseline_hvac(model_file, climate_zone, building_type, floor_area,
220
+ story_count, output_file):
221
+ """Convert a Model's HVAC to be conformant with ASHRAE 90.1-2004 appendix G.
222
+
223
+ This includes the selection of the correct Appendix G template HVAC based on
224
+ the inputs and the application of this HVAC to all conditioned spaces in
225
+ the model.
226
+
227
+ \b
228
+ Args:
229
+ model_file: Full path to a Honeybee Model file.
230
+ climate_zone: Text indicating the ASHRAE climate zone. This can be a single
231
+ integer (in which case it is interpreted as A) or it can include the
232
+ A, B, or C qualifier (eg. 3C).
233
+ """
234
+ try:
235
+ model = Model.from_file(model_file)
236
+ model_hvac_to_baseline(
237
+ model, climate_zone, building_type, floor_area, story_count)
238
+ output_file.write(json.dumps(model.to_dict()))
239
+ except Exception as e:
240
+ _logger.exception('Model baseline HVAC creation failed.\n{}'.format(e))
241
+ sys.exit(1)
242
+ else:
243
+ sys.exit(0)
244
+
245
+
246
+ @baseline.command('shw')
247
+ @click.argument('model-file', type=click.Path(
248
+ exists=True, file_okay=True, dir_okay=False, resolve_path=True))
249
+ @click.option(
250
+ '--building-type', '-b', help='Text for the building type that the '
251
+ 'Model represents. This is used to determine the baseline system. If the type '
252
+ 'is not recognized or is "Unknown", it will be assumed that the building is '
253
+ 'a generic NonResidential. The following have specified systems per the standard: '
254
+ 'Residential, NonResidential, MidriseApartment, HighriseApartment, LargeOffice, '
255
+ 'MediumOffice, SmallOffice, Retail, StripMall, PrimarySchool, SecondarySchool, '
256
+ 'SmallHotel, LargeHotel, Hospital, Outpatient, Warehouse, SuperMarket, '
257
+ 'FullServiceRestaurant, QuickServiceRestaurant, Laboratory',
258
+ type=str, default='NonResidential', show_default=True)
259
+ @click.option('--output-file', '-f', help='Optional hbjson file to output the JSON '
260
+ 'string of the converted model. By default this will be printed out to '
261
+ 'stdout', type=click.File('w'), default='-', show_default=True)
262
+ def baseline_shw(model_file, building_type, output_file):
263
+ """Convert a Model's geometry to be conformant with ASHRAE 90.1-2004 appendix G.
264
+
265
+ This includes stripping out all attached shades (leaving detached shade as context),
266
+ reducing the vertical glazing ratio to 40% it it's above this value, and
267
+ reducing the skylight ratio to 5% if it's above this value.
268
+
269
+ \b
270
+ Args:
271
+ model_file: Path to a Honeybee Model file.
272
+ """
273
+ try:
274
+ model = Model.from_file(model_file)
275
+ model_shw_to_baseline(model, building_type)
276
+ output_file.write(json.dumps(model.to_dict()))
277
+ except Exception as e:
278
+ _logger.exception('Model baseline SHW creation failed.\n{}'.format(e))
279
+ sys.exit(1)
280
+ else:
281
+ sys.exit(0)
282
+
283
+
284
+ @baseline.command('remove-ecms')
285
+ @click.argument('model-file', type=click.Path(
286
+ exists=True, file_okay=True, dir_okay=False, resolve_path=True))
287
+ @click.option('--output-file', '-f', help='Optional hbjson file to output the JSON '
288
+ 'string of the converted model. By default this will be printed out '
289
+ 'to stdout', type=click.File('w'), default='-', show_default=True)
290
+ def remove_ecms(model_file, output_file):
291
+ """Remove energy conservation strategies (ECMs) not associated with baseline models.
292
+
293
+ This includes removing the opening behavior of all operable windows, daylight
294
+ controls, etc.
295
+
296
+ \b
297
+ Args:
298
+ model_file: Full path to a Honeybee Model file.
299
+ """
300
+ try:
301
+ model = Model.from_file(model_file)
302
+ model_remove_ecms(model)
303
+ output_file.write(json.dumps(model.to_dict()))
304
+ except Exception as e:
305
+ _logger.exception('Model remove ECMs failed.\n{}'.format(e))
306
+ sys.exit(1)
307
+ else:
308
+ sys.exit(0)
309
+
310
+
311
+ @baseline.command('appendix-g-summary')
312
+ @click.argument('proposed-sql', type=click.Path(
313
+ exists=True, file_okay=True, dir_okay=False, resolve_path=True))
314
+ @click.argument('baseline-sqls', nargs=-1, required=True, type=click.Path(
315
+ exists=True, file_okay=True, dir_okay=True, resolve_path=True))
316
+ @click.argument('climate-zone', type=str)
317
+ @click.option(
318
+ '--building-type', '-b', help='Text for the building type that the Model represents.'
319
+ ' This is used to determine the baseline window-to-wall ratio and HVAC system. If '
320
+ 'the type is not recognized or is "Unknown", it will be assumed that the building is'
321
+ ' a generic NonResidential. The following have meaning per the standard: '
322
+ 'Residential, NonResidential, MidriseApartment, HighriseApartment, LargeOffice, '
323
+ 'MediumOffice, SmallOffice, Retail, StripMall, PrimarySchool, SecondarySchool, '
324
+ 'SmallHotel, LargeHotel, Hospital, Outpatient, Warehouse, SuperMarket, '
325
+ 'FullServiceRestaurant, QuickServiceRestaurant, Laboratory, Courthouse',
326
+ type=str, default='NonResidential', show_default=True)
327
+ @click.option(
328
+ '--electricity-cost', '-e', help='A number for the cost per each kWh of electricity.'
329
+ ' This can be in any currency as long as it is coordinated with the costs of '
330
+ 'other inputs to this method. (Default: 0.12 for the average 2020 cost of '
331
+ 'electricity in the US in $/kWh).', type=float, default=0.12, show_default=True)
332
+ @click.option(
333
+ '--natural-gas-cost', '-g', help='A number for the cost per each kWh of natural gas.'
334
+ ' This can be in any currency as long as it is coordinated with the costs of '
335
+ 'other inputs to this method. (Default: 0.06 for the average 2020 cost of natural '
336
+ 'gas in the US in $/kWh).', type=float, default=0.06, show_default=True)
337
+ @click.option(
338
+ '--district-cooling-cost', '-dc', help='A number for the cost per each kWh of '
339
+ 'district cooling energy. This can be in any currency as long as it is coordinated '
340
+ 'with the costs of other inputs to this method. (Default: 0.04 assuming average '
341
+ '2020 US cost of electricity in $/kWh with a COP 3.5 chiller).',
342
+ type=float, default=0.04, show_default=True)
343
+ @click.option(
344
+ '--district-heating-cost', '-dh', help='A number for the cost per each kWh of '
345
+ 'district heating energy. This can be in any currency as long as it is coordinated '
346
+ 'with the costs of other inputs to this method. (Default: 0.08 assuming average '
347
+ '2020 US cost of natural gas in $/kWh with an efficiency of 0.75 with all burner '
348
+ 'and distribution losses).', type=float, default=0.08, show_default=True)
349
+ @click.option(
350
+ '--output-file', '-f', help='Optional json file to output the JSON '
351
+ 'string of the summary report. By default this will be printed out '
352
+ 'to stdout', type=click.File('w'), default='-', show_default=True)
353
+ def compute_appendix_g_summary(
354
+ proposed_sql, baseline_sqls, climate_zone, building_type,
355
+ electricity_cost, natural_gas_cost,
356
+ district_cooling_cost, district_heating_cost, output_file):
357
+ """Get a JSON with a summary of ASHRAE-90.1 Appendix G performance.
358
+
359
+ This includes Appendix G performance for versions 2016, 2019, and 2022.
360
+
361
+ \b
362
+ Args:
363
+ proposed_sql: The path of the SQL result file that has been generated from an
364
+ energy simulation of a proposed building.
365
+ baseline_sqls: The path of a directory with several SQL result files generated
366
+ from an energy simulation of a baseline building (eg. for several
367
+ simulations of different orientations). The baseline performance will
368
+ be computed as the average across all SQL files in the directory.
369
+ climate_zone: Text indicating the ASHRAE climate zone. This can be a single
370
+ integer (in which case it is interpreted as A) or it can include the
371
+ A, B, or C qualifier (eg. 3C).
372
+ """
373
+ try:
374
+ # get a dictionary with the Appendix G results
375
+ result_dict = appendix_g_summary(
376
+ proposed_sql, baseline_sqls, climate_zone, building_type,
377
+ electricity_cost, natural_gas_cost,
378
+ district_cooling_cost, district_heating_cost)
379
+ # write everything into the output file
380
+ output_file.write(json.dumps(result_dict, indent=4))
381
+ except Exception as e:
382
+ _logger.exception('Failed to compute Appendix G summary.\n{}'.format(e))
383
+ sys.exit(1)
384
+ else:
385
+ sys.exit(0)
386
+
387
+
388
+ @baseline.command('leed-v4-summary')
389
+ @click.argument('proposed-sql', type=click.Path(
390
+ exists=True, file_okay=True, dir_okay=False, resolve_path=True))
391
+ @click.argument('baseline-sqls', nargs=-1, required=True, type=click.Path(
392
+ exists=True, file_okay=True, dir_okay=True, resolve_path=True))
393
+ @click.argument('climate-zone', type=str)
394
+ @click.option(
395
+ '--building-type', '-b', help='Text for the building type that the Model represents.'
396
+ ' This is used to determine the baseline window-to-wall ratio and HVAC system. If '
397
+ 'the type is not recognized or is "Unknown", it will be assumed that the building is'
398
+ ' a generic NonResidential. The following have meaning per the standard: '
399
+ 'Residential, NonResidential, MidriseApartment, HighriseApartment, LargeOffice, '
400
+ 'MediumOffice, SmallOffice, Retail, StripMall, PrimarySchool, SecondarySchool, '
401
+ 'SmallHotel, LargeHotel, Hospital, Outpatient, Warehouse, SuperMarket, '
402
+ 'FullServiceRestaurant, QuickServiceRestaurant, Laboratory, Courthouse',
403
+ type=str, default='NonResidential', show_default=True)
404
+ @click.option(
405
+ '--electricity-cost', '-e', help='A number for the cost per each kWh of electricity.'
406
+ ' This can be in any currency as long as it is coordinated with the costs of '
407
+ 'other inputs to this method. (Default: 0.12 for the average 2020 cost of '
408
+ 'electricity in the US in $/kWh).', type=float, default=0.12, show_default=True)
409
+ @click.option(
410
+ '--natural-gas-cost', '-g', help='A number for the cost per each kWh of natural gas.'
411
+ ' This can be in any currency as long as it is coordinated with the costs of '
412
+ 'other inputs to this method. (Default: 0.06 for the average 2020 cost of natural '
413
+ 'gas in the US in $/kWh).', type=float, default=0.06, show_default=True)
414
+ @click.option(
415
+ '--district-cooling-cost', '-dc', help='A number for the cost per each kWh of '
416
+ 'district cooling energy. This can be in any currency as long as it is coordinated '
417
+ 'with the costs of other inputs to this method. (Default: 0.04 assuming average '
418
+ '2020 US cost of electricity in $/kWh with a COP 3 chiller).',
419
+ type=float, default=0.04, show_default=True)
420
+ @click.option(
421
+ '--district-heating-cost', '-dh', help='A number for the cost per each kWh of '
422
+ 'district heating energy. This can be in any currency as long as it is coordinated '
423
+ 'with the costs of other inputs to this method. (Default: 0.08 assuming average '
424
+ '2020 US cost of natural gas in $/kWh with an efficiency of 0.75 with all burner '
425
+ 'and distribution losses).', type=float, default=0.08, show_default=True)
426
+ @click.option(
427
+ '--electricity-emissions', '-ee', help='A number for the electric grid '
428
+ 'carbon emissions in kg CO2 per MWh. For locations in the USA, this can be '
429
+ 'obtained from he honeybee_energy.result.emissions future_electricity_emissions '
430
+ 'method. For locations outside of the USA where specific data is unavailable, '
431
+ 'the following rules of thumb may be used as a guide. (Default: 400).\n'
432
+ '800 kg/MWh - for an inefficient coal or oil-dominated grid\n'
433
+ '400 kg/MWh - for the US (energy mixed) grid around 2020\n'
434
+ '100-200 kg/MWh - for grids with majority renewable/nuclear composition\n'
435
+ '0-100 kg/MWh - for grids with renewables and storage',
436
+ type=float, default=400, show_default=True)
437
+ @click.option(
438
+ '--output-file', '-f', help='Optional json file to output the JSON '
439
+ 'string of the summary report. By default this will be printed out '
440
+ 'to stdout', type=click.File('w'), default='-', show_default=True)
441
+ def compute_leed_v4_summary(
442
+ proposed_sql, baseline_sqls, climate_zone, building_type,
443
+ electricity_cost, natural_gas_cost, district_cooling_cost, district_heating_cost,
444
+ electricity_emissions, output_file):
445
+ """Get a JSON with a summary of LEED V4 (and 4.1) performance.
446
+
447
+ This includes ASHRAE 90.1-2016 Appendix G performance for both cost and
448
+ carbon (GHG) emissions as well as the estimated number of LEED "Optimize
449
+ Energy Performance" points.
450
+
451
+ \b
452
+ Args:
453
+ proposed_sql: The path of the SQL result file that has been generated from an
454
+ energy simulation of a proposed building.
455
+ baseline_sqls: The path of a directory with several SQL result files generated
456
+ from an energy simulation of a baseline building (eg. for several
457
+ simulations of different orientations). The baseline performance will
458
+ be computed as the average across all SQL files in the directory.
459
+ climate_zone: Text indicating the ASHRAE climate zone. This can be a single
460
+ integer (in which case it is interpreted as A) or it can include the
461
+ A, B, or C qualifier (eg. 3C).
462
+ """
463
+ try:
464
+ # get a dictionary with the Appendix G results
465
+ result_dict = leed_v4_summary(
466
+ proposed_sql, baseline_sqls, climate_zone, building_type,
467
+ electricity_cost, natural_gas_cost,
468
+ district_cooling_cost, district_heating_cost, electricity_emissions)
469
+ # write everything into the output file
470
+ output_file.write(json.dumps(result_dict, indent=4))
471
+ except Exception as e:
472
+ _logger.exception('Failed to compute Appendix G summary.\n{}'.format(e))
473
+ sys.exit(1)
474
+ else:
475
+ sys.exit(0)