::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
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:
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:
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.
::opc::opc clsid barney
CLSIDFromProgID failed, rc=0x800401f3
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:
% ::opc::opc client c1 [::opc::opc clsid OpcSample.OpcDa30Server.1]
c1
% ::opc::opc client c2 ed0e3ade-0cf5-47cd-a1ab-522e5e759999
CoCreateInstanceEx failed, rc=0x80040154
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.
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.
proc opc_client_on_shutdown {ocname errCode reason} {
# first thing we do is release the execution stack to return to the callers
# which may include the remote server
# or a local call to ping or GetStatus
after 0 [list opc_client_shutdown $ocname $errCode $reason]
}
proc opc_client_shutdown {ocname errCode reason} {
global $ocname
# ...
}
$ocname onShutdown opc_client_on_shutdown
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:
% foreach {name value} [c1 status] {puts "$name = \"$value\""}
startTime = "2009-04-30T20:56:05.375"
currentTime = "2009-05-01T15:43:11.192"
lastUpdateTime = "2009-05-01T15:43:09.442"
serverState = "running"
groupCount = "3"
bandwidth = "-1"
majorVersion = "3"
minorVersion = "0"
buildNumber = "101"
reserved = "34600"
vendorInfo = "OPC Data Access 3.00 Sample Server"
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.
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:
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.
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 properties used by the group callbacks command include:
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}
# ...
}
}
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.
The ocname group delete
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.
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:
code | type | code | type |
---|---|---|---|
0 | VT_EMPTY | 2 | int16 |
3 | int32 | 4 | float |
5 | double | 6 | currency (decimal) |
7 | datetime | 8 | string |
11 | boolean | 12 | variant |
14 | decimal | 16 | sbyte |
17 | byte | 18 | uint16 |
19 | uint32 | 20 | int64 |
21 | uint64 | 64 | FILETIME |
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.
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.
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.
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}}