NAME

opc - Tcl commands for using OPC (OLE for Process Control)

SYNOPSIS

package require humeopc
::opc::opc catlist
::opc::opc clsid ProgId
::opc::opc client ocname clsid ?hostnameOrIP?
::opc::opc clients
::opc::opc enum categoryTagList ?hostnameOrIP?
::opc::opc help
::opc::opc hosts
::opc::opc type name

::opc::quality_text qualityCode
::opc::ts_utc2local timestamp
::opc::ts_utc_now
::opc::type_text variantTypeCode


The OPC client connection commands are listed and described by category:
ocname browsing commands
ocname group configuration commands
ocname group IO commands
ocname group item commands
ocname item commands
ocname miscellaneous commands


DESCRIPTION

This set of commands is used to communicate with OPC Servers from a Tcl/Tk application. See the OPC Supervisor Application document for information on the Hume written configurable application that uses these commands. Tcl has a tremendous advantage for working with OPC data over strongly typed languages because the underlying variant data passed by COM is directly compatible with Tcl variable values.  A newcomer to Tcl may be interested in seeing a comparison of Tcl to VB6, or a paper that discusses the rising popularity and productivity of high-level scripting languages.

OPC was originally an acronym for OLE for Process Control. The OPC Foundation has created standards that describe the use of OLE for the integration of computerized sensors and instruments. Over time the term OLE has been deprecated in favor of the terms COM and DCOM which refer to Microsoft's proprietary implementation of inter-process communication using remote procedure calls (RPC).

The ::opc::opc catlist command returns a list of shorthand tags used to specify particular categories of server types that the ::opc::opc enum command is able to enumerate. The list of tags includes:

da1
represents the Data Access Custom Interface Standard Version 1.0
da2
represents the Data Access Custom Interface Standard Version 2.05
da3
represents the Data Access Custom Interface Standard Version 3.0
xmlda
represents the XML Data Access Standard Version 1.1

The value returned by the enum command is list of five elements for each server found. The record for each server is formatted as a single element in the result list. The format of each record is:

An example server record returned by enum is: The ::opc::opc enum command uses the IOPCServerList2 COM interface described in the OPC Common Definitions standard.  The enum command relies on the OPCENUM.EXE program being installed on the target computer system. This program, which usually runs as a Windows background service process, is customarily provided by OPC Server vendors and installed when a server is installed. It is available from the OPC Foundation website in the OPC Core Components 3.00 Redistributable (x86) download. When using the enum command, you are able to specify the target computer system by the optional argument hostname_or_IP_address. The default host is the computer that the software is executing on which may be specified as an empty string, or as localhost. If you do specify a target computer system that is not equivalent to localhost then you must configure Windows security permissions on both the target system and your own system to allow the remote use of DCOM. Instructions on how to perform this task may be obtained from the OPC Foundation website as the download entitled Using OPC via DCOM with Windows XP Service Pack 2 in the White Papers section.

You are advised that enabling and using DCOM presents certain security and performance risks. The design of DCOM isolates you from the underlying network communication and security issues. When things run smoothly, this is good. When there are issues with the network or malicious software, this isolation exacerbates the problems. There are inadequate features in DCOM for status and diagnostics. Things will simply be broken, unresponsive, insecure, and crash-prone. Our advice to you is to avoid the hassles of using DCOM and exposing your systems to security risks - run the OPC interface software on the same computer where the OPC servers are. Then use the DMH message system to connect to the server computer from any other systems on your network including non-windows platforms. This approach is much more robust and much easier to deploy and manage.

The ::opc::opc clsid command is used to lookup the clsid value for a particular program ID, ProgID. The command relies on information that is configured in the Windows Registry.

Error Codes and Error Results

The clsid command and many of the other commands map directly to calling a COM interface method. If the underlying COM method call returns an error code as the HRESULT value, the Tcl command returns an error result, with the error text set to where the error code HRESULT value is formatted as a hexadecimal value. For example,

Many of the method calls returns lists of error code values, one for each item specified in the input arguments. A return value containing multiple error codes occurs with normal execution of the Tcl command since the COM method call is successfully executed. The individual error codes are formatted as hexadecimal integers if they are non-zero since error code documentation commonly uses hex notation.

Do not assume the behaviors of integer error values that correspond to a 32 bit binary representation.  For example, OPC and COM declare error codes with an unsigned hex notation such as 0xC0040001.  Then, in C-code, the high bit of error code values is tested with the FAILED(hr) macro which is implemented as (hr < 0).  The FAILED macro comparison assumes 32 bit signed values and is not portable.  In Tcl the expression, "expr {$hr & 0x80000000}" can be used instead to determine if an error code implies failure or success with a warning.

The Hume Datahub SQL command does not accept hexadecimal notation for integer values.  Use the Tcl expression, "expr {$rc}" to convert a hexadecimal value to an ordinary integer.

Once a client connection is established, the ocname errmsg command may be used to obtain an error message, and the error code may be passed to this command as a hexadecimal code or as a decimal integer. Generally, if an error code starts with 0xC004 it has been defined by OPC, but if it starts with 0x80 it is defined by Microsoft and indicates a lower level problem that may even prevent use of the ocname errmsg command.

The ::opc::opc help command displays a summary of the ::opc command usage, similar to the information in the SYNOPSIS section at the top of this document.

The ::opc::opc hosts command returns a list of COMPUTERNAMES from your Windows Network Neighborhood.

The ::opc::quality_text qualityCode command is used to interpret the quality codes used by OPC. The usual return value is "good" for the usual code of 192. The procedure source code may be examined to ascertain the possible descriptions which map all of the standard bitfield uses specified by the standard.

The ::opc::type_text variantTypeCode command provides a string representation of the variant data type codes used by OPC. For example, the string value for 17 which indicates an unsigned 8 bit data item is byte.  You are able to work with OPC data in Tcl without the cumbersome aspects of a strongly typed language.  Tcl is able to represent and work with 64 bit integers, 4 and 8 byte floating point data, and the other data types of OPC, without explicit type declarations.

Floating point values are consistently formatted in a Locale invariant manner using the period as the decimal separator.  There are also exceptional floating point values which are referred to as NaN values.  These values are used to indicate error conditions and they cannot be manipulated as ordinary values.  The package logic explicitly checks incoming data for NaN values.  When NaN values are found, the floating point value is set to 0.0 and the associated quality property is set to 0 (OPC_QUALITY_BAD).   The presence of a single NaN value in a vector causes the quality property for the vector value to be bad.  This feature complies with the OPC specifications for handling NaN values.  Your application is freed from the inconsistencies and exceptional handling of NaN values since you can count on floating point values always being proper numbers.  The other lesson is that quality property values should not be ignored.

The commands ::opc::ts_utc2local timestamp and ::opc::ts_utc_now provide for converting the UTC timestamp values used by OPC to the local timezone, or obtaining the a UTC timestamp representing the current time. Do not use local timestamp values for database keys because that creates problems in locales where Daylight Savings Time is observed. The dmh package commands mktime and localtime are also available for date and time manipulation in addition to the Tcl clock command.

The ::opc::opc client command is used to create a connection to a server that implements any version of the Data Access Custom Interface standard. The argument ocname becomes a new Tcl command that is used to communicate with the server, and it is also used as the name of a global array that is used to manage data items for the connection. Therefore the ocname value should not already exists as a Tcl command or scalar variable, and it should not contain imbedded white space. The name should start with a letter or the underscore and consist of alphanumeric characters. Dashes or underscores may also be used after the leading character.

If the ::opc::opc client command succeeds, the return value is the name of the OPC client connection, ocname. If the command fails, an error result is returned. For example:

The ::opc::opc clients command returns a list of the existing OPC client connections.

The ::opc::opc type name command returns the value client if name is the name of an OPC client connection. If name is not an OPC object command, the return value is an empty string.

OPC Client Miscellaneous Commands

ocname close
ocname errmsg error_number
ocname help
ocname locale get
ocname locale list
ocname locale set id
ocname name clientname
ocname onShutdown code
ocname ping
ocname status

The ocname close command releases all connection related resources such as interface pointers and data structures and disconnects from the server. The ocname Tcl command is removed. The global array ocname is not unset, and its continued existence does not interfere with resuming the connection in the future.

The ocname errmsg command is used to request error message text for a return code value using the IOPCServer::GetErrorString method. Note that if an error code indicates the connection is lost, using this method will likely return the same error code.

The ocname help command replies with a synopsis of the ocname command usage including the reply formats.

The ocname locale commands are used to list, get or set Locale integer ID codes. Per the standard, the Locale ID value set for the connection becomes the default Locale ID for groups that are subsequently defined. The standard use is that the Locale ID selects the language used for error messages and text string values.

The ocname name command sends a string value, clientname, to the server that can be used for diagnostic or status purposes, nominally for the purpose of identifying the client.

The ocname onShutdown command registers callback code that is executed in the event that the server calls the IOPCShutdown::ShutdownRequest. In addition, the callback code is executed in the event that a failing return code is obtained from using the ocname ping command or the ocname status commands. The callback code is executed as follows; three additional arguments, ocname, errorCode and reason are appended to it as list elements, and the result is executed at the topmost, global level of the Tcl interpreter. The errorCode argument is an integer value that is 0 if the server initiates the shutdown call, or the failing return code that otherwise triggers the call formatted as a hexadecimal integer. The reason argument will be a text string provided by the server, or a value such as "Failed reply to GetStatus" if the call is initiated by this software. It is common to close the connection from your callback code.

The ocname ping command executes a method call with the server and thereby tests that the connection is functional. If the method call fails, the onShutdown callback code is executed if it exists, and a Tcl error result is returned. The ping command is marginally more efficient than the status command.

The ocname status command executes the IOPCServer::GetStatus method call with the server and returns the obtained data. If the method call does not succeed, the onShutdown callback code is executed if it exists, and a Tcl error result is returned. The success result is formatted as an alternating list of name and values. The names are invariant. Here is an example from which you may determine the names:

Timestamp values are consistently exchanged as UTC timezone values. You may use the command ::opc::ts_utc2local to convert a UTC timestamp to the local time.

OPC Client Browsing Commands

Version 3 Browsing:
ocname browse ?branchID?

Version 2 Browsing:
ocname bsasAP ?itemID?
ocname bsasIDs {b[ranch*] | l[ea*] | f[lat]}
ocname bsasItemID id
ocname bsasOrg
ocname bsasPos {up | down branch | to branch}
ocname v2Props itemID

Browsing features enable you to discover the data items and their properties that are hosted by the server. Collectively, the data items and their organization are termed the server's address space. Conceptually the address space is described as a tree hierarchy with the items being associated with descriptive branches similar to the directory structure of a file system. If there are no branches, and the items are associated at the root of the hierarchy, the address space is said to be flat. We'll use the term node to describe a location in the hierarchy which may be a branch or an item.

A Version 3 server supports the ocname browse ?branchID? command. The command returns a list of records for each node underneath the optional branchID argument, or under the root of the tree. The record for a node is a list of 4 elements:

The displayName value is a shorthand text string suitable for descibing the node when seen in the context of its parentage. The branchID is a full pathname to the node. The kids1Item2Bits is used as an integer bitfield where the 1 bit means that the node is a branch that has child nodes and the 2 bit indicates that the node is a valid item for data IO. If the node is an item, then the branchID value is the fully qualified itemID value and the propertyList value will be a list of property records. Each property record is formatted as a list of five elements:

The propertyID is an integer ID code indicating the property type as understood from the tables of standard properties in Section 4.2.14 of the Data Access Custom Interface Standard Version 3 document. The itemID is non-blank if the property is accessible as an independent item. The description value describes the property item just in case you do not have Section 4.2.14 of the manual handy to decode the standard propertyID values, or for the less common sitation of a non-standard property item with a propertyID value of 5000 or above. The valueType is an integer code indicating the variant data type, and the value is the current value of the property, which may possibly be an array.

Browsing is an optionally implemented feature for a Version 2 server. The interfaces require more back-and-forth calls to determine comparable information to the Version 3 browse result. There is a concept of a current position in the navigation hierarchy so the game is to iteratively change positions and use method calls to characterize the current position - something like the original Adventure computer game where you are in a maze of twisty little passages, all alike.

The command ocname bsasPos {up | down branch | to branch} is used to change the current browse position. The braces and or bars (|) shown in the command description indicate that there is a choice of specifying up as an argument, or specifying the phrase down branch or the phrase to branch as the trailing arguments. The underlying standard specification was revised at some point and not all servers will accept the to branch phrase. Use the up option to get to the root of the tree and from that position, all of the branches are downward.

At the current position use the ocname bsasIDs {b[ranches] | l[eaves] | f[lat]} command to discover branches and items. Again the braces and bars (|) signify that there is a choice of supplying b, l, or f as an argument value. The square brackets show you that specifying additional letters to make your code more understandable is optional - you may specify branch, branches, leaf, leaves, or flat. The branch choice returns a list of shorthand id values for child nodes. The leaf choice returns a list of shorthand id values for items at the current position. The flat choice acts as if the hierarchy is flattened below the current position and returns all of the child nodes.

Use the ocname bsasItemID id command to convert the shorthand id values returned from the bsasIDs browsing to fully qualified itemIDs.

The ocname v2Props itemID command is used to obtain the properties for an item. The return value is a list of property records. Each property record is a list of five elements:

The elements are the same as described above for the property records of Version 3 except that the errorCode item is a possible error value from the GetItemProperties method call.

The ocname bsasOrg command returns the literal text flat or hierarchical to describe the server address space.

The ocname bsasAP item_id command calls the Version 2 method BrowseAccessPaths to obtain a list of strings that are the AccessPaths for an item.

OPC Client Group Configuration Commands

ocname group add name ?-active 1|0? ?-period millisecs? ?-timebias min? ?-deadband percent? ?-locale localeId? ?-handle handle?
ocname group callbacks groupname ?option? ?value? ?option value?*
ocname group clone groupname newname
ocname group configure groupname ?property? ?value? ?property value?*
ocname group delete groupname ?force?
ocname group enum ?private?
ocname group find name
ocname group rename groupname newname

The ocname group add name ?property value?* command creates a new group with the name name. If name is specified as an empty string, the server will assign the name. You are able to specify various properties for the group in the add command, or subsequently using the group configure command. These properties are discussed, below, with the group configure command. The successful return value is a two element list, the actual group name, and the actual refresh period.

The ocnamegroup callbacks groupname enables you to set or query properties related to callback evaluation that occurs with receiving data and asynchronous IO.

Here is how to use the trailing arguments of this command and of the similar group configure command. If you specify

the return value is a list of property value pairs showing you all of the current property values. If the trailing argument is a single property such as -OdcEnable then the return value is the value of that property. To set property values, execute the command with one or more pairs of property value arguments.

The properties used by the group callbacks command include:

-OnDataChange code
Use this property to set the callback code to process data received from the group by the usual periodic reporting, and also in response to refresh commands. The callback code is evaluated as follows. The data is appended as a single list argument and then the result is evaluated at the topmost, global level of the interpreter. The data is structured as follows: The itemList element is a list of records, each record is structured as follows: The ocname and groupname values are are provided so that you may easily share the same callback code for multiple connections and groups. The transactionId integer value is 0 for the usual periodic group reports. Otherwise the value correlates to the values passed as arguments to the refresh commands. The masterQuality value will be 0 only if all of the item data is good. The masterError value will be 0 only if all of the item data is without error. The groupHandle value is the configured -handle value for the group. Similarly, each item is identified with the itemHandle value that is configured when the item is added to the group.

It is easy to work with nested lists using the Hume vset command. Here is example callback code:

$ocname group callbacks -OnDataChange opc_OnDataChange

proc opc_OnDataChange {data} {
vset $data {ocname groupname transactionID clientGroupHandle masterQuality masterErr itemData}
# the OPC client name is a global data array and a command
global $ocname
foreach row $itemData {
vset $row {clientItemHandle value quality ts err}
# ...
}
}
-OnReadComplete code
This property is used to register callback code to handle replies to asynchronous read requests. The data format and callback usage is the same as with the -OnDataChange property.
-OnWriteComplete code
This property is used to register callback code to handle replies to asynchronous write requests. The data format is a little different than with reads although it is still appended to the callback code as a single argument. The format used is: Then each record in the itemList is structured as:
-onCancelComplete code
This property is used to register callback code to handle replies to asynchronous cancel requests. The data is appended to the callback code as a single argument. The format used is:
-OdcEnable 1|0
The -OdcEnable is used as a boolean to pause or resume the data being delivered to the -OnDataChange callback. When the group is created, the value is set true by default and periodic data reporting is enabled.

The ocname group clone groupname newname command is used to create a new group with the same properties and set of items as an existing group. At the time of creation, the new group is not active for data reporting. Said in specific terms, the -active property value of the new group is 0.

The ocname group configure groupname ?property? ?value? ?property value?* command lets you query or set properties of the group. The trailing arguments to the command are used the same way as with the group callbacks command presented above.

-active 1|0
The -active property is used as a boolean to enable data reporting or any IO usage.
-period milliseconds
The -period property is the refresh period for data reporting in milliseconds. The value 0 is used to mean a request for updates at the minimum supported interval.
-deadband percent
A -deadband percentage value may be established for the group to eliminate reporting of insignificant data changes. The deadband value only applies to Analog data items.
-timebias minutes
The default time offset is 0 minutes meaning reported time values are for the UTC timezone. Use this property to set a desired time offset in minutes for the group.
-locale LocaleID
This property is used to set a Locale code for the group. Values should be constrained to those supported by the server (locale list).
-handle handle
The -handle property is used to set or query an integer value which is used for correlating the group's identity in the OnDataChange callback data.
-keepalive milliseconds
The -keepalive property for the group is only supported for a Version 3 server. If your server does not support -keepalive you do not see it in the display of all the property values. If set to a non-zero value of milliseconds, the OnDataChange callback will be called even if none of the group values have changed sufficiently to warrant invoking the OnDataChange callback. The feature eliminates the need for polling to verify that the server is functional. There can be a difference between the requested keepalive period and the interval that the server is willing to support.

The ocname group delete ?force? command calls IOPCServer::RemoveGroup to delete the definition of the group at the server. The optional force argument removes the group even if pointer references to the low-level COM classes are outstanding.

The ocname group enum ?private? command asks the server to report the list of defined groups. In the early days of OPC there were concepts of private and shared public groups and some muddled concepts of group persistence. The optional private flag causes the server to only report private groups. This option should not be needed in a modern deployment.

The ocname group find name causes the Tcl software to setup data structures and callbacks so that you can use a group the same as if the group was added using the group add command. So if you do encounter one of those older servers with muddled concepts of group persistence you are able to use any of the groups that already exist.

The ocname group rename groupname newname enables you to change the name of a group. The OPC standards do not specify rules for naming groups other than stating that names are case sensitive. Therefore any naming considerations are server-specific.

OPC Client Group IO Commands

Your application will work best using the periodic asynchronous data change notifications available from the server using the OnDataChange callback mechanism. These notifications work well with the single-threaded logic of this software. Your application thread is notified during event dispatching of new input without risk of being hung up in an unresponsive method call. If you base the application on using synchronous calls, you run the risk of having occaisons when the application is unresponsive. Even the initiation of an asynchronous IO call goes out to the server as a synchronous method call and it can get hung up if the network or the server have hiccups. It is not desirable to use any of these IO methods from a single-threaded OPC client in any repeated fashion. Stay with the core OnDataChange callback mechanism - it works without risk. If you need to write values regularly, you may want to exec a child process that does the writing for the parent process so the parent can stay responsive to the user. The DMH message system works well for providing a coordination mechanism with the child process.

ocname group cancel groupname cancelID
ocname group readAsync groupname svrHandles transID
ocname group readSync groupname svrHandles ?device?
ocname group readAgeAsync groupname svrHandle_Age_Pairs transID
ocname group readAgeSync groupname svrHandle_Age_Pairs
ocname group refresh groupname ?transID? ?device?
ocname group refreshAge groupname ageMillisecs transID
ocname group writeAsync groupname htvTrioList transID
ocname group writeSync groupname htvTrioList
ocname group writeVQTAsync groupname items transID
ocname group writeVQTSync groupname items

The ocname group cancel groupname cancelID is used to attempt to cancel an asynchronous request. The cancelID argument is obtained from the result of the earlier request.

The ocname group readAsync groupname svrHandles transID command is used to initiate an asynchronous read request (IOPCAsyncIO2::Read) for one or more items in the group. The svrHandles argument is a list of the server's handles for the items. The return value is a list of two elements, the cancelID and a list of error codes, one for each item in the svrHandles list. The data is delivered asynchronously to your -OnReadComplete callback.

The ocname group readSync groupname svrHandles ?device? command is used to request a read (IOPCSyncIO::Read) for one or more items in the group. The optional device argument tells the server to read the values from the sensor devices and not from a cache. During the time it takes for the method to execute, your application is completely unresponsive.

The reply format is a list of records. Each record is a list of the following elements:

The clientHandle is the client handle for the item. The quality value is an integer bitfield which may be decoded using the ::opc::quality_text procedure.

Do not base your application on making periodic synchronous read calls. Use the subscription model with your OnDataChange callback and let the OPC server bear the risk of getting hung up in an unresponsive method call.

The ocname group readAgeAsync groupname svrHandle_Age_Pairs transID command makes the IOPCAsyncIO3::ReadMaxAge method call which is a Version 3 feature.

The notion of Age is that the caller supplies a period of time in milliseconds. If the server has not obtained a value from the sensor device within the previous Age interval, the server obtains a fresh reading of the value before responding to the caller. The svrHandle_Age_Pairs argument is a list of two element lists. Each two element list specifies the server handle for a data in the group and an age value. The age value is passed as a 32 bit unsigned integer so the maximum value is 0xffffffff. The transID is a 32bit integer value of the caller's choice. It is passed as an argument to the callback for correlation of request and reply. The return value is a list of two elements, the cancelID and a list of error codes, one for each item in the svrHandle_Age_Pairs list. The data is delivered asynchronously to your -OnReadComplete callback.

The ocname group readAgeSync groupname svrHandle_Age_Pairs command makes the IOPCSyncIO2::ReadMaxAge method call which is a Version 3 feature. The Age concept and the svrHandle_Age_Pairs input argument are explained in the previous paragraph. The return value of the call is a list of four element records, each record is formatted as:

The ocname group refresh groupname ?transID? ?device? command requests that the server executes the OnDataChange callback with the current data. The command makes the IOPCAsyncIO2::Refresh2 method call which is supported by Version 2 and 3 servers. The optional device argument specifies that the server should obtain fresh data values from the underlying sensor devices. You are able to specify an integer transaction ID value, transID, to be passed as an argument to your callback to distinguish the response to the refresh call from the usual periodic invocations where the transID value is 0. The successful return value is a cancelID.

The ocname group refreshAge groupname ageMillisecs transID command makes the IOPCAsyncIO3::RefreshMaxAge method call which is a Version 3 feature. The Age concept is explained above. So this method is simply the refresh command with the added feature of being able to specify an Age value in milliseconds. The return value is a cancelID.

The ocname group writeAsync groupname htvTrioList transID command provides the means to write item values using the IOPCAsyncIO2::Write method which is supported by Version 2 and 3 servers. The htvTrioList is a list of records, one for each data item. Each record is a three element list structured as:

The variantTypeCode is an integer value which specifies the data type to be passed as a variant data structure in the method call. The variant types most commonly used for OPC include:

If the 0x2000 bit in the type code is set, it indicates a vector of the base type is being passed.

In the case of specifying a vector of variant values, (12|0x2000), each supplied value should be passed as a two element list providing the element type code and the element value.

The return value is a list of two elements, the cancelID and a list of error codes, one for each item in the input list. When the writeAsync call is completed, your -OnWriteComplete callback is executed.

The ocname group writeSync groupname htvTrioList command calls the IOPCSyncIO::Write method to write a set of values to the underlying device(s). The command does not return until the write is completed. The htvTrioList argument is described immediately above. The return value is a list of error codes, one for each item.

The ocname group writeVQTAsync groupname items transID command uses the Version 3 IOPCAsyncIO3::WriteVQT method to write values, qualities, and timestamps. The items argument is a list of records, one for each item. Each record is formatted as:

The writebits argument is used as a bitfield to specify which of the value (bit 1 set), quality (bit 2 set), and timestamp (bit 4 set) values should be written. The quality value is the usual OPC integer bitfield explained in section 6.8 of the Data Access Version 3 specification. The timestamp value is a string of the format

which means the usual ::dmh::localtime 16 value is fine. Notice that you may optionally specify the timezone and use a format that is accordance with ISO 8601. The return value is a list of two elements, the cancelID and a list of error codes, one for each item. After write completion the -OnWriteComplete callback is executed.

The ocname group writeVQTSync groupname items command is just like the writeVQTAsync command described immediately above except that the call does not return until after writing to the device layer is completed. The return value is a list of error codes, one for each item.

OPC Client Group Item Commands

ocname group itemsAdd groupname items
ocname group itemsAddValidate groupname items
ocname group itemsBufferedGet groupname svrHandles
ocname group itemsBufferedSet groupname svrH_be_pairs
ocname group itemsDeadBGet groupname svrHandles
ocname group itemsDeadBSet groupname svrH_db_pairs
ocname group itemsDeadBClear groupname svrHandles
ocname group itemsList groupname
ocname group itemsRemove groupname svrHandles
ocname group itemsSamplingGet groupname svrHandles
ocname group itemsSamplingSet groupname svrH_period_pairs
ocname group itemsSamplingClear groupname svrHandles
ocname group itemsSetActive groupname svrHandles bActive
ocname group itemsSetHandles groupname svrH_clientH_pairs
ocname group itemsSetTypes groupname svrH_vT_pairlist

The commands in this section are for working with items in the context of their membership in a group.

The ocname group itemsAdd groupname items command is used to add items to an existing group. The items argument is a list of records, one for each item. Each record is formatted as a five element list:

The ItemID is the fully qualified string value identifying the item. The AccessPath value is a string used by certain servers. An empty string is used as a place holder if it is not relevant. The bActive value is a boolean 1|0 indication of whether the item is active for IO operations. The handle value is an integer assigned by you as a shorthand way to identify the item in data value reports. The RequestedType is an integer value which is usually set to 0 to specify that the server should pass data values using the canonical data type of the item. Optionally, you may specify a variantTypeCode to indicate that the server should convert values of the item to a different binary representation before passing them. VariantTypeCode values are explained above.

The return value of the command is a list of records, one for each item. Each record is formatted as a four element list:

The errCode value is non-zero if there is an error with adding the item. The serverHandle value is the server's integer handle for item that is used for various methods as a shorthand means of identification. The type value indicates the server's canonical variantTypeCode for the data type of the item's values. The rw value is a bitfield showing whether reads (bit 1 set) or writes (bit 2 set) are possible.

The ocname group itemsAddValidate groupname items command is just like the group itemsAdd command except that the item or items are not actually added to the group. So this is a means to validate ItemID values and to obtain type and IO information.

The ocname group itemsBufferedGet groupname svrHandles command calls the optional Version 3 method IOPCSamplingMgt::GetItemBufferEnable to determine whether buffering has been enabled for selected items. The svrHandles argument is a list of serverHandle values specifying which items in the group are selected. In brief, when buffering is enabled for an item whose reporting period is less than the group refresh period, then it is possible to see more than one value for the item in the OnDataChange callback notification. The return value for the method is a list of records, one for each item. Each record is a two element list, errCode and isBuffered. The latter is a boolean value indicating whether buffering is enabled for the item.

The ocname group itemsBufferedSet groupname svrH_be_pairs command is used with the optional Version 3 method IOPCSamplingMgt::SetItemBuufferEnable to specify whether buffering is enabled for selected items. By default, buffering is not enabled. The svrH_be_pairs argument is a list of records one for each item. Each record is a two element list, serverHandle and the boolean value isBuffered. The return value is a list of error codes, one for each item.

ocname group itemsDeadBGet groupname serverHandles
ocname group itemsDeadBSet groupname svrH_db_pairs
ocname group itemsDeadBClear groupname serverHandles

These commands use the Version 3 IOPCItemDeadBandMgt interface to let you specify deadband percentages for specific items that override the value specified for the group. The Get command enables you to query current settings and it returns a list of errorCode and percentage pairs, one pair for each item. If a deadband value has not been set for the item, an error code value, 0xC0040400, is returned instead of the group value. The Set command uses the argument svrH_db_pairs which is structured as a list of pairs, the serverHandle and the deadbandPercentage for each item. The return value of the Set command is a list of error codes, one value for each item. The Clear command tells the server to revert the selected items to the group deadband value.

The ocname group itemsList groupname command is used to list the items in a group. The return value is a list of records, one for each item. Each record is a 10 element list:

Most of the list elements should be obvious from similar methods. The typeRequested and type values show the variantTypeCodes as requested by the client and the canonical type for the item. The EUtype value indicates possible Engineering Unit information. The value 1 means the item is an analog value and the EUdata provides a low and high floating point value for the low and high of the expected range. The EUtype value of 2 indicates that the item is an enumerated unsigned integer value. In this case, the EUdata provides a list of string values corresponding to the integer values 0, 1, 2, .... The EUtype value of 0 is defined to mean no EU information is available.

The ocname group itemsRemove groupname svrHandles command is used to remove one or more items from a group. The return value is a list of error codes, one for each item.

ocname group itemsSamplingGet groupname svrHandles
ocname group itemsSamplingSet groupname svrH_period_pairs
ocname group itemsSamplingClear groupname svrHandles

These commands are used with the optional Version 3 IOPCItemSamplingMgt interface to manage sampling periods for individual items that are different than the sampling period established for the group. The OPC Standards unfortunately use the term sampling rate in discussion of sampling periods and therefore cause confusion and ambiguity since rate and period are inversely related.

The Get command enables you to query current settings and it returns a list of errorCode and period pairs, one pair for each item. If a period value has not been set for the item, an error code value, 0xC0040405, is returned instead of the group value. The Set command uses the argument svrH_period_pairs which is structured as a list of pairs, the serverHandle and the samplingPeriod for each item. The return value of the Set command is a list of error codes, one value for each item. The Clear command tells the server to revert the selected items to the group period value.

The ocname group itemsSetActive groupname serverHandles bActive command enables you to enable or disable selected items in the group for IO actions. The serverHandles argument is a list of server handles for selected items in the group. The bActive argument is a single, scalar boolean value to apply to all of the selected items. The return value is a list of error codes, one for each item.

The ocname group itemsSetHandles groupname svrH_clientH_pairs command allows for revising the client handles for selected items in the group. The svrH_clientH_pairs argument is list of pairs, each pair is a list of two elements, the serverHandle and the clientHandle for the item. The return value is a list of error codes, one for each item.

The ocname group itemsSetTypes groupname svrH_vT_pairlist command enables the caller to set requested data conversions for selected items in the group. The svrH_vT_pairlist argument is a list of pairs, each pair is a list of two elements, the serverHandle and the variantTypeCode for the item. The return value is a list of error codes, one for each item.

OPC Client Item Commands

ocname read items
ocname write items

These commands provide for item IO without the complexity of defining and configuring groups to include the items. The commands are only supported by Version 3 servers. The OPC specification warns that the performance may compare to the server invisibly creating a group, performing the IO, and deleting the group.

Certainly these commands are not recommended for regular use - use the Group mechanism with the periodic delivery of data to the -OnDataChange callback instead.

The ocname read items command performs the IOPCItemIO::Read method call. The items argument is a list of records, one for each item. Each record is a two element list consisting of:

The ItemID value is the fully qualified Item identifying string. The maxAgeMilliseconds is the maximum age value for the item in milliseconds. The concept of Age is explained above with the group readAgeAsync command. The return value of the command is a list of records, one for each item. Each record is a four element list structured as:

The ocname write items command performs the IOPCItem::WriteVQT method call. The items argument is a list of records, one for each item. Each record is a six element list consisting of:

The ItemID value is the fully qualified Item identifying string. The other arguments are explained above with the similar group write command. The return value is a list of error codes, one for each item.

EXAMPLE

Review the OPC Supervisor Application source code for a complete, production worthy example.

package require humeopc
set server_selection [::opc::opc enum [::opc::opc catlist] localhost]

set clsid [opc clsid OpcSample.OpcDa30Server.1]
puts [::dmh::mh_eval {opc client c1 $clsid}]

foreach cmd {\
 {c1 group add g1 -handle 777} \
 {c1 group itemsAdd g1 { {{Dynamic/Analog Types/Int} {} 1 101 0} {{Dynamic/Analog Types/Double} {} 1 102 0} \
   {{Dynamic/Enumerated Types/Fellowship} {} 1 103 0}}}\
 {c1 group callback g1 -OnDataChange puts -OnReadComplete puts} \
 } {
   puts "::dmh::mh_eval {$cmd}"   ;# show command
   puts [::dmh::mh_eval $cmd]     ;# show result
   }
puts "some commands to try...(cut-and-paste)"
puts "c1 group config g1 -active 1 -period 2000"
puts "c1 write { {{Dynamic/Analog Types/Int} 1 3 99 192 {}}}"
puts "c1 write [list [list [list {Dynamic/Analog Types/Int} 7 3 101 192 [::dmh::localtime 16]]]]"
puts "c1 read { {{Dynamic/Analog Types/Int} 2000}}"
set x  [list [list {Static/Analog Types/Int} 7 3 101 192 [::dmh::localtime 16]]]
c1 write $x
c1 read { {{Static/Analog Types/Int} 2000}}
  

AUTHOR

Hume Integration Software, www.hume.com

SEE ALSO

OPC Supervisor Application

KEYWORDS

OPC, COM, DCOM, OLE, Process Control, SCADA, HMI