blob: e0ea9b24ffc233c548cc7c1550b0def409c42252 [file] [log] [blame]
package org.eclipse.basyx.examples.mockup.devicemanager;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.basyx.aas.api.modelurn.ModelUrn;
import org.eclipse.basyx.aas.api.registry.AASHTTPRegistryProxy;
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.aas.metamodel.hashmap.aas.descriptor.AASDescriptor;
import org.eclipse.basyx.components.configuration.CFGBaSyxProtocolType;
import org.eclipse.basyx.components.devicemanager.TCPDeviceManagerComponent;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
import org.eclipse.basyx.vab.core.VABConnectionManager;
import org.eclipse.basyx.vab.core.proxy.VABElementProxy;
/**
* 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);
// Configure this device manager
configure()
.registryURL("http://localhost:8080/basys.examples/Components/Directory/SQL")
.connectionManagerType(CFGBaSyxProtocolType.HTTP)
.directoryService(new ExamplesPreconfiguredDirectory())
.end();
// configure()
// .registryURL()
// .connectionManagerDirectory(new ExamplesPreconfiguredDirectory())
// .connectionManagerProtocol(HTTP)
// .AASServerObjectID(...)
// .addAASAAS()
// .whateverAASProperty()
// .addSubmodel()
// .property()
// .endSubModel()
// .end();
// configure(Map<>...)
// 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(SubModel.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:")) {
// Start of process
if (hasPrefix(rxStr, "invocation:start")) {
// 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);
}
// End of process
if (hasPrefix(rxStr, "invocation:end")) {
// Do nothing for now
}
}
}
}