diff --git a/sdk/README.md b/sdk/README.md index 942f57555..7dbeb1b4d 100644 --- a/sdk/README.md +++ b/sdk/README.md @@ -124,7 +124,8 @@ write_aas_xml_file(file='Simple_Submodel.xml', data=data) For further examples and tutorials, check out the `basyx.aas.examples`-package. Here is a quick overview: * [`tutorial_create_simple_aas`](./basyx/aas/examples/tutorial_create_simple_aas.py): Create an Asset Administration Shell, including an Asset object and a Submodel -* [`tutorial_storage`](./basyx/aas/examples/tutorial_storage.py): Manage a larger number of Asset Administration Shells in an IdentifiableStore and resolve references +* [`tutorial_navigate_aas`](./basyx/aas/examples/tutorial_navigate_aas.py): Navigate Asset Administration Shell Submodels using IdShorts and IdShortPaths +* [`tutorial_storage`](./basyx/aas/examples/tutorial_storage.py): Manage a larger number of Asset Administration Shells in an ObjectStore and resolve references * [`tutorial_serialization_deserialization`](./basyx/aas/examples/tutorial_serialization_deserialization.py): Use the JSON and XML serialization/deserialization for single objects or full standard-compliant files * [`tutorial_aasx`](./basyx/aas/examples/tutorial_aasx.py): Export Asset Administration Shells with related objects and auxiliary files to AASX package files * [`tutorial_backend_couchdb`](./basyx/aas/examples/tutorial_backend_couchdb.py): Use the *CouchDBIdentifiableStore* to manage and retrieve AAS objects in a CouchDB document database diff --git a/sdk/basyx/aas/examples/tutorial_navigate_aas.py b/sdk/basyx/aas/examples/tutorial_navigate_aas.py new file mode 100644 index 000000000..2bbb9f89d --- /dev/null +++ b/sdk/basyx/aas/examples/tutorial_navigate_aas.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python3 +# This work is licensed under a Creative Commons CCZero 1.0 Universal License. +# See http://creativecommons.org/publicdomain/zero/1.0/ for more information. +""" +Tutorial for navigating a Submodel's hierarchy using IdShorts and IdShortPaths. +""" + +from basyx.aas import model +from typing import cast + +# In this tutorial, you will learn how to create a Submodel with different kinds of SubmodelElements and how to navigate +# through them using IdShorts and IdShortPaths. +# +# Step-by-Step Guide: +# Step 1: Create a Submodel with a Property, a SubmodelElementCollection of Properties, a SubmodelElementList of +# Properties and a SubmodelElementList of SubmodelElementCollections +# +# Submodel "https://iat.rwth-aachen.de/Simple_Submodel" +# ├── Property "MyProperty" +# │ +# ├── SubmodelElementCollection "MyPropertyCollection" +# │ ├── Property "MyProperty0" +# │ └── Property "MyProperty1" +# │ +# ├── SubmodelElementList "MyPropertyList" +# │ ├── Property [0] +# │ └── Property [1] +# │ +# └── SubmodelElementList "MyCollectionList" +# ├── SubmodelElementCollection [0] +# │ └── Property "MyProperty" +# ├── SubmodelElementCollection [1] +# │ └── Property "MyProperty" +# └── SubmodelElementCollection [2] +# └── Property "MyProperty" +# +# Step 2: Navigate through the Submodel using IdShorts and IdShortPaths + + +######################################################################## +# Step 1: Create a Submodel with a navigable SubmodelElement hierarchy # +######################################################################## + +# Step 1.1: Create a Submodel +submodel = model.Submodel(id_="https://iat.rwth-aachen.de/Simple_Submodel") + +# Step 1.2: Add a single Property to the Submodel +my_property = model.Property( + id_short="MyProperty", + value_type=model.datatypes.String, + value="I am a simple Property" +) +submodel.submodel_element.add(my_property) + +# Step 1.3: Add a SubmodelElementCollection of Properties to the Submodel +my_property_collection = model.SubmodelElementCollection( + id_short="MyPropertyCollection", + value={ + model.Property( + id_short="MyProperty0", + value_type=model.datatypes.String, + value="I am the first of two Properties within a SubmodelElementCollection" + ), + model.Property( + id_short="MyProperty1", + value_type=model.datatypes.String, + value="I am the second of two Properties within a SubmodelElementCollection" + ) + } +) +submodel.submodel_element.add(my_property_collection) + +# Step 1.4: Add a SubmodelElementList of Properties to the Submodel +my_property_list = model.SubmodelElementList( + id_short="MyPropertyList", + type_value_list_element=model.Property, + value_type_list_element=model.datatypes.String, + order_relevant=True, + value=[ + model.Property( + id_short=None, + value_type=model.datatypes.String, + value="I am Property 0 within a SubmodelElementList" + ), + model.Property( + id_short=None, + value_type=model.datatypes.String, + value="I am Property 1 within a SubmodelElementList" + ) + ] +) +submodel.submodel_element.add(my_property_list) + +# Step 1.5: Add a SubmodelElementList of SubmodelElementCollections to the Submodel +my_property_collection_0 = model.SubmodelElementCollection( + id_short=None, + value={model.Property( + id_short="MyProperty", + value_type=model.datatypes.String, + value="I am a simple Property within SubmodelElementCollection 0" + )} +) +my_property_collection_1 = model.SubmodelElementCollection( + id_short=None, + value={model.Property( + id_short="MyProperty", + value_type=model.datatypes.String, + value="I am a simple Property within SubmodelElementCollection 1" + )} +) +my_property_collection_2 = model.SubmodelElementCollection( + id_short=None, + value={model.Property( + id_short="MyProperty", + value_type=model.datatypes.String, + value="I am a simple Property within SubmodelElementCollection 2" + )} +) +my_collection_list = model.SubmodelElementList( + id_short="MyCollectionList", + type_value_list_element=model.SubmodelElementCollection, + order_relevant=True, + value=[my_property_collection_0, my_property_collection_1, my_property_collection_2] +) +submodel.submodel_element.add(my_collection_list) + + +######################################################################### +# Step 2: Navigate through the Submodel using IdShorts and IdShortPaths # +######################################################################### + +# Step 2.1: Access a single Property via its IdShort +my_property = cast(model.Property, submodel.get_referable("MyProperty")) +print(f"my_property: id_short = {my_property.id_short}, value = {my_property.value}\n") + +# Step 2.2: Navigate through a SubmodelElementCollection of Properties +# Step 2.2.1: Access a Property within a SubmodelElementCollection step by step via its IdShort +my_property_collection = cast(model.SubmodelElementCollection, submodel.get_referable("MyPropertyCollection")) +my_property_collection_property_0 = cast(model.Property, my_property_collection.get_referable("MyProperty0")) +print( + f"my_property_collection_property_0: " + f"id_short = {my_property_collection_property_0}, " + f"value = {my_property_collection_property_0.value}" +) + +# Step 2.2.2: Access a Property within a SubmodelElementCollection via its IdShortPath +my_property_collection_property_1 = cast( + model.Property, + submodel.get_referable(["MyPropertyCollection", "MyProperty1"]) +) +print( + f"my_property_collection_property_1: " + f"id_short = {my_property_collection_property_1}, " + f"value = {my_property_collection_property_1.value}\n" +) + +# Step 2.3: Navigate through a SubmodelElementList of Properties +# Step 2.3.1: Access a Property within a SubmodelElementList step by step via its index +my_property_list = cast(model.SubmodelElementList, submodel.get_referable("MyPropertyList")) +my_property_list_property_0 = cast(model.Property, my_property_list.get_referable("0")) +print( + f"my_property_list_property_0: " + f"id_short = {my_property_list_property_0}, " + f"value = {my_property_list_property_0.value}" +) + +# Step 2.3.2: Access a Property within a SubmodelElementList via its IdShortPath +my_property_list_property_1 = cast(model.Property, submodel.get_referable(["MyPropertyList", "1"])) +print( + f"my_property_list_property_1: " + f"id_short = {my_property_list_property_1}, " + f"value = {my_property_list_property_1.value}\n" +) + +# Step 2.4: Navigate through a SubmodelElementList of SubmodelElementCollections +# Step 2.4.1: Access a Property within a SubmodelElementList of SubmodelElementCollections step by step via its index +# and IdShort +my_collection_list = cast(model.SubmodelElementList, submodel.get_referable("MyCollectionList")) +my_collection_list_collection_0 = cast(model.SubmodelElementCollection, my_collection_list.get_referable("0")) +my_collection_list_collection_0_property_0 = cast( + model.Property, + my_collection_list_collection_0.get_referable("MyProperty") +) +print( + f"my_collection_list_collection_0_property_0: " + f"id_short = {my_collection_list_collection_0_property_0}, " + f"value = {my_collection_list_collection_0_property_0.value}" +) + +# Step 2.4.2: Access a Property within a SubmodelElementList of SubmodelElementCollections via its IdShortPath +my_collection_list_collection_2_property_0 = cast( + model.Property, + submodel.get_referable(["MyCollectionList", "2", "MyProperty"]) +) +print( + f"my_collection_list_collection_2_property_0: " + f"id_short = {my_collection_list_collection_2_property_0}, " + f"value = {my_collection_list_collection_2_property_0.value}" +) diff --git a/sdk/docs/source/tutorials/index.rst b/sdk/docs/source/tutorials/index.rst index ce2fe76ad..24f0282ab 100644 --- a/sdk/docs/source/tutorials/index.rst +++ b/sdk/docs/source/tutorials/index.rst @@ -7,7 +7,8 @@ Tutorials for working with the Eclipse BaSyx Python SDK :caption: Contents: tutorial_create_simple_aas - tutorial_serialization_deserialization + tutorial_navigate_aas tutorial_storage - tutorial_backend_couchdb + tutorial_serialization_deserialization tutorial_aasx + tutorial_backend_couchdb diff --git a/sdk/docs/source/tutorials/tutorial_navigate_aas.rst b/sdk/docs/source/tutorials/tutorial_navigate_aas.rst new file mode 100644 index 000000000..57c6a935b --- /dev/null +++ b/sdk/docs/source/tutorials/tutorial_navigate_aas.rst @@ -0,0 +1,7 @@ +Tutorial: Navigate Submodels +============================ + +.. _tutorial_navigate_aas: + +.. literalinclude:: ../../../basyx/aas/examples/tutorial_navigate_aas.py + :language: python