honeybee-energy 1.116.106__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- honeybee_energy/__init__.py +24 -0
- honeybee_energy/__main__.py +4 -0
- honeybee_energy/_extend_honeybee.py +145 -0
- honeybee_energy/altnumber.py +21 -0
- honeybee_energy/baseline/__init__.py +2 -0
- honeybee_energy/baseline/create.py +608 -0
- honeybee_energy/baseline/data/__init__.py +1 -0
- honeybee_energy/baseline/data/constructions.csv +64 -0
- honeybee_energy/baseline/data/fen_ratios.csv +15 -0
- honeybee_energy/baseline/data/lpd_building.csv +21 -0
- honeybee_energy/baseline/data/pci_2016.csv +22 -0
- honeybee_energy/baseline/data/pci_2019.csv +22 -0
- honeybee_energy/baseline/data/pci_2022.csv +22 -0
- honeybee_energy/baseline/data/shw.csv +21 -0
- honeybee_energy/baseline/pci.py +512 -0
- honeybee_energy/baseline/result.py +371 -0
- honeybee_energy/boundarycondition.py +128 -0
- honeybee_energy/cli/__init__.py +69 -0
- honeybee_energy/cli/baseline.py +475 -0
- honeybee_energy/cli/edit.py +327 -0
- honeybee_energy/cli/lib.py +1154 -0
- honeybee_energy/cli/result.py +810 -0
- honeybee_energy/cli/setconfig.py +124 -0
- honeybee_energy/cli/settings.py +569 -0
- honeybee_energy/cli/simulate.py +380 -0
- honeybee_energy/cli/translate.py +1714 -0
- honeybee_energy/cli/validate.py +224 -0
- honeybee_energy/config.json +11 -0
- honeybee_energy/config.py +842 -0
- honeybee_energy/construction/__init__.py +1 -0
- honeybee_energy/construction/_base.py +374 -0
- honeybee_energy/construction/air.py +325 -0
- honeybee_energy/construction/dictutil.py +89 -0
- honeybee_energy/construction/dynamic.py +607 -0
- honeybee_energy/construction/opaque.py +460 -0
- honeybee_energy/construction/shade.py +319 -0
- honeybee_energy/construction/window.py +1096 -0
- honeybee_energy/construction/windowshade.py +847 -0
- honeybee_energy/constructionset.py +1655 -0
- honeybee_energy/dictutil.py +56 -0
- honeybee_energy/generator/__init__.py +5 -0
- honeybee_energy/generator/loadcenter.py +204 -0
- honeybee_energy/generator/pv.py +535 -0
- honeybee_energy/hvac/__init__.py +21 -0
- honeybee_energy/hvac/_base.py +124 -0
- honeybee_energy/hvac/_template.py +270 -0
- honeybee_energy/hvac/allair/__init__.py +22 -0
- honeybee_energy/hvac/allair/_base.py +349 -0
- honeybee_energy/hvac/allair/furnace.py +168 -0
- honeybee_energy/hvac/allair/psz.py +131 -0
- honeybee_energy/hvac/allair/ptac.py +163 -0
- honeybee_energy/hvac/allair/pvav.py +109 -0
- honeybee_energy/hvac/allair/vav.py +128 -0
- honeybee_energy/hvac/detailed.py +337 -0
- honeybee_energy/hvac/doas/__init__.py +28 -0
- honeybee_energy/hvac/doas/_base.py +345 -0
- honeybee_energy/hvac/doas/fcu.py +127 -0
- honeybee_energy/hvac/doas/radiant.py +329 -0
- honeybee_energy/hvac/doas/vrf.py +81 -0
- honeybee_energy/hvac/doas/wshp.py +91 -0
- honeybee_energy/hvac/heatcool/__init__.py +23 -0
- honeybee_energy/hvac/heatcool/_base.py +177 -0
- honeybee_energy/hvac/heatcool/baseboard.py +61 -0
- honeybee_energy/hvac/heatcool/evapcool.py +72 -0
- honeybee_energy/hvac/heatcool/fcu.py +92 -0
- honeybee_energy/hvac/heatcool/gasunit.py +53 -0
- honeybee_energy/hvac/heatcool/radiant.py +269 -0
- honeybee_energy/hvac/heatcool/residential.py +77 -0
- honeybee_energy/hvac/heatcool/vrf.py +54 -0
- honeybee_energy/hvac/heatcool/windowac.py +70 -0
- honeybee_energy/hvac/heatcool/wshp.py +62 -0
- honeybee_energy/hvac/idealair.py +699 -0
- honeybee_energy/internalmass.py +310 -0
- honeybee_energy/lib/__init__.py +1 -0
- honeybee_energy/lib/_loadconstructions.py +194 -0
- honeybee_energy/lib/_loadconstructionsets.py +117 -0
- honeybee_energy/lib/_loadmaterials.py +83 -0
- honeybee_energy/lib/_loadprogramtypes.py +125 -0
- honeybee_energy/lib/_loadschedules.py +87 -0
- honeybee_energy/lib/_loadtypelimits.py +64 -0
- honeybee_energy/lib/constructions.py +207 -0
- honeybee_energy/lib/constructionsets.py +95 -0
- honeybee_energy/lib/materials.py +67 -0
- honeybee_energy/lib/programtypes.py +125 -0
- honeybee_energy/lib/schedules.py +61 -0
- honeybee_energy/lib/scheduletypelimits.py +31 -0
- honeybee_energy/load/__init__.py +1 -0
- honeybee_energy/load/_base.py +190 -0
- honeybee_energy/load/daylight.py +397 -0
- honeybee_energy/load/dictutil.py +47 -0
- honeybee_energy/load/equipment.py +771 -0
- honeybee_energy/load/hotwater.py +543 -0
- honeybee_energy/load/infiltration.py +460 -0
- honeybee_energy/load/lighting.py +480 -0
- honeybee_energy/load/people.py +497 -0
- honeybee_energy/load/process.py +472 -0
- honeybee_energy/load/setpoint.py +816 -0
- honeybee_energy/load/ventilation.py +550 -0
- honeybee_energy/material/__init__.py +1 -0
- honeybee_energy/material/_base.py +166 -0
- honeybee_energy/material/dictutil.py +59 -0
- honeybee_energy/material/frame.py +367 -0
- honeybee_energy/material/gas.py +1087 -0
- honeybee_energy/material/glazing.py +854 -0
- honeybee_energy/material/opaque.py +1351 -0
- honeybee_energy/material/shade.py +1360 -0
- honeybee_energy/measure.py +472 -0
- honeybee_energy/programtype.py +723 -0
- honeybee_energy/properties/__init__.py +1 -0
- honeybee_energy/properties/aperture.py +333 -0
- honeybee_energy/properties/door.py +342 -0
- honeybee_energy/properties/extension.py +244 -0
- honeybee_energy/properties/face.py +274 -0
- honeybee_energy/properties/model.py +2640 -0
- honeybee_energy/properties/room.py +1747 -0
- honeybee_energy/properties/shade.py +314 -0
- honeybee_energy/properties/shademesh.py +262 -0
- honeybee_energy/reader.py +48 -0
- honeybee_energy/result/__init__.py +1 -0
- honeybee_energy/result/colorobj.py +648 -0
- honeybee_energy/result/emissions.py +290 -0
- honeybee_energy/result/err.py +101 -0
- honeybee_energy/result/eui.py +100 -0
- honeybee_energy/result/generation.py +160 -0
- honeybee_energy/result/loadbalance.py +890 -0
- honeybee_energy/result/match.py +202 -0
- honeybee_energy/result/osw.py +90 -0
- honeybee_energy/result/rdd.py +59 -0
- honeybee_energy/result/zsz.py +190 -0
- honeybee_energy/run.py +1577 -0
- honeybee_energy/schedule/__init__.py +1 -0
- honeybee_energy/schedule/day.py +626 -0
- honeybee_energy/schedule/dictutil.py +59 -0
- honeybee_energy/schedule/fixedinterval.py +1012 -0
- honeybee_energy/schedule/rule.py +619 -0
- honeybee_energy/schedule/ruleset.py +1867 -0
- honeybee_energy/schedule/typelimit.py +310 -0
- honeybee_energy/shw.py +315 -0
- honeybee_energy/simulation/__init__.py +1 -0
- honeybee_energy/simulation/control.py +214 -0
- honeybee_energy/simulation/daylightsaving.py +185 -0
- honeybee_energy/simulation/dictutil.py +51 -0
- honeybee_energy/simulation/output.py +646 -0
- honeybee_energy/simulation/parameter.py +606 -0
- honeybee_energy/simulation/runperiod.py +443 -0
- honeybee_energy/simulation/shadowcalculation.py +295 -0
- honeybee_energy/simulation/sizing.py +546 -0
- honeybee_energy/ventcool/__init__.py +5 -0
- honeybee_energy/ventcool/_crack_data.py +91 -0
- honeybee_energy/ventcool/afn.py +289 -0
- honeybee_energy/ventcool/control.py +269 -0
- honeybee_energy/ventcool/crack.py +126 -0
- honeybee_energy/ventcool/fan.py +493 -0
- honeybee_energy/ventcool/opening.py +365 -0
- honeybee_energy/ventcool/simulation.py +314 -0
- honeybee_energy/writer.py +1078 -0
- honeybee_energy-1.116.106.dist-info/METADATA +113 -0
- honeybee_energy-1.116.106.dist-info/RECORD +162 -0
- honeybee_energy-1.116.106.dist-info/WHEEL +5 -0
- honeybee_energy-1.116.106.dist-info/entry_points.txt +2 -0
- honeybee_energy-1.116.106.dist-info/licenses/LICENSE +661 -0
- honeybee_energy-1.116.106.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1655 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""Energy Construction Set."""
|
|
3
|
+
from __future__ import division
|
|
4
|
+
|
|
5
|
+
from .construction.dictutil import dict_to_construction
|
|
6
|
+
from .construction.opaque import OpaqueConstruction
|
|
7
|
+
from .construction.window import WindowConstruction
|
|
8
|
+
from .construction.windowshade import WindowConstructionShade
|
|
9
|
+
from .construction.dynamic import WindowConstructionDynamic
|
|
10
|
+
from .construction.shade import ShadeConstruction
|
|
11
|
+
from .construction.air import AirBoundaryConstruction
|
|
12
|
+
import honeybee_energy.lib.constructions as _lib
|
|
13
|
+
|
|
14
|
+
from honeybee._lockable import lockable
|
|
15
|
+
from honeybee.typing import valid_ep_string, clean_rad_string
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@lockable
|
|
19
|
+
class ConstructionSet(object):
|
|
20
|
+
"""Set containing all energy constructions needed to create an energy model.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
identifier: Text string for a unique ConstructionSet ID. Must be < 100
|
|
24
|
+
characters and not contain any EnergyPlus special characters. This
|
|
25
|
+
will be used to identify the object across a model and in the
|
|
26
|
+
exported IDF.
|
|
27
|
+
wall_set: An optional WallConstructionSet object for this ConstructionSet.
|
|
28
|
+
If None, it will be the honeybee generic default WallConstructionSet.
|
|
29
|
+
floor_set: An optional FloorConstructionSet object for this ConstructionSet.
|
|
30
|
+
If None, it will be the honeybee generic default FloorConstructionSet.
|
|
31
|
+
roof_ceiling_set: An optional RoofCeilingConstructionSet object for this
|
|
32
|
+
ConstructionSet. If None, it will be the honeybee generic default
|
|
33
|
+
RoofCeilingConstructionSet.
|
|
34
|
+
aperture_set: An optional ApertureConstructionSet object for this
|
|
35
|
+
ConstructionSet. If None, it will be the honeybee generic default
|
|
36
|
+
ApertureConstructionSet.
|
|
37
|
+
door_set: An optional DoorConstructionSet object for this ConstructionSet.
|
|
38
|
+
If None, it will be the honeybee generic default DoorConstructionSet.
|
|
39
|
+
shade_construction: An optional ShadeConstruction to set the reflectance
|
|
40
|
+
properties of all outdoor shades to which this ConstructionSet is
|
|
41
|
+
assigned. If None, it will be the honeybee generic shade construction.
|
|
42
|
+
air_boundary_construction: An optional AirBoundaryConstruction or
|
|
43
|
+
OpaqueConstruction to set the properties of Faces with an AirBoundary
|
|
44
|
+
type. If None, it will be the honeybee generic air boundary construction.
|
|
45
|
+
|
|
46
|
+
Properties:
|
|
47
|
+
* identifier
|
|
48
|
+
* display_name
|
|
49
|
+
* wall_set
|
|
50
|
+
* floor_set
|
|
51
|
+
* roof_ceiling_set
|
|
52
|
+
* aperture_set
|
|
53
|
+
* door_set
|
|
54
|
+
* shade_construction
|
|
55
|
+
* air_boundary_construction
|
|
56
|
+
* constructions
|
|
57
|
+
* modified_constructions
|
|
58
|
+
* constructions_unique
|
|
59
|
+
* modified_constructions_unique
|
|
60
|
+
* materials_unique
|
|
61
|
+
* modified_materials_unique
|
|
62
|
+
* is_interior_defaulted
|
|
63
|
+
* is_interior_symmetric
|
|
64
|
+
* user_data
|
|
65
|
+
"""
|
|
66
|
+
__slots__ = ('_identifier', '_display_name', '_wall_set', '_floor_set',
|
|
67
|
+
'_roof_ceiling_set', '_aperture_set', '_door_set',
|
|
68
|
+
'_shade_construction', '_air_boundary_construction',
|
|
69
|
+
'_locked', '_user_data')
|
|
70
|
+
|
|
71
|
+
def __init__(self, identifier, wall_set=None, floor_set=None, roof_ceiling_set=None,
|
|
72
|
+
aperture_set=None, door_set=None, shade_construction=None,
|
|
73
|
+
air_boundary_construction=None):
|
|
74
|
+
"""Initialize energy construction set."""
|
|
75
|
+
self._locked = False # unlocked by default
|
|
76
|
+
self.identifier = identifier
|
|
77
|
+
self._display_name = None
|
|
78
|
+
self.wall_set = wall_set
|
|
79
|
+
self.floor_set = floor_set
|
|
80
|
+
self.roof_ceiling_set = roof_ceiling_set
|
|
81
|
+
self.aperture_set = aperture_set
|
|
82
|
+
self.door_set = door_set
|
|
83
|
+
self.shade_construction = shade_construction
|
|
84
|
+
self.air_boundary_construction = air_boundary_construction
|
|
85
|
+
self._user_data = None
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def identifier(self):
|
|
89
|
+
"""Get or set a text string for a unique construction set identifier."""
|
|
90
|
+
return self._identifier
|
|
91
|
+
|
|
92
|
+
@identifier.setter
|
|
93
|
+
def identifier(self, identifier):
|
|
94
|
+
self._identifier = valid_ep_string(identifier, 'construction set identifier')
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def display_name(self):
|
|
98
|
+
"""Get or set a string for the object name without any character restrictions.
|
|
99
|
+
|
|
100
|
+
If not set, this will be equal to the identifier.
|
|
101
|
+
"""
|
|
102
|
+
if self._display_name is None:
|
|
103
|
+
return self._identifier
|
|
104
|
+
return self._display_name
|
|
105
|
+
|
|
106
|
+
@display_name.setter
|
|
107
|
+
def display_name(self, value):
|
|
108
|
+
if value is not None:
|
|
109
|
+
try:
|
|
110
|
+
value = str(value)
|
|
111
|
+
except UnicodeEncodeError: # Python 2 machine lacking the character set
|
|
112
|
+
pass # keep it as unicode
|
|
113
|
+
self._display_name = value
|
|
114
|
+
|
|
115
|
+
@property
|
|
116
|
+
def wall_set(self):
|
|
117
|
+
"""Get or set the WallConstructionSet assigned to this ConstructionSet."""
|
|
118
|
+
return self._wall_set
|
|
119
|
+
|
|
120
|
+
@wall_set.setter
|
|
121
|
+
def wall_set(self, value):
|
|
122
|
+
if value is not None:
|
|
123
|
+
assert isinstance(value, WallConstructionSet), \
|
|
124
|
+
'Expected WallConstructionSet. Got {}'.format(type(value))
|
|
125
|
+
self._wall_set = value
|
|
126
|
+
else:
|
|
127
|
+
self._wall_set = WallConstructionSet()
|
|
128
|
+
|
|
129
|
+
@property
|
|
130
|
+
def floor_set(self):
|
|
131
|
+
"""Get or set the FloorConstructionSet assigned to this ConstructionSet."""
|
|
132
|
+
return self._floor_set
|
|
133
|
+
|
|
134
|
+
@floor_set.setter
|
|
135
|
+
def floor_set(self, value):
|
|
136
|
+
if value is not None:
|
|
137
|
+
assert isinstance(value, FloorConstructionSet), \
|
|
138
|
+
'Expected FloorConstructionSet. Got {}'.format(type(value))
|
|
139
|
+
self._floor_set = value
|
|
140
|
+
else:
|
|
141
|
+
self._floor_set = FloorConstructionSet()
|
|
142
|
+
|
|
143
|
+
@property
|
|
144
|
+
def roof_ceiling_set(self):
|
|
145
|
+
"""Get or set the RoofCeilingConstructionSet assigned to this ConstructionSet."""
|
|
146
|
+
return self._roof_ceiling_set
|
|
147
|
+
|
|
148
|
+
@roof_ceiling_set.setter
|
|
149
|
+
def roof_ceiling_set(self, value):
|
|
150
|
+
if value is not None:
|
|
151
|
+
assert isinstance(value, RoofCeilingConstructionSet), \
|
|
152
|
+
'Expected RoofCeilingConstructionSet. Got {}'.format(type(value))
|
|
153
|
+
self._roof_ceiling_set = value
|
|
154
|
+
else:
|
|
155
|
+
self._roof_ceiling_set = RoofCeilingConstructionSet()
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def aperture_set(self):
|
|
159
|
+
"""Get or set the ApertureConstructionSet assigned to this ConstructionSet."""
|
|
160
|
+
return self._aperture_set
|
|
161
|
+
|
|
162
|
+
@aperture_set.setter
|
|
163
|
+
def aperture_set(self, value):
|
|
164
|
+
if value is not None:
|
|
165
|
+
assert isinstance(value, ApertureConstructionSet), \
|
|
166
|
+
'Expected ApertureConstructionSet. Got {}'.format(type(value))
|
|
167
|
+
self._aperture_set = value
|
|
168
|
+
else:
|
|
169
|
+
self._aperture_set = ApertureConstructionSet()
|
|
170
|
+
|
|
171
|
+
@property
|
|
172
|
+
def door_set(self):
|
|
173
|
+
"""Get or set the DoorConstructionSet assigned to this ConstructionSet."""
|
|
174
|
+
return self._door_set
|
|
175
|
+
|
|
176
|
+
@door_set.setter
|
|
177
|
+
def door_set(self, value):
|
|
178
|
+
if value is not None:
|
|
179
|
+
assert isinstance(value, DoorConstructionSet), \
|
|
180
|
+
'Expected DoorConstructionSet. Got {}'.format(type(value))
|
|
181
|
+
self._door_set = value
|
|
182
|
+
else:
|
|
183
|
+
self._door_set = DoorConstructionSet()
|
|
184
|
+
|
|
185
|
+
@property
|
|
186
|
+
def shade_construction(self):
|
|
187
|
+
"""Get or set the ShadeConstruction assigned to this ConstructionSet."""
|
|
188
|
+
if self._shade_construction is None:
|
|
189
|
+
return _lib.generic_shade
|
|
190
|
+
return self._shade_construction
|
|
191
|
+
|
|
192
|
+
@shade_construction.setter
|
|
193
|
+
def shade_construction(self, value):
|
|
194
|
+
if value is not None:
|
|
195
|
+
assert isinstance(value, ShadeConstruction), \
|
|
196
|
+
'Expected ShadeConstruction. Got {}'.format(type(value))
|
|
197
|
+
value.lock() # lock editing in case construction has multiple references
|
|
198
|
+
self._shade_construction = value
|
|
199
|
+
|
|
200
|
+
@property
|
|
201
|
+
def air_boundary_construction(self):
|
|
202
|
+
"""Get or set the AirBoundaryConstruction assigned to this ConstructionSet."""
|
|
203
|
+
if self._air_boundary_construction is None:
|
|
204
|
+
return _lib.air_boundary
|
|
205
|
+
return self._air_boundary_construction
|
|
206
|
+
|
|
207
|
+
@air_boundary_construction.setter
|
|
208
|
+
def air_boundary_construction(self, value):
|
|
209
|
+
if value is not None:
|
|
210
|
+
assert isinstance(value, (AirBoundaryConstruction, OpaqueConstruction)), \
|
|
211
|
+
'Expected AirBoundaryConstruction or OpaqueConstruction. ' \
|
|
212
|
+
'Got {}'.format(type(value))
|
|
213
|
+
value.lock() # lock editing in case construction has multiple references
|
|
214
|
+
self._air_boundary_construction = value
|
|
215
|
+
|
|
216
|
+
@property
|
|
217
|
+
def constructions(self):
|
|
218
|
+
"""List of all constructions contained within the set."""
|
|
219
|
+
return self.wall_set.constructions + \
|
|
220
|
+
self.floor_set.constructions + \
|
|
221
|
+
self.roof_ceiling_set.constructions + \
|
|
222
|
+
self.aperture_set.constructions + \
|
|
223
|
+
self.door_set.constructions + \
|
|
224
|
+
[self.shade_construction, self.air_boundary_construction]
|
|
225
|
+
|
|
226
|
+
@property
|
|
227
|
+
def modified_constructions(self):
|
|
228
|
+
"""List of all constructions that are not defaulted within the set."""
|
|
229
|
+
mod_constructions = self.wall_set.modified_constructions + \
|
|
230
|
+
self.floor_set.modified_constructions + \
|
|
231
|
+
self.roof_ceiling_set.modified_constructions + \
|
|
232
|
+
self.aperture_set.modified_constructions + \
|
|
233
|
+
self.door_set.modified_constructions
|
|
234
|
+
if self._shade_construction is not None:
|
|
235
|
+
mod_constructions.append(self._shade_construction)
|
|
236
|
+
if self._air_boundary_construction is not None:
|
|
237
|
+
mod_constructions.append(self._air_boundary_construction)
|
|
238
|
+
return mod_constructions
|
|
239
|
+
|
|
240
|
+
@property
|
|
241
|
+
def constructions_unique(self):
|
|
242
|
+
"""List of all unique constructions contained within the set."""
|
|
243
|
+
return list(set(self.constructions))
|
|
244
|
+
|
|
245
|
+
@property
|
|
246
|
+
def modified_constructions_unique(self):
|
|
247
|
+
"""List of all unique constructions that are not defaulted within the set."""
|
|
248
|
+
return list(set(self.modified_constructions))
|
|
249
|
+
|
|
250
|
+
@property
|
|
251
|
+
def materials_unique(self):
|
|
252
|
+
"""List of all unique materials contained within the set."""
|
|
253
|
+
materials = []
|
|
254
|
+
for constr in self.constructions:
|
|
255
|
+
try:
|
|
256
|
+
materials.extend(constr.materials)
|
|
257
|
+
if constr.has_frame:
|
|
258
|
+
materials.append(constr.frame)
|
|
259
|
+
except AttributeError:
|
|
260
|
+
pass # ShadeConstruction or AirBoundaryConstruction
|
|
261
|
+
return list(set(materials))
|
|
262
|
+
|
|
263
|
+
@property
|
|
264
|
+
def modified_materials_unique(self):
|
|
265
|
+
"""List of all unique materials that are not defaulted within the set."""
|
|
266
|
+
materials = []
|
|
267
|
+
for constr in self.modified_constructions:
|
|
268
|
+
try:
|
|
269
|
+
materials.extend(constr.materials)
|
|
270
|
+
if constr.has_frame:
|
|
271
|
+
materials.append(constr.frame)
|
|
272
|
+
except AttributeError:
|
|
273
|
+
pass # ShadeConstruction or AirBoundaryConstruction
|
|
274
|
+
return list(set(materials))
|
|
275
|
+
|
|
276
|
+
@property
|
|
277
|
+
def is_interior_defaulted(self):
|
|
278
|
+
"""Get a boolean for whether all interior constructions of the set are defaulted.
|
|
279
|
+
|
|
280
|
+
If all construction sets in a model use the same default interior constructions,
|
|
281
|
+
it meas that the construction sets won't create any conflicts between adjacent
|
|
282
|
+
interior Faces.
|
|
283
|
+
"""
|
|
284
|
+
return self.wall_set._interior_construction is None and \
|
|
285
|
+
self.aperture_set._interior_construction is None and \
|
|
286
|
+
self.door_set._interior_construction is None and \
|
|
287
|
+
self.floor_set._interior_construction is None and \
|
|
288
|
+
self.roof_ceiling_set._interior_construction is None
|
|
289
|
+
|
|
290
|
+
@property
|
|
291
|
+
def is_interior_symmetric(self):
|
|
292
|
+
"""Get a boolean for whether all interior constructions of the set are symmetric.
|
|
293
|
+
|
|
294
|
+
This will only be true if the interior wall, window and door constructions
|
|
295
|
+
are symmetric and the material layers of the interior floor construction
|
|
296
|
+
is a reversed version of the ceiling construction. When these criteria
|
|
297
|
+
are met, it meas that the construction set can be applied to all rooms
|
|
298
|
+
of a Model without concern for it creating conflicts between adjacent
|
|
299
|
+
interior Faces.
|
|
300
|
+
"""
|
|
301
|
+
# check the constructions that are supposed to be symmetric
|
|
302
|
+
wall_con = self.wall_set._interior_construction
|
|
303
|
+
if wall_con is not None and not wall_con.is_symmetric:
|
|
304
|
+
return False
|
|
305
|
+
win_con = self.aperture_set._interior_construction
|
|
306
|
+
if win_con is not None and not win_con.is_symmetric:
|
|
307
|
+
return False
|
|
308
|
+
door_con = self.door_set._interior_construction
|
|
309
|
+
if door_con is not None and not door_con.is_symmetric:
|
|
310
|
+
return False
|
|
311
|
+
glz_dr_con = self.door_set._interior_glass_construction
|
|
312
|
+
if glz_dr_con is not None and not glz_dr_con.is_symmetric:
|
|
313
|
+
return False
|
|
314
|
+
# check that the floor is the reverse of the floor
|
|
315
|
+
floor_con = self.floor_set.interior_construction
|
|
316
|
+
ceil_con = self.roof_ceiling_set.interior_construction
|
|
317
|
+
if floor_con.materials != tuple(reversed(ceil_con.materials)):
|
|
318
|
+
return False
|
|
319
|
+
return True
|
|
320
|
+
|
|
321
|
+
@property
|
|
322
|
+
def user_data(self):
|
|
323
|
+
"""Get or set an optional dictionary for additional meta data for this object.
|
|
324
|
+
|
|
325
|
+
This will be None until it has been set. All keys and values of this
|
|
326
|
+
dictionary should be of a standard Python type to ensure correct
|
|
327
|
+
serialization of the object to/from JSON (eg. str, float, int, list, dict)
|
|
328
|
+
"""
|
|
329
|
+
if self._user_data is not None:
|
|
330
|
+
return self._user_data
|
|
331
|
+
|
|
332
|
+
@user_data.setter
|
|
333
|
+
def user_data(self, value):
|
|
334
|
+
if value is not None:
|
|
335
|
+
assert isinstance(value, dict), 'Expected dictionary for honeybee_energy' \
|
|
336
|
+
'object user_data. Got {}.'.format(type(value))
|
|
337
|
+
self._user_data = value
|
|
338
|
+
|
|
339
|
+
def get_face_construction(self, face_type, boundary_condition):
|
|
340
|
+
"""Get a construction object that will be assigned to a given type of face.
|
|
341
|
+
|
|
342
|
+
Args:
|
|
343
|
+
face_type: Text string for the type of face (eg. 'Wall', 'Floor',
|
|
344
|
+
'Roof', 'AirBoundary').
|
|
345
|
+
boundary_condition: Text string for the boundary condition
|
|
346
|
+
(eg. 'Outdoors', 'Surface', 'Adiabatic', 'Ground')
|
|
347
|
+
"""
|
|
348
|
+
if face_type == 'Wall':
|
|
349
|
+
return self._get_constr_from_set(self.wall_set, boundary_condition)
|
|
350
|
+
elif face_type == 'Floor':
|
|
351
|
+
return self._get_constr_from_set(self.floor_set, boundary_condition)
|
|
352
|
+
elif face_type == 'RoofCeiling':
|
|
353
|
+
return self._get_constr_from_set(self.roof_ceiling_set, boundary_condition)
|
|
354
|
+
elif face_type == 'AirBoundary':
|
|
355
|
+
return self.air_boundary_construction
|
|
356
|
+
else:
|
|
357
|
+
raise NotImplementedError(
|
|
358
|
+
'Face type {} is not recognized for ConstructionSet'.format(face_type))
|
|
359
|
+
|
|
360
|
+
def get_aperture_construction(self, boundary_condition, is_operable,
|
|
361
|
+
parent_face_type):
|
|
362
|
+
"""Get a construction object that will be assigned to a given type of aperture.
|
|
363
|
+
|
|
364
|
+
Args:
|
|
365
|
+
boundary_condition: Text string for the boundary condition
|
|
366
|
+
(eg. 'Outdoors', 'Surface')
|
|
367
|
+
is_operable: Boolean to note whether the aperture is operable.
|
|
368
|
+
parent_face_type: Text string for the type of face to which the aperture
|
|
369
|
+
is a child (eg. 'Wall', 'Floor', 'Roof').
|
|
370
|
+
"""
|
|
371
|
+
if boundary_condition == 'Outdoors':
|
|
372
|
+
if not is_operable:
|
|
373
|
+
if parent_face_type == 'Wall':
|
|
374
|
+
return self.aperture_set.window_construction
|
|
375
|
+
else:
|
|
376
|
+
return self.aperture_set.skylight_construction
|
|
377
|
+
else:
|
|
378
|
+
return self.aperture_set.operable_construction
|
|
379
|
+
elif boundary_condition == 'Surface':
|
|
380
|
+
return self.aperture_set.interior_construction
|
|
381
|
+
else:
|
|
382
|
+
raise NotImplementedError(
|
|
383
|
+
'Boundary condition {} is not recognized for apertures in '
|
|
384
|
+
'ConstructionSet'.format(boundary_condition))
|
|
385
|
+
|
|
386
|
+
def get_door_construction(self, boundary_condition, is_glass, parent_face_type):
|
|
387
|
+
"""Get a construction object that will be assigned to a given type of door.
|
|
388
|
+
|
|
389
|
+
Args:
|
|
390
|
+
boundary_condition: Text string for the boundary condition
|
|
391
|
+
(eg. 'Outdoors', 'Surface')
|
|
392
|
+
is_glass: Boolean to note whether the door is glass (instead of opaque).
|
|
393
|
+
parent_face_type: Text string for the type of face to which the door
|
|
394
|
+
is a child (eg. 'Wall', 'Floor', 'Roof').
|
|
395
|
+
"""
|
|
396
|
+
if boundary_condition == 'Outdoors':
|
|
397
|
+
if not is_glass:
|
|
398
|
+
if parent_face_type == 'Wall':
|
|
399
|
+
return self.door_set.exterior_construction
|
|
400
|
+
else:
|
|
401
|
+
return self.door_set.overhead_construction
|
|
402
|
+
else:
|
|
403
|
+
return self.door_set.exterior_glass_construction
|
|
404
|
+
elif boundary_condition == 'Surface':
|
|
405
|
+
if not is_glass:
|
|
406
|
+
return self.door_set.interior_construction
|
|
407
|
+
else:
|
|
408
|
+
return self.door_set.interior_glass_construction
|
|
409
|
+
else:
|
|
410
|
+
raise NotImplementedError(
|
|
411
|
+
'Boundary condition {} is not recognized for doors in '
|
|
412
|
+
'ConstructionSet'.format(boundary_condition))
|
|
413
|
+
|
|
414
|
+
@classmethod
|
|
415
|
+
def from_dict(cls, data):
|
|
416
|
+
"""Create a ConstructionSet from a dictionary.
|
|
417
|
+
|
|
418
|
+
Note that the dictionary must be a non-abridged version for this
|
|
419
|
+
classmethod to work.
|
|
420
|
+
|
|
421
|
+
Args:
|
|
422
|
+
data: Dictionary describing the ConstructionSet with the
|
|
423
|
+
format below.
|
|
424
|
+
|
|
425
|
+
.. code-block:: python
|
|
426
|
+
|
|
427
|
+
{
|
|
428
|
+
"type": 'ConstructionSet',
|
|
429
|
+
"identifier": str, # ConstructionSet identifier
|
|
430
|
+
"display_name": str, # ConstructionSet display name
|
|
431
|
+
"wall_set": {}, # A WallConstructionSet dictionary
|
|
432
|
+
"floor_set": {}, # A FloorConstructionSet dictionary
|
|
433
|
+
"roof_ceiling_set": {}, # A RoofCeilingConstructionSet dictionary
|
|
434
|
+
"aperture_set": {}, # A ApertureConstructionSet dictionary
|
|
435
|
+
"door_set": {}, # A DoorConstructionSet dictionary
|
|
436
|
+
"shade_construction": {}, # ShadeConstruction dictionary
|
|
437
|
+
"air_boundary_construction": {}, # AirBoundaryConstruction dictionary
|
|
438
|
+
}
|
|
439
|
+
"""
|
|
440
|
+
assert data['type'] == 'ConstructionSet', \
|
|
441
|
+
'Expected ConstructionSet. Got {}.'.format(data['type'])
|
|
442
|
+
|
|
443
|
+
# build each of the sub-construction sets
|
|
444
|
+
wall_set = WallConstructionSet.from_dict(data['wall_set']) if 'wall_set' \
|
|
445
|
+
in data and data['wall_set'] is not None else None
|
|
446
|
+
floor_set = FloorConstructionSet.from_dict(data['floor_set']) if 'floor_set' \
|
|
447
|
+
in data and data['floor_set'] is not None else None
|
|
448
|
+
roof_ceiling_set = \
|
|
449
|
+
RoofCeilingConstructionSet.from_dict(data['roof_ceiling_set']) \
|
|
450
|
+
if 'roof_ceiling_set' in data and data['roof_ceiling_set'] \
|
|
451
|
+
is not None else None
|
|
452
|
+
aperture_set = ApertureConstructionSet.from_dict(data['aperture_set']) if \
|
|
453
|
+
'aperture_set' in data and data['aperture_set'] is not None else None
|
|
454
|
+
door_set = DoorConstructionSet.from_dict(data['door_set']) if \
|
|
455
|
+
'door_set' in data and data['door_set'] is not None else None
|
|
456
|
+
shade_con = ShadeConstruction.from_dict(data['shade_construction']) if \
|
|
457
|
+
'shade_construction' in data and data['shade_construction'] is not None \
|
|
458
|
+
else None
|
|
459
|
+
air_con = None
|
|
460
|
+
if 'air_boundary_construction' in data and \
|
|
461
|
+
data['air_boundary_construction'] is not None:
|
|
462
|
+
if data['air_boundary_construction']['type'] == 'AirBoundaryConstruction':
|
|
463
|
+
air_con = AirBoundaryConstruction.from_dict(
|
|
464
|
+
data['air_boundary_construction'])
|
|
465
|
+
else:
|
|
466
|
+
air_con = OpaqueConstruction.from_dict(data['air_boundary_construction'])
|
|
467
|
+
|
|
468
|
+
new_obj = cls(data['identifier'], wall_set, floor_set, roof_ceiling_set,
|
|
469
|
+
aperture_set, door_set, shade_con, air_con)
|
|
470
|
+
if 'display_name' in data and data['display_name'] is not None:
|
|
471
|
+
new_obj.display_name = data['display_name']
|
|
472
|
+
if 'user_data' in data and data['user_data'] is not None:
|
|
473
|
+
new_obj.user_data = data['user_data']
|
|
474
|
+
return new_obj
|
|
475
|
+
|
|
476
|
+
@classmethod
|
|
477
|
+
def from_dict_abridged(cls, data, construction_dict):
|
|
478
|
+
"""Create a ConstructionSet from an abridged dictionary.
|
|
479
|
+
|
|
480
|
+
Args:
|
|
481
|
+
data: A ConstructionSetAbridged dictionary.
|
|
482
|
+
construction_dict: A dictionary with construction identifiers as keys and
|
|
483
|
+
honeybee construction objects as values. These will be used to
|
|
484
|
+
assign the constructions to the ConstructionSet object.
|
|
485
|
+
|
|
486
|
+
.. code-block:: python
|
|
487
|
+
|
|
488
|
+
{
|
|
489
|
+
"type": 'ConstructionSetAbridged',
|
|
490
|
+
"identifier": str, # ConstructionSet identifier
|
|
491
|
+
"display_name": str, # ConstructionSet display name
|
|
492
|
+
"wall_set": {}, # A WallConstructionSetAbridged dictionary
|
|
493
|
+
"floor_set": {}, # A FloorConstructionSetAbridged dictionary
|
|
494
|
+
"roof_ceiling_set": {}, # A RoofCeilingConstructionSetAbridged dictionary
|
|
495
|
+
"aperture_set": {}, # A ApertureConstructionSetAbridged dictionary
|
|
496
|
+
"door_set": {}, # A DoorConstructionSetAbridged dictionary
|
|
497
|
+
"shade_construction": str, # ShadeConstruction identifier
|
|
498
|
+
"air_boundary_construction": str # AirBoundaryConstruction identifier
|
|
499
|
+
}
|
|
500
|
+
"""
|
|
501
|
+
assert data['type'] == 'ConstructionSetAbridged', \
|
|
502
|
+
'Expected ConstructionSetAbridged. Got {}.'.format(data['type'])
|
|
503
|
+
try:
|
|
504
|
+
wall_set, floor_set, roof_ceiling_set, aperture_set, door_set, shade_con, \
|
|
505
|
+
air_con = cls._get_subsets_from_abridged(data, construction_dict)
|
|
506
|
+
except KeyError as e:
|
|
507
|
+
raise ValueError(
|
|
508
|
+
'The following construction is missing from the model: {}'.format(e)
|
|
509
|
+
)
|
|
510
|
+
new_obj = cls(data['identifier'], wall_set, floor_set, roof_ceiling_set,
|
|
511
|
+
aperture_set, door_set, shade_con, air_con)
|
|
512
|
+
if 'display_name' in data and data['display_name'] is not None:
|
|
513
|
+
new_obj.display_name = data['display_name']
|
|
514
|
+
if 'user_data' in data and data['user_data'] is not None:
|
|
515
|
+
new_obj.user_data = data['user_data']
|
|
516
|
+
return new_obj
|
|
517
|
+
|
|
518
|
+
def to_dict(self, abridged=False, none_for_defaults=True):
|
|
519
|
+
"""Get ConstructionSet as a dictionary.
|
|
520
|
+
|
|
521
|
+
Args:
|
|
522
|
+
abridged: Boolean noting whether detailed materials and construction
|
|
523
|
+
objects should be written into the ConstructionSet (False) or just
|
|
524
|
+
an abridged version (True). Default: False.
|
|
525
|
+
none_for_defaults: Boolean to note whether default constructions in the
|
|
526
|
+
set should be included in detail (False) or should be None (True).
|
|
527
|
+
Default: True.
|
|
528
|
+
"""
|
|
529
|
+
base = {'type': 'ConstructionSet'} if not \
|
|
530
|
+
abridged else {'type': 'ConstructionSetAbridged'}
|
|
531
|
+
base['identifier'] = self.identifier
|
|
532
|
+
base['wall_set'] = self.wall_set.to_dict(abridged, none_for_defaults)
|
|
533
|
+
base['floor_set'] = self.floor_set.to_dict(abridged, none_for_defaults)
|
|
534
|
+
base['roof_ceiling_set'] = \
|
|
535
|
+
self.roof_ceiling_set.to_dict(abridged, none_for_defaults)
|
|
536
|
+
base['aperture_set'] = self.aperture_set.to_dict(abridged, none_for_defaults)
|
|
537
|
+
base['door_set'] = self.door_set.to_dict(abridged, none_for_defaults)
|
|
538
|
+
if none_for_defaults:
|
|
539
|
+
if abridged:
|
|
540
|
+
base['shade_construction'] = self._shade_construction.identifier \
|
|
541
|
+
if self._shade_construction is not None else None
|
|
542
|
+
else:
|
|
543
|
+
base['shade_construction'] = self._shade_construction.to_dict() \
|
|
544
|
+
if self._shade_construction is not None else None
|
|
545
|
+
else:
|
|
546
|
+
base['shade_construction'] = self.shade_construction.identifier \
|
|
547
|
+
if abridged else self.shade_construction.to_dict()
|
|
548
|
+
if none_for_defaults:
|
|
549
|
+
if abridged:
|
|
550
|
+
base['air_boundary_construction'] = \
|
|
551
|
+
self._air_boundary_construction.identifier if \
|
|
552
|
+
self._air_boundary_construction is not None else None
|
|
553
|
+
else:
|
|
554
|
+
base['air_boundary_construction'] = \
|
|
555
|
+
self._air_boundary_construction.to_dict() if \
|
|
556
|
+
self._air_boundary_construction is not None else None
|
|
557
|
+
else:
|
|
558
|
+
base['air_boundary_construction'] = \
|
|
559
|
+
self.air_boundary_construction.identifier \
|
|
560
|
+
if abridged else self.air_boundary_construction.to_dict()
|
|
561
|
+
|
|
562
|
+
if self._display_name is not None:
|
|
563
|
+
base['display_name'] = self.display_name
|
|
564
|
+
if self._user_data is not None:
|
|
565
|
+
base['user_data'] = self.user_data
|
|
566
|
+
return base
|
|
567
|
+
|
|
568
|
+
def to_radiance_solar_interior(self):
|
|
569
|
+
"""Honeybee Radiance modifier set for the interior solar properties."""
|
|
570
|
+
# convert all interior constructions into modifiers
|
|
571
|
+
unique_mods = {}
|
|
572
|
+
for constr in self.constructions_unique:
|
|
573
|
+
unique_mods[constr.identifier] = constr.to_radiance_solar_interior() \
|
|
574
|
+
if isinstance(constr, OpaqueConstruction) else constr.to_radiance_solar()
|
|
575
|
+
return self._create_modifier_set('Solar_Interior', unique_mods)
|
|
576
|
+
|
|
577
|
+
def to_radiance_visible_interior(self):
|
|
578
|
+
"""Honeybee Radiance modifier set for the interior visible properties."""
|
|
579
|
+
# convert all interior constructions into modifiers
|
|
580
|
+
unique_mods = {}
|
|
581
|
+
for constr in self.constructions_unique:
|
|
582
|
+
unique_mods[constr.identifier] = constr.to_radiance_visible_interior() \
|
|
583
|
+
if isinstance(constr, OpaqueConstruction) \
|
|
584
|
+
else constr.to_radiance_visible()
|
|
585
|
+
return self._create_modifier_set('Visible_Interior', unique_mods)
|
|
586
|
+
|
|
587
|
+
def to_radiance_solar_exterior(self):
|
|
588
|
+
"""Honeybee Radiance modifier set for the exterior solar properties."""
|
|
589
|
+
# convert all exterior constructions into modifiers
|
|
590
|
+
unique_mods = {}
|
|
591
|
+
for constr in self.constructions_unique:
|
|
592
|
+
unique_mods[constr.identifier] = constr.to_radiance_solar_exterior() \
|
|
593
|
+
if isinstance(constr, OpaqueConstruction) else constr.to_radiance_solar()
|
|
594
|
+
return self._create_modifier_set('Solar_Exterior', unique_mods)
|
|
595
|
+
|
|
596
|
+
def to_radiance_visible_exterior(self):
|
|
597
|
+
"""Honeybee Radiance modifier set for the exterior visible properties."""
|
|
598
|
+
# convert all exterior constructions into modifiers
|
|
599
|
+
unique_mods = {}
|
|
600
|
+
for constr in self.constructions_unique:
|
|
601
|
+
unique_mods[constr.identifier] = constr.to_radiance_visible_exterior() \
|
|
602
|
+
if isinstance(constr, OpaqueConstruction) \
|
|
603
|
+
else constr.to_radiance_visible()
|
|
604
|
+
return self._create_modifier_set('Visible_Exterior', unique_mods)
|
|
605
|
+
|
|
606
|
+
def duplicate(self):
|
|
607
|
+
"""Get a copy of this ConstructionSet."""
|
|
608
|
+
return self.__copy__()
|
|
609
|
+
|
|
610
|
+
def lock(self):
|
|
611
|
+
"""The lock() method to will also lock the WallConstructionSet, etc."""
|
|
612
|
+
self._locked = True
|
|
613
|
+
self._wall_set.lock()
|
|
614
|
+
self._floor_set.lock()
|
|
615
|
+
self._roof_ceiling_set.lock()
|
|
616
|
+
self._aperture_set.lock()
|
|
617
|
+
self._door_set.lock()
|
|
618
|
+
|
|
619
|
+
def unlock(self):
|
|
620
|
+
"""The unlock() method will also unlock the WallConstructionSet, etc."""
|
|
621
|
+
self._locked = False
|
|
622
|
+
self._wall_set.unlock()
|
|
623
|
+
self._floor_set.unlock()
|
|
624
|
+
self._roof_ceiling_set.unlock()
|
|
625
|
+
self._aperture_set.unlock()
|
|
626
|
+
self._door_set.unlock()
|
|
627
|
+
|
|
628
|
+
def _create_modifier_set(self, mod_type, unique_mods):
|
|
629
|
+
"""Create a modifier set from a dictionary of radiance modifiers."""
|
|
630
|
+
# import the radiance dependency
|
|
631
|
+
try:
|
|
632
|
+
from honeybee_radiance.modifierset import ModifierSet
|
|
633
|
+
except ImportError as e:
|
|
634
|
+
raise ImportError('honeybee_radiance library must be installed to use '
|
|
635
|
+
'to_radiance_solar() method. {}'.format(e))
|
|
636
|
+
# create the modifier set object
|
|
637
|
+
mod_set = ModifierSet(
|
|
638
|
+
'{}_{}'.format(clean_rad_string(self.identifier), mod_type))
|
|
639
|
+
mod_set.wall_set.exterior_modifier = \
|
|
640
|
+
unique_mods[self.wall_set.exterior_construction.identifier]
|
|
641
|
+
mod_set.wall_set.interior_modifier = \
|
|
642
|
+
unique_mods[self.wall_set.interior_construction.identifier]
|
|
643
|
+
mod_set.floor_set.exterior_modifier = \
|
|
644
|
+
unique_mods[self.floor_set.exterior_construction.identifier]
|
|
645
|
+
mod_set.floor_set.interior_modifier = \
|
|
646
|
+
unique_mods[self.floor_set.interior_construction.identifier]
|
|
647
|
+
mod_set.roof_ceiling_set.exterior_modifier = \
|
|
648
|
+
unique_mods[self.roof_ceiling_set.exterior_construction.identifier]
|
|
649
|
+
mod_set.roof_ceiling_set.interior_modifier = \
|
|
650
|
+
unique_mods[self.roof_ceiling_set.interior_construction.identifier]
|
|
651
|
+
mod_set.aperture_set.window_modifier = \
|
|
652
|
+
unique_mods[self.aperture_set.window_construction.identifier]
|
|
653
|
+
mod_set.aperture_set.interior_modifier = \
|
|
654
|
+
unique_mods[self.aperture_set.interior_construction.identifier]
|
|
655
|
+
mod_set.aperture_set.skylight_modifier = \
|
|
656
|
+
unique_mods[self.aperture_set.skylight_construction.identifier]
|
|
657
|
+
mod_set.aperture_set.operable_modifier = \
|
|
658
|
+
unique_mods[self.aperture_set.operable_construction.identifier]
|
|
659
|
+
mod_set.door_set.exterior_modifier = \
|
|
660
|
+
unique_mods[self.door_set.exterior_construction.identifier]
|
|
661
|
+
mod_set.door_set.interior_modifier = \
|
|
662
|
+
unique_mods[self.door_set.interior_construction.identifier]
|
|
663
|
+
mod_set.door_set.exterior_glass_modifier = \
|
|
664
|
+
unique_mods[self.door_set.exterior_glass_construction.identifier]
|
|
665
|
+
mod_set.door_set.interior_glass_modifier = \
|
|
666
|
+
unique_mods[self.door_set.interior_glass_construction.identifier]
|
|
667
|
+
mod_set.door_set.overhead_modifier = \
|
|
668
|
+
unique_mods[self.door_set.overhead_construction.identifier]
|
|
669
|
+
mod_set.shade_set.exterior_modifier = \
|
|
670
|
+
unique_mods[self.shade_construction.identifier]
|
|
671
|
+
mod_set.air_boundary_modifier = \
|
|
672
|
+
unique_mods[self.air_boundary_construction.identifier]
|
|
673
|
+
return mod_set
|
|
674
|
+
|
|
675
|
+
def _get_constr_from_set(self, face_type_set, boundary_condition):
|
|
676
|
+
"""Get a specific construction from a face_type_set."""
|
|
677
|
+
if boundary_condition == 'Outdoors':
|
|
678
|
+
return face_type_set.exterior_construction
|
|
679
|
+
elif boundary_condition == 'Surface' or boundary_condition == 'Adiabatic':
|
|
680
|
+
return face_type_set.interior_construction
|
|
681
|
+
else:
|
|
682
|
+
return face_type_set.ground_construction
|
|
683
|
+
|
|
684
|
+
@staticmethod
|
|
685
|
+
def _get_subsets_from_abridged(data, constructions):
|
|
686
|
+
"""Get subset objects from and abridged dictionary."""
|
|
687
|
+
wall_set = ConstructionSet._make_construction_subset(
|
|
688
|
+
data, WallConstructionSet(), 'wall_set', constructions)
|
|
689
|
+
floor_set = ConstructionSet._make_construction_subset(
|
|
690
|
+
data, FloorConstructionSet(), 'floor_set', constructions)
|
|
691
|
+
roof_ceiling_set = ConstructionSet._make_construction_subset(
|
|
692
|
+
data, RoofCeilingConstructionSet(), 'roof_ceiling_set', constructions)
|
|
693
|
+
aperture_set = ConstructionSet._make_aperture_subset(
|
|
694
|
+
data, ApertureConstructionSet(), constructions)
|
|
695
|
+
door_set = ConstructionSet._make_door_subset(
|
|
696
|
+
data, DoorConstructionSet(), constructions)
|
|
697
|
+
if 'shade_construction' in data and data['shade_construction'] is not None:
|
|
698
|
+
shade = constructions[data['shade_construction']]
|
|
699
|
+
else:
|
|
700
|
+
shade = None
|
|
701
|
+
if 'air_boundary_construction' in data and \
|
|
702
|
+
data['air_boundary_construction'] is not None:
|
|
703
|
+
air = constructions[data['air_boundary_construction']]
|
|
704
|
+
else:
|
|
705
|
+
air = None
|
|
706
|
+
return wall_set, floor_set, roof_ceiling_set, aperture_set, door_set, shade, air
|
|
707
|
+
|
|
708
|
+
@staticmethod
|
|
709
|
+
def _make_construction_subset(data, sub_set, sub_set_id, constructions):
|
|
710
|
+
"""Make a wall set, floor set, or roof ceiling set from dictionary."""
|
|
711
|
+
if sub_set_id in data:
|
|
712
|
+
if 'exterior_construction' in data[sub_set_id] and \
|
|
713
|
+
data[sub_set_id]['exterior_construction'] is not None:
|
|
714
|
+
sub_set.exterior_construction = \
|
|
715
|
+
constructions[data[sub_set_id]['exterior_construction']]
|
|
716
|
+
if 'interior_construction' in data[sub_set_id] and \
|
|
717
|
+
data[sub_set_id]['interior_construction'] is not None:
|
|
718
|
+
sub_set.interior_construction = \
|
|
719
|
+
constructions[data[sub_set_id]['interior_construction']]
|
|
720
|
+
if 'ground_construction' in data[sub_set_id] and \
|
|
721
|
+
data[sub_set_id]['ground_construction'] is not None:
|
|
722
|
+
sub_set.ground_construction = \
|
|
723
|
+
constructions[data[sub_set_id]['ground_construction']]
|
|
724
|
+
return sub_set
|
|
725
|
+
|
|
726
|
+
@staticmethod
|
|
727
|
+
def _make_aperture_subset(data, sub_set, constructions):
|
|
728
|
+
"""Make an ApertureConstructionSet from a dictionary."""
|
|
729
|
+
if 'aperture_set' in data:
|
|
730
|
+
if 'window_construction' in data['aperture_set'] and \
|
|
731
|
+
data['aperture_set']['window_construction'] is not None:
|
|
732
|
+
sub_set.window_construction = \
|
|
733
|
+
constructions[data['aperture_set']['window_construction']]
|
|
734
|
+
if 'interior_construction' in data['aperture_set'] and \
|
|
735
|
+
data['aperture_set']['interior_construction'] is not None:
|
|
736
|
+
sub_set.interior_construction = \
|
|
737
|
+
constructions[data['aperture_set']['interior_construction']]
|
|
738
|
+
if 'skylight_construction' in data['aperture_set'] and \
|
|
739
|
+
data['aperture_set']['skylight_construction'] is not None:
|
|
740
|
+
sub_set.skylight_construction = \
|
|
741
|
+
constructions[data['aperture_set']['skylight_construction']]
|
|
742
|
+
if 'operable_construction' in data['aperture_set'] and \
|
|
743
|
+
data['aperture_set']['operable_construction'] is not None:
|
|
744
|
+
sub_set.operable_construction = \
|
|
745
|
+
constructions[data['aperture_set']['operable_construction']]
|
|
746
|
+
return sub_set
|
|
747
|
+
|
|
748
|
+
@staticmethod
|
|
749
|
+
def _make_door_subset(data, sub_set, constructions):
|
|
750
|
+
"""Make a DoorConstructionSet from dictionary."""
|
|
751
|
+
if 'door_set' in data:
|
|
752
|
+
if 'exterior_construction' in data['door_set'] and \
|
|
753
|
+
data['door_set']['exterior_construction'] is not None:
|
|
754
|
+
sub_set.exterior_construction = \
|
|
755
|
+
constructions[data['door_set']['exterior_construction']]
|
|
756
|
+
if 'interior_construction' in data['door_set'] and \
|
|
757
|
+
data['door_set']['interior_construction'] is not None:
|
|
758
|
+
sub_set.interior_construction = \
|
|
759
|
+
constructions[data['door_set']['interior_construction']]
|
|
760
|
+
if 'exterior_glass_construction' in data['door_set'] and \
|
|
761
|
+
data['door_set']['exterior_glass_construction'] is not None:
|
|
762
|
+
sub_set.exterior_glass_construction = \
|
|
763
|
+
constructions[data['door_set']['exterior_glass_construction']]
|
|
764
|
+
if 'interior_glass_construction' in data['door_set'] and \
|
|
765
|
+
data['door_set']['interior_glass_construction'] is not None:
|
|
766
|
+
sub_set.interior_glass_construction = \
|
|
767
|
+
constructions[data['door_set']['interior_glass_construction']]
|
|
768
|
+
if 'overhead_construction' in data['door_set'] and \
|
|
769
|
+
data['door_set']['overhead_construction'] is not None:
|
|
770
|
+
sub_set.overhead_construction = \
|
|
771
|
+
constructions[data['door_set']['overhead_construction']]
|
|
772
|
+
return sub_set
|
|
773
|
+
|
|
774
|
+
def ToString(self):
|
|
775
|
+
"""Overwrite .NET ToString."""
|
|
776
|
+
return self.__repr__()
|
|
777
|
+
|
|
778
|
+
def __copy__(self):
|
|
779
|
+
new_obj = ConstructionSet(self.identifier,
|
|
780
|
+
self.wall_set.duplicate(),
|
|
781
|
+
self.floor_set.duplicate(),
|
|
782
|
+
self.roof_ceiling_set.duplicate(),
|
|
783
|
+
self.aperture_set.duplicate(),
|
|
784
|
+
self.door_set.duplicate(),
|
|
785
|
+
self._shade_construction,
|
|
786
|
+
self._air_boundary_construction)
|
|
787
|
+
new_obj._display_name = self._display_name
|
|
788
|
+
new_obj.user_data = None if self._user_data is None else self._user_data.copy()
|
|
789
|
+
return new_obj
|
|
790
|
+
|
|
791
|
+
def __key(self):
|
|
792
|
+
"""A tuple based on the object properties, useful for hashing."""
|
|
793
|
+
return (self.identifier,) + tuple(hash(cnstr) for cnstr in self.constructions)
|
|
794
|
+
|
|
795
|
+
def __hash__(self):
|
|
796
|
+
return hash(self.__key())
|
|
797
|
+
|
|
798
|
+
def __eq__(self, other):
|
|
799
|
+
return isinstance(other, ConstructionSet) and self.__key() == other.__key()
|
|
800
|
+
|
|
801
|
+
def __ne__(self, other):
|
|
802
|
+
return not self.__eq__(other)
|
|
803
|
+
|
|
804
|
+
def __repr__(self):
|
|
805
|
+
return 'Energy Construction Set: {}'.format(self.display_name)
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
@lockable
|
|
809
|
+
class _FaceSetBase(object):
|
|
810
|
+
"""Base class for the sets assigned to Faces.
|
|
811
|
+
|
|
812
|
+
This includesWallConstructionSet, FloorConstructionSet, and the
|
|
813
|
+
RoofCeilingConstructionSet.
|
|
814
|
+
|
|
815
|
+
Args:
|
|
816
|
+
exterior_construction: An OpaqueConstruction object for faces with an
|
|
817
|
+
Outdoors boundary condition.
|
|
818
|
+
interior_construction: An OpaqueConstruction object for faces with a
|
|
819
|
+
Surface or Adiabatic boundary condition.
|
|
820
|
+
ground_construction: : An OpaqueConstruction object for faces with a
|
|
821
|
+
Ground boundary condition.
|
|
822
|
+
"""
|
|
823
|
+
|
|
824
|
+
__slots__ = ('_exterior_construction', '_interior_construction',
|
|
825
|
+
'_ground_construction', '_locked')
|
|
826
|
+
|
|
827
|
+
def __init__(self, exterior_construction=None, interior_construction=None,
|
|
828
|
+
ground_construction=None):
|
|
829
|
+
"""Initialize set."""
|
|
830
|
+
self._locked = False # unlocked by default
|
|
831
|
+
self.exterior_construction = exterior_construction
|
|
832
|
+
self.interior_construction = interior_construction
|
|
833
|
+
self.ground_construction = ground_construction
|
|
834
|
+
|
|
835
|
+
@property
|
|
836
|
+
def exterior_construction(self):
|
|
837
|
+
"""Get or set the OpaqueConstruction for exterior Faces."""
|
|
838
|
+
return self._exterior_construction
|
|
839
|
+
|
|
840
|
+
@exterior_construction.setter
|
|
841
|
+
def exterior_construction(self, value):
|
|
842
|
+
self._exterior_construction = value
|
|
843
|
+
|
|
844
|
+
@property
|
|
845
|
+
def interior_construction(self):
|
|
846
|
+
"""Get or set the OpaqueConstruction for interior Faces."""
|
|
847
|
+
return self._interior_construction
|
|
848
|
+
|
|
849
|
+
@interior_construction.setter
|
|
850
|
+
def interior_construction(self, value):
|
|
851
|
+
self._interior_construction = value
|
|
852
|
+
|
|
853
|
+
@property
|
|
854
|
+
def ground_construction(self):
|
|
855
|
+
"""Get or set the OpaqueConstruction for underground Faces."""
|
|
856
|
+
return self._ground_construction
|
|
857
|
+
|
|
858
|
+
@ground_construction.setter
|
|
859
|
+
def ground_construction(self, value):
|
|
860
|
+
self._ground_construction = value
|
|
861
|
+
|
|
862
|
+
@property
|
|
863
|
+
def constructions(self):
|
|
864
|
+
"""List of all constructions contained within the set."""
|
|
865
|
+
return [self.exterior_construction,
|
|
866
|
+
self.interior_construction,
|
|
867
|
+
self.ground_construction]
|
|
868
|
+
|
|
869
|
+
@property
|
|
870
|
+
def modified_constructions(self):
|
|
871
|
+
"""List of all constructions that are not defaulted within the set."""
|
|
872
|
+
constructions = []
|
|
873
|
+
if self._exterior_construction is not None:
|
|
874
|
+
constructions.append(self._exterior_construction)
|
|
875
|
+
if self._interior_construction is not None:
|
|
876
|
+
constructions.append(self._interior_construction)
|
|
877
|
+
if self._ground_construction is not None:
|
|
878
|
+
constructions.append(self._ground_construction)
|
|
879
|
+
return constructions
|
|
880
|
+
|
|
881
|
+
@property
|
|
882
|
+
def is_modified(self):
|
|
883
|
+
"""Boolean noting whether any constructions are modified from the default."""
|
|
884
|
+
return self._exterior_construction is not None or \
|
|
885
|
+
self._interior_construction is not None or \
|
|
886
|
+
self._ground_construction is not None
|
|
887
|
+
|
|
888
|
+
@classmethod
|
|
889
|
+
def from_dict(cls, data):
|
|
890
|
+
"""Create a SubSet from a dictionary.
|
|
891
|
+
|
|
892
|
+
Note that the dictionary must be a non-abridged version for this
|
|
893
|
+
classmethod to work.
|
|
894
|
+
|
|
895
|
+
Args:
|
|
896
|
+
data: Dictionary describing the Set of the object.
|
|
897
|
+
"""
|
|
898
|
+
assert data['type'] == cls.__name__, \
|
|
899
|
+
'Expected {}. Got {}.'.format(cls.__name__, data['type'])
|
|
900
|
+
extc = OpaqueConstruction.from_dict(data['exterior_construction']) \
|
|
901
|
+
if 'exterior_construction' in data and data['exterior_construction'] \
|
|
902
|
+
is not None else None
|
|
903
|
+
intc = OpaqueConstruction.from_dict(data['interior_construction']) \
|
|
904
|
+
if 'interior_construction' in data and data['interior_construction'] \
|
|
905
|
+
is not None else None
|
|
906
|
+
gndc = OpaqueConstruction.from_dict(data['ground_construction']) \
|
|
907
|
+
if 'ground_construction' in data and data['ground_construction'] \
|
|
908
|
+
is not None else None
|
|
909
|
+
return cls(extc, intc, gndc)
|
|
910
|
+
|
|
911
|
+
def to_dict(self, abridged=False, none_for_defaults=True):
|
|
912
|
+
"""Get the Set as a dictionary.
|
|
913
|
+
|
|
914
|
+
Args:
|
|
915
|
+
abridged: Boolean noting whether detailed materials and construction
|
|
916
|
+
objects should be written into the ConstructionSet (False) or just
|
|
917
|
+
an abridged version (True). Default: False.
|
|
918
|
+
none_for_defaults: Boolean to note whether default constructions in the
|
|
919
|
+
set should be included in detail (False) or should be None (True).
|
|
920
|
+
Default: True.
|
|
921
|
+
"""
|
|
922
|
+
base = {'type': self.__class__.__name__ + 'Abridged'} if abridged else \
|
|
923
|
+
{'type': self.__class__.__name__}
|
|
924
|
+
if none_for_defaults:
|
|
925
|
+
if abridged:
|
|
926
|
+
base['exterior_construction'] = self._exterior_construction.identifier \
|
|
927
|
+
if self._exterior_construction is not None else None
|
|
928
|
+
base['interior_construction'] = self._interior_construction.identifier \
|
|
929
|
+
if self._interior_construction is not None else None
|
|
930
|
+
base['ground_construction'] = self._ground_construction.identifier \
|
|
931
|
+
if self._ground_construction is not None else None
|
|
932
|
+
else:
|
|
933
|
+
base['exterior_construction'] = self._exterior_construction.to_dict() \
|
|
934
|
+
if self._exterior_construction is not None else None
|
|
935
|
+
base['interior_construction'] = self._interior_construction.to_dict() \
|
|
936
|
+
if self._interior_construction is not None else None
|
|
937
|
+
base['ground_construction'] = self._ground_construction.to_dict() \
|
|
938
|
+
if self._ground_construction is not None else None
|
|
939
|
+
else:
|
|
940
|
+
base['exterior_construction'] = self.exterior_construction.identifier \
|
|
941
|
+
if abridged else self.exterior_construction.to_dict()
|
|
942
|
+
base['interior_construction'] = self.interior_construction.identifier \
|
|
943
|
+
if abridged else self.exterior_construction.to_dict()
|
|
944
|
+
base['ground_construction'] = self.ground_construction.identifier \
|
|
945
|
+
if abridged else self.exterior_construction.to_dict()
|
|
946
|
+
return base
|
|
947
|
+
|
|
948
|
+
def duplicate(self):
|
|
949
|
+
"""Get a copy of this set."""
|
|
950
|
+
return self.__copy__()
|
|
951
|
+
|
|
952
|
+
def _check_construction(self, value):
|
|
953
|
+
"""Check an OpaqueConstruction before assigning it."""
|
|
954
|
+
assert isinstance(value, OpaqueConstruction), \
|
|
955
|
+
'Expected OpaqueConstruction. Got {}'.format(type(value))
|
|
956
|
+
value.lock() # lock editing in case construction has multiple references
|
|
957
|
+
|
|
958
|
+
def ToString(self):
|
|
959
|
+
"""Overwrite .NET ToString."""
|
|
960
|
+
return self.__repr__()
|
|
961
|
+
|
|
962
|
+
def __len__(self):
|
|
963
|
+
return 3
|
|
964
|
+
|
|
965
|
+
def __iter__(self):
|
|
966
|
+
return iter(self.constructions)
|
|
967
|
+
|
|
968
|
+
def __copy__(self):
|
|
969
|
+
new_obj = self.__class__(
|
|
970
|
+
self._exterior_construction, self._interior_construction,
|
|
971
|
+
self._ground_construction)
|
|
972
|
+
return new_obj
|
|
973
|
+
|
|
974
|
+
def __repr__(self):
|
|
975
|
+
return 'Base Face Set'
|
|
976
|
+
|
|
977
|
+
|
|
978
|
+
@lockable
|
|
979
|
+
class WallConstructionSet(_FaceSetBase):
|
|
980
|
+
"""Set containing all energy constructions needed to for an energy model's Walls.
|
|
981
|
+
|
|
982
|
+
Properties:
|
|
983
|
+
* exterior_construction
|
|
984
|
+
* interior_construction
|
|
985
|
+
* ground_construction
|
|
986
|
+
* constructions
|
|
987
|
+
* modified_constructions
|
|
988
|
+
* is_modified
|
|
989
|
+
"""
|
|
990
|
+
__slots__ = ()
|
|
991
|
+
|
|
992
|
+
@property
|
|
993
|
+
def exterior_construction(self):
|
|
994
|
+
"""Get or set the OpaqueConstruction for exterior walls."""
|
|
995
|
+
if self._exterior_construction is None:
|
|
996
|
+
return _lib.generic_exterior_wall
|
|
997
|
+
return self._exterior_construction
|
|
998
|
+
|
|
999
|
+
@exterior_construction.setter
|
|
1000
|
+
def exterior_construction(self, value):
|
|
1001
|
+
if value is not None:
|
|
1002
|
+
self._check_construction(value)
|
|
1003
|
+
self._exterior_construction = value
|
|
1004
|
+
|
|
1005
|
+
@property
|
|
1006
|
+
def interior_construction(self):
|
|
1007
|
+
"""Get or set the OpaqueConstruction for interior walls."""
|
|
1008
|
+
if self._interior_construction is None:
|
|
1009
|
+
return _lib.generic_interior_wall
|
|
1010
|
+
return self._interior_construction
|
|
1011
|
+
|
|
1012
|
+
@interior_construction.setter
|
|
1013
|
+
def interior_construction(self, value):
|
|
1014
|
+
if value is not None:
|
|
1015
|
+
self._check_construction(value)
|
|
1016
|
+
self._interior_construction = value
|
|
1017
|
+
|
|
1018
|
+
@property
|
|
1019
|
+
def ground_construction(self):
|
|
1020
|
+
"""Get or set the OpaqueConstruction for underground walls."""
|
|
1021
|
+
if self._ground_construction is None:
|
|
1022
|
+
return _lib.generic_underground_wall
|
|
1023
|
+
return self._ground_construction
|
|
1024
|
+
|
|
1025
|
+
@ground_construction.setter
|
|
1026
|
+
def ground_construction(self, value):
|
|
1027
|
+
if value is not None:
|
|
1028
|
+
self._check_construction(value)
|
|
1029
|
+
self._ground_construction = value
|
|
1030
|
+
|
|
1031
|
+
def __repr__(self):
|
|
1032
|
+
return 'Wall Construction Set: [Exterior: {}] [Interior: {}]' \
|
|
1033
|
+
' [Ground: {}]'.format(self.exterior_construction.display_name,
|
|
1034
|
+
self.interior_construction.display_name,
|
|
1035
|
+
self.ground_construction.display_name)
|
|
1036
|
+
|
|
1037
|
+
|
|
1038
|
+
@lockable
|
|
1039
|
+
class FloorConstructionSet(_FaceSetBase):
|
|
1040
|
+
"""Set containing all energy constructions needed to for an energy model's Floors.
|
|
1041
|
+
|
|
1042
|
+
Properties:
|
|
1043
|
+
* exterior_construction
|
|
1044
|
+
* interior_construction
|
|
1045
|
+
* ground_construction
|
|
1046
|
+
* constructions
|
|
1047
|
+
* modified_constructions
|
|
1048
|
+
* is_modified
|
|
1049
|
+
"""
|
|
1050
|
+
__slots__ = ()
|
|
1051
|
+
|
|
1052
|
+
@property
|
|
1053
|
+
def exterior_construction(self):
|
|
1054
|
+
"""Get or set the OpaqueConstruction for exterior-exposed floors."""
|
|
1055
|
+
if self._exterior_construction is None:
|
|
1056
|
+
return _lib.generic_exposed_floor
|
|
1057
|
+
return self._exterior_construction
|
|
1058
|
+
|
|
1059
|
+
@exterior_construction.setter
|
|
1060
|
+
def exterior_construction(self, value):
|
|
1061
|
+
if value is not None:
|
|
1062
|
+
self._check_construction(value)
|
|
1063
|
+
self._exterior_construction = value
|
|
1064
|
+
|
|
1065
|
+
@property
|
|
1066
|
+
def interior_construction(self):
|
|
1067
|
+
"""Get or set the OpaqueConstruction for interior floors."""
|
|
1068
|
+
if self._interior_construction is None:
|
|
1069
|
+
return _lib.generic_interior_floor
|
|
1070
|
+
return self._interior_construction
|
|
1071
|
+
|
|
1072
|
+
@interior_construction.setter
|
|
1073
|
+
def interior_construction(self, value):
|
|
1074
|
+
if value is not None:
|
|
1075
|
+
self._check_construction(value)
|
|
1076
|
+
self._interior_construction = value
|
|
1077
|
+
|
|
1078
|
+
@property
|
|
1079
|
+
def ground_construction(self):
|
|
1080
|
+
"""Get or set the OpaqueConstruction for ground-contact floor slabs."""
|
|
1081
|
+
if self._ground_construction is None:
|
|
1082
|
+
return _lib.generic_ground_slab
|
|
1083
|
+
return self._ground_construction
|
|
1084
|
+
|
|
1085
|
+
@ground_construction.setter
|
|
1086
|
+
def ground_construction(self, value):
|
|
1087
|
+
if value is not None:
|
|
1088
|
+
self._check_construction(value)
|
|
1089
|
+
self._ground_construction = value
|
|
1090
|
+
|
|
1091
|
+
def __repr__(self):
|
|
1092
|
+
return 'Floor Construction Set: [Exterior: {}] [Interior: {}]' \
|
|
1093
|
+
' [Ground: {}]'.format(self.exterior_construction.display_name,
|
|
1094
|
+
self.interior_construction.display_name,
|
|
1095
|
+
self.ground_construction.display_name)
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
@lockable
|
|
1099
|
+
class RoofCeilingConstructionSet(_FaceSetBase):
|
|
1100
|
+
"""Set containing all energy constructions needed to for an energy model's Roofs.
|
|
1101
|
+
|
|
1102
|
+
Properties:
|
|
1103
|
+
* exterior_construction
|
|
1104
|
+
* interior_construction
|
|
1105
|
+
* ground_construction
|
|
1106
|
+
* constructions
|
|
1107
|
+
* modified_constructions
|
|
1108
|
+
* is_modified
|
|
1109
|
+
"""
|
|
1110
|
+
__slots__ = ()
|
|
1111
|
+
|
|
1112
|
+
@property
|
|
1113
|
+
def exterior_construction(self):
|
|
1114
|
+
"""Get or set the OpaqueConstruction for exterior roofs."""
|
|
1115
|
+
if self._exterior_construction is None:
|
|
1116
|
+
return _lib.generic_roof
|
|
1117
|
+
return self._exterior_construction
|
|
1118
|
+
|
|
1119
|
+
@exterior_construction.setter
|
|
1120
|
+
def exterior_construction(self, value):
|
|
1121
|
+
if value is not None:
|
|
1122
|
+
self._check_construction(value)
|
|
1123
|
+
self._exterior_construction = value
|
|
1124
|
+
|
|
1125
|
+
@property
|
|
1126
|
+
def interior_construction(self):
|
|
1127
|
+
"""Get or set the OpaqueConstruction for interior ceilings."""
|
|
1128
|
+
if self._interior_construction is None:
|
|
1129
|
+
return _lib.generic_interior_ceiling
|
|
1130
|
+
return self._interior_construction
|
|
1131
|
+
|
|
1132
|
+
@interior_construction.setter
|
|
1133
|
+
def interior_construction(self, value):
|
|
1134
|
+
if value is not None:
|
|
1135
|
+
self._check_construction(value)
|
|
1136
|
+
self._interior_construction = value
|
|
1137
|
+
|
|
1138
|
+
@property
|
|
1139
|
+
def ground_construction(self):
|
|
1140
|
+
"""Get or set the OpaqueConstruction for underground roofs."""
|
|
1141
|
+
if self._ground_construction is None:
|
|
1142
|
+
return _lib.generic_underground_roof
|
|
1143
|
+
return self._ground_construction
|
|
1144
|
+
|
|
1145
|
+
@ground_construction.setter
|
|
1146
|
+
def ground_construction(self, value):
|
|
1147
|
+
if value is not None:
|
|
1148
|
+
self._check_construction(value)
|
|
1149
|
+
self._ground_construction = value
|
|
1150
|
+
|
|
1151
|
+
def __repr__(self):
|
|
1152
|
+
return 'RoofCeiling Construction Set: [Exterior: {}] [Interior: {}]' \
|
|
1153
|
+
' [Ground: {}]'.format(self.exterior_construction.display_name,
|
|
1154
|
+
self.interior_construction.display_name,
|
|
1155
|
+
self.ground_construction.display_name)
|
|
1156
|
+
|
|
1157
|
+
|
|
1158
|
+
@lockable
|
|
1159
|
+
class ApertureConstructionSet(object):
|
|
1160
|
+
"""Set containing all constructions needed to for an energy model's Apertures.
|
|
1161
|
+
|
|
1162
|
+
Args:
|
|
1163
|
+
window_construction: A WindowConstruction object for apertures
|
|
1164
|
+
with an Outdoors boundary condition, False is_operable property,
|
|
1165
|
+
and a Wall face type for their parent face.
|
|
1166
|
+
interior_construction: A WindowConstruction object for all apertures
|
|
1167
|
+
with a Surface boundary condition.
|
|
1168
|
+
skylight_construction: : A WindowConstruction object for apertures with a
|
|
1169
|
+
Outdoors boundary condition, False is_operable property, and a
|
|
1170
|
+
RoofCeiling or Floor face type for their parent face.
|
|
1171
|
+
operable_construction: A WindowConstruction object for all apertures
|
|
1172
|
+
with an Outdoors boundary condition and True is_operable property.
|
|
1173
|
+
|
|
1174
|
+
Properties:
|
|
1175
|
+
* window_construction
|
|
1176
|
+
* interior_construction
|
|
1177
|
+
* skylight_construction
|
|
1178
|
+
* operable_construction
|
|
1179
|
+
* constructions
|
|
1180
|
+
* modified_constructions
|
|
1181
|
+
* is_modified
|
|
1182
|
+
"""
|
|
1183
|
+
__slots__ = ('_window_construction', '_interior_construction',
|
|
1184
|
+
'_skylight_construction', '_operable_construction', '_locked')
|
|
1185
|
+
|
|
1186
|
+
def __init__(self, window_construction=None, interior_construction=None,
|
|
1187
|
+
skylight_construction=None, operable_construction=None):
|
|
1188
|
+
"""Initialize aperture set."""
|
|
1189
|
+
self._locked = False # unlocked by default
|
|
1190
|
+
self.window_construction = window_construction
|
|
1191
|
+
self.interior_construction = interior_construction
|
|
1192
|
+
self.skylight_construction = skylight_construction
|
|
1193
|
+
self.operable_construction = operable_construction
|
|
1194
|
+
|
|
1195
|
+
@property
|
|
1196
|
+
def window_construction(self):
|
|
1197
|
+
"""Get or set the WindowConstruction for exterior fixed windows in walls."""
|
|
1198
|
+
if self._window_construction is None:
|
|
1199
|
+
return _lib.generic_double_pane
|
|
1200
|
+
return self._window_construction
|
|
1201
|
+
|
|
1202
|
+
@window_construction.setter
|
|
1203
|
+
def window_construction(self, value):
|
|
1204
|
+
if value is not None:
|
|
1205
|
+
self._check_window_construction(value)
|
|
1206
|
+
self._window_construction = value
|
|
1207
|
+
|
|
1208
|
+
@property
|
|
1209
|
+
def interior_construction(self):
|
|
1210
|
+
"""Get or set the WindowConstruction for all interior apertures."""
|
|
1211
|
+
if self._interior_construction is None:
|
|
1212
|
+
return _lib.generic_single_pane
|
|
1213
|
+
return self._interior_construction
|
|
1214
|
+
|
|
1215
|
+
@interior_construction.setter
|
|
1216
|
+
def interior_construction(self, value):
|
|
1217
|
+
if value is not None:
|
|
1218
|
+
self._check_window_construction(value)
|
|
1219
|
+
self._interior_construction = value
|
|
1220
|
+
|
|
1221
|
+
@property
|
|
1222
|
+
def skylight_construction(self):
|
|
1223
|
+
"""Get or set the WindowConstruction for exterior fixed windows in roofs."""
|
|
1224
|
+
if self._skylight_construction is None:
|
|
1225
|
+
return _lib.generic_double_pane
|
|
1226
|
+
return self._skylight_construction
|
|
1227
|
+
|
|
1228
|
+
@skylight_construction.setter
|
|
1229
|
+
def skylight_construction(self, value):
|
|
1230
|
+
if value is not None:
|
|
1231
|
+
self._check_window_construction(value)
|
|
1232
|
+
self._skylight_construction = value
|
|
1233
|
+
|
|
1234
|
+
@property
|
|
1235
|
+
def operable_construction(self):
|
|
1236
|
+
"""Get or set the WindowConstruction for all exterior operable windows."""
|
|
1237
|
+
if self._operable_construction is None:
|
|
1238
|
+
return _lib.generic_double_pane
|
|
1239
|
+
return self._operable_construction
|
|
1240
|
+
|
|
1241
|
+
@operable_construction.setter
|
|
1242
|
+
def operable_construction(self, value):
|
|
1243
|
+
if value is not None:
|
|
1244
|
+
self._check_window_construction(value)
|
|
1245
|
+
self._operable_construction = value
|
|
1246
|
+
|
|
1247
|
+
@property
|
|
1248
|
+
def constructions(self):
|
|
1249
|
+
"""List of all constructions contained within the set."""
|
|
1250
|
+
return [self.window_construction,
|
|
1251
|
+
self.interior_construction,
|
|
1252
|
+
self.skylight_construction,
|
|
1253
|
+
self.operable_construction]
|
|
1254
|
+
|
|
1255
|
+
@property
|
|
1256
|
+
def modified_constructions(self):
|
|
1257
|
+
"""List of all constructions that are not defaulted within the set."""
|
|
1258
|
+
constructions = []
|
|
1259
|
+
if self._window_construction is not None:
|
|
1260
|
+
constructions.append(self._window_construction)
|
|
1261
|
+
if self._interior_construction is not None:
|
|
1262
|
+
constructions.append(self._interior_construction)
|
|
1263
|
+
if self._skylight_construction is not None:
|
|
1264
|
+
constructions.append(self._skylight_construction)
|
|
1265
|
+
if self._operable_construction is not None:
|
|
1266
|
+
constructions.append(self._operable_construction)
|
|
1267
|
+
return constructions
|
|
1268
|
+
|
|
1269
|
+
@property
|
|
1270
|
+
def is_modified(self):
|
|
1271
|
+
"""Boolean noting whether any constructions are modified from the default."""
|
|
1272
|
+
return self._window_construction is not None or \
|
|
1273
|
+
self._interior_construction is not None or \
|
|
1274
|
+
self._skylight_construction is not None or \
|
|
1275
|
+
self._operable_construction is not None
|
|
1276
|
+
|
|
1277
|
+
@classmethod
|
|
1278
|
+
def from_dict(cls, data):
|
|
1279
|
+
"""Create a ApertureConstructionSet from a dictionary.
|
|
1280
|
+
|
|
1281
|
+
Note that the dictionary must be a non-abridged version for this
|
|
1282
|
+
classmethod to work.
|
|
1283
|
+
|
|
1284
|
+
Args:
|
|
1285
|
+
data: Dictionary describing the Set of the object.
|
|
1286
|
+
"""
|
|
1287
|
+
assert data['type'] == 'ApertureConstructionSet', \
|
|
1288
|
+
'Expected ApertureConstructionSet. Got {}.'.format(data['type'])
|
|
1289
|
+
winc = dict_to_construction(data['window_construction']) \
|
|
1290
|
+
if 'window_construction' in data and data['window_construction'] \
|
|
1291
|
+
is not None else None
|
|
1292
|
+
intc = dict_to_construction(data['interior_construction']) \
|
|
1293
|
+
if 'interior_construction' in data and data['interior_construction'] \
|
|
1294
|
+
is not None else None
|
|
1295
|
+
skyc = dict_to_construction(data['skylight_construction']) \
|
|
1296
|
+
if 'skylight_construction' in data and data['skylight_construction'] \
|
|
1297
|
+
is not None else None
|
|
1298
|
+
opc = dict_to_construction(data['operable_construction'])\
|
|
1299
|
+
if 'operable_construction' in data and data['operable_construction'] \
|
|
1300
|
+
is not None else None
|
|
1301
|
+
return cls(winc, intc, skyc, opc)
|
|
1302
|
+
|
|
1303
|
+
def to_dict(self, abridged=False, none_for_defaults=True):
|
|
1304
|
+
"""Get ApertureConstructionSet as a dictionary.
|
|
1305
|
+
|
|
1306
|
+
Args:
|
|
1307
|
+
abridged: Boolean noting whether detailed materials and construction
|
|
1308
|
+
objects should be written into the ConstructionSet (False) or just
|
|
1309
|
+
an abridged version (True). Default: False.
|
|
1310
|
+
none_for_defaults: Boolean to note whether default constructions in the
|
|
1311
|
+
set should be included in detail (False) or should be None (True).
|
|
1312
|
+
Default: True.
|
|
1313
|
+
"""
|
|
1314
|
+
base = {'type': 'ApertureConstructionSetAbridged'} if abridged \
|
|
1315
|
+
else {'type': 'ApertureConstructionSet'}
|
|
1316
|
+
if none_for_defaults:
|
|
1317
|
+
if abridged:
|
|
1318
|
+
base['window_construction'] = self._window_construction.identifier if \
|
|
1319
|
+
self._window_construction is not None else None
|
|
1320
|
+
base['interior_construction'] = \
|
|
1321
|
+
self._interior_construction.identifier if \
|
|
1322
|
+
self._interior_construction is not None else None
|
|
1323
|
+
base['skylight_construction'] = \
|
|
1324
|
+
self._skylight_construction.identifier if \
|
|
1325
|
+
self._skylight_construction is not None else None
|
|
1326
|
+
base['operable_construction'] = \
|
|
1327
|
+
self._operable_construction.identifier if \
|
|
1328
|
+
self._operable_construction is not None else None
|
|
1329
|
+
else:
|
|
1330
|
+
base['window_construction'] = self._window_construction.to_dict() \
|
|
1331
|
+
if self._window_construction is not None else None
|
|
1332
|
+
base['interior_construction'] = self._interior_construction.to_dict() \
|
|
1333
|
+
if self._interior_construction is not None else None
|
|
1334
|
+
base['skylight_construction'] = self._skylight_construction.to_dict() \
|
|
1335
|
+
if self._skylight_construction is not None else None
|
|
1336
|
+
base['operable_construction'] = \
|
|
1337
|
+
self._operable_construction.to_dict() if \
|
|
1338
|
+
self._operable_construction is not None else None
|
|
1339
|
+
else:
|
|
1340
|
+
base['window_construction'] = self.window_construction.identifier if \
|
|
1341
|
+
abridged else self.window_construction.to_dict()
|
|
1342
|
+
base['interior_construction'] = self.interior_construction.identifier if \
|
|
1343
|
+
abridged else self.interior_construction.to_dict()
|
|
1344
|
+
base['skylight_construction'] = self.skylight_construction.identifier if \
|
|
1345
|
+
abridged else self.skylight_construction.to_dict()
|
|
1346
|
+
base['operable_construction'] = self.operable_construction.identifier if \
|
|
1347
|
+
abridged else self.operable_construction.to_dict()
|
|
1348
|
+
return base
|
|
1349
|
+
|
|
1350
|
+
def duplicate(self):
|
|
1351
|
+
"""Get a copy of this set."""
|
|
1352
|
+
return self.__copy__()
|
|
1353
|
+
|
|
1354
|
+
def _check_window_construction(self, value):
|
|
1355
|
+
"""Check that a construction is valid before assigning it."""
|
|
1356
|
+
val_w = (WindowConstruction, WindowConstructionShade, WindowConstructionDynamic)
|
|
1357
|
+
assert isinstance(value, val_w), \
|
|
1358
|
+
'Expected Window Construction. Got {}'.format(type(value))
|
|
1359
|
+
value.lock() # lock editing in case construction has multiple references
|
|
1360
|
+
|
|
1361
|
+
def ToString(self):
|
|
1362
|
+
"""Overwrite .NET ToString."""
|
|
1363
|
+
return self.__repr__()
|
|
1364
|
+
|
|
1365
|
+
def __len__(self):
|
|
1366
|
+
return 4
|
|
1367
|
+
|
|
1368
|
+
def __iter__(self):
|
|
1369
|
+
return iter(self.constructions)
|
|
1370
|
+
|
|
1371
|
+
def __copy__(self):
|
|
1372
|
+
new_obj = self.__class__(
|
|
1373
|
+
self._window_construction, self._interior_construction,
|
|
1374
|
+
self._skylight_construction, self._operable_construction
|
|
1375
|
+
)
|
|
1376
|
+
return new_obj
|
|
1377
|
+
|
|
1378
|
+
def __repr__(self):
|
|
1379
|
+
return 'Aperture Construction Set: [Window: {}] [Interior: {}]' \
|
|
1380
|
+
' [Skylight: {}] [Operable: {}]'.format(
|
|
1381
|
+
self.window_construction.display_name,
|
|
1382
|
+
self.interior_construction.display_name,
|
|
1383
|
+
self.skylight_construction.display_name,
|
|
1384
|
+
self.operable_construction.display_name)
|
|
1385
|
+
|
|
1386
|
+
|
|
1387
|
+
@lockable
|
|
1388
|
+
class DoorConstructionSet(object):
|
|
1389
|
+
"""Set containing all energy constructions needed to for an energy model's Roofs.
|
|
1390
|
+
|
|
1391
|
+
Args:
|
|
1392
|
+
exterior_construction: An OpaqueConstruction object for opaque doors with an
|
|
1393
|
+
Outdoors boundary condition and a Wall face type for their parent face.
|
|
1394
|
+
interior_construction: An OpaqueConstruction object for all opaque doors
|
|
1395
|
+
with a Surface boundary condition.
|
|
1396
|
+
exterior_glass_construction: A WindowConstruction object for all glass
|
|
1397
|
+
doors with an Outdoors boundary condition.
|
|
1398
|
+
interior_glass_construction: A WindowConstruction object for all glass
|
|
1399
|
+
doors with a Surface boundary condition.
|
|
1400
|
+
overhead_construction: An OpaqueConstruction object for opaque doors with
|
|
1401
|
+
an Outdoors boundary condition and a RoofCeiling or Floor face type for
|
|
1402
|
+
their parent face.
|
|
1403
|
+
|
|
1404
|
+
Properties:
|
|
1405
|
+
* exterior_construction
|
|
1406
|
+
* interior_construction
|
|
1407
|
+
* exterior_glass_construction
|
|
1408
|
+
* interior_glass_construction
|
|
1409
|
+
* overhead_construction
|
|
1410
|
+
* constructions
|
|
1411
|
+
* modified_constructions
|
|
1412
|
+
* is_modified
|
|
1413
|
+
"""
|
|
1414
|
+
__slots__ = ('_exterior_construction', '_interior_construction',
|
|
1415
|
+
'_exterior_glass_construction', '_interior_glass_construction',
|
|
1416
|
+
'_overhead_construction', '_locked')
|
|
1417
|
+
|
|
1418
|
+
def __init__(self, exterior_construction=None, interior_construction=None,
|
|
1419
|
+
exterior_glass_construction=None, interior_glass_construction=None,
|
|
1420
|
+
overhead_construction=None):
|
|
1421
|
+
"""Initialize door set."""
|
|
1422
|
+
self._locked = False # unlocked by default
|
|
1423
|
+
self.exterior_construction = exterior_construction
|
|
1424
|
+
self.interior_construction = interior_construction
|
|
1425
|
+
self.exterior_glass_construction = exterior_glass_construction
|
|
1426
|
+
self.interior_glass_construction = interior_glass_construction
|
|
1427
|
+
self.overhead_construction = overhead_construction
|
|
1428
|
+
|
|
1429
|
+
@property
|
|
1430
|
+
def exterior_construction(self):
|
|
1431
|
+
"""Get or set the OpaqueConstruction for exterior opaque doors in walls."""
|
|
1432
|
+
if self._exterior_construction is None:
|
|
1433
|
+
return _lib.generic_exterior_door
|
|
1434
|
+
return self._exterior_construction
|
|
1435
|
+
|
|
1436
|
+
@exterior_construction.setter
|
|
1437
|
+
def exterior_construction(self, value):
|
|
1438
|
+
if value is not None:
|
|
1439
|
+
self._check_construction(value)
|
|
1440
|
+
self._exterior_construction = value
|
|
1441
|
+
|
|
1442
|
+
@property
|
|
1443
|
+
def interior_construction(self):
|
|
1444
|
+
"""Get or set the OpaqueConstruction for all interior opaque doors."""
|
|
1445
|
+
if self._interior_construction is None:
|
|
1446
|
+
return _lib.generic_interior_door
|
|
1447
|
+
return self._interior_construction
|
|
1448
|
+
|
|
1449
|
+
@interior_construction.setter
|
|
1450
|
+
def interior_construction(self, value):
|
|
1451
|
+
if value is not None:
|
|
1452
|
+
self._check_construction(value)
|
|
1453
|
+
self._interior_construction = value
|
|
1454
|
+
|
|
1455
|
+
@property
|
|
1456
|
+
def exterior_glass_construction(self):
|
|
1457
|
+
"""Get or set the WindowConstruction for exterior glass doors."""
|
|
1458
|
+
if self._exterior_glass_construction is None:
|
|
1459
|
+
return _lib.generic_double_pane
|
|
1460
|
+
return self._exterior_glass_construction
|
|
1461
|
+
|
|
1462
|
+
@exterior_glass_construction.setter
|
|
1463
|
+
def exterior_glass_construction(self, value):
|
|
1464
|
+
if value is not None:
|
|
1465
|
+
self._check_window_construction(value)
|
|
1466
|
+
self._exterior_glass_construction = value
|
|
1467
|
+
|
|
1468
|
+
@property
|
|
1469
|
+
def interior_glass_construction(self):
|
|
1470
|
+
"""Get or set the WindowConstruction for all interior glass doors."""
|
|
1471
|
+
if self._interior_glass_construction is None:
|
|
1472
|
+
return _lib.generic_single_pane
|
|
1473
|
+
return self._interior_glass_construction
|
|
1474
|
+
|
|
1475
|
+
@interior_glass_construction.setter
|
|
1476
|
+
def interior_glass_construction(self, value):
|
|
1477
|
+
if value is not None:
|
|
1478
|
+
self._check_window_construction(value)
|
|
1479
|
+
self._interior_glass_construction = value
|
|
1480
|
+
|
|
1481
|
+
@property
|
|
1482
|
+
def overhead_construction(self):
|
|
1483
|
+
"""Get or set the OpaqueConstruction for exterior opaque doors in roofs/floors.
|
|
1484
|
+
"""
|
|
1485
|
+
if self._overhead_construction is None:
|
|
1486
|
+
return _lib.generic_exterior_door
|
|
1487
|
+
return self._overhead_construction
|
|
1488
|
+
|
|
1489
|
+
@overhead_construction.setter
|
|
1490
|
+
def overhead_construction(self, value):
|
|
1491
|
+
if value is not None:
|
|
1492
|
+
self._check_construction(value)
|
|
1493
|
+
self._overhead_construction = value
|
|
1494
|
+
|
|
1495
|
+
@property
|
|
1496
|
+
def constructions(self):
|
|
1497
|
+
"""List of all constructions contained within the set."""
|
|
1498
|
+
return [self.exterior_construction,
|
|
1499
|
+
self.interior_construction,
|
|
1500
|
+
self.exterior_glass_construction,
|
|
1501
|
+
self.interior_glass_construction,
|
|
1502
|
+
self.overhead_construction]
|
|
1503
|
+
|
|
1504
|
+
@property
|
|
1505
|
+
def modified_constructions(self):
|
|
1506
|
+
"""List of all constructions that are not defaulted within the set."""
|
|
1507
|
+
constructions = []
|
|
1508
|
+
if self._exterior_construction is not None:
|
|
1509
|
+
constructions.append(self._exterior_construction)
|
|
1510
|
+
if self._interior_construction is not None:
|
|
1511
|
+
constructions.append(self._interior_construction)
|
|
1512
|
+
if self._exterior_glass_construction is not None:
|
|
1513
|
+
constructions.append(self._exterior_glass_construction)
|
|
1514
|
+
if self._interior_glass_construction is not None:
|
|
1515
|
+
constructions.append(self._interior_glass_construction)
|
|
1516
|
+
if self._overhead_construction is not None:
|
|
1517
|
+
constructions.append(self._overhead_construction)
|
|
1518
|
+
return constructions
|
|
1519
|
+
|
|
1520
|
+
@property
|
|
1521
|
+
def is_modified(self):
|
|
1522
|
+
"""Boolean noting whether any constructions are modified from the default."""
|
|
1523
|
+
return self._exterior_construction is not None or \
|
|
1524
|
+
self._interior_construction is not None or \
|
|
1525
|
+
self._exterior_glass_construction is not None or \
|
|
1526
|
+
self._interior_glass_construction is not None or \
|
|
1527
|
+
self._overhead_construction is None
|
|
1528
|
+
|
|
1529
|
+
@classmethod
|
|
1530
|
+
def from_dict(cls, data):
|
|
1531
|
+
"""Create a DoorConstructionSet from a dictionary.
|
|
1532
|
+
|
|
1533
|
+
Note that the dictionary must be a non-abridged version for this
|
|
1534
|
+
classmethod to work.
|
|
1535
|
+
|
|
1536
|
+
Args:
|
|
1537
|
+
data: Dictionary describing the Set of the object.
|
|
1538
|
+
"""
|
|
1539
|
+
assert data['type'] == 'DoorConstructionSet', \
|
|
1540
|
+
'Expected DoorConstructionSet. Got {}.'.format(data['type'])
|
|
1541
|
+
extc = OpaqueConstruction.from_dict(data['exterior_construction']) \
|
|
1542
|
+
if 'exterior_construction' in data and data['exterior_construction'] \
|
|
1543
|
+
is not None else None
|
|
1544
|
+
intc = OpaqueConstruction.from_dict(data['interior_construction']) \
|
|
1545
|
+
if 'interior_construction' in data and data['interior_construction'] \
|
|
1546
|
+
is not None else None
|
|
1547
|
+
egc = dict_to_construction(data['exterior_glass_construction']) \
|
|
1548
|
+
if 'exterior_glass_construction' in data and \
|
|
1549
|
+
data['exterior_glass_construction'] is not None else None
|
|
1550
|
+
igc = dict_to_construction(data['interior_glass_construction']) \
|
|
1551
|
+
if 'interior_glass_construction' in data and \
|
|
1552
|
+
data['interior_glass_construction'] is not None else None
|
|
1553
|
+
ohc = OpaqueConstruction.from_dict(data['overhead_construction']) \
|
|
1554
|
+
if 'overhead_construction' in data and data['overhead_construction'] \
|
|
1555
|
+
is not None else None
|
|
1556
|
+
|
|
1557
|
+
return cls(extc, intc, egc, igc, ohc)
|
|
1558
|
+
|
|
1559
|
+
def to_dict(self, abridged=False, none_for_defaults=True):
|
|
1560
|
+
"""Get the DoorConstructionSet as a dictionary.
|
|
1561
|
+
|
|
1562
|
+
Args:
|
|
1563
|
+
abridged: Boolean noting whether detailed materials and construction
|
|
1564
|
+
objects should be written into the ConstructionSet (False) or just
|
|
1565
|
+
an abridged version (True). Default: False.
|
|
1566
|
+
none_for_defaults: Boolean to note whether default constructions in the
|
|
1567
|
+
set should be included in detail (False) or should be None (True).
|
|
1568
|
+
Default: True.
|
|
1569
|
+
"""
|
|
1570
|
+
base = {'type': 'DoorConstructionSetAbridged'} if abridged \
|
|
1571
|
+
else {'type': 'DoorConstructionSet'}
|
|
1572
|
+
if none_for_defaults:
|
|
1573
|
+
if abridged:
|
|
1574
|
+
base['exterior_construction'] = self._exterior_construction.identifier \
|
|
1575
|
+
if self._exterior_construction is not None else None
|
|
1576
|
+
base['interior_construction'] = self._interior_construction.identifier \
|
|
1577
|
+
if self._interior_construction is not None else None
|
|
1578
|
+
base['exterior_glass_construction'] = \
|
|
1579
|
+
self._exterior_glass_construction.identifier if \
|
|
1580
|
+
self._exterior_glass_construction is not None else None
|
|
1581
|
+
base['interior_glass_construction'] = \
|
|
1582
|
+
self._interior_glass_construction.identifier if \
|
|
1583
|
+
self._interior_glass_construction is not None else None
|
|
1584
|
+
base['overhead_construction'] = self._overhead_construction.identifier \
|
|
1585
|
+
if self._overhead_construction is not None else None
|
|
1586
|
+
else:
|
|
1587
|
+
base['exterior_construction'] = self._exterior_construction.to_dict() \
|
|
1588
|
+
if self._exterior_construction is not None else None
|
|
1589
|
+
base['interior_construction'] = self._interior_construction.to_dict() \
|
|
1590
|
+
if self._interior_construction is not None else None
|
|
1591
|
+
base['exterior_glass_construction'] = \
|
|
1592
|
+
self._exterior_glass_construction.to_dict() \
|
|
1593
|
+
if self._exterior_glass_construction is not None else None
|
|
1594
|
+
base['interior_glass_construction'] = \
|
|
1595
|
+
self._interior_glass_construction.to_dict() if \
|
|
1596
|
+
self._interior_glass_construction is not None else None
|
|
1597
|
+
base['overhead_construction'] = self._overhead_construction.to_dict() \
|
|
1598
|
+
if self._overhead_construction is not None else None
|
|
1599
|
+
else:
|
|
1600
|
+
base['exterior_construction'] = self.exterior_construction.identifier if \
|
|
1601
|
+
abridged else self.exterior_construction.to_dict()
|
|
1602
|
+
base['interior_construction'] = self.interior_construction.identifier if \
|
|
1603
|
+
abridged else self.interior_construction.to_dict()
|
|
1604
|
+
base['exterior_glass_construction'] = \
|
|
1605
|
+
self.exterior_glass_construction.identifier if \
|
|
1606
|
+
abridged else self.exterior_glass_construction.to_dict()
|
|
1607
|
+
base['interior_glass_construction'] = \
|
|
1608
|
+
self.interior_glass_construction.identifier if \
|
|
1609
|
+
abridged else self.interior_glass_construction.to_dict()
|
|
1610
|
+
base['overhead_construction'] = self.overhead_construction.identifier if \
|
|
1611
|
+
abridged else self.overhead_construction.to_dict()
|
|
1612
|
+
return base
|
|
1613
|
+
|
|
1614
|
+
def duplicate(self):
|
|
1615
|
+
"""Get a copy of this set."""
|
|
1616
|
+
return self.__copy__()
|
|
1617
|
+
|
|
1618
|
+
def _check_construction(self, value):
|
|
1619
|
+
"""Check an OpaqueConstruction before assigning it."""
|
|
1620
|
+
assert isinstance(value, OpaqueConstruction), \
|
|
1621
|
+
'Expected OpaqueConstruction. Got {}'.format(type(value))
|
|
1622
|
+
value.lock() # lock editing in case construction has multiple references
|
|
1623
|
+
|
|
1624
|
+
def _check_window_construction(self, value):
|
|
1625
|
+
"""Check that a construction is valid before assigning it."""
|
|
1626
|
+
val_w = (WindowConstruction, WindowConstructionShade, WindowConstructionDynamic)
|
|
1627
|
+
assert isinstance(value, val_w), \
|
|
1628
|
+
'Expected Window Construction. Got {}'.format(type(value))
|
|
1629
|
+
value.lock() # lock editing in case construction has multiple references
|
|
1630
|
+
|
|
1631
|
+
def ToString(self):
|
|
1632
|
+
"""Overwrite .NET ToString."""
|
|
1633
|
+
return self.__repr__()
|
|
1634
|
+
|
|
1635
|
+
def __len__(self):
|
|
1636
|
+
return 5
|
|
1637
|
+
|
|
1638
|
+
def __iter__(self):
|
|
1639
|
+
return iter(self.constructions)
|
|
1640
|
+
|
|
1641
|
+
def __copy__(self):
|
|
1642
|
+
new_obj = self.__class__(
|
|
1643
|
+
self._exterior_construction, self._interior_construction,
|
|
1644
|
+
self._exterior_glass_construction, self._interior_glass_construction,
|
|
1645
|
+
self._overhead_construction)
|
|
1646
|
+
return new_obj
|
|
1647
|
+
|
|
1648
|
+
def __repr__(self):
|
|
1649
|
+
return 'Door Construction Set: [Exterior: {}] [Interior: {}]' \
|
|
1650
|
+
' [Exterior Glass: {}] [Interior Glass: {}] [Overhead: {}]'.format(
|
|
1651
|
+
self.exterior_construction.display_name,
|
|
1652
|
+
self.interior_construction.display_name,
|
|
1653
|
+
self.exterior_glass_construction.display_name,
|
|
1654
|
+
self.interior_glass_construction.display_name,
|
|
1655
|
+
self.overhead_construction.display_name)
|