Skip to content

Commit e148e52

Browse files
committed
Files header updated, README updated
1 parent 845d44d commit e148e52

77 files changed

Lines changed: 722 additions & 39 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,9 @@ public class TestPhysicalAdapter extends PhysicalAdapter {
616616
}
617617
```
618618

619+
Both Physical Adapters and Digital Adapters can be defined natively with a custom configuration provided by the developer
620+
as illustrated in the dedicated Section: [Configurable Physical & Digital Adapters](#configurable-physical-and-digital-adapters).
621+
619622
### Shadowing Function
620623

621624
After the definition of the Physical Adapter it is time to start implementing the core of our DT through the definition of
@@ -1353,6 +1356,9 @@ protected void onDigitalTwinStateEventNotificationReceived(DigitalTwinStateEvent
13531356
}
13541357
```
13551358
1359+
Both Physical Adapters and Digital Adapters can be defined natively with a custom configuration provided by the developer
1360+
as illustrated in the dedicated Section: [Configurable Physical & Digital Adapters](#configurable-physical-and-digital-adapters).
1361+
13561362
## Digital Twin Process
13571363
13581364
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
@@ -1691,3 +1697,286 @@ protected void onStateChangeRelationshipInstanceDeleted(DigitalTwinStateRelation
16911697
System.out.println("[TestDigitalAdapter] -> onStateChangeRelationshipInstanceDeleted(): " + digitalTwinStateRelationshipInstance);
16921698
}
16931699
```
1700+
1701+
## Configurable Physical and Digital Adapters
1702+
1703+
The WLDT library provides a native method to define Configurable Physical ad Digital Adapters specifying a
1704+
custom configuration class passed as parameter in the constructor.
1705+
1706+
Starting with the Physical Adapter created in the previous example ```TestPhysicalAdapter ``` instead of extending the
1707+
base class ```PhysicalAdapter``` we can extend now ```ConfigurablePhysicalAdapter<C>``` where ```C``` is the name of the
1708+
that we would like to use as configuration.
1709+
1710+
In our example we can create a simple configuration class called ```TestPhysicalAdapterConfiguration``` where we move
1711+
the constant variable used to implement the behaviour of our demo physical adapter. The resulting class will be the
1712+
following:
1713+
1714+
```java
1715+
public class TestPhysicalAdapterConfiguration {
1716+
1717+
private final static int MESSAGE_UPDATE_TIME = 1000;
1718+
private final static int MESSAGE_UPDATE_NUMBER = 10;
1719+
private final static double TEMPERATURE_MIN_VALUE = 20;
1720+
private final static double TEMPERATURE_MAX_VALUE = 30;
1721+
1722+
private int messageUpdateTime = MESSAGE_UPDATE_TIME;
1723+
1724+
private int messageUpdateNumber = MESSAGE_UPDATE_NUMBER;
1725+
1726+
private double temperatureMinValue = TEMPERATURE_MIN_VALUE;
1727+
1728+
private double temperatureMaxValue = TEMPERATURE_MAX_VALUE;
1729+
1730+
public TestPhysicalAdapterConfiguration() {
1731+
}
1732+
1733+
public TestPhysicalAdapterConfiguration(int messageUpdateTime, int messageUpdateNumber, double temperatureMinValue, double temperatureMaxValue) {
1734+
this.messageUpdateTime = messageUpdateTime;
1735+
this.messageUpdateNumber = messageUpdateNumber;
1736+
this.temperatureMinValue = temperatureMinValue;
1737+
this.temperatureMaxValue = temperatureMaxValue;
1738+
}
1739+
1740+
public int getMessageUpdateTime() {
1741+
return messageUpdateTime;
1742+
}
1743+
1744+
public void setMessageUpdateTime(int messageUpdateTime) {
1745+
this.messageUpdateTime = messageUpdateTime;
1746+
}
1747+
1748+
public int getMessageUpdateNumber() {
1749+
return messageUpdateNumber;
1750+
}
1751+
1752+
public void setMessageUpdateNumber(int messageUpdateNumber) {
1753+
this.messageUpdateNumber = messageUpdateNumber;
1754+
}
1755+
1756+
public double getTemperatureMinValue() {
1757+
return temperatureMinValue;
1758+
}
1759+
1760+
public void setTemperatureMinValue(double temperatureMinValue) {
1761+
this.temperatureMinValue = temperatureMinValue;
1762+
}
1763+
1764+
public double getTemperatureMaxValue() {
1765+
return temperatureMaxValue;
1766+
}
1767+
1768+
public void setTemperatureMaxValue(double temperatureMaxValue) {
1769+
this.temperatureMaxValue = temperatureMaxValue;
1770+
}
1771+
}
1772+
```
1773+
1774+
Now we can create or update our Physical Adapter extending ```ConfigurablePhysicalAdapter<DemoPhysicalAdapterConfiguration>```
1775+
as illustrated in the following snippet:
1776+
1777+
```java
1778+
public class TestPhysicalAdapter extends ConfigurablePhysicalAdapter<DemoPhysicalAdapterConfiguration> {
1779+
[...]
1780+
}
1781+
```
1782+
1783+
Extending this class also the constructor should be updated getting as a parameter the expected configuration instance.
1784+
Our constructor will be the following:
1785+
1786+
```java
1787+
public TestConfPhysicalAdapter(String id, DemoPhysicalAdapterConfiguration configuration) {
1788+
super(id, configuration);
1789+
}
1790+
```
1791+
1792+
After that change since we removed and moved the used constant values into the new Configuration class we have also to
1793+
update the ```deviceEmulation()``` method having access to the configuration through the method ```getConfiguration()``` or ```this.getConfiguration()```
1794+
directly on the adapter.
1795+
1796+
```java
1797+
private Runnable deviceEmulation(){
1798+
return () -> {
1799+
try {
1800+
1801+
1802+
System.out.println("[DemoPhysicalAdapter] -> Sleeping before Starting Physical Device Emulation ...");
1803+
1804+
//Sleep 5 seconds to emulate device startup
1805+
Thread.sleep(10000);
1806+
1807+
System.out.println("[DemoPhysicalAdapter] -> Starting Physical Device Emulation ...");
1808+
1809+
//Create a new random object to emulate temperature variations
1810+
Random r = new Random();
1811+
1812+
//Publish an initial Event for a normal condition
1813+
publishPhysicalAssetEventWldtEvent(new PhysicalAssetEventWldtEvent<>(OVERHEATING_EVENT_KEY, "normal"));
1814+
1815+
//Emulate the generation on 'n' temperature measurements
1816+
for(int i = 0; i < getConfiguration().getMessageUpdateNumber(); i++){
1817+
1818+
//Sleep to emulate sensor measurement
1819+
Thread.sleep(getConfiguration().getMessageUpdateTime());
1820+
1821+
//Update the
1822+
double randomTemperature = getConfiguration().getTemperatureMinValue() + (getConfiguration().getTemperatureMaxValue() - getConfiguration().getTemperatureMinValue()) * r.nextDouble();
1823+
1824+
//Create a new event to notify the variation of a Physical Property
1825+
PhysicalAssetPropertyWldtEvent<Double> newPhysicalPropertyEvent = new PhysicalAssetPropertyWldtEvent<>(TEMPERATURE_PROPERTY_KEY, randomTemperature);
1826+
1827+
//Publish the WLDTEvent associated to the Physical Property Variation
1828+
publishPhysicalAssetPropertyWldtEvent(newPhysicalPropertyEvent);
1829+
}
1830+
1831+
//Publish a demo Physical Event associated to a 'critical' overheating condition
1832+
publishPhysicalAssetEventWldtEvent(new PhysicalAssetEventWldtEvent<>(OVERHEATING_EVENT_KEY, "critical"));
1833+
1834+
} catch (EventBusException | InterruptedException e) {
1835+
e.printStackTrace();
1836+
}
1837+
};
1838+
}
1839+
```
1840+
1841+
A similar approach can be adopted also for the Digital Adapter with the small difference that the base class
1842+
```DigitalAdapter``` already allow the possibility to specify a configuration. For this reason in the previous example
1843+
we extended ```DigitalAdapter<Void>``` avoiding to specifying a configuration.
1844+
1845+
In this updated version we can create a new ```TestDigitalAdapterConfiguration``` class containing the parameter association
1846+
to the emulation of the action and then update our adapter to support the new configuration. Our new configuration class will be:
1847+
1848+
```java
1849+
public class TestDigitalAdapterConfiguration {
1850+
1851+
private static final int SLEEP_TIME_MS = 1000;
1852+
1853+
private static final int EMULATED_ACTION_COUNT = 5;
1854+
1855+
private final static double TEMPERATURE_MIN_VALUE = 20;
1856+
1857+
private final static double TEMPERATURE_MAX_VALUE = 30;
1858+
1859+
private int sleepTimeMs = SLEEP_TIME_MS;
1860+
1861+
private int emulatedActionCount = EMULATED_ACTION_COUNT;
1862+
1863+
private double temperatureMinValue = TEMPERATURE_MIN_VALUE;
1864+
1865+
private double temperatureMaxValue = TEMPERATURE_MAX_VALUE;
1866+
1867+
public TestDigitalAdapterConfiguration() {
1868+
}
1869+
1870+
public TestDigitalAdapterConfiguration(int sleepTimeMs, int emulatedActionCount, double temperatureMinValue, double temperatureMaxValue) {
1871+
this.sleepTimeMs = sleepTimeMs;
1872+
this.emulatedActionCount = emulatedActionCount;
1873+
this.temperatureMinValue = temperatureMinValue;
1874+
this.temperatureMaxValue = temperatureMaxValue;
1875+
}
1876+
1877+
public int getSleepTimeMs() {
1878+
return sleepTimeMs;
1879+
}
1880+
1881+
public void setSleepTimeMs(int sleepTimeMs) {
1882+
this.sleepTimeMs = sleepTimeMs;
1883+
}
1884+
1885+
public int getEmulatedActionCount() {
1886+
return emulatedActionCount;
1887+
}
1888+
1889+
public void setEmulatedActionCount(int emulatedActionCount) {
1890+
this.emulatedActionCount = emulatedActionCount;
1891+
}
1892+
1893+
public double getTemperatureMinValue() {
1894+
return temperatureMinValue;
1895+
}
1896+
1897+
public void setTemperatureMinValue(double temperatureMinValue) {
1898+
this.temperatureMinValue = temperatureMinValue;
1899+
}
1900+
1901+
public double getTemperatureMaxValue() {
1902+
return temperatureMaxValue;
1903+
}
1904+
1905+
public void setTemperatureMaxValue(double temperatureMaxValue) {
1906+
this.temperatureMaxValue = temperatureMaxValue;
1907+
}
1908+
}
1909+
```
1910+
1911+
After that we can update the declaration of our Digital Adapter and modify its constructor to accept the configuration.
1912+
The resulting class will be:
1913+
1914+
```java
1915+
public class TestDigitalAdapter extends DigitalAdapter<TestDigitalAdapterConfiguration> {
1916+
1917+
public TestDigitalAdapter(String id, TestDigitalAdapterConfiguration configuration) {
1918+
super(id, configuration);
1919+
}
1920+
1921+
[...]
1922+
}
1923+
```
1924+
1925+
Of course the possibility to have this configuration will allow us to improve the ```emulateIncomingDigitalAction``` method
1926+
in the following way having access to the configuration through the method ```getConfiguration()``` or ```this.getConfiguration()```
1927+
directly on the adapter:
1928+
1929+
```java
1930+
private Runnable emulateIncomingDigitalAction(){
1931+
return () -> {
1932+
try {
1933+
1934+
System.out.println("[DemoDigitalAdapter] -> Sleeping before Emulating Incoming Digital Action ...");
1935+
Thread.sleep(5000);
1936+
Random random = new Random();
1937+
1938+
//Emulate the generation on 'n' temperature measurements
1939+
for(int i = 0; i < getConfiguration().getEmulatedActionCount(); i++){
1940+
1941+
//Sleep to emulate sensor measurement
1942+
Thread.sleep(getConfiguration().getSleepTimeMs());
1943+
1944+
double randomTemperature = getConfiguration().getTemperatureMinValue() + (getConfiguration().getTemperatureMaxValue() - getConfiguration().getTemperatureMinValue()) * random.nextDouble();
1945+
publishDigitalActionWldtEvent("set-temperature-action-key", randomTemperature);
1946+
1947+
}
1948+
1949+
} catch (Exception e) {
1950+
e.printStackTrace();
1951+
}
1952+
};
1953+
}
1954+
```
1955+
1956+
When we have updated both adapters making them configurable we can update our ```main``` function in the process
1957+
that we have previouly device using the updated adapters and passing the configurations:
1958+
1959+
````java
1960+
public class TestDigitalTwin {
1961+
1962+
public static void main(String[] args) {
1963+
try{
1964+
1965+
WldtEngine digitalTwinEngine = new WldtEngine(new DemoShadowingFunction("test-shadowing-function"), "test-digital-twin");
1966+
1967+
//Default Physical and Digital Adapter
1968+
//digitalTwinEngine.addPhysicalAdapter(new TestPhysicalAdapter("test-physical-adapter"));
1969+
//digitalTwinEngine.addDigitalAdapter(new TestDigitalAdapter("test-digital-adapter"));
1970+
1971+
//Physical and Digital Adapters with Configuration
1972+
digitalTwinEngine.addPhysicalAdapter(new TestConfPhysicalAdapter("test-physical-adapter", new TestPhysicalAdapterConfiguration()));
1973+
digitalTwinEngine.addDigitalAdapter(new TestConfDigitalAdapter("test-digital-adapter", new TestDigitalAdapterConfiguration()));
1974+
1975+
digitalTwinEngine.startLifeCycle();
1976+
1977+
}catch (Exception e){
1978+
e.printStackTrace();
1979+
}
1980+
}
1981+
}
1982+
````

src/main/java/it/wldt/adapter/digital/DigitalAdapter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
* Authors:
2424
* Marco Picone, Ph.D. (picone.m@gmail.com)
2525
* Marta Spadoni (marta.spadoni2@studio.unibo.it)
26+
*
2627
* Date: 01/02/2023
2728
* Project: White Label Digital Twin Java Framework - (whitelabel-digitaltwin)
2829
*

src/main/java/it/wldt/adapter/digital/DigitalAdapterLifeCycleListener.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44

55
import java.util.Map;
66

7+
/**
8+
* Authors:
9+
* Marco Picone, Ph.D. (picone.m@gmail.com)
10+
* Date: 01/02/2023
11+
* Project: White Label Digital Twin Java Framework - (whitelabel-digitaltwin)
12+
*
13+
* Internal Listener to monitor the DT Life Cycle
14+
*/
715
public interface DigitalAdapterLifeCycleListener {
816
void onPhysicalAdapterBound(String adapterId, PhysicalAssetDescription physicalAssetDescription);
917

src/main/java/it/wldt/adapter/digital/DigitalAdapterListener.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
/**
44
* Authors:
55
* Marco Picone, Ph.D. (picone.m@gmail.com)
6+
*
67
* Date: 01/02/2023
78
* Project: White Label Digital Twin Java Framework - (whitelabel-digitaltwin)
89
*

src/main/java/it/wldt/adapter/digital/event/DigitalActionWldtEvent.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55

66
import java.util.Map;
77

8+
/**
9+
* Authors:
10+
* Marco Picone, Ph.D. (picone.m@gmail.com)
11+
* Date: 01/02/2023
12+
* Project: White Label Digital Twin Java Framework - (whitelabel-digitaltwin)
13+
*
14+
* An Action targeting the DT received on the Digital Interface and that should reach the Shadowing Function
15+
* for its management
16+
*/
817
public class DigitalActionWldtEvent<T> extends WldtEvent<T> {
918

1019
public static final String EVENT_BASIC_TYPE = "dt.digital.event.action";

src/main/java/it/wldt/adapter/digital/event/DigitalWldtEvent.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55

66
import java.util.Map;
77

8+
/**
9+
* Authors:
10+
* Marco Picone, Ph.D. (picone.m@gmail.com)
11+
* Date: 01/02/2023
12+
* Project: White Label Digital Twin Java Framework - (whitelabel-digitaltwin)
13+
*
14+
* A Digital Event that can be used by the Digital Adapter
15+
*/
816
public class DigitalWldtEvent<T> extends WldtEvent<T> {
917

1018
public static final String DIGITAL_EVENT_BASIC_TYPE = "dt.digital.event";

src/main/java/it/wldt/adapter/physical/ConfigurablePhysicalAdapter.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
package it.wldt.adapter.physical;
22

3+
/**
4+
* Authors:
5+
* Marco Picone, Ph.D. (picone.m@gmail.com)
6+
* Date: 01/02/2023
7+
* Project: White Label Digital Twin Java Framework - (whitelabel-digitaltwin)
8+
*
9+
* A variation of the PhysicalAdapter with the possibility to specify a target Configuration (with a specific class)
10+
* that can be used to customize/adapt the behaviour of the adapter
11+
*/
312
public abstract class ConfigurablePhysicalAdapter<C> extends PhysicalAdapter {
413

514
private C configuration;

src/main/java/it/wldt/adapter/physical/PhysicalAdapter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* Marco Picone, Ph.D. (picone.m@gmail.com)
2020
* Marta Spadoni (marta.spadoni2@studio.unibo.it)
2121
* Samuele Burattini (samuele.burattini@unibo.it)
22+
*
2223
* Date: 01/02/2023
2324
* Project: White Label Digital Twin Java Framework - (whitelabel-digitaltwin)
2425
*

0 commit comments

Comments
 (0)