This articles outlines OPC-UA as a potential data collection method with MachineMetrics. It covers what tools and techniques are available to explore the key space on your OPC-UA server, how data is structured in OPC-UA, and how those data points can be referenced and transformed into a model that is consistent across all pieces of equipment monitored using MachineMetrics.
What is OPC-UA?
OPC-UA ("Open Platform Communications Unified Architecture") is a common interoperability standard for the secure and reliable exchange of data in the industrial automation space and in other industries. It is platform-independent and ensures the seamless flow of information among devices from multiple vendors. By itself, it does not describe the data that is made available by it in a consistent manner. Each data point that can be retrieved from an OPC-UA server (in this context, a machine), has a meaning that is specific to the implementation. Each make, family, model and even individual configuration of a machine can have a different set of data points that mean different things. While OPC-UA is in the process of being standardized for CNC machines and unified through specifications for various verticals like UMATI and the MTConnect/OPC-UA Companion Specification for manufacturing equipment, the adoption of these standards are just starting and won't be widely available for some time.
The OPC Foundation is responsible for the development and maintenance of this standard.
Browsing the OPC-UA Server
There are a number of client tools available to browse your OPC-UA server. We’ll suggest a few to choose from, which we will use to determine which node IDs we want to monitor (as well as the possible need for custom data structure definitions; more information in the OPC-UA Custom Data Types section).
Command line/terminal client
For a command line client, capable of printing out sections of the OPC-UA data tree, we recommend using the 'a command' line client called
uals, from the python-OPC-UA tools library (source code and installation documentation can be found here). Using the
uals tool, we can print the tree-like data of the opc-ua server in plaintext. The following command template would print a given namespace and depth from an OPC-UA server (without a username or password).
uals -u opc.tcp://<address>:<port> -i <namespace_id> -d <tree_depth>
If you are uncertain of the namespace you need to browse, that parameter can be omitted to include all namespaces on the server. There is no harm in this. The responses may simply contain extra, unnecessary data.
For a more involved interactive command line client, capable of viewing and browsing the data tree manually, we recommend using
opcua-commander, for which the source code and documentation can be found here. (This requires node.js be installed on your system).
The OPC Foundation recommends a few GUI clients, which can be found here: https://opcfoundation.org/products/view/opc-ua-client-free-product
And here: https://opcfoundation.org/products/view/uaexpert
Typically, GUI clients are more intuitive and straightforward in their setup than terminal clients for a majority of non-technical users. These clients should have sufficient documentation to allow you to connect and find the data items MachineMetrics will need to get your data reporting through our system.
note: Both of these GUI clients are only supported on Windows 7 or higher (not linux or macOS). If you do not have access to a Windows machine, then the only option is to use one of the terminal clients listed above to discover the proper node ID’s
OPC-UA Data Structure
OPC-UA data is comprised of Simple and Custom types.
- Int32 (possibly other Int sizes as well, untested however)
- Complex Types
- Enum Types
- Array Types (not currently supported)
Complex types are effectively structs or hash tables of properties, enum types define a specific set of values, and array types are an ordered collection of items. Complex types and array types can have properties and items that are custom types or simple types. Currently, only complex types with simple type properties are supported.
In the context of MachineMetrics’ OPC-UA implementation, the order of the custom types as they’re listed above is important which we’ll address later.
Referencing and Transforming OPC-UA Data in MachineMetrics
MachineMetrics uses a YAML document to reference OPC-UA tags, describe the structure of the custom types, and transform that data into a model that is consistent across all types of equipment. Here is a complete configuration for an OPC-UA device.
- name: PlanGuid
- name: PartQuantity
ACTIVE: laser-power > 0
tags section of the OPC-UA configuration defines references to specific nodes in the OPC-UA browse space. Tags should be formatted as follows below; the name of the tag will specify a MachineMetrics configuration label which can be referenced elsewhere in the configuration. The tags are defined by a
path property, which should point to a node ID of a variable in the OPC-UA tree (for more information on determining node ID’s, see the Browsing the OPC-UA Server section). An example of a single tag monitoring a value with a simple type of integer representing the power of the laser would look as follows:
Referencing Custom Types in Tags
It is also possible to reference nodes which are custom structures defined by the OPC-UA server. A description of how to configure these custom types can be found below in the OPC-UA Custom Data Types section.
Suppose there was a custom data type called
PlanInfo, found at the node
ns=2;s=Laser.CurrentPlan. We could reference properties on the CurrentPlan node in our tags like so:
This would give us the
partQuantity property on the CurrentPlan node. This assumes the
PlanInfo type has a
partQuantity property defined which we’ll address in a later section. The value of this property can be referenced later in the data-items section via the
OPC-UA Custom Data Types
Finding Custom Type Definitions
If your server utilizes custom data structures, it will be necessary to configure the data types so they can be properly decoded and read. If your machine vendor supplies information on these custom data types, it will be possible to write the custom type definitions using that documentation as reference. If they do not describe the custom types, you will need to retrieve their definitions from the OPC-UA server manually, and translate them into MachineMetrics OPC-UA Custom Data Type YAML definitions. Typically, these data structs are stored in XML under the
Types Node. (Possibly a path similar to:
Types/DataTypes/XML Schema). It will be necessary for you to read that XML, and convert as described below.
Defining Custom Types
Custom types are defined within the machine’s YAML configuration file, under a property called
custom-types. If the values you are attempting to read from the OPC-UA server are not encoded in custom structs, defining custom data types is not necessary, and this section can be ignored. The exception to this is the entire structure of a custom type must be described in full. If a value you are attempting to read is within a custom type that has references to other custom types, all of those custom types must be defined.
All custom type definitions are characterized by the presence of a
name property. This property is mandatory and each custom type MUST have a name. It is common for the
name to match the custom type itself. Custom types must also be a member of one of the following subcategories: Complex Types, Enum Types, or Array Types.
Each of these subcategories is indicated by a boolean property:
The other attributes in the custom type definition vary based on the subcategory as described below.
If a type is incorrectly identified as multiple different subtypes, precedence will be taken in the order listed above. If a custom type has properties indicating that it is both a
arrayType, for example, it will be considered a
Complex Custom Types
The necessary properties for a Complex Custom Type are illustrated with the following example of a
PartInfo custom complex type:
- name: PlanGuid
- name: PartQuantity
In addition to the complex type boolean flag, complex types are further characterized by the
fields property, which is an array of objects consisting of definitions of the given fields found within the complex type. Field definitions should have the following structure:
- name: <fieldName>
isExtentionType: <extensionTypeBool> #defaults to false
These fields can either be simple types, or references to other custom types, characterized by the
isExtensionType property (where
true would indicate a reference to another custom type). The
propertyName field is used to reference a specific field within a complex type in the tag definition.
The name property on the fields is actually optional and does not perform any function, other than as a visual label for what a field should represent. This should NOT be confused with the name property on the Custom Type object itself, which is necessary to characterize a custom type.
Enum types are characterized by the presence of an
enum property, which is a simple list of the possible enum values. For example:
- ON # IsCutting
- OFF # IsNotCutting
Data that is transferred from the OPC-UA server for enum types is an integer value. The specific enum types listed in your enum custom type definition can, but are not required to, match the enumerated values documented by the machine builder. In some cases, it may be beneficial to alter the documented enumerations to assist in transforming the data into MachineMetrics data items.
Array types are characterized by an
elementType property, which specifies what the type of the elements are in the array.
Accessing values from array types is currently not supported but defining the custom array type might be necessary for defining a complete structure.
The final piece of the MachineMetrics YAML config is a
data-items section. This section is where values monitored from
tags are able to be modeled in a way that is consistent for all pieces of equipment in MachineMetrics. As seen below, basic transformation is possible in the
Here is an example defining the data items that will be sent to MachineMetrics. Values can either be passed through directly, transformed with boolean conditions and mathematical equations, and applied to switch-case-like syntax for specifying enumerations.
part_count is passing the integer value retrieved from the
cutting is passing through the string retrieved from the
PartCutState enumeration value found in the
cut-state tag. In this case, the actual enumerated values documented by the machine builder for
PartCutState did not match those required for the
Cutting type in MachineMetrics so
OFF were used in the custom type definition for that enumeration instead.
execution is outputting
ACTIVE if the integer value of the
laser-power tag is greater than 0. If it is less than or equal to 0, the fall-through state that is output is
ACTIVE: laser-power > 0