diff --git a/basyx/aas/adapter/json/aasJSONSchema.json b/basyx/aas/adapter/json/aasJSONSchema.json
index 8d77c7aac..c9f5fa22a 100644
--- a/basyx/aas/adapter/json/aasJSONSchema.json
+++ b/basyx/aas/adapter/json/aasJSONSchema.json
@@ -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])*$"
}
}
}
diff --git a/basyx/aas/adapter/json/json_deserialization.py b/basyx/aas/adapter/json/json_deserialization.py
index a6756957b..40820ac4c 100644
--- a/basyx/aas/adapter/json/json_deserialization.py
+++ b/basyx/aas/adapter/json/json_deserialization.py
@@ -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
diff --git a/basyx/aas/adapter/json/json_serialization.py b/basyx/aas/adapter/json/json_serialization.py
index 96dfa3532..4a79290ac 100644
--- a/basyx/aas/adapter/json/json_serialization.py
+++ b/basyx/aas/adapter/json/json_serialization.py
@@ -186,6 +186,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
diff --git a/basyx/aas/adapter/xml/AAS.xsd b/basyx/aas/adapter/xml/AAS.xsd
index d2f6759cd..66364120b 100644
--- a/basyx/aas/adapter/xml/AAS.xsd
+++ b/basyx/aas/adapter/xml/AAS.xsd
@@ -17,6 +17,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/basyx/aas/adapter/xml/xml_deserialization.py b/basyx/aas/adapter/xml/xml_deserialization.py
index b8e441230..f933bd58b 100644
--- a/basyx/aas/adapter/xml/xml_deserialization.py
+++ b/basyx/aas/adapter/xml/xml_deserialization.py
@@ -600,8 +600,12 @@ def construct_administrative_information(cls, element: etree.Element, object_cla
**_kwargs: Any) -> model.AdministrativeInformation:
administrative_information = object_class(
revision=_get_text_or_none(element.find(NS_AAS + "revision")),
- version=_get_text_or_none(element.find(NS_AAS + "version"))
+ version=_get_text_or_none(element.find(NS_AAS + "version")),
+ template_id=_get_text_or_none(element.find(NS_AAS + "templateId"))
)
+ creator = _failsafe_construct(element.find(NS_AAS + "creator"), cls.construct_reference, cls.failsafe)
+ if creator is not None:
+ administrative_information.creator = creator
cls._amend_abstract_attributes(administrative_information, element)
return administrative_information
diff --git a/basyx/aas/adapter/xml/xml_serialization.py b/basyx/aas/adapter/xml/xml_serialization.py
index 51c9c6d9a..987cc1e56 100644
--- a/basyx/aas/adapter/xml/xml_serialization.py
+++ b/basyx/aas/adapter/xml/xml_serialization.py
@@ -184,6 +184,10 @@ def administrative_information_to_xml(obj: model.AdministrativeInformation,
et_administration.append(_generate_element(name=NS_AAS + "version", text=obj.version))
if obj.revision:
et_administration.append(_generate_element(name=NS_AAS + "revision", text=obj.revision))
+ if obj.creator:
+ et_administration.append(reference_to_xml(obj.creator, tag=NS_AAS + "creator"))
+ if obj.template_id:
+ et_administration.append(_generate_element(name=NS_AAS + "templateId", text=obj.template_id))
return et_administration
diff --git a/basyx/aas/examples/data/example_aas.py b/basyx/aas/examples/data/example_aas.py
index 6a422f8b6..499597209 100644
--- a/basyx/aas/examples/data/example_aas.py
+++ b/basyx/aas/examples/data/example_aas.py
@@ -193,7 +193,14 @@ def create_example_asset_identification_submodel() -> model.Submodel:
'de': 'Ein Beispiel-Identifikations-Submodel für eine Test-Anwendung'}),
parent=None,
administration=model.AdministrativeInformation(version='9',
- revision='0'),
+ revision='0',
+ creator=model.GlobalReference((
+ model.Key(model.KeyTypes.GLOBAL_REFERENCE,
+ 'http://acplt.org/AdministrativeInformation/'
+ 'TestAsset/Identification'),
+ )),
+ template_id='http://acplt.org/AdministrativeInformation'
+ 'Templates/TestAsset/Identification'),
semantic_id=model.ModelReference((model.Key(type_=model.KeyTypes.SUBMODEL,
value='http://acplt.org/SubmodelTemplates/AssetIdentification'),),
model.Submodel),
@@ -313,7 +320,9 @@ def create_example_bill_of_material_submodel() -> model.Submodel:
description=model.LangStringSet({'en-US': 'An example bill of material submodel for the test application',
'de': 'Ein Beispiel-BillofMaterial-Submodel für eine Test-Anwendung'}),
parent=None,
- administration=model.AdministrativeInformation(version='9'),
+ administration=model.AdministrativeInformation(version='9',
+ template_id='http://acplt.org/AdministrativeInformation'
+ 'Templates/TestAsset/BillOfMaterial'),
semantic_id=model.ModelReference((model.Key(type_=model.KeyTypes.SUBMODEL,
value='http://acplt.org/SubmodelTemplates/BillOfMaterial'),),
model.Submodel),
@@ -703,7 +712,12 @@ def create_example_submodel() -> model.Submodel:
'de': 'Ein Beispiel-Teilmodell für eine Test-Anwendung'}),
parent=None,
administration=model.AdministrativeInformation(version='9',
- revision='0'),
+ revision='0',
+ creator=model.GlobalReference((
+ model.Key(model.KeyTypes.GLOBAL_REFERENCE,
+ 'http://acplt.org/AdministrativeInformation/'
+ 'Test_Submodel'),
+ )),),
semantic_id=model.GlobalReference((model.Key(type_=model.KeyTypes.GLOBAL_REFERENCE,
value='http://acplt.org/SubmodelTemplates/'
'ExampleSubmodel'),)),
@@ -732,7 +746,15 @@ def create_example_concept_description() -> model.ConceptDescription:
description=model.LangStringSet({'en-US': 'An example concept description for the test application',
'de': 'Ein Beispiel-ConceptDescription für eine Test-Anwendung'}),
parent=None,
- administration=model.AdministrativeInformation(version='9', revision='0',
+ administration=model.AdministrativeInformation(version='9',
+ revision='0',
+ creator=model.GlobalReference((
+ model.Key(model.KeyTypes.GLOBAL_REFERENCE,
+ 'http://acplt.org/AdministrativeInformation/'
+ 'Test_ConceptDescription'),
+ )),
+ template_id='http://acplt.org/AdministrativeInformation'
+ 'Templates/Test_ConceptDescription',
embedded_data_specifications=(
_embedded_data_specification_iec61360,
)),
@@ -778,7 +800,14 @@ def create_example_asset_administration_shell() -> \
'de': 'Ein Beispiel-Verwaltungsschale für eine Test-Anwendung'}),
parent=None,
administration=model.AdministrativeInformation(version='9',
- revision='0'),
+ revision='0',
+ creator=model.GlobalReference((
+ model.Key(model.KeyTypes.GLOBAL_REFERENCE,
+ 'http://acplt.org/AdministrativeInformation/'
+ 'Test_AssetAdministrationShell'),
+ )),
+ template_id='http://acplt.org/AdministrativeInformation'
+ 'Templates/Test_AssetAdministrationShell'),
submodel={model.ModelReference((model.Key(type_=model.KeyTypes.SUBMODEL,
value='https://acplt.org/Test_Submodel'),),
model.Submodel,
diff --git a/basyx/aas/model/base.py b/basyx/aas/model/base.py
index 9dedc6e91..80c80e0cf 100644
--- a/basyx/aas/model/base.py
+++ b/basyx/aas/model/base.py
@@ -1094,6 +1094,7 @@ def __init__(
@_string_constraints.constrain_version_type("version")
+@_string_constraints.constrain_identifier("template_id")
class AdministrativeInformation(HasDataSpecification):
"""
Administrative meta-information for an element like version information.
@@ -1103,6 +1104,17 @@ class AdministrativeInformation(HasDataSpecification):
:ivar version: Version of the element.
:ivar revision: Revision of the element.
+ :ivar creator: The subject ID of the subject responsible for making the element
+ :ivar template_id: Identifier of the template that guided the creation of the element
+
+ *Note:* In case of a submodel, the template ID is the identifier of the submodel template that guided the
+ creation of the submodel.
+
+ *Note:* The submodel template ID is not relevant for validation. Here, the Submodel/semanticId shall be used
+
+ *Note:* Usage of the template ID is not restricted to submodel instances.
+ The creation of submodel templates can also be guided by another submodel template.
+
:ivar embedded_data_specifications: List of Embedded data specification.
used by the element.
"""
@@ -1110,6 +1122,8 @@ class AdministrativeInformation(HasDataSpecification):
def __init__(self,
version: Optional[VersionType] = None,
revision: Optional[RevisionType] = None,
+ creator: Optional[Reference] = None,
+ template_id: Optional[Identifier] = None,
embedded_data_specifications: Iterable[EmbeddedDataSpecification] = ()):
"""
Initializer of AdministrativeInformation
@@ -1122,6 +1136,8 @@ def __init__(self,
self.version: Optional[VersionType] = version
self._revision: Optional[RevisionType]
self.revision = revision
+ self.creator: Optional[Reference] = creator
+ self.template_id: Optional[Identifier] = template_id
self.embedded_data_specifications: List[EmbeddedDataSpecification] = list(embedded_data_specifications)
def _get_revision(self):
@@ -1140,10 +1156,14 @@ def _set_revision(self, revision: Optional[RevisionType]):
def __eq__(self, other) -> bool:
if not isinstance(other, AdministrativeInformation):
return NotImplemented
- return self.version == other.version and self._revision == other._revision
+ return self.version == other.version \
+ and self._revision == other._revision \
+ and self.creator == other.creator \
+ and self.template_id == other.template_id
def __repr__(self) -> str:
- return "AdministrativeInformation(version={}, revision={})".format(self.version, self.revision)
+ return "AdministrativeInformation(version={}, revision={}, creator={}, template_id={})".format(
+ self.version, self.revision, self.creator, self.template_id)
@_string_constraints.constrain_identifier("id")
diff --git a/test/compliance_tool/files/test_demo_full_example.json b/test/compliance_tool/files/test_demo_full_example.json
index 0bd28746d..897185b63 100644
--- a/test/compliance_tool/files/test_demo_full_example.json
+++ b/test/compliance_tool/files/test_demo_full_example.json
@@ -16,7 +16,17 @@
"id": "https://acplt.org/Test_AssetAdministrationShell",
"administration": {
"version": "9",
- "revision": "0"
+ "revision": "0",
+ "creator": {
+ "type": "GlobalReference",
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "value": "http://acplt.org/AdministrativeInformation/Test_AssetAdministrationShell"
+ }
+ ]
+ },
+ "templateId": "http://acplt.org/AdministrativeInformationTemplates/Test_AssetAdministrationShell"
},
"derivedFrom": {
"type": "ModelReference",
@@ -322,7 +332,17 @@
"id": "http://acplt.org/Submodels/Assets/TestAsset/Identification",
"administration": {
"version": "9",
- "revision": "0"
+ "revision": "0",
+ "creator": {
+ "type": "GlobalReference",
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "value": "http://acplt.org/AdministrativeInformation/TestAsset/Identification"
+ }
+ ]
+ },
+ "templateId": "http://acplt.org/AdministrativeInformationTemplates/TestAsset/Identification"
},
"semanticId": {
"type": "ModelReference",
@@ -488,7 +508,8 @@
"modelType": "Submodel",
"id": "http://acplt.org/Submodels/Assets/TestAsset/BillOfMaterial",
"administration": {
- "version": "9"
+ "version": "9",
+ "templateId": "http://acplt.org/AdministrativeInformationTemplates/TestAsset/BillOfMaterial"
},
"semanticId": {
"type": "ModelReference",
@@ -760,7 +781,16 @@
"id": "https://acplt.org/Test_Submodel",
"administration": {
"version": "9",
- "revision": "0"
+ "revision": "0",
+ "creator": {
+ "type": "GlobalReference",
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "value": "http://acplt.org/AdministrativeInformation/Test_Submodel"
+ }
+ ]
+ }
},
"semanticId": {
"type": "GlobalReference",
@@ -3086,6 +3116,16 @@
"administration": {
"version": "9",
"revision": "0",
+ "creator": {
+ "type": "GlobalReference",
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "value": "http://acplt.org/AdministrativeInformation/Test_ConceptDescription"
+ }
+ ]
+ },
+ "templateId": "http://acplt.org/AdministrativeInformationTemplates/Test_ConceptDescription",
"embeddedDataSpecifications": [
{
"dataSpecification": {
diff --git a/test/compliance_tool/files/test_demo_full_example.xml b/test/compliance_tool/files/test_demo_full_example.xml
index ca16d9aef..d13b2c0da 100644
--- a/test/compliance_tool/files/test_demo_full_example.xml
+++ b/test/compliance_tool/files/test_demo_full_example.xml
@@ -16,6 +16,16 @@
9
0
+
+ GlobalReference
+
+
+ GlobalReference
+ http://acplt.org/AdministrativeInformation/Test_AssetAdministrationShell
+
+
+
+ http://acplt.org/AdministrativeInformationTemplates/Test_AssetAdministrationShell
https://acplt.org/Test_AssetAdministrationShell
@@ -308,6 +318,16 @@
9
0
+
+ GlobalReference
+
+
+ GlobalReference
+ http://acplt.org/AdministrativeInformation/TestAsset/Identification
+
+
+
+ http://acplt.org/AdministrativeInformationTemplates/TestAsset/Identification
http://acplt.org/Submodels/Assets/TestAsset/Identification
Instance
@@ -472,6 +492,7 @@
9
+ http://acplt.org/AdministrativeInformationTemplates/TestAsset/BillOfMaterial
http://acplt.org/Submodels/Assets/TestAsset/BillOfMaterial
Instance
@@ -638,6 +659,15 @@
9
0
+
+ GlobalReference
+
+
+ GlobalReference
+ http://acplt.org/AdministrativeInformation/Test_Submodel
+
+
+
https://acplt.org/Test_Submodel
Instance
@@ -3031,6 +3061,16 @@
9
0
+
+ GlobalReference
+
+
+ GlobalReference
+ http://acplt.org/AdministrativeInformation/Test_ConceptDescription
+
+
+
+ http://acplt.org/AdministrativeInformationTemplates/Test_ConceptDescription
https://acplt.org/Test_ConceptDescription
diff --git a/test/compliance_tool/files/test_demo_full_example_json.aasx b/test/compliance_tool/files/test_demo_full_example_json.aasx
index 963b156f7..e961c7eb4 100644
Binary files a/test/compliance_tool/files/test_demo_full_example_json.aasx and b/test/compliance_tool/files/test_demo_full_example_json.aasx differ
diff --git a/test/compliance_tool/files/test_demo_full_example_wrong_attribute.json b/test/compliance_tool/files/test_demo_full_example_wrong_attribute.json
index 832336123..7de93fad6 100644
--- a/test/compliance_tool/files/test_demo_full_example_wrong_attribute.json
+++ b/test/compliance_tool/files/test_demo_full_example_wrong_attribute.json
@@ -16,7 +16,17 @@
"id": "https://acplt.org/Test_AssetAdministrationShell",
"administration": {
"version": "9",
- "revision": "0"
+ "revision": "0",
+ "creator": {
+ "type": "GlobalReference",
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "value": "http://acplt.org/AdministrativeInformation/Test_AssetAdministrationShell"
+ }
+ ]
+ },
+ "templateId": "http://acplt.org/AdministrativeInformationTemplates/Test_AssetAdministrationShell"
},
"derivedFrom": {
"type": "ModelReference",
@@ -322,7 +332,17 @@
"id": "http://acplt.org/Submodels/Assets/TestAsset/Identification",
"administration": {
"version": "9",
- "revision": "0"
+ "revision": "0",
+ "creator": {
+ "type": "GlobalReference",
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "value": "http://acplt.org/AdministrativeInformation/TestAsset/Identification"
+ }
+ ]
+ },
+ "templateId": "http://acplt.org/AdministrativeInformationTemplates/TestAsset/Identification"
},
"semanticId": {
"type": "ModelReference",
@@ -488,7 +508,8 @@
"modelType": "Submodel",
"id": "http://acplt.org/Submodels/Assets/TestAsset/BillOfMaterial",
"administration": {
- "version": "9"
+ "version": "9",
+ "templateId": "http://acplt.org/AdministrativeInformationTemplates/TestAsset/BillOfMaterial"
},
"semanticId": {
"type": "ModelReference",
@@ -760,7 +781,16 @@
"id": "https://acplt.org/Test_Submodel",
"administration": {
"version": "9",
- "revision": "0"
+ "revision": "0",
+ "creator": {
+ "type": "GlobalReference",
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "value": "http://acplt.org/AdministrativeInformation/Test_Submodel"
+ }
+ ]
+ }
},
"semanticId": {
"type": "GlobalReference",
@@ -3086,6 +3116,16 @@
"administration": {
"version": "9",
"revision": "0",
+ "creator": {
+ "type": "GlobalReference",
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "value": "http://acplt.org/AdministrativeInformation/Test_ConceptDescription"
+ }
+ ]
+ },
+ "templateId": "http://acplt.org/AdministrativeInformationTemplates/Test_ConceptDescription",
"embeddedDataSpecifications": [
{
"dataSpecification": {
diff --git a/test/compliance_tool/files/test_demo_full_example_wrong_attribute.xml b/test/compliance_tool/files/test_demo_full_example_wrong_attribute.xml
index af9ae65be..7625ef26f 100644
--- a/test/compliance_tool/files/test_demo_full_example_wrong_attribute.xml
+++ b/test/compliance_tool/files/test_demo_full_example_wrong_attribute.xml
@@ -16,6 +16,16 @@
9
0
+
+ GlobalReference
+
+
+ GlobalReference
+ http://acplt.org/AdministrativeInformation/Test_AssetAdministrationShell
+
+
+
+ http://acplt.org/AdministrativeInformationTemplates/Test_AssetAdministrationShell
https://acplt.org/Test_AssetAdministrationShell
@@ -308,6 +318,16 @@
9
0
+
+ GlobalReference
+
+
+ GlobalReference
+ http://acplt.org/AdministrativeInformation/TestAsset/Identification
+
+
+
+ http://acplt.org/AdministrativeInformationTemplates/TestAsset/Identification
http://acplt.org/Submodels/Assets/TestAsset/Identification
Instance
@@ -472,6 +492,7 @@
9
+ http://acplt.org/AdministrativeInformationTemplates/TestAsset/BillOfMaterial
http://acplt.org/Submodels/Assets/TestAsset/BillOfMaterial
Instance
@@ -638,6 +659,15 @@
9
0
+
+ GlobalReference
+
+
+ GlobalReference
+ http://acplt.org/AdministrativeInformation/Test_Submodel
+
+
+
https://acplt.org/Test_Submodel
Instance
@@ -3031,6 +3061,16 @@
9
0
+
+ GlobalReference
+
+
+ GlobalReference
+ http://acplt.org/AdministrativeInformation/Test_ConceptDescription
+
+
+
+ http://acplt.org/AdministrativeInformationTemplates/Test_ConceptDescription
https://acplt.org/Test_ConceptDescription
diff --git a/test/compliance_tool/files/test_demo_full_example_xml.aasx b/test/compliance_tool/files/test_demo_full_example_xml.aasx
index 87e317115..8a378350a 100644
Binary files a/test/compliance_tool/files/test_demo_full_example_xml.aasx and b/test/compliance_tool/files/test_demo_full_example_xml.aasx differ
diff --git a/test/compliance_tool/files/test_demo_full_example_xml_wrong_attribute.aasx b/test/compliance_tool/files/test_demo_full_example_xml_wrong_attribute.aasx
index faca6a196..627426cbd 100644
Binary files a/test/compliance_tool/files/test_demo_full_example_xml_wrong_attribute.aasx and b/test/compliance_tool/files/test_demo_full_example_xml_wrong_attribute.aasx differ