Skip to content

Commit fcd29e3

Browse files
authored
sdk: Add tutorial for Submodel navigation (#411)
Previously, we lacked a tutorial demonstrating how to navigate a Submodel's hierarchy using IdShorts and IdShortPaths. This adds a simple tutorial for Submodel navigation and updates the documentation to reference it. The end user is shown how to navigate SubmodelElements, such as simple Properties, Property Collections, Property Lists and Collection Lists. Fixes #351
1 parent 1b1a884 commit fcd29e3

4 files changed

Lines changed: 211 additions & 3 deletions

File tree

sdk/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ write_aas_xml_file(file='Simple_Submodel.xml', data=data)
124124
For further examples and tutorials, check out the `basyx.aas.examples`-package. Here is a quick overview:
125125

126126
* [`tutorial_create_simple_aas`](./basyx/aas/examples/tutorial_create_simple_aas.py): Create an Asset Administration Shell, including an Asset object and a Submodel
127-
* [`tutorial_storage`](./basyx/aas/examples/tutorial_storage.py): Manage a larger number of Asset Administration Shells in an IdentifiableStore and resolve references
127+
* [`tutorial_navigate_aas`](./basyx/aas/examples/tutorial_navigate_aas.py): Navigate Asset Administration Shell Submodels using IdShorts and IdShortPaths
128+
* [`tutorial_storage`](./basyx/aas/examples/tutorial_storage.py): Manage a larger number of Asset Administration Shells in an ObjectStore and resolve references
128129
* [`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
129130
* [`tutorial_aasx`](./basyx/aas/examples/tutorial_aasx.py): Export Asset Administration Shells with related objects and auxiliary files to AASX package files
130131
* [`tutorial_backend_couchdb`](./basyx/aas/examples/tutorial_backend_couchdb.py): Use the *CouchDBIdentifiableStore* to manage and retrieve AAS objects in a CouchDB document database
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
#!/usr/bin/env python3
2+
# This work is licensed under a Creative Commons CCZero 1.0 Universal License.
3+
# See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
4+
"""
5+
Tutorial for navigating a Submodel's hierarchy using IdShorts and IdShortPaths.
6+
"""
7+
8+
from basyx.aas import model
9+
from typing import cast
10+
11+
# In this tutorial, you will learn how to create a Submodel with different kinds of SubmodelElements and how to navigate
12+
# through them using IdShorts and IdShortPaths.
13+
#
14+
# Step-by-Step Guide:
15+
# Step 1: Create a Submodel with a Property, a SubmodelElementCollection of Properties, a SubmodelElementList of
16+
# Properties and a SubmodelElementList of SubmodelElementCollections
17+
#
18+
# Submodel "https://iat.rwth-aachen.de/Simple_Submodel"
19+
# ├── Property "MyProperty"
20+
# │
21+
# ├── SubmodelElementCollection "MyPropertyCollection"
22+
# │ ├── Property "MyProperty0"
23+
# │ └── Property "MyProperty1"
24+
# │
25+
# ├── SubmodelElementList "MyPropertyList"
26+
# │ ├── Property [0]
27+
# │ └── Property [1]
28+
# │
29+
# └── SubmodelElementList "MyCollectionList"
30+
# ├── SubmodelElementCollection [0]
31+
# │ └── Property "MyProperty"
32+
# ├── SubmodelElementCollection [1]
33+
# │ └── Property "MyProperty"
34+
# └── SubmodelElementCollection [2]
35+
# └── Property "MyProperty"
36+
#
37+
# Step 2: Navigate through the Submodel using IdShorts and IdShortPaths
38+
39+
40+
########################################################################
41+
# Step 1: Create a Submodel with a navigable SubmodelElement hierarchy #
42+
########################################################################
43+
44+
# Step 1.1: Create a Submodel
45+
submodel = model.Submodel(id_="https://iat.rwth-aachen.de/Simple_Submodel")
46+
47+
# Step 1.2: Add a single Property to the Submodel
48+
my_property = model.Property(
49+
id_short="MyProperty",
50+
value_type=model.datatypes.String,
51+
value="I am a simple Property"
52+
)
53+
submodel.submodel_element.add(my_property)
54+
55+
# Step 1.3: Add a SubmodelElementCollection of Properties to the Submodel
56+
my_property_collection = model.SubmodelElementCollection(
57+
id_short="MyPropertyCollection",
58+
value={
59+
model.Property(
60+
id_short="MyProperty0",
61+
value_type=model.datatypes.String,
62+
value="I am the first of two Properties within a SubmodelElementCollection"
63+
),
64+
model.Property(
65+
id_short="MyProperty1",
66+
value_type=model.datatypes.String,
67+
value="I am the second of two Properties within a SubmodelElementCollection"
68+
)
69+
}
70+
)
71+
submodel.submodel_element.add(my_property_collection)
72+
73+
# Step 1.4: Add a SubmodelElementList of Properties to the Submodel
74+
my_property_list = model.SubmodelElementList(
75+
id_short="MyPropertyList",
76+
type_value_list_element=model.Property,
77+
value_type_list_element=model.datatypes.String,
78+
order_relevant=True,
79+
value=[
80+
model.Property(
81+
id_short=None,
82+
value_type=model.datatypes.String,
83+
value="I am Property 0 within a SubmodelElementList"
84+
),
85+
model.Property(
86+
id_short=None,
87+
value_type=model.datatypes.String,
88+
value="I am Property 1 within a SubmodelElementList"
89+
)
90+
]
91+
)
92+
submodel.submodel_element.add(my_property_list)
93+
94+
# Step 1.5: Add a SubmodelElementList of SubmodelElementCollections to the Submodel
95+
my_property_collection_0 = model.SubmodelElementCollection(
96+
id_short=None,
97+
value={model.Property(
98+
id_short="MyProperty",
99+
value_type=model.datatypes.String,
100+
value="I am a simple Property within SubmodelElementCollection 0"
101+
)}
102+
)
103+
my_property_collection_1 = model.SubmodelElementCollection(
104+
id_short=None,
105+
value={model.Property(
106+
id_short="MyProperty",
107+
value_type=model.datatypes.String,
108+
value="I am a simple Property within SubmodelElementCollection 1"
109+
)}
110+
)
111+
my_property_collection_2 = model.SubmodelElementCollection(
112+
id_short=None,
113+
value={model.Property(
114+
id_short="MyProperty",
115+
value_type=model.datatypes.String,
116+
value="I am a simple Property within SubmodelElementCollection 2"
117+
)}
118+
)
119+
my_collection_list = model.SubmodelElementList(
120+
id_short="MyCollectionList",
121+
type_value_list_element=model.SubmodelElementCollection,
122+
order_relevant=True,
123+
value=[my_property_collection_0, my_property_collection_1, my_property_collection_2]
124+
)
125+
submodel.submodel_element.add(my_collection_list)
126+
127+
128+
#########################################################################
129+
# Step 2: Navigate through the Submodel using IdShorts and IdShortPaths #
130+
#########################################################################
131+
132+
# Step 2.1: Access a single Property via its IdShort
133+
my_property = cast(model.Property, submodel.get_referable("MyProperty"))
134+
print(f"my_property: id_short = {my_property.id_short}, value = {my_property.value}\n")
135+
136+
# Step 2.2: Navigate through a SubmodelElementCollection of Properties
137+
# Step 2.2.1: Access a Property within a SubmodelElementCollection step by step via its IdShort
138+
my_property_collection = cast(model.SubmodelElementCollection, submodel.get_referable("MyPropertyCollection"))
139+
my_property_collection_property_0 = cast(model.Property, my_property_collection.get_referable("MyProperty0"))
140+
print(
141+
f"my_property_collection_property_0: "
142+
f"id_short = {my_property_collection_property_0}, "
143+
f"value = {my_property_collection_property_0.value}"
144+
)
145+
146+
# Step 2.2.2: Access a Property within a SubmodelElementCollection via its IdShortPath
147+
my_property_collection_property_1 = cast(
148+
model.Property,
149+
submodel.get_referable(["MyPropertyCollection", "MyProperty1"])
150+
)
151+
print(
152+
f"my_property_collection_property_1: "
153+
f"id_short = {my_property_collection_property_1}, "
154+
f"value = {my_property_collection_property_1.value}\n"
155+
)
156+
157+
# Step 2.3: Navigate through a SubmodelElementList of Properties
158+
# Step 2.3.1: Access a Property within a SubmodelElementList step by step via its index
159+
my_property_list = cast(model.SubmodelElementList, submodel.get_referable("MyPropertyList"))
160+
my_property_list_property_0 = cast(model.Property, my_property_list.get_referable("0"))
161+
print(
162+
f"my_property_list_property_0: "
163+
f"id_short = {my_property_list_property_0}, "
164+
f"value = {my_property_list_property_0.value}"
165+
)
166+
167+
# Step 2.3.2: Access a Property within a SubmodelElementList via its IdShortPath
168+
my_property_list_property_1 = cast(model.Property, submodel.get_referable(["MyPropertyList", "1"]))
169+
print(
170+
f"my_property_list_property_1: "
171+
f"id_short = {my_property_list_property_1}, "
172+
f"value = {my_property_list_property_1.value}\n"
173+
)
174+
175+
# Step 2.4: Navigate through a SubmodelElementList of SubmodelElementCollections
176+
# Step 2.4.1: Access a Property within a SubmodelElementList of SubmodelElementCollections step by step via its index
177+
# and IdShort
178+
my_collection_list = cast(model.SubmodelElementList, submodel.get_referable("MyCollectionList"))
179+
my_collection_list_collection_0 = cast(model.SubmodelElementCollection, my_collection_list.get_referable("0"))
180+
my_collection_list_collection_0_property_0 = cast(
181+
model.Property,
182+
my_collection_list_collection_0.get_referable("MyProperty")
183+
)
184+
print(
185+
f"my_collection_list_collection_0_property_0: "
186+
f"id_short = {my_collection_list_collection_0_property_0}, "
187+
f"value = {my_collection_list_collection_0_property_0.value}"
188+
)
189+
190+
# Step 2.4.2: Access a Property within a SubmodelElementList of SubmodelElementCollections via its IdShortPath
191+
my_collection_list_collection_2_property_0 = cast(
192+
model.Property,
193+
submodel.get_referable(["MyCollectionList", "2", "MyProperty"])
194+
)
195+
print(
196+
f"my_collection_list_collection_2_property_0: "
197+
f"id_short = {my_collection_list_collection_2_property_0}, "
198+
f"value = {my_collection_list_collection_2_property_0.value}"
199+
)

sdk/docs/source/tutorials/index.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ Tutorials for working with the Eclipse BaSyx Python SDK
77
:caption: Contents:
88

99
tutorial_create_simple_aas
10-
tutorial_serialization_deserialization
10+
tutorial_navigate_aas
1111
tutorial_storage
12-
tutorial_backend_couchdb
12+
tutorial_serialization_deserialization
1313
tutorial_aasx
14+
tutorial_backend_couchdb
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Tutorial: Navigate Submodels
2+
============================
3+
4+
.. _tutorial_navigate_aas:
5+
6+
.. literalinclude:: ../../../basyx/aas/examples/tutorial_navigate_aas.py
7+
:language: python

0 commit comments

Comments
 (0)