File transfer via OPC UA

It is generally agreed that OPC UA can be used for many communication tasks, and that it also offers several ways to achieve the same thing. One of the topics commonly discussed in OPC UA working groups is file transfer. The new document structure makes it clear that OPC UA provides options for this: since version 1.5.2, file transfer has been removed from Part 5 and given its own section (UA Part 20: File Transfer). This article will present the different options for file transfer via OPC UA, provide application examples, and then compare OPC UA file transfer with other protocols.

The mechanisms and types for file transfer have been available in OPC UA for a long time. The FileType (as ObjectType) and ImageType (as  Subtype of the DataType ByteString) have long been part of the built-in model and are also used in many Companion Specifications (e.g.; OPC UA for Devices, OPC UA for Machine Vision, OPC UA for CNC).

There are three basic variants for file transfer via OPC UA (with Variant 3 being an extension of Variant 2):

  • Variant 1: via Data Access of a variable
  • Variant 2: via method call of the FileType
  • Variant 3: via method calls of the TemporaryFileType and FileType

The individual variants are described in detail below.

Variant 1: via Data Access of a variable

A variable is created on the server which can be read and written via Data Access. The OPC UA standard suggests using ByteString as the DataType, and even provides subtypes for audio data (AudioDataType) and images (ImageType) in various image file formats such as GIF or JPG.

In OPC UA for Devices (OPC UA DI), this type of file transfer is implemented in the ISupportInfoType interface. Figure 1 shows a schematic diagram of this interface. It consists of five folders, each of which contains files. DeviceTypeImage and ImageSet each contain a MandatoryPlaceholder for variables with the DataType ImageType. The Documentation and ProtocolSupport folders each contain MandatoryPlaceholders of the DataType ByteString and can contain text files or PDF files, for example. Alternatively, the folder DocumentationFiles may also contain Documentation files which are transferred via FileType. Their use will be described in Variant 2.

While the file  format of the (image) file is clear when using the ImageType subtype, this is not the case with ByteString (Documentation/ProtocolSupport). OPC UA DI therefore requires that the BrowseName of each variable consists of the filename, including the extension (e.g.; “readme.txt,” “instruction.pdf”). This makes it possible to identify the file format.

The biggest potential limitation of this variant is file size. Both the OPC UA DI Companion Specification and UA Part 20: File Transfer state that large contents (which are to be expected with this type of variable) may lead to limitations due to (resource) constraints in the client or server stack. A common empirical value of just how large these files can actually be in practice does not yet exist. OPC UA DI specifies the standard maximum size for an array of bytes as 1 megabyte. However, files up to 16 megabyte have already been used in some applications. An OPC UA server can use the optional MaxByteStringLength property (under Server.ServerCapabilities) to specify the maximum size of a ByteString variable.

The advantage of this variant is that it is straightforward to implement and use (one request is sufficient), but it is only suitable for smaller files like images.

Variant 2: via method call of the FileType

The second file transfer variant uses the OPC UA object structure and methods. The FileType ObjectType, which represents a file and is addressed with methods or described with properties, exists for this purpose.

The methods of the FileType correspond to the methods in programming languages such as C or C++, as can be seen in Table 1:

OPC UA method

C/C++ methods (see [1])

Comment

Open

fopen

Both methods open a file and require a mode as information on how the file should be handled (e.g.; read-only, read/write). Both return a fileHandle which must be used by all other methods. The fileHandle contains information about the access rights and the position within the file.

Close

fclose

Opposite of the open method; releases the file.

Read

fread

Both methods require the fileHandle and the number of elements to be read as input, and then output the read elements.

Write

fwrite

Both methods have the fileHandle and the data to be written to the file as input.

GetPosition

fgetpos

In both cases, the fileHandle is used as input and the current position at which the file is written/read is returned.

SetPosition

fsetpos

In both cases, the new position of the fileHandle is specified in addition to the fileHandle and the position is reset accordingly.

Table 1: comparison between OPC UA FileType and C/C++ file methods

The sequence for handling the file is also the same in both cases (reading/writing). First, the file is opened (call Open method) and locked for other applications if necessary. The mode specifies whether the file is read only, write only, or read and write. The Open method then returns a so-called fileHandle, which must be specified in the following methods. The fileHandle is generated by the server and is unique for the session. It contains both the access rights to the file and the current position at which it is written. Finally, the Close method releases the file.

One difference to many programming languages is that the mode is not specified as a string (e.g., “r” for read), but as an 8-bit bitmask (e.g.; 0 for read). Table 2 shows a comparison of the OPC UA mode with the C++ mode. Due to the bitmask, the mode from C++ can also be mapped in OPC UA.

OPC UA

C++

Comment

Action if file already exists

Action if file does not exist

Append

EraseExisting

Write

Read

0

0

0

1

“r”

Open a file for reading

read from start

error

0

1

1

0

“w”

Create a file for writing

destroy contents

create new

1

0

1

0

“a”

Append to a file for writing

write to end

create new

0

0

1

1

“r+”

Open a file for read/write

read from start

error in C/C++[2]

0

1

1

1

“w+”

Create a file for read/write

destroy contents

create new

1

0

1

1

“a+”

Open a file for read/write

write to end

create new

Table 2: comparison between OPC UA file mode and C/C++ file mode

The FileType can either be used in single locations such as in the DocumentationFiles folder of the ISupportInfoType (see Figure 1), or in combination with the FileDirectoryType and FileSystemType to map a complete file system (see UA Part 20: File Transfer for details). For example, this is implemented in the CncInterfaceType of the OPC UA for CNC Companion Specification.

By splitting the file into smaller chunks, even large files can be transferred via OPC UA without problems. However, this is accompanied by increased effort for both the server and the client.

Especially if an entire file system is to be mapped, large files are to be transferred, or the file size cannot yet be determined, FileType is preferable to “Variant 1: via Data Access of a variable”. Another advantage is that simultaneous access can be handled better by the method.

Variant 3: via method calls of the TemporaryFileType and FileType

The last variant represents an extension of the FileType concept. Sometimes files should only be stored on the server temporarily or should only be temporarily available (e.g.; firmware update, recipe upload, or result report download). This requires additional steps to prepare the file transfer. The TemporaryFileType can be used in this case.

This has two generator methods (GenerateFileForRead/GenerateFileForWrite), each of which creates a temporary FileType object with the file content (GenerateFileForRead) and returns the NodeId of this object and the fileHandle to access the file. The file object is non-browsable in the AddressSpace and can only be accessed with the NodeId returned by the GenerateFileForRead/GenerateFileForWrite method.

If the creation or preparation is asynchronous to the method call or takes a long time, an additional transfer state machine (type: FileTransferStateMachineType) can be provided which indicates the current status of the transfer.

As with Variant 2, the handling of the file object takes place after the creation. However, the open method does not need to be called and the CloseAndCommit method is called in place of the close method at the end when writing. This applies the content and then deletes the temporary file after the transaction.

In OPC UA DI, this method is used to download and upload software. Another successful use case is with the ResultTransferType from Machinery, which is designed to generate a corresponding report for a measurement result and transfer it to the client. Especially for devices with few resources, it makes sense to generate the report only when the file is transferred to the client with GenerateFileForRead.

The advantage of this variant is that it saves resources on the server, but it is accompanied by additional complexity. However, it is identical to Variant 2 with regard to the transfer quality.

Comparison with other protocols

Many factors play a role in comparing the transmission quality of different protocols, such as the programs used, packet dropout, and the bandwidth among other things. For the purpose of this article, a simplified comparison is made which ignores most of these factors. Thus, this experiment has no scientific claim and should only be used for a rudimentary comparison between OPC UA, FTP, and HTTP. The source code used is available under open source at GitHub (https://github.com/Kantiran91/opcua-filetransfer-comparison).

The hardware setup consists of two laptops connected via Wi-Fi. One machine is running an OPC UA server (eclipse Milo), an FTP server (ftp docker), and an HTTP server (apache2), each hosting a 79.6 MB file. A python script is started on the other machine which downloads the file via the OPC UA (asyncua), FTP (ftplib), and HTTP (requests) clients, respectively. This comparison is repeated 10 times in each case. Table 3 shows the maximum, minimum, and average transfer times.

Protocol

Max. transfer time

Min. transfer time

Average transfer time

HTTP

36.96 [s]

17.01 [s]

22.27 [s]

FTP

34.73 [s]

19.41 [s]

22.99 [s]

OPC UA

23.88 [s]

18.21 [s]

20.53 [s]

Table 3: comparison of the transfer times for an 80 MB file via HTTP, FTP, OPC UA binary

Generally speaking, the results for the OPC UA protocol are slightly better than those for HTTP or FTP. However, since the difference between max transfer time and min transfer timer of the protocols (e.g., the difference in HTTP is 19,95[s]) are significantly higher, it can be assumed that the network itself has a greater influence on the transmission than the selection of the protocol.

Conclusion

OPC UA offers multiple options for transferring files. For small files, a variable of the ByteString type can be used without major compromises. For larger files, file systems, or temporary files, two ObjectType methods are available with FileType or TemporaryFileType. These offer the advantage that the file can be divided into multiple chunks.

File transmission speeds via OPC UA are comparable to common protocols. Therefore, it represents a viable alternative for transferring files without needing to open additional communication channels on the devices or implement further authorization and authentication mechanisms.

 

[1] en.cppreference.com/w/cpp/io/c
[2] In OPC UA, the behavior depends on the server implementation