Utgard使用总结(OPC)

来源:互联网 发布:矩阵型组织结构 编辑:程序博客网 时间:2024/06/05 01:06

一、在使用utgard之前需要详细配置好服务器端DCOM组件,详情可参照下面的网址:

https://wenku.baidu.com/view/3ec0acc87e21af45b207a82d.html

注:

    1.在根据上面网址描述步骤进行配置的时候,用户需要有密码。

    2.在配置防火墙的时候可以不关闭防火墙,假如后面程序访问无效,可以尝试新增防火墙入站规则,开放TCP/UDP协议的135端口(Utgard使用了RPC方法),设置后如下图:


二、使用Utgard访问OPC server

1.首先需要导入jar包,在编写简单的demo程序中只需下面几个jar包:(红框是核心jar包)

2.然后编写demo,设置连接服务器的主机用户密码等信息

private static String host = "localhost";private static String domain = "localhost";private static String progId = "Matrikon.OPC.Simulation";private static String user = "opcuser";private static String password = "opcuser";

在不知道服务器有什么OPC Server的情况下可以通过ServerList类获取服务器端所有OPCServer信息

ServerList serverList = new ServerList(host,user,password,domain);showAllOPCServer(serverList);

/** * 该函数用于显示当前连接服务器上所有支持OPC DA2.0规范的OPC服务器应用 * @param serverList * @throws JIException * @throws IllegalArgumentException * @throws UnknownHostException */protected static void showAllOPCServer(ServerList serverList) throws JIException, IllegalArgumentException, UnknownHostException {final Collection<ClassDetails> detailsList = serverList.listServersWithDetails (new Category[] { Categories.OPCDAServer20 }, new Category[] {} );for ( final ClassDetails details : detailsList ){System.out.println ( String.format ( "Found: %s", details.getClsId () ) );System.out.println ( String.format ( "\tProgID: %s", details.getProgId () ) );System.out.println ( String.format ( "\tDescription: %s", details.getDescription () ) );}}

3.创建ConnectionInformation类

final ConnectionInformation ci = new ConnectionInformation();ci.setHost(host);ci.setClsid(serverList.getClsIdFromProgId ("Matrikon.OPC.Simulation"));ci.setUser(user);ci.setPassword(password);

其中通过Clsid的方式查找OPC Server更快,但如果事先不知道clsid,也可以通过ServerList类的getClsIdFromProgId方法来查询相应OPC Server名称的Clsid。

4.创建Server类并连接,需要处理connect方法可能抛出的异常

ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();Server server = new Server(ci, exec);server.connect();

之后server对象就可以复用了。

假如两次访问间隔的时间较长,可以通过AutoReconnectController类来为我们自动重新创立连接:

ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();Server server = new Server(ci, exec);AutoReconnectController autoReconnectController = new AutoReconnectController ( server );autoReconnectController.connect();

5.Utgard有两种数据访问方式——直接通过itemread/write方法或者使用AccessBase(读取数据)

需要注意的是,不管采用哪一种方式,返回结果都是通过ItemState类来获取,通过调用ItemStategetValue方法可以获得访问结果,返回结果是JIVarant类型的,里面包含了OPC访问时的各种类型及处理方法(如下图)。

1) 通过item的read/write方法

/** * 使用Item类write方法写入数据,并直接通过Item的read方法同步读数据 * @throws Exception */public static void syncWrite(Server server) throws Exception{final String itemId="Bucket Brigade.Int4";Group group = server.addGroup("test");Item item = group.addItem(itemId); //get item for writing//第一次读ItemState itemState = item.read(true);System.out.println("<<< first read: " + itemState.getValue());final JIVariant value = new JIVariant(100);try {System.out.println(">>> writing value: " + value.getObjectAsInt());item.write(value);} catch (JIException e) {e.printStackTrace();}itemState = item.read(true);System.out.println("<<< after writing: " + itemState.getValue());}

item的read/write实际上调用了所属group的read/write方法,而group的read/write方法实际调用的是syncIO的read/write方法,因而该方式属于同步读写。

2) 使用AccessBase类(读取数据)

AccessBase接口有两个实现类——SyncAccess类和Async20Access类,使用方法见下(代码中所会抛出的异常已经被throw给了上层调用者):

A.  同步访问SyncAccess

/** * 使用SyncAccess类隔时间段地进行同步读取数据 * SyncAccess实现了Runnable接口,实际上通过另一个线程进行同步读 * @throws Exception */public static void syncRead(Server server) throws Exception{final String itemId="Random.Int4";//每隔1秒同步读AccessBase access = new SyncAccess(server,1000);access.addItem(itemId, new DataCallback() {@Overridepublic void changed(Item item, ItemState itemState) {System.out.println(itemState);}});// start readingaccess.bind();// wait a little bitThread.sleep(5*1000);// stop readingaccess.unbind();}
B.  异步访问Async20Access类

/** * 使用Async20Access类隔时间段地进行异步读取数据 * Async20Access实现了IOPCDataCallback接口,基于事件回调的实现 * @throws Exception */public static void asyncRead(Server server) throws Exception{final String itemId = "Random.Int4";//第三个参数用于设置初始化时是否执行访问AccessBase access = new Async20Access(server, 1000, false);access.addItem(itemId, new DataCallback(){@Overridepublic void changed(Item item, ItemState itemState) {System.out.println(">>> Asynchronized read: value=" + itemState.getValue());}});access.bind();Thread.sleep(5*1000);access.unbind();}



2 0
原创粉丝点击