T04 - Multiple Protocols
Multiple protocols is a use case to test the communication between an asset and its AAS DT via different communication protocols. The current version supports 11 protocols: HTTP, OPC UA, MQTT, ROS2, WebSocket, Modbus TCP, COAP, Zenoh, UA FX, EtherNetIP, and CANOpen.
Note: UA FX, EtherNetIP and CANOpen are not yet included in this tutorial.
Requirements
The following components are required:
Computer with pre-installed Papyrus4Manufacturing nightly version
LocalSEA T04 Kit including some read-to-run software components
The following knowledge are required:
Intermediate about Networking
Basic about Java + Eclipse IDE
Basic about Docker
Deployment Instructions
In this example, the computer runs a software presenting a digital circle. The computer also hosts a Circle AAS DT to change the color of the digital circle. After downloading the T04 Kit, decompress it to get the two packages: (1) circle_v0.1.tar.gz contains the Docker image for the digital circle software, and (2) T04-Mprotocols.tar.gz contains the AAS model design for the computer.
Circle Object setup
On the computer, install and run the Docker image with the following command:
$ docker load -i circle_v0.1.tar.gz
$ docker run -it --net=host --rm circle:v0.1
Open a web browser and access noVNC page at http://127.0.0.1:6081/vnc.html
,
click connect to view the circle
as in Figure 1. The circle has four colors: white, red, green, blue,
corresponding to four values: 0, 1, 2, 3.

Circle DT setup
On the computer, extract T04-Mprotocols.tar.gz with the following command:
$ tar -xzvf T04-Mprotocols.tar.gz
Open Papyrus4Manufacturing and import the project as in Figure 2. The AAS Design Diagram shows the basic elements of the project. Note that users can see operation switch inside submodel Color. This operation aims to change the color of the circle.

In Model Explorer, right click on the AssetAministrationShell Circle, choose AAS, then click Generate Asset Administration Shell Basyx code (AAS). When a new project AAS_UR3e is generated, open the file DynamicElementsWorkspace.java inside the package color and modify function switch( ). Depending on the protocol, the code will be different as follows.
a. HTTP
public void Color_switch() {
int tmp = Integer.parseInt(connectedDevices.ep_http.readValue("").strip());
switch (tmp) {
case 0:
connectedDevices.ep_http.writeValue("", "1", "PUT");
break;
case 1:
connectedDevices.ep_http.writeValue("", "2", "PUT");
break;
case 2:
connectedDevices.ep_http.writeValue("", "3", "PUT");
break;
case 3:
connectedDevices.ep_http.writeValue("", "0", "PUT");
break;
default:
throw new IllegalArgumentException("Unexpected value: " + tmp);
}
};
b. OPC UA
public void Color_switch() {
int tmp = Integer.parseInt(connectedDevices.ep_opcua.readValue(new NodeId(2,2))
.toString());
switch (tmp) {
case 0:
connectedDevices.ep_opcua.writeValue(new NodeId(2,2), "1");
break;
case 1:
connectedDevices.ep_opcua.writeValue(new NodeId(2,2), "2");
break;
case 2:
connectedDevices.ep_opcua.writeValue(new NodeId(2,2), "3");
break;
case 3:
connectedDevices.ep_opcua.writeValue(new NodeId(2,2), "0");
break;
default:
throw new IllegalArgumentException("Unexpected value: " + tmp);
}
};
c. MQTT
public void Color_switch() {
int tmp = Integer.parseInt(connectedDevices.ep_mqtt.readValue("read").toString());
switch (tmp) {
case 0:
connectedDevices.ep_mqtt.writeValue("write", "1");
break;
case 1:
connectedDevices.ep_mqtt.writeValue("write", "2");
break;
case 2:
connectedDevices.ep_mqtt.writeValue("write", "3");
break;
case 3:
connectedDevices.ep_mqtt.writeValue("write", "0");
break;
default:
throw new IllegalArgumentException("Unexpected value: " + tmp);
}
};
d. ROS2
public void Color_switch() {
int tmp = Integer.parseInt(connectedDevices.ep_ros2.readValue("read").toString());
switch (tmp) {
case 0:
connectedDevices.ep_ros2.writeValue("write", "1");
break;
case 1:
connectedDevices.ep_ros2.writeValue("write", "2");
break;
case 2:
connectedDevices.ep_ros2.writeValue("write", "3");
break;
case 3:
connectedDevices.ep_ros2.writeValue("write", "0");
break;
default:
throw new IllegalArgumentException("Unexpected value: " + tmp);
}
};
e. WebSocket
public void Color_switch() {
int tmp = Integer.parseInt(connectedDevices.ep_ws.readValue("").toString());
switch (tmp) {
case 0:
connectedDevices.ep_ws.writeValue("", "1");
break;
case 1:
connectedDevices.ep_ws.writeValue("", "2");
break;
case 2:
connectedDevices.ep_ws.writeValue("", "3");
break;
case 3:
connectedDevices.ep_ws.writeValue("", "0");
break;
default:
throw new IllegalArgumentException("Unexpected value: " + tmp);
}
};
f. Modbus TCP
public void Color_switch() {
int tmp = Integer.parseInt(connectedDevices.ep_mtcp.readValue(0, EDataTypeMODBUS.REGISTER,
0, 1).toString());
switch (tmp) {
case 0:
connectedDevices.ep_mtcp.writeValue(0, EDataTypeMODBUS.REGISTER, 0, 1, 1);
break;
case 1:
connectedDevices.ep_mtcp.writeValue(0, EDataTypeMODBUS.REGISTER, 0, 1, 2);
break;
case 2:
connectedDevices.ep_mtcp.writeValue(0, EDataTypeMODBUS.REGISTER, 0, 1, 3);
break;
case 3:
connectedDevices.ep_mtcp.writeValue(0, EDataTypeMODBUS.REGISTER, 0, 1, 0);
break;
default:
throw new IllegalArgumentException("Unexpected value: " + tmp);
}
};
g. COAP
public void Color_switch() {
int tmp = Integer.parseInt(connectedDevices.ep_coap.readValue().toString());
switch (tmp) {
case 0:
connectedDevices.ep_coap.writeValue("1");
break;
case 1:
connectedDevices.ep_coap.writeValue("2");
break;
case 2:
connectedDevices.ep_coap.writeValue("3");
break;
case 3:
connectedDevices.ep_coap.writeValue("0");
break;
default:
throw new IllegalArgumentException("Unexpected value: " + tmp);
}
};
h. Zenoh
public void Color_switch() {
int tmp = Integer.parseInt(connectedDevices.ep_zenoh.readValue("read").toString());
switch (tmp) {
case 0:
connectedDevices.ep_zenoh.writeValue("write", "1");
break;
case 1:
connectedDevices.ep_zenoh.writeValue("write", "2");
break;
case 2:
connectedDevices.ep_zenoh.writeValue("write", "3");
break;
case 3:
connectedDevices.ep_zenoh.writeValue("write", "0");
break;
default:
throw new IllegalArgumentException("Unexpected value: " + tmp);
}
};
UAFX
TODO…
EtherNetIP
TODO…
CANOpen
TODO…
Verification
If all the above setups are correct, then the Circle AAS DT is connecting to the Circle software. The aim is to send command to Circle AAS DT to switch the color of the circle object.
The command requires a body. Create a file named Body and add the following content:
{
"requestId": "{{$timestamp}}",
"inputArguments": [],
"outputArguments": [],
"timeout":5000
}
Run the following command to switch color of the circle object:
$ curl -X POST -H 'Content-Type: application/json' -d @Body \
http://127.0.0.1:8001/aas/submodels/Circle/submodel/submodelElements/switch/invoke