dk.opi.io.opc.opcclient
Class OpcClientApi

java.lang.Object
  extended byjava.lang.Thread
      extended bydk.opi.io.opc.opcclient.OpcClientApi
All Implemented Interfaces:
IOServer, IOServer2, Runnable

public class OpcClientApi
extends Thread
implements IOServer2

This class is the interface to the Java native methods necessary for tapping into the OPC (D)COM interface, ie. use this interface when you want to read/write item values from/to a device which has an OPC server. The example below shows how to use this interface in order to monitor values from an simulated ICONICS OPC server.

 import dk.opi.io.*;
 import dk.opi.io.opc.opcclient.*;

 public class SimpleExample implements IOListener {
   protected IOItem boolItem;
   protected IOItem intItem;
   protected IOItem stringItem;
   IOServer is = null;

   public static void main(String[] args) {
     SimpleExample opct = new SimpleExample();
   }

   public SimpleExample() {
     try {
       // Connect to OPC server and create items
       connect();

       // Create test group and add items to it. This object is assigned as
       // listener when values change
       IOGroup g1 = createGroup1(this);

       // Fire an onValueChange() event for all added items in order to
       // get the initial item values
       g1.fireAllItems(this);

       // Try to change value of one of the registers and note that the
       // onValueChanged() method is called whenever the value change
       boolean bVals[] = {false, true, false};
       int iVals[] = {10, 20, 30};
       String sVals[] = {"string1", "string2", "string3"};

       for (int i = 0; i < 3; i++) {
         try {
           System.out.println("Writing loop=" + i);

           boolItem.writeValue(new Boolean(bVals[i]));
           intItem.writeValue(iVals[i]);
           stringItem.writeValue(sVals[i]);
         }
         catch (RbxIOException e) {
           e.printStackTrace();
         }

         try {Thread.sleep(2000);} catch(Exception e){};
       }
     }
     catch (RbxIOException e) {
       e.printStackTrace();
     }

     // release connection to OPC server again. It's important to call this
     // method. If it's not called the OPC server will not shut down
     // automatically
     if (is != null)
       is.releaseConnection();

     System.exit(0);
   }

   // This method implements the specific details of connecting to the OPC
   // server
   public void connect() throws RbxIOException {
     // Initialize the OPC client interface to a Iconics simulated OPC server
     this.is = new OpcClientApi("ICONICS.Simulator");
   }

   // This method implements the specific details of adding groups and
   // items to the already open OPC server
   public IOGroup createGroup1(IOListener iol) throws RbxIOException {
     // Get the reference to the OPC Server
     OpcClientApi oa1 = (OpcClientApi)this.is;

     // Add a group to this server
     OpcGroup og1 = oa1.addGroup("testgrp", true, 500, 0f);

     // Sign up specified listener for value change events. The
     // onValueChanged() method of the listener will be callled. It's
     // important to sign up as listener before items are added, otherwise
     // notifications may be lost
     og1.addIOListener(iol);

     // Add three items - the item name is specific for the type of device
     // you are going to read from. The specified item name (ie.
     // "Device1.boolItem") must match the item name as it is known to the
     // OPC server.
     boolItem = og1.addItem("Device1.boolItem", null, true,
                            IOItem.DATATYPE_BOOL, "myBoolItem");
     intItem = og1.addItem("Device1.intItem", null, true,
                           IOItem.DATATYPE_INT, "myIntItem");
     stringItem = og1.addItem("Device1.stringItem", null, true,
                              IOItem.DATATYPE_STRING, "myStringItem");

     return(og1);
   }

   // Called when a data value has changed
   public void onValueChanged(IOItem i) {
     System.out.println("onValueChanged action=" + i.getActionCommand() + " " +
                        i + "=" + i.getOldValue());
   }
 }
 
The following is sample ouput generated by the above example:
 C:\>java OPCTest2
 onValueChanged action=myBoolItem Device1.boolItem=false
 onValueChanged action=myIntItem Device1.intItem=0
 onValueChanged action=myStringItem Device1.stringItem=
 Writing loop=0
 onValueChanged action=myStringItem Device1.stringItem=string1
 onValueChanged action=myIntItem Device1.intItem=10
 Writing loop=1
 onValueChanged action=myStringItem Device1.stringItem=string2
 onValueChanged action=myIntItem Device1.intItem=20
 onValueChanged action=myBoolItem Device1.boolItem=true
 Writing loop=2
 onValueChanged action=myStringItem Device1.stringItem=string3
 onValueChanged action=myIntItem Device1.intItem=30
 onValueChanged action=myBoolItem Device1.boolItem=false
 


Field Summary
static int DEBUG_LEVEL_ALL
          the highest debug level
static int DEBUG_LEVEL_DEBUG
          debug level - a lot of debug info is printed
static int DEBUG_LEVEL_INFO
          informational debug level - top level info is printed
static int DEBUG_LEVEL_NORMAL
          the normal debug level - only errors are printed
 
Fields inherited from class java.lang.Thread
MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY
 
Constructor Summary
OpcClientApi(String name)
          Create OpcClientApi object
OpcClientApi(String name, int msecTimeout)
          Create OpcClientApi object
OpcClientApi(String hName, String name)
          Create OpcClientApi object
OpcClientApi(String hName, String name, int msecTimeout)
          Create OpcClientApi object
 
Method Summary
 OpcGroup addGroup(String name, boolean active, int updateRate, float percentDeadBand)
          Add a group to this server
 OpcGroup addGroup(String name, boolean active, int updateRate, float percentDeadBand, String descr)
          Add a group to this server
 Vector getGroups()
          Return Vector of all IOGroups currently added to this server.
 int getHandle()
           
 String getServerHostName()
          Returns the name of the machine hosting the OPC server this client connects to
static IOServerInfo[] getServerInfo()
          Static method returning an array of IOServerInfo objects holding information about OPC servers available from the local machine.
 IOItemBrowseTreeNode getServerItemsInfo()
          This method returns a tree of available groups and items on the OPC server.
 String getServerName()
          Returns the server name for the OPC server this client connects to, ie.
 Object readValue(OpcItem i)
          Read a value for specified item.
 Object readValue(OpcItem i, int dataSource)
          Read an value for specified item.
 void releaseConnection()
          Close client connections and release all handles and connections to the OPC server.
 void releaseConnection(int msecTimeout)
          Close client connections and release all handles and connections to the OPC server.
 void removeGroup(IOGroup iog)
          Remove a group from this server
 void run()
          Thread started when object connects to the OPC server.
 void setDebugLevel(int level)
          Set the debug level.
 boolean setGroupActive(OpcGroup g, boolean value)
          Make group inactive or active.
 void writeDoubleValue(OpcItem i, double value)
          Write a double value for specified item.
 void writeFloatValue(OpcItem i, float value)
          Write a float value for specified item.
 void writeIntValue(OpcItem i, int value)
          Write an integer value for specified item.
 boolean writeMultipleItems(Vector itemWriteList)
          Used for bulk write of one or more OpcItem objects.
 void writeStringValue(OpcItem i, String value)
          Write a String value for specified item.
 
Methods inherited from class java.lang.Thread
activeCount, checkAccess, countStackFrames, currentThread, destroy, dumpStack, enumerate, getContextClassLoader, getName, getPriority, getThreadGroup, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, resume, setContextClassLoader, setDaemon, setName, setPriority, sleep, sleep, start, stop, stop, suspend, toString, yield
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

DEBUG_LEVEL_NORMAL

public static final int DEBUG_LEVEL_NORMAL
the normal debug level - only errors are printed

See Also:
Constant Field Values

DEBUG_LEVEL_INFO

public static final int DEBUG_LEVEL_INFO
informational debug level - top level info is printed

See Also:
Constant Field Values

DEBUG_LEVEL_DEBUG

public static final int DEBUG_LEVEL_DEBUG
debug level - a lot of debug info is printed

See Also:
Constant Field Values

DEBUG_LEVEL_ALL

public static final int DEBUG_LEVEL_ALL
the highest debug level

See Also:
Constant Field Values
Constructor Detail

OpcClientApi

public OpcClientApi(String name)
             throws RbxIOException
Create OpcClientApi object

Parameters:
name - name of the server to contact, ie. ICONICS.Simulator. The server should be located on the local machine. Alternatively the NT dcomcnf.exe utility may be used in order to specify a different location. In any way the OPC server should have been installed on the local machine, in order to create reference to the CLSID in the local registry.
Throws:
RbxIOException - thrown if the server connection could not be established

OpcClientApi

public OpcClientApi(String name,
                    int msecTimeout)
             throws RbxIOException
Create OpcClientApi object

Parameters:
name - name of the server to contact, ie. ICONICS.Simulator. The server should be located on the local machine. Alternatively the NT dcomcnf.exe utility may be used in order to specify a different location. In any way the OPC server should have been installed on the local machine, in order to create reference to the CLSID in the local registry.
msecTimeout - number of milliseconds to wait before timing out on the connect attempt. Due to DCOM implementation details two orphan connection threads will pend for a while after a timeout, but the threads will eventually disappear. Use a value of 0 to specify no timeout.
Throws:
RbxIOException - thrown if the server connection could not be established
Since:
JOPCClient v1.106

OpcClientApi

public OpcClientApi(String hName,
                    String name)
             throws RbxIOException
Create OpcClientApi object

Parameters:
hName - name of the machine hosting the OPC server that this client should connect to. The name may be specified as an IP-address, a DNS name (ie. server.com). Specify null if the server is located on the local machine.

If the server is located on a remote machine, it is still necessary to install it locally first, in order to create the CLSID in the local registry. Alternatively the CLSID may be created manually, consult documentation of your OPC server for more info on this issue.

name - name of the server to contact, ie. ICONICS.Simulator
Throws:
RbxIOException - thrown if the server connection could not be established

OpcClientApi

public OpcClientApi(String hName,
                    String name,
                    int msecTimeout)
             throws RbxIOException
Create OpcClientApi object

Parameters:
hName - name of the machine hosting the OPC server that this client should connect to. The name may be specified as an IP-address, a DNS name (ie. server.com). Specify null if the server is located on the local machine.

If the server is located on a remote machine, it is still necessary to install it locally first, in order to create the CLSID in the local registry. Alternatively the CLSID may be created manually, consult documentation of your OPC server for more info on this issue.

name - name of the server to contact, ie. ICONICS.Simulator
msecTimeout - number of milliseconds to wait before timing out on the connect attempt. Due to DCOM implementation details two orphan connection threads will pend for a while after a timeout, but the threads will eventually disappear. Use a value of 0 to specify no timeout.
Throws:
RbxIOException - thrown if the server connection could not be established
Since:
JOPCClient v1.106
Method Detail

getServerName

public String getServerName()
Returns the server name for the OPC server this client connects to, ie. the OPC server name specified in the constructor of OpcClientApi.

Returns:
the server name for this object

addGroup

public OpcGroup addGroup(String name,
                         boolean active,
                         int updateRate,
                         float percentDeadBand)
                  throws RbxIOException
Add a group to this server

Parameters:
name - name of the group. Must be unique within this server
active - if items in this group are going to be monitored
updateRate - requested update rate for items in this group in milli seconds
percentDeadBand - if items in this group are monitored using AdviseSink function then values are only changed when they have been changed more than specified by this value.
Returns:
OpcGroup object which should be used when adding items
Throws:
RbxIOException - thrown if the group could not be addded

addGroup

public OpcGroup addGroup(String name,
                         boolean active,
                         int updateRate,
                         float percentDeadBand,
                         String descr)
                  throws RbxIOException
Add a group to this server

Parameters:
name - name of the group. Must be unique within this server
active - if items in this group are going to be monitored
updateRate - requested update rate for items in this group in milli seconds
percentDeadBand - if items in this group are monitored using AdviseSink function then values are only changed when they have been changed more than specified by this value.
descr - description of the item. Can be queried by a call to getDescription()
Returns:
OpcGroup object which should be used when adding items
Throws:
RbxIOException - thrown if the group could not be addded

getGroups

public Vector getGroups()
Return Vector of all IOGroups currently added to this server.

Specified by:
getGroups in interface IOServer
Returns:
Vector object containing list of all IOGroups added to this server

removeGroup

public void removeGroup(IOGroup iog)
                 throws RbxIOException
Remove a group from this server

Specified by:
removeGroup in interface IOServer
Parameters:
iog - The group to remove
Throws:
RbxIOException - thrown if it was not possible to remove the specified group, for instance if the specified group is not a member of this server.

getHandle

public int getHandle()

releaseConnection

public void releaseConnection()
Close client connections and release all handles and connections to the OPC server. After this method has been executed no further read or write request can be made to this object. Create a new instance if you want to reconnect to the OPC server

Known bug: Releasing and immidiately after reconnecting to the same OPC server instance may cause an error, if the OPC server is closed on the call to releaseConnection(). This is caused by a flaw in the DCOM object activation frame work. A workaround is to always sleep app. 500 ms. before reconnecting to the same OPC server, in order to allow the OPC server to completely shut down before creating a new connection.

Specified by:
releaseConnection in interface IOServer

releaseConnection

public void releaseConnection(int msecTimeout)
                       throws RbxIOException
Close client connections and release all handles and connections to the OPC server. After this method has been executed no further read or write request can be made to this object. Create a new instance if you want to reconnect to the OPC server

Known bug: Releasing and immidiately after reconnecting to the same OPC server instance may cause an error, if the OPC server is closed on the call to releaseConnection(). This is caused by a flaw in the DCOM object activation frame work. A workaround is to always sleep app. 500 ms. before reconnecting to the same OPC server, in order to allow the OPC server to completely shut down before creating a new connection.

Specified by:
releaseConnection in interface IOServer
Parameters:
msecTimeout - number of milliseconds to wait before timing out in case connection could not be released within specified timeout period. A timeout may occur in the event that the delegating releaseConnection call to the OPC server hangs, eg. the OPC server is currently unavailable on the network.

Even in the event of a timeout all claimed resources will be released, thus the caller should not attempt any further calls to releaseConnection(), even after a timeout

Throws:
RbxIOException - thrown in case of timeout, however connection will still be released.
Since:
JOPCClient v1.106

readValue

public Object readValue(OpcItem i)
                 throws RbxIOException
Read a value for specified item. The value is read from the cache of the OPC server

Parameters:
i - Item to read value from
Returns:
the value read from the item. The object returned are either of type Integer, Boolean etc. depending on the datatype of the item
Throws:
RbxIOException - thrown if the read operation failed

readValue

public Object readValue(OpcItem i,
                        int dataSource)
                 throws RbxIOException
Read an value for specified item. The value is read from the cache of the OPC server

Parameters:
i - Item to read value from
Returns:
the value read from the item. The object returned are either of type Integer, Boolean etc. depending on the datatype of the item
Throws:
RbxIOException - thrown if the read operation failed

writeMultipleItems

public boolean writeMultipleItems(Vector itemWriteList)
                           throws RbxIOException
Used for bulk write of one or more OpcItem objects. Use this method to improve write performance when writing to many items at the same time. All the items are sent to the OPC server as a single package, thus minimizing network bandwidth.

The method runs to completion. The values are written to the DEVICE. That is, the method will not return until it verifies that the device has actually accepted (or rejected) the data.

Writes are not affected by the ACTIVE state of the item.

Example of usage:

 import java.util.Vector;
 import dk.opi.io.*;
 import dk.opi.io.opc.opcclient.*;

 IOServer2 is;

 IOItem intItem;
 IOItem boolItem;
 IOItem stringItem;

 Vector witems = new Vector();
 witems.addElement(new IOItemWriteValue(intItem, new Integer(22)));
 witems.addElement(new IOItemWriteValue(boolItem, Boolean.TRUE));
 witems.addElement(new IOItemWriteValue(stringItem, "test string"));

 if (is.writeMultipleItems(witems)) {
   // one or more items not written - check the error
   for (int j = 0; j < witems.size(); j++) {
     IOItemWriteValue wVal = (IOItemWriteValue )witems.elementAt(j);
     String errText = wVal.getErrorText();
     if (errText != null) {
       System.out.println("errorText item no." + j +
                          " errorText=" + errText);
     } // end of if ()
   } // end of for (int  = 0;  < ; ++)
 } // end of if ()
 

Specified by:
writeMultipleItems in interface IOServer2
Parameters:
itemWriteList - a Vector holding IOItemWriteValue objects. If an element in itemWriteList is not of this type, an exception will be thrown
Returns:
true if one or more items were not succesfully written to the the server. In that event the caller should check the itemWriteList Vector querying the IOItemWriteValue.getErrorText() method for the error description. In case false is returned all items were sucessfully written, so the user need not query the itemWriteList Vector.
Throws:
RbxIOException - if an write failure occured or if the size of the items and values Vectors are not the same.

writeIntValue

public void writeIntValue(OpcItem i,
                          int value)
                   throws RbxIOException
Write an integer value for specified item.

Parameters:
i - Item to write value to
value - the value to write
Throws:
RbxIOException - thrown if the write operation failed

writeFloatValue

public void writeFloatValue(OpcItem i,
                            float value)
                     throws RbxIOException
Write a float value for specified item.

Parameters:
i - Item to write value to
value - the value to write
Throws:
RbxIOException - thrown if the write operation failed

writeDoubleValue

public void writeDoubleValue(OpcItem i,
                             double value)
                      throws RbxIOException
Write a double value for specified item.

Parameters:
i - Item to write value to
value - the value to write
Throws:
RbxIOException - thrown if the write operation failed

writeStringValue

public void writeStringValue(OpcItem i,
                             String value)
                      throws RbxIOException
Write a String value for specified item.

Parameters:
i - Item to write value to
value - the value to write
Throws:
RbxIOException - thrown if the write operation failed

setGroupActive

public boolean setGroupActive(OpcGroup g,
                              boolean value)
Make group inactive or active. In the active state all items in the group are monitored and events are sent out when a value has changed.

Important: not intended for public use, instead use the OpcGroup.setActive(boolean) method

Parameters:
g - Group to set active/inactive
value - true if group should be set to active, false otherwise.
Returns:
true if the value was sucessfully updated, false otherwise

getServerInfo

public static IOServerInfo[] getServerInfo()
                                    throws RbxIOException
Static method returning an array of IOServerInfo objects holding information about OPC servers available from the local machine. The server list is obtained by performing a Windows registry lookup. The information in the returned IOServerInfo object may be used for creating an OPC connection by creating a new instance of OpcClientApi. Example:
 IOServerInfo[] srvList = OpcClientApi.getServerInfo();
 OpcClientApi server = new OpcClientApi(srvList[1].getName());
 

Returns:
an array of IOServerInfo objects. An array with length 0 means no servers are availble
Throws:
RbxIOException - if an error occur
Since:
JOPCClient v1.200

getServerItemsInfo

public IOItemBrowseTreeNode getServerItemsInfo()
                                        throws RbxIOException
This method returns a tree of available groups and items on the OPC server. The information in the returned tree is dynamically obtained from the OPC server when the method is called. The returned IOItemBrowseTreeNode captures a snapshot of all available groups and items, ie. the information in the returned tree structure is static, thus to update the information, make a repeated call to getServerInfo().

The returned tree may be shown in a JTree by using the wrapper class JTreeIOTreeNode, please refer to this class for an example of the usage of IOItemBrowseTreeNode in combination with a JTree.

Returns:
an IOItemBrowseTreeNode value
Throws:
RbxIOException - if an error occur
Since:
JOPCClient v1.200

setDebugLevel

public void setDebugLevel(int level)
Set the debug level. Debug messages are printed to stdout

Parameters:
level - any of the values DEBUG_LEVEL_NORMAL, DEBUG_LEVEL_INFO, DEBUG_LEVEL_DEBUG or DEBUG_LEVEL_ALL
Throws:
IllegalArgumentException - if level is unknown

run

public void run()
Thread started when object connects to the OPC server. Not for public use

Specified by:
run in interface Runnable

getServerHostName

public String getServerHostName()
Returns the name of the machine hosting the OPC server this client connects to

Returns:
the server host name or null if the server is running on the local machine
Since:
JOPCClient v1.107