Skip to main content
Version: 3.8 (Latest)

OPC UA Model Filters

Why filter?

The OPC UA specification allows very wide latitude in how developers of OPC UA servers present their data, assuming the specification is followed. It often isn’t. As a result, most OPC UA servers will contain somewhere between a little and huge quantities of modeled information that is either wholly irrelevant or actively impeding you from getting any use out of the server itself.

To help you narrow down your server’s model to the data that is useful and relevant, Model Reader offers two sets of filters:

  • Model filters let you pick which parts of the OPC UA model will be converted into an equivalent in Elevate and Fusion.
  • Tag filters additionally let you define which portions of an OPC UA server’s model represent tags.

Terminology

Model reader uses filter expressions to determine what to do with various parts of the OPC UA hierarchy. Explanations of the filter expressions will refer to OPC UA terminology defined here if you’re unfamiliar with it.

Browse name:

All nodes can be uniquely identified by their node ID. They can also be identified by name: their browse name is a mostly human readable name that, combined with the browse name of the other nodes which are encountered on a path to that node from the root of the hierarchy, represents a unique path to that node. Nodes' browse names often include the namespace index of the namespace they’re in. Unlike node IDs, browse names are not required to be unique for a given server or even for a given namespace. The OPC UA specification defines browse names here.

Browse path:

A browse path is the sequence of browse names of the nodes passed through on a path from one node to another. For instance, if node A with browse name “A” had child node “B” with browse name “B”, and B had child node “C” with browse name “C”, a browse path from A to C would look like “A/B/C”. OPC UA defines a specification for browse paths here.

Display name:

nodes will typically have a display name as well as a browse names. A node's display name will contain the name for the node in whatever language is used to connect to the server: it may be the same as the browse name, it may not. When a user connects to the server with an OPC UA client, the display name is typically what is displayed for a given node. The OPC UA specification defines display names here.

Namespace:

In order to organize the nodes in the system, they are grouped into namespaces. Nodes which have been defined as part of the OPC UA specification, for instance, are in the namespace whose URI is “http://opcfoundation.org/UA/”. This namespace is usually at index 0.

Namespace index:

Namespaces are presented in a given order by the server. A namespace’s index represents the namespace’s position in that order, starting with 0. Namespace indexes may change from session to session.

Namespace URI:

Namespaces are represented uniquely by a URI.

Node:

Every thing in the OPC UA hierarchy is, at its base, a node. There are different types of nodes for objects, variables, types, methods, and others. All nodes have an identifier, a browse name, are part of a namespace, and have a type.

Node identifier:

A node identifier, or node ID, is used to uniquely identify a given node on a server. Node IDs are strings, usually with two parts - a namespace and an identifier. The namespace part can either reference the namespace’s index or its full URI. The identifier part is a string, integer, GUID, or set of bytes identifying the particular node. A typical node ID might look something like “ns=1;s=AnalogItems”.

Object:

An object in an OPC UA hierarchy is a type of node that usually represents a physical object or a concept. It can exist independently of other objects. It typically has properties which provide information about the object, some of which may be variable, i.e. changing over time.

Type:

A type is a type of node which defines what an object looks like. An object’s type is used to define which properties will be present on an object when it’s created. Types can be inherited from; when this happens the type which inherits includes all the inherited types' properties, and may define more.

Variable:

A variable is type node that represents a property of an object that has a value. For instance, a tire may have a variable whose name is “Pressure” and whose value is the tire’s current pressure in PSI. Variables are linked to a parent object - they cannot exist in the server’s hierarchy without being part of an object.

Filter expressions

Filter expressions are strings which specify a set of nodes on the OPC UA server. They let you select nodes by their type, their name, or their relationship to other nodes, and let you combine those sets with others to form a complete set of nodes that you want to be represented in your model. They also let you select nodes to identify as tags. At the top level, the syntax for a filter expression is:

<node type> (<selectors> (<conjunction> <selectors)*)

Filter expression keywords are case-insensitive. NODES NAME IS “Bob” is the same as Nodes name is “Bob” and nodes name is “Bob”.

When browsing an OPC UA server to construct a model, the Model Reader tests each node it encounters against the filter expressions defined in the Filters and TagFilters sections of the server’s configuration. If any filter expression matches the node, it is included in the model. If the node additionally matches a TagFilters expression, it is included as a tag.

<node type>

Node type helps you limit the set of nodes you’re interested in, and can be one of a few words:

  • NODE, NODES: this node type selects any object or variable in the OPC UA hierarchy.
  • OBJECT, OBJECTS: this node type selects only objects from the OPC UA hierarchy.
  • VAR, VARS, VARIABLE, VARIABLES: this node type selects only variables from the OPC UA hierarchy.

<selectors>

Selectors help you narrow down the set of nodes from your node type based on qualities of the node. The following selectors work on properties of the node itself.

  • BROWSEPATH <string> : this lets you select a particular node by browse path. The <string> must follow the OPC UA browse path specification and will be relative to the Objects folder at the root of the OPC UA hierarchy.
  • DISPLAYNAME <stringoperator> <string>: this lets you select a particular node by comparing its display name to the <string> you provide using one of the string operators.
  • NAME <stringoperator> <string>: this lets you select a particular node by comparing its browse name to the <string> you provide using one of the string operators.
  • NAMESPACE <string>: this lets you select a particular node by comparing the node’s namespace URI with the <string> you provide. If the two match (case is not important here), the node will be selected.
  • NAMESPACEINDEX <number> : this lets you select a particular node by comparing the node’s namespace index with the number you provide. If the two match, the node will be selected. Note that a node’s namespace index is not guaranteed to remain the same in general.
  • NODEID <stringoperator> <string> : this lets you select a particular node by comparing its node ID to the given <string> using a <stringoperator>. When using EQUALS or IS, this comparison is case-sensitive. Otherwise it is not.
  • TYPEID <typeoperator> <string> : this lets you select a particular node by comparing the node ID of the node’s type to the given <string> using a <typeoperator>. When using EQUALS or IS, this comparison is case-sensitive. Otherwise it is not.
  • TYPENAME <typeoperator> <string> : this lets you select a particular node by comparing the browse name of the node’s type to the given <string> using a <typeoperator>. Note: filters which use TYPENAME require the Model Reader to browse the server’s type hierarchy before beginning to browse its model hierarchy. This may take extra time on slow connections. If you can find the node ID of the type you care about in your TYPENAME operation, using TYPEID will be equivalent and faster than using TYPENAME. However, TYPENAME is much more human readable and maintainable.

The following selectors begin new expressions to qualify nodes based on the qualities of their ancestors in the browse hierarchy.

  • ANCESTOR <node type> (<selectors> (<conjunctions> <selector>)*): begins a new select expression that attempts to match that node or any of its ancestors. For instance, to exclude any node whose browse name starts with _ or any node under those nodes, you could use NODES ANCESTOR NODE NAME NOT STARTSWITH “_”.
  • PARENT *<node type> (<selectors> (<conjunctions> <selector>)*): begins a new select expression that attempts to match against specifically the parent node of the current node.

<stringoperator>

String operators let you examine strings for matching substrings or equality. Most of the time, string operators do not care about the case of the letters in the strings they are comparing.

  • CONTAINS: matches if the first string contains the other. For instance, if a node's browse name is “ABCD”, NAME CONTAINS “bc” is a match, NAME CONTAINS “ABCD” is a match, and NAME CONTAINS “da” isn’t.
  • ENDSWITH: matches if the first string ends with the second. For instance, if a node's browse name is “ABCD”, NAME ENDSWITH “CD” is a match, NAME ENDSWITH “bcd” is a match, and NAME ENDSWITH “q” isn’t.
  • EQUALS, IS: matches if the two strings have the same value. “A string” EQUALS “a string” is a match. “ABS” IS “ABC” isn’t. Note that when comparing node IDs, EQUALS and IS are case sensitive: NODEID IS “ns=1;s=AnalogItems” is not the same as NODEID IS “ns=1;s=analogitems”.
  • STARTSWITH: matches if the first string starts with the other. For instance, if a node's browse name is “ABCD”, NAME STARTSWITH “ab” is true, NAME STARTSWITH “ABC” is true, and NAME STARTSWITH “da” is false.

<typeoperator>

Type operators let you compare objects' and variables' types using node IDs (if your selector is TYPEID) or browse names (if your selector is TYPENAME).

  • DERIVEDFROM, ISA <string> : matches if the node's type is the same as the type provided in <string> or if it inherits from that type. For instance, the standard type named “DataItemType” inherits or derives from the standard type named “BaseDataVariable”, so for a node whose type was “DataItemType”, TYPENAME DERIVEDFROM “BaseDataVariable” or TYPENAME ISA “BaseDataVariable” would match.

  • EXACTLY, IS <string> : matches if the node's type is the same as the type provided in <string>. For a node whose type is “DataItemType”, TYPENAME EXACTLY “DataItemType” or TYPENAME IS “DataItemType” would match.

<conjunction>

Conjunctions can be used to join two matching expressions together.

  • <selector> AND <selector> : matches if both expressions do.
  • <selector> OR <selector> : matches if one of the expressions does.
  • <selector> EXCEPT <selector> : matches if the first expression does and the second does not.
  • NOT <selector> : matches if the expression does not match. NOT can also be inserted in selector expressions for type and string operators. For instance, NAME IS NOT “Bob”, NAME NOT CONTAINS “asdf”, or TYPENAME NOT DERIVEDFROM “BaseDataVariable”.

The precedence of conjunctions is NOT, AND, OR, EXCEPT. That is to say

    NOT NAME CONTAINS “abc” AND NAME STARTSWITH “A” OR NAME STARTSWITH “B”

is the same as

    (NAME NOT CONTAINS “abc” AND NAME STARTSWITH “A”) OR NAME STARTSWITH “B”

Brackets

Brackets () can be used to change precedence of conjunctions or force particular parsings to work in cases where they are unclear. See <conjunction> above for an example.

<string>

Strings within filter expressions are delimited using double quotes (“) - see many examples above. If your string has a double quote itself, that quote can be escaped using a backslash (\). For instance, to search for nodes whose name contains a quotation mark you would use the expression nodes name contains “\””.

Note: all filter expression examples here include strings in just a pair of quotation marks for ease of reading. When entering filter expressions into Elevate’s configuration, which is stored in JSON, strings which contain quotation marks need those quotation marks to be escaped with a backslash. So a filter expression which is rendered here as name startswith “text” would need to be written into Elevate’s configuration as

"Filters": ["name startswith \"text\""],

If your filter expression contains a backslash, that will also need to be escaped. For instance, to actually configure a match for nodes whose name contains a quotation mark, you would need to enter

"Filters": ["name contains \"\\\""],

Each quotation mark in the filter expression is entered as " and each backslash is entered as \.

Some sample expressions

  • variables typeid isa “nsu=http://opcfoundation.org/UA/;i=2365” This selects variables whose type ID is given above. That URI corresponds to the standard defined DataItemType type which should be used for all variables that are tags in a historian. This is the default TagFilter expression if none are provided.

  • variables typeid isa “nsu=http://opcfoundation.org/UA/;i=62” Kepware’s OPC UA server presents its tags as being derived from BaseDataVariable instead of DataItemType as the specification suggests. As a result, unless this is used as a TagFilter, Model Reader will find no tags on a Kepware server.

  • nodes name not startswith “_” and not ancestor node nodeid is “nsu=http://opcfoundation.org/UA/;i=2253” Kepware’s OPC UA server presents a number of server internal variables to OPC UA clients most of which are not useful, and all of which have browse names that start with _. This Filter removes those nodes. It also removes nodes under (and including) the Server object which is defined for OPC UA servers. The Server object contains information about the server and clients connected to it. Generally the information is only useful to OPC UA clients and not modelling. It may also expose information clients find sensitive.

Filters recommend for particular OPC UA servers

The following provides the Filters and TagFilters values we’ve found to work best for particular brands of OPC UA server in testing. Depending on what information you want to extract from the server, you may need to tweak these. These filters include JSON escaping so they can be added to configuration files directly.