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,569 @@
|
|
|
1
|
+
"""commands to generate honeybee energy simulation settings."""
|
|
2
|
+
import click
|
|
3
|
+
import sys
|
|
4
|
+
import logging
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
|
|
8
|
+
from ladybug.futil import preparedir
|
|
9
|
+
from ladybug.analysisperiod import AnalysisPeriod
|
|
10
|
+
from ladybug.dt import Date
|
|
11
|
+
from honeybee.config import folders
|
|
12
|
+
from honeybee.model import Model
|
|
13
|
+
|
|
14
|
+
from honeybee_energy.simulation.parameter import SimulationParameter
|
|
15
|
+
from honeybee_energy.simulation.runperiod import RunPeriod
|
|
16
|
+
from honeybee_energy.simulation.control import SimulationControl
|
|
17
|
+
from honeybee_energy.construction.windowshade import WindowConstructionShade
|
|
18
|
+
from honeybee_energy.construction.dynamic import WindowConstructionDynamic
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
_logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@click.group(help='Commands for simulating Honeybee JSON files in EnergyPlus.')
|
|
25
|
+
def settings():
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@settings.command('default-sim-par')
|
|
30
|
+
@click.argument('ddy-file', type=click.Path(
|
|
31
|
+
file_okay=True, dir_okay=False, resolve_path=True))
|
|
32
|
+
@click.option(
|
|
33
|
+
'--reporting-frequency', '-rf', help='Text for the frequency at which '
|
|
34
|
+
'the outputs are reported. (Default: Hourly). Choose from the following: '
|
|
35
|
+
'Annual, Monthly, Daily, Hourly, Timestep', default='Hourly', type=str)
|
|
36
|
+
@click.option(
|
|
37
|
+
'--run-period', '-rp', help='An AnalysisPeriod or RunPeriod string '
|
|
38
|
+
'to dictate the start and end of the simulation '
|
|
39
|
+
'(eg. "6/21 to 9/21 between 0 and 23 @1"). If unspecified, the '
|
|
40
|
+
'simulation will be for the whole year.', default=None, type=str)
|
|
41
|
+
@click.option(
|
|
42
|
+
'--north', '-n', default=0, type=float, show_default=True,
|
|
43
|
+
help='Number from -360 to 360 for the counterclockwise difference between '
|
|
44
|
+
'North and the positive Y-axis in degrees. 90 is west; 270 is east')
|
|
45
|
+
@click.option(
|
|
46
|
+
'--filter-des-days/--all-des-days', ' /-all', help='Flag to note whether '
|
|
47
|
+
'the design days in the ddy-file should be filtered to only include 99.6 '
|
|
48
|
+
'and 0.4 design days.', default=True, show_default=True)
|
|
49
|
+
@click.option(
|
|
50
|
+
'--efficiency-standard', '-es', help='Text to set the efficiency standard, which '
|
|
51
|
+
'will automatically set the efficiencies of all HVAC equipment when provided. '
|
|
52
|
+
'Note that providing a standard here will cause the OpenStudio translation '
|
|
53
|
+
'process to perform an additional sizing calculation with EnergyPlus, '
|
|
54
|
+
'which is needed since the default efficiencies of equipment vary depending '
|
|
55
|
+
'on their size. THIS WILL SIGNIFICANTLY INCREASE TRANSLATION TIME. '
|
|
56
|
+
'However, it is often worthwhile when the goal is to match the '
|
|
57
|
+
'HVAC specification with a particular standard.Choose from the following: '
|
|
58
|
+
'DOE_Ref_Pre_1980, DOE_Ref_1980_2004, ASHRAE_2004, ASHRAE_2007, ASHRAE_2010, '
|
|
59
|
+
'ASHRAE_2013, ASHRAE_2016, ASHRAE_2019', default=None, type=str)
|
|
60
|
+
@click.option(
|
|
61
|
+
'--climate-zone', '-cz', help='Text indicating the ASHRAE climate zone to be '
|
|
62
|
+
'used with the efficiency_standard. When unspecified, the climate zone will be '
|
|
63
|
+
'inferred from the design days. This input can be a single integer (in which '
|
|
64
|
+
'case it is interpreted as A) or it can include the A, B, or C qualifier '
|
|
65
|
+
'(eg. 3C).', default=None, type=str)
|
|
66
|
+
@click.option(
|
|
67
|
+
'--building-type', '-bt', help='Text for the building type to be used in '
|
|
68
|
+
'the efficiency_standard. If the type is not recognized or is None, it will '
|
|
69
|
+
'be assumed that the building is a generic NonResidential.',
|
|
70
|
+
default=None, type=str)
|
|
71
|
+
@click.option(
|
|
72
|
+
'--output-file', '-f', help='Optional file to output the JSON string of '
|
|
73
|
+
'the simulation parameters. By default, it will be printed to stdout.',
|
|
74
|
+
type=click.File('w'), default='-', show_default=True)
|
|
75
|
+
def default_sim_par(
|
|
76
|
+
ddy_file, reporting_frequency, run_period, north, filter_des_days,
|
|
77
|
+
efficiency_standard, climate_zone, building_type, output_file):
|
|
78
|
+
"""Get a SimulationParameter JSON with default outputs for energy use only.
|
|
79
|
+
|
|
80
|
+
\b
|
|
81
|
+
Args:
|
|
82
|
+
ddy_file: Full path to a DDY file that will be used to specify design days
|
|
83
|
+
within the simulation parameter.
|
|
84
|
+
"""
|
|
85
|
+
try:
|
|
86
|
+
sim_par = SimulationParameter()
|
|
87
|
+
sim_par.output.add_zone_energy_use()
|
|
88
|
+
sim_par.output.add_hvac_energy_use()
|
|
89
|
+
sim_par.output.add_electricity_generation()
|
|
90
|
+
sim_par.output.reporting_frequency = reporting_frequency
|
|
91
|
+
_apply_run_period(run_period, sim_par)
|
|
92
|
+
sim_par.north_angle = north
|
|
93
|
+
if os.path.isfile(ddy_file):
|
|
94
|
+
_apply_design_days(ddy_file, filter_des_days, sim_par)
|
|
95
|
+
if efficiency_standard is not None and efficiency_standard != '':
|
|
96
|
+
sim_par.sizing_parameter.efficiency_standard = efficiency_standard
|
|
97
|
+
if climate_zone is not None and climate_zone != '':
|
|
98
|
+
sim_par.sizing_parameter.climate_zone = climate_zone
|
|
99
|
+
if building_type is not None and building_type != '':
|
|
100
|
+
sim_par.sizing_parameter.building_type = building_type
|
|
101
|
+
output_file.write(json.dumps(sim_par.to_dict()))
|
|
102
|
+
except Exception as e:
|
|
103
|
+
_logger.exception('Failed to generate simulation parameter.\n{}'.format(e))
|
|
104
|
+
sys.exit(1)
|
|
105
|
+
else:
|
|
106
|
+
sys.exit(0)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@settings.command('load-balance-sim-par')
|
|
110
|
+
@click.argument('ddy-file', type=click.Path(
|
|
111
|
+
file_okay=True, dir_okay=False, resolve_path=True))
|
|
112
|
+
@click.option('--load-type', '-lt', help='A text value to set the type of load outputs '
|
|
113
|
+
'requested. Choose from the following:\nAll - all energy use '
|
|
114
|
+
'including heat lost from the zone\nTotal - the total load added to the '
|
|
115
|
+
'zone (both sensible and latent)\nSensible - the sensible load added to '
|
|
116
|
+
'the zone\nLatent - the latent load added to the zone.',
|
|
117
|
+
type=str, default='Total', show_default=True)
|
|
118
|
+
@click.option('--reporting-frequency', '-rf', help='Text for the frequency at which '
|
|
119
|
+
'the outputs are reported. (Default: Hourly). Choose from the following: '
|
|
120
|
+
'Annual, Monthly, Daily, Hourly Timestep', default='Hourly', type=str)
|
|
121
|
+
@click.option('--run-period', '-rp', help='An AnalysisPeriod or RunPeriod string '
|
|
122
|
+
'to dictate the start and end of the simulation '
|
|
123
|
+
'(eg. "6/21 to 9/21 between 0 and 23 @1"). If unspecified, the '
|
|
124
|
+
'simulation will be for the whole year.', default=None, type=str)
|
|
125
|
+
@click.option('--north', '-n', default=0, type=float, show_default=True,
|
|
126
|
+
help='Number from -360 to 360 for the counterclockwise difference between '
|
|
127
|
+
'North and the positive Y-axis in degrees. 90 is west; 270 is east')
|
|
128
|
+
@click.option('--filter-des-days/--all-des-days', ' /-all', help='Flag to note whether '
|
|
129
|
+
'the design days in the ddy-file should be filtered to only include 99.6 '
|
|
130
|
+
'and 0.4 design days.', default=True, show_default=True)
|
|
131
|
+
@click.option('--output-file', '-f', help='Optional file to output the JSON string of '
|
|
132
|
+
'the simulation parameters. By default, it will be printed to stdout.',
|
|
133
|
+
type=click.File('w'), default='-', show_default=True)
|
|
134
|
+
def load_balance_sim_par(ddy_file, load_type, reporting_frequency, run_period, north,
|
|
135
|
+
filter_des_days, output_file):
|
|
136
|
+
"""Get a SimulationParameter JSON with outputs for thermal load balances.
|
|
137
|
+
|
|
138
|
+
\b
|
|
139
|
+
Args:
|
|
140
|
+
ddy_file: Full path to a DDY file that will be used to specify design days
|
|
141
|
+
within the simulation parameter.
|
|
142
|
+
"""
|
|
143
|
+
try:
|
|
144
|
+
sim_par = SimulationParameter()
|
|
145
|
+
sim_par.output.add_zone_energy_use(load_type)
|
|
146
|
+
gl_load_type = load_type if load_type != 'All' else 'Total'
|
|
147
|
+
sim_par.output.add_gains_and_losses(gl_load_type)
|
|
148
|
+
sim_par.output.add_surface_energy_flow()
|
|
149
|
+
sim_par.output.reporting_frequency = reporting_frequency
|
|
150
|
+
_apply_run_period(run_period, sim_par)
|
|
151
|
+
sim_par.north_angle = north
|
|
152
|
+
if os.path.isfile(ddy_file):
|
|
153
|
+
_apply_design_days(ddy_file, filter_des_days, sim_par)
|
|
154
|
+
output_file.write(json.dumps(sim_par.to_dict()))
|
|
155
|
+
except Exception as e:
|
|
156
|
+
_logger.exception('Failed to generate simulation parameter.\n{}'.format(e))
|
|
157
|
+
sys.exit(1)
|
|
158
|
+
else:
|
|
159
|
+
sys.exit(0)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
@settings.command('comfort-sim-par')
|
|
163
|
+
@click.argument('ddy-file', type=click.Path(
|
|
164
|
+
file_okay=True, dir_okay=False, resolve_path=True))
|
|
165
|
+
@click.option('--run-period', '-rp', help='An AnalysisPeriod or RunPeriod string '
|
|
166
|
+
'to dictate the start and end of the simulation '
|
|
167
|
+
'(eg. "6/21 to 9/21 between 0 and 23 @1"). If unspecified, the '
|
|
168
|
+
'simulation will be for the whole year.', default=None, type=str)
|
|
169
|
+
@click.option('--north', '-n', default=0, type=float, show_default=True,
|
|
170
|
+
help='Number from -360 to 360 for the counterclockwise difference between '
|
|
171
|
+
'North and the positive Y-axis in degrees. 90 is west; 270 is east')
|
|
172
|
+
@click.option('--filter-des-days/--all-des-days', ' /-all', help='Flag to note whether '
|
|
173
|
+
'the design days in the ddy-file should be filtered to only include 99.6 '
|
|
174
|
+
'and 0.4 design days.', default=True, show_default=True)
|
|
175
|
+
@click.option('--output-file', '-f', help='Optional file to output the JSON string of '
|
|
176
|
+
'the simulation parameters. By default, it will be printed to stdout.',
|
|
177
|
+
type=click.File('w'), default='-', show_default=True)
|
|
178
|
+
def comfort_sim_par(ddy_file, run_period, north, filter_des_days, output_file):
|
|
179
|
+
"""Get a SimulationParameter JSON with outputs for thermal comfort mapping.
|
|
180
|
+
|
|
181
|
+
\b
|
|
182
|
+
Args:
|
|
183
|
+
ddy_file: Full path to a DDY file that will be used to specify design days
|
|
184
|
+
within the simulation parameter.
|
|
185
|
+
"""
|
|
186
|
+
try:
|
|
187
|
+
sim_par = SimulationParameter()
|
|
188
|
+
sim_par.shadow_calculation.solar_distribution = \
|
|
189
|
+
'FullInteriorAndExteriorWithReflections'
|
|
190
|
+
sim_par.output.add_comfort_metrics()
|
|
191
|
+
sim_par.output.add_surface_temperature()
|
|
192
|
+
_apply_run_period(run_period, sim_par)
|
|
193
|
+
sim_par.north_angle = north
|
|
194
|
+
if os.path.isfile(ddy_file):
|
|
195
|
+
_apply_design_days(ddy_file, filter_des_days, sim_par)
|
|
196
|
+
output_file.write(json.dumps(sim_par.to_dict()))
|
|
197
|
+
except Exception as e:
|
|
198
|
+
_logger.exception('Failed to generate simulation parameter.\n{}'.format(e))
|
|
199
|
+
sys.exit(1)
|
|
200
|
+
else:
|
|
201
|
+
sys.exit(0)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
@settings.command('sizing-sim-par')
|
|
205
|
+
@click.argument('ddy-file', type=click.Path(
|
|
206
|
+
file_okay=True, dir_okay=False, resolve_path=True))
|
|
207
|
+
@click.option('--load-type', '-lt', help='A text value to set the type of load outputs '
|
|
208
|
+
'requested. Choose from the following:\nAll - all energy use '
|
|
209
|
+
'including heat lost from the zone\nTotal - the total load added to the '
|
|
210
|
+
'zone (both sensible and latent)\nSensible - the sensible load added to '
|
|
211
|
+
'the zone\nLatent - the latent load added to the zone.',
|
|
212
|
+
type=str, default='Total', show_default=True)
|
|
213
|
+
@click.option('--north', '-n', default=0, type=float, show_default=True,
|
|
214
|
+
help='Number from -360 to 360 for the counterclockwise difference between '
|
|
215
|
+
'North and the positive Y-axis in degrees. 90 is west; 270 is east')
|
|
216
|
+
@click.option('--filter-des-days/--all-des-days', ' /-all', help='Flag to note whether '
|
|
217
|
+
'the design days in the ddy-file should be filtered to only include 99.6 '
|
|
218
|
+
'and 0.4 design days.', default=True, show_default=True)
|
|
219
|
+
@click.option('--output-file', '-f', help='Optional file to output the JSON string of '
|
|
220
|
+
'the simulation parameters. By default, it will be printed to stdout.',
|
|
221
|
+
type=click.File('w'), default='-', show_default=True)
|
|
222
|
+
def sizing_sim_par(ddy_file, load_type, north, filter_des_days, output_file):
|
|
223
|
+
"""Get a SimulationParameter JSON with outputs and run period for HVAC sizing.
|
|
224
|
+
|
|
225
|
+
\b
|
|
226
|
+
Args:
|
|
227
|
+
ddy_file: Full path to a DDY file that will be used to specify design days
|
|
228
|
+
within the simulation parameter.
|
|
229
|
+
"""
|
|
230
|
+
try:
|
|
231
|
+
sim_par = SimulationParameter()
|
|
232
|
+
sim_par.output.add_zone_energy_use(load_type)
|
|
233
|
+
gl_load_type = load_type if load_type != 'All' else 'Total'
|
|
234
|
+
sim_par.output.add_gains_and_losses(gl_load_type)
|
|
235
|
+
sim_par.output.add_surface_energy_flow()
|
|
236
|
+
sim_par.simulation_control = SimulationControl(True, True, True, True, False)
|
|
237
|
+
sim_par.north_angle = north
|
|
238
|
+
if os.path.isfile(ddy_file):
|
|
239
|
+
_apply_design_days(ddy_file, filter_des_days, sim_par)
|
|
240
|
+
output_file.write(json.dumps(sim_par.to_dict()))
|
|
241
|
+
except Exception as e:
|
|
242
|
+
_logger.exception('Failed to generate simulation parameter.\n{}'.format(e))
|
|
243
|
+
sys.exit(1)
|
|
244
|
+
else:
|
|
245
|
+
sys.exit(0)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
@settings.command('custom-sim-par')
|
|
249
|
+
@click.argument('ddy-file', type=click.Path(
|
|
250
|
+
file_okay=True, dir_okay=False, resolve_path=True))
|
|
251
|
+
@click.argument('output-names', nargs=-1)
|
|
252
|
+
@click.option('--reporting-frequency', '-rf', help='Text for the frequency at which '
|
|
253
|
+
'the outputs are reported. (Default: Hourly). Choose from the following: '
|
|
254
|
+
'Annual, Monthly, Daily, Hourly Timestep', default='Hourly', type=str)
|
|
255
|
+
@click.option('--run-period', '-rp', help='An AnalysisPeriod or RunPeriod string '
|
|
256
|
+
'to dictate the start and end of the simulation '
|
|
257
|
+
'(eg. "6/21 to 9/21 between 0 and 23 @1"). If unspecified, the '
|
|
258
|
+
'simulation will be for the whole year.', default=None, type=str)
|
|
259
|
+
@click.option('--north', '-n', default=0, type=float, show_default=True,
|
|
260
|
+
help='Number from -360 to 360 for the counterclockwise difference between '
|
|
261
|
+
'North and the positive Y-axis in degrees. 90 is west; 270 is east')
|
|
262
|
+
@click.option('--filter-des-days/--all-des-days', ' /-all', help='Flag to note whether '
|
|
263
|
+
'the design days in the ddy-file should be filtered to only include 99.6 '
|
|
264
|
+
'and 0.4 design days.', default=True, show_default=True)
|
|
265
|
+
@click.option('--output-file', '-f', help='Optional file to output the JSON string of '
|
|
266
|
+
'the simulation parameters. By default, it will be printed to stdout.',
|
|
267
|
+
type=click.File('w'), default='-', show_default=True)
|
|
268
|
+
def custom_sim_par(ddy_file, output_names, reporting_frequency, run_period, north,
|
|
269
|
+
filter_des_days, output_file):
|
|
270
|
+
"""Get a SimulationParameter JSON with an option for custom outputs.
|
|
271
|
+
|
|
272
|
+
\b
|
|
273
|
+
Args:
|
|
274
|
+
ddy_file: Full path to a DDY file that will be used to specify design days
|
|
275
|
+
within the simulation parameter.
|
|
276
|
+
output_names: Any number of EnergyPlus output names as strings (eg.
|
|
277
|
+
'Surface Window System Solar Transmittance'. These outputs will be
|
|
278
|
+
requested from the simulation.
|
|
279
|
+
"""
|
|
280
|
+
try:
|
|
281
|
+
sim_par = SimulationParameter()
|
|
282
|
+
for output_name in output_names:
|
|
283
|
+
sim_par.output.add_output(output_name)
|
|
284
|
+
sim_par.output.reporting_frequency = reporting_frequency
|
|
285
|
+
_apply_run_period(run_period, sim_par)
|
|
286
|
+
sim_par.north_angle = north
|
|
287
|
+
if os.path.isfile(ddy_file):
|
|
288
|
+
_apply_design_days(ddy_file, filter_des_days, sim_par)
|
|
289
|
+
output_file.write(json.dumps(sim_par.to_dict()))
|
|
290
|
+
except Exception as e:
|
|
291
|
+
_logger.exception('Failed to generate simulation parameter.\n{}'.format(e))
|
|
292
|
+
sys.exit(1)
|
|
293
|
+
else:
|
|
294
|
+
sys.exit(0)
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
@settings.command('orientation-sim-pars')
|
|
298
|
+
@click.argument('ddy-file', type=click.Path(
|
|
299
|
+
file_okay=True, dir_okay=False, resolve_path=True))
|
|
300
|
+
@click.argument('north-angles', nargs=-1, type=float)
|
|
301
|
+
@click.option('--default-outputs/--no-default-outputs', ' /-nd', help='Flag to note '
|
|
302
|
+
'whether the default outputs for energy usage should be included in '
|
|
303
|
+
'the simulation parameters or no outputs should be requested except '
|
|
304
|
+
'for those explicitly listed with --output-name.',
|
|
305
|
+
default=True, show_default=True)
|
|
306
|
+
@click.option('--output-name', '-o', help='Any number of EnergyPlus output names as '
|
|
307
|
+
'strings (eg. Surface Window System Solar Transmittance). These outputs '
|
|
308
|
+
'will be requested from the simulation.',
|
|
309
|
+
type=click.STRING, multiple=True, default=None, show_default=True)
|
|
310
|
+
@click.option('--reporting-frequency', '-rf', help='Text for the frequency at which '
|
|
311
|
+
'the outputs are reported. (Default: Hourly). Choose from the following: '
|
|
312
|
+
'Annual, Monthly, Daily, Hourly Timestep', default='Hourly', type=str)
|
|
313
|
+
@click.option('--run-period', '-rp', help='An AnalysisPeriod or RunPeriod string '
|
|
314
|
+
'to dictate the start and end of the simulation '
|
|
315
|
+
'(eg. "6/21 to 9/21 between 0 and 23 @1"). If unspecified, the '
|
|
316
|
+
'simulation will be for the whole year.', default=None, type=str)
|
|
317
|
+
@click.option('--start-north', '-n', default=0, type=float, show_default=True,
|
|
318
|
+
help='Number from -360 to 360 for the starting north angle. This will be '
|
|
319
|
+
'added to the north-angles in order to shift all norths.')
|
|
320
|
+
@click.option('--filter-des-days/--all-des-days', ' /-all', help='Flag to note whether '
|
|
321
|
+
'the design days in the ddy-file should be filtered to only include 99.6 '
|
|
322
|
+
'and 0.4 design days.', default=True, show_default=True)
|
|
323
|
+
@click.option(
|
|
324
|
+
'--efficiency-standard', '-es', help='Text to set the efficiency standard, which '
|
|
325
|
+
'will automatically set the efficiencies of all HVAC equipment when provided. '
|
|
326
|
+
'Note that providing a standard here will cause the OpenStudio translation '
|
|
327
|
+
'process to perform an additional sizing calculation with EnergyPlus, '
|
|
328
|
+
'which is needed since the default efficiencies of equipment vary depending '
|
|
329
|
+
'on their size. THIS WILL SIGNIFICANTLY INCREASE TRANSLATION TIME. '
|
|
330
|
+
'However, it is often worthwhile when the goal is to match the '
|
|
331
|
+
'HVAC specification with a particular standard.Choose from the following: '
|
|
332
|
+
'DOE_Ref_Pre_1980, DOE_Ref_1980_2004, ASHRAE_2004, ASHRAE_2007, ASHRAE_2010, '
|
|
333
|
+
'ASHRAE_2013, ASHRAE_2016, ASHRAE_2019', default=None, type=str)
|
|
334
|
+
@click.option(
|
|
335
|
+
'--climate-zone', '-cz', help='Text indicating the ASHRAE climate zone to be '
|
|
336
|
+
'used with the efficiency_standard. When unspecified, the climate zone will be '
|
|
337
|
+
'inferred from the design days. This input can be a single integer (in which '
|
|
338
|
+
'case it is interpreted as A) or it can include the A, B, or C qualifier '
|
|
339
|
+
'(eg. 3C).', default=None, type=str)
|
|
340
|
+
@click.option(
|
|
341
|
+
'--building-type', '-bt', help='Text for the building type to be used in '
|
|
342
|
+
'the efficiency_standard. If the type is not recognized or is None, it will '
|
|
343
|
+
'be assumed that the building is a generic NonResidential.', default=None, type=str)
|
|
344
|
+
@click.option('--folder', '-f', help='Output folder for the simulation parameter JSONS.',
|
|
345
|
+
default=None, show_default=True,
|
|
346
|
+
type=click.Path(file_okay=False, dir_okay=True, resolve_path=True))
|
|
347
|
+
@click.option('--log-file', '-log', help='Optional log file to output the paths of the '
|
|
348
|
+
'simulation parameters. By default the list will be printed out to '
|
|
349
|
+
'stdout.', type=click.File('w'), default='-')
|
|
350
|
+
def orientation_sim_pars(
|
|
351
|
+
ddy_file, north_angles, default_outputs, output_name, reporting_frequency,
|
|
352
|
+
run_period, start_north, filter_des_days,
|
|
353
|
+
efficiency_standard, climate_zone, building_type, folder, log_file):
|
|
354
|
+
"""Get SimulationParameter JSONs with different north angles for orientation studies.
|
|
355
|
+
|
|
356
|
+
\b
|
|
357
|
+
Args:
|
|
358
|
+
ddy_file: Full path to a DDY file that will be used to specify design days
|
|
359
|
+
within the simulation parameter.
|
|
360
|
+
north_angles: Any number of values between -360 and 360 for the counterclockwise
|
|
361
|
+
difference between the North and the positive Y-axis in degrees. 90 is
|
|
362
|
+
West and 270 is East.
|
|
363
|
+
"""
|
|
364
|
+
try:
|
|
365
|
+
# get a default folder if none was specified
|
|
366
|
+
if folder is None:
|
|
367
|
+
folder = os.path.join(folders.default_simulation_folder, 'orientation_study')
|
|
368
|
+
preparedir(folder, remove_content=False)
|
|
369
|
+
|
|
370
|
+
# create a base set of simulation parameters to be edited parametrically
|
|
371
|
+
sim_par = SimulationParameter()
|
|
372
|
+
if default_outputs:
|
|
373
|
+
sim_par.output.add_zone_energy_use()
|
|
374
|
+
sim_par.output.add_hvac_energy_use()
|
|
375
|
+
sim_par.output.add_electricity_generation()
|
|
376
|
+
for out_name in output_name:
|
|
377
|
+
sim_par.output.add_output(out_name)
|
|
378
|
+
sim_par.output.reporting_frequency = reporting_frequency
|
|
379
|
+
_apply_run_period(run_period, sim_par)
|
|
380
|
+
if os.path.isfile(ddy_file):
|
|
381
|
+
_apply_design_days(ddy_file, filter_des_days, sim_par)
|
|
382
|
+
|
|
383
|
+
# set the sizing parameters if specified
|
|
384
|
+
if efficiency_standard is not None and efficiency_standard != '':
|
|
385
|
+
sim_par.sizing_parameter.efficiency_standard = efficiency_standard
|
|
386
|
+
if climate_zone is not None and climate_zone != '':
|
|
387
|
+
sim_par.sizing_parameter.climate_zone = climate_zone
|
|
388
|
+
if building_type is not None and building_type != '':
|
|
389
|
+
sim_par.sizing_parameter.building_type = building_type
|
|
390
|
+
|
|
391
|
+
# shift all of the north angles by the start_north if specified
|
|
392
|
+
if start_north != 0:
|
|
393
|
+
north_angles = [angle + start_north for angle in north_angles]
|
|
394
|
+
for i, angle in enumerate(north_angles):
|
|
395
|
+
angle = angle - 360 if angle > 360 else angle
|
|
396
|
+
angle = angle + 360 if angle < -360 else angle
|
|
397
|
+
north_angles[i] = angle
|
|
398
|
+
|
|
399
|
+
# loop through the north angles and write a simulation parameter for each
|
|
400
|
+
json_files = []
|
|
401
|
+
for angle in north_angles:
|
|
402
|
+
sim_par.north_angle = angle
|
|
403
|
+
base_name = 'sim_par_north_{}'.format(int(angle))
|
|
404
|
+
file_name = '{}.json'.format(base_name)
|
|
405
|
+
file_path = os.path.join(folder, file_name)
|
|
406
|
+
with open(file_path, 'w') as fp:
|
|
407
|
+
json.dump(sim_par.to_dict(), fp)
|
|
408
|
+
sp_info = {
|
|
409
|
+
'id': base_name,
|
|
410
|
+
'path': file_name,
|
|
411
|
+
'full_path': os.path.abspath(file_path)
|
|
412
|
+
}
|
|
413
|
+
json_files.append(sp_info)
|
|
414
|
+
log_file.write(json.dumps(json_files))
|
|
415
|
+
except Exception as e:
|
|
416
|
+
_logger.exception('Failed to generate simulation parameters.\n{}'.format(e))
|
|
417
|
+
sys.exit(1)
|
|
418
|
+
else:
|
|
419
|
+
sys.exit(0)
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
@settings.command('run-period')
|
|
423
|
+
@click.argument('start-month', type=int)
|
|
424
|
+
@click.argument('start-day', type=int)
|
|
425
|
+
@click.argument('end-month', type=int)
|
|
426
|
+
@click.argument('end-day', type=int)
|
|
427
|
+
@click.option('--start-day-of-week', '-dow', help='Text for the day of the week '
|
|
428
|
+
'on which the simulation starts.', type=str, default='Sunday',
|
|
429
|
+
show_default=True)
|
|
430
|
+
@click.option('--holidays', '-h', help='Text for the holidays within the simulation. '
|
|
431
|
+
'Dates should be formatted as follows: "[day int] [month text]" '
|
|
432
|
+
'(eg. "25 Dec"). If not specified, no holidays are applied.',
|
|
433
|
+
type=str, default=None, show_default=True, multiple=True)
|
|
434
|
+
@click.option('--output-file', '-f', help='Optional file to output the JSON string of '
|
|
435
|
+
'the run period. By default, it will be printed to stdout.',
|
|
436
|
+
type=click.File('w'), default='-', show_default=True)
|
|
437
|
+
def run_period(start_month, start_day, end_month, end_day, start_day_of_week,
|
|
438
|
+
holidays, output_file):
|
|
439
|
+
"""Get a RunPeriod string that can be used to set the simulation run period.
|
|
440
|
+
|
|
441
|
+
\b
|
|
442
|
+
Args:
|
|
443
|
+
start_month: Start month (1-12).
|
|
444
|
+
start_day: Start day (1-31).
|
|
445
|
+
end_month: End month (1-12).
|
|
446
|
+
end_day: End day (1-31).
|
|
447
|
+
"""
|
|
448
|
+
try:
|
|
449
|
+
# create the run period
|
|
450
|
+
a_period = AnalysisPeriod(start_month, start_day, 0, end_month, end_day, 23)
|
|
451
|
+
run_period = RunPeriod.from_analysis_period(a_period)
|
|
452
|
+
# set the start day of the week if it is input
|
|
453
|
+
if start_day_of_week is not None:
|
|
454
|
+
run_period.start_day_of_week = start_day_of_week.title()
|
|
455
|
+
# set the holidays if requested.
|
|
456
|
+
if holidays:
|
|
457
|
+
dates = tuple(Date.from_date_string(date) for date in holidays)
|
|
458
|
+
run_period.holidays = dates
|
|
459
|
+
output_file.write(str(run_period))
|
|
460
|
+
except Exception as e:
|
|
461
|
+
_logger.exception('Failed to generate run period.\n{}'.format(e))
|
|
462
|
+
sys.exit(1)
|
|
463
|
+
else:
|
|
464
|
+
sys.exit(0)
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
@settings.command('dynamic-window-outputs')
|
|
468
|
+
@click.argument('model-file', type=click.Path(
|
|
469
|
+
exists=True, file_okay=True, dir_okay=False, resolve_path=True))
|
|
470
|
+
@click.option(
|
|
471
|
+
'--base-idf', '-i', help='An optional base IDF file to which the outputs '
|
|
472
|
+
'for dynamic windows will be appended.', default=None, show_default=True,
|
|
473
|
+
type=click.Path(exists=False, file_okay=True, dir_okay=False, resolve_path=True))
|
|
474
|
+
@click.option(
|
|
475
|
+
'--output-file', '-f', help='Optional IDF file to output the list of outputs to '
|
|
476
|
+
'add to the EnergyPlus simulation. By default this will be printed out to '
|
|
477
|
+
'stdout', type=click.File('w'), default='-', show_default=True)
|
|
478
|
+
def dynamic_window_outputs(model_file, base_idf, output_file):
|
|
479
|
+
"""Get an IDF string that requests transmittance outputs for dynamic windows.
|
|
480
|
+
|
|
481
|
+
This should be used within comfort mapping workflows to request transmittance
|
|
482
|
+
outputs for dynamic windows. Note that the output is just an IDF text string
|
|
483
|
+
that should be incorporated in the energy simulation by means of additional
|
|
484
|
+
strings or additional IDF.
|
|
485
|
+
|
|
486
|
+
\b
|
|
487
|
+
Args:
|
|
488
|
+
model_file: Full path to a Model JSON or Pkl file to be analyzed for
|
|
489
|
+
dynamic window constructions.
|
|
490
|
+
"""
|
|
491
|
+
try:
|
|
492
|
+
# define templates to be reused for each dynamic window
|
|
493
|
+
out_vars = [
|
|
494
|
+
'Surface Window Transmitted Beam to Beam Solar Radiation Rate',
|
|
495
|
+
'Surface Window Transmitted Beam to Diffuse Solar Radiation Rate',
|
|
496
|
+
'Surface Window Transmitted Diffuse Solar Radiation Rate',
|
|
497
|
+
'Surface Outside Face Incident Solar Radiation Rate per Area',
|
|
498
|
+
]
|
|
499
|
+
out_per_win = ['Output:Variable, {}, ' + var + ', Timestep;' for var in out_vars]
|
|
500
|
+
|
|
501
|
+
# define dynamic constructions and re-serialize the Model to Python
|
|
502
|
+
dyn_con = (WindowConstructionShade, WindowConstructionDynamic)
|
|
503
|
+
model = Model.from_file(model_file)
|
|
504
|
+
|
|
505
|
+
# load up the contents of the base IDF file if it exists
|
|
506
|
+
out_strs = []
|
|
507
|
+
if base_idf is not None and os.path.isfile(base_idf):
|
|
508
|
+
with open(base_idf, "r") as add_idf_file:
|
|
509
|
+
out_strs.append(add_idf_file.read())
|
|
510
|
+
|
|
511
|
+
# loop through the apertures and add outputs to be requested
|
|
512
|
+
for room in model.rooms:
|
|
513
|
+
for face in room.faces:
|
|
514
|
+
for ap in face.apertures:
|
|
515
|
+
if isinstance(ap.properties.energy.construction, dyn_con):
|
|
516
|
+
for op in out_per_win:
|
|
517
|
+
out_strs.append(op.format(ap.identifier))
|
|
518
|
+
|
|
519
|
+
# write the IDF string
|
|
520
|
+
output_file.write('\n'.join(out_strs))
|
|
521
|
+
except Exception as e:
|
|
522
|
+
_logger.exception('Model baseline geometry creation failed.\n{}'.format(e))
|
|
523
|
+
sys.exit(1)
|
|
524
|
+
else:
|
|
525
|
+
sys.exit(0)
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
def _load_run_period_str(run_period_str):
|
|
529
|
+
"""Load a RunPeriod from a string of a run period or analysis period.
|
|
530
|
+
|
|
531
|
+
Args:
|
|
532
|
+
run_period_str: A string of a RunPeriod or AnalysisPeriod to be loaded.
|
|
533
|
+
"""
|
|
534
|
+
if run_period_str is not None and run_period_str != '' \
|
|
535
|
+
and run_period_str != 'None':
|
|
536
|
+
if run_period_str.startswith('RunPeriod'):
|
|
537
|
+
return RunPeriod.from_string(run_period_str)
|
|
538
|
+
else:
|
|
539
|
+
return RunPeriod.from_analysis_period(
|
|
540
|
+
AnalysisPeriod.from_string(run_period_str))
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
def _apply_run_period(run_period_json, sim_par):
|
|
544
|
+
"""Helper function to apply a RunPeriod from a JSON to simulation parameters.
|
|
545
|
+
|
|
546
|
+
Args:
|
|
547
|
+
run_period_json: A JSON file of a RunPeriod or AnalysisPeriod to be loaded.
|
|
548
|
+
sim_par: A SimulationParameter object.
|
|
549
|
+
"""
|
|
550
|
+
run_period = _load_run_period_str(run_period_json)
|
|
551
|
+
if run_period is not None:
|
|
552
|
+
sim_par.run_period = run_period
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
def _apply_design_days(ddy_file, filter_des_days, sim_par):
|
|
556
|
+
"""Apply design days from a DDY file to simulation parameters.
|
|
557
|
+
|
|
558
|
+
Args:
|
|
559
|
+
ddy_file: Path to a .ddy file.
|
|
560
|
+
filter_des_days: Boolean for whether design days should be filtered.
|
|
561
|
+
sim_par: A SimulationPArameter object.
|
|
562
|
+
"""
|
|
563
|
+
try:
|
|
564
|
+
if filter_des_days:
|
|
565
|
+
sim_par.sizing_parameter.add_from_ddy_996_004(ddy_file)
|
|
566
|
+
else:
|
|
567
|
+
sim_par.sizing_parameter.add_from_ddy(ddy_file)
|
|
568
|
+
except AssertionError: # no design days in the DDY file
|
|
569
|
+
pass
|