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.
- honeybee_energy/__init__.py +24 -0
- honeybee_energy/__main__.py +4 -0
- honeybee_energy/_extend_honeybee.py +145 -0
- honeybee_energy/altnumber.py +21 -0
- honeybee_energy/baseline/__init__.py +2 -0
- honeybee_energy/baseline/create.py +608 -0
- honeybee_energy/baseline/data/__init__.py +1 -0
- honeybee_energy/baseline/data/constructions.csv +64 -0
- honeybee_energy/baseline/data/fen_ratios.csv +15 -0
- honeybee_energy/baseline/data/lpd_building.csv +21 -0
- honeybee_energy/baseline/data/pci_2016.csv +22 -0
- honeybee_energy/baseline/data/pci_2019.csv +22 -0
- honeybee_energy/baseline/data/pci_2022.csv +22 -0
- honeybee_energy/baseline/data/shw.csv +21 -0
- honeybee_energy/baseline/pci.py +512 -0
- honeybee_energy/baseline/result.py +371 -0
- honeybee_energy/boundarycondition.py +128 -0
- honeybee_energy/cli/__init__.py +69 -0
- honeybee_energy/cli/baseline.py +475 -0
- honeybee_energy/cli/edit.py +327 -0
- honeybee_energy/cli/lib.py +1154 -0
- honeybee_energy/cli/result.py +810 -0
- honeybee_energy/cli/setconfig.py +124 -0
- honeybee_energy/cli/settings.py +569 -0
- honeybee_energy/cli/simulate.py +380 -0
- honeybee_energy/cli/translate.py +1714 -0
- honeybee_energy/cli/validate.py +224 -0
- honeybee_energy/config.json +11 -0
- honeybee_energy/config.py +842 -0
- honeybee_energy/construction/__init__.py +1 -0
- honeybee_energy/construction/_base.py +374 -0
- honeybee_energy/construction/air.py +325 -0
- honeybee_energy/construction/dictutil.py +89 -0
- honeybee_energy/construction/dynamic.py +607 -0
- honeybee_energy/construction/opaque.py +460 -0
- honeybee_energy/construction/shade.py +319 -0
- honeybee_energy/construction/window.py +1096 -0
- honeybee_energy/construction/windowshade.py +847 -0
- honeybee_energy/constructionset.py +1655 -0
- honeybee_energy/dictutil.py +56 -0
- honeybee_energy/generator/__init__.py +5 -0
- honeybee_energy/generator/loadcenter.py +204 -0
- honeybee_energy/generator/pv.py +535 -0
- honeybee_energy/hvac/__init__.py +21 -0
- honeybee_energy/hvac/_base.py +124 -0
- honeybee_energy/hvac/_template.py +270 -0
- honeybee_energy/hvac/allair/__init__.py +22 -0
- honeybee_energy/hvac/allair/_base.py +349 -0
- honeybee_energy/hvac/allair/furnace.py +168 -0
- honeybee_energy/hvac/allair/psz.py +131 -0
- honeybee_energy/hvac/allair/ptac.py +163 -0
- honeybee_energy/hvac/allair/pvav.py +109 -0
- honeybee_energy/hvac/allair/vav.py +128 -0
- honeybee_energy/hvac/detailed.py +337 -0
- honeybee_energy/hvac/doas/__init__.py +28 -0
- honeybee_energy/hvac/doas/_base.py +345 -0
- honeybee_energy/hvac/doas/fcu.py +127 -0
- honeybee_energy/hvac/doas/radiant.py +329 -0
- honeybee_energy/hvac/doas/vrf.py +81 -0
- honeybee_energy/hvac/doas/wshp.py +91 -0
- honeybee_energy/hvac/heatcool/__init__.py +23 -0
- honeybee_energy/hvac/heatcool/_base.py +177 -0
- honeybee_energy/hvac/heatcool/baseboard.py +61 -0
- honeybee_energy/hvac/heatcool/evapcool.py +72 -0
- honeybee_energy/hvac/heatcool/fcu.py +92 -0
- honeybee_energy/hvac/heatcool/gasunit.py +53 -0
- honeybee_energy/hvac/heatcool/radiant.py +269 -0
- honeybee_energy/hvac/heatcool/residential.py +77 -0
- honeybee_energy/hvac/heatcool/vrf.py +54 -0
- honeybee_energy/hvac/heatcool/windowac.py +70 -0
- honeybee_energy/hvac/heatcool/wshp.py +62 -0
- honeybee_energy/hvac/idealair.py +699 -0
- honeybee_energy/internalmass.py +310 -0
- honeybee_energy/lib/__init__.py +1 -0
- honeybee_energy/lib/_loadconstructions.py +194 -0
- honeybee_energy/lib/_loadconstructionsets.py +117 -0
- honeybee_energy/lib/_loadmaterials.py +83 -0
- honeybee_energy/lib/_loadprogramtypes.py +125 -0
- honeybee_energy/lib/_loadschedules.py +87 -0
- honeybee_energy/lib/_loadtypelimits.py +64 -0
- honeybee_energy/lib/constructions.py +207 -0
- honeybee_energy/lib/constructionsets.py +95 -0
- honeybee_energy/lib/materials.py +67 -0
- honeybee_energy/lib/programtypes.py +125 -0
- honeybee_energy/lib/schedules.py +61 -0
- honeybee_energy/lib/scheduletypelimits.py +31 -0
- honeybee_energy/load/__init__.py +1 -0
- honeybee_energy/load/_base.py +190 -0
- honeybee_energy/load/daylight.py +397 -0
- honeybee_energy/load/dictutil.py +47 -0
- honeybee_energy/load/equipment.py +771 -0
- honeybee_energy/load/hotwater.py +543 -0
- honeybee_energy/load/infiltration.py +460 -0
- honeybee_energy/load/lighting.py +480 -0
- honeybee_energy/load/people.py +497 -0
- honeybee_energy/load/process.py +472 -0
- honeybee_energy/load/setpoint.py +816 -0
- honeybee_energy/load/ventilation.py +550 -0
- honeybee_energy/material/__init__.py +1 -0
- honeybee_energy/material/_base.py +166 -0
- honeybee_energy/material/dictutil.py +59 -0
- honeybee_energy/material/frame.py +367 -0
- honeybee_energy/material/gas.py +1087 -0
- honeybee_energy/material/glazing.py +854 -0
- honeybee_energy/material/opaque.py +1351 -0
- honeybee_energy/material/shade.py +1360 -0
- honeybee_energy/measure.py +472 -0
- honeybee_energy/programtype.py +723 -0
- honeybee_energy/properties/__init__.py +1 -0
- honeybee_energy/properties/aperture.py +333 -0
- honeybee_energy/properties/door.py +342 -0
- honeybee_energy/properties/extension.py +244 -0
- honeybee_energy/properties/face.py +274 -0
- honeybee_energy/properties/model.py +2640 -0
- honeybee_energy/properties/room.py +1747 -0
- honeybee_energy/properties/shade.py +314 -0
- honeybee_energy/properties/shademesh.py +262 -0
- honeybee_energy/reader.py +48 -0
- honeybee_energy/result/__init__.py +1 -0
- honeybee_energy/result/colorobj.py +648 -0
- honeybee_energy/result/emissions.py +290 -0
- honeybee_energy/result/err.py +101 -0
- honeybee_energy/result/eui.py +100 -0
- honeybee_energy/result/generation.py +160 -0
- honeybee_energy/result/loadbalance.py +890 -0
- honeybee_energy/result/match.py +202 -0
- honeybee_energy/result/osw.py +90 -0
- honeybee_energy/result/rdd.py +59 -0
- honeybee_energy/result/zsz.py +190 -0
- honeybee_energy/run.py +1577 -0
- honeybee_energy/schedule/__init__.py +1 -0
- honeybee_energy/schedule/day.py +626 -0
- honeybee_energy/schedule/dictutil.py +59 -0
- honeybee_energy/schedule/fixedinterval.py +1012 -0
- honeybee_energy/schedule/rule.py +619 -0
- honeybee_energy/schedule/ruleset.py +1867 -0
- honeybee_energy/schedule/typelimit.py +310 -0
- honeybee_energy/shw.py +315 -0
- honeybee_energy/simulation/__init__.py +1 -0
- honeybee_energy/simulation/control.py +214 -0
- honeybee_energy/simulation/daylightsaving.py +185 -0
- honeybee_energy/simulation/dictutil.py +51 -0
- honeybee_energy/simulation/output.py +646 -0
- honeybee_energy/simulation/parameter.py +606 -0
- honeybee_energy/simulation/runperiod.py +443 -0
- honeybee_energy/simulation/shadowcalculation.py +295 -0
- honeybee_energy/simulation/sizing.py +546 -0
- honeybee_energy/ventcool/__init__.py +5 -0
- honeybee_energy/ventcool/_crack_data.py +91 -0
- honeybee_energy/ventcool/afn.py +289 -0
- honeybee_energy/ventcool/control.py +269 -0
- honeybee_energy/ventcool/crack.py +126 -0
- honeybee_energy/ventcool/fan.py +493 -0
- honeybee_energy/ventcool/opening.py +365 -0
- honeybee_energy/ventcool/simulation.py +314 -0
- honeybee_energy/writer.py +1078 -0
- honeybee_energy-1.116.106.dist-info/METADATA +113 -0
- honeybee_energy-1.116.106.dist-info/RECORD +162 -0
- honeybee_energy-1.116.106.dist-info/WHEEL +5 -0
- honeybee_energy-1.116.106.dist-info/entry_points.txt +2 -0
- honeybee_energy-1.116.106.dist-info/licenses/LICENSE +661 -0
- 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)
|