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,397 @@
1
+ # coding=utf-8
2
+ """Room daylight controls, including sensor location and setpoint."""
3
+ from __future__ import division
4
+ import math
5
+
6
+ from ladybug_geometry.geometry3d.pointvector import Point3D
7
+ from honeybee.typing import float_in_range, float_positive
8
+
9
+ from ..reader import parse_idf_string
10
+ from ..writer import generate_idf_string
11
+
12
+
13
+ class DaylightingControl(object):
14
+ """Room daylight controls, including sensor location and setpoint.
15
+
16
+ Args:
17
+ sensor_position: A ladybug_geometry Point3D for the position of the daylight
18
+ sensor within the parent Room. This point should lie within the Room
19
+ volume in order for the results to be meaningful. The ladybug_geometry
20
+ Polyface.is_point_inside method can be used to check whether a given
21
+ point is inside the room volume.
22
+ illuminance_setpoint: A number for the illuminance setpoint in lux beyond
23
+ which electric lights are dimmed if there is sufficient daylight.
24
+ Some common setpoints are listed below. (Default: 300 lux).
25
+
26
+ * 50 lux - Corridors and hallways.
27
+ * 150 lux - Computer work spaces (screens provide illumination).
28
+ * 300 lux - Paper work spaces (reading from surfaces needing illumination).
29
+ * 500 lux - Retail spaces or museums illuminating merchandise/artifacts.
30
+ * 1000 lux - Operating rooms and workshops where light is needed for safety.
31
+
32
+ control_fraction: A number between 0 and 1 that represents the fraction of
33
+ the Room lights that are dimmed when the illuminance at the sensor
34
+ position is at the specified illuminance. 1 indicates that all lights are
35
+ dim-able while 0 indicates that no lights are dim-able. Deeper rooms
36
+ should have lower control fractions to account for the face that the
37
+ lights in the back of the space do not dim in response to suitable
38
+ daylight at the front of the room. (Default: 1).
39
+ min_power_input: A number between 0 and 1 for the the lowest power the
40
+ lighting system can dim down to, expressed as a fraction of maximum
41
+ input power. (Default: 0.3).
42
+ min_light_output: A number between 0 and 1 the lowest lighting output the
43
+ lighting system can dim down to, expressed as a fraction of maximum
44
+ light output. (Default: 0.2).
45
+ off_at_minimum: Boolean to note whether lights should switch off completely
46
+ when they get to the minimum power input. (Default: False).
47
+
48
+
49
+ Properties:
50
+ * sensor_position
51
+ * illuminance_setpoint
52
+ * control_fraction
53
+ * min_power_input
54
+ * min_light_output
55
+ * off_at_minimum
56
+ * parent
57
+ * has_parent
58
+ * is_sensor_inside_parent
59
+ """
60
+ __slots__ = ('_sensor_position', '_illuminance_setpoint', '_control_fraction',
61
+ '_min_power_input', '_min_light_output', '_off_at_minimum', '_parent')
62
+
63
+ def __init__(self, sensor_position, illuminance_setpoint=300, control_fraction=1,
64
+ min_power_input=0.3, min_light_output=0.2, off_at_minimum=False):
65
+ self.sensor_position = sensor_position
66
+ self.illuminance_setpoint = illuminance_setpoint
67
+ self.control_fraction = control_fraction
68
+ self.min_power_input = min_power_input
69
+ self.min_light_output = min_light_output
70
+ self.off_at_minimum = off_at_minimum
71
+ self._parent = None # _parent will be set when the object is added to a Room
72
+
73
+ @property
74
+ def sensor_position(self):
75
+ """Get or set a Point3D for the sensor position for the daylight sensor."""
76
+ return self._sensor_position
77
+
78
+ @sensor_position.setter
79
+ def sensor_position(self, value):
80
+ assert isinstance(value, Point3D), 'Expected Point3D for DaylightingControl ' \
81
+ 'sensor_position. Got {}.'.format(type(value))
82
+ self._sensor_position = value
83
+
84
+ @property
85
+ def illuminance_setpoint(self):
86
+ """Get or set a number for the illuminance setpoint in lux."""
87
+ return self._illuminance_setpoint
88
+
89
+ @illuminance_setpoint.setter
90
+ def illuminance_setpoint(self, value):
91
+ self._illuminance_setpoint = float_positive(value, 'illuminance setpoint')
92
+
93
+ @property
94
+ def control_fraction(self):
95
+ """Get or set the fraction of the Room lights that are dimmed."""
96
+ return self._control_fraction
97
+
98
+ @control_fraction.setter
99
+ def control_fraction(self, value):
100
+ if value is not None:
101
+ self._control_fraction = float_in_range(
102
+ value, 0.0, 1.0, 'daylighting control fraction')
103
+ else:
104
+ self._control_fraction = 1
105
+
106
+ @property
107
+ def min_power_input(self):
108
+ """Get or set the lowest power the lighting system can dim down to."""
109
+ return self._min_power_input
110
+
111
+ @min_power_input.setter
112
+ def min_power_input(self, value):
113
+ if value is not None:
114
+ self._min_power_input = float_in_range(
115
+ value, 0.0, 1.0, 'daylighting control min_power_input')
116
+ else:
117
+ self._min_power_input = 0.3
118
+
119
+ @property
120
+ def min_light_output(self):
121
+ """Get or set the lowest lighting output the lighting system can dim down to."""
122
+ return self._min_light_output
123
+
124
+ @min_light_output.setter
125
+ def min_light_output(self, value):
126
+ if value is not None:
127
+ self._min_light_output = float_in_range(
128
+ value, 0.0, 1.0, 'daylighting control min_light_output')
129
+ else:
130
+ self._min_light_output = 0.2
131
+
132
+ @property
133
+ def off_at_minimum(self):
134
+ """Get or set a boolean to indicate whether the lights switch off completely."""
135
+ return self._off_at_minimum
136
+
137
+ @off_at_minimum.setter
138
+ def off_at_minimum(self, value):
139
+ self._off_at_minimum = bool(value)
140
+
141
+ @property
142
+ def parent(self):
143
+ """Get the parent Room if assigned. None if not assigned."""
144
+ return self._parent
145
+
146
+ @property
147
+ def has_parent(self):
148
+ """Get a boolean noting whether this object has a parent Room."""
149
+ return self._parent is not None
150
+
151
+ @property
152
+ def is_sensor_inside_parent(self):
153
+ """Get a boolean for whether the sensor position is inside the parent Room.
154
+
155
+ This will always be True if no parent is assigned.
156
+ """
157
+ if self.parent is not None:
158
+ return self.parent.geometry.is_point_inside(self.sensor_position)
159
+
160
+ def move(self, moving_vec):
161
+ """Move this object along a vector.
162
+
163
+ Args:
164
+ moving_vec: A ladybug_geometry Vector3D with the direction and distance
165
+ to move the sensor.
166
+ """
167
+ self.sensor_position = self.sensor_position.move(moving_vec)
168
+
169
+ def rotate(self, angle, axis, origin):
170
+ """Rotate this object by a certain angle around an axis and origin.
171
+
172
+ Args:
173
+ angle: An angle for rotation in degrees.
174
+ axis: Rotation axis as a Vector3D.
175
+ origin: A ladybug_geometry Point3D for the origin around which the
176
+ object will be rotated.
177
+ """
178
+ rad_angle = math.radians(angle)
179
+ self.sensor_position = self.sensor_position.rotate(axis, rad_angle, origin)
180
+
181
+ def rotate_xy(self, angle, origin):
182
+ """Rotate this object counterclockwise in the world XY plane by a certain angle.
183
+
184
+ Args:
185
+ angle: An angle in degrees.
186
+ origin: A ladybug_geometry Point3D for the origin around which the
187
+ object will be rotated.
188
+ """
189
+ rad_angle = math.radians(angle)
190
+ self.sensor_position = self.sensor_position.rotate_xy(rad_angle, origin)
191
+
192
+ def reflect(self, plane):
193
+ """Reflect this object across a plane.
194
+
195
+ Args:
196
+ plane: A ladybug_geometry Plane across which the object will
197
+ be reflected.
198
+ """
199
+ self.sensor_position = self.sensor_position.reflect(plane.n, plane.o)
200
+
201
+ def scale(self, factor, origin=None):
202
+ """Scale this object by a factor from an origin point.
203
+
204
+ Args:
205
+ factor: A number representing how much the object should be scaled.
206
+ origin: A ladybug_geometry Point3D representing the origin from which
207
+ to scale. If None, it will be scaled from the World origin (0, 0, 0).
208
+ """
209
+ self.sensor_position = self.sensor_position.scale(factor, origin)
210
+
211
+ @classmethod
212
+ def from_idf(cls, idf_string, idf_point_string):
213
+ """Create a DaylightingControl object from an EnergyPlus IDF text string.
214
+
215
+ Args:
216
+ idf_string: A text string fully describing an EnergyPlus
217
+ Daylighting:Controls definition.
218
+ idf_point_string: A text string fully describing an EnergyPlus
219
+ Daylighting:ReferencePoint definition.
220
+
221
+ Returns:
222
+ A DaylightingControl object loaded from the idf_string.
223
+ """
224
+ # check the inputs
225
+ ep_strs = parse_idf_string(idf_string, 'Daylighting:Controls,')
226
+ ep_strs_pt = parse_idf_string(idf_point_string, 'Daylighting:ReferencePoint,')
227
+ assert ep_strs[1] == ep_strs_pt[1], 'Zone names do not match between ' \
228
+ 'IDF daylight controls and reference point'
229
+
230
+ # extract the properties from the string
231
+ off_at_min = True if ep_strs[4].lower() == 'continuousoff' else False
232
+ min_power = ep_strs[5] if ep_strs[5] != '' else 0.3
233
+ min_output = ep_strs[6] if ep_strs[6] != '' else 0.2
234
+ cntrl_fract = 1
235
+ setpoint = 500
236
+ try:
237
+ cntrl_fract = ep_strs[14] if ep_strs[14] != '' else 1
238
+ setpoint = ep_strs[15] if ep_strs[15] != '' else 500
239
+ except IndexError:
240
+ pass # shorter daylight controls definition lacking certain fields
241
+
242
+ # extract the coordinates of the control point
243
+ ptx, pty = ep_strs_pt[2], ep_strs_pt[3]
244
+ try:
245
+ ptz = ep_strs_pt[4] if ep_strs_pt[4] != '' else 0.8
246
+ except IndexError:
247
+ pass # shorter definition lacking certain fields
248
+
249
+ # return the daylighting object
250
+ return cls(Point3D(ptx, pty, ptz), setpoint, cntrl_fract,
251
+ min_power, min_output, off_at_min)
252
+
253
+ @classmethod
254
+ def from_dict(cls, data):
255
+ """Create a DaylightingControl object from a dictionary.
256
+
257
+ Args:
258
+ data: A DaylightingControl dictionary in following the format below.
259
+
260
+ .. code-block:: python
261
+
262
+ {
263
+ "type": 'DaylightingControl',
264
+ "sensor_position": [5, 5, 0.8] # array of xyz coordinates for the sensor
265
+ "illuminance_setpoint": 300, # number for illuminance setpoint in lux
266
+ "control_fraction": 0.5, # fraction of the lights that are dim-able
267
+ "min_power_input": 0.3, # minimum fraction of lighting power
268
+ "min_light_output": 0.2, # minimum fraction of lighting output
269
+ "off_at_minimum": True # boolean for whether the lights switch off
270
+ }
271
+ """
272
+ assert data['type'] == 'DaylightingControl', \
273
+ 'Expected DaylightingControl dictionary. Got {}.'.format(data['type'])
274
+ sensor = Point3D.from_array(data['sensor_position'])
275
+ setpoint = data['illuminance_setpoint'] \
276
+ if 'illuminance_setpoint' in data else 300
277
+ cntrl_fract = data['control_fraction'] if 'control_fraction' in data else 1
278
+ min_pow = data['min_power_input'] if 'min_power_input' in data else 0.3
279
+ min_out = data['min_light_output'] if 'min_light_output' in data else 0.2
280
+ off_min = data['off_at_minimum'] if 'off_at_minimum' in data else False
281
+ return cls(sensor, setpoint, cntrl_fract, min_pow, min_out, off_min)
282
+
283
+ def to_idf(self):
284
+ """IDF string representation of DaylightingControl object.
285
+
286
+ Returns:
287
+ A tuple with two values.
288
+
289
+ - idf_control -- IDF string for the Daylighting:Controls object.
290
+
291
+ - idf_point -- IDF string for the Daylighting:ReferencePoint object.
292
+
293
+ .. code-block:: shell
294
+
295
+ Daylighting:Controls,
296
+ West Zone_DaylCtrl, !- Name
297
+ West Zone, !- Zone or Space Name
298
+ SplitFlux, !- Daylighting Method
299
+ , !- Availability Schedule Name
300
+ Continuous, !- Lighting Control Type
301
+ 0.3, !- Minimum Input Power Fraction for Dimming
302
+ 0.2, !- Minimum Light Output Fraction for Dimming
303
+ , !- Number of Stepped Control Steps
304
+ 1.0, !- Probability Lighting Needs Reset
305
+ West Zone_DaylRefPt1, !- Glare Daylighting Reference Point Name
306
+ 180.0, !- Glare Azimuth Angle of View Direction {deg}
307
+ 20.0, !- Maximum Allowable Discomfort Glare Index
308
+ , !- DElight Gridding Resolution {m2}
309
+ West Zone_DaylRefPt1, !- Daylighting Reference Point 1 Name
310
+ 1.0, !- Fraction of Lights Controlled by Point 1
311
+ 500.; !- Illuminance Setpoint at Reference Point 1 {lux}
312
+
313
+ Daylighting:ReferencePoint,
314
+ West Zone_DaylRefPt1, !- Name
315
+ West Zone, !- Zone or Space Name
316
+ 3.048, !- X-Coordinate of Reference Point {m}
317
+ 3.048, !- Y-Coordinate of Reference Point {m}
318
+ 0.9; !- Z-Coordinate of Reference Point {m}
319
+ """
320
+ # create the identifiers
321
+ zone_id = self.parent.identifier if self.has_parent else 'Unknown_Room'
322
+ controls_name = '{}_Daylighting'.format(zone_id)
323
+ point_name = '{}_Sensor'.format(zone_id)
324
+
325
+ # create the IDF string for the Daylighting:Controls
326
+ cntrl_type = 'ContinuousOff' if self.off_at_minimum else 'Continuous'
327
+ cntrl_values = \
328
+ (controls_name, zone_id, 'SplitFlux', '', cntrl_type, self.min_power_input,
329
+ self.min_light_output, '', '', '', '', '', '', point_name,
330
+ self.control_fraction, self.illuminance_setpoint)
331
+ cntrl_comments = \
332
+ ('name', 'zone name', 'daylight method', 'availability schedule',
333
+ 'control type', 'min power input', 'min lighting input',
334
+ 'control step count', 'reset probability', 'glare point', 'glare azimuth',
335
+ 'max glare index', 'DElight grid res', 'reference point',
336
+ 'control fraction', 'illuminance setpoint')
337
+ idf_control = generate_idf_string(
338
+ 'Daylighting:Controls', cntrl_values, cntrl_comments)
339
+
340
+ # create the IDF string for the Daylighting:ReferencePoint
341
+ sensor = self.sensor_position
342
+ pt_values = (point_name, zone_id, sensor.x, sensor.y, sensor.z)
343
+ pt_comments = ('name', 'zone name', 'X', 'Y', 'Z')
344
+ idf_point = generate_idf_string(
345
+ 'Daylighting:ReferencePoint', pt_values, pt_comments)
346
+ return idf_control, idf_point
347
+
348
+ def to_dict(self, abridged=False):
349
+ """DaylightingControl dictionary representation.
350
+
351
+ Args:
352
+ abridged: Boolean to note whether the full dictionary describing the
353
+ object should be returned (False) or just an abridged version (True),
354
+ which only specifies the identifiers of schedules. Default: False.
355
+ """
356
+ return {
357
+ 'type': 'DaylightingControl',
358
+ 'sensor_position': self.sensor_position.to_array(),
359
+ 'illuminance_setpoint': self.illuminance_setpoint,
360
+ 'control_fraction': self.control_fraction,
361
+ 'min_power_input': self.min_power_input,
362
+ 'min_light_output': self.min_light_output,
363
+ 'off_at_minimum': self.off_at_minimum
364
+ }
365
+
366
+ def duplicate(self):
367
+ """Get a copy of this object."""
368
+ return self.__copy__()
369
+
370
+ def ToString(self):
371
+ """Overwrite .NET ToString."""
372
+ return self.__repr__()
373
+
374
+ def __key(self):
375
+ """A tuple based on the object properties, useful for hashing."""
376
+ return (hash(self.sensor_position), self.illuminance_setpoint,
377
+ self.control_fraction, self.min_power_input, self.min_light_output,
378
+ self.off_at_minimum)
379
+
380
+ def __hash__(self):
381
+ return hash(self.__key())
382
+
383
+ def __eq__(self, other):
384
+ return isinstance(other, DaylightingControl) and self.__key() == other.__key()
385
+
386
+ def __ne__(self, other):
387
+ return not self.__eq__(other)
388
+
389
+ def __copy__(self):
390
+ return DaylightingControl(
391
+ self.sensor_position, self.illuminance_setpoint, self.control_fraction,
392
+ self.min_power_input, self.min_light_output, self.off_at_minimum)
393
+
394
+ def __repr__(self):
395
+ pt = self.sensor_position
396
+ return 'DaylightingControl: [sensor: {}] [{} lux]'.format(
397
+ '(%.2f, %.2f, %.2f)' % (pt.x, pt.y, pt.z), self.illuminance_setpoint)
@@ -0,0 +1,47 @@
1
+ # coding=utf-8
2
+ """Utilities to convert load dictionaries to Python objects."""
3
+ from honeybee_energy.load.people import People
4
+ from honeybee_energy.load.lighting import Lighting
5
+ from honeybee_energy.load.equipment import ElectricEquipment, GasEquipment
6
+ from honeybee_energy.load.infiltration import Infiltration
7
+ from honeybee_energy.load.ventilation import Ventilation
8
+ from honeybee_energy.load.setpoint import Setpoint
9
+
10
+
11
+ LOAD_TYPES = ('People', 'Lighting', 'ElectricEquipment', 'GasEquipment',
12
+ 'Infiltration', 'Ventilation', 'Setpoint')
13
+
14
+
15
+ def dict_to_load(load_dict, raise_exception=True):
16
+ """Get a Python object of any Load from a dictionary.
17
+
18
+ Args:
19
+ load_dict: A dictionary of any Honeybee energy load. Note
20
+ that this should be a non-abridged dictionary to be valid.
21
+ raise_exception: Boolean to note whether an excpetion should be raised
22
+ if the object is not identified as a load. Default: True.
23
+
24
+ Returns:
25
+ A Python object derived from the input load_dict.
26
+ """
27
+ try: # get the type key from the dictionary
28
+ load_type = load_dict['type']
29
+ except KeyError:
30
+ raise ValueError('Load dictionary lacks required "type" key.')
31
+
32
+ if load_type == 'People':
33
+ return People.from_dict(load_dict)
34
+ elif load_type == 'Lighting':
35
+ return Lighting.from_dict(load_dict)
36
+ elif load_type == 'ElectricEquipment':
37
+ return ElectricEquipment.from_dict(load_dict)
38
+ elif load_type == 'GasEquipment':
39
+ return GasEquipment.from_dict(load_dict)
40
+ elif load_type == 'Infiltration':
41
+ return Infiltration.from_dict(load_dict)
42
+ elif load_type == 'Ventilation':
43
+ return Ventilation.from_dict(load_dict)
44
+ elif load_type == 'Setpoint':
45
+ return Setpoint.from_dict(load_dict)
46
+ elif raise_exception:
47
+ raise ValueError('{} is not a recognized energy Load type'.format(load_type))