From aa5d2496f845352c849749379438a53ba48a4185 Mon Sep 17 00:00:00 2001 From: Julian Vogel Date: Mon, 18 Nov 2024 16:50:48 +0100 Subject: [PATCH 1/4] aas.adapter: skip writing `ExternalReference`s without log message --- sdk/basyx/aas/adapter/aasx.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdk/basyx/aas/adapter/aasx.py b/sdk/basyx/aas/adapter/aasx.py index 1c27640f..1477c33c 100644 --- a/sdk/basyx/aas/adapter/aasx.py +++ b/sdk/basyx/aas/adapter/aasx.py @@ -402,6 +402,8 @@ def write_aas(self, concept_descriptions: List[model.ConceptDescription] = [] for identifiable in objects_to_be_written: for semantic_id in traversal.walk_semantic_ids_recursive(identifiable): + if isinstance(semantic_id, model.ExternalReference): + continue if not isinstance(semantic_id, model.ModelReference) \ or semantic_id.type is not model.ConceptDescription: logger.info("semanticId %s does not reference a ConceptDescription.", str(semantic_id)) From 3de9498e2f8af717b6e2560b83e0492b9a12d55b Mon Sep 17 00:00:00 2001 From: Julian Vogel Date: Mon, 18 Nov 2024 17:02:30 +0100 Subject: [PATCH 2/4] aas.adapter.json: deserialize ModelReferences with last key type --- sdk/basyx/aas/adapter/json/json_deserialization.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sdk/basyx/aas/adapter/json/json_deserialization.py b/sdk/basyx/aas/adapter/json/json_deserialization.py index 455a309e..50d9e04f 100644 --- a/sdk/basyx/aas/adapter/json/json_deserialization.py +++ b/sdk/basyx/aas/adapter/json/json_deserialization.py @@ -340,10 +340,12 @@ def _construct_model_reference(cls, dct: Dict[str, object], type_: Type[T], obje if reference_type is not model.ModelReference: raise ValueError(f"Expected a reference of type {model.ModelReference}, got {reference_type}!") keys = [cls._construct_key(key_data) for key_data in _get_ts(dct, "keys", list)] - if keys and not issubclass(KEY_TYPES_CLASSES_INVERSE.get(keys[-1].type, type(None)), type_): + last_key_type = KEY_TYPES_CLASSES_INVERSE.get(keys[-1].type, type(None)) + if keys and not issubclass(last_key_type, type_): logger.warning("type %s of last key of reference to %s does not match reference type %s", keys[-1].type.name, " / ".join(str(k) for k in keys), type_.__name__) - return object_class(tuple(keys), type_, cls._construct_reference(_get_ts(dct, 'referredSemanticId', dict)) + return object_class(tuple(keys), last_key_type, + cls._construct_reference(_get_ts(dct, 'referredSemanticId', dict)) if 'referredSemanticId' in dct else None) @classmethod From f8b232ac220334c8cefecac7207092f2897c4df4 Mon Sep 17 00:00:00 2001 From: Julian Vogel Date: Thu, 21 Nov 2024 17:11:43 +0100 Subject: [PATCH 3/4] aas.adapter: check semantic ids have same model reference type --- sdk/basyx/aas/examples/data/_helper.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sdk/basyx/aas/examples/data/_helper.py b/sdk/basyx/aas/examples/data/_helper.py index 231ba2ad..6e0170ac 100644 --- a/sdk/basyx/aas/examples/data/_helper.py +++ b/sdk/basyx/aas/examples/data/_helper.py @@ -212,7 +212,15 @@ def _check_has_semantics_equal(self, object_: model.HasSemantics, expected_objec :param expected_object: The expected HasSemantic object :return: The value of expression to be used in control statements """ - self.check_attribute_equal(object_, "semantic_id", expected_object.semantic_id) + if self.check_attribute_equal(object_, "semantic_id", expected_object.semantic_id) and \ + isinstance(expected_object.semantic_id, model.ModelReference): + if self.check(isinstance(object_.semantic_id, model.ModelReference), + '{} must be a ModelReference'.format(repr(object_))): # type: ignore + self.check( + object_.semantic_id.type == expected_object.semantic_id.type, # type: ignore + 'ModelReference type {} of {} must be equal to {}'.format(object_.semantic_id.type, # type: ignore + repr(object_), + expected_object.semantic_id.type)) for suppl_semantic_id in expected_object.supplemental_semantic_id: given_semantic_id = self._find_reference(suppl_semantic_id, object_.supplemental_semantic_id) self.check(given_semantic_id is not None, f"{object_!r} must have supplementalSemanticId", From a441d203a11ce2d009e032c778501bec7d0652b2 Mon Sep 17 00:00:00 2001 From: Julian Vogel Date: Mon, 9 Dec 2024 14:25:36 +0100 Subject: [PATCH 4/4] aas.adapter: raise error when model ref to cd is missing --- sdk/basyx/aas/adapter/aasx.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sdk/basyx/aas/adapter/aasx.py b/sdk/basyx/aas/adapter/aasx.py index 1477c33c..a266ffed 100644 --- a/sdk/basyx/aas/adapter/aasx.py +++ b/sdk/basyx/aas/adapter/aasx.py @@ -411,12 +411,13 @@ def write_aas(self, try: cd = semantic_id.resolve(object_store) except KeyError: - logger.info("ConceptDescription for semanticId %s not found in object store.", str(semantic_id)) - continue + raise KeyError("ConceptDescription for semanticId {} not found in object store.".format( + str(semantic_id))) except model.UnexpectedTypeError as e: - logger.error("semanticId %s resolves to %s, which is not a ConceptDescription", - str(semantic_id), e.value) - continue + raise model.UnexpectedTypeError( + e.value, + "semanticId {} resolves to {}, which is not a ConceptDescription".format( + str(semantic_id), e.value)) concept_descriptions.append(cd) objects_to_be_written.update(concept_descriptions)