openepd 2.0.0__py3-none-any.whl → 3.1.0__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 (95) hide show
  1. openepd/__init__.py +1 -1
  2. openepd/__version__.py +2 -2
  3. openepd/api/__init__.py +19 -0
  4. openepd/api/base_sync_client.py +550 -0
  5. openepd/api/category/__init__.py +19 -0
  6. openepd/api/category/dto.py +25 -0
  7. openepd/api/category/sync_api.py +44 -0
  8. openepd/api/common.py +239 -0
  9. openepd/api/dto/__init__.py +19 -0
  10. openepd/api/dto/base.py +41 -0
  11. openepd/api/dto/common.py +115 -0
  12. openepd/api/dto/meta.py +69 -0
  13. openepd/api/dto/mf.py +59 -0
  14. openepd/api/dto/params.py +19 -0
  15. openepd/api/epd/__init__.py +19 -0
  16. openepd/api/epd/dto.py +121 -0
  17. openepd/api/epd/sync_api.py +105 -0
  18. openepd/api/errors.py +86 -0
  19. openepd/api/pcr/__init__.py +19 -0
  20. openepd/api/pcr/dto.py +41 -0
  21. openepd/api/pcr/sync_api.py +49 -0
  22. openepd/api/sync_client.py +67 -0
  23. openepd/api/test/__init__.py +19 -0
  24. openepd/bundle/__init__.py +1 -1
  25. openepd/bundle/base.py +1 -1
  26. openepd/bundle/model.py +5 -6
  27. openepd/bundle/reader.py +5 -5
  28. openepd/bundle/writer.py +5 -4
  29. openepd/compat/__init__.py +19 -0
  30. openepd/compat/pydantic.py +29 -0
  31. openepd/model/__init__.py +1 -1
  32. openepd/model/base.py +114 -15
  33. openepd/model/category.py +39 -0
  34. openepd/model/common.py +33 -25
  35. openepd/model/epd.py +97 -78
  36. openepd/model/factory.py +48 -0
  37. openepd/model/lcia.py +24 -13
  38. openepd/model/org.py +28 -18
  39. openepd/model/pcr.py +42 -14
  40. openepd/model/specs/README.md +19 -0
  41. openepd/model/specs/__init__.py +72 -4
  42. openepd/model/specs/aluminium.py +67 -0
  43. openepd/model/specs/asphalt.py +87 -0
  44. openepd/model/specs/base.py +60 -0
  45. openepd/model/specs/concrete.py +288 -24
  46. openepd/model/specs/generated/accessories.py +63 -0
  47. openepd/model/specs/generated/aggregates.py +71 -0
  48. openepd/model/specs/generated/aluminium.py +66 -0
  49. openepd/model/specs/generated/asphalt.py +86 -0
  50. openepd/model/specs/generated/bulk_materials.py +26 -0
  51. openepd/model/specs/generated/cast_decks_and_underlayment.py +26 -0
  52. openepd/model/specs/generated/cladding.py +214 -0
  53. openepd/model/specs/generated/cmu.py +46 -0
  54. openepd/model/specs/generated/common.py +27 -0
  55. openepd/model/specs/generated/concrete.py +151 -0
  56. openepd/model/specs/generated/conveying_equipment.py +57 -0
  57. openepd/model/specs/generated/electrical.py +297 -0
  58. openepd/model/specs/generated/electrical_transmission_and_distribution_equipment.py +63 -0
  59. openepd/model/specs/generated/electricity.py +26 -0
  60. openepd/model/specs/generated/enums.py +2420 -0
  61. openepd/model/specs/generated/finishes.py +519 -0
  62. openepd/model/specs/generated/fire_and_smoke_protection.py +79 -0
  63. openepd/model/specs/generated/furnishings.py +95 -0
  64. openepd/model/specs/generated/grouting.py +26 -0
  65. openepd/model/specs/generated/manufacturing_inputs.py +131 -0
  66. openepd/model/specs/generated/masonry.py +77 -0
  67. openepd/model/specs/generated/material_handling.py +35 -0
  68. openepd/model/specs/generated/mechanical.py +271 -0
  69. openepd/model/specs/generated/mechanical_insulation.py +41 -0
  70. openepd/model/specs/generated/network_infrastructure.py +181 -0
  71. openepd/model/specs/generated/openings.py +423 -0
  72. openepd/model/specs/generated/other_electrical_equipment.py +26 -0
  73. openepd/model/specs/generated/other_materials.py +123 -0
  74. openepd/model/specs/generated/plumbing.py +153 -0
  75. openepd/model/specs/generated/precast_concrete.py +68 -0
  76. openepd/model/specs/generated/sheathing.py +74 -0
  77. openepd/model/specs/generated/steel.py +224 -0
  78. openepd/model/specs/generated/thermal_moisture_protection.py +233 -0
  79. openepd/model/specs/generated/utility_piping.py +65 -0
  80. openepd/model/specs/generated/wood.py +167 -0
  81. openepd/model/specs/generated/wood_joists.py +38 -0
  82. openepd/model/specs/glass.py +360 -0
  83. openepd/model/specs/steel.py +184 -0
  84. openepd/model/specs/wood.py +130 -0
  85. openepd/model/standard.py +2 -3
  86. openepd/model/validation/__init__.py +19 -0
  87. openepd/model/validation/common.py +59 -0
  88. openepd/model/validation/numbers.py +26 -0
  89. openepd/model/validation/quantity.py +132 -0
  90. openepd/model/versioning.py +129 -0
  91. {openepd-2.0.0.dist-info → openepd-3.1.0.dist-info}/METADATA +36 -5
  92. openepd-3.1.0.dist-info/RECORD +95 -0
  93. openepd-2.0.0.dist-info/RECORD +0 -22
  94. {openepd-2.0.0.dist-info → openepd-3.1.0.dist-info}/LICENSE +0 -0
  95. {openepd-2.0.0.dist-info → openepd-3.1.0.dist-info}/WHEEL +0 -0
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2023 by C Change Labs Inc. www.c-change-labs.com
2
+ # Copyright 2024 by C Change Labs Inc. www.c-change-labs.com
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -18,10 +18,16 @@
18
18
  # Find out more at www.BuildingTransparency.org
19
19
  #
20
20
  from enum import StrEnum
21
+ from typing import Literal
21
22
 
22
- import pydantic as pyd
23
-
24
- from openepd.model.base import BaseOpenEpdSpec
23
+ from openepd.compat.pydantic import pyd
24
+ from openepd.model.base import BaseOpenEpdSchema
25
+ from openepd.model.common import OpenEPDUnit
26
+ from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec, BaseOpenEpdSpec
27
+ from openepd.model.specs.generated.enums import AciExposureClass, CsaExposureClass, EnExposureClass
28
+ from openepd.model.validation.common import together_validator
29
+ from openepd.model.validation.numbers import RatioFloat
30
+ from openepd.model.validation.quantity import LengthMmStr, PressureMPaStr, validate_unit_factory
25
31
 
26
32
 
27
33
  class CmuWeightClassification(StrEnum):
@@ -35,55 +41,313 @@ class CmuWeightClassification(StrEnum):
35
41
  """Lightweight CMU has a density less than 105 lbs/cu. ft."""
36
42
 
37
43
 
38
- class CmuOptions(BaseOpenEpdSpec):
44
+ class CmuOptions(BaseOpenEpdSchema):
39
45
  """Concrete Masonry Unit options."""
40
46
 
41
47
  load_bearing: bool | None = pyd.Field(
42
48
  description="Load-Bearing. CMUs intended to be loadbearing, rather than simply cosmetic",
49
+ example=True,
43
50
  default=None,
44
- json_schema_extra={"example": True},
45
51
  )
46
52
  aerated_concrete: bool | None = pyd.Field(
47
- description="AAC Aerated Concrete. Aerated Autoclaved Concrete, a foam concrete.",
48
- default=None,
49
- json_schema_extra={"example": True},
53
+ description="AAC Aerated Concrete. Aerated Autoclaved Concrete, a foam concrete.", example=True, default=None
50
54
  )
51
55
  insulated: bool | None = pyd.Field(
52
- description="Insulated. CMUs with integral insulation",
53
- default=None,
56
+ description="Insulated. CMUs with integral insulation", example=True, default=None
54
57
  )
55
58
  sound_absorbing: bool | None = pyd.Field(
56
- description="Sound Absorbing. CMUs structured for sound absorbtion",
57
- default=None,
59
+ description="Sound Absorbing. CMUs structured for sound absorbtion", example=True, default=None
58
60
  )
59
61
  white: bool | None = pyd.Field(
60
- description="White. CMU using white cement and light-colored aggregate",
61
- default=None,
62
+ description="White. CMU using white cement and light-colored aggregate", example=True, default=None
62
63
  )
63
64
  recycled_aggregate: bool | None = pyd.Field(
64
- description="Recycled aggregate. CMU using primarily reycled aggregates",
65
- default=None,
65
+ description="Recycled aggregate. CMU using primarily reycled aggregates", example=True, default=None
66
66
  )
67
67
  groundface: bool | None = pyd.Field(
68
- description="Ground Face. Ground or Honed facing, typically for improved appearance", default=None
68
+ description="Ground Face. Ground or Honed facing, typically for improved appearance", example=True, default=None
69
69
  )
70
70
  splitface: bool | None = pyd.Field(
71
- description="Splitface. Rough surface texture via splitting; aggregate can be seen", default=None
71
+ description="Splitface. Rough surface texture via splitting; aggregate can be seen", example=True, default=None
72
+ )
73
+ smoothface: bool | None = pyd.Field(
74
+ description="Smooth Face. Standard smooth-faced blocks", example=True, default=None
72
75
  )
73
- smoothface: bool | None = pyd.Field(description="Smooth Face. Standard smooth-faced blocks", default=None)
74
76
  slumpstone: bool | None = pyd.Field(
75
77
  description="Slumpstone. A slightly rounded, random distortion with the look of rustic adobe.",
78
+ example=True,
79
+ default=None,
80
+ )
81
+
82
+
83
+ class ConcreteTypicalApplication(BaseOpenEpdSpec):
84
+ """Typical Application for Concrete."""
85
+
86
+ fnd: bool | None = pyd.Field(
87
+ description="Foundation. Typically used in direct contact with soil, e.g. footings, piles, mass concrete, "
88
+ "mat foundations, and similar applications.",
89
+ example=True,
90
+ default=None,
91
+ )
92
+ sog: bool | None = pyd.Field(
93
+ description="Slab on Grade. Typically used in continuously supported horizontal "
94
+ "applications e.g. slab on grade, topping slabs, sidewalks, and roadways.",
95
+ example=True,
96
+ default=None,
97
+ )
98
+ hrz: bool | None = pyd.Field(
99
+ description="Elevated Horizontal. Typically used in elevated horizontal applications, either on metal deck or "
100
+ "where soffit formwork must be removed, e.g. post-tension plates, rebar plates, beams and slabs, "
101
+ "waffle slabs.",
102
+ example=True,
103
+ default=None,
104
+ )
105
+ vrt_wall: bool | None = pyd.Field(description="Vertical Wall.", example=True, default=None)
106
+ vrt_column: bool | None = pyd.Field(description="Vertical Column.", example=True, default=None)
107
+ vrt_other: bool | None = pyd.Field(
108
+ description="Vertical Other. Typically used in vertical applications other than "
109
+ "walls or columns, e.g. sloped surfaces where formwork is required "
110
+ "on multiple faces.",
111
+ example=True,
112
+ default=None,
113
+ )
114
+ sht: bool | None = pyd.Field(
115
+ description="Shotcrete. Pneumatically applied, without formwork on all sides.", example=True, default=None
116
+ )
117
+ cdf: bool | None = pyd.Field(
118
+ description="Flowable Fill (CDF). Typically used to fill voids, backfill retaining "
119
+ "walls, as a sub-base, and similar applications. Also called Controlled "
120
+ "Density Fill (CDF) or Controlled Low Strength Materials (CLSM).",
121
+ example=True,
122
+ default=None,
123
+ )
124
+ sac: bool | None = pyd.Field(
125
+ description="Typically used in concrete sidewalks and barrier curbs.", example=True, default=None
126
+ )
127
+ pav: bool | None = pyd.Field(description="Typically used in pervious concrete", example=True, default=None)
128
+ oil: bool | None = pyd.Field(
129
+ description="Concretes for use in creation, maintenance, and decommissioning of "
130
+ "petroleum extraction wells and similar applications. Includes foamed "
131
+ "cement; often called cement in the drilling industry. Differs from "
132
+ "flowable fill and grout in that it contains no sand or other aggregates.",
133
+ example=True,
134
+ default=None,
135
+ )
136
+ grt: bool | None = pyd.Field(
137
+ description="Cement grouting is a slurry that is placed as a flowable liquid. It is "
138
+ "an effective material for filling and strengthening granular soils, "
139
+ "voids in rocks, foundation underpinnings, and other underground voids. "
140
+ "Also called structural grout, these materials typically impart"
141
+ " significant strength to the system",
142
+ example=True,
76
143
  default=None,
77
144
  )
145
+ ota: bool | None = pyd.Field(
146
+ description="Typical application not covered by other values.", example=True, default=None
147
+ )
78
148
 
79
149
 
80
150
  class CmuSpec(BaseOpenEpdSpec):
81
151
  """Standardized Concrete Masonry Unit-specific extension for OpenEPD."""
82
152
 
83
- strength: str = pyd.Field(
84
- description="Compressive strength",
85
- json_schema_extra=dict(example="4000 psi"),
86
- )
153
+ strength: str = pyd.Field(description="Compressive strength", example="4000 psi")
87
154
  options: CmuOptions = pyd.Field(
88
155
  description="Options for CMU. List of true/false properties", default_factory=CmuOptions
89
156
  )
157
+
158
+
159
+ class Cementitious(BaseOpenEpdSchema):
160
+ """List of cementitious materials, and proportion by mass."""
161
+
162
+ opc: RatioFloat | None = pyd.Field(default=None, description="Ordinary Gray Portland Cement")
163
+ wht: RatioFloat | None = pyd.Field(default=None, description="White Portland Cement")
164
+ ggbs: RatioFloat | None = pyd.Field(default=None, description="Ground Granulated Blast Furnace Slag")
165
+ flyAsh: RatioFloat | None = pyd.Field(default=None, description="Fly Ash, including types F, CL, and CH")
166
+ siFume: RatioFloat | None = pyd.Field(default=None, description="Silica Fume")
167
+ gg45: RatioFloat | None = pyd.Field(default=None, description="Ground Glass, 45um or smaller")
168
+ natPoz: RatioFloat | None = pyd.Field(default=None, description="Natural pozzolan")
169
+ mk: RatioFloat | None = pyd.Field(default=None, description="Metakaolin")
170
+ CaCO3: RatioFloat | None = pyd.Field(default=None, description="Limestone")
171
+ other: RatioFloat | None = pyd.Field(default=None, description="Other SCMs")
172
+
173
+
174
+ class TypicalApplication(BaseOpenEpdSchema):
175
+ """Concrete typical application."""
176
+
177
+ fnd: bool | None = pyd.Field(description="Foundation", default=None)
178
+ sog: bool | None = pyd.Field(description="Slab on Grade", default=None)
179
+ hrz: bool | None = pyd.Field(description="Elevated Horizontal", default=None)
180
+ vrt_wall: bool | None = pyd.Field(description="Vertical Wall", default=None)
181
+ vrt_column: bool | None = pyd.Field(description="Vertical Column", default=None)
182
+ vrt_other: bool | None = pyd.Field(description="Vertical Other", default=None)
183
+ sht: bool | None = pyd.Field(description="Shotcrete", default=None)
184
+ cdf: bool | None = pyd.Field(description="Flowable Fill (CDF,default=None)", default=None)
185
+ sac: bool | None = pyd.Field(description="Sidewalk and Curb", default=None)
186
+ pav: bool | None = pyd.Field(description="Paving", default=None)
187
+ oil: bool | None = pyd.Field(description="Oil Patch", default=None)
188
+ grt: bool | None = pyd.Field(description="Cement Grout", default=None)
189
+ ota: bool | None = pyd.Field(description="Other", default=None)
190
+
191
+
192
+ class ConcreteV1Options(BaseOpenEpdSchema):
193
+ """Concrete options."""
194
+
195
+ lightweight: bool | None = pyd.Field(description="Lightweight", default=None)
196
+ plc: bool | None = pyd.Field(description="Portland Limestone Cement", default=None)
197
+ scc: bool | None = pyd.Field(description="Self Compacting", default=None)
198
+ finishable: bool | None = pyd.Field(description="Finishable", default=None)
199
+ air: bool | None = pyd.Field(description="Air Entrainment", default=None)
200
+ co2: bool | None = pyd.Field(description="CO2 Curing", default=None)
201
+ white: bool | None = pyd.Field(description="White Cement", default=None)
202
+ fiber_reinforced: bool | None = pyd.Field(description="Fiber reinforced", default=None)
203
+
204
+
205
+ class ReadyMixV1(BaseOpenEpdHierarchicalSpec):
206
+ """Concretes to be mixed and then poured on-site."""
207
+
208
+ _EXT_VERSION = "1.0"
209
+
210
+
211
+ class FlowableFillV1(BaseOpenEpdHierarchicalSpec):
212
+ """
213
+ Flowable fill is a slurry that is placed as a flowable liquid (high slump) and sets with no compaction.
214
+
215
+ It is often used in tight or restricted access areas where placing and compacting
216
+ fill is difficult. Applications include filling large voids such as abandoned underground storage
217
+ tanks, basements, tunnels, mines, and sewers. It can also be used as paving sub-base, bridge
218
+ abutment, and retaining wall backfill. Also called Controlled Density Fill (CDF) or Controlled
219
+ Low Strength Materials (CLSMs). These materials typically have compressive strengths
220
+ under 1200 psi.
221
+ """
222
+
223
+ _EXT_VERSION = "1.0"
224
+
225
+
226
+ class OilPatchV1(BaseOpenEpdHierarchicalSpec):
227
+ """
228
+ Concretes for use in petroleum extraction wells and similar applications.
229
+
230
+ Includes foamed cement; often called cement in the drilling industry. Differs from
231
+ flowable fill and grout in that it contains no sand or other aggregates.
232
+ """
233
+
234
+ _EXT_VERSION = "1.0"
235
+
236
+
237
+ class ConcretePavingV1(BaseOpenEpdHierarchicalSpec):
238
+ """Concrete paving."""
239
+
240
+ _EXT_VERSION = "1.0"
241
+
242
+
243
+ class ShotcreteV1(BaseOpenEpdHierarchicalSpec):
244
+ """Concretes sprayed on a target."""
245
+
246
+ _EXT_VERSION = "1.0"
247
+
248
+
249
+ class CementGroutV1(BaseOpenEpdHierarchicalSpec):
250
+ """
251
+ Cement grouting is a slurry that is placed as a flowable liquid.
252
+
253
+ It is an effective material for filling and
254
+ strengthening granular soils, voids in rocks, foundation underpinnings, and other underground voids. Also called
255
+ structural grout, these materials typically impart significant compressive strength to the system.
256
+
257
+ """
258
+
259
+ _EXT_VERSION = "1.0"
260
+
261
+
262
+ class ConcreteV1(BaseOpenEpdHierarchicalSpec):
263
+ """Concrete spec."""
264
+
265
+ _EXT_VERSION = "1.0"
266
+
267
+ strength_28d: PressureMPaStr | None = pyd.Field(
268
+ default=None, example="30 MPa", description="Concrete strength after 28 days"
269
+ )
270
+ strength_early: PressureMPaStr | None = pyd.Field(
271
+ default=None,
272
+ example="30 MPa",
273
+ description="A strength spec which is to be reached earlier than 28 days (e.g. 3d)",
274
+ )
275
+ strength_early_d: Literal[3, 7, 14] | None = pyd.Field(default=None, description="Test Day for the Early Strength")
276
+ strength_late: PressureMPaStr | None = pyd.Field(
277
+ default=None,
278
+ example="30 MPa",
279
+ description="A strength spec which is to be reached later than 28 days (e.g. 42d)",
280
+ )
281
+ strength_late_d: Literal[42, 56, 72, 96, 120] | None = pyd.Field(
282
+ default=None, description="Test Day for the Late Strength"
283
+ )
284
+ slump: LengthMmStr | None = pyd.Field(description="Minimum test slump", example="40 mm", default=None)
285
+ w_c_ratio: RatioFloat | None = pyd.Field(description="Ratio of water to cement", example=0.3, default=None)
286
+ aci_exposure_classes: list[AciExposureClass] = pyd.Field(
287
+ description=(AciExposureClass.__doc__ or "").lstrip(), default_factory=list
288
+ )
289
+ csa_exposure_classes: list[CsaExposureClass] = pyd.Field(
290
+ description=(CsaExposureClass.__doc__ or "").lstrip(), default_factory=list
291
+ )
292
+ en_exposure_classes: list[EnExposureClass] = pyd.Field(
293
+ description=(EnExposureClass.__doc__ or "").lstrip(), default_factory=list
294
+ )
295
+ cementitious: Cementitious | None = pyd.Field(
296
+ default=None,
297
+ description="List of cementitious materials, and proportion by mass. Each field is 0 to 1.",
298
+ )
299
+ application: TypicalApplication | None = pyd.Field(description="Typical Application", default=None)
300
+ options: ConcreteV1Options | None = pyd.Field(description="Concrete options", default=None)
301
+
302
+ # Nested specs
303
+ ReadyMix: ReadyMixV1 | None = None
304
+ FlowableFill: FlowableFillV1 | None = None
305
+ OilPatch: OilPatchV1 | None = None
306
+ ConcretePaving: ConcretePavingV1 | None = None
307
+ Shotcrete: ShotcreteV1 | None = None
308
+ CementGrout: CementGroutV1 | None = None
309
+
310
+ _compressive_strength_unit_validator = pyd.validator("strength_28d", allow_reuse=True, check_fields=False)(
311
+ validate_unit_factory(OpenEPDUnit.MPa)
312
+ )
313
+ _strength_early_unit_validator = pyd.validator("strength_early", allow_reuse=True)(
314
+ validate_unit_factory(OpenEPDUnit.MPa)
315
+ )
316
+ _strength_late_unit_validator = pyd.validator("strength_late", allow_reuse=True)(
317
+ validate_unit_factory(OpenEPDUnit.MPa)
318
+ )
319
+
320
+ @pyd.root_validator
321
+ def _late_validator(cls, values):
322
+ together_validator("strength_late", "strength_late_d", values)
323
+ return values
324
+
325
+ @pyd.root_validator
326
+ def _early_validator(cls, values):
327
+ together_validator("strength_early", "strength_early_d", values)
328
+ return values
329
+
330
+
331
+ class PrecastConcreteV1(BaseOpenEpdHierarchicalSpec):
332
+ """Precast Concrete spec."""
333
+
334
+ _EXT_VERSION = "1.0"
335
+
336
+ strength_28d: PressureMPaStr | None = pyd.Field(
337
+ default=None, example="30 MPa", description="Concrete strength after 28 days"
338
+ )
339
+
340
+ lightweight: bool | None = pyd.Field(description="Lightweight", default=None)
341
+ steel_mass_percentage: RatioFloat | None = pyd.Field(
342
+ default=None,
343
+ description="Percent of total mass that is steel reinforcement. Steel reinforcement "
344
+ "substantially changes functional performance and usually adds substantial GWP "
345
+ "per declared unit.",
346
+ )
347
+
348
+ insulated: bool | None = pyd.Field(description="Insulated", default=None)
349
+ gfrc: bool | None = pyd.Field(description="Glass Fiber Reinforced Concrete", default=None)
350
+
351
+ _compressive_strength_unit_validator = pyd.validator("strength_28d", allow_reuse=True)(
352
+ validate_unit_factory(OpenEPDUnit.MPa)
353
+ )
@@ -0,0 +1,63 @@
1
+ #
2
+ # Copyright 2024 by C Change Labs Inc. www.c-change-labs.com
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ # This software was developed with support from the Skanska USA,
17
+ # Charles Pankow Foundation, Microsoft Sustainability Fund, Interface, MKA Foundation, and others.
18
+ # Find out more at www.BuildingTransparency.org
19
+ #
20
+ from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
21
+
22
+
23
+ class BlanketFacingV1(BaseOpenEpdHierarchicalSpec):
24
+ """Blanket facing performance specification."""
25
+
26
+ _EXT_VERSION = "1.0"
27
+
28
+
29
+ class DoorsHardwareV1(BaseOpenEpdHierarchicalSpec):
30
+ """Doors hardware performance specification."""
31
+
32
+ _EXT_VERSION = "1.0"
33
+
34
+
35
+ class FlooringAccessoriesV1(BaseOpenEpdHierarchicalSpec):
36
+ """Flooring accessories performance specification."""
37
+
38
+ _EXT_VERSION = "1.0"
39
+
40
+
41
+ class MortarV1(BaseOpenEpdHierarchicalSpec):
42
+ """Mortar performance specification."""
43
+
44
+ _EXT_VERSION = "1.0"
45
+
46
+
47
+ class TileGroutV1(BaseOpenEpdHierarchicalSpec):
48
+ """Tile grout performance specification."""
49
+
50
+ _EXT_VERSION = "1.0"
51
+
52
+
53
+ class AccessoriesV1(BaseOpenEpdHierarchicalSpec):
54
+ """Accessories performance specification."""
55
+
56
+ _EXT_VERSION = "1.0"
57
+
58
+ # Nested specs:
59
+ BlanketFacing: BlanketFacingV1 | None = None
60
+ DoorsHardware: DoorsHardwareV1 | None = None
61
+ FlooringAccessories: FlooringAccessoriesV1 | None = None
62
+ Mortar: MortarV1 | None = None
63
+ TileGrout: TileGroutV1 | None = None
@@ -0,0 +1,71 @@
1
+ #
2
+ # Copyright 2024 by C Change Labs Inc. www.c-change-labs.com
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ # This software was developed with support from the Skanska USA,
17
+ # Charles Pankow Foundation, Microsoft Sustainability Fund, Interface, MKA Foundation, and others.
18
+ # Find out more at www.BuildingTransparency.org
19
+ #
20
+ from openepd.compat.pydantic import pyd
21
+ from openepd.model.base import BaseOpenEpdSchema
22
+ from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
23
+ from openepd.model.specs.generated.enums import AggregateGradation, AggregateWeightClassification
24
+ from openepd.model.validation.numbers import RatioFloat
25
+ from openepd.model.validation.quantity import LengthMmStr
26
+
27
+
28
+ class AggregateApplication(BaseOpenEpdSchema):
29
+ """Application for aggregates."""
30
+
31
+ concrete: bool | None = pyd.Field(default=None, description="Aggregates used in concrete and masonry applications")
32
+ asphalt: bool | None = pyd.Field(
33
+ default=None, description="Aggregates used in bituminous paving and surface applications"
34
+ )
35
+ unbound: bool | None = pyd.Field(default=None)
36
+
37
+
38
+ class AggregatesV1(BaseOpenEpdHierarchicalSpec):
39
+ """
40
+ Construction Aggregates.
41
+
42
+ Includes sand, gravel, crushed stone, etc. for use as bases, ballasts, or as a component in concrete or asphalt.
43
+ """
44
+
45
+ _EXT_VERSION = "1.0"
46
+
47
+ # Own fields:
48
+ recycled_content: RatioFloat | None = pyd.Field(
49
+ example=0.3, default=None, description="Percent of total mass that is recycled aggregate"
50
+ )
51
+ nominal_max_size: LengthMmStr | None = pyd.Field(
52
+ default=None,
53
+ example="10 mm",
54
+ description="Nominal maximum aggregate size is defined as one sieve size smaller than the maximum "
55
+ "aggregate size. "
56
+ "The maximum aggregate size is defined as the smallest sieve size that requires 100% passing.",
57
+ )
58
+ weight_classification: AggregateWeightClassification | None = pyd.Field(
59
+ example=str(AggregateWeightClassification.HEAVY_WEIGHT), default=None
60
+ )
61
+ gradation: AggregateGradation | None = pyd.Field(example=str(AggregateGradation.GAP), default=None)
62
+ manufactured: bool | None = pyd.Field(
63
+ default=None,
64
+ description="Aggregate produced via expansion or sintering at high temperatures of the following materials: "
65
+ "clay, shale, slate, perlite, vermiculite, or slag. Typically used to produce lightweight aggregate",
66
+ )
67
+ slag: bool | None = pyd.Field(
68
+ default=None,
69
+ description="Pelletized, foamed, and granulated blast furnace slag can be used as construction aggregate.",
70
+ )
71
+ application: AggregateApplication | None = None
@@ -0,0 +1,66 @@
1
+ #
2
+ # Copyright 2024 by C Change Labs Inc. www.c-change-labs.com
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ # This software was developed with support from the Skanska USA,
17
+ # Charles Pankow Foundation, Microsoft Sustainability Fund, Interface, MKA Foundation, and others.
18
+ # Find out more at www.BuildingTransparency.org
19
+ #
20
+ from openepd.compat.pydantic import pyd
21
+ from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
22
+ from openepd.model.specs.generated.enums import AluminiumAlloy
23
+
24
+
25
+ class AluminiumBilletsV1(BaseOpenEpdHierarchicalSpec):
26
+ """Aluminium billets performance specification."""
27
+
28
+ _EXT_VERSION = "1.0"
29
+
30
+
31
+ class AluminiumExtrusionsV1(BaseOpenEpdHierarchicalSpec):
32
+ """Aluminium extrusions performance specification."""
33
+
34
+ _EXT_VERSION = "1.0"
35
+
36
+ # Own fields:
37
+ thermally_improved: bool | None = pyd.Field(default=None, description="", example=True)
38
+
39
+
40
+ class AluminiumSheetGoodsV1(BaseOpenEpdHierarchicalSpec):
41
+ """Aluminium sheet goods performance specification."""
42
+
43
+ _EXT_VERSION = "1.0"
44
+
45
+
46
+ class AluminiumSuspensionAssemblyV1(BaseOpenEpdHierarchicalSpec):
47
+ """Aluminium suspension assembly performance specification."""
48
+
49
+ _EXT_VERSION = "1.0"
50
+
51
+
52
+ class AluminiumV1(BaseOpenEpdHierarchicalSpec):
53
+ """Material definition for objects made primarily from Aluminium and its alloys."""
54
+
55
+ _EXT_VERSION = "1.0"
56
+
57
+ # Own fields:
58
+ alloy: AluminiumAlloy | None = pyd.Field(default=None, description="", example=str(AluminiumAlloy.ALLOY_1XXX))
59
+ anodized: bool | None = pyd.Field(default=None, description="", example=True)
60
+ painted: bool | None = pyd.Field(default=None, description="", example=True)
61
+
62
+ # Nested specs:
63
+ AluminiumBillets: AluminiumBilletsV1 | None = None
64
+ AluminiumExtrusions: AluminiumExtrusionsV1 | None = None
65
+ AluminiumSheetGoods: AluminiumSheetGoodsV1 | None = None
66
+ AluminiumSuspensionAssembly: AluminiumSuspensionAssemblyV1 | None = None
@@ -0,0 +1,86 @@
1
+ #
2
+ # Copyright 2024 by C Change Labs Inc. www.c-change-labs.com
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ # This software was developed with support from the Skanska USA,
17
+ # Charles Pankow Foundation, Microsoft Sustainability Fund, Interface, MKA Foundation, and others.
18
+ # Find out more at www.BuildingTransparency.org
19
+ #
20
+ from openepd.compat.pydantic import pyd
21
+ from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
22
+ from openepd.model.specs.generated.enums import AsphaltGradation, AsphaltMixType
23
+ from openepd.model.validation.numbers import RatioFloat
24
+ from openepd.model.validation.quantity import LengthMmStr, TemperatureCStr, validate_unit_factory
25
+
26
+
27
+ class AsphaltV1(BaseOpenEpdHierarchicalSpec):
28
+ """Asphalt performance specification."""
29
+
30
+ _EXT_VERSION = "1.0"
31
+
32
+ # Own fields:
33
+ aggregate_size_max: LengthMmStr | None = pyd.Field(default=None, description="Max aggregate size", example="20 mm")
34
+ rap: RatioFloat | None = pyd.Field(
35
+ default=None,
36
+ description="Percent of mixture that has been replaced by recycled asphalt pavement (RAP).",
37
+ example=0.5,
38
+ ge=0,
39
+ le=1,
40
+ )
41
+ ras: RatioFloat | None = pyd.Field(
42
+ default=None,
43
+ description="Percent of mixture that has been replaced by recycled asphalt shingles (RAS).",
44
+ example=0.5,
45
+ ge=0,
46
+ le=1,
47
+ )
48
+ ground_tire_rubber: RatioFloat | None = pyd.Field(
49
+ default=None,
50
+ description="Percent of mixture that has been replaced by ground tire rubber (GTR).",
51
+ example=0.5,
52
+ ge=0,
53
+ le=1,
54
+ )
55
+ max_temperature: TemperatureCStr | None = pyd.Field(
56
+ default=None,
57
+ description="The upper threshold temperature to which an asphalt "
58
+ "binder can be heated preventing the asphalt mixture "
59
+ "from rutting",
60
+ example="90 °C",
61
+ )
62
+ min_temperature: TemperatureCStr | None = pyd.Field(
63
+ default=None,
64
+ description="The lower threshold temperature for an asphalt "
65
+ "binder to prevent thermal cracking of the asphalt"
66
+ " mixture.",
67
+ example="-20 °C",
68
+ )
69
+ mix_type: AsphaltMixType | None = pyd.Field(default=None, description="Asphalt mix type", example="WMA")
70
+ gradation: AsphaltGradation | None = pyd.Field(default=None, description="Asphalt gradation", example="Gap-graded")
71
+
72
+ sbr: bool | None = pyd.Field(default=None, description="Styrene-butadiene rubber (SBR)", example=True)
73
+ sbs: bool | None = pyd.Field(default=None, description="Styrene-butadiene-styrene (SBS)", example=True)
74
+ ppa: bool | None = pyd.Field(default=None, description="Polyphosphoric acid (PPA)", example=True)
75
+ gtr: bool | None = pyd.Field(default=None, description="Ground tire rubber (GTR)", example=True)
76
+ pmb: bool | None = pyd.Field(default=None, description="Polymer modified bitumen (PMB)", example=True)
77
+
78
+ _asphalt_aggregate_size_max_is_quantity_validator = pyd.validator("aggregate_size_max", allow_reuse=True)(
79
+ validate_unit_factory("m")
80
+ )
81
+ _asphalt_max_temperature_is_quantity_validator = pyd.validator("max_temperature", allow_reuse=True)(
82
+ validate_unit_factory("°C")
83
+ )
84
+ _asphalt_min_temperature_is_quantity_validator = pyd.validator("min_temperature", allow_reuse=True)(
85
+ validate_unit_factory("°C")
86
+ )
@@ -0,0 +1,26 @@
1
+ #
2
+ # Copyright 2024 by C Change Labs Inc. www.c-change-labs.com
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ # This software was developed with support from the Skanska USA,
17
+ # Charles Pankow Foundation, Microsoft Sustainability Fund, Interface, MKA Foundation, and others.
18
+ # Find out more at www.BuildingTransparency.org
19
+ #
20
+ from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
21
+
22
+
23
+ class BulkMaterialsV1(BaseOpenEpdHierarchicalSpec):
24
+ """Bulk materials performance specification."""
25
+
26
+ _EXT_VERSION = "1.0"