aas-standard-parser 0.1.9__tar.gz → 0.2.0__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.
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/PKG-INFO +1 -1
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/aimc_parser.py +49 -31
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser.egg-info/PKG-INFO +1 -1
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/pyproject.toml +1 -1
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/tests/test_aimc_parser.py +32 -16
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/LICENSE +0 -0
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/README.md +0 -0
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/__init__.py +0 -0
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/aid_parser.py +0 -0
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/collection_helpers.py +0 -0
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/demo/demo_process.py +0 -0
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/demo/logging_handler.py +0 -0
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/reference_helpers.py +0 -0
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/submodel_parser.py +0 -0
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/utils.py +0 -0
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser.egg-info/SOURCES.txt +0 -0
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser.egg-info/dependency_links.txt +0 -0
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser.egg-info/requires.txt +0 -0
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser.egg-info/top_level.txt +0 -0
- {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/setup.cfg +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import logging
|
|
5
|
-
from dataclasses import
|
|
5
|
+
from dataclasses import field
|
|
6
6
|
|
|
7
7
|
import basyx.aas.adapter.json
|
|
8
8
|
from basyx.aas import model
|
|
@@ -12,14 +12,25 @@ import aas_standard_parser.collection_helpers as ch
|
|
|
12
12
|
logger = logging.getLogger(__name__)
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
class ReferenceProperties:
|
|
16
|
+
"""Class representing properties of a reference in the mapping configuration."""
|
|
17
|
+
|
|
18
|
+
submodel_id: str = field(metadata={"description": "Identifier of the submodel used by the reference."})
|
|
19
|
+
property_name: str = field(metadata={"description": "Name of the mapped property."})
|
|
20
|
+
parent_path: list[str] = field(metadata={"description": "List of idShorts representing the parent path of the reference."})
|
|
21
|
+
|
|
22
|
+
|
|
15
23
|
class SourceSinkRelation:
|
|
16
24
|
"""Class representing a source-sink relation in the mapping configuration."""
|
|
17
25
|
|
|
18
|
-
|
|
26
|
+
source_submodel_id: str = field(metadata={"description": "Identifier of the source (AID) submodel used by the source reference."})
|
|
27
|
+
sink_submodel_id: str = field(metadata={"description": "Identifier of the target submodel used by the sink reference."})
|
|
19
28
|
source: model.ExternalReference = field(metadata={"description": "Reference to the source property in the AID submodel."})
|
|
20
29
|
sink: model.ExternalReference = field(metadata={"description": "Reference to the sink property in the target submodel."})
|
|
21
|
-
|
|
22
|
-
|
|
30
|
+
source_property_name: str = field(metadata={"description": "Name of the mapped property in source."})
|
|
31
|
+
sink_property_name: str = field(metadata={"description": "Name of the mapped property in sink."})
|
|
32
|
+
source_parent_path: list[str] = field(metadata={"description": "List of idShorts representing the parent path of the source reference."})
|
|
33
|
+
sink_parent_path: list[str] = field(metadata={"description": "List of idShorts representing the parent path of the reference."})
|
|
23
34
|
|
|
24
35
|
def source_as_dict(self) -> dict:
|
|
25
36
|
"""Convert the source reference to a dictionary.
|
|
@@ -37,13 +48,6 @@ class SourceSinkRelation:
|
|
|
37
48
|
"""
|
|
38
49
|
return json.loads(json.dumps(self.sink, cls=basyx.aas.adapter.json.AASToJsonEncoder))
|
|
39
50
|
|
|
40
|
-
def get_source_parent_property_group_name(self) -> str:
|
|
41
|
-
"""Get the name of the parent property group from the source. Ignore 'properties' entries from the path."""
|
|
42
|
-
if len(self.source_parent_path) == 0:
|
|
43
|
-
return ""
|
|
44
|
-
|
|
45
|
-
return next((n for n in reversed(self.source_parent_path) if n != "properties"), "")
|
|
46
|
-
|
|
47
51
|
|
|
48
52
|
class MappingConfiguration:
|
|
49
53
|
"""Class representing a mapping configuration."""
|
|
@@ -164,7 +168,7 @@ def parse_mapping_configuration_element(
|
|
|
164
168
|
return None
|
|
165
169
|
|
|
166
170
|
# check if all relations have the same AID submodel
|
|
167
|
-
aid_submodel_ids = list({source_sink_relation.
|
|
171
|
+
aid_submodel_ids = list({source_sink_relation.source_submodel_id for source_sink_relation in source_sink_relations})
|
|
168
172
|
|
|
169
173
|
if len(aid_submodel_ids) != 1:
|
|
170
174
|
logger.error(
|
|
@@ -233,35 +237,49 @@ def _generate_source_sink_relations(mapping_configuration_element: model.Submode
|
|
|
233
237
|
logger.warning(f"'second' reference is missing in RelationshipElement '{source_sink_relation.id_short}'")
|
|
234
238
|
continue
|
|
235
239
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
global_ref = next((key for key in source_ref.key if key.type == model.KeyTypes.GLOBAL_REFERENCE), None)
|
|
239
|
-
|
|
240
|
-
if global_ref is None:
|
|
241
|
-
logger.warning(f"No GLOBAL_REFERENCE key found in 'first' reference of RelationshipElement '{source_sink_relation.id_short}'")
|
|
242
|
-
continue
|
|
243
|
-
|
|
244
|
-
last_fragment_ref = next(
|
|
245
|
-
(key for key in reversed(source_ref.key) if key.type == model.KeyTypes.FRAGMENT_REFERENCE),
|
|
246
|
-
None,
|
|
247
|
-
)
|
|
248
|
-
|
|
249
|
-
if last_fragment_ref is None:
|
|
250
|
-
logger.warning(f"No FRAGMENT_REFERENCE key found in 'first' reference of RelationshipElement '{source_sink_relation.id_short}'")
|
|
251
|
-
continue
|
|
240
|
+
source_ref_properties = _get_reference_properties(source_sink_relation.first)
|
|
241
|
+
sink_ref_properties = _get_reference_properties(source_sink_relation.second)
|
|
252
242
|
|
|
253
243
|
relation = SourceSinkRelation()
|
|
244
|
+
|
|
254
245
|
relation.source = source_sink_relation.first
|
|
246
|
+
relation.source_submodel_id = source_ref_properties.submodel_id
|
|
247
|
+
relation.source_property_name = source_ref_properties.property_name
|
|
248
|
+
relation.source_parent_path = source_ref_properties.parent_path
|
|
249
|
+
|
|
255
250
|
relation.sink = source_sink_relation.second
|
|
256
|
-
relation.
|
|
257
|
-
relation.
|
|
258
|
-
relation.
|
|
251
|
+
relation.sink_submodel_id = sink_ref_properties.submodel_id
|
|
252
|
+
relation.sink_property_name = sink_ref_properties.property_name
|
|
253
|
+
relation.sink_parent_path = sink_ref_properties.parent_path
|
|
259
254
|
|
|
260
255
|
source_sink_relations.append(relation)
|
|
261
256
|
|
|
262
257
|
return source_sink_relations
|
|
263
258
|
|
|
264
259
|
|
|
260
|
+
def _get_reference_properties(reference: model.ExternalReference) -> ReferenceProperties | None:
|
|
261
|
+
global_ref = next((key for key in reference.key if key.type == model.KeyTypes.GLOBAL_REFERENCE), None)
|
|
262
|
+
|
|
263
|
+
if global_ref is None:
|
|
264
|
+
logger.warning(f"No GLOBAL_REFERENCE key found in 'first' reference of RelationshipElement '{reference}'")
|
|
265
|
+
return None
|
|
266
|
+
|
|
267
|
+
last_fragment_ref = next((key for key in reversed(reference.key) if key.type == model.KeyTypes.FRAGMENT_REFERENCE), None)
|
|
268
|
+
|
|
269
|
+
if last_fragment_ref is None:
|
|
270
|
+
logger.warning(f"No FRAGMENT_REFERENCE key found in 'first' reference of RelationshipElement '{reference.id_short}'")
|
|
271
|
+
return None
|
|
272
|
+
|
|
273
|
+
parent_path = _get_reference_parent_path(reference)
|
|
274
|
+
|
|
275
|
+
ref_properties = ReferenceProperties()
|
|
276
|
+
ref_properties.submodel_id = global_ref.value
|
|
277
|
+
ref_properties.property_name = last_fragment_ref.value
|
|
278
|
+
ref_properties.parent_path = parent_path
|
|
279
|
+
|
|
280
|
+
return ref_properties
|
|
281
|
+
|
|
282
|
+
|
|
265
283
|
def _get_reference_parent_path(reference: model.ExternalReference) -> list[str]:
|
|
266
284
|
"""Get the parent path of a reference as a list of idShorts.
|
|
267
285
|
|
|
@@ -40,7 +40,7 @@ def test_003_parse_mapping_configuration_element(aimc_submodel: model.submodel):
|
|
|
40
40
|
|
|
41
41
|
assert configuration is not None
|
|
42
42
|
_check_interface_ref(configuration)
|
|
43
|
-
|
|
43
|
+
_check_relations(configuration)
|
|
44
44
|
_check_relations(configuration)
|
|
45
45
|
|
|
46
46
|
def test_004_parse_mapping_configurations(aimc_submodel: model.submodel):
|
|
@@ -56,7 +56,7 @@ def test_004_parse_mapping_configurations(aimc_submodel: model.submodel):
|
|
|
56
56
|
assert configuration.aid_submodel_id == "https://fluid40.de/ids/sm/4757_4856_8464_1441"
|
|
57
57
|
|
|
58
58
|
_check_interface_ref(configuration)
|
|
59
|
-
|
|
59
|
+
_check_relations(configuration)
|
|
60
60
|
_check_relations(configuration)
|
|
61
61
|
|
|
62
62
|
def _check_interface_ref(configuration: MappingConfiguration):
|
|
@@ -74,32 +74,51 @@ def _check_interface_ref(configuration: MappingConfiguration):
|
|
|
74
74
|
assert key is not None
|
|
75
75
|
assert key.value == "https://fluid40.de/ids/sm/4757_4856_8464_1442/Interface_MQTT"
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
|
|
78
|
+
def _check_relations(configuration: MappingConfiguration):
|
|
78
79
|
assert len(configuration.source_sink_relations) > 0
|
|
79
80
|
|
|
80
81
|
relation = configuration.source_sink_relations[0]
|
|
81
82
|
assert relation is not None
|
|
82
|
-
assert relation.aid_submodel_id == configuration.aid_submodel_id
|
|
83
83
|
|
|
84
|
-
assert relation.
|
|
85
|
-
assert relation.
|
|
84
|
+
assert relation.source is not None
|
|
85
|
+
assert relation.source_submodel_id == configuration.aid_submodel_id
|
|
86
86
|
|
|
87
|
+
assert relation.sink is not None
|
|
87
88
|
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
_check_relations_source(relation)
|
|
90
|
+
_check_relations_sink(relation)
|
|
91
|
+
_check_relation_methods(relation)
|
|
90
92
|
|
|
91
|
-
|
|
93
|
+
def _check_relations_source(relation: SourceSinkRelation):
|
|
92
94
|
assert relation is not None
|
|
93
|
-
|
|
94
|
-
assert relation.
|
|
95
|
+
|
|
96
|
+
assert isinstance(relation.source, model.ExternalReference)
|
|
97
|
+
|
|
98
|
+
assert relation.source_property_name is not None
|
|
99
|
+
assert relation.source_property_name == "HandlingC"
|
|
100
|
+
|
|
95
101
|
assert relation.source_parent_path is not None
|
|
96
102
|
assert len(relation.source_parent_path) == 5
|
|
97
103
|
assert relation.source_parent_path[3] == "axes_position"
|
|
98
104
|
|
|
99
|
-
assert
|
|
105
|
+
assert relation.source_submodel_id is not None
|
|
106
|
+
assert relation.source_submodel_id == relation.source.key[0].value
|
|
107
|
+
|
|
108
|
+
def _check_relations_sink(relation: SourceSinkRelation):
|
|
109
|
+
assert relation is not None
|
|
110
|
+
|
|
100
111
|
assert isinstance(relation.sink, model.ExternalReference)
|
|
101
112
|
|
|
102
|
-
|
|
113
|
+
assert relation.sink_property_name is not None
|
|
114
|
+
assert relation.sink_property_name == "HandlingC"
|
|
115
|
+
|
|
116
|
+
assert relation.sink_parent_path is not None
|
|
117
|
+
assert len(relation.sink_parent_path) == 2
|
|
118
|
+
assert relation.sink_parent_path[1] == "AxesPosition"
|
|
119
|
+
|
|
120
|
+
assert relation.sink_submodel_id is not None
|
|
121
|
+
assert relation.sink_submodel_id == relation.sink.key[0].value
|
|
103
122
|
|
|
104
123
|
def _check_relation_methods(relation: SourceSinkRelation):
|
|
105
124
|
# test to_json methods
|
|
@@ -110,6 +129,3 @@ def _check_relation_methods(relation: SourceSinkRelation):
|
|
|
110
129
|
sink_json = relation.sink_as_dict()
|
|
111
130
|
assert sink_json is not None
|
|
112
131
|
assert "type" in sink_json
|
|
113
|
-
|
|
114
|
-
parent_name = relation.get_source_parent_property_group_name()
|
|
115
|
-
assert parent_name == "axes_position"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/collection_helpers.py
RENAMED
|
File without changes
|
{aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/demo/demo_process.py
RENAMED
|
File without changes
|
{aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/demo/logging_handler.py
RENAMED
|
File without changes
|
{aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/reference_helpers.py
RENAMED
|
File without changes
|
{aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/submodel_parser.py
RENAMED
|
File without changes
|
|
File without changes
|
{aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser.egg-info/requires.txt
RENAMED
|
File without changes
|
{aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|