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,67 @@
1
+ """Establish the default materials within the honeybee_energy library."""
2
+ from honeybee_energy.material.dictutil import dict_to_material
3
+
4
+ from ._loadconstructions import _opaque_materials, _window_materials
5
+ from ._loadmaterials import _opaque_mat_standards_dict, _window_mat_standards_dict
6
+
7
+
8
+ # establish variables for the default materials used across the library
9
+ brick = _opaque_materials['Generic Brick']
10
+ concrete_lw = _opaque_materials['Generic LW Concrete']
11
+ concrete_hw = _opaque_materials['Generic HW Concrete']
12
+ insulation = _opaque_materials['Generic 50mm Insulation']
13
+ insulation_thin = _opaque_materials['Generic 25mm Insulation']
14
+ gypsum = _opaque_materials['Generic Gypsum Board']
15
+ acoustic_tile = _opaque_materials['Generic Acoustic Tile']
16
+ painted_metal = _opaque_materials['Generic Painted Metal']
17
+ roof_membrane = _opaque_materials['Generic Roof Membrane']
18
+ wood = _opaque_materials['Generic 25mm Wood']
19
+ wall_gap = _opaque_materials['Generic Wall Air Gap']
20
+ ceiling_gap = _opaque_materials['Generic Ceiling Air Gap']
21
+ clear_glass = _window_materials['Generic Clear Glass']
22
+ lowe_glass = _window_materials['Generic Low-e Glass']
23
+ air_gap = _window_materials['Generic Window Air Gap']
24
+ argon_gap = _window_materials['Generic Window Argon Gap']
25
+
26
+
27
+ # make lists of material identifiers to look up items in the library
28
+ OPAQUE_MATERIALS = tuple(_opaque_materials.keys()) + \
29
+ tuple(_opaque_mat_standards_dict.keys())
30
+ WINDOW_MATERIALS = tuple(_window_materials.keys()) + \
31
+ tuple(_window_mat_standards_dict.keys())
32
+
33
+
34
+ def opaque_material_by_identifier(material_identifier):
35
+ """Get an opaque material from the library given the material identifier.
36
+
37
+ Args:
38
+ material_identifier: A text string for the identifier of the material.
39
+ """
40
+ try: # first check the default data
41
+ return _opaque_materials[material_identifier]
42
+ except KeyError:
43
+ try: # search the extension data
44
+ _mat_dict = _opaque_mat_standards_dict[material_identifier]
45
+ return dict_to_material(_mat_dict)
46
+ except KeyError: # material is nowhere to be found; raise an error
47
+ raise ValueError(
48
+ '"{}" was not found in the opaque energy material library.'.format(
49
+ material_identifier))
50
+
51
+
52
+ def window_material_by_identifier(material_identifier):
53
+ """Get an window material from the library given the material identifier.
54
+
55
+ Args:
56
+ material_identifier: A text string for the identifier of the material.
57
+ """
58
+ try: # first check the default data
59
+ return _window_materials[material_identifier]
60
+ except KeyError:
61
+ try: # search the extension data
62
+ _mat_dict = _window_mat_standards_dict[material_identifier]
63
+ return dict_to_material(_mat_dict)
64
+ except KeyError: # material is nowhere to be found; raise an error
65
+ raise ValueError(
66
+ '"{}" was not found in the window energy material library.'.format(
67
+ material_identifier))
@@ -0,0 +1,125 @@
1
+ """Collection of program types."""
2
+ from honeybee_energy.programtype import ProgramType
3
+
4
+ from ._loadprogramtypes import _program_types, _program_types_standards_dict, \
5
+ _program_types_standards_registry, _building_programs_dict
6
+ import honeybee_energy.lib.schedules as _s
7
+
8
+
9
+ # establish variables for the default schedules used across the library
10
+ plenum_program = _program_types['Plenum']
11
+ office_program = _program_types['Generic Office Program']
12
+
13
+
14
+ # make lists of program types to look up items in the library
15
+ PROGRAM_TYPES = tuple(_program_types.keys()) + \
16
+ tuple(_program_types_standards_dict.keys())
17
+ STANDARDS_REGISTRY = _program_types_standards_registry
18
+ BUILDING_TYPES = tuple(_building_programs_dict.keys())
19
+
20
+
21
+ def program_type_by_identifier(program_type_identifier):
22
+ """Get a program_type from the library given its identifier.
23
+
24
+ Args:
25
+ program_type_identifier: A text string for the identifier of the ProgramType.
26
+ """
27
+ try:
28
+ return _program_types[program_type_identifier]
29
+ except KeyError:
30
+ try: # search the extension data
31
+ p_type_dict = _program_types_standards_dict[program_type_identifier]
32
+ scheds = _scheds_from_ptype_dict(p_type_dict)
33
+ return ProgramType.from_dict_abridged(p_type_dict, scheds)
34
+ except KeyError: # construction is nowhere to be found; raise an error
35
+ raise ValueError('"{}" was not found in the program type library.'.format(
36
+ program_type_identifier))
37
+
38
+
39
+ def building_program_type_by_identifier(building_type):
40
+ """Get a program_type representing the program mix of a building_type.
41
+
42
+ Args:
43
+ building_type: A text string for the type of building. This must appear
44
+ under the BUILDING_TYPES constant of this module.
45
+ """
46
+ program_id = '{} Building'.format(building_type)
47
+ try:
48
+ return _program_types[program_id]
49
+ except KeyError:
50
+ try: # search the extension data
51
+ bld_mix_dict = _building_programs_dict[building_type]
52
+ progs, ratios = [], []
53
+ for key, val in bld_mix_dict.items():
54
+ progs.append(program_type_by_identifier(key))
55
+ ratios.append(val)
56
+ bld_program = ProgramType.average(program_id, progs, ratios)
57
+ bld_program.lock()
58
+ _program_types[program_id] = bld_program # cache the object for next time
59
+ return bld_program
60
+ except KeyError: # construction is nowhere to be found; raise an error
61
+ raise ValueError(
62
+ '"{}" was not found in the building types.\nChoose from:\n{}'.format(
63
+ building_type, '\n'.join(BUILDING_TYPES)))
64
+
65
+
66
+ def _scheds_from_ptype_dict(p_type_dict):
67
+ """Get a dictionary of schedules used in a ProgramTypeAbridged dictionary."""
68
+ def add_schedule(scheds, p_type_dict, load_id, sch_id):
69
+ try:
70
+ sch_id = p_type_dict[load_id][sch_id]
71
+ scheds[sch_id] = _s.schedule_by_identifier(sch_id)
72
+ except KeyError:
73
+ pass # key is not included
74
+
75
+ scheds = {}
76
+ add_schedule(scheds, p_type_dict, 'people', 'occupancy_schedule')
77
+ add_schedule(scheds, p_type_dict, 'people', 'activity_schedule')
78
+ add_schedule(scheds, p_type_dict, 'lighting', 'schedule')
79
+ add_schedule(scheds, p_type_dict, 'electric_equipment', 'schedule')
80
+ add_schedule(scheds, p_type_dict, 'gas_equipment', 'schedule')
81
+ add_schedule(scheds, p_type_dict, 'service_hot_water', 'schedule')
82
+ add_schedule(scheds, p_type_dict, 'infiltration', 'schedule')
83
+ add_schedule(scheds, p_type_dict, 'ventilation', 'schedule')
84
+ add_schedule(scheds, p_type_dict, 'setpoint', 'heating_schedule')
85
+ add_schedule(scheds, p_type_dict, 'setpoint', 'cooling_schedule')
86
+ add_schedule(scheds, p_type_dict, 'setpoint', 'humidifying_schedule')
87
+ add_schedule(scheds, p_type_dict, 'setpoint', 'dehumidifying_schedule')
88
+ return scheds
89
+
90
+
91
+ def lib_dict_abridged_to_program_type(program_dict, schedules):
92
+ """Get a Python object of a ProgramType from an abridged dictionary.
93
+
94
+ When the sub-objects needed to create the program type are not available
95
+ in the resources provided, the current standards library will be searched.
96
+
97
+ Args:
98
+ program_dict: An abridged dictionary of a Honeybee ProgramType.
99
+ schedules: Dictionary of all schedule objects that might be used in the
100
+ construction set with the schedule identifiers as the keys.
101
+
102
+ Returns:
103
+ A Python object derived from the input program_dict.
104
+ """
105
+ def add_schedule(scheds, p_type_dict, load_id, sch_id):
106
+ try:
107
+ sch_id = p_type_dict[load_id][sch_id]
108
+ if sch_id not in scheds:
109
+ scheds[sch_id] = _s.schedule_by_identifier(sch_id)
110
+ except KeyError:
111
+ pass # key is not included
112
+
113
+ add_schedule(schedules, program_dict, 'people', 'occupancy_schedule')
114
+ add_schedule(schedules, program_dict, 'people', 'activity_schedule')
115
+ add_schedule(schedules, program_dict, 'lighting', 'schedule')
116
+ add_schedule(schedules, program_dict, 'electric_equipment', 'schedule')
117
+ add_schedule(schedules, program_dict, 'gas_equipment', 'schedule')
118
+ add_schedule(schedules, program_dict, 'service_hot_water', 'schedule')
119
+ add_schedule(schedules, program_dict, 'infiltration', 'schedule')
120
+ add_schedule(schedules, program_dict, 'ventilation', 'schedule')
121
+ add_schedule(schedules, program_dict, 'setpoint', 'heating_schedule')
122
+ add_schedule(schedules, program_dict, 'setpoint', 'cooling_schedule')
123
+ add_schedule(schedules, program_dict, 'setpoint', 'humidifying_schedule')
124
+ add_schedule(schedules, program_dict, 'setpoint', 'dehumidifying_schedule')
125
+ return ProgramType.from_dict_abridged(program_dict, schedules)
@@ -0,0 +1,61 @@
1
+ """Establish the default schedule types within the honeybee_energy library."""
2
+ from honeybee_energy.schedule.dictutil import dict_abridged_to_schedule
3
+ from ._loadschedules import _schedules, _schedule_standards_dict
4
+
5
+ import honeybee_energy.lib.scheduletypelimits as _stl
6
+
7
+
8
+ # establish variables for the default schedules used across the library
9
+ seated_activity = _schedules['Seated Adult Activity']
10
+ always_on = _schedules['Always On']
11
+ generic_office_occupancy = _schedules['Generic Office Occupancy']
12
+ generic_office_lighting = _schedules['Generic Office Lighting']
13
+ generic_office_equipment = _schedules['Generic Office Equipment']
14
+ generic_office_infiltration = _schedules['Generic Office Infiltration']
15
+ generic_office_heating = _schedules['Generic Office Heating']
16
+ generic_office_cooling = _schedules['Generic Office Cooling']
17
+
18
+
19
+ # make lists of schedules to look up items in the library
20
+ SCHEDULES = tuple(_schedules.keys()) + tuple(_schedule_standards_dict.keys())
21
+
22
+
23
+ def schedule_by_identifier(schedule_identifier):
24
+ """Get a schedule from the library given its identifier.
25
+
26
+ Args:
27
+ schedule_identifier: A text string for the identifier of the schedule.
28
+ """
29
+ try: # first check the default data
30
+ return _schedules[schedule_identifier]
31
+ except KeyError:
32
+ try: # search the extension data
33
+ _sch_dict = _schedule_standards_dict[schedule_identifier]
34
+ try:
35
+ _tl = _stl.schedule_type_limit_by_identifier(
36
+ _sch_dict['schedule_type_limit'])
37
+ except KeyError:
38
+ _tl = _stl.fractional
39
+ return dict_abridged_to_schedule(_sch_dict, {_tl.identifier: _tl})
40
+ except KeyError: # schedule is nowhere to be found; raise an error
41
+ raise ValueError('"{}" was not found in the schedule library.'.format(
42
+ schedule_identifier))
43
+
44
+
45
+ def lib_dict_abridged_to_schedule(sch_dict, schedule_type_limits):
46
+ """Get a Python object of any Schedule from an abridged dictionary.
47
+
48
+ Args:
49
+ sch_dict: A dictionary of any Honeybee energy schedules. Note
50
+ that this should be a non-abridged dictionary to be valid.
51
+ schedule_type_limits: Dictionary of all schedule type limit objects that
52
+ might be used in the schedule with the type limit identifiers as the keys.
53
+
54
+ Returns:
55
+ A Python object derived from the input sch_dict.
56
+ """
57
+ if 'schedule_type_limit' in sch_dict and sch_dict['schedule_type_limit'] is not None:
58
+ if sch_dict['schedule_type_limit'] not in schedule_type_limits:
59
+ schedule_type_limits[sch_dict['schedule_type_limit']] = \
60
+ _stl.schedule_type_limit_by_identifier(sch_dict['schedule_type_limit'])
61
+ return dict_abridged_to_schedule(sch_dict, schedule_type_limits)
@@ -0,0 +1,31 @@
1
+ """Establish the default schedule types within the honeybee_energy library."""
2
+ from ._loadtypelimits import _schedule_type_limits
3
+
4
+
5
+ # establish variables for the default schedule types used across the library
6
+ fractional = _schedule_type_limits['Fractional']
7
+ on_off = _schedule_type_limits['On-Off']
8
+ temperature = _schedule_type_limits['Temperature']
9
+ activity_level = _schedule_type_limits['Activity Level']
10
+ power = _schedule_type_limits['Power']
11
+ humidity = _schedule_type_limits['Humidity']
12
+ angle = _schedule_type_limits['Angle']
13
+ delta_temperature = _schedule_type_limits['Delta Temperature']
14
+
15
+
16
+ # make lists of schedule types to look up items in the library
17
+ SCHEDULE_TYPE_LIMITS = tuple(_schedule_type_limits.keys())
18
+
19
+
20
+ def schedule_type_limit_by_identifier(schedule_type_limit_identifier):
21
+ """Get a schedule type from the library given its identifier.
22
+
23
+ Args:
24
+ schedule_type_limit_identifier: A text string for the identifier of the
25
+ schedule type.
26
+ """
27
+ try:
28
+ return _schedule_type_limits[schedule_type_limit_identifier]
29
+ except KeyError:
30
+ raise ValueError('"{}" was not found in the schedule type limits '
31
+ 'library.'.format(schedule_type_limit_identifier))
@@ -0,0 +1 @@
1
+ """honeybee-energy load definitions."""
@@ -0,0 +1,190 @@
1
+ # coding=utf-8
2
+ """Base object for all load definitions."""
3
+ from __future__ import division
4
+ import random
5
+
6
+ from honeybee._lockable import lockable
7
+ from honeybee.typing import valid_ep_string, tuple_with_length
8
+
9
+ from ..schedule.ruleset import ScheduleRuleset
10
+ from ..schedule.fixedinterval import ScheduleFixedInterval
11
+
12
+
13
+ @lockable
14
+ class _LoadBase(object):
15
+ """A base object for all load definitions.
16
+
17
+ Args:
18
+ identifier: Text string for a unique Load ID. Must be < 100 characters
19
+ and not contain any EnergyPlus special characters. This will be used to
20
+ identify the object across a model and in the exported IDF.
21
+
22
+ Properties:
23
+ * identifier
24
+ * display_name
25
+ * user_data
26
+ """
27
+ __slots__ = ('_identifier', '_display_name', '_locked',
28
+ '_properties', '_user_data')
29
+
30
+ def __init__(self, identifier):
31
+ """Initialize LoadBase."""
32
+ self._locked = False # unlocked by default
33
+ self.identifier = identifier
34
+ self._display_name = None
35
+ self._user_data = None
36
+ self._properties = None
37
+
38
+ @property
39
+ def identifier(self):
40
+ """Get or set the text string for object identifier."""
41
+ return self._identifier
42
+
43
+ @identifier.setter
44
+ def identifier(self, identifier):
45
+ self._identifier = valid_ep_string(identifier)
46
+
47
+ @property
48
+ def display_name(self):
49
+ """Get or set a string for the object name without any character restrictions.
50
+
51
+ If not set, this will be equal to the identifier.
52
+ """
53
+ if self._display_name is None:
54
+ return self._identifier
55
+ return self._display_name
56
+
57
+ @display_name.setter
58
+ def display_name(self, value):
59
+ if value is not None:
60
+ try:
61
+ value = str(value)
62
+ except UnicodeEncodeError: # Python 2 machine lacking the character set
63
+ pass # keep it as unicode
64
+ self._display_name = value
65
+
66
+ @property
67
+ def user_data(self):
68
+ """Get or set an optional dictionary for additional meta data for this object.
69
+
70
+ This will be None until it has been set. All keys and values of this
71
+ dictionary should be of a standard Python type to ensure correct
72
+ serialization of the object to/from JSON (eg. str, float, int, list, dict)
73
+ """
74
+ return self._user_data
75
+
76
+ @user_data.setter
77
+ def user_data(self, value):
78
+ if value is not None:
79
+ assert isinstance(value, dict), 'Expected dictionary for honeybee_energy' \
80
+ 'object user_data. Got {}.'.format(type(value))
81
+ self._user_data = value
82
+
83
+ @property
84
+ def properties(self):
85
+ """Get properties for extensions."""
86
+ return self._properties
87
+
88
+ def duplicate(self):
89
+ """Get a copy of this object."""
90
+ return self.__copy__()
91
+
92
+ def _check_fractional_schedule_type(self, schedule, obj_name=''):
93
+ """Check that the type limit of an input schedule is fractional."""
94
+ if schedule.schedule_type_limit is not None:
95
+ t_lim = schedule.schedule_type_limit
96
+ assert t_lim.unit == 'fraction', '{} schedule should be fractional ' \
97
+ '[Dimensionless]. Got a schedule of unit_type ' \
98
+ '[{}].'.format(obj_name, t_lim.unit_type)
99
+ assert t_lim.lower_limit == 0, '{} schedule should have either no type ' \
100
+ 'limit or a lower limit of 0. Got a schedule type with lower limit ' \
101
+ '[{}].'.format(obj_name, t_lim.lower_limit)
102
+ assert t_lim.upper_limit == 1, '{} schedule should have either no type ' \
103
+ 'limit or an upper limit of 1. Got a schedule type with upper limit ' \
104
+ '[{}].'.format(obj_name, t_lim.upper_limit)
105
+
106
+ @staticmethod
107
+ def _check_avg_weights(load_objects, weights, obj_name):
108
+ """Check input weights of an average calculation and generate them if None."""
109
+ if weights is None:
110
+ weights = unity_weights = [1 / len(load_objects)] * len(load_objects) if \
111
+ len(load_objects) > 0 else []
112
+ else:
113
+ weights = tuple_with_length(weights, len(load_objects), float,
114
+ 'average {} weights'.format(obj_name))
115
+ total_weight = sum(weights)
116
+ assert total_weight <= 1 + 1e-3, 'Average {} weights must be less than ' \
117
+ 'or equal to 1. Got {}.'.format(obj_name, sum(weights))
118
+ unity_weights = [w / total_weight for w in weights]
119
+
120
+ return weights, unity_weights
121
+
122
+ @staticmethod
123
+ def _average_schedule(identifier, scheds, weights, timestep):
124
+ """Average a set of schedules together (no matter their type)."""
125
+ try:
126
+ return ScheduleRuleset.average_schedules(
127
+ identifier, scheds, weights, timestep)
128
+ except AttributeError:
129
+ return ScheduleFixedInterval.average_schedules(identifier, scheds, weights)
130
+
131
+ @staticmethod
132
+ def _max_schedule(identifier, scheds, timestep=1):
133
+ """Create a schedule that uses the maximum value between schedules."""
134
+ try:
135
+ return ScheduleRuleset.max_schedules(identifier, scheds, timestep)
136
+ except AttributeError:
137
+ return ScheduleFixedInterval.max_schedules(identifier, scheds)
138
+
139
+ @staticmethod
140
+ def _min_schedule(identifier, scheds, timestep=1):
141
+ """Create a schedule that uses the minimum value between schedules."""
142
+ try:
143
+ return ScheduleRuleset.min_schedules(identifier, scheds, timestep)
144
+ except AttributeError:
145
+ return ScheduleFixedInterval.min_schedules(identifier, scheds)
146
+
147
+ @staticmethod
148
+ def _get_schedule_from_dict(sch_dict):
149
+ """Get a schedule object from a schedule dictionary."""
150
+ if sch_dict['type'] == 'ScheduleRuleset':
151
+ return ScheduleRuleset.from_dict(sch_dict)
152
+ elif sch_dict['type'] == 'ScheduleFixedInterval':
153
+ return ScheduleFixedInterval.from_dict(sch_dict)
154
+ else:
155
+ raise NotImplementedError(
156
+ 'Schedule {} is not supported.'.format(sch_dict['type']))
157
+
158
+ @staticmethod
159
+ def _shift_schedule(schedule, schedule_offset, timestep):
160
+ """Take a schedule and shift it behind and then ahead."""
161
+ if schedule_offset == 0:
162
+ return [schedule] * 3
163
+ else:
164
+ behind = schedule.shift_by_step(-schedule_offset, timestep)
165
+ ahead = schedule.shift_by_step(schedule_offset, timestep)
166
+ return [behind, schedule, ahead]
167
+
168
+ @staticmethod
169
+ def _gaussian_values(count, load_value, load_stdev):
170
+ """Generate Gaussian values for a load and a corresponding schedule integers."""
171
+ new_loads, sch_int = [], []
172
+ for _ in range(count):
173
+ val = random.gauss(load_value, load_stdev)
174
+ final_val = 1e-6 if val <= 0 else val # avoid negative values
175
+ new_loads.append(final_val)
176
+ sch_int.append(random.randint(0, 2))
177
+ return new_loads, sch_int
178
+
179
+ def __copy__(self):
180
+ new_obj = _LoadBase(self.identifier)
181
+ new_obj._display_name = self._display_name
182
+ new_obj._user_data = None if self._user_data is None else self._user_data.copy()
183
+ return new_obj
184
+
185
+ def ToString(self):
186
+ """Overwrite .NET ToString."""
187
+ return self.__repr__()
188
+
189
+ def __repr__(self):
190
+ return 'Load Base: {}'.format(self.display_name)