Build Your First Digital Twin Model
In this tutorial, you’ll learn how to build a very simple digital twin model.
First, decide whether you’d like to build your model with C#, Java, or low-code Business Rules. Then follow the instructions below for your preferred language.
Note
If you would like to skip this step and deploy the model immediately, you can download the finished files from here. Then you can jump directly to the Deploy Your Model section.
Install Digital Twin Templates
Install Templates
Run the following command to install Digital Twin project templates. This will enable you to access Digital Twin templates through Visual Studio.
dotnet new install Scaleout.DigitalTwin.Templates
You can confirm that the templates were installed correctly by running:
dotnet new dt-sln --help
Create a Solution
Next, run the following command to create a new solution.
dotnet new dt-sln -n MyFirstModel
Add Real-Time Project
Option 1: Visual Studio
Open the Solution in Visual Studio. It should already contain a Messages project.
Choose File > New > Project… or press Ctrl+Shift+N to add a new project.
Select the ScaleOut Real-Time Model template.
Name the project MyRealTimeTwin (or another name of your choosing) and make sure Solution is set to Add to Solution. Then click Create.
Option 2: Command Line
If you are using Linux (or you would rather use the command line to create your project), run the following commands from the folder that contains your sln file:
dotnet new dt-rt -n MyRealTimeTwin
dotnet sln add MyRealTimeTwin
The ScaleOut Digital Twin Maven Archetypes generate a Java project tailored for real-time digital twin applications — ready to deploy to the ScaleOut Digital Twins™ service or an on-premises deployment.
Make sure the following tools are installed:
Java JDK 8 or later
Use the Maven Archetype Plugin to generate the quickstart project:
mvn archetype:generate \
-DarchetypeGroupId=com.scaleoutsoftware.archetypes \
-DarchetypeArtifactId=scaleout-realtime-digitaltwin \
-DarchetypeVersion=1.0.6 \
-DgroupId=com.mycompany.digitaltwin \
-DartifactId=java-digitaltwin-quickstart \
-Dpackage=com.digitaltwin.example \
-DmodelName=MyRealTimeTwinModel \
-DmessageName=MyRealTimeTwinMessage \
-DmessageProcessorName=MyRealTimeTwinMessageProcessor \
-DinteractiveMode=false
What these options do:
Property |
Description |
---|---|
|
Your organization or namespace |
|
Name of the generated project directory |
|
The class representing the digital twin |
|
The class message that is sent to the message processor |
|
The class that handles messsage processing logic |
This will create a new project folder named java-digitaltwin-quickstart
with the following classes located in the src/main/java/
directory’s com.digitaltwin.example
package:
MyRealTimeTwinModel.java
MyRealTimeTwinMessage.java
MyRealTimeTwinMessageProcessor.java
pom.xml
We’ll finish implementing these classes in the following steps.
Implement the Model
Digital Twin Model
A digital twin model is a template that represents a group of real-world entities, like IoT devices or vehicles. Each digital twin instance corresponds to a specific entity and uses the data structure defined in the model.
A model can contain real-time data, static values, and computed values that are derived when it receives new data. In this basic example, our model only contains a single string property.
Open the file MyRealTimeTwinModel.cs. The class “MyRealTimeTwinModel” has been generated for you. Add the following property inside the class:
public class MyRealTimeTwinModel : DigitalTwinBase
{
public string currentValue { get; set; }
}
From your IDE of choice (IntelliJ, Eclipse, or VS Code) open the file MyRealTimeTwinModel.java and add the following String property, getter, and setter:
package com.digitaltwin.example;
import com.scaleoutsoftware.digitaltwin.core.DigitalTwinBase;
public class MyRealTimeTwinModel extends DigitalTwinBase {
public String _currentValue;
public String getCurrentValue() {
return _currentValue;
}
public void setCurrentValue(String value) {
_currentValue = value;
}
}
Open the ScaleOut Model Development Tool program. Click “New Model…” when prompted.
On the left sidebar, select Model Name. Name your model “MyRealTimeTwin” and click Update.
Under Model Definition > Instance Properties, click + Add New Property. Give the property the following values:
Name: currentValue
Type: String
Leave the “Initial Value” field blank. Click Add to Model to add the property.
Messages
A message is an object that holds data sent from a device to its corresponding digital twin instance. If you’re running a simulation, messages can also be sent by simulated devices. In this step, we define the structure of the message object. For this simple example, it only has one string property.
Find the file called ExampleMessage.cs in the Messages project. Rename it MyRealTimeTwinMessage.cs (or another name of your choosing). If prompted to perform a rename, select “Yes”.
The MyRealTimeTwinMessage class should contain a single string property: “MyProperty”. Rename this property to StringPayload.
From your IDE of choice (IntelliJ, Eclipse, or VS Code) open the file MyRealTimeTwinMessage.java and add the following String property, constructor, and getter.
package com.digitaltwin.example;
public class MyRealTimeTwinMessage {
private String _stringPayload;
public MyRealTimeTwinMessage(String stringPayload) {
_stringPayload = stringPayload;
}
public String getStringPayload() {
return _stringPayload;
}
}
Under Incoming Messages > Message Properties, click + Add New Property. Give the property the following values:
Name: StringPayload
Type: String
Click Add to Model to add the property.
Message Processor
When the digital twin system receives new messages from devices, it needs to process those messages and update the corresponding instances. We implement the message processing code in the Message Processor class. The Message Processor can simply update the instance properties with the new values from the message, or it can run more complex logic like computing a moving average or deciding whether to raise an alert.
For this example, we simply update the digital twin instance’s currentValue property to be the value of the StringPayload from the incoming message. We also log a notification with the instance ID and the contents of the message.
Open the file MyRealTimeTwinMessageProcessor.cs.
Replace the commented-out code in the foreach
loop with the following:
switch (message)
{
case MyRealTimeTwinMessage exampleMessage:
// Update the digital twin's current value
digitalTwin.currentValue = exampleMessage.StringPayload;
// Log an informational message
context.LogMessage(
LogSeverity.Informational,
$"The real-time digital twin '{digitalTwin.Id}' says '{digitalTwin.currentValue}'"
);
break;
default:
throw new NotImplementedException($"Message processor does not support message type {message.GetType()}");
}
From your IDE of choice (IntelliJ, Eclipse, or VS Code) open the file MyRealTimeTwinMessageProcessor.java and replace the processMessages
method with the following snippet that logs the twins currentValue
to the ScaleOut DigitalTwin streaming service:
@Override
public ProcessingResult processMessages(ProcessingContext processingContext, MyRealTimeTwinModel twin, Iterable<MyRealTimeTwinMessage> messages) throws Exception {
// apply the updates from the messages
for (MyRealTimeTwinMessage message : messages) {
twin.setCurrentValue(message.getStringPayload());
processingContext.logMessage(Level.INFO, "The real-time digital twin '" + twin.Id + "' says '" + twin.getStringPayload() + "'");
}
return ProcessingResult.UpdateDigitalTwin;
}
We’ll test these changes on the workbench in the next section.
We’ll be adding two message processing rules: one to update the digital twin instance, and the other to log a notification.
Under Message Rules, click + Add New Message Rule.
For the first rule, name it “UpdateValue”. In the Text field, add the following rule:
DO currentValue = Incoming.StringPayload
Check the Hints field to confirm the rule is valid. Then click Add to Model.
Repeat the process for the second rule. Name it “LogMessage”. For the text, add the rule:
DO LOG_MESSAGE(0, "The real-time digital twin '" + Id + "' says '" + Incoming.StringPayload + "'")
Click Add to Model. You should see the two rules, UpdateValue and LogMessage, listed under Message Rules.
In the next step, you’ll learn how to test a digital twin model before deployment.