<h2>Name</h2>

<b>opcua</b> - Tcl binding to the OPC/UA implementation of

<h2>Synopsis</h2>

<tt>package require topcua</tt><br>
<tt>opcua <i>cmd</i>

<h2>Description</h2>

This command provides several operations to manage and communicate using the OPC/UA implementation of It is available on common POSIX and Windows platforms. indicates which operation  to carry out. Any unique abbreviation for is acceptable. The valid commands are:


<tt>opcua add <i>handle</i> DataType <i>nodeid parent reftype brname

    Adds an new node of node class <tt>DataType</tt> in the server  object and returns the node identifer. The parameter is the requested new node identifier of the  node  to  be  created. is the parent node identifier and the reference type or node identifier of the reference between the parent and the new node. is the browse name (see section <b>Qualified Names</b>) of the new node. The optional parameter specifies attributes for the new node in form of a dictionary (see <tt>opcua attr default</tt>). If it is omitted, default values  are used. The attribute if left empty is preset to the name part of the browse name parameter.

<tt>opcua add <i>handle</i> Method <i>nodeid parent reftype outargs brname inargs cmd

    Adds an new node of node class <tt>Method</tt> in the server object and returns the node identifer. The parameter describes the output arguments of the method as a list  of zero or more pairs of data type and argument name. Likewise, describes the input arguments of the method. The  parameter is the Tcl callback to handle the method invocation, see section <b>Method Callbacks</b> for more information. For the  other parameters, refer to <tt>opcua add DataType</tt>.

<tt>opcua add <i>handle</i> Namespace

    Adds the new namespace to the server object and returns a numeric identifier for this namespace.

<tt>opcua add <i>handle</i> Object <i>nodeid parent reftype brname ?typeid

    Adds an new node of node class <tt>Object</tt> in the server object and returns the node identifer. The optional parameter must be a known data type name (see  <tt>opcua  types</tt>) or a node  identifier of a data type. For the other parameters, refer to <tt>opcua add DataType</tt>.

<tt>opcua add <i>handle</i> ObjectType <i>nodeid parent reftype brname

    Adds an new node of node class <tt>ObjectType</tt> in the  server object and returns the node identifer. For the other parameters, refer to <tt>opcua add DataType</tt>.

<tt>opcua add <i>handle</i> Reference <i>srcid reftype target

    Adds a reference of type (see <tt>opcua reftype</tt>) between the node identifiers and on the server object The optional parameter must be a boolean indicating the direction of the reference (true, the default, is forward, false is inverse).

<tt>opcua add <i>handle</i> ReferenceType <i>nodeid parent reftype brname

    Adds an new node of node class <tt>ReferenceType</tt> in the server object  and returns the node identifer. For the other parameters, refer to <tt>opcua add DataType</tt>.

<tt>opcua add <i>handle</i> Variable <i>nodeid parent reftype brname ?typeid  attrs

    Adds an new node of node class <tt>Variable</tt> in the server object and returns the node identifer. The optional parameter must be a known data type name (see <tt>opcua types</tt>)  or a node identifier of a data type or an empty string for a default value. Parameter is an optional data source callback which produces  (read operation) or consumes (write operation) the variable's value. See section <b>Data Source Callbacks</b> for  more information. For the other parameters, refer to <tt>opcua add DataType</tt>.

<tt>opcua add <i>handle</i> VariableType <i>nodeid parent reftype brname ?typeid

    Adds an new node of node class <tt>VariableType</tt> in the server object and returns the node identifer. The optional parameter must be a known data type name (see <tt>opcua types</tt>) or a node identifier of a data type or an empty string for a default value. For the other parameters, refer to <tt>opcua add DataType</tt>.

<tt>opcua add <i>handle</i> View <i>nodeid parent reftype brname

    Adds an new node of node class <tt>View</tt> in the server object and returns the node identifer. For the other parameters, refer to <tt>opcua add DataType</tt>.

<tt>opcua attrs ?list|default?

    Without further arguments returns a list of attribute names the <tt>opcua read</tt> and <tt>opcua write</tt> commands support, e.g. <tt>Value</tt>, <tt>NodeClass</tt>, etc. With the <tt>list</tt> keyword a list of the data types  used as attributes for creation of nodes with the <tt>opcua add</tt> command is returned. With the <tt>default</tt> keyword combined with the of the data type a dictionary describing the default attributes of this type is returned, e.g <tt>opcua attrs default <i>DataTypeAttributes<i></tt> yields a default dictionary for creation of a <tt>DataType</tt> node.

<tt>opcua browse <i>handle nodeid ?dir refid mask

    Performs a browse operation on the client or server object starting at the node The browse direction can be specified with the parameter as <tt>Forward</tt>, <tt>Inverse</tt>, or <tt>Both</tt>. <tt>Forward</tt> is the default direction. The optional and following parameters select specific node classes <tt>Object</tt>, <tt>Variable</tt>, <tt>Method</tt>, <tt>ObjectType</tt>, <tt>VariableType</tt>, <tt>ReferenceType</tt>, <tt>DataType</tt>, and <tt>View</tt>. The result of the browse operation is a list where each item is made up of node identifier, browse name (qualified name), display name (locale and text), node class, reference node identifier, and type node identifier.

<tt>opcua call <i>handle nodeid methodid ?type value

    Calls the method with node identifier on the object with node identifier on the client or server object with parameters described by pairs of (data type, e.g. <tt>Int32</tt> or <tt>String</tt>) and value (the parameter's value). The method's result  is  returned. The method is carried out on the server, i.e. when directly used with a server handle there's no network traffic since the method is run locally.

<tt>opcua children <i>handle

    Returns the child node identifiers of the given node identifier on the client or server object

<tt>opcua connect <i>handle url ?user

    Connects the client object to the URL using the optional credentials and

<tt>opcua datasources

    Returns information on data sources (variable nodes with callbacks) for the server object For each data source two list elements  with node identifier and callback command are added to the result.

<tt>opcua datetime ?seconds|...|utc

    Returns either POSIX or OPC/UA timestamps as <b>Tcl_WideInt</b> values. If  called without further parameters the current OPC/UA local <tt>DateTime</tt> is returned. If called with the single keyword <tt>utc</tt> the current OPC/UA  <tt>UtcTime</tt> is returned. Otherwise, is required and converted from POSIX to OPC/UA <tt>UtcTime</tt> for the keywords <tt>seconds</tt>, <tt>milliseconds</tt>, and <tt>microseconds</tt>, and from OPC/UA <tt>UtcTime</tt> to POSIX for the keywords <tt>unixseconds</tt>, <tt>unixmillis</tt>, and <tt>unixmicros</tt>, respectively.

<tt>opcua deftypes <i>handle nsuri

    Defines custom datatypes (currently only structures) in the server object and namespace URI The namespace is created with the <tt>opcua add Namespace</tt> command and must exist before the <tt>opcua deftypes</tt> command is called. The parameter describes the structures to be created. The command does all necessary steps to create the required nodes in the server object's address space and to store an XML bytestring describing the (de)serialization for the structures as extension objects. That XML is later to be reparsed with the <tt>opcua gentypes</tt> command. For details refer to section <b>Defining Custom Data Structures</b> below.

<tt>opcua delete <i>handle</i> Node <i>nodeid

    Deletes the node with identifier on the server object
If is true, the references of  the node are deleted, too.

<tt>opcua delete <i>handle</i> Reference <i>srcid reftypeid targetid ?forward?

    Deletes the reference described by and on the server object The  boolean flag selects  forward or inverse direction of the reference to be deleted. The boolean flag requests a bidirectional reference to be deleted. The default is to delete in forward direction only.

<tt>opcua destroy

    Destroys the client or server object and releases  its resources, e.g. closes network connections, tears down the handle specific namespace, etc.

<tt>opcua disconnect

    Disconnects the client object

<tt>opcua endpoints

    Queries the local OPC/UA server or the server specified by the parameter for endpoints and returns a list of URLs describing the endpoints found.

<tt>opcua genstubs <i>handle ?strip

    Generates stubs for methods in the handle specific address space derived  from the client or server object The address space is traversed and browse paths and node class paths are accumulated. The resulting browse paths optionally get the prefix stripped off from the beginning and optionally  filtered using the glob patterns following the parameter. For all nodes matching the node class path pattern the optional <tt>InputArguments</tt> and  <tt>OutputArguments</tt> child nodes are retrieved and stub procedures are written using the browse path and argument information.

<tt>opcua gentypes

    Generates custom data type mappings using information obtained from analyzing the address space derived from the client or server object This feature is highly experimental and requires the  tDOM package for parsing XML. It can create encoders/decoders for simple structure data types defined in the address space which perform a mapping from/to Tcl dictionaries. For further information, see the <b>server_types.tcl</b> and <b>client_types.tcl</b> scripts in the examples directory. If this command is used, it should be invoked prior to creating method stubs, since methods may require custom data types in their arguments.

<tt>opcua info

    Returns the object type of either <tt>client</tt> or <tt>server</tt>. If is omitted, a list of all known client and server object handles is returned.

<tt>opcua methods

    Returns information on methods for the server object For each method three list elements with node identifier, result type name, and callback command are added to the result.

<tt>opcua monitor <i>handle</i> configure <i>subid monid ?cmd mode

    Configures the monitor in subscription on the client object with the provided parameters, see <tt>opcua  monitor new</tt> for further information.

<tt>opcua monitor <i>handle</i> destroy <i>subid

    Destroys the monitor in subscription on the client object and releases all its resources.

<tt>opcua monitor <i>handle</i> info <i>subid

    Returns information on monitor in subscription on the client object The result is a list of monitor type (<tt>data</tt> or <tt>event</tt>), the node identifier, the callback command, the attribute, and the interval. If is omitted, a list of  all monitor identifers registered in the subscription is returned.

<tt>opcua monitor <i>handle</i> new <i>subid type cmd nodeid ?attr mode

    Creates a monitored item of (<tt>data</tt> or <tt>event</tt>) for the node identifier in the subscription on the client object The optional parameter selects the attribute of the node  to be monitored (<tt>Value</tt> is the default). The monitor mode must be one of <tt>Disabled</tt>, <tt>Sampling</tt>, and <tt>Reporting</tt>. The monitoring interval must be given as number of milliseconds, if omitted its value is derived from the subscription. The callback command parameter is discussed in section <b>Monitor Callbacks</b> below. The command returns a numeric identifier of the newly created monitor.

<tt>opcua namespace <i>handle

    Returns the namespace index for the namespace of the client or server object (or throws an error e.g. when the namespace doesn't exist). If is omitted, a list of all known namespace indices and corresponding URIs is returned.

<tt>opcua new ?client|server <i>port

    Creates a new client or server object and returns its handle. The parameter must be present for server objects and specifies the server's TCP port. The optional is the object name (the  handle). If no arguments are given to <tt>opcua new</tt> a client object with an automatic name is created. During that process the Tcl namespace is created which later is used to hold method stub procedures  and other information. That namespace is tied to the life time of the client or server object.

<tt>opcua parent <i>handle

    Returns the parent node identifier of the given node identifier on the client or server object

<tt>opcua ptree <i>handle

    Returns information similar to <tt>opcua tree</tt> using the client or server object The address space is traversed starting at the node identifier (the root node if omitted). The result list is made up of browse path name, node identifier, node class path, reference node identier, and type node identifier. The browse path name is a path name like notation made up of the browse names pointing to the final node as seen from the starting node. Browse names are written as qualified names, i.e. including the numeric namespace index if not in root namespace. Similarly, the node class path is a path name like notation made up of the node classes of all nodes along the path. The <tt>opcua ptree</tt> command is used internally by the <tt>opcua genstubs</tt> command in order to filter out objects and methods when creating stub Tcl commands to invoke methods on objects.

<tt>opcua read <i>handle nodeid

    Performs a read operation on the client or server object and returns the value of attribute of the node identifier If is omitted, it defaults to the <tt>Value</tt> attribute.

<tt>opcua reftype

    Returns the node identifier for the reference type When is omitted, a list of all reference type names is returned.

<tt>opcua root</tt>

    Returns the node identifier of the root node.

<tt>opcua run <i>handle

    Runs asynchronous operations (subscriptions, monitored items) on the client object for milliseconds. If is omitted, that duration defaults to one millisecond.

<tt>opcua sc2str

    Translates the numeric status code to an error message string.

<tt>opcua servers

    Queries the local OPC/UA server or the server specified by the parameter for server information and returns a list made up of three elements per server with server name, server URL, and server description.

<tt>opcua start

    Starts the server object See section <b>Server Object And Event Loop</b> below for further information.

<tt>opcua stop

    Stops the server object

<tt>opcua subscription <i>handle</i> configure <i>id ?interval lifetime keepalive max

    Configures the subscription on the client object See <tt>opcua subscription new</tt> for the optional arguments.

<tt>opcua subscription <i>handle</i> destroy

    Destroys the subscription on the client object

<tt>opcua subscription <i>handle</i> info

    Returns information about subscription on the client object as a list of enable flag, interval, lifetime,  keepalive, and  maximum counters, and the priority value. If is omitted, a list of all subscription identifiers of the client object is returned.

<tt>opcua subscription <i>handle</i> new <i>?flag interval lifetime keepalive max

    Creates a new subscription (a container for monitored items, see <tt>opcua monitor</tt>) on the client object and returns a numeric identifier of it. The following optional parameters control properties of the subscription: is the initial enable state (on by default),  and the timing and queuing parameters, and the subscription's priority.

<tt>opcua subscription <i>handle</i> off

    Disables the subscription on the client object

<tt>opcua subscription <i>handle</i> on

    Enables the subscription on the client object

<tt>opcua translate <i>handle nodeid reftype target

    Performs a translate operation on the client or server object The operation starts at node identifier and traverses the object tree along the references and browse name A list made up of the node identifier, namespace URI, and server index of the final target is returned as the result. References can be preceeded with an exclamation mark in order to reverse their direction. A reference may be abbreviated as slash for <tt>HierarchicalReferences</tt> or as dot for <tt>Aggregates</tt>.

<tt>opcua tree <i>handle

    Returns information similar to <tt>opcua browse</tt> using the client or server object The address space is traversed starting at the node identifier (the root node if omitted). The result list is made up of tree level (0-based), node identifier, browse name (qualified name), display name  (locale  and  text), node class, reference node identifier, and type node identifier.

<tt>opcua type <i>handle nodeid

    Performs a read operation on the client or server object like <tt>opcua read</tt> but instead of the attribute's value returns the type name of attribute of the node  identifier If is omitted, it defaults to the <tt>Value</tt> attribute.

<tt>opcua types basic|empty|list|nodeid

    Returns a list of OPC/UA type names for the <tt>basic</tt> and <tt>list</tt> subcommands. Basic types are primitives (e.g. integer numbers) for which a mapping to Tcl objects is provided. The subcommand requires to be a known OPC/UA type name and produces and returns an empty value of this type, e.g. 0.0 for a floating point type. The <tt><i>nodeid</i><tt> subcommand returns the node identifier for the type name.

<tt>opcua write <i>handle nodeid ?attr? type

    Performs a write operation on the client or server object writing with type into the attribute of the node identifier If is omitted, it defaults to <tt>Value</tt>.

<h2>OPC/UA Ensemble</h2>

The current implementation uses an ensemble and namespace <tt>opcua</tt>, i.e.
the command <tt>opcua info</tt> can be alternatively written as <tt>opcua::info</tt>. Some more complex subcommands of the <tt>opcua</tt> namespace are implemented in Tcl, namely the <tt>opcua tree</tt> and <tt>opcua genstubs</tt> procedures.

<h2>Node Identifiers</h2>

Numeric node identifiers can be written as <tt>ns=N;i=I</tt> where <tt>N</tt> is  the numeric namespace, and <tt>I</tt> the numeric identifier. Likewise, string node identifiers are written as <tt>ns=N;s=S</tt> with <tt>S</tt> being the string identifier. GUID node identifiers are written as <tt>ns=N;g=G</tt> where the GUID is <tt>G</tt> with the usual format as sequence of hexadecimal numbers  and dashes. The namespace part can be left out when namespace zero is addressed. Currently, byte string node identifiers are not supported. If the format cannot  be determined (e.g. since the equal sign is missing) the fallback chosen is string node identifier in namespace zero. String named namespaces are not supported.

<h2>Qualified Names</h2>

Qualified names are used for example in the <tt>opcua browse</tt> and <tt>opcua translate</tt> operations as so called browse names. These are made up of an optional numeric namespace prefix (a number followed by a colon) and a name, e.g. The namespace prefix is left out if the name refers to namespace zero.

<h2>Supported Data Types</h2>

Currently, most of the data types of namespace zero are supported and can be mapped to/from Tcl, i.e. integral and floating point numbers, strings, GUIDs, and interal extension objects (similar to structures). For the latter, dictionaries are used in both directions, i.e. for encoding, a dictionary is searched for the respective member names, for decoding, a dictionary is created from the internal representation using the member names of the data type, see <tt>opcua attrs default</tt> for example. Support for custom  data  types  is  highly experimental and underdocumented (see <tt>opcua gentypes</tt>).

<h2>Monitor Callbacks</h2>

Monitor callbacks are invoked when a monitored item (data or event) is received. The callback parameter given in <tt>opcua monitor new</tt> must have proper  list format and gets a single value (data) or a list of values (event) appended prior to invocation.

<h2>Data Source Callbacks</h2>

Data source callbacks are invoked when a is read or  written to. The callback parameter given in the node creation (<tt>opcua add Variable</tt>) must have proper list format and gets the following  parameters appended prior to invocation: the node identifier of the the operation (either <tt>read</tt> or <tt>write</tt>), and the value attribute for write operations. For read operations the callback must return a two element list of the data type (e.g. <tt>String</tt> or <tt>Int32</tt>) and the value itself. If the callback returns the <b>TCL_BREAK</b> return code, the value is assumed to be an array and splitted into list elements which then are converted to OPC/UA data in an OPC/UA array.

<h2>Method Callbacks</h2>

Method callbacks are invoked when a node is called. The callback parameter given in the node creation (<tt>opcua add Method</tt>) must  have proper list format and gets the following parameters appended prior to invocation: the object node identifier, the method node identifier, and zero or more parameters as decribed in the input argument list at creation time of the node. The callback must return a single value which is converted to the respective OPC/UA data value according to the output argument information at creation of the node. Multiple output  arguments are not supported. The same rule regarding the <b>TCL_BREAK</b> return code as described in section <b>Data Source Callbacks</b> is applied to support array results.

<h2>Client Object And Event Loop</h2>

A client object obtained with <tt>opcua new client</tt> requires a running event loop only when subscriptions and/or monitored items are involved. All other operations are performed synchronously (and thus blocking). In order to receive monitored information the <tt>opcua run</tt> operation must be invoked regularly e.g. in a timed <tt>after</tt> procedure.

<h2>Client Example</h2>

<verbatim>

    package require topcua

    # create client
    opcua new client C

    # connect to server
    opcua connect C

    # get MyNamespace
    set ns [opcua namespace C MyNamespace]

    # generate stub procs to methods in server
    # these are created in the client specific ::opcua::C namespace
    opcua genstubs C

    # list all procs in client specific namespace
    puts stderr [info procs ::opcua::C::*]

    # call stubs
    puts stderr [::opcua::C::Reverse esreveR]
    puts stderr [::opcua::C::WordSplit

    # read a variable
    puts stderr [opcua read C "ns=${ns};ItsTclTime"]

    # monitor callback proc
    proc monitor {data} {
        puts stderr "Monitor: $data"
    }

    # make a subscription
    set sub [opcua subscription C new 1 1000.0]

    # make a monitor
    set mon [opcua monitor C new $sub data monitor "ns=${ns};ItsTclTime"]
    puts stderr "Subscription: $sub"
    puts stderr "Monitor: $mon"

    # handle monitors for a few seconds
    set count 0
    while {$count < 600} {
        update
        opcua run C 20
        incr count
    }

    # delete monitor and subscription
    opcua monitor C destroy $sub $mon
    opcua subscription C destroy $sub

    # shut down the server using a method call
    ::opcua::C::Exit

    # destroy the client
    opcua destroy C

</verbatim>

<h2>Server Object And Event Loop</h2>

A server object obtained with <tt>opcua new server</tt> requires a running event loop as long as it is in running state (started with <tt>opcua start</tt>). It re-dispatches itself using a Tcl timer callback whose interval is controlled by the protocol timers of the OPC/UA stack implementation.

<h2>Server Example</h2>

<verbatim>

    package require topcua

    # create server
    opcua new server 4840 S

    # implementations of methods etc.
    namespace eval ::opcua::S {
        # method callback
        proc _reverse {obj meth string} {
            return [string reverse $string]
        }
        # method callback
        proc _wordsplit {obj meth string} {
            set w [regexp -all -inline {\S+} $string]
            # return code break makes into an array result
            return -code break $w
        }
        # method callback
        proc _exit {obj meth} {
            after 1000 [namespace current]::_real_exit
            return {}
        }
        # helper proc
        proc _real_exit {} {
            catch {
                ::opcua::stop S
                ::opcua::destroy S
            }
            exit 0
        }
        # data source callback
        proc _its_tcl_time {node op {value {}}} {
            if {$op eq "read"} {
                return [list String [clock format [clock seconds]]]
            }
            return {}
        }
    }

    # create our OPC/UA namespace
    set ns [opcua add S Namespace MyNamespace]

    # get Objects folder
    set OF [lindex [opcua translate S [opcua root] / Objects] 0]

    # create an object in our namespace in Objects folder
    set obj [opcua add S Object "ns=$ns;s=MyObject" $OF Organizes \
        "$ns:MyObject"]

    # create methods on object
    set meth [opcua add S Method "ns=$ns;s=Reverse" \
                  $obj HasComponent \
                  {String out} "$ns:Reverse" {String in} \
                  ::opcua::S::_reverse]
    set meth [opcua add S Method "ns=$ns;s=WordSplit" \
                  $obj HasComponent \
                  {String out} "$ns:WordSplit" {String in} \
                  ::opcua::S::_wordsplit]
    set meth [opcua add S Method "ns=$ns;s=Exit" \
                  $obj HasComponent \
                  {} "$ns:Exit" {} \
                  ::opcua::S::_exit]

    # create a variable in our namespace in Objects folder
    set var [opcua add S Variable "ns=$ns;s=ItsTclTime" \
                 $OF Organizes \
                 "$ns:ItsTclTime" {} {} \
                 ::opcua::S::_its_tcl_time]

    # dump methods
    puts stderr [opcua methods S]

    # generate stubs to methods in server
    # these are created in the server specific ::opcua::S namespace
    opcua genstubs S

    # list all procs in server specific namespace
    puts stderr [info procs ::opcua::S::*]

    # call stubs directly on server
    puts stderr [::opcua::S::Reverse esreveR]
    puts stderr [::opcua::S::WordSplit

    # read our variable
    puts stderr [opcua read S $var]

    # start server
    opcua start S

    # enter event loop
    vwait forever

</verbatim>

<h2>Defining Custom Data Structures</h2>

<verbatim>

    package require topcua

    # create server
    opcua new server 4840 S

    # create our namespace
    set NS
    set nsidx [opcua add S Namespace $NS]

    # create structs
    opcua deftypes S $NS {
        struct KVPair {
            String name
            String value
        }
        struct RGB {
            UInt16 red
            UInt16 green
            UInt16 blue
        }
        struct NamedColor {
            String name
            RGB color
        }
    }

    # import type defs
    opcua gentypes S

    # make some variables using the structs from above
    set OF [lindex [opcua translate S [opcua root] / Objects] 0]
    foreach {name type} {
        X1 KVPair
        X2 RGB
        X3 NamedColor
    } {
        set att [opcua attrs default VariableAttributes]
        dict set att dataType [opcua types nodeid S $type]
        dict set att value [list $type [opcua types empty S $type]]
        opcua add S Variable "ns=${nsidx};s=$name" $OF Organizes \
            "${nsidx}:$name" {} $att
    }

    # start server
    opcua start S

    # enter event loop
    vwait forever

</verbatim>