Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "BaSyx / Introductory Examples / Java / Step 3"

Line 1: Line 1:
= Step 3: Creating the oven sub model =
+
= Step 3: Creating the oven Submodel =
  
This step will create the oven sub model and a test application for that sub model. The AAS and its sub models can be realized in different ways with Eclipse BaSyx:
+
This step will create the oven Submodel and a test application for that Submodel. The AAS and its Submodels can be realized in different ways with Eclipse BaSyx:
* If the sub model contains static data only, it can be deserialized from an AASX file, or from a JSON file that defines the sub model structure and data.
+
* If the Submodel contains static data only, it can be deserialized from an AASX file, or from a JSON file that defines the Submodel structure and data.
* If the sub model provides also dynamic data, but all dynamic data is pushed from outside the sub model, e.g. from the device, the sub model can be deserialized from an AASX file, or from a JSON file.
+
* If the Submodel provides also dynamic data, but all dynamic data is pushed from outside the Submodel, e.g. from the device, the Submodel can be deserialized from an AASX file, or from a JSON file.
* If the sub model also contains active parts, e.g. services or the ability to actively pull data from data sources, e.g. from the device, it can be created using the Eclipse BaSyx SDKs.  
+
* If the Submodel also contains active parts, e.g. services or the ability to actively pull data from data sources, e.g. from the device, it can be created using the Eclipse BaSyx SDKs.  
  
  
Sub models of the same AAS can be created by different means. In this example, we will illustrate the creation of an AAS and of the oven sub model with the Java SDK.
+
Submodels of the same AAS can be created by different means. In this example, we will illustrate the creation of an AAS and of the oven Submodel with the Java SDK.
 
Communication between the oven and the edge device is via an analogues connection that encodes values as current, which must be periodically sampled by the edge device. Commands for controlling the oven are provided via individual digital lines. The edge device therefore needs to periodically sample input values, and set digital output lines to reflect commands to the oven. This device specific interface code is not part of the example. We define a Java interface that enables access to these functions, and that enables us to substitute the real-world edge device with a stub that simulates the device behavior to create a self-contained example.
 
Communication between the oven and the edge device is via an analogues connection that encodes values as current, which must be periodically sampled by the edge device. Commands for controlling the oven are provided via individual digital lines. The edge device therefore needs to periodically sample input values, and set digital output lines to reflect commands to the oven. This device specific interface code is not part of the example. We define a Java interface that enables access to these functions, and that enables us to substitute the real-world edge device with a stub that simulates the device behavior to create a self-contained example.
  
Line 30: Line 30:
  
  
== Realizing the sub model ==
+
== Realizing the Submodel ==
  
Sub models define all domain and asset specific properties. We will therefore first define a sub model for the oven. The oven sub model defines two properties: The ID that identifies this heater, and the temperature that provides access to the current temperature from the temperature sensor. Two operations enable to activate and to deactivate the oven.
+
Submodels define all domain and asset specific properties. We will therefore first define a Submodel for the oven. The oven Submodel defines two properties: The ID that identifies this heater, and the temperature that provides access to the current temperature from the temperature sensor. Two operations enable to activate and to deactivate the oven.
  
Currently, Eclipse BaSyx handles sub model definitions as hash maps. A map will therefore contain all properties and services of a sub model, which are stored as maps as well. The first map that we create for the oven sub model is therefore a map that contains all sub model properties.
 
  
 
<syntaxhighlight lang="java" style="margin-left: 4em">
 
<syntaxhighlight lang="java" style="margin-left: 4em">
Map<String, Object> properties = new HashMap<>();
+
Submodel ovenSubmodel = new Submodel();
 
</syntaxhighlight>
 
</syntaxhighlight>
  
  
The ID of the oven will be a static value. It is stored in the ID property. The path to this property in the sub model is therefore /id:
+
The ID of the oven will be a static value. It set as the idShort of the Submodel.
  
 
<syntaxhighlight lang="java" style="margin-left: 4em">
 
<syntaxhighlight lang="java" style="margin-left: 4em">
properties.put("id", "heater01");
+
ovenSubmodel.setIdShort("oven");
 
</syntaxhighlight>
 
</syntaxhighlight>
  
  
The second property temperature provides access to the current temperature of the oven. As the oven in our case does provide a very simple interface, the sub model samples the current temperature value whenever a temperature value is requested. This is realized with a function that is invoked whenever the property value is requested. For this reason, it uses the Oven interface [[ BaSyx_/_Introductory_Examples_/_Java_/_Example_Oven | IOven]].
+
The Identification of a Submodel has to be set as a unique identifier.
 +
 
 +
<syntaxhighlight lang="java" style="margin-left: 4em">
 +
ovenSubmodel.setIdentification(new ModelUrn("heater1"));
 +
</syntaxhighlight>
 +
 
 +
 
 +
The temperature property provides access to the current temperature of the oven. As the oven in our case does provide a very simple interface, the Submodel samples the current temperature value whenever a temperature value is requested. This is realized with a function that is invoked whenever the property value is requested. For this reason, it uses the Oven interface [[ BaSyx_/_Introductory_Examples_/_Java_/_Example_Oven | IOven]].
  
 
<syntaxhighlight lang="java" style="margin-left: 4em">
 
<syntaxhighlight lang="java" style="margin-left: 4em">
 
// Create a dynamic property that can resolve its value during runtime
 
// Create a dynamic property that can resolve its value during runtime
 
// 1. Create a supplier function that can determine the oven temperature using the sensor
 
// 1. Create a supplier function that can determine the oven temperature using the sensor
 
 
Supplier<Object> lambdaReadFunction = () -> oven.getSensor().readValue();
 
Supplier<Object> lambdaReadFunction = () -> oven.getSensor().readValue();
  
// 2. Use a VABLambdaProviderHelper in order to create a lambda property out of that supplier
+
// 2. Create a new empty Property
 +
Property dynamicTemperatureProperty = new Property();
 +
 
 +
// 3. Set the id of the new Property
 +
dynamicTemperatureProperty.setIdShort("temperature");
 +
 
 +
// 4. Use the AASLambdaPropertyHelper to add the Getter to the new Property
 
// NOTE: A setter function is not required (=> null), because a sensor temperature is "read only"
 
// NOTE: A setter function is not required (=> null), because a sensor temperature is "read only"
 +
AASLambdaPropertyHelper.setLambdaValue(dynamicTemperatureProperty, lambdaReadFunction, null)
  
Map<String, Object> dynamicTemperatureProperty = VABLambdaProviderHelper.createSimple(lambdaReadFunction, null);
+
// 5. Add that lambda property to the model
 
+
ovenSubmodel.addSubmodelElement(dynamicTemperatureProperty);
// 3. Add that lambda property to the model exactly like the static property before
+
properties.put("temperature", dynamicTemperatureProperty);
+
 
</syntaxhighlight>
 
</syntaxhighlight>
  
  
 
The temperature is read through a call to the readValue() call of the sensor (obtained via getSensor()).  
 
The temperature is read through a call to the readValue() call of the sensor (obtained via getSensor()).  
Besides of properties, the sub model also may export operations. Similar to sub model properties, operations are provided as map as well.  
+
Besides of properties, the Submodel also may export operations.
  
<syntaxhighlight lang="java" style="margin-left: 4em">
+
The Submodel will define two functions: An activate and an deactivate function. Both functions are created as lambda function objects and are placed in the operations map.
// Create an empty container for custom operations
+
Map<String, Object> operations = new HashMap<>();
+
</syntaxhighlight>
+
 
+
 
+
The sub model will define two functions: An activate and an deactivate function. Both functions are created as lambda function objects and are placed in the operations map.
+
  
 
<syntaxhighlight lang="java" style="margin-left: 4em">
 
<syntaxhighlight lang="java" style="margin-left: 4em">
Line 83: Line 87:
 
return null;
 
return null;
 
};
 
};
 +
 +
// Encapsulate the function in an operation
 +
Operation activateOperation = new Operation(activateFunction);
 +
 +
// Set the id of the operation
 +
activateOperation.setIdShort("activateOven");
  
// Add a function that deactivates the oven and implements a functional interface
+
// Add an operation that activates the oven and implements a functional interface
operations.put("activateOven", activateFunction);
+
ovenSubmodel.addSubmodelElement(activateOperation);
  
+
 
// Add a function that deactivates the oven and implements a functional interface
 
// Add a function that deactivates the oven and implements a functional interface
 
Function<Object, Object> deactivateFunction = (args) -> {
 
Function<Object, Object> deactivateFunction = (args) -> {
Line 93: Line 103:
 
return null;
 
return null;
 
};
 
};
 +
 +
// Encapsulate the function in an operation
 +
Operation deactivateOperation = new Operation(deactivateFunction);
 +
 +
// Set the id of the operation
 +
activateOperation.setIdShort("deactivateOven");
  
// Add a function that deactivates the oven and implements a functional interface
+
// Add an operation that deactivates the oven and implements a functional interface
operations.put("deactivateOven", deactivateFunction);
+
ovenSubmodel.addSubmodelElement(deactivateOperation);
</syntaxhighlight>
+
 
+
 
+
The sub model is now created by combining the properties and operations maps:
+
 
+
<syntaxhighlight lang="java" style="margin-left: 4em">
+
Map<String, Object> subModel = new HashMap<>();
+
subModel.put("operations", operations);
+
subModel.put("properties", properties);
+
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 115: Line 122:
  
 
<syntaxhighlight lang="java" style="margin-left: 4em">
 
<syntaxhighlight lang="java" style="margin-left: 4em">
public static Map<String, Object> createMyOvenModel(Oven oven) {
+
public static Submodel createMyOvenModel(Oven oven) {
// Create an empty container for custom properties
+
// Create an empty Submodel
Map<String, Object> properties = new HashMap<>();
+
Submodel ovenSubmodel = new Submodel();
 +
 +
// Set its idShort
 +
ovenSubmodel.setIdShort("Oven");
 +
 +
// Set its unique identification
 +
ovenSubmodel.setIdentification(new ModelUrn("heater1"));
  
// Add a static element
 
properties.put("id", "heater01");
 
 
// Now we want to create a dynamic property that can resolve its value during runtime
 
// Now we want to create a dynamic property that can resolve its value during runtime
// 1. Create a supplier function that can determine the oven temperature using the +sensor
+
// 1. Create a supplier function that can determine the oven temperature using the sensor
Supplier<Object> lambdaFunction = () -> oven.getSensor().readValue();
+
Supplier<Object> lambdaReadFunction = () -> oven.getSensor().readValue();
// 2. Use a VABLambdaProviderHelper in order to create a lambda property out of that supplier
+
// 2. Create a new empty Property
 +
Property dynamicTemperatureProperty = new Property();
 +
// 3. Set the id of the new Property
 +
dynamicTemperatureProperty.setIdShort("temperature");
 +
// 4. Use the AASLambdaPropertyHelper to add the Getter to the new Property
 
// NOTE: A setter function is not required (=> null), because a sensor temperature is "read only"
 
// NOTE: A setter function is not required (=> null), because a sensor temperature is "read only"
Map<String, Object> lambdaProperty = VABLambdaProviderHelper.createSimple(lambdaFunction, null);
+
AASLambdaPropertyHelper.setLambdaValue(dynamicTemperatureProperty, lambdaReadFunction, null)
// 3. Add that lambda property to the model exactly like the static property before
+
// 5. Add that lambda property to the model
properties.put("temperature", lambdaProperty);
+
ovenSubmodel.addSubmodelElement(dynamicTemperatureProperty);
 
   
 
   
// Create an empty container for custom operations
 
Map<String, Object> operations = new HashMap<>();
 
 
// Add a function that activates the oven and implements a functional interface
 
// Add a function that activates the oven and implements a functional interface
 
Function<Object, Object> activateFunction = (args) -> {
 
Function<Object, Object> activateFunction = (args) -> {
Line 137: Line 150:
 
return null;
 
return null;
 
};
 
};
// Add a function that deactivates the oven and implements a functional interface
+
// Encapsulate the function in an operation
operations.put("activateOven", activateFunction);
+
Operation activateOperation = new Operation(activateFunction);
+
// Set the id of the operation
 +
activateOperation.setIdShort("activateOven");
 +
// Add an operation that activates the oven and implements a functional interface
 +
ovenSubmodel.addSubmodelElement(activateOperation);
 +
 
 +
 
// Add a function that deactivates the oven and implements a functional interface
 
// Add a function that deactivates the oven and implements a functional interface
 
Function<Object, Object> deactivateFunction = (args) -> {
 
Function<Object, Object> deactivateFunction = (args) -> {
Line 145: Line 163:
 
return null;
 
return null;
 
};
 
};
// Add a function that deactivates the oven and implements a functional interface
+
// Encapsulate the function in an operation
operations.put("deactivateOven", deactivateFunction);
+
Operation deactivateOperation = new Operation(deactivateFunction);
 +
// Set the id of the operation
 +
activateOperation.setIdShort("deactivateOven");
 +
// Add an operation that deactivates the oven and implements a functional interface
 +
ovenSubmodel.addSubmodelElement(deactivateOperation);
 
   
 
   
// Create a root map and return a single model with the created operations and properties
+
// Return the Submodel
Map<String, Object> subModel = new HashMap<>();
+
return ovenSubmodel;
subModel.put("operations", operations);
+
subModel.put("properties", properties);
+
return subModel ;
+
 
}
 
}
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
  
  
== Testing the sub model ==
+
== Testing the Submodel ==
  
It always makes sense to create regression tests that ensure that changes to not have unwanted side effects. Therefore, a sub model can be tested without an extensive BaSyx deployment.  
+
It always makes sense to create regression tests that ensure that changes to not have unwanted side effects. Therefore, a Submodel can be tested without an extensive BaSyx deployment.  
The first step when testing a sub model is to warp it into a VABLambaProvider that enables access to this sub model. The code below first creates the sub model under test and then wraps it into a provider. The model connects to a simulated oven instance using the Oven stub.  
+
The first step when testing a Submodel is to warp it into a VABLambaProvider that enables access to this Submodel. The code below first creates the Submodel under test and then wraps it into a provider. The model connects to a simulated oven instance using the Oven stub.  
  
 
<syntaxhighlight lang="java" style="margin-left: 4em">
 
<syntaxhighlight lang="java" style="margin-left: 4em">
// Create a model for an oven device. Models in the BaSyx Java SDK are based on HashMaps.
+
// Create a model for an oven device.
Map<String, Object> myOvenModel = createMyOvenModel(new Oven());
+
Submodel myOvenModel = createMyOvenModel(new Oven());
 
+
// Wrap the device model in a VAB model provider. In this case, a VABLambdaProvider is used that enables dynamic
+
// resolution of model properties.
+
// There are also other providers like the VABMapProvider and the FileSystemProvider
+
IModelProvider provider = new VABLambdaProvider(myOvenModel);
+
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 178: Line 191:
  
 
<syntaxhighlight lang="java" style="margin-left: 4em">
 
<syntaxhighlight lang="java" style="margin-left: 4em">
// Now you can access the properties of the oven via the five primitives using the model provider.
+
// Get the Identification of the Submodel
// CREATE: IModelProvider::createValue
+
String id = myOvenModel.getIdentification().getId();
// DELETE: IModelProvider::deleteValue
+
// RETRIEVE: IModelProvider::getModelPropertyValue
+
// UPDATE: IModelProvider::setModelPropertyValue
+
// INVOKE: IModelProvider::invokeOperation
+
String id = (String) provider.getValue("/properties/id");
+
 
System.out.println("Heater id: " + id);
 
System.out.println("Heater id: " + id);
 
+
// NOTE A: getModelPropertyValue has "Object" as the return type, so you probably will have to cast the result
+
// to the appropriate type.
+
// NOTE B: The argument "/properties/id" references the static id property of the model. This path depends
+
// on the structure of the HashMap => /properties/id assumes that the model structure matches the intended map
+
// structure that is proposed at the beginning of "helperfunction".
+
+
 
// The operations can be invoked via the model provider like this:
 
// The operations can be invoked via the model provider like this:
provider.invokeOperation("/operations/activateOven");
+
IOperation activateOperation = myOvenModel.getOperations().get("activateOven");
 +
activateOperation.invoke();
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 201: Line 204:
 
== Conclusion ==
 
== Conclusion ==
  
This second step did illustrate the creation of a sub model for the oven. This is not yet a complete asset administration shell but a specific domain model that describes the specific properties and services of the oven. The sub model defines an interface that may be for all ovens that can be activated and deactivated, and that provide the current temperature. More complex systems will define multiple sub models for their assets, and keep every sub model focused on a specific aspect. Depending on the type of the asset, many sub model types are possible, e.g. the nameplate, spare parts and their availability, sensor data, asset health, or offered services.
+
This second step did illustrate the creation of a Submodel for the oven. This is not yet a complete Asset Administration Shell but a specific domain model that describes the specific properties and services of the oven. The Submodel defines an interface that may be for all ovens that can be activated and deactivated, and that provide the current temperature. More complex systems will define multiple Submodels for their assets, and keep every Submodel focused on a specific aspect. Depending on the type of the asset, many Submodel types are possible, e.g. the nameplate, spare parts and their availability, sensor data, asset health, or offered services.

Revision as of 08:34, 13 April 2021

Step 3: Creating the oven Submodel

This step will create the oven Submodel and a test application for that Submodel. The AAS and its Submodels can be realized in different ways with Eclipse BaSyx:

  • If the Submodel contains static data only, it can be deserialized from an AASX file, or from a JSON file that defines the Submodel structure and data.
  • If the Submodel provides also dynamic data, but all dynamic data is pushed from outside the Submodel, e.g. from the device, the Submodel can be deserialized from an AASX file, or from a JSON file.
  • If the Submodel also contains active parts, e.g. services or the ability to actively pull data from data sources, e.g. from the device, it can be created using the Eclipse BaSyx SDKs.


Submodels of the same AAS can be created by different means. In this example, we will illustrate the creation of an AAS and of the oven Submodel with the Java SDK. Communication between the oven and the edge device is via an analogues connection that encodes values as current, which must be periodically sampled by the edge device. Commands for controlling the oven are provided via individual digital lines. The edge device therefore needs to periodically sample input values, and set digital output lines to reflect commands to the oven. This device specific interface code is not part of the example. We define a Java interface that enables access to these functions, and that enables us to substitute the real-world edge device with a stub that simulates the device behavior to create a self-contained example.


/**
 * Generic interface for sensors
 */
public interface ISensor {
 
	/**
	 * Read sensor value
	 * 
	 * @return The last sampled sensor value
	 */
	public double readValue();
}


The temperature sensor stub that we are using in this example for testing implements this interface and therefore can be accessed through the readValue() function. The user of this interface therefore does not need to know whether he will be communicating with a real-world asset or with a simulated instance.


Realizing the Submodel

Submodels define all domain and asset specific properties. We will therefore first define a Submodel for the oven. The oven Submodel defines two properties: The ID that identifies this heater, and the temperature that provides access to the current temperature from the temperature sensor. Two operations enable to activate and to deactivate the oven.


Submodel ovenSubmodel = new Submodel();


The ID of the oven will be a static value. It set as the idShort of the Submodel.

ovenSubmodel.setIdShort("oven");


The Identification of a Submodel has to be set as a unique identifier.

ovenSubmodel.setIdentification(new ModelUrn("heater1"));


The temperature property provides access to the current temperature of the oven. As the oven in our case does provide a very simple interface, the Submodel samples the current temperature value whenever a temperature value is requested. This is realized with a function that is invoked whenever the property value is requested. For this reason, it uses the Oven interface IOven.

// Create a dynamic property that can resolve its value during runtime
// 1. Create a supplier function that can determine the oven temperature using the sensor
Supplier<Object> lambdaReadFunction = () -> oven.getSensor().readValue();
 
// 2. Create a new empty Property
Property dynamicTemperatureProperty = new Property();
 
// 3. Set the id of the new Property
dynamicTemperatureProperty.setIdShort("temperature");
 
// 4. Use the AASLambdaPropertyHelper to add the Getter to the new Property
// NOTE: A setter function is not required (=> null), because a sensor temperature is "read only"
AASLambdaPropertyHelper.setLambdaValue(dynamicTemperatureProperty, lambdaReadFunction, null)
 
// 5. Add that lambda property to the model
ovenSubmodel.addSubmodelElement(dynamicTemperatureProperty);


The temperature is read through a call to the readValue() call of the sensor (obtained via getSensor()). Besides of properties, the Submodel also may export operations.

The Submodel will define two functions: An activate and an deactivate function. Both functions are created as lambda function objects and are placed in the operations map.

// Add a function that activates the oven and implements a functional interface
Function<Object, Object> activateFunction = (args) -> {
	oven.getHeater().activate();
	return null;
};
 
// Encapsulate the function in an operation
Operation activateOperation = new Operation(activateFunction);
 
// Set the id of the operation
activateOperation.setIdShort("activateOven");
 
// Add an operation that activates the oven and implements a functional interface
ovenSubmodel.addSubmodelElement(activateOperation);
 
 
// Add a function that deactivates the oven and implements a functional interface
Function<Object, Object> deactivateFunction = (args) -> {
	oven.getHeater().deactivate();
	return null;
};
 
// Encapsulate the function in an operation
Operation deactivateOperation = new Operation(deactivateFunction);
 
// Set the id of the operation
activateOperation.setIdShort("deactivateOven");
 
// Add an operation that deactivates the oven and implements a functional interface
ovenSubmodel.addSubmodelElement(deactivateOperation);


Putting everything together

The complete code is provided below:


	public static Submodel createMyOvenModel(Oven oven) {
		// Create an empty Submodel
		Submodel ovenSubmodel = new Submodel();
 
		// Set its idShort
		ovenSubmodel.setIdShort("Oven");
 
		// Set its unique identification
		ovenSubmodel.setIdentification(new ModelUrn("heater1"));
 
		// Now we want to create a dynamic property that can resolve its value during runtime
		// 1. Create a supplier function that can determine the oven temperature using the sensor
		Supplier<Object> lambdaReadFunction = () -> oven.getSensor().readValue();
		// 2. Create a new empty Property
		Property dynamicTemperatureProperty = new Property();
		// 3. Set the id of the new Property
		dynamicTemperatureProperty.setIdShort("temperature");
		// 4. Use the AASLambdaPropertyHelper to add the Getter to the new Property
		// NOTE: A setter function is not required (=> null), because a sensor temperature is "read only"
		AASLambdaPropertyHelper.setLambdaValue(dynamicTemperatureProperty, lambdaReadFunction, null)
		// 5. Add that lambda property to the model
		ovenSubmodel.addSubmodelElement(dynamicTemperatureProperty);
 
		// Add a function that activates the oven and implements a functional interface
		Function<Object, Object> activateFunction = (args) -> {
			oven.getHeater().activate();
			return null;
		};
		// Encapsulate the function in an operation
		Operation activateOperation = new Operation(activateFunction);
		// Set the id of the operation
		activateOperation.setIdShort("activateOven");
		// Add an operation that activates the oven and implements a functional interface
		ovenSubmodel.addSubmodelElement(activateOperation);
 
 
		// Add a function that deactivates the oven and implements a functional interface
		Function<Object, Object> deactivateFunction = (args) -> {
			oven.getHeater().deactivate();
			return null;
		};
		// Encapsulate the function in an operation
		Operation deactivateOperation = new Operation(deactivateFunction);
		// Set the id of the operation
		activateOperation.setIdShort("deactivateOven");
		// Add an operation that deactivates the oven and implements a functional interface
		ovenSubmodel.addSubmodelElement(deactivateOperation);
 
		// Return the Submodel
		return ovenSubmodel;
	}


Testing the Submodel

It always makes sense to create regression tests that ensure that changes to not have unwanted side effects. Therefore, a Submodel can be tested without an extensive BaSyx deployment. The first step when testing a Submodel is to warp it into a VABLambaProvider that enables access to this Submodel. The code below first creates the Submodel under test and then wraps it into a provider. The model connects to a simulated oven instance using the Oven stub.

// Create a model for an oven device.
Submodel myOvenModel = createMyOvenModel(new Oven());


Now, the model can be used to read/write values, and to execute lambda functions that e.g. preprocess data or access a simulation model during testing.

// Get the Identification of the Submodel
String id = myOvenModel.getIdentification().getId();
System.out.println("Heater id: " + id);
 
// The operations can be invoked via the model provider like this:
IOperation activateOperation = myOvenModel.getOperations().get("activateOven");
activateOperation.invoke();


Conclusion

This second step did illustrate the creation of a Submodel for the oven. This is not yet a complete Asset Administration Shell but a specific domain model that describes the specific properties and services of the oven. The Submodel defines an interface that may be for all ovens that can be activated and deactivated, and that provide the current temperature. More complex systems will define multiple Submodels for their assets, and keep every Submodel focused on a specific aspect. Depending on the type of the asset, many Submodel types are possible, e.g. the nameplate, spare parts and their availability, sensor data, asset health, or offered services.

Back to the top