openepd 5.1.0__py3-none-any.whl → 6.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 (81) hide show
  1. openepd/__version__.py +1 -1
  2. openepd/api/average_dataset/generic_estimate_sync_api.py +11 -3
  3. openepd/api/epd/sync_api.py +6 -2
  4. openepd/api/utils.py +40 -0
  5. openepd/bundle/model.py +3 -0
  6. openepd/model/common.py +65 -1
  7. openepd/model/epd.py +1 -1
  8. openepd/model/org.py +0 -1
  9. openepd/model/specs/__init__.py +34 -75
  10. openepd/model/specs/base.py +2 -1
  11. openepd/model/specs/{generated/enums.py → enums.py} +51 -3
  12. openepd/model/specs/range/aggregates.py +2 -2
  13. openepd/model/specs/range/aluminium.py +1 -1
  14. openepd/model/specs/range/asphalt.py +4 -4
  15. openepd/model/specs/range/cladding.py +1 -1
  16. openepd/model/specs/range/cmu.py +6 -5
  17. openepd/model/specs/range/concrete.py +1 -1
  18. openepd/model/specs/range/conveying_equipment.py +1 -1
  19. openepd/model/specs/range/electrical.py +3 -2
  20. openepd/model/specs/range/finishes.py +13 -6
  21. openepd/model/specs/range/fire_and_smoke_protection.py +1 -1
  22. openepd/model/specs/range/furnishings.py +1 -1
  23. openepd/model/specs/range/manufacturing_inputs.py +1 -1
  24. openepd/model/specs/range/masonry.py +2 -2
  25. openepd/model/specs/range/mechanical.py +1 -1
  26. openepd/model/specs/range/mechanical_insulation.py +1 -1
  27. openepd/model/specs/range/network_infrastructure.py +1 -1
  28. openepd/model/specs/range/openings.py +12 -5
  29. openepd/model/specs/range/plumbing.py +1 -1
  30. openepd/model/specs/range/precast_concrete.py +1 -1
  31. openepd/model/specs/range/sheathing.py +3 -3
  32. openepd/model/specs/range/steel.py +10 -5
  33. openepd/model/specs/range/thermal_moisture_protection.py +1 -1
  34. openepd/model/specs/range/utility_piping.py +1 -1
  35. openepd/model/specs/range/wood.py +8 -6
  36. openepd/model/specs/range/wood_joists.py +1 -1
  37. openepd/model/specs/{generated → singular}/__init__.py +37 -35
  38. openepd/model/specs/{generated → singular}/aggregates.py +1 -1
  39. openepd/model/specs/{generated → singular}/aluminium.py +1 -1
  40. openepd/model/specs/{generated → singular}/asphalt.py +6 -4
  41. openepd/model/specs/{generated → singular}/cladding.py +1 -1
  42. openepd/model/specs/{generated → singular}/cmu.py +10 -4
  43. openepd/model/specs/{generated → singular}/concrete.py +12 -1
  44. openepd/model/specs/{generated → singular}/conveying_equipment.py +1 -1
  45. openepd/model/specs/{generated → singular}/electrical.py +4 -3
  46. openepd/model/specs/{generated → singular}/finishes.py +9 -6
  47. openepd/model/specs/{generated → singular}/fire_and_smoke_protection.py +1 -1
  48. openepd/model/specs/{generated → singular}/furnishings.py +1 -1
  49. openepd/model/specs/{generated → singular}/manufacturing_inputs.py +1 -1
  50. openepd/model/specs/{generated → singular}/masonry.py +4 -1
  51. openepd/model/specs/{generated → singular}/mechanical.py +1 -1
  52. openepd/model/specs/{generated → singular}/mechanical_insulation.py +1 -1
  53. openepd/model/specs/{generated → singular}/mixins/conduit_mixin.py +1 -1
  54. openepd/model/specs/{generated → singular}/network_infrastructure.py +2 -2
  55. openepd/model/specs/{generated → singular}/openings.py +10 -4
  56. openepd/model/specs/{generated → singular}/plumbing.py +1 -1
  57. openepd/model/specs/{generated → singular}/sheathing.py +3 -3
  58. openepd/model/specs/{generated → singular}/steel.py +11 -5
  59. openepd/model/specs/{generated → singular}/thermal_moisture_protection.py +1 -1
  60. openepd/model/specs/{generated → singular}/utility_piping.py +1 -1
  61. openepd/model/specs/{generated → singular}/wood.py +13 -7
  62. openepd/model/specs/{generated → singular}/wood_joists.py +2 -2
  63. openepd/model/validation/enum.py +42 -0
  64. openepd/model/validation/quantity.py +179 -0
  65. {openepd-5.1.0.dist-info → openepd-6.1.0.dist-info}/METADATA +1 -1
  66. openepd-6.1.0.dist-info/RECORD +139 -0
  67. openepd-5.1.0.dist-info/RECORD +0 -138
  68. /openepd/model/specs/{generated → singular}/accessories.py +0 -0
  69. /openepd/model/specs/{generated → singular}/bulk_materials.py +0 -0
  70. /openepd/model/specs/{generated → singular}/cast_decks_and_underlayment.py +0 -0
  71. /openepd/model/specs/{generated → singular}/common.py +0 -0
  72. /openepd/model/specs/{generated → singular}/electrical_transmission_and_distribution_equipment.py +0 -0
  73. /openepd/model/specs/{generated → singular}/electricity.py +0 -0
  74. /openepd/model/specs/{generated → singular}/grouting.py +0 -0
  75. /openepd/model/specs/{generated → singular}/material_handling.py +0 -0
  76. /openepd/model/specs/{generated → singular}/mixins/__init__.py +0 -0
  77. /openepd/model/specs/{generated → singular}/other_electrical_equipment.py +0 -0
  78. /openepd/model/specs/{generated → singular}/other_materials.py +0 -0
  79. /openepd/model/specs/{generated → singular}/precast_concrete.py +0 -0
  80. {openepd-5.1.0.dist-info → openepd-6.1.0.dist-info}/LICENSE +0 -0
  81. {openepd-5.1.0.dist-info → openepd-6.1.0.dist-info}/WHEEL +0 -0
@@ -16,7 +16,7 @@
16
16
  from openepd.compat.pydantic import pyd
17
17
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
18
18
  from openepd.model.specs.concrete import Cementitious
19
- from openepd.model.specs.generated.enums import (
19
+ from openepd.model.specs.enums import (
20
20
  AdmixtureEffects,
21
21
  CarpetYarnType,
22
22
  CementAstmType,
@@ -17,6 +17,7 @@ from openepd.compat.pydantic import pyd
17
17
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
18
18
  from openepd.model.validation.quantity import (
19
19
  PressureMPaStr,
20
+ ThermalConductivityStr,
20
21
  validate_quantity_ge_factory,
21
22
  validate_quantity_unit_factory,
22
23
  )
@@ -35,7 +36,9 @@ class AutoclavedAeratedConcreteV1(BaseOpenEpdHierarchicalSpec):
35
36
 
36
37
  # Own fields:
37
38
  strength_28d: PressureMPaStr | None = pyd.Field(default=None, description="", example="1 MPa")
38
- thermal_conductivity: str | None = pyd.Field(default=None, description="", example="1 W / (m * K)")
39
+ thermal_conductivity: ThermalConductivityStr | None = pyd.Field(
40
+ default=None, description="", example="1 W / (m * K)"
41
+ )
39
42
  white: bool | None = pyd.Field(default=None, description="", example=True)
40
43
 
41
44
  _aac_thermal_conductivity_is_quantity_validator = pyd.validator("thermal_conductivity", allow_reuse=True)(
@@ -15,7 +15,7 @@
15
15
  #
16
16
  from openepd.compat.pydantic import pyd
17
17
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
18
- from openepd.model.specs.generated.enums import (
18
+ from openepd.model.specs.enums import (
19
19
  AhuAirflowControl,
20
20
  AhuZoneControl,
21
21
  AirFiltersMediaType,
@@ -15,7 +15,7 @@
15
15
  #
16
16
  from openepd.compat.pydantic import pyd
17
17
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
18
- from openepd.model.specs.generated.enums import InsulatingMaterial, InsulationIntendedApplication
18
+ from openepd.model.specs.enums import InsulatingMaterial, InsulationIntendedApplication
19
19
  from openepd.model.validation.quantity import LengthMmStr
20
20
 
21
21
 
@@ -17,7 +17,7 @@ __all__ = ["ConduitMixin"]
17
17
 
18
18
  from openepd.compat.pydantic import pyd
19
19
  from openepd.model.specs.base import BaseOpenEpdSpec
20
- from openepd.model.specs.generated.enums import ConduitMaterial
20
+ from openepd.model.specs.enums import ConduitMaterial
21
21
  from openepd.model.validation.quantity import LengthMmStr
22
22
 
23
23
 
@@ -15,7 +15,7 @@
15
15
  #
16
16
  from openepd.compat.pydantic import pyd
17
17
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
18
- from openepd.model.specs.generated.enums import (
18
+ from openepd.model.specs.enums import (
19
19
  CableTraysMaterial,
20
20
  CablingCategory,
21
21
  CablingFireRating,
@@ -27,7 +27,7 @@ from openepd.model.specs.generated.enums import (
27
27
  RacewaysMaterial,
28
28
  RackType,
29
29
  )
30
- from openepd.model.specs.generated.mixins.conduit_mixin import ConduitMixin
30
+ from openepd.model.specs.singular.mixins.conduit_mixin import ConduitMixin
31
31
  from openepd.model.validation.quantity import (
32
32
  ElectricalCurrentStr,
33
33
  LengthMmStr,
@@ -17,7 +17,7 @@
17
17
  from openepd.compat.pydantic import pyd
18
18
  from openepd.model.base import BaseOpenEpdSchema
19
19
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
20
- from openepd.model.specs.generated.enums import (
20
+ from openepd.model.specs.enums import (
21
21
  FlatGlassPanesThickness,
22
22
  FrameMaterial,
23
23
  HardwareFunction,
@@ -26,7 +26,13 @@ from openepd.model.specs.generated.enums import (
26
26
  ThermalSeparation,
27
27
  )
28
28
  from openepd.model.validation.numbers import RatioFloat
29
- from openepd.model.validation.quantity import LengthMmStr, PressureMPaStr, SpeedStr, validate_quantity_unit_factory
29
+ from openepd.model.validation.quantity import (
30
+ LengthMmStr,
31
+ PressureMPaStr,
32
+ SpeedStr,
33
+ UFactorStr,
34
+ validate_quantity_unit_factory,
35
+ )
30
36
 
31
37
 
32
38
  class GlazingIntendedApplication(BaseOpenEpdSchema):
@@ -346,7 +352,7 @@ class NAFSFenestrationV1(BaseOpenEpdHierarchicalSpec, GlazingOptionsMixin):
346
352
  default=None, description="The product has been designed to resist windborne debris.", example=True
347
353
  )
348
354
 
349
- assembly_u_factor: str | None = pyd.Field(
355
+ assembly_u_factor: UFactorStr | None = pyd.Field(
350
356
  default=None,
351
357
  description="Weighted average conductance of heat across assembly (including frame).",
352
358
  example="1 USI",
@@ -417,7 +423,7 @@ class InsulatingGlazingUnitsV1(BaseOpenEpdHierarchicalSpec, GlazingOptionsMixin)
417
423
  description="Number of panes, each separated by a cavity. A 3 pane unit has 2 cavities. example: 3",
418
424
  example=3,
419
425
  )
420
- cog_u_factor: str | None = pyd.Field(
426
+ cog_u_factor: UFactorStr | None = pyd.Field(
421
427
  default=None, description="Conductance of heat at center of glass.", example="1 USI"
422
428
  )
423
429
  spacer: Spacer | None = pyd.Field(
@@ -15,7 +15,7 @@
15
15
  #
16
16
  from openepd.compat.pydantic import pyd
17
17
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
18
- from openepd.model.specs.generated.enums import FireProtectionPipingMaterial, PipingAnsiSchedule, PlumbingPipingMaterial
18
+ from openepd.model.specs.enums import FireProtectionPipingMaterial, PipingAnsiSchedule, PlumbingPipingMaterial
19
19
  from openepd.model.validation.quantity import LengthMmStr, MassPerLengthStr
20
20
 
21
21
 
@@ -15,8 +15,8 @@
15
15
  #
16
16
  from openepd.compat.pydantic import pyd
17
17
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
18
- from openepd.model.specs.generated.enums import GypsumFacing, GypsumFireRating, GypsumThickness
19
- from openepd.model.validation.quantity import LengthMmStr, validate_quantity_unit_factory
18
+ from openepd.model.specs.enums import GypsumFacing, GypsumFireRating, GypsumThickness
19
+ from openepd.model.validation.quantity import LengthMmStr, RFactorStr, validate_quantity_unit_factory
20
20
 
21
21
 
22
22
  class CementitiousSheathingBoardV1(BaseOpenEpdHierarchicalSpec):
@@ -51,7 +51,7 @@ class GypsumSheathingBoardV1(BaseOpenEpdHierarchicalSpec):
51
51
  thickness: GypsumThickness | None = pyd.Field(default=None, description="", example="9 mm")
52
52
  facing: GypsumFacing | None = pyd.Field(default=None, description="", example="Paper")
53
53
 
54
- r_factor: str | None = pyd.Field(default=None, description="", example="1 RSI")
54
+ r_factor: RFactorStr | None = pyd.Field(default=None, description="", example="1 RSI")
55
55
 
56
56
  flame_spread_astm_e84: int | None = pyd.Field(default=None, description="", example=3)
57
57
  smoke_production_astm_e84: int | None = pyd.Field(default=None, description="", example=3)
@@ -18,10 +18,16 @@ from typing import Annotated
18
18
  from openepd.compat.pydantic import pyd
19
19
  from openepd.model.base import BaseOpenEpdSchema
20
20
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec, BaseOpenEpdSpec, CodegenSpec
21
- from openepd.model.specs.generated.enums import SteelComposition, SteelRebarGrade
21
+ from openepd.model.specs.enums import SteelComposition, SteelRebarGrade
22
22
  from openepd.model.standard import Standard
23
23
  from openepd.model.validation.numbers import RatioFloat
24
- from openepd.model.validation.quantity import LengthMmStr, PressureMPaStr, validate_quantity_unit_factory
24
+ from openepd.model.validation.quantity import (
25
+ LengthMmStr,
26
+ PressureMPaStr,
27
+ ThermalConductivityStr,
28
+ ThermalExpansionStr,
29
+ validate_quantity_unit_factory,
30
+ )
25
31
 
26
32
 
27
33
  class SteelMakingRoute(BaseOpenEpdSchema):
@@ -175,15 +181,15 @@ class StructuralSteelV1(BaseOpenEpdHierarchicalSpec):
175
181
  description="Modulus of Elasticity, https://en.wikipedia.org/wiki/Elastic_modulus ",
176
182
  example="193 GPa",
177
183
  )
178
- thermal_expansion: str | None = pyd.Field(
184
+ thermal_expansion: ThermalExpansionStr | None = pyd.Field(
179
185
  default=None,
180
186
  description="Thermal Expansion, https://en.wikipedia.org/wiki/Thermal_expansion",
181
187
  example="1.11E-5 / K",
182
188
  )
183
- thermal_conductivity: str | None = pyd.Field(
189
+ thermal_conductivity: ThermalConductivityStr | None = pyd.Field(
184
190
  default=None,
185
191
  description="Thermal Conductivity, https://en.wikipedia.org/wiki/Thermal_conductivity_and_resistivity",
186
- example="1.45E-5 W / (m * K)",
192
+ example="1.45E-5 W / m / K)",
187
193
  )
188
194
 
189
195
  _steel_thermal_expansion_is_quantity_validator = pyd.validator("thermal_expansion", allow_reuse=True)(
@@ -15,7 +15,7 @@
15
15
  #
16
16
  from openepd.compat.pydantic import pyd
17
17
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
18
- from openepd.model.specs.generated.enums import (
18
+ from openepd.model.specs.enums import (
19
19
  FoamType,
20
20
  InsulatingMaterial,
21
21
  InsulationIntendedApplication,
@@ -15,7 +15,7 @@
15
15
  #
16
16
  from openepd.compat.pydantic import pyd
17
17
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
18
- from openepd.model.specs.generated.enums import BuriedPipingType, PipingAnsiSchedule, UtilityPipingMaterial
18
+ from openepd.model.specs.enums import BuriedPipingType, PipingAnsiSchedule, UtilityPipingMaterial
19
19
  from openepd.model.validation.quantity import LengthMmStr, MassPerLengthStr
20
20
 
21
21
 
@@ -13,10 +13,11 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
+ from typing import Annotated
17
+
16
18
  from openepd.compat.pydantic import pyd
17
- from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
18
- from openepd.model.specs.generated.common import HasForestPracticesCertifiers
19
- from openepd.model.specs.generated.enums import (
19
+ from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec, CodegenSpec
20
+ from openepd.model.specs.enums import (
20
21
  AllFabrication,
21
22
  AllTimberSpecies,
22
23
  CompositeLumberFabrication,
@@ -25,6 +26,7 @@ from openepd.model.specs.generated.enums import (
25
26
  SawnTimberSpecies,
26
27
  SheathingPanelsFabrication,
27
28
  )
29
+ from openepd.model.specs.singular.common import HasForestPracticesCertifiers
28
30
  from openepd.model.validation.numbers import RatioFloat
29
31
  from openepd.model.validation.quantity import LengthMmStr
30
32
 
@@ -156,15 +158,19 @@ class WoodV1(BaseOpenEpdHierarchicalSpec, HasForestPracticesCertifiers):
156
158
  weather_exposed: bool | None = pyd.Field(default=None, description="Weather exposed", example=True)
157
159
  fire_retardant: bool | None = pyd.Field(default=None, description="Fire retardant", example=True)
158
160
  decay_resistant: bool | None = pyd.Field(default=None, description="Decay resistant", example=True)
159
- fsc_certified: RatioFloat | None = pyd.Field(
161
+ fsc_certified: Annotated[RatioFloat | None, CodegenSpec(override_type=RatioFloat)] = pyd.Field(
160
162
  default=None, description="Forest Stewardship Council certified proportion", example=0.3, ge=0, le=1
161
163
  )
162
- fsc_certified_z: float | None = pyd.Field(default=None, description="", example=0.7)
164
+ fsc_certified_z: Annotated[float | None, CodegenSpec(override_type=float)] = pyd.Field(
165
+ default=None, description="", example=0.7
166
+ )
163
167
 
164
- recycled_content: RatioFloat | None = pyd.Field(
168
+ recycled_content: Annotated[RatioFloat | None, CodegenSpec(override_type=RatioFloat)] = pyd.Field(
165
169
  default=None, description="Recycled content", example=0.3, ge=0, le=1
166
170
  )
167
- recycled_content_z: float | None = pyd.Field(default=None, description="", example=0.7)
171
+ recycled_content_z: Annotated[float | None, CodegenSpec(override_type=float)] = pyd.Field(
172
+ default=None, description="", example=0.7
173
+ )
168
174
 
169
175
  # Nested specs:
170
176
  CompositeLumber: CompositeLumberV1 | None = None
@@ -15,8 +15,8 @@
15
15
  #
16
16
  from openepd.compat.pydantic import pyd
17
17
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
18
- from openepd.model.specs.generated.common import HasForestPracticesCertifiers
19
- from openepd.model.specs.generated.enums import AllFabrication, AllTimberSpecies
18
+ from openepd.model.specs.enums import AllFabrication, AllTimberSpecies
19
+ from openepd.model.specs.singular.common import HasForestPracticesCertifiers
20
20
 
21
21
 
22
22
  class WoodJoistsV1(BaseOpenEpdHierarchicalSpec, HasForestPracticesCertifiers):
@@ -0,0 +1,42 @@
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
+ from typing import Any, Callable
17
+
18
+ from openepd.model.common import EnumGroupingAware
19
+
20
+
21
+ def exclusive_groups_validator_factory(enum_type: type[EnumGroupingAware]) -> Callable[[type, Any], Any]:
22
+ """
23
+ Create an exclusive groups validator.
24
+
25
+ If we have a certain enum TheEnum, and a field of list[TheEnum], where list can contain only one value of each of
26
+ the groups, this validator should be used. For example, ACI exposure classes for concrete specify various
27
+ parameters such as water resistance, chemical resistance, etc., and the list of classes can have 0 or 1 from each
28
+ group.
29
+
30
+ :param enum_type:Enum type which supports groupings.
31
+ :return:value, or raises ValueError if not allowed combination is given.
32
+ """
33
+
34
+ def enum_exclusive_grouping_validator(cls, value: list | None) -> list | None:
35
+ for grouping in enum_type.get_groupings():
36
+ matching_from_group = [v for v in (value or []) if v in grouping]
37
+ if len(matching_from_group) > 1:
38
+ raise ValueError(f"Values {', '.join(matching_from_group)} are not allowed together.")
39
+
40
+ return value
41
+
42
+ return enum_exclusive_grouping_validator
@@ -307,6 +307,48 @@ class AreaPerVolumeStr(QuantityStr):
307
307
  unit = "m2 / l"
308
308
 
309
309
 
310
+ class ThermalConductivityStr(QuantityStr):
311
+ """Thermal conductivity quantity type."""
312
+
313
+ unit = "1 W / K / m"
314
+
315
+
316
+ class ThermalExpansionStr(QuantityStr):
317
+ """Thermal conductivity quantity type."""
318
+
319
+ unit = "1 / K"
320
+
321
+
322
+ class ForceNStr(QuantityStr):
323
+ """Force (N) type."""
324
+
325
+ unit = "1 N"
326
+
327
+
328
+ class YarnWeightStr(QuantityStr):
329
+ """Yarn weight quantity type."""
330
+
331
+ unit = "1 g / m2"
332
+
333
+
334
+ class UtilizationStr(QuantityStr):
335
+ """Utilization quantity type."""
336
+
337
+ unit = "1 h / yr"
338
+
339
+
340
+ class UFactorStr(QuantityStr):
341
+ """Utilization quantity type."""
342
+
343
+ unit = "1 USI"
344
+
345
+
346
+ class RFactorStr(QuantityStr):
347
+ """R-Factor type."""
348
+
349
+ unit = "1 RSI"
350
+
351
+
310
352
  class WithDimensionalityMixin(BaseOpenEpdSchema):
311
353
  """Class for dimensionality-validated amounts."""
312
354
 
@@ -696,6 +738,136 @@ class AmountRangeAreaPerVolume(AmountRangeWithDimensionality, WithFlowRateMixin)
696
738
  pass
697
739
 
698
740
 
741
+ class WithThermalConductivity(WithDimensionalityMixin):
742
+ """Unit validation mixin."""
743
+
744
+ dimensionality_unit = ThermalConductivityStr.unit
745
+
746
+
747
+ class AmountThermalConductivityMixin(Amount, WithThermalConductivity):
748
+ """Area per volume."""
749
+
750
+ pass
751
+
752
+
753
+ class AmountRangeThermalConductivity(AmountRangeWithDimensionality, WithThermalConductivity):
754
+ """Area per volume range."""
755
+
756
+ pass
757
+
758
+
759
+ class WithForce(WithDimensionalityMixin):
760
+ """
761
+ Unit validation mixin.
762
+
763
+ May the Force be with you.
764
+ """
765
+
766
+ dimensionality_unit = ForceNStr.unit
767
+
768
+
769
+ class AmountForce(Amount, WithForce):
770
+ """Area per volume."""
771
+
772
+ pass
773
+
774
+
775
+ class AmountRangeForce(AmountRangeWithDimensionality, WithForce):
776
+ """Area per volume range."""
777
+
778
+ pass
779
+
780
+
781
+ class WithYarnWeight(WithDimensionalityMixin):
782
+ """Unit validation mixin."""
783
+
784
+ dimensionality_unit = YarnWeightStr.unit
785
+
786
+
787
+ class AmountYarnWeight(Amount, WithYarnWeight):
788
+ """Yarn weight."""
789
+
790
+ pass
791
+
792
+
793
+ class AmountRangeYarnWeight(AmountRangeWithDimensionality, WithYarnWeight):
794
+ """Yarn weight range."""
795
+
796
+ pass
797
+
798
+
799
+ class WithThermalExpansion(WithDimensionalityMixin):
800
+ """Unit validation mixin."""
801
+
802
+ dimensionality_unit = ThermalExpansionStr.unit
803
+
804
+
805
+ class AmountThermalExpansion(Amount, WithThermalExpansion):
806
+ """Yarn weight."""
807
+
808
+ pass
809
+
810
+
811
+ class AmountRangeThermalExpansion(AmountRangeWithDimensionality, WithThermalExpansion):
812
+ """Yarn weight range."""
813
+
814
+ pass
815
+
816
+
817
+ class WithUtilization(WithDimensionalityMixin):
818
+ """Unit validation mixin."""
819
+
820
+ dimensionality_unit = UtilizationStr.unit
821
+
822
+
823
+ class AmountUtilization(Amount, WithUtilization):
824
+ """Utilization."""
825
+
826
+ pass
827
+
828
+
829
+ class AmountRangeUtilization(AmountRangeWithDimensionality, WithUtilization):
830
+ """Utilization range."""
831
+
832
+ pass
833
+
834
+
835
+ class WithUFactor(WithDimensionalityMixin):
836
+ """Unit validation mixin."""
837
+
838
+ dimensionality_unit = UFactorStr.unit
839
+
840
+
841
+ class AmountUFactor(Amount, WithUFactor):
842
+ """U-Factor."""
843
+
844
+ pass
845
+
846
+
847
+ class AmountRangeUFactor(AmountRangeWithDimensionality, WithUFactor):
848
+ """U-Factor range."""
849
+
850
+ pass
851
+
852
+
853
+ class WithRFactor(WithDimensionalityMixin):
854
+ """Unit validation mixin."""
855
+
856
+ dimensionality_unit = RFactorStr.unit
857
+
858
+
859
+ class AmountRFactor(Amount, WithRFactor):
860
+ """R-Factor."""
861
+
862
+ pass
863
+
864
+
865
+ class AmountRangeRFactor(AmountRangeWithDimensionality, WithRFactor):
866
+ """R-Factor range."""
867
+
868
+ pass
869
+
870
+
699
871
  # known range amounts
700
872
  SUPPORTED_RANGE_TYPES: tuple[type[AmountRangeWithDimensionality], ...] = (
701
873
  AmountRangeMass,
@@ -718,6 +890,13 @@ SUPPORTED_RANGE_TYPES: tuple[type[AmountRangeWithDimensionality], ...] = (
718
890
  AmountRangeFlowRate,
719
891
  AmountRangeMassPerLength,
720
892
  AmountRangeAreaPerVolume,
893
+ AmountRangeThermalConductivity,
894
+ AmountRangeForce,
895
+ AmountRangeYarnWeight,
896
+ AmountRangeThermalExpansion,
897
+ AmountRangeUtilization,
898
+ AmountRangeUFactor,
899
+ AmountRangeRFactor,
721
900
  )
722
901
 
723
902
  # known range amount mapping by unit
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openepd
3
- Version: 5.1.0
3
+ Version: 6.1.0
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