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,1360 @@
1
+ # coding=utf-8
2
+ """Shade materials representing shades, blinds, or screens in a window construction.
3
+
4
+ They can exist in only one of three possible locations in a window construction:
5
+
6
+ 1) On the innermost material layer.
7
+ 2) On the outermost material layer.
8
+ 3) In between two glazing materials. In the case of window constructions with
9
+ multiple glazing surfaces, the shade material must be between the two
10
+ inner glass layers.
11
+
12
+ Note that shade materials should never be bounded by gas gap layers in honeybee-energy.
13
+ """
14
+ from __future__ import division
15
+
16
+ from ._base import _EnergyMaterialWindowBase
17
+ from .gas import EnergyWindowMaterialGas
18
+ from ..properties.extension import EnergyWindowMaterialShadeProperties, EnergyWindowMaterialBlindProperties
19
+ from ..reader import parse_idf_string
20
+ from ..writer import generate_idf_string
21
+
22
+ from honeybee._lockable import lockable
23
+ from honeybee.typing import float_in_range, float_positive
24
+
25
+
26
+ @lockable
27
+ class _EnergyWindowMaterialShadeBase(_EnergyMaterialWindowBase):
28
+ """Base for all shade material layers."""
29
+ __slots__ = ('_infrared_transmittance', '_emissivity', '_distance_to_glass',
30
+ '_top_opening_multiplier', '_bottom_opening_multiplier',
31
+ '_left_opening_multiplier', '_right_opening_multiplier')
32
+
33
+ def __init__(self, identifier, infrared_transmittance=0, emissivity=0.9,
34
+ distance_to_glass=0.05, opening_multiplier=0.5):
35
+ """Initialize base shade energy material."""
36
+ _EnergyMaterialWindowBase.__init__(self, identifier)
37
+ self.infrared_transmittance = infrared_transmittance
38
+ self.emissivity = emissivity
39
+ self.distance_to_glass = distance_to_glass
40
+ self.set_all_opening_multipliers(opening_multiplier)
41
+
42
+ @property
43
+ def is_shade_material(self):
44
+ """Boolean to note whether the material is a shade layer."""
45
+ return True
46
+
47
+ @property
48
+ def infrared_transmittance(self):
49
+ """Get or set the infrared transmittance of the shade."""
50
+ return self._infrared_transmittance
51
+
52
+ @infrared_transmittance.setter
53
+ def infrared_transmittance(self, ir_tr):
54
+ self._infrared_transmittance = float_in_range(
55
+ ir_tr, 0.0, 1.0, 'shade material infrared transmittance')
56
+
57
+ @property
58
+ def emissivity(self):
59
+ """Get or set the hemispherical emissivity of the shade."""
60
+ return self._emissivity
61
+
62
+ @emissivity.setter
63
+ def emissivity(self, ir_e):
64
+ ir_e = float_in_range(ir_e, 0.0, 1.0, 'shade material emissivity')
65
+ self._emissivity = ir_e
66
+
67
+ @property
68
+ def distance_to_glass(self):
69
+ """Get or set the shade distance to the glass [m]."""
70
+ return self._distance_to_glass
71
+
72
+ @distance_to_glass.setter
73
+ def distance_to_glass(self, dist):
74
+ self._distance_to_glass = float_in_range(
75
+ dist, 0.001, 1.0, 'shade material distance to glass')
76
+
77
+ @property
78
+ def top_opening_multiplier(self):
79
+ """Get or set the top opening multiplier."""
80
+ return self._top_opening_multiplier
81
+
82
+ @top_opening_multiplier.setter
83
+ def top_opening_multiplier(self, multiplier):
84
+ self._top_opening_multiplier = float_in_range(
85
+ multiplier, 0.0, 1.0, 'shade material opening multiplier')
86
+
87
+ @property
88
+ def bottom_opening_multiplier(self):
89
+ """Get or set the bottom opening multiplier."""
90
+ return self._bottom_opening_multiplier
91
+
92
+ @bottom_opening_multiplier.setter
93
+ def bottom_opening_multiplier(self, multiplier):
94
+ self._bottom_opening_multiplier = float_in_range(
95
+ multiplier, 0.0, 1.0, 'shade material opening multiplier')
96
+
97
+ @property
98
+ def left_opening_multiplier(self):
99
+ """Get or set the left opening multiplier."""
100
+ return self._left_opening_multiplier
101
+
102
+ @left_opening_multiplier.setter
103
+ def left_opening_multiplier(self, multiplier):
104
+ self._left_opening_multiplier = float_in_range(
105
+ multiplier, 0.0, 1.0, 'shade material opening multiplier')
106
+
107
+ @property
108
+ def right_opening_multiplier(self):
109
+ """Get or set the right opening multiplier."""
110
+ return self._right_opening_multiplier
111
+
112
+ @right_opening_multiplier.setter
113
+ def right_opening_multiplier(self, multiplier):
114
+ self._right_opening_multiplier = float_in_range(
115
+ multiplier, 0.0, 1.0, 'shade material opening multiplier')
116
+
117
+ @property
118
+ def r_value(self):
119
+ """R-value of the material layer [m2-K/W] (excluding air film resistance)."""
120
+ return 0
121
+
122
+ def set_all_opening_multipliers(self, multiplier):
123
+ """Set all opening multipliers to the same value at once."""
124
+ self.top_opening_multiplier = multiplier
125
+ self.bottom_opening_multiplier = multiplier
126
+ self.left_opening_multiplier = multiplier
127
+ self.right_opening_multiplier = multiplier
128
+
129
+ def r_value_exterior(self, delta_t=7.5, emissivity=0.84, height=1.0, angle=90,
130
+ t_kelvin=273.15, pressure=101325):
131
+ """Get an estimate of the R-value of the shade + air gap when it is exterior.
132
+
133
+ Args:
134
+ delta_t: The temperature difference across the air gap [C]. This
135
+ influences how strong the convection is within the air gap. Default is
136
+ 7.5C, which is consistent with the NFRC standard for double glazed units.
137
+ emissivity: The emissivity of the glazing surface adjacent to the shade.
138
+ Default is 0.84, which is typical of clear, uncoated glass.
139
+ height: An optional height for the cavity between the shade and the
140
+ glass in meters. Default is 1.0.
141
+ angle: An angle in degrees between 0 and 180.
142
+
143
+ * 0 = A horizontal surface with downward heat flow through the layer.
144
+ * 90 = A vertical surface
145
+ * 180 = A horizontal surface with upward heat flow through the layer.
146
+
147
+ t_kelvin: The average temperature of the gas cavity in Kelvin.
148
+ Default: 273.15 K (0C).
149
+ pressure: The average air pressure in Pa. Default is 101325 Pa for sea level.
150
+ """
151
+ # TODO: Account for air permeability and side openings in gap u-value.
152
+ # https://bigladdersoftware.com/epx/docs/9-0/engineering-reference/
153
+ # window-heat-balance-calculation.html#solving-for-gap-airflow-and-temperature
154
+ _gap = EnergyWindowMaterialGas(
155
+ identifier='Generic Shade Gap', thickness=self.distance_to_glass,
156
+ gas_type='Air')
157
+ try:
158
+ _shade_e = self.emissivity_back
159
+ except AttributeError:
160
+ _shade_e = self.emissivity
161
+ _r_gap = 1 / _gap.u_value_at_angle(delta_t, _shade_e, emissivity,
162
+ height, angle, t_kelvin, pressure)
163
+ return self.r_value + _r_gap
164
+
165
+ def r_value_interior(self, delta_t=7.5, emissivity=0.84, height=1.0, angle=90,
166
+ t_kelvin=273.15, pressure=101325):
167
+ """Get an estimate of the R-value of the shade + air gap when it is interior.
168
+
169
+ Args:
170
+ delta_t: The temperature difference across the air gap [C]. This
171
+ influences how strong the convection is within the air gap. Default is
172
+ 7.5C, which is consistent with the NFRC standard for double glazed units.
173
+ emissivity: The emissivity of the glazing surface adjacent to the shade.
174
+ Default is 0.84, which is typical of clear, uncoated glass.
175
+ height: An optional height for the cavity between the shade and the
176
+ glass in meters. Default is 1.0.
177
+ angle: An angle in degrees between 0 and 180.
178
+
179
+ * 0 = A horizontal surface with downward heat flow through the layer.
180
+ * 90 = A vertical surface
181
+ * 180 = A horizontal surface with upward heat flow through the layer.
182
+
183
+ t_kelvin: The average temperature of the gas cavity in Kelvin.
184
+ Default: 273.15 K (0C).
185
+ pressure: The average air pressure in Pa. Default is 101325 Pa for sea level.
186
+ """
187
+ # TODO: Account for air permeability and side openings in gap u-value.
188
+ # https://bigladdersoftware.com/epx/docs/9-0/engineering-reference/
189
+ # window-heat-balance-calculation.html#solving-for-gap-airflow-and-temperature
190
+ _gap = EnergyWindowMaterialGas(
191
+ identifier='Generic Shade Gap', thickness=self.distance_to_glass,
192
+ gas_type='Air')
193
+ _shade_e = self.emissivity
194
+ _r_gap = 1 / _gap.u_value_at_angle(delta_t, _shade_e, emissivity,
195
+ height, angle, t_kelvin, pressure)
196
+ return self.r_value + _r_gap
197
+
198
+ def r_value_between(self, delta_t=7.5, emissivity_1=0.84, emissivity_2=0.84,
199
+ height=1.0, angle=90, t_kelvin=273.15, pressure=101325):
200
+ """Get an estimate of the R-value of the shade + air gap when it is interior.
201
+
202
+ Args:
203
+ delta_t: The temperature difference across the air gap [C]. This
204
+ influences how strong the convection is within the air gap. Default is
205
+ 7.5C, which is consistent with the NFRC standard for double glazed units.
206
+ emissivity_1: The emissivity of the glazing surface on one side of the shade.
207
+ Default is 0.84, which is typical of clear, uncoated glass.
208
+ emissivity_2: The emissivity of the glazing surface on the other side of
209
+ the shade. Default is 0.84, which is typical of clear, uncoated glass.
210
+ height: An optional height for the cavity between the shade and the
211
+ glass in meters. Default is 1.0.
212
+ angle: An angle in degrees between 0 and 180.
213
+
214
+ * 0 = A horizontal surface with downward heat flow through the layer.
215
+ * 90 = A vertical surface
216
+ * 180 = A horizontal surface with upward heat flow through the layer.
217
+
218
+ t_kelvin: The average temperature of the gas cavity in Kelvin.
219
+ Default: 273.15 K (0C).
220
+ pressure: The average air pressure in Pa. Default is 101325 Pa for sea level.
221
+ """
222
+ _gap = EnergyWindowMaterialGas(
223
+ identifier='Generic Shade Gap', thickness=self.distance_to_glass,
224
+ gas_type='Air')
225
+ _shade_e = self.emissivity
226
+ _r_gap_1 = 1 / _gap.u_value_at_angle(delta_t, _shade_e, emissivity_1,
227
+ height, angle, t_kelvin, pressure)
228
+ _r_gap_2 = 1 / _gap.u_value_at_angle(delta_t, _shade_e, emissivity_2,
229
+ height, angle, t_kelvin, pressure)
230
+ return self.r_value + _r_gap_1 + _r_gap_2
231
+
232
+
233
+ @lockable
234
+ class EnergyWindowMaterialShade(_EnergyWindowMaterialShadeBase):
235
+ """A material for a shade layer in a window construction.
236
+
237
+ Reflectance and emissivity properties are assumed to be the same on both sides of
238
+ the shade. Shades are considered to be perfect diffusers.
239
+
240
+ Args:
241
+ identifier: Text string for a unique Material ID. Must be < 100 characters
242
+ and not contain any EnergyPlus special characters. This will be used to
243
+ identify the object across a model and in the exported IDF.
244
+ thickness: Number for the thickness of the shade layer [m].
245
+ Default: 0.005 meters (5 mm).
246
+ solar_transmittance: Number between 0 and 1 for the transmittance
247
+ of solar radiation through the shade.
248
+ Default: 0.4, which is typical of a white diffusing shade.
249
+ solar_reflectance: Number between 0 and 1 for the reflectance of solar
250
+ radiation off of the shade, averaged over the solar spectrum.
251
+ Default: 0.5, which is typical of a white diffusing shade.
252
+ visible_transmittance: Number between 0 and 1 for the transmittance
253
+ of visible light through the shade.
254
+ Default: 0.4, which is typical of a white diffusing shade.
255
+ visible_reflectance: Number between 0 and 1 for the reflectance of
256
+ visible light off of the shade.
257
+ Default: 0.4, which is typical of a white diffusing shade.
258
+ infrared_transmittance: Long-wave hemispherical transmittance of the shade.
259
+ Default: 0, which is typical of diffusing shades.
260
+ emissivity: Number between 0 and 1 for the infrared hemispherical
261
+ emissivity of the front side of the shade. Default: 0.9, which
262
+ is typical of most diffusing shade materials.
263
+ conductivity: Number for the thermal conductivity of the shade [W/m-K].
264
+ Default: 0.05, typical of cotton shades.
265
+ distance_to_glass: A number between 0.001 and 1.0 for the distance
266
+ between the shade and neighboring glass layers [m]. Default: 0.05 (50 mm).
267
+ opening_multiplier: Factor between 0 and 1 that is multiplied by the
268
+ area at the top, bottom and sides of the shade for air flow
269
+ calculations. Default: 0.5.
270
+ airflow_permeability: The fraction of the shade surface that is open to
271
+ air flow. Must be between 0 and 0.8. Default: 0 for no permeability.
272
+
273
+ Properties:
274
+ * identifier
275
+ * display_name
276
+ * thickness
277
+ * solar_transmittance
278
+ * solar_reflectance
279
+ * visible_transmittance
280
+ * visible_reflectance
281
+ * infrared_transmittance
282
+ * emissivity
283
+ * conductivity
284
+ * distance_to_glass
285
+ * top_opening_multiplier
286
+ * bottom_opening_multiplier
287
+ * left_opening_multiplier
288
+ * right_opening_multiplier
289
+ * airflow_permeability
290
+ * resistivity
291
+ * u_value
292
+ * r_value
293
+ * user_data
294
+ * properties
295
+ """
296
+ __slots__ = ('_thickness', '_solar_transmittance', '_solar_reflectance',
297
+ '_visible_transmittance', '_visible_reflectance',
298
+ '_conductivity', '_airflow_permeability')
299
+
300
+ def __init__(self, identifier, thickness=0.005, solar_transmittance=0.4,
301
+ solar_reflectance=0.5,
302
+ visible_transmittance=0.4, visible_reflectance=0.4,
303
+ infrared_transmittance=0, emissivity=0.9,
304
+ conductivity=0.05, distance_to_glass=0.05,
305
+ opening_multiplier=0.5, airflow_permeability=0.0):
306
+ """Initialize energy window material shade."""
307
+ _EnergyWindowMaterialShadeBase.__init__(
308
+ self, identifier, infrared_transmittance, emissivity,
309
+ distance_to_glass, opening_multiplier)
310
+
311
+ # default for checking transmittance + reflectance < 1
312
+ self._solar_reflectance = 0
313
+ self._visible_reflectance = 0
314
+
315
+ self.thickness = thickness
316
+ self.solar_transmittance = solar_transmittance
317
+ self.solar_reflectance = solar_reflectance
318
+ self.visible_transmittance = visible_transmittance
319
+ self.visible_reflectance = visible_reflectance
320
+ self.infrared_transmittance = infrared_transmittance
321
+ self.conductivity = conductivity
322
+ self.airflow_permeability = airflow_permeability
323
+ self._properties = EnergyWindowMaterialShadeProperties(self)
324
+
325
+ @property
326
+ def thickness(self):
327
+ """Get or set the thickess of the shade material layer [m]."""
328
+ return self._thickness
329
+
330
+ @thickness.setter
331
+ def thickness(self, thick):
332
+ self._thickness = float_positive(thick, 'shade material thickness')
333
+
334
+ @property
335
+ def solar_transmittance(self):
336
+ """Get or set the solar transmittance of the shade."""
337
+ return self._solar_transmittance
338
+
339
+ @solar_transmittance.setter
340
+ def solar_transmittance(self, s_tr):
341
+ s_tr = float_in_range(s_tr, 0.0, 1.0, 'shade material solar transmittance')
342
+ assert s_tr + self._solar_reflectance <= 1, 'Sum of shade transmittance and ' \
343
+ 'reflectance ({}) is greater than 1.'.format(s_tr + self._solar_reflectance)
344
+ self._solar_transmittance = s_tr
345
+
346
+ @property
347
+ def solar_reflectance(self):
348
+ """Get or set the front solar reflectance of the shade."""
349
+ return self._solar_reflectance
350
+
351
+ @solar_reflectance.setter
352
+ def solar_reflectance(self, s_ref):
353
+ s_ref = float_in_range(s_ref, 0.0, 1.0, 'shade material solar reflectance')
354
+ assert s_ref + self._solar_transmittance <= 1, 'Sum of shade transmittance ' \
355
+ 'and reflectance ({}) is greater than 1.'.format(
356
+ s_ref + self._solar_transmittance)
357
+ self._solar_reflectance = s_ref
358
+
359
+ @property
360
+ def visible_transmittance(self):
361
+ """Get or set the visible transmittance of the shade."""
362
+ return self._visible_transmittance
363
+
364
+ @visible_transmittance.setter
365
+ def visible_transmittance(self, v_tr):
366
+ v_tr = float_in_range(v_tr, 0.0, 1.0, 'shade material visible transmittance')
367
+ assert v_tr + self._visible_reflectance <= 1, 'Sum of shade transmittance ' \
368
+ 'and reflectance ({}) is greater than 1.'.format(
369
+ v_tr + self._visible_reflectance)
370
+ self._visible_transmittance = v_tr
371
+
372
+ @property
373
+ def visible_reflectance(self):
374
+ """Get or set the front visible reflectance of the shade."""
375
+ return self._visible_reflectance
376
+
377
+ @visible_reflectance.setter
378
+ def visible_reflectance(self, v_ref):
379
+ v_ref = float_in_range(v_ref, 0.0, 1.0, 'shade material visible reflectance')
380
+ assert v_ref + self._visible_transmittance <= 1, 'Sum of shade transmittance ' \
381
+ 'and reflectance ({}) is greater than 1.'.format(
382
+ v_ref + self._visible_transmittance)
383
+ self._visible_reflectance = v_ref
384
+
385
+ @property
386
+ def conductivity(self):
387
+ """Get or set the conductivity of the shade layer [W/m-K]."""
388
+ return self._conductivity
389
+
390
+ @conductivity.setter
391
+ def conductivity(self, cond):
392
+ self._conductivity = float_positive(cond, 'shade material conductivity')
393
+
394
+ @property
395
+ def airflow_permeability(self):
396
+ """Get or set the fraction of the shade surface open to air flow."""
397
+ return self._airflow_permeability
398
+
399
+ @airflow_permeability.setter
400
+ def airflow_permeability(self, perm):
401
+ self._airflow_permeability = float_in_range(
402
+ perm, 0.0, 0.8, 'shade material permeability')
403
+
404
+ @property
405
+ def resistivity(self):
406
+ """Get or set the resistivity of the shade layer [m-K/W]."""
407
+ return 1 / self._conductivity
408
+
409
+ @resistivity.setter
410
+ def resistivity(self, resis):
411
+ self._conductivity = 1 / float_positive(resis, 'shade material resistivity')
412
+
413
+ @property
414
+ def u_value(self):
415
+ """U-value of the material layer [W/m2-K] (excluding air film resistance)."""
416
+ return self.conductivity / self.thickness
417
+
418
+ @u_value.setter
419
+ def u_value(self, u_val):
420
+ self.r_value = 1 / float_positive(u_val, 'shade material u-value')
421
+
422
+ @property
423
+ def r_value(self):
424
+ """R-value of the material layer [m2-K/W] (excluding air film resistance)."""
425
+ return self.thickness / self.conductivity
426
+
427
+ @r_value.setter
428
+ def r_value(self, r_val):
429
+ self._conductivity = self.thickness / \
430
+ float_positive(r_val, 'shade material r-value')
431
+
432
+ @classmethod
433
+ def from_idf(cls, idf_string):
434
+ """Create EnergyWindowMaterialShade from an EnergyPlus text string.
435
+
436
+ Args:
437
+ idf_string: A text string fully describing an EnergyPlus material.
438
+ """
439
+ ep_s = parse_idf_string(idf_string, 'WindowMaterial:Shade,')
440
+ idf_defaults = {9: 0.05, 10: 0.5, 11: 0.5, 12: 0.5, 13: 0.5, 14: 0.0}
441
+ for i, ep_str in enumerate(ep_s): # fill in any default values
442
+ if ep_str == '' and i in idf_defaults:
443
+ ep_s[i] = idf_defaults[i]
444
+
445
+ new_mat = cls(ep_s[0], ep_s[7], ep_s[1], ep_s[2], ep_s[3], ep_s[4],
446
+ ep_s[6], ep_s[5], ep_s[8], ep_s[9], ep_s[10], ep_s[14])
447
+ new_mat.bottom_opening_multiplier = ep_s[11]
448
+ new_mat.left_opening_multiplier = ep_s[12]
449
+ new_mat.right_opening_multiplier = ep_s[13]
450
+ return new_mat
451
+
452
+ @classmethod
453
+ def from_dict(cls, data):
454
+ """Create a EnergyWindowMaterialShade from a dictionary.
455
+
456
+ Args:
457
+ data: A python dictionary in the following format
458
+
459
+ .. code-block:: python
460
+
461
+ {
462
+ "type": 'EnergyWindowMaterialShade',
463
+ "identifier": 'Insulating_Shade_0020_005_020_010',
464
+ "identifier": 'Dark Insulating Shade',
465
+ "thickness": 0.02,
466
+ "solar_transmittance": 0.05,
467
+ "solar_reflectance": 0.2,
468
+ "visible_transmittance": 0.05,
469
+ "visible_reflectance": 0.15,
470
+ "emissivity": 0.9,
471
+ "infrared_transmittance": 0,
472
+ "conductivity": 0.1
473
+ }
474
+ """
475
+ assert data['type'] == 'EnergyWindowMaterialShade', \
476
+ 'Expected EnergyWindowMaterialShade. Got {}.'.format(data['type'])
477
+
478
+ thick = data['thickness'] if 'thickness' in data and data['thickness'] \
479
+ is not None else 0.005
480
+ t_sol = data['solar_transmittance'] if 'solar_transmittance' in data and \
481
+ data['solar_transmittance'] is not None else 0.4
482
+ r_sol = data['solar_reflectance'] if 'solar_reflectance' in data and \
483
+ data['solar_reflectance'] is not None else 0.5
484
+ t_vis = data['visible_transmittance'] if 'visible_transmittance' in data and \
485
+ data['visible_transmittance'] is not None else 0.4
486
+ r_vis = data['visible_reflectance'] if 'visible_reflectance' in data and \
487
+ data['visible_reflectance'] is not None else 0.5
488
+ t_inf = data['infrared_transmittance'] if 'infrared_transmittance' in data and \
489
+ data['infrared_transmittance'] is not None else 0.0
490
+ emis = data['emissivity'] if 'emissivity' in data and \
491
+ data['emissivity'] is not None else 0.9
492
+ cond = data['conductivity'] if 'conductivity' in data and \
493
+ data['conductivity'] is not None else 0.9
494
+ dist = data['distance_to_glass'] if 'distance_to_glass' in data and \
495
+ data['distance_to_glass'] is not None else 0.05
496
+ top = data['top_opening_multiplier'] if 'top_opening_multiplier' in data \
497
+ and data['top_opening_multiplier'] is not None else 0.5
498
+ bot = data['bottom_opening_multiplier'] if 'bottom_opening_multiplier' in data \
499
+ and data['bottom_opening_multiplier'] is not None else 0.5
500
+ left = data['left_opening_multiplier'] if 'left_opening_multiplier' in data \
501
+ and data['left_opening_multiplier'] is not None else 0.5
502
+ right = data['right_opening_multiplier'] if 'right_opening_multiplier' in data \
503
+ and data['right_opening_multiplier'] is not None else 0.5
504
+ air = data['airflow_permeability'] if 'airflow_permeability' in data \
505
+ and data['airflow_permeability'] is not None else 0
506
+
507
+ new_mat = cls(data['identifier'], thick, t_sol, r_sol, t_vis, r_vis,
508
+ t_inf, emis, cond, dist, top, air)
509
+ new_mat.bottom_opening_multiplier = bot
510
+ new_mat.left_opening_multiplier = left
511
+ new_mat.right_opening_multiplier = right
512
+ if 'display_name' in data and data['display_name'] is not None:
513
+ new_mat.display_name = data['display_name']
514
+ if 'user_data' in data and data['user_data'] is not None:
515
+ new_mat.user_data = data['user_data']
516
+ if 'properties' in data and data['properties'] is not None:
517
+ new_mat._properties._load_extension_attr_from_dict(data['properties'])
518
+ return new_mat
519
+
520
+ def to_idf(self):
521
+ """Get an EnergyPlus string representation of the material.
522
+
523
+ .. code-block:: shell
524
+
525
+ WindowMaterial:Shade,
526
+ DRAPES - CLOSE WEAVE MEDIUM, !- Name
527
+ 0.05, !- Solar transmittance
528
+ 0.3000000, !- Solar Reflectance
529
+ .05, !- Visible transmittance
530
+ 0.3000000, !- Visible reflectance
531
+ 0.9000000, !- Infrared Hemispherical Emissivity
532
+ 0.0, !- Infrared Transmittance
533
+ 0.003, !- Thickness {m}
534
+ 0.1, !- Conductivity {W/m-K}
535
+ 0.050, !- Shade to glass distance {m}
536
+ 1.0, !- Top opening multiplier
537
+ 1.0, !- Bottom opening multiplier
538
+ 0.0, !- Left-side opening multiplier
539
+ 0.0, !- Right-side opening multiplier
540
+ 0.0; !- Air flow permeability
541
+ """
542
+ values = (self.identifier, self.solar_transmittance, self.solar_reflectance,
543
+ self.visible_transmittance, self.visible_reflectance,
544
+ self.emissivity, self.infrared_transmittance, self.thickness,
545
+ self.conductivity, self.top_opening_multiplier,
546
+ self.bottom_opening_multiplier, self.left_opening_multiplier,
547
+ self.right_opening_multiplier, self.airflow_permeability)
548
+ comments = ('name', 'solar transmittance', 'solar reflectance',
549
+ 'visible transmittance', 'visible reflectance', 'emissivity',
550
+ 'infrared transmittance', 'thickness {m}', 'conductivity {W/m-K}',
551
+ 'distance to glass {m}', 'top opening multiplier',
552
+ 'bottom opening multiplier', 'left opening multiplier',
553
+ 'right opening multiplier', 'airflow permeability')
554
+ return generate_idf_string('WindowMaterial:Shade', values, comments)
555
+
556
+ def to_dict(self):
557
+ """Energy Window Material Shade dictionary representation."""
558
+ base = {
559
+ 'type': 'EnergyWindowMaterialShade',
560
+ 'identifier': self.identifier,
561
+ 'thickness': self.thickness,
562
+ 'solar_transmittance': self.solar_transmittance,
563
+ 'solar_reflectance': self.solar_reflectance,
564
+ 'visible_transmittance': self.visible_transmittance,
565
+ 'visible_reflectance': self.visible_reflectance,
566
+ 'infrared_transmittance': self.infrared_transmittance,
567
+ 'emissivity': self.emissivity,
568
+ 'conductivity': self.conductivity,
569
+ 'distance_to_glass': self.distance_to_glass,
570
+ 'top_opening_multiplier': self.top_opening_multiplier,
571
+ 'bottom_opening_multiplier': self.bottom_opening_multiplier,
572
+ 'left_opening_multiplier': self.left_opening_multiplier,
573
+ 'right_opening_multiplier': self.right_opening_multiplier,
574
+ 'airflow_permeability': self.airflow_permeability
575
+ }
576
+ if self._display_name is not None:
577
+ base['display_name'] = self.display_name
578
+ if self._user_data is not None:
579
+ base['user_data'] = self.user_data
580
+ prop_dict = self._properties.to_dict()
581
+ if prop_dict is not None:
582
+ base['properties'] = prop_dict
583
+ return base
584
+
585
+ def __key(self):
586
+ """A tuple based on the object properties, useful for hashing."""
587
+ return (self.identifier, self.thickness, self.solar_transmittance,
588
+ self.solar_reflectance, self.visible_transmittance,
589
+ self.visible_reflectance, self.infrared_transmittance,
590
+ self.emissivity, self.conductivity, self.distance_to_glass,
591
+ self.top_opening_multiplier, self.bottom_opening_multiplier,
592
+ self.left_opening_multiplier, self.right_opening_multiplier,
593
+ self.airflow_permeability)
594
+
595
+ def __hash__(self):
596
+ return hash(self.__key())
597
+
598
+ def __eq__(self, other):
599
+ return isinstance(other, EnergyWindowMaterialShade) and \
600
+ self.__key() == other.__key()
601
+
602
+ def __ne__(self, other):
603
+ return not self.__eq__(other)
604
+
605
+ def __repr__(self):
606
+ return self.to_idf()
607
+
608
+ def __copy__(self):
609
+ new_material = EnergyWindowMaterialShade(
610
+ self.identifier, self.thickness, self.solar_transmittance,
611
+ self.solar_reflectance, self.visible_transmittance, self.visible_reflectance,
612
+ self.infrared_transmittance, self.emissivity,
613
+ self.conductivity, self.distance_to_glass,
614
+ self.top_opening_multiplier, self.airflow_permeability)
615
+ new_material._top_opening_multiplier = self._top_opening_multiplier
616
+ new_material._bottom_opening_multiplier = self._bottom_opening_multiplier
617
+ new_material._left_opening_multiplier = self._left_opening_multiplier
618
+ new_material._right_opening_multiplier = self._right_opening_multiplier
619
+ new_material._display_name = self._display_name
620
+ new_material._user_data = None if self._user_data is None \
621
+ else self._user_data.copy()
622
+ new_material._properties._duplicate_extension_attr(self._properties)
623
+ return new_material
624
+
625
+
626
+ @lockable
627
+ class EnergyWindowMaterialBlind(_EnergyWindowMaterialShadeBase):
628
+ """A material for a blind layer in a window construction.
629
+
630
+ Window blind properties consist of flat, equally-spaced slats.
631
+
632
+ Args:
633
+ identifier: Text string for a unique Material ID. Must be < 100 characters
634
+ and not contain any EnergyPlus special characters. This will be used to
635
+ identify the object across a model and in the exported IDF.
636
+ slat_orientation: Text describing the orientation of the slats.
637
+ Only the following two options are acceptable:
638
+ "Horizontal", "Vertical". Default: "Horizontal"
639
+ slat_width: The width of slat measured from edge to edge [m].
640
+ Default: 0.025 m (25 mm).
641
+ slat_separation: The distance between each of the slats [m].
642
+ Default: 0.01875 m (18.75 mm).
643
+ slat_thickness: A number between 0 and 0.1 for the thickness of the slat [m].
644
+ Default: 0.001 m (1 mm).
645
+ slat_angle: A number between 0 and 180 for the angle between the slats
646
+ and the glazing normal in degrees. 90 signifies slats that are
647
+ perpendicular to the glass. Default: 45.
648
+ slat_conductivity: The thermal conductivity of the blind material [W/m-K].
649
+ Default is 221, which is characteristic of metal blinds.
650
+ solar_transmittance: Number between 0 and 1 for the transmittance
651
+ of solar radiation through the blind material. Default: 0.
652
+ solar_reflectance: Number between 0 and 1 for the front reflectance
653
+ of solar radiation off of the blind, averaged over the solar
654
+ spectrum. Default: 0.5.
655
+ visible_transmittance: Number between 0 and 1 for the transmittance
656
+ of visible light through the blind material. Default : 0.
657
+ visible_reflectance: Number between 0 and 1 for the reflectance of
658
+ visible light off of the blind. Default: 0.5.
659
+ infrared_transmittance: Long-wave hemispherical transmittance of the blind.
660
+ Default value is 0.
661
+ emissivity: Number between 0 and 1 for the infrared hemispherical
662
+ emissivity of the blind. Default is 0.9.
663
+ distance_to_glass: A number between 0.001 and 1.0 for the distance from
664
+ the mid-plane of the blind to the adjacent glass layers [m].
665
+ Default is 0.05 (50 mm).
666
+ opening_multiplier: Factor between 0 and 1 that is multiplied by the
667
+ area at the top, bottom and sides of the shade for air flow
668
+ calculations. Default: 0.5.
669
+
670
+ Properties:
671
+ * identifier
672
+ * display_name
673
+ * slat_orientation
674
+ * slat_width
675
+ * slat_separation
676
+ * slat_thickness
677
+ * slat_angle
678
+ * slat_conductivity
679
+ * beam_solar_transmittance
680
+ * beam_solar_reflectance
681
+ * beam_solar_reflectance_back
682
+ * diffuse_solar_transmittance
683
+ * diffuse_solar_reflectance
684
+ * diffuse_solar_reflectance_back
685
+ * beam_visible_transmittance
686
+ * beam_visible_reflectance
687
+ * beam_visible_reflectance_back
688
+ * diffuse_visible_transmittance
689
+ * diffuse_visible_reflectance
690
+ * diffuse_visible_reflectance_back
691
+ * infrared_transmittance
692
+ * emissivity
693
+ * emissivity_back
694
+ * distance_to_glass
695
+ * top_opening_multiplier
696
+ * bottom_opening_multiplier
697
+ * left_opening_multiplier
698
+ * right_opening_multiplier
699
+ * slat_resistivity
700
+ * u_value
701
+ * r_value
702
+ * user_data
703
+ * properties
704
+ """
705
+ ORIENTATIONS = ('Horizontal', 'Vertical')
706
+ __slots__ = ('_slat_orientation', '_slat_width', '_slat_separation',
707
+ '_slat_thickness', '_slat_angle', '_slat_conductivity',
708
+ '_beam_solar_transmittance', '_beam_solar_reflectance',
709
+ '_beam_solar_reflectance_back', '_diffuse_solar_transmittance',
710
+ '_diffuse_solar_reflectance', '_diffuse_solar_reflectance_back',
711
+ '_beam_visible_transmittance', '_beam_visible_reflectance',
712
+ '_beam_visible_reflectance_back', '_diffuse_visible_transmittance',
713
+ '_diffuse_visible_reflectance', '_diffuse_visible_reflectance_back',
714
+ '_emissivity_back')
715
+
716
+ def __init__(self, identifier, slat_orientation='Horizontal', slat_width=0.025,
717
+ slat_separation=0.01875, slat_thickness=0.001, slat_angle=45,
718
+ slat_conductivity=221, solar_transmittance=0, solar_reflectance=0.5,
719
+ visible_transmittance=0, visible_reflectance=0.5,
720
+ infrared_transmittance=0, emissivity=0.9,
721
+ distance_to_glass=0.05, opening_multiplier=0.5):
722
+ """Initialize energy window material blind."""
723
+ _EnergyWindowMaterialShadeBase.__init__(
724
+ self, identifier, infrared_transmittance, emissivity,
725
+ distance_to_glass, opening_multiplier)
726
+
727
+ # default for checking transmittance + reflectance < 1
728
+ self._beam_solar_reflectance = 0
729
+ self._beam_solar_reflectance_back = None
730
+ self._diffuse_solar_reflectance = 0
731
+ self._diffuse_solar_reflectance_back = None
732
+ self._beam_visible_reflectance = 0
733
+ self._beam_visible_reflectance_back = None
734
+ self._diffuse_visible_reflectance = 0
735
+ self._diffuse_visible_reflectance_back = None
736
+
737
+ self.slat_orientation = slat_orientation
738
+ self.slat_width = slat_width
739
+ self.slat_separation = slat_separation
740
+ self.slat_thickness = slat_thickness
741
+ self.slat_angle = slat_angle
742
+ self.slat_conductivity = slat_conductivity
743
+ self.set_all_solar_transmittance(solar_transmittance)
744
+ self.set_all_solar_reflectance(solar_reflectance)
745
+ self.set_all_visible_transmittance(visible_transmittance)
746
+ self.set_all_visible_reflectance(visible_reflectance)
747
+ self.infrared_transmittance = infrared_transmittance
748
+ self.emissivity_back = None
749
+ self._properties = EnergyWindowMaterialBlindProperties(self)
750
+
751
+ @property
752
+ def slat_orientation(self):
753
+ """Get or set text describing the slat orientation.
754
+
755
+ Must be one of the following: ["Horizontal", "Vertical"].
756
+ """
757
+ return self._slat_orientation
758
+
759
+ @slat_orientation.setter
760
+ def slat_orientation(self, orient):
761
+ assert orient in self.ORIENTATIONS, 'Invalid input "{}" for slat ' \
762
+ 'orientation.\nMust be one of the following:{}'.format(
763
+ orient, self.ORIENTATIONS)
764
+ self._slat_orientation = orient
765
+
766
+ @property
767
+ def slat_width(self):
768
+ """Get or set the width of slat measured from edge to edge [m]"""
769
+ return self._slat_width
770
+
771
+ @slat_width.setter
772
+ def slat_width(self, width):
773
+ self._slat_width = float_in_range(width, 0.0, 1.0, 'shade material slat width')
774
+
775
+ @property
776
+ def slat_separation(self):
777
+ """Get or set the distance between each of the slats [m]"""
778
+ return self._slat_separation
779
+
780
+ @slat_separation.setter
781
+ def slat_separation(self, separ):
782
+ self._slat_separation = float_in_range(
783
+ separ, 0.0, 1.0, 'shade material slat separation')
784
+
785
+ @property
786
+ def slat_thickness(self):
787
+ """Get or set the thickness of the slat [m]."""
788
+ return self._slat_thickness
789
+
790
+ @slat_thickness.setter
791
+ def slat_thickness(self, thick):
792
+ self._slat_thickness = float_in_range(
793
+ thick, 0.0, 0.1, 'shade material slat thickness')
794
+
795
+ @property
796
+ def slat_angle(self):
797
+ """Get or set the angle between the slats and the glazing normal."""
798
+ return self._slat_angle
799
+
800
+ @slat_angle.setter
801
+ def slat_angle(self, angle):
802
+ self._slat_angle = float_in_range(angle, 0, 180, 'shade material slat angle')
803
+
804
+ @property
805
+ def slat_conductivity(self):
806
+ """Get or set the conductivity of the blind material [W/m-K]."""
807
+ return self._slat_conductivity
808
+
809
+ @slat_conductivity.setter
810
+ def slat_conductivity(self, cond):
811
+ self._slat_conductivity = float_positive(cond, 'shade material conductivity')
812
+
813
+ @property
814
+ def beam_solar_transmittance(self):
815
+ """Get or set the beam solar transmittance of the blind material."""
816
+ return self._beam_solar_transmittance
817
+
818
+ @beam_solar_transmittance.setter
819
+ def beam_solar_transmittance(self, s_tr):
820
+ s_tr = float_in_range(s_tr, 0.0, 1.0, 'shade material solar transmittance')
821
+ assert s_tr + self._beam_solar_reflectance <= 1, 'Sum of blind ' \
822
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
823
+ s_tr + self._beam_solar_reflectance)
824
+ if self._beam_solar_reflectance_back is not None:
825
+ assert s_tr + self._beam_solar_reflectance_back <= 1, 'Sum of blind ' \
826
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
827
+ s_tr + self._beam_solar_reflectance_back)
828
+ self._beam_solar_transmittance = s_tr
829
+
830
+ @property
831
+ def beam_solar_reflectance(self):
832
+ """Get or set the front beam solar reflectance of the blind."""
833
+ return self._beam_solar_reflectance
834
+
835
+ @beam_solar_reflectance.setter
836
+ def beam_solar_reflectance(self, s_ref):
837
+ s_ref = float_in_range(s_ref, 0.0, 1.0, 'shade material solar reflectance')
838
+ assert s_ref + self._beam_solar_transmittance <= 1, 'Sum of window ' \
839
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
840
+ s_ref + self._beam_solar_transmittance)
841
+ self._beam_solar_reflectance = s_ref
842
+
843
+ @property
844
+ def beam_solar_reflectance_back(self):
845
+ """Get or set the back beam solar reflectance of the blind."""
846
+ return self._beam_solar_reflectance_back if \
847
+ self._beam_solar_reflectance_back is not None \
848
+ else self._beam_solar_reflectance
849
+
850
+ @beam_solar_reflectance_back.setter
851
+ def beam_solar_reflectance_back(self, s_ref):
852
+ if s_ref is not None:
853
+ s_ref = float_in_range(s_ref, 0.0, 1.0, 'shade material solar reflectance')
854
+ assert s_ref + self._beam_solar_transmittance <= 1, 'Sum of window ' \
855
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
856
+ s_ref + self._beam_solar_transmittance)
857
+ self._beam_solar_reflectance_back = s_ref
858
+
859
+ @property
860
+ def diffuse_solar_transmittance(self):
861
+ """Get or set the diffuse solar transmittance of the blind material."""
862
+ return self._diffuse_solar_transmittance
863
+
864
+ @diffuse_solar_transmittance.setter
865
+ def diffuse_solar_transmittance(self, s_tr):
866
+ s_tr = float_in_range(s_tr, 0.0, 1.0, 'shade material solar transmittance')
867
+ assert s_tr + self._diffuse_solar_reflectance <= 1, 'Sum of blind ' \
868
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
869
+ s_tr + self._diffuse_solar_reflectance)
870
+ if self._diffuse_solar_reflectance_back is not None:
871
+ assert s_tr + self._diffuse_solar_reflectance_back <= 1, 'Sum of blind' \
872
+ ' transmittance and reflectance ({}) is greater than 1.'.format(
873
+ s_tr + self._diffuse_solar_reflectance_back)
874
+ self._diffuse_solar_transmittance = s_tr
875
+
876
+ @property
877
+ def diffuse_solar_reflectance(self):
878
+ """Get or set the front diffuse solar reflectance of the blind."""
879
+ return self._diffuse_solar_reflectance
880
+
881
+ @diffuse_solar_reflectance.setter
882
+ def diffuse_solar_reflectance(self, s_ref):
883
+ s_ref = float_in_range(s_ref, 0.0, 1.0, 'shade material solar reflectance')
884
+ assert s_ref + self._diffuse_solar_transmittance <= 1, 'Sum of window ' \
885
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
886
+ s_ref + self._diffuse_solar_transmittance)
887
+ self._diffuse_solar_reflectance = s_ref
888
+
889
+ @property
890
+ def diffuse_solar_reflectance_back(self):
891
+ """Get or set the back diffuse solar reflectance of the blind."""
892
+ return self._diffuse_solar_reflectance_back if \
893
+ self._diffuse_solar_reflectance_back is not None \
894
+ else self._diffuse_solar_reflectance
895
+
896
+ @diffuse_solar_reflectance_back.setter
897
+ def diffuse_solar_reflectance_back(self, s_ref):
898
+ if s_ref is not None:
899
+ s_ref = float_in_range(s_ref, 0.0, 1.0, 'shade material solar reflectance')
900
+ assert s_ref + self._diffuse_solar_transmittance <= 1, 'Sum of window ' \
901
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
902
+ s_ref + self._diffuse_solar_transmittance)
903
+ self._diffuse_solar_reflectance_back = s_ref
904
+
905
+ @property
906
+ def beam_visible_transmittance(self):
907
+ """Get or set the beam visible transmittance of the blind material."""
908
+ return self._beam_visible_transmittance
909
+
910
+ @beam_visible_transmittance.setter
911
+ def beam_visible_transmittance(self, s_tr):
912
+ s_tr = float_in_range(s_tr, 0.0, 1.0, 'shade material solar transmittance')
913
+ assert s_tr + self._beam_visible_reflectance <= 1, 'Sum of blind ' \
914
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
915
+ s_tr + self._beam_visible_reflectance)
916
+ if self._beam_visible_reflectance_back is not None:
917
+ assert s_tr + self._beam_visible_reflectance_back <= 1, 'Sum of blind ' \
918
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
919
+ s_tr + self._beam_visible_reflectance_back)
920
+ self._beam_visible_transmittance = s_tr
921
+
922
+ @property
923
+ def beam_visible_reflectance(self):
924
+ """Get or set the front beam visible reflectance of the blind."""
925
+ return self._beam_visible_reflectance
926
+
927
+ @beam_visible_reflectance.setter
928
+ def beam_visible_reflectance(self, s_ref):
929
+ s_ref = float_in_range(s_ref, 0.0, 1.0, 'shade material solar reflectance')
930
+ assert s_ref + self._beam_visible_transmittance <= 1, 'Sum of window ' \
931
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
932
+ s_ref + self._beam_visible_transmittance)
933
+ self._beam_visible_reflectance = s_ref
934
+
935
+ @property
936
+ def beam_visible_reflectance_back(self):
937
+ """Get or set the back beam visible reflectance of the blind."""
938
+ return self._beam_visible_reflectance_back if \
939
+ self._beam_visible_reflectance_back is not None \
940
+ else self._beam_visible_reflectance
941
+
942
+ @beam_visible_reflectance_back.setter
943
+ def beam_visible_reflectance_back(self, s_ref):
944
+ if s_ref is not None:
945
+ s_ref = float_in_range(s_ref, 0.0, 1.0, 'shade material solar reflectance')
946
+ assert s_ref + self._beam_visible_transmittance <= 1, 'Sum of window ' \
947
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
948
+ s_ref + self._beam_visible_transmittance)
949
+ self._beam_visible_reflectance_back = s_ref
950
+
951
+ @property
952
+ def diffuse_visible_transmittance(self):
953
+ """Get or set the diffuse visible transmittance of the blind material."""
954
+ return self._diffuse_visible_transmittance
955
+
956
+ @diffuse_visible_transmittance.setter
957
+ def diffuse_visible_transmittance(self, s_tr):
958
+ s_tr = float_in_range(s_tr, 0.0, 1.0, 'shade material solar transmittance')
959
+ assert s_tr + self._diffuse_visible_reflectance <= 1, 'Sum of blind ' \
960
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
961
+ s_tr + self._diffuse_visible_reflectance)
962
+ if self._diffuse_visible_reflectance_back is not None:
963
+ assert s_tr + self._diffuse_visible_reflectance_back <= 1, 'Sum of blind' \
964
+ ' transmittance and reflectance ({}) is greater than 1.'.format(
965
+ s_tr + self._diffuse_visible_reflectance_back)
966
+ self._diffuse_visible_transmittance = s_tr
967
+
968
+ @property
969
+ def diffuse_visible_reflectance(self):
970
+ """Get or set the front diffuse visible reflectance of the blind."""
971
+ return self._diffuse_visible_reflectance
972
+
973
+ @diffuse_visible_reflectance.setter
974
+ def diffuse_visible_reflectance(self, s_ref):
975
+ s_ref = float_in_range(s_ref, 0.0, 1.0, 'shade material solar reflectance')
976
+ assert s_ref + self._diffuse_visible_transmittance <= 1, 'Sum of window ' \
977
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
978
+ s_ref + self._diffuse_visible_transmittance)
979
+ self._diffuse_visible_reflectance = s_ref
980
+
981
+ @property
982
+ def diffuse_visible_reflectance_back(self):
983
+ """Get or set the back diffuse visible reflectance of the blind."""
984
+ return self._diffuse_visible_reflectance_back if \
985
+ self._diffuse_visible_reflectance_back is not None \
986
+ else self._diffuse_visible_reflectance
987
+
988
+ @diffuse_visible_reflectance_back.setter
989
+ def diffuse_visible_reflectance_back(self, s_ref):
990
+ if s_ref is not None:
991
+ s_ref = float_in_range(s_ref, 0.0, 1.0, 'shade material solar reflectance')
992
+ assert s_ref + self._diffuse_visible_transmittance <= 1, 'Sum of window ' \
993
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
994
+ s_ref + self._diffuse_visible_transmittance)
995
+ self._diffuse_visible_reflectance_back = s_ref
996
+
997
+ @property
998
+ def emissivity_back(self):
999
+ """Get or set the hemispherical emissivity of the back side of the glass."""
1000
+ return self._emissivity_back if self._emissivity_back is not None \
1001
+ else self._emissivity
1002
+
1003
+ @emissivity_back.setter
1004
+ def emissivity_back(self, ir_e):
1005
+ if ir_e is not None:
1006
+ ir_e = float_in_range(ir_e, 0.0, 1.0, 'shade material emissivity')
1007
+ self._emissivity_back = ir_e
1008
+
1009
+ @property
1010
+ def slat_resistivity(self):
1011
+ """Get or set the resistivity of the blind layer [m-K/W]."""
1012
+ return 1 / self._slat_conductivity
1013
+
1014
+ @slat_resistivity.setter
1015
+ def slat_resistivity(self, resis):
1016
+ self._slat_conductivity = 1 / float_positive(resis, 'shade material resistivity')
1017
+
1018
+ @property
1019
+ def u_value(self):
1020
+ """U-value of the blind slats [W/m2-K] (excluding air film resistance).
1021
+
1022
+ Note that this value assumes that blinds are completely closed (at 0 degrees).
1023
+ """
1024
+ return self.slat_conductivity / self.slat_thickness
1025
+
1026
+ @u_value.setter
1027
+ def u_value(self, u_val):
1028
+ self.r_value = 1 / float_positive(u_val, 'shade material u-value')
1029
+
1030
+ @property
1031
+ def r_value(self):
1032
+ """R-value of the blind slats [m2-K/W] (excluding air film resistance).
1033
+
1034
+ Note that this value assumes that blinds are completely closed (at 0 degrees).
1035
+ """
1036
+ return self.slat_thickness / self.slat_conductivity
1037
+
1038
+ @r_value.setter
1039
+ def r_value(self, r_val):
1040
+ self._slat_conductivity = self.slat_thickness / \
1041
+ float_positive(r_val, 'shade material r-value')
1042
+
1043
+ def set_all_solar_transmittance(self, transmittance):
1044
+ """Set all solar transmittance to the same value at once."""
1045
+ self.beam_solar_transmittance = transmittance
1046
+ self.diffuse_solar_transmittance = transmittance
1047
+
1048
+ def set_all_solar_reflectance(self, reflectance):
1049
+ """Set all solar reflectance to the same value at once."""
1050
+ self.beam_solar_reflectance = reflectance
1051
+ self.beam_solar_reflectance_back = None
1052
+ self.diffuse_solar_reflectance = reflectance
1053
+ self.diffuse_solar_reflectance_back = None
1054
+
1055
+ def set_all_visible_transmittance(self, transmittance):
1056
+ """Set all solar transmittance to the same value at once."""
1057
+ self.beam_visible_transmittance = transmittance
1058
+ self.diffuse_visible_transmittance = transmittance
1059
+
1060
+ def set_all_visible_reflectance(self, reflectance):
1061
+ """Set all visible reflectance to the same value at once."""
1062
+ self.beam_visible_reflectance = reflectance
1063
+ self.beam_visible_reflectance_back = None
1064
+ self.diffuse_visible_reflectance = reflectance
1065
+ self.diffuse_visible_reflectance_back = None
1066
+
1067
+ @classmethod
1068
+ def from_idf(cls, idf_string):
1069
+ """Create EnergyWindowMaterialBlind from an EnergyPlus text string.
1070
+
1071
+ Args:
1072
+ idf_string: A text string fully describing an EnergyPlus material.
1073
+ """
1074
+ ep_s = parse_idf_string(idf_string, 'WindowMaterial:Blind,')
1075
+ idf_defaults = {1: 'Horizontal', 4: 0.00025, 5: 45, 6: 221.0, 7: 0.0,
1076
+ 10: 0.0, 14: 0.0, 15: 0.0, 16: 0.0, 17: 0.0, 18: 0.0,
1077
+ 19: 0.0, 20: 0.9, 21: 0.9, 22: 0.05, 23: 0.5, 24: 0.0,
1078
+ 25: 0.5, 26: 0.5}
1079
+ for i, ep_str in enumerate(ep_s): # fill in any default values
1080
+ if ep_str == '' and i in idf_defaults:
1081
+ ep_s[i] = idf_defaults[i]
1082
+
1083
+ new_mat = cls(ep_s[0], ep_s[1], ep_s[2], ep_s[3], ep_s[4], ep_s[5],
1084
+ ep_s[6], ep_s[7], ep_s[8], ep_s[13], ep_s[14], ep_s[19],
1085
+ ep_s[20], ep_s[22], ep_s[23])
1086
+ new_mat.beam_solar_reflectance_back = ep_s[9]
1087
+ new_mat.diffuse_solar_transmittance = ep_s[10]
1088
+ new_mat.diffuse_solar_reflectance = ep_s[11]
1089
+ new_mat.diffuse_solar_reflectance_back = ep_s[12]
1090
+ new_mat.beam_visible_reflectance_back = ep_s[15]
1091
+ new_mat.diffuse_visible_transmittance = ep_s[16]
1092
+ new_mat.diffuse_visible_reflectance = ep_s[17]
1093
+ new_mat.diffuse_visible_reflectance_back = ep_s[18]
1094
+ new_mat.emissivity_back = ep_s[21]
1095
+ new_mat.bottom_opening_multiplier = ep_s[24]
1096
+ new_mat.left_opening_multiplier = ep_s[25]
1097
+ new_mat.right_opening_multiplier = ep_s[26]
1098
+ return new_mat
1099
+
1100
+ @classmethod
1101
+ def from_dict(cls, data):
1102
+ """Create a EnergyWindowMaterialBlind from a dictionary.
1103
+
1104
+ Args:
1105
+ data: A python dictionary in the following format
1106
+
1107
+ .. code-block:: python
1108
+
1109
+ {
1110
+ "type": 'EnergyWindowMaterialBlind',
1111
+ "identifier": 'Plastic_Blind_Horiz_0040_0030_0002_90',
1112
+ "display_name": 'Plastic Blind',
1113
+ "slat_orientation": 'Horizontal',
1114
+ "slat_width": 0.04,
1115
+ "slat_separation": 0.03,
1116
+ "slat_thickness": 0.002,
1117
+ "slat_angle": 90,
1118
+ "slat_conductivity": 0.2
1119
+ }
1120
+ """
1121
+ assert data['type'] == 'EnergyWindowMaterialBlind', \
1122
+ 'Expected EnergyWindowMaterialBlind. Got {}.'.format(data['type'])
1123
+
1124
+ orient = data['slat_orientation'] if 'slat_orientation' in data and \
1125
+ data['slat_orientation'] is not None else 'Horizontal'
1126
+ width = data['slat_width'] if 'slat_width' in data and \
1127
+ data['slat_width'] is not None else 0.025
1128
+ sep = data['slat_separation'] if 'slat_separation' in data and \
1129
+ data['slat_separation'] is not None else 0.01875
1130
+ thick = data['slat_thickness'] if 'slat_thickness' in data and \
1131
+ data['slat_thickness'] is not None else 0.001
1132
+ angle = data['slat_angle'] if 'slat_angle' in data and \
1133
+ data['slat_angle'] is not None else 45
1134
+ cond = data['slat_conductivity'] if 'slat_conductivity' in data and \
1135
+ data['slat_conductivity'] is not None else 221
1136
+ t_sol = data['beam_solar_transmittance'] if 'beam_solar_transmittance' in data \
1137
+ and data['beam_solar_transmittance'] is not None else 0.0
1138
+ r_sol = data['beam_solar_reflectance'] if 'beam_solar_reflectance' in data and \
1139
+ data['beam_solar_reflectance'] is not None else 0.5
1140
+ r_sol_b = data['beam_solar_reflectance_back'] if 'beam_solar_reflectance_back' \
1141
+ in data else None
1142
+ td_sol = data['diffuse_solar_transmittance'] if 'diffuse_solar_transmittance' \
1143
+ in data and data['diffuse_solar_transmittance'] is not None else 0.0
1144
+ rd_sol = data['diffuse_solar_reflectance'] if 'diffuse_solar_reflectance' in \
1145
+ data and data['diffuse_solar_reflectance'] is not None else 0.5
1146
+ rd_sol_b = data['diffuse_solar_reflectance_back'] if \
1147
+ 'diffuse_solar_reflectance_back' in data else None
1148
+
1149
+ t_vis = data['beam_visible_transmittance'] if 'beam_visible_transmittance' in \
1150
+ data and data['beam_visible_transmittance'] is not None else 0.0
1151
+ r_vis = data['beam_visible_reflectance'] if 'beam_visible_reflectance' \
1152
+ in data and data['beam_visible_reflectance'] is not None else 0.5
1153
+ r_vis_b = data['beam_visible_reflectance_back'] if \
1154
+ 'beam_visible_reflectance_back' in data else None
1155
+ td_vis = data['diffuse_visible_transmittance'] \
1156
+ if 'diffuse_visible_transmittance' in data \
1157
+ and data['diffuse_visible_transmittance'] is not None else 0.0
1158
+ rd_vis = data['diffuse_visible_reflectance'] if 'diffuse_visible_reflectance' \
1159
+ in data and data['diffuse_visible_reflectance'] is not None else 0.5
1160
+ rd_vis_b = data['diffuse_visible_reflectance_back'] if \
1161
+ 'diffuse_visible_reflectance_back' in data else None
1162
+
1163
+ t_inf = data['infrared_transmittance'] if 'infrared_transmittance' in data and \
1164
+ data['infrared_transmittance'] is not None else 0.0
1165
+ emis = data['emissivity'] if 'emissivity' in data and \
1166
+ data['emissivity'] is not None else 0.9
1167
+ emis_b = data['emissivity_back'] if 'emissivity_back' in data else None
1168
+ dist = data['distance_to_glass'] if 'distance_to_glass' in data and \
1169
+ data['distance_to_glass'] is not None else 0.05
1170
+ top = data['top_opening_multiplier'] if 'top_opening_multiplier' in data \
1171
+ and data['top_opening_multiplier'] is not None else 0.5
1172
+ bot = data['bottom_opening_multiplier'] if 'bottom_opening_multiplier' in data \
1173
+ and data['bottom_opening_multiplier'] is not None else 0.5
1174
+ left = data['left_opening_multiplier'] if 'left_opening_multiplier' in data \
1175
+ and data['left_opening_multiplier'] is not None else 0.5
1176
+ right = data['right_opening_multiplier'] if 'right_opening_multiplier' in data \
1177
+ and data['right_opening_multiplier'] is not None else 0.5
1178
+
1179
+ new_mat = cls(
1180
+ data['identifier'], orient, width, sep, thick, angle, cond, t_sol, r_sol,
1181
+ t_vis, r_vis, t_inf, emis, dist, top)
1182
+
1183
+ new_mat.beam_solar_reflectance_back = r_sol_b
1184
+ new_mat.diffuse_solar_transmittance = td_sol
1185
+ new_mat.diffuse_solar_reflectance = rd_sol
1186
+ new_mat.diffuse_solar_reflectance_back = rd_sol_b
1187
+ new_mat.beam_visible_reflectance_back = r_vis_b
1188
+ new_mat.diffuse_visible_transmittance = td_vis
1189
+ new_mat.diffuse_visible_reflectance = rd_vis
1190
+ new_mat.diffuse_visible_reflectance_back = rd_vis_b
1191
+ new_mat.emissivity_back = emis_b
1192
+ new_mat.bottom_opening_multiplier = bot
1193
+ new_mat.left_opening_multiplier = left
1194
+ new_mat.right_opening_multiplier = right
1195
+ if 'display_name' in data and data['display_name'] is not None:
1196
+ new_mat.display_name = data['display_name']
1197
+ if 'user_data' in data and data['user_data'] is not None:
1198
+ new_mat.user_data = data['user_data']
1199
+ if 'properties' in data and data['properties'] is not None:
1200
+ new_mat._properties._load_extension_attr_from_dict(data['properties'])
1201
+ return new_mat
1202
+
1203
+ def to_idf(self):
1204
+ """Get an EnergyPlus string representation of the material.
1205
+
1206
+ .. code-block:: shell
1207
+
1208
+ WindowMaterial:Blind,
1209
+ White Painted Metal Blind, !- Name
1210
+ HORIZONTAL, !- Slat orientation
1211
+ 0.025 , !- Slat width (m)
1212
+ 0.01875 , !- Slat separation (m)
1213
+ 0.001 , !- Slat thickness (m)
1214
+ 45.0 , !- Slat angle (deg)
1215
+ 44.9 , !- Slat conductivity (W/m-K)
1216
+ 0.0 , !- Slat beam solar transmittance
1217
+ 0.8 , !- Front Side Slat beam solar reflectance
1218
+ 0.8 , !- Back Side Slat beam solar reflectance
1219
+ 0.0 , !- Slat diffuse solar transmittance
1220
+ 0.8 , !- Front Side Slat diffuse solar reflectance
1221
+ 0.8 , !- Back Side Slat diffuse solar reflectance
1222
+ 0.0 , !- Slat beam visible transmittance
1223
+ 0.7 , !- Front Side Slat beam visible reflectance
1224
+ 0.7 , !- Back Side Slat beam visible reflectance
1225
+ 0.0 , !- Slat diffuse visible transmittance
1226
+ 0.7 , !- Front Side Slat diffuse visible reflectance
1227
+ 0.7 , !- Back Side Slat diffuse visible reflectance
1228
+ 0.0 , !- Slat Infrared hemispherical transmittance
1229
+ 0.9 , !- Front Side Slat Infrared hemispherical emissivity
1230
+ 0.9 , !- Back Side Slat Infrared hemispherical emissivity
1231
+ 0.050 , !- Blind-to-glass distance
1232
+ 0.0 , !- Blind top opening multiplier
1233
+ 0.0 , !- Blind bottom opening multiplier
1234
+ 0.5 , !- Blind left-side opening multiplier
1235
+ 0.5 , !- Blind right-side opening multiplier
1236
+ , !- Minimum slat angle (deg)
1237
+ ; !- Maximum slat angle (deg)
1238
+ """
1239
+ values = (self.identifier, self.slat_orientation, self.slat_width,
1240
+ self.slat_separation, self.slat_thickness, self.slat_angle,
1241
+ self.slat_conductivity, self.beam_solar_transmittance,
1242
+ self.beam_solar_reflectance, self.beam_solar_reflectance_back,
1243
+ self.diffuse_solar_transmittance, self.diffuse_solar_reflectance,
1244
+ self.diffuse_solar_reflectance_back, self.beam_visible_transmittance,
1245
+ self.beam_visible_reflectance, self.beam_visible_reflectance_back,
1246
+ self.diffuse_visible_transmittance, self.diffuse_visible_reflectance,
1247
+ self.diffuse_visible_reflectance_back, self.infrared_transmittance,
1248
+ self.emissivity, self.emissivity_back, self.distance_to_glass,
1249
+ self.top_opening_multiplier, self.bottom_opening_multiplier,
1250
+ self.left_opening_multiplier, self.right_opening_multiplier, 0, 180)
1251
+ comments = (
1252
+ 'name', 'slat orientation', 'slat width {m}', 'slat separation {m}',
1253
+ 'slat thickness {m}', 'slat angle {deg}',
1254
+ 'slat conductivity {W/m-K}', 'beam solar transmittance',
1255
+ 'beam solar reflectance front', 'beam solar reflectance back',
1256
+ 'diffuse solar transmittance', 'diffuse solar reflectance front',
1257
+ 'diffuse solar reflectance back', 'beam visible transmittance',
1258
+ 'beam visible reflectance front', 'beam visible reflectance back',
1259
+ 'diffuse visible transmittance', 'diffuse visible reflectance front',
1260
+ 'diffuse visible reflectance back', 'infrared transmittance',
1261
+ 'emissivity front', 'emissivity back', 'distance to glass {m}',
1262
+ 'top opening multiplier', 'bottom opening multiplier',
1263
+ 'left opening multiplier', 'right opening multiplier',
1264
+ 'minimum slat angle {deg}', 'maximum slat angle {deg}')
1265
+ return generate_idf_string('WindowMaterial:Blind', values, comments)
1266
+
1267
+ def to_dict(self):
1268
+ """Energy Window Material Blind dictionary representation."""
1269
+ base = {
1270
+ 'type': 'EnergyWindowMaterialBlind',
1271
+ 'identifier': self.identifier,
1272
+ 'slat_orientation': self.slat_orientation,
1273
+ 'slat_width': self.slat_width,
1274
+ 'slat_separation': self.slat_separation,
1275
+ 'slat_thickness': self.slat_thickness,
1276
+ 'slat_angle': self.slat_angle,
1277
+ 'slat_conductivity': self.slat_conductivity,
1278
+ 'beam_solar_transmittance': self.beam_solar_transmittance,
1279
+ 'beam_solar_reflectance': self.beam_solar_reflectance,
1280
+ 'beam_solar_reflectance_back': self.beam_solar_reflectance_back,
1281
+ 'diffuse_solar_transmittance': self.diffuse_solar_transmittance,
1282
+ 'diffuse_solar_reflectance': self.diffuse_solar_reflectance,
1283
+ 'diffuse_solar_reflectance_back': self.diffuse_solar_reflectance_back,
1284
+ 'beam_visible_transmittance': self.beam_visible_transmittance,
1285
+ 'beam_visible_reflectance': self.beam_visible_reflectance,
1286
+ 'beam_visible_reflectance_back': self.beam_visible_reflectance_back,
1287
+ 'diffuse_visible_transmittance': self.diffuse_visible_transmittance,
1288
+ 'diffuse_visible_reflectance': self.diffuse_visible_reflectance,
1289
+ 'diffuse_visible_reflectance_back': self.diffuse_visible_reflectance_back,
1290
+ 'infrared_transmittance': self.infrared_transmittance,
1291
+ 'emissivity': self.emissivity,
1292
+ 'emissivity_back': self.emissivity_back,
1293
+ 'distance_to_glass': self.distance_to_glass,
1294
+ 'top_opening_multiplier': self.top_opening_multiplier,
1295
+ 'bottom_opening_multiplier': self.bottom_opening_multiplier,
1296
+ 'left_opening_multiplier': self.left_opening_multiplier,
1297
+ 'right_opening_multiplier': self.right_opening_multiplier
1298
+ }
1299
+ if self._display_name is not None:
1300
+ base['display_name'] = self.display_name
1301
+ if self._user_data is not None:
1302
+ base['user_data'] = self.user_data
1303
+ prop_dict = self._properties.to_dict()
1304
+ if prop_dict is not None:
1305
+ base['properties'] = prop_dict
1306
+ return base
1307
+
1308
+ def __key(self):
1309
+ """A tuple based on the object properties, useful for hashing."""
1310
+ return (self.identifier, self.slat_orientation, self.slat_width,
1311
+ self.slat_separation, self.slat_thickness, self.slat_angle,
1312
+ self.slat_conductivity, self.beam_solar_transmittance,
1313
+ self.beam_solar_reflectance, self.beam_solar_reflectance_back,
1314
+ self.diffuse_solar_transmittance, self.diffuse_solar_reflectance,
1315
+ self.diffuse_solar_reflectance_back, self.beam_visible_transmittance,
1316
+ self.beam_visible_reflectance, self.beam_visible_reflectance_back,
1317
+ self.diffuse_visible_transmittance, self.diffuse_visible_reflectance,
1318
+ self.diffuse_visible_reflectance_back, self.infrared_transmittance,
1319
+ self.emissivity, self.emissivity_back, self.distance_to_glass,
1320
+ self.top_opening_multiplier, self.bottom_opening_multiplier,
1321
+ self.left_opening_multiplier, self.right_opening_multiplier)
1322
+
1323
+ def __hash__(self):
1324
+ return hash(self.__key())
1325
+
1326
+ def __eq__(self, other):
1327
+ return isinstance(other, EnergyWindowMaterialBlind) and \
1328
+ self.__key() == other.__key()
1329
+
1330
+ def __ne__(self, other):
1331
+ return not self.__eq__(other)
1332
+
1333
+ def __repr__(self):
1334
+ return self.to_idf()
1335
+
1336
+ def __copy__(self):
1337
+ new_m = EnergyWindowMaterialBlind(
1338
+ self.identifier, self.slat_orientation, self.slat_width,
1339
+ self.slat_separation, self.slat_thickness,
1340
+ self.slat_angle, self.slat_conductivity,
1341
+ self.beam_solar_transmittance, self.beam_solar_reflectance,
1342
+ self.beam_visible_transmittance, self.beam_visible_reflectance,
1343
+ self.infrared_transmittance, self.emissivity, self.distance_to_glass,
1344
+ self.top_opening_multiplier)
1345
+ new_m._diffuse_solar_transmittance = self._diffuse_solar_transmittance
1346
+ new_m._beam_solar_reflectance_back = self._beam_solar_reflectance_back
1347
+ new_m._diffuse_solar_reflectance = self._diffuse_solar_reflectance
1348
+ new_m._diffuse_solar_reflectance_back = self._diffuse_solar_reflectance_back
1349
+ new_m._diffuse_visible_transmittance = self._diffuse_visible_transmittance
1350
+ new_m._beam_visible_reflectance_back = self._beam_visible_reflectance_back
1351
+ new_m._diffuse_visible_reflectance = self._diffuse_visible_reflectance
1352
+ new_m._diffuse_visible_reflectance_back = self._diffuse_visible_reflectance_back
1353
+ new_m._top_opening_multiplier = self._top_opening_multiplier
1354
+ new_m._bottom_opening_multiplier = self._bottom_opening_multiplier
1355
+ new_m._left_opening_multiplier = self._left_opening_multiplier
1356
+ new_m._right_opening_multiplier = self._right_opening_multiplier
1357
+ new_m._display_name = self._display_name
1358
+ new_m._user_data = None if self._user_data is None else self._user_data.copy()
1359
+ new_m._properties._duplicate_extension_attr(self._properties)
1360
+ return new_m