Giter Club home page Giter Club logo

opcua's Introduction

Version GitHub Actions status Codacy grade

opcua - EPICS Device Support for OPC UA

EPICS Device Support module for interfacing to the OPC UA protocol. The architecture allows supporting different implementations of the low level client library.

Linux and Windows builds are supported.

Status

โš ๏ธ This module is under development. Please contact the author Ralph Lange for details. :warning:

There are two choices for the low-level OPC UA client library:

  1. The commercially available Unified Automation C++ Based OPC UA Client SDK.
    This is the original, full implementation.

  2. The open source client implementation of the open62541 project.
    This integration is still experimental and does not support structured data yet.

Prerequisites

  • A C++ compiler that supports the C++11 standard.
    Microsoft Visual C++ needs to be from Visual Studio 2015 or newer. g++ needs to be 4.6 or above.

  • EPICS Base 3.15 (>= 3.15.7) or EPICS 7 (>= 7.0.4).

  • The gtest module if you want to compile and run the Google Test based unit tests.

Using the Unified Automation Client SDK

  • Unified Automation C++ Based OPC UA Client SDK (1.5/1.6/1.7 are supported, as well as their evaluation bundles; 1.8 is having trouble).

  • For OPC UA security support (authentication/encryption), you need openssl/libcrypto on your system - both when compiling the SDK and when generating any binaries (IOCs).

  • In CONFIG_SITE.local, set UASDK to the path of the SDK installation.

  • For more details, refer to the README.md in the devOpcuaSup/UaSdk directory.

Using the open62541 SDK

  • The open62541 SDK is available at https://open62541.org/
    Choose a recent release (1.2 and 1.3 are supported).

  • For OPC UA security support (authentication/encryption), you need openssl/libcrypto on your system - both when compiling the SDK and when generating any binaries (IOCs).

  • In CONFIG_SITE.local, set OPEN62541 to the path of the SDK installation.

  • For more details, refer to the README.md in the devOpcuaSup/open62541 directory.

Building the module

This is a standard EPICS module.

Inside the configure subdirectory or one level above the TOP location (TOP is where this README file resides), create a file RELEASE.local that sets EPICS_BASE and GTEST to the absolute paths inside your EPICS installation. The GTEST module is needed to compile and run the tests. Not defining it produces a clean build, but without any tests.

Configure the compiler on Linux to use the C++11 standard by adding

USR_CXXFLAGS_Linux += -std=c++11

to the CONFIG_SITE file (or one of the host/target specific site configuration files).
It is preferable to set this option globally in EPICS Base.

The configuration necessary when building against a specific client library is documented in the README.md file inside the respective subdirectory of devOpcuaSup.

Using the module

IOC applications that use the module need to

  • add an entry to the Device Support module in their RELEASE.local file
  • include opcua.dbd when building the IOC's DBD file
  • include opcua in the support libraries for the IOC binary.

Documentation

Sparse, but getting better.

The documentation folder of the Device Support module contains the Requirements Specification (SRS) giving an introduction and the list of requirements that should convey a good idea of the planned features.

The Cheat Sheet explains the configuration in the startup script and the database links.

Binary Distribution

Please look at the "Assets" sections of specific releases on the release page for the binary distribution tars. These tars contain an EPICS module with a binary Linux shared library (libopcua.so.<version>) that contains (embeds) the Unified Automation low-level client. In your build setup, the module from the binary distribution can be used like a support module built from source. The binary device support is fully functional and can be used without limitations or any fees.

You need to download the binary distribution tar that matches your Linux distribution and the exact EPICS Base version, else you will not be able to create IOCs.

Feedback / Reporting issues

Please use the GitHub project's issue tracker.

Credits

This module is based on extensive prototype work by Bernhard Kuner (HZB/BESSY) and uses ideas and code snippets from Michael Davidsaver (Osprey DCS).

Support for the open62541 client library was added by Dirk Zimoch (PSI) with additional help from Carsten Winkler (HZB/BESSY).

The end-to-end test suite is a reduced clone of the test application that has been developed at the ESS by Ross Elliot and Karl Vestin.

License

This module is distributed subject to a Software License Agreement found in file LICENSE that is included with this distribution.

opcua's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

opcua's Issues

Add unit tests for user interface (iocShell/linkParser)

Time to get some Google Test things in place.

A good starting point would be covering the user facing APIs:

  • The commands that are being called from the iocShell (st.cmd script)
  • The parser that converts a link field to a linkInfo structure

Don't understand this:

in DataElementuaSdk.cpp, readInt32(), line 132

 line 132    if (OpcUa_IsNotGood(tempValue.toInt32(v)))
        throw std::runtime_error(SB() << "incoming data out-of-bounds");

To me there is the value of data compared to 0xC0000000. Seems to be nonsens.
See definition of macro OpcUa_IsNotGood():

/* tests if a status code is not good. */
#define OpcUa_IsNotGood(xCode) (((xCode) & 0xC0000000) != 0x00000000)

Suppress error message when no nodes are to be registered

If no nodes are configured for registration, the service call is issued anyway and prints

OPC UA session LA: (registerNodes) registerNodes service failed with status BadNothingToDo

The service call should not be issued if there are no nodes to be registered.

Float/double value range-checking is broken

originally reported by @bkuner:

Value range-check for float/double does not allow 0 or negative values
The range check on outgoing values rejects 0 or negative values for OPC UA variables of type OpcUa_Float or OpcUa_Double.

To Reproduce

  1. Setup server with a float or double value
  2. Create IOC database with a record that writes to that item
  3. Start IOC, write to the record

Screenshots
Two analog records pointing to the same OpcUa_Float item.
First, -12 is written to the server using UaExpert (both records update).
Then, a CA put tries to write -3.6 to the ao record.

Element [ROOT] set data (incomingData) for record ao4 (queue use 1/3)
Registering record ao4 for processing (incomingData)
Element [ROOT] set data (incomingData) for record ai4 (queue use 1/3)
Registering record ai4 for processing (incomingData)
cbLow: dbProcess of 'ao4'
ao4: (server time 2019-08-29 11:21:20.065000000) reading -12 (OpcUa_Float) as Float64 (remaining queue 0/3)
ao4: read status is 'Good'
ao4: read -> VAL=-12
cbLow: dbProcess of 'ai4'
ai4: (server time 2019-08-29 11:21:20.066000000) reading -12 (OpcUa_Float) as Float64 (remaining queue 0/3)
ai4: read status is 'Good'
ai4: read -> VAL=-12

epics> 
epics> ca:ralph@debian-testing: dbProcess of 'ao4'
ao4 Error : outgoing data out-of-bounds
ao4: write <- VAL=-3.6

Setup

  • OPCUA Support: v0.5.1
  • Platform: Debian Testing
  • EPICS Base: 7.0.3
  • Client library: UA SDK 1.5.5
  • Server: S7-1500

Support array data

Support reading/monitoring/writing of arrays of OPC UA basic data types, using the waveform and aai/aao record types from EPICS base.

Test: improve integration of GoogleTest in EPICS build

The currently used TAP listener has two disadvantages:

  1. On stdout, the good output of GoogleTest is replaced by the primitive TAP output.
  2. Only one test or test fixture is allowed per test program.

It would be advised to change the EPICS integration to

  • keep the good GoogleTest output on the console
  • write the TAP output directly to files (one per test / fixture) and collect those results

Misspelled NodeIDs show up on access as conversion errors

Reported by Mikel Rojo:

When NodeIDs are misspelled in record links, they do not generate warning messages or set the record INVALID. Instead, every use of the record generates an "no such conversion" exception. This is very misleading.

Support writing of structures

Structured data should be written by taking a copy of the cached incoming structure held at item level, then setting all data elements from those record-connected leafs of the structure that have been written to, finally calling the write service.

Wrong behavior for OROC limited ao records that use monitor=y

When using the OROC rate-of-change limiting functionality, updating the record with data received from OPC UA does not work.

Updates from OPC UA should be blocked while the output is ramping.

When this happens on a record for the first time, a warning message should be logged.

Make integer range checking strictness configurable

Suggested by @bkuner:

Properly checked integer ranges are nice and consequential, but can also be a pain.
What about a "sloppy" checking mode that only checks for the size (number of bytes) and/or a "none" checking mode that just reads/writes?
Should be configurable by record/data element.

Add 'pini' option to control reconnect process behaviour

PINI processing does not work for OPC UA, instead all records are being read when the connection comes up.

However, there are cases where the IOC designer wants to forcefully write an output record when the connection comes up. To achieve this, an equivalent option in the link specification is needed.

Possible values:

  • read (default): read and update record on connection
  • ignore: read on connection to determine data type, don't update record
  • write: read on connection to determine data type, then write the record value.

Read completion callback segfaults after WatchdogTimeout

release 0.5.2, SDK 1.6.3

Manuel Zaera-Sanz (ESS) reported;

  1. Recently, from time to time, the IOC crashes with a segmentation fault when a timeout of the communications occurs instead of trying to reconnect:
OPC UA session MPSoS:Ctrl-IOC-01:Mag: connection status changed from Connected to ConnectionWarningWatchdogTimeout
/home/iocuser/epics/base-7.0.3/require/3.1.1/bin/iocsh.bash: line 145:  3909 Segmentation fault      (core dumped)
This is the stack trace:
#0  0x00007f4480faf1d0 in UaStatusCode::operator=(unsigned int const&) ()
   from /home/iocuser/epics/base-7.0.3/require/3.1.1/siteMods/opcua/0.5.2/lib/linux-x86_64/../../../../../siteLibs/vendor/opcua/0.5.2/libuabasecpp.so
#1  0x00007f448136a99f in setReadStatus (status=<optimized out>, this=0x1ae0f20)
    at ../devOpcuaSup/UaSdk/ItemUaSdk.h:101
#2  DevOpcua::SessionUaSdk::readComplete (this=0x1604bc0, transactionId=<optimized out>, result=..., values=..., 
    diagnosticInfos=...) at ../devOpcuaSup/UaSdk/SessionUaSdk.cpp:570
#3  0x00007f44854d43ef in UaClientSdk::UaSessionPrivate::readCallback(_OpcUa_ReadResponse*, unsigned int) ()
   from /home/iocuser/epics/base-7.0.3/require/3.1.1/siteMods/opcua/0.5.2/lib/linux-x86_64/../../../../../siteLibs/vendor/opcua/0.5.2/libuaclientcpp.so
#4  0x00007f44854dbdb1 in UaClientSdk::CallbackJob::execute() ()
   from /home/iocuser/epics/base-7.0.3/require/3.1.1/siteMods/opcua/0.5.2/lib/linux-x86_64/../../../../../siteLibs/vendor/opcua/0.5.2/libuaclientcpp.so
#5  0x00007f4481150555 in UaJobThread::run() ()
   from /home/iocuser/epics/base-7.0.3/require/3.1.1/siteMods/opcua/0.5.2/lib/linux-x86_64/../../../../../siteLibs/vendor/opcua/0.5.2/libuabasecpp.so
#6  0x00007f4480d19310 in InternalThreadMain ()
   from /home/iocuser/epics/base-7.0.3/require/3.1.1/siteMods/opcua/0.5.2/lib/linux-x86_64/../../../../../siteLibs/vendor/opcua/0.5.2/libuastack.so
#7  0x00007f4480d25e64 in pthread_main ()
   from /home/iocuser/epics/base-7.0.3/require/3.1.1/siteMods/opcua/0.5.2/lib/linux-x86_64/../../../../../siteLibs/vendor/opcua/0.5.2/libuastack.so
#8  0x00007f448281fdd5 in start_thread () from /lib64/libpthread.so.0
#9  0x00007f4482b31ead in clone () from /lib64/libc.so.6

I do not know why is this happening. We are investigating the issue with the infrastructure group. It happens since yesterday, not before, so I assume is something related to networking but not sure.

The latest SDK evaluation version question

Describe the bug
Compiling failure

To Reproduce
Steps to reproduce the behavior:

  1. Extract the latest SDK into /home/jhlee/programs/UASDK

  2. Set the following variables in configure/CONFIG_SITE.local

UASDK:=/home/jhlee/programs/UASDK
STATIC_BUILD=YES
SHARED_LIBRARIES=NO
  1. make distclean and make
/usr/bin/g++  -D_GNU_SOURCE -D_DEFAULT_SOURCE            -D_X86_64_  -DUNIX  -Dlinux      -O3   -Wall     -std=c++11  -mtune=generic      -m64  -I. -I../O.Common -I. -I. -I.. -I../../include/compiler/gcc -I../../include/os/Linux -I../../include   -I../../../include -I/home/jhlee/epics-7.0.4/epics-base/include/compiler/gcc -I/home/jhlee/epics-7.0.4/epics-base/include/os/Linux -I/home/jhlee/epics-7.0.4/epics-base/include        -I/home/jhlee/programs/UASDK/include -I/home/jhlee/programs/UASDK/include/uaclientcpp -I/home/jhlee/programs/UASDK/include/uapkicpp -I/home/jhlee/programs/UASDK/include/uabasecpp -I/home/jhlee/programs/UASDK/include/uastack -I/home/jhlee/programs/UASDK/include/xmlparsercpp    -c ../opcuaIocMain.cpp
/usr/bin/g++ -o opcuaIoc -Wl,-Bstatic -L/home/jhlee/gitsrc/EPICS-env/opcua-src/lib/linux-x86_64 -L/home/jhlee/gitsrc/EPICS-env/opcua-src/exampleTop/lib/linux-x86_64 -L/home/jhlee/epics-7.0.4/epics-base/lib/linux-x86_64 -L/home/jhlee/programs/UASDK/lib -Wl,-rpath,/home/jhlee/gitsrc/EPICS-env/opcua-src/lib/linux-x86_64 -Wl,-rpath,/home/jhlee/gitsrc/EPICS-env/opcua-src/exampleTop/lib/linux-x86_64 -Wl,-rpath,/home/jhlee/epics-7.0.4/epics-base/lib/linux-x86_64 -Wl,-rpath,/home/jhlee/programs/UASDK/lib     -Wl,--disable-new-dtags       -rdynamic -m64         opcuaIoc_registerRecordDeviceDriver.o opcuaIocMain.o    -lopcua -ldbRecStd -ldbCore -lca -lCom -luaclientcpp -luapkicpp -luabasecpp -luastack -lxmlparsercpp -Wl,-Bdynamic -lxml2 -lcrypto -lpthread   -lreadline -lm -lrt -ldl -lgcc
/usr/bin/ld: cannot find -luastack
collect2: error: ld returned 1 exit status

because the latest SDK have all static libraries and has only libuastack.so as dynamic.

  1. So, I went to into exampleTop/opcuaIocApp/O.linux-x86_64, then change libuastack to be in dynamic area such as
O.linux-x86_64 (master)$ /usr/bin/g++ -o opcuaIoc -Wl,-Bstatic -L/home/jhlee/gitsrc/EPICS-env/opcua-src/lib/linux-x86_64 -L/home/jhlee/gitsrc/EPICS-env/opcua-src/exampleTop/lib/linux-x86_64 -L/home/jhlee/epics-7.0.4/epics-base/lib/linux-x86_64 -L/home/jhlee/programs/UASDK/lib -Wl,-rpath,/home/jhlee/gitsrc/EPICS-env/opcua-src/lib/linux-x86_64 -Wl,-rpath,/home/jhlee/gitsrc/EPICS-env/opcua-src/exampleTop/lib/linux-x86_64 -Wl,-rpath,/home/jhlee/epics-7.0.4/epics-base/lib/linux-x86_64 -Wl,-rpath,/home/jhlee/programs/UASDK/lib     -Wl,--disable-new-dtags       -rdynamic -m64         opcuaIoc_registerRecordDeviceDriver.o opcuaIocMain.o    -lopcua -ldbRecStd -ldbCore -lca -lCom -luaclientcpp -luapkicpp -luabasecpp  -lxmlparsercpp -Wl,-Bdynamic -lxml2 -lcrypto -lpthread   -lreadline -lm -lrt -ldl -lgcc -luastack
  1. I have opcuaIoc in that directory.

Expected behavior

Setup (please complete the following information if applicable):

  • OPCUA Support: master branch

  • Platform:

Linux 4.19.0-10-amd64 #1 SMP Debian 4.19.132-1 (2020-07-24) x86_64 GNU/Linux
gcc (Debian 8.3.0-6) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  • EPICS Base: 7.0.4

  • Client library: uasdkcppbundlepubsub-bin-EVAL-debian9.2.3-x86_64-gcc6.3.0-v1.7.2-493.tar.gz

  • Server: N/A

Additional context

What do you @ralphlange thinking about this? Is my approach valid? Anyway I am coming back to OPCUA world now. So I can fork you more. :)

One more issue: if I set the INSTALL_LOCATION in configure/CONFIG_SITE.local. the opcuaIocApp cannot find the dbd file. Is it better to adjust OPCUA in exampleTop to point the INSTALL_LOCATION instead of $(TOP)/..? Or is this a duty which each user has to define it clearly?

Support registration of NodeIDs

To speed up access, OPC UA supports registration of Node IDs. This allows the client to use numerical IDs in the wire and enables optimizations on the server (shortcuts to device data).

This should be configurable (link option), as servers may limit the number of registrations. (E.g. the Siemens S7-1500 has a limit of 1000 registered nodes.)

Special care needed to handle re-registration correctly after cases of connection loss.

Batch read and write service requests in separate threads

To improve performance, the single item (asynchronous) requests for the OPC UA read and write services should be replaced by a combination of queues (probably three: one for each EPICS record priority) and separate threads that use synchronous calls to the OPC UA services.

Batch sizes can be honored when pulling work off the queue.

Queues should be templates to allow all implementations to use them. (Threads that use client library calls are part of the implementation.)

Using monitor=y in element record is treated as error

Setting monitor=y in element record triggers false positive
In the item record / element record setup, correctly configured element records trigger fatal errors:
Error in add_record : monitor requires link to a subscription

To reproduce

  1. Create IOC database that contains an element record pointing to an item record.
  2. Start IOC.

Expected behavior
The error condition should rather be:
monitor requires link to a subscription or to an item record (with a link to a subscription).

Screenshots

#CPU0-TEST-TEST-FC0.db (after remove register option)

record (opcuaItem,"TEST-OPC-FC0:STATES")
{
	field(DESC, "structure")
	field(DTYP, "OPCUA")
	field(INP, "@SUB ns=3;s=\"OpcDbWp\".\"States\" sampling=100")
	field(SCAN, "I/O Intr")
	field(TSE, "-2")
}

record (mbbiDirect,"TEST-TEST-FC0:STS-REGISTER")
{
	field(DESC, "STATUS REGISTER")
	field(DTYP, "OPCUA")
	field(INP, "@TEST-OPC-FC0:STATES element=TEST_TEST_FC0.WP_0002.bin_status.StsReg01")
	field(TSE, "-2")
}

#IOC shell error

OPC UA Client Device Support v0.5.0; using Unified Automation C++ Based OPC UA Client SDK
item record: set pitem to 0xdce5a0 in connector at pvt 0xdcdf20
TEST-TEST-FC0:STS-REGISTER Error in add_record : monitor requires link to a subscription
reboot_restore: entry for file 'iocTEST-TEST-PSH0CPU.sav'
reboot_restore: Found filename 'iocTEST-TEST-PSH0CPU.sav' in restoreFileList.
*** restoring from '/home/codac-dev/UNICOS/b-ACL-OPC-MRG/var/autosave/iocTEST-TEST-PSH0CPU.sav' at initHookState 7 (after record/device init) ***
1 PV had no saved value.
reboot_restore: done with file 'iocTEST-TEST-PSH0CPU.sav'

OPC UA: Autoconnecting sessions
OPC UA session PLC: connection status changed from Disconnected to Connected
OPC UA session PLC: (registerNodes) registerNodes service failed with status BadNothingToDo
terminate called after throwing an instance of 'std::runtime_error'
  what():  stale pointer to root data element
/opt/codac-6.1/bin/services/service-startup: line 344: 34071 Aborted                 (core dumped) /bin/bash -c ```

**Setup**
-   OPCUA Support: 0.5.0

linkParser: report misspelled options

Misspelled link options are silently ignored
When misspelling the option setting monitor=n as monitoring=n, it is silently ignored and the default monitor=y is being used.
When linked to a session (not a subscription), the only error message is

ao1 Error in add_record : monitoring an output requires a valid subscription

showing that monitor=y is being used.

To Reproduce
Steps to reproduce the behavior:

  1. Create IOC database that specifies monitoring=n in an output record.
  2. Start IOC.

Expected behavior
A clear and concise error message about an unrecognized option.

Setup:

  • OPCUA Support: v0.4.0

Connection failures trigger "no incoming data" errors

Seen by @bkuner:

Problem
When the server drops the connection, records are being processed (probably to recognize the connection status change) and print "no incoming data" errors - one for each record.

Expected behavior
In case of processing after connection loss, having no incoming data is the normal case and should not be treated as an error.

Support spaces in NodeID name string

As we mailed, there is a need of support blanks in node - because it is an allowed character for a node definition - as well as the cruel ". We can ask our own programmers to avoid this but not externals.
My suggestion is to implement the link as an name=value; list, maybe with user definable seperator for the node and more parameters.
E.g. 'SUBSCRIPTION_TAG ns=2;s=what. is this; monitor=y,somthing=else'

Improve error/status handling

After introducing the client side queues, error and status handling have to be re-organized.

Status information must not be cached in the item, but put in the client side queue together with the data and timestamp. In principle connection drops do not have status and data - maybe a dummy package could keep the code consistent and simple.

This is related to #12, which is a side-effect of not handling errors appropriately.

opcuaSetOption

Describe the bug
Without arguments, if one executes opcuaSetOption, there is a segmentation fault.

To Reproduce
Steps to reproduce the behavior:

  1. Build the example ioc
  2. Run the ioc
  3. within ioc prompt,
epics> opcuaSetOption
missing argument #1 (session name)
missing argument #2 (option name)
Segmentation fault

Expected behavior
A clear and concise description of what you expected to happen.

It will print out "help"

Setup (please complete the following information if applicable):

  • OPCUA Support: a52002c
  • Platform: Debian 10 / CentOS 7
  • EPICS Base: 7.0.3
  • Client library: UA SDK 1.7.0
  • Server: Without any server

Additional context
Add any other context about the problem here.

Silently ignore processing while the connection is down

Currently, every record processing (periodic or passive/CA) while the connection is down leads to error messages:

OPC UA session LA: (requestRead) beginRead service failed with status BadConnectionClosed

While the connection is closed, no OPC UA services should be triggered. Records should already be in the COMM/INVALID state, as that happens when the connection drops.

Max-items-per-service-call does not work with UA SDK

Bug Description
The UA SDK feature of setting the maximum number of items per service call is buggy. The setting is only honored by synchronous OPC UA service calls and does not work for the asynchronous call variants.

To Reproduce
Steps to reproduce the behavior:

  1. Setup an S7-1500 server (that has a limit of 1000 items per service call)
  2. Create IOC database that puts >1000 items on a single subscription
  3. The subscription will not work at all

Setup

  • OPCUA Support: 0.4.0
  • Platform: RHEL7.4
  • EPICS Base: 7.0.2
  • Client library: UA SDK 1.5.5
  • Server: S7-1500

Add connection status PV (by session)

SSIA.

There needs to be support for an mbbi "connection status" PV per session, so that connection history and status can be seen and archived without going to the console log.

Move session/subscription registrar into a template

The registrar functions of the session and the subscription have lots of repeated code.

The name keeping and management should be handled generically in a template class that can be used by sessions and subscriptions of all implementations.

Allow DESC field to be set from OPC UA item

OPC UA items have a description that could be used to set DESC
There is an information structure for all OPC UA items that contains a string field with a description. This could be read at connection time and used to set the DESC field of the record that connects to the item.

Since this description might not contain useful information on a specific OPC UA server, and to avoid clashing with DESC settings in the EPICS database, this should be configurable per record (option) with a global default (variable) that can be set from the startup script.

monitored mbboDirect record does not get updated properly

RVAL is not back-converted to VAL
For an mbboDirect record that is bidirectional (uses monitor=y), any update from OPC UA is correctly written into RVAL, but VAL does not get updated.

To Reproduce

  1. Setup server with a data item of type DWord
  2. Create IOC database that connects an mbboDirect record to the DWord
  3. Start IOC, change the value on the OPC UA server (e.g. using UaExpert)
  4. See the RVAL changing, but VAL and B0...Bn keeping the same

Expected behavior
On a data update from OPC UA, the RVAL value should be converted to the VAL, and VAL as well as the single bit fields should be updated.

Screenshots

ralph@debian-testing:~$ camonitor mbbod2 mbbod2.RVAL mbbod2.B1  mbbod2.B2 mbbod2.B3 mbbod2.B4 mbbod2.B5 mbbod2.B6 mbbod2.B7 mbbod2.B0
mbbod2                         2019-07-10 11:28:40.865000 0  
mbbod2.RVAL                    2019-07-10 11:28:40.865000 15  
mbbod2.B1                      2019-07-10 11:28:40.865000 0  
mbbod2.B2                      2019-07-10 11:28:40.865000 0  
mbbod2.B3                      2019-07-10 11:28:40.865000 0  
mbbod2.B4                      2019-07-10 11:28:40.865000 0  
mbbod2.B5                      2019-07-10 11:28:40.865000 0  
mbbod2.B6                      2019-07-10 11:28:40.865000 0  
mbbod2.B7                      2019-07-10 11:28:40.865000 0  
mbbod2.B0                      2019-07-10 11:28:40.865000 0  

mbbod2.RVAL                    2019-07-10 11:29:48.865000 2  
mbbod2.RVAL                    2019-07-10 11:30:33.865000 3  
mbbod2.RVAL                    2019-07-10 11:30:38.865000 4  

Setup (please complete the following information if applicable):

  • OPCUA Support: v0.4.0

On IOC shutdown, do not set records to COMM/INVALID

When the IOC shuts down, all records are being processed for ProcessReason::connectionLoss because the connection to the OPC UA server is shut down.

While this is correct for connections going down during the IOC life time, doing this as part of shutdown does not make sense.

Add example application

The example application should

  • build an IOC binary
  • contain generic (namespace 0) databases that will work on any server
  • contain specific databases for server types that show how server specific things would look like.

Travis-ci: skip builds for PRs

Travis-CI builds for PRs are not working, as the UA SDK build uses secrets which are not available for PR builds.
To avoid PRs showing failed builds, these should be skipped instead.

Invalid single element record creates core dump

A single invalid element record leaves the item record with a stale pointer
If the only element record of a structured item does not get initialized properly, the item record is left with a stale root element record pointer, leading to a core dump during initialization.

To reproduce

  1. Create IOC database with a single element record pointing to an item record and an error (invalid option) in that single element record.
  2. Start IOC.

Expected behavior
An error in an element record should leave the existing structure intact with no residual stale pointers, even in the corner case of the element record being the only part of the structure.

Screenshots

#CPU0-TEST-TEST-FC0.db (original version, working with driver v0.4)
record (opcuaItem,"TEST-OPC-FC0:STATES")
{
	field(DESC, "structure")
	field(DTYP, "OPCUA")
	field(INP, "@SUB ns=3;s=\"OpcDbWp\".\"States\" sampling=100")
	field(SCAN, "I/O Intr")
	field(TSE, "-2")
}

record (mbbiDirect,"TEST-TEST-FC0:STS-REGISTER")
{
	field(DESC, "STATUS REGISTER")
	field(DTYP, "OPCUA")
	field(INP, "@TEST-OPC-FC0:STATES element=TEST_TEST_FC0.WP_0002.bin_status.StsReg01 register=y")
	field(TSE, "-2")
}

#IOC shell error

OPC UA Client Device Support v0.5.0; using Unified Automation C++ Based OPC UA Client SDK
item record: set pitem to 0x1b736b0 in connector at pvt 0x1b73030
TEST-TEST-FC0:STS-REGISTER Error in add_record : invalid option 'register'
reboot_restore: entry for file 'iocTEST-TEST-PSH0CPU.sav'
reboot_restore: Found filename 'iocTEST-TEST-PSH0CPU.sav' in restoreFileList.
*** restoring from '/home/codac-dev/UNICOS/b-ACL-OPC-MRG/var/autosave/iocTEST-TEST-PSH0CPU.sav' at initHookState 7 (after record/device init) ***
1 PV had no saved value.
reboot_restore: done with file 'iocTEST-TEST-PSH0CPU.sav'

OPC UA: Autoconnecting sessions
OPC UA session PLC: connection status changed from Disconnected to Connected
OPC UA session PLC: (registerNodes) registerNodes service failed with status BadNothingToDo
terminate called after throwing an instance of 'std::runtime_error'
  what():  stale pointer to root data element
/opt/codac-6.1/bin/services/service-startup: line 344: 23835 Aborted                 (core dumped) /bin/bash -c "$cmd"

Setup

  • OPCUA Support: 0.5.0

Include actual item properties in show() function

The OPC UA server can override item configuration, enforcing server-defined limits on sampling interval, queue size or discard policy.

The show() method of items should print the actual and the configured value for these properties.

Allow the same options for monitor and autoconnect

@ralphlange

Is your feature request related to a problem? Please describe.

It is not any problem, but it would be better to use the same options. For example,

In https://github.com/ralphlange/opcua/blob/master/devOpcuaSup/linkParser.cpp#L101,
the available options are YyTt1 or NnFf0 in order to enable or disable monitor such as

                char c = optval[0];
                if (strchr("YyTt1", c))
                    pinfo->monitor = true;
                else if (strchr("NnFf0", c))
                    pinfo->monitor = false;
                else

However, in https://github.com/ralphlange/opcua/blob/master/devOpcuaSup/iocshIntegration.cpp#L104
the available options for autoconnect have YyTt or NnFf such as

            char c = args[3].sval[0];
            if (c == 'n' || c == 'N' || c == 'f' || c == 'F') {
                autoconnect = false;
            } else if (c != 'y' && c != 'Y' && c != 't' && c != 'T') {
                errlogPrintf("invalid argument #4 (autoconnect) '%s'\n",
                             args[6].sval);
            }

Describe the solution you'd like

It would be better to use YyTt1 or NnFf0 in both places.

Thanks,
@jeonghanlee

monitored bo record does not get updated properly

RVAL is not back-converted to VAL
For a bo record that is bidirectional (uses monitor=y), any update from OPC UA is correctly written into RVAL, but VAL does not get updated.

To Reproduce

  1. Setup server with a data item of type bool
  2. Create IOC database that connects a bo record to the bool data
  3. Start IOC, flip the bit on the OPC UA server (e.g. using UaExpert)
  4. See the RVAL changing, but VAL kept the same

Expected behavior
On a data update from OPC UA, the RVAL value must be converted to the VAL enum, very much like in the case of an mbbo record.

Screenshots

ralph@debian-testing:~$ camonitor bo2 bo2.RVAL
bo2                            2019-07-10 09:47:29.018082 true  
bo2.RVAL                       2019-07-10 09:47:29.018082 0  

bo2.RVAL                       2019-07-10 09:48:23.033573 1  
bo2.RVAL                       2019-07-10 09:48:28.039508 0  

Setup (please complete the following information if applicable):

  • OPCUA Support: v0.4.0

Make subscription debug level configurable from iocShell

Debugging on subscription level should be configurable from the iocShell
Similar to opcuaDebugSession that allows setting the debug level for session level debugging, there should be a function allowing to set the debug level for the subscription.

opcuaDebugSubscription would be an appropriate name.

Support for server-side queues

Support for server-side queues needs incoming data also be queued on the client side.

This queue needs to be able to drop updates when full (but keep a drop counter) and handle disconnect events.

Implementation should be in the generic part, probably as a template class. (As it needs to work with data update objects from different client implementations. )

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.