openepd 3.1.2__tar.gz → 3.1.3__tar.gz

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 (96) hide show
  1. {openepd-3.1.2 → openepd-3.1.3}/PKG-INFO +1 -1
  2. {openepd-3.1.2 → openepd-3.1.3}/pyproject.toml +1 -1
  3. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/__version__.py +1 -1
  4. openepd-3.1.3/src/openepd/compat/compat_functional_validators.py +29 -0
  5. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/compat/pydantic.py +6 -1
  6. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/concrete.py +1 -157
  7. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/asphalt.py +1 -11
  8. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/cladding.py +4 -16
  9. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/cmu.py +1 -8
  10. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/concrete.py +0 -19
  11. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/conveying_equipment.py +2 -12
  12. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/electrical.py +9 -12
  13. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/finishes.py +2 -36
  14. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/fire_and_smoke_protection.py +1 -3
  15. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/furnishings.py +1 -3
  16. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/masonry.py +5 -4
  17. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/mechanical.py +25 -93
  18. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/mechanical_insulation.py +1 -5
  19. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/network_infrastructure.py +2 -12
  20. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/openings.py +5 -17
  21. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/plumbing.py +3 -19
  22. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/precast_concrete.py +1 -5
  23. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/steel.py +9 -12
  24. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/thermal_moisture_protection.py +1 -15
  25. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/utility_piping.py +2 -10
  26. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/wood.py +1 -5
  27. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/validation/quantity.py +158 -16
  28. openepd-3.1.2/src/openepd/model/specs/aluminium.py +0 -67
  29. openepd-3.1.2/src/openepd/model/specs/glass.py +0 -360
  30. openepd-3.1.2/src/openepd/model/specs/steel.py +0 -184
  31. openepd-3.1.2/src/openepd/model/specs/wood.py +0 -130
  32. {openepd-3.1.2 → openepd-3.1.3}/LICENSE +0 -0
  33. {openepd-3.1.2 → openepd-3.1.3}/README.md +0 -0
  34. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/__init__.py +0 -0
  35. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/__init__.py +0 -0
  36. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/base_sync_client.py +0 -0
  37. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/category/__init__.py +0 -0
  38. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/category/dto.py +0 -0
  39. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/category/sync_api.py +0 -0
  40. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/common.py +0 -0
  41. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/dto/__init__.py +0 -0
  42. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/dto/base.py +0 -0
  43. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/dto/common.py +0 -0
  44. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/dto/meta.py +0 -0
  45. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/dto/mf.py +0 -0
  46. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/dto/params.py +0 -0
  47. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/epd/__init__.py +0 -0
  48. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/epd/dto.py +0 -0
  49. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/epd/sync_api.py +0 -0
  50. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/errors.py +0 -0
  51. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/pcr/__init__.py +0 -0
  52. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/pcr/dto.py +0 -0
  53. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/pcr/sync_api.py +0 -0
  54. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/sync_client.py +0 -0
  55. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/api/test/__init__.py +0 -0
  56. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/bundle/__init__.py +0 -0
  57. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/bundle/base.py +0 -0
  58. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/bundle/model.py +0 -0
  59. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/bundle/reader.py +0 -0
  60. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/bundle/writer.py +0 -0
  61. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/compat/__init__.py +0 -0
  62. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/__init__.py +0 -0
  63. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/base.py +0 -0
  64. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/category.py +0 -0
  65. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/common.py +0 -0
  66. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/epd.py +0 -0
  67. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/factory.py +0 -0
  68. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/lcia.py +0 -0
  69. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/org.py +0 -0
  70. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/pcr.py +0 -0
  71. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/README.md +0 -0
  72. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/__init__.py +0 -0
  73. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/asphalt.py +0 -0
  74. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/base.py +0 -0
  75. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/accessories.py +0 -0
  76. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/aggregates.py +0 -0
  77. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/aluminium.py +0 -0
  78. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/bulk_materials.py +0 -0
  79. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/cast_decks_and_underlayment.py +0 -0
  80. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/common.py +0 -0
  81. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/electrical_transmission_and_distribution_equipment.py +0 -0
  82. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/electricity.py +0 -0
  83. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/enums.py +0 -0
  84. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/grouting.py +0 -0
  85. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/manufacturing_inputs.py +0 -0
  86. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/material_handling.py +0 -0
  87. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/other_electrical_equipment.py +0 -0
  88. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/other_materials.py +0 -0
  89. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/sheathing.py +0 -0
  90. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/specs/generated/wood_joists.py +0 -0
  91. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/standard.py +0 -0
  92. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/validation/__init__.py +0 -0
  93. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/validation/common.py +0 -0
  94. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/validation/numbers.py +0 -0
  95. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/model/versioning.py +0 -0
  96. {openepd-3.1.2 → openepd-3.1.3}/src/openepd/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openepd
3
- Version: 3.1.2
3
+ Version: 3.1.3
4
4
  Summary: Python library to work with OpenEPD format
5
5
  Home-page: https://github.com/cchangelabs/openepd
6
6
  License: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "openepd"
3
- version = "3.1.2"
3
+ version = "3.1.3"
4
4
  license = "Apache-2.0"
5
5
  description = "Python library to work with OpenEPD format"
6
6
  authors = ["C-Change Labs <support@c-change-labs.com>"]
@@ -17,4 +17,4 @@
17
17
  # Charles Pankow Foundation, Microsoft Sustainability Fund, Interface, MKA Foundation, and others.
18
18
  # Find out more at www.BuildingTransparency.org
19
19
  #
20
- VERSION = "3.1.2"
20
+ VERSION = "3.1.3"
@@ -0,0 +1,29 @@
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 typing import Any
21
+
22
+ __all__ = ["AfterValidator"]
23
+
24
+
25
+ class AfterValidator:
26
+ """Placeholder stub for validator, unused in pydantic 1."""
27
+
28
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
29
+ pass
@@ -18,12 +18,17 @@
18
18
  # Find out more at www.BuildingTransparency.org
19
19
  #
20
20
  try:
21
+ from pydantic import functional_validators # type: ignore
21
22
  from pydantic import v1 as pyd # type: ignore
22
23
  from pydantic.v1 import generics as pyd_generics # type: ignore
24
+
23
25
  except ImportError:
24
26
  import pydantic as pyd # type: ignore[no-redef]
25
27
  from pydantic import generics as pyd_generics # type: ignore[no-redef]
26
28
 
29
+ from . import compat_functional_validators as functional_validators # type: ignore[no-redef]
30
+
31
+
27
32
  pydantic = pyd
28
33
 
29
- __all__ = ["pyd", "pydantic", "pyd_generics"]
34
+ __all__ = ["pyd", "pydantic", "pyd_generics", "functional_validators"]
@@ -18,16 +18,11 @@
18
18
  # Find out more at www.BuildingTransparency.org
19
19
  #
20
20
  from enum import StrEnum
21
- from typing import Literal
22
21
 
23
22
  from openepd.compat.pydantic import pyd
24
23
  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
24
+ from openepd.model.specs.base import BaseOpenEpdSpec
29
25
  from openepd.model.validation.numbers import RatioFloat
30
- from openepd.model.validation.quantity import LengthMmStr, PressureMPaStr, validate_unit_factory
31
26
 
32
27
 
33
28
  class CmuWeightClassification(StrEnum):
@@ -208,154 +203,3 @@ class ConcreteV1Options(BaseOpenEpdSchema):
208
203
  co2: bool | None = pyd.Field(description="CO2 Curing", default=None)
209
204
  white: bool | None = pyd.Field(description="White Cement", default=None)
210
205
  fiber_reinforced: bool | None = pyd.Field(description="Fiber reinforced", default=None)
211
-
212
-
213
- class ReadyMixV1(BaseOpenEpdHierarchicalSpec):
214
- """Concretes to be mixed and then poured on-site."""
215
-
216
- _EXT_VERSION = "1.0"
217
-
218
-
219
- class FlowableFillV1(BaseOpenEpdHierarchicalSpec):
220
- """
221
- Flowable fill is a slurry that is placed as a flowable liquid (high slump) and sets with no compaction.
222
-
223
- It is often used in tight or restricted access areas where placing and compacting
224
- fill is difficult. Applications include filling large voids such as abandoned underground storage
225
- tanks, basements, tunnels, mines, and sewers. It can also be used as paving sub-base, bridge
226
- abutment, and retaining wall backfill. Also called Controlled Density Fill (CDF) or Controlled
227
- Low Strength Materials (CLSMs). These materials typically have compressive strengths
228
- under 1200 psi.
229
- """
230
-
231
- _EXT_VERSION = "1.0"
232
-
233
-
234
- class OilPatchV1(BaseOpenEpdHierarchicalSpec):
235
- """
236
- Concretes for use in petroleum extraction wells and similar applications.
237
-
238
- Includes foamed cement; often called cement in the drilling industry. Differs from
239
- flowable fill and grout in that it contains no sand or other aggregates.
240
- """
241
-
242
- _EXT_VERSION = "1.0"
243
-
244
-
245
- class ConcretePavingV1(BaseOpenEpdHierarchicalSpec):
246
- """Concrete paving."""
247
-
248
- _EXT_VERSION = "1.0"
249
-
250
-
251
- class ShotcreteV1(BaseOpenEpdHierarchicalSpec):
252
- """Concretes sprayed on a target."""
253
-
254
- _EXT_VERSION = "1.0"
255
-
256
-
257
- class CementGroutV1(BaseOpenEpdHierarchicalSpec):
258
- """
259
- Cement grouting is a slurry that is placed as a flowable liquid.
260
-
261
- It is an effective material for filling and
262
- strengthening granular soils, voids in rocks, foundation underpinnings, and other underground voids. Also called
263
- structural grout, these materials typically impart significant compressive strength to the system.
264
-
265
- """
266
-
267
- _EXT_VERSION = "1.0"
268
-
269
-
270
- class ConcreteV1(BaseOpenEpdHierarchicalSpec):
271
- """Concrete spec."""
272
-
273
- _EXT_VERSION = "1.0"
274
-
275
- strength_28d: PressureMPaStr | None = pyd.Field(
276
- default=None, example="30 MPa", description="Concrete strength after 28 days"
277
- )
278
- strength_early: PressureMPaStr | None = pyd.Field(
279
- default=None,
280
- example="30 MPa",
281
- description="A strength spec which is to be reached earlier than 28 days (e.g. 3d)",
282
- )
283
- strength_early_d: Literal[3, 7, 14] | None = pyd.Field(default=None, description="Test Day for the Early Strength")
284
- strength_late: PressureMPaStr | None = pyd.Field(
285
- default=None,
286
- example="30 MPa",
287
- description="A strength spec which is to be reached later than 28 days (e.g. 42d)",
288
- )
289
- strength_late_d: Literal[42, 56, 72, 96, 120] | None = pyd.Field(
290
- default=None, description="Test Day for the Late Strength"
291
- )
292
- slump: LengthMmStr | None = pyd.Field(description="Minimum test slump", example="40 mm", default=None)
293
- w_c_ratio: RatioFloat | None = pyd.Field(description="Ratio of water to cement", example=0.3, default=None)
294
- aci_exposure_classes: list[AciExposureClass] = pyd.Field(
295
- description=(AciExposureClass.__doc__ or "").lstrip(), default_factory=list
296
- )
297
- csa_exposure_classes: list[CsaExposureClass] = pyd.Field(
298
- description=(CsaExposureClass.__doc__ or "").lstrip(), default_factory=list
299
- )
300
- en_exposure_classes: list[EnExposureClass] = pyd.Field(
301
- description=(EnExposureClass.__doc__ or "").lstrip(), default_factory=list
302
- )
303
- cementitious: Cementitious | None = pyd.Field(
304
- default=None,
305
- description="List of cementitious materials, and proportion by mass. Each field is 0 to 1.",
306
- )
307
- application: TypicalApplication | None = pyd.Field(description="Typical Application", default=None)
308
- options: ConcreteV1Options | None = pyd.Field(description="Concrete options", default=None)
309
-
310
- # Nested specs
311
- ReadyMix: ReadyMixV1 | None = None
312
- FlowableFill: FlowableFillV1 | None = None
313
- OilPatch: OilPatchV1 | None = None
314
- ConcretePaving: ConcretePavingV1 | None = None
315
- Shotcrete: ShotcreteV1 | None = None
316
- CementGrout: CementGroutV1 | None = None
317
-
318
- _compressive_strength_unit_validator = pyd.validator("strength_28d", allow_reuse=True, check_fields=False)(
319
- validate_unit_factory(OpenEPDUnit.MPa)
320
- )
321
- _strength_early_unit_validator = pyd.validator("strength_early", allow_reuse=True)(
322
- validate_unit_factory(OpenEPDUnit.MPa)
323
- )
324
- _strength_late_unit_validator = pyd.validator("strength_late", allow_reuse=True)(
325
- validate_unit_factory(OpenEPDUnit.MPa)
326
- )
327
-
328
- @pyd.root_validator
329
- def _late_validator(cls, values):
330
- together_validator("strength_late", "strength_late_d", values)
331
- return values
332
-
333
- @pyd.root_validator
334
- def _early_validator(cls, values):
335
- together_validator("strength_early", "strength_early_d", values)
336
- return values
337
-
338
-
339
- class PrecastConcreteV1(BaseOpenEpdHierarchicalSpec):
340
- """Precast Concrete spec."""
341
-
342
- _EXT_VERSION = "1.0"
343
-
344
- strength_28d: PressureMPaStr | None = pyd.Field(
345
- default=None, example="30 MPa", description="Concrete strength after 28 days"
346
- )
347
-
348
- lightweight: bool | None = pyd.Field(description="Lightweight", default=None)
349
- steel_mass_percentage: RatioFloat | None = pyd.Field(
350
- default=None,
351
- description="Percent of total mass that is steel reinforcement. Steel reinforcement "
352
- "substantially changes functional performance and usually adds substantial GWP "
353
- "per declared unit.",
354
- )
355
-
356
- insulated: bool | None = pyd.Field(description="Insulated", default=None)
357
- gfrc: bool | None = pyd.Field(description="Glass Fiber Reinforced Concrete", default=None)
358
-
359
- _compressive_strength_unit_validator = pyd.validator("strength_28d", allow_reuse=True)(
360
- validate_unit_factory(OpenEPDUnit.MPa)
361
- )
@@ -21,7 +21,7 @@ from openepd.compat.pydantic import pyd
21
21
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
22
22
  from openepd.model.specs.generated.enums import AsphaltGradation, AsphaltMixType
23
23
  from openepd.model.validation.numbers import RatioFloat
24
- from openepd.model.validation.quantity import LengthMmStr, TemperatureCStr, validate_unit_factory
24
+ from openepd.model.validation.quantity import LengthMmStr, TemperatureCStr
25
25
 
26
26
 
27
27
  class AsphaltV1(BaseOpenEpdHierarchicalSpec):
@@ -74,13 +74,3 @@ class AsphaltV1(BaseOpenEpdHierarchicalSpec):
74
74
  ppa: bool | None = pyd.Field(default=None, description="Polyphosphoric acid (PPA)", example=True)
75
75
  gtr: bool | None = pyd.Field(default=None, description="Ground tire rubber (GTR)", example=True)
76
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
- )
@@ -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 CladdingFacingMaterial, CladdingInsulatingMaterial, SidingFormFactor
23
- from openepd.model.validation.quantity import LengthMmStr, LengthMStr, validate_unit_factory
23
+ from openepd.model.validation.quantity import LengthMmStr, LengthMStr, RValueStr, validate_unit_factory
24
24
 
25
25
 
26
26
  class AluminiumSidingV1(BaseOpenEpdHierarchicalSpec):
@@ -126,13 +126,9 @@ class SidingV1(BaseOpenEpdHierarchicalSpec):
126
126
  insulated: bool | None = pyd.Field(default=None, description="", example=True)
127
127
  ventilated: bool | None = pyd.Field(default=None, description="", example=True)
128
128
  paint_or_stain_required: bool | None = pyd.Field(default=None, description="", example=True)
129
- r_value: str | None = pyd.Field(default=None, description="", example="1 K * m2 / W")
129
+ r_value: RValueStr | None = pyd.Field(default=None, description="")
130
130
  form_factor: SidingFormFactor | None = pyd.Field(default=None, description="", example="Lap")
131
131
 
132
- _siding_r_value_is_quantity_validator = pyd.validator("r_value", allow_reuse=True)(
133
- validate_unit_factory("K * m2 / W")
134
- )
135
-
136
132
  # Nested specs:
137
133
  MetalSiding: MetalSidingV1 | None = None
138
134
  CompositionSiding: CompositionSidingV1 | None = None
@@ -150,15 +146,11 @@ class InsulatedRoofPanelsV1(BaseOpenEpdHierarchicalSpec):
150
146
  _EXT_VERSION = "1.0"
151
147
 
152
148
  # Own fields:
153
- r_value: str | None = pyd.Field(default=None, description="", example="1 K * m2 / W")
149
+ r_value: RValueStr | None = pyd.Field(default=None, description="")
154
150
  insulating_material: CladdingInsulatingMaterial | None = pyd.Field(
155
151
  default=None, description="", example="No Insulation"
156
152
  )
157
153
 
158
- _cladding_r_value_is_quantity_validator = pyd.validator("r_value", allow_reuse=True)(
159
- validate_unit_factory("K * m2 / W")
160
- )
161
-
162
154
 
163
155
  class InsulatedWallPanelsV1(BaseOpenEpdHierarchicalSpec):
164
156
  """Insulated wall panels performance specification."""
@@ -166,15 +158,11 @@ class InsulatedWallPanelsV1(BaseOpenEpdHierarchicalSpec):
166
158
  _EXT_VERSION = "1.0"
167
159
 
168
160
  # Own fields:
169
- r_value: str | None = pyd.Field(default=None, description="", example="1 K * m2 / W")
161
+ r_value: RValueStr | None = pyd.Field(default=None, description="")
170
162
  insulating_material: CladdingInsulatingMaterial | None = pyd.Field(
171
163
  default=None, description="", example="No Insulation"
172
164
  )
173
165
 
174
- _cladding_r_value_is_quantity_validator = pyd.validator("r_value", allow_reuse=True)(
175
- validate_unit_factory("K * m2 / W")
176
- )
177
-
178
166
 
179
167
  class RoofPanelsV1(BaseOpenEpdHierarchicalSpec):
180
168
  """Roof panels 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.specs.generated.enums import CmuBlockType, CmuWeightClassification
23
- from openepd.model.validation.quantity import GwpKgCo2eStr, PressureMPaStr, validate_unit_factory
23
+ from openepd.model.validation.quantity import GwpKgCo2eStr, PressureMPaStr
24
24
 
25
25
 
26
26
  class CMUV1(BaseOpenEpdHierarchicalSpec):
@@ -37,10 +37,3 @@ class CMUV1(BaseOpenEpdHierarchicalSpec):
37
37
  sound_performance: bool | None = pyd.Field(default=None, description="", example=True)
38
38
  b1_recarbonation: GwpKgCo2eStr | None = pyd.Field(default=None, description="", example="1 kgCO2e")
39
39
  b1_recarbonation_z: float | None = pyd.Field(default=None, description="", example=2.3)
40
-
41
- _concrete_compressive_strength_28d_is_quantity_validator = pyd.validator("strength_28d", allow_reuse=True)(
42
- validate_unit_factory("MPa")
43
- )
44
- _b1_recarbonation_is_quantity_validator = pyd.validator("b1_recarbonation", allow_reuse=True)(
45
- validate_unit_factory("kgCO2e")
46
- )
@@ -168,25 +168,6 @@ class ConcreteV1(BaseOpenEpdHierarchicalSpec):
168
168
  )
169
169
  typical_application: ConcreteTypicalApplication | None = pyd.Field(default=None, description="Typical Application")
170
170
 
171
- _concrete_compressive_strength_28d_is_quantity_validator = pyd.validator("strength_28d", allow_reuse=True)(
172
- validate_unit_factory("MPa")
173
- )
174
- _concrete_compressive_strength_other_is_quantity_validator = pyd.validator("strength_other", allow_reuse=True)(
175
- validate_unit_factory("MPa")
176
- )
177
- _concrete_slump_is_quantity_validator = pyd.validator("slump", allow_reuse=True)(validate_unit_factory("m"))
178
- _concrete_min_slump_is_quantity_validator = pyd.validator("min_slump", allow_reuse=True)(validate_unit_factory("m"))
179
- _concrete_max_slump_is_quantity_validator = pyd.validator("max_slump", allow_reuse=True)(validate_unit_factory("m"))
180
- _concrete_min_pipeline_size_is_quantity_validator = pyd.validator("min_pipeline_size", allow_reuse=True)(
181
- validate_unit_factory("m")
182
- )
183
- _concrete_aggregate_size_max_is_quantity_validator = pyd.validator("aggregate_size_max", allow_reuse=True)(
184
- validate_unit_factory("m")
185
- )
186
- _concrete_cement_content_is_quantity_validator = pyd.validator("cement_content", allow_reuse=True)(
187
- validate_unit_factory("kg")
188
- )
189
-
190
171
  # Nested specs:
191
172
  CementGrout: CementGroutV1 | None = None
192
173
  ConcretePaving: ConcretePavingV1 | 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 ElevatorsBuildingRise, ElevatorsUsageIntensity
23
- from openepd.model.validation.quantity import LengthMStr, MassKgStr, validate_unit_factory
23
+ from openepd.model.validation.quantity import LengthMStr, MassKgStr, SpeedStr
24
24
 
25
25
 
26
26
  class ElevatorsV1(BaseOpenEpdHierarchicalSpec):
@@ -34,19 +34,9 @@ class ElevatorsV1(BaseOpenEpdHierarchicalSpec):
34
34
  )
35
35
  travel_length: LengthMStr | None = pyd.Field(default=None, description="", example="1 m")
36
36
  rated_load: MassKgStr | None = pyd.Field(default=None, description="", example="1 kg")
37
- rated_speed: str | None = pyd.Field(default=None, description="", example="1 m / s")
37
+ rated_speed: SpeedStr | None = pyd.Field(default=None, description="", example="1 m / s")
38
38
  building_rise: ElevatorsBuildingRise | None = pyd.Field(default=None, description="", example="Low-rise")
39
39
 
40
- _elevators_travel_length_is_quantity_validator = pyd.validator("travel_length", allow_reuse=True)(
41
- validate_unit_factory("m")
42
- )
43
- _elevators_rated_load_is_quantity_validator = pyd.validator("rated_load", allow_reuse=True)(
44
- validate_unit_factory("kg")
45
- )
46
- _elevators_rated_speed_is_quantity_validator = pyd.validator("rated_speed", allow_reuse=True)(
47
- validate_unit_factory("m / s")
48
- )
49
-
50
40
 
51
41
  class ConveyingEquipmentV1(BaseOpenEpdHierarchicalSpec):
52
42
  """Conveying equipment performance specification."""
@@ -21,10 +21,12 @@ from openepd.compat.pydantic import pyd
21
21
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
22
22
  from openepd.model.specs.generated.enums import CableTraysMaterial, EnergySource, RacewaysMaterial
23
23
  from openepd.model.validation.quantity import (
24
+ ColorTemperatureStr,
24
25
  LengthMmStr,
25
26
  LengthMStr,
27
+ LuminosityStr,
26
28
  MassKgStr,
27
- TemperatureCStr,
29
+ PowerStr,
28
30
  validate_quantity_ge_factory,
29
31
  validate_quantity_le_factory,
30
32
  validate_unit_factory,
@@ -70,11 +72,6 @@ class CableTraysV1(BaseOpenEpdHierarchicalSpec):
70
72
  )
71
73
  cable_trays_material: CableTraysMaterial | None = pyd.Field(default=None, description="", example="Stainless Steel")
72
74
 
73
- _height_is_quantity_validator = pyd.validator("height", allow_reuse=True)(validate_unit_factory("m"))
74
- _width_is_quantity_validator = pyd.validator("width", allow_reuse=True)(validate_unit_factory("m"))
75
- _depth_is_quantity_validator = pyd.validator("depth", allow_reuse=True)(validate_unit_factory("m"))
76
- _static_load_is_quantity_validator = pyd.validator("static_load", allow_reuse=True)(validate_unit_factory("kg"))
77
-
78
75
 
79
76
  class ElectricalBusesV1(BaseOpenEpdHierarchicalSpec):
80
77
  """Electrical buses performance specification."""
@@ -110,9 +107,6 @@ class RacewaysV1(BaseOpenEpdHierarchicalSpec):
110
107
  divided: bool | None = pyd.Field(default=None, description="", example=True)
111
108
  raceways_material: RacewaysMaterial | None = pyd.Field(default=None, description="", example="Aluminum")
112
109
 
113
- _width_is_quantity_validator = pyd.validator("width", allow_reuse=True)(validate_unit_factory("m"))
114
- _depth_is_quantity_validator = pyd.validator("depth", allow_reuse=True)(validate_unit_factory("m"))
115
-
116
110
 
117
111
  class FueledElectricalGeneratorsV1(BaseOpenEpdHierarchicalSpec):
118
112
  """Fueled electrical generators performance specification."""
@@ -250,10 +244,10 @@ class LightingV1(BaseOpenEpdHierarchicalSpec):
250
244
  _EXT_VERSION = "1.0"
251
245
 
252
246
  # Own fields:
253
- color_temperature: TemperatureCStr | None = pyd.Field(default=None, description="", example="1 K")
247
+ color_temperature: ColorTemperatureStr | None = pyd.Field(default=None, description="", example="1 K")
254
248
  typical_utilization: str | None = pyd.Field(default=None, description="", example="1 h / yr")
255
- luminosity: str | None = pyd.Field(default=None, description="", example="1 lumen")
256
- wattage: str | None = pyd.Field(default=None, description="", example="1000.0 W")
249
+ luminosity: LuminosityStr | None = pyd.Field(default=None, description="", example="1 lumen")
250
+ wattage: PowerStr | None = pyd.Field(default=None, description="")
257
251
  color_rendering_index: float | None = pyd.Field(default=None, description="", example=2.3)
258
252
  dimmable: bool | None = pyd.Field(default=None, description="", example=True)
259
253
 
@@ -263,6 +257,9 @@ class LightingV1(BaseOpenEpdHierarchicalSpec):
263
257
  _color_temperature_quantity_le_validator = pyd.validator("color_temperature", allow_reuse=True)(
264
258
  validate_quantity_le_factory("1E+04 K")
265
259
  )
260
+ _typical_utilization_unit_validator = pyd.validator("typical_utilization", allow_reuse=True)(
261
+ validate_unit_factory("h / yr")
262
+ )
266
263
  _typical_utilization_quantity_ge_validator = pyd.validator("typical_utilization", allow_reuse=True)(
267
264
  validate_quantity_ge_factory("25 h / yr")
268
265
  )
@@ -81,18 +81,6 @@ class AccessFlooringV1(BaseOpenEpdHierarchicalSpec):
81
81
  rolling_load_10_pass: str | None = pyd.Field(default=None, description="", example="1 N")
82
82
  rolling_load_10000_pass: str | None = pyd.Field(default=None, description="", example="1 N")
83
83
 
84
- _access_flooring_finished_floor_height_is_quantity_validator = pyd.validator(
85
- "finished_floor_height", allow_reuse=True
86
- )(validate_unit_factory("m"))
87
- _access_flooring_panel_thickness_is_quantity_validator = pyd.validator("panel_thickness", allow_reuse=True)(
88
- validate_unit_factory("m")
89
- )
90
- _access_flooring_concentrated_load_is_quantity_validator = pyd.validator("concentrated_load", allow_reuse=True)(
91
- validate_unit_factory("MPa")
92
- )
93
- _access_flooring_uniform_load_is_quantity_validator = pyd.validator("uniform_load", allow_reuse=True)(
94
- validate_unit_factory("MPa")
95
- )
96
84
  _access_flooring_rolling_load_10_pass_is_quantity_validator = pyd.validator(
97
85
  "rolling_load_10_pass", allow_reuse=True
98
86
  )(validate_unit_factory("N"))
@@ -124,15 +112,8 @@ class CarpetV1(BaseOpenEpdHierarchicalSpec):
124
112
  gwp_factor_base: GwpKgCo2eStr | None = pyd.Field(default=None, description="", example="1 kgCO2e")
125
113
  gwp_factor_yarn: GwpKgCo2eStr | None = pyd.Field(default=None, description="", example="1 kgCO2e")
126
114
 
127
- _length_is_quantity_validator = pyd.validator("length", allow_reuse=True)(validate_unit_factory("m"))
128
- _width_is_quantity_validator = pyd.validator("width", allow_reuse=True)(validate_unit_factory("m"))
129
115
  _yarn_weight_is_quantity_validator = pyd.validator("yarn_weight", allow_reuse=True)(validate_unit_factory("g / m2"))
130
- _gwp_factor_base_is_quantity_validator = pyd.validator("gwp_factor_base", allow_reuse=True)(
131
- validate_unit_factory("kgCO2e")
132
- )
133
- _gwp_factor_yarn_is_quantity_validator = pyd.validator("gwp_factor_yarn", allow_reuse=True)(
134
- validate_unit_factory("kgCO2e")
135
- )
116
+ _yarn_weight_ge_validator = pyd.validator("yarn_weight", allow_reuse=True)(validate_quantity_ge_factory("0 g / m2"))
136
117
 
137
118
 
138
119
  class LaminateV1(BaseOpenEpdHierarchicalSpec):
@@ -167,12 +148,6 @@ class ResilientFlooringV1(BaseOpenEpdHierarchicalSpec):
167
148
  floor_score: bool | None = pyd.Field(default=None, description="", example=True)
168
149
  nsf332: bool | None = pyd.Field(default=None, description="", example=True)
169
150
 
170
- _length_is_quantity_validator = pyd.validator("length", allow_reuse=True)(validate_unit_factory("m"))
171
- _width_is_quantity_validator = pyd.validator("width", allow_reuse=True)(validate_unit_factory("m"))
172
- _resilient_flooring_wear_layer_is_quantity_validator = pyd.validator("wear_layer", allow_reuse=True)(
173
- validate_unit_factory("m")
174
- )
175
-
176
151
 
177
152
  class WallBaseV1(BaseOpenEpdHierarchicalSpec):
178
153
  """Wall base performance specification."""
@@ -194,8 +169,6 @@ class WoodFlooringV1(BaseOpenEpdHierarchicalSpec, HasForestPracticesCertifiers):
194
169
  fabrication: WoodFlooringFabrication | None = pyd.Field(default=None, description="", example="Solid hardwood")
195
170
  forest_practices_certifiers: list[OrgRef] | None = pyd.Field(default=None, description="")
196
171
 
197
- _thickness_is_quantity_validator = pyd.validator("thickness", allow_reuse=True)(validate_unit_factory("m"))
198
-
199
172
 
200
173
  class AcousticalCeilingsV1(BaseOpenEpdHierarchicalSpec):
201
174
  """Acoustical ceilings performance specification."""
@@ -205,8 +178,6 @@ class AcousticalCeilingsV1(BaseOpenEpdHierarchicalSpec):
205
178
  # Own fields:
206
179
  thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="10 mm")
207
180
 
208
- _thickness_is_quantity_validator = pyd.validator("thickness", allow_reuse=True)(validate_unit_factory("m"))
209
-
210
181
 
211
182
  class CeramicTileV1(BaseOpenEpdHierarchicalSpec):
212
183
  """Ceramic tile performance specification."""
@@ -373,7 +344,7 @@ class TilingV1(BaseOpenEpdHierarchicalSpec):
373
344
  _EXT_VERSION = "1.0"
374
345
 
375
346
  # Own fields:
376
- thickness: LengthMStr | None = pyd.Field(default=None, description="", example="1 m")
347
+ thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="9 mm")
377
348
  flooring: bool | None = pyd.Field(default=None, description="Tiling intended for walking.", example=True)
378
349
  wall_finish: bool | None = pyd.Field(
379
350
  default=None,
@@ -418,8 +389,6 @@ class TilingV1(BaseOpenEpdHierarchicalSpec):
418
389
  le=1,
419
390
  )
420
391
 
421
- _thickness_is_quantity_validator = pyd.validator("thickness", allow_reuse=True)(validate_unit_factory("m"))
422
- _thickness_min_validator = pyd.validator("thickness", allow_reuse=True)(validate_quantity_ge_factory("0 mm"))
423
392
  _thickness_max_validator = pyd.validator("thickness", allow_reuse=True)(validate_quantity_le_factory("50 mm"))
424
393
 
425
394
  # Nested specs:
@@ -470,7 +439,6 @@ class GypsumV1(BaseOpenEpdHierarchicalSpec):
470
439
  moisture_resistant: bool | None = pyd.Field(default=None, description="", example=True)
471
440
  abuse_resistant: bool | None = pyd.Field(default=None, description="", example=True)
472
441
 
473
- _gypsum_thickness_is_quantity_validator = pyd.validator("thickness", allow_reuse=True)(validate_unit_factory("m"))
474
442
  _gypsum_r_factor_is_quantity_validator = pyd.validator("r_factor", allow_reuse=True)(validate_unit_factory("RSI"))
475
443
 
476
444
  # Nested specs:
@@ -497,8 +465,6 @@ class WallFinishesV1(BaseOpenEpdHierarchicalSpec):
497
465
  # Own fields:
498
466
  thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="10 mm")
499
467
 
500
- _thickness_is_quantity_validator = pyd.validator("thickness", allow_reuse=True)(validate_unit_factory("m"))
501
-
502
468
 
503
469
  class FinishesV1(BaseOpenEpdHierarchicalSpec):
504
470
  """Finishes performance specification."""
@@ -24,7 +24,7 @@ from openepd.model.specs.generated.enums import (
24
24
  SprayFireproofingDensity,
25
25
  SprayFireproofingMaterialType,
26
26
  )
27
- from openepd.model.validation.quantity import LengthMmStr, validate_unit_factory
27
+ from openepd.model.validation.quantity import LengthMmStr
28
28
 
29
29
 
30
30
  class IntumescentFireproofingV1(BaseOpenEpdHierarchicalSpec):
@@ -56,8 +56,6 @@ class AppliedFireproofingV1(BaseOpenEpdHierarchicalSpec):
56
56
  # Own fields:
57
57
  thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="10 mm")
58
58
 
59
- _thickness_is_quantity_validator = pyd.validator("thickness", allow_reuse=True)(validate_unit_factory("m"))
60
-
61
59
  # Nested specs:
62
60
  IntumescentFireproofing: IntumescentFireproofingV1 | None = None
63
61
  SprayFireproofing: SprayFireproofingV1 | 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 CountertopMaterial
23
- from openepd.model.validation.quantity import LengthMmStr, validate_unit_factory
23
+ from openepd.model.validation.quantity import LengthMmStr
24
24
 
25
25
 
26
26
  class DemountablePartitionTrackV1(BaseOpenEpdHierarchicalSpec):
@@ -44,8 +44,6 @@ class CountertopsV1(BaseOpenEpdHierarchicalSpec):
44
44
  thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="30 mm")
45
45
  countertop_material: CountertopMaterial | None = pyd.Field(default=None, description="", example="Stone")
46
46
 
47
- _thickness_is_quantity_validator = pyd.validator("thickness", allow_reuse=True)(validate_unit_factory("m"))
48
-
49
47
 
50
48
  class DemountablePartitionsV1(BaseOpenEpdHierarchicalSpec):
51
49
  """Demountable partitions performance specification."""
@@ -19,7 +19,7 @@
19
19
  #
20
20
  from openepd.compat.pydantic import pyd
21
21
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
22
- from openepd.model.validation.quantity import PressureMPaStr, validate_unit_factory
22
+ from openepd.model.validation.quantity import PressureMPaStr, validate_quantity_ge_factory, validate_unit_factory
23
23
 
24
24
 
25
25
  class GMUV1(BaseOpenEpdHierarchicalSpec):
@@ -38,13 +38,14 @@ class AutoclavedAeratedConcreteV1(BaseOpenEpdHierarchicalSpec):
38
38
  thermal_conductivity: str | None = pyd.Field(default=None, description="", example="1 W / (m * K)")
39
39
  white: bool | None = pyd.Field(default=None, description="", example=True)
40
40
 
41
- _concrete_compressive_strength_28d_is_quantity_validator = pyd.validator("strength_28d", allow_reuse=True)(
42
- validate_unit_factory("MPa")
43
- )
44
41
  _aac_thermal_conductivity_is_quantity_validator = pyd.validator("thermal_conductivity", allow_reuse=True)(
45
42
  validate_unit_factory("W / (m * K)")
46
43
  )
47
44
 
45
+ _aac_thermal_conductivity_min_validator = pyd.validator("thermal_conductivity", allow_reuse=True)(
46
+ validate_quantity_ge_factory("0 W / (m * K)")
47
+ )
48
+
48
49
 
49
50
  class BrickV1(BaseOpenEpdHierarchicalSpec):
50
51
  """Brick performance specification."""