BaSyx examples update
diff --git a/examples/basys.examples/examples/org/eclipse/basyx/examples/mockup/device/ControllableTCPDeviceMockup.java b/examples/basys.examples/examples/org/eclipse/basyx/examples/mockup/device/ControllableTCPDeviceMockup.java
index d1c788c..c5c02d1 100644
--- a/examples/basys.examples/examples/org/eclipse/basyx/examples/mockup/device/ControllableTCPDeviceMockup.java
+++ b/examples/basys.examples/examples/org/eclipse/basyx/examples/mockup/device/ControllableTCPDeviceMockup.java
@@ -1,9 +1,6 @@
package org.eclipse.basyx.examples.mockup.device;
-import org.eclipse.basyx.components.controlcomponent.ExecutionState;
-import org.eclipse.basyx.components.device.BaseTCPDevice;
-import org.eclipse.basyx.components.netcomm.NetworkReceiver;
-import org.eclipse.basyx.components.netcomm.TCPClient;
+import org.eclipse.basyx.components.device.BaseTCPControllableDevice;
@@ -16,16 +13,9 @@
* @author kuhn
*
*/
-public class ControllableTCPDeviceMockup extends BaseTCPDevice implements NetworkReceiver {
+public class ControllableTCPDeviceMockup extends BaseTCPControllableDevice {
- /**
- * Receive thread
- */
- protected Thread rxThread = null;
-
-
-
/**
* Constructor
@@ -35,82 +25,17 @@
super(port);
}
-
+
/**
- * Start the device
+ * Indicate device status change to device manager
*/
@Override
- public void start() {
+ protected void statusChange(String newStatus) {
// Invoke base implementation
- super.start();
+ super.statusChange(newStatus);
- // Add this component as message listener
- communicationClient.addTCPMessageListener(this);
- // - Start receive thread
- rxThread = new Thread(communicationClient);
- // - Start receiving
- rxThread.start();
- }
-
-
- /**
- * Stop the device
- */
- @Override
- public void stop() {
- // Invoke base implementation
- super.stop();
-
- // End communication
- communicationClient.close();
- }
-
-
- /**
- * Wait for end of all threads
- */
- @Override
- public void waitFor() {
- // Invoke base implementation
- super.waitFor();
-
- // Wait for end of TCP thread
- try {rxThread.join();} catch (InterruptedException e) {e.printStackTrace();}
- }
-
-
-
-
- /**
- * Changed operation mode
- */
- protected void onOperationModeChange(String newOperationMode) {
- // Do nothing
- }
-
-
- /**
- * State change
- */
- protected void onStateChange(ExecutionState newExState) {
- // Do nothing
- }
-
-
- /**
- * A message has been received
- */
- @Override
- public void onReceive(byte[] message) {
- // Convert message to String
- String rxMessage = TCPClient.toString(message);
-
- // Process message
- if (rxMessage.startsWith("state:")) {onStateChange(ExecutionState.byValue(rxMessage.substring("state:".length()))); return;}
- if (rxMessage.startsWith("opMode:")) {onOperationModeChange(rxMessage.substring("opMode:".length())); return;}
-
- // Indicate exception
- throw new RuntimeException("Unexpected message received:"+rxMessage);
+ // Write bytes to device manager
+ communicationClient.sendMessage("status:"+newStatus+"\n");
}
}
diff --git a/examples/basys.examples/examples/org/eclipse/basyx/examples/mockup/device/SmartBaSyxTCPDeviceMockup.java b/examples/basys.examples/examples/org/eclipse/basyx/examples/mockup/device/SmartBaSyxTCPDeviceMockup.java
index ad9a74f..c1c0ce9 100644
--- a/examples/basys.examples/examples/org/eclipse/basyx/examples/mockup/device/SmartBaSyxTCPDeviceMockup.java
+++ b/examples/basys.examples/examples/org/eclipse/basyx/examples/mockup/device/SmartBaSyxTCPDeviceMockup.java
@@ -84,6 +84,15 @@
/**
+ * Indicate device service end
+ */
+ @Override
+ protected void onServiceEnd() {
+ // Do nothing
+ }
+
+
+ /**
* Smart device control component indicates an execution state change
*/
@Override
@@ -91,11 +100,6 @@
// Invoke base implementation
super.onChangedExecutionState(newExecutionState);
- // Communicate device state change to asset administration shell
- //statusChange(newExecutionState.getValue());
- System.out.println("Changing to:"+newExecutionState.getValue());
-
-
// Update property "properties/status" in external AAS
aasServerConnection.updateElementValue(lookupURN("Status").getEncodedURN()+"/properties/status", newExecutionState.getValue());
}
@@ -144,21 +148,16 @@
// Register AAS and sub models in directory (push AAS descriptor to server)
- // - Delete AAS registration for a fresh start - ignore if URL was not found. In this case, there was
- // no previous registration and the registry was clean
- getRegistry().delete(lookupURN("AAS"));
// - AAS repository server URL
String aasRepoURL = "http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer";
- // - Create an AAS descriptor
- AASDescriptor deviceAASDescriptor = new AASDescriptor(lookupURN("AAS"), aasRepoURL);
- // - Add sub model descriptors
- deviceAASDescriptor.addSubmodelDescriptor(lookupURN("Status"), aasRepoURL);
- deviceAASDescriptor.addSubmodelDescriptor(lookupURN("Controller"), "basyx://127.0.0.1:"+serverPort);
-
+ // - Build an AAS descriptor, add sub model descriptors
+ AASDescriptor deviceAASDescriptor = new AASDescriptor(lookupURN("AAS"), aasRepoURL)
+ .addSubmodelDescriptor(lookupURN("Status"), aasRepoURL)
+ .addSubmodelDescriptor(lookupURN("Controller"), "basyx://127.0.0.1:"+serverPort);
// - Push AAS descriptor to server
- getRegistry().register(deviceAASDescriptor);
+ getRegistry().register(lookupURN("AAS"), deviceAASDescriptor);
}
-
+
/**
* Stop smart device
diff --git a/examples/basys.examples/examples/org/eclipse/basyx/examples/mockup/devicemanager/BaSyxTCPControlManufacturingDeviceManager.java b/examples/basys.examples/examples/org/eclipse/basyx/examples/mockup/devicemanager/BaSyxTCPControlManufacturingDeviceManager.java
new file mode 100644
index 0000000..74ba403
--- /dev/null
+++ b/examples/basys.examples/examples/org/eclipse/basyx/examples/mockup/devicemanager/BaSyxTCPControlManufacturingDeviceManager.java
@@ -0,0 +1,187 @@
+package org.eclipse.basyx.examples.mockup.devicemanager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.backend.connector.http.HTTPConnectorProvider;
+import org.eclipse.basyx.aas.metamodel.hashmap.aas.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.hashmap.aas.SubModel;
+import org.eclipse.basyx.components.controlcomponent.ControlComponentChangeListener;
+import org.eclipse.basyx.components.devicemanager.TCPControllableDeviceManagerComponent;
+import org.eclipse.basyx.components.proxy.registry.AASHTTPRegistryProxy;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.vab.backend.server.basyx.BaSyxTCPServer;
+import org.eclipse.basyx.vab.core.VABConnectionManager;
+import org.eclipse.basyx.vab.core.proxy.VABElementProxy;
+import org.eclipse.basyx.vab.provider.hashmap.VABHashmapProvider;
+
+import basys.examples.aasdescriptor.AASDescriptor;
+import basys.examples.aasdescriptor.ModelUrn;
+
+
+
+/**
+ * Example manufacturing device manager code
+ *
+ * This example code extends the BaSyxTCPManufacturingDeviceManager by adding a control component sub model to control the managed device.
+ *
+ *
+ * @author kuhn
+ *
+ */
+public class BaSyxTCPControlManufacturingDeviceManager extends TCPControllableDeviceManagerComponent implements ControlComponentChangeListener {
+
+
+ /**
+ * AAS server connection
+ */
+ protected VABElementProxy aasServerConnection = null;
+
+
+
+
+ /**
+ * Constructor
+ */
+ public BaSyxTCPControlManufacturingDeviceManager(int deviceTCPPort, int ctrlComponentServerPort) {
+ // Invoke base constructor
+ super(deviceTCPPort, ctrlComponentServerPort);
+
+
+ // Set registry that will be used by this service
+ setRegistry(new AASHTTPRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"));
+
+
+ // Set service connection manager and create AAS server connection
+ setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider()));
+ // - Create AAS server connection
+ aasServerConnection = getConnectionManager().connectToHTTPVABElement("AASServer", "/aas/submodels/aasRepository/");
+
+
+ // Set AAS server VAB object ID, AAS server URL, and AAS server path prefix
+ setAASServerObjectID("AASServer");
+ setAASServerURL("http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer");
+ setAASServerPathPrefix("/aas/submodels/aasRepository/");
+ }
+
+
+ /**
+ * Initialize the device, and register it with the backend
+ */
+ @Override
+ public void start() {
+ // Base implementation
+ super.start();
+
+ // Create the device AAS and sub model structure
+ createDeviceAASAndSubModels();
+
+ // Register AAS and sub model descriptors in directory (push AAS descriptor to server)
+ getRegistry().register(lookupURN("AAS"), getAASDescriptor());
+ }
+
+
+
+ /**
+ * Create the device AAS and sub model structure
+ */
+ @SuppressWarnings("unchecked")
+ protected void createDeviceAASAndSubModels() {
+ // Register URNs of managed VAB objects
+ addShortcut("AAS", new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001"));
+ addShortcut("Status", new ModelUrn("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#001"));
+ addShortcut("Controller", new ModelUrn("urn:de.FHG:devices.es.iese:controllerSM:1.0:3:x-509#001"));
+
+
+ // Create device AAS
+ AssetAdministrationShell aas = new AssetAdministrationShell();
+ // - Populate AAS
+ aas.setId("DeviceIDShort");
+ // - Transfer device AAS to server
+ aasServerConnection.createElement(lookupURN("AAS").toString(), aas);
+
+
+ // The device also brings a sub model structure with an own ID that is being pushed on the server
+ // - Create generic sub model and add properties
+ SubModel statusSM = new SubModel()
+ // - Property status: indicate device status
+ .putPath("properties/status", "offline")
+ // - Property statistics: export invocation statistics for every service
+ // - invocations: indicate total service invocations. Properties are not persisted in this example,
+ // therefore we start counting always at 0.
+ .putPath("properties/statistics/default/invocations", 0);
+ // - Transfer device sub model to server
+ aasServerConnection.createElement(lookupURN("Status").toString(), statusSM);
+
+
+ // The device also brings a sub model structure with an own ID that is being pushed on the server
+ // - Create generic sub model
+ SubModel controllerSM = new SubModel();
+ // - Create sub model contents manually
+ Map<String, Object> listOfControllers = new HashMap<>();
+ ((Map<String, Object>) controllerSM.get("properties")).put("controllers", listOfControllers);
+ // - Transfer device sub model to server
+ aasServerConnection.createElement(lookupURN("Controller").toString(), controllerSM);
+
+
+
+ // Register URNs of control component VAB object
+ addShortcut("ControlComponent", new ModelUrn("urn:de.FHG:devices.es.iese:controlComponentSM:1.0:3:x-509#001"));
+
+
+ // Register control component as local sub model
+ // - This sub model will stay with the device
+ server = new BaSyxTCPServer<>(new VABHashmapProvider(simpleControlComponent), controlComponentServerPort);
+ // - Start local BaSyx/TCP server
+ server.start();
+ }
+
+
+
+ /**
+ * Get AAS descriptor for managed device
+ */
+ @Override
+ protected AASDescriptor getAASDescriptor() {
+ // Create AAS and sub model descriptors
+ AASDescriptor aasDescriptor = createAASDescriptorURI(lookupURN("AAS"));
+ addSubModelDescriptorURI(aasDescriptor, lookupURN("Status"));
+ addSubModelDescriptorURI(aasDescriptor, lookupURN("Controller"));
+
+ // Add descriptor for control component sub model
+ aasDescriptor.addSubmodelDescriptor(lookupURN("ControlComponent"), "basyx://127.0.0.1:"+controlComponentServerPort);
+
+ // Return AAS, sub model descriptors, and added control component sub model descriptor
+ return aasDescriptor;
+ }
+
+
+
+ /**
+ * Received a string from network
+ */
+ @Override
+ public void onReceive(byte[] rxData) {
+ // Do not process null values
+ if (rxData == null) return;
+
+ // Convert received data to string
+ String rxStr = new String(rxData);
+ // - Trim string to remove possibly trailing and leading white spaces
+ rxStr = rxStr.trim();
+
+ // Check what was being received. This check is performed based on a prefix that he device has to provide);
+ // - Update of device status
+ if (hasPrefix(rxStr, "status:")) aasServerConnection.updateElementValue(lookupURN("Status").getEncodedURN()+"/properties/status", removePrefix(rxStr, "status"));
+ // - Device indicates service invocation
+ if (hasPrefix(rxStr, "invocation:")) {
+ // Read and increment invocation counter
+ int invocations = (int) aasServerConnection.readElementValue(lookupURN("Status").getEncodedURN()+"/properties/statistics/default/invocations");
+ aasServerConnection.updateElementValue(lookupURN("Status").getEncodedURN()+"/properties/statistics/default/invocations", ++invocations);
+ }
+
+ // Let base implementation process the message
+ super.onReceive(rxData);
+ }
+}
+
diff --git a/examples/basys.examples/examples/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceManager.java b/examples/basys.examples/examples/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceManager.java
new file mode 100644
index 0000000..c0f3dca
--- /dev/null
+++ b/examples/basys.examples/examples/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceManager.java
@@ -0,0 +1,179 @@
+package org.eclipse.basyx.examples.mockup.devicemanager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.backend.connector.http.HTTPConnectorProvider;
+import org.eclipse.basyx.aas.metamodel.hashmap.aas.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.hashmap.aas.SubModel;
+import org.eclipse.basyx.components.devicemanager.TCPDeviceManagerComponent;
+import org.eclipse.basyx.components.proxy.registry.AASHTTPRegistryProxy;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.vab.core.VABConnectionManager;
+import org.eclipse.basyx.vab.core.proxy.VABElementProxy;
+import basys.examples.aasdescriptor.AASDescriptor;
+import basys.examples.aasdescriptor.ModelUrn;
+
+
+
+/**
+ * Example manufacturing device manager code
+ *
+ * This example code illustrates a basic device manager component. It implements the interaction between a device and the BaSyx infrastructure.
+ * This code is for example deployed on the device (in case of availability of a Java runtime environment) or to an explicit connector device.
+ * The Asset Administration Shell is not kept on the device, but transferred to an AAS server during registration. This ensures its presence also
+ * if the device itself is not available, e.g. due to a failure. Important asset data, such as manufacturer, and support contacts remain available
+ * in this case.
+ *
+ * This code implements the following:
+ * - Registration of device the AAS and sub models with the BaSyx infrastructure
+ * - Updating of sub model properties to reflect the device status
+ * - TCP connection to legacy device
+ *
+ *
+ * @author kuhn
+ *
+ */
+public class ManufacturingDeviceManager extends TCPDeviceManagerComponent {
+
+
+ /**
+ * AAS server connection
+ */
+ protected VABElementProxy aasServerConnection = null;
+
+
+
+
+
+
+ /**
+ * Constructor
+ */
+ public ManufacturingDeviceManager(int port) {
+ // Invoke base constructor
+ super(port);
+
+
+ // Set registry that will be used by this service
+ setRegistry(new AASHTTPRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"));
+
+
+ // Set service connection manager and create AAS server connection
+ setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider()));
+ // - Create AAS server connection
+ aasServerConnection = getConnectionManager().connectToHTTPVABElement("AASServer", "/aas/submodels/aasRepository/");
+
+
+ // Set AAS server VAB object ID, AAS server URL, and AAS server path prefix
+ setAASServerObjectID("AASServer");
+ setAASServerURL("http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer");
+ setAASServerPathPrefix("/aas/submodels/aasRepository/");
+ }
+
+
+
+ /**
+ * Initialize the device, and register it with the backend
+ */
+ @Override
+ public void start() {
+ // Base implementation
+ super.start();
+
+ // Create the device AAS and sub model structure
+ createDeviceAASAndSubModels();
+
+ // Register AAS and sub model descriptors in directory (push AAS descriptor to server)
+ getRegistry().register(lookupURN("AAS"), getAASDescriptor());
+ }
+
+
+ /**
+ * Get AAS descriptor for managed device
+ */
+ @Override
+ protected AASDescriptor getAASDescriptor() {
+ // Create AAS and sub model descriptors
+ AASDescriptor aasDescriptor = createAASDescriptorURI(lookupURN("AAS"));
+ addSubModelDescriptorURI(aasDescriptor, lookupURN("Status"));
+ addSubModelDescriptorURI(aasDescriptor, lookupURN("Controller"));
+
+ // Return AAS and sub model descriptors
+ return aasDescriptor;
+ }
+
+
+
+ /**
+ * Create the device AAS and sub model structure
+ */
+ @SuppressWarnings("unchecked")
+ protected void createDeviceAASAndSubModels() {
+
+ // Register URNs of managed VAB objects
+ addShortcut("AAS", new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001"));
+ addShortcut("Status", new ModelUrn("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#001"));
+ addShortcut("Controller", new ModelUrn("urn:de.FHG:devices.es.iese:controllerSM:1.0:3:x-509#001"));
+
+
+ // Create device AAS
+ AssetAdministrationShell aas = new AssetAdministrationShell();
+ // - Populate AAS
+ aas.setId("DeviceIDShort");
+ // - Transfer device AAS to server
+ aasServerConnection.createElement(lookupURN("AAS").toString(), aas);
+
+
+ // The device also brings a sub model structure with an own ID that is being pushed on the server
+ // - Create generic sub model and add properties
+ SubModel statusSM = new SubModel()
+ // - Property status: indicate device status
+ .putPath("properties/status", "offline")
+ // - Property statistics: export invocation statistics for every service
+ // - invocations: indicate total service invocations. Properties are not persisted in this example,
+ // therefore we start counting always at 0.
+ .putPath("properties/statistics/default/invocations", 0);
+ // - Transfer device sub model to server
+ aasServerConnection.createElement(lookupURN("Status").toString(), statusSM);
+
+
+ // The device also brings a sub model structure with an own ID that is being pushed on the server
+ // - Create generic sub model
+ SubModel controllerSM = new SubModel();
+ // - Create sub model contents manually
+ Map<String, Object> listOfControllers = new HashMap<>();
+ ((Map<String, Object>) controllerSM.get("properties")).put("controllers", listOfControllers);
+ // - Transfer device sub model to server
+ aasServerConnection.createElement(lookupURN("Controller").toString(), controllerSM);
+ }
+
+
+
+
+
+
+ /**
+ * Received a string from network
+ */
+ @Override
+ public void onReceive(byte[] rxData) {
+ // Do not process null values
+ if (rxData == null) return;
+
+ // Convert received data to string
+ String rxStr = new String(rxData);
+ // - Trim string to remove possibly trailing and leading white spaces
+ rxStr = rxStr.trim();
+
+ // Check what was being received. This check is performed based on a prefix that he device has to provide);
+ // - Update of device status
+ if (hasPrefix(rxStr, "status:")) aasServerConnection.updateElementValue(lookupURN("Status").getEncodedURN()+"/properties/status", removePrefix(rxStr, "status"));
+ // - Device indicates service invocation
+ if (hasPrefix(rxStr, "invocation:")) {
+ // Read and increment invocation counter
+ int invocations = (int) aasServerConnection.readElementValue(lookupURN("Status").getEncodedURN()+"/properties/statistics/default/invocations");
+ aasServerConnection.updateElementValue(lookupURN("Status").getEncodedURN()+"/properties/statistics/default/invocations", ++invocations);
+ }
+ }
+}
diff --git a/examples/basys.examples/examples/org/eclipse/basyx/examples/scenarios/device/RunSimpleTCPDevice.java b/examples/basys.examples/examples/org/eclipse/basyx/examples/scenarios/device/RunSimpleTCPDevice.java
index ba47710..0c89bdb 100644
--- a/examples/basys.examples/examples/org/eclipse/basyx/examples/scenarios/device/RunSimpleTCPDevice.java
+++ b/examples/basys.examples/examples/org/eclipse/basyx/examples/scenarios/device/RunSimpleTCPDevice.java
@@ -8,7 +8,7 @@
import org.eclipse.basyx.examples.examplescenario.BaSyxExampleScenario;
import org.eclipse.basyx.examples.mockup.application.ReceiveDeviceStatusApplication;
import org.eclipse.basyx.examples.mockup.device.SimpleTCPDeviceMockup;
-import org.eclipse.basyx.examples.mockup.devicemanager.BaSyxTCPManufacturingDeviceManager;
+import org.eclipse.basyx.examples.mockup.devicemanager.ManufacturingDeviceManager;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
import org.eclipse.basyx.vab.core.VABConnectionManager;
import org.junit.ClassRule;
@@ -50,7 +50,7 @@
// Simulated runnables
// - Manufacturing device manager, e.g. deployed to additonal device
- new BaSyxTCPManufacturingDeviceManager(9998).setName("DeviceManager"),
+ new ManufacturingDeviceManager(9998).setName("DeviceManager"),
// Simulated mockups
new SimpleTCPDeviceMockup(9998).setName("Device"),
@@ -74,48 +74,38 @@
public void test() throws Exception {
// Device updates status to ready
((SimpleTCPDeviceMockup) context.getRunnable("Device")).deviceInitialized();
-System.out.println("XXXXXX-1");
// Application waits for status change
waitfor( () -> ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("IDLE") );
assertTrue( ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("IDLE") );
-System.out.println("XXXXXX-2");
// Application checks invocation counter
assertTrue( ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceInvocationCounter() == 0 );
-System.out.println("XXXXXX-3");
// Device updates status to running
// - The device indicates that a process step is running
((SimpleTCPDeviceMockup) context.getRunnable("Device")).serviceRunning();
-System.out.println("XXXXXX-4");
// Application waits for status change
waitfor( () -> ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("EXECUTE") );
assertTrue( ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("EXECUTE") );
-System.out.println("XXXXXX-5");
// Device updates status to complete
// - The device indicates that process step did finish
((SimpleTCPDeviceMockup) context.getRunnable("Device")).serviceCompleted();
-System.out.println("XXXXXX-6");
// Application waits for status change
waitfor( () -> ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("COMPLETE") );
assertTrue( ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("COMPLETE") );
-System.out.println("XXXXXX-7");
// Device updates status to ready again, next process step may be invoked
((SimpleTCPDeviceMockup) context.getRunnable("Device")).resetCompleted();
-System.out.println("XXXXXX-8");
// Application waits for status change
waitfor( () -> ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("IDLE") );
assertTrue( ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("IDLE") );
-System.out.println("XXXXXX-9");
// Application checks invocation counter
assertTrue( ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceInvocationCounter() == 1 );
-System.out.println("XXXXXX-10");
}
}
diff --git a/examples/basys.examples/examples/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleControllableTCPDevice.java b/examples/basys.examples/examples/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleControllableTCPDevice.java
new file mode 100644
index 0000000..2c628d2
--- /dev/null
+++ b/examples/basys.examples/examples/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleControllableTCPDevice.java
@@ -0,0 +1,142 @@
+package org.eclipse.basyx.examples.scenarios.device.controllable;
+
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.basyx.aas.backend.connector.JSONConnector;
+import org.eclipse.basyx.aas.backend.connector.basyx.BaSyxConnector;
+import org.eclipse.basyx.aas.backend.connector.http.HTTPConnectorProvider;
+import org.eclipse.basyx.components.controlcomponent.ExecutionState;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.examplescenario.BaSyxExampleScenario;
+import org.eclipse.basyx.examples.mockup.application.ReceiveDeviceStatusApplication;
+import org.eclipse.basyx.examples.mockup.device.ControllableTCPDeviceMockup;
+import org.eclipse.basyx.examples.mockup.devicemanager.BaSyxTCPControlManufacturingDeviceManager;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.vab.core.VABConnectionManager;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Run example for controllable device
+ *
+ * @author kuhn
+ *
+ */
+public class RunExampleSimpleControllableTCPDevice extends BaSyxExampleScenario {
+
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider());
+
+
+ /**
+ * BaSyx connector instance
+ */
+ protected BaSyxConnector basyxConnector = null;
+
+
+ /**
+ * Communication stream to connected device control component
+ */
+ protected JSONConnector toControlComponent = null;
+
+
+
+
+ /**
+ * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+ * components on the IP address of the host. Therefore, all components use the same IP address.
+ */
+ @ClassRule
+ public static BaSyxDeployment context = new BaSyxDeployment(
+ // BaSyx infrastructure
+ // - BaSys topology with one AAS Server and one SQL directory
+ new BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory(),
+
+ // Simulated runnables
+ // - Manufacturing device manager, e.g. deployed to additonal device
+ new BaSyxTCPControlManufacturingDeviceManager(9998, 9997).setName("DeviceManager"),
+
+ // Device mockups
+ new ControllableTCPDeviceMockup(9998).setName("Device"),
+
+ // Application mockups
+ new ReceiveDeviceStatusApplication().setName("Application")
+ );
+
+
+
+ /**
+ * Test sequence:
+ * - Device status update
+ * - Read device status from AAS
+ */
+ @Test
+ public void test() throws Exception {
+ // Create connection to device control component on smart device
+ // - Create BaSyx connector to connect with the device manager
+ basyxConnector = new BaSyxConnector("localhost", 9997);
+ // - Create connection to device control component
+ toControlComponent = new JSONConnector(basyxConnector);
+
+
+
+ // Device finishes initialization and moves to idle state
+ ((ControllableTCPDeviceMockup) context.getRunnable("Device")).deviceInitialized();
+
+ // Application waits for status change
+ waitfor( () -> ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("IDLE") );
+ // - Validate device status
+ waitfor( () -> ((ControllableTCPDeviceMockup) context.getRunnable("Device")).exState == ExecutionState.IDLE );
+
+
+ // Change device operation mode
+ toControlComponent.setModelPropertyValue("status/opMode", "RegularMilling");
+ // - Validate device operation mode
+ waitfor( () -> ((ControllableTCPDeviceMockup) context.getRunnable("Device")).opMode.equals("RegularMilling") );
+
+ // Application checks invocation counter
+ assertTrue( ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceInvocationCounter() == 0 );
+
+
+ // Start device service
+ toControlComponent.setModelPropertyValue("cmd", "start");
+ // - Application waits for status change
+ waitfor( () -> ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("EXECUTE") );
+ // - Validate device status
+ waitfor( () -> ((ControllableTCPDeviceMockup) context.getRunnable("Device")).exState == ExecutionState.EXECUTE );
+
+
+ // Device indicates service end
+ ((ControllableTCPDeviceMockup) context.getRunnable("Device")).serviceCompleted();
+ // - Application waits for status change
+ waitfor( () -> ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("COMPLETE") );
+ // - Validate device status
+ waitfor( () -> ((ControllableTCPDeviceMockup) context.getRunnable("Device")).exState == ExecutionState.COMPLETE );
+
+
+ // Reset device to enable subsequent service calls
+ toControlComponent.setModelPropertyValue("cmd", "reset");
+ // - Application waits for status change
+ waitfor( () -> ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("RESETTING") );
+ // - Validate device status
+ waitfor( () -> ((ControllableTCPDeviceMockup) context.getRunnable("Device")).exState == ExecutionState.RESETTING );
+
+
+ // Device finishes reset and moves to idle state
+ ((ControllableTCPDeviceMockup) context.getRunnable("Device")).resetCompleted();
+ // - Application waits for status change
+ waitfor( () -> ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("IDLE") );
+ // - Validate device status
+ waitfor( () -> ((ControllableTCPDeviceMockup) context.getRunnable("Device")).exState == ExecutionState.IDLE );
+
+
+ // Application checks invocation counter
+ assertTrue( ((ReceiveDeviceStatusApplication) context.getRunnable("Application")).getDeviceInvocationCounter() == 1 );
+ }
+}
diff --git a/examples/basys.examples/examples/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleSmartDevice.java b/examples/basys.examples/examples/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleSmartDevice.java
index c357999..49c6296 100644
--- a/examples/basys.examples/examples/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleSmartDevice.java
+++ b/examples/basys.examples/examples/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleSmartDevice.java
@@ -40,9 +40,9 @@
/**
- * Communication stream to connected device manager
+ * Communication stream to connected device control component
*/
- protected JSONConnector toDeviceManager = null;
+ protected JSONConnector toControlComponent = null;
@@ -76,8 +76,8 @@
// Create connection to device control component on smart device
// - Create BaSyx connector to connect with the device manager
basyxConnector = new BaSyxConnector("localhost", 9997);
- // - Create connection to device manager
- toDeviceManager = new JSONConnector(basyxConnector);
+ // - Create connection to device control component
+ toControlComponent = new JSONConnector(basyxConnector);
@@ -89,7 +89,7 @@
// Change device operation mode
- ((SmartBaSyxTCPDeviceMockup) context.getRunnable("Device")).getControlComponent().setOperationMode("RegularMilling");
+ toControlComponent.setModelPropertyValue("status/opMode", "RegularMilling");
// - Validate device control component operation mode
waitfor( () -> ((SmartBaSyxTCPDeviceMockup) context.getRunnable("Device")).getControlComponent().getOperationMode().equals("RegularMilling") );
@@ -98,7 +98,7 @@
// Start device service
- ((SmartBaSyxTCPDeviceMockup) context.getRunnable("Device")).getControlComponent().setCommand("start");
+ toControlComponent.setModelPropertyValue("cmd", "start");
// - Validate control component status
waitfor( () -> ((SmartBaSyxTCPDeviceMockup) context.getRunnable("Device")).getControlComponent().getExecutionState().equals(ExecutionState.EXECUTE.getValue()) );
// - Indicate service end
@@ -108,7 +108,7 @@
// Reset device to enable subsequent service calls
- ((SmartBaSyxTCPDeviceMockup) context.getRunnable("Device")).getControlComponent().setCommand("reset");
+ toControlComponent.setModelPropertyValue("cmd", "reset");
// - Device finishes reset and moves to idle state
((SmartBaSyxTCPDeviceMockup) context.getRunnable("Device")).resetCompleted();
diff --git a/examples/basys.examples/src/org/eclipse/basyx/components/devicemanager/DeviceManagerComponent.java b/examples/basys.examples/src/org/eclipse/basyx/components/devicemanager/DeviceManagerComponent.java
index bdabb71..d94b1fb 100644
--- a/examples/basys.examples/src/org/eclipse/basyx/components/devicemanager/DeviceManagerComponent.java
+++ b/examples/basys.examples/src/org/eclipse/basyx/components/devicemanager/DeviceManagerComponent.java
@@ -103,6 +103,13 @@
return aasServerPrefix;
}
+
+
+ /**
+ * Get AAS descriptor for managed device
+ */
+ protected abstract AASDescriptor getAASDescriptor();
+
diff --git a/examples/basys.examples/src/org/eclipse/basyx/components/netcomm/TCPCommunicator.java b/examples/basys.examples/src/org/eclipse/basyx/components/netcomm/TCPCommunicator.java
index b686915..5332032 100644
--- a/examples/basys.examples/src/org/eclipse/basyx/components/netcomm/TCPCommunicator.java
+++ b/examples/basys.examples/src/org/eclipse/basyx/components/netcomm/TCPCommunicator.java
@@ -138,6 +138,9 @@
* Buffer must point to where transmission should start
*/
public void sendMessage(ByteBuffer messageBuffer) {
+ // Only continue if client is connected
+ if (communicationToClient == null) return;
+
// Transmit frame
try {communicationToClient.write(messageBuffer);} catch (IOException e) {e.printStackTrace();}
}
diff --git a/examples/basys.examples/src/org/eclipse/basyx/components/proxy/registry/AASHTTPRegistryProxy.java b/examples/basys.examples/src/org/eclipse/basyx/components/proxy/registry/AASHTTPRegistryProxy.java
index 557c6c5..acd08c3 100644
--- a/examples/basys.examples/src/org/eclipse/basyx/components/proxy/registry/AASHTTPRegistryProxy.java
+++ b/examples/basys.examples/src/org/eclipse/basyx/components/proxy/registry/AASHTTPRegistryProxy.java
@@ -58,10 +58,23 @@
/**
+ * Register AAS descriptor in registry, delete old registration
+ */
+ @Override
+ public void register(ModelUrn aasID, AASDescriptor deviceAASDescriptor) {
+ // Invoke delete operation of AAS registry
+ try {client.delete(aasRegistryURL+"/api/v1/registry/"+URLEncoder.encode(aasID.getURN(), "UTF-8"));} catch (Exception e) {e.printStackTrace();}
+
+ // Perform web service call to registry
+ client.post(aasRegistryURL+"/api/v1/registry", serializer.getJsonString(serializer.serialize(deviceAASDescriptor)));
+ }
+
+
+ /**
* Register AAS descriptor in registry
*/
@Override
- public void register(AASDescriptor deviceAASDescriptor) {
+ public void registerOnly(AASDescriptor deviceAASDescriptor) {
// Perform web service call to registry
client.post(aasRegistryURL+"/api/v1/registry", serializer.getJsonString(serializer.serialize(deviceAASDescriptor)));
}
diff --git a/examples/basys.examples/src/org/eclipse/basyx/components/proxy/registry/AASRegistryProxyIF.java b/examples/basys.examples/src/org/eclipse/basyx/components/proxy/registry/AASRegistryProxyIF.java
index d986976..3f538f9 100644
--- a/examples/basys.examples/src/org/eclipse/basyx/components/proxy/registry/AASRegistryProxyIF.java
+++ b/examples/basys.examples/src/org/eclipse/basyx/components/proxy/registry/AASRegistryProxyIF.java
@@ -16,10 +16,16 @@
/**
- * Register AAS descriptor in registry
+ * Register AAS descriptor in registry, delete old registration
*/
- public void register(AASDescriptor deviceAASDescriptor);
+ public void register(ModelUrn aasID, AASDescriptor deviceAASDescriptor);
+
+ /**
+ * Only register AAS descriptor in registry
+ */
+ public void registerOnly(AASDescriptor deviceAASDescriptor);
+
/**
* Delete AAS descriptor from registry