honeybee-energy 1.116.106__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. honeybee_energy/__init__.py +24 -0
  2. honeybee_energy/__main__.py +4 -0
  3. honeybee_energy/_extend_honeybee.py +145 -0
  4. honeybee_energy/altnumber.py +21 -0
  5. honeybee_energy/baseline/__init__.py +2 -0
  6. honeybee_energy/baseline/create.py +608 -0
  7. honeybee_energy/baseline/data/__init__.py +1 -0
  8. honeybee_energy/baseline/data/constructions.csv +64 -0
  9. honeybee_energy/baseline/data/fen_ratios.csv +15 -0
  10. honeybee_energy/baseline/data/lpd_building.csv +21 -0
  11. honeybee_energy/baseline/data/pci_2016.csv +22 -0
  12. honeybee_energy/baseline/data/pci_2019.csv +22 -0
  13. honeybee_energy/baseline/data/pci_2022.csv +22 -0
  14. honeybee_energy/baseline/data/shw.csv +21 -0
  15. honeybee_energy/baseline/pci.py +512 -0
  16. honeybee_energy/baseline/result.py +371 -0
  17. honeybee_energy/boundarycondition.py +128 -0
  18. honeybee_energy/cli/__init__.py +69 -0
  19. honeybee_energy/cli/baseline.py +475 -0
  20. honeybee_energy/cli/edit.py +327 -0
  21. honeybee_energy/cli/lib.py +1154 -0
  22. honeybee_energy/cli/result.py +810 -0
  23. honeybee_energy/cli/setconfig.py +124 -0
  24. honeybee_energy/cli/settings.py +569 -0
  25. honeybee_energy/cli/simulate.py +380 -0
  26. honeybee_energy/cli/translate.py +1714 -0
  27. honeybee_energy/cli/validate.py +224 -0
  28. honeybee_energy/config.json +11 -0
  29. honeybee_energy/config.py +842 -0
  30. honeybee_energy/construction/__init__.py +1 -0
  31. honeybee_energy/construction/_base.py +374 -0
  32. honeybee_energy/construction/air.py +325 -0
  33. honeybee_energy/construction/dictutil.py +89 -0
  34. honeybee_energy/construction/dynamic.py +607 -0
  35. honeybee_energy/construction/opaque.py +460 -0
  36. honeybee_energy/construction/shade.py +319 -0
  37. honeybee_energy/construction/window.py +1096 -0
  38. honeybee_energy/construction/windowshade.py +847 -0
  39. honeybee_energy/constructionset.py +1655 -0
  40. honeybee_energy/dictutil.py +56 -0
  41. honeybee_energy/generator/__init__.py +5 -0
  42. honeybee_energy/generator/loadcenter.py +204 -0
  43. honeybee_energy/generator/pv.py +535 -0
  44. honeybee_energy/hvac/__init__.py +21 -0
  45. honeybee_energy/hvac/_base.py +124 -0
  46. honeybee_energy/hvac/_template.py +270 -0
  47. honeybee_energy/hvac/allair/__init__.py +22 -0
  48. honeybee_energy/hvac/allair/_base.py +349 -0
  49. honeybee_energy/hvac/allair/furnace.py +168 -0
  50. honeybee_energy/hvac/allair/psz.py +131 -0
  51. honeybee_energy/hvac/allair/ptac.py +163 -0
  52. honeybee_energy/hvac/allair/pvav.py +109 -0
  53. honeybee_energy/hvac/allair/vav.py +128 -0
  54. honeybee_energy/hvac/detailed.py +337 -0
  55. honeybee_energy/hvac/doas/__init__.py +28 -0
  56. honeybee_energy/hvac/doas/_base.py +345 -0
  57. honeybee_energy/hvac/doas/fcu.py +127 -0
  58. honeybee_energy/hvac/doas/radiant.py +329 -0
  59. honeybee_energy/hvac/doas/vrf.py +81 -0
  60. honeybee_energy/hvac/doas/wshp.py +91 -0
  61. honeybee_energy/hvac/heatcool/__init__.py +23 -0
  62. honeybee_energy/hvac/heatcool/_base.py +177 -0
  63. honeybee_energy/hvac/heatcool/baseboard.py +61 -0
  64. honeybee_energy/hvac/heatcool/evapcool.py +72 -0
  65. honeybee_energy/hvac/heatcool/fcu.py +92 -0
  66. honeybee_energy/hvac/heatcool/gasunit.py +53 -0
  67. honeybee_energy/hvac/heatcool/radiant.py +269 -0
  68. honeybee_energy/hvac/heatcool/residential.py +77 -0
  69. honeybee_energy/hvac/heatcool/vrf.py +54 -0
  70. honeybee_energy/hvac/heatcool/windowac.py +70 -0
  71. honeybee_energy/hvac/heatcool/wshp.py +62 -0
  72. honeybee_energy/hvac/idealair.py +699 -0
  73. honeybee_energy/internalmass.py +310 -0
  74. honeybee_energy/lib/__init__.py +1 -0
  75. honeybee_energy/lib/_loadconstructions.py +194 -0
  76. honeybee_energy/lib/_loadconstructionsets.py +117 -0
  77. honeybee_energy/lib/_loadmaterials.py +83 -0
  78. honeybee_energy/lib/_loadprogramtypes.py +125 -0
  79. honeybee_energy/lib/_loadschedules.py +87 -0
  80. honeybee_energy/lib/_loadtypelimits.py +64 -0
  81. honeybee_energy/lib/constructions.py +207 -0
  82. honeybee_energy/lib/constructionsets.py +95 -0
  83. honeybee_energy/lib/materials.py +67 -0
  84. honeybee_energy/lib/programtypes.py +125 -0
  85. honeybee_energy/lib/schedules.py +61 -0
  86. honeybee_energy/lib/scheduletypelimits.py +31 -0
  87. honeybee_energy/load/__init__.py +1 -0
  88. honeybee_energy/load/_base.py +190 -0
  89. honeybee_energy/load/daylight.py +397 -0
  90. honeybee_energy/load/dictutil.py +47 -0
  91. honeybee_energy/load/equipment.py +771 -0
  92. honeybee_energy/load/hotwater.py +543 -0
  93. honeybee_energy/load/infiltration.py +460 -0
  94. honeybee_energy/load/lighting.py +480 -0
  95. honeybee_energy/load/people.py +497 -0
  96. honeybee_energy/load/process.py +472 -0
  97. honeybee_energy/load/setpoint.py +816 -0
  98. honeybee_energy/load/ventilation.py +550 -0
  99. honeybee_energy/material/__init__.py +1 -0
  100. honeybee_energy/material/_base.py +166 -0
  101. honeybee_energy/material/dictutil.py +59 -0
  102. honeybee_energy/material/frame.py +367 -0
  103. honeybee_energy/material/gas.py +1087 -0
  104. honeybee_energy/material/glazing.py +854 -0
  105. honeybee_energy/material/opaque.py +1351 -0
  106. honeybee_energy/material/shade.py +1360 -0
  107. honeybee_energy/measure.py +472 -0
  108. honeybee_energy/programtype.py +723 -0
  109. honeybee_energy/properties/__init__.py +1 -0
  110. honeybee_energy/properties/aperture.py +333 -0
  111. honeybee_energy/properties/door.py +342 -0
  112. honeybee_energy/properties/extension.py +244 -0
  113. honeybee_energy/properties/face.py +274 -0
  114. honeybee_energy/properties/model.py +2640 -0
  115. honeybee_energy/properties/room.py +1747 -0
  116. honeybee_energy/properties/shade.py +314 -0
  117. honeybee_energy/properties/shademesh.py +262 -0
  118. honeybee_energy/reader.py +48 -0
  119. honeybee_energy/result/__init__.py +1 -0
  120. honeybee_energy/result/colorobj.py +648 -0
  121. honeybee_energy/result/emissions.py +290 -0
  122. honeybee_energy/result/err.py +101 -0
  123. honeybee_energy/result/eui.py +100 -0
  124. honeybee_energy/result/generation.py +160 -0
  125. honeybee_energy/result/loadbalance.py +890 -0
  126. honeybee_energy/result/match.py +202 -0
  127. honeybee_energy/result/osw.py +90 -0
  128. honeybee_energy/result/rdd.py +59 -0
  129. honeybee_energy/result/zsz.py +190 -0
  130. honeybee_energy/run.py +1577 -0
  131. honeybee_energy/schedule/__init__.py +1 -0
  132. honeybee_energy/schedule/day.py +626 -0
  133. honeybee_energy/schedule/dictutil.py +59 -0
  134. honeybee_energy/schedule/fixedinterval.py +1012 -0
  135. honeybee_energy/schedule/rule.py +619 -0
  136. honeybee_energy/schedule/ruleset.py +1867 -0
  137. honeybee_energy/schedule/typelimit.py +310 -0
  138. honeybee_energy/shw.py +315 -0
  139. honeybee_energy/simulation/__init__.py +1 -0
  140. honeybee_energy/simulation/control.py +214 -0
  141. honeybee_energy/simulation/daylightsaving.py +185 -0
  142. honeybee_energy/simulation/dictutil.py +51 -0
  143. honeybee_energy/simulation/output.py +646 -0
  144. honeybee_energy/simulation/parameter.py +606 -0
  145. honeybee_energy/simulation/runperiod.py +443 -0
  146. honeybee_energy/simulation/shadowcalculation.py +295 -0
  147. honeybee_energy/simulation/sizing.py +546 -0
  148. honeybee_energy/ventcool/__init__.py +5 -0
  149. honeybee_energy/ventcool/_crack_data.py +91 -0
  150. honeybee_energy/ventcool/afn.py +289 -0
  151. honeybee_energy/ventcool/control.py +269 -0
  152. honeybee_energy/ventcool/crack.py +126 -0
  153. honeybee_energy/ventcool/fan.py +493 -0
  154. honeybee_energy/ventcool/opening.py +365 -0
  155. honeybee_energy/ventcool/simulation.py +314 -0
  156. honeybee_energy/writer.py +1078 -0
  157. honeybee_energy-1.116.106.dist-info/METADATA +113 -0
  158. honeybee_energy-1.116.106.dist-info/RECORD +162 -0
  159. honeybee_energy-1.116.106.dist-info/WHEEL +5 -0
  160. honeybee_energy-1.116.106.dist-info/entry_points.txt +2 -0
  161. honeybee_energy-1.116.106.dist-info/licenses/LICENSE +661 -0
  162. honeybee_energy-1.116.106.dist-info/top_level.txt +1 -0
@@ -0,0 +1,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)