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.
- openepd/__version__.py +1 -1
- openepd/api/average_dataset/generic_estimate_sync_api.py +11 -3
- openepd/api/epd/sync_api.py +6 -2
- openepd/api/utils.py +40 -0
- openepd/bundle/model.py +3 -0
- openepd/model/common.py +65 -1
- openepd/model/epd.py +1 -1
- openepd/model/org.py +0 -1
- openepd/model/specs/__init__.py +34 -75
- openepd/model/specs/base.py +2 -1
- openepd/model/specs/{generated/enums.py → enums.py} +51 -3
- openepd/model/specs/range/aggregates.py +2 -2
- openepd/model/specs/range/aluminium.py +1 -1
- openepd/model/specs/range/asphalt.py +4 -4
- openepd/model/specs/range/cladding.py +1 -1
- openepd/model/specs/range/cmu.py +6 -5
- openepd/model/specs/range/concrete.py +1 -1
- openepd/model/specs/range/conveying_equipment.py +1 -1
- openepd/model/specs/range/electrical.py +3 -2
- openepd/model/specs/range/finishes.py +13 -6
- openepd/model/specs/range/fire_and_smoke_protection.py +1 -1
- openepd/model/specs/range/furnishings.py +1 -1
- openepd/model/specs/range/manufacturing_inputs.py +1 -1
- openepd/model/specs/range/masonry.py +2 -2
- openepd/model/specs/range/mechanical.py +1 -1
- openepd/model/specs/range/mechanical_insulation.py +1 -1
- openepd/model/specs/range/network_infrastructure.py +1 -1
- openepd/model/specs/range/openings.py +12 -5
- openepd/model/specs/range/plumbing.py +1 -1
- openepd/model/specs/range/precast_concrete.py +1 -1
- openepd/model/specs/range/sheathing.py +3 -3
- openepd/model/specs/range/steel.py +10 -5
- openepd/model/specs/range/thermal_moisture_protection.py +1 -1
- openepd/model/specs/range/utility_piping.py +1 -1
- openepd/model/specs/range/wood.py +8 -6
- openepd/model/specs/range/wood_joists.py +1 -1
- openepd/model/specs/{generated → singular}/__init__.py +37 -35
- openepd/model/specs/{generated → singular}/aggregates.py +1 -1
- openepd/model/specs/{generated → singular}/aluminium.py +1 -1
- openepd/model/specs/{generated → singular}/asphalt.py +6 -4
- openepd/model/specs/{generated → singular}/cladding.py +1 -1
- openepd/model/specs/{generated → singular}/cmu.py +10 -4
- openepd/model/specs/{generated → singular}/concrete.py +12 -1
- openepd/model/specs/{generated → singular}/conveying_equipment.py +1 -1
- openepd/model/specs/{generated → singular}/electrical.py +4 -3
- openepd/model/specs/{generated → singular}/finishes.py +9 -6
- openepd/model/specs/{generated → singular}/fire_and_smoke_protection.py +1 -1
- openepd/model/specs/{generated → singular}/furnishings.py +1 -1
- openepd/model/specs/{generated → singular}/manufacturing_inputs.py +1 -1
- openepd/model/specs/{generated → singular}/masonry.py +4 -1
- openepd/model/specs/{generated → singular}/mechanical.py +1 -1
- openepd/model/specs/{generated → singular}/mechanical_insulation.py +1 -1
- openepd/model/specs/{generated → singular}/mixins/conduit_mixin.py +1 -1
- openepd/model/specs/{generated → singular}/network_infrastructure.py +2 -2
- openepd/model/specs/{generated → singular}/openings.py +10 -4
- openepd/model/specs/{generated → singular}/plumbing.py +1 -1
- openepd/model/specs/{generated → singular}/sheathing.py +3 -3
- openepd/model/specs/{generated → singular}/steel.py +11 -5
- openepd/model/specs/{generated → singular}/thermal_moisture_protection.py +1 -1
- openepd/model/specs/{generated → singular}/utility_piping.py +1 -1
- openepd/model/specs/{generated → singular}/wood.py +13 -7
- openepd/model/specs/{generated → singular}/wood_joists.py +2 -2
- openepd/model/validation/enum.py +42 -0
- openepd/model/validation/quantity.py +179 -0
- {openepd-5.1.0.dist-info → openepd-6.1.0.dist-info}/METADATA +1 -1
- openepd-6.1.0.dist-info/RECORD +139 -0
- openepd-5.1.0.dist-info/RECORD +0 -138
- /openepd/model/specs/{generated → singular}/accessories.py +0 -0
- /openepd/model/specs/{generated → singular}/bulk_materials.py +0 -0
- /openepd/model/specs/{generated → singular}/cast_decks_and_underlayment.py +0 -0
- /openepd/model/specs/{generated → singular}/common.py +0 -0
- /openepd/model/specs/{generated → singular}/electrical_transmission_and_distribution_equipment.py +0 -0
- /openepd/model/specs/{generated → singular}/electricity.py +0 -0
- /openepd/model/specs/{generated → singular}/grouting.py +0 -0
- /openepd/model/specs/{generated → singular}/material_handling.py +0 -0
- /openepd/model/specs/{generated → singular}/mixins/__init__.py +0 -0
- /openepd/model/specs/{generated → singular}/other_electrical_equipment.py +0 -0
- /openepd/model/specs/{generated → singular}/other_materials.py +0 -0
- /openepd/model/specs/{generated → singular}/precast_concrete.py +0 -0
- {openepd-5.1.0.dist-info → openepd-6.1.0.dist-info}/LICENSE +0 -0
- {openepd-5.1.0.dist-info → openepd-6.1.0.dist-info}/WHEEL +0 -0
openepd/__version__.py
CHANGED
@@ -21,7 +21,7 @@ from openepd.api.base_sync_client import BaseApiMethodGroup
|
|
21
21
|
from openepd.api.common import StreamingListResponse, paging_meta_from_v1_api
|
22
22
|
from openepd.api.dto.common import BaseMeta, OpenEpdApiResponse
|
23
23
|
from openepd.api.dto.meta import PagingMetaMixin
|
24
|
-
from openepd.api.utils import encode_path_param
|
24
|
+
from openepd.api.utils import encode_path_param, remove_none_id_fields
|
25
25
|
from openepd.model.generic_estimate import (
|
26
26
|
GenericEstimate,
|
27
27
|
GenericEstimatePreview,
|
@@ -61,7 +61,11 @@ class GenericEstimateApi(BaseApiMethodGroup):
|
|
61
61
|
) -> tuple[GenericEstimate, Response]: ...
|
62
62
|
|
63
63
|
@overload
|
64
|
-
def post_with_refs(
|
64
|
+
def post_with_refs(
|
65
|
+
self,
|
66
|
+
ge: GenericEstimateWithDeps,
|
67
|
+
with_response: Literal[False] = False,
|
68
|
+
) -> GenericEstimate: ...
|
65
69
|
|
66
70
|
def post_with_refs(
|
67
71
|
self, ge: GenericEstimateWithDeps, with_response: bool = False
|
@@ -71,12 +75,16 @@ class GenericEstimateApi(BaseApiMethodGroup):
|
|
71
75
|
|
72
76
|
:param ge: GenericEstimate
|
73
77
|
:param with_response: return the response object togather with the GenericEstimate
|
78
|
+
:param exclude_defaults: If True, fields with default values are excluded from the payload
|
74
79
|
:return: GenericEstimate alone, or GenericEstimate with HTTP Response object depending on parameter
|
75
80
|
"""
|
81
|
+
data = ge.to_serializable(exclude_unset=True, by_alias=True)
|
82
|
+
# Remove 'id' fields with None values, as 'id' cannot be None
|
83
|
+
data = remove_none_id_fields(data)
|
76
84
|
response = self._client.do_request(
|
77
85
|
"patch",
|
78
86
|
"/generic_estimates/post_with_refs",
|
79
|
-
json=
|
87
|
+
json=data,
|
80
88
|
)
|
81
89
|
content = response.json()
|
82
90
|
if with_response:
|
openepd/api/epd/sync_api.py
CHANGED
@@ -20,7 +20,7 @@ from requests import Response
|
|
20
20
|
from openepd.api.base_sync_client import BaseApiMethodGroup
|
21
21
|
from openepd.api.common import StreamingListResponse
|
22
22
|
from openepd.api.epd.dto import EpdSearchResponse, EpdStatisticsResponse, StatisticsDto
|
23
|
-
from openepd.api.utils import encode_path_param
|
23
|
+
from openepd.api.utils import encode_path_param, remove_none_id_fields
|
24
24
|
from openepd.model.epd import Epd
|
25
25
|
|
26
26
|
|
@@ -117,12 +117,16 @@ class EpdApi(BaseApiMethodGroup):
|
|
117
117
|
|
118
118
|
:param epd: EPD
|
119
119
|
:param with_response: return the response object togather with the EPD
|
120
|
+
:param exclude_defaults: If True, fields with default values are excluded from the payload
|
120
121
|
:return: EPD or EPD with HTTP Response object depending on parameter
|
121
122
|
"""
|
123
|
+
epd_data = epd.to_serializable(exclude_unset=True, by_alias=True)
|
124
|
+
# Remove 'id' fields with None values, as 'id' cannot be None
|
125
|
+
epd_data = remove_none_id_fields(epd_data)
|
122
126
|
response = self._client.do_request(
|
123
127
|
"patch",
|
124
128
|
"/epds/post-with-refs",
|
125
|
-
json=
|
129
|
+
json=epd_data,
|
126
130
|
)
|
127
131
|
content = response.json()
|
128
132
|
if with_response:
|
openepd/api/utils.py
CHANGED
@@ -26,3 +26,43 @@ def encode_path_param(value: str) -> str:
|
|
26
26
|
:return: encoded value
|
27
27
|
"""
|
28
28
|
return quote(value, safe="")
|
29
|
+
|
30
|
+
|
31
|
+
def remove_none_id_fields(d: dict) -> dict:
|
32
|
+
"""
|
33
|
+
Remove any key 'id' with a None value from the dictionary, including nested dicts.
|
34
|
+
|
35
|
+
:param d: the dict which may contain 'id' keys with None values.
|
36
|
+
:return: a new dict with 'id' keys that have None values removed.
|
37
|
+
|
38
|
+
:note:
|
39
|
+
- This function does not modify the original dictionary (no side effects).
|
40
|
+
- It returns a new dictionary with the necessary modifications applied.
|
41
|
+
|
42
|
+
:example:
|
43
|
+
>>> data = {
|
44
|
+
... "id": None,
|
45
|
+
... "name": "item1",
|
46
|
+
... "details": {
|
47
|
+
... "id": None,
|
48
|
+
... "category": "tools",
|
49
|
+
... "nested": {
|
50
|
+
... "id": None,
|
51
|
+
... "value": 42
|
52
|
+
... }
|
53
|
+
... }
|
54
|
+
... }
|
55
|
+
>>> remove_none_id_fields(data)
|
56
|
+
{'name': 'item1', 'details': {'category': 'tools', 'nested': {'value': 42}}}
|
57
|
+
"""
|
58
|
+
if not isinstance(d, dict):
|
59
|
+
return d
|
60
|
+
|
61
|
+
cleaned_dict = {}
|
62
|
+
for k, v in d.items():
|
63
|
+
if isinstance(v, dict):
|
64
|
+
v = remove_none_id_fields(v)
|
65
|
+
if not (k == "id" and v is None):
|
66
|
+
cleaned_dict[k] = v
|
67
|
+
|
68
|
+
return cleaned_dict
|
openepd/bundle/model.py
CHANGED
@@ -13,6 +13,7 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
|
+
from datetime import datetime
|
16
17
|
from enum import StrEnum
|
17
18
|
|
18
19
|
from openepd.compat.pydantic import pyd
|
@@ -61,6 +62,8 @@ class BundleManifest(BaseOpenEpdSchema):
|
|
61
62
|
"""The generator of the bundle."""
|
62
63
|
assets: BundleManifestAssetsStats = pyd.Field(default_factory=BundleManifestAssetsStats)
|
63
64
|
comment: str | None = pyd.Field(default=None)
|
65
|
+
created_at: datetime = pyd.Field(default_factory=datetime.utcnow)
|
66
|
+
"""The date and time when the bundle was generated."""
|
64
67
|
|
65
68
|
|
66
69
|
class AssetInfo(BaseOpenEpdSchema):
|
openepd/model/common.py
CHANGED
@@ -18,6 +18,7 @@ from typing import Annotated, Any
|
|
18
18
|
|
19
19
|
from openepd.compat.pydantic import pyd
|
20
20
|
from openepd.model.base import BaseOpenEpdSchema
|
21
|
+
from openepd.model.validation.numbers import RatioFloat
|
21
22
|
|
22
23
|
|
23
24
|
class Amount(BaseOpenEpdSchema):
|
@@ -38,6 +39,32 @@ class Amount(BaseOpenEpdSchema):
|
|
38
39
|
return f"{self.qty or ''} {self.unit or 'str'}".strip()
|
39
40
|
|
40
41
|
|
42
|
+
class Distribution(StrEnum):
|
43
|
+
"""
|
44
|
+
Distribution of the measured value.
|
45
|
+
|
46
|
+
* log-normal: Probability distribution of any random parameter whose natural log is normally distributed (the
|
47
|
+
PDF is gaussian).
|
48
|
+
* normal: Probability distribution of any random parameter whose value is normally distributed around the mean
|
49
|
+
(the PDF is gaussian).
|
50
|
+
* Continuous uniform probability distribution between minimum value and maximum value and "0" probability beyond
|
51
|
+
these.
|
52
|
+
* Probability distribution of any random parameter between minimum value and maximum value with the highest
|
53
|
+
probability at the average value of minimum plus maximum value. Linear change of probability between minimum,
|
54
|
+
maximum and average value.
|
55
|
+
* Means Impact is not known, but with >95% certainty the true value is below the declared value.
|
56
|
+
So [1e-6,"kgCFC11e",0,"max"] means the ODP was not exactly measured, but it is guaranteed to be below
|
57
|
+
1E-6 kg CO2e. It is acceptable to treat a 'max' distribution a normal or lognormal distribution with variation
|
58
|
+
0.1%. This is conservative, because the 'max' value is usually much greater than the true impact.
|
59
|
+
"""
|
60
|
+
|
61
|
+
LOG_NORMAL = "log-normal"
|
62
|
+
NORMAL = "normal"
|
63
|
+
UNIFORM = "uniform"
|
64
|
+
TRIANGULAR = "triangular"
|
65
|
+
MAX = "max"
|
66
|
+
|
67
|
+
|
41
68
|
class Measurement(BaseOpenEpdSchema):
|
42
69
|
"""A scientific value with units and uncertainty."""
|
43
70
|
|
@@ -46,7 +73,15 @@ class Measurement(BaseOpenEpdSchema):
|
|
46
73
|
rsd: pyd.PositiveFloat | None = pyd.Field(
|
47
74
|
description="Relative standard deviation, i.e. standard_deviation/mean", default=None
|
48
75
|
)
|
49
|
-
dist:
|
76
|
+
dist: Distribution | None = pyd.Field(
|
77
|
+
description="Statistical distribution of the measurement error.", default=None
|
78
|
+
)
|
79
|
+
|
80
|
+
|
81
|
+
class IngredientEvidenceTypeEnum(StrEnum):
|
82
|
+
"""Supported types of evidence for indirect ingredient."""
|
83
|
+
|
84
|
+
PRODUCT_EPD = "Product EPD"
|
50
85
|
|
51
86
|
|
52
87
|
class Ingredient(BaseOpenEpdSchema):
|
@@ -56,6 +91,11 @@ class Ingredient(BaseOpenEpdSchema):
|
|
56
91
|
The Ingredients list gives the core data references and quantities. This list is used to document supply-chain
|
57
92
|
transparency, such as the EPDs of major components (e.g. cement in concrete, or recycled steel
|
58
93
|
in hot-rolled sections).
|
94
|
+
|
95
|
+
Since the exact ingredients may be viewed as a proprietary information by Manufacturers, this schema also allows
|
96
|
+
to pass some data about ingredient about explicitly saying what it is. Further, this data can be used to
|
97
|
+
calculate the supply chain specificity of the product and uncertainty adjusted factor. For this option, use
|
98
|
+
gwp_fraction, citation and evidence_type.
|
59
99
|
"""
|
60
100
|
|
61
101
|
qty: float | None = pyd.Field(
|
@@ -67,6 +107,16 @@ class Ingredient(BaseOpenEpdSchema):
|
|
67
107
|
default=None,
|
68
108
|
)
|
69
109
|
|
110
|
+
gwp_fraction: RatioFloat | None = pyd.Field(
|
111
|
+
default=None,
|
112
|
+
description="Fraction of product's A1-A3 GWP this flow represents. This value, along with the specificity of "
|
113
|
+
"the reference, are used to caclulate supply chain specificity.",
|
114
|
+
)
|
115
|
+
evidence_type: IngredientEvidenceTypeEnum | None = pyd.Field(
|
116
|
+
default=None, description="Type of evidence used, which can be used to calculate degree of specificity"
|
117
|
+
)
|
118
|
+
citation: str | None = pyd.Field(default=None, description="Text citation describing the data source ")
|
119
|
+
|
70
120
|
|
71
121
|
class LatLng(BaseOpenEpdSchema):
|
72
122
|
"""A latitude and longitude."""
|
@@ -189,3 +239,17 @@ class RangeAmount(RangeFloat):
|
|
189
239
|
"""Structure representing a range of quantities."""
|
190
240
|
|
191
241
|
unit: str | None = pyd.Field(default=None, description="Unit of the range.")
|
242
|
+
|
243
|
+
|
244
|
+
class EnumGroupingAware:
|
245
|
+
"""
|
246
|
+
Mixin for enums to support groups.
|
247
|
+
|
248
|
+
With the groups, enum can group its values into more than one groups, so that the validator higher in code can check
|
249
|
+
for mutual exclusivity, for example that only one value from the group is permitted at the same time.
|
250
|
+
"""
|
251
|
+
|
252
|
+
@classmethod
|
253
|
+
def get_groupings(cls) -> list[list]:
|
254
|
+
"""Return logical groupings of the values."""
|
255
|
+
return []
|
openepd/model/epd.py
CHANGED
@@ -29,7 +29,7 @@ from openepd.model.declaration import (
|
|
29
29
|
)
|
30
30
|
from openepd.model.lcia import WithLciaMixin
|
31
31
|
from openepd.model.org import Org, Plant
|
32
|
-
from openepd.model.specs import Specs
|
32
|
+
from openepd.model.specs.singular import Specs
|
33
33
|
from openepd.model.versioning import OpenEpdVersions, Version
|
34
34
|
|
35
35
|
MANUFACTURER_DESCRIPTION = (
|
openepd/model/org.py
CHANGED
@@ -69,7 +69,6 @@ class Plant(WithAttachmentsMixin, WithAltIdsMixin, BaseOpenEpdSchema):
|
|
69
69
|
description="Plus code (aka Open Location Code) of plant's location and "
|
70
70
|
"owner's web domain joined with `.`(dot).",
|
71
71
|
example="865P2W3V+3W.interface.com",
|
72
|
-
alias="pluscode",
|
73
72
|
default=None,
|
74
73
|
)
|
75
74
|
owner: Org | None = pyd.Field(description="Organization that owns the plant", default=None)
|
openepd/model/specs/__init__.py
CHANGED
@@ -14,80 +14,39 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
|
17
|
-
from openepd.model.
|
18
|
-
from openepd.model.specs.
|
19
|
-
from openepd.model.specs.
|
20
|
-
from openepd.model.specs.
|
21
|
-
from openepd.model.specs.
|
22
|
-
from openepd.model.specs.
|
23
|
-
from openepd.model.specs.
|
24
|
-
from openepd.model.specs.
|
25
|
-
from openepd.model.specs.
|
26
|
-
from openepd.model.specs.
|
27
|
-
from openepd.model.specs.
|
28
|
-
from openepd.model.specs.
|
29
|
-
from openepd.model.specs.generated.electrical_transmission_and_distribution_equipment import (
|
17
|
+
from openepd.model.specs.singular.accessories import AccessoriesV1
|
18
|
+
from openepd.model.specs.singular.aggregates import AggregatesV1
|
19
|
+
from openepd.model.specs.singular.aluminium import AluminiumV1
|
20
|
+
from openepd.model.specs.singular.asphalt import AsphaltV1
|
21
|
+
from openepd.model.specs.singular.bulk_materials import BulkMaterialsV1
|
22
|
+
from openepd.model.specs.singular.cast_decks_and_underlayment import CastDecksAndUnderlaymentV1
|
23
|
+
from openepd.model.specs.singular.cladding import CladdingV1
|
24
|
+
from openepd.model.specs.singular.cmu import CMUV1
|
25
|
+
from openepd.model.specs.singular.concrete import ConcreteV1
|
26
|
+
from openepd.model.specs.singular.conveying_equipment import ConveyingEquipmentV1
|
27
|
+
from openepd.model.specs.singular.electrical import ElectricalV1
|
28
|
+
from openepd.model.specs.singular.electrical_transmission_and_distribution_equipment import (
|
30
29
|
ElectricalTransmissionAndDistributionEquipmentV1,
|
31
30
|
)
|
32
|
-
from openepd.model.specs.
|
33
|
-
from openepd.model.specs.
|
34
|
-
from openepd.model.specs.
|
35
|
-
from openepd.model.specs.
|
36
|
-
from openepd.model.specs.
|
37
|
-
from openepd.model.specs.
|
38
|
-
from openepd.model.specs.
|
39
|
-
from openepd.model.specs.
|
40
|
-
from openepd.model.specs.
|
41
|
-
from openepd.model.specs.
|
42
|
-
from openepd.model.specs.
|
43
|
-
from openepd.model.specs.
|
44
|
-
from openepd.model.specs.
|
45
|
-
from openepd.model.specs.
|
46
|
-
from openepd.model.specs.
|
47
|
-
from openepd.model.specs.
|
48
|
-
from openepd.model.specs.
|
49
|
-
from openepd.model.specs.
|
50
|
-
from openepd.model.specs.
|
51
|
-
from openepd.model.specs.
|
52
|
-
from openepd.model.specs.
|
53
|
-
from openepd.model.specs.
|
54
|
-
|
55
|
-
|
56
|
-
class Specs(BaseOpenEpdSchema):
|
57
|
-
"""Material specific specs."""
|
58
|
-
|
59
|
-
# Nested specs:
|
60
|
-
CMU: CMUV1 | None = None
|
61
|
-
Masonry: MasonryV1 | None = None
|
62
|
-
Steel: SteelV1 | None = None
|
63
|
-
NetworkInfrastructure: NetworkInfrastructureV1 | None = None
|
64
|
-
Finishes: FinishesV1 | None = None
|
65
|
-
ManufacturingInputs: ManufacturingInputsV1 | None = None
|
66
|
-
Accessories: AccessoriesV1 | None = None
|
67
|
-
ElectricalTransmissionAndDistributionEquipment: ElectricalTransmissionAndDistributionEquipmentV1 | None = None
|
68
|
-
Aggregates: AggregatesV1 | None = None
|
69
|
-
ThermalMoistureProtection: ThermalMoistureProtectionV1 | None = None
|
70
|
-
Mechanical: MechanicalV1 | None = None
|
71
|
-
Aluminium: AluminiumV1 | None = None
|
72
|
-
Cladding: CladdingV1 | None = None
|
73
|
-
FireAndSmokeProtection: FireAndSmokeProtectionV1 | None = None
|
74
|
-
PrecastConcrete: PrecastConcreteV1 | None = None
|
75
|
-
Asphalt: AsphaltV1 | None = None
|
76
|
-
OtherMaterials: OtherMaterialsV1 | None = None
|
77
|
-
Plumbing: PlumbingV1 | None = None
|
78
|
-
Electrical: ElectricalV1 | None = None
|
79
|
-
UtilityPiping: UtilityPipingV1 | None = None
|
80
|
-
BulkMaterials: BulkMaterialsV1 | None = None
|
81
|
-
CastDecksAndUnderlayment: CastDecksAndUnderlaymentV1 | None = None
|
82
|
-
Concrete: ConcreteV1 | None = None
|
83
|
-
Sheathing: SheathingV1 | None = None
|
84
|
-
Furnishings: FurnishingsV1 | None = None
|
85
|
-
Wood: WoodV1 | None = None
|
86
|
-
ConveyingEquipment: ConveyingEquipmentV1 | None = None
|
87
|
-
MaterialHandling: MaterialHandlingV1 | None = None
|
88
|
-
Openings: OpeningsV1 | None = None
|
89
|
-
Electricity: ElectricityV1 | None = None
|
90
|
-
Grouting: GroutingV1 | None = None
|
91
|
-
MechanicalInsulation: MechanicalInsulationV1 | None = None
|
92
|
-
OtherElectricalEquipment: OtherElectricalEquipmentV1 | None = None
|
93
|
-
WoodJoists: WoodJoistsV1 | None = None
|
31
|
+
from openepd.model.specs.singular.electricity import ElectricityV1
|
32
|
+
from openepd.model.specs.singular.finishes import FinishesV1
|
33
|
+
from openepd.model.specs.singular.fire_and_smoke_protection import FireAndSmokeProtectionV1
|
34
|
+
from openepd.model.specs.singular.furnishings import FurnishingsV1
|
35
|
+
from openepd.model.specs.singular.grouting import GroutingV1
|
36
|
+
from openepd.model.specs.singular.manufacturing_inputs import ManufacturingInputsV1
|
37
|
+
from openepd.model.specs.singular.masonry import MasonryV1
|
38
|
+
from openepd.model.specs.singular.material_handling import MaterialHandlingV1
|
39
|
+
from openepd.model.specs.singular.mechanical import MechanicalV1
|
40
|
+
from openepd.model.specs.singular.mechanical_insulation import MechanicalInsulationV1
|
41
|
+
from openepd.model.specs.singular.network_infrastructure import NetworkInfrastructureV1
|
42
|
+
from openepd.model.specs.singular.openings import OpeningsV1
|
43
|
+
from openepd.model.specs.singular.other_electrical_equipment import OtherElectricalEquipmentV1
|
44
|
+
from openepd.model.specs.singular.other_materials import OtherMaterialsV1
|
45
|
+
from openepd.model.specs.singular.plumbing import PlumbingV1
|
46
|
+
from openepd.model.specs.singular.precast_concrete import PrecastConcreteV1
|
47
|
+
from openepd.model.specs.singular.sheathing import SheathingV1
|
48
|
+
from openepd.model.specs.singular.steel import SteelV1
|
49
|
+
from openepd.model.specs.singular.thermal_moisture_protection import ThermalMoistureProtectionV1
|
50
|
+
from openepd.model.specs.singular.utility_piping import UtilityPipingV1
|
51
|
+
from openepd.model.specs.singular.wood import WoodV1
|
52
|
+
from openepd.model.specs.singular.wood_joists import WoodJoistsV1
|
openepd/model/specs/base.py
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
import dataclasses
|
17
|
+
from types import UnionType
|
17
18
|
from typing import Any
|
18
19
|
|
19
20
|
from openepd.compat.pydantic import pyd
|
@@ -63,4 +64,4 @@ class CodegenSpec:
|
|
63
64
|
"""
|
64
65
|
|
65
66
|
exclude_from_codegen: bool = False
|
66
|
-
override_type: type
|
67
|
+
override_type: type | UnionType
|
@@ -15,6 +15,8 @@
|
|
15
15
|
#
|
16
16
|
from enum import StrEnum
|
17
17
|
|
18
|
+
from openepd.model.common import EnumGroupingAware
|
19
|
+
|
18
20
|
# Enums used
|
19
21
|
|
20
22
|
|
@@ -2182,7 +2184,7 @@ class FloorBoxFloorMaterial(StrEnum):
|
|
2182
2184
|
OTHER = "Other"
|
2183
2185
|
|
2184
2186
|
|
2185
|
-
class AciExposureClass(StrEnum):
|
2187
|
+
class AciExposureClass(EnumGroupingAware, StrEnum):
|
2186
2188
|
"""
|
2187
2189
|
American Concrete Institute concrete exposure classes.
|
2188
2190
|
|
@@ -2196,6 +2198,7 @@ class AciExposureClass(StrEnum):
|
|
2196
2198
|
* `aci.S2` - Exposed to <10000 ppm of SO4 in water and <2% SO4 in soil
|
2197
2199
|
* `aci.S3` - Exposed to >10000 ppm of SO4 in water or >2% SO4 in soil
|
2198
2200
|
|
2201
|
+
* `aci.C0` - Concrete dry or protected from moisture.
|
2199
2202
|
* `aci.C1` - Concrete in contact with moisture, but the external source of chloride does not reach it.
|
2200
2203
|
* `aci.C2` - Concrete subjected to moisture and an external source of chlorides such as deicing chemicals,
|
2201
2204
|
salt, brackish water, seawater, or spray from these sources.
|
@@ -2212,14 +2215,25 @@ class AciExposureClass(StrEnum):
|
|
2212
2215
|
S1 = "aci.S1"
|
2213
2216
|
S2 = "aci.S2"
|
2214
2217
|
S3 = "aci.S3"
|
2218
|
+
C0 = "aci.C1"
|
2215
2219
|
C1 = "aci.C1"
|
2216
2220
|
C2 = "aci.C2"
|
2217
2221
|
W0 = "aci.W0"
|
2218
2222
|
W1 = "aci.W1"
|
2219
2223
|
W2 = "aci.W2"
|
2220
2224
|
|
2225
|
+
@classmethod
|
2226
|
+
def get_groupings(cls) -> list[list]:
|
2227
|
+
"""Return logical groupings of the values."""
|
2228
|
+
return [
|
2229
|
+
[AciExposureClass.F0, AciExposureClass.F1, AciExposureClass.F2, AciExposureClass.F3],
|
2230
|
+
[AciExposureClass.S0, AciExposureClass.S1, AciExposureClass.S2, AciExposureClass.S3],
|
2231
|
+
[AciExposureClass.W0, AciExposureClass.W1],
|
2232
|
+
[AciExposureClass.C0, AciExposureClass.C1, AciExposureClass.C2],
|
2233
|
+
]
|
2234
|
+
|
2221
2235
|
|
2222
|
-
class CsaExposureClass(StrEnum):
|
2236
|
+
class CsaExposureClass(EnumGroupingAware, StrEnum):
|
2223
2237
|
"""
|
2224
2238
|
Canadian Standard Association concrete exposure classes.
|
2225
2239
|
|
@@ -2286,8 +2300,20 @@ class CsaExposureClass(StrEnum):
|
|
2286
2300
|
A_3 = "csa.A-3"
|
2287
2301
|
A_4 = "csa.A-4"
|
2288
2302
|
|
2303
|
+
@classmethod
|
2304
|
+
def get_groupings(cls) -> list[list]:
|
2305
|
+
"""Return logical groupings of the values."""
|
2306
|
+
return [
|
2307
|
+
[CsaExposureClass.C_XL],
|
2308
|
+
[CsaExposureClass.C_1, CsaExposureClass.C_2, CsaExposureClass.C_3, CsaExposureClass.C_4],
|
2309
|
+
[CsaExposureClass.F_1, CsaExposureClass.F2],
|
2310
|
+
[CsaExposureClass.N],
|
2311
|
+
[CsaExposureClass.A_1, CsaExposureClass.A_2, CsaExposureClass.A_3, CsaExposureClass.A_4],
|
2312
|
+
[CsaExposureClass.S_1, CsaExposureClass.S_2, CsaExposureClass.S_3],
|
2313
|
+
]
|
2289
2314
|
|
2290
|
-
|
2315
|
+
|
2316
|
+
class EnExposureClass(EnumGroupingAware, StrEnum):
|
2291
2317
|
"""
|
2292
2318
|
EN 206 Class (Europe).
|
2293
2319
|
|
@@ -2348,6 +2374,28 @@ class EnExposureClass(StrEnum):
|
|
2348
2374
|
en206_XA2 = "en206.XA2"
|
2349
2375
|
en206_XA3 = "en206.XA3"
|
2350
2376
|
|
2377
|
+
@classmethod
|
2378
|
+
def get_groupings(cls) -> list[list]:
|
2379
|
+
"""Return logical groupings of the values."""
|
2380
|
+
return [
|
2381
|
+
[EnExposureClass.en206_X0],
|
2382
|
+
[
|
2383
|
+
EnExposureClass.en206_XC1,
|
2384
|
+
EnExposureClass.en206_XC2,
|
2385
|
+
EnExposureClass.en206_XC3,
|
2386
|
+
EnExposureClass.en206_XC4,
|
2387
|
+
],
|
2388
|
+
[EnExposureClass.en206_XD1, EnExposureClass.en206_XD2, EnExposureClass.en206_XD3],
|
2389
|
+
[EnExposureClass.en206_XS1, EnExposureClass.en206_XS2, EnExposureClass.en206_XS3],
|
2390
|
+
[
|
2391
|
+
EnExposureClass.en206_XF1,
|
2392
|
+
EnExposureClass.en206_XF2,
|
2393
|
+
EnExposureClass.en206_XF3,
|
2394
|
+
EnExposureClass.en206_XF4,
|
2395
|
+
],
|
2396
|
+
[EnExposureClass.en206_XA1, EnExposureClass.en206_XA2, EnExposureClass.en206_XA3],
|
2397
|
+
]
|
2398
|
+
|
2351
2399
|
|
2352
2400
|
class AggregateWeightClassification(StrEnum):
|
2353
2401
|
"""
|
@@ -21,8 +21,8 @@ __all__ = ("AggregatesRangeV1",)
|
|
21
21
|
from openepd.compat.pydantic import pyd
|
22
22
|
from openepd.model.common import RangeRatioFloat
|
23
23
|
from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
|
24
|
-
from openepd.model.specs.
|
25
|
-
from openepd.model.specs.
|
24
|
+
from openepd.model.specs.enums import AggregateGradation, AggregateWeightClassification
|
25
|
+
from openepd.model.specs.singular.aggregates import AggregateApplication
|
26
26
|
from openepd.model.validation.quantity import AmountRangeLengthMm
|
27
27
|
|
28
28
|
|
@@ -26,7 +26,7 @@ __all__ = (
|
|
26
26
|
|
27
27
|
from openepd.compat.pydantic import pyd
|
28
28
|
from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
|
29
|
-
from openepd.model.specs.
|
29
|
+
from openepd.model.specs.enums import AluminiumAlloy
|
30
30
|
|
31
31
|
|
32
32
|
class AluminiumBilletsRangeV1(BaseOpenEpdHierarchicalSpec):
|
@@ -21,8 +21,8 @@ __all__ = ("AsphaltRangeV1",)
|
|
21
21
|
from openepd.compat.pydantic import pyd
|
22
22
|
from openepd.model.common import RangeRatioFloat
|
23
23
|
from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
|
24
|
-
from openepd.model.specs.
|
25
|
-
from openepd.model.validation.quantity import AmountRangeLengthMm,
|
24
|
+
from openepd.model.specs.enums import AsphaltGradation, AsphaltMixType
|
25
|
+
from openepd.model.validation.quantity import AmountRangeLengthMm, TemperatureCStr
|
26
26
|
|
27
27
|
|
28
28
|
class AsphaltRangeV1(BaseOpenEpdHierarchicalSpec):
|
@@ -44,11 +44,11 @@ class AsphaltRangeV1(BaseOpenEpdHierarchicalSpec):
|
|
44
44
|
ground_tire_rubber: RangeRatioFloat | None = pyd.Field(
|
45
45
|
default=None, description="Percent of mixture that has been replaced by ground tire rubber (GTR)."
|
46
46
|
)
|
47
|
-
max_temperature:
|
47
|
+
max_temperature: TemperatureCStr | None = pyd.Field(
|
48
48
|
default=None,
|
49
49
|
description="The upper threshold temperature to which an asphalt binder can be heated preventing the asphalt mixture from rutting",
|
50
50
|
)
|
51
|
-
min_temperature:
|
51
|
+
min_temperature: TemperatureCStr | None = pyd.Field(
|
52
52
|
default=None,
|
53
53
|
description="The lower threshold temperature for an asphalt binder to prevent thermal cracking of the asphalt mixture.",
|
54
54
|
)
|
@@ -40,7 +40,7 @@ __all__ = (
|
|
40
40
|
|
41
41
|
from openepd.compat.pydantic import pyd
|
42
42
|
from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
|
43
|
-
from openepd.model.specs.
|
43
|
+
from openepd.model.specs.enums import CladdingFacingMaterial, CladdingInsulatingMaterial, SidingFormFactor
|
44
44
|
from openepd.model.validation.quantity import AmountRangeLengthMm, AmountRangeRValue
|
45
45
|
|
46
46
|
|
openepd/model/specs/range/cmu.py
CHANGED
@@ -18,11 +18,12 @@ __all__ = ("CMURangeV1",)
|
|
18
18
|
# NB! This is a generated code. Do not edit it manually. Please see src/openepd/model/specs/README.md
|
19
19
|
|
20
20
|
|
21
|
+
from builtins import float
|
22
|
+
|
21
23
|
from openepd.compat.pydantic import pyd
|
22
|
-
from openepd.model.common import RangeFloat
|
23
24
|
from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
|
24
|
-
from openepd.model.specs.
|
25
|
-
from openepd.model.validation.quantity import
|
25
|
+
from openepd.model.specs.enums import CmuBlockType, CmuWeightClassification
|
26
|
+
from openepd.model.validation.quantity import AmountRangePressureMpa, GwpKgCo2eStr
|
26
27
|
|
27
28
|
|
28
29
|
class CMURangeV1(BaseOpenEpdHierarchicalSpec):
|
@@ -40,5 +41,5 @@ class CMURangeV1(BaseOpenEpdHierarchicalSpec):
|
|
40
41
|
block_type: list[CmuBlockType] | None = pyd.Field(default=None, description="")
|
41
42
|
insulated: bool | None = pyd.Field(default=None, description="")
|
42
43
|
sound_performance: bool | None = pyd.Field(default=None, description="")
|
43
|
-
b1_recarbonation:
|
44
|
-
b1_recarbonation_z:
|
44
|
+
b1_recarbonation: GwpKgCo2eStr | None = pyd.Field(default=None, description="")
|
45
|
+
b1_recarbonation_z: float | None = pyd.Field(default=None, description="")
|
@@ -32,7 +32,7 @@ from openepd.compat.pydantic import pyd
|
|
32
32
|
from openepd.model.common import RangeRatioFloat
|
33
33
|
from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
|
34
34
|
from openepd.model.specs.concrete import Cementitious, ConcreteTypicalApplication
|
35
|
-
from openepd.model.specs.
|
35
|
+
from openepd.model.specs.enums import AciExposureClass, CsaExposureClass, EnExposureClass
|
36
36
|
from openepd.model.validation.quantity import (
|
37
37
|
AmountRangeLengthInch,
|
38
38
|
AmountRangeLengthMm,
|
@@ -24,7 +24,7 @@ __all__ = (
|
|
24
24
|
|
25
25
|
from openepd.compat.pydantic import pyd
|
26
26
|
from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
|
27
|
-
from openepd.model.specs.
|
27
|
+
from openepd.model.specs.enums import ElevatorsBuildingRise, ElevatorsUsageIntensity
|
28
28
|
from openepd.model.validation.quantity import (
|
29
29
|
AmountRangeCapacityPerHour,
|
30
30
|
AmountRangeLengthMm,
|
@@ -51,13 +51,14 @@ __all__ = (
|
|
51
51
|
from openepd.compat.pydantic import pyd
|
52
52
|
from openepd.model.common import RangeFloat
|
53
53
|
from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
|
54
|
-
from openepd.model.specs.
|
54
|
+
from openepd.model.specs.enums import CableTraysMaterial, ConduitMaterial, EnergySource, RacewaysMaterial
|
55
55
|
from openepd.model.validation.quantity import (
|
56
56
|
AmountRangeColorTemperature,
|
57
57
|
AmountRangeLengthMm,
|
58
58
|
AmountRangeLuminosity,
|
59
59
|
AmountRangeMass,
|
60
60
|
AmountRangePower,
|
61
|
+
AmountRangeUtilization,
|
61
62
|
)
|
62
63
|
|
63
64
|
|
@@ -376,7 +377,7 @@ class LightingRangeV1(BaseOpenEpdHierarchicalSpec):
|
|
376
377
|
_EXT_VERSION = "1.0"
|
377
378
|
|
378
379
|
color_temperature: AmountRangeColorTemperature | None = pyd.Field(default=None, description="")
|
379
|
-
typical_utilization:
|
380
|
+
typical_utilization: AmountRangeUtilization | None = pyd.Field(default=None, description="")
|
380
381
|
luminosity: AmountRangeLuminosity | None = pyd.Field(default=None, description="")
|
381
382
|
wattage: AmountRangePower | None = pyd.Field(default=None, description="")
|
382
383
|
color_rendering_index: RangeFloat | None = pyd.Field(default=None, description="")
|