Skip to content

Commit

Permalink
Merge branch 'improve/V30' into V30/specific_asset_id_value
Browse files Browse the repository at this point in the history
  • Loading branch information
s-heppner authored Aug 24, 2023
2 parents daa6316 + e0e724b commit 5479388
Show file tree
Hide file tree
Showing 31 changed files with 1,035 additions and 782 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ submodel = model.Submodel(identifier)

Create a `Property` and add it to the `Submodel`:
```python
# create a global reference to a semantic description of the property
semantic_reference = model.GlobalReference(
# create an external reference to a semantic description of the property
semantic_reference = model.ExternalReference(
(model.Key(
type_=model.KeyTypes.GLOBAL_REFERENCE,
value='http://acplt.org/Properties/SimpleProperty'
Expand Down
10 changes: 5 additions & 5 deletions basyx/aas/adapter/_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
XML_NS_MAP = {"aas": "https://admin-shell.io/aas/3/0"}
XML_NS_AAS = "{" + XML_NS_MAP["aas"] + "}"

MODELING_KIND: Dict[model.ModelingKind, str] = {
model.ModelingKind.TEMPLATE: 'Template',
model.ModelingKind.INSTANCE: 'Instance'}
MODELLING_KIND: Dict[model.ModellingKind, str] = {
model.ModellingKind.TEMPLATE: 'Template',
model.ModellingKind.INSTANCE: 'Instance'}

ASSET_KIND: Dict[model.AssetKind, str] = {
model.AssetKind.TYPE: 'Type',
Expand All @@ -39,7 +39,7 @@
model.StateOfEvent.OFF: 'off'}

REFERENCE_TYPES: Dict[Type[model.Reference], str] = {
model.GlobalReference: 'GlobalReference',
model.ExternalReference: 'ExternalReference',
model.ModelReference: 'ModelReference'}

KEY_TYPES: Dict[model.KeyTypes, str] = {
Expand Down Expand Up @@ -92,7 +92,7 @@
model.base.IEC61360LevelType.MAX: 'max',
}

MODELING_KIND_INVERSE: Dict[str, model.ModelingKind] = {v: k for k, v in MODELING_KIND.items()}
MODELLING_KIND_INVERSE: Dict[str, model.ModellingKind] = {v: k for k, v in MODELLING_KIND.items()}
ASSET_KIND_INVERSE: Dict[str, model.AssetKind] = {v: k for k, v in ASSET_KIND.items()}
QUALIFIER_KIND_INVERSE: Dict[str, model.QualifierKind] = {v: k for k, v in QUALIFIER_KIND.items()}
DIRECTION_INVERSE: Dict[str, model.Direction] = {v: k for k, v in DIRECTION.items()}
Expand Down
15 changes: 12 additions & 3 deletions basyx/aas/adapter/json/aasJSONSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@
"revision": {
"type": "string",
"minLength": 1
},
"creator": {
"$ref": "#/definitions/Reference"
},
"templateId": {
"type": "string",
"minLength": 1,
"maxLength": 2000,
"pattern": "^([\\t\\n\\r -\ud7ff\ue000-\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$"
}
}
}
Expand Down Expand Up @@ -654,7 +663,7 @@
"type": "object",
"properties": {
"kind": {
"$ref": "#/definitions/ModelingKind"
"$ref": "#/definitions/ModellingKind"
}
}
},
Expand Down Expand Up @@ -802,7 +811,7 @@
"SubmodelElementList"
]
},
"ModelingKind": {
"ModellingKind": {
"type": "string",
"enum": [
"Instance",
Expand Down Expand Up @@ -1059,7 +1068,7 @@
"ReferenceTypes": {
"type": "string",
"enum": [
"GlobalReference",
"ExternalReference",
"ModelReference"
]
},
Expand Down
28 changes: 16 additions & 12 deletions basyx/aas/adapter/json/json_deserialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from typing import Dict, Callable, TypeVar, Type, List, IO, Optional, Set

from basyx.aas import model
from .._generic import MODELING_KIND_INVERSE, ASSET_KIND_INVERSE, KEY_TYPES_INVERSE, ENTITY_TYPES_INVERSE, \
from .._generic import MODELLING_KIND_INVERSE, ASSET_KIND_INVERSE, KEY_TYPES_INVERSE, ENTITY_TYPES_INVERSE, \
IEC61360_DATA_TYPES_INVERSE, IEC61360_LEVEL_TYPES_INVERSE, KEY_TYPES_CLASSES_INVERSE, REFERENCE_TYPES_INVERSE, \
DIRECTION_INVERSE, STATE_OF_EVENT_INVERSE, QUALIFIER_KIND_INVERSE

Expand Down Expand Up @@ -263,8 +263,8 @@ def _amend_abstract_attributes(cls, obj: object, dct: Dict[str, object]) -> None
# TODO: remove the following type: ignore comment when mypy supports abstract types for Type[T]
# see https://github.com/python/mypy/issues/5374
model.EmbeddedDataSpecification(
data_specification=cls._construct_global_reference(_get_ts(dspec, 'dataSpecification',
dict)),
data_specification=cls._construct_external_reference(_get_ts(dspec, 'dataSpecification',
dict)),
data_specification_content=_get_ts(dspec, 'dataSpecificationContent',
model.DataSpecificationContent) # type: ignore
)
Expand All @@ -275,14 +275,14 @@ def _amend_abstract_attributes(cls, obj: object, dct: Dict[str, object]) -> None
obj.extension.add(cls._construct_extension(extension))

@classmethod
def _get_kind(cls, dct: Dict[str, object]) -> model.ModelingKind:
def _get_kind(cls, dct: Dict[str, object]) -> model.ModellingKind:
"""
Utility method to get the kind of an HasKind object from its JSON representation.
:param dct: The object's dict representation from JSON
:return: The object's `kind` value
"""
return MODELING_KIND_INVERSE[_get_ts(dct, "kind", str)] if 'kind' in dct else model.ModelingKind.INSTANCE
return MODELLING_KIND_INVERSE[_get_ts(dct, "kind", str)] if 'kind' in dct else model.ModellingKind.INSTANCE

# #############################################################################
# Helper Constructor Methods starting from here
Expand All @@ -303,7 +303,7 @@ def _construct_specific_asset_id(cls, dct: Dict[str, object], object_class=model
# semantic_id can't be applied by _amend_abstract_attributes because specificAssetId is immutable
return object_class(name=_get_ts(dct, 'name', str),
value=_get_ts(dct, 'value', str),
external_subject_id=cls._construct_global_reference(
external_subject_id=cls._construct_external_reference(
_get_ts(dct, 'externalSubjectId', dict)),
semantic_id=cls._construct_reference(_get_ts(dct, 'semanticId', dict))
if 'semanticId' in dct else None,
Expand All @@ -317,16 +317,16 @@ def _construct_reference(cls, dct: Dict[str, object]) -> model.Reference:
reference_type: Type[model.Reference] = REFERENCE_TYPES_INVERSE[_get_ts(dct, 'type', str)]
if reference_type is model.ModelReference:
return cls._construct_model_reference(dct, model.Referable) # type: ignore
elif reference_type is model.GlobalReference:
return cls._construct_global_reference(dct)
elif reference_type is model.ExternalReference:
return cls._construct_external_reference(dct)
raise ValueError(f"Unsupported reference type {reference_type}!")

@classmethod
def _construct_global_reference(cls, dct: Dict[str, object], object_class=model.GlobalReference)\
-> model.GlobalReference:
def _construct_external_reference(cls, dct: Dict[str, object], object_class=model.ExternalReference)\
-> model.ExternalReference:
reference_type: Type[model.Reference] = REFERENCE_TYPES_INVERSE[_get_ts(dct, 'type', str)]
if reference_type is not model.GlobalReference:
raise ValueError(f"Expected a reference of type {model.GlobalReference}, got {reference_type}!")
if reference_type is not model.ExternalReference:
raise ValueError(f"Expected a reference of type {model.ExternalReference}, got {reference_type}!")
keys = [cls._construct_key(key_data) for key_data in _get_ts(dct, "keys", list)]
return object_class(tuple(keys), cls._construct_reference(_get_ts(dct, 'referredSemanticId', dict))
if 'referredSemanticId' in dct else None)
Expand Down Expand Up @@ -356,6 +356,10 @@ def _construct_administrative_information(
ret.revision = _get_ts(dct, 'revision', str)
elif 'revision' in dct:
logger.warning("Ignoring 'revision' attribute of AdministrativeInformation object due to missing 'version'")
if 'creator' in dct:
ret.creator = cls._construct_reference(_get_ts(dct, 'creator', dict))
if 'templateId' in dct:
ret.template_id = _get_ts(dct, 'templateId', str)
return ret

@classmethod
Expand Down
23 changes: 14 additions & 9 deletions basyx/aas/adapter/json/json_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def default(self, obj: object) -> object:
model.Extension: self._extension_to_json,
model.File: self._file_to_json,
model.Key: self._key_to_json,
model.LangStringSet: self._lang_string_set_to_json,
model.MultiLanguageProperty: self._multi_language_property_to_json,
model.Operation: self._operation_to_json,
model.OperationVariable: self._operation_variable_to_json,
Expand Down Expand Up @@ -123,11 +124,11 @@ def _abstract_classes_to_json(cls, obj: object) -> Dict[str, object]:
if obj.id_short:
data['idShort'] = obj.id_short
if obj.display_name:
data['displayName'] = cls._lang_string_set_to_json(obj.display_name)
data['displayName'] = obj.display_name
if obj.category:
data['category'] = obj.category
if obj.description:
data['description'] = cls._lang_string_set_to_json(obj.description)
data['description'] = obj.description
try:
ref_type = next(iter(t for t in inspect.getmro(type(obj)) if t in model.KEY_TYPES_CLASSES))
except StopIteration as e:
Expand All @@ -144,8 +145,8 @@ def _abstract_classes_to_json(cls, obj: object) -> Dict[str, object]:
if obj.supplemental_semantic_id:
data['supplementalSemanticIds'] = list(obj.supplemental_semantic_id)
if isinstance(obj, model.HasKind):
if obj.kind is model.ModelingKind.TEMPLATE:
data['kind'] = _generic.MODELING_KIND[obj.kind]
if obj.kind is model.ModellingKind.TEMPLATE:
data['kind'] = _generic.MODELLING_KIND[obj.kind]
if isinstance(obj, model.Qualifiable) and not cls.stripped:
if obj.qualifier:
data['qualifiers'] = list(obj.qualifier)
Expand Down Expand Up @@ -186,6 +187,10 @@ def _administrative_information_to_json(cls, obj: model.AdministrativeInformatio
data['version'] = obj.version
if obj.revision:
data['revision'] = obj.revision
if obj.creator:
data['creator'] = obj.creator
if obj.template_id:
data['templateId'] = obj.template_id
return data

@classmethod
Expand Down Expand Up @@ -337,14 +342,14 @@ def _data_specification_iec61360_to_json(
"""
data_spec: Dict[str, object] = {
'modelType': 'DataSpecificationIEC61360',
'preferredName': cls._lang_string_set_to_json(obj.preferred_name)
'preferredName': obj.preferred_name
}
if obj.data_type is not None:
data_spec['dataType'] = _generic.IEC61360_DATA_TYPES[obj.data_type]
if obj.definition is not None:
data_spec['definition'] = cls._lang_string_set_to_json(obj.definition)
data_spec['definition'] = obj.definition
if obj.short_name is not None:
data_spec['shortName'] = cls._lang_string_set_to_json(obj.short_name)
data_spec['shortName'] = obj.short_name
if obj.unit is not None:
data_spec['unit'] = obj.unit
if obj.unit_id is not None:
Expand Down Expand Up @@ -375,7 +380,7 @@ def _data_specification_physical_unit_to_json(
'modelType': 'DataSpecificationPhysicalUnit',
'unitName': obj.unit_name,
'unitSymbol': obj.unit_symbol,
'definition': cls._lang_string_set_to_json(obj.definition)
'definition': obj.definition
}
if obj.si_notation is not None:
data_spec['siNotation'] = obj.si_notation
Expand Down Expand Up @@ -470,7 +475,7 @@ def _multi_language_property_to_json(cls, obj: model.MultiLanguageProperty) -> D
"""
data = cls._abstract_classes_to_json(obj)
if obj.value:
data['value'] = cls._lang_string_set_to_json(obj.value)
data['value'] = obj.value
if obj.value_id:
data['valueId'] = obj.value_id
return data
Expand Down
15 changes: 12 additions & 3 deletions basyx/aas/adapter/xml/AAS.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="creator" type="reference_t" minOccurs="0" maxOccurs="1"/>
<xs:element name="templateId" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="2000"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:group>
<xs:group name="annotatedRelationshipElement">
Expand Down Expand Up @@ -526,7 +535,7 @@
</xs:group>
<xs:group name="hasKind">
<xs:sequence>
<xs:element name="kind" type="modelingKind_t" minOccurs="0" maxOccurs="1"/>
<xs:element name="kind" type="modellingKind_t" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:group>
<xs:group name="hasKind_choice">
Expand Down Expand Up @@ -1101,7 +1110,7 @@
<xs:group ref="levelType"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="modelingKind_t">
<xs:simpleType name="modellingKind_t">
<xs:restriction base="xs:string">
<xs:enumeration value="Template"/>
<xs:enumeration value="Instance"/>
Expand All @@ -1116,7 +1125,7 @@
</xs:simpleType>
<xs:simpleType name="referenceTypes_t">
<xs:restriction base="xs:string">
<xs:enumeration value="GlobalReference"/>
<xs:enumeration value="ExternalReference"/>
<xs:enumeration value="ModelReference"/>
</xs:restriction>
</xs:simpleType>
Expand Down
Loading

0 comments on commit 5479388

Please sign in to comment.