Note
This service is designed for EdgeX Foundry v4.0
This repository is a Go-based EdgeX Foundry Device Service which uses OPC-UA protocol to interact with the devices or IoT objects.
- Subscribe/Unsubscribe one or more variables
- Execute read command
- Execute write command
- Execute method
- Edgex-go: core data, core command, core metadata
- OPCUA Server (Prosys Simulation Server, for example)
Download the Prosys OPC UA Simulation Server. Install and run it to have access to the default configured resources.
Define devices for device-sdk to auto upload device profile and create device instance. Please modify devices.yml file found under the ./cmd/res/devices folder.
deviceList:
- name: SimulationServer
profileName: OPCUA-Server
description: OPCUA device is created for test purpose
labels:
- test
protocols:
opcua:
Endpoint: "opc.tcp://127.0.0.1:53530/OPCUA/SimulationServer"
# Security policy: None, Basic128Rsa15, Basic256, Basic256Sha256, Aes128Sha256RsaOaep, Aes256Sha256RsaPss. Default: None
Policy: None
# Security mode: None, Sign, SignAndEncrypt. Default: None
Mode: None
# Path to cert.pem. Required for security mode/policy != None
CertFile: ""
# Path to private key.pem. Required for security mode/policy != None
KeyFile: ""
Resources: [Counter, Random]A Device Profile can be thought of as a template of a type or classification of a Device.
Write a device profile for your own devices; define deviceResources and deviceCommands. Please refer to cmd/res/profiles/OpcuaServer.yaml.
OPC UA methods can be referenced in the device profile and called with a read command. An example of a method instance might look something like this:
deviceResources:
- name: "SetDefaultsMethod"
description: "Set all variables to their default values"
isHidden: "false" # Specifies if the method can be called
properties:
valueType: "String" # Response type will always be String
readWrite: "R"
attributes: { methodId: "ns=5;s=Defaults", objectId: "ns=5;i=1111" }Notice that method calls require specifying the Node ID of both the method and its parent object.
A REST endpoint is available at POST /api/v3/call to handle method calls. The request body is defined as follows:
{
"device": "Device_Name",
"method": "Device_Resource_Name",
"parameters": [""]
}Both device and method properties are required, and parameters is optional.
make build
EDGEX_SECURITY_SECRET_STORE=false make runmake dockerUpdate docker-compose-no-secty.yml with the following service configuration:
services:
device-opcua:
container_name: edgex-device-opcua
depends_on:
core-common-config-bootstrapper:
condition: service_started
required: true
core-keeper:
condition: service_started
required: true
core-data:
condition: service_started
required: true
core-metadata:
condition: service_started
required: true
environment:
EDGEX_SECURITY_SECRET_STORE: "false"
SERVICE_HOST: edgex-device-opcua
hostname: edgex-device-opcua
# Update image ref if necessary
image: edgexfoundry/device-opcua-go:0.0.0-dev
networks:
edgex-network: null
ports:
- mode: ingress
host_ip: 127.0.0.1
target: 59997
published: "59997"
protocol: tcp
read_only: true
restart: always
security_opt:
- no-new-privileges:true
user: 2002:2001
volumes:
- type: bind
source: /etc/localtime
target: /etc/localtime
read_only: true
bind:
create_host_path: trueUpdate docker-compose.yml with the following configuration changes:
services:
# Update custom proxy route
security-proxy-setup:
environment:
EDGEX_ADD_PROXY_ROUTE: device-opcua.http://edgex-device-opcua:59997
# Update known secrets and secretstore tokens
security-secretstore-setup:
environment:
EDGEX_ADD_KNOWN_SECRETS: postgres[device-opcua],message-bus[device-opcua]
EDGEX_ADD_SECRETSTORE_TOKENS: "device-opcua"
# Device service configuration
device-opcua:
command:
- /device-opcua
- --registry
- -cp=keeper.http://edgex-core-keeper:59890
container_name: edgex-device-opcua
depends_on:
core-common-config-bootstrapper:
condition: service_started
required: true
core-keeper:
condition: service_started
required: true
core-data:
condition: service_started
required: true
core-metadata:
condition: service_started
required: true
security-bootstrapper:
condition: service_started
required: true
entrypoint:
- /edgex-init/ready_to_run_wait_install.sh
environment:
CLIENTS_SECURITY_SECRETSTORE_SETUP_HOST: edgex-security-secretstore-setup
EDGEX_SECURITY_SECRET_STORE: "true"
PROXY_SETUP_HOST: edgex-security-proxy-setup
SECRETSTORE_HOST: edgex-secret-store
SERVICE_HOST: edgex-device-opcua
STAGEGATE_BOOTSTRAPPER_HOST: edgex-security-bootstrapper
STAGEGATE_BOOTSTRAPPER_STARTPORT: "54321"
STAGEGATE_DATABASE_HOST: edgex-postgres
STAGEGATE_DATABASE_PORT: "5432"
STAGEGATE_DATABASE_READYPORT: "5432"
STAGEGATE_PROXYSETUP_READYPORT: "54325"
STAGEGATE_READY_TORUNPORT: "54329"
STAGEGATE_REGISTRY_HOST: edgex-core-keeper
STAGEGATE_REGISTRY_PORT: "59890"
STAGEGATE_REGISTRY_READYPORT: "54324"
STAGEGATE_SECRETSTORESETUP_HOST: edgex-security-secretstore-setup
STAGEGATE_SECRETSTORESETUP_TOKENS_READYPORT: "54322"
STAGEGATE_WAITFOR_TIMEOUT: 60s
hostname: edgex-device-opcua
# Update image ref if necessary
image: edgexfoundry/device-opcua-go:0.0.0-dev
networks:
edgex-network: null
ports:
- mode: ingress
host_ip: 127.0.0.1
target: 59997
published: "59997"
protocol: tcp
read_only: true
restart: always
security_opt:
- no-new-privileges:true
user: 2002:2001
volumes:
- type: volume
source: edgex-init
target: /edgex-init
read_only: true
volume: {}
- type: bind
source: /etc/localtime
target: /etc/localtime
read_only: true
bind:
create_host_path: true
- type: bind
source: /tmp/edgex/secrets/device-opcua
target: /tmp/edgex/secrets/device-opcua
read_only: true
bind:
selinux: z
create_host_path: trueCurrently, the NATS Messaging capability (NATS MessageBus) is opt-in at build time. This means that the published Docker image and Snaps do not include the NATS messaging capability.
The following make commands will build the local binary or local Docker image with NATS messaging capability included.
make build-nats
make docker-natsThe locally built Docker image can then be used in place of the published Docker image in your compose file.
See Compose Builder nat-bus option to generate compose file for NATS and local dev images.
Unit tests can be run with the following commands:
# Required once
make install-mockery
# Required if any interface in pkg/gopcua changes
mockery
# Run tests
make testThe Attributions.txt file can be generated by running
make attributionsThis will install github.com/google/go-licenses/v2 and run it against the repository contents, then report any missing attributions using ./bin/test-attribution-txt.sh.
Sometimes dependencies are only resolved when GOFLAGS includes particular -tags. The go-licenses module needs to be explicitly told to include these -tags since the dependencies will be part of go.mod.
In the event that running ./bin/test-attribution-txt.sh results in the report of missing entries, it is required to determine which build tag(s) are required to include them. This can be achieved by running go mod why <module> and investigating the second-to-last package in the list. Any missing build tags should be added to the make attributions command.
If, for some reason, there is a problem including a specific tag, the missing attribution entries should be appended manually to ./bin/attributions.template.