度娘还行,尽管不好用,但所有的开发人员不懈努力地写博客,能得到很多东西! 这里向所有未谋面的博主们致敬!

搜了一堆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 主要功能简介的更多相关文章

  1. DYN-B201 Dynamics CRM 云生产力解决方案与功能简介

    DYN-B201 Dynamics CRM 云生产力解决方案与功能简介 讲师:王健.林松涛Dynamics CRM 云产品正式落地中国,CRM 与 Azure.O365 深度整合无缝集成,带来无与伦比 ...

  2. (视频) 《快速创建网站》 2.3 WordPress初始化和功能简介

    本文是<快速创建网站>系列的第4篇,如果你还没有看过之前的内容,建议你点击以下目录中的章节先阅读其他内容再回到本文. 访问本系列目录,请点击:http://devopshub.cn/tag ...

  3. SharePoint 2013 "通知我"功能简介

    功能简介 "通知我"主要是在列表或者文档库里面的项目,有添加/删除/修改等操作,发送邮件通知设置的用户的功能:可以针对列表或者文档库设置通知,也可以针对单一项目设置通知功能,是Sh ...

  4. Beginning SDL 2.0(1) SDL功能简介

    原文链接为 http://wiki.libsdl.org/Introduction. 由于近期整理音视频可视化的技术,发现好久不更新的SDL发布了2.0版本,以前也没有过于关注,这里准备尝试下.了解S ...

  5. HelloX操作系统网络功能简介及使用和开发指南

    HelloX网络功能简介及使用和开发指南 HelloX网络功能简介 作为物联网操作系统,网络功能是必备的核心功能之一.按照规划,HelloX实现了两个不同类型的TCP/IP协议栈,一个面向资源受限的嵌 ...

  6. 部分GDAL工具功能简介

    主要转自http://blog.csdn.net/liminlu0314?viewmode=contents 部分GDAL工具功能简介 gdalinfo.exe 显示GDAL支持的各种栅格文件的信息. ...

  7. 全国天气预报信息数据 API 功能简介与代码调用实战视频

    此文章对开放数据接口 API 之「全国天气预报信息数据 API」进行了功能介绍.使用场景介绍以及调用方法的说明,供用户在使用数据接口时参考之用,并对实战开发进行了视频演示. 1. 产品功能 接口开放了 ...

  8. Hadoop生态圈-Ambari控制台功能简介

    Hadoop生态圈-Ambari控制台功能简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在经历一系列安装过程之后(部署过HDP后我终于发现为什么大家喜欢用它了,部署比CDH简 ...

  9. Redis安装和主要功能简介

    Redis安装和主要功能简介   Redis(https://redis.io/), 是一个内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 安装Redis 我很少在开发机中直接装各种数 ...

随机推荐

  1. Selenium(六)对话框处理与登录测试

    1.以百度为例,找到登录框,查看元素,可以看到这是一个div 操作登录框: 通过判断是否找到这个错误提示元素查看是否登录成功. 一个简单的登录脚本:

  2. 使用 EasyExcel 读取Excel(两种方式)

    引入 jar 包 <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel&l ...

  3. java web项目中后台控制层对参数进行自定义验证 类 Pattern

    Pattern pattern = Pattern.compile("/^([1-9]\d+元*|[0]{0,1})$/");//将给定的正则表达式编译到模式中 if(!" ...

  4. spring+mybatis所需各种服务的搭建

    1.mysql5.6 2.jdk1.7 3.zookeeper 4.dubbo-admin 5.activtymq 6.maven 7.nexus 8.mybatis脚本文件生成工具使用

  5. tomcat——context.xml

    本机tomcat位置:D:\tomcat7\apache-tomcat-7.0.61 context.xml 位置:D:\tomcat7\apache-tomcat-7.0.61\conf 每个Web ...

  6. Python 10.1.1

  7. Codeforces Round #598 (Div. 3) A,B,C,D{E,F待补}

    A. Payment Without Change   #include<bits/stdc++.h> using namespace std; #define int long long ...

  8. 五十八.Kibana使用 、 Logstash配置扩展插件

    1.导入数据 批量导入数据并查看    1.1 导入数据   1) 使用POST方式批量导入数据,数据格式为json,url 编码使用data-binary导入含有index配置的json文件 ]# ...

  9. 路由器配置——DHCP+DHCP中继服务配置

    一.实验目的:掌握DHCP服务基本配置及DHCP中继服务配置,实现全网互通 二.拓扑图: 三.具体步骤配置: (1)R1路由器配置: Router>enable  --进入特权模式 Router ...

  10. 2018-2019 ACM-ICPC, Asia Jiaozuo Regional Contest

    目录 Contest Info Solutions A. Xu Xiake in Henan Province D. Keiichi Tsuchiya the Drift King E. Resist ...