Device OPC-UA - Getting Started
This page describes how to connect OPC-UA devices to EdgeX.
In this example, we simulate the OPC UA Simulation Server instead of using a real device. This provides a straightforward way to test the device service features.
Environment
You can use any operating system that supports docker and docker-compose. In this example, we use Ubuntu to deploy EdgeX using docker.
Prosys OPC UA Simulation Server
- Download Prosys OPC UA Simulation Server
Download the latest version of Prosys OPC UA Simulation Server from the OPC UA Simulation Server Download .
-
Install the simulation server
-
Startup the simulation server
-
Verify the simulation server
-
Status
Copy the Connection Address(UA TCP) value: opc.tcp://jiekemacbookpro14.lan:53530/OPCUA/SimulationServer
- Objects
Set Up Before Starting Services
The following sections describe how to complete the set up before starting the services.
- Using the pre-defined Configuration for testing
- Set Up New Configuration
Using the pre-defined Configuration for testing
The pre-defined configuration in the folder: cmd/res/
Pre-defined Device Profile
The deivce profile profiles/OpcuaServer.yaml described a simulation device, it contains 3 resources, the table described each resource of the device profile:
Resource Name | valueType of EdgeX | nodeId | Description |
---|---|---|---|
Constant | Float64 | ns=3;i=1001 | generated constant number |
Counter | Int32 | ns=3;i=1002 | generated counter number |
Random | Float64 | ns=3;i=1003 | generated random number |
Pre-defined Device Configuration
The device configuration devices/Simple-Devices.yaml described two devices as shown below.
The protocols.opcua.Endpoint
value is the same above metioned.
---
protocols:
opcua:
Endpoint: 'opc.tcp://jiekemacbookpro14.lan:53530/OPCUA/SimulationServer'
Set Up New Configuration
Create a Custom configuration folder
Run the following command:
mkdir -p custom-config
Set Up Device Profile
Run the following command to create your device profile:
cd custom-config
vi new-device-profile.yaml
Insert your device profile definition, it's up to your OPC-UA device configuration.
Set Up Device Service Configuration
cd custom-config
vi new-device-config.yaml
Fill in the new-device-config.yaml file.
Prepare docker-compose File
Generate docker compose file
- Clone edgex-compose
git clone https://github.com/edgexfoundry/edgex-compose.git
- Generate the docker-compose.yml file
cd edgex-compose
make gen no-secty ds-opc-ua
Add Custom Configuration to docker-compose File
Add prepared configuration files to docker-compose file, you can mount them using volumes and change the environment for device-opc-ua internal use.
Open the docker-compose.yml
file and then add volumes path and environment as shown below:
device-opc-ua:
...
environment:
...
DEVICE_PROFILESDIR: /custom-config
DEVICE_DEVICESDIR: /custom-config
volumes:
...
- /path/to/custom-config:/custom-config
Start EdgeX Foundry on Docker
Since we generate the docker-compose.yml
file at the previous step, we can deplay EdgeX as shown below:
cd edgex-compose/compose-builder
make up
[+] Running 12/12
✔ Container edgex-core-consul Started 0.0s
✔ Container edgex-ui-go Started 0.0s
✔ Container edgex-redis Started 0.0s
✔ Container edgex-core-common-config-bootstrapper Started 0.1s
✔ Container edgex-support-scheduler Started 0.0s
✔ Container edgex-kuiper Started 0.0s
✔ Container edgex-support-notifications Started 0.1s
✔ Container edgex-core-metadata Started 0.1s
✔ Container edgex-core-command Started 0.0s
✔ Container edgex-core-data Started 0.0s
✔ Container edgex-app-rules-engine Started 0.0s
✔ Container edgex-device-opc-ua Started 0.0s
Set Up After Starting Services
If the services are already running and you want to add a device, you can use the Core Metadata API
as outlined in this section. If you set up the device profile and Service as described in Set Up Before Starting Services, you can skip this section.
To add a device after starting the services, complete the following steps:
- Upload the device profile above to metadata with a POST to http://localhost:59881/api/v3/deviceprofile/uploadfile and add the file as key "file" to the body in form-data format, and the created ID will be returned. The following example command uses curl to send the request:
curl http://localhost:59881/api/v3/deviceprofile/uploadfile \
-X POST \
-F "file=@new-device-profile.yml"
-
Ensure the OPC-UA device service is running, adjust the service name below to match if necessary or if using other device services.
-
Add the device with a POST to http://localhost:59881/api/v3/device, the body will look something like:
curl http://localhost:59881/api/v3/device -H "Content-Type:application/json" -X POST \
-d '[
{
"apiVersion" : "v3",
"device" : {
"adminState" : "UNLOCKED",
"description" : "OPCUA device",
"labels" : [
"OPCUA",
"TEST"
],
"name" : "SimulationServer1",
"operatingState" : "UP",
"profileName" : "OPCUA-Server",
"protocols" : {
"opcua" : {
"Endpoint" : "opc.tcp://192.168.123.21:53530/OPCUA/SimulationServer"
}
},
"serviceName" : "device-opc-ua"
}
}
]'
The service name must match/refer to the target device service(device-opc-ua
), and the profile name must match the device profile name(OPCUA-Server
) from the previous steps.
Execute Commands
Now we're ready to run some commands.
Find Executable Commands
Use the following query to find executable commands:
curl http://localhost:59882/api/v3/device/name/SimulationServer1 | json_pp
{
"apiVersion": "v3",
"deviceCoreCommand": {
"coreCommands": [
{
"get": true,
"name": "ConstantNum",
"parameters": [
{
"resourceName": "Constant",
"valueType": "Float64"
}
],
"path": "/api/v3/device/name/SimulationServer1/ConstantNum",
"set": true,
"url": "http://edgex-core-command:59882"
},
{
"get": true,
"name": "CounterNum",
"parameters": [
{
"resourceName": "Counter",
"valueType": "Int32"
}
],
"path": "/api/v3/device/name/SimulationServer1/CounterNum",
"url": "http://edgex-core-command:59882"
},
{
"get": true,
"name": "RandomNum",
"parameters": [
{
"resourceName": "Random",
"valueType": "Float64"
}
],
"path": "/api/v3/device/name/SimulationServer1/RandomNum",
"url": "http://edgex-core-command:59882"
},
{
"get": true,
"name": "Constant",
"parameters": [
{
"resourceName": "Constant",
"valueType": "Float64"
}
],
"path": "/api/v3/device/name/SimulationServer1/Constant",
"set": true,
"url": "http://edgex-core-command:59882"
},
{
"get": true,
"name": "Counter",
"parameters": [
{
"resourceName": "Counter",
"valueType": "Int32"
}
],
"path": "/api/v3/device/name/SimulationServer1/Counter",
"url": "http://edgex-core-command:59882"
},
{
"get": true,
"name": "Random",
"parameters": [
{
"resourceName": "Random",
"valueType": "Float64"
}
],
"path": "/api/v3/device/name/SimulationServer1/Random",
"url": "http://edgex-core-command:59882"
}
],
"deviceName": "SimulationServer1",
"profileName": "OPCUA-Server"
},
"statusCode": 200
}
Execute SET command
Execute SET command according to url
and parameterNames
, replacing localhost
with the server IP when running the SET command.
Here we use the Constant
command:
curl http://localhost:59882/api/v3/device/name/SimulationServer1/Constant \
-H "Content-Type:application/json" -X PUT \
-d '{"Constant": "199.99"}'
{"apiVersion":"v3","statusCode":200}
Execute GET command
Replace localhost
with the server IP when running the GET command.
Here we use the Constant
command:
curl http://localhost:59882/api/v3/device/name/SimulationServer1/Constant
We got the result, "value" : "1.999900e+02"
:
{
"apiVersion": "v3",
"event": {
"apiVersion": "v3",
"deviceName": "SimulationServer1",
"id": "cc8ea84d-0a5f-4d5b-b4db-9126368f4aa3",
"origin": 1702613269923352589,
"profileName": "OPCUA-Server",
"readings": [
{
"deviceName": "SimulationServer1",
"origin": 1702613269921,
"profileName": "OPCUA-Server",
"resourceName": "Constant",
"value": "1.999900e+02",
"valueType": "Float64"
}
],
"sourceName": "Constant"
},
"statusCode": 200
}
AutoEvent
The AutoEvent
is defined in the autoEvents
section of the device definition file:
deviceList:
autoEvents:
interval: '30s'
onChange: false
sourceName: 'Constant'
After service startup, query core-data's
API. The results show that the service auto-executes the command every 30 seconds
.