diff --git a/aas/adapter/aasx.py b/aas/adapter/aasx.py new file mode 100644 index 0000000000000000000000000000000000000000..65f170e637a22d1b56ee9f5bcc425277fa2f5f16 --- /dev/null +++ b/aas/adapter/aasx.py @@ -0,0 +1,684 @@ +# Copyright 2019 PyI40AAS Contributors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +""" +Functionality for reading and writing AASX files according to "Details of the Asset Administration Shell Part 1 V2.0", +section 7. + +The AASX file format is built upon the Open Packaging Conventions (OPC; ECMA 376-2). We use the `pyecma376_2` library +for low level OPC reading and writing. It currently supports all required features except for embedded digital +signatures. + +Writing and reading of AASX packages is performed through the AASXReader and AASXWriter classes. Each instance of these +classes wraps an existing AASX file resp. a file to be created and allows to read/write the included AAS objects +into/form object stores. For handling of embedded supplementary files, this module provides the +`AbstractSupplementaryFileContainer` class interface and the `DictSupplementaryFileContainer` implementation. +""" + +import abc +import hashlib +import io +import logging +import os +import re +from typing import Dict, Tuple, IO, Union, List, Set, Optional + +from .. import model +from .json.json_deserialization import read_json_aas_file +from .json.json_serialization import write_aas_json_file +import pyecma376_2 +from ..util import traversal + +logger = logging.getLogger(__name__) + +RELATIONSHIP_TYPE_AASX_ORIGIN = "http://www.admin-shell.io/aasx/relationships/aasx-origin" +RELATIONSHIP_TYPE_AAS_SPEC = "http://www.admin-shell.io/aasx/relationships/aas-spec" +RELATIONSHIP_TYPE_AAS_SPEC_SPLIT = "http://www.admin-shell.io/aasx/relationships/aas-spec-split" +RELATIONSHIP_TYPE_AAS_SUPL = "http://www.admin-shell.io/aasx/relationships/aas-suppl" + + +class AASXReader: + """ + An AASXReader wraps an existing AASX package file to allow reading its contents and metadata. + + Basic usage: + + objects = DictObjectStore() + files = DictSupplementaryFileContainer() + with AASXReader("filename.aasx") as reader: + meta_data = reader.get_core_properties() + reader.read_into(objects, files) + """ + def __init__(self, file: Union[os.PathLike, str, IO]): + """ + Open an AASX reader for the given filename or file handle + + The given file is opened as OPC ZIP package. Make sure to call `AASXReader.close()` after reading the file + contents to close the underlying ZIP file reader. You may also use the AASXReader as a context manager to ensure + closing under any circumstances. + + :param file: A filename, file path or an open file-like object in binary mode + :raises ValueError: If the file is not a valid OPC zip package + """ + try: + logger.debug("Opening {} as AASX pacakge for reading ...".format(file)) + self.reader = pyecma376_2.ZipPackageReader(file) + except Exception as e: + raise ValueError("{} is not a valid ECMA376-2 (OPC) file".format(file)) from e + + def get_core_properties(self) -> pyecma376_2.OPCCoreProperties: + """ + Retrieve the OPC Core Properties (meta data) of the AASX package file. + + If no meta data is provided in the package file, an emtpy OPCCoreProperties object is returned. + + :return: The AASX package's meta data + """ + return self.reader.get_core_properties() + + def get_thumbnail(self) -> Optional[bytes]: + """ + Retrieve the packages thumbnail image + + The thumbnail image file is read into memory and returned as bytes object. You may use some python image library + for further processing or conversion, e.g. `pillow`: + + import io + from PIL import Image + thumbnail = Image.open(io.BytesIO(reader.get_thumbnail())) + + :return: The AASX package thumbnail's file contents or None if no thumbnail is provided + """ + try: + thumbnail_part = self.reader.get_related_parts_by_type()[pyecma376_2.RELATIONSHIP_TYPE_THUMBNAIL][0] + except IndexError: + return None + + with self.reader.open_part(thumbnail_part) as p: + return p.read() + + def read_into(self, object_store: model.AbstractObjectStore, + file_store: "AbstractSupplementaryFileContainer", + override_existing: bool = False) -> Set[model.Identifier]: + """ + Read the contents of the AASX package and add them into a given ObjectStore + + This function does the main job of reading the AASX file's contents. It traverses the relationships within the + package to find AAS JSON or XML parts, parses them and adds the contained AAS objects into the provided + `object_store`. While doing so, it searches all parsed Submodels for File objects to extract the supplementary + files. The referenced supplementary files are added to the given `file_store` and the File objects' values are + updated with the absolute name of the supplementary file to allow for robust resolution the file within the + `file_store` later. + + :param object_store: An ObjectStore to add the AAS objects from the AASX file to + :param file_store: A SupplementaryFileContainer to add the embedded supplementary files to + :param override_existing: If True, existing objects in the object store are overridden with objects from the + AASX that have the same Identifer. Default behavior is to skip those objects from the AASX. + :return: A set of the Identifiers of all Identifiable objects parsed from the AASX file + """ + # Find AASX-Origin part + core_rels = self.reader.get_related_parts_by_type() + try: + aasx_origin_part = core_rels[RELATIONSHIP_TYPE_AASX_ORIGIN][0] + except IndexError as e: + raise ValueError("Not a valid AASX file: aasx-origin Relationship is missing.") from e + + read_identifiables: Set[model.Identifier] = set() + + # Iterate AAS files + for aas_part in self.reader.get_related_parts_by_type(aasx_origin_part)[ + RELATIONSHIP_TYPE_AAS_SPEC]: + self._read_aas_part_into(aas_part, object_store, file_store, read_identifiables, override_existing) + + # Iterate split parts of AAS file + for split_part in self.reader.get_related_parts_by_type(aas_part)[ + RELATIONSHIP_TYPE_AAS_SPEC_SPLIT]: + self._read_aas_part_into(split_part, object_store, file_store, read_identifiables, override_existing) + + return read_identifiables + + def close(self) -> None: + """ + Close the AASXReader and the underlying OPC / ZIP file readers. Must be called after reading the file. + """ + self.reader.close() + + def __enter__(self) -> "AASXReader": + return self + + def __exit__(self, exc_type, exc_val, exc_tb) -> None: + self.close() + + def _read_aas_part_into(self, part_name: str, + object_store: model.AbstractObjectStore, + file_store: "AbstractSupplementaryFileContainer", + read_identifiables: Set[model.Identifier], + override_existing: bool) -> None: + """ + Helper function for `read_into()` to read and process the contents of an AAS-spec part of the AASX file. + + This method primarily checks for duplicate objects. It uses `_parse_aas_parse()` to do the actual parsing and + `_collect_supplementary_files()` for supplementary file processing of non-duplicate objects. + + :param part_name: The OPC part name to read + :param object_store: An ObjectStore to add the AAS objects from the AASX file to + :param file_store: A SupplementaryFileContainer to add the embedded supplementary files to, which are reference + from a File object of this part + :param read_identifiables: A set of Identifiers of objects which have already been read. New objects' + Identifiers are added to this set. Objects with already known Identifiers are skipped silently. + :param override_existing: If True, existing objects in the object store are overridden with objects from the + AASX that have the same Identifer. Default behavior is to skip those objects from the AASX. + """ + for obj in self._parse_aas_part(part_name): + if obj.identification in read_identifiables: + continue + if obj.identification in object_store: + if override_existing: + logger.info("Overriding existing object in ObjectStore with {} ...".format(obj)) + object_store.discard(obj) + else: + logger.warning("Skipping {}, since an object with the same id is already contained in the " + "ObjectStore".format(obj)) + continue + object_store.add(obj) + read_identifiables.add(obj.identification) + if isinstance(obj, model.Submodel): + self._collect_supplementary_files(part_name, obj, file_store) + + def _parse_aas_part(self, part_name: str) -> model.DictObjectStore: + """ + Helper function to parse the AAS objects from a single JSON or XML part of the AASX package. + + This method chooses and calls the correct parser. + + :param part_name: The OPC part name of the part to be parsed + :return: A DictObjectStore containing the parsed AAS objects + """ + content_type = self.reader.get_content_type(part_name) + extension = part_name.split("/")[-1].split(".")[-1] + if content_type.split(";")[0] in ("text/xml", "application/xml") or content_type == "" and extension == "xml": + logger.debug("Parsing AAS objects from XML stream in OPC part {} ...".format(part_name)) + # TODO XML Deserialization + raise NotImplementedError("XML deserialization is not implemented yet. Thus, AASX files with XML parts are " + "not supported.") + elif content_type.split(";")[0] in ("text/json", "application/json") \ + or content_type == "" and extension == "json": + logger.debug("Parsing AAS objects from JSON stream in OPC part {} ...".format(part_name)) + with self.reader.open_part(part_name) as p: + return read_json_aas_file(io.TextIOWrapper(p, encoding='utf-8-sig')) + else: + logger.error("Could not determine part format of AASX part {} (Content Type: {}, extension: {}" + .format(part_name, content_type, extension)) + return model.DictObjectStore() + + def _collect_supplementary_files(self, part_name: str, submodel: model.Submodel, + file_store: "AbstractSupplementaryFileContainer") -> None: + """ + Helper function to search File objects within a single parsed Submodel, extract the referenced supplementary + files and update the File object's values with the absolute path. + + :param part_name: The OPC part name of the part the submodel has been parsed from. This is used to resolve + relative file paths. + :param submodel: The Submodel to process + :param file_store: The SupplementaryFileContainer to add the extracted supplementary files to + """ + for element in traversal.walk_submodel(submodel): + if isinstance(element, model.File): + if element.value is None: + continue + absolute_name = pyecma376_2.package_model.part_realpath(element.value, part_name) + logger.debug("Reading supplementary file {} from AASX package ...".format(absolute_name)) + with self.reader.open_part(absolute_name) as p: + final_name = file_store.add_file(absolute_name, p, self.reader.get_content_type(absolute_name)) + element.value = final_name + + +class AASXWriter: + """ + An AASXWriter wraps a new AASX package file to write its contents to it piece by piece. + + Basic usage: + + # object_store and file_store are expected to be given (e.g. some storage backend or previously created data) + cp = OPCCoreProperties() + cp.creator = "ACPLT" + cp.created = datetime.datetime.now() + + with AASXWriter("filename.aasx") as writer: + writer.write_aas(Identifier("https://acplt.org/AssetAdministrationShell", IdentifierType.IRI), + object_store, + file_store) + writer.write_aas(Identifier("https://acplt.org/AssetAdministrationShell2", IdentifierType.IRI), + object_store, + file_store) + writer.write_core_properties(cp) + + Attention: The AASXWriter must always be closed using the close() method or its context manager functionality (as + shown above). Otherwise the resulting AASX file will lack important data structures and will not be readable. + """ + AASX_ORIGIN_PART_NAME = "/aasx/aasx-origin" + + def __init__(self, file: Union[os.PathLike, str, IO]): + """ + Create a new AASX package in the given file and open the AASXWriter to add contents to the package. + + Make sure to call `AASXWriter.close()` after writing all contents to write the aas-spec relationships for all + AAS parts to the file and close the underlying ZIP file writer. You may also use the AASXWriter as a context + manager to ensure closing under any circumstances. + + :param file: filename, path, or binary file handle opened for writing + """ + # names of aas-spec parts, used by `_write_aasx_origin_relationships()` + self._aas_part_names: List[str] = [] + # name of the thumbnail part (if any) + self._thumbnail_part: Optional[str] = None + # name of the core properties part (if any) + self._properties_part: Optional[str] = None + # names and hashes of all supplementary file parts that have already been written + self._supplementary_part_names: Dict[str, Optional[bytes]] = {} + self._aas_name_friendlyfier = NameFriendlyfier() + + # Open OPC package writer + self.writer = pyecma376_2.ZipPackageWriter(file) + + # Create AASX origin part + logger.debug("Creating AASX origin part in AASX package ...") + p = self.writer.open_part(self.AASX_ORIGIN_PART_NAME, "text/plain") + p.close() + + # TODO allow to specify, which supplementary parts (submodels, conceptDescriptions) should be added to the package + # TODO allow to select JSON/XML serialization + def write_aas(self, + aas_id: model.Identifier, + object_store: model.AbstractObjectStore, + file_store: "AbstractSupplementaryFileContainer") -> None: + """ + Add an Asset Administration Shell with all included and referenced objects to the AASX package. + + This method takes the AAS's Identifier (as `aas_id`) to retrieve it from the given object_store. References to + the Asset, ConceptDescriptions and Submodels are also resolved using the object_store. All of these objects are + written to aas-spec parts in the AASX package, follwing the conventions presented in "Details of the Asset + Administration Shell". For each Submodel, a aas-spec-split part is used. Supplementary files which are + referenced by a File object in any of the Submodels, are also added to the AASX package. + + :param aas_id: Identifier of the AAS to be added to the AASX file + :param object_store: ObjectStore to retrieve the Identifiable AAS objects (AAS, Asset, ConceptDescriptions and + Submodels) from + :param file_store: SupplementaryFileContainer to retrieve supplementary files from, which are referenced by File + objects + """ + aas_friendly_name = self._aas_name_friendlyfier.get_friendly_name(aas_id) + aas_part_name = "/aasx/{0}/{0}.aas.json".format(aas_friendly_name) + self._aas_part_names.append(aas_part_name) + aas_friendlyfier = NameFriendlyfier() + + aas: model.AssetAdministrationShell = object_store.get_identifiable(aas_id) # type: ignore + objects_to_be_written: model.DictObjectStore[model.Identifiable] = model.DictObjectStore() + objects_to_be_written.add(aas) + + # Add the Asset object to the objects in the AAS part + try: + objects_to_be_written.add(aas.asset.resolve(object_store)) + except KeyError as e: + logger.warning("Skipping Asset object, since {} could not be resolved: {}".format(aas.asset, e)) + pass + + # Add referenced ConceptDescriptions to the AAS part + for dictionary in aas.concept_dictionary: + for concept_rescription_ref in dictionary.concept_description: + try: + obj = concept_rescription_ref.resolve(object_store) + except KeyError as e: + logger.warning("Skipping ConceptDescription, since {} could not be resolved: {}" + .format(concept_rescription_ref, e)) + continue + try: + objects_to_be_written.add(obj) + except KeyError: + # Ignore duplicate ConceptDescriptions (i.e. same Description referenced from multiple + # Dictionaries) + pass + + # Write AAS part + logger.debug("Writing AAS {} to part {} in AASX package ...".format(aas.identification, aas_part_name)) + with self.writer.open_part(aas_part_name, "application/json") as p: + write_aas_json_file(io.TextIOWrapper(p, encoding='utf-8'), objects_to_be_written) + + # Create a AAS split part for each (available) submodel of the AAS + aas_split_part_names: List[str] = [] + for submodel_ref in aas.submodel: + try: + submodel = submodel_ref.resolve(object_store) + except KeyError as e: + logger.warning("Skipping Submodel, since {} could not be resolved: {}".format(submodel_ref, e)) + continue + submodel_friendly_name = aas_friendlyfier.get_friendly_name(submodel.identification) + submodel_part_name = "/aasx/{0}/{1}/{1}.submodel.json".format(aas_friendly_name, submodel_friendly_name) + self._write_submodel_part(file_store, submodel, submodel_part_name) + aas_split_part_names.append(submodel_part_name) + + # Add relationships from AAS part to (submodel) split parts + logger.debug("Writing aas-spec-split relationships for AAS {} to AASX package ..." + .format(aas.identification)) + self.writer.write_relationships( + (pyecma376_2.OPCRelationship("r{}".format(i), + RELATIONSHIP_TYPE_AAS_SPEC_SPLIT, + submodel_part_name, + pyecma376_2.OPCTargetMode.INTERNAL) + for i, submodel_part_name in enumerate(aas_split_part_names)), + aas_part_name) + + def _write_submodel_part(self, file_store: "AbstractSupplementaryFileContainer", + submodel: model.Submodel, submodel_part_name: str) -> None: + """ + Helper function for `write_aas()` to write an aas-spec-split part for a Submodel object and add the relevant + supplementary files. + + :param file_store: The SupplementaryFileContainer to retrieve supplementary files from + :param submodel: The submodel to be written into the AASX package + :param submodel_part_name: OPC part name of the aas-spec-split part for this Submodel + """ + logger.debug("Writing Submodel {} to part {} in AASX package ..." + .format(submodel.identification, submodel_part_name)) + + submodel_file_objects: model.DictObjectStore[model.Identifiable] = model.DictObjectStore() + submodel_file_objects.add(submodel) + with self.writer.open_part(submodel_part_name, "application/json") as p: + write_aas_json_file(io.TextIOWrapper(p, encoding='utf-8'), submodel_file_objects) + + # Write submodel's supplementary files to AASX file + submodel_file_names = [] + for element in traversal.walk_submodel(submodel): + if isinstance(element, model.File): + file_name = element.value + if file_name is None: + continue + try: + content_type = file_store.get_content_type(file_name) + hash = file_store.get_sha256(file_name) + except KeyError: + logger.warning("Could not find file {} in file store, referenced from {}." + .format(file_name, element)) + continue + # Check if this supplementary file has already been written to the AASX package or has a name conflict + if self._supplementary_part_names.get(file_name) == hash: + continue + elif file_name in self._supplementary_part_names: + logger.error("Trying to write supplementary file {} to AASX twice with different contents" + .format(file_name)) + logger.debug("Writing supplementary file {} to AASX package ...".format(file_name)) + with self.writer.open_part(file_name, content_type) as p: + file_store.write_file(file_name, p) + submodel_file_names.append(pyecma376_2.package_model.normalize_part_name(file_name)) + self._supplementary_part_names[file_name] = hash + + # Add relationships from submodel to supplementary parts + # TODO should the relationships be added from the AAS instead? + logger.debug("Writing aas-suppl relationships for Submodel {} to AASX package ..." + .format(submodel.identification)) + self.writer.write_relationships( + (pyecma376_2.OPCRelationship("r{}".format(i), + RELATIONSHIP_TYPE_AAS_SUPL, + submodel_file_name, + pyecma376_2.OPCTargetMode.INTERNAL) + for i, submodel_file_name in enumerate(submodel_file_names)), + submodel_part_name) + + def write_core_properties(self, core_properties: pyecma376_2.OPCCoreProperties): + """ + Write OPC Core Properties (meta data) to the AASX package file. + + Attention: This method may only be called once for each AASXWriter! + + :param core_properties: The OPCCoreProperties object with the meta data to be written to the package file + """ + if self._properties_part is not None: + raise RuntimeError("Core Properties have already been written.") + logger.debug("Writing core properties to AASX package ...") + with self.writer.open_part(pyecma376_2.DEFAULT_CORE_PROPERTIES_NAME, "application/xml") as p: + core_properties.write_xml(p) + self._properties_part = pyecma376_2.DEFAULT_CORE_PROPERTIES_NAME + + def write_thumbnail(self, name: str, data: bytearray, content_type: str): + """ + Write an image file as thumbnail image to the AASX package. + + Attention: This method may only be called once for each AASXWriter! + + :param name: The OPC part name of the thumbnail part. Should not contain '/' or URI-encoded '/' or '\'. + :param data: The image file's binary contents to be written + :param content_type: OPC content type (MIME type) of the image file + """ + if self._thumbnail_part is not None: + raise RuntimeError("package thumbnail has already been written to {}.".format(self._thumbnail_part)) + with self.writer.open_part(name, content_type) as p: + p.write(data) + self._thumbnail_part = name + + def close(self): + """ + Write relationships for all data files to package and close underlying OPC package and ZIP file. + """ + self._write_aasx_origin_relationships() + self._write_package_relationships() + self.writer.close() + + def __enter__(self) -> "AASXWriter": + return self + + def __exit__(self, exc_type, exc_val, exc_tb) -> None: + self.close() + + def _write_aasx_origin_relationships(self): + """ + Helper function to write aas-spec relationships of the aasx-origin part. + + This method uses the list of aas-spec parts in `_aas_part_names`. It should be called just before closing the + file to make sure all aas-spec parts of the package have already been written. + """ + # Add relationships from AASX-origin part to AAS parts + logger.debug("Writing aas-spec relationships to AASX package ...") + self.writer.write_relationships( + (pyecma376_2.OPCRelationship("r{}".format(i), RELATIONSHIP_TYPE_AAS_SPEC, + aas_part_name, + pyecma376_2.OPCTargetMode.INTERNAL) + for i, aas_part_name in enumerate(self._aas_part_names)), + self.AASX_ORIGIN_PART_NAME) + + def _write_package_relationships(self): + """ + Helper function to write package (root) relationships to the OPC package. + + This method must be called just before closing the package file to make sure we write exactly the correct + relationships: + * aasx-origin (always) + * core-properties (if core properties have been added) + * thumbnail (if thumbnail part has been added) + """ + logger.debug("Writing package relationships to AASX package ...") + package_relationships: List[pyecma376_2.OPCRelationship] = [ + pyecma376_2.OPCRelationship("r1", RELATIONSHIP_TYPE_AASX_ORIGIN, + self.AASX_ORIGIN_PART_NAME, + pyecma376_2.OPCTargetMode.INTERNAL), + ] + if self._properties_part is not None: + package_relationships.append(pyecma376_2.OPCRelationship( + "r2", pyecma376_2.RELATIONSHIP_TYPE_CORE_PROPERTIES, self._properties_part, + pyecma376_2.OPCTargetMode.INTERNAL)) + if self._thumbnail_part is not None: + package_relationships.append(pyecma376_2.OPCRelationship( + "r3", pyecma376_2.RELATIONSHIP_TYPE_THUMBNAIL, self._thumbnail_part, + pyecma376_2.OPCTargetMode.INTERNAL)) + self.writer.write_relationships(package_relationships) + + +class NameFriendlyfier: + """ + A simple helper class to create unique "AAS friendly names" according to DotAAS, section 7.6. + + Objects of this class store the already created friendly names to avoid name collisions within one set of names. + """ + RE_NON_ALPHANUMERICAL = re.compile(r"[^a-zA-Z0-9]") + + def __init__(self) -> None: + self.issued_names: Set[str] = set() + + def get_friendly_name(self, identifier: model.Identifier): + """ + Generate a friendly name from an AAS identifier. + + According to section 7.6 of "Details of the Asset Administration Shell", all non-alphanumerical characters are + replaced with underscores. We also replace all non-ASCII characters to generate valid URIs as the result. + If this replacement results in a collision with a previously generated friendly name of this NameFriendlifier, + a number is appended with underscore to the friendly name. Example + + >>> friendlyfier = NameFriendlyfier() + >>> friendlyfier.get_friendly_name(model.Identifier("http://example.com/AAS-a", model.IdentifierType.IRI)) + "http___example_com_AAS_a" + >>> friendlyfier.get_friendly_name(model.Identifier("http://example.com/AAS+a", model.IdentifierType.IRI)) + "http___example_com_AAS_a_1" + + """ + # friendlify name + raw_name = self.RE_NON_ALPHANUMERICAL.sub('_', identifier.id) + + # Unify name (avoid collisions) + amended_name = raw_name + i = 1 + while amended_name in self.issued_names: + amended_name = "{}_{}".format(raw_name, i) + i += 1 + + self.issued_names.add(amended_name) + return amended_name + + +class AbstractSupplementaryFileContainer(metaclass=abc.ABCMeta): + """ + Abstract interface for containers of supplementary files for AASs. + + Supplementary files may be PDF files or other binary or textual files, referenced in a File object of an AAS by + their name. They are used to provide associated documents without embedding their contents (as Blob object) in the + AAS. + + A SupplementaryFileContainer keeps track of the name and content_type (MIME type) for each file. Additionally it + allows to resolve name conflicts by comparing the files' contents and providing an alternative name for a dissimilar + new file. It also provides each files sha256 hash sum to allow name conflict checking in other classes (e.g. when + writing AASX files). + """ + @abc.abstractmethod + def add_file(self, name: str, file: IO[bytes], content_type: str) -> str: + """ + Add a new file to the SupplementaryFileContainer and resolve name conflicts. + + The file contents must be provided as a binary file-like object to be read by the SupplementaryFileContainer. + If the container already contains an equally named file, the content_type and file contents are compared (using + a hash sum). In case of dissimilar files, a new unique name for the new file is computed and returned. It should + be used to update in the File object of the AAS. + + :param name: The file's proposed name. Should start with a '/'. Should not contain URI-encoded '/' or '\' + :param file: A binary file-like opened for reading the file contents + :param content_type: The file's content_type + :return: The file name as stored in the SupplementaryFileContainer. Typically `name` or a modified version of + `name` to resolve conflicts. + """ + pass # pragma: no cover + + @abc.abstractmethod + def get_content_type(self, name: str) -> str: + """ + Get a stored file's content_type. + + :param name: file name of questioned file + :return: The file's content_type + :raises KeyError: If no file with this name is stored + """ + pass # pragma: no cover + + @abc.abstractmethod + def get_sha256(self, name: str) -> bytes: + """ + Get a stored file content's sha256 hash sum. + + This may be used by other classes (e.g. the AASXWriter) to check for name conflicts. + + :param name: file name of questioned file + :return: The file content's sha256 hash sum + :raises KeyError: If no file with this name is stored + """ + pass # pragma: no cover + + @abc.abstractmethod + def write_file(self, name: str, file: IO[bytes]) -> None: + """ + Retrieve a stored file's contents by writing them into a binary writable file-like object. + + :param name: file name of questioned file + :param file: A binary file-like object with write() method to write the file contents into + :raises KeyError: If no file with this name is stored + """ + pass # pragma: no cover + + @abc.abstractmethod + def __contains__(self, item: str) -> bool: + """ + Check if a file with the given name is stored in this SupplementaryFileContainer. + """ + pass # pragma: no cover + + +class DictSupplementaryFileContainer(AbstractSupplementaryFileContainer): + """ + SupplementaryFileContainer implementation using a dict to store the file contents in-memory. + """ + def __init__(self): + # Stores the files' contents, identified by their sha256 hash + self._store: Dict[bytes, bytes] = {} + # Maps file names to (sha256, content_type) + self._name_map: Dict[str, Tuple[bytes, str]] = {} + + def add_file(self, name: str, file: IO[bytes], content_type: str) -> str: + data = file.read() + hash = hashlib.sha256(data).digest() + if hash not in self._store: + self._store[hash] = data + name_map_data = (hash, content_type) + new_name = name + i = 1 + while True: + if new_name not in self._name_map: + self._name_map[new_name] = name_map_data + return new_name + elif self._name_map[new_name] == name_map_data: + return new_name + new_name = self._append_counter(name, i) + i += 1 + + @staticmethod + def _append_counter(name: str, i: int) -> str: + split1 = name.split('/') + split2 = split1[-1].split('.') + index = -2 if len(split2) > 1 else -1 + new_basename = "{}_{:04d}".format(split2[index], i) + split2[index] = new_basename + split1[-1] = ".".join(split2) + return "/".join(split1) + + def get_content_type(self, name: str) -> str: + return self._name_map[name][1] + + def get_sha256(self, name: str) -> bytes: + return self._name_map[name][0] + + def write_file(self, name: str, file: IO[bytes]) -> None: + file.write(self._store[self._name_map[name][0]]) + + def __contains__(self, item: object) -> bool: + return item in self._name_map diff --git a/aas/examples/data/example_aas.py b/aas/examples/data/example_aas.py index dc8330a72b7ad4411d6b5d6fcf29eeb1e2717827..3463494b44410d0ae560140d53fd0343230b8795 100644 --- a/aas/examples/data/example_aas.py +++ b/aas/examples/data/example_aas.py @@ -637,7 +637,18 @@ def create_example_asset_administration_shell(concept_dictionary: model.ConceptD local=False, value='https://acplt.org/Test_Submodel', id_type=model.KeyType.IRI),), - model.Submodel)}, + model.Submodel), + model.AASReference((model.Key(type_=model.KeyElements.SUBMODEL, + local=False, + value='http://acplt.org/Submodels/Assets/TestAsset/Identification', + id_type=model.KeyType.IRI),), + model.Submodel), + model.AASReference((model.Key(type_=model.KeyElements.SUBMODEL, + local=False, + value='http://acplt.org/Submodels/Assets/TestAsset/BillOfMaterial', + id_type=model.KeyType.IRI),), + model.Submodel), + }, concept_dictionary=[concept_dictionary], view=[], derived_from=model.AASReference((model.Key(type_=model.KeyElements.ASSET_ADMINISTRATION_SHELL, diff --git a/aas/model/provider.py b/aas/model/provider.py index 05089ae08b3b1c891386fc82a379460d82f97780..3a3fd15097f252d831afbe748227de22fe239f6f 100644 --- a/aas/model/provider.py +++ b/aas/model/provider.py @@ -76,8 +76,10 @@ class DictObjectStore(AbstractObjectStore[_IT], Generic[_IT]): """ A local in-memory object store for Identifiable Objects, backed by a dict, mapping Identifier → Identifiable """ - def __init__(self): + def __init__(self, objects: Iterable[_IT] = ()) -> None: self._backend: Dict[Identifier, _IT] = {} + for x in objects: + self.add(x) def get_identifiable(self, identifier: Identifier) -> _IT: return self._backend[identifier] diff --git a/aas/util/traversal.py b/aas/util/traversal.py new file mode 100644 index 0000000000000000000000000000000000000000..cea419a1b80f992a0fdb3f0c885de5195f123e4d --- /dev/null +++ b/aas/util/traversal.py @@ -0,0 +1,32 @@ +# Copyright 2019 PyI40AAS Contributors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +""" +A module with helper functions for traversing AAS object strcutures. +""" + +from typing import Union, Iterator + +from .. import model + + +def walk_submodel(collection: Union[model.Submodel, model.SubmodelElementCollection]) \ + -> Iterator[model.SubmodelElement]: + """ + Traverse the SubmodelElements in a Submodel or a SubmodelElementCollection recursively in post-order tree-traversal. + + This is a generator function, yielding all the SubmodelElements. No SubmodelElements should be added, removed or + moved while iterating, as this could result in undefined behaviour. + """ + elements = collection.submodel_element if isinstance(collection, model.Submodel) else collection.value + for element in elements: + if isinstance(element, model.SubmodelElementCollection): + yield from walk_submodel(element) + yield element diff --git a/requirements.txt b/requirements.txt index a449b9b661d7c1ca86654f47c41464914ebe801c..c83c985c77f8da68a7807b86f27b180f52506a89 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ jsonschema>=3.2,<4.0 lxml>=4.2,<5 -python-dateutil>=2.8,<3.0 \ No newline at end of file +python-dateutil>=2.8,<3.0 +pyecma376-2>=0.2 diff --git a/setup.py b/setup.py index 621e35be96a010764a71f222b8c69a5406b9f448..58d41b83fd138898d3b76341a86f05c194ffefef 100755 --- a/setup.py +++ b/setup.py @@ -42,5 +42,6 @@ setuptools.setup( install_requires=[ 'python-dateutil>=2.8,<3', 'lxml>=4.2,<5', + 'pyecma376-2>=0.2', ] ) diff --git a/test/adapter/aasx/TestFile.pdf b/test/adapter/aasx/TestFile.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2bccbec5f60ea7a8f51e5fd41eda019cf27a08d7 Binary files /dev/null and b/test/adapter/aasx/TestFile.pdf differ diff --git a/test/adapter/aasx/__init__.py b/test/adapter/aasx/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/test/adapter/aasx/test_aasx.py b/test/adapter/aasx/test_aasx.py new file mode 100644 index 0000000000000000000000000000000000000000..8d81894e0bae22a67e0adc9a02ffa69f0ba8a0be --- /dev/null +++ b/test/adapter/aasx/test_aasx.py @@ -0,0 +1,106 @@ +# Copyright 2019 PyI40AAS Contributors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +import datetime +import hashlib +import io +import os +import tempfile +import unittest + +import pyecma376_2 +from aas import model +from aas.adapter import aasx +from aas.examples.data import example_aas, _helper + + +class TestAASXUtils(unittest.TestCase): + def test_name_friendlyfier(self) -> None: + friendlyfier = aasx.NameFriendlyfier() + name1 = friendlyfier.get_friendly_name(model.Identifier("http://example.com/AAS-a", model.IdentifierType.IRI)) + self.assertEqual("http___example_com_AAS_a", name1) + name2 = friendlyfier.get_friendly_name(model.Identifier("http://example.com/AAS+a", model.IdentifierType.IRI)) + self.assertEqual("http___example_com_AAS_a_1", name2) + + def test_supplementary_file_container(self) -> None: + container = aasx.DictSupplementaryFileContainer() + with open(os.path.join(os.path.dirname(__file__), 'TestFile.pdf'), 'rb') as f: + new_name = container.add_file("/TestFile.pdf", f, "application/pdf") + # Name should not be modified, since there is no conflict + self.assertEqual("/TestFile.pdf", new_name) + f.seek(0) + container.add_file("/TestFile.pdf", f, "application/pdf") + # Name should not be modified, since there is still no conflict + self.assertEqual("/TestFile.pdf", new_name) + + with open(__file__, 'rb') as f: + new_name = container.add_file("/TestFile.pdf", f, "application/pdf") + # Now, we have a conflict + self.assertNotEqual("/TestFile.pdf", new_name) + self.assertIn(new_name, container) + + # Check metadata + self.assertEqual("application/pdf", container.get_content_type("/TestFile.pdf")) + self.assertEqual("b18229b24a4ee92c6c2b6bc6a8018563b17472f1150d35d5a5945afeb447ed44", + container.get_sha256("/TestFile.pdf").hex()) + self.assertIn("/TestFile.pdf", container) + + # Check contents + file_content = io.BytesIO() + container.write_file("/TestFile.pdf", file_content) + self.assertEqual(hashlib.sha1(file_content.getvalue()).hexdigest(), "78450a66f59d74c073bf6858db340090ea72a8b1") + + +class AASXWriterTest(unittest.TestCase): + def test_writing_reading_example_aas(self) -> None: + # Create example data and file_store + data = example_aas.create_full_example() + files = aasx.DictSupplementaryFileContainer() + with open(os.path.join(os.path.dirname(__file__), 'TestFile.pdf'), 'rb') as f: + files.add_file("/TestFile.pdf", f, "application/pdf") + f.seek(0) + + # Create OPC/AASX core properties + cp = pyecma376_2.OPCCoreProperties() + cp.created = datetime.datetime.now() + cp.creator = "PyI40AAS Testing Framework" + + # Write AASX file + fd, filename = tempfile.mkstemp(suffix=".aasx") + os.close(fd) + with aasx.AASXWriter(filename) as writer: + writer.write_aas(model.Identifier(id_='https://acplt.org/Test_AssetAdministrationShell', + id_type=model.IdentifierType.IRI), + data, files) + writer.write_core_properties(cp) + + # Read AASX file + new_data: model.DictObjectStore[model.Identifiable] = model.DictObjectStore() + new_files = aasx.DictSupplementaryFileContainer() + with aasx.AASXReader(filename) as reader: + reader.read_into(new_data, new_files) + new_cp = reader.get_core_properties() + + # Check AAS objects + checker = _helper.AASDataChecker(raise_immediately=True) + example_aas.check_full_example(checker, new_data) + + # Check core properties + self.assertEqual(new_cp.created, cp.created) + self.assertEqual(new_cp.creator, "PyI40AAS Testing Framework") + self.assertIsNone(new_cp.lastModifiedBy) + + # Check files + self.assertEqual(new_files.get_content_type("/TestFile.pdf"), "application/pdf") + file_content = io.BytesIO() + new_files.write_file("/TestFile.pdf", file_content) + self.assertEqual(hashlib.sha1(file_content.getvalue()).hexdigest(), "78450a66f59d74c073bf6858db340090ea72a8b1") + + os.unlink(filename) diff --git a/test/compliance_tool/files/test_demo_full_example.json b/test/compliance_tool/files/test_demo_full_example.json index 5e2f8d0212740c2753e1ab6fccc1ad89c18cb5ab..ca56b954685eb4be48ffd69ccd4020267d8a863f 100644 --- a/test/compliance_tool/files/test_demo_full_example.json +++ b/test/compliance_tool/files/test_demo_full_example.json @@ -1 +1 @@ -{"assetAdministrationShells": [{"idShort": "TestAssetAdministrationShell", "description": [{"language": "en-us", "text": "An Example Asset Administration Shell for the test application"}, {"language": "de", "text": "Ein Beispiel-Verwaltungsschale f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "AssetAdministrationShell"}, "identification": {"id": "https://acplt.org/Test_AssetAdministrationShell", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "derivedFrom": {"keys": [{"type": "AssetAdministrationShell", "idType": "IRI", "value": "https://acplt.org/TestAssetAdministrationShell2", "local": false}]}, "asset": {"keys": [{"type": "Asset", "idType": "IRI", "value": "https://acplt.org/Test_Asset", "local": false}]}, "submodels": [{"keys": [{"type": "Submodel", "idType": "IRI", "value": "https://acplt.org/Test_Submodel", "local": false}]}], "conceptDictionaries": [{"idShort": "TestConceptDictionary", "description": [{"language": "en-us", "text": "An example concept dictionary for the test application"}, {"language": "de", "text": "Ein Beispiel-ConceptDictionary f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "ConceptDictionary"}, "conceptDescriptions": [{"keys": [{"type": "ConceptDescription", "idType": "IRI", "value": "https://acplt.org/Test_ConceptDescription", "local": false}]}]}]}, {"idShort": "", "modelType": {"name": "AssetAdministrationShell"}, "identification": {"id": "https://acplt.org/Test_AssetAdministrationShell_Mandatory", "idType": "IRI"}, "asset": {"keys": [{"type": "Asset", "idType": "IRI", "value": "https://acplt.org/Test_Asset_Mandatory", "local": false}]}, "submodels": [{"keys": [{"type": "Submodel", "idType": "IRI", "value": "https://acplt.org/Test_Submodel_Mandatory", "local": false}]}, {"keys": [{"type": "Submodel", "idType": "IRI", "value": "https://acplt.org/Test_Submodel2_Mandatory", "local": false}]}], "conceptDictionaries": [{"idShort": "TestConceptDictionary", "modelType": {"name": "ConceptDictionary"}}]}, {"idShort": "", "modelType": {"name": "AssetAdministrationShell"}, "identification": {"id": "https://acplt.org/Test_AssetAdministrationShell2_Mandatory", "idType": "IRI"}, "asset": {"keys": [{"type": "Asset", "idType": "IRI", "value": "https://acplt.org/Test_Asset_Mandatory", "local": false}]}}, {"idShort": "TestAssetAdministrationShell", "description": [{"language": "en-us", "text": "An Example Asset Administration Shell for the test application"}, {"language": "de", "text": "Ein Beispiel-Verwaltungsschale f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "AssetAdministrationShell"}, "identification": {"id": "https://acplt.org/Test_AssetAdministrationShell_Missing", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "asset": {"keys": [{"type": "Asset", "idType": "IRI", "value": "https://acplt.org/Test_Asset_Missing", "local": false}]}, "submodels": [{"keys": [{"type": "Submodel", "idType": "IRI", "value": "https://acplt.org/Test_Submodel_Missing", "local": false}]}], "views": [{"idShort": "ExampleView", "modelType": {"name": "View"}, "containedElements": [{"keys": [{"type": "Submodel", "idType": "IRI", "value": "https://acplt.org/Test_Submodel_Missing", "local": false}]}]}, {"idShort": "ExampleView2", "modelType": {"name": "View"}}], "conceptDictionaries": [{"idShort": "TestConceptDictionary", "description": [{"language": "en-us", "text": "An example concept dictionary for the test application"}, {"language": "de", "text": "Ein Beispiel-ConceptDictionary f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "ConceptDictionary"}, "conceptDescriptions": [{"keys": [{"type": "ConceptDescription", "idType": "IRI", "value": "https://acplt.org/Test_ConceptDescription_Missing", "local": false}]}]}]}], "submodels": [{"idShort": "Identification", "description": [{"language": "en-us", "text": "An example asset identification submodel for the test application"}, {"language": "de", "text": "Ein Beispiel-Identifikations-Submodel f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "Submodel"}, "identification": {"id": "http://acplt.org/Submodels/Assets/TestAsset/Identification", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "semanticId": {"keys": [{"type": "Submodel", "idType": "IRI", "value": "http://acplt.org/SubmodelTemplates/AssetIdentification", "local": false}]}, "submodelElements": [{"idShort": "ManufacturerName", "description": [{"language": "en-us", "text": "Legally valid designation of the natural or judicial person which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into circulation."}, {"language": "de", "text": "Bezeichnung f\u00fcr eine nat\u00fcrliche oder juristische Person, die f\u00fcr die Auslegung, Herstellung und Verpackung sowie die Etikettierung eines Produkts im Hinblick auf das 'Inverkehrbringen' im eigenen Namen verantwortlich ist"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "0173-1#02-AAO677#002", "local": false}]}, "qualifiers": [{"modelType": {"name": "Qualifier"}, "value": "100", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "int", "type": "http://acplt.org/Qualifier/ExampleQualifier"}, {"modelType": {"name": "Qualifier"}, "value": "50", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "int", "type": "http://acplt.org/Qualifier/ExampleQualifier2"}], "value": "ACPLT", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}, {"idShort": "InstanceId", "description": [{"language": "en-us", "text": "Legally valid designation of the natural or judicial person which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into circulation."}, {"language": "de", "text": "Bezeichnung f\u00fcr eine nat\u00fcrliche oder juristische Person, die f\u00fcr die Auslegung, Herstellung und Verpackung sowie die Etikettierung eines Produkts im Hinblick auf das 'Inverkehrbringen' im eigenen Namen verantwortlich ist"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://opcfoundation.org/UA/DI/1.1/DeviceType/Serialnumber", "local": false}]}, "value": "978-8234-234-342", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}]}, {"idShort": "BillOfMaterial", "description": [{"language": "en-us", "text": "An example bill of material submodel for the test application"}, {"language": "de", "text": "Ein Beispiel-BillofMaterial-Submodel f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "Submodel"}, "identification": {"id": "http://acplt.org/Submodels/Assets/TestAsset/BillOfMaterial", "idType": "IRI"}, "administration": {"version": "0.9"}, "semanticId": {"keys": [{"type": "Submodel", "idType": "IRI", "value": "http://acplt.org/SubmodelTemplates/BillOfMaterial", "local": false}]}, "submodelElements": [{"idShort": "ExampleEntity", "description": [{"language": "en-us", "text": "Legally valid designation of the natural or judicial person which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into circulation."}, {"language": "de", "text": "Bezeichnung f\u00fcr eine nat\u00fcrliche oder juristische Person, die f\u00fcr die Auslegung, Herstellung und Verpackung sowie die Etikettierung eines Produkts im Hinblick auf das 'Inverkehrbringen' im eigenen Namen verantwortlich ist"}], "modelType": {"name": "Entity"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://opcfoundation.org/UA/DI/1.1/DeviceType/Serialnumber", "local": false}]}, "statements": [{"idShort": "ExampleProperty2", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "value": "exampleValue2", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}, {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "value": "exampleValue", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}], "entityType": "CoManagedEntity"}, {"idShort": "ExampleEntity2", "description": [{"language": "en-us", "text": "Legally valid designation of the natural or judicial person which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into circulation."}, {"language": "de", "text": "Bezeichnung f\u00fcr eine nat\u00fcrliche oder juristische Person, die f\u00fcr die Auslegung, Herstellung und Verpackung sowie die Etikettierung eines Produkts im Hinblick auf das 'Inverkehrbringen' im eigenen Namen verantwortlich ist"}], "modelType": {"name": "Entity"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://opcfoundation.org/UA/DI/1.1/DeviceType/Serialnumber", "local": false}]}, "entityType": "SelfManagedEntity", "asset": {"keys": [{"type": "Asset", "idType": "IRI", "value": "https://acplt.org/Test_Asset2", "local": false}]}}]}, {"idShort": "TestSubmodel", "description": [{"language": "en-us", "text": "An example submodel for the test application"}, {"language": "de", "text": "Ein Beispiel-Teilmodell f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "Submodel"}, "identification": {"id": "https://acplt.org/Test_Submodel", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelTemplates/ExampleSubmodel", "local": false}]}, "submodelElements": [{"idShort": "ExampleRelationshipElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example RelationshipElement object"}, {"language": "de", "text": "Beispiel RelationshipElement Element"}], "modelType": {"name": "RelationshipElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/RelationshipElements/ExampleRelationshipElement", "local": false}]}, "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty2", "local": true}]}}, {"idShort": "ExampleAnnotatedRelationshipElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example AnnotatedRelationshipElement object"}, {"language": "de", "text": "Beispiel AnnotatedRelationshipElement Element"}], "modelType": {"name": "AnnotatedRelationshipElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/RelationshipElements/ExampleAnnotatedRelationshipElement", "local": false}]}, "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty2", "local": true}]}, "annotation": [{"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty3", "local": true}]}]}, {"idShort": "ExampleOperation", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Operation object"}, {"language": "de", "text": "Beispiel Operation Element"}], "modelType": {"name": "Operation"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Operations/ExampleOperation", "local": false}]}, "inputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "value": "exampleValue", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}}], "outputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "value": "exampleValue", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}}], "inoutputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "value": "exampleValue", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}}]}, {"idShort": "ExampleCapability", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Capability object"}, {"language": "de", "text": "Beispiel Capability Element"}], "modelType": {"name": "Capability"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Capabilities/ExampleCapability", "local": false}]}}, {"idShort": "ExampleBasicEvent", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example BasicEvent object"}, {"language": "de", "text": "Beispiel BasicEvent Element"}], "modelType": {"name": "BasicEvent"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Events/ExampleBasicEvent", "local": false}]}, "observed": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleSubmodelCollectionOrdered", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example SubmodelElementCollectionOrdered object"}, {"language": "de", "text": "Beispiel SubmodelElementCollectionOrdered Element"}], "modelType": {"name": "SubmodelElementCollection"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelElementCollections/ExampleSubmodelElementCollectionOrdered", "local": false}]}, "value": [{"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "value": "exampleValue", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}, {"idShort": "ExampleMultiLanguageProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example MultiLanguageProperty object"}, {"language": "de", "text": "Beispiel MulitLanguageProperty Element"}], "modelType": {"name": "MultiLanguageProperty"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/MultiLanguageProperties/ExampleMultiLanguageProperty", "local": false}]}, "value": [{"language": "en-us", "text": "Example value of a MultiLanguageProperty element"}, {"language": "de", "text": "Beispielswert f\u00fcr ein MulitLanguageProperty-Element"}], "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleMultiLanguageValueId", "local": false}]}}, {"idShort": "ExampleRange", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Range object"}, {"language": "de", "text": "Beispiel Range Element"}], "modelType": {"name": "Range"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Ranges/ExampleRange", "local": false}]}, "valueType": "int", "min": "0", "max": "100"}], "ordered": true}, {"idShort": "ExampleSubmodelCollectionUnordered", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example SubmodelElementCollectionUnordered object"}, {"language": "de", "text": "Beispiel SubmodelElementCollectionUnordered Element"}], "modelType": {"name": "SubmodelElementCollection"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelElementCollections/ExampleSubmodelElementCollectionUnordered", "local": false}]}, "value": [{"idShort": "ExampleBlob", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Blob object"}, {"language": "de", "text": "Beispiel Blob Element"}], "modelType": {"name": "Blob"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Blobs/ExampleBlob", "local": false}]}, "mimeType": "application/pdf", "value": "AQIDBAU="}, {"idShort": "ExampleFile", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example File object"}, {"language": "de", "text": "Beispiel File Element"}], "modelType": {"name": "File"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Files/ExampleFile", "local": false}]}, "value": "/TestFile.pdf", "mimeType": "application/pdf"}, {"idShort": "ExampleReferenceElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Reference Element object"}, {"language": "de", "text": "Beispiel Reference Element Element"}], "modelType": {"name": "ReferenceElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ReferenceElements/ExampleReferenceElement", "local": false}]}, "value": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}], "ordered": false}]}, {"idShort": "", "modelType": {"name": "Submodel"}, "identification": {"id": "https://acplt.org/Test_Submodel_Mandatory", "idType": "IRI"}, "submodelElements": [{"idShort": "ExampleRelationshipElement", "modelType": {"name": "RelationshipElement"}, "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleAnnotatedRelationshipElement", "modelType": {"name": "AnnotatedRelationshipElement"}, "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleOperation", "modelType": {"name": "Operation"}}, {"idShort": "ExampleCapability", "modelType": {"name": "Capability"}}, {"idShort": "ExampleBasicEvent", "modelType": {"name": "BasicEvent"}, "observed": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleSubmodelCollectionOrdered", "modelType": {"name": "SubmodelElementCollection"}, "value": [{"idShort": "ExampleProperty", "modelType": {"name": "Property"}, "value": null, "valueType": "string"}, {"idShort": "ExampleMultiLanguageProperty", "modelType": {"name": "MultiLanguageProperty"}}, {"idShort": "ExampleRange", "modelType": {"name": "Range"}, "valueType": "int", "min": null, "max": null}], "ordered": true}, {"idShort": "ExampleSubmodelCollectionUnordered", "modelType": {"name": "SubmodelElementCollection"}, "value": [{"idShort": "ExampleBlob", "modelType": {"name": "Blob"}, "mimeType": "application/pdf"}, {"idShort": "ExampleFile", "modelType": {"name": "File"}, "value": null, "mimeType": "application/pdf"}, {"idShort": "ExampleReferenceElement", "modelType": {"name": "ReferenceElement"}}], "ordered": false}, {"idShort": "ExampleSubmodelCollectionUnordered2", "modelType": {"name": "SubmodelElementCollection"}, "ordered": false}]}, {"idShort": "", "modelType": {"name": "Submodel"}, "identification": {"id": "https://acplt.org/Test_Submodel2_Mandatory", "idType": "IRI"}}, {"idShort": "TestSubmodel", "description": [{"language": "en-us", "text": "An example submodel for the test application"}, {"language": "de", "text": "Ein Beispiel-Teilmodell f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "Submodel"}, "identification": {"id": "https://acplt.org/Test_Submodel_Missing", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelTemplates/ExampleSubmodel", "local": false}]}, "submodelElements": [{"idShort": "ExampleRelationshipElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example RelationshipElement object"}, {"language": "de", "text": "Beispiel RelationshipElement Element"}], "modelType": {"name": "RelationshipElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/RelationshipElements/ExampleRelationshipElement", "local": false}]}, "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleAnnotatedRelationshipElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example AnnotatedRelationshipElement object"}, {"language": "de", "text": "Beispiel AnnotatedRelationshipElement Element"}], "modelType": {"name": "AnnotatedRelationshipElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/RelationshipElements/ExampleAnnotatedRelationshipElement", "local": false}]}, "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "annotation": [{"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}]}, {"idShort": "ExampleOperation", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Operation object"}, {"language": "de", "text": "Beispiel Operation Element"}], "modelType": {"name": "Operation"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Operations/ExampleOperation", "local": false}]}, "inputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "qualifiers": [{"modelType": {"name": "Qualifier"}, "valueType": "string", "type": "http://acplt.org/Qualifier/ExampleQualifier"}], "value": "exampleValue", "valueType": "string"}}], "outputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "qualifiers": [{"modelType": {"name": "Qualifier"}, "valueType": "string", "type": "http://acplt.org/Qualifier/ExampleQualifier"}], "value": "exampleValue", "valueType": "string"}}], "inoutputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "qualifiers": [{"modelType": {"name": "Qualifier"}, "valueType": "string", "type": "http://acplt.org/Qualifier/ExampleQualifier"}], "value": "exampleValue", "valueType": "string"}}]}, {"idShort": "ExampleCapability", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Capability object"}, {"language": "de", "text": "Beispiel Capability Element"}], "modelType": {"name": "Capability"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Capabilities/ExampleCapability", "local": false}]}}, {"idShort": "ExampleBasicEvent", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example BasicEvent object"}, {"language": "de", "text": "Beispiel BasicEvent Element"}], "modelType": {"name": "BasicEvent"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Events/ExampleBasicEvent", "local": false}]}, "observed": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleSubmodelCollectionOrdered", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example SubmodelElementCollectionOrdered object"}, {"language": "de", "text": "Beispiel SubmodelElementCollectionOrdered Element"}], "modelType": {"name": "SubmodelElementCollection"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelElementCollections/ExampleSubmodelElementCollectionOrdered", "local": false}]}, "value": [{"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "qualifiers": [{"modelType": {"name": "Qualifier"}, "valueType": "string", "type": "http://acplt.org/Qualifier/ExampleQualifier"}], "value": "exampleValue", "valueType": "string"}, {"idShort": "ExampleMultiLanguageProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example MultiLanguageProperty object"}, {"language": "de", "text": "Beispiel MulitLanguageProperty Element"}], "modelType": {"name": "MultiLanguageProperty"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/MultiLanguageProperties/ExampleMultiLanguageProperty", "local": false}]}, "value": [{"language": "en-us", "text": "Example value of a MultiLanguageProperty element"}, {"language": "de", "text": "Beispielswert f\u00fcr ein MulitLanguageProperty-Element"}]}, {"idShort": "ExampleRange", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Range object"}, {"language": "de", "text": "Beispiel Range Element"}], "modelType": {"name": "Range"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Ranges/ExampleRange", "local": false}]}, "valueType": "int", "min": "0", "max": "100"}], "ordered": true}, {"idShort": "ExampleSubmodelCollectionUnordered", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example SubmodelElementCollectionUnordered object"}, {"language": "de", "text": "Beispiel SubmodelElementCollectionUnordered Element"}], "modelType": {"name": "SubmodelElementCollection"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelElementCollections/ExampleSubmodelElementCollectionUnordered", "local": false}]}, "value": [{"idShort": "ExampleBlob", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Blob object"}, {"language": "de", "text": "Beispiel Blob Element"}], "modelType": {"name": "Blob"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Blobs/ExampleBlob", "local": false}]}, "mimeType": "application/pdf", "value": "AQIDBAU="}, {"idShort": "ExampleFile", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example File object"}, {"language": "de", "text": "Beispiel File Element"}], "modelType": {"name": "File"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Files/ExampleFile", "local": false}]}, "value": "/TestFile.pdf", "mimeType": "application/pdf"}, {"idShort": "ExampleReferenceElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Reference Element object"}, {"language": "de", "text": "Beispiel Reference Element Element"}], "modelType": {"name": "ReferenceElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ReferenceElements/ExampleReferenceElement", "local": false}]}, "value": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}], "ordered": false}]}, {"idShort": "TestSubmodel", "description": [{"language": "en-us", "text": "An example submodel for the test application"}, {"language": "de", "text": "Ein Beispiel-Teilmodell f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "Submodel"}, "identification": {"id": "https://acplt.org/Test_Submodel_Template", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelTemplates/ExampleSubmodel", "local": false}]}, "kind": "Template", "submodelElements": [{"idShort": "ExampleRelationshipElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example RelationshipElement object"}, {"language": "de", "text": "Beispiel RelationshipElement Element"}], "modelType": {"name": "RelationshipElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/RelationshipElements/ExampleRelationshipElement", "local": false}]}, "kind": "Template", "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleAnnotatedRelationshipElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example AnnotatedRelationshipElement object"}, {"language": "de", "text": "Beispiel AnnotatedRelationshipElement Element"}], "modelType": {"name": "AnnotatedRelationshipElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/RelationshipElements/ExampleAnnotatedRelationshipElement", "local": false}]}, "kind": "Template", "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleOperation", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Operation object"}, {"language": "de", "text": "Beispiel Operation Element"}], "modelType": {"name": "Operation"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Operations/ExampleOperation", "local": false}]}, "kind": "Template", "inputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "kind": "Template", "value": null, "valueType": "string"}}], "outputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "kind": "Template", "value": null, "valueType": "string"}}], "inoutputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "kind": "Template", "value": null, "valueType": "string"}}]}, {"idShort": "ExampleCapability", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Capability object"}, {"language": "de", "text": "Beispiel Capability Element"}], "modelType": {"name": "Capability"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Capabilities/ExampleCapability", "local": false}]}, "kind": "Template"}, {"idShort": "ExampleBasicEvent", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example BasicEvent object"}, {"language": "de", "text": "Beispiel BasicEvent Element"}], "modelType": {"name": "BasicEvent"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Events/ExampleBasicEvent", "local": false}]}, "kind": "Template", "observed": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleSubmodelCollectionOrdered", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example SubmodelElementCollectionOrdered object"}, {"language": "de", "text": "Beispiel SubmodelElementCollectionOrdered Element"}], "modelType": {"name": "SubmodelElementCollection"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelElementCollections/ExampleSubmodelElementCollectionOrdered", "local": false}]}, "kind": "Template", "value": [{"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "kind": "Template", "value": null, "valueType": "string"}, {"idShort": "ExampleMultiLanguageProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example MultiLanguageProperty object"}, {"language": "de", "text": "Beispiel MulitLanguageProperty Element"}], "modelType": {"name": "MultiLanguageProperty"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/MultiLanguageProperties/ExampleMultiLanguageProperty", "local": false}]}, "kind": "Template"}, {"idShort": "ExampleRange", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Range object"}, {"language": "de", "text": "Beispiel Range Element"}], "modelType": {"name": "Range"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Ranges/ExampleRange", "local": false}]}, "kind": "Template", "valueType": "int", "min": null, "max": "100"}, {"idShort": "ExampleRange2", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Range object"}, {"language": "de", "text": "Beispiel Range Element"}], "modelType": {"name": "Range"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Ranges/ExampleRange", "local": false}]}, "kind": "Template", "valueType": "int", "min": "0", "max": null}], "ordered": true}, {"idShort": "ExampleSubmodelCollectionUnordered", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example SubmodelElementCollectionUnordered object"}, {"language": "de", "text": "Beispiel SubmodelElementCollectionUnordered Element"}], "modelType": {"name": "SubmodelElementCollection"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelElementCollections/ExampleSubmodelElementCollectionUnordered", "local": false}]}, "kind": "Template", "value": [{"idShort": "ExampleBlob", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Blob object"}, {"language": "de", "text": "Beispiel Blob Element"}], "modelType": {"name": "Blob"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Blobs/ExampleBlob", "local": false}]}, "kind": "Template", "mimeType": "application/pdf"}, {"idShort": "ExampleFile", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example File object"}, {"language": "de", "text": "Beispiel File Element"}], "modelType": {"name": "File"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Files/ExampleFile", "local": false}]}, "kind": "Template", "value": null, "mimeType": "application/pdf"}, {"idShort": "ExampleReferenceElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Reference Element object"}, {"language": "de", "text": "Beispiel Reference Element Element"}], "modelType": {"name": "ReferenceElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ReferenceElements/ExampleReferenceElement", "local": false}]}, "kind": "Template"}], "ordered": false}, {"idShort": "ExampleSubmodelCollectionUnordered2", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example SubmodelElementCollectionUnordered object"}, {"language": "de", "text": "Beispiel SubmodelElementCollectionUnordered Element"}], "modelType": {"name": "SubmodelElementCollection"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelElementCollections/ExampleSubmodelElementCollectionUnordered", "local": false}]}, "kind": "Template", "ordered": false}]}], "assets": [{"idShort": "Test_Asset", "description": [{"language": "en-us", "text": "An example asset for the test application"}, {"language": "de", "text": "Ein Beispiel-Asset f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "Asset"}, "identification": {"id": "https://acplt.org/Test_Asset", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "kind": "Instance", "assetIdentificationModel": {"keys": [{"type": "Submodel", "idType": "IRI", "value": "http://acplt.org/Submodels/Assets/TestAsset/Identification", "local": false}]}, "billOfMaterial": {"keys": [{"type": "Submodel", "idType": "IRI", "value": "http://acplt.org/Submodels/Assets/TestAsset/BillOfMaterial", "local": false}]}}, {"idShort": "", "modelType": {"name": "Asset"}, "identification": {"id": "https://acplt.org/Test_Asset_Mandatory", "idType": "IRI"}, "kind": "Instance"}, {"idShort": "Test_Asset", "description": [{"language": "en-us", "text": "An example asset for the test application"}, {"language": "de", "text": "Ein Beispiel-Asset f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "Asset"}, "identification": {"id": "https://acplt.org/Test_Asset_Missing", "idType": "IRI"}, "administration": {}, "kind": "Instance"}], "conceptDescriptions": [{"idShort": "TestConceptDescription", "description": [{"language": "en-us", "text": "An example concept description for the test application"}, {"language": "de", "text": "Ein Beispiel-ConceptDescription f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "ConceptDescription"}, "identification": {"id": "https://acplt.org/Test_ConceptDescription", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "isCaseOf": [{"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/DataSpecifications/ConceptDescriptions/TestConceptDescription", "local": false}]}]}, {"idShort": "", "modelType": {"name": "ConceptDescription"}, "identification": {"id": "https://acplt.org/Test_ConceptDescription_Mandatory", "idType": "IRI"}}, {"idShort": "TestConceptDescription", "description": [{"language": "en-us", "text": "An example concept description for the test application"}, {"language": "de", "text": "Ein Beispiel-ConceptDescription f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "ConceptDescription"}, "identification": {"id": "https://acplt.org/Test_ConceptDescription_Missing", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}}, {"idShort": "TestSpec_01", "modelType": {"name": "ConceptDescription"}, "identification": {"id": "http://acplt.org/DataSpecifciations/Example/Identification", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "isCaseOf": [{"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ReferenceElements/ConceptDescriptionX", "local": false}]}], "embeddedDataSpecifications": [{"dataSpecification": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360/2/0", "local": false}]}, "dataSpecificationContent": {"preferredName": [{"language": "de", "text": "Test Specification"}, {"language": "en-us", "text": "TestSpecification"}], "dataType": "REAL_MEASURE", "definition": [{"language": "de", "text": "Dies ist eine Data Specification f\u00fcr Testzwecke"}, {"language": "en-us", "text": "This is a DataSpecification for testing purposes"}], "shortName": [{"language": "de", "text": "Test Spec"}, {"language": "en-us", "text": "TestSpec"}], "unit": "SpaceUnit", "unitId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Units/SpaceUnit", "local": false}]}, "sourceOfDefinition": "http://acplt.org/DataSpec/ExampleDef", "symbol": "SU", "valueFormat": "string", "valueList": {"valueReferencePairTypes": [{"value": "exampleValue", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}, {"value": "exampleValue2", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId2", "local": false}]}, "valueType": "string"}]}, "value": "TEST", "levelType": ["Min", "Max"]}}]}]} \ No newline at end of file +{"assetAdministrationShells": [{"idShort": "TestAssetAdministrationShell", "description": [{"language": "en-us", "text": "An Example Asset Administration Shell for the test application"}, {"language": "de", "text": "Ein Beispiel-Verwaltungsschale f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "AssetAdministrationShell"}, "identification": {"id": "https://acplt.org/Test_AssetAdministrationShell", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "derivedFrom": {"keys": [{"type": "AssetAdministrationShell", "idType": "IRI", "value": "https://acplt.org/TestAssetAdministrationShell2", "local": false}]}, "asset": {"keys": [{"type": "Asset", "idType": "IRI", "value": "https://acplt.org/Test_Asset", "local": false}]}, "submodels": [{"keys": [{"type": "Submodel", "idType": "IRI", "value": "https://acplt.org/Test_Submodel", "local": false}]}, {"keys": [{"type": "Submodel", "idType": "IRI", "value": "http://acplt.org/Submodels/Assets/TestAsset/BillOfMaterial", "local": false}]}, {"keys": [{"type": "Submodel", "idType": "IRI", "value": "http://acplt.org/Submodels/Assets/TestAsset/Identification", "local": false}]}], "conceptDictionaries": [{"idShort": "TestConceptDictionary", "description": [{"language": "en-us", "text": "An example concept dictionary for the test application"}, {"language": "de", "text": "Ein Beispiel-ConceptDictionary f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "ConceptDictionary"}, "conceptDescriptions": [{"keys": [{"type": "ConceptDescription", "idType": "IRI", "value": "https://acplt.org/Test_ConceptDescription", "local": false}]}]}]}, {"idShort": "", "modelType": {"name": "AssetAdministrationShell"}, "identification": {"id": "https://acplt.org/Test_AssetAdministrationShell_Mandatory", "idType": "IRI"}, "asset": {"keys": [{"type": "Asset", "idType": "IRI", "value": "https://acplt.org/Test_Asset_Mandatory", "local": false}]}, "submodels": [{"keys": [{"type": "Submodel", "idType": "IRI", "value": "https://acplt.org/Test_Submodel_Mandatory", "local": false}]}, {"keys": [{"type": "Submodel", "idType": "IRI", "value": "https://acplt.org/Test_Submodel2_Mandatory", "local": false}]}], "conceptDictionaries": [{"idShort": "TestConceptDictionary", "modelType": {"name": "ConceptDictionary"}}]}, {"idShort": "", "modelType": {"name": "AssetAdministrationShell"}, "identification": {"id": "https://acplt.org/Test_AssetAdministrationShell2_Mandatory", "idType": "IRI"}, "asset": {"keys": [{"type": "Asset", "idType": "IRI", "value": "https://acplt.org/Test_Asset_Mandatory", "local": false}]}}, {"idShort": "TestAssetAdministrationShell", "description": [{"language": "en-us", "text": "An Example Asset Administration Shell for the test application"}, {"language": "de", "text": "Ein Beispiel-Verwaltungsschale f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "AssetAdministrationShell"}, "identification": {"id": "https://acplt.org/Test_AssetAdministrationShell_Missing", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "asset": {"keys": [{"type": "Asset", "idType": "IRI", "value": "https://acplt.org/Test_Asset_Missing", "local": false}]}, "submodels": [{"keys": [{"type": "Submodel", "idType": "IRI", "value": "https://acplt.org/Test_Submodel_Missing", "local": false}]}], "views": [{"idShort": "ExampleView", "modelType": {"name": "View"}, "containedElements": [{"keys": [{"type": "Submodel", "idType": "IRI", "value": "https://acplt.org/Test_Submodel_Missing", "local": false}]}]}, {"idShort": "ExampleView2", "modelType": {"name": "View"}}], "conceptDictionaries": [{"idShort": "TestConceptDictionary", "description": [{"language": "en-us", "text": "An example concept dictionary for the test application"}, {"language": "de", "text": "Ein Beispiel-ConceptDictionary f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "ConceptDictionary"}, "conceptDescriptions": [{"keys": [{"type": "ConceptDescription", "idType": "IRI", "value": "https://acplt.org/Test_ConceptDescription_Missing", "local": false}]}]}]}], "submodels": [{"idShort": "Identification", "description": [{"language": "en-us", "text": "An example asset identification submodel for the test application"}, {"language": "de", "text": "Ein Beispiel-Identifikations-Submodel f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "Submodel"}, "identification": {"id": "http://acplt.org/Submodels/Assets/TestAsset/Identification", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "semanticId": {"keys": [{"type": "Submodel", "idType": "IRI", "value": "http://acplt.org/SubmodelTemplates/AssetIdentification", "local": false}]}, "submodelElements": [{"idShort": "ManufacturerName", "description": [{"language": "en-us", "text": "Legally valid designation of the natural or judicial person which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into circulation."}, {"language": "de", "text": "Bezeichnung f\u00fcr eine nat\u00fcrliche oder juristische Person, die f\u00fcr die Auslegung, Herstellung und Verpackung sowie die Etikettierung eines Produkts im Hinblick auf das 'Inverkehrbringen' im eigenen Namen verantwortlich ist"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "0173-1#02-AAO677#002", "local": false}]}, "qualifiers": [{"modelType": {"name": "Qualifier"}, "value": "100", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "int", "type": "http://acplt.org/Qualifier/ExampleQualifier"}, {"modelType": {"name": "Qualifier"}, "value": "50", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "int", "type": "http://acplt.org/Qualifier/ExampleQualifier2"}], "value": "ACPLT", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}, {"idShort": "InstanceId", "description": [{"language": "en-us", "text": "Legally valid designation of the natural or judicial person which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into circulation."}, {"language": "de", "text": "Bezeichnung f\u00fcr eine nat\u00fcrliche oder juristische Person, die f\u00fcr die Auslegung, Herstellung und Verpackung sowie die Etikettierung eines Produkts im Hinblick auf das 'Inverkehrbringen' im eigenen Namen verantwortlich ist"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://opcfoundation.org/UA/DI/1.1/DeviceType/Serialnumber", "local": false}]}, "value": "978-8234-234-342", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}]}, {"idShort": "BillOfMaterial", "description": [{"language": "en-us", "text": "An example bill of material submodel for the test application"}, {"language": "de", "text": "Ein Beispiel-BillofMaterial-Submodel f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "Submodel"}, "identification": {"id": "http://acplt.org/Submodels/Assets/TestAsset/BillOfMaterial", "idType": "IRI"}, "administration": {"version": "0.9"}, "semanticId": {"keys": [{"type": "Submodel", "idType": "IRI", "value": "http://acplt.org/SubmodelTemplates/BillOfMaterial", "local": false}]}, "submodelElements": [{"idShort": "ExampleEntity", "description": [{"language": "en-us", "text": "Legally valid designation of the natural or judicial person which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into circulation."}, {"language": "de", "text": "Bezeichnung f\u00fcr eine nat\u00fcrliche oder juristische Person, die f\u00fcr die Auslegung, Herstellung und Verpackung sowie die Etikettierung eines Produkts im Hinblick auf das 'Inverkehrbringen' im eigenen Namen verantwortlich ist"}], "modelType": {"name": "Entity"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://opcfoundation.org/UA/DI/1.1/DeviceType/Serialnumber", "local": false}]}, "statements": [{"idShort": "ExampleProperty2", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "value": "exampleValue2", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}, {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "value": "exampleValue", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}], "entityType": "CoManagedEntity"}, {"idShort": "ExampleEntity2", "description": [{"language": "en-us", "text": "Legally valid designation of the natural or judicial person which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into circulation."}, {"language": "de", "text": "Bezeichnung f\u00fcr eine nat\u00fcrliche oder juristische Person, die f\u00fcr die Auslegung, Herstellung und Verpackung sowie die Etikettierung eines Produkts im Hinblick auf das 'Inverkehrbringen' im eigenen Namen verantwortlich ist"}], "modelType": {"name": "Entity"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://opcfoundation.org/UA/DI/1.1/DeviceType/Serialnumber", "local": false}]}, "entityType": "SelfManagedEntity", "asset": {"keys": [{"type": "Asset", "idType": "IRI", "value": "https://acplt.org/Test_Asset2", "local": false}]}}]}, {"idShort": "TestSubmodel", "description": [{"language": "en-us", "text": "An example submodel for the test application"}, {"language": "de", "text": "Ein Beispiel-Teilmodell f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "Submodel"}, "identification": {"id": "https://acplt.org/Test_Submodel", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelTemplates/ExampleSubmodel", "local": false}]}, "submodelElements": [{"idShort": "ExampleRelationshipElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example RelationshipElement object"}, {"language": "de", "text": "Beispiel RelationshipElement Element"}], "modelType": {"name": "RelationshipElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/RelationshipElements/ExampleRelationshipElement", "local": false}]}, "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty2", "local": true}]}}, {"idShort": "ExampleAnnotatedRelationshipElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example AnnotatedRelationshipElement object"}, {"language": "de", "text": "Beispiel AnnotatedRelationshipElement Element"}], "modelType": {"name": "AnnotatedRelationshipElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/RelationshipElements/ExampleAnnotatedRelationshipElement", "local": false}]}, "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty2", "local": true}]}, "annotation": [{"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty3", "local": true}]}]}, {"idShort": "ExampleOperation", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Operation object"}, {"language": "de", "text": "Beispiel Operation Element"}], "modelType": {"name": "Operation"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Operations/ExampleOperation", "local": false}]}, "inputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "value": "exampleValue", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}}], "outputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "value": "exampleValue", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}}], "inoutputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "value": "exampleValue", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}}]}, {"idShort": "ExampleCapability", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Capability object"}, {"language": "de", "text": "Beispiel Capability Element"}], "modelType": {"name": "Capability"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Capabilities/ExampleCapability", "local": false}]}}, {"idShort": "ExampleBasicEvent", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example BasicEvent object"}, {"language": "de", "text": "Beispiel BasicEvent Element"}], "modelType": {"name": "BasicEvent"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Events/ExampleBasicEvent", "local": false}]}, "observed": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleSubmodelCollectionOrdered", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example SubmodelElementCollectionOrdered object"}, {"language": "de", "text": "Beispiel SubmodelElementCollectionOrdered Element"}], "modelType": {"name": "SubmodelElementCollection"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelElementCollections/ExampleSubmodelElementCollectionOrdered", "local": false}]}, "value": [{"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "value": "exampleValue", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}, {"idShort": "ExampleMultiLanguageProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example MultiLanguageProperty object"}, {"language": "de", "text": "Beispiel MulitLanguageProperty Element"}], "modelType": {"name": "MultiLanguageProperty"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/MultiLanguageProperties/ExampleMultiLanguageProperty", "local": false}]}, "value": [{"language": "en-us", "text": "Example value of a MultiLanguageProperty element"}, {"language": "de", "text": "Beispielswert f\u00fcr ein MulitLanguageProperty-Element"}], "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleMultiLanguageValueId", "local": false}]}}, {"idShort": "ExampleRange", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Range object"}, {"language": "de", "text": "Beispiel Range Element"}], "modelType": {"name": "Range"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Ranges/ExampleRange", "local": false}]}, "valueType": "int", "min": "0", "max": "100"}], "ordered": true}, {"idShort": "ExampleSubmodelCollectionUnordered", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example SubmodelElementCollectionUnordered object"}, {"language": "de", "text": "Beispiel SubmodelElementCollectionUnordered Element"}], "modelType": {"name": "SubmodelElementCollection"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelElementCollections/ExampleSubmodelElementCollectionUnordered", "local": false}]}, "value": [{"idShort": "ExampleBlob", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Blob object"}, {"language": "de", "text": "Beispiel Blob Element"}], "modelType": {"name": "Blob"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Blobs/ExampleBlob", "local": false}]}, "mimeType": "application/pdf", "value": "AQIDBAU="}, {"idShort": "ExampleFile", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example File object"}, {"language": "de", "text": "Beispiel File Element"}], "modelType": {"name": "File"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Files/ExampleFile", "local": false}]}, "value": "/TestFile.pdf", "mimeType": "application/pdf"}, {"idShort": "ExampleReferenceElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Reference Element object"}, {"language": "de", "text": "Beispiel Reference Element Element"}], "modelType": {"name": "ReferenceElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ReferenceElements/ExampleReferenceElement", "local": false}]}, "value": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}], "ordered": false}]}, {"idShort": "", "modelType": {"name": "Submodel"}, "identification": {"id": "https://acplt.org/Test_Submodel_Mandatory", "idType": "IRI"}, "submodelElements": [{"idShort": "ExampleRelationshipElement", "modelType": {"name": "RelationshipElement"}, "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleAnnotatedRelationshipElement", "modelType": {"name": "AnnotatedRelationshipElement"}, "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleOperation", "modelType": {"name": "Operation"}}, {"idShort": "ExampleCapability", "modelType": {"name": "Capability"}}, {"idShort": "ExampleBasicEvent", "modelType": {"name": "BasicEvent"}, "observed": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleSubmodelCollectionOrdered", "modelType": {"name": "SubmodelElementCollection"}, "value": [{"idShort": "ExampleProperty", "modelType": {"name": "Property"}, "value": null, "valueType": "string"}, {"idShort": "ExampleMultiLanguageProperty", "modelType": {"name": "MultiLanguageProperty"}}, {"idShort": "ExampleRange", "modelType": {"name": "Range"}, "valueType": "int", "min": null, "max": null}], "ordered": true}, {"idShort": "ExampleSubmodelCollectionUnordered", "modelType": {"name": "SubmodelElementCollection"}, "value": [{"idShort": "ExampleBlob", "modelType": {"name": "Blob"}, "mimeType": "application/pdf"}, {"idShort": "ExampleFile", "modelType": {"name": "File"}, "value": null, "mimeType": "application/pdf"}, {"idShort": "ExampleReferenceElement", "modelType": {"name": "ReferenceElement"}}], "ordered": false}, {"idShort": "ExampleSubmodelCollectionUnordered2", "modelType": {"name": "SubmodelElementCollection"}, "ordered": false}]}, {"idShort": "", "modelType": {"name": "Submodel"}, "identification": {"id": "https://acplt.org/Test_Submodel2_Mandatory", "idType": "IRI"}}, {"idShort": "TestSubmodel", "description": [{"language": "en-us", "text": "An example submodel for the test application"}, {"language": "de", "text": "Ein Beispiel-Teilmodell f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "Submodel"}, "identification": {"id": "https://acplt.org/Test_Submodel_Missing", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelTemplates/ExampleSubmodel", "local": false}]}, "submodelElements": [{"idShort": "ExampleRelationshipElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example RelationshipElement object"}, {"language": "de", "text": "Beispiel RelationshipElement Element"}], "modelType": {"name": "RelationshipElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/RelationshipElements/ExampleRelationshipElement", "local": false}]}, "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleAnnotatedRelationshipElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example AnnotatedRelationshipElement object"}, {"language": "de", "text": "Beispiel AnnotatedRelationshipElement Element"}], "modelType": {"name": "AnnotatedRelationshipElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/RelationshipElements/ExampleAnnotatedRelationshipElement", "local": false}]}, "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "annotation": [{"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}]}, {"idShort": "ExampleOperation", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Operation object"}, {"language": "de", "text": "Beispiel Operation Element"}], "modelType": {"name": "Operation"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Operations/ExampleOperation", "local": false}]}, "inputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "qualifiers": [{"modelType": {"name": "Qualifier"}, "valueType": "string", "type": "http://acplt.org/Qualifier/ExampleQualifier"}], "value": "exampleValue", "valueType": "string"}}], "outputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "qualifiers": [{"modelType": {"name": "Qualifier"}, "valueType": "string", "type": "http://acplt.org/Qualifier/ExampleQualifier"}], "value": "exampleValue", "valueType": "string"}}], "inoutputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "qualifiers": [{"modelType": {"name": "Qualifier"}, "valueType": "string", "type": "http://acplt.org/Qualifier/ExampleQualifier"}], "value": "exampleValue", "valueType": "string"}}]}, {"idShort": "ExampleCapability", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Capability object"}, {"language": "de", "text": "Beispiel Capability Element"}], "modelType": {"name": "Capability"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Capabilities/ExampleCapability", "local": false}]}}, {"idShort": "ExampleBasicEvent", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example BasicEvent object"}, {"language": "de", "text": "Beispiel BasicEvent Element"}], "modelType": {"name": "BasicEvent"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Events/ExampleBasicEvent", "local": false}]}, "observed": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleSubmodelCollectionOrdered", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example SubmodelElementCollectionOrdered object"}, {"language": "de", "text": "Beispiel SubmodelElementCollectionOrdered Element"}], "modelType": {"name": "SubmodelElementCollection"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelElementCollections/ExampleSubmodelElementCollectionOrdered", "local": false}]}, "value": [{"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "qualifiers": [{"modelType": {"name": "Qualifier"}, "valueType": "string", "type": "http://acplt.org/Qualifier/ExampleQualifier"}], "value": "exampleValue", "valueType": "string"}, {"idShort": "ExampleMultiLanguageProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example MultiLanguageProperty object"}, {"language": "de", "text": "Beispiel MulitLanguageProperty Element"}], "modelType": {"name": "MultiLanguageProperty"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/MultiLanguageProperties/ExampleMultiLanguageProperty", "local": false}]}, "value": [{"language": "en-us", "text": "Example value of a MultiLanguageProperty element"}, {"language": "de", "text": "Beispielswert f\u00fcr ein MulitLanguageProperty-Element"}]}, {"idShort": "ExampleRange", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Range object"}, {"language": "de", "text": "Beispiel Range Element"}], "modelType": {"name": "Range"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Ranges/ExampleRange", "local": false}]}, "valueType": "int", "min": "0", "max": "100"}], "ordered": true}, {"idShort": "ExampleSubmodelCollectionUnordered", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example SubmodelElementCollectionUnordered object"}, {"language": "de", "text": "Beispiel SubmodelElementCollectionUnordered Element"}], "modelType": {"name": "SubmodelElementCollection"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelElementCollections/ExampleSubmodelElementCollectionUnordered", "local": false}]}, "value": [{"idShort": "ExampleBlob", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Blob object"}, {"language": "de", "text": "Beispiel Blob Element"}], "modelType": {"name": "Blob"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Blobs/ExampleBlob", "local": false}]}, "mimeType": "application/pdf", "value": "AQIDBAU="}, {"idShort": "ExampleFile", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example File object"}, {"language": "de", "text": "Beispiel File Element"}], "modelType": {"name": "File"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Files/ExampleFile", "local": false}]}, "value": "/TestFile.pdf", "mimeType": "application/pdf"}, {"idShort": "ExampleReferenceElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Reference Element object"}, {"language": "de", "text": "Beispiel Reference Element Element"}], "modelType": {"name": "ReferenceElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ReferenceElements/ExampleReferenceElement", "local": false}]}, "value": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}], "ordered": false}]}, {"idShort": "TestSubmodel", "description": [{"language": "en-us", "text": "An example submodel for the test application"}, {"language": "de", "text": "Ein Beispiel-Teilmodell f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "Submodel"}, "identification": {"id": "https://acplt.org/Test_Submodel_Template", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelTemplates/ExampleSubmodel", "local": false}]}, "kind": "Template", "submodelElements": [{"idShort": "ExampleRelationshipElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example RelationshipElement object"}, {"language": "de", "text": "Beispiel RelationshipElement Element"}], "modelType": {"name": "RelationshipElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/RelationshipElements/ExampleRelationshipElement", "local": false}]}, "kind": "Template", "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleAnnotatedRelationshipElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example AnnotatedRelationshipElement object"}, {"language": "de", "text": "Beispiel AnnotatedRelationshipElement Element"}], "modelType": {"name": "AnnotatedRelationshipElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/RelationshipElements/ExampleAnnotatedRelationshipElement", "local": false}]}, "kind": "Template", "first": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}, "second": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleOperation", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Operation object"}, {"language": "de", "text": "Beispiel Operation Element"}], "modelType": {"name": "Operation"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Operations/ExampleOperation", "local": false}]}, "kind": "Template", "inputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "kind": "Template", "value": null, "valueType": "string"}}], "outputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "kind": "Template", "value": null, "valueType": "string"}}], "inoutputVariable": [{"value": {"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "kind": "Template", "value": null, "valueType": "string"}}]}, {"idShort": "ExampleCapability", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Capability object"}, {"language": "de", "text": "Beispiel Capability Element"}], "modelType": {"name": "Capability"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Capabilities/ExampleCapability", "local": false}]}, "kind": "Template"}, {"idShort": "ExampleBasicEvent", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example BasicEvent object"}, {"language": "de", "text": "Beispiel BasicEvent Element"}], "modelType": {"name": "BasicEvent"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Events/ExampleBasicEvent", "local": false}]}, "kind": "Template", "observed": {"keys": [{"type": "Property", "idType": "IdShort", "value": "ExampleProperty", "local": true}]}}, {"idShort": "ExampleSubmodelCollectionOrdered", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example SubmodelElementCollectionOrdered object"}, {"language": "de", "text": "Beispiel SubmodelElementCollectionOrdered Element"}], "modelType": {"name": "SubmodelElementCollection"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelElementCollections/ExampleSubmodelElementCollectionOrdered", "local": false}]}, "kind": "Template", "value": [{"idShort": "ExampleProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example Property object"}, {"language": "de", "text": "Beispiel Property Element"}], "modelType": {"name": "Property"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Properties/ExampleProperty", "local": false}]}, "kind": "Template", "value": null, "valueType": "string"}, {"idShort": "ExampleMultiLanguageProperty", "category": "CONSTANT", "description": [{"language": "en-us", "text": "Example MultiLanguageProperty object"}, {"language": "de", "text": "Beispiel MulitLanguageProperty Element"}], "modelType": {"name": "MultiLanguageProperty"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/MultiLanguageProperties/ExampleMultiLanguageProperty", "local": false}]}, "kind": "Template"}, {"idShort": "ExampleRange", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Range object"}, {"language": "de", "text": "Beispiel Range Element"}], "modelType": {"name": "Range"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Ranges/ExampleRange", "local": false}]}, "kind": "Template", "valueType": "int", "min": null, "max": "100"}, {"idShort": "ExampleRange2", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Range object"}, {"language": "de", "text": "Beispiel Range Element"}], "modelType": {"name": "Range"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Ranges/ExampleRange", "local": false}]}, "kind": "Template", "valueType": "int", "min": "0", "max": null}], "ordered": true}, {"idShort": "ExampleSubmodelCollectionUnordered", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example SubmodelElementCollectionUnordered object"}, {"language": "de", "text": "Beispiel SubmodelElementCollectionUnordered Element"}], "modelType": {"name": "SubmodelElementCollection"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelElementCollections/ExampleSubmodelElementCollectionUnordered", "local": false}]}, "kind": "Template", "value": [{"idShort": "ExampleBlob", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Blob object"}, {"language": "de", "text": "Beispiel Blob Element"}], "modelType": {"name": "Blob"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Blobs/ExampleBlob", "local": false}]}, "kind": "Template", "mimeType": "application/pdf"}, {"idShort": "ExampleFile", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example File object"}, {"language": "de", "text": "Beispiel File Element"}], "modelType": {"name": "File"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Files/ExampleFile", "local": false}]}, "kind": "Template", "value": null, "mimeType": "application/pdf"}, {"idShort": "ExampleReferenceElement", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example Reference Element object"}, {"language": "de", "text": "Beispiel Reference Element Element"}], "modelType": {"name": "ReferenceElement"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ReferenceElements/ExampleReferenceElement", "local": false}]}, "kind": "Template"}], "ordered": false}, {"idShort": "ExampleSubmodelCollectionUnordered2", "category": "PARAMETER", "description": [{"language": "en-us", "text": "Example SubmodelElementCollectionUnordered object"}, {"language": "de", "text": "Beispiel SubmodelElementCollectionUnordered Element"}], "modelType": {"name": "SubmodelElementCollection"}, "semanticId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/SubmodelElementCollections/ExampleSubmodelElementCollectionUnordered", "local": false}]}, "kind": "Template", "ordered": false}]}], "assets": [{"idShort": "Test_Asset", "description": [{"language": "en-us", "text": "An example asset for the test application"}, {"language": "de", "text": "Ein Beispiel-Asset f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "Asset"}, "identification": {"id": "https://acplt.org/Test_Asset", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "kind": "Instance", "assetIdentificationModel": {"keys": [{"type": "Submodel", "idType": "IRI", "value": "http://acplt.org/Submodels/Assets/TestAsset/Identification", "local": false}]}, "billOfMaterial": {"keys": [{"type": "Submodel", "idType": "IRI", "value": "http://acplt.org/Submodels/Assets/TestAsset/BillOfMaterial", "local": false}]}}, {"idShort": "", "modelType": {"name": "Asset"}, "identification": {"id": "https://acplt.org/Test_Asset_Mandatory", "idType": "IRI"}, "kind": "Instance"}, {"idShort": "Test_Asset", "description": [{"language": "en-us", "text": "An example asset for the test application"}, {"language": "de", "text": "Ein Beispiel-Asset f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "Asset"}, "identification": {"id": "https://acplt.org/Test_Asset_Missing", "idType": "IRI"}, "administration": {}, "kind": "Instance"}], "conceptDescriptions": [{"idShort": "TestConceptDescription", "description": [{"language": "en-us", "text": "An example concept description for the test application"}, {"language": "de", "text": "Ein Beispiel-ConceptDescription f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "ConceptDescription"}, "identification": {"id": "https://acplt.org/Test_ConceptDescription", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "isCaseOf": [{"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/DataSpecifications/ConceptDescriptions/TestConceptDescription", "local": false}]}]}, {"idShort": "", "modelType": {"name": "ConceptDescription"}, "identification": {"id": "https://acplt.org/Test_ConceptDescription_Mandatory", "idType": "IRI"}}, {"idShort": "TestConceptDescription", "description": [{"language": "en-us", "text": "An example concept description for the test application"}, {"language": "de", "text": "Ein Beispiel-ConceptDescription f\u00fcr eine Test-Anwendung"}], "modelType": {"name": "ConceptDescription"}, "identification": {"id": "https://acplt.org/Test_ConceptDescription_Missing", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}}, {"idShort": "TestSpec_01", "modelType": {"name": "ConceptDescription"}, "identification": {"id": "http://acplt.org/DataSpecifciations/Example/Identification", "idType": "IRI"}, "administration": {"version": "0.9", "revision": "0"}, "isCaseOf": [{"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ReferenceElements/ConceptDescriptionX", "local": false}]}], "embeddedDataSpecifications": [{"dataSpecification": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360/2/0", "local": false}]}, "dataSpecificationContent": {"preferredName": [{"language": "de", "text": "Test Specification"}, {"language": "en-us", "text": "TestSpecification"}], "dataType": "REAL_MEASURE", "definition": [{"language": "de", "text": "Dies ist eine Data Specification f\u00fcr Testzwecke"}, {"language": "en-us", "text": "This is a DataSpecification for testing purposes"}], "shortName": [{"language": "de", "text": "Test Spec"}, {"language": "en-us", "text": "TestSpec"}], "unit": "SpaceUnit", "unitId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/Units/SpaceUnit", "local": false}]}, "sourceOfDefinition": "http://acplt.org/DataSpec/ExampleDef", "symbol": "SU", "valueFormat": "string", "valueList": {"valueReferencePairTypes": [{"value": "exampleValue", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId", "local": false}]}, "valueType": "string"}, {"value": "exampleValue2", "valueId": {"keys": [{"type": "GlobalReference", "idType": "IRI", "value": "http://acplt.org/ValueId/ExampleValueId2", "local": false}]}, "valueType": "string"}]}, "value": "TEST", "levelType": ["Min", "Max"]}}]}]} \ No newline at end of file diff --git a/test/compliance_tool/test_json.py b/test/compliance_tool/test_json.py index 33fa3d23674dc36d534a43a05b77d6429a2496bc..7a52c959b2a65f7db06133c9047e141c00dd87a3 100644 --- a/test/compliance_tool/test_json.py +++ b/test/compliance_tool/test_json.py @@ -15,7 +15,8 @@ import aas.compliance_tool.compliance_check_json as compliance_tool from aas.compliance_tool.state_manager import ComplianceToolStateManager, Status dirname = os.path.dirname -JSON_SCHEMA_FILE = os.path.join(dirname(dirname(dirname(__file__))), 'test\\adapter\\json\\aasJSONSchemaV2.0.json') +JSON_SCHEMA_FILE = os.path.join(dirname(dirname(dirname(__file__))), 'test', 'adapter', 'json', + 'aasJSONSchemaV2.0.json') class ComplianceToolJsonTest(unittest.TestCase):