Skip to content

ttrau/opcua-smart

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OPC-UA Ruby Bindings (open62541)

The development of OPC UA applications takes currently a lot of effort. This is caused by the large possibilities of the OPC UA specification. With this implemtation we want to define some conventions, which shoud make the technology more useable.

Table of Contents

  1. Modelling Style
  2. Installation
  3. Examples
    1. Server
      1. Create Server and Namespace
      2. Create ObjectTypes 1.Add Variable 2.Add Object 3.Add Method
      3. Manifest Objects
      4. Find Nodes in the Addressspace
      5. Loop for getting Real Life Data
    2. Client

Modelling Style

The idea of the opcua-smart library is to simplify the OPC UA application generation. Since OPC UA has more than 1500 pages of basic specifications, and the number is still growing, we decided to make some simplification.

This is done by some constraints regarding the modeling functionality of OPC UA. This library deliberately does not offer all functions of OPC UA to simplify the creation of applications.

COPYING

Copyright (C) 2019-* Jürgen "eTM" Mangler [email protected]. opcua-smart is freely distributable according to the terms of the GNU Lesser General Public License 3.0 (see the file 'COPYING'). This code is distributed without any warranty. See the file 'COPYING' for details.

Installation

# Debian/Ubuntu
apt install build-essential cmake-curses-gui libmbedtls-dev libxml2-dev libxslt-dev libz-dev libssl-dev libicu-dev 
# Fedora/Redhat
dnf install @buildsys-build @development-tools cmake libxml2-devel libxslt-devel zlib-devel libicu-devel mbedtls-devel

Dependency: https://github.com/open62541/open62541 > 0.4 (master branch as of 2019-04-26)

git clone https://github.com/open62541/open62541.git
cd open62541
mkdir build
cd build
cmake ..
ccmake ..
# Configuration, see picture below
make
sudo make install
gem install opcua

ccmake Config

If the installation works correctly, but examples are still complaining about missing lib62541.so, try this:

sudo echo "/usr/local/lib" > /etc/ld.so.conf.d/local.conf # add to libs path
sudo ldconfig # update libs
sudo ldconfig -p | grep libopen62541 # check if its there

or on 64-bit systems:

sudo echo "/usr/local/lib64" > /etc/ld.so.conf.d/local.conf # add to libs path
sudo ldconfig # update libs
sudo ldconfig -p | grep libopen62541 # check if its there

Development

Use rake to build c bindings:

rake

Run server with verbose:

ruby example/server_import_nodeset.rb -v restart

Use relative paths to ruby libraries:

#require 'opcua/server'
require_relative '../lib/opcua/server'

EXAMPLES

Server

The server has following functions:

  • Create the server and add_namespace
  • Create ObjectTypes
  • Manifest ObjectTypes
  • Delete Objects
  • Find nodes in the adress space
  • Loop for getting real life data

Every server application uses the Demonite gem, which allows to run the server as service.

Daemonite.new do
  on startup do |opts|
    ...
  end
  run do |opts|
    ...
  end
  on exit do
    ...
  end
end.loop!

Each server has 3 sections the startup, run, and exit. In the startup we create the server and the namespace, define all nodes and typically manifest the adress space. The run section loops and therefore updates the values of the nodes in the server. On exit we can d additionally things e.g. close the connection to another interface.

Create Server and Namespace

server = OPCUA::Server.new
server.add_namespace "https://yourdomain/testserver"

Create ObjectTypes

Basically all new created types are subtypes of the BaseObjectType. With server.types.add_object_type(:TestObjectType) a new type is defined in the information model. All nodes of the new created type are defined in the tap{} region.

to = server.types.add_object_type(:TestObjectType).tap{ |t|
  t.add_variable :TestVariable
  t.add_object(:TestObject, server.types.folder).tap{ |u|
    u.add_object :M, mt, OPCUA::OPTIONAL
  }
  t.add_method :TestMethod, inputarg1: OPCUA::TYPES::STRING, inputarg2: OPCUA::TYPES::DATETIME do |node, inputarg1, inputarg2|
    #do some stuff here
  end
}

In this example the TestObjectType is defined. It consits of TestVariable of the BaseVariableType an TestObject of the FolderType and a TestMethod.

Add Variable

The .add_variable :TestVariable command adds a variable with the name TestVariable. Multible variables can be defined at once with the .add_variables command.

t.add_variables :TestVar1, :TestVar2

By default variables are read-only. If you want to add a variable with read/write support you must use the .add_Varable_rw method.

t.add_variable_rw :TestVar1
Add Object

With .add_object(:TestObject) a new object named TestObject is added. The second parameter is optional and definies of which type the new object is. Default the object is from BaseObjectType. In this example the created object is from FolderType. All child nodes of the object can be definded in the tap{} area.

Add Method

Methods are added with the .add_method(:TestMethod) function. Per default the method has no input and output arguments. By adding additional arguments you can define input arguments. The code for defining a method with input arguments looks like

 t.add_method :TestMethod, inputarg1: OPCUA::TYPES::STRING, inputarg2: OPCUA::TYPES::DATETIME do |node, inputarg1, inputarg2|
    #do some stuff here
   end

Input arguments can have a name and a type. in the do...endsection you write the code which should be executed by calling the method.

Manifest Objects

ObjectTypes can be instiantiated with the .manifest method.

testobject =server.objects.manifest(:TestObjectType, to)

Delete Objects

Objects can be deleted witch the .delete! function.

testobject =server.objects.manifest(:TestObjectType, to)
testobject.delete!

Find Nodes in the Addressspace

To get a specific node you should use the .find method.

tv = to.find :TestVariable

tv is now the TestVariable node.

You can also find several nodes at the same time.

tva = to.find :TestVariable1, :TestVariable2

tva is now a array containing the requested nodes.

tv1, tv2 = to.find :TestVariable1, :TestVariable2

You can also request several nodes with one find statement.

Access the value of a node

To get the value of a specific node use the .value method.

tv.value = 10
tv.value = 'ten'
puts tv.value

You can assign vlaues without definig a datatype. The correct DataType will be used. Default we use _UA::STRING, UA::DOUBLE and UA::INT. Additional Datatypes can be added by request.

Loop for getting Real Life Data

The server loop looks like follows:

 run do 
    sleep server.run
    to.value = 'Testvariable1'
    p to.value
 rescue => e
    puts e.message
 end

The loop starts with sleep server.run. This is recommended by the open62541 developer. With the .value function you can write or get the value of a node.

Client

TBD. See examples subdirectory.

About

OPC-UA Ruby Bindings (open62541)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C 97.9%
  • Ruby 2.1%