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,83 @@
|
|
|
1
|
+
"""Load all materials from the JSON libraries."""
|
|
2
|
+
from honeybee_energy.config import folders
|
|
3
|
+
from honeybee_energy.material.dictutil import dict_to_material
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# empty dictionaries to hold loaded materials
|
|
10
|
+
_opaque_materials = {}
|
|
11
|
+
_window_materials = {}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# first load the honeybee defaults
|
|
15
|
+
with open(folders.defaults_file) as json_file:
|
|
16
|
+
default_data = json.load(json_file)['materials']
|
|
17
|
+
for mat_dict in default_data:
|
|
18
|
+
mat_obj = dict_to_material(mat_dict, False)
|
|
19
|
+
mat_obj.lock()
|
|
20
|
+
if mat_obj.is_window_material:
|
|
21
|
+
_window_materials[mat_dict['identifier']] = mat_obj
|
|
22
|
+
else:
|
|
23
|
+
_opaque_materials[mat_dict['identifier']] = mat_obj
|
|
24
|
+
_default_mats = set(list(_opaque_materials.keys()) + list(_window_materials.keys()))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# then load honeybee extension data into a dictionary but don't make the objects yet
|
|
28
|
+
_opaque_mat_standards_dict = {}
|
|
29
|
+
_window_mat_standards_dict = {}
|
|
30
|
+
|
|
31
|
+
for ext_folder in folders.standards_extension_folders:
|
|
32
|
+
_data_dir = os.path.join(ext_folder, 'constructions')
|
|
33
|
+
_opaque_dir = os.path.join(_data_dir, 'opaque_material.json')
|
|
34
|
+
if os.path.isfile(_opaque_dir):
|
|
35
|
+
with open(_opaque_dir, 'r') as f:
|
|
36
|
+
_opaque_mat_standards_dict.update(json.load(f))
|
|
37
|
+
_window_dir = os.path.join(_data_dir, 'window_material.json')
|
|
38
|
+
if os.path.isfile(_window_dir):
|
|
39
|
+
with open(_window_dir, 'r') as f:
|
|
40
|
+
_window_mat_standards_dict.update(json.load(f))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# then load material JSONs from the default and user-supplied files
|
|
44
|
+
def load_material_object(mat_dict, opaque_mats, window_mats):
|
|
45
|
+
"""Load a material object from a dictionary and add it to the library dict."""
|
|
46
|
+
try:
|
|
47
|
+
mat_obj = dict_to_material(mat_dict, False)
|
|
48
|
+
if mat_obj is not None:
|
|
49
|
+
mat_obj.lock()
|
|
50
|
+
assert mat_dict['identifier'] not in _default_mats, 'Cannot overwrite ' \
|
|
51
|
+
'default material "{}".'.format(mat_dict['identifier'])
|
|
52
|
+
if mat_obj.is_window_material:
|
|
53
|
+
window_mats[mat_dict['identifier']] = mat_obj
|
|
54
|
+
else:
|
|
55
|
+
opaque_mats[mat_dict['identifier']] = mat_obj
|
|
56
|
+
except (TypeError, KeyError):
|
|
57
|
+
pass # not a Honeybee Material JSON; possibly a comment
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def load_materials_from_folder(construction_lib_folder):
|
|
61
|
+
"""Load all of the material layer objects from a construction standards folder.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
construction_lib_folder: Path to a constructions sub-folder within a
|
|
65
|
+
honeybee standards folder.
|
|
66
|
+
"""
|
|
67
|
+
opaque_mats, window_mats = {}, {}
|
|
68
|
+
for f in os.listdir(construction_lib_folder):
|
|
69
|
+
f_path = os.path.join(construction_lib_folder, f)
|
|
70
|
+
if os.path.isfile(f_path) and f_path.endswith('.json'):
|
|
71
|
+
with open(f_path) as json_file:
|
|
72
|
+
data = json.load(json_file)
|
|
73
|
+
if 'type' in data: # single object
|
|
74
|
+
load_material_object(data, opaque_mats, window_mats)
|
|
75
|
+
else: # a collection of several objects
|
|
76
|
+
for mat_id in data:
|
|
77
|
+
load_material_object(data[mat_id], opaque_mats, window_mats)
|
|
78
|
+
return opaque_mats, window_mats
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
opaque_m, window_m = load_materials_from_folder(folders.construction_lib)
|
|
82
|
+
_opaque_materials.update(opaque_m)
|
|
83
|
+
_window_materials.update(window_m)
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"""Load all program types from the JSON libraries."""
|
|
2
|
+
from honeybee_energy.config import folders
|
|
3
|
+
from honeybee_energy.programtype import ProgramType
|
|
4
|
+
|
|
5
|
+
from ._loadschedules import _schedules
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import json
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# empty dictionary to hold loaded program types
|
|
12
|
+
_program_types = {}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# first load the honeybee defaults
|
|
16
|
+
with open(folders.defaults_file) as json_file:
|
|
17
|
+
default_data = json.load(json_file)['program_types']
|
|
18
|
+
for pro_dict in default_data:
|
|
19
|
+
program = ProgramType.from_dict_abridged(pro_dict, _schedules)
|
|
20
|
+
program.lock()
|
|
21
|
+
_program_types[pro_dict['identifier']] = program
|
|
22
|
+
_default_programs = set(list(_program_types.keys()))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _add_schedule(scheds, p_type_dict, load_id, sch_id):
|
|
26
|
+
import honeybee_energy.lib.schedules as _s
|
|
27
|
+
try:
|
|
28
|
+
sch_id = p_type_dict[load_id][sch_id]
|
|
29
|
+
if sch_id not in scheds:
|
|
30
|
+
scheds[sch_id] = _s.schedule_by_identifier(sch_id)
|
|
31
|
+
except KeyError:
|
|
32
|
+
pass # key is not included
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# then load honeybee extension data into a dictionary but don't make the objects yet
|
|
36
|
+
_program_types_standards_dict = {}
|
|
37
|
+
_program_types_standards_registry = {}
|
|
38
|
+
_building_programs_dict = {}
|
|
39
|
+
|
|
40
|
+
for ext_folder in folders.standards_extension_folders:
|
|
41
|
+
_data_dir = os.path.join(ext_folder, 'programtypes')
|
|
42
|
+
for _p_type_json in os.listdir(_data_dir):
|
|
43
|
+
if _p_type_json.endswith('.json'):
|
|
44
|
+
_p_type_dir = os.path.join(_data_dir, _p_type_json)
|
|
45
|
+
with open(_p_type_dir, 'r') as f:
|
|
46
|
+
_program_types_standards_dict.update(json.load(f))
|
|
47
|
+
_data_dir = os.path.join(ext_folder, 'programtypes_registry')
|
|
48
|
+
if os.path.isdir(_data_dir):
|
|
49
|
+
for _p_type_json in os.listdir(_data_dir):
|
|
50
|
+
if _p_type_json.endswith('_registry.json'):
|
|
51
|
+
_p_type_dir = os.path.join(_data_dir, _p_type_json)
|
|
52
|
+
vintage = _p_type_json.split('_registry.json')[0]
|
|
53
|
+
try:
|
|
54
|
+
with open(_p_type_dir, 'r') as f:
|
|
55
|
+
_program_types_standards_registry[vintage] = json.load(f)
|
|
56
|
+
except FileNotFoundError:
|
|
57
|
+
pass
|
|
58
|
+
_bld_file = os.path.join(ext_folder, 'building_mix.json')
|
|
59
|
+
if os.path.isfile(_bld_file):
|
|
60
|
+
with open(_bld_file, 'r') as f:
|
|
61
|
+
_building_programs_dict.update(json.load(f))
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# then load program types from the user-supplied files
|
|
65
|
+
def load_program_object(pro_dict, loaded_schedules, p_types, misc_scheds):
|
|
66
|
+
"""Load a program object from a dictionary and add it to the _program_types dict."""
|
|
67
|
+
try:
|
|
68
|
+
if pro_dict['type'] == 'ProgramTypeAbridged':
|
|
69
|
+
program = ProgramType.from_dict_abridged(pro_dict, loaded_schedules)
|
|
70
|
+
else:
|
|
71
|
+
program = ProgramType.from_dict(pro_dict)
|
|
72
|
+
misc_scheds.extend(program.schedules)
|
|
73
|
+
program.lock()
|
|
74
|
+
assert pro_dict['identifier'] not in _default_programs, 'Cannot overwrite ' \
|
|
75
|
+
'default program type "{}".'.format(pro_dict['identifier'])
|
|
76
|
+
p_types[pro_dict['identifier']] = program
|
|
77
|
+
except Exception:
|
|
78
|
+
try:
|
|
79
|
+
if pro_dict['type'] == 'ProgramTypeAbridged':
|
|
80
|
+
schedules = loaded_schedules
|
|
81
|
+
_add_schedule(schedules, pro_dict, 'people', 'occupancy_schedule')
|
|
82
|
+
_add_schedule(schedules, pro_dict, 'people', 'activity_schedule')
|
|
83
|
+
_add_schedule(schedules, pro_dict, 'lighting', 'schedule')
|
|
84
|
+
_add_schedule(schedules, pro_dict, 'electric_equipment', 'schedule')
|
|
85
|
+
_add_schedule(schedules, pro_dict, 'gas_equipment', 'schedule')
|
|
86
|
+
_add_schedule(schedules, pro_dict, 'service_hot_water', 'schedule')
|
|
87
|
+
_add_schedule(schedules, pro_dict, 'infiltration', 'schedule')
|
|
88
|
+
_add_schedule(schedules, pro_dict, 'ventilation', 'schedule')
|
|
89
|
+
_add_schedule(schedules, pro_dict, 'setpoint', 'heating_schedule')
|
|
90
|
+
_add_schedule(schedules, pro_dict, 'setpoint', 'cooling_schedule')
|
|
91
|
+
_add_schedule(schedules, pro_dict, 'setpoint', 'humidifying_schedule')
|
|
92
|
+
_add_schedule(schedules, pro_dict, 'setpoint', 'dehumidifying_schedule')
|
|
93
|
+
p_types[pro_dict['identifier']] = \
|
|
94
|
+
ProgramType.from_dict_abridged(pro_dict, schedules)
|
|
95
|
+
except Exception:
|
|
96
|
+
pass # not a Honeybee ProgramType JSON; possibly a comment
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def load_programtypes_from_folder(programtypes_lib_folder, loaded_schedules):
|
|
100
|
+
"""Load all of the ProgramTypes objects from a programtypes standards folder.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
programtypes_lib_folder: Path to a programtypes sub-folder within a
|
|
104
|
+
honeybee standards folder.
|
|
105
|
+
loaded_schedules: A dictionary of schedules that have already been
|
|
106
|
+
loaded from the library.
|
|
107
|
+
"""
|
|
108
|
+
p_types, misc_scheds = {}, []
|
|
109
|
+
for f in os.listdir(programtypes_lib_folder):
|
|
110
|
+
f_path = os.path.join(programtypes_lib_folder, f)
|
|
111
|
+
if os.path.isfile(f_path) and f_path.endswith('.json'):
|
|
112
|
+
with open(f_path, 'r') as json_file:
|
|
113
|
+
p_dict = json.load(json_file)
|
|
114
|
+
if 'type' in p_dict: # single object
|
|
115
|
+
load_program_object(p_dict, loaded_schedules, p_types, misc_scheds)
|
|
116
|
+
else: # a collection of several objects
|
|
117
|
+
for p_id in p_dict:
|
|
118
|
+
load_program_object(
|
|
119
|
+
p_dict[p_id], loaded_schedules, p_types, misc_scheds)
|
|
120
|
+
return p_types, misc_scheds
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
loaded_p_types, misc_s = \
|
|
124
|
+
load_programtypes_from_folder(folders.programtype_lib, _schedules)
|
|
125
|
+
_program_types.update(loaded_p_types)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Load all schedules from the IDF libraries."""
|
|
2
|
+
from honeybee_energy.config import folders
|
|
3
|
+
from honeybee_energy.schedule.ruleset import ScheduleRuleset
|
|
4
|
+
from honeybee_energy.schedule.dictutil import dict_abridged_to_schedule, \
|
|
5
|
+
dict_to_schedule
|
|
6
|
+
|
|
7
|
+
from ._loadtypelimits import _schedule_type_limits
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
import json
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# empty dictionary to hold loaded schedules
|
|
14
|
+
_schedules = {}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# first load the honeybee defaults
|
|
18
|
+
with open(folders.defaults_file) as json_file:
|
|
19
|
+
default_data = json.load(json_file)['schedules']
|
|
20
|
+
for sch_dict in default_data:
|
|
21
|
+
sch_obj = dict_abridged_to_schedule(sch_dict, _schedule_type_limits, False)
|
|
22
|
+
sch_obj.lock()
|
|
23
|
+
_schedules[sch_dict['identifier']] = sch_obj
|
|
24
|
+
_default_schedules = set(list(_schedules.keys()))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# then load honeybee extension data into a dictionary but don't make the objects yet
|
|
28
|
+
_schedule_standards_dict = {}
|
|
29
|
+
|
|
30
|
+
for ext_folder in folders.standards_extension_folders:
|
|
31
|
+
_data_dir = os.path.join(ext_folder, 'schedules', 'schedule.json')
|
|
32
|
+
if os.path.isfile(_data_dir):
|
|
33
|
+
with open(_data_dir, 'r') as f:
|
|
34
|
+
_schedule_standards_dict.update(json.load(f))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# then load schedules from the user-supplied files
|
|
38
|
+
def lock_and_check_schedule(sch):
|
|
39
|
+
"""Lock a schedule and check that it's not overwriting a default."""
|
|
40
|
+
sch.lock()
|
|
41
|
+
assert sch.identifier not in _default_schedules, 'Cannot overwrite ' \
|
|
42
|
+
'default schedule "{}".'.format(sch.identifier)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def load_schedule_object(sch_dict, loaded_type_limits, scheds):
|
|
46
|
+
"""Load a schedule object from a dictionary and add it to the scheds dict."""
|
|
47
|
+
try:
|
|
48
|
+
sch_obj = dict_abridged_to_schedule(sch_dict, loaded_type_limits, False)
|
|
49
|
+
if sch_obj is None:
|
|
50
|
+
sch_obj = dict_to_schedule(sch_dict, False)
|
|
51
|
+
if sch_obj is not None:
|
|
52
|
+
lock_and_check_schedule(sch_obj)
|
|
53
|
+
scheds[sch_dict['identifier']] = sch_obj
|
|
54
|
+
except (TypeError, KeyError, ValueError):
|
|
55
|
+
pass # not a Honeybee Schedule JSON; possibly a comment
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def load_schedules_from_folder(schedule_lib_folder, loaded_type_limits):
|
|
59
|
+
"""Load all of the schedule objects from a schedule standards folder.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
schedule_lib_folder: Path to a schedules sub-folder within a honeybee
|
|
63
|
+
standards folder.
|
|
64
|
+
loaded_type_limits: A dictionary of type limits that have already been
|
|
65
|
+
loaded from the library.
|
|
66
|
+
"""
|
|
67
|
+
scheds = {}
|
|
68
|
+
for f in os.listdir(schedule_lib_folder):
|
|
69
|
+
f_path = os.path.join(schedule_lib_folder, f)
|
|
70
|
+
if os.path.isfile(f_path):
|
|
71
|
+
if f_path.endswith('.idf'):
|
|
72
|
+
schedule_rulesets = ScheduleRuleset.extract_all_from_idf_file(f_path)
|
|
73
|
+
for sch in schedule_rulesets:
|
|
74
|
+
lock_and_check_schedule(sch)
|
|
75
|
+
scheds[sch.identifier] = sch
|
|
76
|
+
elif f_path.endswith('.json'): # parse as a honeybee JSON
|
|
77
|
+
with open(f_path) as json_file:
|
|
78
|
+
data = json.load(json_file)
|
|
79
|
+
if 'type' in data: # single object
|
|
80
|
+
load_schedule_object(data, loaded_type_limits, scheds)
|
|
81
|
+
for sch_id in data: # a collection of several objects
|
|
82
|
+
load_schedule_object(data[sch_id], loaded_type_limits, scheds)
|
|
83
|
+
return scheds
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
u_scheds = load_schedules_from_folder(folders.schedule_lib, _schedule_type_limits)
|
|
87
|
+
_schedules.update(u_scheds)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Load all schedule type limits from the standards library."""
|
|
2
|
+
from honeybee_energy.config import folders
|
|
3
|
+
from honeybee_energy.schedule.typelimit import ScheduleTypeLimit
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# empty dictionary to hold loaded schedule type limits
|
|
10
|
+
_schedule_type_limits = {}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# first load the honeybee defaults
|
|
14
|
+
with open(folders.defaults_file) as json_file:
|
|
15
|
+
default_data = json.load(json_file)['schedule_type_limits']
|
|
16
|
+
for stl_dict in default_data:
|
|
17
|
+
stl_obj = ScheduleTypeLimit.from_dict(stl_dict)
|
|
18
|
+
_schedule_type_limits[stl_dict['identifier']] = stl_obj
|
|
19
|
+
_default_stls = set(list(_schedule_type_limits.keys()))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# then load schedule types from the user-supplied files
|
|
23
|
+
def check_and_add_schedule_type_limit(stl, type_lms):
|
|
24
|
+
"""Check that a schedule type limit is not overwriting a default and add it."""
|
|
25
|
+
# we won't raise an error for this case as schedule types are fairly universal
|
|
26
|
+
if stl.identifier not in _default_stls:
|
|
27
|
+
type_lms[stl.identifier] = stl
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def load_type_limits_from_folder(schedule_lib_folder):
|
|
31
|
+
"""Load all of the type limit objects from a schedule standards folder.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
schedule_lib_folder: Path to a schedules sub-folder within a honeybee
|
|
35
|
+
standards folder.
|
|
36
|
+
"""
|
|
37
|
+
type_limits = {}
|
|
38
|
+
for f in os.listdir(schedule_lib_folder):
|
|
39
|
+
f_path = os.path.join(schedule_lib_folder, f)
|
|
40
|
+
if os.path.isfile(f_path):
|
|
41
|
+
if f_path.endswith('.idf'):
|
|
42
|
+
schedule_type_limits = ScheduleTypeLimit.extract_all_from_idf_file(f_path)
|
|
43
|
+
for typ in schedule_type_limits:
|
|
44
|
+
check_and_add_schedule_type_limit(typ, type_limits)
|
|
45
|
+
elif f_path.endswith('.json'):
|
|
46
|
+
with open(f_path) as json_file:
|
|
47
|
+
data = json.load(json_file)
|
|
48
|
+
if 'type' in data and data['type'] == 'ScheduleTypeLimit': # single object
|
|
49
|
+
check_and_add_schedule_type_limit(
|
|
50
|
+
ScheduleTypeLimit.from_dict(data), type_limits)
|
|
51
|
+
else: # a collection of several objects
|
|
52
|
+
for stl_id in data:
|
|
53
|
+
try:
|
|
54
|
+
stl_dict = data[stl_id]
|
|
55
|
+
if stl_dict['type'] == 'ScheduleTypeLimit':
|
|
56
|
+
check_and_add_schedule_type_limit(
|
|
57
|
+
ScheduleTypeLimit.from_dict(stl_dict), type_limits)
|
|
58
|
+
except (TypeError, KeyError):
|
|
59
|
+
pass # not a ScheduleTypeLimit JSON; possibly a comment
|
|
60
|
+
return type_limits
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
type_l = load_type_limits_from_folder(folders.schedule_lib)
|
|
64
|
+
_schedule_type_limits.update(type_l)
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"""Load all of the constructions and materials from the IDF libraries."""
|
|
2
|
+
from honeybee_energy.construction.opaque import OpaqueConstruction
|
|
3
|
+
from honeybee_energy.construction.window import WindowConstruction
|
|
4
|
+
from honeybee_energy.construction.windowshade import WindowConstructionShade
|
|
5
|
+
from honeybee_energy.construction.dynamic import WindowConstructionDynamic
|
|
6
|
+
from honeybee_energy.construction.shade import ShadeConstruction
|
|
7
|
+
from honeybee_energy.construction.air import AirBoundaryConstruction
|
|
8
|
+
from ._loadconstructions import _opaque_constructions, _window_constructions, \
|
|
9
|
+
_shade_constructions, _opaque_constr_standards_dict, _window_constr_standards_dict, \
|
|
10
|
+
_shade_constr_standards_dict
|
|
11
|
+
|
|
12
|
+
import honeybee_energy.lib.materials as _m
|
|
13
|
+
import honeybee_energy.lib.schedules as _s
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# establish variables for the default constructions used across the library
|
|
17
|
+
generic_exterior_wall = _opaque_constructions['Generic Exterior Wall']
|
|
18
|
+
generic_interior_wall = _opaque_constructions['Generic Interior Wall']
|
|
19
|
+
generic_underground_wall = _opaque_constructions['Generic Underground Wall']
|
|
20
|
+
generic_exposed_floor = _opaque_constructions['Generic Exposed Floor']
|
|
21
|
+
generic_interior_floor = _opaque_constructions['Generic Interior Floor']
|
|
22
|
+
generic_ground_slab = _opaque_constructions['Generic Ground Slab']
|
|
23
|
+
generic_roof = _opaque_constructions['Generic Roof']
|
|
24
|
+
generic_interior_ceiling = _opaque_constructions['Generic Interior Ceiling']
|
|
25
|
+
generic_underground_roof = _opaque_constructions['Generic Underground Roof']
|
|
26
|
+
generic_double_pane = _window_constructions['Generic Double Pane']
|
|
27
|
+
generic_single_pane = _window_constructions['Generic Single Pane']
|
|
28
|
+
generic_exterior_door = _opaque_constructions['Generic Exterior Door']
|
|
29
|
+
generic_interior_door = _opaque_constructions['Generic Interior Door']
|
|
30
|
+
air_boundary = _opaque_constructions['Generic Air Boundary']
|
|
31
|
+
generic_context = _shade_constructions['Generic Context']
|
|
32
|
+
generic_shade = _shade_constructions['Generic Shade']
|
|
33
|
+
try:
|
|
34
|
+
ceiling_plenum_bottom = _opaque_constructions['Ceiling Plenum Bottom']
|
|
35
|
+
floor_plenum_top = _opaque_constructions['Floor Plenum Top']
|
|
36
|
+
except KeyError: # older version of honeybee-standards
|
|
37
|
+
ceiling_plenum_bottom = \
|
|
38
|
+
OpaqueConstruction('Ceiling Plenum Bottom', [_m.acoustic_tile])
|
|
39
|
+
floor_plenum_top = OpaqueConstruction('Floor Plenum Top', [_m.wood])
|
|
40
|
+
|
|
41
|
+
# make lists of construction identifiers to look up items in the library
|
|
42
|
+
OPAQUE_CONSTRUCTIONS = tuple(_opaque_constructions.keys()) + \
|
|
43
|
+
tuple(_opaque_constr_standards_dict.keys())
|
|
44
|
+
WINDOW_CONSTRUCTIONS = tuple(_window_constructions.keys()) + \
|
|
45
|
+
tuple(_window_constr_standards_dict.keys())
|
|
46
|
+
SHADE_CONSTRUCTIONS = tuple(_shade_constructions.keys()) + \
|
|
47
|
+
tuple(_shade_constr_standards_dict.keys())
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def opaque_construction_by_identifier(construction_identifier):
|
|
51
|
+
"""Get an opaque construction from the library given the construction identifier.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
construction_identifier: A text string for the identifier of the construction.
|
|
55
|
+
"""
|
|
56
|
+
try:
|
|
57
|
+
return _opaque_constructions[construction_identifier]
|
|
58
|
+
except KeyError:
|
|
59
|
+
try: # search the extension data
|
|
60
|
+
constr_dict = _opaque_constr_standards_dict[construction_identifier]
|
|
61
|
+
if constr_dict['type'] == 'OpaqueConstructionAbridged':
|
|
62
|
+
mats = {}
|
|
63
|
+
mat_key = 'layers' if 'layers' in constr_dict else 'materials'
|
|
64
|
+
for mat in constr_dict[mat_key]:
|
|
65
|
+
mats[mat] = _m.opaque_material_by_identifier(mat)
|
|
66
|
+
return OpaqueConstruction.from_dict_abridged(constr_dict, mats)
|
|
67
|
+
else: # AirBoundaryConstruction
|
|
68
|
+
try:
|
|
69
|
+
sch_id = constr_dict['air_mixing_schedule']
|
|
70
|
+
schs = {sch_id: _s.schedule_by_identifier(sch_id)}
|
|
71
|
+
except KeyError: # no air mixing key provided
|
|
72
|
+
schs = {}
|
|
73
|
+
return AirBoundaryConstruction.from_dict_abridged(constr_dict, schs)
|
|
74
|
+
except KeyError: # construction is nowhere to be found; raise an error
|
|
75
|
+
raise ValueError(
|
|
76
|
+
'"{}" was not found in the opaque energy construction library.'.format(
|
|
77
|
+
construction_identifier))
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def window_construction_by_identifier(construction_identifier):
|
|
81
|
+
"""Get an window construction from the library given the construction identifier.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
construction_identifier: A text string for the identifier of the construction.
|
|
85
|
+
"""
|
|
86
|
+
try:
|
|
87
|
+
return _window_constructions[construction_identifier]
|
|
88
|
+
except KeyError:
|
|
89
|
+
try: # search the extension data
|
|
90
|
+
constr_dict = _window_constr_standards_dict[construction_identifier]
|
|
91
|
+
if constr_dict['type'] == 'WindowConstructionAbridged':
|
|
92
|
+
mats = {}
|
|
93
|
+
mat_key = 'layers' if 'layers' in constr_dict else 'materials'
|
|
94
|
+
for mat in constr_dict[mat_key]:
|
|
95
|
+
mats[mat] = _m.window_material_by_identifier(mat)
|
|
96
|
+
return WindowConstruction.from_dict_abridged(constr_dict, mats)
|
|
97
|
+
elif constr_dict['type'] == 'WindowConstructionShadeAbridged':
|
|
98
|
+
mats = {}
|
|
99
|
+
mat_key = 'layers' if 'layers' in constr_dict['window_construction'] \
|
|
100
|
+
else 'materials'
|
|
101
|
+
for mat in constr_dict['window_construction'][mat_key]:
|
|
102
|
+
mats[mat] = _m.window_material_by_identifier(mat)
|
|
103
|
+
shd_mat = constr_dict['shade_material']
|
|
104
|
+
mats[shd_mat] = _m.window_material_by_identifier(shd_mat)
|
|
105
|
+
try:
|
|
106
|
+
sch_id = constr_dict['schedule']
|
|
107
|
+
schs = {sch_id: _s.schedule_by_identifier(sch_id)}
|
|
108
|
+
except KeyError: # no schedule key provided
|
|
109
|
+
schs = {}
|
|
110
|
+
return WindowConstructionShade.from_dict_abridged(
|
|
111
|
+
constr_dict, mats, schs)
|
|
112
|
+
elif constr_dict['type'] == 'WindowConstructionDynamicAbridged':
|
|
113
|
+
mats = {}
|
|
114
|
+
for con in constr_dict['constructions']:
|
|
115
|
+
for mat in constr_dict['materials']:
|
|
116
|
+
mats[mat] = _m.window_material_by_identifier(mat)
|
|
117
|
+
sch_id = constr_dict['schedule']
|
|
118
|
+
schs = {sch_id: _s.schedule_by_identifier(sch_id)}
|
|
119
|
+
return WindowConstructionDynamic.from_dict_abridged(
|
|
120
|
+
constr_dict, mats, schs)
|
|
121
|
+
except KeyError: # construction is nowhere to be found; raise an error
|
|
122
|
+
raise ValueError(
|
|
123
|
+
'"{}" was not found in the window energy construction library.'.format(
|
|
124
|
+
construction_identifier))
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def shade_construction_by_identifier(construction_identifier):
|
|
128
|
+
"""Get an shade construction from the library given the construction identifier.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
construction_identifier: A text string for the identifier of the construction.
|
|
132
|
+
"""
|
|
133
|
+
try:
|
|
134
|
+
return _shade_constructions[construction_identifier]
|
|
135
|
+
except KeyError:
|
|
136
|
+
try: # search the extension data
|
|
137
|
+
constr_dict = _shade_constr_standards_dict[construction_identifier]
|
|
138
|
+
return ShadeConstruction.from_dict(constr_dict)
|
|
139
|
+
except KeyError: # construction is nowhere to be found; raise an error
|
|
140
|
+
raise ValueError(
|
|
141
|
+
'"{}" was not found in the shade energy construction library.'.format(
|
|
142
|
+
construction_identifier))
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def lib_dict_abridged_to_construction(constr_dict, materials, schedules):
|
|
146
|
+
"""Get a Python object of a Construction from an abridged dictionary.
|
|
147
|
+
|
|
148
|
+
When the sub-objects needed to create the construction are not available
|
|
149
|
+
in the resources provided, the current standards library will be searched.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
constr_dict: An abridged dictionary of any Honeybee energy construction.
|
|
153
|
+
materials: Dictionary of all material objects that might be used in the
|
|
154
|
+
construction with the material identifiers as the keys.
|
|
155
|
+
schedules: Dictionary of all schedule objects that might be used in the
|
|
156
|
+
construction with the schedule identifiers as the keys.
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
A Python object derived from the input constr_dict.
|
|
160
|
+
"""
|
|
161
|
+
try: # get the type key from the dictionary
|
|
162
|
+
constr_type = constr_dict['type']
|
|
163
|
+
except KeyError:
|
|
164
|
+
raise ValueError('Construction dictionary lacks required "type" key.')
|
|
165
|
+
|
|
166
|
+
if constr_type == 'OpaqueConstructionAbridged':
|
|
167
|
+
for mat_id in constr_dict['materials']:
|
|
168
|
+
if mat_id not in materials:
|
|
169
|
+
materials[mat_id] = _m.opaque_material_by_identifier(mat_id)
|
|
170
|
+
return OpaqueConstruction.from_dict_abridged(constr_dict, materials)
|
|
171
|
+
elif constr_type == 'WindowConstructionAbridged':
|
|
172
|
+
for mat_id in constr_dict['materials']:
|
|
173
|
+
if mat_id not in materials:
|
|
174
|
+
materials[mat_id] = _m.window_material_by_identifier(mat_id)
|
|
175
|
+
return WindowConstruction.from_dict_abridged(constr_dict, materials)
|
|
176
|
+
elif constr_type == 'WindowConstructionShadeAbridged':
|
|
177
|
+
all_mat = constr_dict['window_construction']['materials'] + \
|
|
178
|
+
[constr_dict['shade_material']]
|
|
179
|
+
for mat_id in all_mat:
|
|
180
|
+
if mat_id not in materials:
|
|
181
|
+
materials[mat_id] = _m.window_material_by_identifier(mat_id)
|
|
182
|
+
if 'schedule' in constr_dict and constr_dict['schedule'] is not None:
|
|
183
|
+
if constr_dict['schedule'] not in schedules:
|
|
184
|
+
schedules[constr_dict['schedule']] = \
|
|
185
|
+
_s.schedule_by_identifier(constr_dict['schedule'])
|
|
186
|
+
return WindowConstructionShade.from_dict_abridged(
|
|
187
|
+
constr_dict, materials, schedules)
|
|
188
|
+
elif constr_type == 'WindowConstructionDynamicAbridged':
|
|
189
|
+
for c_abr in constr_dict['constructions']:
|
|
190
|
+
for mat_id in c_abr['materials']:
|
|
191
|
+
if mat_id not in materials:
|
|
192
|
+
materials[mat_id] = _m.window_material_by_identifier(mat_id)
|
|
193
|
+
if constr_dict['schedule'] not in schedules:
|
|
194
|
+
schedules[constr_dict['schedule']] = \
|
|
195
|
+
_s.schedule_by_identifier(constr_dict['schedule'])
|
|
196
|
+
return WindowConstructionDynamic.from_dict_abridged(
|
|
197
|
+
constr_dict, materials, schedules)
|
|
198
|
+
elif constr_type == 'ShadeConstruction':
|
|
199
|
+
return ShadeConstruction.from_dict(constr_dict)
|
|
200
|
+
elif constr_type == 'AirBoundaryConstructionAbridged':
|
|
201
|
+
if constr_dict['air_mixing_schedule'] not in schedules:
|
|
202
|
+
schedules[constr_dict['air_mixing_schedule']] = \
|
|
203
|
+
_s.schedule_by_identifier(constr_dict['air_mixing_schedule'])
|
|
204
|
+
return AirBoundaryConstruction.from_dict_abridged(constr_dict, schedules)
|
|
205
|
+
else:
|
|
206
|
+
raise ValueError(
|
|
207
|
+
'{} is not a recognized energy Construction type'.format(constr_type))
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""Collection of construction sets."""
|
|
2
|
+
from honeybee_energy.constructionset import ConstructionSet
|
|
3
|
+
from ._loadconstructionsets import _construction_sets, _construction_set_standards_dict
|
|
4
|
+
|
|
5
|
+
import honeybee_energy.lib.constructions as _c
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# establish variables for the default construction sets used across the library
|
|
9
|
+
generic_construction_set = _construction_sets['Default Generic Construction Set']
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# make lists of program types to look up items in the library
|
|
13
|
+
CONSTRUCTION_SETS = tuple(_construction_sets.keys()) + \
|
|
14
|
+
tuple(_construction_set_standards_dict.keys())
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def construction_set_by_identifier(construction_set_identifier):
|
|
18
|
+
"""Get a construction_set from the library given its identifier.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
construction_set_identifier: A text string for the identifier of the
|
|
22
|
+
ConstructionSet.
|
|
23
|
+
"""
|
|
24
|
+
try:
|
|
25
|
+
return _construction_sets[construction_set_identifier]
|
|
26
|
+
except KeyError:
|
|
27
|
+
try: # search the extension data
|
|
28
|
+
con_set_dict = _construction_set_standards_dict[construction_set_identifier]
|
|
29
|
+
constrs = _constrs_from_set_dict(con_set_dict)
|
|
30
|
+
return ConstructionSet.from_dict_abridged(con_set_dict, constrs)
|
|
31
|
+
except KeyError: # construction is nowhere to be found; raise an error
|
|
32
|
+
raise ValueError(
|
|
33
|
+
'"{}" was not found in the construction set library.'.format(
|
|
34
|
+
construction_set_identifier))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _constrs_from_set_dict(con_set_dict):
|
|
38
|
+
"""Get a dictionary of constructions used in a ConstructionSetAbridged dictionary.
|
|
39
|
+
"""
|
|
40
|
+
constrs = {}
|
|
41
|
+
for key in con_set_dict:
|
|
42
|
+
if isinstance(con_set_dict[key], dict):
|
|
43
|
+
sub_dict = con_set_dict[key]
|
|
44
|
+
for sub_key in sub_dict:
|
|
45
|
+
if sub_key != 'type':
|
|
46
|
+
try:
|
|
47
|
+
constrs[sub_dict[sub_key]] = \
|
|
48
|
+
_c.opaque_construction_by_identifier(sub_dict[sub_key])
|
|
49
|
+
except ValueError:
|
|
50
|
+
constrs[sub_dict[sub_key]] = \
|
|
51
|
+
_c.window_construction_by_identifier(sub_dict[sub_key])
|
|
52
|
+
elif key == 'shade_construction':
|
|
53
|
+
constrs[con_set_dict[key]] = \
|
|
54
|
+
_c.shade_construction_by_identifier(con_set_dict[key])
|
|
55
|
+
elif key == 'air_boundary_construction':
|
|
56
|
+
constrs[con_set_dict[key]] = \
|
|
57
|
+
_c.opaque_construction_by_identifier(con_set_dict[key])
|
|
58
|
+
return constrs
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def lib_dict_abridged_to_construction_set(con_set_dict, constructions):
|
|
62
|
+
"""Get a Python object of a ConstructionSet from an abridged dictionary.
|
|
63
|
+
|
|
64
|
+
When the sub-objects needed to create the construction set are not available
|
|
65
|
+
in the resources provided, the current standards library will be searched.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
con_set_dict: An abridged dictionary of a Honeybee ConstructionSet.
|
|
69
|
+
constructions: Dictionary of all construction objects that might be used in the
|
|
70
|
+
construction set with the construction identifiers as the keys.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
A Python object derived from the input con_set_dict.
|
|
74
|
+
"""
|
|
75
|
+
for key in con_set_dict:
|
|
76
|
+
if isinstance(con_set_dict[key], dict):
|
|
77
|
+
sub_dict = con_set_dict[key]
|
|
78
|
+
for sub_key in sub_dict:
|
|
79
|
+
if sub_key == 'type' or sub_key in constructions:
|
|
80
|
+
continue
|
|
81
|
+
if sub_dict[sub_key] not in constructions:
|
|
82
|
+
try:
|
|
83
|
+
constructions[sub_dict[sub_key]] = \
|
|
84
|
+
_c.opaque_construction_by_identifier(sub_dict[sub_key])
|
|
85
|
+
except ValueError:
|
|
86
|
+
constructions[sub_dict[sub_key]] = \
|
|
87
|
+
_c.window_construction_by_identifier(sub_dict[sub_key])
|
|
88
|
+
elif key == 'shade_construction' and con_set_dict[key] not in constructions:
|
|
89
|
+
constructions[con_set_dict[key]] = \
|
|
90
|
+
_c.shade_construction_by_identifier(con_set_dict[key])
|
|
91
|
+
elif key == 'air_boundary_construction' \
|
|
92
|
+
and con_set_dict[key] not in constructions:
|
|
93
|
+
constructions[con_set_dict[key]] = \
|
|
94
|
+
_c.opaque_construction_by_identifier(con_set_dict[key])
|
|
95
|
+
return ConstructionSet.from_dict_abridged(con_set_dict, constructions)
|