Closed GMGassner closed 3 weeks ago
Hi! Thanks for the suggestion! From my (admittedly superficial) knowledge of Azure Digital Twins and DTDL, the scope of what you're proposing can vary dramatically depending on the specifics.
From what I understand about ADT, you're describing the entire model through the DTDL (i.e., the environment, rules and relationships, actions, etc). From a high-level perspective, this is similar to what you're doing when defining a model through AL and the "languages" it provides (i.e., flowcharts, statecharts, Java code, etc.).
If your proposal is to have complete support for converting DTDL to an AL model, this is definitely out of the scope of this project. That would require not only parsing the DTDL but figuring out the AL equivalents and how you can 'map' from one to the other. For example, how to link defined Commands to some code in the user's model.
The other route I can think of is just to use DTDL for the structure of how it defines its objects. Essentially you'd use it as a schema specification for agent types you've already defined in AL, with a customized serializer for converting that structure to the agent type defined in the schema. Customized serializers is already something that's in the works, namely for a way to use JSON with a different structure than what JSONifier expects.
Let me know if I missed anything or what your thoughts are!
Hi, thank you so much for the quick reply! You are right regarding the varying scope of my post so I want to narrow it down and explain my experience. I was looking into Manufacturing Ontologies, which ties together DTDL, W3C WoT and ISA95, as an ontology for my project.
My approach was to look at the unit level of manufacturing equipment and have a description, which is relatively flexible. Using the newest version (v3) of DTDL enables that through components and modularity. This concept would be to have one DTDL per unit and use the key concepts in DTDL for a comprehensive description.
Interface: An interface defines the structure and capabilities of a digital twin. It specifies the properties, telemetry, commands, and relationships that a digital twin can have.
Property: Properties are attributes or state variables of a digital twin. They can be read-only or writable and have a specific data type, such as string, integer, or boolean.
Telemetry: Telemetry represents data emitted by a digital twin, typically time-series data from sensors or measurements. It can include data points like temperature, pressure, or status updates.
Command: Commands are actions that can be invoked on a digital twin. They allow you to trigger specific behaviors or operations on the digital twin, such as starting a process or updating a setting.
Relationship: Relationships define how digital twins are connected to each other. They represent the associations or dependencies between different digital twins, such as a device being part of a larger system.
Schema: Schemas define the data types used in properties, telemetry, and commands. DTDL supports primitive types (e.g., string, integer) as well as complex types like enums, objects, and arrays.
Component: Components allow you to modularize and reuse common definitions across multiple interfaces. They enable you to create reusable building blocks for your digital twin models.
Here's an example of a DTDL v3 model that represents a manufacturing machine:
{
"@id": "dtmi:com:example:ManufacturingMachine;3",
"@type": "Interface",
"@context": "dtmi:dtdl:context;3",
"displayName": "Manufacturing Machine",
"contents": [
{
"@type": "Property",
"name": "machineId",
"schema": "string",
"writable": false
},
{
"@type": "Property",
"name": "machineType",
"schema": "string",
"writable": false
},
{
"@type": "Property",
"name": "status",
"schema": {
"@type": "Enum",
"valueSchema": "string",
"enumValues": [
{
"name": "Idle",
"enumValue": "idle"
},
{
"name": "Running",
"enumValue": "running"
},
{
"name": "Maintenance",
"enumValue": "maintenance"
}
]
},
"writable": true
},
{
"@type": "Telemetry",
"name": "temperature",
"schema": "double"
},
{
"@type": "Telemetry",
"name": "vibration",
"schema": "double"
},
{
"@type": "Property",
"name": "productionRate",
"schema": "integer",
"unit": "units/hour",
"writable": false
},
{
"@type": "Relationship",
"name": "hasOutputProducts",
"target": "dtmi:com:example:Product;1"
},
{
"@type": "Command",
"name": "startProduction",
"request": {
"name": "productionSettings",
"schema": {
"@type": "Object",
"fields": [
{
"name": "productType",
"schema": "string"
},
{
"name": "quantity",
"schema": "integer"
}
]
}
}
}
]
}
In this example:
The @id
property identifies the model as a manufacturing machine with version 3.
The displayName
property provides a human-readable name for the machine.
The contents
property defines the properties, telemetry, relationships, and commands of the machine:
Property elements represent the machine's attributes, such as machineId, machineType, status (an enum property), and productionRate.
Telemetry elements define the data points emitted by the machine, such as temperature and vibration.
The Relationship element hasOutputProducts
indicates that the machine produces products, referencing the Product model.
The Command element startProduction
defines an action to start the production process, accepting productionSettings
as a request parameter with productType
and quantity fields.
So in essence use DTDL to instantiate agents like with the JSONifer, just in a richer format that also enables other use cases. A customized serializer for converting that structure to the agent is essentially what it boils down to.
I would love to help and am happy to hear that something is in the works to enable that. How can i help?
Thanks for the extremely detailed explanation, including the example that tied all the mentioned concepts together.
So in essence use DTDL to instantiate agents like with the JSONifer
The part I'm missing though is that the DTDL example you provided is in an interface, not an instance. What you're describing seems to be like a conversion from a DTDL model to an AnyLogic agent type definition. In other words, the library would create agent types themselves dynamically (in traditional Java terms, auto-generated classes). To do this currently would require reverse engineering the XML which makes up the source of an AnyLogic model (which has no guarantee to remain consistent) and is way more complex than what the Jsonifier does.
The only equivalent to the Jsonifier would be if you wanted to take a DTDL instance and import it to the sim to be converted to a pre-defined agent type, with parameters that would map to everything that could be provided by the DTDL instance. The property and telemetry would likely map nicely to parameters, though there's no way to make parameters read-only. You can define enums in the AnyLogic model; they'd just need to be predefined and match up with the naming from the DTDL model. Relationships are trickier because the library would need logic to figure out a way to map whatever value is in the relationship fields to what's in the AnyLogic model (again, pre-defined).
I'm curious to know which route you were thinking about going in! Knowing that will definitely help clarify the feasibility of this.
Thanks for taking the time and effort to my request! Sry for the delayed response, I could not find time up until now. I completely agree with you,
create agent types themselves dynamically (in traditional Java terms, auto-generated classes)
is way beyond and not part of my request.
My train of thought was rather simple. From what I gathered a DTDL Interface describes a DT with its components. If I have a DTDL file of every unit I want to have a DT for (like a machine in manufacturing) the sum of DTDL files describe my manufacturing process in a way to be able to have digital twins of every unit and of the whole process. If I wanted to have a simulation that is used for manufacturing optimization, everything that is needed for this to work should be already in the DTDL files (parameters, specification, states, etc.). So my idea was, why not use this detailed description of units and processes to instantiate agents in a simulation. So basically use DTDL not only for connecting machines to their DT, but also to instantiate agents in a simulation model that generates data needed to drive the DT. Of course this has limitation and agent types would have to be compatible in their composition to be instantiated with the files.
In a more structured way: DTDL Interface. "Interface describes the contents (Commands, Components, Properties, Relationships, and Telemetries) of any digital twin. Interfaces are reusable and can be reused as the schema for Components in another Interface."
DTDL Interface:
AnyLogic Agent:
The similarity lies in how both DTDL interfaces and AnyLogic agent types serve as templates for creating instances.
An inspiration was this paper on how DTDL and OPC UA could map to each other Proposal of Mapping Digital Twins Definition Language to Open Platform Communications Unified Architecture
Maybe I'm barking up the wrong tree, but I thought I'll share this with you to see whether it has some merit to it.
Again, thank you for such a thorough explanation! I'm starting to see where my previous disconnect was, which I'll speak to first.
The Jsonifier implementation takes advantage of the API shared across all agents, notably the parameter functions (getParameter(name)
, setParameter(name, value)
, etc.) which are the main source of initialization targets; most other sources are assumed to be assigned as part of the dynamic logic.
What it seems like you're proposing is an extension of this, also initializing variable values, nested agents/populations, other attributes (e.g., position, speed), connections, schedule events, etc. This is feasible through a much more robust specification (the Jsonifier's intention is to be as simple/inutive as possible).
The more complicated aspect is that the way people define these in their model can vary. For example, sometimes a relationship is defined via a 'Link to agents' and other times with typed variables. This could be theoretically resolved through documentation though.
Where I'm still lost though is the practical, actual nuts and bolts of the implementation and workflow.
If I wanted to have a simulation that is used for manufacturing optimization, everything that is needed for this to work should be already in the DTDL files (parameters, specification, states, etc.).
But this is backwards, is it not? The simulation is essentially a replacement for the real-world equivalent + IoT devices.
To clarify with an example, say I'm wanting to monitor/control my house's temperature/its thermostat. My (limited) understanding is that the Azure DT workflow looks like this:
In diagram form:
DTDL ----(uploaded to)----v
AZURE
Thermostat <--> IOT <--> DIGITAL TWIN <--> Me (remotely)
^________House_________^
With a simulation model, I'm not just defining the house but also recreating the physics of temperature propagation (or recreating the effects of it) and all the dynamics of the real world system (e.g., simulating how I respond and the points in which I override the set temperature). It also serves as where experimentation/data gathering happens via running experiments. In this way, it's like a replacement for the thermostat + IoT + Azure Digital Twin platform. You could actually create a DTDL model from a simulation model; whereas, the the other way around - uploading a DTDL model to a sim - is like trying to pass it to the IoT devices.
The other (maybe obvious) thing to note is that, unlike Azure DT, syncing to the real, live system only happens at once on startup. After this point, it's assumed it has all the rules and relationships of the system baked into it so that it can accurately play out one possible future trajectory of the environment.
I imagine the true intention is to rather take whatever is outputted by the IoT device, specifically in whatever data format the Azure DT expects as input (maybe this is still referred to as being in DTDL? I couldn't find many resources on actual integration with real systems) and have some library that can parse that and apply it to the sim(?)
Also, I did read through the paper you sent (I wasn't previously aware of OPC UA, so thank you!).
From what I gather, in terms of their relationship to a simulation model, the real-time data from both OPC UA-enabled devices or digital twins defined using DTDL could be used to feed into the sim as input on its startup; this would be in whatever data format/structure is outputted by each (or by the underlying IoT device, if you wanted to go that route too).
Thanks for thoroughly reading my post and your great answer.
But this is backwards, is it not? The simulation is essentially a replacement for the real-world equivalent + IoT devices.
the real-time data from both OPC UA-enabled devices or digital twins defined using DTDL could be used to feed into the sim as input on its startup
You have grasped my theory very well, but I want to discuss the practical nuts and bolts of implementation and workflow. I hope to build on your example and give you a perspective that illustrates my use case since it aims at a different goal than Azure.
I hypothesize that a digital twin defined in DTDL (or similar) & some initial data should also contain everything needed to be useable as an agent in a simulation. There will be practical limits to the implementation in AnyLogic, but I chose to go down this rabbit hole and explore these.
Based on your example: I want to monitor/control my house's temperature/its thermostat and use a simulation to check different configurations of environment, equipment, and usages.
In mermaid diagram form:
graph LR
subgraph "DTDL Definition"
A["Define House in DTDL"]
A --> C(Rooms)
A --> D(AirCon)
A --> E(Radiators)
A --> F(Heat Sources)
A --> G(Cooling Sources)
end
subgraph "Agent Instantiation"
H["Instantiate Agents from DTDL"] --> I(AirCon Agents)
H --> J(Radiator Agents)
H --> K(Heat Source Agents)
H --> L(Cooling Source Agents)
end
subgraph "Real-World Data"
M["Get Real-World Data (IoT)"] --> N(Initial Room Temperatures)
M --> O(HVAC Settings)
M --> B(Thermostat)
end
subgraph "AnyLogic Simulation"
P["Run Simulation"] --> Q(Room Temperature Changes)
P --> R(Energy Consumption)
end
subgraph "Analysis & Decision"
S["Analyze Results"]
end
B --> P
C --> H
D --> H
E --> H
F --> H
G --> H
I --> P
J --> P
K --> P
L --> P
N --> P
O --> P
Q --> S
R --> S
I want to be able to use a file that is intended for digital twins to recreate similar digital twins in an AL model to simulate their behavior and track their metrics. How data finds its way into the sim is my next obstacle, but getting agents configured based on DTDL into a sim would be a first step. Thanks for taking the time to understand my question and I hope I was able to convey the rough idea.
You absolutely conveyed the rough idea, so thank you for that! The only bit I'm missing in terms of the feasibility of this is the actual nuts and bolts of the implementation.
Inline with the current example, I created this DTDL definition.
Because you said you were not trying to auto-generate the model itself, just instantiate it, I needed to build the AnyLogic model, pretending there was some pre-established rules about how the DTDL concepts map to the AnyLogic model, shown in the screenshot below. For this example, writable properties = variables; non-writable properties = parameters; interace = agent type; array of an interface = agent population.
And now comes the point where the AnyLogic library (i.e., JSONifier or a new one) would come into play. Based on my understanding, the spec doc shows all example implementations using normal JSON. Thus, me/the user would provide a JSON file like this one. Is my understanding correct here?
Thank you for your immediate reaction and efforts! From what i can see, you model looks similar to what I would have envisioned given the example we used. If you built the model to this extent, a simple JSON is enough to convey the agents properties into the sim. This is kinda similar to:
Property example(analog to the Telemetry example) This is the semantic information about the sensor in DTDL you modeled. A simple Telemetry definition of a temperature measurement, with the data type double.
{
"@type": "Property",
"name": "currentTemperature",
"schema": "double",
"displayName": "Current Temperature"
},
When JSON is used to serialize Property data for e.g. initial conditions.
"currentTemperature": 42.5
Based on my understanding, the spec doc shows all example implementations using normal JSON. Thus, me/the user would provide a JSON file like this one. Is my understanding correct here?
In your "house" model, the semantics of the DTDL have already been built into the model, with the JSON als properties.
In my idea, a simulation user would have to built a model but their semantic connections, states in a state chart, etc. would be brought in by provide a DTDL file, JSON-LD, to the appropriate agents, like your ihvac.json
Additionally, a "normal" JSON (or database connection), like yours, is used to fill in information for setting the properties within the agent. Like your mymodel.json
If I had correctly interpreted "the practical, actual nuts and bolts of the implementation and workflow." I would have also posted a screenshot of my current implementation, but better late than never.
This is my model for monitoring energy consumption, which is in an early stage and needs improvement.
with this example JSON (with some meaningless double for properties):
{
"stateConsumptionRates": {
"OFF": 0.5,
"IDLE": 5.0,
"WARMUP": 50.0,
"RUNNING": 80.0,
"COOLDOWN": 10.0
},
"stateProductionRates": {
"OFF": 0.5,
"IDLE": 1.0,
"WARMUP": 0.5,
"RUNNING": 3.0,
"COOLDOWN": 1.0
},
"stateTimes": {
"OFF": 0.5,
"IDLE": 1.0,
"WARMUP": 0.5,
"RUNNING": 3.0,
"COOLDOWN": 1.0
},
"stateInitialProperties": {
"intialState": 1.0,
"targetTemperature": 1.0,
"intialLevel": 1.0
},
"unitProperties": {
"capacity": 1.0,
"efficiency": 1.0,
"transferRate": 600.0
},
"unitSpecification": {
"Type": "Conveyor",
"manufacturer": "Custom",
"model": "BeltConveyor"
}
}
It currently works ok with my custom JSON (above), like your DTDL: "Basic House HVAC (Implementation). Instantiating agents into a population works on a basic level with:
Equipment equipment = jsonifier.fromAgentJson(jsonFilePath, Equipment.class, targetPopulation);
However, the semantics of these agents to communicate and get processes working to have these agents act as interconnected units, like in manufacturing, is missing. In my understanding, this gap could be filled with DTDL for instantiation.
From what I read, the format JSON-LD is designed around the concept of a "context" to provide additional mappings from JSON to an RDF model. The context links object properties in a JSON document to concepts in an ontology. And this property is being used in DTDL v3 and can bring together semantics and parameters in a nice way.
When first encountering this property, I immediately thought of using this concept for simulation. I wanted to explore the possibility of using JSON-LD to not only "parse" properties but also semantic information like relationships and connections.
In my thought process, directly parsing DTDL could open up the possibility of a simpler base model with the necessary semantic information being implementable/instantiable from the "keywords" (lines with a @
).
{
"@id": "dtmi:com:example:ManufacturingMachine;3",
"@type": "Interface",
"@context": "dtmi:dtdl:context;3",
"displayName": "Manufacturing Machine",
"contents": [
{
"@type": "Property",
"name": "machineId",
"schema": "string",
"writable": false
},
{
"@type": "Property",
"name": "machineType",
"schema": "string",
"writable": false
},
{
"@type": "Property",
"name": "status",
"schema": {
"@type": "Enum",
"valueSchema": "string",
"enumValues": [
{
"name": "Idle",
"enumValue": "idle"
},
{
"name": "Running",
"enumValue": "running"
},
{
"name": "Maintenance",
"enumValue": "maintenance"
}
]
},
"writable": true
},
{
"@type": "Telemetry",
"name": "temperature",
"schema": "double"
},
{
"@type": "Telemetry",
"name": "vibration",
"schema": "double"
},
{
"@type": "Property",
"name": "productionRate",
"schema": "integer",
"unit": "units/hour",
"writable": false
},
{
"@type": "Relationship",
"name": "hasOutputProducts",
"target": "dtmi:com:example:Product;1"
},
{
"@type": "Command",
"name": "startProduction",
"request": {
"name": "productionSettings",
"schema": {
"@type": "Object",
"fields": [
{
"name": "productType",
"schema": "string"
},
{
"name": "quantity",
"schema": "integer"
}
]
}
}
}
]
}
non-writeable "Property" would be parameters writable "Property" would be variables "Property" of type ENUM would be a state chart "Telemetry" would be an output "Relationship" would be a connection to another agent "Command" would be an event or function
So, if my example could work like envisioned, you would model four agent types (Storage, Converter, Consumer, and Recoverer) with all the necessary bells and whistles for any units they are designed to instantiate. DTDL would do the specific setup for each agent.
Relatively "simple" model + DTDL => "digital twins" in model + JSON => initial condition for simulating "digital twins".
Your DTDL v2 files are quite close to what I tried to show with my DTDL v3, the key differences between DTDL v2 and DTDL v3
Fun fact, this also extends to the Web of Things (WoT) Thing Description , which is currently being merged with DTDL v3 to a universal standard for digital twins. A nice comparison between the two can be found here.
Sorry that it took so many interactions to convey this concept and idea, but I hope that I haven't missed something, and I'm curious what your thoughts are.
This is my model for monitoring energy consumption, which is in an early stage and needs improvement.
As you point out, this part of the concept is there and I've completely understood the significance of what you're doing here.
However, the semantics of these agents to communicate and get processes working to have these agents act as interconnected units, like in manufacturing, is missing. In my understanding, this gap could be filled with DTDL for instantiation.
This is where it becomes ambiguous again. What you're describing here would require users to already have the such logic/framework set up in their model. The DTDL you provide shows the definition, but not an implementation; to be able to pass the definition would require such a library to modify the actual AnyLogic model.
If it's believed I missing something, I'd be open to hearing what you think the actual logic of the library would look like (as in, pseudo code) - because providing that would really sync our understandings. Unfortunately my time at AnyLogic has come to an end. I'll be forking the repo after transferring it if you want to continue there and if I have personal time, I may look into exploring this further :) Otherwise, thanks for the great educational experience!
Dear Tyler, I am currently using AL in my research and have recently explored the possibility of utilizing Digital Twins Definition Language v3 for the instantiation of some agents in AL 8.9. In addition to my research, I have observed that several major companies, such as Microsoft and Siemens, are increasingly adopting DTDL for digital twins.
Given that DTDL is JSON-LD based, I believe there is potential to advance support in this direction. Perhaps a separate "DTDLifier" could be developed to facilitate this integration.
I am very interested in contributing to this development if you decide to support DTDL. Please let me know if there is any chance to advance support for DTDL in AL 8.9.
Thank you in advance for considering this request. I look forward to your response.