From 325264c9cbfb62f774e28e6e449c7193e50f0192 Mon Sep 17 00:00:00 2001 From: piconem Date: Thu, 5 Sep 2024 13:03:41 +0000 Subject: [PATCH] deploy: 048a15b762a6acf542e0f0612c0a4f0c63855306 --- blog/index.html | 4 +- blog/index.xml | 2 +- blog/sitemap.xml | 2 +- .../index.html | 4 +- blog/wldt-library-version-0.4.0/index.html | 7 + docs/adapters/http-digital-adapter/index.html | 82 ++++++-- docs/adapters/index.html | 6 +- docs/adapters/mqtt-digital-adapter/index.html | 16 +- .../adapters/mqtt-physical-adapter/index.html | 16 +- docs/adapters/sitemap.xml | 2 +- docs/change-logs/change-log-0.3.0/index.html | 14 +- docs/change-logs/change-log-0.4.0/index.html | 140 ++++++++++++++ docs/change-logs/index.html | 8 +- docs/change-logs/index.xml | 2 +- docs/change-logs/sitemap.xml | 2 +- docs/guides/configurable-adapters/index.html | 14 +- docs/guides/digital-actions/index.html | 14 +- docs/guides/digital-adapter/index.html | 14 +- docs/guides/dt-engine-dt-instance/index.html | 14 +- docs/guides/dt-relationships/index.html | 182 ++++++++++++++++++ docs/guides/index.html | 8 +- docs/guides/index.xml | 2 +- docs/guides/physical-adapter/index.html | 14 +- docs/guides/shadowing-function/index.html | 14 +- docs/guides/sitemap.xml | 2 +- docs/guides/storage-layer/index.html | 130 +++++++++++++ docs/index.html | 8 +- docs/introduction/dt-events/index.html | 17 ++ docs/introduction/dt-life-cycle/index.html | 14 +- docs/introduction/dt-model/index.html | 14 +- docs/introduction/index.html | 8 +- docs/introduction/index.xml | 2 +- .../index.html | 16 +- docs/introduction/sitemap.xml | 2 +- docs/sitemap.xml | 2 +- en/sitemap.xml | 2 +- ...ad9a910f_2490323_1024x0_resize_q75_box.jpg | Bin 0 -> 89913 bytes ...910f_2490323_1024x0_resize_q75_h2_box.webp | Bin 0 -> 46812 bytes ...ad9a910f_2490323_1366x0_resize_q75_box.jpg | Bin 0 -> 138430 bytes ...910f_2490323_1366x0_resize_q75_h2_box.webp | Bin 0 -> 68658 bytes ...cad9a910f_2490323_480x0_resize_q75_box.jpg | Bin 0 -> 27514 bytes ...a910f_2490323_480x0_resize_q75_h2_box.webp | Bin 0 -> 16444 bytes ...cad9a910f_2490323_640x0_resize_q75_box.jpg | Bin 0 -> 44581 bytes ...a910f_2490323_640x0_resize_q75_h2_box.webp | Bin 0 -> 25266 bytes ...cad9a910f_2490323_768x0_resize_q75_box.jpg | Bin 0 -> 59529 bytes ...a910f_2490323_768x0_resize_q75_h2_box.webp | Bin 0 -> 32190 bytes index.xml | 3 +- privacy/index.html | 2 +- search-index.json | 2 +- sitemap.xml | 2 +- 50 files changed, 672 insertions(+), 137 deletions(-) rename blog/{ls-wldt-library-version-0.3.0 => wldt-library-version-0.3.0}/index.html (68%) create mode 100644 blog/wldt-library-version-0.4.0/index.html create mode 100644 docs/change-logs/change-log-0.4.0/index.html create mode 100644 docs/guides/dt-relationships/index.html create mode 100644 docs/guides/storage-layer/index.html create mode 100644 docs/introduction/dt-events/index.html create mode 100644 images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_1024x0_resize_q75_box.jpg create mode 100644 images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_1024x0_resize_q75_h2_box.webp create mode 100644 images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_1366x0_resize_q75_box.jpg create mode 100644 images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_1366x0_resize_q75_h2_box.webp create mode 100644 images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_480x0_resize_q75_box.jpg create mode 100644 images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_480x0_resize_q75_h2_box.webp create mode 100644 images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_640x0_resize_q75_box.jpg create mode 100644 images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_640x0_resize_q75_h2_box.webp create mode 100644 images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_768x0_resize_q75_box.jpg create mode 100644 images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_768x0_resize_q75_h2_box.webp diff --git a/blog/index.html b/blog/index.html index c383680..c68d672 100644 --- a/blog/index.html +++ b/blog/index.html @@ -1,7 +1,7 @@ -Blog | WLDT

Blog

\ No newline at end of file diff --git a/blog/index.xml b/blog/index.xml index 9b8595b..d7e3a0b 100644 --- a/blog/index.xml +++ b/blog/index.xml @@ -1 +1 @@ -Blog on WLDThttps://wldt.github.io/blog/Recent content in Blog on WLDTHugo -- gohugo.ioenCopyright (c) 2023 HyasThu, 07 Sep 2023 16:21:44 +0200ls WLDT Library Version 0.3.0https://wldt.github.io/blog/ls-wldt-library-version-0.3.0/Wed, 13 Mar 2024 16:27:22 +0200https://wldt.github.io/blog/ls-wldt-library-version-0.3.0/📣 We’re thrilled to announce the release of version 0.3.0 of the White Label Digital Twins (WLDT) library! This release brings significant enhancements, improvements, and new features to further empower developers in designing, developing, and deploying Digital Twins within Internet of Things (IoT) ecosystems. \ No newline at end of file +Blog on WLDThttps://wldt.github.io/blog/Recent content in Blog on WLDTHugo -- gohugo.ioenCopyright (c) 2023 HyasThu, 07 Sep 2023 16:21:44 +0200WLDT Library Version 0.4.0https://wldt.github.io/blog/wldt-library-version-0.4.0/Thu, 29 Aug 2024 17:40:54 +0200https://wldt.github.io/blog/wldt-library-version-0.4.0/We’re excited to announce the release of WLDT version 0.4.0! This update brings powerful new features to enhance your Digital Twin (DT) experience, including event observation capabilities, a robust storage layer, and a flexible query system.WLDT Library Version 0.3.0https://wldt.github.io/blog/wldt-library-version-0.3.0/Wed, 13 Mar 2024 16:27:22 +0200https://wldt.github.io/blog/wldt-library-version-0.3.0/📣 We’re thrilled to announce the release of version 0.3.0 of the White Label Digital Twins (WLDT) library! This release brings significant enhancements, improvements, and new features to further empower developers in designing, developing, and deploying Digital Twins within Internet of Things (IoT) ecosystems. \ No newline at end of file diff --git a/blog/sitemap.xml b/blog/sitemap.xml index fc8204e..23dceb9 100644 --- a/blog/sitemap.xml +++ b/blog/sitemap.xml @@ -1 +1 @@ -https://wldt.github.io/blog/ls-wldt-library-version-0.3.0/2024-03-15T10:45:36+01:00monthly0.5 \ No newline at end of file +https://wldt.github.io/blog/wldt-library-version-0.4.0/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/blog/wldt-library-version-0.3.0/2024-09-05T15:02:33+02:00monthly0.5 \ No newline at end of file diff --git a/blog/ls-wldt-library-version-0.3.0/index.html b/blog/wldt-library-version-0.3.0/index.html similarity index 68% rename from blog/ls-wldt-library-version-0.3.0/index.html rename to blog/wldt-library-version-0.3.0/index.html index 125cbca..0f4804e 100644 --- a/blog/ls-wldt-library-version-0.3.0/index.html +++ b/blog/wldt-library-version-0.3.0/index.html @@ -1,9 +1,9 @@ -ls WLDT Library Version 0.3.0 | WLDT

WLDT Library Version 0.3.0

March 13, 2024 ‐ 3 min read

📣 We’re thrilled to announce the release of version 0.3.0 of the White Label Digital Twins (WLDT) library! This release brings significant enhancements, improvements, and new features to further empower developers in designing, developing, and deploying Digital Twins within Internet of Things (IoT) ecosystems.

For detailed information about these changes and their impact, please refer to the information provided:

Let’s dive into the key changes and updates included in this release:

Migration Digital Adapters

In version 0.3.0, we’ve made several enhancements and adjustments to the Digital Adapter class to improve its functionality and usability. Notable changes include:

  • Discontinued Methods: Several methods have been discontinued and removed from the DigitalAdapter class to streamline its interface and improve clarity. Method Signature Changes: The signatures of certain methods have been updated for consistency and clarity, ensuring a more intuitive developer experience.
  • New Methods: We’ve introduced new methods to provide additional functionality and flexibility for handling state updates and event notifications.

Migration Shadowing Function

We’ve made significant improvements to the ShadowingModelFunction, which is now renamed to ShadowingFunction. Additionally, we’ve introduced changes to how the DigitalTwinState is managed within the Shadowing Function, providing developers with more control and flexibility.

Migrating WLDT Engine & DT Creation

In version 0.3.0, the WldtEngine class has been renamed to DigitalTwin, offering improved clarity and consistency. We’ve also made adjustments to the lifecycle management of Digital Twins, streamlining the process and enhancing usability.

Digital Twin & Digital Twin Engine

We’ve introduced enhancements to the Digital Twin and Digital Twin Engine classes, providing developers with improved functionality and ease of use. Notable updates include:

  • Simplified Digital Twin Creation: Creating and managing Digital Twins is now more intuitive and streamlined.
  • Lifecycle Management: We’ve enhanced the lifecycle management of Digital Twins, making it easier to start, stop, and manage multiple instances.

Digital Twin State Manager

The DigitalTwinStateManager class has been improved to provide better support for managing the state of Digital Twins. With features such as transaction support and event notification, developers can more effectively manage changes to Digital Twin states and respond to events.

To learn more about the capabilities of the DigitalTwinStateManager, please refer to the Digital Twin State Manager section.

Digital Adapter

We’ve extended and improved the Digital Adapter base class to provide enhanced support for handling Digital Twin state updates and event notifications. With the introduction of the onStateUpdate and onEventNotificationReceived methods, developers can more effectively respond to changes in Digital Twin states and events.

Get Started with WLDT 0.3.0

To get started with version 0.3.0 of the WLDT library, simply update your dependencies to include the latest release. Detailed documentation and usage examples are available in the project repository, providing comprehensive guidance on leveraging the new features and enhancements.

We’re excited about the improvements and new capabilities introduced in WLDT 0.3.0, and we can’t wait to see how developers utilize them to create innovative IoT solutions powered by Digital Twins. As always, we welcome your feedback and contributions to help us further improve the library and empower the community.

Happy coding with WLDT 0.3.0! 🚀

\ No newline at end of file diff --git a/blog/wldt-library-version-0.4.0/index.html b/blog/wldt-library-version-0.4.0/index.html new file mode 100644 index 0000000..2dac31a --- /dev/null +++ b/blog/wldt-library-version-0.4.0/index.html @@ -0,0 +1,7 @@ + +WLDT Library Version 0.4.0 | WLDT

WLDT Library Version 0.4.0

August 29, 2024 ‐ 1 min read

We’re excited to announce the release of WLDT version 0.4.0! This update brings powerful new features to enhance your Digital Twin (DT) experience, including event observation capabilities, a robust storage layer, and a flexible query system.

For detailed information about these changes and their impact, please refer to the information provided:

Key Highlights

  • WldtEventObserver: A new class has been introduced, simplifying the observation of specific events generated by Digital Twins and their components
  • Storage Layer: The new storage layer allows DTs to store data related to their state, events, actions, and more. It consists of:
    • Storage Manager: Manage and use various storage systems (e.g., in-memory, file-based, DBMS) simultaneously.
    • WldtStorage: An abstract class to implement custom storage systems. The default in-memory storage is available for development and testing.
    • Query System: The query system enables external components like Digital Adapters to retrieve stored data efficiently, supporting both synchronous and asynchronous queries.

WLDT 0.4.0 significantly enhances the flexibility and capabilities of Digital Twins, making it easier to manage and retrieve data, and observe events. We encourage developers to explore these new features and integrate them into their projects.

Stay tuned for more updates!

+
\ No newline at end of file diff --git a/docs/adapters/http-digital-adapter/index.html b/docs/adapters/http-digital-adapter/index.html index 8371e25..ced853c 100644 --- a/docs/adapters/http-digital-adapter/index.html +++ b/docs/adapters/http-digital-adapter/index.html @@ -2,23 +2,23 @@ HTTP Digital Adapter | WLDT

HTTP Digital Adapter

The HttpDigitalAdapter is a powerful component designed to facilitate the integration of Digital Twins into HTTP-based systems. It serves as a bridge between a Digital Twin and HTTP-based applications, allowing developers to easily expose and interact with -Digital Twin data and functionalities over HTTP.

Key Features:

  • HTTP Integration: Seamlessly integrates Digital Twins into HTTP environments, enabling communication with web applications and services.
  • Dynamic Configuration: Offers a flexible configuration mechanism through the HttpDigitalAdapterConfiguration, allowing developers to customize the adapter’s behavior based on specific requirements.
  • State Monitoring: Monitors changes in the Digital Twin state and provides HTTP endpoints to query the state of the Digital Twin (properties, events, actions and relationships).
  • Event Notifications: Allows developers to retrieve event notifications triggered by changes in the Digital Twin state.

HTTP Digital Adapter

A complete example is provided in the test folder with a complete DT Creation in the TestMain class together with a demo DT with and emulated Physical Adapter and the HTTP Digital Adapter.

WLDT-Core Version Compatibility

The correct mapping and compatibility between versions is reported in the following table

http-digital-adapterwldt-core 0.2.1wldt-core 0.3.0
0.1.1

Installation

To use HttpDigitalAdapter in your Java project, you can include it as a dependency using Maven or Gradle.

Maven

<dependency>
+Digital Twin data and functionalities over HTTP.

Key Features:

  • HTTP Integration: Seamlessly integrates Digital Twins into HTTP environments, enabling communication with web applications and services.
  • Dynamic Configuration: Offers a flexible configuration mechanism through the HttpDigitalAdapterConfiguration, allowing developers to customize the adapter’s behavior based on specific requirements.
  • State Monitoring: Monitors changes in the Digital Twin state and provides HTTP endpoints to query the state of the Digital Twin (properties, events, actions and relationships).
  • Event Notifications: Allows developers to retrieve event notifications triggered by changes in the Digital Twin state.
  • Storage & Query: Since version 0.2 the HTTP Digital Adapter is able to retrieve Storage Statistics and execute query on the target DT

HTTP Digital Adapter

A complete example is provided in the test folder with a complete DT Creation in the TestMain class together with a demo DT with and emulated Physical Adapter and the HTTP Digital Adapter.

WLDT-Core Version Compatibility

The correct mapping and compatibility between versions is reported in the following table

http-digital-adapterwldt-core 0.2.1wldt-core 0.3.0wldt-core 0.4.0
0.1.1
0.2

Installation

To use HttpDigitalAdapter in your Java project, you can include it as a dependency using Maven or Gradle.

Maven

<dependency>
     <groupId>io.github.wldt</groupId>
     <artifactId>http-digital-adapter</artifactId>
-    <version>0.1.1</version>
+    <version>0.2</version>
 </dependency>
-

Gradle

implementation 'io.github.wldt:http-digital-adapter:0.1.1'
+

Gradle

implementation 'io.github.wldt:http-digital-adapter:0.2'
 

Class Structure & Functionalities

HttpDigitalAdapterConfiguration

The HttpDigitalAdapterConfiguration is a crucial part of the HttpDigitalAdapter, providing the necessary settings to tailor the adapter’s behavior to meet specific needs.

Represents the configuration for an HTTP Digital Adapter, specifying the host, port, and filters for properties, actions, events, and relationships.

The filters are used to selectively include or exclude specific properties, actions, @@ -66,6 +66,66 @@ digitalTwinEngine.startAll();

HTTP RESTful API

This section of the documentation provides detailed information about the RESTful API exposed by the WLDT - HTTP Digital Adapter. The API allows you to interact with the Digital Twin (DT) instance, retrieve its state, read properties, actions, event and relationships description, -and trigger actions.

Available endpoints with the associated methods are:

  • GET /instance: Retrieves information about the Digital Twin instance.
  • GET /state: Retrieves the current state of the Digital Twin.
  • GET /state/changes: Retrieves the list of state changes in the Digital Twin.
  • GET /state/previous: Retrieves the previous state of the Digital Twin.
  • GET /state/properties: Retrieves the list of properties in the Digital Twin state.
  • GET /properties/{propertyKey}: Retrieves the value of a specific property (e.g., /properties/color) from the Digital Twin state.
  • GET /state/events: Retrieves the list of events in the Digital Twin state.
  • GET /state/actions: Retrieves the list of actions in the Digital Twin state.
  • POST /state/actions/{actionKey}: Triggers the specified action (e.g., /state/actions/switch_on) in the Digital Twin state. The raw body contains the action request payload.
  • GET /state/relationships: Retrieves the list of relationships in the Digital Twin state.
  • GET /state/relationships/{relationshipName}/instances: Retrieves the instances of the specified relationship (e.g., /state/relationships/insideIn/instances) in the Digital Twin state.

Note: Replace {propertyKey}, {actionKey}, and {relationshipName} with the actual values you want to retrieve or trigger. -Make sure to use the appropriate HTTP method (GET, POST) and include any required parameters or payload as described in each endpoint’s description. For more detailed information, refer to the Postman Collection for this API available in the folder api: http_adapter_api_postman.json

+and trigger actions.

Available endpoints with the associated methods are:

Note: Replace {propertyKey}, {actionKey}, and {relationshipName} with the actual values you want to retrieve or trigger. +Make sure to use the appropriate HTTP method (GET, POST) and include any required parameters or payload as described in each endpoint’s description. For more detailed information, refer to the Postman Collection for this API available in the folder api: http_adapter_api_postman.json

Example of Storage Query Requests are the following:

Retrieve the first 4 Digital Twin State Variations

{
+    "resourceType": "DIGITAL_TWIN_STATE",
+    "queryType": "SAMPLE_RANGE",
+    "startIndex": 0,
+    "endIndex": 3
+}
+

Retrieve Digital Twin State Variations in a Time Range

{
+    "resourceType": "DIGITAL_TWIN_STATE",
+    "queryType": "TIME_RANGE",
+    "startIndex": 161989898,
+    "endIndex": 162989898
+}
+

Retrieve the last Digital Twin State

{
+    "resourceType": "DIGITAL_TWIN_STATE",
+    "queryType": "LAST_VALUE"
+}
+

Available keywords for Query Resource Type and Query Type are the following (as explained in the dedicated Query System Page):

- PHYSICAL_ASSET_PROPERTY_VARIATION
+	- TIME_RANGE
+	- SAMPLE_RANGE
+	- COUNT
+- PHYSICAL_ASSET_EVENT_NOTIFICATION
+	- TIME_RANGE
+	- SAMPLE_RANGE
+	- COUNT
+- PHYSICAL_ACTION_REQUEST
+	- TIME_RANGE
+	- SAMPLE_RANGE
+	- COUNT
+- DIGITAL_ACTION_REQUEST
+	- TIME_RANGE
+	- SAMPLE_RANGE
+	- COUNT
+- DIGITAL_TWIN_STATE
+	- TIME_RANGE
+	- SAMPLE_RANGE
+	- COUNT
+	- LAST_VALUE
+- NEW_PAD_NOTIFICATION
+	- TIME_RANGE
+	- SAMPLE_RANGE
+	- COUNT
+- UPDATED_PAD_NOTIFICATION
+	- TIME_RANGE
+	- SAMPLE_RANGE
+	- COUNT
+- PHYSICAL_RELATIONSHIP_INSTANCE_CREATED_NOTIFICATION
+	- TIME_RANGE
+	- SAMPLE_RANGE
+	- COUNT
+- PHYSICAL_RELATIONSHIP_INSTANCE_DELETED_NOTIFICATION
+	- TIME_RANGE
+	- SAMPLE_RANGE
+	- COUNT
+- LIFE_CYCLE_EVENT
+	- TIME_RANGE
+	- SAMPLE_RANGE
+	- COUNT
+	- LAST_VALUE
+- STORAGE_STATS
+	- LAST_VALUE
+
\ No newline at end of file diff --git a/docs/adapters/index.html b/docs/adapters/index.html index ac64c4d..08ac96a 100644 --- a/docs/adapters/index.html +++ b/docs/adapters/index.html @@ -2,10 +2,10 @@ Adapters | WLDT
\ No newline at end of file diff --git a/docs/adapters/mqtt-digital-adapter/index.html b/docs/adapters/mqtt-digital-adapter/index.html index 0d754ff..f77e55f 100644 --- a/docs/adapters/mqtt-digital-adapter/index.html +++ b/docs/adapters/mqtt-digital-adapter/index.html @@ -5,17 +5,17 @@ MqttDigitalAdapterConfiguration, and MqttDigitalAdapterConfigurationBuilder classes and guides you through using these classes to set up an MQTT Digital Adapter within WLDT.">

MQTT Digital Adapter

The MqttDigitalAdapter,
MqttDigitalAdapterConfiguration, and MqttDigitalAdapterConfigurationBuilder classes and guides you through using these classes to set up an MQTT Digital Adapter within WLDT.

Requires an external MQTT broker to send messages.

Main functionalities are:

  • Manages the interaction between the Digital Twin and external systems.
  • Handles state updates, events, and property changes.
  • Dynamic configuration of the MqttDigitalAdapter with broker details, topics, and other settings.
  • Allows customization of data and payload management associated to MQTT topics for properties, events, and actions.

MQTT Digital Adapter

Prerequisites:

  • External MQTT Broker: The MqttDigitalAdapter library requires an external MQTT broker for optimal functionality and communication.
  • Users must have access to a reliable MQTT broker to which the adapter can subscribe and publish.
  • This external broker serves as the central communication hub, facilitating the exchange of messages between the adapter and digital applications

A complete example is provided in the test folder with a complete DT Creation in the TestMain class together with MQTT IoT demo device and -a test MQTT consumer.

WLDT-Core Version Compatibility

The correct mapping and compatibility between versions is reported in the following table

mqtt-digital-adapterwldt-core 0.2.1wldt-core 0.3.0
0.1.0
0.1.1

Installation

To use MqttDigitalAdapter in your Java project, you can include it as a dependency using Maven or Gradle.

Maven

<dependency>
+Change Logs

MQTT Digital Adapter

The MqttDigitalAdapter,
MqttDigitalAdapterConfiguration, and MqttDigitalAdapterConfigurationBuilder classes and guides you through using these classes to set up an MQTT Digital Adapter within WLDT.

Requires an external MQTT broker to send messages.

Main functionalities are:

  • Manages the interaction between the Digital Twin and external systems.
  • Handles state updates, events, and property changes.
  • Dynamic configuration of the MqttDigitalAdapter with broker details, topics, and other settings.
  • Allows customization of data and payload management associated to MQTT topics for properties, events, and actions.

MQTT Digital Adapter

Prerequisites:

  • External MQTT Broker: The MqttDigitalAdapter library requires an external MQTT broker for optimal functionality and communication.
  • Users must have access to a reliable MQTT broker to which the adapter can subscribe and publish.
  • This external broker serves as the central communication hub, facilitating the exchange of messages between the adapter and digital applications

A complete example is provided in the test folder with a complete DT Creation in the TestMain class together with MQTT IoT demo device and +a test MQTT consumer.

WLDT-Core Version Compatibility

The correct mapping and compatibility between versions is reported in the following table

mqtt-digital-adapterwldt-core 0.2.1wldt-core 0.3.0wldt-core 0.4.0
0.1.0
0.1.1

Installation

To use MqttDigitalAdapter in your Java project, you can include it as a dependency using Maven or Gradle.

Maven

<dependency>
     <groupId>io.github.wldt</groupId>
     <artifactId>mqtt-digital-adapter</artifactId>
     <version>0.1.1</version>
@@ -55,5 +55,5 @@
 
 digitalTwinEngine.addDigitalTwin(digitalTwin);
 digitalTwinEngine.startAll();
-
+
\ No newline at end of file diff --git a/docs/adapters/mqtt-physical-adapter/index.html b/docs/adapters/mqtt-physical-adapter/index.html index a17b834..4d59227 100644 --- a/docs/adapters/mqtt-physical-adapter/index.html +++ b/docs/adapters/mqtt-physical-adapter/index.html @@ -2,22 +2,22 @@ MQTT Physical Adapter | WLDT

MQTT Physical Adapter

The MqttPhysicalAdapter library provides a streamlined solution for efficiently managing physical assets through the MQTT protocol. It offers a range of features, including a versatile builder for effortless configuration of MQTT connections, dedicated classes for handling both incoming and outgoing topics, and a specialized adapter designed for seamless integration with diverse physical assets.

Key Features:

  • Builder for MQTT Configuration: The library incorporates a flexible builder pattern, enabling users to effortlessly configure the essential parameters of the MQTT connection. This includes specifying the MQTT broker’s address, port, and other relevant details to establish a reliable and customizable communication link.
  • Incoming and Outgoing Topic Handling: MqttPhysicalAdapter facilitates the handling of incoming and outgoing topics, crucial for communication between the physical assets and the MQTT broker. The library includes dedicated classes for defining and managing topics, allowing users to efficiently subscribe to incoming data and publish outgoing messages.
  • Adapter for Physical Asset Integration: At the core of the library is a robust adapter designed specifically for integrating with various physical assets. This adapter streamlines the process of connecting and interacting with physical devices, ensuring a smooth and standardized approach to managing asset-related data.

In the WLDT library, Physical Adapters has the responsibility to generate and publish the PhysicalAssetDescription (PAD) to describe the capabilities and the characteristics of our object allowing the Shadowing Function to decide how to digitalize its physical counterpart.

In the MqttPhysicalAdapter the generation of the PAD (Physical Asset Description) is automatically and internally executed by the adapter itself accordingly to the adapter configuration in terms of MQTT topics and their mapping with DT’s properties, events and actions.

MQTT Physical Adapter

Prerequisites:

  • External MQTT Broker: The MqttPhysicalAdapter library requires an external MQTT broker for optimal functionality.
  • Users must have access to a reliable MQTT broker to which the adapter can subscribe.
  • This external broker serves as the central communication hub, facilitating the exchange of messages between the adapter and the physical assets.

A complete example is provided in the test folder with a complete DT Creation in the TestMain class together with MQTT IoT demo device and -a test MQTT consumer.

WLDT-Core Version Compatibility

The correct mapping and compatibility between versions is reported in the following table

mqtt-physical-adapterwldt-core 0.2.1wldt-core 0.3.0
0.1.0
0.1.1

Installation

To use MqttPhysicalAdapter in your Java project, you can include it as a dependency using Maven or Gradle.

Maven

<dependency>
+a test MQTT consumer.

WLDT-Core Version Compatibility

The correct mapping and compatibility between versions is reported in the following table

mqtt-physical-adapterwldt-core 0.2.1wldt-core 0.3.0wldt-core 0.4.0
0.1.0
0.1.1

Installation

To use MqttPhysicalAdapter in your Java project, you can include it as a dependency using Maven or Gradle.

Maven

<dependency>
     <groupId>io.github.wldt</groupId>
     <artifactId>mqtt-physical-adapter</artifactId>
     <version>0.1.1</version>
@@ -78,5 +78,5 @@
         return properties;
     }
 

This information are used by the adapter to build the PAD describe the capabilities and the characteristics of our object allowing -the Shadowing Function to decide how to digitalize its physical counterpart.

+the Shadowing Function to decide how to digitalize its physical counterpart.

\ No newline at end of file diff --git a/docs/adapters/sitemap.xml b/docs/adapters/sitemap.xml index 3f568e1..8f03aa0 100644 --- a/docs/adapters/sitemap.xml +++ b/docs/adapters/sitemap.xml @@ -1 +1 @@ -https://wldt.github.io/docs/adapters/mqtt-physical-adapter/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/adapters/mqtt-digital-adapter/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/adapters/http-digital-adapter/2024-03-15T10:45:36+01:00monthly0.5 \ No newline at end of file +https://wldt.github.io/docs/adapters/mqtt-physical-adapter/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/adapters/mqtt-digital-adapter/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/adapters/http-digital-adapter/2024-09-05T15:02:33+02:00monthly0.5 \ No newline at end of file diff --git a/docs/change-logs/change-log-0.3.0/index.html b/docs/change-logs/change-log-0.3.0/index.html index c93cd8b..17811cf 100644 --- a/docs/change-logs/change-log-0.3.0/index.html +++ b/docs/change-logs/change-log-0.3.0/index.html @@ -2,16 +2,16 @@ Change Log 0.3.0 | WLDT

Change Log 0.3.0

Digital Adapters

  • The following methods have been discontinued and removed from the DigitalAdapter class:
    • onStateChangePropertyCreated
    • onStateChangePropertyUpdated
    • onStateChangePropertyDeleted
    • onStatePropertyUpdated
    • onStatePropertyDeleted
    • onStateChangeActionEnabled
    • onStateChangeActionUpdated
    • onStateChangeActionDisabled
    • onStateChangeEventRegistered
    • onStateChangeEventRegistrationUpdated
    • onStateChangeEventUnregistered
    • onStateChangeRelationshipInstanceDeleted
    • onStateChangeRelationshipDeleted
    • onStateChangeRelationshipInstanceCreated
    • onStateChangeRelationshipCreated
    • onDigitalTwinStateEventNotificationReceived
  • The Signature of the following methods have been changed:
    • onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) -> onDigitalTwinSync(DigitalTwinState currentDigitalTwinState)
    • onDigitalTwinUnSync(IDigitalTwinState currentDigitalTwinState) -> onDigitalTwinUnSync(DigitalTwinState currentDigitalTwinState)
  • New methods that have been added are:
    • onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList<DigitalTwinStateChange> digitalTwinStateChangeList)
    • onEventNotificationReceived(DigitalTwinStateEventNotification<?> digitalTwinStateEventNotification)
  • For additional details about Digital Adapters check Sub Section [[Change Log - v.0.3.0#Digital Adapter| Digital Adapters]]

Shadowing Function

  • ShadowingModelFunction is now ShadowingFunction
  • this.digitalTwinState is not directly accessible anymore and it is wrapped through the DigitalTwinStateManager using the variable digitalTwinStateManager (see next descriptions and changes)
  • The method addRelationshipInstance now take only one parameter that is the DigitalTwinStateRelationshipInstance
  • The same change for example should be applied in the point of the code where the Shadowing Function receive a variation from the Physical world through a target adapter and the callback method onPhysicalAssetPropertyVariation(...)
  • When the Shadowing Function has to compute the new DT State it can now work with the following method to handle DT State Transition:
    • this.digitalTwinStateManager.startStateTransaction()
    • DT State variation methods such as:
      • digitalTwinStateManager.createProperty()
      • digitalTwinStateManager.updateProperty()
      • digitalTwinStateManager.updatePropertyValue()
      • digitalTwinStateManager.deleteProperty()
      • digitalTwinStateManager.enableAction()
      • digitalTwinStateManager.updateAction()
      • digitalTwinStateManager.disableAction()
      • digitalTwinStateManager.registerEvent()
      • digitalTwinStateManager.updateRegisteredEvent()
      • digitalTwinStateManager.unRegisterEvent()
      • digitalTwinStateManager.createRelationship()
      • digitalTwinStateManager.addRelationshipInstance()
      • digitalTwinStateManager.deleteRelationship()
      • digitalTwinStateManager.deleteRelationshipInstance()
    • At the end the transaction can be committed using the method: digitalTwinStateManager.commitStateTransaction()
    • The method notifyDigitalTwinStateEvent is now available through the digitalTwinStateManager
  • Additional Details associated to Shadowing Function Migration can be found in the dedicated section [[Change Log - v.0.3.0#Shadowing Function Changes | Shadowing Function Changes]]

WLDT Engine & DT Creation

  • WldtEngine is now DigitalTwin and model and structure a single Digital Twin and takes the following parameters:
    • String digitalTwinId
    • ShadowingFunction shadowingFunction
  • The startLifeCycle has been removed from the DigitalTwin (previously WLDT Engine) and now DigitalTwinEngine should be used to start twins
  • Once a new Digital Twin has been create it has to be added to the DigitalTwinEngine
  • DigitalTwinEngine has dedicated method to start and stop twins such as:
    • startAll()
    • startDigitalTwin(<DIGITAL_TWIN_ID>);
    • stopAll()
    • digitalTwinEngine.stopDigitalTwin(<DIGITAL_TWIN_ID>);

Digital Twin & Digital Twin Engine

With the following code we now create a new Digital Twin Instance

// Create the new Digital Twin with its Shadowing Function  
+Change Logs

Change Log 0.3.0

Digital Adapters

  • The following methods have been discontinued and removed from the DigitalAdapter class:
    • onStateChangePropertyCreated
    • onStateChangePropertyUpdated
    • onStateChangePropertyDeleted
    • onStatePropertyUpdated
    • onStatePropertyDeleted
    • onStateChangeActionEnabled
    • onStateChangeActionUpdated
    • onStateChangeActionDisabled
    • onStateChangeEventRegistered
    • onStateChangeEventRegistrationUpdated
    • onStateChangeEventUnregistered
    • onStateChangeRelationshipInstanceDeleted
    • onStateChangeRelationshipDeleted
    • onStateChangeRelationshipInstanceCreated
    • onStateChangeRelationshipCreated
    • onDigitalTwinStateEventNotificationReceived
  • The Signature of the following methods have been changed:
    • onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) -> onDigitalTwinSync(DigitalTwinState currentDigitalTwinState)
    • onDigitalTwinUnSync(IDigitalTwinState currentDigitalTwinState) -> onDigitalTwinUnSync(DigitalTwinState currentDigitalTwinState)
  • New methods that have been added are:
    • onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList<DigitalTwinStateChange> digitalTwinStateChangeList)
    • onEventNotificationReceived(DigitalTwinStateEventNotification<?> digitalTwinStateEventNotification)
  • For additional details about Digital Adapters check Sub Section [[Change Log - v.0.3.0#Digital Adapter| Digital Adapters]]

Shadowing Function

  • ShadowingModelFunction is now ShadowingFunction
  • this.digitalTwinState is not directly accessible anymore and it is wrapped through the DigitalTwinStateManager using the variable digitalTwinStateManager (see next descriptions and changes)
  • The method addRelationshipInstance now take only one parameter that is the DigitalTwinStateRelationshipInstance
  • The same change for example should be applied in the point of the code where the Shadowing Function receive a variation from the Physical world through a target adapter and the callback method onPhysicalAssetPropertyVariation(...)
  • When the Shadowing Function has to compute the new DT State it can now work with the following method to handle DT State Transition:
    • this.digitalTwinStateManager.startStateTransaction()
    • DT State variation methods such as:
      • digitalTwinStateManager.createProperty()
      • digitalTwinStateManager.updateProperty()
      • digitalTwinStateManager.updatePropertyValue()
      • digitalTwinStateManager.deleteProperty()
      • digitalTwinStateManager.enableAction()
      • digitalTwinStateManager.updateAction()
      • digitalTwinStateManager.disableAction()
      • digitalTwinStateManager.registerEvent()
      • digitalTwinStateManager.updateRegisteredEvent()
      • digitalTwinStateManager.unRegisterEvent()
      • digitalTwinStateManager.createRelationship()
      • digitalTwinStateManager.addRelationshipInstance()
      • digitalTwinStateManager.deleteRelationship()
      • digitalTwinStateManager.deleteRelationshipInstance()
    • At the end the transaction can be committed using the method: digitalTwinStateManager.commitStateTransaction()
    • The method notifyDigitalTwinStateEvent is now available through the digitalTwinStateManager
  • Additional Details associated to Shadowing Function Migration can be found in the dedicated section [[Change Log - v.0.3.0#Shadowing Function Changes | Shadowing Function Changes]]

WLDT Engine & DT Creation

  • WldtEngine is now DigitalTwin and model and structure a single Digital Twin and takes the following parameters:
    • String digitalTwinId
    • ShadowingFunction shadowingFunction
  • The startLifeCycle has been removed from the DigitalTwin (previously WLDT Engine) and now DigitalTwinEngine should be used to start twins
  • Once a new Digital Twin has been create it has to be added to the DigitalTwinEngine
  • DigitalTwinEngine has dedicated method to start and stop twins such as:
    • startAll()
    • startDigitalTwin(<DIGITAL_TWIN_ID>);
    • stopAll()
    • digitalTwinEngine.stopDigitalTwin(<DIGITAL_TWIN_ID>);

Digital Twin & Digital Twin Engine

With the following code we now create a new Digital Twin Instance

// Create the new Digital Twin with its Shadowing Function  
 DigitalTwin digitalTwin = new DigitalTwin(digitalTwinId, new DemoShadowingFunction());  
   
 // Physical Adapter with Configuration  
@@ -235,5 +235,5 @@
         System.out.println("No state changes detected.");
     }
 }
-

In this example, the method iterates over the list of state changes, extracts information about each change, and performs custom actions based on the changes. Developers can adapt this method to suit the specific requirements of their Digital Twin application.

+

In this example, the method iterates over the list of state changes, extracts information about each change, and performs custom actions based on the changes. Developers can adapt this method to suit the specific requirements of their Digital Twin application.

\ No newline at end of file diff --git a/docs/change-logs/change-log-0.4.0/index.html b/docs/change-logs/change-log-0.4.0/index.html new file mode 100644 index 0000000..e3c4231 --- /dev/null +++ b/docs/change-logs/change-log-0.4.0/index.html @@ -0,0 +1,140 @@ + +Change Log 0.4.0 | WLDT

Change Log 0.4.0

New Features

WldtEventObserver

A new class called WldtEventObserver has been introduced to allow a simplified observation of target specific events generated by the Digital Twin and its components such as adapters and the model. Main mapped events and filters are:

  • State Events: State Update and State Event Notifications
  • Physical Asset Events: Physical Property Variation, Physical Event Notification, Physical Relationship Instance Creation and Deletion
  • Physical Asset Action Events: Physical Action Trigger
  • Digital Action Events: Digital Action Event
  • Physical Asset Description Events: Physical Asset Description Available and Updated
  • Life Cycle Events: Digital Twin Life Cycle Events
  • Query Request Events: Storage Query Request Events (See next sections for additional information)

For each event type dedicated observation and un-observation methods (e.g., observePhysicalAssetEvents() and unObservePhysicalAssetEvents()) are available in order to create an instance of the observer and decide which events to receive.

To build a WldtEventObserver a dedicated listener IWldtEventObserverListener should be implemented by the developer to receive the callbacks related to the incoming events. All the events are of the generic type WldtEvent and it is up to the developer the validate and check the received object and if it match with the expected one.

An example of usage for the event observer is the following:

WldtEventObserver eventObserver = new WldtEventObserver(  
+        "DT_TEST_ID_1",  
+        "test-observer",  
+        myObserverListener);  
+  
+// Start all the available observation  
+eventObserver.observePhysicalAssetEvents();  
+eventObserver.observePhysicalAssetActionEvents();  
+eventObserver.observeStateEvents();  
+eventObserver.observeDigitalActionEvents();  
+eventObserver.observePhysicalAssetDescriptionEvents();  
+eventObserver.observeLifeCycleEvents();
+

The WldtEventObserver has been currently used internally within the library to simplify the implementation and usage of the Storage Layer and the associated Storage Query System as described in the dedicated sections.

Storage Layer

A new storage layer has been integrated into the core WLDT library, enabling Digital Twins (DTs) to store data related to the evolution of their state, generated events, and any variations involving properties, events, actions, relationships, and life cycle. The Storage Layer consists of two main components:

  • Storage Manager: This is the central component of the storage system, facilitating the structured and modular storage and retrieval of information. It allows developers to create and utilize various storage systems (e.g., in-memory, file-based, or DBMS) simultaneously. The Storage Layer is accessible in both read and write modes internally by the DT’s Model, and in read-only mode via the Query System by Digital Adapters.
  • Query System: To delegate and encapsulate the responsibility of data storage within the DT’s model, a query system has been integrated. This system enables Digital Adapters to retrieve stored data and expose it according to their specific logic and implementation.

The storage layer is designed for easy extension, allowing developers to create and share new storage layers (e.g., using Redis, MySQL, or MongoDB). The provided in-memory implementation serves only for basic development and testing purposes. Similarly, the Query Manager can be extended and customized by developers to implement additional query management features or to enhance the default functionalities provided by the library.

Storage Manager

The main module of the Storage Layer is the one associated to Storage Capabilities and it is composed by two main classes: StorageManager and WldStorage with the following characteristics and main methods:

  • StorageManager: The StorageManager class is a class that represents the storage manager for a DigitalTwin. It is responsible for managing the storage of the data related to the DigitalTwin. It is an observer of the WldtEventBus, and it is able to save the data in the available storages. The class extends a DigitalTwinWorker, in order to allow the component to work in a structure and integrated way on a different thread that the core of a DT can coordinate starting and stopping it when required. The manager allow the usage of different storage systems at the same time in order to allow the developers to memorize the information accordingly to their need in the right storage system at the same time (e.g., REDIS for quick cached information and MongDB for historical data). Main associated methods are:
    • putStorage(WldtStorage storage): Add a new WldtStorage to the StorageManager
    • getStorageIdList(): Returns the list of id of the WldtStorage in the StorageManager
    • isStorageAvailable(String storageId): Checks if a target Storage Id is available in the Storage Manager
    • getStorage(String storageId): Get the target WldtStorage by id from the Storage Manager
    • removeStorage(String storageId): Remove an existing WldtStorage by id from the StorageManager
  • WldtStorage: Defines an abstract class allowing the Digital Twin developer to implement its internal storage system for the Digital Twin instance.
    • The class defines methods for the management of:
      • Digital Twin State storage and retrieval with the associated change list;
      • Generated State Digital Events;
      • Life Cycle State storage and retrieval;
      • Physical Asset Description storage and retrieval;
      • Physical Asset Property Variation storage and retrieval;
      • Physical Asset Relationship Instance storage and retrieval;
      • Digital Action Request storage and retrieval;
      • Physical Asset Action Request storage and retrieval;
      • Physical Asset Event Notification storage and retrieval;
    • Each WldtStorage instance can be configured (using the right constructor method) to:
      • Observe all Wldt events (stateEvents, physicalAssetEvents, physicalAssetActionEvents, physicalAssetDescriptionEvents, digitalActionEvents, lifeCycleEvents)
      • Filter only for specific class of events
      • Once the WldtStorage has been properly configured to receive target events the StorageManager automatically save information of interest for that specific storage. For example we can have a StorageA (e.g, REDIS) configured to receive all the generated events and a StorageB (e.g., MongoDB) in charge of saving only DT’s state variation over time.
    • The default implementation of the WldtStorage is the class DefaultWldtStorage. This class provides a simple storage solution for digital twin states, digital twin state changes, physical asset events, and digital twin events. The class provides ONLY a memory based approach for storage using ArrayLists and HashMaps and more advanced solution should be implemented for production oriented Digital Twins for examples using external storage and memorization solutions.
    • Methods available and implemented by WldtStorage implementations are the following grouped by categories:
      • Digital Twin State:
        • saveDigitalTwinState(DigitalTwinState digitalTwinState, List<DigitalTwinStateChange> digitalTwinStateChangeList): Save a new computed instance of the DT State in the Storage together with the list of the changes with respect to the previous state
        • getLastDigitalTwinState(): Returns the latest computed Digital Twin State of the target Digital Twin instance
        • getDigitalTwinStateCount(): Returns the number of computed and stored Digital Twin States
        • getDigitalTwinStateInTimeRange(long startTimestampMs, long endTimestampMs): Retrieves a list of DigitalTwinState objects within the specified time range
        • getDigitalTwinStateInRange(int startIndex, int endIndex): Retrieves a list of Digital Twin states within the specified range of indices
      • Digital Twin State Event Notification:
        • saveDigitalTwinStateEventNotification(DigitalTwinStateEventNotification<?> digitalTwinStateEventNotification): Save the Digital Twin State Event Notification
        • getDigitalTwinStateEventNotificationCount(): Get the number of Digital Twin State Event Notification
        • getDigitalTwinStateEventNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Digital Twin State Event Notification in the specified time range
        • getDigitalTwinStateEventNotificationInRange(int startIndex, int endIndex): Get the Digital Twin State Event Notification in the specified range of indices
      • Life Cycle State Variation:
        • saveLifeCycleState(LifeCycleStateVariation lifeCycleStateVariation): Save the LifeCycleState of the Digital Twin
        • getLastLifeCycleState(): Get the last LifeCycleState of the Digital Twin
        • getLifeCycleStateCount(): Get the number of LifeCycleState of the Digital Twin
        • getLifeCycleStateInTimeRange(long startTimestampMs, long endTimestampMs): Get the last LifeCycleState of the Digital Twin
        • getLifeCycleStateInRange(int startIndex, int endIndex): Get the LifeCycleState of the Digital Twin in the specified range of indices
      • Physical Asset Event Notification:
        • savePhysicalAssetEventNotification(PhysicalAssetEventNotification physicalAssetEventNotification): Save the Physical Asset Event Notification
        • getPhysicalAssetEventNotificationCount(): Get the number of Physical Asset Event Notification
        • getPhysicalAssetEventNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Event Notification in the specified time range
        • getPhysicalAssetEventNotificationInRange(int startIndex, int endIndex): Get the Physical Asset Event Notification in the specified range of indices
      • Physical Action Request:
        • savePhysicalAssetActionRequest(PhysicalAssetActionRequest physicalAssetActionRequest): Save Physical Asset Action Request
        • getPhysicalAssetActionRequestCount(): Get the number of Physical Asset Action Request
        • getPhysicalAssetActionRequestInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Action Request in the specified time range
        • getPhysicalAssetActionRequestInRange(int startIndex, int endIndex): Get the Physical Asset Action Request in the specified range of indices
      • Digital Action Request:
        • saveDigitalActionRequest(DigitalActionRequest digitalActionRequest): Save a Digital Action Request
        • getDigitalActionRequestCount(): Get the number of Digital Action Request Stored
        • getDigitalActionRequestInTimeRange(long startTimestampMs, long endTimestampMs): Get the Digital Action Request in the specified time range
        • getDigitalActionRequestInRange(int startIndex, int endIndex): Get the Digital Action Request in the specified range of indices
      • Physical Asset Description (PAD) Notification
        • New PAD Notification
          • saveNewPhysicalAssetDescriptionNotification(PhysicalAssetDescriptionNotification physicalAssetDescriptionNotification): Save a new Physical Asset Description Available
          • getNewPhysicalAssetDescriptionNotificationCount(): Get the number of New Physical Asset Description Notifications available
          • getNewPhysicalAssetDescriptionNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the New Physical Asset Description Available in the specified time range
          • getNewPhysicalAssetDescriptionNotificationInRange(int startIndex, int endIndex): Get the New Physical Asset Description Available in the specified range of indices
        • Updated PAD Notification
          • saveUpdatedPhysicalAssetDescriptionNotification(PhysicalAssetDescriptionNotification physicalAssetDescriptionNotification): Save the updated Physical Asset Description Notification
          • getUpdatedPhysicalAssetDescriptionNotificationCount(): Get the number of Updated Physical Asset Description
          • getUpdatedPhysicalAssetDescriptionNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Updated Physical Asset Description in the specified time range
          • getUpdatedPhysicalAssetDescriptionNotificationInRange(int startIndex, int endIndex): Get the Updated Physical Asset Description in the specified range of indices
      • Physical Asset Property Variation:
        • savePhysicalAssetPropertyVariation(PhysicalAssetPropertyVariation physicalAssetPropertyVariation): Save the Physical Asset Property Variation
        • getPhysicalAssetPropertyVariationCount(): Get the number of Physical Asset Property Variation
        • getPhysicalAssetPropertyVariationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Property Variation in the specified time range
        • getPhysicalAssetPropertyVariationInRange(int startIndex, int endIndex): Get the Physical Asset Property Variation in the specified range of indices
      • Physical Asset Relationship Instance Notification
        • Created Relationship Instance
          • savePhysicalAssetRelationshipInstanceCreatedNotification(PhysicalRelationshipInstanceVariation physicalRelationshipInstanceVariation): Save the Physical Asset Relationship Instance Created Event
          • getPhysicalAssetRelationshipInstanceCreatedNotificationCount(): Get the number of Physical Asset Relationship Instance Created Event
          • getPhysicalAssetRelationshipInstanceCreatedNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Relationship Instance Created Event in the specified time range
          • getPhysicalAssetRelationshipInstanceCreatedNotificationInRange(int startIndex, int endIndex): Get the Physical Asset Relationship Instance Created Event in the specified range of indices
        • Deleted Relationship Instance
          • savePhysicalAssetRelationshipInstanceDeletedNotification(PhysicalRelationshipInstanceVariation physicalRelationshipInstanceVariation): Save the Physical Asset Relationship Instance Updated Event
          • getPhysicalAssetRelationshipInstanceDeletedNotificationCount(): Get the number of Physical Asset Relationship Instance Updated Event
          • getPhysicalAssetRelationshipInstanceDeletedNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Relationship Instance Updated Event in the specified time range
          • getPhysicalAssetRelationshipInstanceDeletedNotificationInRange(int startIndex, int endIndex): Get the Physical Asset Relationship Instance Updated Event in the specified range of indices

Some examples of usage for the Storage Layer are the following:

Lets’ create a new Digital Twin with a single Storage in charge of automatically observe and store all the event generated and going through the target DT instance

// Create the Digital Twin Engine
+DigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine();  
+
+// Create a new Digital Twin with a Demo Shadowing Function
+DigitalTwin digitalTwin = new DigitalTwin(TEST_DIGITAL_TWIN_ID, new DemoShadowingFunction());
+
+// Physical Adapter Configuration  
+DemoPhysicalAdapter physicalAdapter = new DemoPhysicalAdapter(...);  
+digitalTwin.addPhysicalAdapter(physicalAdapter);
+
+// Digital Adapter Configuration
+digitalAdapter = new DemoDigitalAdapter(...);  
+digitalTwin.addDigitalAdapter(digitalAdapter);
+
+// Create a new WldtStorage instance using the default implementation and observing all the events  
+DefaultWldtStorage myStorage = new DefaultWldtStorage("test_storage", true)
+
+// Add the new Default Storage Instance to the Digital Twin Storage Manager 
+digitalTwin.getStorageManager().putStorage(myStorage);
+
+// Add the Twin to the Engine  
+digitalTwinEngine.addDigitalTwin(digitalTwin);  
+  
+// Start the Digital Twin  
+digitalTwinEngine.startDigitalTwin(TEST_DIGITAL_TWIN_ID);
+

Now let’s suppose to have two additional implementation of the WldtStorage class supporting Redis and MongDB and called RedisWldtStorage and MongoDbWldtStorage. +We would like to use Redis to automatically observe all the events and MongoDb only to store DT’s state and life cycle variations.

[...]
+
+// Create a new RedisWldtStorage instance using the default implementation and observing all the events  
+RedisWldtStorage myRedisStorage = new RedisWldtStorage("redis_storage", true);
+myRedisStorage.setRedisConfiguration(myRedisConfiguration);
+
+// Add the new Redis Storage Instance to the Digital Twin Storage Manager 
+digitalTwin.getStorageManager().putStorage(myRedisStorage);
+
+// Create a new MongoDbWldtStorage instance using the default implementation and observing only State and LifeCycle Events
+MongoDbWldtStorage myMongoDbStorage = new MongoDbWldtStorage("mongo_db_storage", true, false, false, false, false, true);
+myMongoDbStorage.setMongoDbConfiguration(myMongoDbConfiguration);
+
+// Add the new MongoDb Storage Instance to the Digital Twin Storage Manager 
+digitalTwin.getStorageManager().putStorage(myRedisStorage);
+
+[...]
+

Within the ShadowingFunction it is possible to have the reference to the StorageManager in order to access available Storage in both reading and writing mode. +This is an example of how to retrieve an available WldtStorage through its id and the use it to read Properties values in a time range of the last 5 minutes:

String TARGET_STORAGE_ID = "test_storage";  
+  
+if(this.storageManager.isStorageAvailable(TARGET_STORAGE_ID)){  
+  
+    // Access the Storage Manager to store the last value of the property  
+    WldtStorage targetStorage = this.storageManager.getStorage(TARGET_STORAGE_ID);  
+  
+    // Get the current time in milliseconds  
+    long endTime = System.currentTimeMillis();  
+  
+    // Get the Time in the last 5 minutes  
+    long startTime = endTime - (5 * 60 * 1000);  
+  
+    // Get the last Physical Asset Action Request in the last 5 minutes  
+    List<PhysicalAssetPropertyVariationRecord> propertyVariationRecords = targetStorage.getPhysicalAssetPropertyVariationInTimeRange(startTime, endTime);  
+        for(PhysicalAssetPropertyVariationRecord propertyVariationRecord : propertyVariationRecords){  
+        logger.info("Property Variation Record: {}", propertyVariationRecord);  
+        [...]  
+    }  
+}
+

Note: The StorageManager, as previously described, can automatically store DT-related events based on the configuration and setup of each WldtStorage instance added to the manager. However, since the ShadowingFunction has direct access to the StorageManager in both read and write modes, manual handling of data storage is also possible. To achieve this, you can disable automatic storage by setting it to false for specific event types or for all event types. This allows you to manually manage the storage of information within the ShadowingFunction.

Query System

Given the library’s goal of maximizing modularity and decoupling responsibilities among the available components, the Query System has been introduced. This system allows components external to the core responsibilities of the Digital Twin (e.g., Digital Adapters and Augmentation Functions) to retrieve stored data and use or expose it according to their specific logic and implementation. For instance, an HTTP Digital Adapter could expose stored information about a DT’s state variations over time, or a Monitoring Adapter could use available storage instances to retrieve events for a deeper understanding of the target DT instance’s behavior. The query system has been implemented entirely through dedicated events in order to maximize the decoupling of the solution and and supports at the same time both synchronous and asynchronous queries.

The main classes associated to the Query System are the following:

  • QueryManager: This class represents the Query Manager responsible to handle the query request and manage the query execution and has been designed to be extended by the user to implement the desired query management logic (e.g., as with the DefaultQueryManager).
  • QueryRequest: The class contains all the information needed to perform a query on the storage system
  • QueryRequestType: This Enum represents the Query Request Type used to specify the type of query to be performed on the storage system supporting:
    • TIME_RANGE
    • SAMPLE_RANGE
    • LAST_VALUE
    • COUNT
  • QueryResourceType: This Enum represents the Query Resource Type used to specify the type of resource to be queried on the storage system supporting the following resource types mapping those available and managed by the storage manager:
    • PHYSICAL_ASSET_PROPERTY_VARIATION
    • PHYSICAL_ASSET_EVENT_NOTIFICATION
    • PHYSICAL_ACTION_REQUEST
    • DIGITAL_ACTION_REQUEST
    • DIGITAL_TWIN_STATE
    • NEW_PAD_NOTIFICATION
    • UPDATED_PAD_NOTIFICATION
    • PHYSICAL_RELATIONSHIP_INSTANCE_CREATED_NOTIFICATION
    • PHYSICAL_RELATIONSHIP_INSTANCE_DELETED_NOTIFICATION
    • LIFE_CYCLE_EVENT
  • QueryExecutor: This class represents the Query Executor used to execute queries on the storage system supporting both synchronous and asynchronous query execution. Internally is implemented through an event-based mechanism to handle the query request and response
  • QueryResult: This class represents the Query Result returned by the Query Executor containing the query results and the query status (successful or not) and error message (if any) together with also the original request
  • IQueryResultListener: This interface represents the Query Result Listener used to receive the query results

An example of Synchronous query is:

QueryExecutor queryExecutor = new QueryExecutor(TEST_DIGITAL_TWIN_ID, "query-executor");  
+  
+// Create Query Request to the Storage Manager for the Last Digital Twin State  
+QueryRequest queryRequest = new QueryRequest();  
+queryRequest.setResourceType(QueryResourceType.DIGITAL_TWIN_STATE);  
+queryRequest.setRequestType(QueryRequestType.LAST_VALUE);  
+  
+// Send the Query Request to the Storage Manager for the target DT  
+QueryResult<?> queryResult = queryExecutor.syncQueryExecute(queryRequest);
+

Following the same approach an Asynchrounouse query can be executed as follows:

QueryExecutor queryExecutor = new QueryExecutor(TEST_DIGITAL_TWIN_ID, "query-executor");  
+  
+// Create Query Request to the Storage Manager for the Last Digital Twin State  
+QueryRequest queryRequest = new QueryRequest();  
+queryRequest.setResourceType(QueryResourceType.DIGITAL_TWIN_STATE);  
+queryRequest.setRequestType(QueryRequestType.LAST_VALUE);  
+    
+// Send the Query Request to the Storage Manager for the target DT  
+queryExecutor.asyncQueryExecute(queryRequest, new IQueryResultListener() {  
+    @Override  
+    public void onQueryResult(QueryResult<?> queryResult) {  
+        [...]  
+    }  
+});
+

The class DigitalAdapter has been updated adding also an internal reference to a QueryExecutor in order to simplify the interaction with the query system directly from an adapter like in the following example where we use the query Executor of the Digital Adapter invokeAction callback through its internal variable accessible through this.queryExecutor without creating a new executor:

public <T> void invokeAction(String actionKey, T body){  
+    try {  
+          
+        // Create Query Request to the Storage Manager for the Last Digital Twin State  
+        QueryRequest queryRequest = new QueryRequest();  
+        queryRequest.setResourceType(QueryResourceType.DIGITAL_TWIN_STATE);  
+        queryRequest.setRequestType(QueryRequestType.LAST_VALUE);  
+  
+        // Send the Query Request to the Storage Manager for the target DT  
+        QueryResult<?> queryResult = this.queryExecutor.syncQueryExecute(queryRequest);  
+        
+        // Do Something with the Query Result  
+        for(Object result : queryResult.getResults()){  
+	        // Check the type of the Resulting class accordingly to the query
+		    if(result instanceof DigitalTwinState)  
+		        logger.info("LAST DT STATE: {}", result);  
+		    else
+			    logger.error("INVALID RESULT TYPE: {}", result.getClass().getName());  
+		}
+          
+        logger.info("INVOKING ACTION: {} BODY: {}", actionKey, body);  
+        publishDigitalActionWldtEvent(actionKey, body);  
+    } catch (EventBusException e) {  
+        e.printStackTrace();  
+    }  
+}
+

Migration Info: 0.3.0 - 0.4.0

  • Now PhysicalAssetRelationship constructor has also the type in order to match the DigitalTwinStateRelationship and simplify its management
  • The method notifyDigitalTwinStateEvent throws only the Exception WldtDigitalTwinStateEventNotificationException while EventBusException has been removed

Additional Improvements & Fixed Bugs

  • Synchronized the update of the current DT Life Cycle State in order to avoid wrong data
  • The WldtEventBus now supports the use of topics Wildcard (at the moment only multi-level with the character *). For example with this approach is possible to subscribe to all the events associated to property variations (topic: dt.physical.event.property.*). New methods added to WldtEventBus are:
    • matchWildCardType(String eventType, String filterType): Check if the provided event type match the WildCard Type
    • isWildCardType(String filterEventType): Check if the provided event type is a WildCard Type
  • The class WldtEventTypes has been introduced to contain all the event types in the WLDT Framework and support internal message exchange. Includes types for events associated and adopted by: i) Physical Adapters; ii) Model and Shadowing Function; and iii) Digital Adapters.
  • The EventManager class has been added to centralize and simplify the event management in the WLDT Framework providing a set of static methods to publish events associated to a target digital twin and publisher (e.g., the physical adapter of the twin).
  • Now PhysicalAssetRelationship class has also the type in order to match the DigitalTwinStateRelationship and simplify its management
  • The internal class ModelEngine has been renamed into DigitalTwinModel as an initial update for further development of the next version 0.5.0 where the structure of the DT’s Model and the associated classes will be improved
+
\ No newline at end of file diff --git a/docs/change-logs/index.html b/docs/change-logs/index.html index eb712cb..a6aa484 100644 --- a/docs/change-logs/index.html +++ b/docs/change-logs/index.html @@ -2,10 +2,10 @@ Change Logs | WLDT +
\ No newline at end of file diff --git a/docs/change-logs/index.xml b/docs/change-logs/index.xml index 890d00b..bcecd41 100644 --- a/docs/change-logs/index.xml +++ b/docs/change-logs/index.xml @@ -1 +1 @@ -Change Logs on WLDThttps://wldt.github.io/docs/change-logs/Recent content in Change Logs on WLDTHugo -- gohugo.ioenCopyright (c) 2023 HyasFri, 09 Feb 2024 12:24:39 +0100Change Log 0.3.0https://wldt.github.io/docs/change-logs/change-log-0.3.0/Fri, 09 Feb 2024 12:23:33 +0100https://wldt.github.io/docs/change-logs/change-log-0.3.0/Digital Adapters The following methods have been discontinued and removed from the DigitalAdapter class: onStateChangePropertyCreated onStateChangePropertyUpdated onStateChangePropertyDeleted onStatePropertyUpdated onStatePropertyDeleted onStateChangeActionEnabled onStateChangeActionUpdated onStateChangeActionDisabled onStateChangeEventRegistered onStateChangeEventRegistrationUpdated onStateChangeEventUnregistered onStateChangeRelationshipInstanceDeleted onStateChangeRelationshipDeleted onStateChangeRelationshipInstanceCreated onStateChangeRelationshipCreated onDigitalTwinStateEventNotificationReceived The Signature of the following methods have been changed: onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) -&gt; onDigitalTwinSync(DigitalTwinState currentDigitalTwinState) onDigitalTwinUnSync(IDigitalTwinState currentDigitalTwinState) -&gt; onDigitalTwinUnSync(DigitalTwinState currentDigitalTwinState) New methods that have been added are: onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList&lt;DigitalTwinStateChange&gt; digitalTwinStateChangeList) onEventNotificationReceived(DigitalTwinStateEventNotification&lt;? \ No newline at end of file +Change Logs on WLDThttps://wldt.github.io/docs/change-logs/Recent content in Change Logs on WLDTHugo -- gohugo.ioenCopyright (c) 2023 HyasFri, 09 Feb 2024 12:24:39 +0100Change Log 0.3.0https://wldt.github.io/docs/change-logs/change-log-0.3.0/Fri, 09 Feb 2024 12:23:33 +0100https://wldt.github.io/docs/change-logs/change-log-0.3.0/Digital Adapters The following methods have been discontinued and removed from the DigitalAdapter class: onStateChangePropertyCreated onStateChangePropertyUpdated onStateChangePropertyDeleted onStatePropertyUpdated onStatePropertyDeleted onStateChangeActionEnabled onStateChangeActionUpdated onStateChangeActionDisabled onStateChangeEventRegistered onStateChangeEventRegistrationUpdated onStateChangeEventUnregistered onStateChangeRelationshipInstanceDeleted onStateChangeRelationshipDeleted onStateChangeRelationshipInstanceCreated onStateChangeRelationshipCreated onDigitalTwinStateEventNotificationReceived The Signature of the following methods have been changed: onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) -&gt; onDigitalTwinSync(DigitalTwinState currentDigitalTwinState) onDigitalTwinUnSync(IDigitalTwinState currentDigitalTwinState) -&gt; onDigitalTwinUnSync(DigitalTwinState currentDigitalTwinState) New methods that have been added are: onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList&lt;DigitalTwinStateChange&gt; digitalTwinStateChangeList) onEventNotificationReceived(DigitalTwinStateEventNotification&lt;?Change Log 0.4.0https://wldt.github.io/docs/change-logs/change-log-0.4.0/Thu, 29 Aug 2024 17:24:16 +0200https://wldt.github.io/docs/change-logs/change-log-0.4.0/New Features WldtEventObserver A new class called WldtEventObserver has been introduced to allow a simplified observation of target specific events generated by the Digital Twin and its components such as adapters and the model. \ No newline at end of file diff --git a/docs/change-logs/sitemap.xml b/docs/change-logs/sitemap.xml index 6c255d0..67c037c 100644 --- a/docs/change-logs/sitemap.xml +++ b/docs/change-logs/sitemap.xml @@ -1 +1 @@ -https://wldt.github.io/docs/change-logs/change-log-0.3.0/2024-03-15T10:45:36+01:00monthly0.5 \ No newline at end of file +https://wldt.github.io/docs/change-logs/change-log-0.3.0/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/change-logs/change-log-0.4.0/2024-09-05T15:02:33+02:00monthly0.5 \ No newline at end of file diff --git a/docs/guides/configurable-adapters/index.html b/docs/guides/configurable-adapters/index.html index 80278bb..f88a7f8 100644 --- a/docs/guides/configurable-adapters/index.html +++ b/docs/guides/configurable-adapters/index.html @@ -2,16 +2,16 @@ Configurable Adapters | WLDT

Configurable Adapters

The WLDT library provides a native method to define Configurable Physical ad Digital Adapters specifying a custom configuration class passed as parameter in the constructor.

Starting with the Physical Adapter created in the previous example DemoPhysicalAdapter instead of extending the base class PhysicalAdapter we can extend now ConfigurablePhysicalAdapter<C> where C is the name of the that we would like to use as configuration.

In our example we can create a simple configuration class called DemoPhysicalAdapterConfiguration where we move @@ -233,5 +233,5 @@ } } } -

+
\ No newline at end of file diff --git a/docs/guides/digital-actions/index.html b/docs/guides/digital-actions/index.html index 55c968c..7e5b2a5 100644 --- a/docs/guides/digital-actions/index.html +++ b/docs/guides/digital-actions/index.html @@ -2,16 +2,16 @@ Digital Actions | WLDT

Digital Actions

In this demo implementation, we are going to emulate an incoming Digital Action on the Digital Adapter in order to show how it can be handled by the adapter and properly forwarded to the Shadowing Function for validation and the consequent interaction with the Physical Adapter and then with the physical twin.

In order to add a demo Digital Action trigger on the Digital Adapter we add the following method to the DemoDigitalAdapter class:

private Runnable emulateIncomingDigitalAction(){
     return () -> {
         try {
@@ -71,5 +71,5 @@
         e.printStackTrace();
     }
 }
-
+
\ No newline at end of file diff --git a/docs/guides/digital-adapter/index.html b/docs/guides/digital-adapter/index.html index 98fdd65..c2054e7 100644 --- a/docs/guides/digital-adapter/index.html +++ b/docs/guides/digital-adapter/index.html @@ -2,16 +2,16 @@ Digital Adapter | WLDT

Digital Adapter

The las component that we have to implement to complete our first simple Digital Twin definition through the WLDT library is a Digital Adapter in charge of:

  • Receiving event from the DT’s Core related to the variation of properties, events, available actions and relationships
  • Expose received information to the external world according to its implementation and the supported protocol
  • Handle incoming digital action and forward them to the Core in order to be validated and processed by the Shadowing Function

The basic library class that we are going to extend is called DigitalAdapter and creating a new class named DemoDigitalAdapter. The DigitalTwinAdapter class can take as Generic Type the type of Configuration used to configure its behaviours. In this simplified example we are defining a DigitalAdapter without any Configuration.

A Digital Adapter has direct access to the current DT’s State through callbacks or directly in a synchronous way using the @@ -190,5 +190,5 @@ }

In this example, the method iterates over the list of state changes, extracts information about each change, and performs custom actions based on the changes. Developers can adapt this method to suit the specific requirements of their Digital Twin application.

Both Physical Adapters and Digital Adapters can be defined natively with a custom configuration provided by the developer -as illustrated in the dedicated Section: Configurable Physical & Digital Adapters.

+as illustrated in the dedicated Section: Configurable Physical & Digital Adapters.

\ No newline at end of file diff --git a/docs/guides/dt-engine-dt-instance/index.html b/docs/guides/dt-engine-dt-instance/index.html index 4280321..db9b84e 100644 --- a/docs/guides/dt-engine-dt-instance/index.html +++ b/docs/guides/dt-engine-dt-instance/index.html @@ -2,16 +2,16 @@ DT Engine & DT Instance | WLDT

DT Engine & DT Instance

Now that we have created the main fundamental element of a DT (Physical Adapter, Shadowing Function and Digital Adapter) we can create Class file with a main to create the WLDT Engine with the created components and start the DT.

Create a new Java file called DemoDigitalTwin adding the following code:

With the following code we now create a new Digital Twin Instance

// Create the new Digital Twin with its Shadowing Function  
 DigitalTwin digitalTwin = new DigitalTwin(digitalTwinId, new DemoShadowingFunction());  
   
@@ -87,5 +87,5 @@
         }
     }
 }
-
+
\ No newline at end of file diff --git a/docs/guides/dt-relationships/index.html b/docs/guides/dt-relationships/index.html new file mode 100644 index 0000000..6784296 --- /dev/null +++ b/docs/guides/dt-relationships/index.html @@ -0,0 +1,182 @@ + +DT Relationships | WLDT

DT Relationships

The same management that we have illustrated for Properties, Events and Action can be applied also to Digital Twin Relationships. +Relationships represent the links that exist between the modeled physical assets and other physical entity +of the organizations through links to their corresponding Digital Twins. +Like properties, relationships can be observed, dynamically created, and change over time, +but unlike properties, they are not properly part of the PA’s state but of its operational context +(e.g., a DT of a robot within a production line).

It is necessary to distinguish between two concepts: i) Relationship; and ii) Relationship Instance. +The first one models the relationship from a semantic point of view, +defining its name and target type. +The second one represents an instantiation of the concept in reality. +For example, in the context of a Smart Home, +the Home Digital Twin (DT) will define a Relationship called has_room +which has possible targets represented by DTs that represent different rooms of the house. +The actual link between the Home DT and the Bedroom DT +will be modeled by a specific Relationship Instance of the has_room relationship.

Within the state of the DT, it is necessary to +differentiate between the concept of a relationship and that of an instance of a relationship. +In the first case, we refer to a semantic concept where each relationship, +through its name and the semantic type of its target, +determines the different type of link that the DT can establish. +On the other hand, an instanc of a relationship represents the concrete +link present between the DT that establishes it and the target DT. +For instance, in the case of a Smart Home, +the Bedroom DT may have two relationships in its model: one named is_room_of and another called has_device. +An instance of the first type of relationship could, for example, +have the Home DT as its target, while the has_device relationship could have +multiple instances, one for each device present in the room. +An example of a possible instance is one targeting the Air Conditioner DT.

From an implementation perspective, in the Physical Adapter and in particular where we handle the definition of the PAD we can also +specify the existing relationships. In our case, since the Relationship is useful also to define its future instance we +keep a reference of the relationship as in internal variable called insideInRelationship.

Then we can update the code as follows:

private PhysicalAssetRelationship<String> insideInRelationship = null;
+
+@Override
+public void onIncomingPhysicalAction(PhysicalAssetActionWldtEvent<?> physicalAssetActionWldtEvent) {
+    try{
+        
+        [...]
+        
+        //Create Test Relationship to describe that the Physical Device is inside a building
+        this.insideInRelationship=new PhysicalAssetRelationship<>("insideId");
+        pad.getRelationships().add(insideInRelationship);
+        
+        [...]
+        
+    } catch (Exception e){
+        e.printStackTrace();
+    }
+}
+

Of course always in the Physical Adapter we need to publish an effective instance of the definite Relationship. +To do that, we have defined a dedicated method that we can call inside the adapter to notify the DT’s Core and in +particular the Shadowing Function on the presence of a new Relationship.

The following method can be added for example at the beginning of the Device Emulation:

private void publishPhysicalRelationshipInstance() {
+    try{
+
+        String relationshipTarget = "building-hq";
+
+        Map<String, Object> relationshipMetadata = new HashMap<>();
+        relationshipMetadata.put("floor", "f0");
+        relationshipMetadata.put("room", "r0");
+
+        PhysicalAssetRelationshipInstance<String> relInstance = this.insideInRelationship.createRelationshipInstance(relationshipTarget, relationshipMetadata);
+
+        PhysicalAssetRelationshipInstanceCreatedWldtEvent<String> relInstanceEvent = new PhysicalAssetRelationshipInstanceCreatedWldtEvent<>(relInstance);
+        publishPhysicalAssetRelationshipCreatedWldtEvent(relInstanceEvent);
+
+    }catch (Exception e){
+        e.printStackTrace();
+    }
+}
+

On the other hand, as already done for all the other Properties, Actions and Events we have to handle them on the +Shadowing Function and in particular updating the onDigitalTwinBound(...) method managing Relationship declaration. +Also for the Relationships there is the method denoted as observePhysicalAssetRelationship(relationship) to observe the variation +of the target entity.

@Override
+protected void onDigitalTwinBound(Map<String, PhysicalAssetDescription> adaptersPhysicalAssetDescriptionMap) {
+
+    try{
+
+        //Iterate over all the received PAD from connected Physical Adapters
+        adaptersPhysicalAssetDescriptionMap.values().forEach(pad -> {
+            
+            [...]
+
+            //Iterate over Physical Relationships
+            pad.getRelationships().forEach(relationship -> {
+                try{
+                    if(relationship != null && relationship.getName().equals(GlobalKeywords.INSIDE_IN_RELATIONSHIP)){
+                        DigitalTwinStateRelationship<String> insideInDtStateRelationship = new DigitalTwinStateRelationship<>(relationship.getName(), relationship.getName());
+                        this.digitalTwinState.createRelationship(insideInDtStateRelationship);
+                        observePhysicalAssetRelationship(relationship);
+                    }
+                }catch (Exception e){
+                    e.printStackTrace();
+                }
+            });
+
+        });
+
+        [...]
+
+    }catch (Exception e){
+        e.printStackTrace();
+    }
+}
+

When an Instance for a target observed Relationship has been notified by the Physical Adapter, we will receive a call back on the +Shadowing Function method called: onPhysicalAssetRelationshipEstablished(PhysicalAssetRelationshipInstanceCreatedWldtEvent<?> physicalAssetRelationshipInstanceCreatedWldtEvent). +The object PhysicalAssetRelationshipInstanceCreatedWldtEvent describes the events and contains an object PhysicalAssetRelationshipInstance +with all the information about the new Relationship Instance.

The Shadowing Function analyzes the instance and create the corresponding Digital Relationship instance on the DT’State +through the class DigitalTwinStateRelationshipInstance and the method this.digitalTwinState.addRelationshipInstance(relName, instance);. +The resulting implemented method is the following:

//// Physical Relationships Notification Callbacks ////
+@Override
+protected void onPhysicalAssetRelationshipEstablished(PhysicalAssetRelationshipInstanceCreatedWldtEvent<?> physicalAssetRelationshipInstanceCreatedWldtEvent) {
+    try{
+
+        if(physicalAssetRelationshipInstanceCreatedWldtEvent != null
+        && physicalAssetRelationshipInstanceCreatedWldtEvent.getBody() != null){
+    
+            PhysicalAssetRelationshipInstance<?> paRelInstance = physicalAssetRelationshipInstanceCreatedWldtEvent.getBody();
+        
+            if(paRelInstance.getTargetId() instanceof String){
+        
+                String relName = paRelInstance.getRelationship().getName();
+                String relKey = paRelInstance.getKey();
+                String relTargetId = (String)paRelInstance.getTargetId();
+            
+                DigitalTwinStateRelationshipInstance<String> instance = new DigitalTwinStateRelationshipInstance<String>(relName, relTargetId, relKey);
+
+                //Update Digital Twin State
+                //NEW from 0.3.0 -> Start State Transaction
+                this.digitalTwinStateManager.startStateTransaction();
+  
+                this.digitalTwinStateManager.addRelationshipInstance(instance);
+  
+                //NEW from 0.3.0 -> Commit State Transaction
+                this.digitalTwinStateManager.commitStateTransaction();
+            }
+        }
+    }catch (Exception e){
+        e.printStackTrace();
+    }
+}
+
+@Override
+protected void onPhysicalAssetRelationshipDeleted(PhysicalAssetRelationshipInstanceDeletedWldtEvent<?> physicalAssetRelationshipInstanceDeletedWldtEvent) {
+
+}
+

At the end the new DT’s Relationships and the associated instances can be managed +on a Digital Adapter using the onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) method and +the following DT state callback method: onStateUpdate().

For example a simple implementation logging on the console can be:

@Override
+protected void onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList<DigitalTwinStateChange> digitalTwinStateChangeList) {
+
+  // In newDigitalTwinState we have the new DT State
+  System.out.println("New DT State is: " + newDigitalTwinState);
+
+  // The previous DT State is available through the variable previousDigitalTwinState
+  System.out.println("Previous DT State is: " + previousDigitalTwinState);
+
+  // We can also check each DT's state change potentially differentiating the behaviour for each change
+  if (digitalTwinStateChangeList != null && !digitalTwinStateChangeList.isEmpty()) {
+
+    // Iterate through each state change in the list
+    [...]
+
+      // Specific log example for Relationships Instance Variation
+      if(resourceType.equals(DigitalTwinStateChange.ResourceType.RELATIONSHIP_INSTANCE))
+        System.out.println("New Relationship Instance operation:" + operation + " Resource:" + resource);
+    }
+  } else {
+    // No state changes
+    System.out.println("No state changes detected.");
+  }
+}
+
+
\ No newline at end of file diff --git a/docs/guides/index.html b/docs/guides/index.html index bcaecc9..29152c8 100644 --- a/docs/guides/index.html +++ b/docs/guides/index.html @@ -2,10 +2,10 @@ Getting Started | WLDT
+
\ No newline at end of file diff --git a/docs/guides/index.xml b/docs/guides/index.xml index 42749b0..39e89ed 100644 --- a/docs/guides/index.xml +++ b/docs/guides/index.xml @@ -1 +1 @@ -Getting Started on WLDThttps://wldt.github.io/docs/guides/Recent content in Getting Started on WLDTHugo -- gohugo.ioenCopyright (c) 2023 HyasFri, 09 Feb 2024 12:11:11 +0100Physical Adapterhttps://wldt.github.io/docs/guides/physical-adapter/Fri, 09 Feb 2024 12:09:02 +0100https://wldt.github.io/docs/guides/physical-adapter/The developer can use an existing Physical Adapter or create a new one to handle the communication with a specific physical twin.Shadowing Functionhttps://wldt.github.io/docs/guides/shadowing-function/Fri, 09 Feb 2024 12:15:33 +0100https://wldt.github.io/docs/guides/shadowing-function/After the definition of the Physical Adapter it is time to start implementing the core of our DT through the definition of its shadowing function in charge of:Digital Adapterhttps://wldt.github.io/docs/guides/digital-adapter/Fri, 09 Feb 2024 12:16:06 +0100https://wldt.github.io/docs/guides/digital-adapter/The las component that we have to implement to complete our first simple Digital Twin definition through the WLDT library is a Digital Adapter in charge of:DT Engine & DT Instancehttps://wldt.github.io/docs/guides/dt-engine-dt-instance/Fri, 09 Feb 2024 12:16:36 +0100https://wldt.github.io/docs/guides/dt-engine-dt-instance/Now that we have created the main fundamental element of a DT (Physical Adapter, Shadowing Function and Digital Adapter) we can create Class file with a main to create the WLDT Engine with the created components and start the DT.Digital Actionshttps://wldt.github.io/docs/guides/digital-actions/Fri, 09 Feb 2024 12:18:13 +0100https://wldt.github.io/docs/guides/digital-actions/In this demo implementation, we are going to emulate an incoming Digital Action on the Digital Adapter in order to show how it can be handled by the adapter and properly forwarded to the Shadowing Function for validation and the consequent interaction with the Physical Adapter and then with the physical twin.Configurable Adaptershttps://wldt.github.io/docs/guides/configurable-adapters/Fri, 09 Feb 2024 12:19:37 +0100https://wldt.github.io/docs/guides/configurable-adapters/The WLDT library provides a native method to define Configurable Physical ad Digital Adapters specifying a custom configuration class passed as parameter in the constructor. \ No newline at end of file +Getting Started on WLDThttps://wldt.github.io/docs/guides/Recent content in Getting Started on WLDTHugo -- gohugo.ioenCopyright (c) 2023 HyasFri, 09 Feb 2024 12:11:11 +0100Physical Adapterhttps://wldt.github.io/docs/guides/physical-adapter/Fri, 09 Feb 2024 12:09:02 +0100https://wldt.github.io/docs/guides/physical-adapter/The developer can use an existing Physical Adapter or create a new one to handle the communication with a specific physical twin.Shadowing Functionhttps://wldt.github.io/docs/guides/shadowing-function/Fri, 09 Feb 2024 12:15:33 +0100https://wldt.github.io/docs/guides/shadowing-function/After the definition of the Physical Adapter it is time to start implementing the core of our DT through the definition of its shadowing function in charge of:Digital Adapterhttps://wldt.github.io/docs/guides/digital-adapter/Fri, 09 Feb 2024 12:16:06 +0100https://wldt.github.io/docs/guides/digital-adapter/The las component that we have to implement to complete our first simple Digital Twin definition through the WLDT library is a Digital Adapter in charge of:DT Engine & DT Instancehttps://wldt.github.io/docs/guides/dt-engine-dt-instance/Fri, 09 Feb 2024 12:16:36 +0100https://wldt.github.io/docs/guides/dt-engine-dt-instance/Now that we have created the main fundamental element of a DT (Physical Adapter, Shadowing Function and Digital Adapter) we can create Class file with a main to create the WLDT Engine with the created components and start the DT.Digital Actionshttps://wldt.github.io/docs/guides/digital-actions/Fri, 09 Feb 2024 12:18:13 +0100https://wldt.github.io/docs/guides/digital-actions/In this demo implementation, we are going to emulate an incoming Digital Action on the Digital Adapter in order to show how it can be handled by the adapter and properly forwarded to the Shadowing Function for validation and the consequent interaction with the Physical Adapter and then with the physical twin.DT Relationshipshttps://wldt.github.io/docs/guides/dt-relationships/Fri, 09 Feb 2024 12:19:08 +0100https://wldt.github.io/docs/guides/dt-relationships/The same management that we have illustrated for Properties, Events and Action can be applied also to Digital Twin Relationships. Relationships represent the links that exist between the modeled physical assets and other physical entity of the organizations through links to their corresponding Digital Twins.Configurable Adaptershttps://wldt.github.io/docs/guides/configurable-adapters/Fri, 09 Feb 2024 12:19:37 +0100https://wldt.github.io/docs/guides/configurable-adapters/The WLDT library provides a native method to define Configurable Physical ad Digital Adapters specifying a custom configuration class passed as parameter in the constructor.Storage Layerhttps://wldt.github.io/docs/guides/storage-layer/Thu, 29 Aug 2024 17:46:07 +0200https://wldt.github.io/docs/guides/storage-layer/The storage layer has been integrated into the core WLDT library, enabling Digital Twins to manually and automatically store data related to the evolution of their state, generated events (as illustrated in DT Events Page), and any variations involving properties, events, actions, relationships, and life cycle. \ No newline at end of file diff --git a/docs/guides/physical-adapter/index.html b/docs/guides/physical-adapter/index.html index 4882626..b64f431 100644 --- a/docs/guides/physical-adapter/index.html +++ b/docs/guides/physical-adapter/index.html @@ -2,16 +2,16 @@ Physical Adapter | WLDT

Physical Adapter

The developer can use an existing Physical Adapter or create a new one to handle the communication with a specific physical twin. In this documentation we focus on the creation of a new Physical Adapter in order to explain library core functionalities. However, existing Physical Adapters can be found on the official repository and linked in the core documentation and webpage (WLDT-GitHub).

In general WLDT Physical Adapter extends the class PhysicalAdapter and it is responsible to talk with the physical world and handling the following main tasks:

  • Generate a PAD describing the properties, events, actions and relationships available on the physical twin using the class PhysicalAssetDescription
  • Generate Physical Event using the class PhysicalAssetEventWldtEvent associated to the variation of any aspect of the physical state (properties, events, and relationships)
  • Handle action request coming from the Digital World through the DT Shadowing Function by implementing the method onIncomingPhysicalAction and processing events modeled through the class PhysicalAssetActionWldtEvent

Create a new class called DemoPhysicalAdapter extending the library class PhysicalAdapter and implement the following methods:

  • onAdapterStart: A callback method used to notify when the adapter has been effectively started withing the DT’s life cycle
  • onAdapterStop: A call method invoked when the adapter has been stopped and will be dismissed by the core
  • onIncomingPhysicalAction: The callback method called when a new PhysicalAssetActionWldtEvent is sent by the Shadowing Function upon the receiving of a valid Digital Action through a Digital Adapter

Then you have to create a constructor for your Physical Adapter with a single String parameter representing the id of the adapter. This id will be used internally by the library to handle and coordinate multiple adapters, adapts logs and execute functions upon the arrival of a new event. @@ -257,5 +257,5 @@ } }

Both Physical Adapters and Digital Adapters can be defined natively with a custom configuration provided by the developer -as illustrated in the dedicated Section: Configurable Physical & Digital Adapters.

+as illustrated in the dedicated Section: Configurable Physical & Digital Adapters.

\ No newline at end of file diff --git a/docs/guides/shadowing-function/index.html b/docs/guides/shadowing-function/index.html index 2ed487f..4bb9125 100644 --- a/docs/guides/shadowing-function/index.html +++ b/docs/guides/shadowing-function/index.html @@ -2,16 +2,16 @@ Shadowing Function | WLDT

Shadowing Function

After the definition of the Physical Adapter it is time to start implementing the core of our DT through the definition of its shadowing function in charge of:

  • Handle received PAD from Physical Adapters in order to device which properties, events, relationships or actions available on connected physical twins should be mapped and managed into the DT State
  • Manage incoming notifications/callbacks associated to the variation of physical properties (e.g, temperature variation) or the generation of physical event (e.g., overheating)
  • Process action requests from the digital world that should be validated and forward to the correct Physical Adapter in order to trigger the associated actions on the physical world

The Shadowing Function has the responsibility to build and maintain the updated state of the Digital Twin The internal variable of any WLDT Shadowing Function (available through the base class ShadowingFunction) used to do that is DigitalTwinStateManager accessible through the variable: this.digitalTwinStateManager

When the Shadowing Function has to compute the new DT State it can now work with the following method to handle DT State Transition:

  • Start the DT State Transaction: startStateTransaction()
  • DT State variation methods such as:
    • createProperty()
    • updateProperty()
    • updatePropertyValue()
    • deleteProperty()
    • enableAction()
    • updateAction()
    • disableAction()
    • registerEvent()
    • updateRegisteredEvent()
    • unRegisterEvent()
    • createRelationship()
    • addRelationshipInstance()
    • deleteRelationship()
    • deleteRelationshipInstance()
  • At the end the transaction can be committed using the method: commitStateTransaction()

To access the current DT State the Shadowing Function implementation can use the method this.digitalTwinStateManager.getDigitalTwinState() The information available on the DT State are:

  • properties: List of Properties with their values (if available)
  • actions: List of Actions that can be called on the DT
  • events: List of Events that can be generated by the DT
  • relationships: List of Relationships and their instances (if available)
  • evaluationInstant: The timestamp representing the evaluation instant of the DT state

Available main methods on that class instance are:

  • Properties:
    • getProperty(String propertyKey): Retrieves if present the target DigitalTwinStateProperty by Key
    • containsProperty(String propertyKey): Checks if a target Property Key is already available in the current Digital Twin’s State
    • getPropertyList(): Loads the list of available Properties (described by the class DigitalTwinStateProperty) available on the Digital Twin’s State
    • createProperty(DigitalTwinStateProperty<?> dtStateProperty): Allows the creation of a new Property on the Digital Twin’s State through the class DigitalTwinStateProperty
    • readProperty(String propertyKey): Retrieves if present the target DigitalTwinStateProperty by Key
    • updateProperty(DigitalTwinStateProperty<?> dtStateProperty): Updates the target property using the DigitalTwinStateProperty and the associated Property Key field
    • deleteProperty(String propertyKey): Deletes the target property identified by the specified key
  • Actions:
    • containsAction(String actionKey): Checks if a Digital Twin State Action with the specified key is correctly registered
    • getAction(String actionKey): Loads the target DigitalTwinStateAction by key
    • getActionList(): Gets the list of available Actions registered on the Digital Twin’s State
    • enableAction(DigitalTwinStateAction digitalTwinStateAction): Enables and registers the target Action described through an instance of the DigitalTwinStateAction class
    • updateAction(DigitalTwinStateAction digitalTwinStateAction): Update the already registered target Action described through an instance of the DigitalTwinStateAction class
    • disableAction(String actionKey): Disables and unregisters the target Action described through an instance of the DigitalTwinStateAction class
  • Events:
    • containsEvent(String eventKey): Check if a Digital Twin State Event with the specified key is correctly registered
    • getEvent(String eventKey): Return the description of a registered Digital Twin State Event according to its Key
    • getEventList(): Return the list of existing and registered Digital Twin State Events
    • registerEvent(DigitalTwinStateEvent digitalTwinStateEvent): Register a new Digital Twin State Event
    • updateRegisteredEvent(DigitalTwinStateEvent digitalTwinStateEvent): Update the registration and signature of an existing Digital Twin State Event
    • unRegisterEvent(String eventKey): Un-register a Digital Twin State Event
    • notifyDigitalTwinStateEvent(DigitalTwinStateEventNotification<?> digitalTwinStateEventNotification): Method to notify the occurrence of the target Digital Twin State Event
  • Relationships:
    • containsRelationship(String relationshipName): Checks if a Relationship Name is already available in the current Digital Twin’s State
    • createRelationship(DigitalTwinStateRelationship<?> relationship): Creates a new Relationships (described by the class DigitalTwinStateRelationship) in the Digital Twin’s State
    • addRelationshipInstance(String name, DigitalTwinStateRelationshipInstance<?> instance): Adds a new Relationship instance described through the class DigitalTwinStateRelationshipInstance and identified through its name
    • getRelationshipList(): Loads the list of existing relationships on the Digital Twin’s State through a list of DigitalTwinStateRelationship
    • getRelationship(String name): Gets a target Relationship identified through its name and described through the class DigitalTwinStateRelationship
    • deleteRelationship(String name): Deletes a target Relationship identified through its name
    • deleteRelationshipInstance(String relationshipName, String instanceKey): Deletes the target Relationship Instance using relationship name and instance Key

The basic library class that we are going to extend is called ShadowingFunction and creating a new class named DemoShadowingFunction the resulting @@ -273,5 +273,5 @@ to the Physical Adapter with the method of the Shadowing Function denoted as this.publishPhysicalAssetActionWldtEvent and passing directly the action key and the target Body. No additional processing or validation have been introduced here, but they might be required in advanced scenario in order to properly adapt incoming digital action request to what is effectively expected on the -physical counterpart.

+physical counterpart.

\ No newline at end of file diff --git a/docs/guides/sitemap.xml b/docs/guides/sitemap.xml index 864bad4..61d7373 100644 --- a/docs/guides/sitemap.xml +++ b/docs/guides/sitemap.xml @@ -1 +1 @@ -https://wldt.github.io/docs/guides/physical-adapter/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/shadowing-function/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/digital-adapter/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/dt-engine-dt-instance/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/digital-actions/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/configurable-adapters/2024-03-15T10:45:36+01:00monthly0.5 \ No newline at end of file +https://wldt.github.io/docs/guides/physical-adapter/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/shadowing-function/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/digital-adapter/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/dt-engine-dt-instance/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/digital-actions/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/dt-relationships/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/configurable-adapters/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/storage-layer/2024-09-05T15:02:33+02:00monthly0.5 \ No newline at end of file diff --git a/docs/guides/storage-layer/index.html b/docs/guides/storage-layer/index.html new file mode 100644 index 0000000..d981d87 --- /dev/null +++ b/docs/guides/storage-layer/index.html @@ -0,0 +1,130 @@ + +Storage Layer | WLDT

Storage Layer

The storage layer has been integrated into the core WLDT library, enabling Digital Twins to manually and automatically store data related to the evolution of their state, generated events (as illustrated in DT Events Page), and any variations involving properties, events, actions, relationships, and life cycle.

The WLDT Storage Layer consists of two main components:

  • Storage Manager: This is the central component of the storage system, facilitating the structured and modular storage and retrieval of information. It allows developers to create and utilize various storage systems (e.g., in-memory, file-based, or DBMS) simultaneously. The Storage Layer is accessible in both read and write modes internally by the DT’s Model, and in read-only mode via the Query System by Digital Adapters.
  • Query System: To delegate and encapsulate the responsibility of data storage within the DT’s model, a query system has been integrated. This system enables Digital Adapters to retrieve stored data and expose it according to their specific logic and implementation.

The storage layer is designed for easy extension, allowing developers to create and share new storage layers (e.g., using Redis, MySQL, or MongoDB). The provided in-memory implementation serves only for basic development and testing purposes. Similarly, the Query Manager can be extended and customized by developers to implement additional query management features or to enhance the default functionalities provided by the library.

Storage Manager

The main module of the Storage Layer is the one associated to Storage Capabilities and it is composed by two main classes: StorageManager and WldStorage with the following characteristics and main methods:

  • StorageManager: The StorageManager class is a class that represents the storage manager for a DigitalTwin. It is responsible for managing the storage of the data related to the DigitalTwin. It is an observer of the WldtEventBus, and it is able to save the data in the available storages. The class extends a DigitalTwinWorker, in order to allow the component to work in a structure and integrated way on a different thread that the core of a DT can coordinate starting and stopping it when required. The manager allow the usage of different storage systems at the same time in order to allow the developers to memorize the information accordingly to their need in the right storage system at the same time (e.g., REDIS for quick cached information and MongDB for historical data). Main associated methods are:
    • putStorage(WldtStorage storage): Add a new WldtStorage to the StorageManager
    • getStorageIdList(): Returns the list of id of the WldtStorage in the StorageManager
    • isStorageAvailable(String storageId): Checks if a target Storage Id is available in the Storage Manager
    • getStorage(String storageId): Get the target WldtStorage by id from the Storage Manager
    • removeStorage(String storageId): Remove an existing WldtStorage by id from the StorageManager
  • WldtStorage: Defines an abstract class allowing the Digital Twin developer to implement its internal storage system for the Digital Twin instance.
    • The class defines methods for the management of:
      • Digital Twin State storage and retrieval with the associated change list;
      • Generated State Digital Events;
      • Life Cycle State storage and retrieval;
      • Physical Asset Description storage and retrieval;
      • Physical Asset Property Variation storage and retrieval;
      • Physical Asset Relationship Instance storage and retrieval;
      • Digital Action Request storage and retrieval;
      • Physical Asset Action Request storage and retrieval;
      • Physical Asset Event Notification storage and retrieval;
    • Each WldtStorage instance can be configured (using the right constructor method) to:
      • Observe all Wldt events (stateEvents, physicalAssetEvents, physicalAssetActionEvents, physicalAssetDescriptionEvents, digitalActionEvents, lifeCycleEvents)
      • Filter only for specific class of events
      • Once the WldtStorage has been properly configured to receive target events the StorageManager automatically save information of interest for that specific storage. For example we can have a StorageA (e.g, REDIS) configured to receive all the generated events and a StorageB (e.g., MongoDB) in charge of saving only DT’s state variation over time.
    • The default implementation of the WldtStorage is the class DefaultWldtStorage. This class provides a simple storage solution for digital twin states, digital twin state changes, physical asset events, and digital twin events. The class provides ONLY a memory based approach for storage using ArrayLists and HashMaps and more advanced solution should be implemented for production oriented Digital Twins for examples using external storage and memorization solutions.
    • Each Record written and returned by methods available through the WldtStorage implementations are extension of the StorageRecord used to represents a single record in the storage with a unique id
    • Methods available and implemented by WldtStorage implementations are the following grouped by categories:
      • Digital Twin State:
        • saveDigitalTwinState(DigitalTwinState digitalTwinState, List<DigitalTwinStateChange> digitalTwinStateChangeList): Save a new computed instance of the DT State in the Storage together with the list of the changes with respect to the previous state
        • getLastDigitalTwinState(): Returns the latest computed Digital Twin State of the target Digital Twin instance
        • getDigitalTwinStateCount(): Returns the number of computed and stored Digital Twin States
        • getDigitalTwinStateInTimeRange(long startTimestampMs, long endTimestampMs): Retrieves a list of DigitalTwinState objects within the specified time range
        • getDigitalTwinStateInRange(int startIndex, int endIndex): Retrieves a list of Digital Twin states within the specified range of indices
      • Digital Twin State Event Notification:
        • saveDigitalTwinStateEventNotification(DigitalTwinStateEventNotification<?> digitalTwinStateEventNotification): Save the Digital Twin State Event Notification
        • getDigitalTwinStateEventNotificationCount(): Get the number of Digital Twin State Event Notification
        • getDigitalTwinStateEventNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Digital Twin State Event Notification in the specified time range
        • getDigitalTwinStateEventNotificationInRange(int startIndex, int endIndex): Get the Digital Twin State Event Notification in the specified range of indices
      • Life Cycle State Variation:
        • saveLifeCycleState(LifeCycleStateVariation lifeCycleStateVariation): Save the LifeCycleState of the Digital Twin
        • getLastLifeCycleState(): Get the last LifeCycleState of the Digital Twin
        • getLifeCycleStateCount(): Get the number of LifeCycleState of the Digital Twin
        • getLifeCycleStateInTimeRange(long startTimestampMs, long endTimestampMs): Get the last LifeCycleState of the Digital Twin
        • getLifeCycleStateInRange(int startIndex, int endIndex): Get the LifeCycleState of the Digital Twin in the specified range of indices
      • Physical Asset Event Notification:
        • savePhysicalAssetEventNotification(PhysicalAssetEventNotification physicalAssetEventNotification): Save the Physical Asset Event Notification
        • getPhysicalAssetEventNotificationCount(): Get the number of Physical Asset Event Notification
        • getPhysicalAssetEventNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Event Notification in the specified time range
        • getPhysicalAssetEventNotificationInRange(int startIndex, int endIndex): Get the Physical Asset Event Notification in the specified range of indices
      • Physical Action Request:
        • savePhysicalAssetActionRequest(PhysicalAssetActionRequest physicalAssetActionRequest): Save Physical Asset Action Request
        • getPhysicalAssetActionRequestCount(): Get the number of Physical Asset Action Request
        • getPhysicalAssetActionRequestInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Action Request in the specified time range
        • getPhysicalAssetActionRequestInRange(int startIndex, int endIndex): Get the Physical Asset Action Request in the specified range of indices
      • Digital Action Request:
        • saveDigitalActionRequest(DigitalActionRequest digitalActionRequest): Save a Digital Action Request
        • getDigitalActionRequestCount(): Get the number of Digital Action Request Stored
        • getDigitalActionRequestInTimeRange(long startTimestampMs, long endTimestampMs): Get the Digital Action Request in the specified time range
        • getDigitalActionRequestInRange(int startIndex, int endIndex): Get the Digital Action Request in the specified range of indices
      • Physical Asset Description (PAD) Notification
        • New PAD Notification
          • saveNewPhysicalAssetDescriptionNotification(PhysicalAssetDescriptionNotification physicalAssetDescriptionNotification): Save a new Physical Asset Description Available
          • getNewPhysicalAssetDescriptionNotificationCount(): Get the number of New Physical Asset Description Notifications available
          • getNewPhysicalAssetDescriptionNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the New Physical Asset Description Available in the specified time range
          • getNewPhysicalAssetDescriptionNotificationInRange(int startIndex, int endIndex): Get the New Physical Asset Description Available in the specified range of indices
        • Updated PAD Notification
          • saveUpdatedPhysicalAssetDescriptionNotification(PhysicalAssetDescriptionNotification physicalAssetDescriptionNotification): Save the updated Physical Asset Description Notification
          • getUpdatedPhysicalAssetDescriptionNotificationCount(): Get the number of Updated Physical Asset Description
          • getUpdatedPhysicalAssetDescriptionNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Updated Physical Asset Description in the specified time range
          • getUpdatedPhysicalAssetDescriptionNotificationInRange(int startIndex, int endIndex): Get the Updated Physical Asset Description in the specified range of indices
      • Physical Asset Property Variation:
        • savePhysicalAssetPropertyVariation(PhysicalAssetPropertyVariation physicalAssetPropertyVariation): Save the Physical Asset Property Variation
        • getPhysicalAssetPropertyVariationCount(): Get the number of Physical Asset Property Variation
        • getPhysicalAssetPropertyVariationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Property Variation in the specified time range
        • getPhysicalAssetPropertyVariationInRange(int startIndex, int endIndex): Get the Physical Asset Property Variation in the specified range of indices
      • Physical Asset Relationship Instance Notification
        • Created Relationship Instance
          • savePhysicalAssetRelationshipInstanceCreatedNotification(PhysicalRelationshipInstanceVariation physicalRelationshipInstanceVariation): Save the Physical Asset Relationship Instance Created Event
          • getPhysicalAssetRelationshipInstanceCreatedNotificationCount(): Get the number of Physical Asset Relationship Instance Created Event
          • getPhysicalAssetRelationshipInstanceCreatedNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Relationship Instance Created Event in the specified time range
          • getPhysicalAssetRelationshipInstanceCreatedNotificationInRange(int startIndex, int endIndex): Get the Physical Asset Relationship Instance Created Event in the specified range of indices
        • Deleted Relationship Instance
          • savePhysicalAssetRelationshipInstanceDeletedNotification(PhysicalRelationshipInstanceVariation physicalRelationshipInstanceVariation): Save the Physical Asset Relationship Instance Updated Event
          • getPhysicalAssetRelationshipInstanceDeletedNotificationCount(): Get the number of Physical Asset Relationship Instance Updated Event
          • getPhysicalAssetRelationshipInstanceDeletedNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Relationship Instance Updated Event in the specified time range
          • getPhysicalAssetRelationshipInstanceDeletedNotificationInRange(int startIndex, int endIndex): Get the Physical Asset Relationship Instance Updated Event in the specified range of indices
      • Storage Statistics:
        • Retrieve and returns storage statistics in terms of the number of stored records for each type and the associated time range of the stored records (start and end timestamp in milliseconds). Storage Statistics are mapped and modeled using the classes StorageStats and StorageStatsRecord.

Storage Manager Code

Some examples of usage for the Storage Layer are the following:

Lets’ create a new Digital Twin with a single Storage in charge of automatically observe and store all the event generated and going through the target DT instance

// Create the Digital Twin Engine
+DigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine();  
+
+// Create a new Digital Twin with a Demo Shadowing Function
+DigitalTwin digitalTwin = new DigitalTwin(TEST_DIGITAL_TWIN_ID, new DemoShadowingFunction());
+
+// Physical Adapter Configuration  
+DemoPhysicalAdapter physicalAdapter = new DemoPhysicalAdapter(...);  
+digitalTwin.addPhysicalAdapter(physicalAdapter);
+
+// Digital Adapter Configuration
+digitalAdapter = new DemoDigitalAdapter(...);  
+digitalTwin.addDigitalAdapter(digitalAdapter);
+
+// Create a new WldtStorage instance using the default implementation and observing all the events  
+DefaultWldtStorage myStorage = new DefaultWldtStorage("test_storage", true);
+
+// Add the new Default Storage Instance to the Digital Twin Storage Manager 
+digitalTwin.getStorageManager().putStorage(myStorage);
+
+// Add the Twin to the Engine  
+digitalTwinEngine.addDigitalTwin(digitalTwin);  
+  
+// Start the Digital Twin  
+digitalTwinEngine.startDigitalTwin(TEST_DIGITAL_TWIN_ID);
+

Now let’s suppose to have two additional implementation of the WldtStorage class supporting Redis and MongDB and called RedisWldtStorage and MongoDbWldtStorage. +We would like to use Redis to automatically observe all the events and MongoDb only to store DT’s state and life cycle variations.

[...]
+
+// Create a new RedisWldtStorage instance using the default implementation and observing all the events  
+RedisWldtStorage myRedisStorage = new RedisWldtStorage("redis_storage", true);
+myRedisStorage.setRedisConfiguration(myRedisConfiguration);
+
+// Add the new Redis Storage Instance to the Digital Twin Storage Manager 
+digitalTwin.getStorageManager().putStorage(myRedisStorage);
+
+// Create a new MongoDbWldtStorage instance using the default implementation and observing only State and LifeCycle Events
+MongoDbWldtStorage myMongoDbStorage = new MongoDbWldtStorage("mongo_db_storage", true, false, false, false, false, true);
+myMongoDbStorage.setMongoDbConfiguration(myMongoDbConfiguration);
+
+// Add the new MongoDb Storage Instance to the Digital Twin Storage Manager 
+digitalTwin.getStorageManager().putStorage(myRedisStorage);
+
+[...]
+

Within the ShadowingFunction it is possible to have the reference to the StorageManager in order to access available Storage in both reading and writing mode. +This is an example of how to retrieve an available WldtStorage through its id and the use it to read Properties values in a time range of the last 5 minutes:

String TARGET_STORAGE_ID = "test_storage";  
+  
+if(this.storageManager.isStorageAvailable(TARGET_STORAGE_ID)){  
+  
+    // Access the Storage Manager to store the last value of the property  
+    WldtStorage targetStorage = this.storageManager.getStorage(TARGET_STORAGE_ID);  
+  
+    // Get the current time in milliseconds  
+    long endTime = System.currentTimeMillis();  
+  
+    // Get the Time in the last 5 minutes  
+    long startTime = endTime - (5 * 60 * 1000);  
+  
+    // Get the last Physical Asset Action Request in the last 5 minutes  
+    List<PhysicalAssetPropertyVariationRecord> propertyVariationRecords = targetStorage.getPhysicalAssetPropertyVariationInTimeRange(startTime, endTime);  
+        for(PhysicalAssetPropertyVariationRecord propertyVariationRecord : propertyVariationRecords){  
+        logger.info("Property Variation Record: {}", propertyVariationRecord);  
+        [...]  
+    }  
+}
+

Note: The StorageManager, as previously described, can automatically store DT-related events based on the configuration and setup of each WldtStorage instance added to the manager. However, since the ShadowingFunction has direct access to the StorageManager in both read and write modes, manual handling of data storage is also possible. To achieve this, you can disable automatic storage by setting it to false for specific event types or for all event types. This allows you to manually manage the storage of information within the ShadowingFunction.

Custom Storage

As previously mentioned, the class WldtStorage is an abstract class allowing the developer to implement its internal storage system for the Digital Twin instance. The class defines a set of abstract methods that should be implemented by the developer to shape the management of reading and writing data from and to the target Storage and associated to the identified variations and changes:

  • Digital Twin State
  • Generated State Digital Events
  • Life Cycle State
  • Physical Asset Description
  • Physical Asset Property Variation
  • Physical Asset Relationship Instance
  • Digital Action Request
  • Physical Asset Action Request
  • Physical Asset Event Notification
  • Storage Statistics

According to the type of the managed resource the type of queries can be characterized in terms of:

  • Time Query: Returns available records in a time range made by a start time in ms and and end time in ms
  • Index Query: Returns available records in a index range made a start and end index
  • Last Value Query: Return the last available value for the target resource
  • Count Query: Returns the number of element of that specific resource

All the stored and retrieve information and record as mapped into dedicated classes available in the package storage.model and associated to the different type of managed resources: digital, lifecycle, physical, state. Each record class extends the base class StorageRecord.

A default Storage module denoted as DefaultWldtStorage is natively available in the library providing a simple in-memory storage solution but a developer can implement its own Storage module (e.g., to enable the support for MongoDb or REDIS).

In order to implement its own storage module the developer should extend the basic abstract class WldtStorage and implement all the supported method to handle data writing and reading. These new classes can extend also the constructor and the required information for example to handle and manager storage configuration (e.g., ip address and port of the storage system or the local folder where tha stored file should be written).

Query System

Given the library’s goal of maximizing modularity and decoupling responsibilities among the available components, the Query System has been introduced. This system allows components external to the core responsibilities of the Digital Twin (e.g., Digital Adapters and Augmentation Functions) to retrieve stored data and use or expose it according to their specific logic and implementation. For instance, an HTTP Digital Adapter could expose stored information about a DT’s state variations over time, or a Monitoring Adapter could use available storage instances to retrieve events for a deeper understanding of the target DT instance’s behavior. The query system has been implemented entirely through dedicated events in order to maximize the decoupling of the solution and and supports at the same time both synchronous and asynchronous queries.

The main classes associated to the Query System are the following:

  • QueryManager: This class represents the Query Manager responsible to handle the query request and manage the query execution and has been designed to be extended by the user to implement the desired query management logic (e.g., as with the DefaultQueryManager).
  • QueryRequest: The class contains all the information needed to perform a query on the storage system
  • QueryRequestType: This Enum represents the Query Request Type used to specify the type of query to be performed on the storage system supporting:
    • TIME_RANGE
    • SAMPLE_RANGE
    • LAST_VALUE
    • COUNT
  • QueryResourceType: This Enum represents the Query Resource Type used to specify the type of resource to be queried on the storage system supporting the following resource types mapping those available and managed by the storage manager (and the supported and associated RequestType):
    • PHYSICAL_ASSET_PROPERTY_VARIATION
      • TIME_RANGE
      • SAMPLE_RANGE
      • COUNT
    • PHYSICAL_ASSET_EVENT_NOTIFICATION
      • TIME_RANGE
      • SAMPLE_RANGE
      • COUNT
    • PHYSICAL_ACTION_REQUEST
      • TIME_RANGE
      • SAMPLE_RANGE
      • COUNT
    • DIGITAL_ACTION_REQUEST
      • TIME_RANGE
      • SAMPLE_RANGE
      • COUNT
    • DIGITAL_TWIN_STATE
      • TIME_RANGE
      • SAMPLE_RANGE
      • COUNT
      • LAST_VALUE
    • NEW_PAD_NOTIFICATION
      • TIME_RANGE
      • SAMPLE_RANGE
      • COUNT
    • UPDATED_PAD_NOTIFICATION
      • TIME_RANGE
      • SAMPLE_RANGE
      • COUNT
    • PHYSICAL_RELATIONSHIP_INSTANCE_CREATED_NOTIFICATION
      • TIME_RANGE
      • SAMPLE_RANGE
      • COUNT
    • PHYSICAL_RELATIONSHIP_INSTANCE_DELETED_NOTIFICATION
      • TIME_RANGE
      • SAMPLE_RANGE
      • COUNT
    • LIFE_CYCLE_EVENT
      • TIME_RANGE
      • SAMPLE_RANGE
      • COUNT
      • LAST_VALUE
    • STORAGE_STATS
      • LAST_VALUE
  • QueryExecutor: This class represents the Query Executor used to execute queries on the storage system supporting both synchronous and asynchronous query execution. Internally is implemented through an event-based mechanism to handle the query request and response
  • QueryResult: This class represents the Query Result returned by the Query Executor containing the query results and the query status (successful or not) and error message (if any) together with also the original request
  • IQueryResultListener: This interface represents the Query Result Listener used to receive the query results

Query System Code

An example of Synchronous query is:

QueryExecutor queryExecutor = new QueryExecutor(TEST_DIGITAL_TWIN_ID, "query-executor");  
+  
+// Create Query Request to the Storage Manager for the Last Digital Twin State  
+QueryRequest queryRequest = new QueryRequest();  
+queryRequest.setResourceType(QueryResourceType.DIGITAL_TWIN_STATE);  
+queryRequest.setRequestType(QueryRequestType.LAST_VALUE);  
+  
+// Send the Query Request to the Storage Manager for the target DT  
+QueryResult<?> queryResult = queryExecutor.syncQueryExecute(queryRequest);
+

Following the same approach an Asynchrounouse query can be executed as follows:

QueryExecutor queryExecutor = new QueryExecutor(TEST_DIGITAL_TWIN_ID, "query-executor");  
+  
+// Create Query Request to the Storage Manager for the Last Digital Twin State  
+QueryRequest queryRequest = new QueryRequest();  
+queryRequest.setResourceType(QueryResourceType.DIGITAL_TWIN_STATE);  
+queryRequest.setRequestType(QueryRequestType.LAST_VALUE);  
+    
+// Send the Query Request to the Storage Manager for the target DT  
+queryExecutor.asyncQueryExecute(queryRequest, new IQueryResultListener() {  
+    @Override  
+    public void onQueryResult(QueryResult<?> queryResult) {  
+        [...]  
+    }  
+});
+

The class DigitalAdapter has been updated adding also an internal reference to a QueryExecutor in order to simplify the interaction with the query system directly from an adapter like in the following example where we use the query Executor of the Digital Adapter invokeAction callback through its internal variable accessible through this.queryExecutor without creating a new executor:

public <T> void invokeAction(String actionKey, T body){  
+    try {  
+          
+        // Create Query Request to the Storage Manager for the Last Digital Twin State  
+        QueryRequest queryRequest = new QueryRequest();  
+        queryRequest.setResourceType(QueryResourceType.DIGITAL_TWIN_STATE);  
+        queryRequest.setRequestType(QueryRequestType.LAST_VALUE);  
+  
+        // Send the Query Request to the Storage Manager for the target DT  
+        QueryResult<?> queryResult = this.queryExecutor.syncQueryExecute(queryRequest);  
+        
+        // Do Something with the Query Result  
+        for(Object result : queryResult.getResults()){  
+	        // Check the type of the Resulting class accordingly to the query
+		    if(result instanceof DigitalTwinState)  
+		        logger.info("LAST DT STATE: {}", result);  
+		    else
+			    logger.error("INVALID RESULT TYPE: {}", result.getClass().getName());  
+		}
+          
+        logger.info("INVOKING ACTION: {} BODY: {}", actionKey, body);  
+        publishDigitalActionWldtEvent(actionKey, body);  
+    } catch (EventBusException e) {  
+        e.printStackTrace();  
+    }  
+}
+

Custom Query Manager

The class in charge of managing an incoming query is called QueryManager and it is characterized by two core methods:

  • handleQuery(QueryRequest queryRequest, Map<String, WldtStorage> storageMap): Handle Query Request allowing its management through the storage map and the associated storage objects. Uses the method getTargetStorage to select the target storage to be used to handle the query.
  • getTargetStorage(QueryRequest queryRequest, Map<String, WldtStorage> storageMap): The method has been designed to return the desired storage object from the storage map to be used for the query management starting from the target QueryRequest and the StorageMap of the DT. In the default implementation, the method returns the first storage object available in the storage map.

The QueryManager class has a list of methods that structure the type of available queries and that return +an instance of QueryResult with an error and a message of “Query not supported by the current implementation !”. The list of these methods is the following:

  • handleLifeCycleEventQuery(...): Handle Life Cycle Event Query Request
  • handlePhysicalRelationshipInstanceDeletedNotificationQuery(...): Handle Physical Relationship Instance Deleted Notification Query Request
  • handlePhysicalRelationshipInstanceCreatedNotificationQuery(...): Handle Physical Relationship Instance Created Notification Query Request
  • handleUpdatedPadNotification(...): Handle Updated Pad Notification Query Request
  • handleNewPadNotification(...): Handle New Pad Notification Query Request
  • handleDigitalActionRequestQuery(...): Handle Digital Action Request Query Request
  • handlePhysicalActionRequestQuery(...): Handle Physical Action Request Query Request
  • handlePhysicalAssetEventNotificationQuery(...): Handle Physical Asset Event Notification Query Request
  • handlePhysicalAssetPropertyVariationQuery(...): Handle Physical Asset Property Variation Query Request
  • handleStateQuery(...): Handle Digital Twin State Query Request
  • handleStorageStatsQuery(...): Handle Storage Stats Query

The library provides a default implementation that is ready to use and automatically activated in every DT instance and called DefaultQueryManager. This class extends the QueryManager class and implements the default behavior for the query management implementing each of the previous listed methods. In the default implementation the method getTargetStorage returns the first storage object available in the storage map. The behavior can be changed by overriding the method in the custom query manager implementation. In the custom implementation, the method can be used to select different storage according to the query.

In order to extend and customize the adopter QueryManager a developer can:

  • Create a new Class extending the QueryManager
  • Implement (if required) a custom getTargetStorage method to return the correct available storage according to the type of request (e.g., the State of the DT are stored on MongoDB while the variation of the Physical Asset on REDIS)
  • If required the developer can implement o change the behavior of the query manager in terms of the query management methods

One a custom QueryManager has been defined it can be set and configured through the following method setQueryManager on the StorageManager of each Digital Twin:

digitalTwin.getStorageManager().setQueryManager(myQueryManager);
+
+
\ No newline at end of file diff --git a/docs/index.html b/docs/index.html index dfdbb78..0346734 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2,10 +2,10 @@ Docs | WLDT
+
\ No newline at end of file diff --git a/docs/introduction/dt-events/index.html b/docs/introduction/dt-events/index.html new file mode 100644 index 0000000..546f710 --- /dev/null +++ b/docs/introduction/dt-events/index.html @@ -0,0 +1,17 @@ + +DT Events | WLDT

DT Events

DT Life Cycle

The entire WLDT Library and the associated DTs modeling has been designed as an event-driven system where each component is (almost) fully decoupled +from the other and focused on a specific responsibilities. The communication among these independent components (e.g., Physical Adapters, Digital Adapters, Model, Storage, Shadowing Function etc ..) +is implemented through an event-driven system and and effective exchange of messages and depicted in the reported Figure.

In order to better understand the type and nature of the available events this section provides additional information about the characteristics and responsibility for each category and are of interest in the Digital Twin.

Physical Asset Events

Those events maps every bidirectional interaction with the Physical Asset (or multiple assets) that the DT is in charge of digitalizing. Involved events are related to:

  • Physical Asset Description: Associated to any variation in the description of the Physical Asset through the structure denoted as PhysicalAssetDescription (PAD)
    • New Physical Asset Description: Maps the availability of a new PAD from a specific target Physical Asset through a Physical Adapter
    • Updated Physical Asset Description: Maps the availability of an updated PAD from a specific target Physical Asset through a Physical Adapter
  • Physical Asset Variation: Associated to any variation of the Physical Asset in terms of Properties, Events and Relationships Instances (previously declared in the PAD)
    • Property Variation: Maps a variation of a Physical Property (e.g., temperature value of 25 Celsius Degrees)
    • Event Notification: Maps an event notification generated by the Physical Asset (e.g., Over-Heating)
    • Relation Instance Variation: Maps a variation of Relationships instance associated to a Relationship type declared in the PAD
  • Physical Asset Action Request: Maps an event coming from the DT’s Core for the Physical Asset (managed by the Physical Adapter) to trigger an action in the physical world (e.g., turn on the switch)

Digital Twin’s Events

Those events are on the other end in charge of mapping event generate by the DT itself during its evolution and across its life-cycle. They can be associated to the following aspects:

  • Life Cycle Variation: Maps a change in the life cycle’s state of the DT for example moving from Bound to Synchronized
  • DT State Variation: Maps a variation in the State of the DT communicating the new State and the list of associated changes
  • DT State Event Notification: Maps an event generated by the DT for example mapping an event notification coming from the Physical Asset (e.g., Over-Heating) or a “new” notification from the DT (e.g., Anomaly-Detected)
  • Digital Action Request: Maps an action request on an available action exposed by the DT and that is requested by and external application. This Action trigger can be internally managed by the DT or can generate then a trigger for a Physical Action as previously described.
+
\ No newline at end of file diff --git a/docs/introduction/dt-life-cycle/index.html b/docs/introduction/dt-life-cycle/index.html index 4729379..2176add 100644 --- a/docs/introduction/dt-life-cycle/index.html +++ b/docs/introduction/dt-life-cycle/index.html @@ -2,16 +2,16 @@ DT Life Cycle | WLDT

DT Life Cycle

DT Life Cycle

The modeling of the concept of DT includes also the definition and characterization of its life cycle. Based on the scientific literature, we model (and then map into the library) a life cycle with 5 states through which the DT goes from when it is executed to when it is stopped. The previous Figure shows a graphical representation of the life cycle with the following steps:

  • Operating & Not Bound: this is the state in which the DT is located following the initialization phase, @@ -42,5 +42,5 @@ expose the DT’s State, its properties and capabilities to the external digital world. At the same time, eDT can be used by Digital Adapters to trigger action on the DT and consequently to propagate (if acceptable and/or needed) the incoming request to the physical assets bound with the target DT. Supported events are illustrated in the following -schema.

    DT Life Cycle

+schema.

DT Life Cycle

\ No newline at end of file diff --git a/docs/introduction/dt-model/index.html b/docs/introduction/dt-model/index.html index 39758a4..29bd1ee 100644 --- a/docs/introduction/dt-model/index.html +++ b/docs/introduction/dt-model/index.html @@ -2,16 +2,16 @@ DT Model | WLDT

DT Model


With respect to the element present in the real world, it is defined as a Physical Asset (PA) with the intention of referring to any entity that has a manifestation or relevance in the physical world and a well-defined lifespan.

Abstract DT Structure

The previous Figure schematically illustrates the main component of an abstract Digital Twin and clarifies its responsibility to be a bridge between the cyber and the physical world. @@ -43,5 +43,5 @@ propagates the request through its physical interface. An important aspect to emphasize is that the request for a digital_action does not directly change the state of the DT since any changes can only occur as a result of the -shadowing function from the PA to the DT, as described earlier.

+shadowing function from the PA to the DT, as described earlier.

\ No newline at end of file diff --git a/docs/introduction/index.html b/docs/introduction/index.html index 0e06a40..8726629 100644 --- a/docs/introduction/index.html +++ b/docs/introduction/index.html @@ -2,10 +2,10 @@ Introduction | WLDT
+
\ No newline at end of file diff --git a/docs/introduction/index.xml b/docs/introduction/index.xml index 854b3f5..0435c68 100644 --- a/docs/introduction/index.xml +++ b/docs/introduction/index.xml @@ -1 +1 @@ -Introduction on WLDThttps://wldt.github.io/docs/introduction/Recent content in Introduction on WLDTHugo -- gohugo.ioenCopyright (c) 2023 HyasThu, 07 Sep 2023 16:06:50 +0200Library Structure & Basic Conceptshttps://wldt.github.io/docs/introduction/library-structure-basic-concepts/Fri, 09 Feb 2024 11:54:42 +0100https://wldt.github.io/docs/introduction/library-structure-basic-concepts/The WLDT framework intends to maximize modularity, re-usability and flexibility in order to effectively mirror physical smart objects in their digital counterparts.DT Modelhttps://wldt.github.io/docs/introduction/dt-model/Fri, 09 Feb 2024 11:44:11 +0100https://wldt.github.io/docs/introduction/dt-model/With respect to the element present in the real world, it is defined as a Physical Asset (PA) with the intention of referring to any entity that has a manifestation or relevance in the physical world and a well-defined lifespan.DT Life Cyclehttps://wldt.github.io/docs/introduction/dt-life-cycle/Fri, 09 Feb 2024 11:51:38 +0100https://wldt.github.io/docs/introduction/dt-life-cycle/The modeling of the concept of DT includes also the definition and characterization of its life cycle. Based on the scientific literature, we model (and then map into the library) a life cycle with 5 states through which the DT goes from when it is executed to when it is stopped. \ No newline at end of file +Introduction on WLDThttps://wldt.github.io/docs/introduction/Recent content in Introduction on WLDTHugo -- gohugo.ioenCopyright (c) 2023 HyasThu, 07 Sep 2023 16:06:50 +0200Library Structure & Basic Conceptshttps://wldt.github.io/docs/introduction/library-structure-basic-concepts/Fri, 09 Feb 2024 11:54:42 +0100https://wldt.github.io/docs/introduction/library-structure-basic-concepts/The WLDT framework intends to maximize modularity, re-usability and flexibility in order to effectively mirror physical smart objects in their digital counterparts.DT Modelhttps://wldt.github.io/docs/introduction/dt-model/Fri, 09 Feb 2024 11:44:11 +0100https://wldt.github.io/docs/introduction/dt-model/With respect to the element present in the real world, it is defined as a Physical Asset (PA) with the intention of referring to any entity that has a manifestation or relevance in the physical world and a well-defined lifespan.DT Life Cyclehttps://wldt.github.io/docs/introduction/dt-life-cycle/Fri, 09 Feb 2024 11:51:38 +0100https://wldt.github.io/docs/introduction/dt-life-cycle/The modeling of the concept of DT includes also the definition and characterization of its life cycle. Based on the scientific literature, we model (and then map into the library) a life cycle with 5 states through which the DT goes from when it is executed to when it is stopped.DT Eventshttps://wldt.github.io/docs/introduction/dt-events/Wed, 04 Sep 2024 16:00:10 +0200https://wldt.github.io/docs/introduction/dt-events/The entire WLDT Library and the associated DTs modeling has been designed as an event-driven system where each component is (almost) fully decoupled from the other and focused on a specific responsibilities. \ No newline at end of file diff --git a/docs/introduction/library-structure-basic-concepts/index.html b/docs/introduction/library-structure-basic-concepts/index.html index d6e4e2c..c3b896a 100644 --- a/docs/introduction/library-structure-basic-concepts/index.html +++ b/docs/introduction/library-structure-basic-concepts/index.html @@ -2,16 +2,16 @@ Library Structure & Basic Concepts | WLDT

Library Structure & Basic Concepts

The WLDT framework intends to maximize modularity, re-usability and flexibility in order to effectively mirror physical smart objects in their digital counterparts. The proposed library focuses on the simplification of twins design and development aiming to provide a set of core features and functionalities for the widespread adoption of Internet of Things DTs applications.

A WLDT instance is a general purpose software entity @@ -73,10 +73,10 @@ selects the components of the various PADs that it is interested in managing.

  • Digital Adapter: It provides the set of callbacks that each specific implementation can use to be notified of changes in the DT state. Symmetrically to what happens with Physical Adapters, a Digital Twin can define -multiple Digital Adapters to expose its state and functionality through different protocols.
  • Therefore, to create a Digital Twin using WLDT, it is necessary to define and instantiate a DT with its Shadowing Function and +multiple Digital Adapters to expose its state and functionality through different protocols.

  • Storage Layer: The storage layer has been integrated into the core library with the aim to enable a manual or automatic storage of data related to the evolution of Digital Twins state, the associated generated and processed events, and any variations involving properties, events, actions, relationships, and life cycle.
  • Therefore, to create a Digital Twin using WLDT, it is necessary to define and instantiate a DT with its Shadowing Function and at least one Physical Adapter and one Digital Adapter, in order to enable connection with the physical entity and allow the DT to be used by external applications. Once the 3 components are defined, it is possible to instantiate the WLDT Engine and, subsequently, start the lifecycle of the DT. In the following sections we will go through the fundamental steps to start working with the library and creating all -the basic modules to design, develop and execute our first Java Digital Twin.

    +the basic modules to design, develop and execute our first Java Digital Twin.

    \ No newline at end of file diff --git a/docs/introduction/sitemap.xml b/docs/introduction/sitemap.xml index c6c3f46..d1bdc7e 100644 --- a/docs/introduction/sitemap.xml +++ b/docs/introduction/sitemap.xml @@ -1 +1 @@ -https://wldt.github.io/docs/introduction/library-structure-basic-concepts/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/introduction/dt-model/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/introduction/dt-life-cycle/2024-03-15T10:45:36+01:00monthly0.5 \ No newline at end of file +https://wldt.github.io/docs/introduction/library-structure-basic-concepts/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/introduction/dt-model/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/introduction/dt-life-cycle/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/introduction/dt-events/2024-09-05T15:02:33+02:00monthly0.5 \ No newline at end of file diff --git a/docs/sitemap.xml b/docs/sitemap.xml index a93d56f..9779651 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -1 +1 @@ -https://wldt.github.io/docs/introduction/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/adapters/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/change-logs/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/introduction/library-structure-basic-concepts/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/introduction/dt-model/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/introduction/dt-life-cycle/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/physical-adapter/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/shadowing-function/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/digital-adapter/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/dt-engine-dt-instance/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/digital-actions/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/configurable-adapters/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/adapters/mqtt-physical-adapter/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/adapters/mqtt-digital-adapter/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/adapters/http-digital-adapter/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/change-logs/change-log-0.3.0/2024-03-15T10:45:36+01:00monthly0.5 \ No newline at end of file +https://wldt.github.io/docs/introduction/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/adapters/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/change-logs/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/introduction/library-structure-basic-concepts/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/introduction/dt-model/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/introduction/dt-life-cycle/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/introduction/dt-events/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/physical-adapter/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/shadowing-function/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/digital-adapter/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/dt-engine-dt-instance/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/digital-actions/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/dt-relationships/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/configurable-adapters/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/storage-layer/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/adapters/mqtt-physical-adapter/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/adapters/mqtt-digital-adapter/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/adapters/http-digital-adapter/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/change-logs/change-log-0.3.0/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/change-logs/change-log-0.4.0/2024-09-05T15:02:33+02:00monthly0.5 \ No newline at end of file diff --git a/en/sitemap.xml b/en/sitemap.xml index 54eaf8a..2456f25 100644 --- a/en/sitemap.xml +++ b/en/sitemap.xml @@ -1 +1 @@ -https://wldt.github.io/blog/ls-wldt-library-version-0.3.0/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/blog/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/introduction/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/physical-adapter/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/shadowing-function/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/digital-adapter/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/dt-engine-dt-instance/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/digital-actions/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/guides/configurable-adapters/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/adapters/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/adapters/mqtt-physical-adapter/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/change-logs/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/adapters/mqtt-digital-adapter/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/change-logs/change-log-0.3.0/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/adapters/http-digital-adapter/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/introduction/library-structure-basic-concepts/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/introduction/dt-model/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/introduction/dt-life-cycle/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/docs/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/about/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/privacy/2024-03-15T10:45:36+01:00monthly0.5https://wldt.github.io/categories/monthly0.5https://wldt.github.io/contributors/monthly0.5https://wldt.github.io/tags/monthly0.5 \ No newline at end of file +https://wldt.github.io/blog/wldt-library-version-0.4.0/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/blog/wldt-library-version-0.3.0/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/blog/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/introduction/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/physical-adapter/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/shadowing-function/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/digital-adapter/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/dt-engine-dt-instance/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/digital-actions/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/dt-relationships/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/configurable-adapters/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/adapters/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/adapters/mqtt-physical-adapter/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/change-logs/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/adapters/mqtt-digital-adapter/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/change-logs/change-log-0.3.0/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/adapters/http-digital-adapter/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/introduction/library-structure-basic-concepts/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/introduction/dt-model/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/introduction/dt-life-cycle/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/introduction/dt-events/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/guides/storage-layer/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/change-logs/change-log-0.4.0/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/docs/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/about/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/privacy/2024-09-05T15:02:33+02:00monthly0.5https://wldt.github.io/categories/monthly0.5https://wldt.github.io/contributors/monthly0.5https://wldt.github.io/tags/monthly0.5 \ No newline at end of file diff --git a/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_1024x0_resize_q75_box.jpg b/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_1024x0_resize_q75_box.jpg new file mode 100644 index 0000000000000000000000000000000000000000..57f08b2711f87e0661706a43ef960ab0c8b488aa GIT binary patch literal 89913 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

    i<~#P=I_S=J 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%0A%!lp7=Cj-=3Il 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 literal 0 HcmV?d00001 diff --git a/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_1024x0_resize_q75_h2_box.webp b/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_1024x0_resize_q75_h2_box.webp new file mode 100644 index 0000000000000000000000000000000000000000..8c6ed63ace79ba23f5389831af74f7194cf6c916 GIT binary patch literal 46812 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 E07`linE(I) literal 0 HcmV?d00001 diff --git a/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_1366x0_resize_q75_box.jpg b/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_1366x0_resize_q75_box.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b2ea09d729fa28322e11f033209ab4d75ed85dd3 GIT binary patch literal 138430 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ÐsdHTM;vu{EsQWu;NW%iFV;mgXgIOG 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 z zI;)Lve8s>aR5C5!IMKAtz{Ip;ljl5@%LfBt8>V^;}dFQCJ$c#8Xk zW7m>k-Xz^C3vN(pYEcrBlQ-`p9hn0Tgk@HtZp(({;+lNQky1c{8kok)Mml#PMs@_J zHF=RW0U5>=K&X?GrHcj@Mo+e5 zk2zSc6LQ>a{ALh7J!99+?9+;HJlPixCiqd#J}E`z`A^0IK!zt*#YS$TmzU&PxU4u) z@x-}k9+tkPnabv(LG5v$vv&Ia9s$w(GP4V{z_ImsjjbXMt=-D7k_OcjoJZ;p5|m|@ z2^SupALet=J0lGgull$>GqpPz`uzfN7|Al2%&XqPsOHjgLc9yTlOM3*#wN0|Y%y@l zmeJHU;A)l0#D@0Qf?|TT9?I67n;WBbGA39Xp$zQtesIZR35=@g19=N{!|5Rbu*!N_ z2vW0XJuGAKdClcxnGSa627PcdQw|u( z!J^pY+P@GQXa=S^4FOF!ZG^EYW_T=EXl?vk^?T4^f!K{!2wLwuEedZT&s9el?xKf$ z$;O2sV+tL}tcM2ANHx| z+`>KHLuu>x?q8FvC+Jmzk?{4oYD~ht3R!O^{vt@4O`O<)TRY4B3alx6>t^lwZ2nKt z+pky$Iwv)+T;ip+$G$c{*qgc@+FWP}btq|4^Hw>!Gx18m()*(^xmzsEbkF0XUP#vd zWW@jw1n+o|Fw6Q>5ym4unhU??xl|iN_m|&kUzQqqg9xqoajtvq8mPMk6@99AL+YH* z*J!2FMdX3Zx`DjAuA(%UQegKawL;#_Z64o6Eue0@TevDYzI@TeZo_9oaI0~GmUu5~ zDkE^DF$X<3;A|s&%D;RlKW0%-*vdl*U6>7|>*#q{v_I7}%Sjj94zO-#m&u3$%lS&u zY_YA&uj66X5lo`=+p#eHp<4FQiED>SA_ILi;Xe6`oc0t$uDp1m2ueTY@Ja<}AR z7t0deW47feM5?*EM?m9a)mM6fg8V%pblHfi`wG$%G39wcgi&U9D9%j2YALy2Bcy8nFGLmW_hFW zW9qJ!)4sN&>4=S3)-A&@5*T^?FR}33Q1O5DO(~~oH3g=tOrdlU-qs80ffD8vZaR8~1b{O{W5LRuG-<`raM9>yN!p9BzK_4+R(17ytkO literal 0 HcmV?d00001 diff --git a/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_1366x0_resize_q75_h2_box.webp b/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_1366x0_resize_q75_h2_box.webp new file mode 100644 index 0000000000000000000000000000000000000000..aced9241bdde380a7020512b8d4f8a24cb32d414 GIT binary patch literal 68658 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

    -N-L#t)QO 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 literal 0 HcmV?d00001 diff --git a/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_480x0_resize_q75_box.jpg b/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_480x0_resize_q75_box.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dfb50c5fc7d1e3c34088d00f5e6e903b582e5c98 GIT binary patch literal 27514 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

    Lbt~pGBCBeNI2Le~P}?|MK73#% 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


    X})n) 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
    Tw^&+s}PQ`FR{K|i5Nja4Q}UNOuEgaCh|Og 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 literal 0 HcmV?d00001 diff --git a/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_640x0_resize_q75_h2_box.webp b/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_640x0_resize_q75_h2_box.webp new file mode 100644 index 0000000000000000000000000000000000000000..f0da367561c7076f244dec19331470a30c4b5abb GIT binary patch literal 25266 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 JKb-&o003SOo=N}! literal 0 HcmV?d00001 diff --git a/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_768x0_resize_q75_box.jpg b/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_768x0_resize_q75_box.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1429a10cb3ec1adc679a8bad942eeb199b8af7a6 GIT binary patch literal 59529 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

    cRn*RQfj36CSPUaI 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 z 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

    Vu>riIf7A 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�O98jNnIhG|f7i%dtB^h6`Ygw}84dX;)X2A2lf?Jh@zb0;16im|~-r zhF+m_WB6TbaBJ-?LDT9K->3tgEPsXok+dRPf|iEpN9|{WqLyy_gN{rI4t_FP`;gm# z2b949%F1Gmx+@m4|yw%ppF}WFrjW_ zAJ&ivX~l{;lz+;$62IxOgzh;R{!2XfHD&s6NnactMOo!fCzthk>E zVy&-1>LebTDd(h|>?Vz0ZlbNaD|T#vzIl2$!2vC>{QP!r!m@(=2GFvi6$ij5&qGAt z*xoVznjw6wD$#2bQ^48CgksM1YS}*WGVrZnzUf4j;Ffp}u76K+@duQ5MBILY?t2Z6 zl>S2f8%4irmiI|cV4=ePl>ce-d0@no#36Kw3iyedLJA*7+PBp?GrNToUbUtu{Fpu! zji)mMnt}J}&$DovSkr(&)x90&ymmER;QCAOgznA2FVCcB=uamM zzR(;He0>GeS4LBmcD3FvL(ym4U8n@uH88Rrjn4Bb$o6c>QzP)H302^zMI;1F37?3h z9v$U@vnDU)Z*48G%t_cAa@E`gPJ`p)jwRxuCB@f77%cDeFa#O!mnTaPRql>?# zh~_hF=>Xn!a-B$Xtoh%@AR$(*cMOre-IW`7fwtqX9t!8Y-*11P}`H0bQoZi{<`O&is;og;6Fw!@mj!e;W~OiGfT z5J7AQ>UQLgGU`ZEMFQc#lHa`s$`?6LYB3N)W>)E9?TMxiwudgx2ml|7orx>^%@R6; zWtR2L3wj5Pe_5Z6wr=Yi3{zz;g6h?3%Zb#cP zHrH|fBI{gFMDoPOw!`%rpo9&_;(nGEn}>yP*6JV}6XjJe%R=o&GNJcGJ{{J=HdTw( zmwIPHu2hi$jW?$C43BA(HL2xn8$UL^sO4stUU4^KkS#gK#Z5<~1+YX(62eHpP%NOL zknn@TfZ;~508anvyI2;L>BR#Xl%!n1YpTR3Y zT-KojNOCHjkb)b5`4vzFG@AB7Q+nFyrX64(?2Hs1#S=_$R^-KMB2SI{r3h$ApO#HQ zew&9Q6JF4=p21H)*ShWPeVg2SZx32(QzHUA!q{t4488j{GoSzxx(-OALH>bzSG%Q- zXpxsrce{k{oeu;o58l1CCKVI;J-)3!Vkq3wIM2HX?-a`qaW`@Hq)ee!zM3S`(dP$% zYubIBXmlaUjhHRvnHHukDkX(!#z%_;JBv$mH*?w&o;oSxz?yi3F*Kl@72aeggP)^N2$b`gumW1o=3{=s!M>Ska75I360h`eZN+t75eol zdvnpDMW|p+f5k7bf~v0ns|NOg0IGAtX%tk|<$31&08gWTv5Xd9B)PK$Ru~?fh&aZT z@ig4TonLgZY&-6pi$|Rhc60)gtas*($ZXLx4Oyq)`0#q=6M02(rJmpb`0~mDETsDN zQhM(j+NWeRIBZb96w)7*sqh64F8vPFuFo0a3lRu)AN-v={d*^fRlN!KAtr^lSSQ8K zIq`m-#i_Y*;HLcO7t?udI-FGrzqNO;Nv=myY{+!!bzo5AQP0h>1bz(pVO05O&KGw= zPo&}z>BNv1IFqRt0R{5~Y7>MSG+W}qRO$6D6xa1~I3q56i2+LJw7hXUzC!|te$hUz zS|`4*P|6#A)Mw_baddW3Xg{emj zRqO?o(nzzdw}WCfhBdvYE8d1V6741Taa`oA+WEf1Oiea*c|FhC;O=Wh#%=u?w(oVt zykCQIKDiruQUjTvi7br>cs5reV1jW2aj)sQHI&4r2;AQBGY?YDJS&V#3cw~!qTRP**l-c-HPwS^-YR{;w-rd9`#Cf;JrLNt zJ;*kND5>xw5y?q2){-G=KOqAo;!|L;*ffKd*FkfSDcq=D8unlaM0-ZSi6<>9K_trW zTgH8T)opzxmM=!|!SoMkz#MN|k0_4hfit4u>rW#+wjs2;Z4t`M;ua}5lJ5U!gry<& z3O4#;?86zR5KIPAre93XNzND#m@yF<4VVJ#)C2QB%;W>exZ{lDvZcKx<0D3Excfor zlz6`6S7k_B-)-sygp=mtAP(3ka};ne@--50E>-{D1Vvau_D8 zk$Mvdz9!I=M=Uz%_XsP<)Uz6g3$sQ+iv$u1tWJxZ=^<7e2U{6l8aYeL!MqZ&;%9>5 zGYIPr)U`iK4w^g~u?cMOQ&lmNy*lEiZ6h~!O9pD&acvN-YUQ<5>L(qTKGsbc zu(h|X;GxfXNiO(5jH8Fq2K4=Be0ck%yGXM4JjL!s` z5@(RF7@Ik`y2q$JeuJ;2N^(n{yCqZx8MR{o4Gk$mFB8Sf<(ApBX=?L_N!ag;`_d6f zN4&^{%$BVEiap!-DPNs(eV9~6*Pe$TpJjs)3oHNA6s>*UFf(hqJ4)~~?#O9gFrk6; z<~X5WNXC_F(2@KGKseH*QrL|&a|z%pP-X3$WZ@|zo0d_8m3b?keZA3Be0Hk9?qQ%L zfGn(cwMnV3K3e}LK9m+Ph zaR#c3lL!dUsF-Bsh}`)4$9Dk76ol7WOzp7_%Q+Z-oO~BJk;Eb=8jVMPQ9R#%`D_|; zobv~CP?v>u^P?Ej-x_p^Mkp8tKV7&upg|xf``EwOz!+XiT?Gu#G;(Fd8 zSV;Ah+m1s01-uBU#a>3zbB;N!?NvGjktnOJiNe7RtN{{Ec(g!Q^xVs+4M8^8o5ExA zf(6cU4o>k|hhw{eiTV#Nzexj7aS_nOTfA$N^0UF+%Te!iI9_O};BF^$lsCdu$`=-n1k{XLN9)3hvRV@tyd9k_2J%whfXubqSC2>zV{sE< zBIiX3-cy(SqBfyhs$ZhHhKibPil_n*%XGY6znShm2pWx9&c5XEJq|a&GVLU_|LxjI ze^E}Nf5G|nItod~yF!(9xnZ~AhkySS^Zk2gY}QxC7y}~mVt7Pl-dl9`K#}V3C(#YQ z?^s{-KKM;EXVE4rJ85qa4fZYll@k6;(%o)>{}iuQdsmu&YRZys8ZK~#L}^T^x&kHX zPDwuR6#L2}P4@ZYo`!{_0+9z!ihjIPPqd-j^3nAC46`q^X{yV%t+OBP-P6C>POgth z*~;+qTF{^Ivgz4G2Q$4aohLaTdzf;>p{08RZNc$6+fh51xqp)ZkU&W9PSgjn+6z-C^rBE-Z;!DD zv|?cW==4P0C+#nbi&GX$YKawn_J&Y$CnYMD=;MbEvi?>`BZONaJ8O8s>QOb?XQ72` zj1gNKFSs~JyjVtSKphFmAVlvnG1FcWa#t@4MOm#$4F`_S^koBHn~Pt@RUCTXF6KRC zoX3fl0qIL^Z-1kOvO1(6ZSS_lUPr3sPTS?7Gt>lj;S`e7dc?c|ggM4*+ry*spmXaA zpBLo|D88{5BrUMgB_cI&JI5lS4oGsZXpD;V_(W0*&Drr8n976>iS)=BCk?&V$d-9S ztt6V^bJa|=B%W%@)@99hvZjm}W|f$Z8!ULJWJ{sdNW$)j^?}4Hu@4L3Fry(0Pi(5i zh4%a`oFnbB3;xh|F_cSUzRjJ<`OHPT^qu}rG)OHXVtWg>t)aXggptuDuf>I8`IT$kS4f9I~2+4bb`1_e-{RhB8d`3e*^cmtr%fVEmTvgVN{ z^Ay*IEdq(bo5HeC4oGf;)Ebls)o^bfgN@y-zO9{U1BZM)$@^QOck0(bS~VR3l|h9@B@L(Ljk zHA0wjZWiu#9_oTS`?)is=4IoXnS_jadvRhX(P^CYZPNz1;YeshlnLP={b(l_48+!# zBCKALU$VjxEgfc%$c|&m7>N1nCV7?hdY{|Ln?)f8Dd`7FP(v!bn)D#(3NA}`VLQzc zo1){Dt5t}pXg0C;>npd*X_hhWi~7=F4(l|vD(GAK&ih+fxY2yLM0mJ6cYleM zw8BTGRSD1*PBa-sKKrYNpv?nC>eCA5((x2Lg`l?tA0?-Fs!Py}z|~_P6Gm-<%wM!sLN|p}9gSh7UQu!K%F7X(hRe7 zGBLau;C{Rn@I@d;!i3{F%UNn7V}^h-ZnWt=EDn#%J%K|OWL~X;hHA8HQyc-<_MVFU z`3)+cGIYT96DbiGewBTwo4joTvD zf~<>z&u@!I=@N11e2Blb45-F=v^&~+%Ue%DC%u=iMk$`B zM;m6e_G6{}Y0}x4chWzG_J*aqAtp&K>J981ypcA57wm9g##D(y{* zc4p`S7WVZ><$K}B79$R3<{f87Brto7-)2@@Dbax8VXGSaWa+jqY#A)SVnugu<-!)a zCn#hYl1*9CycHc17qBUp?HVxrU#b0mOi*F}_;mx|g}Chi!{oG*_d!c#uayV!W^Z=P* zMz8K=yHNl^3Y5iRY$#*K+o^qK&p!3OfaNXHnH|y-!M5K31Ulq!@K=wC_^Jv7Me{N* zrxWr(RJgeq%@JS-KSfD*`Oh6v5%sYXt9R;eFHwV#DjyvG32izdC^RJ`OW%=5pVsw# zWv|w)1#pv}Xu1=Nt4x$WMxJq5D`8PEtn9;b~NvW*ng1v}MDLT$HWpv+m1l zE}@gjsnMcbTsMo01a^N|{&u}BbnwGm^LE>61X){+HE`#8ZIi;utBlvKpN%q)q_2R8 zeuioiM?tvGmzdRP_$*^a&w);Abs<(zArrsm61+gU1my(ghlwcVL5K^9HE+)DYyQ#F z*Y;Ne`4eky9#n(!bFhW?|HaRz8C*VeEBjWz5r?htz#`H2b^PV0-etL`lujPM#X23J z%$jZ6Rn;j)z1peydFXmS5jo(S`uwbDdLWAC-dcD!tBS~5dlH{XOTvsfDwj;bv7j-~ zo!9IJ7AHO3`7ihAbU8GT?ib*_OKchru3CmK`xD9=;Rc@O@VXrrRiZ5lXaK)Y`>)04q|XLlFj7**wy!FVdIXw;|j*sfdj$|b8j zBagg}NDkbx^G)X|a=}RX=gCPfiDPG;F|-fbm>LS-jIlDC_4aO-|NddsZnW|S>Szs* zpP`ywl*I%1sm*RP9(8jXnF#l4&+6~8pS{?Hrh2H9LrfcOJ@$HMqjg*boEc^l5H{;| zaVc*xuLo|I_DeM}1xifd6(6UZIwT}@(3hy6W)(NlX&=SsCLehjTxt#VV?um?I<@73aS+DrL7$T0joi2>L@wzMWdiUY*BwZI= zT|e}m!D)s{*VNIi4#ksl+=Rr#3|EF-J1f!%Jt?%f|Bm|cX|LLsH|%L^rWMrvC5|wZ zyz8aiRpC*$P0xsd7Javz(vs@viwqIX8ce%8DdN-{G#_#yBA&OGDj&OP}tamV#;Ovigksn zHFY*4u9+-XOcdqu*C?dY$I&18;8o&Uv)Nm~{Bi7113J%LVF}bDXuOs4j^jVxbe&~q zje0~0P7Ga}(0bocZ_*%V?CY+1$DzSk@YzbhkG2)z=zwtk>dUOnq{RGjOi5?z^(nrC zAk?FY&TDe05A`bQ&%z)nNtfSRk}zh;b`*^9{k`gd`s6^)T17^MV;d*8d3ZGFE4_+$ zJ8}ffuXz%)%w@HXY7rufegtb94C-kSQyE06U>^iM-y;!g&fjg9q}os!qfD<2+@IZC z6u(HM0p`;FefbQ?8QyWP_px2+6>(+G=5$l~^DK3*GZC_PGT~`YNj@dW zu%pI|DG1uCh_@d89jBN_V|Sknpuf67rC&K25w6U5Hn^IzM_I*eRI7A{wJ8p-nP!ob zrJmN!WT_8L_6Paq8XgkFEgmJNZKQKA_ZTIuw$&p(IqF}ksHm<>8_-uCXzWYXIsRRt z8(^?zFtAcI8(yeQ_Z@c)N?Kf0;d#{%+C7reqZ4QKgJJM|re7j*%GiPOF^P#(q|onE zGvI5hoFQwR?@NG~&FPLkK=${KHD-9vrYZUb`Zh?OMFl}544MZywZ3IDFJ|D{d4r1= znz7esUY=>r*i)Y5P#-@cAk^5d4nszQDydzHHZR!wc|EAP!3T?VEthB5nk|gtoBYk%-*iL z1P$$+K82H>t&0nTk5#Lt-a;izj}-K#UOY#8I4G+_g(NNzFD$#?N&{tbXIsavS*`g# zjjYtovE;YqinEtmP%AKg+}}dIe$Yg$Ztp2}T#rwxi_~K`3o?Yqk3FrwbVxC{~J5oxR^mhN7A1jvQ6&1QM2DLOzoR(A*G4MPf@_7U? zZ#ahlE|O7&Q7BZ6mHT=);fjhn^K5i;fWLD((niC~qGkyBt&T<8pRQaeC{p3%cEql0Zo;9u@`NYH+++pkPuZeKf^x$6~V3_)#_b8 zk~>s&uGW21(0VH6kvqMAw?TW)4ew7<5jw@r-*wCy&}<>lQQ{x?wmlQLve2u6JJbxl z1TYvqzI9NKO3Cd;=}M^!x@%jtm{t?fW!4(%lyri$fyTw2*WN`i4sG@D!hv(0aeRpy z>4gW(d8p8hmq*C0U1{y#8nW&DGzdx<-^z0$;p)h7K2UB(hz^0%^tF9eOUM&aSp|*%U%5gOls{F|Z|g?Mg_CR=BW)kQnTXC~X{l5~@PYyRq_c^}NSv z>x$#yDK!xtl>qr!k!P!bggd8~nYqp8C>)%o>@Y3mm`JTGpdNb1+1zr=Hq3Sl$xc#P z%qa`Qbjp5J%GI4O{=<1{qW|uWPn`Rcbv}rBS%$4u41DvUtnR&TEgt?$$OWo60Nw(vsM+Pf%i`3z&Eh6KT;ROkL8A))2?CrWfU3$KFNPPRc}5DY`2K!6 zB~+x$Qa^6C$V!}Z^SGz_8r7Lp`KF-CjE`v-zG-d(7|-1ic|^S8<;UF)ER3AOww=!u z^l#K0{BPw>Y=FF8`ak9M%1TV$2_5<4b8;Bs@O-=;cA_%tR@6Hgk~tk-Jbp(c4W!m+ znL~QBwZgyWnqU{@-#J@M>BPn#b^xs_e%Oa-8Jqjb+dFyN!{CpG#UfGE#06b~XDgDR za7u=RylV`rc%{dGG@sU-cH4RDxG#e(v_^@)bYQs^0!voptF2w-G#1}&%W$Eg10u$dO&>KhT)-{Q6QBq!Bs>zw}1;48ph5FmkR8~aN(=f6Cc&a!}1uD8NZ zo=Ii=;z`gMdJaFf$GZrt4`$l~G~%9b3!g>SM_tpeafhGapmg#oevPz~w=DL$lcBtkUmWXC`O38vi;Deo3wJ@ua9 zGoi^Mg>ldD3^6G$q;`9ij)bsUAEugKA4WX&y;C;3b(JXukjDtkyyXhGUkKLIa zIJ>DcR8oyj!V8~F>w|J4W3ehu{RPZrUp#$WnO)iPOaCQ8n!o$I%Q=(wCGb3lHO_l9&w3lTA9X=rHj)W)Xe(Y1loYo?*E8O_J8B5 I(f>LAADiaw8UO$Q literal 0 HcmV?d00001 diff --git a/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_768x0_resize_q75_h2_box.webp b/images/wldt_events_hu53c7ad9b57bde89835661b1cad9a910f_2490323_768x0_resize_q75_h2_box.webp new file mode 100644 index 0000000000000000000000000000000000000000..85b2adde6e39380d84fa6ec6a43a0f1c53ed7b61 GIT binary patch literal 32190 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 literal 0 HcmV?d00001 diff --git a/index.xml b/index.xml index be998b3..cb88eda 100644 --- a/index.xml +++ b/index.xml @@ -1,2 +1 @@ -White Label Digital Twins on WLDThttps://wldt.github.io/Recent content in White Label Digital Twins on WLDTHugo -- gohugo.ioenCopyright (c) 2023 HyasFri, 06 Oct 2023 08:47:36 +0000ls WLDT Library Version 0.3.0https://wldt.github.io/blog/ls-wldt-library-version-0.3.0/Wed, 13 Mar 2024 16:27:22 +0200https://wldt.github.io/blog/ls-wldt-library-version-0.3.0/📣 We&rsquo;re thrilled to announce the release of version 0.3.0 of the White Label Digital Twins (WLDT) library! This release brings significant enhancements, improvements, and new features to further empower developers in designing, developing, and deploying Digital Twins within Internet of Things (IoT) ecosystems.Physical Adapterhttps://wldt.github.io/docs/guides/physical-adapter/Fri, 09 Feb 2024 12:09:02 +0100https://wldt.github.io/docs/guides/physical-adapter/The developer can use an existing Physical Adapter or create a new one to handle the communication with a specific physical twin.Shadowing Functionhttps://wldt.github.io/docs/guides/shadowing-function/Fri, 09 Feb 2024 12:15:33 +0100https://wldt.github.io/docs/guides/shadowing-function/After the definition of the Physical Adapter it is time to start implementing the core of our DT through the definition of its shadowing function in charge of:Digital Adapterhttps://wldt.github.io/docs/guides/digital-adapter/Fri, 09 Feb 2024 12:16:06 +0100https://wldt.github.io/docs/guides/digital-adapter/The las component that we have to implement to complete our first simple Digital Twin definition through the WLDT library is a Digital Adapter in charge of:DT Engine & DT Instancehttps://wldt.github.io/docs/guides/dt-engine-dt-instance/Fri, 09 Feb 2024 12:16:36 +0100https://wldt.github.io/docs/guides/dt-engine-dt-instance/Now that we have created the main fundamental element of a DT (Physical Adapter, Shadowing Function and Digital Adapter) we can create Class file with a main to create the WLDT Engine with the created components and start the DT.Digital Actionshttps://wldt.github.io/docs/guides/digital-actions/Fri, 09 Feb 2024 12:18:13 +0100https://wldt.github.io/docs/guides/digital-actions/In this demo implementation, we are going to emulate an incoming Digital Action on the Digital Adapter in order to show how it can be handled by the adapter and properly forwarded to the Shadowing Function for validation and the consequent interaction with the Physical Adapter and then with the physical twin.Configurable Adaptershttps://wldt.github.io/docs/guides/configurable-adapters/Fri, 09 Feb 2024 12:19:37 +0100https://wldt.github.io/docs/guides/configurable-adapters/The WLDT library provides a native method to define Configurable Physical ad Digital Adapters specifying a custom configuration class passed as parameter in the constructor.MQTT Physical Adapterhttps://wldt.github.io/docs/adapters/mqtt-physical-adapter/Fri, 09 Feb 2024 12:55:52 +0100https://wldt.github.io/docs/adapters/mqtt-physical-adapter/The MqttPhysicalAdapter library provides a streamlined solution for efficiently managing physical assets through the MQTT protocol. It offers a range of features, including a versatile builder for effortless configuration of MQTT connections, dedicated classes for handling both incoming and outgoing topics, and a specialized adapter designed for seamless integration with diverse physical assets.MQTT Digital Adapterhttps://wldt.github.io/docs/adapters/mqtt-digital-adapter/Fri, 09 Feb 2024 12:58:14 +0100https://wldt.github.io/docs/adapters/mqtt-digital-adapter/The MqttDigitalAdapter, -MqttDigitalAdapterConfiguration, and MqttDigitalAdapterConfigurationBuilder classes and guides you through using these classes to set up an MQTT Digital Adapter within WLDT.Change Log 0.3.0https://wldt.github.io/docs/change-logs/change-log-0.3.0/Fri, 09 Feb 2024 12:23:33 +0100https://wldt.github.io/docs/change-logs/change-log-0.3.0/Digital Adapters The following methods have been discontinued and removed from the DigitalAdapter class: onStateChangePropertyCreated onStateChangePropertyUpdated onStateChangePropertyDeleted onStatePropertyUpdated onStatePropertyDeleted onStateChangeActionEnabled onStateChangeActionUpdated onStateChangeActionDisabled onStateChangeEventRegistered onStateChangeEventRegistrationUpdated onStateChangeEventUnregistered onStateChangeRelationshipInstanceDeleted onStateChangeRelationshipDeleted onStateChangeRelationshipInstanceCreated onStateChangeRelationshipCreated onDigitalTwinStateEventNotificationReceived The Signature of the following methods have been changed: onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) -&gt; onDigitalTwinSync(DigitalTwinState currentDigitalTwinState) onDigitalTwinUnSync(IDigitalTwinState currentDigitalTwinState) -&gt; onDigitalTwinUnSync(DigitalTwinState currentDigitalTwinState) New methods that have been added are: onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList&lt;DigitalTwinStateChange&gt; digitalTwinStateChangeList) onEventNotificationReceived(DigitalTwinStateEventNotification&lt;? \ No newline at end of file +White Label Digital Twins on WLDThttps://wldt.github.io/Recent content in White Label Digital Twins on WLDTHugo -- gohugo.ioenCopyright (c) 2023 HyasFri, 06 Oct 2023 08:47:36 +0000WLDT Library Version 0.4.0https://wldt.github.io/blog/wldt-library-version-0.4.0/Thu, 29 Aug 2024 17:40:54 +0200https://wldt.github.io/blog/wldt-library-version-0.4.0/We&rsquo;re excited to announce the release of WLDT version 0.4.0! This update brings powerful new features to enhance your Digital Twin (DT) experience, including event observation capabilities, a robust storage layer, and a flexible query system.WLDT Library Version 0.3.0https://wldt.github.io/blog/wldt-library-version-0.3.0/Wed, 13 Mar 2024 16:27:22 +0200https://wldt.github.io/blog/wldt-library-version-0.3.0/📣 We&rsquo;re thrilled to announce the release of version 0.3.0 of the White Label Digital Twins (WLDT) library! This release brings significant enhancements, improvements, and new features to further empower developers in designing, developing, and deploying Digital Twins within Internet of Things (IoT) ecosystems.Physical Adapterhttps://wldt.github.io/docs/guides/physical-adapter/Fri, 09 Feb 2024 12:09:02 +0100https://wldt.github.io/docs/guides/physical-adapter/The developer can use an existing Physical Adapter or create a new one to handle the communication with a specific physical twin.Shadowing Functionhttps://wldt.github.io/docs/guides/shadowing-function/Fri, 09 Feb 2024 12:15:33 +0100https://wldt.github.io/docs/guides/shadowing-function/After the definition of the Physical Adapter it is time to start implementing the core of our DT through the definition of its shadowing function in charge of:Digital Adapterhttps://wldt.github.io/docs/guides/digital-adapter/Fri, 09 Feb 2024 12:16:06 +0100https://wldt.github.io/docs/guides/digital-adapter/The las component that we have to implement to complete our first simple Digital Twin definition through the WLDT library is a Digital Adapter in charge of:DT Engine & DT Instancehttps://wldt.github.io/docs/guides/dt-engine-dt-instance/Fri, 09 Feb 2024 12:16:36 +0100https://wldt.github.io/docs/guides/dt-engine-dt-instance/Now that we have created the main fundamental element of a DT (Physical Adapter, Shadowing Function and Digital Adapter) we can create Class file with a main to create the WLDT Engine with the created components and start the DT.Digital Actionshttps://wldt.github.io/docs/guides/digital-actions/Fri, 09 Feb 2024 12:18:13 +0100https://wldt.github.io/docs/guides/digital-actions/In this demo implementation, we are going to emulate an incoming Digital Action on the Digital Adapter in order to show how it can be handled by the adapter and properly forwarded to the Shadowing Function for validation and the consequent interaction with the Physical Adapter and then with the physical twin.DT Relationshipshttps://wldt.github.io/docs/guides/dt-relationships/Fri, 09 Feb 2024 12:19:08 +0100https://wldt.github.io/docs/guides/dt-relationships/The same management that we have illustrated for Properties, Events and Action can be applied also to Digital Twin Relationships. Relationships represent the links that exist between the modeled physical assets and other physical entity of the organizations through links to their corresponding Digital Twins.Configurable Adaptershttps://wldt.github.io/docs/guides/configurable-adapters/Fri, 09 Feb 2024 12:19:37 +0100https://wldt.github.io/docs/guides/configurable-adapters/The WLDT library provides a native method to define Configurable Physical ad Digital Adapters specifying a custom configuration class passed as parameter in the constructor.MQTT Physical Adapterhttps://wldt.github.io/docs/adapters/mqtt-physical-adapter/Fri, 09 Feb 2024 12:55:52 +0100https://wldt.github.io/docs/adapters/mqtt-physical-adapter/The MqttPhysicalAdapter library provides a streamlined solution for efficiently managing physical assets through the MQTT protocol. It offers a range of features, including a versatile builder for effortless configuration of MQTT connections, dedicated classes for handling both incoming and outgoing topics, and a specialized adapter designed for seamless integration with diverse physical assets. \ No newline at end of file diff --git a/privacy/index.html b/privacy/index.html index e76f49c..9b9e6ea 100644 --- a/privacy/index.html +++ b/privacy/index.html @@ -3,5 +3,5 @@

    Privacy Policy

    Last updated on March 15, 2024

    +

    Privacy Policy

    Last updated on September 5, 2024

    \ No newline at end of file diff --git a/search-index.json b/search-index.json index 40acbb5..c960b61 100644 --- a/search-index.json +++ b/search-index.json @@ -1 +1 @@ -[{"content":"📣 We\u0026rsquo;re thrilled to announce the release of version 0.3.0 of the White Label Digital Twins (WLDT) library! This release brings significant enhancements, improvements, and new features to further empower developers in designing, developing, and deploying Digital Twins within Internet of Things (IoT) ecosystems.\nFor detailed information about these changes and their impact, please refer to the information provided:\nOfficial Changelog Official Documentation Let\u0026rsquo;s dive into the key changes and updates included in this release:\nMigration Digital Adapters In version 0.3.0, we\u0026rsquo;ve made several enhancements and adjustments to the Digital Adapter class to improve its functionality and usability. Notable changes include:\nDiscontinued Methods: Several methods have been discontinued and removed from the DigitalAdapter class to streamline its interface and improve clarity. Method Signature Changes: The signatures of certain methods have been updated for consistency and clarity, ensuring a more intuitive developer experience. New Methods: We\u0026rsquo;ve introduced new methods to provide additional functionality and flexibility for handling state updates and event notifications. Migration Shadowing Function We\u0026rsquo;ve made significant improvements to the ShadowingModelFunction, which is now renamed to ShadowingFunction. Additionally, we\u0026rsquo;ve introduced changes to how the DigitalTwinState is managed within the Shadowing Function, providing developers with more control and flexibility.\nMigrating WLDT Engine \u0026amp; DT Creation In version 0.3.0, the WldtEngine class has been renamed to DigitalTwin, offering improved clarity and consistency. We\u0026rsquo;ve also made adjustments to the lifecycle management of Digital Twins, streamlining the process and enhancing usability.\nDigital Twin \u0026amp; Digital Twin Engine We\u0026rsquo;ve introduced enhancements to the Digital Twin and Digital Twin Engine classes, providing developers with improved functionality and ease of use. Notable updates include:\nSimplified Digital Twin Creation: Creating and managing Digital Twins is now more intuitive and streamlined. Lifecycle Management: We\u0026rsquo;ve enhanced the lifecycle management of Digital Twins, making it easier to start, stop, and manage multiple instances. Digital Twin State Manager The DigitalTwinStateManager class has been improved to provide better support for managing the state of Digital Twins. With features such as transaction support and event notification, developers can more effectively manage changes to Digital Twin states and respond to events.\nTo learn more about the capabilities of the DigitalTwinStateManager, please refer to the Digital Twin State Manager section.\nDigital Adapter We\u0026rsquo;ve extended and improved the Digital Adapter base class to provide enhanced support for handling Digital Twin state updates and event notifications. With the introduction of the onStateUpdate and onEventNotificationReceived methods, developers can more effectively respond to changes in Digital Twin states and events.\nGet Started with WLDT 0.3.0 To get started with version 0.3.0 of the WLDT library, simply update your dependencies to include the latest release. Detailed documentation and usage examples are available in the project repository, providing comprehensive guidance on leveraging the new features and enhancements.\nWe\u0026rsquo;re excited about the improvements and new capabilities introduced in WLDT 0.3.0, and we can\u0026rsquo;t wait to see how developers utilize them to create innovative IoT solutions powered by Digital Twins. As always, we welcome your feedback and contributions to help us further improve the library and empower the community.\nHappy coding with WLDT 0.3.0! 🚀\n","date":"March 13, 2024","id":0,"permalink":"/blog/ls-wldt-library-version-0.3.0/","summary":"📣 We\u0026rsquo;re thrilled to announce the release of version 0.3.0 of the White Label Digital Twins (WLDT) library! This release brings significant enhancements, improvements, and new features to further empower developers in designing, developing, and deploying Digital Twins within Internet of Things (IoT) ecosystems.","tags":"","title":"ls WLDT Library Version 0.3.0"},{"content":"","date":"September 7, 2023","id":1,"permalink":"/blog/","summary":"","tags":"","title":"Blog"},{"content":"","date":"September 7, 2023","id":2,"permalink":"/docs/introduction/","summary":"","tags":"","title":"Introduction"},{"content":"","date":"February 9, 2024","id":3,"permalink":"/docs/guides/","summary":"","tags":"","title":"Getting Started"},{"content":"The developer can use an existing Physical Adapter or create a new one to handle the communication with a specific physical twin. In this documentation we focus on the creation of a new Physical Adapter in order to explain library core functionalities. However, existing Physical Adapters can be found on the official repository and linked in the core documentation and webpage (WLDT-GitHub).\nIn general WLDT Physical Adapter extends the class PhysicalAdapter and it is responsible to talk with the physical world and handling the following main tasks:\nGenerate a PAD describing the properties, events, actions and relationships available on the physical twin using the class PhysicalAssetDescription Generate Physical Event using the class PhysicalAssetEventWldtEvent associated to the variation of any aspect of the physical state (properties, events, and relationships) Handle action request coming from the Digital World through the DT Shadowing Function by implementing the method onIncomingPhysicalAction and processing events modeled through the class PhysicalAssetActionWldtEvent Create a new class called DemoPhysicalAdapter extending the library class PhysicalAdapter and implement the following methods:\nonAdapterStart: A callback method used to notify when the adapter has been effectively started withing the DT\u0026rsquo;s life cycle onAdapterStop: A call method invoked when the adapter has been stopped and will be dismissed by the core onIncomingPhysicalAction: The callback method called when a new PhysicalAssetActionWldtEvent is sent by the Shadowing Function upon the receiving of a valid Digital Action through a Digital Adapter Then you have to create a constructor for your Physical Adapter with a single String parameter representing the id of the adapter. This id will be used internally by the library to handle and coordinate multiple adapters, adapts logs and execute functions upon the arrival of a new event. The resulting empty class will the following:\npublic class DemoPhysicalAdapter extends PhysicalAdapter { public DemoPhysicalAdapter(String id) { super(id); } @Override public void onIncomingPhysicalAction(PhysicalAssetActionWldtEvent\u0026lt;?\u0026gt; physicalAssetActionWldtEvent) { } @Override public void onAdapterStart() { } @Override public void onAdapterStop() { } } In our test Physical Adapter example we are going to emulate the communication with an Internet of Things device with the following sensing and actuation characteristics:\nA Temperature Sensor generating data about new measurements The possibility to generate OVER-HEATING events An action to set the target desired temperature value The first step will be to generate and publish the PhysicalAssetDescription (PAD) to describe the capabilities and the characteristics of our object allowing the Shadowing Function to decide how to digitalize its physical counterpart. Of course in our case the PAD is generated manually but according to the nature of the connected physical twin it can be automatically generated starting from a discovery or a configuration passed to the adapter.\nThe generation of the PAD for each active Physical Adapter is the fundamental DT process to handle the binding procedure and to allow the Shadowing Function and consequently the core of the twin to be aware of what is available in the physical world and consequently decide what to observe and digitalize.\nIn order to publish the PAD we can update the onAdapterStart method with the following lines of code:\nprivate final static String TEMPERATURE_PROPERTY_KEY = \u0026#34;temperature-property-key\u0026#34;; private final static String OVERHEATING_EVENT_KEY = \u0026#34;overheating-event-key\u0026#34;; private final static String SET_TEMPERATURE_ACTION_KEY = \u0026#34;set-temperatura-action-key\u0026#34;; @Override public void onAdapterStart() { try { //Create an empty PAD PhysicalAssetDescription pad = new PhysicalAssetDescription(); //Add a new Property associated to the target PAD with a key and a default value PhysicalAssetProperty\u0026lt;Double\u0026gt; temperatureProperty = new PhysicalAssetProperty\u0026lt;Double\u0026gt;(TEMPERATURE_PROPERTY_KEY, 0.0); pad.getProperties().add(temperatureProperty); //Add the declaration of a new type of generated event associated to a event key // and the content type of the generated payload PhysicalAssetEvent overheatingEvent = new PhysicalAssetEvent(OVERHEATING_EVENT_KEY, \u0026#34;text/plain\u0026#34;); pad.getEvents().add(overheatingEvent); //Declare the availability of a target action characterized by a Key, an action type // and the expected content type and the request body PhysicalAssetAction setTemperatureAction = new PhysicalAssetAction(SET_TEMPERATURE_ACTION_KEY, \u0026#34;temperature.actuation\u0026#34;, \u0026#34;text/plain\u0026#34;); pad.getActions().add(setTemperatureAction); //Notify the new PAD to the DT\u0026#39;s Shadowing Function this.notifyPhysicalAdapterBound(pad); //TODO add here the Device Emulation method } catch (PhysicalAdapterException | EventBusException e) { e.printStackTrace(); } } Now we need a simple code to emulate the generation of new temperature measurements and over-heating events. In a real Physical Adapter implementation we have to implement the real communication with the physical twin in order to read its state variation over time according to the supported protocols. In our simplified Physical Adapter we can the following function:\nprivate final static int MESSAGE_UPDATE_TIME = 1000; private final static int MESSAGE_UPDATE_NUMBER = 10; private final static double TEMPERATURE_MIN_VALUE = 20; private final static double TEMPERATURE_MAX_VALUE = 30; private Runnable deviceEmulation(){ return () -\u0026gt; { try { //Sleep 5 seconds to emulate device startup Thread.sleep(5000); //Create a new random object to emulate temperature variations Random r = new Random(); //Publish an initial Event for a normal condition publishPhysicalAssetEventWldtEvent(new PhysicalAssetEventWldtEvent\u0026lt;\u0026gt;(OVERHEATING_EVENT_KEY, \u0026#34;normal\u0026#34;)); //Emulate the generation on \u0026#39;n\u0026#39; temperature measurements for(int i = 0; i \u0026lt; MESSAGE_UPDATE_NUMBER; i++){ //Sleep to emulate sensor measurement Thread.sleep(MESSAGE_UPDATE_TIME); //Update the double randomTemperature = TEMPERATURE_MIN_VALUE + (TEMPERATURE_MAX_VALUE - TEMPERATURE_MIN_VALUE) * r.nextDouble(); //Create a new event to notify the variation of a Physical Property PhysicalAssetPropertyWldtEvent\u0026lt;Double\u0026gt; newPhysicalPropertyEvent = new PhysicalAssetPropertyWldtEvent\u0026lt;\u0026gt;(TEMPERATURE_PROPERTY_KEY, randomTemperature); //Publish the WLDTEvent associated to the Physical Property Variation publishPhysicalAssetPropertyWldtEvent(newPhysicalPropertyEvent); } //Publish a demo Physical Event associated to a \u0026#39;critical\u0026#39; overheating condition publishPhysicalAssetEventWldtEvent(new PhysicalAssetEventWldtEvent\u0026lt;\u0026gt;(OVERHEATING_EVENT_KEY, \u0026#34;critical\u0026#34;)); } catch (EventBusException | InterruptedException e) { e.printStackTrace(); } }; } Now we have to call the deviceEmulationFunction() inside the onAdapterStart() triggering its execution and emulating the physical counterpart of our DT. To do that add the following line at the end of the onAdapterStart() method after the this.notifyPhysicalAdapterBound(pad);.\nThe last step will be to handle an incoming action trying to set a new temperature on the device by implementing the method onIncomingPhysicalAction(). This method will receive a PhysicalAssetActionWldtEvent\u0026lt;?\u0026gt; physicalAssetActionWldtEvent associated to the action request generated by the shadowing function. Since a Physical Adapter can handle multiple action we have to check both action-key and body type in order to properly process the action (in our case just logging the request). The new update method will result like this:\n@Override public void onIncomingPhysicalAction(PhysicalAssetActionWldtEvent\u0026lt;?\u0026gt; physicalAssetActionWldtEvent) { try{ if(physicalAssetActionWldtEvent != null \u0026amp;\u0026amp; physicalAssetActionWldtEvent.getActionKey().equals(SET_TEMPERATURE_ACTION_KEY) \u0026amp;\u0026amp; physicalAssetActionWldtEvent.getBody() instanceof String) { System.out.println(\u0026#34;Received Action Request: \u0026#34; + physicalAssetActionWldtEvent.getActionKey() + \u0026#34; with Body: \u0026#34; + physicalAssetActionWldtEvent.getBody()); } else System.err.println(\u0026#34;Wrong Action Received !\u0026#34;); }catch (Exception e){ e.printStackTrace(); } } The overall class will result as following:\nimport it.wldt.adapter.physical.*; import it.wldt.adapter.physical.event.PhysicalAssetActionWldtEvent; import it.wldt.adapter.physical.event.PhysicalAssetEventWldtEvent; import it.wldt.adapter.physical.event.PhysicalAssetPropertyWldtEvent; import it.wldt.exception.EventBusException; import it.wldt.exception.PhysicalAdapterException; import java.util.Random; public class DemoPhysicalAdapter extends PhysicalAdapter { private final static String TEMPERATURE_PROPERTY_KEY = \u0026#34;temperature-property-key\u0026#34;; private final static String OVERHEATING_EVENT_KEY = \u0026#34;overheating-event-key\u0026#34;; private final static String SET_TEMPERATURE_ACTION_KEY = \u0026#34;set-temperature-action-key\u0026#34;; private final static int MESSAGE_UPDATE_TIME = 1000; private final static int MESSAGE_UPDATE_NUMBER = 10; private final static double TEMPERATURE_MIN_VALUE = 20; private final static double TEMPERATURE_MAX_VALUE = 30; public DemoPhysicalAdapter(String id) { super(id); } @Override public void onIncomingPhysicalAction(PhysicalAssetActionWldtEvent\u0026lt;?\u0026gt; physicalAssetActionWldtEvent) { try{ if(physicalAssetActionWldtEvent != null \u0026amp;\u0026amp; physicalAssetActionWldtEvent.getActionKey().equals(SET_TEMPERATURE_ACTION_KEY) \u0026amp;\u0026amp; physicalAssetActionWldtEvent.getBody() instanceof Double) { System.out.println(\u0026#34;Received Action Request: \u0026#34; + physicalAssetActionWldtEvent.getActionKey() + \u0026#34; with Body: \u0026#34; + physicalAssetActionWldtEvent.getBody()); } else System.err.println(\u0026#34;Wrong Action Received !\u0026#34;); }catch (Exception e){ e.printStackTrace(); } } @Override public void onAdapterStart() { try { //Create an empty PAD PhysicalAssetDescription pad = new PhysicalAssetDescription(); //Add a new Property associated to the target PAD with a key and a default value PhysicalAssetProperty\u0026lt;Double\u0026gt; temperatureProperty = new PhysicalAssetProperty\u0026lt;Double\u0026gt;(GlobalKeywords.TEMPERATURE_PROPERTY_KEY, 0.0); pad.getProperties().add(temperatureProperty); //Add the declaration of a new type of generated event associated to a event key // and the content type of the generated payload PhysicalAssetEvent overheatingEvent = new PhysicalAssetEvent(GlobalKeywords.OVERHEATING_EVENT_KEY, \u0026#34;text/plain\u0026#34;); pad.getEvents().add(overheatingEvent); //Declare the availability of a target action characterized by a Key, an action type // and the expected content type and the request body PhysicalAssetAction setTemperatureAction = new PhysicalAssetAction(GlobalKeywords.SET_TEMPERATURE_ACTION_KEY, \u0026#34;temperature.actuation\u0026#34;, \u0026#34;text/plain\u0026#34;); pad.getActions().add(setTemperatureAction); //Notify the new PAD to the DT\u0026#39;s Shadowing Function this.notifyPhysicalAdapterBound(pad); //Start Device Emulation new Thread(deviceEmulation()).start(); } catch (PhysicalAdapterException | EventBusException e) { e.printStackTrace(); } } @Override public void onAdapterStop() { } private Runnable deviceEmulation(){ return () -\u0026gt; { try { //Sleep 5 seconds to emulate device startup Thread.sleep(5000); //Create a new random object to emulate temperature variations Random r = new Random(); //Publish an initial Event for a normal condition publishPhysicalAssetEventWldtEvent(new PhysicalAssetEventWldtEvent\u0026lt;\u0026gt;(GlobalKeywords.OVERHEATING_EVENT_KEY, \u0026#34;normal\u0026#34;)); //Emulate the generation on \u0026#39;n\u0026#39; temperature measurements for(int i = 0; i \u0026lt; GlobalKeywords.MESSAGE_UPDATE_NUMBER; i++){ //Sleep to emulate sensor measurement Thread.sleep(GlobalKeywords.MESSAGE_UPDATE_TIME); //Update the double randomTemperature = GlobalKeywords.TEMPERATURE_MIN_VALUE + (GlobalKeywords.TEMPERATURE_MAX_VALUE - GlobalKeywords.TEMPERATURE_MIN_VALUE) * r.nextDouble(); //Create a new event to notify the variation of a Physical Property PhysicalAssetPropertyWldtEvent\u0026lt;Double\u0026gt; newPhysicalPropertyEvent = new PhysicalAssetPropertyWldtEvent\u0026lt;\u0026gt;(GlobalKeywords.TEMPERATURE_PROPERTY_KEY, randomTemperature); //Publish the WLDTEvent associated to the Physical Property Variation publishPhysicalAssetPropertyWldtEvent(newPhysicalPropertyEvent); } //Publish a demo Physical Event associated to a \u0026#39;critical\u0026#39; overheating condition publishPhysicalAssetEventWldtEvent(new PhysicalAssetEventWldtEvent\u0026lt;\u0026gt;(GlobalKeywords.OVERHEATING_EVENT_KEY, \u0026#34;critical\u0026#34;)); } catch (EventBusException | InterruptedException e) { e.printStackTrace(); } }; } } Both Physical Adapters and Digital Adapters can be defined natively with a custom configuration provided by the developer as illustrated in the dedicated Section: Configurable Physical \u0026amp; Digital Adapters.\n","date":"February 9, 2024","id":4,"permalink":"/docs/guides/physical-adapter/","summary":"The developer can use an existing Physical Adapter or create a new one to handle the communication with a specific physical twin.","tags":"","title":"Physical Adapter"},{"content":"After the definition of the Physical Adapter it is time to start implementing the core of our DT through the definition of its shadowing function in charge of:\nHandle received PAD from Physical Adapters in order to device which properties, events, relationships or actions available on connected physical twins should be mapped and managed into the DT State Manage incoming notifications/callbacks associated to the variation of physical properties (e.g, temperature variation) or the generation of physical event (e.g., overheating) Process action requests from the digital world that should be validated and forward to the correct Physical Adapter in order to trigger the associated actions on the physical world The Shadowing Function has the responsibility to build and maintain the updated state of the Digital Twin The internal variable of any WLDT Shadowing Function (available through the base class ShadowingFunction) used to do that is DigitalTwinStateManager accessible through the variable: this.digitalTwinStateManager\nWhen the Shadowing Function has to compute the new DT State it can now work with the following method to handle DT State Transition:\nStart the DT State Transaction: startStateTransaction() DT State variation methods such as: createProperty() updateProperty() updatePropertyValue() deleteProperty() enableAction() updateAction() disableAction() registerEvent() updateRegisteredEvent() unRegisterEvent() createRelationship() addRelationshipInstance() deleteRelationship() deleteRelationshipInstance() At the end the transaction can be committed using the method: commitStateTransaction() To access the current DT State the Shadowing Function implementation can use the method this.digitalTwinStateManager.getDigitalTwinState() The information available on the DT State are:\nproperties: List of Properties with their values (if available) actions: List of Actions that can be called on the DT events: List of Events that can be generated by the DT relationships: List of Relationships and their instances (if available) evaluationInstant: The timestamp representing the evaluation instant of the DT state Available main methods on that class instance are:\nProperties: getProperty(String propertyKey): Retrieves if present the target DigitalTwinStateProperty by Key containsProperty(String propertyKey): Checks if a target Property Key is already available in the current Digital Twin\u0026rsquo;s State getPropertyList(): Loads the list of available Properties (described by the class DigitalTwinStateProperty) available on the Digital Twin\u0026rsquo;s State createProperty(DigitalTwinStateProperty\u0026lt;?\u0026gt; dtStateProperty): Allows the creation of a new Property on the Digital Twin\u0026rsquo;s State through the class DigitalTwinStateProperty readProperty(String propertyKey): Retrieves if present the target DigitalTwinStateProperty by Key updateProperty(DigitalTwinStateProperty\u0026lt;?\u0026gt; dtStateProperty): Updates the target property using the DigitalTwinStateProperty and the associated Property Key field deleteProperty(String propertyKey): Deletes the target property identified by the specified key Actions: containsAction(String actionKey): Checks if a Digital Twin State Action with the specified key is correctly registered getAction(String actionKey): Loads the target DigitalTwinStateAction by key getActionList(): Gets the list of available Actions registered on the Digital Twin\u0026rsquo;s State enableAction(DigitalTwinStateAction digitalTwinStateAction): Enables and registers the target Action described through an instance of the DigitalTwinStateAction class updateAction(DigitalTwinStateAction digitalTwinStateAction): Update the already registered target Action described through an instance of the DigitalTwinStateAction class disableAction(String actionKey): Disables and unregisters the target Action described through an instance of the DigitalTwinStateAction class Events: containsEvent(String eventKey): Check if a Digital Twin State Event with the specified key is correctly registered getEvent(String eventKey): Return the description of a registered Digital Twin State Event according to its Key getEventList(): Return the list of existing and registered Digital Twin State Events registerEvent(DigitalTwinStateEvent digitalTwinStateEvent): Register a new Digital Twin State Event updateRegisteredEvent(DigitalTwinStateEvent digitalTwinStateEvent): Update the registration and signature of an existing Digital Twin State Event unRegisterEvent(String eventKey): Un-register a Digital Twin State Event notifyDigitalTwinStateEvent(DigitalTwinStateEventNotification\u0026lt;?\u0026gt; digitalTwinStateEventNotification): Method to notify the occurrence of the target Digital Twin State Event Relationships: containsRelationship(String relationshipName): Checks if a Relationship Name is already available in the current Digital Twin\u0026rsquo;s State createRelationship(DigitalTwinStateRelationship\u0026lt;?\u0026gt; relationship): Creates a new Relationships (described by the class DigitalTwinStateRelationship) in the Digital Twin\u0026rsquo;s State addRelationshipInstance(String name, DigitalTwinStateRelationshipInstance\u0026lt;?\u0026gt; instance): Adds a new Relationship instance described through the class DigitalTwinStateRelationshipInstance and identified through its name getRelationshipList(): Loads the list of existing relationships on the Digital Twin\u0026rsquo;s State through a list of DigitalTwinStateRelationship getRelationship(String name): Gets a target Relationship identified through its name and described through the class DigitalTwinStateRelationship deleteRelationship(String name): Deletes a target Relationship identified through its name deleteRelationshipInstance(String relationshipName, String instanceKey): Deletes the target Relationship Instance using relationship name and instance Key The basic library class that we are going to extend is called ShadowingFunction and creating a new class named DemoShadowingFunction the resulting code is the same after implementing required methods the basic constructor with the id String parameter.\nimport it.wldt.adapter.digital.event.DigitalActionWldtEvent; import it.wldt.adapter.physical.PhysicalAssetDescription; import it.wldt.adapter.physical.event.PhysicalAssetEventWldtEvent; import it.wldt.adapter.physical.event.PhysicalAssetPropertyWldtEvent; import it.wldt.adapter.physical.event.PhysicalAssetRelationshipInstanceCreatedWldtEvent; import it.wldt.adapter.physical.event.PhysicalAssetRelationshipInstanceDeletedWldtEvent; import it.wldt.core.model.ShadowingModelFunction; import java.util.Map; public class DemoShadowingFunction extends ShadowingModelFunction { public DemoShadowingFunction(String id) { super(id); } //// Shadowing Function Management Callbacks //// @Override protected void onCreate() { } @Override protected void onStart() { } @Override protected void onStop() { } //// Bound LifeCycle State Management Callbacks //// @Override protected void onDigitalTwinBound(Map\u0026lt;String, PhysicalAssetDescription\u0026gt; adaptersPhysicalAssetDescriptionMap) { } @Override protected void onDigitalTwinUnBound(Map\u0026lt;String, PhysicalAssetDescription\u0026gt; map, String s) { } @Override protected void onPhysicalAdapterBidingUpdate(String s, PhysicalAssetDescription physicalAssetDescription) { } //// Physical Property Variation Callback //// @Override protected void onPhysicalAssetPropertyVariation(PhysicalAssetPropertyWldtEvent\u0026lt;?\u0026gt; physicalAssetPropertyWldtEvent) { } //// Physical Event Notification Callback //// @Override protected void onPhysicalAssetEventNotification(PhysicalAssetEventWldtEvent\u0026lt;?\u0026gt; physicalAssetEventWldtEvent) { } //// Physical Relationships Notification Callbacks //// @Override protected void onPhysicalAssetRelationshipEstablished(PhysicalAssetRelationshipInstanceCreatedWldtEvent\u0026lt;?\u0026gt; physicalAssetRelationshipInstanceCreatedWldtEvent) { } @Override protected void onPhysicalAssetRelationshipDeleted(PhysicalAssetRelationshipInstanceDeletedWldtEvent\u0026lt;?\u0026gt; physicalAssetRelationshipInstanceDeletedWldtEvent) { } //// Digital Action Received Callbacks //// @Override protected void onDigitalActionEvent(DigitalActionWldtEvent\u0026lt;?\u0026gt; digitalActionWldtEvent) { } } The methods onCreate(), onStart() and onStop() are used to receive callbacks from the DT\u0026rsquo;s core when the Shadowing Function has been effectively created within the twin, is started or stopped according to the evolution of its life cycle. In our initial implementation we are not implementing any of them but they can be useful to trigger specific behaviours according to the different phases.\nThe first method that we have to implement in order to analyze received PAD and build the Digital Twin State in terms of properties, events, relationships and available actions is the onDigitalTwinBound(Map\u0026lt;String, PhysicalAssetDescription\u0026gt; map) method. In our initial implementation we just pass through all the received characteristics recevied from each connected Physical Adapter mapping every physical entity into the DT\u0026rsquo;s state without any change or adaptation (Of course complex behaviour can be implemented to customized the digitalization process).\nThrough the following method we implement the following behaviour:\nAnalyze each received PAD from each connected and active Physical Adapter (in our case we will have just 1 Physical Adapter) Iterate over all the received Properties for each PAD and create the same Property on the Digital Twin State Start observing target Physical Properties in order to receive notification callback about physical variation through the method observePhysicalAssetProperty(property); Analyze received PAD\u0026rsquo;s Events declaration and recreates them also on the DT\u0026rsquo;s State Start observing target Physical Event in order to receive notification callback about physical event generation through the method observePhysicalAssetEvent(event); Check available Physical Action and enable them on the DT\u0026rsquo;s State. Enabled Digital Action are automatically observed by the Shadowing Function in order to receive action requests from active Digital Adapters The possibility to manually observe Physical Properties and Event has been introduced to allow the Shadowing Function to decide what to do according to the nature of the property or of the target event. For example in some cases with static properties it will not be necessary to observe any variation, and it will be enough to read the initial value to build the digital replica of that specific property.\nSince the DT State is managed through the DigitalTwinStateManager class all the changes and variation should be applied on the DT ShadowingFunction using the previously presented transaction management and the correct call of methods startStateTransaction() and commitStateTransaction().\n@Override protected void onDigitalTwinBound(Map\u0026lt;String, PhysicalAssetDescription\u0026gt; adaptersPhysicalAssetDescriptionMap) { try{ // NEW from 0.3.0 -\u0026gt; Start DT State Change Transaction this.digitalTwinStateManager.startStateTransaction(); //Iterate over all the received PAD from connected Physical Adapters adaptersPhysicalAssetDescriptionMap.values().forEach(pad -\u0026gt; { //Iterate over all the received PAD from connected Physical Adapters adaptersPhysicalAssetDescriptionMap.values().forEach(pad -\u0026gt; { pad.getProperties().forEach(property -\u0026gt; { try { //Create and write the property on the DT\u0026#39;s State this.digitalTwinState.createProperty(new DigitalTwinStateProperty\u0026lt;\u0026gt;(property.getKey(),(Double) property.getInitialValue())); //Start observing the variation of the physical property in order to receive notifications //Without this call the Shadowing Function will not receive any notifications or callback about //incoming physical property of the target type and with the target key this.observePhysicalAssetProperty(property); } catch (Exception e) { e.printStackTrace(); } }); //Iterate over available declared Physical Events for the target Physical Adapter\u0026#39;s PAD pad.getEvents().forEach(event -\u0026gt; { try { //Instantiate a new DT State Event with the same key and type DigitalTwinStateEvent dtStateEvent = new DigitalTwinStateEvent(event.getKey(), event.getType()); //Create and write the event on the DT\u0026#39;s State this.digitalTwinState.registerEvent(dtStateEvent); //Start observing the variation of the physical event in order to receive notifications //Without this call the Shadowing Function will not receive any notifications or callback about //incoming physical events of the target type and with the target key this.observePhysicalAssetEvent(event); } catch (Exception e) { e.printStackTrace(); } }); //Iterate over available declared Physical Actions for the target Physical Adapter\u0026#39;s PAD pad.getActions().forEach(action -\u0026gt; { try { //Instantiate a new DT State Action with the same key and type DigitalTwinStateAction dtStateAction = new DigitalTwinStateAction(action.getKey(), action.getType(), action.getContentType()); //Enable the action on the DT\u0026#39;s State this.digitalTwinState.enableAction(dtStateAction); } catch (Exception e) { e.printStackTrace(); } }); }); // NEW from 0.3.0 -\u0026gt; Commit DT State Change Transaction to apply the changes on the DT State and notify about the change this.digitalTwinStateManager.commitStateTransaction(); //Start observation to receive all incoming Digital Action through active Digital Adapter //Without this call the Shadowing Function will not receive any notifications or callback about //incoming request to execute an exposed DT\u0026#39;s Action observeDigitalActionEvents(); //Notify the DT Core that the Bounding phase has been correctly completed and the DT has evaluated its //internal status according to what is available and declared through the Physical Adapters notifyShadowingSync(); }catch (Exception e){ e.printStackTrace(); } } In particular the method observeDigitalActionEvents() should be called start the observation of digital actions and to receive all incoming Digital Action through active Digital Adapters. Without this call the Shadowing Function will not receive any notifications or callback about incoming request to execute an exposed DT\u0026rsquo;s Action. Of course, we have to call this method if we are mapping any digital action in our DT.\nAnother fundamental method is notifyShadowingSync() used to notify the DT Core that the Bounding phase has been correctly completed and the DT has evaluated its internal status according to what is available and declared through the Physical Adapters.\nAs mentioned, in the previous example the Shadowing Function does not apply any control or check on the nature of declared physical property. Of course in order to have a more granular control, it will be possible to use property Key or any other field or even the type of the instance through an instanceof check to implement different controls and behaviours.\nA variation (only for the property management code) to the previous method can be the following:\n//Iterate over available declared Physical Property for the target Physical Adapter\u0026#39;s PAD pad.getProperties().forEach(property -\u0026gt; { try { //Check property Key and Instance of to validate that is a Double if(property.getKey().equals(\u0026#34;temperature-property-key\u0026#34;) \u0026amp;\u0026amp; property.getInitialValue() != null \u0026amp;\u0026amp; property.getInitialValue() instanceof Double) { //Instantiate a new DT State Property of the right type, the same key and initial value DigitalTwinStateProperty\u0026lt;Double\u0026gt; dtStateProperty = new DigitalTwinStateProperty\u0026lt;Double\u0026gt;(property.getKey(),(Double) property.getInitialValue()); //Create and write the property on the DT\u0026#39;s State this.digitalTwinState.createProperty(dtStateProperty); //Start observing the variation of the physical property in order to receive notifications //Without this call the Shadowing Function will not receive any notifications or callback about //incoming physical property of the target type and with the target key this.observePhysicalAssetProperty(property); } } catch (Exception e) { e.printStackTrace(); } }); The next method that we have to implement in order to properly define and implement the behaviour of our DT through its ShadowingModelFunction are:\nonPhysicalAssetPropertyVariation: Method called when a new variation for a specific Physical Property has been detected by the associated Physical Adapter. The method receive as parameter a specific WLDT Event called PhysicalAssetPropertyWldtEvent\u0026lt;?\u0026gt; physicalPropertyEventMessage containing all the information generated by the Physical Adapter upon the variation of the monitored physical counterpart. onPhysicalAssetEventNotification: Callback method used to be notified by a PhysicalAdapter about the generation of a Physical Event. As for the previous method, also this function receive a WLDT Event parameter of type onPhysicalAssetEventNotification(PhysicalAssetEventWldtEvent\u0026lt;?\u0026gt; physicalAssetEventWldtEvent)) containing all the field of the generated physical event. onDigitalActionEvent: On the opposite this method is triggered from one of the active Digital Adapter when an Action request has been received on the Digital Interface. The method receive as parameter an instance of the WLDT Event class DigitalActionWldtEvent\u0026lt;?\u0026gt; digitalActionWldtEvent describing the target digital action request and the associated body. For the onPhysicalAssetPropertyVariation a simple implementation in charge ONLY of mapping the new Physical Property value into the corresponding DT\u0026rsquo;State property can be implemented as follows:\nThe DT State transaction management should be applied in the point of the code where the Shadowing Function receive a variation from the Physical world through a target adapter and the callback method onPhysicalAssetPropertyVariation(...)\n@Override protected void onPhysicalAssetPropertyVariation(PhysicalAssetPropertyWldtEvent\u0026lt;?\u0026gt; physicalPropertyEventMessage) { try { //Update Digital Twin State //NEW from 0.3.0 -\u0026gt; Start State Transaction this.digitalTwinStateManager.startStateTransaction(); this.digitalTwinState.updateProperty(new DigitalTwinStateProperty\u0026lt;\u0026gt;(physicalPropertyEventMessage.getPhysicalPropertyId(), physicalPropertyEventMessage.getBody())); //NEW from 0.3.0 -\u0026gt; Commit State Transaction this.digitalTwinStateManager.commitStateTransaction(); } catch (WldtDigitalTwinStatePropertyException | WldtDigitalTwinStatePropertyBadRequestException | WldtDigitalTwinStatePropertyNotFoundException | WldtDigitalTwinStateException e) { e.printStackTrace(); } } In this case as reported in the code, we call the method this.digitalTwinState.updateProperty on the Shadowing Function in order to update an existing DT\u0026rsquo;State property (previously created in the onDigitalTwinBound method). To update the value we directly use the received data on the PhysicalAssetPropertyWldtEvent without any additional check or change that might be instead needed in advanced examples.\nFollowing the same principle, a simplified digital mapping between physical and digital state upon the receving of a physical event variation can be the following:\n@Override protected void onPhysicalAssetEventNotification(PhysicalAssetEventWldtEvent\u0026lt;?\u0026gt; physicalAssetEventWldtEvent) { try { this.digitalTwinStateManager.notifyDigitalTwinStateEvent(new DigitalTwinStateEventNotification\u0026lt;\u0026gt;(physicalAssetEventWldtEvent.getPhysicalEventKey(), physicalAssetEventWldtEvent.getBody(), physicalAssetEventWldtEvent.getCreationTimestamp())); } catch (WldtDigitalTwinStateEventNotificationException | EventBusException e) { e.printStackTrace(); } } With respect to events management, we use the Shadowint Function method this.digitalTwinState.notifyDigitalTwinStateEvent to notify the other DT Components (e.g., Digital Adapters) the incoming Physical Event by creating a new instance of a DigitalTwinStateEventNotification class containing all the information associated to the event. Of course, additional controls and checks can be introduced in this method validating and processing the incoming physical message to define complex behaviours.\nThe last method that we are going to implement is the onDigitalActionEvent one where we have to handle an incoming Digital Action request associated to an Action declared on the DT\u0026rsquo;s State in the onDigitalTwinBound method. In that case the Digital Action should be forwarded to the Physical Interface in order to be sent to the physical counterpart for the effective execution.\n@Override protected void onDigitalActionEvent(DigitalActionWldtEvent\u0026lt;?\u0026gt; digitalActionWldtEvent) { try { this.publishPhysicalAssetActionWldtEvent(digitalActionWldtEvent.getActionKey(), digitalActionWldtEvent.getBody()); } catch (EventBusException e) { e.printStackTrace(); } } Also in that case we are forwarding the incoming Digital Action request described through the class DigitalActionWldtEvent to the Physical Adapter with the method of the Shadowing Function denoted as this.publishPhysicalAssetActionWldtEvent and passing directly the action key and the target Body. No additional processing or validation have been introduced here, but they might be required in advanced scenario in order to properly adapt incoming digital action request to what is effectively expected on the physical counterpart.\n","date":"February 9, 2024","id":5,"permalink":"/docs/guides/shadowing-function/","summary":"After the definition of the Physical Adapter it is time to start implementing the core of our DT through the definition of its shadowing function in charge of:","tags":"","title":"Shadowing Function"},{"content":"The las component that we have to implement to complete our first simple Digital Twin definition through the WLDT library is a Digital Adapter in charge of:\nReceiving event from the DT\u0026rsquo;s Core related to the variation of properties, events, available actions and relationships Expose received information to the external world according to its implementation and the supported protocol Handle incoming digital action and forward them to the Core in order to be validated and processed by the Shadowing Function The basic library class that we are going to extend is called DigitalAdapter and creating a new class named DemoDigitalAdapter. The DigitalTwinAdapter class can take as Generic Type the type of Configuration used to configure its behaviours. In this simplified example we are defining a DigitalAdapter without any Configuration.\nA Digital Adapter has direct access to the current DT\u0026rsquo;s State through callbacks or directly in a synchronous way using the internal variable called: digitalTwinState. Through it is possibile to navigate all the fields currently composing the state of our Digital Twin.\nThe Digital Adapter class has e long list of callback and notification method to allow the adapter to be updated about all the variation and changes on the twin. Available callbacks can be summarized as follows:\nDigital Adapter Start/Stop: onAdapterStart(): Feedback when the Digital Adapter correctly starts onAdapterStop(): Feedback when the Digital Adapter has been stopped Digital Twin Life Cycle Notifications: onDigitalTwinCreate(): The DT has been created onDigitalTwinStart(): The DT started onDigitalTwinSync(IDigitalTwinState digitalTwinState): The DT is Synchronized with its physical counterpart. The current DigitalTwinState is passed as parameter to allow the Digital Adapter to know the current state and consequently implement its behaviour onDigitalTwinUnSync(IDigitalTwinState digitalTwinState): The DT is not synchronized anymore with its physical counterpart. The last current DigitalTwinState is passed as parameter to allow the Digital Adapter to know the last state and consequently implement its behaviour onDigitalTwinStop(): The DT is stopped onDigitalTwinDestroy(): The DT has been destroyed and the application stopped The Digital Adapter DT State variations and DT events are received by the Adapter from the DT core belongs to the following categories:\nDigital Twin State Update through the method onStateUpdate(...) providing information about the new state of the Digital Twin, the previous state, and a list of changes that occurred between these two states. In the previous version each variation of a property, relationships, actions or events were notified. In the new version only a committed DT\u0026rsquo;State variation is notified to listeners. Event Notifications through the method onEventNotificationReceived(...) whenever there is a notification about an event related to the Digital Twin\u0026rsquo;s state coming from the physical world, generated by the twin and processed by the Shadowing Function. For example in the DT State we can have the declaration of the over-heating-alert structured and received in the DT State while the effective occurrence of the event and the associated notification is notified through this dedicated callback The onStateUpdate method is an abstract method that must be implemented by any class extending the DigitalAdapter class. This method is called whenever there is an update to the Digital Twin\u0026rsquo;s state. It provides information about the new state of the Digital Twin, the previous state, and a list of changes that occurred between these two states.\nThe explanation of the parameters is the following:\nnewDigitalTwinState: This parameter represents the updated state of the Digital Twin. It is an instance of the DigitalTwinState class, which encapsulates the current state information. previousDigitalTwinState: This parameter represents the state of the Digital Twin before the update. It is also an instance of the DigitalTwinState class. digitalTwinStateChangeList: This parameter is an ArrayList containing DigitalTwinStateChange objects. Each DigitalTwinStateChange object encapsulates information about a specific change that occurred between the previous and new states. It includes details such as the property or aspect of the state that changed, the previous value, and the new value. Another core method where a Digital Adapter receive the description of the DT\u0026rsquo;State is onDigitalTwinSync(IDigitalTwinState digitalTwinState). The Adapter using the parameter digitalTwinState can analyze available properties, actions, events and relationships and decide how to implement its internal behaviour with the methods presented in ShadowingFunction. The DT State is automatically monitored by each Digital Adapter while for the Events potentially generated by the DT can be observed by each adapter using:\nobserveAllDigitalTwinEventsNotifications: Enable the observation of available Digital Twin State Events Notifications. unObserveAllDigitalTwinEventsNotifications: Cancel the observation of Digital Twin State Events Notifications observeDigitalTwinEventsNotifications: Enable the observation of the notification associated to a specific list of Digital Twin State events. With respect to event a notification contains the new associated value unObserveDigitalTwinEventsNotifications: Cancel the observation of a target list of properties observeDigitalTwinEventNotification: Enable the observation of the notification associated to a single Digital Twin State event. With respect to event a notification contains the new associated value unObserveDigitalTwinEventNotification: Cancel the observation of a single target event The resulting code will be the following after adding the required methods (still empty) and the basic constructor with the id String parameter is the following:\nimport it.wldt.adapter.digital.DigitalAdapter; import it.wldt.core.state.*; public class DemoDigitalAdapter extends DigitalAdapter\u0026lt;Void\u0026gt; { public DemoDigitalAdapter(String id) { super(id); } /** * Callback to notify the adapter on its correct startup */ @Override public void onAdapterStart() {} /** * Callback to notify the adapter that has been stopped */ @Override public void onAdapterStop() {} /** * DT Life Cycle notification that the DT is correctly on Sync * @param digitalTwinState */ @Override public void onDigitalTwinSync(DigitalTwinState digitalTwinState) {} /** * DT Life Cycle notification that the DT is currently Not Sync * @param digitalTwinState */ @Override public void onDigitalTwinUnSync(DigitalTwinState digitalTwinState) {} /** * DT Life Cycle notification that the DT has been created */ @Override public void onDigitalTwinCreate() {} /** * DT Life Cycle Notification that the DT has correctly Started */ @Override public void onDigitalTwinStart() {} /** * DT Life Cycle Notification that the DT has been stopped */ @Override public void onDigitalTwinStop() {} /** * DT Life Cycle Notification that the DT has destroyed */ @Override public void onDigitalTwinDestroy() {} /** * Callback method allowing the Digital Adapter to receive the updated Digital Twin State together with * the previous state and the list of applied changes * * @param newDigitalTwinState The new Digital Twin State computed by the Shadowing Function * @param previousDigitalTwinState The previous Digital Twin State * @param digitalTwinStateChangeList The list of applied changes to compute the new Digital Twin State */ @Override protected void onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList\u0026lt;DigitalTwinStateChange\u0026gt; digitalTwinStateChangeList) {} /** * Callback method to receive a new computed Event Notification (associated to event declared in the DT State) * * @param digitalTwinStateEventNotification The generated Notification associated to a DT Event */ @Override protected void onEventNotificationReceived(DigitalTwinStateEventNotification\u0026lt;?\u0026gt; digitalTwinStateEventNotification) {} } By default, a Digital Adapter observes all the variation on the DT\u0026rsquo;s State in terms of Properties, Relationships, Actions and Events. As previously mentioned the observation of DT\u0026rsquo;s State Properties allows to receive also properties variation on the method since a property is natively composed by its description (e.g., type) and its current value. On the opposite the observation on DT\u0026rsquo;s State Action, Relationships and Events allow ONLY to receive callbacks when a new entity is added or an update is occurred without receiving updates on values variation.\nThe only thing that we should add in the onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) callback is the direct observation for Events. Following this approach we can change our Digital Adapter in the following methods:\nIn onDigitalTwinSync we observe in this first simple implementation only the incoming values for declared Events in the DT\u0026rsquo;State. As previously mentioned the observation of any variation of the State structure together with Properties Values are by default observed by any Digital Adapter. In this method we use the internal variable digitalTwinState to access the DT\u0026rsquo;s state and find available Events declaration that we would like to observe.\npublic void onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) { try { //Retrieve the list of available events and observe all variations digitalTwinState.getEventList() .map(eventList -\u0026gt; eventList.stream() .map(DigitalTwinStateEvent::getKey) .collect(Collectors.toList())) .ifPresent(eventKeys -\u0026gt; { try { observeDigitalTwinEventsNotifications(eventKeys); } catch (EventBusException e) { e.printStackTrace(); } }); } catch (Exception e) { e.printStackTrace(); } } Developers extending the DigitalAdapter class should implement the onStateUpdate method to define custom logic that needs to be executed whenever the state of the Digital Twin is updated. This could include tasks such as processing state changes, updating internal variables, triggering specific actions, or notifying other components about the state update.\nHere\u0026rsquo;s an example of how the method might be implemented in a concrete subclass of DigitalAdapter:\n@Override protected void onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList\u0026lt;DigitalTwinStateChange\u0026gt; digitalTwinStateChangeList) { // In newDigitalTwinState we have the new DT State System.out.println(\u0026#34;New DT State is: \u0026#34; + newDigitalTwinState); // The previous DT State is available through the variable previousDigitalTwinState System.out.println(\u0026#34;Previous DT State is: \u0026#34; + previousDigitalTwinState); // We can also check each DT\u0026#39;s state change potentially differentiating the behaviour for each change if (digitalTwinStateChangeList != null \u0026amp;\u0026amp; !digitalTwinStateChangeList.isEmpty()) { // Iterate through each state change in the list for (DigitalTwinStateChange stateChange : digitalTwinStateChangeList) { // Get information from the state change DigitalTwinStateChange.Operation operation = stateChange.getOperation(); DigitalTwinStateChange.ResourceType resourceType = stateChange.getResourceType(); DigitalTwinStateResource resource = stateChange.getResource(); // Perform different actions based on the type of operation switch (operation) { case OPERATION_UPDATE: // Handle an update operation System.out.println(\u0026#34;Update operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; case OPERATION_UPDATE_VALUE: // Handle an update value operation System.out.println(\u0026#34;Update value operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; case OPERATION_ADD: // Handle an add operation System.out.println(\u0026#34;Add operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; case OPERATION_REMOVE: // Handle a remove operation System.out.println(\u0026#34;Remove operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; default: // Handle unknown operation (optional) System.out.println(\u0026#34;Unknown operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; } } } else { // No state changes System.out.println(\u0026#34;No state changes detected.\u0026#34;); } } In this example, the method iterates over the list of state changes, extracts information about each change, and performs custom actions based on the changes. Developers can adapt this method to suit the specific requirements of their Digital Twin application.\nBoth Physical Adapters and Digital Adapters can be defined natively with a custom configuration provided by the developer as illustrated in the dedicated Section: Configurable Physical \u0026amp; Digital Adapters.\n","date":"February 9, 2024","id":6,"permalink":"/docs/guides/digital-adapter/","summary":"The las component that we have to implement to complete our first simple Digital Twin definition through the WLDT library is a Digital Adapter in charge of:","tags":"","title":"Digital Adapter"},{"content":"Now that we have created the main fundamental element of a DT (Physical Adapter, Shadowing Function and Digital Adapter) we can create Class file with a main to create the WLDT Engine with the created components and start the DT.\nCreate a new Java file called DemoDigitalTwin adding the following code:\nWith the following code we now create a new Digital Twin Instance\n// Create the new Digital Twin with its Shadowing Function DigitalTwin digitalTwin = new DigitalTwin(digitalTwinId, new DemoShadowingFunction()); // Physical Adapter with Configuration digitalTwin.addPhysicalAdapter( new DemoPhysicalAdapter( String.format(\u0026#34;%s-%s\u0026#34;, digitalTwinId, \u0026#34;test-physical-adapter\u0026#34;), new DemoPhysicalAdapterConfiguration(), true)); // Digital Adapter with Configuration digitalTwin.addDigitalAdapter( new DemoDigitalAdapter( String.format(\u0026#34;%s-%s\u0026#34;, digitalTwinId, \u0026#34;test-digital-adapter\u0026#34;), new DemoDigitalAdapterConfiguration()) ); DTs cannot be directly run but it should be added to the DigitalTwinEngine in order to be executed through the WLDT Library\n// Create the Digital Twin Engine DigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine(); // Add the Digital Twin to the Engine digitalTwinEngine.addDigitalTwin(digitalTwin); In order to start a DT from the Engine you can:\n// Directly start when you add it passing a second boolean value = true digitalTwinEngine.addDigitalTwin(digitalTwin. true); // Starting the single DT on the engine through its id digitalTwinEngine.startDigitalTwin(DIGITAL_TWIN_ID); // Start all the DTs registered on the engine digitalTwinEngine.startAll(); To stop a single twin or all the twin registered on the engine:\n// Stop a single DT on the engine through its id digitalTwinEngine.stopDigitalTwin(DIGITAL_TWIN_ID); // Stop all the DTs registered on the engine digitalTwinEngine.stopAll(); It is also possible to remove a DT from the Engine with a consequent stop if it is active and the deletion of its reference from the engine:\n// Remove a single DT on the engine through its id digitalTwinEngine.removeDigitalTwin(DIGITAL_TWIN_ID); // Remove all the DTs registered on the engine digitalTwinEngine.removeAll(); The resulting code in our case is:\npublic class DemoDigitalTwin { public static void main(String[] args) { try{ // Create the new Digital Twin DigitalTwin digitalTwin = new DigitalTwin( \u0026#34;test-dt-id\u0026#34;, new DemoShadowingFunction(\u0026#34;test-shadowing-function\u0026#34;) ); //Default Physical and Digital Adapter //digitalTwin.addPhysicalAdapter(new DemoPhysicalAdapter(\u0026#34;test-physical-adapter\u0026#34;)); //digitalTwin.addDigitalAdapter(new DemoDigitalAdapter(\u0026#34;test-digital-adapter\u0026#34;)); //Physical and Digital Adapters with Configuration digitalTwin.addPhysicalAdapter(new DemoConfPhysicalAdapter(\u0026#34;test-physical-adapter\u0026#34;, new DemoPhysicalAdapterConfiguration())); digitalTwin.addDigitalAdapter(new DemoConfDigitalAdapter(\u0026#34;test-digital-adapter\u0026#34;, new DemoDigitalAdapterConfiguration())); // Create the Digital Twin Engine DigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine(); // Add the Digital Twin to the Engine digitalTwinEngine.addDigitalTwin(digitalTwin); // Set a new Event-Logger to a Custom One that we created with the class \u0026#39;DemoEventLogger\u0026#39; WldtEventBus.getInstance().setEventLogger(new DemoEventLogger()); // Start all the DTs registered on the engine digitalTwinEngine.startAll(); }catch (Exception e){ e.printStackTrace(); } } } ","date":"February 9, 2024","id":7,"permalink":"/docs/guides/dt-engine-dt-instance/","summary":"Now that we have created the main fundamental element of a DT (Physical Adapter, Shadowing Function and Digital Adapter) we can create Class file with a main to create the WLDT Engine with the created components and start the DT.","tags":"","title":"DT Engine \u0026 DT Instance"},{"content":"In this demo implementation, we are going to emulate an incoming Digital Action on the Digital Adapter in order to show how it can be handled by the adapter and properly forwarded to the Shadowing Function for validation and the consequent interaction with the Physical Adapter and then with the physical twin.\nIn order to add a demo Digital Action trigger on the Digital Adapter we add the following method to the DemoDigitalAdapter class:\nprivate Runnable emulateIncomingDigitalAction(){ return () -\u0026gt; { try { System.out.println(\u0026#34;Sleeping before Emulating Incoming Digital Action ...\u0026#34;); Thread.sleep(5000); Random random = new Random(); //Emulate the generation on \u0026#39;n\u0026#39; temperature measurements for(int i = 0; i \u0026lt; 10; i++){ //Sleep to emulate sensor measurement Thread.sleep(1000); double randomTemperature = 25.0 + (30.0 - 25.0) * random.nextDouble(); publishDigitalActionWldtEvent(\u0026#34;set-temperature-action-key\u0026#34;, randomTemperature); } } catch (Exception e) { e.printStackTrace(); } }; } This method uses the Digital Adapter internal function denoted as publishDigitalActionWldtEvent(String actionKey, T body) allowing the adapter to send a notification to the DT\u0026rsquo;s Core (and consequently the Shadowing Function) about the arrival of a Digital Action with a specific key and body. In our case the key is set-temperature-action-key as declared in the Physical Adapter and in the PAD and the value is a simple Double with the new temperature value.\nThen we call this method in the following way at the end ot the onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) method.\n//Start Digital Action Emulation new Thread(emulateIncomingDigitalAction()).start(); Now the Shadowing Function should be updated in order to handle the incoming Action request from the Digital Adapter. In our case the shadowing function does not apply any validation or check and just forward to action to the Physical Adapter in order to be then forwarded to the physical twin. Of course advanced implementation can be introduced for example to validate action, adapt payload and data-formats or to augment functionalities (e.g., trigger multiple physical actions from a single digital request).\nIn our simple demo implementation the updated Shadowing Function method onDigitalActionEvent(DigitalActionWldtEvent\u0026lt;?\u0026gt; digitalActionWldtEvent) results as follows:\n@Override protected void onDigitalActionEvent(DigitalActionWldtEvent\u0026lt;?\u0026gt; digitalActionWldtEvent) { try { this.publishPhysicalAssetActionWldtEvent(digitalActionWldtEvent.getActionKey(), digitalActionWldtEvent.getBody()); } catch (Exception e) { e.printStackTrace(); } } This forwarding of the action triggers the corresponding Physical Adapter method onIncomingPhysicalAction(PhysicalAssetActionWldtEvent\u0026lt;?\u0026gt; physicalAssetActionWldtEvent) that in our case is emulated just with a Log on the console. Also in that case advanced Physical Adapter implementation can be introduced for example to adapt the request from a high-level (and potentially standard) DT action description to the custom requirements of the specific physical twin managed by the adapter.\n@Override public void onIncomingPhysicalAction(PhysicalAssetActionWldtEvent\u0026lt;?\u0026gt; physicalAssetActionWldtEvent) { try{ if(physicalAssetActionWldtEvent != null \u0026amp;\u0026amp; physicalAssetActionWldtEvent.getActionKey().equals(SET_TEMPERATURE_ACTION_KEY) \u0026amp;\u0026amp; physicalAssetActionWldtEvent.getBody() instanceof Double) { System.out.println(\u0026#34;Received Action Request: \u0026#34; + physicalAssetActionWldtEvent.getActionKey() + \u0026#34; with Body: \u0026#34; + physicalAssetActionWldtEvent.getBody()); } else System.err.println(\u0026#34;Wrong Action Received !\u0026#34;); }catch (Exception e){ e.printStackTrace(); } } ","date":"February 9, 2024","id":8,"permalink":"/docs/guides/digital-actions/","summary":"In this demo implementation, we are going to emulate an incoming Digital Action on the Digital Adapter in order to show how it can be handled by the adapter and properly forwarded to the Shadowing Function for validation and the consequent interaction with the Physical Adapter and then with the physical twin.","tags":"","title":"Digital Actions"},{"content":"The WLDT library provides a native method to define Configurable Physical ad Digital Adapters specifying a custom configuration class passed as parameter in the constructor.\nStarting with the Physical Adapter created in the previous example DemoPhysicalAdapter instead of extending the base class PhysicalAdapter we can extend now ConfigurablePhysicalAdapter\u0026lt;C\u0026gt; where C is the name of the that we would like to use as configuration.\nIn our example we can create a simple configuration class called DemoPhysicalAdapterConfiguration where we move the constant variable used to implement the behaviour of our demo physical adapter. The resulting class will be the following:\npublic class DemoPhysicalAdapterConfiguration { private int messageUpdateTime = GlobalKeywords.MESSAGE_UPDATE_TIME; private int messageUpdateNumber = GlobalKeywords.MESSAGE_UPDATE_NUMBER; private double temperatureMinValue = GlobalKeywords.TEMPERATURE_MIN_VALUE; private double temperatureMaxValue = GlobalKeywords.TEMPERATURE_MAX_VALUE; public DemoPhysicalAdapterConfiguration() { } public DemoPhysicalAdapterConfiguration(int messageUpdateTime, int messageUpdateNumber, double temperatureMinValue, double temperatureMaxValue) { this.messageUpdateTime = messageUpdateTime; this.messageUpdateNumber = messageUpdateNumber; this.temperatureMinValue = temperatureMinValue; this.temperatureMaxValue = temperatureMaxValue; } public int getMessageUpdateTime() { return messageUpdateTime; } public void setMessageUpdateTime(int messageUpdateTime) { this.messageUpdateTime = messageUpdateTime; } public int getMessageUpdateNumber() { return messageUpdateNumber; } public void setMessageUpdateNumber(int messageUpdateNumber) { this.messageUpdateNumber = messageUpdateNumber; } public double getTemperatureMinValue() { return temperatureMinValue; } public void setTemperatureMinValue(double temperatureMinValue) { this.temperatureMinValue = temperatureMinValue; } public double getTemperatureMaxValue() { return temperatureMaxValue; } public void setTemperatureMaxValue(double temperatureMaxValue) { this.temperatureMaxValue = temperatureMaxValue; } } Now we can create or update our Physical Adapter extending ConfigurablePhysicalAdapter\u0026lt;DemoPhysicalAdapterConfiguration\u0026gt; as illustrated in the following snippet:\npublic class DemoPhysicalAdapter extends ConfigurablePhysicalAdapter\u0026lt;DemoPhysicalAdapterConfiguration\u0026gt; { [...] } Extending this class also the constructor should be updated getting as a parameter the expected configuration instance. Our constructor will be the following:\npublic DemoConfPhysicalAdapter(String id, DemoPhysicalAdapterConfiguration configuration) { super(id, configuration); } After that change since we removed and moved the used constant values into the new Configuration class we have also to update the deviceEmulation() method having access to the configuration through the method getConfiguration() or this.getConfiguration() directly on the adapter.\nprivate Runnable deviceEmulation(){ return () -\u0026gt; { try { System.out.println(\u0026#34;[DemoPhysicalAdapter] -\u0026gt; Sleeping before Starting Physical Device Emulation ...\u0026#34;); //Sleep 5 seconds to emulate device startup Thread.sleep(10000); System.out.println(\u0026#34;[DemoPhysicalAdapter] -\u0026gt; Starting Physical Device Emulation ...\u0026#34;); //Create a new random object to emulate temperature variations Random r = new Random(); //Publish an initial Event for a normal condition publishPhysicalAssetEventWldtEvent(new PhysicalAssetEventWldtEvent\u0026lt;\u0026gt;(GlobalKeywords.OVERHEATING_EVENT_KEY, \u0026#34;normal\u0026#34;)); //Emulate the generation on \u0026#39;n\u0026#39; temperature measurements for(int i = 0; i \u0026lt; getConfiguration().getMessageUpdateNumber(); i++){ //Sleep to emulate sensor measurement Thread.sleep(getConfiguration().getMessageUpdateTime()); //Update the double randomTemperature = getConfiguration().getTemperatureMinValue() + (getConfiguration().getTemperatureMaxValue() - getConfiguration().getTemperatureMinValue()) * r.nextDouble(); //Create a new event to notify the variation of a Physical Property PhysicalAssetPropertyWldtEvent\u0026lt;Double\u0026gt; newPhysicalPropertyEvent = new PhysicalAssetPropertyWldtEvent\u0026lt;\u0026gt;(GlobalKeywords.TEMPERATURE_PROPERTY_KEY, randomTemperature); //Publish the WLDTEvent associated to the Physical Property Variation publishPhysicalAssetPropertyWldtEvent(newPhysicalPropertyEvent); } //Publish a demo Physical Event associated to a \u0026#39;critical\u0026#39; overheating condition publishPhysicalAssetEventWldtEvent(new PhysicalAssetEventWldtEvent\u0026lt;\u0026gt;(GlobalKeywords.OVERHEATING_EVENT_KEY, \u0026#34;critical\u0026#34;)); } catch (EventBusException | InterruptedException e) { e.printStackTrace(); } }; } A similar approach can be adopted also for the Digital Adapter with the small difference that the base class DigitalAdapter already allow the possibility to specify a configuration. For this reason in the previous example we extended DigitalAdapter\u0026lt;Void\u0026gt; avoiding to specifying a configuration.\nIn this updated version we can create a new DemoDigitalAdapterConfiguration class containing the parameter association to the emulation of the action and then update our adapter to support the new configuration. Our new configuration class will be:\npublic class DemoDigitalAdapterConfiguration { private int sleepTimeMs = GlobalKeywords.ACTION_SLEEP_TIME_MS; private int emulatedActionCount = GlobalKeywords.EMULATED_ACTION_COUNT; private double temperatureMinValue = GlobalKeywords.TEMPERATURE_MIN_VALUE; private double temperatureMaxValue = GlobalKeywords.TEMPERATURE_MAX_VALUE; public DemoDigitalAdapterConfiguration() { } public DemoDigitalAdapterConfiguration(int sleepTimeMs, int emulatedActionCount, double temperatureMinValue, double temperatureMaxValue) { this.sleepTimeMs = sleepTimeMs; this.emulatedActionCount = emulatedActionCount; this.temperatureMinValue = temperatureMinValue; this.temperatureMaxValue = temperatureMaxValue; } public int getSleepTimeMs() { return sleepTimeMs; } public void setSleepTimeMs(int sleepTimeMs) { this.sleepTimeMs = sleepTimeMs; } public int getEmulatedActionCount() { return emulatedActionCount; } public void setEmulatedActionCount(int emulatedActionCount) { this.emulatedActionCount = emulatedActionCount; } public double getTemperatureMinValue() { return temperatureMinValue; } public void setTemperatureMinValue(double temperatureMinValue) { this.temperatureMinValue = temperatureMinValue; } public double getTemperatureMaxValue() { return temperatureMaxValue; } public void setTemperatureMaxValue(double temperatureMaxValue) { this.temperatureMaxValue = temperatureMaxValue; } } After that we can update the declaration of our Digital Adapter and modify its constructor to accept the configuration. The resulting class will be:\npublic class DemoDigitalAdapter extends DigitalAdapter\u0026lt;DemoDigitalAdapterConfiguration\u0026gt; { public DemoDigitalAdapter(String id, DemoDigitalAdapterConfiguration configuration) { super(id, configuration); } [...] } Of course the possibility to have this configuration will allow us to improve the emulateIncomingDigitalAction method in the following way having access to the configuration through the method getConfiguration() or this.getConfiguration() directly on the adapter:\nprivate Runnable emulateIncomingDigitalAction(){ return () -\u0026gt; { try { System.out.println(\u0026#34;[DemoDigitalAdapter] -\u0026gt; Sleeping before Emulating Incoming Digital Action ...\u0026#34;); Thread.sleep(5000); Random random = new Random(); //Emulate the generation on \u0026#39;n\u0026#39; temperature measurements for(int i = 0; i \u0026lt; getConfiguration().getEmulatedActionCount(); i++){ //Sleep to emulate sensor measurement Thread.sleep(getConfiguration().getSleepTimeMs()); double randomTemperature = getConfiguration().getTemperatureMinValue() + (getConfiguration().getTemperatureMaxValue() - getConfiguration().getTemperatureMinValue()) * random.nextDouble(); publishDigitalActionWldtEvent(\u0026#34;set-temperature-action-key\u0026#34;, randomTemperature); } } catch (Exception e) { e.printStackTrace(); } }; } When we have updated both adapters making them configurable we can update our main function in the process that we have previouly device using the updated adapters and passing the configurations:\npublic class DemoDigitalTwin { public static void main(String[] args) { try{ WldtEngine digitalTwinEngine = new WldtEngine(new DemoShadowingFunction(\u0026#34;test-shadowing-function\u0026#34;), \u0026#34;test-digital-twin\u0026#34;); //Default Physical and Digital Adapter //digitalTwinEngine.addPhysicalAdapter(new DemoPhysicalAdapter(\u0026#34;test-physical-adapter\u0026#34;)); //digitalTwinEngine.addDigitalAdapter(new DemoDigitalAdapter(\u0026#34;test-digital-adapter\u0026#34;)); //Physical and Digital Adapters with Configuration digitalTwinEngine.addPhysicalAdapter(new DemoConfPhysicalAdapter(\u0026#34;test-physical-adapter\u0026#34;, new DemoPhysicalAdapterConfiguration())); digitalTwinEngine.addDigitalAdapter(new DemoConfDigitalAdapter(\u0026#34;test-digital-adapter\u0026#34;, new DemoDigitalAdapterConfiguration())); digitalTwinEngine.startLifeCycle(); }catch (Exception e){ e.printStackTrace(); } } } ","date":"February 9, 2024","id":9,"permalink":"/docs/guides/configurable-adapters/","summary":"The WLDT library provides a native method to define Configurable Physical ad Digital Adapters specifying a custom configuration class passed as parameter in the constructor.","tags":"","title":"Configurable Adapters"},{"content":"","date":"February 9, 2024","id":10,"permalink":"/docs/adapters/","summary":"","tags":"","title":"Adapters"},{"content":"The MqttPhysicalAdapter library provides a streamlined solution for efficiently managing physical assets through the MQTT protocol. It offers a range of features, including a versatile builder for effortless configuration of MQTT connections, dedicated classes for handling both incoming and outgoing topics, and a specialized adapter designed for seamless integration with diverse physical assets.\nKey Features:\nBuilder for MQTT Configuration: The library incorporates a flexible builder pattern, enabling users to effortlessly configure the essential parameters of the MQTT connection. This includes specifying the MQTT broker\u0026rsquo;s address, port, and other relevant details to establish a reliable and customizable communication link. Incoming and Outgoing Topic Handling: MqttPhysicalAdapter facilitates the handling of incoming and outgoing topics, crucial for communication between the physical assets and the MQTT broker. The library includes dedicated classes for defining and managing topics, allowing users to efficiently subscribe to incoming data and publish outgoing messages. Adapter for Physical Asset Integration: At the core of the library is a robust adapter designed specifically for integrating with various physical assets. This adapter streamlines the process of connecting and interacting with physical devices, ensuring a smooth and standardized approach to managing asset-related data. In the WLDT library, Physical Adapters has the responsibility to generate and publish the PhysicalAssetDescription (PAD) to describe the capabilities and the characteristics of our object allowing the Shadowing Function to decide how to digitalize its physical counterpart.\nIn the MqttPhysicalAdapter the generation of the PAD (Physical Asset Description) is automatically and internally executed by the adapter itself accordingly to the adapter configuration in terms of MQTT topics and their mapping with DT\u0026rsquo;s properties, events and actions.\nPrerequisites:\nExternal MQTT Broker: The MqttPhysicalAdapter library requires an external MQTT broker for optimal functionality. Users must have access to a reliable MQTT broker to which the adapter can subscribe. This external broker serves as the central communication hub, facilitating the exchange of messages between the adapter and the physical assets. A complete example is provided in the test folder with a complete DT Creation in the TestMain class together with MQTT IoT demo device and a test MQTT consumer.\nWLDT-Core Version Compatibility The correct mapping and compatibility between versions is reported in the following table\nmqtt-physical-adapter wldt-core 0.2.1 wldt-core 0.3.0 0.1.0 ✅ ❌ 0.1.1 ❌ ✅ Installation To use MqttPhysicalAdapter in your Java project, you can include it as a dependency using Maven or Gradle.\nMaven \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.github.wldt\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;mqtt-physical-adapter\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;0.1.1\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; Gradle implementation \u0026#39;io.github.wldt:mqtt-physical-adapter:0.1.1\u0026#39; Class Structure \u0026amp; Functionalities MqttPhysicalAdapterConfigurationBuilder \u0026amp; Main Methods The MqttPhysicalAdapterConfigurationBuilder is the class used to build the configuration used by the PhysicalAdater and described and implemented through the class MqttPhysicalAdapterConfiguration.\nIn order to create a configuration builder we can use the static method builder() on the MqttPhysicalAdapterConfiguration class:\nMqttPhysicalAdapterConfiguration.builder(); On the builder the available methods that can be used are:\naddPhysicalAssetPropertyAndTopic public \u0026lt;T\u0026gt; MqttPhysicalAdapterConfigurationBuilder addPhysicalAssetPropertyAndTopic(String propertyKey, T initialValue, String topic, Function\u0026lt;String, T\u0026gt; topicFunction) throws MqttPhysicalAdapterConfigurationException Adds a physical asset property and its corresponding MQTT topic to the configuration.\nType Parameter T: The type of the property. propertyKey: The key of the property. initialValue: The initial value of the property. topic: The MQTT topic associated with the property. topicFunction: A function to parse the MQTT topic payload into the property type. Returns: The updated MqttPhysicalAdapterConfigurationBuilder.\nThrows: MqttPhysicalAdapterConfigurationException - If there is a configuration error.\naddPhysicalAssetActionAndTopic public \u0026lt;T\u0026gt; MqttPhysicalAdapterConfigurationBuilder addPhysicalAssetActionAndTopic(String actionKey, String type, String contentType, String topic, Function\u0026lt;T, String\u0026gt; topicFunction) throws MqttPhysicalAdapterConfigurationException Adds a physical asset action and its corresponding MQTT topic to the configuration.\nType Parameter T: The type of the action payload. actionKey: The key of the action. type: The type of the action. contentType: The content type of the action. topic: The MQTT topic associated with the action. topicFunction: A function to convert the action payload into the MQTT topic payload. Returns: The updated MqttPhysicalAdapterConfigurationBuilder.\nThrows: MqttPhysicalAdapterConfigurationException - If there is a configuration error.\naddPhysicalAssetEventAndTopic public \u0026lt;T\u0026gt; MqttPhysicalAdapterConfigurationBuilder addPhysicalAssetEventAndTopic(String eventKey, String type, String topic, Function\u0026lt;String, T\u0026gt; topicFunction) throws MqttPhysicalAdapterConfigurationException Adds a physical asset event and its corresponding MQTT topic to the configuration.\nType Parameter T: The type of the event payload. eventKey: The key of the event. type: The type of the event. topic: The MQTT topic associated with the event. topicFunction: A function to parse the MQTT topic payload into the event payload type. Returns: The updated MqttPhysicalAdapterConfigurationBuilder.\nThrows: MqttPhysicalAdapterConfigurationException - If there is a configuration error.\naddIncomingTopic public MqttPhysicalAdapterConfigurationBuilder addIncomingTopic(DigitalTwinIncomingTopic topic, List\u0026lt;PhysicalAssetProperty\u0026lt;?\u0026gt;\u0026gt; properties, List\u0026lt;PhysicalAssetEvent\u0026gt; events) throws MqttPhysicalAdapterConfigurationException This method is used when multiple properties or events can be associated to a single MQTT topic on the physical device. It adds a DigitalTwinIncomingTopic describing the topic where the DT will receive the data along with its related lists of properties and events associated to that topic.\ntopic: The DigitalTwinIncomingTopic to be added. properties: The list of related physical asset properties. events: The list of related physical asset events. Returns: The updated MqttPhysicalAdapterConfigurationBuilder.\nThrows: MqttPhysicalAdapterConfigurationException - If there is a configuration error.\naddOutgoingTopic public MqttPhysicalAdapterConfigurationBuilder addOutgoingTopic(String actionKey, String type, String contentType, DigitalTwinOutgoingTopic topic) throws MqttPhysicalAdapterConfigurationException Adds a DigitalTwinOutgoingTopic to the configuration.\nactionKey: The key of the associated action. type: The type of the associated action. contentType: The content type of the associated action. topic: The DigitalTwinOutgoingTopic to be added. Returns: The updated MqttPhysicalAdapterConfigurationBuilder.\nThrows: MqttPhysicalAdapterConfigurationException - If there is a configuration error.\nAdditional Methods setConnectionTimeout(Integer connectionTimeout): Sets the connection timeout for the MQTT client. Returns the builder for method chaining. Throws MqttPhysicalAdapterConfigurationException if the provided timeout is invalid. setCleanSessionFlag(boolean cleanSession): Sets the clean session flag for the MQTT client. Returns the builder for method chaining. setAutomaticReconnectFlag(boolean automaticReconnect): Sets the automatic reconnect flag for the MQTT client. Returns the builder for method chaining. setMqttClientPersistence(MqttClientPersistence persistence): Sets the persistence for the MQTT client. Returns the builder for method chaining. Throws MqttPhysicalAdapterConfigurationException if the provided persistence is null. build(): Builds and returns the finalized MqttPhysicalAdapterConfiguration object. Throws MqttPhysicalAdapterConfigurationException if the configuration is incomplete or invalid. MqttPhysicalAdapter The MqttPhysicalAdapter class is the core component for interacting with physical assets. Instantiate it with a unique ID and the configuration. It extends the default WLDT Library PhysicalAdapter implementing all the functionalities to automatically interact with an MQTT physical device following the specifications and details provided in the MqttPhysicalAdapterConfiguration and built using MqttPhysicalAdapterConfigurationBuilder.\nAn example of its creation is:\nMqttPhysicalAdapter mqttPhysicalAdapter = new MqttPhysicalAdapter(\u0026#34;uniqueId\u0026#34;, configuration); Integrated Example This example demonstrates the integration of a MqttPhysicalAdapter within a Digital Twin setup, where multiple adapters (including a console adapter) are added to a Digital Twin, and the overall system is managed by a DigitalTwinEngine.\n// Create a Digital Twin with a default shadowing function DigitalTwin digitalTwin = new DigitalTwin(\u0026#34;mqtt-digital-twin\u0026#34;, new DefaultShadowingFunction()); // Create an instance of ConsoleDigitalAdapter ConsoleDigitalAdapter consoleDigitalAdapter = new ConsoleDigitalAdapter(); // Create an instance of MqttPhysicalAdapterConfiguration MqttPhysicalAdapterConfiguration config = MqttPhysicalAdapterConfiguration.builder(\u0026#34;127.0.0.1\u0026#34;, 1883) .addPhysicalAssetPropertyAndTopic(\u0026#34;intensity\u0026#34;, 0, \u0026#34;sensor/intensity\u0026#34;, Integer::parseInt) .addIncomingTopic(new DigitalTwinIncomingTopic(\u0026#34;sensor/state\u0026#34;, getSensorStateFunction()), createIncomingTopicRelatedPropertyList(), new ArrayList\u0026lt;\u0026gt;()) .addPhysicalAssetEventAndTopic(\u0026#34;overheating\u0026#34;, \u0026#34;text/plain\u0026#34;, \u0026#34;sensor/overheating\u0026#34;, Function.identity()) .addPhysicalAssetActionAndTopic(\u0026#34;switch-off\u0026#34;, \u0026#34;sensor.actuation\u0026#34;, \u0026#34;text/plain\u0026#34;, \u0026#34;sensor/actions/switch\u0026#34;, actionBody -\u0026gt; \u0026#34;switch\u0026#34; + actionBody) .build(); // Create an instance of the MQTT Physical Adapter using the defined configuration MqttPhysicalAdapter mqttPhysicalAdapter = new MqttPhysicalAdapter(\u0026#34;test-mqtt-pa\u0026#34;, config); // Add both Digital and Physical Adapters to the Digital Twin digitalTwin.addDigitalAdapter(consoleDigitalAdapter); digitalTwin.addPhysicalAdapter(mqttPhysicalAdapter); // Create the Digital Twin Engine DigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine(); // Add the Digital Twin to the Engine digitalTwinEngine.addDigitalTwin(digitalTwin); // Start all the Digital Twins registered on the engine digitalTwinEngine.startAll(); In this example the createIncomingTopicRelatedPropertyList() used to map properties and events associated to a single topic is the following:\nprivate static List\u0026lt;PhysicalAssetProperty\u0026lt;?\u0026gt;\u0026gt; createIncomingTopicRelatedPropertyList(){ List\u0026lt;PhysicalAssetProperty\u0026lt;?\u0026gt;\u0026gt; properties = new ArrayList\u0026lt;\u0026gt;(); properties.add(new PhysicalAssetProperty\u0026lt;\u0026gt;(\u0026#34;temperature\u0026#34;, 0)); properties.add(new PhysicalAssetProperty\u0026lt;\u0026gt;(\u0026#34;humidity\u0026#34;, 0)); return properties; } This information are used by the adapter to build the PAD describe the capabilities and the characteristics of our object allowing the Shadowing Function to decide how to digitalize its physical counterpart.\n","date":"February 9, 2024","id":11,"permalink":"/docs/adapters/mqtt-physical-adapter/","summary":"The MqttPhysicalAdapter library provides a streamlined solution for efficiently managing physical assets through the MQTT protocol. It offers a range of features, including a versatile builder for effortless configuration of MQTT connections, dedicated classes for handling both incoming and outgoing topics, and a specialized adapter designed for seamless integration with diverse physical assets.","tags":"","title":"MQTT Physical Adapter"},{"content":"","date":"February 9, 2024","id":12,"permalink":"/docs/change-logs/","summary":"","tags":"","title":"Change Logs"},{"content":"The MqttDigitalAdapter,\nMqttDigitalAdapterConfiguration, and MqttDigitalAdapterConfigurationBuilder classes and guides you through using these classes to set up an MQTT Digital Adapter within WLDT.\nRequires an external MQTT broker to send messages.\nMain functionalities are:\nManages the interaction between the Digital Twin and external systems. Handles state updates, events, and property changes. Dynamic configuration of the MqttDigitalAdapter with broker details, topics, and other settings. Allows customization of data and payload management associated to MQTT topics for properties, events, and actions. Prerequisites:\nExternal MQTT Broker: The MqttDigitalAdapter library requires an external MQTT broker for optimal functionality and communication. Users must have access to a reliable MQTT broker to which the adapter can subscribe and publish. This external broker serves as the central communication hub, facilitating the exchange of messages between the adapter and digital applications A complete example is provided in the test folder with a complete DT Creation in the TestMain class together with MQTT IoT demo device and a test MQTT consumer.\nWLDT-Core Version Compatibility The correct mapping and compatibility between versions is reported in the following table\nmqtt-digital-adapter wldt-core 0.2.1 wldt-core 0.3.0 0.1.0 ✅ ❌ 0.1.1 ❌ ✅ Installation To use MqttDigitalAdapter in your Java project, you can include it as a dependency using Maven or Gradle.\nMaven \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.github.wldt\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;mqtt-digital-adapter\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;0.1.1\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; Gradle implementation \u0026#39;io.github.wldt:mqtt-digital-adapter:0.1.1\u0026#39; Class Structure \u0026amp; Functionalities MqttDigitalAdapterConfiguration MqttDigitalAdapterConfiguration is a crucial class in the Digital Twin library, allowing developers to configure the behavior of the MQTT Digital Adapter. It provides a flexible and customizable way to set up MQTT communication parameters, topics for properties, events, and actions.\nKey functionalities and exposed capabilities:\nBroker Configuration brokerAddress and brokerPort: Set the MQTT broker\u0026rsquo;s address and port. username and password: Set optional credentials for connecting to the broker. Client Configuration clientId: Unique identifier for the MQTT client. cleanSessionFlag: Flag indicating whether the client starts with a clean session. connectionTimeout: Maximum time to wait for the connection to the MQTT broker. MQTT Client Persistence persistence: Configurable persistence for the MQTT client\u0026rsquo;s data. Reconnect Configuration: automaticReconnectFlag: Flag enabling or disabling automatic reconnection. Topic Configuration: propertyUpdateTopics: Map of property update topics. eventNotificationTopics: Map of event notification topics. actionIncomingTopics: Map of incoming action topics. Builder Methods: builder: Static method to start building a new configuration. addPropertyTopic: Add a property topic with specified parameters. addEventNotificationTopic: Add an event notification topic. addActionTopic: Add an action topic. setConnectionTimeout: Set the connection timeout. setCleanSessionFlag: Set the clean session flag. setAutomaticReconnectFlag: Set the automatic reconnect flag. setMqttClientPersistence: Set the MQTT client persistence. build: Finalize the configuration and build the instance. MqttDigitalAdapterConfigurationBuilder The MqttDigitalAdapterConfigurationBuilder is a powerful tool designed to simplify the process of constructing configurations for the MQTT Digital Adapter in the Digital Twin library. It offers a fluent and intuitive interface, allowing developers to define various aspects of MQTT communication seamlessly.\nBuilder Instantiation The builder is instantiated by providing essential parameters like brokerAddress and brokerPort or including an optional clientId\nMqttDigitalAdapterConfigurationBuilder builder = MqttDigitalAdapterConfiguration.builder(\u0026#34;127.0.0.1\u0026#34;, 1883); Adding Property Topics Developers can add property topics with specific configurations, such as the key, topic, QoS level, and a function to convert property values to payload.\nbuilder.addPropertyTopic(\u0026#34;energy\u0026#34;, \u0026#34;dummy/properties/energy\u0026#34;, MqttQosLevel.MQTT_QOS_0, value -\u0026gt; String.valueOf(((Double)value).intValue())); Adding Event Notification Topics Event notification topics are easily added, including event keys, topics, QoS levels, and payload conversion functions.\nbuilder.addEventNotificationTopic(\u0026#34;overheating\u0026#34;, \u0026#34;dummy/events/overheating/notifications\u0026#34;, MqttQosLevel.MQTT_QOS_0, Object::toString); Adding Action Topics Developers can include action topics with key, topic, and a function to convert the payload to the desired action.\nbuilder.addActionTopic(\u0026#34;switch_off\u0026#34;, \u0026#34;app/actions/switch-off\u0026#34;, msg -\u0026gt; \u0026#34;OFF\u0026#34;); Connection Options Developers can set the connection timeout for the MQTT client.\nbuilder.setConnectionTimeout(30); The clean session flag can be configured based on the desired behavior.\nbuilder.setCleanSessionFlag(true); Developers can specify whether the MQTT client should automatically reconnect in case of a connection failure.\nbuilder.setAutomaticReconnectFlag(true); The builder allows setting a custom MQTT client persistence, such as an in-memory persistence or a file-based one.\nbuilder.setMqttClientPersistence(new MemoryPersistence()); Building Configuration The final configuration is built using the build method.\nMqttDigitalAdapterConfiguration configuration = builder.build(); MqttDigitalAdapter MqttDigitalAdapter extends DigitalAdapter and specializes in MQTT communication for Digital Twin instances. It handles the publication of state updates, events, and property changes over MQTT. This class facilitates seamless integration with MQTT-enabled systems.\nIt uses the information defined and provided in the `` to handle the communication both with the DT Core and external application interested to interact with the DT through the MQTT protocol.\nHere\u0026rsquo;s a basic example illustrating how to use MqttDigitalAdapter:\n// Create a Digital Twin instance DigitalTwin digitalTwin = new DigitalTwin(\u0026#34;my-digital-twin\u0026#34;, new DefaultShadowingFunction()); // Add a Physical Adapter to the DT [...] // Build the MQTT Digital Adapter Configuration MqttDigitalAdapterConfiguration configuration = MqttDigitalAdapterConfiguration.builder(\u0026#34;127.0.0.1\u0026#34;, 1883) .addPropertyTopic(\u0026#34;energy\u0026#34;, \u0026#34;dummy/properties/energy\u0026#34;, MqttQosLevel.MQTT_QOS_0, value -\u0026gt; String.valueOf(((Double)value).intValue())) .addActionTopic(\u0026#34;switch_off\u0026#34;, \u0026#34;app/actions/switch-off\u0026#34;, msg -\u0026gt; \u0026#34;OFF\u0026#34;) .build(); // Add the MQTT Digital Adapter to the Digital Twin digitalTwin.addDigitalAdapter(new MqttDigitalAdapter(\u0026#34;mqtt-da\u0026#34;, configuration)); // Create the Digital Twin Engine and start the simulation DigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine(); digitalTwinEngine.addDigitalTwin(digitalTwin); digitalTwinEngine.startAll(); ","date":"February 9, 2024","id":13,"permalink":"/docs/adapters/mqtt-digital-adapter/","summary":"The MqttDigitalAdapter,\nMqttDigitalAdapterConfiguration, and MqttDigitalAdapterConfigurationBuilder classes and guides you through using these classes to set up an MQTT Digital Adapter within WLDT.","tags":"","title":"MQTT Digital Adapter"},{"content":"Digital Adapters The following methods have been discontinued and removed from the DigitalAdapter class: onStateChangePropertyCreated onStateChangePropertyUpdated onStateChangePropertyDeleted onStatePropertyUpdated onStatePropertyDeleted onStateChangeActionEnabled onStateChangeActionUpdated onStateChangeActionDisabled onStateChangeEventRegistered onStateChangeEventRegistrationUpdated onStateChangeEventUnregistered onStateChangeRelationshipInstanceDeleted onStateChangeRelationshipDeleted onStateChangeRelationshipInstanceCreated onStateChangeRelationshipCreated onDigitalTwinStateEventNotificationReceived The Signature of the following methods have been changed: onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) -\u0026gt; onDigitalTwinSync(DigitalTwinState currentDigitalTwinState) onDigitalTwinUnSync(IDigitalTwinState currentDigitalTwinState) -\u0026gt; onDigitalTwinUnSync(DigitalTwinState currentDigitalTwinState) New methods that have been added are: onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList\u0026lt;DigitalTwinStateChange\u0026gt; digitalTwinStateChangeList) onEventNotificationReceived(DigitalTwinStateEventNotification\u0026lt;?\u0026gt; digitalTwinStateEventNotification) For additional details about Digital Adapters check Sub Section [[Change Log - v.0.3.0#Digital Adapter| Digital Adapters]] Shadowing Function ShadowingModelFunction is now ShadowingFunction this.digitalTwinState is not directly accessible anymore and it is wrapped through the DigitalTwinStateManager using the variable digitalTwinStateManager (see next descriptions and changes) The method addRelationshipInstance now take only one parameter that is the DigitalTwinStateRelationshipInstance The same change for example should be applied in the point of the code where the Shadowing Function receive a variation from the Physical world through a target adapter and the callback method onPhysicalAssetPropertyVariation(...) When the Shadowing Function has to compute the new DT State it can now work with the following method to handle DT State Transition: this.digitalTwinStateManager.startStateTransaction() DT State variation methods such as: digitalTwinStateManager.createProperty() digitalTwinStateManager.updateProperty() digitalTwinStateManager.updatePropertyValue() digitalTwinStateManager.deleteProperty() digitalTwinStateManager.enableAction() digitalTwinStateManager.updateAction() digitalTwinStateManager.disableAction() digitalTwinStateManager.registerEvent() digitalTwinStateManager.updateRegisteredEvent() digitalTwinStateManager.unRegisterEvent() digitalTwinStateManager.createRelationship() digitalTwinStateManager.addRelationshipInstance() digitalTwinStateManager.deleteRelationship() digitalTwinStateManager.deleteRelationshipInstance() At the end the transaction can be committed using the method: digitalTwinStateManager.commitStateTransaction() The method notifyDigitalTwinStateEvent is now available through the digitalTwinStateManager Additional Details associated to Shadowing Function Migration can be found in the dedicated section [[Change Log - v.0.3.0#Shadowing Function Changes | Shadowing Function Changes]] WLDT Engine \u0026amp; DT Creation WldtEngine is now DigitalTwin and model and structure a single Digital Twin and takes the following parameters: String digitalTwinId ShadowingFunction shadowingFunction The startLifeCycle has been removed from the DigitalTwin (previously WLDT Engine) and now DigitalTwinEngine should be used to start twins Once a new Digital Twin has been create it has to be added to the DigitalTwinEngine DigitalTwinEngine has dedicated method to start and stop twins such as: startAll() startDigitalTwin(\u0026lt;DIGITAL_TWIN_ID\u0026gt;); stopAll() digitalTwinEngine.stopDigitalTwin(\u0026lt;DIGITAL_TWIN_ID\u0026gt;); Digital Twin \u0026amp; Digital Twin Engine With the following code we now create a new Digital Twin Instance\n// Create the new Digital Twin with its Shadowing Function DigitalTwin digitalTwin = new DigitalTwin(digitalTwinId, new DemoShadowingFunction()); // Physical Adapter with Configuration digitalTwin.addPhysicalAdapter( new DemoPhysicalAdapter( String.format(\u0026#34;%s-%s\u0026#34;, digitalTwinId, \u0026#34;test-physical-adapter\u0026#34;), new DemoPhysicalAdapterConfiguration(), true)); // Digital Adapter with Configuration digitalTwin.addDigitalAdapter( new DemoDigitalAdapter( String.format(\u0026#34;%s-%s\u0026#34;, digitalTwinId, \u0026#34;test-digital-adapter\u0026#34;), new DemoDigitalAdapterConfiguration()) ); In the new version the DT cannot be directly run but it should be added to the DigitalTwinEngine in order to be executed through the WLDT Library\n// Create the Digital Twin Engine DigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine(); // Add the Digital Twin to the Engine digitalTwinEngine.addDigitalTwin(digitalTwin); In order to start a DT from the Engine you can:\n// Directly start when you add it passing a second boolean value = true digitalTwinEngine.addDigitalTwin(digitalTwin. true); // Starting the single DT on the engine through its id digitalTwinEngine.startDigitalTwin(DIGITAL_TWIN_ID); // Start all the DTs registered on the engine digitalTwinEngine.startAll(); To stop a single twin or all the twin registered on the engine:\n// Stop a single DT on the engine through its id digitalTwinEngine.stopDigitalTwin(DIGITAL_TWIN_ID); // Stop all the DTs registered on the engine digitalTwinEngine.stopAll(); It is also possible to remove a DT from the Engine with a consequent stop if it is active and the deletion of its reference from the engine:\n// Remove a single DT on the engine through its id digitalTwinEngine.removeDigitalTwin(DIGITAL_TWIN_ID); // Remove all the DTs registered on the engine digitalTwinEngine.removeAll(); Digital Twin State DT State now has the reference timestamp representing the evaluation instant of the digital twin state, this timestamp is computed through the DigitalTwinStateManager and cannot manually set by the developer The information available on the DT State are: properties: List of Properties with their values (if available) actions: List of Actions that can be called on the DT events: List of Events that can be generated by the DT relationships: List of Relationships and their instances (if available) evaluationInstant: The timestamp representing the evaluation instant of the DT state Available main methods on that class instance are: Properties:\n- getProperty(String propertyKey): Retrieves if present the target DigitalTwinStateProperty by Key\n- containsProperty(String propertyKey): Checks if a target Property Key is already available in the current Digital Twin\u0026rsquo;s State\n- getPropertyList(): Loads the list of available Properties (described by the class DigitalTwinStateProperty) available on the Digital Twin\u0026rsquo;s State\n- createProperty(DigitalTwinStateProperty\u0026lt;?\u0026gt; dtStateProperty): Allows the creation of a new Property on the Digital Twin\u0026rsquo;s State through the class DigitalTwinStateProperty\n- readProperty(String propertyKey): Retrieves if present the target DigitalTwinStateProperty by Key\n- updateProperty(DigitalTwinStateProperty\u0026lt;?\u0026gt; dtStateProperty): Updates the target property using the DigitalTwinStateProperty and the associated Property Key field\n- deleteProperty(String propertyKey): Deletes the target property identified by the specified key Actions:\n- containsAction(String actionKey): Checks if a Digital Twin State Action with the specified key is correctly registered\n- getAction(String actionKey): Loads the target DigitalTwinStateAction by key\n- getActionList(): Gets the list of available Actions registered on the Digital Twin\u0026rsquo;s State\n- enableAction(DigitalTwinStateAction digitalTwinStateAction): Enables and registers the target Action described through an instance of the DigitalTwinStateAction class\n- updateAction(DigitalTwinStateAction digitalTwinStateAction): Update the already registered target Action described through an instance of the DigitalTwinStateAction class\n- disableAction(String actionKey): Disables and unregisters the target Action described through an instance of the DigitalTwinStateAction class Events:\n- containsEvent(String eventKey): Check if a Digital Twin State Event with the specified key is correctly registered\n- getEvent(String eventKey): Return the description of a registered Digital Twin State Event according to its Key\n- getEventList(): Return the list of existing and registered Digital Twin State Events\n- registerEvent(DigitalTwinStateEvent digitalTwinStateEvent): Register a new Digital Twin State Event\n- updateRegisteredEvent(DigitalTwinStateEvent digitalTwinStateEvent): Update the registration and signature of an existing Digital Twin State Event\n- unRegisterEvent(String eventKey): Un-register a Digital Twin State Event\n- notifyDigitalTwinStateEvent(DigitalTwinStateEventNotification\u0026lt;?\u0026gt; digitalTwinStateEventNotification): Method to notify the occurrence of the target Digital Twin State Event Relationships:\n- containsRelationship(String relationshipName): Checks if a Relationship Name is already available in the current Digital Twin\u0026rsquo;s State\n- createRelationship(DigitalTwinStateRelationship\u0026lt;?\u0026gt; relationship): Creates a new Relationships (described by the class DigitalTwinStateRelationship) in the Digital Twin\u0026rsquo;s State\n- addRelationshipInstance(String name, DigitalTwinStateRelationshipInstance\u0026lt;?\u0026gt; instance): Adds a new Relationship instance described through the class DigitalTwinStateRelationshipInstance and identified through its name\n- getRelationshipList(): Loads the list of existing relationships on the Digital Twin\u0026rsquo;s State through a list of DigitalTwinStateRelationship\n- getRelationship(String name): Gets a target Relationship identified through its name and described through the class DigitalTwinStateRelationship\n- deleteRelationship(String name): Deletes a target Relationship identified through its name\n- deleteRelationshipInstance(String relationshipName, String instanceKey): Deletes the target Relationship Instance using relationship name and instance Key Digital Twin State Manager The DigitalTwinStateManager is a Java class that serves as the default implementation of the IDigitalTwinStateManager interface within the White Label Digital Twin Java Framework (whitelabel-digitaltwin). This class allows developers to manage the state of a digital twin, including properties, actions, events, and relationships.\nFeatures State Management: Handles the creation, update, and deletion of properties, actions, events, and relationships associated with the digital twin state. Transaction Support: Allows developers to start, commit, or rollback transactions to manage changes to the digital twin state. Event Notification: Notifies listeners about updates to the digital twin state through the WLDT event bus. When the Shadowing Function has to compute the new DT State it can now work with the following method to handle DT State Transition: - Start the DT State Transaction: startStateTransaction() - DT State variation methods such as: - createProperty() - updateProperty()\n- updatePropertyValue() - deleteProperty() - enableAction() - updateAction() - disableAction() - registerEvent() - updateRegisteredEvent() - unRegisterEvent() - createRelationship() - addRelationshipInstance() - deleteRelationship() - deleteRelationshipInstance()\nAt the end the transaction can be committed using the method: commitStateTransaction()\nUsage To use the DigitalTwinStateManager within your digital twin implementation:\nInitialization: Create an instance of the DigitalTwinStateManager. DigitalTwinStateManager digitalTwinStateManager = new DigitalTwinStateManager(); State Transaction:\nStart a new transaction using startStateTransaction() to manage changes. Make changes to the digital twin state. Commit the transaction using commitStateTransaction() to apply the changes. digitalTwinStateManager.startStateTransaction(); // Make changes to properties, actions, events, or relationships // [...] digitalTwinStateManager.commitStateTransaction(); Event Notification:\nDT State Updates after a commit action are automatically notified to Digital Adapter by the Manager Once an event incoming from the physical or generated by the DT itself is handled by the Shadowing Function, the developer can use notifyDigitalTwinStateUpdate to notify Digital Adapter listening about events variations. // Notify a specific event notification digitalTwinStateManager.notifyDigitalTwinStateEvent(digitalTwinStateEventNotification); Property, Action, Event, Relationship Management:\nCreate, update, or delete properties, actions, events, or relationships as needed. // Begin Digital Twin State Transaction digitalTwinStateManager.startStateTransaction(); // Create a new property digitalTwinStateManager.createProperty(dtStateProperty); // Update an existing property digitalTwinStateManager.updateProperty(dtStateProperty); // Delete a property digitalTwinStateManager.deleteProperty(propertyKey);` // Commit DT State Update to apply all the changes and notify the Digital Adapters and other listeners about the variation digitalTwinStateManager.commitStateTransaction(); Exception Handling The class throws WldtDigitalTwinStateException to indicate errors related to digital twin state management. Proper exception handling is advised to manage potential errors during state transactions. Shadowing Function Changes Now that the DT State is managed through the DigitalTwinStateManager class all the changes and variation should be applied on the DT ShadowingFunction using the previously presented transaction management and the correct call of methods startStateTransaction() and commitStateTransaction().\nHere there is an example of the change with a simple and demo shadowing function on callback onDigitalTwinBound:\n@Override protected void onDigitalTwinBound(Map\u0026lt;String, PhysicalAssetDescription\u0026gt; adaptersPhysicalAssetDescriptionMap) { try{ // NEW -\u0026gt; Start DT State Change Transaction this.digitalTwinStateManager.startStateTransaction(); for(Map.Entry\u0026lt;String, PhysicalAssetDescription\u0026gt; entry : adaptersPhysicalAssetDescriptionMap.entrySet()){ String adapterId = entry.getKey(); PhysicalAssetDescription physicalAssetDescription = entry.getValue(); //In that simple case the Digital Twin shadow all the properties and actions available in the physical asset for(PhysicalAssetProperty\u0026lt;?\u0026gt; p : physicalAssetDescription.getProperties()) this.digitalTwinStateManager.createProperty(new DigitalTwinStateProperty\u0026lt;\u0026gt;(p.getKey(), p.getInitialValue())); for(PhysicalAssetAction a : physicalAssetDescription.getActions()) this.digitalTwinStateManager.enableAction(new DigitalTwinStateAction(a.getKey(), a.getType(), a.getContentType())); for(PhysicalAssetEvent e: physicalAssetDescription.getEvents()) this.digitalTwinStateManager.registerEvent(new DigitalTwinStateEvent(e.getKey(), physicalAssetEvent.getType())); } // NEW -\u0026gt; Commit DT State Change Transaction to apply the changes on the DT State and notify about the change this.digitalTwinStateManager.commitStateTransaction(); //Observer Target Physical Properties for(Map.Entry\u0026lt;String, PhysicalAssetDescription\u0026gt; entry : adaptersPhysicalAssetDescriptionMap.entrySet()){ [...] } //Observe all the target available Physical Asset Events for each Adapter for(Map.Entry\u0026lt;String, PhysicalAssetDescription\u0026gt; entry : adaptersPhysicalAssetDescriptionMap.entrySet()){ [...] } // Observer for Incoming Digital Actions observeDigitalActionEvents(); //Notify Shadowing Completed notifyShadowingSync(); }catch (Exception e){ e.printStackTrace(); } } The same change for example should be applied in the point of the code where the Shadowing Function receive a variation from the Physical world through a target adapter and the callback method onPhysicalAssetPropertyVariation(...)\n@Override protected void onPhysicalAssetPropertyVariation(PhysicalAssetPropertyWldtEvent\u0026lt;?\u0026gt; physicalPropertyEventMessage) { try { if(physicalPropertyEventMessage != null \u0026amp;\u0026amp; getPhysicalEventsFilter().contains(physicalPropertyEventMessage.getType())){ if(physicalPropertyEventMessage.getPhysicalPropertyId().equals(TestPhysicalAdapter.SWITCH_PROPERTY_KEY) \u0026amp;\u0026amp; physicalPropertyEventMessage.getBody() instanceof String){ [...] } else{ //Update Digital Twin State //NEW -\u0026gt; Start State Transaction this.digitalTwinStateManager.startStateTransaction(); // Update State Property Value this.digitalTwinStateManager.updateProperty( new DigitalTwinStateProperty\u0026lt;\u0026gt;( physicalPropertyEventMessage.getPhysicalPropertyId(), physicalPropertyEventMessage.getBody())); //NEW -\u0026gt; Commit State Transaction this.digitalTwinStateManager.commitStateTransaction(); } } else logger.error(\u0026#34;WRONG Physical Event Message Received !\u0026#34;); }catch (Exception e){ e.printStackTrace(); } } Digital Adapter The Digital Adapter base class has been significantly extended and improved with respect to the previous version. In this new Version notifications that are received by the Adapter from the the DT core belongs to the following categories:\nDigital Twin State Update through the method onStateUpdate(...) providing information about the new state of the Digital Twin, the previous state, and a list of changes that occurred between these two states. In the previous version each variation of a property, relationships, actions or events were notified. In the new version only a committed DT\u0026rsquo;State variation is notified to listeners. Event Notifications through the method onEventNotificationReceived(...) whenever there is a notification about an event related to the Digital Twin\u0026rsquo;s state coming from the physical world, generated by the twin and processed by the Shadowing Function. For example in the DT State we can have the declaration of the over-heating-alert structured and received in the DT State while the effective occurrence of the event and the associated notification is notified through this dedicated callback The onStateUpdate method is an abstract method that must be implemented by any class extending the DigitalAdapter class. This method is called whenever there is an update to the Digital Twin\u0026rsquo;s state. It provides information about the new state of the Digital Twin, the previous state, and a list of changes that occurred between these two states.\nHere is an explanation of the parameters:\nnewDigitalTwinState: This parameter represents the updated state of the Digital Twin. It is an instance of the DigitalTwinState class, which encapsulates the current state information.\npreviousDigitalTwinState: This parameter represents the state of the Digital Twin before the update. It is also an instance of the DigitalTwinState class.\ndigitalTwinStateChangeList: This parameter is an ArrayList containing DigitalTwinStateChange objects. Each DigitalTwinStateChange object encapsulates information about a specific change that occurred between the previous and new states. It includes details such as the property or aspect of the state that changed, the previous value, and the new value.\nThe DT State is automatically monitored by each Digital Adapter while for the Events potentially generated by the DT can be observed by each adapter using:\nobserveAllDigitalTwinEventsNotifications: Enable the observation of available Digital Twin State Events Notifications. unObserveAllDigitalTwinEventsNotifications: Cancel the observation of Digital Twin State Events Notifications observeDigitalTwinEventsNotifications: Enable the observation of the notification associated to a specific list of Digital Twin State events. With respect to event a notification contains the new associated value unObserveDigitalTwinEventsNotifications: Cancel the observation of a target list of properties observeDigitalTwinEventNotification: Enable the observation of the notification associated to a single Digital Twin State event. With respect to event a notification contains the new associated value unObserveDigitalTwinEventNotification: Cancel the observation of a single target event DigitalTwinStateChange Class DigitalTwinStateChange Class\nThe DigitalTwinStateChange class is a representation of a change that occurred in the state of a Digital Twin. It encapsulates information about the type of operation, the resource type, and the affected resource within the Digital Twin.\nEnums:\nOperation: Enumerates different types of operations that can be performed on a Digital Twin state. The possible operations are: OPERATION_UPDATE: Represents an update operation on a resource. OPERATION_UPDATE_VALUE: Represents an update operation specifically on the value of a resource. OPERATION_ADD: Represents an addition operation of a new resource. OPERATION_REMOVE: Represents a removal operation of an existing resource. ResourceType: Enumerates different types of resources within a Digital Twin. The possible resource types are: PROPERTY: Represents a property of the Digital Twin. PROPERTY_VALUE: Represents the value of a property within the Digital Twin. EVENT: Represents an event associated with the Digital Twin. ACTION: Represents an action that can be performed on the Digital Twin. RELATIONSHIP: Represents a relationship between different components of the Digital Twin. RELATIONSHIP_INSTANCE: Represents an instance of a relationship. Fields:\noperation: Indicates the type of operation performed on the Digital Twin state (e.g., update, add, remove). resourceType: Represents the type of resource affected by the change (e.g., property, event, relationship). resource: The specific resource that has undergone the change, represented by an instance of the DigitalTwinStateResource class. Available type of DigitalTwinStateResource are:\nDigitalTwinStateProperty\u0026lt;T\u0026gt;: This class define a generic property associated to the Digital Twin State. Each property is associated to a Key and a Value. Furthermore, it can also be associated to a type to identify its nature and data structure. By default, it is associated to the type of the Class (e.g., java.lang.String) but it can be directly changed by the developer to associate it to a specific ontology or data type. DigitalTwinStateEvent: This class define a generic event associated to the Digital Twin State. Events enable a mechanism for asynchronous messages to be sent by the digital twin (e.g., an overheating) . They are different from Properties that can change values according to the type of Digital Twin and may be associated also to telemetry patterns. Each event is associated to a Key and a Type used to identify its nature and data structure. By default, it is associated to the type of the Class (e.g., java.lang.String) but it can be directly changed by the developer to associate it to a specific ontology or data type. DigitalTwinStateAction: This class define a generic action associated to the Digital Twin State. Each action is by a key, an action type and a content type used to identify the expected input required by the action. The type of the can be directly changed by the developer to associate it to a specific ontology or data type. DigitalTwinStateRelationship\u0026lt;T\u0026gt;: Structures and describes a Relationship in the Digital Twins\u0026rsquo;s State. This is just the description of the relationships while the effective values/instances are described through the other class DigitalTwinStateRelationshipInstance DigitalTwinStateRelationshipInstance\u0026lt;T\u0026gt;: Structures and describes a Relationship Instance in the Digital Twins\u0026rsquo;s State. This is effective description of a relationship while its generic declaration is described through the class DigitalTwinStateRelationship. When there is a change in the DT State it is possibile to cast the received resource variation to the correct one. For example in the following code we detect and manage the variation on a Property Value:\n// Get information from the state change DigitalTwinStateChange.Operation operation = stateChange.getOperation(); DigitalTwinStateChange.ResourceType resourceType = stateChange.getResourceType(); DigitalTwinStateResource resource = stateChange.getResource(); // Search for property value variation if(resourceType.equals(DigitalTwinStateChange.ResourceType.PROPERTY_VALUE) \u0026amp;\u0026amp; operation.equals(DigitalTwinStateChange.Operation.OPERATION_UPDATE) \u0026amp;\u0026amp; resource instanceof DigitalTwinStateProperty){ DigitalTwinStateProperty\u0026lt;?\u0026gt; digitalTwinStateProperty = (DigitalTwinStateProperty\u0026lt;?\u0026gt;) resource; if(getConfiguration().getPropertyUpdateTopics().containsKey(digitalTwinStateProperty.getKey())){ //Handle property value variation } } Constructors:\nDigitalTwinStateChange(): An empty constructor that allows creating an instance of the class. DigitalTwinStateChange(Operation operation, ResourceType resourceType, DigitalTwinStateResource resource): Constructs a DigitalTwinStateChange object with specified operation, resource type, and resource. Throws a WldtDigitalTwinStateException if any of the parameters is missing or null. Methods:\nAccessor methods (getOperation(), getResourceType(), getResource()) to retrieve the values of the fields. Mutator methods (setOperation(), setResourceType(), setResource()) to update the values of the fields. Usage Examples Developers extending the DigitalAdapter class should implement the onStateUpdate method to define custom logic that needs to be executed whenever the state of the Digital Twin is updated. This could include tasks such as processing state changes, updating internal variables, triggering specific actions, or notifying other components about the state update.\nHere\u0026rsquo;s an example of how the method might be implemented in a concrete subclass of DigitalAdapter:\n@Override protected void onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList\u0026lt;DigitalTwinStateChange\u0026gt; digitalTwinStateChangeList) { // In newDigitalTwinState we have the new DT State System.out.println(\u0026#34;New DT State is: \u0026#34; + newDigitalTwinState); // The previous DT State is available through the variable previousDigitalTwinState System.out.println(\u0026#34;Previous DT State is: \u0026#34; + previousDigitalTwinState); // We can also check each DT\u0026#39;s state change potentially differentiating the behaviour for each change if (digitalTwinStateChangeList != null \u0026amp;\u0026amp; !digitalTwinStateChangeList.isEmpty()) { // Iterate through each state change in the list for (DigitalTwinStateChange stateChange : digitalTwinStateChangeList) { // Get information from the state change DigitalTwinStateChange.Operation operation = stateChange.getOperation(); DigitalTwinStateChange.ResourceType resourceType = stateChange.getResourceType(); DigitalTwinStateResource resource = stateChange.getResource(); // Perform different actions based on the type of operation switch (operation) { case OPERATION_UPDATE: // Handle an update operation System.out.println(\u0026#34;Update operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; case OPERATION_UPDATE_VALUE: // Handle an update value operation System.out.println(\u0026#34;Update value operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; case OPERATION_ADD: // Handle an add operation System.out.println(\u0026#34;Add operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; case OPERATION_REMOVE: // Handle a remove operation System.out.println(\u0026#34;Remove operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; default: // Handle unknown operation (optional) System.out.println(\u0026#34;Unknown operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; } } } else { // No state changes System.out.println(\u0026#34;No state changes detected.\u0026#34;); } } In this example, the method iterates over the list of state changes, extracts information about each change, and performs custom actions based on the changes. Developers can adapt this method to suit the specific requirements of their Digital Twin application.\n","date":"February 9, 2024","id":14,"permalink":"/docs/change-logs/change-log-0.3.0/","summary":"Digital Adapters The following methods have been discontinued and removed from the DigitalAdapter class: onStateChangePropertyCreated onStateChangePropertyUpdated onStateChangePropertyDeleted onStatePropertyUpdated onStatePropertyDeleted onStateChangeActionEnabled onStateChangeActionUpdated onStateChangeActionDisabled onStateChangeEventRegistered onStateChangeEventRegistrationUpdated onStateChangeEventUnregistered onStateChangeRelationshipInstanceDeleted onStateChangeRelationshipDeleted onStateChangeRelationshipInstanceCreated onStateChangeRelationshipCreated onDigitalTwinStateEventNotificationReceived The Signature of the following methods have been changed: onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) -\u0026gt; onDigitalTwinSync(DigitalTwinState currentDigitalTwinState) onDigitalTwinUnSync(IDigitalTwinState currentDigitalTwinState) -\u0026gt; onDigitalTwinUnSync(DigitalTwinState currentDigitalTwinState) New methods that have been added are: onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList\u0026lt;DigitalTwinStateChange\u0026gt; digitalTwinStateChangeList) onEventNotificationReceived(DigitalTwinStateEventNotification\u0026lt;?","tags":"","title":"Change Log 0.3.0"},{"content":"The HttpDigitalAdapter is a powerful component designed to facilitate the integration of Digital Twins into HTTP-based systems. It serves as a bridge between a Digital Twin and HTTP-based applications, allowing developers to easily expose and interact with Digital Twin data and functionalities over HTTP.\nKey Features:\nHTTP Integration: Seamlessly integrates Digital Twins into HTTP environments, enabling communication with web applications and services. Dynamic Configuration: Offers a flexible configuration mechanism through the HttpDigitalAdapterConfiguration, allowing developers to customize the adapter\u0026rsquo;s behavior based on specific requirements. State Monitoring: Monitors changes in the Digital Twin state and provides HTTP endpoints to query the state of the Digital Twin (properties, events, actions and relationships). Event Notifications: Allows developers to retrieve event notifications triggered by changes in the Digital Twin state. A complete example is provided in the test folder with a complete DT Creation in the TestMain class together with a demo DT with and emulated Physical Adapter and the HTTP Digital Adapter.\nWLDT-Core Version Compatibility The correct mapping and compatibility between versions is reported in the following table\nhttp-digital-adapter wldt-core 0.2.1 wldt-core 0.3.0 0.1.1 ❌ ✅ Installation To use HttpDigitalAdapter in your Java project, you can include it as a dependency using Maven or Gradle.\nMaven \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.github.wldt\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;http-digital-adapter\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;0.1.1\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; Gradle implementation \u0026#39;io.github.wldt:http-digital-adapter:0.1.1\u0026#39; Class Structure \u0026amp; Functionalities HttpDigitalAdapterConfiguration The HttpDigitalAdapterConfiguration is a crucial part of the HttpDigitalAdapter, providing the necessary settings to tailor the adapter\u0026rsquo;s behavior to meet specific needs.\nRepresents the configuration for an HTTP Digital Adapter, specifying the host, port, and filters for properties, actions, events, and relationships.\nThe filters are used to selectively include or exclude specific properties, actions, events, and relationships when interacting with the HTTP Digital Adapter. Filters are meant to be white list filters, if they are empty, it means that ALL fields are considered\nThis class provides methods to add filters for each type and getters to retrieve the configured values.\nKey functionalities and exposed capabilities:\nBasic Configuration Adapter ID: A unique identifier for the HttpDigitalAdapter instance. Host: The hostname or IP address on which the adapter will listen for incoming HTTP requests. Port: The port number on which the adapter will listen for incoming HTTP requests. Filters (Optional) addPropertyFilter(String propertyKey): Adds a single property key to the property filter. addPropertiesFilter(Collection\u0026lt;String\u0026gt; propertiesKey): Adds a collection of property keys to the property filter. addActionFilter(String actionKey): Adds a single action key to the action filter. addActionsFilter(Collection\u0026lt;String\u0026gt; actionsKey): Adds a collection of action keys to the action filter. addEventFilter(String eventKey): Adds a single event key to the event filter. addEventsFilter(Collection\u0026lt;String\u0026gt; eventsKey): Adds a collection of event keys to the event filter. addRelationshipFilter(String relationshipName): Adds a single relationship name to the relationship filter. addRelationshipsFilter(Collection\u0026lt;String\u0026gt; relationshipNames): Adds a collection of relationship names to the relationship filter. Configured Filter can be accessed using: getPropertyFilter() getActionFilter() getEventFilter() getRelationshipFilter() A basic example without any filter that accesses and uses the entire DT State is:\nHttpDigitalAdapterConfiguration config = new HttpDigitalAdapterConfiguration(\u0026#34;my-http-adapter\u0026#34;, \u0026#34;localhost\u0026#34;, 8080); An example of using filter to select specific field of interest can be structured ad follows:\nHttpDigitalAdapterConfiguration config = new HttpDigitalAdapterConfiguration(\u0026#34;my-http-adapter\u0026#34;, \u0026#34;localhost\u0026#34;, 8080); // Add property filter config.addPropertyFilter(\u0026#34;temperature\u0026#34;); config.addPropertiesFilter(Arrays.asList(\u0026#34;humidity\u0026#34;, \u0026#34;pressure\u0026#34;)); // Add action filter config.addActionFilter(\u0026#34;start\u0026#34;); config.addActionsFilter(Arrays.asList(\u0026#34;stop\u0026#34;, \u0026#34;reset\u0026#34;)); // Add event filter config.addEventFilter(\u0026#34;temperatureChange\u0026#34;); config.addEventsFilter(Collections.singletonList(\u0026#34;pressureChange\u0026#34;)); // Add relationship filter config.addRelationshipFilter(\u0026#34;connectedTo\u0026#34;); config.addRelationshipsFilter(Arrays.asList(\u0026#34;parentOf\u0026#34;, \u0026#34;siblingOf\u0026#34;)); // Retrieve and display filters List\u0026lt;String\u0026gt; propertyFilter = config.getPropertyFilter(); List\u0026lt;String\u0026gt; actionFilter = config.getActionFilter(); List\u0026lt;String\u0026gt; eventFilter = config.getEventFilter(); List\u0026lt;String\u0026gt; relationshipFilter = config.getRelationshipFilter(); System.out.println(\u0026#34;Property Filter: \u0026#34; + propertyFilter); System.out.println(\u0026#34;Action Filter: \u0026#34; + actionFilter); System.out.println(\u0026#34;Event Filter: \u0026#34; + eventFilter); System.out.println(\u0026#34;Relationship Filter: \u0026#34; + relationshipFilter); HttpDigitalAdapter The HttpDigitalAdapter itself is the core component responsible for handling HTTP requests and interacting with the underlying Digital Twin. It extends the capabilities of the base DigitalAdapter to specifically cater to HTTP-based scenarios.\nKey Functionalities:\nRESTful Endpoints: Provides RESTful endpoints for reading properties, invoking actions, querying events, and managing relationships. State Updates: Automatically reflects changes in the Digital Twin state to the HTTP endpoints, ensuring real-time information. Event Handling: Listens for Digital Twin events and provides events notifications to HTTP clients. Here\u0026rsquo;s a basic example illustrating how to use MqttDigitalAdapter:\nGetting Started: Create HttpDigitalAdapterConfiguration:\nHttpDigitalAdapterConfiguration config = new HttpDigitalAdapterConfiguration(\u0026#34;my-http-adapter\u0026#34;, \u0026#34;localhost\u0026#34;, 8080); Instantiate HttpDigitalAdapter:\nDigitalTwin digitalTwin = new DigitalTwin(\u0026#34;my-digital-twin\u0026#34;, new DefaultShadowingFunction()); HttpDigitalAdapter httpDigitalAdapter = new HttpDigitalAdapter(config, digitalTwin); // Add a Physical Adapter to the DT [...] Add HttpDigitalAdapter to DigitalTwin:\ndigitalTwin.addDigitalAdapter(httpDigitalAdapter); Start the Digital Twin Engine:\nDigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine(); digitalTwinEngine.addDigitalTwin(digitalTwin); digitalTwinEngine.startAll(); HTTP RESTful API This section of the documentation provides detailed information about the RESTful API exposed by the WLDT - HTTP Digital Adapter. The API allows you to interact with the Digital Twin (DT) instance, retrieve its state, read properties, actions, event and relationships description, and trigger actions.\nAvailable endpoints with the associated methods are:\nGET /instance: Retrieves information about the Digital Twin instance. GET /state: Retrieves the current state of the Digital Twin. GET /state/changes: Retrieves the list of state changes in the Digital Twin. GET /state/previous: Retrieves the previous state of the Digital Twin. GET /state/properties: Retrieves the list of properties in the Digital Twin state. GET /properties/{propertyKey}: Retrieves the value of a specific property (e.g., /properties/color) from the Digital Twin state. GET /state/events: Retrieves the list of events in the Digital Twin state. GET /state/actions: Retrieves the list of actions in the Digital Twin state. POST /state/actions/{actionKey}: Triggers the specified action (e.g., /state/actions/switch_on) in the Digital Twin state. The raw body contains the action request payload. GET /state/relationships: Retrieves the list of relationships in the Digital Twin state. GET /state/relationships/{relationshipName}/instances: Retrieves the instances of the specified relationship (e.g., /state/relationships/insideIn/instances) in the Digital Twin state. Note: Replace {propertyKey}, {actionKey}, and {relationshipName} with the actual values you want to retrieve or trigger. Make sure to use the appropriate HTTP method (GET, POST) and include any required parameters or payload as described in each endpoint\u0026rsquo;s description. For more detailed information, refer to the Postman Collection for this API available in the folder api: http_adapter_api_postman.json\n","date":"February 9, 2024","id":15,"permalink":"/docs/adapters/http-digital-adapter/","summary":"The HttpDigitalAdapter is a powerful component designed to facilitate the integration of Digital Twins into HTTP-based systems. It serves as a bridge between a Digital Twin and HTTP-based applications, allowing developers to easily expose and interact with Digital Twin data and functionalities over HTTP.","tags":"","title":"HTTP Digital Adapter"},{"content":"The WLDT framework intends to maximize modularity, re-usability and flexibility in order to effectively mirror physical smart objects in their digital counterparts. The proposed library focuses on the simplification of twins design and development aiming to provide a set of core features and functionalities for the widespread adoption of Internet of Things DTs applications.\nA WLDT instance is a general purpose software entity implementing all the features and functionalities of a Digital Twin running in cloud or on the edge. It has the peculiar characteristic to be generic and ``attachable\u0026rsquo;\u0026rsquo; to any physical thing in order to impersonate and maintain its digital replica and extend the provided functionalities for example through the support of additional protocols or a specific translation or normalization for data and formats.\nHereafter, the requirements that led the design and development of the WLDT framework are:\ni) Simplicity - with WLDT developers must have the possibility to easily create a new instance by using existing modules or customizing the behavior according the need of their application scenario; ii) Extensibility - while WLDT must be as simple and light as possible, the API should be also easily extendible in order to let programmers to personalize the configuration and/or to add new features loading and executing multiple modules at the same times; iii) Portability \u0026amp; Micorservice Readiness - a digital twin implemented through WLDT must be able to run on any platform without changes and customization. Our goal is to have a simple and light core engine with a strategic set of IoT-oriented features allowing the developer to easily create DT applications modeled as independent software agents and packed as microservices. In the following Figure, the main components that make up the architecture of WLDT are represented, and thus through which the individual Digital Twin is implemented. Specifically, from the image it is possible to identify the three levels on which the architecture is developed: the one related to the core of the library, the one that models the DT, and finally, that of the adapters.\nEach of this core components has the following main characteristics:\nMetrics Manager: Provides the functionalities for managing and tracking various metrics within DT instances combining both internal and custom metrics through a flexible and extensible approach. Logger: Is designed to facilitate efficient and customizable logging within implemented and deployed DTs with configurable log levels and versatile output options. Utils \u0026amp; Commons: Hold a collection of utility classes and common functionalities that can be readily employed across DT implementations ranging from handling common data structures to providing helpful tools for string manipulation. Event Communication Bus: Represents the internal Event Bus, designed to support communication between the different components of the DT\u0026rsquo;s instance. It allows defining customized events to model both physical and digital input and outputs. Each WLDT\u0026rsquo;s component can publish on the shared Event Bus and define an Event Filter to specify which types of events it is interested in managing, associating a specific callback to each one to process the different messages. Digital Twin Engine: Defines the multi-thread engine of the library allowing the execution and monitoring of multiple DTs (and their core components) simultaneously. Therefore, it is also responsible for orchestrating the different internal modules of the architecture while keeping track of each one, and it can be considered the core of the platform itself allowing the execution and control of the deployed DTs. Currently, it supports the execution of twins on the same Java process, however the same engine abstraction might be used to extend the framework to support distributed execution for example through different processes or microservices. Digital Twin: Models a modular DT structure built through the combination of core functionalities together with physical and digital adapter capabilities. This Layer includes the Digital Twin State responsible to structure the state of the DT by defining the list of properties, events, and actions. The different instances included in the lists can correspond directly to elements of the physical asset or can derive from their combination, in any case, it is the Shadowing Function (SF) that defines the mapping, following the model defined by the designer. This component also exposes a set of methods to allow SF manipulation. Every time the Digital Twin State is modified, the latter generates the corresponding DT\u0026rsquo;s event to notify all the components about the variation. Shadowing Function: It is the library component responsible for defining the behavior of the Digital Twin by interacting with the Digital Twin State. Specifically, it implements the shadowing process that allows keeping the DT synchronized with its physical entity. This component is based on a specific implementation of a WLDT Worker called Model Engine, in order to be executed by the WLDT Engine. The Shadowing Model Function is the fundamental component that must be extended by the DT designer to concretize its model. The shadowing function observes the life cycle of the Digital Twin to be notified of the different state changes. For example, it is informed when the DT enters the Bound state, i.e. when its Physical Adapters have completed the binding procedure with the physical asset. This component also allows the designer to define the behavior of the DT in case a property is modified, an event is triggered, or an action is invoked. Physical Adapter: It defines the essential functionalities that the individual extensions, related to specific protocols, must implement. As provided by the DT definition, a DT can be equipped with multiple Physical Adapters in order to manage communication with the corresponding physical entity. Each will produce a Physical Asset Description (PAD), i.e., a description of the properties, events, actions, and relationships that the physical asset exposes through the specific protocol. The DT transitions from the Unbound to the Bound state when all its Physical Adapters have produced their respective PADs. The Shadowing Function, following the DT model, selects the components of the various PADs that it is interested in managing. Digital Adapter: It provides the set of callbacks that each specific implementation can use to be notified of changes in the DT state. Symmetrically to what happens with Physical Adapters, a Digital Twin can define multiple Digital Adapters to expose its state and functionality through different protocols. Therefore, to create a Digital Twin using WLDT, it is necessary to define and instantiate a DT with its Shadowing Function and at least one Physical Adapter and one Digital Adapter, in order to enable connection with the physical entity and allow the DT to be used by external applications. Once the 3 components are defined, it is possible to instantiate the WLDT Engine and, subsequently, start the lifecycle of the DT. In the following sections we will go through the fundamental steps to start working with the library and creating all the basic modules to design, develop and execute our first Java Digital Twin.\n","date":"February 9, 2024","id":16,"permalink":"/docs/introduction/library-structure-basic-concepts/","summary":"The WLDT framework intends to maximize modularity, re-usability and flexibility in order to effectively mirror physical smart objects in their digital counterparts.","tags":"","title":"Library Structure \u0026 Basic Concepts"},{"content":" With respect to the element present in the real world, it is defined as a Physical Asset (PA) with the intention of referring to any entity that has a manifestation or relevance in the physical world and a well-defined lifespan.\nThe previous Figure schematically illustrates the main component of an abstract Digital Twin and clarifies its responsibility to be a bridge between the cyber and the physical world. The blueprint components (then mapped into the WLDT Library) are:\nPhysical Interface The entity in charge of both the initial digitalization o shadowing process and the perpetual responsibility to keep the DT and PA in synch during its life cycle. It can execute multiple Physical Asset Adapters to interact with the PA and detect and digitalize the physical event coming from the physical entity according to its nature and the supported protocols and data formats (e.g., through HTTP and JSON). Digital Interface The component complementary to the Physical Interface and in charge of handling DT\u0026rsquo;s internal variations and events towards external digital entities and consumers. It executes multiple and reusable Digital Adapters in charge of handling digital interactions and events and responsible for making the DT interoperable with external applications. DT\u0026rsquo;s Model The module defining the DT\u0026rsquo;s behaviour and its augmented functionalities. It supports the execution of different configurable and reusable modules and functionalities handling both physical and digial events according to the implemented behaviour. Furthermore, the Model is the component responsible to handle and keep updated the Digital Twin State as described in the following sections. The Digital Twin Model(M) allows capturing and representing the PA at an appropriate level of abstraction, i.e., avoiding irrelevant aspects for its purpose and modeling only domain-level information rather than technological ones. Finally, the link between the physical and digital copy is defined as shadowing. Specifically, the term defines the process that enables continuous and (almost) real-time updating of the internal state of the DT in relation to changes that occur in the PA.\nEach DT is thus equipped with an internal model, which defines how the PA is represented in the digital level. The DT\u0026rsquo;s representation denoted as Digital Twin State supported and defined through M is defined in terms of:\nProperties: represent the observable attributes of the corresponding PA as labeled data whose values can dynamically change over time, in accordance with the evolution of the PA\u0026rsquo;s state. Events: represent the domain-level events that can be observed in the PA. Relationships: represent the links that exist between the modeled PA and other physical assets of the organizations through links to their corresponding Digital Twins. Like properties, relationships can be observed, dynamically created, and change over time, but unlike properties, they are not properly part of the PA\u0026rsquo;s state but of its operational context (e.g., a DT of a robot within a production line). Actions: represent the actions that can be invoked on the PA through interaction with the DT or directly on the DT if they are not directly available on the PA (the DT is augmenting the physical capabilities). Once the model M is defined, the dynamic state of the DT (SDT) can be defined by through the combination of its properties, events, relationships and actions associated to the DT timestamp that represents the current time of synchronization between the physical and digital counterparts.\nThe Shadowing Process The shadowing process (also known as replication of digitalization) allows to keep the Digital Twin State synchronized with that of the corresponding physical resource according to what is defined by the model M. Specifically, each relevant update of the PA state (SPA) is translated into a sequence of 3 main steps:\neach relevant change in physical asset state is modeled by a physical_event (e_pa); the event is propagated to the DT; given the new physical_event, the DT\u0026rsquo;s is updated through the application of a shadowing function, which depends on the model M The shadowing process allows also the DT to reflect and invoke possible actions of the PA. The DT receives an action request (denoted as digital_action) on its digital interface, applies the shadowing function to validate it and then propagates the request through its physical interface. An important aspect to emphasize is that the request for a digital_action does not directly change the state of the DT since any changes can only occur as a result of the shadowing function from the PA to the DT, as described earlier.\n","date":"February 9, 2024","id":17,"permalink":"/docs/introduction/dt-model/","summary":"With respect to the element present in the real world, it is defined as a Physical Asset (PA) with the intention of referring to any entity that has a manifestation or relevance in the physical world and a well-defined lifespan.","tags":"","title":"DT Model"},{"content":"\rThe modeling of the concept of DT includes also the definition and characterization of its life cycle. Based on the scientific literature, we model (and then map into the library) a life cycle with 5 states through which the DT goes from when it is executed to when it is stopped. The previous Figure shows a graphical representation of the life cycle with the following steps:\nOperating \u0026amp; Not Bound: this is the state in which the DT is located following the initialization phase, indicating that all internal modules of the DT are active but there is no association yet with the corresponding PA. Bound: this is the state in which the DT transitions following the correct execution of the binding procedure. The binding procedure allows to connect the two parts and enables bidirectional flow of events. Shadowed: this is the state reached by the DT when the shadowing process begins and its state is correctly synchronized with that of the PA. Out of Sync: this is the state that determines the presence of errors in the shadowing process. When in this state, the DT is not able to handle either state alignment events or those generated by the application layer. Done: this is the state that the DT reaches when the shadowing process is stopped, but the DT continues to be active to handle requests coming from external applications. From Unbound to Bound Taking into account the target reference Life Cycle the first point to address is how we can move from an UnBound state to a Bound condition with respect to the relationship with the Physical Layer.\nThe previous Figure illustrates a simple scenario where a Physical Asset uses two protocols (P1 and P2) to communicate and it is connected to the Digital Twin through a DT\u0026rsquo;s Physical Interface enabled with two dedicated Adapters for protocol P1 and P2. In order to move from the Unbound to Bound state the DT should be aware of the description of the target asset with respect to the two protocols. For example through P1 the asset exposes telemetry data (e.g., light bulb status and energy consumption) while on P2 allows incoming action requests (e.g., turn on/off the light). The Digital Twin can start the shadowing process only when it is bound and has a description of the properties and capabilities of the associated physical counterpart. The schematic procedure is illustrated in the following Figure:\nInvolved steps are:\nThe Adapter P1 communicates with the PA through Protocol 1 and provides a Physical Asset Description from its perspective The Adapter P2 communicates with the PA through Protocol 2 and provides a Physical Asset Description from its perspective Only when all Physical Adapters have been correctly bound (it may require time) to the Physical Asset and the associated Physical Asset Descriptions have been generated, the DT can move from UnBound to Bound Main core aspects associated to the concept of Physical Asset Description (PAD) are the following:\nIt is used to describe the list of properties, actions and relationships of a Physical Asset Each Physical Adapter generates a dedicated PAD associated to its perspective on the Physical Assets and its capabilities to read data and execute actions It is a responsibility of the DT to handle multiple descriptions in order to build the digital replica It will be used by the DT to handle the shadowing process and keep the digital replica synchronized with the physical counterpart From Bound to Shadowed Following the same approach described in the previous step we need to define a procedure to allow the DT to move from a Bound state to a Shadowed condition where the twin identified the interesting capabilities of the Physical Asset that has to be digitalized and according to the received Physical Asset Descriptions start the shadowing procedure to be synchronized with the physical world.\nAs schematically illustrated in the previous Figure, involved steps are:\nThe Model defines which properties should be monitored on the Physical Asset and start observing them through the target adapters Involved Physical Adapters communicate with the Physical Asset, receive data and generate Events (ePA) to notify about physical property changes Received ePA will be used by the Digital Twin Model in order to run the Shadowing function and compute the new DT State The DT can move from the Bound to Shadowed phase until it is able to maintain a proper synchronization with the physical asset over time through its shadowing process and the generation and maintenance of the DT\u0026rsquo;s State The Digital Twin State is structured and characterized by the following elements:\nA list of properties A list of actions A list of relationships Listed elements can be directly associated to the corresponding element of the Physical Asset or generated by DT Model combining multiple physical properties, actions or relationships at the same time. The Digital Twin State can be managed through the Shadowing Function and exposes a set of methods for its manipulated. When there is a change in the DT State an event (eDT) will be generated\nThe manipulation of DT\u0026rsquo;s State generates a set of DT\u0026rsquo;s events (eDT) associated to each specific variation and evolution of the twin during its life cyle. These events are used by the Digital Interface and in particular by its Digital Adapters to expose the DT\u0026rsquo;s State, its properties and capabilities to the external digital world. At the same time, eDT can be used by Digital Adapters to trigger action on the DT and consequently to propagate (if acceptable and/or needed) the incoming request to the physical assets bound with the target DT. Supported events are illustrated in the following schema.\n","date":"February 9, 2024","id":18,"permalink":"/docs/introduction/dt-life-cycle/","summary":"The modeling of the concept of DT includes also the definition and characterization of its life cycle. Based on the scientific literature, we model (and then map into the library) a life cycle with 5 states through which the DT goes from when it is executed to when it is stopped.","tags":"","title":"DT Life Cycle"},{"content":"","date":"September 7, 2023","id":19,"permalink":"/docs/","summary":"","tags":"","title":"Docs"},{"content":"Welcome to White Label Digital Twins (WLDT), an open-source project dedicated to supporting the design, development, and deployment of Digital Twins within the Internet of Things (IoT) ecosystems.\nThe WLDT library has been designed to align with the latest DT definitions from both Industrial and Scientific domains. It identifies DTs as active, flexible, and scalable software components. Our library aims to provide developers with the tools and resources necessary to create robust Digital Twins that effectively simulate and monitor physical assets within IoT environments.\nWhether you\u0026rsquo;re working on IoT, Industrial IoT (IIoT) applications, Smart Cities projects, or any other IoT-related endeavor, the WLDT library offers a versatile solution for implementing Digital Twins that accurately represent real-world objects and support informed decision-making processes.\n💻 Team \u0026amp; Mantainers [Founders \u0026amp; Main Contributors] Marco Picone - University of Modena \u0026amp; Reggio Emilia, Italy - (Link) [Key Contributors] Samuele Burattini - University of Bologna, Italy - (Link) [Additional Contributors] Marta Spadoni - University of Bologna, Italy - Master Thesis 2022 📜 Scientitic Citation \u0026amp; References If you use the WLDT Library in a Scientific Paper please use this reference:\n@article{PICONE2021100661, title = {WLDT: A general purpose library to build IoT digital twins}, journal = {SoftwareX}, volume = {13}, pages = {100661}, year = {2021}, issn = {2352-7110}, doi = {https://doi.org/10.1016/j.softx.2021.100661}, url = {https://www.sciencedirect.com/science/article/pii/S2352711021000066}, author = {Marco Picone and Marco Mamei and Franco Zambonelli}, keywords = {Internet of Things, Digital twin, Library, Software agent} } 📨 Community Join our community and contribute to the advancement of Digital Twin technology with White Label Digital Twins!\nWLDT questions, feedback and discussions are tracked using slack channels in the WLDT Slack Workspace.\nThe workspace is available here: WLDT Slack Workspace\nNew users first need to join the MEC Sandbox slack workspace by creating a new account using the invitation link provided here: Join the WLDT Slack Workspace\n🐛 Reporting Issues WLDT issues should be reported on Slack, where they can be discussed with the core team that maintains the WLDT Library.\n","date":"March 13, 2024","id":20,"permalink":"/about/","summary":"Welcome to White Label Digital Twins (WLDT), an open-source project dedicated to supporting the design, development, and deployment of Digital Twins within the Internet of Things (IoT) ecosystems.","tags":"","title":"About WLDT Library"},{"content":" What is a digital Twin? A Digital Twin (DT) is a comprehensive software representation of any individual Physical Asset (PA) in the real world.\nIt includes the properties, conditions, relationships, and behavior(s) of the real-life object through models and data.\nA Digital Twin is a set of realistic models that can digitalize an object’s behavior in the deployed environment and has the responsibility to represent and reflect its physical counterpart over time maintaining its digital replica across the object’s entire lifecycle.\nWhat can WLDT do for me? The White Label Digital Twin (WLDT) library aims to support the design, development, and deployment of Digital Twins within the Internet of Things (IoT) ecosystems.\nThe library has been designed following the latest DT definitions coming from both Industrial and Scientific domains and identifying DTs as active, flexible and scalable software components.\nScientitic Citation \u0026amp; Reference If you use the WLDT Library in a Scientific Paper refer to the About Page for additional information and scientific references. Thanks :)\n","date":"October 6, 2023","id":21,"permalink":"/","summary":"What is a digital Twin? A Digital Twin (DT) is a comprehensive software representation of any individual Physical Asset (PA) in the real world.","tags":"","title":"White Label Digital Twins"},{"content":"","date":"September 7, 2023","id":22,"permalink":"/privacy/","summary":"","tags":"","title":"Privacy Policy"},{"content":"","date":"January 1, 0001","id":23,"permalink":"/categories/","summary":"","tags":"","title":"Categories"},{"content":"","date":"January 1, 0001","id":24,"permalink":"/contributors/","summary":"","tags":"","title":"Contributors"},{"content":"","date":"January 1, 0001","id":25,"permalink":"/tags/","summary":"","tags":"","title":"Tags"}] \ No newline at end of file +[{"content":"We\u0026rsquo;re excited to announce the release of WLDT version 0.4.0! This update brings powerful new features to enhance your Digital Twin (DT) experience, including event observation capabilities, a robust storage layer, and a flexible query system.\nFor detailed information about these changes and their impact, please refer to the information provided:\nOfficial Changelog Official Documentation Key Highlights WldtEventObserver: A new class has been introduced, simplifying the observation of specific events generated by Digital Twins and their components Storage Layer: The new storage layer allows DTs to store data related to their state, events, actions, and more. It consists of: Storage Manager: Manage and use various storage systems (e.g., in-memory, file-based, DBMS) simultaneously. WldtStorage: An abstract class to implement custom storage systems. The default in-memory storage is available for development and testing. Query System: The query system enables external components like Digital Adapters to retrieve stored data efficiently, supporting both synchronous and asynchronous queries. WLDT 0.4.0 significantly enhances the flexibility and capabilities of Digital Twins, making it easier to manage and retrieve data, and observe events. We encourage developers to explore these new features and integrate them into their projects.\nStay tuned for more updates!\n","date":"August 29, 2024","id":0,"permalink":"/blog/wldt-library-version-0.4.0/","summary":"We\u0026rsquo;re excited to announce the release of WLDT version 0.4.0! This update brings powerful new features to enhance your Digital Twin (DT) experience, including event observation capabilities, a robust storage layer, and a flexible query system.","tags":"","title":"WLDT Library Version 0.4.0"},{"content":"📣 We\u0026rsquo;re thrilled to announce the release of version 0.3.0 of the White Label Digital Twins (WLDT) library! This release brings significant enhancements, improvements, and new features to further empower developers in designing, developing, and deploying Digital Twins within Internet of Things (IoT) ecosystems.\nFor detailed information about these changes and their impact, please refer to the information provided:\nOfficial Changelog Official Documentation Let\u0026rsquo;s dive into the key changes and updates included in this release:\nMigration Digital Adapters In version 0.3.0, we\u0026rsquo;ve made several enhancements and adjustments to the Digital Adapter class to improve its functionality and usability. Notable changes include:\nDiscontinued Methods: Several methods have been discontinued and removed from the DigitalAdapter class to streamline its interface and improve clarity. Method Signature Changes: The signatures of certain methods have been updated for consistency and clarity, ensuring a more intuitive developer experience. New Methods: We\u0026rsquo;ve introduced new methods to provide additional functionality and flexibility for handling state updates and event notifications. Migration Shadowing Function We\u0026rsquo;ve made significant improvements to the ShadowingModelFunction, which is now renamed to ShadowingFunction. Additionally, we\u0026rsquo;ve introduced changes to how the DigitalTwinState is managed within the Shadowing Function, providing developers with more control and flexibility.\nMigrating WLDT Engine \u0026amp; DT Creation In version 0.3.0, the WldtEngine class has been renamed to DigitalTwin, offering improved clarity and consistency. We\u0026rsquo;ve also made adjustments to the lifecycle management of Digital Twins, streamlining the process and enhancing usability.\nDigital Twin \u0026amp; Digital Twin Engine We\u0026rsquo;ve introduced enhancements to the Digital Twin and Digital Twin Engine classes, providing developers with improved functionality and ease of use. Notable updates include:\nSimplified Digital Twin Creation: Creating and managing Digital Twins is now more intuitive and streamlined. Lifecycle Management: We\u0026rsquo;ve enhanced the lifecycle management of Digital Twins, making it easier to start, stop, and manage multiple instances. Digital Twin State Manager The DigitalTwinStateManager class has been improved to provide better support for managing the state of Digital Twins. With features such as transaction support and event notification, developers can more effectively manage changes to Digital Twin states and respond to events.\nTo learn more about the capabilities of the DigitalTwinStateManager, please refer to the Digital Twin State Manager section.\nDigital Adapter We\u0026rsquo;ve extended and improved the Digital Adapter base class to provide enhanced support for handling Digital Twin state updates and event notifications. With the introduction of the onStateUpdate and onEventNotificationReceived methods, developers can more effectively respond to changes in Digital Twin states and events.\nGet Started with WLDT 0.3.0 To get started with version 0.3.0 of the WLDT library, simply update your dependencies to include the latest release. Detailed documentation and usage examples are available in the project repository, providing comprehensive guidance on leveraging the new features and enhancements.\nWe\u0026rsquo;re excited about the improvements and new capabilities introduced in WLDT 0.3.0, and we can\u0026rsquo;t wait to see how developers utilize them to create innovative IoT solutions powered by Digital Twins. As always, we welcome your feedback and contributions to help us further improve the library and empower the community.\nHappy coding with WLDT 0.3.0! 🚀\n","date":"March 13, 2024","id":1,"permalink":"/blog/wldt-library-version-0.3.0/","summary":"📣 We\u0026rsquo;re thrilled to announce the release of version 0.3.0 of the White Label Digital Twins (WLDT) library! This release brings significant enhancements, improvements, and new features to further empower developers in designing, developing, and deploying Digital Twins within Internet of Things (IoT) ecosystems.","tags":"","title":"WLDT Library Version 0.3.0"},{"content":"","date":"September 7, 2023","id":2,"permalink":"/blog/","summary":"","tags":"","title":"Blog"},{"content":"","date":"September 7, 2023","id":3,"permalink":"/docs/introduction/","summary":"","tags":"","title":"Introduction"},{"content":"","date":"February 9, 2024","id":4,"permalink":"/docs/guides/","summary":"","tags":"","title":"Getting Started"},{"content":"The developer can use an existing Physical Adapter or create a new one to handle the communication with a specific physical twin. In this documentation we focus on the creation of a new Physical Adapter in order to explain library core functionalities. However, existing Physical Adapters can be found on the official repository and linked in the core documentation and webpage (WLDT-GitHub).\nIn general WLDT Physical Adapter extends the class PhysicalAdapter and it is responsible to talk with the physical world and handling the following main tasks:\nGenerate a PAD describing the properties, events, actions and relationships available on the physical twin using the class PhysicalAssetDescription Generate Physical Event using the class PhysicalAssetEventWldtEvent associated to the variation of any aspect of the physical state (properties, events, and relationships) Handle action request coming from the Digital World through the DT Shadowing Function by implementing the method onIncomingPhysicalAction and processing events modeled through the class PhysicalAssetActionWldtEvent Create a new class called DemoPhysicalAdapter extending the library class PhysicalAdapter and implement the following methods:\nonAdapterStart: A callback method used to notify when the adapter has been effectively started withing the DT\u0026rsquo;s life cycle onAdapterStop: A call method invoked when the adapter has been stopped and will be dismissed by the core onIncomingPhysicalAction: The callback method called when a new PhysicalAssetActionWldtEvent is sent by the Shadowing Function upon the receiving of a valid Digital Action through a Digital Adapter Then you have to create a constructor for your Physical Adapter with a single String parameter representing the id of the adapter. This id will be used internally by the library to handle and coordinate multiple adapters, adapts logs and execute functions upon the arrival of a new event. The resulting empty class will the following:\npublic class DemoPhysicalAdapter extends PhysicalAdapter { public DemoPhysicalAdapter(String id) { super(id); } @Override public void onIncomingPhysicalAction(PhysicalAssetActionWldtEvent\u0026lt;?\u0026gt; physicalAssetActionWldtEvent) { } @Override public void onAdapterStart() { } @Override public void onAdapterStop() { } } In our test Physical Adapter example we are going to emulate the communication with an Internet of Things device with the following sensing and actuation characteristics:\nA Temperature Sensor generating data about new measurements The possibility to generate OVER-HEATING events An action to set the target desired temperature value The first step will be to generate and publish the PhysicalAssetDescription (PAD) to describe the capabilities and the characteristics of our object allowing the Shadowing Function to decide how to digitalize its physical counterpart. Of course in our case the PAD is generated manually but according to the nature of the connected physical twin it can be automatically generated starting from a discovery or a configuration passed to the adapter.\nThe generation of the PAD for each active Physical Adapter is the fundamental DT process to handle the binding procedure and to allow the Shadowing Function and consequently the core of the twin to be aware of what is available in the physical world and consequently decide what to observe and digitalize.\nIn order to publish the PAD we can update the onAdapterStart method with the following lines of code:\nprivate final static String TEMPERATURE_PROPERTY_KEY = \u0026#34;temperature-property-key\u0026#34;; private final static String OVERHEATING_EVENT_KEY = \u0026#34;overheating-event-key\u0026#34;; private final static String SET_TEMPERATURE_ACTION_KEY = \u0026#34;set-temperatura-action-key\u0026#34;; @Override public void onAdapterStart() { try { //Create an empty PAD PhysicalAssetDescription pad = new PhysicalAssetDescription(); //Add a new Property associated to the target PAD with a key and a default value PhysicalAssetProperty\u0026lt;Double\u0026gt; temperatureProperty = new PhysicalAssetProperty\u0026lt;Double\u0026gt;(TEMPERATURE_PROPERTY_KEY, 0.0); pad.getProperties().add(temperatureProperty); //Add the declaration of a new type of generated event associated to a event key // and the content type of the generated payload PhysicalAssetEvent overheatingEvent = new PhysicalAssetEvent(OVERHEATING_EVENT_KEY, \u0026#34;text/plain\u0026#34;); pad.getEvents().add(overheatingEvent); //Declare the availability of a target action characterized by a Key, an action type // and the expected content type and the request body PhysicalAssetAction setTemperatureAction = new PhysicalAssetAction(SET_TEMPERATURE_ACTION_KEY, \u0026#34;temperature.actuation\u0026#34;, \u0026#34;text/plain\u0026#34;); pad.getActions().add(setTemperatureAction); //Notify the new PAD to the DT\u0026#39;s Shadowing Function this.notifyPhysicalAdapterBound(pad); //TODO add here the Device Emulation method } catch (PhysicalAdapterException | EventBusException e) { e.printStackTrace(); } } Now we need a simple code to emulate the generation of new temperature measurements and over-heating events. In a real Physical Adapter implementation we have to implement the real communication with the physical twin in order to read its state variation over time according to the supported protocols. In our simplified Physical Adapter we can the following function:\nprivate final static int MESSAGE_UPDATE_TIME = 1000; private final static int MESSAGE_UPDATE_NUMBER = 10; private final static double TEMPERATURE_MIN_VALUE = 20; private final static double TEMPERATURE_MAX_VALUE = 30; private Runnable deviceEmulation(){ return () -\u0026gt; { try { //Sleep 5 seconds to emulate device startup Thread.sleep(5000); //Create a new random object to emulate temperature variations Random r = new Random(); //Publish an initial Event for a normal condition publishPhysicalAssetEventWldtEvent(new PhysicalAssetEventWldtEvent\u0026lt;\u0026gt;(OVERHEATING_EVENT_KEY, \u0026#34;normal\u0026#34;)); //Emulate the generation on \u0026#39;n\u0026#39; temperature measurements for(int i = 0; i \u0026lt; MESSAGE_UPDATE_NUMBER; i++){ //Sleep to emulate sensor measurement Thread.sleep(MESSAGE_UPDATE_TIME); //Update the double randomTemperature = TEMPERATURE_MIN_VALUE + (TEMPERATURE_MAX_VALUE - TEMPERATURE_MIN_VALUE) * r.nextDouble(); //Create a new event to notify the variation of a Physical Property PhysicalAssetPropertyWldtEvent\u0026lt;Double\u0026gt; newPhysicalPropertyEvent = new PhysicalAssetPropertyWldtEvent\u0026lt;\u0026gt;(TEMPERATURE_PROPERTY_KEY, randomTemperature); //Publish the WLDTEvent associated to the Physical Property Variation publishPhysicalAssetPropertyWldtEvent(newPhysicalPropertyEvent); } //Publish a demo Physical Event associated to a \u0026#39;critical\u0026#39; overheating condition publishPhysicalAssetEventWldtEvent(new PhysicalAssetEventWldtEvent\u0026lt;\u0026gt;(OVERHEATING_EVENT_KEY, \u0026#34;critical\u0026#34;)); } catch (EventBusException | InterruptedException e) { e.printStackTrace(); } }; } Now we have to call the deviceEmulationFunction() inside the onAdapterStart() triggering its execution and emulating the physical counterpart of our DT. To do that add the following line at the end of the onAdapterStart() method after the this.notifyPhysicalAdapterBound(pad);.\nThe last step will be to handle an incoming action trying to set a new temperature on the device by implementing the method onIncomingPhysicalAction(). This method will receive a PhysicalAssetActionWldtEvent\u0026lt;?\u0026gt; physicalAssetActionWldtEvent associated to the action request generated by the shadowing function. Since a Physical Adapter can handle multiple action we have to check both action-key and body type in order to properly process the action (in our case just logging the request). The new update method will result like this:\n@Override public void onIncomingPhysicalAction(PhysicalAssetActionWldtEvent\u0026lt;?\u0026gt; physicalAssetActionWldtEvent) { try{ if(physicalAssetActionWldtEvent != null \u0026amp;\u0026amp; physicalAssetActionWldtEvent.getActionKey().equals(SET_TEMPERATURE_ACTION_KEY) \u0026amp;\u0026amp; physicalAssetActionWldtEvent.getBody() instanceof String) { System.out.println(\u0026#34;Received Action Request: \u0026#34; + physicalAssetActionWldtEvent.getActionKey() + \u0026#34; with Body: \u0026#34; + physicalAssetActionWldtEvent.getBody()); } else System.err.println(\u0026#34;Wrong Action Received !\u0026#34;); }catch (Exception e){ e.printStackTrace(); } } The overall class will result as following:\nimport it.wldt.adapter.physical.*; import it.wldt.adapter.physical.event.PhysicalAssetActionWldtEvent; import it.wldt.adapter.physical.event.PhysicalAssetEventWldtEvent; import it.wldt.adapter.physical.event.PhysicalAssetPropertyWldtEvent; import it.wldt.exception.EventBusException; import it.wldt.exception.PhysicalAdapterException; import java.util.Random; public class DemoPhysicalAdapter extends PhysicalAdapter { private final static String TEMPERATURE_PROPERTY_KEY = \u0026#34;temperature-property-key\u0026#34;; private final static String OVERHEATING_EVENT_KEY = \u0026#34;overheating-event-key\u0026#34;; private final static String SET_TEMPERATURE_ACTION_KEY = \u0026#34;set-temperature-action-key\u0026#34;; private final static int MESSAGE_UPDATE_TIME = 1000; private final static int MESSAGE_UPDATE_NUMBER = 10; private final static double TEMPERATURE_MIN_VALUE = 20; private final static double TEMPERATURE_MAX_VALUE = 30; public DemoPhysicalAdapter(String id) { super(id); } @Override public void onIncomingPhysicalAction(PhysicalAssetActionWldtEvent\u0026lt;?\u0026gt; physicalAssetActionWldtEvent) { try{ if(physicalAssetActionWldtEvent != null \u0026amp;\u0026amp; physicalAssetActionWldtEvent.getActionKey().equals(SET_TEMPERATURE_ACTION_KEY) \u0026amp;\u0026amp; physicalAssetActionWldtEvent.getBody() instanceof Double) { System.out.println(\u0026#34;Received Action Request: \u0026#34; + physicalAssetActionWldtEvent.getActionKey() + \u0026#34; with Body: \u0026#34; + physicalAssetActionWldtEvent.getBody()); } else System.err.println(\u0026#34;Wrong Action Received !\u0026#34;); }catch (Exception e){ e.printStackTrace(); } } @Override public void onAdapterStart() { try { //Create an empty PAD PhysicalAssetDescription pad = new PhysicalAssetDescription(); //Add a new Property associated to the target PAD with a key and a default value PhysicalAssetProperty\u0026lt;Double\u0026gt; temperatureProperty = new PhysicalAssetProperty\u0026lt;Double\u0026gt;(GlobalKeywords.TEMPERATURE_PROPERTY_KEY, 0.0); pad.getProperties().add(temperatureProperty); //Add the declaration of a new type of generated event associated to a event key // and the content type of the generated payload PhysicalAssetEvent overheatingEvent = new PhysicalAssetEvent(GlobalKeywords.OVERHEATING_EVENT_KEY, \u0026#34;text/plain\u0026#34;); pad.getEvents().add(overheatingEvent); //Declare the availability of a target action characterized by a Key, an action type // and the expected content type and the request body PhysicalAssetAction setTemperatureAction = new PhysicalAssetAction(GlobalKeywords.SET_TEMPERATURE_ACTION_KEY, \u0026#34;temperature.actuation\u0026#34;, \u0026#34;text/plain\u0026#34;); pad.getActions().add(setTemperatureAction); //Notify the new PAD to the DT\u0026#39;s Shadowing Function this.notifyPhysicalAdapterBound(pad); //Start Device Emulation new Thread(deviceEmulation()).start(); } catch (PhysicalAdapterException | EventBusException e) { e.printStackTrace(); } } @Override public void onAdapterStop() { } private Runnable deviceEmulation(){ return () -\u0026gt; { try { //Sleep 5 seconds to emulate device startup Thread.sleep(5000); //Create a new random object to emulate temperature variations Random r = new Random(); //Publish an initial Event for a normal condition publishPhysicalAssetEventWldtEvent(new PhysicalAssetEventWldtEvent\u0026lt;\u0026gt;(GlobalKeywords.OVERHEATING_EVENT_KEY, \u0026#34;normal\u0026#34;)); //Emulate the generation on \u0026#39;n\u0026#39; temperature measurements for(int i = 0; i \u0026lt; GlobalKeywords.MESSAGE_UPDATE_NUMBER; i++){ //Sleep to emulate sensor measurement Thread.sleep(GlobalKeywords.MESSAGE_UPDATE_TIME); //Update the double randomTemperature = GlobalKeywords.TEMPERATURE_MIN_VALUE + (GlobalKeywords.TEMPERATURE_MAX_VALUE - GlobalKeywords.TEMPERATURE_MIN_VALUE) * r.nextDouble(); //Create a new event to notify the variation of a Physical Property PhysicalAssetPropertyWldtEvent\u0026lt;Double\u0026gt; newPhysicalPropertyEvent = new PhysicalAssetPropertyWldtEvent\u0026lt;\u0026gt;(GlobalKeywords.TEMPERATURE_PROPERTY_KEY, randomTemperature); //Publish the WLDTEvent associated to the Physical Property Variation publishPhysicalAssetPropertyWldtEvent(newPhysicalPropertyEvent); } //Publish a demo Physical Event associated to a \u0026#39;critical\u0026#39; overheating condition publishPhysicalAssetEventWldtEvent(new PhysicalAssetEventWldtEvent\u0026lt;\u0026gt;(GlobalKeywords.OVERHEATING_EVENT_KEY, \u0026#34;critical\u0026#34;)); } catch (EventBusException | InterruptedException e) { e.printStackTrace(); } }; } } Both Physical Adapters and Digital Adapters can be defined natively with a custom configuration provided by the developer as illustrated in the dedicated Section: Configurable Physical \u0026amp; Digital Adapters.\n","date":"February 9, 2024","id":5,"permalink":"/docs/guides/physical-adapter/","summary":"The developer can use an existing Physical Adapter or create a new one to handle the communication with a specific physical twin.","tags":"","title":"Physical Adapter"},{"content":"After the definition of the Physical Adapter it is time to start implementing the core of our DT through the definition of its shadowing function in charge of:\nHandle received PAD from Physical Adapters in order to device which properties, events, relationships or actions available on connected physical twins should be mapped and managed into the DT State Manage incoming notifications/callbacks associated to the variation of physical properties (e.g, temperature variation) or the generation of physical event (e.g., overheating) Process action requests from the digital world that should be validated and forward to the correct Physical Adapter in order to trigger the associated actions on the physical world The Shadowing Function has the responsibility to build and maintain the updated state of the Digital Twin The internal variable of any WLDT Shadowing Function (available through the base class ShadowingFunction) used to do that is DigitalTwinStateManager accessible through the variable: this.digitalTwinStateManager\nWhen the Shadowing Function has to compute the new DT State it can now work with the following method to handle DT State Transition:\nStart the DT State Transaction: startStateTransaction() DT State variation methods such as: createProperty() updateProperty() updatePropertyValue() deleteProperty() enableAction() updateAction() disableAction() registerEvent() updateRegisteredEvent() unRegisterEvent() createRelationship() addRelationshipInstance() deleteRelationship() deleteRelationshipInstance() At the end the transaction can be committed using the method: commitStateTransaction() To access the current DT State the Shadowing Function implementation can use the method this.digitalTwinStateManager.getDigitalTwinState() The information available on the DT State are:\nproperties: List of Properties with their values (if available) actions: List of Actions that can be called on the DT events: List of Events that can be generated by the DT relationships: List of Relationships and their instances (if available) evaluationInstant: The timestamp representing the evaluation instant of the DT state Available main methods on that class instance are:\nProperties: getProperty(String propertyKey): Retrieves if present the target DigitalTwinStateProperty by Key containsProperty(String propertyKey): Checks if a target Property Key is already available in the current Digital Twin\u0026rsquo;s State getPropertyList(): Loads the list of available Properties (described by the class DigitalTwinStateProperty) available on the Digital Twin\u0026rsquo;s State createProperty(DigitalTwinStateProperty\u0026lt;?\u0026gt; dtStateProperty): Allows the creation of a new Property on the Digital Twin\u0026rsquo;s State through the class DigitalTwinStateProperty readProperty(String propertyKey): Retrieves if present the target DigitalTwinStateProperty by Key updateProperty(DigitalTwinStateProperty\u0026lt;?\u0026gt; dtStateProperty): Updates the target property using the DigitalTwinStateProperty and the associated Property Key field deleteProperty(String propertyKey): Deletes the target property identified by the specified key Actions: containsAction(String actionKey): Checks if a Digital Twin State Action with the specified key is correctly registered getAction(String actionKey): Loads the target DigitalTwinStateAction by key getActionList(): Gets the list of available Actions registered on the Digital Twin\u0026rsquo;s State enableAction(DigitalTwinStateAction digitalTwinStateAction): Enables and registers the target Action described through an instance of the DigitalTwinStateAction class updateAction(DigitalTwinStateAction digitalTwinStateAction): Update the already registered target Action described through an instance of the DigitalTwinStateAction class disableAction(String actionKey): Disables and unregisters the target Action described through an instance of the DigitalTwinStateAction class Events: containsEvent(String eventKey): Check if a Digital Twin State Event with the specified key is correctly registered getEvent(String eventKey): Return the description of a registered Digital Twin State Event according to its Key getEventList(): Return the list of existing and registered Digital Twin State Events registerEvent(DigitalTwinStateEvent digitalTwinStateEvent): Register a new Digital Twin State Event updateRegisteredEvent(DigitalTwinStateEvent digitalTwinStateEvent): Update the registration and signature of an existing Digital Twin State Event unRegisterEvent(String eventKey): Un-register a Digital Twin State Event notifyDigitalTwinStateEvent(DigitalTwinStateEventNotification\u0026lt;?\u0026gt; digitalTwinStateEventNotification): Method to notify the occurrence of the target Digital Twin State Event Relationships: containsRelationship(String relationshipName): Checks if a Relationship Name is already available in the current Digital Twin\u0026rsquo;s State createRelationship(DigitalTwinStateRelationship\u0026lt;?\u0026gt; relationship): Creates a new Relationships (described by the class DigitalTwinStateRelationship) in the Digital Twin\u0026rsquo;s State addRelationshipInstance(String name, DigitalTwinStateRelationshipInstance\u0026lt;?\u0026gt; instance): Adds a new Relationship instance described through the class DigitalTwinStateRelationshipInstance and identified through its name getRelationshipList(): Loads the list of existing relationships on the Digital Twin\u0026rsquo;s State through a list of DigitalTwinStateRelationship getRelationship(String name): Gets a target Relationship identified through its name and described through the class DigitalTwinStateRelationship deleteRelationship(String name): Deletes a target Relationship identified through its name deleteRelationshipInstance(String relationshipName, String instanceKey): Deletes the target Relationship Instance using relationship name and instance Key The basic library class that we are going to extend is called ShadowingFunction and creating a new class named DemoShadowingFunction the resulting code is the same after implementing required methods the basic constructor with the id String parameter.\nimport it.wldt.adapter.digital.event.DigitalActionWldtEvent; import it.wldt.adapter.physical.PhysicalAssetDescription; import it.wldt.adapter.physical.event.PhysicalAssetEventWldtEvent; import it.wldt.adapter.physical.event.PhysicalAssetPropertyWldtEvent; import it.wldt.adapter.physical.event.PhysicalAssetRelationshipInstanceCreatedWldtEvent; import it.wldt.adapter.physical.event.PhysicalAssetRelationshipInstanceDeletedWldtEvent; import it.wldt.core.model.ShadowingModelFunction; import java.util.Map; public class DemoShadowingFunction extends ShadowingModelFunction { public DemoShadowingFunction(String id) { super(id); } //// Shadowing Function Management Callbacks //// @Override protected void onCreate() { } @Override protected void onStart() { } @Override protected void onStop() { } //// Bound LifeCycle State Management Callbacks //// @Override protected void onDigitalTwinBound(Map\u0026lt;String, PhysicalAssetDescription\u0026gt; adaptersPhysicalAssetDescriptionMap) { } @Override protected void onDigitalTwinUnBound(Map\u0026lt;String, PhysicalAssetDescription\u0026gt; map, String s) { } @Override protected void onPhysicalAdapterBidingUpdate(String s, PhysicalAssetDescription physicalAssetDescription) { } //// Physical Property Variation Callback //// @Override protected void onPhysicalAssetPropertyVariation(PhysicalAssetPropertyWldtEvent\u0026lt;?\u0026gt; physicalAssetPropertyWldtEvent) { } //// Physical Event Notification Callback //// @Override protected void onPhysicalAssetEventNotification(PhysicalAssetEventWldtEvent\u0026lt;?\u0026gt; physicalAssetEventWldtEvent) { } //// Physical Relationships Notification Callbacks //// @Override protected void onPhysicalAssetRelationshipEstablished(PhysicalAssetRelationshipInstanceCreatedWldtEvent\u0026lt;?\u0026gt; physicalAssetRelationshipInstanceCreatedWldtEvent) { } @Override protected void onPhysicalAssetRelationshipDeleted(PhysicalAssetRelationshipInstanceDeletedWldtEvent\u0026lt;?\u0026gt; physicalAssetRelationshipInstanceDeletedWldtEvent) { } //// Digital Action Received Callbacks //// @Override protected void onDigitalActionEvent(DigitalActionWldtEvent\u0026lt;?\u0026gt; digitalActionWldtEvent) { } } The methods onCreate(), onStart() and onStop() are used to receive callbacks from the DT\u0026rsquo;s core when the Shadowing Function has been effectively created within the twin, is started or stopped according to the evolution of its life cycle. In our initial implementation we are not implementing any of them but they can be useful to trigger specific behaviours according to the different phases.\nThe first method that we have to implement in order to analyze received PAD and build the Digital Twin State in terms of properties, events, relationships and available actions is the onDigitalTwinBound(Map\u0026lt;String, PhysicalAssetDescription\u0026gt; map) method. In our initial implementation we just pass through all the received characteristics recevied from each connected Physical Adapter mapping every physical entity into the DT\u0026rsquo;s state without any change or adaptation (Of course complex behaviour can be implemented to customized the digitalization process).\nThrough the following method we implement the following behaviour:\nAnalyze each received PAD from each connected and active Physical Adapter (in our case we will have just 1 Physical Adapter) Iterate over all the received Properties for each PAD and create the same Property on the Digital Twin State Start observing target Physical Properties in order to receive notification callback about physical variation through the method observePhysicalAssetProperty(property); Analyze received PAD\u0026rsquo;s Events declaration and recreates them also on the DT\u0026rsquo;s State Start observing target Physical Event in order to receive notification callback about physical event generation through the method observePhysicalAssetEvent(event); Check available Physical Action and enable them on the DT\u0026rsquo;s State. Enabled Digital Action are automatically observed by the Shadowing Function in order to receive action requests from active Digital Adapters The possibility to manually observe Physical Properties and Event has been introduced to allow the Shadowing Function to decide what to do according to the nature of the property or of the target event. For example in some cases with static properties it will not be necessary to observe any variation, and it will be enough to read the initial value to build the digital replica of that specific property.\nSince the DT State is managed through the DigitalTwinStateManager class all the changes and variation should be applied on the DT ShadowingFunction using the previously presented transaction management and the correct call of methods startStateTransaction() and commitStateTransaction().\n@Override protected void onDigitalTwinBound(Map\u0026lt;String, PhysicalAssetDescription\u0026gt; adaptersPhysicalAssetDescriptionMap) { try{ // NEW from 0.3.0 -\u0026gt; Start DT State Change Transaction this.digitalTwinStateManager.startStateTransaction(); //Iterate over all the received PAD from connected Physical Adapters adaptersPhysicalAssetDescriptionMap.values().forEach(pad -\u0026gt; { //Iterate over all the received PAD from connected Physical Adapters adaptersPhysicalAssetDescriptionMap.values().forEach(pad -\u0026gt; { pad.getProperties().forEach(property -\u0026gt; { try { //Create and write the property on the DT\u0026#39;s State this.digitalTwinState.createProperty(new DigitalTwinStateProperty\u0026lt;\u0026gt;(property.getKey(),(Double) property.getInitialValue())); //Start observing the variation of the physical property in order to receive notifications //Without this call the Shadowing Function will not receive any notifications or callback about //incoming physical property of the target type and with the target key this.observePhysicalAssetProperty(property); } catch (Exception e) { e.printStackTrace(); } }); //Iterate over available declared Physical Events for the target Physical Adapter\u0026#39;s PAD pad.getEvents().forEach(event -\u0026gt; { try { //Instantiate a new DT State Event with the same key and type DigitalTwinStateEvent dtStateEvent = new DigitalTwinStateEvent(event.getKey(), event.getType()); //Create and write the event on the DT\u0026#39;s State this.digitalTwinState.registerEvent(dtStateEvent); //Start observing the variation of the physical event in order to receive notifications //Without this call the Shadowing Function will not receive any notifications or callback about //incoming physical events of the target type and with the target key this.observePhysicalAssetEvent(event); } catch (Exception e) { e.printStackTrace(); } }); //Iterate over available declared Physical Actions for the target Physical Adapter\u0026#39;s PAD pad.getActions().forEach(action -\u0026gt; { try { //Instantiate a new DT State Action with the same key and type DigitalTwinStateAction dtStateAction = new DigitalTwinStateAction(action.getKey(), action.getType(), action.getContentType()); //Enable the action on the DT\u0026#39;s State this.digitalTwinState.enableAction(dtStateAction); } catch (Exception e) { e.printStackTrace(); } }); }); // NEW from 0.3.0 -\u0026gt; Commit DT State Change Transaction to apply the changes on the DT State and notify about the change this.digitalTwinStateManager.commitStateTransaction(); //Start observation to receive all incoming Digital Action through active Digital Adapter //Without this call the Shadowing Function will not receive any notifications or callback about //incoming request to execute an exposed DT\u0026#39;s Action observeDigitalActionEvents(); //Notify the DT Core that the Bounding phase has been correctly completed and the DT has evaluated its //internal status according to what is available and declared through the Physical Adapters notifyShadowingSync(); }catch (Exception e){ e.printStackTrace(); } } In particular the method observeDigitalActionEvents() should be called start the observation of digital actions and to receive all incoming Digital Action through active Digital Adapters. Without this call the Shadowing Function will not receive any notifications or callback about incoming request to execute an exposed DT\u0026rsquo;s Action. Of course, we have to call this method if we are mapping any digital action in our DT.\nAnother fundamental method is notifyShadowingSync() used to notify the DT Core that the Bounding phase has been correctly completed and the DT has evaluated its internal status according to what is available and declared through the Physical Adapters.\nAs mentioned, in the previous example the Shadowing Function does not apply any control or check on the nature of declared physical property. Of course in order to have a more granular control, it will be possible to use property Key or any other field or even the type of the instance through an instanceof check to implement different controls and behaviours.\nA variation (only for the property management code) to the previous method can be the following:\n//Iterate over available declared Physical Property for the target Physical Adapter\u0026#39;s PAD pad.getProperties().forEach(property -\u0026gt; { try { //Check property Key and Instance of to validate that is a Double if(property.getKey().equals(\u0026#34;temperature-property-key\u0026#34;) \u0026amp;\u0026amp; property.getInitialValue() != null \u0026amp;\u0026amp; property.getInitialValue() instanceof Double) { //Instantiate a new DT State Property of the right type, the same key and initial value DigitalTwinStateProperty\u0026lt;Double\u0026gt; dtStateProperty = new DigitalTwinStateProperty\u0026lt;Double\u0026gt;(property.getKey(),(Double) property.getInitialValue()); //Create and write the property on the DT\u0026#39;s State this.digitalTwinState.createProperty(dtStateProperty); //Start observing the variation of the physical property in order to receive notifications //Without this call the Shadowing Function will not receive any notifications or callback about //incoming physical property of the target type and with the target key this.observePhysicalAssetProperty(property); } } catch (Exception e) { e.printStackTrace(); } }); The next method that we have to implement in order to properly define and implement the behaviour of our DT through its ShadowingModelFunction are:\nonPhysicalAssetPropertyVariation: Method called when a new variation for a specific Physical Property has been detected by the associated Physical Adapter. The method receive as parameter a specific WLDT Event called PhysicalAssetPropertyWldtEvent\u0026lt;?\u0026gt; physicalPropertyEventMessage containing all the information generated by the Physical Adapter upon the variation of the monitored physical counterpart. onPhysicalAssetEventNotification: Callback method used to be notified by a PhysicalAdapter about the generation of a Physical Event. As for the previous method, also this function receive a WLDT Event parameter of type onPhysicalAssetEventNotification(PhysicalAssetEventWldtEvent\u0026lt;?\u0026gt; physicalAssetEventWldtEvent)) containing all the field of the generated physical event. onDigitalActionEvent: On the opposite this method is triggered from one of the active Digital Adapter when an Action request has been received on the Digital Interface. The method receive as parameter an instance of the WLDT Event class DigitalActionWldtEvent\u0026lt;?\u0026gt; digitalActionWldtEvent describing the target digital action request and the associated body. For the onPhysicalAssetPropertyVariation a simple implementation in charge ONLY of mapping the new Physical Property value into the corresponding DT\u0026rsquo;State property can be implemented as follows:\nThe DT State transaction management should be applied in the point of the code where the Shadowing Function receive a variation from the Physical world through a target adapter and the callback method onPhysicalAssetPropertyVariation(...)\n@Override protected void onPhysicalAssetPropertyVariation(PhysicalAssetPropertyWldtEvent\u0026lt;?\u0026gt; physicalPropertyEventMessage) { try { //Update Digital Twin State //NEW from 0.3.0 -\u0026gt; Start State Transaction this.digitalTwinStateManager.startStateTransaction(); this.digitalTwinState.updateProperty(new DigitalTwinStateProperty\u0026lt;\u0026gt;(physicalPropertyEventMessage.getPhysicalPropertyId(), physicalPropertyEventMessage.getBody())); //NEW from 0.3.0 -\u0026gt; Commit State Transaction this.digitalTwinStateManager.commitStateTransaction(); } catch (WldtDigitalTwinStatePropertyException | WldtDigitalTwinStatePropertyBadRequestException | WldtDigitalTwinStatePropertyNotFoundException | WldtDigitalTwinStateException e) { e.printStackTrace(); } } In this case as reported in the code, we call the method this.digitalTwinState.updateProperty on the Shadowing Function in order to update an existing DT\u0026rsquo;State property (previously created in the onDigitalTwinBound method). To update the value we directly use the received data on the PhysicalAssetPropertyWldtEvent without any additional check or change that might be instead needed in advanced examples.\nFollowing the same principle, a simplified digital mapping between physical and digital state upon the receving of a physical event variation can be the following:\n@Override protected void onPhysicalAssetEventNotification(PhysicalAssetEventWldtEvent\u0026lt;?\u0026gt; physicalAssetEventWldtEvent) { try { this.digitalTwinStateManager.notifyDigitalTwinStateEvent(new DigitalTwinStateEventNotification\u0026lt;\u0026gt;(physicalAssetEventWldtEvent.getPhysicalEventKey(), physicalAssetEventWldtEvent.getBody(), physicalAssetEventWldtEvent.getCreationTimestamp())); } catch (WldtDigitalTwinStateEventNotificationException | EventBusException e) { e.printStackTrace(); } } With respect to events management, we use the Shadowint Function method this.digitalTwinState.notifyDigitalTwinStateEvent to notify the other DT Components (e.g., Digital Adapters) the incoming Physical Event by creating a new instance of a DigitalTwinStateEventNotification class containing all the information associated to the event. Of course, additional controls and checks can be introduced in this method validating and processing the incoming physical message to define complex behaviours.\nThe last method that we are going to implement is the onDigitalActionEvent one where we have to handle an incoming Digital Action request associated to an Action declared on the DT\u0026rsquo;s State in the onDigitalTwinBound method. In that case the Digital Action should be forwarded to the Physical Interface in order to be sent to the physical counterpart for the effective execution.\n@Override protected void onDigitalActionEvent(DigitalActionWldtEvent\u0026lt;?\u0026gt; digitalActionWldtEvent) { try { this.publishPhysicalAssetActionWldtEvent(digitalActionWldtEvent.getActionKey(), digitalActionWldtEvent.getBody()); } catch (EventBusException e) { e.printStackTrace(); } } Also in that case we are forwarding the incoming Digital Action request described through the class DigitalActionWldtEvent to the Physical Adapter with the method of the Shadowing Function denoted as this.publishPhysicalAssetActionWldtEvent and passing directly the action key and the target Body. No additional processing or validation have been introduced here, but they might be required in advanced scenario in order to properly adapt incoming digital action request to what is effectively expected on the physical counterpart.\n","date":"February 9, 2024","id":6,"permalink":"/docs/guides/shadowing-function/","summary":"After the definition of the Physical Adapter it is time to start implementing the core of our DT through the definition of its shadowing function in charge of:","tags":"","title":"Shadowing Function"},{"content":"The las component that we have to implement to complete our first simple Digital Twin definition through the WLDT library is a Digital Adapter in charge of:\nReceiving event from the DT\u0026rsquo;s Core related to the variation of properties, events, available actions and relationships Expose received information to the external world according to its implementation and the supported protocol Handle incoming digital action and forward them to the Core in order to be validated and processed by the Shadowing Function The basic library class that we are going to extend is called DigitalAdapter and creating a new class named DemoDigitalAdapter. The DigitalTwinAdapter class can take as Generic Type the type of Configuration used to configure its behaviours. In this simplified example we are defining a DigitalAdapter without any Configuration.\nA Digital Adapter has direct access to the current DT\u0026rsquo;s State through callbacks or directly in a synchronous way using the internal variable called: digitalTwinState. Through it is possibile to navigate all the fields currently composing the state of our Digital Twin.\nThe Digital Adapter class has e long list of callback and notification method to allow the adapter to be updated about all the variation and changes on the twin. Available callbacks can be summarized as follows:\nDigital Adapter Start/Stop: onAdapterStart(): Feedback when the Digital Adapter correctly starts onAdapterStop(): Feedback when the Digital Adapter has been stopped Digital Twin Life Cycle Notifications: onDigitalTwinCreate(): The DT has been created onDigitalTwinStart(): The DT started onDigitalTwinSync(IDigitalTwinState digitalTwinState): The DT is Synchronized with its physical counterpart. The current DigitalTwinState is passed as parameter to allow the Digital Adapter to know the current state and consequently implement its behaviour onDigitalTwinUnSync(IDigitalTwinState digitalTwinState): The DT is not synchronized anymore with its physical counterpart. The last current DigitalTwinState is passed as parameter to allow the Digital Adapter to know the last state and consequently implement its behaviour onDigitalTwinStop(): The DT is stopped onDigitalTwinDestroy(): The DT has been destroyed and the application stopped The Digital Adapter DT State variations and DT events are received by the Adapter from the DT core belongs to the following categories:\nDigital Twin State Update through the method onStateUpdate(...) providing information about the new state of the Digital Twin, the previous state, and a list of changes that occurred between these two states. In the previous version each variation of a property, relationships, actions or events were notified. In the new version only a committed DT\u0026rsquo;State variation is notified to listeners. Event Notifications through the method onEventNotificationReceived(...) whenever there is a notification about an event related to the Digital Twin\u0026rsquo;s state coming from the physical world, generated by the twin and processed by the Shadowing Function. For example in the DT State we can have the declaration of the over-heating-alert structured and received in the DT State while the effective occurrence of the event and the associated notification is notified through this dedicated callback The onStateUpdate method is an abstract method that must be implemented by any class extending the DigitalAdapter class. This method is called whenever there is an update to the Digital Twin\u0026rsquo;s state. It provides information about the new state of the Digital Twin, the previous state, and a list of changes that occurred between these two states.\nThe explanation of the parameters is the following:\nnewDigitalTwinState: This parameter represents the updated state of the Digital Twin. It is an instance of the DigitalTwinState class, which encapsulates the current state information. previousDigitalTwinState: This parameter represents the state of the Digital Twin before the update. It is also an instance of the DigitalTwinState class. digitalTwinStateChangeList: This parameter is an ArrayList containing DigitalTwinStateChange objects. Each DigitalTwinStateChange object encapsulates information about a specific change that occurred between the previous and new states. It includes details such as the property or aspect of the state that changed, the previous value, and the new value. Another core method where a Digital Adapter receive the description of the DT\u0026rsquo;State is onDigitalTwinSync(IDigitalTwinState digitalTwinState). The Adapter using the parameter digitalTwinState can analyze available properties, actions, events and relationships and decide how to implement its internal behaviour with the methods presented in ShadowingFunction. The DT State is automatically monitored by each Digital Adapter while for the Events potentially generated by the DT can be observed by each adapter using:\nobserveAllDigitalTwinEventsNotifications: Enable the observation of available Digital Twin State Events Notifications. unObserveAllDigitalTwinEventsNotifications: Cancel the observation of Digital Twin State Events Notifications observeDigitalTwinEventsNotifications: Enable the observation of the notification associated to a specific list of Digital Twin State events. With respect to event a notification contains the new associated value unObserveDigitalTwinEventsNotifications: Cancel the observation of a target list of properties observeDigitalTwinEventNotification: Enable the observation of the notification associated to a single Digital Twin State event. With respect to event a notification contains the new associated value unObserveDigitalTwinEventNotification: Cancel the observation of a single target event The resulting code will be the following after adding the required methods (still empty) and the basic constructor with the id String parameter is the following:\nimport it.wldt.adapter.digital.DigitalAdapter; import it.wldt.core.state.*; public class DemoDigitalAdapter extends DigitalAdapter\u0026lt;Void\u0026gt; { public DemoDigitalAdapter(String id) { super(id); } /** * Callback to notify the adapter on its correct startup */ @Override public void onAdapterStart() {} /** * Callback to notify the adapter that has been stopped */ @Override public void onAdapterStop() {} /** * DT Life Cycle notification that the DT is correctly on Sync * @param digitalTwinState */ @Override public void onDigitalTwinSync(DigitalTwinState digitalTwinState) {} /** * DT Life Cycle notification that the DT is currently Not Sync * @param digitalTwinState */ @Override public void onDigitalTwinUnSync(DigitalTwinState digitalTwinState) {} /** * DT Life Cycle notification that the DT has been created */ @Override public void onDigitalTwinCreate() {} /** * DT Life Cycle Notification that the DT has correctly Started */ @Override public void onDigitalTwinStart() {} /** * DT Life Cycle Notification that the DT has been stopped */ @Override public void onDigitalTwinStop() {} /** * DT Life Cycle Notification that the DT has destroyed */ @Override public void onDigitalTwinDestroy() {} /** * Callback method allowing the Digital Adapter to receive the updated Digital Twin State together with * the previous state and the list of applied changes * * @param newDigitalTwinState The new Digital Twin State computed by the Shadowing Function * @param previousDigitalTwinState The previous Digital Twin State * @param digitalTwinStateChangeList The list of applied changes to compute the new Digital Twin State */ @Override protected void onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList\u0026lt;DigitalTwinStateChange\u0026gt; digitalTwinStateChangeList) {} /** * Callback method to receive a new computed Event Notification (associated to event declared in the DT State) * * @param digitalTwinStateEventNotification The generated Notification associated to a DT Event */ @Override protected void onEventNotificationReceived(DigitalTwinStateEventNotification\u0026lt;?\u0026gt; digitalTwinStateEventNotification) {} } By default, a Digital Adapter observes all the variation on the DT\u0026rsquo;s State in terms of Properties, Relationships, Actions and Events. As previously mentioned the observation of DT\u0026rsquo;s State Properties allows to receive also properties variation on the method since a property is natively composed by its description (e.g., type) and its current value. On the opposite the observation on DT\u0026rsquo;s State Action, Relationships and Events allow ONLY to receive callbacks when a new entity is added or an update is occurred without receiving updates on values variation.\nThe only thing that we should add in the onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) callback is the direct observation for Events. Following this approach we can change our Digital Adapter in the following methods:\nIn onDigitalTwinSync we observe in this first simple implementation only the incoming values for declared Events in the DT\u0026rsquo;State. As previously mentioned the observation of any variation of the State structure together with Properties Values are by default observed by any Digital Adapter. In this method we use the internal variable digitalTwinState to access the DT\u0026rsquo;s state and find available Events declaration that we would like to observe.\npublic void onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) { try { //Retrieve the list of available events and observe all variations digitalTwinState.getEventList() .map(eventList -\u0026gt; eventList.stream() .map(DigitalTwinStateEvent::getKey) .collect(Collectors.toList())) .ifPresent(eventKeys -\u0026gt; { try { observeDigitalTwinEventsNotifications(eventKeys); } catch (EventBusException e) { e.printStackTrace(); } }); } catch (Exception e) { e.printStackTrace(); } } Developers extending the DigitalAdapter class should implement the onStateUpdate method to define custom logic that needs to be executed whenever the state of the Digital Twin is updated. This could include tasks such as processing state changes, updating internal variables, triggering specific actions, or notifying other components about the state update.\nHere\u0026rsquo;s an example of how the method might be implemented in a concrete subclass of DigitalAdapter:\n@Override protected void onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList\u0026lt;DigitalTwinStateChange\u0026gt; digitalTwinStateChangeList) { // In newDigitalTwinState we have the new DT State System.out.println(\u0026#34;New DT State is: \u0026#34; + newDigitalTwinState); // The previous DT State is available through the variable previousDigitalTwinState System.out.println(\u0026#34;Previous DT State is: \u0026#34; + previousDigitalTwinState); // We can also check each DT\u0026#39;s state change potentially differentiating the behaviour for each change if (digitalTwinStateChangeList != null \u0026amp;\u0026amp; !digitalTwinStateChangeList.isEmpty()) { // Iterate through each state change in the list for (DigitalTwinStateChange stateChange : digitalTwinStateChangeList) { // Get information from the state change DigitalTwinStateChange.Operation operation = stateChange.getOperation(); DigitalTwinStateChange.ResourceType resourceType = stateChange.getResourceType(); DigitalTwinStateResource resource = stateChange.getResource(); // Perform different actions based on the type of operation switch (operation) { case OPERATION_UPDATE: // Handle an update operation System.out.println(\u0026#34;Update operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; case OPERATION_UPDATE_VALUE: // Handle an update value operation System.out.println(\u0026#34;Update value operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; case OPERATION_ADD: // Handle an add operation System.out.println(\u0026#34;Add operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; case OPERATION_REMOVE: // Handle a remove operation System.out.println(\u0026#34;Remove operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; default: // Handle unknown operation (optional) System.out.println(\u0026#34;Unknown operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; } } } else { // No state changes System.out.println(\u0026#34;No state changes detected.\u0026#34;); } } In this example, the method iterates over the list of state changes, extracts information about each change, and performs custom actions based on the changes. Developers can adapt this method to suit the specific requirements of their Digital Twin application.\nBoth Physical Adapters and Digital Adapters can be defined natively with a custom configuration provided by the developer as illustrated in the dedicated Section: Configurable Physical \u0026amp; Digital Adapters.\n","date":"February 9, 2024","id":7,"permalink":"/docs/guides/digital-adapter/","summary":"The las component that we have to implement to complete our first simple Digital Twin definition through the WLDT library is a Digital Adapter in charge of:","tags":"","title":"Digital Adapter"},{"content":"Now that we have created the main fundamental element of a DT (Physical Adapter, Shadowing Function and Digital Adapter) we can create Class file with a main to create the WLDT Engine with the created components and start the DT.\nCreate a new Java file called DemoDigitalTwin adding the following code:\nWith the following code we now create a new Digital Twin Instance\n// Create the new Digital Twin with its Shadowing Function DigitalTwin digitalTwin = new DigitalTwin(digitalTwinId, new DemoShadowingFunction()); // Physical Adapter with Configuration digitalTwin.addPhysicalAdapter( new DemoPhysicalAdapter( String.format(\u0026#34;%s-%s\u0026#34;, digitalTwinId, \u0026#34;test-physical-adapter\u0026#34;), new DemoPhysicalAdapterConfiguration(), true)); // Digital Adapter with Configuration digitalTwin.addDigitalAdapter( new DemoDigitalAdapter( String.format(\u0026#34;%s-%s\u0026#34;, digitalTwinId, \u0026#34;test-digital-adapter\u0026#34;), new DemoDigitalAdapterConfiguration()) ); DTs cannot be directly run but it should be added to the DigitalTwinEngine in order to be executed through the WLDT Library\n// Create the Digital Twin Engine DigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine(); // Add the Digital Twin to the Engine digitalTwinEngine.addDigitalTwin(digitalTwin); In order to start a DT from the Engine you can:\n// Directly start when you add it passing a second boolean value = true digitalTwinEngine.addDigitalTwin(digitalTwin. true); // Starting the single DT on the engine through its id digitalTwinEngine.startDigitalTwin(DIGITAL_TWIN_ID); // Start all the DTs registered on the engine digitalTwinEngine.startAll(); To stop a single twin or all the twin registered on the engine:\n// Stop a single DT on the engine through its id digitalTwinEngine.stopDigitalTwin(DIGITAL_TWIN_ID); // Stop all the DTs registered on the engine digitalTwinEngine.stopAll(); It is also possible to remove a DT from the Engine with a consequent stop if it is active and the deletion of its reference from the engine:\n// Remove a single DT on the engine through its id digitalTwinEngine.removeDigitalTwin(DIGITAL_TWIN_ID); // Remove all the DTs registered on the engine digitalTwinEngine.removeAll(); The resulting code in our case is:\npublic class DemoDigitalTwin { public static void main(String[] args) { try{ // Create the new Digital Twin DigitalTwin digitalTwin = new DigitalTwin( \u0026#34;test-dt-id\u0026#34;, new DemoShadowingFunction(\u0026#34;test-shadowing-function\u0026#34;) ); //Default Physical and Digital Adapter //digitalTwin.addPhysicalAdapter(new DemoPhysicalAdapter(\u0026#34;test-physical-adapter\u0026#34;)); //digitalTwin.addDigitalAdapter(new DemoDigitalAdapter(\u0026#34;test-digital-adapter\u0026#34;)); //Physical and Digital Adapters with Configuration digitalTwin.addPhysicalAdapter(new DemoConfPhysicalAdapter(\u0026#34;test-physical-adapter\u0026#34;, new DemoPhysicalAdapterConfiguration())); digitalTwin.addDigitalAdapter(new DemoConfDigitalAdapter(\u0026#34;test-digital-adapter\u0026#34;, new DemoDigitalAdapterConfiguration())); // Create the Digital Twin Engine DigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine(); // Add the Digital Twin to the Engine digitalTwinEngine.addDigitalTwin(digitalTwin); // Set a new Event-Logger to a Custom One that we created with the class \u0026#39;DemoEventLogger\u0026#39; WldtEventBus.getInstance().setEventLogger(new DemoEventLogger()); // Start all the DTs registered on the engine digitalTwinEngine.startAll(); }catch (Exception e){ e.printStackTrace(); } } } ","date":"February 9, 2024","id":8,"permalink":"/docs/guides/dt-engine-dt-instance/","summary":"Now that we have created the main fundamental element of a DT (Physical Adapter, Shadowing Function and Digital Adapter) we can create Class file with a main to create the WLDT Engine with the created components and start the DT.","tags":"","title":"DT Engine \u0026 DT Instance"},{"content":"In this demo implementation, we are going to emulate an incoming Digital Action on the Digital Adapter in order to show how it can be handled by the adapter and properly forwarded to the Shadowing Function for validation and the consequent interaction with the Physical Adapter and then with the physical twin.\nIn order to add a demo Digital Action trigger on the Digital Adapter we add the following method to the DemoDigitalAdapter class:\nprivate Runnable emulateIncomingDigitalAction(){ return () -\u0026gt; { try { System.out.println(\u0026#34;Sleeping before Emulating Incoming Digital Action ...\u0026#34;); Thread.sleep(5000); Random random = new Random(); //Emulate the generation on \u0026#39;n\u0026#39; temperature measurements for(int i = 0; i \u0026lt; 10; i++){ //Sleep to emulate sensor measurement Thread.sleep(1000); double randomTemperature = 25.0 + (30.0 - 25.0) * random.nextDouble(); publishDigitalActionWldtEvent(\u0026#34;set-temperature-action-key\u0026#34;, randomTemperature); } } catch (Exception e) { e.printStackTrace(); } }; } This method uses the Digital Adapter internal function denoted as publishDigitalActionWldtEvent(String actionKey, T body) allowing the adapter to send a notification to the DT\u0026rsquo;s Core (and consequently the Shadowing Function) about the arrival of a Digital Action with a specific key and body. In our case the key is set-temperature-action-key as declared in the Physical Adapter and in the PAD and the value is a simple Double with the new temperature value.\nThen we call this method in the following way at the end ot the onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) method.\n//Start Digital Action Emulation new Thread(emulateIncomingDigitalAction()).start(); Now the Shadowing Function should be updated in order to handle the incoming Action request from the Digital Adapter. In our case the shadowing function does not apply any validation or check and just forward to action to the Physical Adapter in order to be then forwarded to the physical twin. Of course advanced implementation can be introduced for example to validate action, adapt payload and data-formats or to augment functionalities (e.g., trigger multiple physical actions from a single digital request).\nIn our simple demo implementation the updated Shadowing Function method onDigitalActionEvent(DigitalActionWldtEvent\u0026lt;?\u0026gt; digitalActionWldtEvent) results as follows:\n@Override protected void onDigitalActionEvent(DigitalActionWldtEvent\u0026lt;?\u0026gt; digitalActionWldtEvent) { try { this.publishPhysicalAssetActionWldtEvent(digitalActionWldtEvent.getActionKey(), digitalActionWldtEvent.getBody()); } catch (Exception e) { e.printStackTrace(); } } This forwarding of the action triggers the corresponding Physical Adapter method onIncomingPhysicalAction(PhysicalAssetActionWldtEvent\u0026lt;?\u0026gt; physicalAssetActionWldtEvent) that in our case is emulated just with a Log on the console. Also in that case advanced Physical Adapter implementation can be introduced for example to adapt the request from a high-level (and potentially standard) DT action description to the custom requirements of the specific physical twin managed by the adapter.\n@Override public void onIncomingPhysicalAction(PhysicalAssetActionWldtEvent\u0026lt;?\u0026gt; physicalAssetActionWldtEvent) { try{ if(physicalAssetActionWldtEvent != null \u0026amp;\u0026amp; physicalAssetActionWldtEvent.getActionKey().equals(SET_TEMPERATURE_ACTION_KEY) \u0026amp;\u0026amp; physicalAssetActionWldtEvent.getBody() instanceof Double) { System.out.println(\u0026#34;Received Action Request: \u0026#34; + physicalAssetActionWldtEvent.getActionKey() + \u0026#34; with Body: \u0026#34; + physicalAssetActionWldtEvent.getBody()); } else System.err.println(\u0026#34;Wrong Action Received !\u0026#34;); }catch (Exception e){ e.printStackTrace(); } } ","date":"February 9, 2024","id":9,"permalink":"/docs/guides/digital-actions/","summary":"In this demo implementation, we are going to emulate an incoming Digital Action on the Digital Adapter in order to show how it can be handled by the adapter and properly forwarded to the Shadowing Function for validation and the consequent interaction with the Physical Adapter and then with the physical twin.","tags":"","title":"Digital Actions"},{"content":"The same management that we have illustrated for Properties, Events and Action can be applied also to Digital Twin Relationships. Relationships represent the links that exist between the modeled physical assets and other physical entity of the organizations through links to their corresponding Digital Twins. Like properties, relationships can be observed, dynamically created, and change over time, but unlike properties, they are not properly part of the PA\u0026rsquo;s state but of its operational context (e.g., a DT of a robot within a production line).\nIt is necessary to distinguish between two concepts: i) Relationship; and ii) Relationship Instance. The first one models the relationship from a semantic point of view, defining its name and target type. The second one represents an instantiation of the concept in reality. For example, in the context of a Smart Home, the Home Digital Twin (DT) will define a Relationship called has_room which has possible targets represented by DTs that represent different rooms of the house. The actual link between the Home DT and the Bedroom DT will be modeled by a specific Relationship Instance of the has_room relationship.\nWithin the state of the DT, it is necessary to differentiate between the concept of a relationship and that of an instance of a relationship. In the first case, we refer to a semantic concept where each relationship, through its name and the semantic type of its target, determines the different type of link that the DT can establish. On the other hand, an instanc of a relationship represents the concrete link present between the DT that establishes it and the target DT. For instance, in the case of a Smart Home, the Bedroom DT may have two relationships in its model: one named is_room_of and another called has_device. An instance of the first type of relationship could, for example, have the Home DT as its target, while the has_device relationship could have multiple instances, one for each device present in the room. An example of a possible instance is one targeting the Air Conditioner DT.\nFrom an implementation perspective, in the Physical Adapter and in particular where we handle the definition of the PAD we can also specify the existing relationships. In our case, since the Relationship is useful also to define its future instance we keep a reference of the relationship as in internal variable called insideInRelationship.\nThen we can update the code as follows:\nprivate PhysicalAssetRelationship\u0026lt;String\u0026gt; insideInRelationship = null; @Override public void onIncomingPhysicalAction(PhysicalAssetActionWldtEvent\u0026lt;?\u0026gt; physicalAssetActionWldtEvent) { try{ [...] //Create Test Relationship to describe that the Physical Device is inside a building this.insideInRelationship=new PhysicalAssetRelationship\u0026lt;\u0026gt;(\u0026#34;insideId\u0026#34;); pad.getRelationships().add(insideInRelationship); [...] } catch (Exception e){ e.printStackTrace(); } } Of course always in the Physical Adapter we need to publish an effective instance of the definite Relationship. To do that, we have defined a dedicated method that we can call inside the adapter to notify the DT\u0026rsquo;s Core and in particular the Shadowing Function on the presence of a new Relationship.\nThe following method can be added for example at the beginning of the Device Emulation:\nprivate void publishPhysicalRelationshipInstance() { try{ String relationshipTarget = \u0026#34;building-hq\u0026#34;; Map\u0026lt;String, Object\u0026gt; relationshipMetadata = new HashMap\u0026lt;\u0026gt;(); relationshipMetadata.put(\u0026#34;floor\u0026#34;, \u0026#34;f0\u0026#34;); relationshipMetadata.put(\u0026#34;room\u0026#34;, \u0026#34;r0\u0026#34;); PhysicalAssetRelationshipInstance\u0026lt;String\u0026gt; relInstance = this.insideInRelationship.createRelationshipInstance(relationshipTarget, relationshipMetadata); PhysicalAssetRelationshipInstanceCreatedWldtEvent\u0026lt;String\u0026gt; relInstanceEvent = new PhysicalAssetRelationshipInstanceCreatedWldtEvent\u0026lt;\u0026gt;(relInstance); publishPhysicalAssetRelationshipCreatedWldtEvent(relInstanceEvent); }catch (Exception e){ e.printStackTrace(); } } On the other hand, as already done for all the other Properties, Actions and Events we have to handle them on the Shadowing Function and in particular updating the onDigitalTwinBound(...) method managing Relationship declaration. Also for the Relationships there is the method denoted as observePhysicalAssetRelationship(relationship) to observe the variation of the target entity.\n@Override protected void onDigitalTwinBound(Map\u0026lt;String, PhysicalAssetDescription\u0026gt; adaptersPhysicalAssetDescriptionMap) { try{ //Iterate over all the received PAD from connected Physical Adapters adaptersPhysicalAssetDescriptionMap.values().forEach(pad -\u0026gt; { [...] //Iterate over Physical Relationships pad.getRelationships().forEach(relationship -\u0026gt; { try{ if(relationship != null \u0026amp;\u0026amp; relationship.getName().equals(GlobalKeywords.INSIDE_IN_RELATIONSHIP)){ DigitalTwinStateRelationship\u0026lt;String\u0026gt; insideInDtStateRelationship = new DigitalTwinStateRelationship\u0026lt;\u0026gt;(relationship.getName(), relationship.getName()); this.digitalTwinState.createRelationship(insideInDtStateRelationship); observePhysicalAssetRelationship(relationship); } }catch (Exception e){ e.printStackTrace(); } }); }); [...] }catch (Exception e){ e.printStackTrace(); } } When an Instance for a target observed Relationship has been notified by the Physical Adapter, we will receive a call back on the Shadowing Function method called: onPhysicalAssetRelationshipEstablished(PhysicalAssetRelationshipInstanceCreatedWldtEvent\u0026lt;?\u0026gt; physicalAssetRelationshipInstanceCreatedWldtEvent). The object PhysicalAssetRelationshipInstanceCreatedWldtEvent describes the events and contains an object PhysicalAssetRelationshipInstance with all the information about the new Relationship Instance.\nThe Shadowing Function analyzes the instance and create the corresponding Digital Relationship instance on the DT\u0026rsquo;State through the class DigitalTwinStateRelationshipInstance and the method this.digitalTwinState.addRelationshipInstance(relName, instance);. The resulting implemented method is the following:\n//// Physical Relationships Notification Callbacks //// @Override protected void onPhysicalAssetRelationshipEstablished(PhysicalAssetRelationshipInstanceCreatedWldtEvent\u0026lt;?\u0026gt; physicalAssetRelationshipInstanceCreatedWldtEvent) { try{ if(physicalAssetRelationshipInstanceCreatedWldtEvent != null \u0026amp;\u0026amp; physicalAssetRelationshipInstanceCreatedWldtEvent.getBody() != null){ PhysicalAssetRelationshipInstance\u0026lt;?\u0026gt; paRelInstance = physicalAssetRelationshipInstanceCreatedWldtEvent.getBody(); if(paRelInstance.getTargetId() instanceof String){ String relName = paRelInstance.getRelationship().getName(); String relKey = paRelInstance.getKey(); String relTargetId = (String)paRelInstance.getTargetId(); DigitalTwinStateRelationshipInstance\u0026lt;String\u0026gt; instance = new DigitalTwinStateRelationshipInstance\u0026lt;String\u0026gt;(relName, relTargetId, relKey); //Update Digital Twin State //NEW from 0.3.0 -\u0026gt; Start State Transaction this.digitalTwinStateManager.startStateTransaction(); this.digitalTwinStateManager.addRelationshipInstance(instance); //NEW from 0.3.0 -\u0026gt; Commit State Transaction this.digitalTwinStateManager.commitStateTransaction(); } } }catch (Exception e){ e.printStackTrace(); } } @Override protected void onPhysicalAssetRelationshipDeleted(PhysicalAssetRelationshipInstanceDeletedWldtEvent\u0026lt;?\u0026gt; physicalAssetRelationshipInstanceDeletedWldtEvent) { } At the end the new DT\u0026rsquo;s Relationships and the associated instances can be managed on a Digital Adapter using the onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) method and the following DT state callback method: onStateUpdate().\nFor example a simple implementation logging on the console can be:\n@Override protected void onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList\u0026lt;DigitalTwinStateChange\u0026gt; digitalTwinStateChangeList) { // In newDigitalTwinState we have the new DT State System.out.println(\u0026#34;New DT State is: \u0026#34; + newDigitalTwinState); // The previous DT State is available through the variable previousDigitalTwinState System.out.println(\u0026#34;Previous DT State is: \u0026#34; + previousDigitalTwinState); // We can also check each DT\u0026#39;s state change potentially differentiating the behaviour for each change if (digitalTwinStateChangeList != null \u0026amp;\u0026amp; !digitalTwinStateChangeList.isEmpty()) { // Iterate through each state change in the list [...] // Specific log example for Relationships Instance Variation if(resourceType.equals(DigitalTwinStateChange.ResourceType.RELATIONSHIP_INSTANCE)) System.out.println(\u0026#34;New Relationship Instance operation:\u0026#34; + operation + \u0026#34; Resource:\u0026#34; + resource); } } else { // No state changes System.out.println(\u0026#34;No state changes detected.\u0026#34;); } } ","date":"February 9, 2024","id":10,"permalink":"/docs/guides/dt-relationships/","summary":"The same management that we have illustrated for Properties, Events and Action can be applied also to Digital Twin Relationships. Relationships represent the links that exist between the modeled physical assets and other physical entity of the organizations through links to their corresponding Digital Twins.","tags":"","title":"DT Relationships"},{"content":"The WLDT library provides a native method to define Configurable Physical ad Digital Adapters specifying a custom configuration class passed as parameter in the constructor.\nStarting with the Physical Adapter created in the previous example DemoPhysicalAdapter instead of extending the base class PhysicalAdapter we can extend now ConfigurablePhysicalAdapter\u0026lt;C\u0026gt; where C is the name of the that we would like to use as configuration.\nIn our example we can create a simple configuration class called DemoPhysicalAdapterConfiguration where we move the constant variable used to implement the behaviour of our demo physical adapter. The resulting class will be the following:\npublic class DemoPhysicalAdapterConfiguration { private int messageUpdateTime = GlobalKeywords.MESSAGE_UPDATE_TIME; private int messageUpdateNumber = GlobalKeywords.MESSAGE_UPDATE_NUMBER; private double temperatureMinValue = GlobalKeywords.TEMPERATURE_MIN_VALUE; private double temperatureMaxValue = GlobalKeywords.TEMPERATURE_MAX_VALUE; public DemoPhysicalAdapterConfiguration() { } public DemoPhysicalAdapterConfiguration(int messageUpdateTime, int messageUpdateNumber, double temperatureMinValue, double temperatureMaxValue) { this.messageUpdateTime = messageUpdateTime; this.messageUpdateNumber = messageUpdateNumber; this.temperatureMinValue = temperatureMinValue; this.temperatureMaxValue = temperatureMaxValue; } public int getMessageUpdateTime() { return messageUpdateTime; } public void setMessageUpdateTime(int messageUpdateTime) { this.messageUpdateTime = messageUpdateTime; } public int getMessageUpdateNumber() { return messageUpdateNumber; } public void setMessageUpdateNumber(int messageUpdateNumber) { this.messageUpdateNumber = messageUpdateNumber; } public double getTemperatureMinValue() { return temperatureMinValue; } public void setTemperatureMinValue(double temperatureMinValue) { this.temperatureMinValue = temperatureMinValue; } public double getTemperatureMaxValue() { return temperatureMaxValue; } public void setTemperatureMaxValue(double temperatureMaxValue) { this.temperatureMaxValue = temperatureMaxValue; } } Now we can create or update our Physical Adapter extending ConfigurablePhysicalAdapter\u0026lt;DemoPhysicalAdapterConfiguration\u0026gt; as illustrated in the following snippet:\npublic class DemoPhysicalAdapter extends ConfigurablePhysicalAdapter\u0026lt;DemoPhysicalAdapterConfiguration\u0026gt; { [...] } Extending this class also the constructor should be updated getting as a parameter the expected configuration instance. Our constructor will be the following:\npublic DemoConfPhysicalAdapter(String id, DemoPhysicalAdapterConfiguration configuration) { super(id, configuration); } After that change since we removed and moved the used constant values into the new Configuration class we have also to update the deviceEmulation() method having access to the configuration through the method getConfiguration() or this.getConfiguration() directly on the adapter.\nprivate Runnable deviceEmulation(){ return () -\u0026gt; { try { System.out.println(\u0026#34;[DemoPhysicalAdapter] -\u0026gt; Sleeping before Starting Physical Device Emulation ...\u0026#34;); //Sleep 5 seconds to emulate device startup Thread.sleep(10000); System.out.println(\u0026#34;[DemoPhysicalAdapter] -\u0026gt; Starting Physical Device Emulation ...\u0026#34;); //Create a new random object to emulate temperature variations Random r = new Random(); //Publish an initial Event for a normal condition publishPhysicalAssetEventWldtEvent(new PhysicalAssetEventWldtEvent\u0026lt;\u0026gt;(GlobalKeywords.OVERHEATING_EVENT_KEY, \u0026#34;normal\u0026#34;)); //Emulate the generation on \u0026#39;n\u0026#39; temperature measurements for(int i = 0; i \u0026lt; getConfiguration().getMessageUpdateNumber(); i++){ //Sleep to emulate sensor measurement Thread.sleep(getConfiguration().getMessageUpdateTime()); //Update the double randomTemperature = getConfiguration().getTemperatureMinValue() + (getConfiguration().getTemperatureMaxValue() - getConfiguration().getTemperatureMinValue()) * r.nextDouble(); //Create a new event to notify the variation of a Physical Property PhysicalAssetPropertyWldtEvent\u0026lt;Double\u0026gt; newPhysicalPropertyEvent = new PhysicalAssetPropertyWldtEvent\u0026lt;\u0026gt;(GlobalKeywords.TEMPERATURE_PROPERTY_KEY, randomTemperature); //Publish the WLDTEvent associated to the Physical Property Variation publishPhysicalAssetPropertyWldtEvent(newPhysicalPropertyEvent); } //Publish a demo Physical Event associated to a \u0026#39;critical\u0026#39; overheating condition publishPhysicalAssetEventWldtEvent(new PhysicalAssetEventWldtEvent\u0026lt;\u0026gt;(GlobalKeywords.OVERHEATING_EVENT_KEY, \u0026#34;critical\u0026#34;)); } catch (EventBusException | InterruptedException e) { e.printStackTrace(); } }; } A similar approach can be adopted also for the Digital Adapter with the small difference that the base class DigitalAdapter already allow the possibility to specify a configuration. For this reason in the previous example we extended DigitalAdapter\u0026lt;Void\u0026gt; avoiding to specifying a configuration.\nIn this updated version we can create a new DemoDigitalAdapterConfiguration class containing the parameter association to the emulation of the action and then update our adapter to support the new configuration. Our new configuration class will be:\npublic class DemoDigitalAdapterConfiguration { private int sleepTimeMs = GlobalKeywords.ACTION_SLEEP_TIME_MS; private int emulatedActionCount = GlobalKeywords.EMULATED_ACTION_COUNT; private double temperatureMinValue = GlobalKeywords.TEMPERATURE_MIN_VALUE; private double temperatureMaxValue = GlobalKeywords.TEMPERATURE_MAX_VALUE; public DemoDigitalAdapterConfiguration() { } public DemoDigitalAdapterConfiguration(int sleepTimeMs, int emulatedActionCount, double temperatureMinValue, double temperatureMaxValue) { this.sleepTimeMs = sleepTimeMs; this.emulatedActionCount = emulatedActionCount; this.temperatureMinValue = temperatureMinValue; this.temperatureMaxValue = temperatureMaxValue; } public int getSleepTimeMs() { return sleepTimeMs; } public void setSleepTimeMs(int sleepTimeMs) { this.sleepTimeMs = sleepTimeMs; } public int getEmulatedActionCount() { return emulatedActionCount; } public void setEmulatedActionCount(int emulatedActionCount) { this.emulatedActionCount = emulatedActionCount; } public double getTemperatureMinValue() { return temperatureMinValue; } public void setTemperatureMinValue(double temperatureMinValue) { this.temperatureMinValue = temperatureMinValue; } public double getTemperatureMaxValue() { return temperatureMaxValue; } public void setTemperatureMaxValue(double temperatureMaxValue) { this.temperatureMaxValue = temperatureMaxValue; } } After that we can update the declaration of our Digital Adapter and modify its constructor to accept the configuration. The resulting class will be:\npublic class DemoDigitalAdapter extends DigitalAdapter\u0026lt;DemoDigitalAdapterConfiguration\u0026gt; { public DemoDigitalAdapter(String id, DemoDigitalAdapterConfiguration configuration) { super(id, configuration); } [...] } Of course the possibility to have this configuration will allow us to improve the emulateIncomingDigitalAction method in the following way having access to the configuration through the method getConfiguration() or this.getConfiguration() directly on the adapter:\nprivate Runnable emulateIncomingDigitalAction(){ return () -\u0026gt; { try { System.out.println(\u0026#34;[DemoDigitalAdapter] -\u0026gt; Sleeping before Emulating Incoming Digital Action ...\u0026#34;); Thread.sleep(5000); Random random = new Random(); //Emulate the generation on \u0026#39;n\u0026#39; temperature measurements for(int i = 0; i \u0026lt; getConfiguration().getEmulatedActionCount(); i++){ //Sleep to emulate sensor measurement Thread.sleep(getConfiguration().getSleepTimeMs()); double randomTemperature = getConfiguration().getTemperatureMinValue() + (getConfiguration().getTemperatureMaxValue() - getConfiguration().getTemperatureMinValue()) * random.nextDouble(); publishDigitalActionWldtEvent(\u0026#34;set-temperature-action-key\u0026#34;, randomTemperature); } } catch (Exception e) { e.printStackTrace(); } }; } When we have updated both adapters making them configurable we can update our main function in the process that we have previouly device using the updated adapters and passing the configurations:\npublic class DemoDigitalTwin { public static void main(String[] args) { try{ WldtEngine digitalTwinEngine = new WldtEngine(new DemoShadowingFunction(\u0026#34;test-shadowing-function\u0026#34;), \u0026#34;test-digital-twin\u0026#34;); //Default Physical and Digital Adapter //digitalTwinEngine.addPhysicalAdapter(new DemoPhysicalAdapter(\u0026#34;test-physical-adapter\u0026#34;)); //digitalTwinEngine.addDigitalAdapter(new DemoDigitalAdapter(\u0026#34;test-digital-adapter\u0026#34;)); //Physical and Digital Adapters with Configuration digitalTwinEngine.addPhysicalAdapter(new DemoConfPhysicalAdapter(\u0026#34;test-physical-adapter\u0026#34;, new DemoPhysicalAdapterConfiguration())); digitalTwinEngine.addDigitalAdapter(new DemoConfDigitalAdapter(\u0026#34;test-digital-adapter\u0026#34;, new DemoDigitalAdapterConfiguration())); digitalTwinEngine.startLifeCycle(); }catch (Exception e){ e.printStackTrace(); } } } ","date":"February 9, 2024","id":11,"permalink":"/docs/guides/configurable-adapters/","summary":"The WLDT library provides a native method to define Configurable Physical ad Digital Adapters specifying a custom configuration class passed as parameter in the constructor.","tags":"","title":"Configurable Adapters"},{"content":"","date":"February 9, 2024","id":12,"permalink":"/docs/adapters/","summary":"","tags":"","title":"Adapters"},{"content":"The MqttPhysicalAdapter library provides a streamlined solution for efficiently managing physical assets through the MQTT protocol. It offers a range of features, including a versatile builder for effortless configuration of MQTT connections, dedicated classes for handling both incoming and outgoing topics, and a specialized adapter designed for seamless integration with diverse physical assets.\nKey Features:\nBuilder for MQTT Configuration: The library incorporates a flexible builder pattern, enabling users to effortlessly configure the essential parameters of the MQTT connection. This includes specifying the MQTT broker\u0026rsquo;s address, port, and other relevant details to establish a reliable and customizable communication link. Incoming and Outgoing Topic Handling: MqttPhysicalAdapter facilitates the handling of incoming and outgoing topics, crucial for communication between the physical assets and the MQTT broker. The library includes dedicated classes for defining and managing topics, allowing users to efficiently subscribe to incoming data and publish outgoing messages. Adapter for Physical Asset Integration: At the core of the library is a robust adapter designed specifically for integrating with various physical assets. This adapter streamlines the process of connecting and interacting with physical devices, ensuring a smooth and standardized approach to managing asset-related data. In the WLDT library, Physical Adapters has the responsibility to generate and publish the PhysicalAssetDescription (PAD) to describe the capabilities and the characteristics of our object allowing the Shadowing Function to decide how to digitalize its physical counterpart.\nIn the MqttPhysicalAdapter the generation of the PAD (Physical Asset Description) is automatically and internally executed by the adapter itself accordingly to the adapter configuration in terms of MQTT topics and their mapping with DT\u0026rsquo;s properties, events and actions.\nPrerequisites:\nExternal MQTT Broker: The MqttPhysicalAdapter library requires an external MQTT broker for optimal functionality. Users must have access to a reliable MQTT broker to which the adapter can subscribe. This external broker serves as the central communication hub, facilitating the exchange of messages between the adapter and the physical assets. A complete example is provided in the test folder with a complete DT Creation in the TestMain class together with MQTT IoT demo device and a test MQTT consumer.\nWLDT-Core Version Compatibility The correct mapping and compatibility between versions is reported in the following table\nmqtt-physical-adapter wldt-core 0.2.1 wldt-core 0.3.0 wldt-core 0.4.0 0.1.0 ✅ ❌ ❌ 0.1.1 ❌ ✅ ✅ Installation To use MqttPhysicalAdapter in your Java project, you can include it as a dependency using Maven or Gradle.\nMaven \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.github.wldt\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;mqtt-physical-adapter\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;0.1.1\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; Gradle implementation \u0026#39;io.github.wldt:mqtt-physical-adapter:0.1.1\u0026#39; Class Structure \u0026amp; Functionalities MqttPhysicalAdapterConfigurationBuilder \u0026amp; Main Methods The MqttPhysicalAdapterConfigurationBuilder is the class used to build the configuration used by the PhysicalAdater and described and implemented through the class MqttPhysicalAdapterConfiguration.\nIn order to create a configuration builder we can use the static method builder() on the MqttPhysicalAdapterConfiguration class:\nMqttPhysicalAdapterConfiguration.builder(); On the builder the available methods that can be used are:\naddPhysicalAssetPropertyAndTopic public \u0026lt;T\u0026gt; MqttPhysicalAdapterConfigurationBuilder addPhysicalAssetPropertyAndTopic(String propertyKey, T initialValue, String topic, Function\u0026lt;String, T\u0026gt; topicFunction) throws MqttPhysicalAdapterConfigurationException Adds a physical asset property and its corresponding MQTT topic to the configuration.\nType Parameter T: The type of the property. propertyKey: The key of the property. initialValue: The initial value of the property. topic: The MQTT topic associated with the property. topicFunction: A function to parse the MQTT topic payload into the property type. Returns: The updated MqttPhysicalAdapterConfigurationBuilder.\nThrows: MqttPhysicalAdapterConfigurationException - If there is a configuration error.\naddPhysicalAssetActionAndTopic public \u0026lt;T\u0026gt; MqttPhysicalAdapterConfigurationBuilder addPhysicalAssetActionAndTopic(String actionKey, String type, String contentType, String topic, Function\u0026lt;T, String\u0026gt; topicFunction) throws MqttPhysicalAdapterConfigurationException Adds a physical asset action and its corresponding MQTT topic to the configuration.\nType Parameter T: The type of the action payload. actionKey: The key of the action. type: The type of the action. contentType: The content type of the action. topic: The MQTT topic associated with the action. topicFunction: A function to convert the action payload into the MQTT topic payload. Returns: The updated MqttPhysicalAdapterConfigurationBuilder.\nThrows: MqttPhysicalAdapterConfigurationException - If there is a configuration error.\naddPhysicalAssetEventAndTopic public \u0026lt;T\u0026gt; MqttPhysicalAdapterConfigurationBuilder addPhysicalAssetEventAndTopic(String eventKey, String type, String topic, Function\u0026lt;String, T\u0026gt; topicFunction) throws MqttPhysicalAdapterConfigurationException Adds a physical asset event and its corresponding MQTT topic to the configuration.\nType Parameter T: The type of the event payload. eventKey: The key of the event. type: The type of the event. topic: The MQTT topic associated with the event. topicFunction: A function to parse the MQTT topic payload into the event payload type. Returns: The updated MqttPhysicalAdapterConfigurationBuilder.\nThrows: MqttPhysicalAdapterConfigurationException - If there is a configuration error.\naddIncomingTopic public MqttPhysicalAdapterConfigurationBuilder addIncomingTopic(DigitalTwinIncomingTopic topic, List\u0026lt;PhysicalAssetProperty\u0026lt;?\u0026gt;\u0026gt; properties, List\u0026lt;PhysicalAssetEvent\u0026gt; events) throws MqttPhysicalAdapterConfigurationException This method is used when multiple properties or events can be associated to a single MQTT topic on the physical device. It adds a DigitalTwinIncomingTopic describing the topic where the DT will receive the data along with its related lists of properties and events associated to that topic.\ntopic: The DigitalTwinIncomingTopic to be added. properties: The list of related physical asset properties. events: The list of related physical asset events. Returns: The updated MqttPhysicalAdapterConfigurationBuilder.\nThrows: MqttPhysicalAdapterConfigurationException - If there is a configuration error.\naddOutgoingTopic public MqttPhysicalAdapterConfigurationBuilder addOutgoingTopic(String actionKey, String type, String contentType, DigitalTwinOutgoingTopic topic) throws MqttPhysicalAdapterConfigurationException Adds a DigitalTwinOutgoingTopic to the configuration.\nactionKey: The key of the associated action. type: The type of the associated action. contentType: The content type of the associated action. topic: The DigitalTwinOutgoingTopic to be added. Returns: The updated MqttPhysicalAdapterConfigurationBuilder.\nThrows: MqttPhysicalAdapterConfigurationException - If there is a configuration error.\nAdditional Methods setConnectionTimeout(Integer connectionTimeout): Sets the connection timeout for the MQTT client. Returns the builder for method chaining. Throws MqttPhysicalAdapterConfigurationException if the provided timeout is invalid. setCleanSessionFlag(boolean cleanSession): Sets the clean session flag for the MQTT client. Returns the builder for method chaining. setAutomaticReconnectFlag(boolean automaticReconnect): Sets the automatic reconnect flag for the MQTT client. Returns the builder for method chaining. setMqttClientPersistence(MqttClientPersistence persistence): Sets the persistence for the MQTT client. Returns the builder for method chaining. Throws MqttPhysicalAdapterConfigurationException if the provided persistence is null. build(): Builds and returns the finalized MqttPhysicalAdapterConfiguration object. Throws MqttPhysicalAdapterConfigurationException if the configuration is incomplete or invalid. MqttPhysicalAdapter The MqttPhysicalAdapter class is the core component for interacting with physical assets. Instantiate it with a unique ID and the configuration. It extends the default WLDT Library PhysicalAdapter implementing all the functionalities to automatically interact with an MQTT physical device following the specifications and details provided in the MqttPhysicalAdapterConfiguration and built using MqttPhysicalAdapterConfigurationBuilder.\nAn example of its creation is:\nMqttPhysicalAdapter mqttPhysicalAdapter = new MqttPhysicalAdapter(\u0026#34;uniqueId\u0026#34;, configuration); Integrated Example This example demonstrates the integration of a MqttPhysicalAdapter within a Digital Twin setup, where multiple adapters (including a console adapter) are added to a Digital Twin, and the overall system is managed by a DigitalTwinEngine.\n// Create a Digital Twin with a default shadowing function DigitalTwin digitalTwin = new DigitalTwin(\u0026#34;mqtt-digital-twin\u0026#34;, new DefaultShadowingFunction()); // Create an instance of ConsoleDigitalAdapter ConsoleDigitalAdapter consoleDigitalAdapter = new ConsoleDigitalAdapter(); // Create an instance of MqttPhysicalAdapterConfiguration MqttPhysicalAdapterConfiguration config = MqttPhysicalAdapterConfiguration.builder(\u0026#34;127.0.0.1\u0026#34;, 1883) .addPhysicalAssetPropertyAndTopic(\u0026#34;intensity\u0026#34;, 0, \u0026#34;sensor/intensity\u0026#34;, Integer::parseInt) .addIncomingTopic(new DigitalTwinIncomingTopic(\u0026#34;sensor/state\u0026#34;, getSensorStateFunction()), createIncomingTopicRelatedPropertyList(), new ArrayList\u0026lt;\u0026gt;()) .addPhysicalAssetEventAndTopic(\u0026#34;overheating\u0026#34;, \u0026#34;text/plain\u0026#34;, \u0026#34;sensor/overheating\u0026#34;, Function.identity()) .addPhysicalAssetActionAndTopic(\u0026#34;switch-off\u0026#34;, \u0026#34;sensor.actuation\u0026#34;, \u0026#34;text/plain\u0026#34;, \u0026#34;sensor/actions/switch\u0026#34;, actionBody -\u0026gt; \u0026#34;switch\u0026#34; + actionBody) .build(); // Create an instance of the MQTT Physical Adapter using the defined configuration MqttPhysicalAdapter mqttPhysicalAdapter = new MqttPhysicalAdapter(\u0026#34;test-mqtt-pa\u0026#34;, config); // Add both Digital and Physical Adapters to the Digital Twin digitalTwin.addDigitalAdapter(consoleDigitalAdapter); digitalTwin.addPhysicalAdapter(mqttPhysicalAdapter); // Create the Digital Twin Engine DigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine(); // Add the Digital Twin to the Engine digitalTwinEngine.addDigitalTwin(digitalTwin); // Start all the Digital Twins registered on the engine digitalTwinEngine.startAll(); In this example the createIncomingTopicRelatedPropertyList() used to map properties and events associated to a single topic is the following:\nprivate static List\u0026lt;PhysicalAssetProperty\u0026lt;?\u0026gt;\u0026gt; createIncomingTopicRelatedPropertyList(){ List\u0026lt;PhysicalAssetProperty\u0026lt;?\u0026gt;\u0026gt; properties = new ArrayList\u0026lt;\u0026gt;(); properties.add(new PhysicalAssetProperty\u0026lt;\u0026gt;(\u0026#34;temperature\u0026#34;, 0)); properties.add(new PhysicalAssetProperty\u0026lt;\u0026gt;(\u0026#34;humidity\u0026#34;, 0)); return properties; } This information are used by the adapter to build the PAD describe the capabilities and the characteristics of our object allowing the Shadowing Function to decide how to digitalize its physical counterpart.\n","date":"February 9, 2024","id":13,"permalink":"/docs/adapters/mqtt-physical-adapter/","summary":"The MqttPhysicalAdapter library provides a streamlined solution for efficiently managing physical assets through the MQTT protocol. It offers a range of features, including a versatile builder for effortless configuration of MQTT connections, dedicated classes for handling both incoming and outgoing topics, and a specialized adapter designed for seamless integration with diverse physical assets.","tags":"","title":"MQTT Physical Adapter"},{"content":"","date":"February 9, 2024","id":14,"permalink":"/docs/change-logs/","summary":"","tags":"","title":"Change Logs"},{"content":"The MqttDigitalAdapter,\nMqttDigitalAdapterConfiguration, and MqttDigitalAdapterConfigurationBuilder classes and guides you through using these classes to set up an MQTT Digital Adapter within WLDT.\nRequires an external MQTT broker to send messages.\nMain functionalities are:\nManages the interaction between the Digital Twin and external systems. Handles state updates, events, and property changes. Dynamic configuration of the MqttDigitalAdapter with broker details, topics, and other settings. Allows customization of data and payload management associated to MQTT topics for properties, events, and actions. Prerequisites:\nExternal MQTT Broker: The MqttDigitalAdapter library requires an external MQTT broker for optimal functionality and communication. Users must have access to a reliable MQTT broker to which the adapter can subscribe and publish. This external broker serves as the central communication hub, facilitating the exchange of messages between the adapter and digital applications A complete example is provided in the test folder with a complete DT Creation in the TestMain class together with MQTT IoT demo device and a test MQTT consumer.\nWLDT-Core Version Compatibility The correct mapping and compatibility between versions is reported in the following table\nmqtt-digital-adapter wldt-core 0.2.1 wldt-core 0.3.0 wldt-core 0.4.0 0.1.0 ✅ ❌ ❌ 0.1.1 ❌ ✅ ✅ Installation To use MqttDigitalAdapter in your Java project, you can include it as a dependency using Maven or Gradle.\nMaven \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.github.wldt\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;mqtt-digital-adapter\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;0.1.1\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; Gradle implementation \u0026#39;io.github.wldt:mqtt-digital-adapter:0.1.1\u0026#39; Class Structure \u0026amp; Functionalities MqttDigitalAdapterConfiguration MqttDigitalAdapterConfiguration is a crucial class in the Digital Twin library, allowing developers to configure the behavior of the MQTT Digital Adapter. It provides a flexible and customizable way to set up MQTT communication parameters, topics for properties, events, and actions.\nKey functionalities and exposed capabilities:\nBroker Configuration brokerAddress and brokerPort: Set the MQTT broker\u0026rsquo;s address and port. username and password: Set optional credentials for connecting to the broker. Client Configuration clientId: Unique identifier for the MQTT client. cleanSessionFlag: Flag indicating whether the client starts with a clean session. connectionTimeout: Maximum time to wait for the connection to the MQTT broker. MQTT Client Persistence persistence: Configurable persistence for the MQTT client\u0026rsquo;s data. Reconnect Configuration: automaticReconnectFlag: Flag enabling or disabling automatic reconnection. Topic Configuration: propertyUpdateTopics: Map of property update topics. eventNotificationTopics: Map of event notification topics. actionIncomingTopics: Map of incoming action topics. Builder Methods: builder: Static method to start building a new configuration. addPropertyTopic: Add a property topic with specified parameters. addEventNotificationTopic: Add an event notification topic. addActionTopic: Add an action topic. setConnectionTimeout: Set the connection timeout. setCleanSessionFlag: Set the clean session flag. setAutomaticReconnectFlag: Set the automatic reconnect flag. setMqttClientPersistence: Set the MQTT client persistence. build: Finalize the configuration and build the instance. MqttDigitalAdapterConfigurationBuilder The MqttDigitalAdapterConfigurationBuilder is a powerful tool designed to simplify the process of constructing configurations for the MQTT Digital Adapter in the Digital Twin library. It offers a fluent and intuitive interface, allowing developers to define various aspects of MQTT communication seamlessly.\nBuilder Instantiation The builder is instantiated by providing essential parameters like brokerAddress and brokerPort or including an optional clientId\nMqttDigitalAdapterConfigurationBuilder builder = MqttDigitalAdapterConfiguration.builder(\u0026#34;127.0.0.1\u0026#34;, 1883); Adding Property Topics Developers can add property topics with specific configurations, such as the key, topic, QoS level, and a function to convert property values to payload.\nbuilder.addPropertyTopic(\u0026#34;energy\u0026#34;, \u0026#34;dummy/properties/energy\u0026#34;, MqttQosLevel.MQTT_QOS_0, value -\u0026gt; String.valueOf(((Double)value).intValue())); Adding Event Notification Topics Event notification topics are easily added, including event keys, topics, QoS levels, and payload conversion functions.\nbuilder.addEventNotificationTopic(\u0026#34;overheating\u0026#34;, \u0026#34;dummy/events/overheating/notifications\u0026#34;, MqttQosLevel.MQTT_QOS_0, Object::toString); Adding Action Topics Developers can include action topics with key, topic, and a function to convert the payload to the desired action.\nbuilder.addActionTopic(\u0026#34;switch_off\u0026#34;, \u0026#34;app/actions/switch-off\u0026#34;, msg -\u0026gt; \u0026#34;OFF\u0026#34;); Connection Options Developers can set the connection timeout for the MQTT client.\nbuilder.setConnectionTimeout(30); The clean session flag can be configured based on the desired behavior.\nbuilder.setCleanSessionFlag(true); Developers can specify whether the MQTT client should automatically reconnect in case of a connection failure.\nbuilder.setAutomaticReconnectFlag(true); The builder allows setting a custom MQTT client persistence, such as an in-memory persistence or a file-based one.\nbuilder.setMqttClientPersistence(new MemoryPersistence()); Building Configuration The final configuration is built using the build method.\nMqttDigitalAdapterConfiguration configuration = builder.build(); MqttDigitalAdapter MqttDigitalAdapter extends DigitalAdapter and specializes in MQTT communication for Digital Twin instances. It handles the publication of state updates, events, and property changes over MQTT. This class facilitates seamless integration with MQTT-enabled systems.\nIt uses the information defined and provided in the `` to handle the communication both with the DT Core and external application interested to interact with the DT through the MQTT protocol.\nHere\u0026rsquo;s a basic example illustrating how to use MqttDigitalAdapter:\n// Create a Digital Twin instance DigitalTwin digitalTwin = new DigitalTwin(\u0026#34;my-digital-twin\u0026#34;, new DefaultShadowingFunction()); // Add a Physical Adapter to the DT [...] // Build the MQTT Digital Adapter Configuration MqttDigitalAdapterConfiguration configuration = MqttDigitalAdapterConfiguration.builder(\u0026#34;127.0.0.1\u0026#34;, 1883) .addPropertyTopic(\u0026#34;energy\u0026#34;, \u0026#34;dummy/properties/energy\u0026#34;, MqttQosLevel.MQTT_QOS_0, value -\u0026gt; String.valueOf(((Double)value).intValue())) .addActionTopic(\u0026#34;switch_off\u0026#34;, \u0026#34;app/actions/switch-off\u0026#34;, msg -\u0026gt; \u0026#34;OFF\u0026#34;) .build(); // Add the MQTT Digital Adapter to the Digital Twin digitalTwin.addDigitalAdapter(new MqttDigitalAdapter(\u0026#34;mqtt-da\u0026#34;, configuration)); // Create the Digital Twin Engine and start the simulation DigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine(); digitalTwinEngine.addDigitalTwin(digitalTwin); digitalTwinEngine.startAll(); ","date":"February 9, 2024","id":15,"permalink":"/docs/adapters/mqtt-digital-adapter/","summary":"The MqttDigitalAdapter,\nMqttDigitalAdapterConfiguration, and MqttDigitalAdapterConfigurationBuilder classes and guides you through using these classes to set up an MQTT Digital Adapter within WLDT.","tags":"","title":"MQTT Digital Adapter"},{"content":"Digital Adapters The following methods have been discontinued and removed from the DigitalAdapter class: onStateChangePropertyCreated onStateChangePropertyUpdated onStateChangePropertyDeleted onStatePropertyUpdated onStatePropertyDeleted onStateChangeActionEnabled onStateChangeActionUpdated onStateChangeActionDisabled onStateChangeEventRegistered onStateChangeEventRegistrationUpdated onStateChangeEventUnregistered onStateChangeRelationshipInstanceDeleted onStateChangeRelationshipDeleted onStateChangeRelationshipInstanceCreated onStateChangeRelationshipCreated onDigitalTwinStateEventNotificationReceived The Signature of the following methods have been changed: onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) -\u0026gt; onDigitalTwinSync(DigitalTwinState currentDigitalTwinState) onDigitalTwinUnSync(IDigitalTwinState currentDigitalTwinState) -\u0026gt; onDigitalTwinUnSync(DigitalTwinState currentDigitalTwinState) New methods that have been added are: onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList\u0026lt;DigitalTwinStateChange\u0026gt; digitalTwinStateChangeList) onEventNotificationReceived(DigitalTwinStateEventNotification\u0026lt;?\u0026gt; digitalTwinStateEventNotification) For additional details about Digital Adapters check Sub Section [[Change Log - v.0.3.0#Digital Adapter| Digital Adapters]] Shadowing Function ShadowingModelFunction is now ShadowingFunction this.digitalTwinState is not directly accessible anymore and it is wrapped through the DigitalTwinStateManager using the variable digitalTwinStateManager (see next descriptions and changes) The method addRelationshipInstance now take only one parameter that is the DigitalTwinStateRelationshipInstance The same change for example should be applied in the point of the code where the Shadowing Function receive a variation from the Physical world through a target adapter and the callback method onPhysicalAssetPropertyVariation(...) When the Shadowing Function has to compute the new DT State it can now work with the following method to handle DT State Transition: this.digitalTwinStateManager.startStateTransaction() DT State variation methods such as: digitalTwinStateManager.createProperty() digitalTwinStateManager.updateProperty() digitalTwinStateManager.updatePropertyValue() digitalTwinStateManager.deleteProperty() digitalTwinStateManager.enableAction() digitalTwinStateManager.updateAction() digitalTwinStateManager.disableAction() digitalTwinStateManager.registerEvent() digitalTwinStateManager.updateRegisteredEvent() digitalTwinStateManager.unRegisterEvent() digitalTwinStateManager.createRelationship() digitalTwinStateManager.addRelationshipInstance() digitalTwinStateManager.deleteRelationship() digitalTwinStateManager.deleteRelationshipInstance() At the end the transaction can be committed using the method: digitalTwinStateManager.commitStateTransaction() The method notifyDigitalTwinStateEvent is now available through the digitalTwinStateManager Additional Details associated to Shadowing Function Migration can be found in the dedicated section [[Change Log - v.0.3.0#Shadowing Function Changes | Shadowing Function Changes]] WLDT Engine \u0026amp; DT Creation WldtEngine is now DigitalTwin and model and structure a single Digital Twin and takes the following parameters: String digitalTwinId ShadowingFunction shadowingFunction The startLifeCycle has been removed from the DigitalTwin (previously WLDT Engine) and now DigitalTwinEngine should be used to start twins Once a new Digital Twin has been create it has to be added to the DigitalTwinEngine DigitalTwinEngine has dedicated method to start and stop twins such as: startAll() startDigitalTwin(\u0026lt;DIGITAL_TWIN_ID\u0026gt;); stopAll() digitalTwinEngine.stopDigitalTwin(\u0026lt;DIGITAL_TWIN_ID\u0026gt;); Digital Twin \u0026amp; Digital Twin Engine With the following code we now create a new Digital Twin Instance\n// Create the new Digital Twin with its Shadowing Function DigitalTwin digitalTwin = new DigitalTwin(digitalTwinId, new DemoShadowingFunction()); // Physical Adapter with Configuration digitalTwin.addPhysicalAdapter( new DemoPhysicalAdapter( String.format(\u0026#34;%s-%s\u0026#34;, digitalTwinId, \u0026#34;test-physical-adapter\u0026#34;), new DemoPhysicalAdapterConfiguration(), true)); // Digital Adapter with Configuration digitalTwin.addDigitalAdapter( new DemoDigitalAdapter( String.format(\u0026#34;%s-%s\u0026#34;, digitalTwinId, \u0026#34;test-digital-adapter\u0026#34;), new DemoDigitalAdapterConfiguration()) ); In the new version the DT cannot be directly run but it should be added to the DigitalTwinEngine in order to be executed through the WLDT Library\n// Create the Digital Twin Engine DigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine(); // Add the Digital Twin to the Engine digitalTwinEngine.addDigitalTwin(digitalTwin); In order to start a DT from the Engine you can:\n// Directly start when you add it passing a second boolean value = true digitalTwinEngine.addDigitalTwin(digitalTwin. true); // Starting the single DT on the engine through its id digitalTwinEngine.startDigitalTwin(DIGITAL_TWIN_ID); // Start all the DTs registered on the engine digitalTwinEngine.startAll(); To stop a single twin or all the twin registered on the engine:\n// Stop a single DT on the engine through its id digitalTwinEngine.stopDigitalTwin(DIGITAL_TWIN_ID); // Stop all the DTs registered on the engine digitalTwinEngine.stopAll(); It is also possible to remove a DT from the Engine with a consequent stop if it is active and the deletion of its reference from the engine:\n// Remove a single DT on the engine through its id digitalTwinEngine.removeDigitalTwin(DIGITAL_TWIN_ID); // Remove all the DTs registered on the engine digitalTwinEngine.removeAll(); Digital Twin State DT State now has the reference timestamp representing the evaluation instant of the digital twin state, this timestamp is computed through the DigitalTwinStateManager and cannot manually set by the developer The information available on the DT State are: properties: List of Properties with their values (if available) actions: List of Actions that can be called on the DT events: List of Events that can be generated by the DT relationships: List of Relationships and their instances (if available) evaluationInstant: The timestamp representing the evaluation instant of the DT state Available main methods on that class instance are: Properties:\n- getProperty(String propertyKey): Retrieves if present the target DigitalTwinStateProperty by Key\n- containsProperty(String propertyKey): Checks if a target Property Key is already available in the current Digital Twin\u0026rsquo;s State\n- getPropertyList(): Loads the list of available Properties (described by the class DigitalTwinStateProperty) available on the Digital Twin\u0026rsquo;s State\n- createProperty(DigitalTwinStateProperty\u0026lt;?\u0026gt; dtStateProperty): Allows the creation of a new Property on the Digital Twin\u0026rsquo;s State through the class DigitalTwinStateProperty\n- readProperty(String propertyKey): Retrieves if present the target DigitalTwinStateProperty by Key\n- updateProperty(DigitalTwinStateProperty\u0026lt;?\u0026gt; dtStateProperty): Updates the target property using the DigitalTwinStateProperty and the associated Property Key field\n- deleteProperty(String propertyKey): Deletes the target property identified by the specified key Actions:\n- containsAction(String actionKey): Checks if a Digital Twin State Action with the specified key is correctly registered\n- getAction(String actionKey): Loads the target DigitalTwinStateAction by key\n- getActionList(): Gets the list of available Actions registered on the Digital Twin\u0026rsquo;s State\n- enableAction(DigitalTwinStateAction digitalTwinStateAction): Enables and registers the target Action described through an instance of the DigitalTwinStateAction class\n- updateAction(DigitalTwinStateAction digitalTwinStateAction): Update the already registered target Action described through an instance of the DigitalTwinStateAction class\n- disableAction(String actionKey): Disables and unregisters the target Action described through an instance of the DigitalTwinStateAction class Events:\n- containsEvent(String eventKey): Check if a Digital Twin State Event with the specified key is correctly registered\n- getEvent(String eventKey): Return the description of a registered Digital Twin State Event according to its Key\n- getEventList(): Return the list of existing and registered Digital Twin State Events\n- registerEvent(DigitalTwinStateEvent digitalTwinStateEvent): Register a new Digital Twin State Event\n- updateRegisteredEvent(DigitalTwinStateEvent digitalTwinStateEvent): Update the registration and signature of an existing Digital Twin State Event\n- unRegisterEvent(String eventKey): Un-register a Digital Twin State Event\n- notifyDigitalTwinStateEvent(DigitalTwinStateEventNotification\u0026lt;?\u0026gt; digitalTwinStateEventNotification): Method to notify the occurrence of the target Digital Twin State Event Relationships:\n- containsRelationship(String relationshipName): Checks if a Relationship Name is already available in the current Digital Twin\u0026rsquo;s State\n- createRelationship(DigitalTwinStateRelationship\u0026lt;?\u0026gt; relationship): Creates a new Relationships (described by the class DigitalTwinStateRelationship) in the Digital Twin\u0026rsquo;s State\n- addRelationshipInstance(String name, DigitalTwinStateRelationshipInstance\u0026lt;?\u0026gt; instance): Adds a new Relationship instance described through the class DigitalTwinStateRelationshipInstance and identified through its name\n- getRelationshipList(): Loads the list of existing relationships on the Digital Twin\u0026rsquo;s State through a list of DigitalTwinStateRelationship\n- getRelationship(String name): Gets a target Relationship identified through its name and described through the class DigitalTwinStateRelationship\n- deleteRelationship(String name): Deletes a target Relationship identified through its name\n- deleteRelationshipInstance(String relationshipName, String instanceKey): Deletes the target Relationship Instance using relationship name and instance Key Digital Twin State Manager The DigitalTwinStateManager is a Java class that serves as the default implementation of the IDigitalTwinStateManager interface within the White Label Digital Twin Java Framework (whitelabel-digitaltwin). This class allows developers to manage the state of a digital twin, including properties, actions, events, and relationships.\nFeatures State Management: Handles the creation, update, and deletion of properties, actions, events, and relationships associated with the digital twin state. Transaction Support: Allows developers to start, commit, or rollback transactions to manage changes to the digital twin state. Event Notification: Notifies listeners about updates to the digital twin state through the WLDT event bus. When the Shadowing Function has to compute the new DT State it can now work with the following method to handle DT State Transition: - Start the DT State Transaction: startStateTransaction() - DT State variation methods such as: - createProperty() - updateProperty()\n- updatePropertyValue() - deleteProperty() - enableAction() - updateAction() - disableAction() - registerEvent() - updateRegisteredEvent() - unRegisterEvent() - createRelationship() - addRelationshipInstance() - deleteRelationship() - deleteRelationshipInstance()\nAt the end the transaction can be committed using the method: commitStateTransaction()\nUsage To use the DigitalTwinStateManager within your digital twin implementation:\nInitialization: Create an instance of the DigitalTwinStateManager. DigitalTwinStateManager digitalTwinStateManager = new DigitalTwinStateManager(); State Transaction:\nStart a new transaction using startStateTransaction() to manage changes. Make changes to the digital twin state. Commit the transaction using commitStateTransaction() to apply the changes. digitalTwinStateManager.startStateTransaction(); // Make changes to properties, actions, events, or relationships // [...] digitalTwinStateManager.commitStateTransaction(); Event Notification:\nDT State Updates after a commit action are automatically notified to Digital Adapter by the Manager Once an event incoming from the physical or generated by the DT itself is handled by the Shadowing Function, the developer can use notifyDigitalTwinStateUpdate to notify Digital Adapter listening about events variations. // Notify a specific event notification digitalTwinStateManager.notifyDigitalTwinStateEvent(digitalTwinStateEventNotification); Property, Action, Event, Relationship Management:\nCreate, update, or delete properties, actions, events, or relationships as needed. // Begin Digital Twin State Transaction digitalTwinStateManager.startStateTransaction(); // Create a new property digitalTwinStateManager.createProperty(dtStateProperty); // Update an existing property digitalTwinStateManager.updateProperty(dtStateProperty); // Delete a property digitalTwinStateManager.deleteProperty(propertyKey);` // Commit DT State Update to apply all the changes and notify the Digital Adapters and other listeners about the variation digitalTwinStateManager.commitStateTransaction(); Exception Handling The class throws WldtDigitalTwinStateException to indicate errors related to digital twin state management. Proper exception handling is advised to manage potential errors during state transactions. Shadowing Function Changes Now that the DT State is managed through the DigitalTwinStateManager class all the changes and variation should be applied on the DT ShadowingFunction using the previously presented transaction management and the correct call of methods startStateTransaction() and commitStateTransaction().\nHere there is an example of the change with a simple and demo shadowing function on callback onDigitalTwinBound:\n@Override protected void onDigitalTwinBound(Map\u0026lt;String, PhysicalAssetDescription\u0026gt; adaptersPhysicalAssetDescriptionMap) { try{ // NEW -\u0026gt; Start DT State Change Transaction this.digitalTwinStateManager.startStateTransaction(); for(Map.Entry\u0026lt;String, PhysicalAssetDescription\u0026gt; entry : adaptersPhysicalAssetDescriptionMap.entrySet()){ String adapterId = entry.getKey(); PhysicalAssetDescription physicalAssetDescription = entry.getValue(); //In that simple case the Digital Twin shadow all the properties and actions available in the physical asset for(PhysicalAssetProperty\u0026lt;?\u0026gt; p : physicalAssetDescription.getProperties()) this.digitalTwinStateManager.createProperty(new DigitalTwinStateProperty\u0026lt;\u0026gt;(p.getKey(), p.getInitialValue())); for(PhysicalAssetAction a : physicalAssetDescription.getActions()) this.digitalTwinStateManager.enableAction(new DigitalTwinStateAction(a.getKey(), a.getType(), a.getContentType())); for(PhysicalAssetEvent e: physicalAssetDescription.getEvents()) this.digitalTwinStateManager.registerEvent(new DigitalTwinStateEvent(e.getKey(), physicalAssetEvent.getType())); } // NEW -\u0026gt; Commit DT State Change Transaction to apply the changes on the DT State and notify about the change this.digitalTwinStateManager.commitStateTransaction(); //Observer Target Physical Properties for(Map.Entry\u0026lt;String, PhysicalAssetDescription\u0026gt; entry : adaptersPhysicalAssetDescriptionMap.entrySet()){ [...] } //Observe all the target available Physical Asset Events for each Adapter for(Map.Entry\u0026lt;String, PhysicalAssetDescription\u0026gt; entry : adaptersPhysicalAssetDescriptionMap.entrySet()){ [...] } // Observer for Incoming Digital Actions observeDigitalActionEvents(); //Notify Shadowing Completed notifyShadowingSync(); }catch (Exception e){ e.printStackTrace(); } } The same change for example should be applied in the point of the code where the Shadowing Function receive a variation from the Physical world through a target adapter and the callback method onPhysicalAssetPropertyVariation(...)\n@Override protected void onPhysicalAssetPropertyVariation(PhysicalAssetPropertyWldtEvent\u0026lt;?\u0026gt; physicalPropertyEventMessage) { try { if(physicalPropertyEventMessage != null \u0026amp;\u0026amp; getPhysicalEventsFilter().contains(physicalPropertyEventMessage.getType())){ if(physicalPropertyEventMessage.getPhysicalPropertyId().equals(TestPhysicalAdapter.SWITCH_PROPERTY_KEY) \u0026amp;\u0026amp; physicalPropertyEventMessage.getBody() instanceof String){ [...] } else{ //Update Digital Twin State //NEW -\u0026gt; Start State Transaction this.digitalTwinStateManager.startStateTransaction(); // Update State Property Value this.digitalTwinStateManager.updateProperty( new DigitalTwinStateProperty\u0026lt;\u0026gt;( physicalPropertyEventMessage.getPhysicalPropertyId(), physicalPropertyEventMessage.getBody())); //NEW -\u0026gt; Commit State Transaction this.digitalTwinStateManager.commitStateTransaction(); } } else logger.error(\u0026#34;WRONG Physical Event Message Received !\u0026#34;); }catch (Exception e){ e.printStackTrace(); } } Digital Adapter The Digital Adapter base class has been significantly extended and improved with respect to the previous version. In this new Version notifications that are received by the Adapter from the the DT core belongs to the following categories:\nDigital Twin State Update through the method onStateUpdate(...) providing information about the new state of the Digital Twin, the previous state, and a list of changes that occurred between these two states. In the previous version each variation of a property, relationships, actions or events were notified. In the new version only a committed DT\u0026rsquo;State variation is notified to listeners. Event Notifications through the method onEventNotificationReceived(...) whenever there is a notification about an event related to the Digital Twin\u0026rsquo;s state coming from the physical world, generated by the twin and processed by the Shadowing Function. For example in the DT State we can have the declaration of the over-heating-alert structured and received in the DT State while the effective occurrence of the event and the associated notification is notified through this dedicated callback The onStateUpdate method is an abstract method that must be implemented by any class extending the DigitalAdapter class. This method is called whenever there is an update to the Digital Twin\u0026rsquo;s state. It provides information about the new state of the Digital Twin, the previous state, and a list of changes that occurred between these two states.\nHere is an explanation of the parameters:\nnewDigitalTwinState: This parameter represents the updated state of the Digital Twin. It is an instance of the DigitalTwinState class, which encapsulates the current state information.\npreviousDigitalTwinState: This parameter represents the state of the Digital Twin before the update. It is also an instance of the DigitalTwinState class.\ndigitalTwinStateChangeList: This parameter is an ArrayList containing DigitalTwinStateChange objects. Each DigitalTwinStateChange object encapsulates information about a specific change that occurred between the previous and new states. It includes details such as the property or aspect of the state that changed, the previous value, and the new value.\nThe DT State is automatically monitored by each Digital Adapter while for the Events potentially generated by the DT can be observed by each adapter using:\nobserveAllDigitalTwinEventsNotifications: Enable the observation of available Digital Twin State Events Notifications. unObserveAllDigitalTwinEventsNotifications: Cancel the observation of Digital Twin State Events Notifications observeDigitalTwinEventsNotifications: Enable the observation of the notification associated to a specific list of Digital Twin State events. With respect to event a notification contains the new associated value unObserveDigitalTwinEventsNotifications: Cancel the observation of a target list of properties observeDigitalTwinEventNotification: Enable the observation of the notification associated to a single Digital Twin State event. With respect to event a notification contains the new associated value unObserveDigitalTwinEventNotification: Cancel the observation of a single target event DigitalTwinStateChange Class DigitalTwinStateChange Class\nThe DigitalTwinStateChange class is a representation of a change that occurred in the state of a Digital Twin. It encapsulates information about the type of operation, the resource type, and the affected resource within the Digital Twin.\nEnums:\nOperation: Enumerates different types of operations that can be performed on a Digital Twin state. The possible operations are: OPERATION_UPDATE: Represents an update operation on a resource. OPERATION_UPDATE_VALUE: Represents an update operation specifically on the value of a resource. OPERATION_ADD: Represents an addition operation of a new resource. OPERATION_REMOVE: Represents a removal operation of an existing resource. ResourceType: Enumerates different types of resources within a Digital Twin. The possible resource types are: PROPERTY: Represents a property of the Digital Twin. PROPERTY_VALUE: Represents the value of a property within the Digital Twin. EVENT: Represents an event associated with the Digital Twin. ACTION: Represents an action that can be performed on the Digital Twin. RELATIONSHIP: Represents a relationship between different components of the Digital Twin. RELATIONSHIP_INSTANCE: Represents an instance of a relationship. Fields:\noperation: Indicates the type of operation performed on the Digital Twin state (e.g., update, add, remove). resourceType: Represents the type of resource affected by the change (e.g., property, event, relationship). resource: The specific resource that has undergone the change, represented by an instance of the DigitalTwinStateResource class. Available type of DigitalTwinStateResource are:\nDigitalTwinStateProperty\u0026lt;T\u0026gt;: This class define a generic property associated to the Digital Twin State. Each property is associated to a Key and a Value. Furthermore, it can also be associated to a type to identify its nature and data structure. By default, it is associated to the type of the Class (e.g., java.lang.String) but it can be directly changed by the developer to associate it to a specific ontology or data type. DigitalTwinStateEvent: This class define a generic event associated to the Digital Twin State. Events enable a mechanism for asynchronous messages to be sent by the digital twin (e.g., an overheating) . They are different from Properties that can change values according to the type of Digital Twin and may be associated also to telemetry patterns. Each event is associated to a Key and a Type used to identify its nature and data structure. By default, it is associated to the type of the Class (e.g., java.lang.String) but it can be directly changed by the developer to associate it to a specific ontology or data type. DigitalTwinStateAction: This class define a generic action associated to the Digital Twin State. Each action is by a key, an action type and a content type used to identify the expected input required by the action. The type of the can be directly changed by the developer to associate it to a specific ontology or data type. DigitalTwinStateRelationship\u0026lt;T\u0026gt;: Structures and describes a Relationship in the Digital Twins\u0026rsquo;s State. This is just the description of the relationships while the effective values/instances are described through the other class DigitalTwinStateRelationshipInstance DigitalTwinStateRelationshipInstance\u0026lt;T\u0026gt;: Structures and describes a Relationship Instance in the Digital Twins\u0026rsquo;s State. This is effective description of a relationship while its generic declaration is described through the class DigitalTwinStateRelationship. When there is a change in the DT State it is possibile to cast the received resource variation to the correct one. For example in the following code we detect and manage the variation on a Property Value:\n// Get information from the state change DigitalTwinStateChange.Operation operation = stateChange.getOperation(); DigitalTwinStateChange.ResourceType resourceType = stateChange.getResourceType(); DigitalTwinStateResource resource = stateChange.getResource(); // Search for property value variation if(resourceType.equals(DigitalTwinStateChange.ResourceType.PROPERTY_VALUE) \u0026amp;\u0026amp; operation.equals(DigitalTwinStateChange.Operation.OPERATION_UPDATE) \u0026amp;\u0026amp; resource instanceof DigitalTwinStateProperty){ DigitalTwinStateProperty\u0026lt;?\u0026gt; digitalTwinStateProperty = (DigitalTwinStateProperty\u0026lt;?\u0026gt;) resource; if(getConfiguration().getPropertyUpdateTopics().containsKey(digitalTwinStateProperty.getKey())){ //Handle property value variation } } Constructors:\nDigitalTwinStateChange(): An empty constructor that allows creating an instance of the class. DigitalTwinStateChange(Operation operation, ResourceType resourceType, DigitalTwinStateResource resource): Constructs a DigitalTwinStateChange object with specified operation, resource type, and resource. Throws a WldtDigitalTwinStateException if any of the parameters is missing or null. Methods:\nAccessor methods (getOperation(), getResourceType(), getResource()) to retrieve the values of the fields. Mutator methods (setOperation(), setResourceType(), setResource()) to update the values of the fields. Usage Examples Developers extending the DigitalAdapter class should implement the onStateUpdate method to define custom logic that needs to be executed whenever the state of the Digital Twin is updated. This could include tasks such as processing state changes, updating internal variables, triggering specific actions, or notifying other components about the state update.\nHere\u0026rsquo;s an example of how the method might be implemented in a concrete subclass of DigitalAdapter:\n@Override protected void onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList\u0026lt;DigitalTwinStateChange\u0026gt; digitalTwinStateChangeList) { // In newDigitalTwinState we have the new DT State System.out.println(\u0026#34;New DT State is: \u0026#34; + newDigitalTwinState); // The previous DT State is available through the variable previousDigitalTwinState System.out.println(\u0026#34;Previous DT State is: \u0026#34; + previousDigitalTwinState); // We can also check each DT\u0026#39;s state change potentially differentiating the behaviour for each change if (digitalTwinStateChangeList != null \u0026amp;\u0026amp; !digitalTwinStateChangeList.isEmpty()) { // Iterate through each state change in the list for (DigitalTwinStateChange stateChange : digitalTwinStateChangeList) { // Get information from the state change DigitalTwinStateChange.Operation operation = stateChange.getOperation(); DigitalTwinStateChange.ResourceType resourceType = stateChange.getResourceType(); DigitalTwinStateResource resource = stateChange.getResource(); // Perform different actions based on the type of operation switch (operation) { case OPERATION_UPDATE: // Handle an update operation System.out.println(\u0026#34;Update operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; case OPERATION_UPDATE_VALUE: // Handle an update value operation System.out.println(\u0026#34;Update value operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; case OPERATION_ADD: // Handle an add operation System.out.println(\u0026#34;Add operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; case OPERATION_REMOVE: // Handle a remove operation System.out.println(\u0026#34;Remove operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; default: // Handle unknown operation (optional) System.out.println(\u0026#34;Unknown operation on \u0026#34; + resourceType + \u0026#34;: \u0026#34; + resource); break; } } } else { // No state changes System.out.println(\u0026#34;No state changes detected.\u0026#34;); } } In this example, the method iterates over the list of state changes, extracts information about each change, and performs custom actions based on the changes. Developers can adapt this method to suit the specific requirements of their Digital Twin application.\n","date":"February 9, 2024","id":16,"permalink":"/docs/change-logs/change-log-0.3.0/","summary":"Digital Adapters The following methods have been discontinued and removed from the DigitalAdapter class: onStateChangePropertyCreated onStateChangePropertyUpdated onStateChangePropertyDeleted onStatePropertyUpdated onStatePropertyDeleted onStateChangeActionEnabled onStateChangeActionUpdated onStateChangeActionDisabled onStateChangeEventRegistered onStateChangeEventRegistrationUpdated onStateChangeEventUnregistered onStateChangeRelationshipInstanceDeleted onStateChangeRelationshipDeleted onStateChangeRelationshipInstanceCreated onStateChangeRelationshipCreated onDigitalTwinStateEventNotificationReceived The Signature of the following methods have been changed: onDigitalTwinSync(IDigitalTwinState currentDigitalTwinState) -\u0026gt; onDigitalTwinSync(DigitalTwinState currentDigitalTwinState) onDigitalTwinUnSync(IDigitalTwinState currentDigitalTwinState) -\u0026gt; onDigitalTwinUnSync(DigitalTwinState currentDigitalTwinState) New methods that have been added are: onStateUpdate(DigitalTwinState newDigitalTwinState, DigitalTwinState previousDigitalTwinState, ArrayList\u0026lt;DigitalTwinStateChange\u0026gt; digitalTwinStateChangeList) onEventNotificationReceived(DigitalTwinStateEventNotification\u0026lt;?","tags":"","title":"Change Log 0.3.0"},{"content":"The HttpDigitalAdapter is a powerful component designed to facilitate the integration of Digital Twins into HTTP-based systems. It serves as a bridge between a Digital Twin and HTTP-based applications, allowing developers to easily expose and interact with Digital Twin data and functionalities over HTTP.\nKey Features:\nHTTP Integration: Seamlessly integrates Digital Twins into HTTP environments, enabling communication with web applications and services. Dynamic Configuration: Offers a flexible configuration mechanism through the HttpDigitalAdapterConfiguration, allowing developers to customize the adapter\u0026rsquo;s behavior based on specific requirements. State Monitoring: Monitors changes in the Digital Twin state and provides HTTP endpoints to query the state of the Digital Twin (properties, events, actions and relationships). Event Notifications: Allows developers to retrieve event notifications triggered by changes in the Digital Twin state. Storage \u0026amp; Query: Since version 0.2 the HTTP Digital Adapter is able to retrieve Storage Statistics and execute query on the target DT A complete example is provided in the test folder with a complete DT Creation in the TestMain class together with a demo DT with and emulated Physical Adapter and the HTTP Digital Adapter.\nWLDT-Core Version Compatibility The correct mapping and compatibility between versions is reported in the following table\nhttp-digital-adapter wldt-core 0.2.1 wldt-core 0.3.0 wldt-core 0.4.0 0.1.1 ❌ ✅ ✅ 0.2 ❌ ❌ ✅ Installation To use HttpDigitalAdapter in your Java project, you can include it as a dependency using Maven or Gradle.\nMaven \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.github.wldt\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;http-digital-adapter\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;0.2\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; Gradle implementation \u0026#39;io.github.wldt:http-digital-adapter:0.2\u0026#39; Class Structure \u0026amp; Functionalities HttpDigitalAdapterConfiguration The HttpDigitalAdapterConfiguration is a crucial part of the HttpDigitalAdapter, providing the necessary settings to tailor the adapter\u0026rsquo;s behavior to meet specific needs.\nRepresents the configuration for an HTTP Digital Adapter, specifying the host, port, and filters for properties, actions, events, and relationships.\nThe filters are used to selectively include or exclude specific properties, actions, events, and relationships when interacting with the HTTP Digital Adapter. Filters are meant to be white list filters, if they are empty, it means that ALL fields are considered\nThis class provides methods to add filters for each type and getters to retrieve the configured values.\nKey functionalities and exposed capabilities:\nBasic Configuration Adapter ID: A unique identifier for the HttpDigitalAdapter instance. Host: The hostname or IP address on which the adapter will listen for incoming HTTP requests. Port: The port number on which the adapter will listen for incoming HTTP requests. Filters (Optional) addPropertyFilter(String propertyKey): Adds a single property key to the property filter. addPropertiesFilter(Collection\u0026lt;String\u0026gt; propertiesKey): Adds a collection of property keys to the property filter. addActionFilter(String actionKey): Adds a single action key to the action filter. addActionsFilter(Collection\u0026lt;String\u0026gt; actionsKey): Adds a collection of action keys to the action filter. addEventFilter(String eventKey): Adds a single event key to the event filter. addEventsFilter(Collection\u0026lt;String\u0026gt; eventsKey): Adds a collection of event keys to the event filter. addRelationshipFilter(String relationshipName): Adds a single relationship name to the relationship filter. addRelationshipsFilter(Collection\u0026lt;String\u0026gt; relationshipNames): Adds a collection of relationship names to the relationship filter. Configured Filter can be accessed using: getPropertyFilter() getActionFilter() getEventFilter() getRelationshipFilter() A basic example without any filter that accesses and uses the entire DT State is:\nHttpDigitalAdapterConfiguration config = new HttpDigitalAdapterConfiguration(\u0026#34;my-http-adapter\u0026#34;, \u0026#34;localhost\u0026#34;, 8080); An example of using filter to select specific field of interest can be structured ad follows:\nHttpDigitalAdapterConfiguration config = new HttpDigitalAdapterConfiguration(\u0026#34;my-http-adapter\u0026#34;, \u0026#34;localhost\u0026#34;, 8080); // Add property filter config.addPropertyFilter(\u0026#34;temperature\u0026#34;); config.addPropertiesFilter(Arrays.asList(\u0026#34;humidity\u0026#34;, \u0026#34;pressure\u0026#34;)); // Add action filter config.addActionFilter(\u0026#34;start\u0026#34;); config.addActionsFilter(Arrays.asList(\u0026#34;stop\u0026#34;, \u0026#34;reset\u0026#34;)); // Add event filter config.addEventFilter(\u0026#34;temperatureChange\u0026#34;); config.addEventsFilter(Collections.singletonList(\u0026#34;pressureChange\u0026#34;)); // Add relationship filter config.addRelationshipFilter(\u0026#34;connectedTo\u0026#34;); config.addRelationshipsFilter(Arrays.asList(\u0026#34;parentOf\u0026#34;, \u0026#34;siblingOf\u0026#34;)); // Retrieve and display filters List\u0026lt;String\u0026gt; propertyFilter = config.getPropertyFilter(); List\u0026lt;String\u0026gt; actionFilter = config.getActionFilter(); List\u0026lt;String\u0026gt; eventFilter = config.getEventFilter(); List\u0026lt;String\u0026gt; relationshipFilter = config.getRelationshipFilter(); System.out.println(\u0026#34;Property Filter: \u0026#34; + propertyFilter); System.out.println(\u0026#34;Action Filter: \u0026#34; + actionFilter); System.out.println(\u0026#34;Event Filter: \u0026#34; + eventFilter); System.out.println(\u0026#34;Relationship Filter: \u0026#34; + relationshipFilter); HttpDigitalAdapter The HttpDigitalAdapter itself is the core component responsible for handling HTTP requests and interacting with the underlying Digital Twin. It extends the capabilities of the base DigitalAdapter to specifically cater to HTTP-based scenarios.\nKey Functionalities:\nRESTful Endpoints: Provides RESTful endpoints for reading properties, invoking actions, querying events, and managing relationships. State Updates: Automatically reflects changes in the Digital Twin state to the HTTP endpoints, ensuring real-time information. Event Handling: Listens for Digital Twin events and provides events notifications to HTTP clients. Here\u0026rsquo;s a basic example illustrating how to use MqttDigitalAdapter:\nGetting Started: Create HttpDigitalAdapterConfiguration:\nHttpDigitalAdapterConfiguration config = new HttpDigitalAdapterConfiguration(\u0026#34;my-http-adapter\u0026#34;, \u0026#34;localhost\u0026#34;, 8080); Instantiate HttpDigitalAdapter:\nDigitalTwin digitalTwin = new DigitalTwin(\u0026#34;my-digital-twin\u0026#34;, new DefaultShadowingFunction()); HttpDigitalAdapter httpDigitalAdapter = new HttpDigitalAdapter(config, digitalTwin); // Add a Physical Adapter to the DT [...] Add HttpDigitalAdapter to DigitalTwin:\ndigitalTwin.addDigitalAdapter(httpDigitalAdapter); Start the Digital Twin Engine:\nDigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine(); digitalTwinEngine.addDigitalTwin(digitalTwin); digitalTwinEngine.startAll(); HTTP RESTful API This section of the documentation provides detailed information about the RESTful API exposed by the WLDT - HTTP Digital Adapter. The API allows you to interact with the Digital Twin (DT) instance, retrieve its state, read properties, actions, event and relationships description, and trigger actions.\nAvailable endpoints with the associated methods are:\nGET /instance: Retrieves information about the Digital Twin instance. GET /state: Retrieves the current state of the Digital Twin. GET /state/changes: Retrieves the list of state changes in the Digital Twin. GET /state/previous: Retrieves the previous state of the Digital Twin. GET /state/properties: Retrieves the list of properties in the Digital Twin state. GET /properties/{propertyKey}: Retrieves the value of a specific property (e.g., /properties/color) from the Digital Twin state. GET /state/events: Retrieves the list of events in the Digital Twin state. GET /state/actions: Retrieves the list of actions in the Digital Twin state. POST /state/actions/{actionKey}: Triggers the specified action (e.g., /state/actions/switch_on) in the Digital Twin state. The raw body contains the action request payload. GET /state/relationships: Retrieves the list of relationships in the Digital Twin state. GET /state/relationships/{relationshipName}/instances: Retrieves the instances of the specified relationship (e.g., /state/relationships/insideIn/instances) in the Digital Twin state. GET /storage: Retrieves Storage Statistics from the target Digital Twin POST /storage/query: Allows the execution of a query, where the query structure is specified through a JSON Message in the request Body. For additional information about the Query System see Query System Page Note: Replace {propertyKey}, {actionKey}, and {relationshipName} with the actual values you want to retrieve or trigger. Make sure to use the appropriate HTTP method (GET, POST) and include any required parameters or payload as described in each endpoint\u0026rsquo;s description. For more detailed information, refer to the Postman Collection for this API available in the folder api: http_adapter_api_postman.json\nExample of Storage Query Requests are the following:\nRetrieve the first 4 Digital Twin State Variations\n{ \u0026#34;resourceType\u0026#34;: \u0026#34;DIGITAL_TWIN_STATE\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;SAMPLE_RANGE\u0026#34;, \u0026#34;startIndex\u0026#34;: 0, \u0026#34;endIndex\u0026#34;: 3 } Retrieve Digital Twin State Variations in a Time Range\n{ \u0026#34;resourceType\u0026#34;: \u0026#34;DIGITAL_TWIN_STATE\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;TIME_RANGE\u0026#34;, \u0026#34;startIndex\u0026#34;: 161989898, \u0026#34;endIndex\u0026#34;: 162989898 } Retrieve the last Digital Twin State\n{ \u0026#34;resourceType\u0026#34;: \u0026#34;DIGITAL_TWIN_STATE\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;LAST_VALUE\u0026#34; } Available keywords for Query Resource Type and Query Type are the following (as explained in the dedicated Query System Page):\n- PHYSICAL_ASSET_PROPERTY_VARIATION - TIME_RANGE - SAMPLE_RANGE - COUNT - PHYSICAL_ASSET_EVENT_NOTIFICATION - TIME_RANGE - SAMPLE_RANGE - COUNT - PHYSICAL_ACTION_REQUEST - TIME_RANGE - SAMPLE_RANGE - COUNT - DIGITAL_ACTION_REQUEST - TIME_RANGE - SAMPLE_RANGE - COUNT - DIGITAL_TWIN_STATE - TIME_RANGE - SAMPLE_RANGE - COUNT - LAST_VALUE - NEW_PAD_NOTIFICATION - TIME_RANGE - SAMPLE_RANGE - COUNT - UPDATED_PAD_NOTIFICATION - TIME_RANGE - SAMPLE_RANGE - COUNT - PHYSICAL_RELATIONSHIP_INSTANCE_CREATED_NOTIFICATION - TIME_RANGE - SAMPLE_RANGE - COUNT - PHYSICAL_RELATIONSHIP_INSTANCE_DELETED_NOTIFICATION - TIME_RANGE - SAMPLE_RANGE - COUNT - LIFE_CYCLE_EVENT - TIME_RANGE - SAMPLE_RANGE - COUNT - LAST_VALUE - STORAGE_STATS - LAST_VALUE ","date":"February 9, 2024","id":17,"permalink":"/docs/adapters/http-digital-adapter/","summary":"The HttpDigitalAdapter is a powerful component designed to facilitate the integration of Digital Twins into HTTP-based systems. It serves as a bridge between a Digital Twin and HTTP-based applications, allowing developers to easily expose and interact with Digital Twin data and functionalities over HTTP.","tags":"","title":"HTTP Digital Adapter"},{"content":"The WLDT framework intends to maximize modularity, re-usability and flexibility in order to effectively mirror physical smart objects in their digital counterparts. The proposed library focuses on the simplification of twins design and development aiming to provide a set of core features and functionalities for the widespread adoption of Internet of Things DTs applications.\nA WLDT instance is a general purpose software entity implementing all the features and functionalities of a Digital Twin running in cloud or on the edge. It has the peculiar characteristic to be generic and ``attachable\u0026rsquo;\u0026rsquo; to any physical thing in order to impersonate and maintain its digital replica and extend the provided functionalities for example through the support of additional protocols or a specific translation or normalization for data and formats.\nHereafter, the requirements that led the design and development of the WLDT framework are:\ni) Simplicity - with WLDT developers must have the possibility to easily create a new instance by using existing modules or customizing the behavior according the need of their application scenario; ii) Extensibility - while WLDT must be as simple and light as possible, the API should be also easily extendible in order to let programmers to personalize the configuration and/or to add new features loading and executing multiple modules at the same times; iii) Portability \u0026amp; Micorservice Readiness - a digital twin implemented through WLDT must be able to run on any platform without changes and customization. Our goal is to have a simple and light core engine with a strategic set of IoT-oriented features allowing the developer to easily create DT applications modeled as independent software agents and packed as microservices. In the following Figure, the main components that make up the architecture of WLDT are represented, and thus through which the individual Digital Twin is implemented. Specifically, from the image it is possible to identify the three levels on which the architecture is developed: the one related to the core of the library, the one that models the DT, and finally, that of the adapters.\nEach of this core components has the following main characteristics:\nMetrics Manager: Provides the functionalities for managing and tracking various metrics within DT instances combining both internal and custom metrics through a flexible and extensible approach. Logger: Is designed to facilitate efficient and customizable logging within implemented and deployed DTs with configurable log levels and versatile output options. Utils \u0026amp; Commons: Hold a collection of utility classes and common functionalities that can be readily employed across DT implementations ranging from handling common data structures to providing helpful tools for string manipulation. Event Communication Bus: Represents the internal Event Bus, designed to support communication between the different components of the DT\u0026rsquo;s instance. It allows defining customized events to model both physical and digital input and outputs. Each WLDT\u0026rsquo;s component can publish on the shared Event Bus and define an Event Filter to specify which types of events it is interested in managing, associating a specific callback to each one to process the different messages. Digital Twin Engine: Defines the multi-thread engine of the library allowing the execution and monitoring of multiple DTs (and their core components) simultaneously. Therefore, it is also responsible for orchestrating the different internal modules of the architecture while keeping track of each one, and it can be considered the core of the platform itself allowing the execution and control of the deployed DTs. Currently, it supports the execution of twins on the same Java process, however the same engine abstraction might be used to extend the framework to support distributed execution for example through different processes or microservices. Digital Twin: Models a modular DT structure built through the combination of core functionalities together with physical and digital adapter capabilities. This Layer includes the Digital Twin State responsible to structure the state of the DT by defining the list of properties, events, and actions. The different instances included in the lists can correspond directly to elements of the physical asset or can derive from their combination, in any case, it is the Shadowing Function (SF) that defines the mapping, following the model defined by the designer. This component also exposes a set of methods to allow SF manipulation. Every time the Digital Twin State is modified, the latter generates the corresponding DT\u0026rsquo;s event to notify all the components about the variation. Shadowing Function: It is the library component responsible for defining the behavior of the Digital Twin by interacting with the Digital Twin State. Specifically, it implements the shadowing process that allows keeping the DT synchronized with its physical entity. This component is based on a specific implementation of a WLDT Worker called Model Engine, in order to be executed by the WLDT Engine. The Shadowing Model Function is the fundamental component that must be extended by the DT designer to concretize its model. The shadowing function observes the life cycle of the Digital Twin to be notified of the different state changes. For example, it is informed when the DT enters the Bound state, i.e. when its Physical Adapters have completed the binding procedure with the physical asset. This component also allows the designer to define the behavior of the DT in case a property is modified, an event is triggered, or an action is invoked. Physical Adapter: It defines the essential functionalities that the individual extensions, related to specific protocols, must implement. As provided by the DT definition, a DT can be equipped with multiple Physical Adapters in order to manage communication with the corresponding physical entity. Each will produce a Physical Asset Description (PAD), i.e., a description of the properties, events, actions, and relationships that the physical asset exposes through the specific protocol. The DT transitions from the Unbound to the Bound state when all its Physical Adapters have produced their respective PADs. The Shadowing Function, following the DT model, selects the components of the various PADs that it is interested in managing. Digital Adapter: It provides the set of callbacks that each specific implementation can use to be notified of changes in the DT state. Symmetrically to what happens with Physical Adapters, a Digital Twin can define multiple Digital Adapters to expose its state and functionality through different protocols. Storage Layer: The storage layer has been integrated into the core library with the aim to enable a manual or automatic storage of data related to the evolution of Digital Twins state, the associated generated and processed events, and any variations involving properties, events, actions, relationships, and life cycle. Therefore, to create a Digital Twin using WLDT, it is necessary to define and instantiate a DT with its Shadowing Function and at least one Physical Adapter and one Digital Adapter, in order to enable connection with the physical entity and allow the DT to be used by external applications. Once the 3 components are defined, it is possible to instantiate the WLDT Engine and, subsequently, start the lifecycle of the DT. In the following sections we will go through the fundamental steps to start working with the library and creating all the basic modules to design, develop and execute our first Java Digital Twin.\n","date":"February 9, 2024","id":18,"permalink":"/docs/introduction/library-structure-basic-concepts/","summary":"The WLDT framework intends to maximize modularity, re-usability and flexibility in order to effectively mirror physical smart objects in their digital counterparts.","tags":"","title":"Library Structure \u0026 Basic Concepts"},{"content":" With respect to the element present in the real world, it is defined as a Physical Asset (PA) with the intention of referring to any entity that has a manifestation or relevance in the physical world and a well-defined lifespan.\nThe previous Figure schematically illustrates the main component of an abstract Digital Twin and clarifies its responsibility to be a bridge between the cyber and the physical world. The blueprint components (then mapped into the WLDT Library) are:\nPhysical Interface The entity in charge of both the initial digitalization o shadowing process and the perpetual responsibility to keep the DT and PA in synch during its life cycle. It can execute multiple Physical Asset Adapters to interact with the PA and detect and digitalize the physical event coming from the physical entity according to its nature and the supported protocols and data formats (e.g., through HTTP and JSON). Digital Interface The component complementary to the Physical Interface and in charge of handling DT\u0026rsquo;s internal variations and events towards external digital entities and consumers. It executes multiple and reusable Digital Adapters in charge of handling digital interactions and events and responsible for making the DT interoperable with external applications. DT\u0026rsquo;s Model The module defining the DT\u0026rsquo;s behaviour and its augmented functionalities. It supports the execution of different configurable and reusable modules and functionalities handling both physical and digial events according to the implemented behaviour. Furthermore, the Model is the component responsible to handle and keep updated the Digital Twin State as described in the following sections. The Digital Twin Model(M) allows capturing and representing the PA at an appropriate level of abstraction, i.e., avoiding irrelevant aspects for its purpose and modeling only domain-level information rather than technological ones. Finally, the link between the physical and digital copy is defined as shadowing. Specifically, the term defines the process that enables continuous and (almost) real-time updating of the internal state of the DT in relation to changes that occur in the PA.\nEach DT is thus equipped with an internal model, which defines how the PA is represented in the digital level. The DT\u0026rsquo;s representation denoted as Digital Twin State supported and defined through M is defined in terms of:\nProperties: represent the observable attributes of the corresponding PA as labeled data whose values can dynamically change over time, in accordance with the evolution of the PA\u0026rsquo;s state. Events: represent the domain-level events that can be observed in the PA. Relationships: represent the links that exist between the modeled PA and other physical assets of the organizations through links to their corresponding Digital Twins. Like properties, relationships can be observed, dynamically created, and change over time, but unlike properties, they are not properly part of the PA\u0026rsquo;s state but of its operational context (e.g., a DT of a robot within a production line). Actions: represent the actions that can be invoked on the PA through interaction with the DT or directly on the DT if they are not directly available on the PA (the DT is augmenting the physical capabilities). Once the model M is defined, the dynamic state of the DT (SDT) can be defined by through the combination of its properties, events, relationships and actions associated to the DT timestamp that represents the current time of synchronization between the physical and digital counterparts.\nThe Shadowing Process The shadowing process (also known as replication of digitalization) allows to keep the Digital Twin State synchronized with that of the corresponding physical resource according to what is defined by the model M. Specifically, each relevant update of the PA state (SPA) is translated into a sequence of 3 main steps:\neach relevant change in physical asset state is modeled by a physical_event (e_pa); the event is propagated to the DT; given the new physical_event, the DT\u0026rsquo;s is updated through the application of a shadowing function, which depends on the model M The shadowing process allows also the DT to reflect and invoke possible actions of the PA. The DT receives an action request (denoted as digital_action) on its digital interface, applies the shadowing function to validate it and then propagates the request through its physical interface. An important aspect to emphasize is that the request for a digital_action does not directly change the state of the DT since any changes can only occur as a result of the shadowing function from the PA to the DT, as described earlier.\n","date":"February 9, 2024","id":19,"permalink":"/docs/introduction/dt-model/","summary":"With respect to the element present in the real world, it is defined as a Physical Asset (PA) with the intention of referring to any entity that has a manifestation or relevance in the physical world and a well-defined lifespan.","tags":"","title":"DT Model"},{"content":"\rThe modeling of the concept of DT includes also the definition and characterization of its life cycle. Based on the scientific literature, we model (and then map into the library) a life cycle with 5 states through which the DT goes from when it is executed to when it is stopped. The previous Figure shows a graphical representation of the life cycle with the following steps:\nOperating \u0026amp; Not Bound: this is the state in which the DT is located following the initialization phase, indicating that all internal modules of the DT are active but there is no association yet with the corresponding PA. Bound: this is the state in which the DT transitions following the correct execution of the binding procedure. The binding procedure allows to connect the two parts and enables bidirectional flow of events. Shadowed: this is the state reached by the DT when the shadowing process begins and its state is correctly synchronized with that of the PA. Out of Sync: this is the state that determines the presence of errors in the shadowing process. When in this state, the DT is not able to handle either state alignment events or those generated by the application layer. Done: this is the state that the DT reaches when the shadowing process is stopped, but the DT continues to be active to handle requests coming from external applications. From Unbound to Bound Taking into account the target reference Life Cycle the first point to address is how we can move from an UnBound state to a Bound condition with respect to the relationship with the Physical Layer.\nThe previous Figure illustrates a simple scenario where a Physical Asset uses two protocols (P1 and P2) to communicate and it is connected to the Digital Twin through a DT\u0026rsquo;s Physical Interface enabled with two dedicated Adapters for protocol P1 and P2. In order to move from the Unbound to Bound state the DT should be aware of the description of the target asset with respect to the two protocols. For example through P1 the asset exposes telemetry data (e.g., light bulb status and energy consumption) while on P2 allows incoming action requests (e.g., turn on/off the light). The Digital Twin can start the shadowing process only when it is bound and has a description of the properties and capabilities of the associated physical counterpart. The schematic procedure is illustrated in the following Figure:\nInvolved steps are:\nThe Adapter P1 communicates with the PA through Protocol 1 and provides a Physical Asset Description from its perspective The Adapter P2 communicates with the PA through Protocol 2 and provides a Physical Asset Description from its perspective Only when all Physical Adapters have been correctly bound (it may require time) to the Physical Asset and the associated Physical Asset Descriptions have been generated, the DT can move from UnBound to Bound Main core aspects associated to the concept of Physical Asset Description (PAD) are the following:\nIt is used to describe the list of properties, actions and relationships of a Physical Asset Each Physical Adapter generates a dedicated PAD associated to its perspective on the Physical Assets and its capabilities to read data and execute actions It is a responsibility of the DT to handle multiple descriptions in order to build the digital replica It will be used by the DT to handle the shadowing process and keep the digital replica synchronized with the physical counterpart From Bound to Shadowed Following the same approach described in the previous step we need to define a procedure to allow the DT to move from a Bound state to a Shadowed condition where the twin identified the interesting capabilities of the Physical Asset that has to be digitalized and according to the received Physical Asset Descriptions start the shadowing procedure to be synchronized with the physical world.\nAs schematically illustrated in the previous Figure, involved steps are:\nThe Model defines which properties should be monitored on the Physical Asset and start observing them through the target adapters Involved Physical Adapters communicate with the Physical Asset, receive data and generate Events (ePA) to notify about physical property changes Received ePA will be used by the Digital Twin Model in order to run the Shadowing function and compute the new DT State The DT can move from the Bound to Shadowed phase until it is able to maintain a proper synchronization with the physical asset over time through its shadowing process and the generation and maintenance of the DT\u0026rsquo;s State The Digital Twin State is structured and characterized by the following elements:\nA list of properties A list of actions A list of relationships Listed elements can be directly associated to the corresponding element of the Physical Asset or generated by DT Model combining multiple physical properties, actions or relationships at the same time. The Digital Twin State can be managed through the Shadowing Function and exposes a set of methods for its manipulated. When there is a change in the DT State an event (eDT) will be generated\nThe manipulation of DT\u0026rsquo;s State generates a set of DT\u0026rsquo;s events (eDT) associated to each specific variation and evolution of the twin during its life cyle. These events are used by the Digital Interface and in particular by its Digital Adapters to expose the DT\u0026rsquo;s State, its properties and capabilities to the external digital world. At the same time, eDT can be used by Digital Adapters to trigger action on the DT and consequently to propagate (if acceptable and/or needed) the incoming request to the physical assets bound with the target DT. Supported events are illustrated in the following schema.\n","date":"February 9, 2024","id":20,"permalink":"/docs/introduction/dt-life-cycle/","summary":"The modeling of the concept of DT includes also the definition and characterization of its life cycle. Based on the scientific literature, we model (and then map into the library) a life cycle with 5 states through which the DT goes from when it is executed to when it is stopped.","tags":"","title":"DT Life Cycle"},{"content":"\rThe entire WLDT Library and the associated DTs modeling has been designed as an event-driven system where each component is (almost) fully decoupled from the other and focused on a specific responsibilities. The communication among these independent components (e.g., Physical Adapters, Digital Adapters, Model, Storage, Shadowing Function etc ..) is implemented through an event-driven system and and effective exchange of messages and depicted in the reported Figure.\nIn order to better understand the type and nature of the available events this section provides additional information about the characteristics and responsibility for each category and are of interest in the Digital Twin.\nPhysical Asset Events Those events maps every bidirectional interaction with the Physical Asset (or multiple assets) that the DT is in charge of digitalizing. Involved events are related to:\nPhysical Asset Description: Associated to any variation in the description of the Physical Asset through the structure denoted as PhysicalAssetDescription (PAD) New Physical Asset Description: Maps the availability of a new PAD from a specific target Physical Asset through a Physical Adapter Updated Physical Asset Description: Maps the availability of an updated PAD from a specific target Physical Asset through a Physical Adapter Physical Asset Variation: Associated to any variation of the Physical Asset in terms of Properties, Events and Relationships Instances (previously declared in the PAD) Property Variation: Maps a variation of a Physical Property (e.g., temperature value of 25 Celsius Degrees) Event Notification: Maps an event notification generated by the Physical Asset (e.g., Over-Heating) Relation Instance Variation: Maps a variation of Relationships instance associated to a Relationship type declared in the PAD Physical Asset Action Request: Maps an event coming from the DT\u0026rsquo;s Core for the Physical Asset (managed by the Physical Adapter) to trigger an action in the physical world (e.g., turn on the switch) Digital Twin\u0026rsquo;s Events Those events are on the other end in charge of mapping event generate by the DT itself during its evolution and across its life-cycle. They can be associated to the following aspects:\nLife Cycle Variation: Maps a change in the life cycle\u0026rsquo;s state of the DT for example moving from Bound to Synchronized DT State Variation: Maps a variation in the State of the DT communicating the new State and the list of associated changes DT State Event Notification: Maps an event generated by the DT for example mapping an event notification coming from the Physical Asset (e.g., Over-Heating) or a \u0026ldquo;new\u0026rdquo; notification from the DT (e.g., Anomaly-Detected) Digital Action Request: Maps an action request on an available action exposed by the DT and that is requested by and external application. This Action trigger can be internally managed by the DT or can generate then a trigger for a Physical Action as previously described. ","date":"September 4, 2024","id":21,"permalink":"/docs/introduction/dt-events/","summary":"The entire WLDT Library and the associated DTs modeling has been designed as an event-driven system where each component is (almost) fully decoupled from the other and focused on a specific responsibilities.","tags":"","title":"DT Events"},{"content":"The storage layer has been integrated into the core WLDT library, enabling Digital Twins to manually and automatically store data related to the evolution of their state, generated events (as illustrated in DT Events Page), and any variations involving properties, events, actions, relationships, and life cycle.\nThe WLDT Storage Layer consists of two main components:\nStorage Manager: This is the central component of the storage system, facilitating the structured and modular storage and retrieval of information. It allows developers to create and utilize various storage systems (e.g., in-memory, file-based, or DBMS) simultaneously. The Storage Layer is accessible in both read and write modes internally by the DT\u0026rsquo;s Model, and in read-only mode via the Query System by Digital Adapters. Query System: To delegate and encapsulate the responsibility of data storage within the DT\u0026rsquo;s model, a query system has been integrated. This system enables Digital Adapters to retrieve stored data and expose it according to their specific logic and implementation. The storage layer is designed for easy extension, allowing developers to create and share new storage layers (e.g., using Redis, MySQL, or MongoDB). The provided in-memory implementation serves only for basic development and testing purposes. Similarly, the Query Manager can be extended and customized by developers to implement additional query management features or to enhance the default functionalities provided by the library.\nStorage Manager The main module of the Storage Layer is the one associated to Storage Capabilities and it is composed by two main classes: StorageManager and WldStorage with the following characteristics and main methods:\nStorageManager: The StorageManager class is a class that represents the storage manager for a DigitalTwin. It is responsible for managing the storage of the data related to the DigitalTwin. It is an observer of the WldtEventBus, and it is able to save the data in the available storages. The class extends a DigitalTwinWorker, in order to allow the component to work in a structure and integrated way on a different thread that the core of a DT can coordinate starting and stopping it when required. The manager allow the usage of different storage systems at the same time in order to allow the developers to memorize the information accordingly to their need in the right storage system at the same time (e.g., REDIS for quick cached information and MongDB for historical data). Main associated methods are: putStorage(WldtStorage storage): Add a new WldtStorage to the StorageManager getStorageIdList(): Returns the list of id of the WldtStorage in the StorageManager isStorageAvailable(String storageId): Checks if a target Storage Id is available in the Storage Manager getStorage(String storageId): Get the target WldtStorage by id from the Storage Manager removeStorage(String storageId): Remove an existing WldtStorage by id from the StorageManager WldtStorage: Defines an abstract class allowing the Digital Twin developer to implement its internal storage system for the Digital Twin instance. The class defines methods for the management of: Digital Twin State storage and retrieval with the associated change list; Generated State Digital Events; Life Cycle State storage and retrieval; Physical Asset Description storage and retrieval; Physical Asset Property Variation storage and retrieval; Physical Asset Relationship Instance storage and retrieval; Digital Action Request storage and retrieval; Physical Asset Action Request storage and retrieval; Physical Asset Event Notification storage and retrieval; Each WldtStorage instance can be configured (using the right constructor method) to: Observe all Wldt events (stateEvents, physicalAssetEvents, physicalAssetActionEvents, physicalAssetDescriptionEvents, digitalActionEvents, lifeCycleEvents) Filter only for specific class of events Once the WldtStorage has been properly configured to receive target events the StorageManager automatically save information of interest for that specific storage. For example we can have a StorageA (e.g, REDIS) configured to receive all the generated events and a StorageB (e.g., MongoDB) in charge of saving only DT\u0026rsquo;s state variation over time. The default implementation of the WldtStorage is the class DefaultWldtStorage. This class provides a simple storage solution for digital twin states, digital twin state changes, physical asset events, and digital twin events. The class provides ONLY a memory based approach for storage using ArrayLists and HashMaps and more advanced solution should be implemented for production oriented Digital Twins for examples using external storage and memorization solutions. Each Record written and returned by methods available through the WldtStorage implementations are extension of the StorageRecord used to represents a single record in the storage with a unique id Methods available and implemented by WldtStorage implementations are the following grouped by categories: Digital Twin State: saveDigitalTwinState(DigitalTwinState digitalTwinState, List\u0026lt;DigitalTwinStateChange\u0026gt; digitalTwinStateChangeList): Save a new computed instance of the DT State in the Storage together with the list of the changes with respect to the previous state getLastDigitalTwinState(): Returns the latest computed Digital Twin State of the target Digital Twin instance getDigitalTwinStateCount(): Returns the number of computed and stored Digital Twin States getDigitalTwinStateInTimeRange(long startTimestampMs, long endTimestampMs): Retrieves a list of DigitalTwinState objects within the specified time range getDigitalTwinStateInRange(int startIndex, int endIndex): Retrieves a list of Digital Twin states within the specified range of indices Digital Twin State Event Notification: saveDigitalTwinStateEventNotification(DigitalTwinStateEventNotification\u0026lt;?\u0026gt; digitalTwinStateEventNotification): Save the Digital Twin State Event Notification getDigitalTwinStateEventNotificationCount(): Get the number of Digital Twin State Event Notification getDigitalTwinStateEventNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Digital Twin State Event Notification in the specified time range getDigitalTwinStateEventNotificationInRange(int startIndex, int endIndex): Get the Digital Twin State Event Notification in the specified range of indices Life Cycle State Variation: saveLifeCycleState(LifeCycleStateVariation lifeCycleStateVariation): Save the LifeCycleState of the Digital Twin getLastLifeCycleState(): Get the last LifeCycleState of the Digital Twin getLifeCycleStateCount(): Get the number of LifeCycleState of the Digital Twin getLifeCycleStateInTimeRange(long startTimestampMs, long endTimestampMs): Get the last LifeCycleState of the Digital Twin getLifeCycleStateInRange(int startIndex, int endIndex): Get the LifeCycleState of the Digital Twin in the specified range of indices Physical Asset Event Notification: savePhysicalAssetEventNotification(PhysicalAssetEventNotification physicalAssetEventNotification): Save the Physical Asset Event Notification getPhysicalAssetEventNotificationCount(): Get the number of Physical Asset Event Notification getPhysicalAssetEventNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Event Notification in the specified time range getPhysicalAssetEventNotificationInRange(int startIndex, int endIndex): Get the Physical Asset Event Notification in the specified range of indices Physical Action Request: savePhysicalAssetActionRequest(PhysicalAssetActionRequest physicalAssetActionRequest): Save Physical Asset Action Request getPhysicalAssetActionRequestCount(): Get the number of Physical Asset Action Request getPhysicalAssetActionRequestInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Action Request in the specified time range getPhysicalAssetActionRequestInRange(int startIndex, int endIndex): Get the Physical Asset Action Request in the specified range of indices Digital Action Request: saveDigitalActionRequest(DigitalActionRequest digitalActionRequest): Save a Digital Action Request getDigitalActionRequestCount(): Get the number of Digital Action Request Stored getDigitalActionRequestInTimeRange(long startTimestampMs, long endTimestampMs): Get the Digital Action Request in the specified time range getDigitalActionRequestInRange(int startIndex, int endIndex): Get the Digital Action Request in the specified range of indices Physical Asset Description (PAD) Notification New PAD Notification saveNewPhysicalAssetDescriptionNotification(PhysicalAssetDescriptionNotification physicalAssetDescriptionNotification): Save a new Physical Asset Description Available getNewPhysicalAssetDescriptionNotificationCount(): Get the number of New Physical Asset Description Notifications available getNewPhysicalAssetDescriptionNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the New Physical Asset Description Available in the specified time range getNewPhysicalAssetDescriptionNotificationInRange(int startIndex, int endIndex): Get the New Physical Asset Description Available in the specified range of indices Updated PAD Notification saveUpdatedPhysicalAssetDescriptionNotification(PhysicalAssetDescriptionNotification physicalAssetDescriptionNotification): Save the updated Physical Asset Description Notification getUpdatedPhysicalAssetDescriptionNotificationCount(): Get the number of Updated Physical Asset Description getUpdatedPhysicalAssetDescriptionNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Updated Physical Asset Description in the specified time range getUpdatedPhysicalAssetDescriptionNotificationInRange(int startIndex, int endIndex): Get the Updated Physical Asset Description in the specified range of indices Physical Asset Property Variation: savePhysicalAssetPropertyVariation(PhysicalAssetPropertyVariation physicalAssetPropertyVariation): Save the Physical Asset Property Variation getPhysicalAssetPropertyVariationCount(): Get the number of Physical Asset Property Variation getPhysicalAssetPropertyVariationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Property Variation in the specified time range getPhysicalAssetPropertyVariationInRange(int startIndex, int endIndex): Get the Physical Asset Property Variation in the specified range of indices Physical Asset Relationship Instance Notification Created Relationship Instance savePhysicalAssetRelationshipInstanceCreatedNotification(PhysicalRelationshipInstanceVariation physicalRelationshipInstanceVariation): Save the Physical Asset Relationship Instance Created Event getPhysicalAssetRelationshipInstanceCreatedNotificationCount(): Get the number of Physical Asset Relationship Instance Created Event getPhysicalAssetRelationshipInstanceCreatedNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Relationship Instance Created Event in the specified time range getPhysicalAssetRelationshipInstanceCreatedNotificationInRange(int startIndex, int endIndex): Get the Physical Asset Relationship Instance Created Event in the specified range of indices Deleted Relationship Instance savePhysicalAssetRelationshipInstanceDeletedNotification(PhysicalRelationshipInstanceVariation physicalRelationshipInstanceVariation): Save the Physical Asset Relationship Instance Updated Event getPhysicalAssetRelationshipInstanceDeletedNotificationCount(): Get the number of Physical Asset Relationship Instance Updated Event getPhysicalAssetRelationshipInstanceDeletedNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Relationship Instance Updated Event in the specified time range getPhysicalAssetRelationshipInstanceDeletedNotificationInRange(int startIndex, int endIndex): Get the Physical Asset Relationship Instance Updated Event in the specified range of indices Storage Statistics: Retrieve and returns storage statistics in terms of the number of stored records for each type and the associated time range of the stored records (start and end timestamp in milliseconds). Storage Statistics are mapped and modeled using the classes StorageStats and StorageStatsRecord. Storage Manager Code Some examples of usage for the Storage Layer are the following:\nLets\u0026rsquo; create a new Digital Twin with a single Storage in charge of automatically observe and store all the event generated and going through the target DT instance\n// Create the Digital Twin Engine DigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine(); // Create a new Digital Twin with a Demo Shadowing Function DigitalTwin digitalTwin = new DigitalTwin(TEST_DIGITAL_TWIN_ID, new DemoShadowingFunction()); // Physical Adapter Configuration DemoPhysicalAdapter physicalAdapter = new DemoPhysicalAdapter(...); digitalTwin.addPhysicalAdapter(physicalAdapter); // Digital Adapter Configuration digitalAdapter = new DemoDigitalAdapter(...); digitalTwin.addDigitalAdapter(digitalAdapter); // Create a new WldtStorage instance using the default implementation and observing all the events DefaultWldtStorage myStorage = new DefaultWldtStorage(\u0026#34;test_storage\u0026#34;, true); // Add the new Default Storage Instance to the Digital Twin Storage Manager digitalTwin.getStorageManager().putStorage(myStorage); // Add the Twin to the Engine digitalTwinEngine.addDigitalTwin(digitalTwin); // Start the Digital Twin digitalTwinEngine.startDigitalTwin(TEST_DIGITAL_TWIN_ID); Now let\u0026rsquo;s suppose to have two additional implementation of the WldtStorage class supporting Redis and MongDB and called RedisWldtStorage and MongoDbWldtStorage. We would like to use Redis to automatically observe all the events and MongoDb only to store DT\u0026rsquo;s state and life cycle variations.\n[...] // Create a new RedisWldtStorage instance using the default implementation and observing all the events RedisWldtStorage myRedisStorage = new RedisWldtStorage(\u0026#34;redis_storage\u0026#34;, true); myRedisStorage.setRedisConfiguration(myRedisConfiguration); // Add the new Redis Storage Instance to the Digital Twin Storage Manager digitalTwin.getStorageManager().putStorage(myRedisStorage); // Create a new MongoDbWldtStorage instance using the default implementation and observing only State and LifeCycle Events MongoDbWldtStorage myMongoDbStorage = new MongoDbWldtStorage(\u0026#34;mongo_db_storage\u0026#34;, true, false, false, false, false, true); myMongoDbStorage.setMongoDbConfiguration(myMongoDbConfiguration); // Add the new MongoDb Storage Instance to the Digital Twin Storage Manager digitalTwin.getStorageManager().putStorage(myRedisStorage); [...] Within the ShadowingFunction it is possible to have the reference to the StorageManager in order to access available Storage in both reading and writing mode. This is an example of how to retrieve an available WldtStorage through its id and the use it to read Properties values in a time range of the last 5 minutes:\nString TARGET_STORAGE_ID = \u0026#34;test_storage\u0026#34;; if(this.storageManager.isStorageAvailable(TARGET_STORAGE_ID)){ // Access the Storage Manager to store the last value of the property WldtStorage targetStorage = this.storageManager.getStorage(TARGET_STORAGE_ID); // Get the current time in milliseconds long endTime = System.currentTimeMillis(); // Get the Time in the last 5 minutes long startTime = endTime - (5 * 60 * 1000); // Get the last Physical Asset Action Request in the last 5 minutes List\u0026lt;PhysicalAssetPropertyVariationRecord\u0026gt; propertyVariationRecords = targetStorage.getPhysicalAssetPropertyVariationInTimeRange(startTime, endTime); for(PhysicalAssetPropertyVariationRecord propertyVariationRecord : propertyVariationRecords){ logger.info(\u0026#34;Property Variation Record: {}\u0026#34;, propertyVariationRecord); [...] } } Note: The StorageManager, as previously described, can automatically store DT-related events based on the configuration and setup of each WldtStorage instance added to the manager. However, since the ShadowingFunction has direct access to the StorageManager in both read and write modes, manual handling of data storage is also possible. To achieve this, you can disable automatic storage by setting it to false for specific event types or for all event types. This allows you to manually manage the storage of information within the ShadowingFunction.\nCustom Storage As previously mentioned, the class WldtStorage is an abstract class allowing the developer to implement its internal storage system for the Digital Twin instance. The class defines a set of abstract methods that should be implemented by the developer to shape the management of reading and writing data from and to the target Storage and associated to the identified variations and changes:\nDigital Twin State Generated State Digital Events Life Cycle State Physical Asset Description Physical Asset Property Variation Physical Asset Relationship Instance Digital Action Request Physical Asset Action Request Physical Asset Event Notification Storage Statistics According to the type of the managed resource the type of queries can be characterized in terms of:\nTime Query: Returns available records in a time range made by a start time in ms and and end time in ms Index Query: Returns available records in a index range made a start and end index Last Value Query: Return the last available value for the target resource Count Query: Returns the number of element of that specific resource All the stored and retrieve information and record as mapped into dedicated classes available in the package storage.model and associated to the different type of managed resources: digital, lifecycle, physical, state. Each record class extends the base class StorageRecord.\nA default Storage module denoted as DefaultWldtStorage is natively available in the library providing a simple in-memory storage solution but a developer can implement its own Storage module (e.g., to enable the support for MongoDb or REDIS).\nIn order to implement its own storage module the developer should extend the basic abstract class WldtStorage and implement all the supported method to handle data writing and reading. These new classes can extend also the constructor and the required information for example to handle and manager storage configuration (e.g., ip address and port of the storage system or the local folder where tha stored file should be written).\nQuery System Given the library\u0026rsquo;s goal of maximizing modularity and decoupling responsibilities among the available components, the Query System has been introduced. This system allows components external to the core responsibilities of the Digital Twin (e.g., Digital Adapters and Augmentation Functions) to retrieve stored data and use or expose it according to their specific logic and implementation. For instance, an HTTP Digital Adapter could expose stored information about a DT\u0026rsquo;s state variations over time, or a Monitoring Adapter could use available storage instances to retrieve events for a deeper understanding of the target DT instance\u0026rsquo;s behavior. The query system has been implemented entirely through dedicated events in order to maximize the decoupling of the solution and and supports at the same time both synchronous and asynchronous queries.\nThe main classes associated to the Query System are the following:\nQueryManager: This class represents the Query Manager responsible to handle the query request and manage the query execution and has been designed to be extended by the user to implement the desired query management logic (e.g., as with the DefaultQueryManager). QueryRequest: The class contains all the information needed to perform a query on the storage system QueryRequestType: This Enum represents the Query Request Type used to specify the type of query to be performed on the storage system supporting: TIME_RANGE SAMPLE_RANGE LAST_VALUE COUNT QueryResourceType: This Enum represents the Query Resource Type used to specify the type of resource to be queried on the storage system supporting the following resource types mapping those available and managed by the storage manager (and the supported and associated RequestType): PHYSICAL_ASSET_PROPERTY_VARIATION TIME_RANGE SAMPLE_RANGE COUNT PHYSICAL_ASSET_EVENT_NOTIFICATION TIME_RANGE SAMPLE_RANGE COUNT PHYSICAL_ACTION_REQUEST TIME_RANGE SAMPLE_RANGE COUNT DIGITAL_ACTION_REQUEST TIME_RANGE SAMPLE_RANGE COUNT DIGITAL_TWIN_STATE TIME_RANGE SAMPLE_RANGE COUNT LAST_VALUE NEW_PAD_NOTIFICATION TIME_RANGE SAMPLE_RANGE COUNT UPDATED_PAD_NOTIFICATION TIME_RANGE SAMPLE_RANGE COUNT PHYSICAL_RELATIONSHIP_INSTANCE_CREATED_NOTIFICATION TIME_RANGE SAMPLE_RANGE COUNT PHYSICAL_RELATIONSHIP_INSTANCE_DELETED_NOTIFICATION TIME_RANGE SAMPLE_RANGE COUNT LIFE_CYCLE_EVENT TIME_RANGE SAMPLE_RANGE COUNT LAST_VALUE STORAGE_STATS LAST_VALUE QueryExecutor: This class represents the Query Executor used to execute queries on the storage system supporting both synchronous and asynchronous query execution. Internally is implemented through an event-based mechanism to handle the query request and response QueryResult: This class represents the Query Result returned by the Query Executor containing the query results and the query status (successful or not) and error message (if any) together with also the original request IQueryResultListener: This interface represents the Query Result Listener used to receive the query results Query System Code An example of Synchronous query is:\nQueryExecutor queryExecutor = new QueryExecutor(TEST_DIGITAL_TWIN_ID, \u0026#34;query-executor\u0026#34;); // Create Query Request to the Storage Manager for the Last Digital Twin State QueryRequest queryRequest = new QueryRequest(); queryRequest.setResourceType(QueryResourceType.DIGITAL_TWIN_STATE); queryRequest.setRequestType(QueryRequestType.LAST_VALUE); // Send the Query Request to the Storage Manager for the target DT QueryResult\u0026lt;?\u0026gt; queryResult = queryExecutor.syncQueryExecute(queryRequest); Following the same approach an Asynchrounouse query can be executed as follows:\nQueryExecutor queryExecutor = new QueryExecutor(TEST_DIGITAL_TWIN_ID, \u0026#34;query-executor\u0026#34;); // Create Query Request to the Storage Manager for the Last Digital Twin State QueryRequest queryRequest = new QueryRequest(); queryRequest.setResourceType(QueryResourceType.DIGITAL_TWIN_STATE); queryRequest.setRequestType(QueryRequestType.LAST_VALUE); // Send the Query Request to the Storage Manager for the target DT queryExecutor.asyncQueryExecute(queryRequest, new IQueryResultListener() { @Override public void onQueryResult(QueryResult\u0026lt;?\u0026gt; queryResult) { [...] } }); The class DigitalAdapter has been updated adding also an internal reference to a QueryExecutor in order to simplify the interaction with the query system directly from an adapter like in the following example where we use the query Executor of the Digital Adapter invokeAction callback through its internal variable accessible through this.queryExecutor without creating a new executor:\npublic \u0026lt;T\u0026gt; void invokeAction(String actionKey, T body){ try { // Create Query Request to the Storage Manager for the Last Digital Twin State QueryRequest queryRequest = new QueryRequest(); queryRequest.setResourceType(QueryResourceType.DIGITAL_TWIN_STATE); queryRequest.setRequestType(QueryRequestType.LAST_VALUE); // Send the Query Request to the Storage Manager for the target DT QueryResult\u0026lt;?\u0026gt; queryResult = this.queryExecutor.syncQueryExecute(queryRequest); // Do Something with the Query Result for(Object result : queryResult.getResults()){ // Check the type of the Resulting class accordingly to the query if(result instanceof DigitalTwinState) logger.info(\u0026#34;LAST DT STATE: {}\u0026#34;, result); else logger.error(\u0026#34;INVALID RESULT TYPE: {}\u0026#34;, result.getClass().getName()); } logger.info(\u0026#34;INVOKING ACTION: {} BODY: {}\u0026#34;, actionKey, body); publishDigitalActionWldtEvent(actionKey, body); } catch (EventBusException e) { e.printStackTrace(); } } Custom Query Manager The class in charge of managing an incoming query is called QueryManager and it is characterized by two core methods:\nhandleQuery(QueryRequest queryRequest, Map\u0026lt;String, WldtStorage\u0026gt; storageMap): Handle Query Request allowing its management through the storage map and the associated storage objects. Uses the method getTargetStorage to select the target storage to be used to handle the query. getTargetStorage(QueryRequest queryRequest, Map\u0026lt;String, WldtStorage\u0026gt; storageMap): The method has been designed to return the desired storage object from the storage map to be used for the query management starting from the target QueryRequest and the StorageMap of the DT. In the default implementation, the method returns the first storage object available in the storage map. The QueryManager class has a list of methods that structure the type of available queries and that return an instance of QueryResult with an error and a message of \u0026ldquo;Query not supported by the current implementation !\u0026rdquo;. The list of these methods is the following:\nhandleLifeCycleEventQuery(...): Handle Life Cycle Event Query Request handlePhysicalRelationshipInstanceDeletedNotificationQuery(...): Handle Physical Relationship Instance Deleted Notification Query Request handlePhysicalRelationshipInstanceCreatedNotificationQuery(...): Handle Physical Relationship Instance Created Notification Query Request handleUpdatedPadNotification(...): Handle Updated Pad Notification Query Request handleNewPadNotification(...): Handle New Pad Notification Query Request handleDigitalActionRequestQuery(...): Handle Digital Action Request Query Request handlePhysicalActionRequestQuery(...): Handle Physical Action Request Query Request handlePhysicalAssetEventNotificationQuery(...): Handle Physical Asset Event Notification Query Request handlePhysicalAssetPropertyVariationQuery(...): Handle Physical Asset Property Variation Query Request handleStateQuery(...): Handle Digital Twin State Query Request handleStorageStatsQuery(...): Handle Storage Stats Query The library provides a default implementation that is ready to use and automatically activated in every DT instance and called DefaultQueryManager. This class extends the QueryManager class and implements the default behavior for the query management implementing each of the previous listed methods. In the default implementation the method getTargetStorage returns the first storage object available in the storage map. The behavior can be changed by overriding the method in the custom query manager implementation. In the custom implementation, the method can be used to select different storage according to the query.\nIn order to extend and customize the adopter QueryManager a developer can:\nCreate a new Class extending the QueryManager Implement (if required) a custom getTargetStorage method to return the correct available storage according to the type of request (e.g., the State of the DT are stored on MongoDB while the variation of the Physical Asset on REDIS) If required the developer can implement o change the behavior of the query manager in terms of the query management methods One a custom QueryManager has been defined it can be set and configured through the following method setQueryManager on the StorageManager of each Digital Twin:\ndigitalTwin.getStorageManager().setQueryManager(myQueryManager); ","date":"August 29, 2024","id":22,"permalink":"/docs/guides/storage-layer/","summary":"The storage layer has been integrated into the core WLDT library, enabling Digital Twins to manually and automatically store data related to the evolution of their state, generated events (as illustrated in DT Events Page), and any variations involving properties, events, actions, relationships, and life cycle.","tags":"","title":"Storage Layer"},{"content":"New Features WldtEventObserver A new class called WldtEventObserver has been introduced to allow a simplified observation of target specific events generated by the Digital Twin and its components such as adapters and the model. Main mapped events and filters are:\nState Events: State Update and State Event Notifications Physical Asset Events: Physical Property Variation, Physical Event Notification, Physical Relationship Instance Creation and Deletion Physical Asset Action Events: Physical Action Trigger Digital Action Events: Digital Action Event Physical Asset Description Events: Physical Asset Description Available and Updated Life Cycle Events: Digital Twin Life Cycle Events Query Request Events: Storage Query Request Events (See next sections for additional information) For each event type dedicated observation and un-observation methods (e.g., observePhysicalAssetEvents() and unObservePhysicalAssetEvents()) are available in order to create an instance of the observer and decide which events to receive.\nTo build a WldtEventObserver a dedicated listener IWldtEventObserverListener should be implemented by the developer to receive the callbacks related to the incoming events. All the events are of the generic type WldtEvent and it is up to the developer the validate and check the received object and if it match with the expected one.\nAn example of usage for the event observer is the following:\nWldtEventObserver eventObserver = new WldtEventObserver( \u0026#34;DT_TEST_ID_1\u0026#34;, \u0026#34;test-observer\u0026#34;, myObserverListener); // Start all the available observation eventObserver.observePhysicalAssetEvents(); eventObserver.observePhysicalAssetActionEvents(); eventObserver.observeStateEvents(); eventObserver.observeDigitalActionEvents(); eventObserver.observePhysicalAssetDescriptionEvents(); eventObserver.observeLifeCycleEvents(); The WldtEventObserver has been currently used internally within the library to simplify the implementation and usage of the Storage Layer and the associated Storage Query System as described in the dedicated sections.\nStorage Layer A new storage layer has been integrated into the core WLDT library, enabling Digital Twins (DTs) to store data related to the evolution of their state, generated events, and any variations involving properties, events, actions, relationships, and life cycle. The Storage Layer consists of two main components:\nStorage Manager: This is the central component of the storage system, facilitating the structured and modular storage and retrieval of information. It allows developers to create and utilize various storage systems (e.g., in-memory, file-based, or DBMS) simultaneously. The Storage Layer is accessible in both read and write modes internally by the DT\u0026rsquo;s Model, and in read-only mode via the Query System by Digital Adapters. Query System: To delegate and encapsulate the responsibility of data storage within the DT\u0026rsquo;s model, a query system has been integrated. This system enables Digital Adapters to retrieve stored data and expose it according to their specific logic and implementation. The storage layer is designed for easy extension, allowing developers to create and share new storage layers (e.g., using Redis, MySQL, or MongoDB). The provided in-memory implementation serves only for basic development and testing purposes. Similarly, the Query Manager can be extended and customized by developers to implement additional query management features or to enhance the default functionalities provided by the library.\nStorage Manager The main module of the Storage Layer is the one associated to Storage Capabilities and it is composed by two main classes: StorageManager and WldStorage with the following characteristics and main methods:\nStorageManager: The StorageManager class is a class that represents the storage manager for a DigitalTwin. It is responsible for managing the storage of the data related to the DigitalTwin. It is an observer of the WldtEventBus, and it is able to save the data in the available storages. The class extends a DigitalTwinWorker, in order to allow the component to work in a structure and integrated way on a different thread that the core of a DT can coordinate starting and stopping it when required. The manager allow the usage of different storage systems at the same time in order to allow the developers to memorize the information accordingly to their need in the right storage system at the same time (e.g., REDIS for quick cached information and MongDB for historical data). Main associated methods are: putStorage(WldtStorage storage): Add a new WldtStorage to the StorageManager getStorageIdList(): Returns the list of id of the WldtStorage in the StorageManager isStorageAvailable(String storageId): Checks if a target Storage Id is available in the Storage Manager getStorage(String storageId): Get the target WldtStorage by id from the Storage Manager removeStorage(String storageId): Remove an existing WldtStorage by id from the StorageManager WldtStorage: Defines an abstract class allowing the Digital Twin developer to implement its internal storage system for the Digital Twin instance. The class defines methods for the management of: Digital Twin State storage and retrieval with the associated change list; Generated State Digital Events; Life Cycle State storage and retrieval; Physical Asset Description storage and retrieval; Physical Asset Property Variation storage and retrieval; Physical Asset Relationship Instance storage and retrieval; Digital Action Request storage and retrieval; Physical Asset Action Request storage and retrieval; Physical Asset Event Notification storage and retrieval; Each WldtStorage instance can be configured (using the right constructor method) to: Observe all Wldt events (stateEvents, physicalAssetEvents, physicalAssetActionEvents, physicalAssetDescriptionEvents, digitalActionEvents, lifeCycleEvents) Filter only for specific class of events Once the WldtStorage has been properly configured to receive target events the StorageManager automatically save information of interest for that specific storage. For example we can have a StorageA (e.g, REDIS) configured to receive all the generated events and a StorageB (e.g., MongoDB) in charge of saving only DT\u0026rsquo;s state variation over time. The default implementation of the WldtStorage is the class DefaultWldtStorage. This class provides a simple storage solution for digital twin states, digital twin state changes, physical asset events, and digital twin events. The class provides ONLY a memory based approach for storage using ArrayLists and HashMaps and more advanced solution should be implemented for production oriented Digital Twins for examples using external storage and memorization solutions. Methods available and implemented by WldtStorage implementations are the following grouped by categories: Digital Twin State: saveDigitalTwinState(DigitalTwinState digitalTwinState, List\u0026lt;DigitalTwinStateChange\u0026gt; digitalTwinStateChangeList): Save a new computed instance of the DT State in the Storage together with the list of the changes with respect to the previous state getLastDigitalTwinState(): Returns the latest computed Digital Twin State of the target Digital Twin instance getDigitalTwinStateCount(): Returns the number of computed and stored Digital Twin States getDigitalTwinStateInTimeRange(long startTimestampMs, long endTimestampMs): Retrieves a list of DigitalTwinState objects within the specified time range getDigitalTwinStateInRange(int startIndex, int endIndex): Retrieves a list of Digital Twin states within the specified range of indices Digital Twin State Event Notification: saveDigitalTwinStateEventNotification(DigitalTwinStateEventNotification\u0026lt;?\u0026gt; digitalTwinStateEventNotification): Save the Digital Twin State Event Notification getDigitalTwinStateEventNotificationCount(): Get the number of Digital Twin State Event Notification getDigitalTwinStateEventNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Digital Twin State Event Notification in the specified time range getDigitalTwinStateEventNotificationInRange(int startIndex, int endIndex): Get the Digital Twin State Event Notification in the specified range of indices Life Cycle State Variation: saveLifeCycleState(LifeCycleStateVariation lifeCycleStateVariation): Save the LifeCycleState of the Digital Twin getLastLifeCycleState(): Get the last LifeCycleState of the Digital Twin getLifeCycleStateCount(): Get the number of LifeCycleState of the Digital Twin getLifeCycleStateInTimeRange(long startTimestampMs, long endTimestampMs): Get the last LifeCycleState of the Digital Twin getLifeCycleStateInRange(int startIndex, int endIndex): Get the LifeCycleState of the Digital Twin in the specified range of indices Physical Asset Event Notification: savePhysicalAssetEventNotification(PhysicalAssetEventNotification physicalAssetEventNotification): Save the Physical Asset Event Notification getPhysicalAssetEventNotificationCount(): Get the number of Physical Asset Event Notification getPhysicalAssetEventNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Event Notification in the specified time range getPhysicalAssetEventNotificationInRange(int startIndex, int endIndex): Get the Physical Asset Event Notification in the specified range of indices Physical Action Request: savePhysicalAssetActionRequest(PhysicalAssetActionRequest physicalAssetActionRequest): Save Physical Asset Action Request getPhysicalAssetActionRequestCount(): Get the number of Physical Asset Action Request getPhysicalAssetActionRequestInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Action Request in the specified time range getPhysicalAssetActionRequestInRange(int startIndex, int endIndex): Get the Physical Asset Action Request in the specified range of indices Digital Action Request: saveDigitalActionRequest(DigitalActionRequest digitalActionRequest): Save a Digital Action Request getDigitalActionRequestCount(): Get the number of Digital Action Request Stored getDigitalActionRequestInTimeRange(long startTimestampMs, long endTimestampMs): Get the Digital Action Request in the specified time range getDigitalActionRequestInRange(int startIndex, int endIndex): Get the Digital Action Request in the specified range of indices Physical Asset Description (PAD) Notification New PAD Notification saveNewPhysicalAssetDescriptionNotification(PhysicalAssetDescriptionNotification physicalAssetDescriptionNotification): Save a new Physical Asset Description Available getNewPhysicalAssetDescriptionNotificationCount(): Get the number of New Physical Asset Description Notifications available getNewPhysicalAssetDescriptionNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the New Physical Asset Description Available in the specified time range getNewPhysicalAssetDescriptionNotificationInRange(int startIndex, int endIndex): Get the New Physical Asset Description Available in the specified range of indices Updated PAD Notification saveUpdatedPhysicalAssetDescriptionNotification(PhysicalAssetDescriptionNotification physicalAssetDescriptionNotification): Save the updated Physical Asset Description Notification getUpdatedPhysicalAssetDescriptionNotificationCount(): Get the number of Updated Physical Asset Description getUpdatedPhysicalAssetDescriptionNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Updated Physical Asset Description in the specified time range getUpdatedPhysicalAssetDescriptionNotificationInRange(int startIndex, int endIndex): Get the Updated Physical Asset Description in the specified range of indices Physical Asset Property Variation: savePhysicalAssetPropertyVariation(PhysicalAssetPropertyVariation physicalAssetPropertyVariation): Save the Physical Asset Property Variation getPhysicalAssetPropertyVariationCount(): Get the number of Physical Asset Property Variation getPhysicalAssetPropertyVariationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Property Variation in the specified time range getPhysicalAssetPropertyVariationInRange(int startIndex, int endIndex): Get the Physical Asset Property Variation in the specified range of indices Physical Asset Relationship Instance Notification Created Relationship Instance savePhysicalAssetRelationshipInstanceCreatedNotification(PhysicalRelationshipInstanceVariation physicalRelationshipInstanceVariation): Save the Physical Asset Relationship Instance Created Event getPhysicalAssetRelationshipInstanceCreatedNotificationCount(): Get the number of Physical Asset Relationship Instance Created Event getPhysicalAssetRelationshipInstanceCreatedNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Relationship Instance Created Event in the specified time range getPhysicalAssetRelationshipInstanceCreatedNotificationInRange(int startIndex, int endIndex): Get the Physical Asset Relationship Instance Created Event in the specified range of indices Deleted Relationship Instance savePhysicalAssetRelationshipInstanceDeletedNotification(PhysicalRelationshipInstanceVariation physicalRelationshipInstanceVariation): Save the Physical Asset Relationship Instance Updated Event getPhysicalAssetRelationshipInstanceDeletedNotificationCount(): Get the number of Physical Asset Relationship Instance Updated Event getPhysicalAssetRelationshipInstanceDeletedNotificationInTimeRange(long startTimestampMs, long endTimestampMs): Get the Physical Asset Relationship Instance Updated Event in the specified time range getPhysicalAssetRelationshipInstanceDeletedNotificationInRange(int startIndex, int endIndex): Get the Physical Asset Relationship Instance Updated Event in the specified range of indices Some examples of usage for the Storage Layer are the following:\nLets\u0026rsquo; create a new Digital Twin with a single Storage in charge of automatically observe and store all the event generated and going through the target DT instance\n// Create the Digital Twin Engine DigitalTwinEngine digitalTwinEngine = new DigitalTwinEngine(); // Create a new Digital Twin with a Demo Shadowing Function DigitalTwin digitalTwin = new DigitalTwin(TEST_DIGITAL_TWIN_ID, new DemoShadowingFunction()); // Physical Adapter Configuration DemoPhysicalAdapter physicalAdapter = new DemoPhysicalAdapter(...); digitalTwin.addPhysicalAdapter(physicalAdapter); // Digital Adapter Configuration digitalAdapter = new DemoDigitalAdapter(...); digitalTwin.addDigitalAdapter(digitalAdapter); // Create a new WldtStorage instance using the default implementation and observing all the events DefaultWldtStorage myStorage = new DefaultWldtStorage(\u0026#34;test_storage\u0026#34;, true) // Add the new Default Storage Instance to the Digital Twin Storage Manager digitalTwin.getStorageManager().putStorage(myStorage); // Add the Twin to the Engine digitalTwinEngine.addDigitalTwin(digitalTwin); // Start the Digital Twin digitalTwinEngine.startDigitalTwin(TEST_DIGITAL_TWIN_ID); Now let\u0026rsquo;s suppose to have two additional implementation of the WldtStorage class supporting Redis and MongDB and called RedisWldtStorage and MongoDbWldtStorage. We would like to use Redis to automatically observe all the events and MongoDb only to store DT\u0026rsquo;s state and life cycle variations.\n[...] // Create a new RedisWldtStorage instance using the default implementation and observing all the events RedisWldtStorage myRedisStorage = new RedisWldtStorage(\u0026#34;redis_storage\u0026#34;, true); myRedisStorage.setRedisConfiguration(myRedisConfiguration); // Add the new Redis Storage Instance to the Digital Twin Storage Manager digitalTwin.getStorageManager().putStorage(myRedisStorage); // Create a new MongoDbWldtStorage instance using the default implementation and observing only State and LifeCycle Events MongoDbWldtStorage myMongoDbStorage = new MongoDbWldtStorage(\u0026#34;mongo_db_storage\u0026#34;, true, false, false, false, false, true); myMongoDbStorage.setMongoDbConfiguration(myMongoDbConfiguration); // Add the new MongoDb Storage Instance to the Digital Twin Storage Manager digitalTwin.getStorageManager().putStorage(myRedisStorage); [...] Within the ShadowingFunction it is possible to have the reference to the StorageManager in order to access available Storage in both reading and writing mode. This is an example of how to retrieve an available WldtStorage through its id and the use it to read Properties values in a time range of the last 5 minutes:\nString TARGET_STORAGE_ID = \u0026#34;test_storage\u0026#34;; if(this.storageManager.isStorageAvailable(TARGET_STORAGE_ID)){ // Access the Storage Manager to store the last value of the property WldtStorage targetStorage = this.storageManager.getStorage(TARGET_STORAGE_ID); // Get the current time in milliseconds long endTime = System.currentTimeMillis(); // Get the Time in the last 5 minutes long startTime = endTime - (5 * 60 * 1000); // Get the last Physical Asset Action Request in the last 5 minutes List\u0026lt;PhysicalAssetPropertyVariationRecord\u0026gt; propertyVariationRecords = targetStorage.getPhysicalAssetPropertyVariationInTimeRange(startTime, endTime); for(PhysicalAssetPropertyVariationRecord propertyVariationRecord : propertyVariationRecords){ logger.info(\u0026#34;Property Variation Record: {}\u0026#34;, propertyVariationRecord); [...] } } Note: The StorageManager, as previously described, can automatically store DT-related events based on the configuration and setup of each WldtStorage instance added to the manager. However, since the ShadowingFunction has direct access to the StorageManager in both read and write modes, manual handling of data storage is also possible. To achieve this, you can disable automatic storage by setting it to false for specific event types or for all event types. This allows you to manually manage the storage of information within the ShadowingFunction.\nQuery System Given the library\u0026rsquo;s goal of maximizing modularity and decoupling responsibilities among the available components, the Query System has been introduced. This system allows components external to the core responsibilities of the Digital Twin (e.g., Digital Adapters and Augmentation Functions) to retrieve stored data and use or expose it according to their specific logic and implementation. For instance, an HTTP Digital Adapter could expose stored information about a DT\u0026rsquo;s state variations over time, or a Monitoring Adapter could use available storage instances to retrieve events for a deeper understanding of the target DT instance\u0026rsquo;s behavior. The query system has been implemented entirely through dedicated events in order to maximize the decoupling of the solution and and supports at the same time both synchronous and asynchronous queries.\nThe main classes associated to the Query System are the following:\nQueryManager: This class represents the Query Manager responsible to handle the query request and manage the query execution and has been designed to be extended by the user to implement the desired query management logic (e.g., as with the DefaultQueryManager). QueryRequest: The class contains all the information needed to perform a query on the storage system QueryRequestType: This Enum represents the Query Request Type used to specify the type of query to be performed on the storage system supporting: TIME_RANGE SAMPLE_RANGE LAST_VALUE COUNT QueryResourceType: This Enum represents the Query Resource Type used to specify the type of resource to be queried on the storage system supporting the following resource types mapping those available and managed by the storage manager: PHYSICAL_ASSET_PROPERTY_VARIATION PHYSICAL_ASSET_EVENT_NOTIFICATION PHYSICAL_ACTION_REQUEST DIGITAL_ACTION_REQUEST DIGITAL_TWIN_STATE NEW_PAD_NOTIFICATION UPDATED_PAD_NOTIFICATION PHYSICAL_RELATIONSHIP_INSTANCE_CREATED_NOTIFICATION PHYSICAL_RELATIONSHIP_INSTANCE_DELETED_NOTIFICATION LIFE_CYCLE_EVENT QueryExecutor: This class represents the Query Executor used to execute queries on the storage system supporting both synchronous and asynchronous query execution. Internally is implemented through an event-based mechanism to handle the query request and response QueryResult: This class represents the Query Result returned by the Query Executor containing the query results and the query status (successful or not) and error message (if any) together with also the original request IQueryResultListener: This interface represents the Query Result Listener used to receive the query results An example of Synchronous query is:\nQueryExecutor queryExecutor = new QueryExecutor(TEST_DIGITAL_TWIN_ID, \u0026#34;query-executor\u0026#34;); // Create Query Request to the Storage Manager for the Last Digital Twin State QueryRequest queryRequest = new QueryRequest(); queryRequest.setResourceType(QueryResourceType.DIGITAL_TWIN_STATE); queryRequest.setRequestType(QueryRequestType.LAST_VALUE); // Send the Query Request to the Storage Manager for the target DT QueryResult\u0026lt;?\u0026gt; queryResult = queryExecutor.syncQueryExecute(queryRequest); Following the same approach an Asynchrounouse query can be executed as follows:\nQueryExecutor queryExecutor = new QueryExecutor(TEST_DIGITAL_TWIN_ID, \u0026#34;query-executor\u0026#34;); // Create Query Request to the Storage Manager for the Last Digital Twin State QueryRequest queryRequest = new QueryRequest(); queryRequest.setResourceType(QueryResourceType.DIGITAL_TWIN_STATE); queryRequest.setRequestType(QueryRequestType.LAST_VALUE); // Send the Query Request to the Storage Manager for the target DT queryExecutor.asyncQueryExecute(queryRequest, new IQueryResultListener() { @Override public void onQueryResult(QueryResult\u0026lt;?\u0026gt; queryResult) { [...] } }); The class DigitalAdapter has been updated adding also an internal reference to a QueryExecutor in order to simplify the interaction with the query system directly from an adapter like in the following example where we use the query Executor of the Digital Adapter invokeAction callback through its internal variable accessible through this.queryExecutor without creating a new executor:\npublic \u0026lt;T\u0026gt; void invokeAction(String actionKey, T body){ try { // Create Query Request to the Storage Manager for the Last Digital Twin State QueryRequest queryRequest = new QueryRequest(); queryRequest.setResourceType(QueryResourceType.DIGITAL_TWIN_STATE); queryRequest.setRequestType(QueryRequestType.LAST_VALUE); // Send the Query Request to the Storage Manager for the target DT QueryResult\u0026lt;?\u0026gt; queryResult = this.queryExecutor.syncQueryExecute(queryRequest); // Do Something with the Query Result for(Object result : queryResult.getResults()){ // Check the type of the Resulting class accordingly to the query if(result instanceof DigitalTwinState) logger.info(\u0026#34;LAST DT STATE: {}\u0026#34;, result); else logger.error(\u0026#34;INVALID RESULT TYPE: {}\u0026#34;, result.getClass().getName()); } logger.info(\u0026#34;INVOKING ACTION: {} BODY: {}\u0026#34;, actionKey, body); publishDigitalActionWldtEvent(actionKey, body); } catch (EventBusException e) { e.printStackTrace(); } } Migration Info: 0.3.0 - 0.4.0 Now PhysicalAssetRelationship constructor has also the type in order to match the DigitalTwinStateRelationship and simplify its management The method notifyDigitalTwinStateEvent throws only the Exception WldtDigitalTwinStateEventNotificationException while EventBusException has been removed Additional Improvements \u0026amp; Fixed Bugs Synchronized the update of the current DT Life Cycle State in order to avoid wrong data The WldtEventBus now supports the use of topics Wildcard (at the moment only multi-level with the character *). For example with this approach is possible to subscribe to all the events associated to property variations (topic: dt.physical.event.property.*). New methods added to WldtEventBus are: matchWildCardType(String eventType, String filterType): Check if the provided event type match the WildCard Type isWildCardType(String filterEventType): Check if the provided event type is a WildCard Type The class WldtEventTypes has been introduced to contain all the event types in the WLDT Framework and support internal message exchange. Includes types for events associated and adopted by: i) Physical Adapters; ii) Model and Shadowing Function; and iii) Digital Adapters. The EventManager class has been added to centralize and simplify the event management in the WLDT Framework providing a set of static methods to publish events associated to a target digital twin and publisher (e.g., the physical adapter of the twin). Now PhysicalAssetRelationship class has also the type in order to match the DigitalTwinStateRelationship and simplify its management The internal class ModelEngine has been renamed into DigitalTwinModel as an initial update for further development of the next version 0.5.0 where the structure of the DT\u0026rsquo;s Model and the associated classes will be improved ","date":"August 29, 2024","id":23,"permalink":"/docs/change-logs/change-log-0.4.0/","summary":"New Features WldtEventObserver A new class called WldtEventObserver has been introduced to allow a simplified observation of target specific events generated by the Digital Twin and its components such as adapters and the model.","tags":"","title":"Change Log 0.4.0"},{"content":"","date":"September 7, 2023","id":24,"permalink":"/docs/","summary":"","tags":"","title":"Docs"},{"content":"Welcome to White Label Digital Twins (WLDT), an open-source project dedicated to supporting the design, development, and deployment of Digital Twins within the Internet of Things (IoT) ecosystems.\nThe WLDT library has been designed to align with the latest DT definitions from both Industrial and Scientific domains. It identifies DTs as active, flexible, and scalable software components. Our library aims to provide developers with the tools and resources necessary to create robust Digital Twins that effectively simulate and monitor physical assets within IoT environments.\nWhether you\u0026rsquo;re working on IoT, Industrial IoT (IIoT) applications, Smart Cities projects, or any other IoT-related endeavor, the WLDT library offers a versatile solution for implementing Digital Twins that accurately represent real-world objects and support informed decision-making processes.\n💻 Team \u0026amp; Mantainers [Founders \u0026amp; Main Contributors] Marco Picone - University of Modena \u0026amp; Reggio Emilia, Italy - (Link) [Key Contributors] Samuele Burattini - University of Bologna, Italy - (Link) [Additional Contributors] Marta Spadoni - University of Bologna, Italy - Master Thesis 2022 📜 Scientitic Citation \u0026amp; References If you use the WLDT Library in a Scientific Paper please use this reference:\n@article{PICONE2021100661, title = {WLDT: A general purpose library to build IoT digital twins}, journal = {SoftwareX}, volume = {13}, pages = {100661}, year = {2021}, issn = {2352-7110}, doi = {https://doi.org/10.1016/j.softx.2021.100661}, url = {https://www.sciencedirect.com/science/article/pii/S2352711021000066}, author = {Marco Picone and Marco Mamei and Franco Zambonelli}, keywords = {Internet of Things, Digital twin, Library, Software agent} } 📨 Community Join our community and contribute to the advancement of Digital Twin technology with White Label Digital Twins!\nWLDT questions, feedback and discussions are tracked using slack channels in the WLDT Slack Workspace.\nThe workspace is available here: WLDT Slack Workspace\nNew users first need to join the MEC Sandbox slack workspace by creating a new account using the invitation link provided here: Join the WLDT Slack Workspace\n🐛 Reporting Issues WLDT issues should be reported on Slack, where they can be discussed with the core team that maintains the WLDT Library.\n","date":"March 13, 2024","id":25,"permalink":"/about/","summary":"Welcome to White Label Digital Twins (WLDT), an open-source project dedicated to supporting the design, development, and deployment of Digital Twins within the Internet of Things (IoT) ecosystems.","tags":"","title":"About WLDT Library"},{"content":" What is a digital Twin? A Digital Twin (DT) is a comprehensive software representation of any individual Physical Asset (PA) in the real world.\nIt includes the properties, conditions, relationships, and behavior(s) of the real-life object through models and data.\nA Digital Twin is a set of realistic models that can digitalize an object’s behavior in the deployed environment and has the responsibility to represent and reflect its physical counterpart over time maintaining its digital replica across the object’s entire lifecycle.\nWhat can WLDT do for me? The White Label Digital Twin (WLDT) library aims to support the design, development, and deployment of Digital Twins within the Internet of Things (IoT) ecosystems.\nThe library has been designed following the latest DT definitions coming from both Industrial and Scientific domains and identifying DTs as active, flexible and scalable software components.\nScientitic Citation \u0026amp; Reference If you use the WLDT Library in a Scientific Paper refer to the About Page for additional information and scientific references. Thanks :)\n","date":"October 6, 2023","id":26,"permalink":"/","summary":"What is a digital Twin? A Digital Twin (DT) is a comprehensive software representation of any individual Physical Asset (PA) in the real world.","tags":"","title":"White Label Digital Twins"},{"content":"","date":"September 7, 2023","id":27,"permalink":"/privacy/","summary":"","tags":"","title":"Privacy Policy"},{"content":"","date":"January 1, 0001","id":28,"permalink":"/categories/","summary":"","tags":"","title":"Categories"},{"content":"","date":"January 1, 0001","id":29,"permalink":"/contributors/","summary":"","tags":"","title":"Contributors"},{"content":"","date":"January 1, 0001","id":30,"permalink":"/tags/","summary":"","tags":"","title":"Tags"}] \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index b8f2299..d8750d1 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1 +1 @@ -https://wldt.github.io/en/sitemap.xml2024-03-15T10:45:36+01:00 \ No newline at end of file +https://wldt.github.io/en/sitemap.xml2024-09-05T15:02:33+02:00 \ No newline at end of file