utgard OPC 主要功能简介
度娘还行,尽管不好用,但所有的开发人员不懈努力地写博客,能得到很多东西! 这里向所有未谋面的博主们致敬!
搜了一堆OPC资料,在这里整理一下,用一个封装类来说明utgard的主要接口。使用了java自带的观察者模式,回调通知检测点数据;
1. opc客户端主类
public class OpcClient extends Observable {
private Server mServer = null;
/**
* 连接opc server
*/
public synchronized boolean connectServer(String host, String progId, String user, String password, String domain) {
boolean mState = false;
ServerList serverList = null;
try {
// 获取server上的opc server应用列表
serverList = new ServerList(host, user, password, domain);
// 连接server
final ConnectionInformation connectionInfo = new ConnectionInformation();
connectionInfo.setHost(host);
connectionInfo.setClsid(serverList.getClsIdFromProgId(progId));// TODO 设置ProgId,无法连接server;设置Clsid,连接server成功
connectionInfo.setUser(user);
connectionInfo.setPassword(password);
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
mServer = new Server(connectionInfo, executor);
mServer.connect();
mServer.addStateListener(new ServerConnectionStateListener() {
@Override
public void connectionStateChanged(boolean state) {
System.out.println("connectionStateChanged state=" + state);
}
});
mState = true;
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (JIException e) {
e.printStackTrace();
} catch (AlreadyConnectedException e) {
e.printStackTrace();
} finally {
if (!mState) {
mServer = null;
}
}
return mState;
}
/**
* 断开连接opc server
*/
public synchronized void disconnectServer() {
if (mServer == null) {
return;
}
mServer.disconnect();
mServer = null;
}
/*
* 显示server上的OPC服务器应用列表
*/
public void showAllOPCServer(String host, String user, String password, String domain) {
try {
ServerList serverList = new ServerList(host, user, password, domain);
// 支持DA 1.0,DA 2.0规范
Collection<ClassDetails> detailsList = serverList.listServersWithDetails(
new Category[] { Categories.OPCDAServer10, Categories.OPCDAServer20 }, new Category[] {});
for (final ClassDetails details : detailsList) {
System.out.println("ClsId=" + details.getClsId() + " ProgId=" + details.getProgId() + " Description="
+ details.getDescription());
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 检查opc server中是否包含指定的监测点列表
*/
public boolean checkItemList(List<String> list) {
// 获取opc server上的所有检测点
FlatBrowser flatBrowser = mServer.getFlatBrowser();
if (flatBrowser == null) {
return false;
}
try {
Collection<String> collection = flatBrowser.browse();
return collection.containsAll(list);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 异步读取数据 Async20Access实现了IOPCDataCallback接口,基于事件回调的实现
*/
public void asyncReadObject(final String itemId, int period) {
// 第三个参数用于设置初始化时是否执行访问
AccessBase accessBase;
try {
accessBase = new Async20Access(mServer, period, false);
accessBase.addItem(itemId, new DataCallback() {
@Override
public void changed(Item item, ItemState itemState) {
System.out.println("asyncReadObject item=" + itemState);
try {
Object value = itemState.getValue().getObject();
setData(itemId, value);
} catch (JIException e) {
e.printStackTrace();
}
}
});
// 开始读取
accessBase.bind();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (NotConnectedException e) {
e.printStackTrace();
} catch (JIException e) {
e.printStackTrace();
} catch (DuplicateGroupException e) {
e.printStackTrace();
} catch (AddFailedException e) {
e.printStackTrace();
}
}
/**
* 同步读取数据
*/
public void syncReadObject(final String itemId, int period) {
AccessBase accessBase;
try {
// SyncAccess会开启一个线程,按照period时间间隔,定时去获取监控点数据
accessBase = new SyncAccess(mServer, period);
//这个好像用处不太大
accessBase.addStateListener(new AccessStateListener() {
@Override
public void stateChanged(boolean state) {
System.out.println("stateChanged state=" + state);
}
@Override
public void errorOccured(Throwable arg) {
System.out.println("errorOccured arg=" + arg);
}
});
accessBase.addItem(itemId, new DataCallback() {
@Override
public void changed(Item item, ItemState itemState) {
System.out.println("syncReadObject item=" + itemState);
if (itemState == null) {
System.out.println("itemState is null");
return;
}
try {
Object value = itemState.getValue().getObject();
setData(itemId, value);
} catch (JIException e) {
e.printStackTrace();
}
}
});
// 开始读取
accessBase.bind();
// 解除绑定,停止读取
// accessBase.unbind();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (NotConnectedException e) {
e.printStackTrace();
} catch (JIException e) {
e.printStackTrace();
} catch (DuplicateGroupException e) {
e.printStackTrace();
} catch (AddFailedException e) {
e.printStackTrace();
}
}
/**
* 加入观察者
*/
public void subscribe(Observer observer) {
this.addObserver(observer);
}
/**
* 数据变化,通知观察者
*/
private void setData(String itemId, Object value) {
setChanged();
notifyObservers(new Result(itemId, value));
}
}
2. 检测点数据Result.java
public class Result {
private String itemId;// 监控位置
private Object value;// 监控值
public Result(String itemId, Object value) {
this.itemId = itemId;
this.value = value;
}
public String getItemId() {
return itemId;
}
public Object getValue() {
return value;
}
@Override
public String toString() {
return "[itemId=" + itemId + ", value=" + value + "]";
}
}
测试:
public class Main {
public static void main(String[] args) {
String host = "127.0.0.1";// server
String domain = "";// domain
String progId = "ICONICS.SimulatorOPCDA.2";
String user = "OpcUser";// server上的访问用户
String password = "xxxxxx";// 访问用户的密码
OpcClient opcClient = new OpcClient();
// 1.显示server上的opc server应用列表
opcClient.showAllOPCServer(host, user, password, domain);
// 2.连接指定的opc server
boolean ret = opcClient.connectServer(host, progId, user, password, domain);
if (!ret) {
System.out.println("connect opc server fail");
return;
}
// 3.检查opc server上的检测点
List<String> itemIdList = new ArrayList<String>();
itemIdList.add("TEST.FA");
itemIdList.add("TEST.FB");
ret = opcClient.checkItemList(itemIdList);
if (!ret) {
System.out.println("not contain item list");
return;
}
// 4.注册回调
opcClient.subscribe(new Observer() {
@Override
public void update(Observable observable, Object arg) {
Result result = (Result) arg;
System.out.println("update result=" + result);
}
});
// 5.添加监听检测点的数据
// client和server在不同网段,可以访问
opcClient.syncReadObject("TEST.FA", 500);
/**
* TODO 问题
* client和server在不同网段,访问失败,比如:server为10.1.1.132,该网段下面又连接了扩展路由器,192.168.1.x,client为192.168.1.100
*/
opcClient.asyncReadObject("TEST.FB", 500);
// 延迟
delay(5 * 60 * 1000);
}
private static void delay(long time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
utgard OPC 主要功能简介的更多相关文章
- DYN-B201 Dynamics CRM 云生产力解决方案与功能简介
DYN-B201 Dynamics CRM 云生产力解决方案与功能简介 讲师:王健.林松涛Dynamics CRM 云产品正式落地中国,CRM 与 Azure.O365 深度整合无缝集成,带来无与伦比 ...
- (视频) 《快速创建网站》 2.3 WordPress初始化和功能简介
本文是<快速创建网站>系列的第4篇,如果你还没有看过之前的内容,建议你点击以下目录中的章节先阅读其他内容再回到本文. 访问本系列目录,请点击:http://devopshub.cn/tag ...
- SharePoint 2013 "通知我"功能简介
功能简介 "通知我"主要是在列表或者文档库里面的项目,有添加/删除/修改等操作,发送邮件通知设置的用户的功能:可以针对列表或者文档库设置通知,也可以针对单一项目设置通知功能,是Sh ...
- Beginning SDL 2.0(1) SDL功能简介
原文链接为 http://wiki.libsdl.org/Introduction. 由于近期整理音视频可视化的技术,发现好久不更新的SDL发布了2.0版本,以前也没有过于关注,这里准备尝试下.了解S ...
- HelloX操作系统网络功能简介及使用和开发指南
HelloX网络功能简介及使用和开发指南 HelloX网络功能简介 作为物联网操作系统,网络功能是必备的核心功能之一.按照规划,HelloX实现了两个不同类型的TCP/IP协议栈,一个面向资源受限的嵌 ...
- 部分GDAL工具功能简介
主要转自http://blog.csdn.net/liminlu0314?viewmode=contents 部分GDAL工具功能简介 gdalinfo.exe 显示GDAL支持的各种栅格文件的信息. ...
- 全国天气预报信息数据 API 功能简介与代码调用实战视频
此文章对开放数据接口 API 之「全国天气预报信息数据 API」进行了功能介绍.使用场景介绍以及调用方法的说明,供用户在使用数据接口时参考之用,并对实战开发进行了视频演示. 1. 产品功能 接口开放了 ...
- Hadoop生态圈-Ambari控制台功能简介
Hadoop生态圈-Ambari控制台功能简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在经历一系列安装过程之后(部署过HDP后我终于发现为什么大家喜欢用它了,部署比CDH简 ...
- Redis安装和主要功能简介
Redis安装和主要功能简介 Redis(https://redis.io/), 是一个内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 安装Redis 我很少在开发机中直接装各种数 ...
随机推荐
- pandas实现hive的lag和lead函数 以及 first_value和last_value函数
lag和lead VS shift 该函数的格式如下: 第一个参数为列名, 第二个参数为往上第n行(可选,默认为1), 第三个参数为默认值(当往上第n行为NULL时候,取默认值,如不指定,则为NULL ...
- python的logging日志模块(二)
晚上比较懒,直接搬砖了. 1.简单的将日志打印到屏幕 import logging logging.debug('This is debug message') logging.info('Thi ...
- python库下载网址
wheel文件下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/
- P4053 [JSOI2007]建筑抢修 堆贪心
思路:堆贪心 提交:1次 题解: 先按时间\(sort\),然后如果能修就直接扔堆里,不能修取堆顶比一下时间长短,把时间短的扔进堆: #include<cstdio> #include&l ...
- php中的print函数
php print函数怎么用? 定义和用法 print() 函数输出一个或多个字符串. 注释:print() 函数实际不是一个函数,所以您不必对它使用括号. 提示:print() 函数比 echo() ...
- 014_linux驱动之_信号符号名、描述和它们的信号值
符号名 信号值 描述 是否符合POSIX SIGHUP 1 在控制终端上检测到挂断或控制线程死 亡 是 SIGINT 2 交互注意信号 是 SIGQUIT 3 交 互中止信号 是 SIGILL 4 检 ...
- 034_非交互自动生成 SSH 密钥文件
#!/bin/bash#-t 指定 SSH 密钥的算法为 RSA 算法;-N 设置密钥的密码为空;-f 指定生成的密钥文件存放在哪里 rm -rf ~/.ssh/{known_hosts,id_rsa ...
- CF #589 (Div. 2)C. Primes and Multiplication 快速幂+质因数
题目链接:https://www.luogu.org/problem/CF1228C 问题可以转化为:求质数 $p$ 在 $1\sim n$ 中的每个数中的次幂之和. 因为 $p$ 是一个质数,只能由 ...
- 洛谷P1903 [国家集训队]数颜色 / 维护队列 ( 带 修 )
题意:有两种操作: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P Col 把第P支画笔替换为颜色Col. 对每个1操作 输出答案: 带修莫队 模板题 (加 ...
- HTML基础要点归纳
一.开发环境 常用的HTML编辑器有Sublime Text.Hbuild.Dreamweare.以及vs code.pycharm等都可以.我目前在用的就是Sublime text3和Hbuild两 ...