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.
Files changed (20) hide show
  1. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/PKG-INFO +1 -1
  2. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/aimc_parser.py +49 -31
  3. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser.egg-info/PKG-INFO +1 -1
  4. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/pyproject.toml +1 -1
  5. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/tests/test_aimc_parser.py +32 -16
  6. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/LICENSE +0 -0
  7. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/README.md +0 -0
  8. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/__init__.py +0 -0
  9. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/aid_parser.py +0 -0
  10. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/collection_helpers.py +0 -0
  11. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/demo/demo_process.py +0 -0
  12. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/demo/logging_handler.py +0 -0
  13. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/reference_helpers.py +0 -0
  14. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/submodel_parser.py +0 -0
  15. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser/utils.py +0 -0
  16. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser.egg-info/SOURCES.txt +0 -0
  17. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser.egg-info/dependency_links.txt +0 -0
  18. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser.egg-info/requires.txt +0 -0
  19. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/aas_standard_parser.egg-info/top_level.txt +0 -0
  20. {aas_standard_parser-0.1.9 → aas_standard_parser-0.2.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aas-standard-parser
3
- Version: 0.1.9
3
+ Version: 0.2.0
4
4
  Summary: Some auxiliary functions for parsing standard submodels
5
5
  Author-email: Daniel Klein <daniel.klein@em.ag>
6
6
  License: MIT License
@@ -2,7 +2,7 @@
2
2
 
3
3
  import json
4
4
  import logging
5
- from dataclasses import dataclass, field
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
- aid_submodel_id: str = field(metadata={"description": "Identifier of the AID submodel used by the source reference."})
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
- property_name: str = field(metadata={"description": "Name of the mapped property."})
22
- source_parent_path: list[str] = field(metadata={"description": "List of idShorts representing the parent path of the reference."})
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.aid_submodel_id for source_sink_relation in source_sink_relations})
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
- source_ref = source_sink_relation.first
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.aid_submodel_id = global_ref.value
257
- relation.property_name = last_fragment_ref.value
258
- relation.source_parent_path = _get_reference_parent_path(source_ref)
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aas-standard-parser
3
- Version: 0.1.9
3
+ Version: 0.2.0
4
4
  Summary: Some auxiliary functions for parsing standard submodels
5
5
  Author-email: Daniel Klein <daniel.klein@em.ag>
6
6
  License: MIT License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "aas-standard-parser"
7
- version = "0.1.9"
7
+ version = "0.2.0"
8
8
  description = "Some auxiliary functions for parsing standard submodels"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -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
- _check_relations_aid(configuration)
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
- _check_relations_aid(configuration)
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
- def _check_relations_aid(configuration: MappingConfiguration):
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.property_name is not None
85
- assert relation.property_name == "HandlingC"
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
- def _check_relations(configuration: MappingConfiguration):
89
- assert len(configuration.source_sink_relations) > 0
89
+ _check_relations_source(relation)
90
+ _check_relations_sink(relation)
91
+ _check_relation_methods(relation)
90
92
 
91
- relation = configuration.source_sink_relations[0]
93
+ def _check_relations_source(relation: SourceSinkRelation):
92
94
  assert relation is not None
93
- assert relation.source is not None
94
- assert relation.sink is not None
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 isinstance(relation.source, model.ExternalReference)
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
- _check_relation_methods(relation)
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"