openepd 3.1.1__py3-none-any.whl → 3.1.3__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 (34) hide show
  1. openepd/__version__.py +1 -1
  2. openepd/compat/compat_functional_validators.py +29 -0
  3. openepd/compat/pydantic.py +6 -1
  4. openepd/model/specs/concrete.py +1 -157
  5. openepd/model/specs/generated/asphalt.py +1 -11
  6. openepd/model/specs/generated/cladding.py +4 -16
  7. openepd/model/specs/generated/cmu.py +1 -8
  8. openepd/model/specs/generated/concrete.py +59 -33
  9. openepd/model/specs/generated/conveying_equipment.py +2 -12
  10. openepd/model/specs/generated/electrical.py +9 -12
  11. openepd/model/specs/generated/enums.py +26 -20
  12. openepd/model/specs/generated/finishes.py +2 -36
  13. openepd/model/specs/generated/fire_and_smoke_protection.py +1 -3
  14. openepd/model/specs/generated/furnishings.py +1 -3
  15. openepd/model/specs/generated/masonry.py +5 -4
  16. openepd/model/specs/generated/mechanical.py +25 -93
  17. openepd/model/specs/generated/mechanical_insulation.py +1 -5
  18. openepd/model/specs/generated/network_infrastructure.py +2 -12
  19. openepd/model/specs/generated/openings.py +209 -91
  20. openepd/model/specs/generated/plumbing.py +3 -19
  21. openepd/model/specs/generated/precast_concrete.py +1 -5
  22. openepd/model/specs/generated/steel.py +117 -53
  23. openepd/model/specs/generated/thermal_moisture_protection.py +1 -15
  24. openepd/model/specs/generated/utility_piping.py +2 -10
  25. openepd/model/specs/generated/wood.py +1 -5
  26. openepd/model/validation/quantity.py +158 -16
  27. {openepd-3.1.1.dist-info → openepd-3.1.3.dist-info}/METADATA +2 -1
  28. {openepd-3.1.1.dist-info → openepd-3.1.3.dist-info}/RECORD +30 -33
  29. openepd/model/specs/aluminium.py +0 -67
  30. openepd/model/specs/glass.py +0 -360
  31. openepd/model/specs/steel.py +0 -184
  32. openepd/model/specs/wood.py +0 -130
  33. {openepd-3.1.1.dist-info → openepd-3.1.3.dist-info}/LICENSE +0 -0
  34. {openepd-3.1.1.dist-info → openepd-3.1.3.dist-info}/WHEEL +0 -0
@@ -30,7 +30,7 @@ from openepd.model.specs.generated.enums import (
30
30
  ThermalSeparation,
31
31
  )
32
32
  from openepd.model.validation.numbers import RatioFloat
33
- from openepd.model.validation.quantity import LengthMmStr, PressureMPaStr, validate_unit_factory
33
+ from openepd.model.validation.quantity import LengthMmStr, PressureMPaStr, SpeedStr, validate_unit_factory
34
34
 
35
35
 
36
36
  class GlazingIntendedApplication(BaseOpenEpdSchema):
@@ -68,6 +68,63 @@ class GlazingIntendedApplication(BaseOpenEpdSchema):
68
68
  )
69
69
 
70
70
 
71
+ class GlazingOptionsMixin(BaseOpenEpdSchema):
72
+ """Common glazing options."""
73
+
74
+ low_emissivity: bool | None = pyd.Field(default=None, description="Low Emissivity coatings", example=True)
75
+ electrochromic: bool | None = pyd.Field(
76
+ default=None,
77
+ description="Glazing with an electrically controllable solar heat gain and/or other properties.",
78
+ example=True,
79
+ )
80
+ acid_etched: bool | None = pyd.Field(
81
+ default=None, description="Flat glass that has undergone a chemical etching process.", example=True
82
+ )
83
+ tempered: bool | None = pyd.Field(
84
+ default=None,
85
+ description="Consists of a single pane that has been heat-treated to give the glass increased impact "
86
+ "resistance. Standard typically used in North America.",
87
+ example=True,
88
+ )
89
+ toughened: bool | None = pyd.Field(
90
+ default=None,
91
+ description="Consists of a single pane that has been specially heat-treated to give the glass increased impact "
92
+ "resistance. Standard typically used in Europe.",
93
+ example=True,
94
+ )
95
+ laminated: bool | None = pyd.Field(
96
+ default=None,
97
+ description="Consists of at least two glass panes lying one on top of the other, with one or several layers of "
98
+ "a tear-resistant, viscoelastic film positioned between the panes, which consist of polyvinyl "
99
+ "butyral (PVB)",
100
+ example=True,
101
+ )
102
+ fire_resistant: bool | None = pyd.Field(default=None, example=True)
103
+ fire_protection: bool | None = pyd.Field(
104
+ default=None,
105
+ description="Specifically tested for its ability to block flames and smoke, but not radiant heat. Ranges from"
106
+ " specialty tempered products rated for ~20 minutes to glass ceramics rated up to 3 hours.",
107
+ example=True,
108
+ )
109
+ pyrolytic_coated: bool | None = pyd.Field(
110
+ default=None,
111
+ description="At least one coating is applied in a pyrolytic process, typically during float glass production.",
112
+ example=True,
113
+ )
114
+ sputter_coat: bool | None = pyd.Field(
115
+ default=None,
116
+ description="At least one coating is applied using sputter (vacuum deposition) coating.",
117
+ example=True,
118
+ )
119
+ solar_heat_gain: RatioFloat | None = pyd.Field(
120
+ default=None,
121
+ description="Solar heat gain, measured at a certain level of Differential Pressure. Range is 0 to 1.",
122
+ example=0.5,
123
+ ge=0,
124
+ le=1,
125
+ )
126
+
127
+
71
128
  class PanelDoorsV1(BaseOpenEpdHierarchicalSpec):
72
129
  """Panel doors performance specification."""
73
130
 
@@ -75,13 +132,18 @@ class PanelDoorsV1(BaseOpenEpdHierarchicalSpec):
75
132
 
76
133
 
77
134
  class PressureResistantDoorsV1(BaseOpenEpdHierarchicalSpec):
78
- """Pressure resistant doors performance specification."""
135
+ """Pressure-Resistant Doors."""
79
136
 
80
137
  _EXT_VERSION = "1.0"
81
138
 
82
139
 
83
140
  class SpecialFunctionDoorsV1(BaseOpenEpdHierarchicalSpec):
84
- """Special function doors performance specification."""
141
+ """
142
+ Special function doors.
143
+
144
+ Includes doors for e.g., cold storage, hangars, lightproof applications,
145
+ security, sound control, vaults, etc.
146
+ """
85
147
 
86
148
  _EXT_VERSION = "1.0"
87
149
 
@@ -97,23 +159,32 @@ class SlidingGlassDoorsV1(BaseOpenEpdHierarchicalSpec):
97
159
 
98
160
 
99
161
  class FenestrationAccessoriesV1(BaseOpenEpdHierarchicalSpec):
100
- """Fenestration accessories performance specification."""
162
+ """
163
+ Fenestration accessories.
164
+
165
+ Gaskets, seals, fasteners, and other low-mass items which may be useful in calculating the impact of a
166
+ fenestration system.
167
+ """
101
168
 
102
169
  _EXT_VERSION = "1.0"
103
170
 
104
171
 
105
172
  class FenestrationFramingV1(BaseOpenEpdHierarchicalSpec):
106
- """Fenestration framing performance specification."""
173
+ """
174
+ Fenestration Framing.
175
+
176
+ Lineal elements ("sticks") for use in fenestration, including frames, sashes, and mullions.
177
+ """
107
178
 
108
179
  _EXT_VERSION = "1.0"
109
180
 
110
181
  # Own fields:
111
- thermal_separation: ThermalSeparation | None = pyd.Field(default=None, description="", example="Aluminium")
112
- material: FrameMaterial | None = pyd.Field(default=None, description="", example="Vinyl")
182
+ thermal_separation: ThermalSeparation | None = pyd.Field(default=None, example="Aluminium")
183
+ material: FrameMaterial | None = pyd.Field(default=None, example="Vinyl")
113
184
 
114
185
 
115
186
  class FenestrationHardwareV1(BaseOpenEpdHierarchicalSpec):
116
- """Fenestration hardware performance specification."""
187
+ """Locks, operation hardware, and other substantial items declared on a per-piece basis."""
117
188
 
118
189
  _EXT_VERSION = "1.0"
119
190
 
@@ -122,69 +193,81 @@ class FenestrationHardwareV1(BaseOpenEpdHierarchicalSpec):
122
193
 
123
194
 
124
195
  class FlatGlassPanesV1(BaseOpenEpdHierarchicalSpec):
125
- """Flat glass panes performance specification."""
196
+ """Monolithic, uncoated flat glass panes that are not substantially processed."""
126
197
 
127
198
  _EXT_VERSION = "1.0"
128
199
 
129
200
  # Own fields:
130
- thickness: FlatGlassPanesThickness | None = pyd.Field(default=None, description="", example="12 mm")
201
+ thickness: FlatGlassPanesThickness | None = pyd.Field(default=None, example="12 mm")
131
202
 
132
203
  _flat_glass_panes_thickness_is_quantity_validator = pyd.validator("thickness", allow_reuse=True)(
133
204
  validate_unit_factory("m")
134
205
  )
135
206
 
136
207
 
137
- class ProcessedNonInsulatingGlassPanesV1(BaseOpenEpdHierarchicalSpec):
138
- """Processed non insulating glass panes performance specification."""
208
+ class ProcessedNonInsulatingGlassPanesV1(BaseOpenEpdHierarchicalSpec, GlazingOptionsMixin):
209
+ """
210
+ Solid glass panes without internal gaps which have been heat-treated or otherwise substantially processed.
139
211
 
140
- _EXT_VERSION = "1.0"
212
+ Includes:
213
+ 1. Coatings including low-e and other coatings (see PCR)
214
+ 2. laminating (fire-rated, glass clad polycarbonate, interlayers
215
+ 3. Heat treated (heat strengthened, tempered, fire-rated)
216
+ 4. Mechanically or chemically processed or fabricated
217
+ (edging, bending, etching, drilling, notching, cutting, polishing, etc)
218
+ 5. combined products of processing in 1-5.
219
+ """
141
220
 
142
- # Own fields:
143
- low_emissivity: bool | None = pyd.Field(default=None, description="", example=True)
144
- electrochromic: bool | None = pyd.Field(default=None, description="", example=True)
145
- acid_etched: bool | None = pyd.Field(default=None, description="", example=True)
146
- tempered: bool | None = pyd.Field(default=None, description="", example=True)
147
- toughened: bool | None = pyd.Field(default=None, description="", example=True)
148
- laminated: bool | None = pyd.Field(default=None, description="", example=True)
149
- fire_resistant: bool | None = pyd.Field(default=None, description="", example=True)
150
- fire_protection: bool | None = pyd.Field(default=None, description="", example=True)
151
- pyrolytic_coated: bool | None = pyd.Field(default=None, description="", example=True)
152
- sputter_coat: bool | None = pyd.Field(default=None, description="", example=True)
153
- solar_heat_gain: RatioFloat | None = pyd.Field(default=None, description="", example=0.5, ge=0, le=1)
221
+ _EXT_VERSION = "1.0"
154
222
 
155
223
 
156
224
  class GlazedDoorsV1(BaseOpenEpdHierarchicalSpec):
157
- """Glazed doors performance specification."""
225
+ """
226
+ Factory assembled door which is at least 50% glass by area.
227
+
228
+ Includes sliding patio doors and hinged doors.
229
+ """
158
230
 
159
231
  _EXT_VERSION = "1.0"
160
232
 
161
233
 
162
234
  class UnitSkylightsV1(BaseOpenEpdHierarchicalSpec):
163
- """Unit skylights performance specification."""
235
+ """
236
+ Unit skylights performance specification.
237
+
238
+ A factory assembled fenestration unit for installation on the roof of a structure to provide interior
239
+ building spaces with natural daylight, warmth, and ventilation; generally not operable
240
+ by hand (cf. roof window). Includes frame(s) and possibly operating hardware.
241
+ """
164
242
 
165
243
  _EXT_VERSION = "1.0"
166
244
 
167
245
 
168
246
  class WindowsV1(BaseOpenEpdHierarchicalSpec):
169
- """Windows performance specification."""
247
+ """Windows including glazing and frame material."""
170
248
 
171
249
  _EXT_VERSION = "1.0"
172
250
 
173
251
 
174
252
  class IntegratedDoorsOpeningAssembliesV1(BaseOpenEpdHierarchicalSpec):
175
- """Integrated doors opening assemblies performance specification."""
253
+ """Pre-installed unit that includes door, frame, and hardware."""
176
254
 
177
255
  _EXT_VERSION = "1.0"
178
256
 
179
257
 
180
258
  class MetalDoorAndFramesV1(BaseOpenEpdHierarchicalSpec):
181
- """Metal door and frames performance specification."""
259
+ """Metal doors and frames."""
182
260
 
183
261
  _EXT_VERSION = "1.0"
184
262
 
185
263
 
186
264
  class SpecialtyDoorsAndFramesV1(BaseOpenEpdHierarchicalSpec):
187
- """Specialty doors and frames performance specification."""
265
+ """
266
+ Specialty doors and frames.
267
+
268
+ Includes e.g., access doors and panels, sliding glass doors, coiling doors, special function doors,
269
+ folding doors, etc.
270
+ """
188
271
 
189
272
  _EXT_VERSION = "1.0"
190
273
 
@@ -200,7 +283,12 @@ class WoodDoorsV1(BaseOpenEpdHierarchicalSpec):
200
283
 
201
284
 
202
285
  class FenestrationPartsV1(BaseOpenEpdHierarchicalSpec):
203
- """Fenestration parts performance specification."""
286
+ """
287
+ Fenestration Parts.
288
+
289
+ Parts and assemblies for integration into building fenestration such as windows, curtain walls,
290
+ and storefronts.
291
+ """
204
292
 
205
293
  _EXT_VERSION = "1.0"
206
294
 
@@ -216,7 +304,7 @@ class FenestrationPartsV1(BaseOpenEpdHierarchicalSpec):
216
304
 
217
305
 
218
306
  class GlassPanesV1(BaseOpenEpdHierarchicalSpec):
219
- """Glass panes performance specification."""
307
+ """Flat glass panes."""
220
308
 
221
309
  _EXT_VERSION = "1.0"
222
310
 
@@ -252,29 +340,34 @@ class NAFSPerformanceClass(BaseOpenEpdSchema):
252
340
  )
253
341
 
254
342
 
255
- class NAFSFenestrationV1(BaseOpenEpdHierarchicalSpec):
256
- """NAFS fenestration performance specification."""
343
+ class NAFSFenestrationV1(BaseOpenEpdHierarchicalSpec, GlazingOptionsMixin):
344
+ """Factory assembled fenestration units compliant to the North American Fenestration Standard."""
257
345
 
258
346
  _EXT_VERSION = "1.0"
259
347
 
260
348
  # Own fields:
261
- hurricane_resistant: bool | None = pyd.Field(default=None, description="", example=True)
262
- low_emissivity: bool | None = pyd.Field(default=None, description="", example=True)
263
- electrochromic: bool | None = pyd.Field(default=None, description="", example=True)
264
- acid_etched: bool | None = pyd.Field(default=None, description="", example=True)
265
- tempered: bool | None = pyd.Field(default=None, description="", example=True)
266
- toughened: bool | None = pyd.Field(default=None, description="", example=True)
267
- laminated: bool | None = pyd.Field(default=None, description="", example=True)
268
- fire_resistant: bool | None = pyd.Field(default=None, description="", example=True)
269
- fire_protection: bool | None = pyd.Field(default=None, description="", example=True)
270
- pyrolytic_coated: bool | None = pyd.Field(default=None, description="", example=True)
271
- sputter_coat: bool | None = pyd.Field(default=None, description="", example=True)
272
- thermal_separation: ThermalSeparation | None = pyd.Field(default=None, description="", example="Aluminium")
273
- assembly_u_factor: str | None = pyd.Field(default=None, description="", example="1 USI")
274
- solar_heat_gain: RatioFloat | None = pyd.Field(default=None, description="", example=0.5, ge=0, le=1)
275
- air_infiltration: str | None = pyd.Field(default=None, description="", example="1 m / s")
349
+ hurricane_resistant: bool | None = pyd.Field(
350
+ default=None, description="The product has been designed to resist windborne debris.", example=True
351
+ )
352
+
353
+ assembly_u_factor: str | None = pyd.Field(
354
+ default=None,
355
+ description="Weighted average conductance of heat across assembly (including frame).",
356
+ example="1 USI",
357
+ )
358
+ air_infiltration: SpeedStr | None = pyd.Field(
359
+ default=None,
360
+ description="Air infiltration, measured at a certain level of Differential Pressure.",
361
+ example="1 m3 / m2 / s",
362
+ )
363
+
364
+ thermal_separation: ThermalSeparation | None = pyd.Field(default=None, example="Aluminium")
276
365
  dp_rating: PressureMPaStr | None = pyd.Field(default=None, description="", example="1 MPa")
277
- glass_panes: int | None = pyd.Field(default=None, description="", example=3)
366
+ glass_panes: int | None = pyd.Field(
367
+ default=None,
368
+ description="Number of panes, each separated by a cavity. A 3 pane unit has 2 cavities. example: 3",
369
+ example=3,
370
+ )
278
371
 
279
372
  performance_class: NAFSPerformanceClass | None = pyd.Field(
280
373
  default=None, description="Performance class according to NAFS."
@@ -293,10 +386,6 @@ class NAFSFenestrationV1(BaseOpenEpdHierarchicalSpec):
293
386
  _assembly_u_factor_is_quantity_validator = pyd.validator("assembly_u_factor", allow_reuse=True)(
294
387
  validate_unit_factory("USI")
295
388
  )
296
- _air_infiltration_is_quantity_validator = pyd.validator("air_infiltration", allow_reuse=True)(
297
- validate_unit_factory("m / s")
298
- )
299
- _dp_rating_is_quantity_validator = pyd.validator("dp_rating", allow_reuse=True)(validate_unit_factory("MPa"))
300
389
  _nafs_performance_grade_is_quantity_validator = pyd.validator("performance_grade", allow_reuse=True)(
301
390
  validate_unit_factory("psf")
302
391
  )
@@ -307,7 +396,7 @@ class NAFSFenestrationV1(BaseOpenEpdHierarchicalSpec):
307
396
  Windows: WindowsV1 | None = None
308
397
 
309
398
 
310
- class InsulatingGlazingUnitsV1(BaseOpenEpdHierarchicalSpec):
399
+ class InsulatingGlazingUnitsV1(BaseOpenEpdHierarchicalSpec, GlazingOptionsMixin):
311
400
  """Insulating glazing units performance specification."""
312
401
 
313
402
  _EXT_VERSION = "1.0"
@@ -317,48 +406,54 @@ class InsulatingGlazingUnitsV1(BaseOpenEpdHierarchicalSpec):
317
406
  default=None, description="Intended application for IGUs."
318
407
  )
319
408
 
320
- hurricane_resistant: bool | None = pyd.Field(default=None, description="", example=True)
321
- low_emissivity: bool | None = pyd.Field(default=None, description="", example=True)
322
- electrochromic: bool | None = pyd.Field(default=None, description="", example=True)
323
- acid_etched: bool | None = pyd.Field(default=None, description="", example=True)
324
- tempered: bool | None = pyd.Field(default=None, description="", example=True)
325
- toughened: bool | None = pyd.Field(default=None, description="", example=True)
326
- laminated: bool | None = pyd.Field(default=None, description="", example=True)
327
- fire_resistant: bool | None = pyd.Field(default=None, description="", example=True)
328
- fire_protection: bool | None = pyd.Field(default=None, description="", example=True)
329
- pyrolytic_coated: bool | None = pyd.Field(default=None, description="", example=True)
330
- sputter_coat: bool | None = pyd.Field(default=None, description="", example=True)
331
- solar_heat_gain: RatioFloat | None = pyd.Field(default=None, description="", example=0.5, ge=0, le=1)
332
- air_infiltration: str | None = pyd.Field(default=None, description="", example="1 m / s")
333
- dp_rating: PressureMPaStr | None = pyd.Field(default=None, description="", example="1 MPa")
334
- glass_panes: int | None = pyd.Field(default=None, description="", example=3)
335
- cog_u_factor: str | None = pyd.Field(default=None, description="", example="1 USI")
336
- spacer: Spacer | None = pyd.Field(default=None, description="", example="Aluminium")
409
+ hurricane_resistant: bool | None = pyd.Field(default=None, example=True)
337
410
 
338
- _air_infiltration_is_quantity_validator = pyd.validator("air_infiltration", allow_reuse=True)(
339
- validate_unit_factory("m / s")
411
+ dp_rating: PressureMPaStr | None = pyd.Field(
412
+ default=None, description="Maximum Differential Pressure, a measure of wind tolerance.", example="1 MPa"
340
413
  )
414
+ air_infiltration: SpeedStr | None = pyd.Field(
415
+ default=None,
416
+ description="Air infiltration, measured at a certain level of Differential Pressure.",
417
+ example="1 m3 / m2 / s",
418
+ )
419
+ glass_panes: int | None = pyd.Field(
420
+ default=None,
421
+ description="Number of panes, each separated by a cavity. A 3 pane unit has 2 cavities. example: 3",
422
+ example=3,
423
+ )
424
+ cog_u_factor: str | None = pyd.Field(
425
+ default=None, description="Conductance of heat at center of glass.", example="1 USI"
426
+ )
427
+ spacer: Spacer | None = pyd.Field(
428
+ default=None, description="Spacer material for Integrated Glass Unit.", example="Aluminium"
429
+ )
430
+
341
431
  _dp_rating_is_quantity_validator = pyd.validator("dp_rating", allow_reuse=True)(validate_unit_factory("MPa"))
342
432
  _cog_u_factor_is_quantity_validator = pyd.validator("cog_u_factor", allow_reuse=True)(validate_unit_factory("USI"))
343
433
 
344
434
 
345
435
  class CurtainWallsV1(BaseOpenEpdHierarchicalSpec):
346
- """Curtain walls performance specification."""
436
+ """
437
+ Curtain Walls.
438
+
439
+ Exterior skin of building where walls are non-structural and are outboard of the floor slabs,
440
+ often as system of aluminum framing with vision glass and opaque panels of glass, metal, or other
441
+ materials.
442
+
443
+ Can be 'unitized' (prefabricated off-site) or 'stick' (fabricated on site).
444
+ """
347
445
 
348
446
  _EXT_VERSION = "1.0"
349
447
 
350
448
 
351
449
  class DoorsAndFramesV1(BaseOpenEpdHierarchicalSpec):
352
- """Doors and frames performance specification."""
450
+ """Doors (the operable part) and frames (what holds the door proper)."""
353
451
 
354
452
  _EXT_VERSION = "1.0"
355
453
 
356
454
  # Own fields:
357
- height: LengthMmStr | None = pyd.Field(default=None, description="", example="1200 mm")
358
- width: LengthMmStr | None = pyd.Field(default=None, description="", example="600 mm")
359
-
360
- _height_is_quantity_validator = pyd.validator("height", allow_reuse=True)(validate_unit_factory("m"))
361
- _width_is_quantity_validator = pyd.validator("width", allow_reuse=True)(validate_unit_factory("m"))
455
+ height: LengthMmStr | None = pyd.Field(default=None, example="1200 mm")
456
+ width: LengthMmStr | None = pyd.Field(default=None, example="600 mm")
362
457
 
363
458
  # Nested specs:
364
459
  IntegratedDoorsOpeningAssemblies: IntegratedDoorsOpeningAssembliesV1 | None = None
@@ -368,13 +463,18 @@ class DoorsAndFramesV1(BaseOpenEpdHierarchicalSpec):
368
463
 
369
464
 
370
465
  class EntrancesV1(BaseOpenEpdHierarchicalSpec):
371
- """Entrances performance specification."""
466
+ """Building entrances (distinct from the door proper)."""
372
467
 
373
468
  _EXT_VERSION = "1.0"
374
469
 
375
470
 
376
471
  class GlazingV1(BaseOpenEpdHierarchicalSpec):
377
- """Glazing performance specification."""
472
+ """
473
+ Glazing performance specification.
474
+
475
+ Broad category of glass-based products, accessories, and assemblies ranging from
476
+ glass panes and framing to curtain walls.
477
+ """
378
478
 
379
479
  _EXT_VERSION = "1.0"
380
480
 
@@ -386,32 +486,50 @@ class GlazingV1(BaseOpenEpdHierarchicalSpec):
386
486
 
387
487
 
388
488
  class StorefrontsV1(BaseOpenEpdHierarchicalSpec):
389
- """Storefronts performance specification."""
489
+ """
490
+ Storefronts.
491
+
492
+ Fabricated building facades commonly used in retail applications, typically one or two stories
493
+ tall and using metal framing and glass.
494
+ """
390
495
 
391
496
  _EXT_VERSION = "1.0"
392
497
 
393
498
 
394
499
  class TranslucentWallAndRoofAssembliesV1(BaseOpenEpdHierarchicalSpec):
395
- """Translucent wall and roof assemblies performance specification."""
500
+ """
501
+ Translucent wall and roof assemblies.
502
+
503
+ Includes structured polycarbonate panel and fiberglass sandwich panel assemblies.
504
+ """
396
505
 
397
506
  _EXT_VERSION = "1.0"
398
507
 
399
508
 
400
509
  class WindowWallAssembliesV1(BaseOpenEpdHierarchicalSpec):
401
- """Window wall assemblies performance specification."""
510
+ """
511
+ Window Wall Assemblies.
512
+
513
+ Exterior skin of building where walls are non-structural and sit between floor slabs, often as
514
+ system of aluminum framing with vision glass and opaque panels of glass, metal,
515
+ or other materials.
516
+ """
402
517
 
403
518
  _EXT_VERSION = "1.0"
404
519
 
405
520
 
406
521
  class OpeningsV1(BaseOpenEpdHierarchicalSpec):
407
- """Openings performance specification."""
522
+ """
523
+ Openings performance specification.
524
+
525
+ General category that includes windows, storefronts, window walls, curtain walls,
526
+ doors, entrances, etc.
527
+ """
408
528
 
409
529
  _EXT_VERSION = "1.0"
410
530
 
411
531
  # Own fields:
412
- thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="80 mm")
413
-
414
- _thickness_is_quantity_validator = pyd.validator("thickness", allow_reuse=True)(validate_unit_factory("m"))
532
+ thickness: LengthMmStr | None = pyd.Field(default=None, example="80 mm")
415
533
 
416
534
  # Nested specs:
417
535
  CurtainWalls: CurtainWallsV1 | None = None
@@ -20,7 +20,7 @@
20
20
  from openepd.compat.pydantic import pyd
21
21
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
22
22
  from openepd.model.specs.generated.enums import FireProtectionPipingMaterial, PipingAnsiSchedule, PlumbingPipingMaterial
23
- from openepd.model.validation.quantity import LengthMmStr, validate_unit_factory
23
+ from openepd.model.validation.quantity import LengthMmStr, MassPerLengthStr
24
24
 
25
25
 
26
26
  class BathtubsV1(BaseOpenEpdHierarchicalSpec):
@@ -55,20 +55,12 @@ class FireProtectionPipingV1(BaseOpenEpdHierarchicalSpec):
55
55
  # Own fields:
56
56
  thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="6 mm")
57
57
  piping_diameter: LengthMmStr | None = pyd.Field(default=None, description="", example="120 mm")
58
- mass_per_unit_length: str | None = pyd.Field(default=None, description="", example="1 kg / m")
58
+ mass_per_unit_length: MassPerLengthStr | None = pyd.Field(default=None, description="", example="1 kg / m")
59
59
  piping_ansi_schedule: PipingAnsiSchedule | None = pyd.Field(default=None, description="", example="5")
60
60
  fire_protection_piping_material: FireProtectionPipingMaterial | None = pyd.Field(
61
61
  default=None, description="", example="PVC"
62
62
  )
63
63
 
64
- _thickness_is_quantity_validator = pyd.validator("thickness", allow_reuse=True)(validate_unit_factory("m"))
65
- _piping_diameter_is_quantity_validator = pyd.validator("piping_diameter", allow_reuse=True)(
66
- validate_unit_factory("m")
67
- )
68
- _mass_per_unit_length_is_quantity_validator = pyd.validator("mass_per_unit_length", allow_reuse=True)(
69
- validate_unit_factory("kg / m")
70
- )
71
-
72
64
 
73
65
  class FireSprinklersV1(BaseOpenEpdHierarchicalSpec):
74
66
  """Fire sprinklers performance specification."""
@@ -118,18 +110,10 @@ class PipingV1(BaseOpenEpdHierarchicalSpec):
118
110
  # Own fields:
119
111
  thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="6 mm")
120
112
  piping_diameter: LengthMmStr | None = pyd.Field(default=None, description="", example="120 mm")
121
- mass_per_unit_length: str | None = pyd.Field(default=None, description="", example="1 kg / m")
113
+ mass_per_unit_length: MassPerLengthStr | None = pyd.Field(default=None, description="", example="1 kg / m")
122
114
  piping_ansi_schedule: PipingAnsiSchedule | None = pyd.Field(default=None, description="", example="5")
123
115
  plumbing_piping_material: PlumbingPipingMaterial | None = pyd.Field(default=None, description="", example="PVC")
124
116
 
125
- _thickness_is_quantity_validator = pyd.validator("thickness", allow_reuse=True)(validate_unit_factory("m"))
126
- _piping_diameter_is_quantity_validator = pyd.validator("piping_diameter", allow_reuse=True)(
127
- validate_unit_factory("m")
128
- )
129
- _mass_per_unit_length_is_quantity_validator = pyd.validator("mass_per_unit_length", allow_reuse=True)(
130
- validate_unit_factory("kg / m")
131
- )
132
-
133
117
 
134
118
  class PlumbingEquipmentV1(BaseOpenEpdHierarchicalSpec):
135
119
  """Plumbing equipment performance specification."""
@@ -20,7 +20,7 @@
20
20
  from openepd.compat.pydantic import pyd
21
21
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
22
22
  from openepd.model.validation.numbers import RatioFloat
23
- from openepd.model.validation.quantity import PressureMPaStr, validate_unit_factory
23
+ from openepd.model.validation.quantity import PressureMPaStr
24
24
 
25
25
 
26
26
  class ArchitecturalPrecastV1(BaseOpenEpdHierarchicalSpec):
@@ -58,10 +58,6 @@ class PrecastConcreteV1(BaseOpenEpdHierarchicalSpec):
58
58
  )
59
59
  steel_mass_percentage: RatioFloat | None = pyd.Field(default=None, description="", example=0.5, ge=0, le=1)
60
60
 
61
- _concrete_compressive_strength_28d_is_quantity_validator = pyd.validator(
62
- "concrete_compressive_strength_28d", allow_reuse=True
63
- )(validate_unit_factory("MPa"))
64
-
65
61
  # Nested specs:
66
62
  ArchitecturalPrecast: ArchitecturalPrecastV1 | None = None
67
63
  StructuralPrecast: StructuralPrecastV1 | None = None