|
@@ -0,0 +1,245 @@
|
|
|
|
+package com.platform.opc.util;
|
|
|
|
+
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.jinterop.dcom.common.JIErrorCodes;
|
|
|
|
+import org.jinterop.dcom.common.JIException;
|
|
|
|
+import org.jinterop.dcom.core.JIVariant;
|
|
|
|
+import org.openscada.opc.dcom.da.OPCSERVERSTATE;
|
|
|
|
+import org.openscada.opc.lib.common.AlreadyConnectedException;
|
|
|
|
+import org.openscada.opc.lib.common.ConnectionInformation;
|
|
|
|
+import org.openscada.opc.lib.da.*;
|
|
|
|
+
|
|
|
|
+import java.net.UnknownHostException;
|
|
|
|
+import java.util.*;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @Auther: 熊
|
|
|
|
+ * @DATE: 2022/6/8 14:58
|
|
|
|
+ * @Description: opc da客户端
|
|
|
|
+ */
|
|
|
|
+@Slf4j
|
|
|
|
+public class OpcDAClient {
|
|
|
|
+ public static String host = "192.168.108.108";
|
|
|
|
+ public static String user = "Administrator";
|
|
|
|
+ public static String password = "Hollysys";
|
|
|
|
+ public static String clsId = "001AAAA6-FB54-4627-84B2-8777379E5868";
|
|
|
|
+ public static String tag_prefix = "Channel1.Device1.";
|
|
|
|
+ private Server server;
|
|
|
|
+ private String bakHost;
|
|
|
|
+ private Group group = null;
|
|
|
|
+ private Map<String, Item> groupItems = null;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 初始化连接信息
|
|
|
|
+ *
|
|
|
|
+ * @param host
|
|
|
|
+ * @param user
|
|
|
|
+ * @param password
|
|
|
|
+ * @param clsId
|
|
|
|
+ */
|
|
|
|
+ public OpcDAClient(String host, String user, String password, String clsId) {
|
|
|
|
+ this.host = host;
|
|
|
|
+ this.user = user;
|
|
|
|
+ this.password = password;
|
|
|
|
+ this.clsId = clsId;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 设置备用服务地址
|
|
|
|
+ *
|
|
|
|
+ * @param bakHost
|
|
|
|
+ */
|
|
|
|
+ public void setBakHost(String bakHost) {
|
|
|
|
+ this.bakHost = bakHost;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 创建连接
|
|
|
|
+ */
|
|
|
|
+ public void connect() {
|
|
|
|
+ if (server != null && server.getServerState() != null && server.getServerState().getServerState().equals(OPCSERVERSTATE.OPC_STATUS_RUNNING)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ final ConnectionInformation ci = new ConnectionInformation();
|
|
|
|
+ ci.setHost(host);
|
|
|
|
+ ci.setDomain(""); // 域 为空
|
|
|
|
+ ci.setUser(user);
|
|
|
|
+ ci.setPassword(password);
|
|
|
|
+ ci.setClsid(clsId);
|
|
|
|
+ server = new Server(ci, null);
|
|
|
|
+ try {
|
|
|
|
+ server.connect();
|
|
|
|
+ } catch (UnknownHostException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ log.error("opc 地址错误:", e);
|
|
|
|
+ } catch (JIException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ log.error("opc 连接失败:", e);
|
|
|
|
+ log.info("开始连接备用服务...");
|
|
|
|
+ try {
|
|
|
|
+ ci.setHost(bakHost);
|
|
|
|
+ server = new Server(ci, null);
|
|
|
|
+ server.connect();
|
|
|
|
+ } catch (Exception e2) {
|
|
|
|
+ log.error("备用服务连接失败:", e2);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } catch (AlreadyConnectedException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ log.error("opc 已连接:", e);
|
|
|
|
+ }
|
|
|
|
+ log.info("OPC Server connect success...");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 根据地址获取数据
|
|
|
|
+ *
|
|
|
|
+ * @param itemId
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public Object getItemValue(String itemId) {
|
|
|
|
+ try {
|
|
|
|
+ Group group = server.addGroup();
|
|
|
|
+ Item item = group.addItem(itemId);
|
|
|
|
+ return getVal(item.read(true).getValue());
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ log.error("获取数据异常 itemId:{}", itemId, e);
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取多组数据
|
|
|
|
+ *
|
|
|
|
+ * @param itemIdList
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public Map<String, Object> getItemValues(List<String> itemIdList) {
|
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
|
+ try {
|
|
|
|
+ if (groupItems == null || group == null) {
|
|
|
|
+ log.info("开始建组...");
|
|
|
|
+ group = server.addGroup();
|
|
|
|
+ String[] items = itemIdList.toArray(new String[]{});
|
|
|
|
+ groupItems = group.addItems(items);
|
|
|
|
+ log.info("组建完成,开始查询数据...");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Set itemSet = new HashSet(groupItems.values());
|
|
|
|
+ Item[] itemArr = new Item[itemSet.size()];
|
|
|
|
+ itemSet.toArray(itemArr);
|
|
|
|
+ Map<Item, ItemState> resultMap = group.read(true, itemArr);
|
|
|
|
+ log.info("数据获取完成:{}条", resultMap.size());
|
|
|
|
+ for (Item item : resultMap.keySet()) {
|
|
|
|
+ ItemState itemMap = resultMap.get(item);
|
|
|
|
+ result.put(item.getId(), getVal(itemMap.getValue()));
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ log.error("批量获取数据异常:", e);
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取value
|
|
|
|
+ *
|
|
|
|
+ * @param var
|
|
|
|
+ * @return
|
|
|
|
+ * @throws JIException
|
|
|
|
+ */
|
|
|
|
+ private static Object getVal(JIVariant var) throws JIException {
|
|
|
|
+ Object value;
|
|
|
|
+ int type = var.getType();
|
|
|
|
+ switch (type) {
|
|
|
|
+ case JIVariant.VT_I2:
|
|
|
|
+ value = var.getObjectAsShort();
|
|
|
|
+ break;
|
|
|
|
+ case JIVariant.VT_I4:
|
|
|
|
+ value = var.getObjectAsInt();
|
|
|
|
+ break;
|
|
|
|
+ case JIVariant.VT_I8:
|
|
|
|
+ value = var.getObjectAsLong();
|
|
|
|
+ break;
|
|
|
|
+ case JIVariant.VT_R4:
|
|
|
|
+ value = var.getObjectAsFloat();
|
|
|
|
+ break;
|
|
|
|
+ case JIVariant.VT_R8:
|
|
|
|
+ value = var.getObjectAsDouble();
|
|
|
|
+ break;
|
|
|
|
+ case JIVariant.VT_BSTR:
|
|
|
|
+ value = var.getObjectAsString2();
|
|
|
|
+ break;
|
|
|
|
+ case JIVariant.VT_BOOL:
|
|
|
|
+ value = var.getObjectAsBoolean();
|
|
|
|
+ break;
|
|
|
|
+ case JIVariant.VT_UI2:
|
|
|
|
+ case JIVariant.VT_UI4:
|
|
|
|
+ value = var.getObjectAsUnsigned().getValue();
|
|
|
|
+ break;
|
|
|
|
+ case JIVariant.VT_EMPTY:
|
|
|
|
+ throw new JIException(JIErrorCodes.JI_VARIANT_IS_NULL, "Variant is Empty.");
|
|
|
|
+ case JIVariant.VT_NULL:
|
|
|
|
+ throw new JIException(JIErrorCodes.JI_VARIANT_IS_NULL, "Variant is null.");
|
|
|
|
+ default:
|
|
|
|
+ throw new JIException(JIErrorCodes.JI_VARIANT_IS_NULL, "Unknown Type.");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return value;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将一组数据平均分成n组
|
|
|
|
+ *
|
|
|
|
+ * @param source 要分组的数据源
|
|
|
|
+ * @param n 平均分成n组
|
|
|
|
+ * @param <T>
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private static <T> List<List<T>> averageAssign(List<T> source, int n) {
|
|
|
|
+ List<List<T>> result = new ArrayList<List<T>>();
|
|
|
|
+ int remainder = source.size() % n; //(先计算出余数)
|
|
|
|
+ int number = source.size() / n; //然后是商
|
|
|
|
+ int offset = 0;//偏移量
|
|
|
|
+ for (int i = 0; i < n; i++) {
|
|
|
|
+ List<T> value = null;
|
|
|
|
+ if (remainder > 0) {
|
|
|
|
+ value = source.subList(i * number + offset, (i + 1) * number + offset + 1);
|
|
|
|
+ remainder--;
|
|
|
|
+ offset++;
|
|
|
|
+ } else {
|
|
|
|
+ value = source.subList(i * number + offset, (i + 1) * number + offset);
|
|
|
|
+ }
|
|
|
|
+ result.add(value);
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 关闭连接
|
|
|
|
+ */
|
|
|
|
+ public void disconnect() {
|
|
|
|
+ server.disconnect();
|
|
|
|
+ if (null == server.getServerState()) {
|
|
|
|
+ log.info("OPC Server Disconnect...");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static String[] tagList = new String[]{"AT_11001_AV", "AT_11002_AV", "AT_11003_AV", "AT_11004_AV", "AT_11005_AV", "AT_11006_AV", "AT_11007_AV", "AT_11008_AV", "AT_7101A_AV", "AT_7101B_AV", "AT_7101C_AV"};
|
|
|
|
+
|
|
|
|
+ public static void run() {
|
|
|
|
+ OpcDAClient opcDAClient = new OpcDAClient(OpcDAClient.host, OpcDAClient.user, OpcDAClient.password, OpcDAClient.clsId);
|
|
|
|
+ opcDAClient.connect();
|
|
|
|
+ List<String> itemList = new ArrayList<>();
|
|
|
|
+ for (String tag : tagList) {
|
|
|
|
+ itemList.add(tag_prefix + tag);
|
|
|
|
+ }
|
|
|
|
+ Map<String, Object> stringObjectMap = opcDAClient.getItemValues(itemList);
|
|
|
|
+ for (String key : stringObjectMap.keySet()) {
|
|
|
|
+ Object itemMap = stringObjectMap.get(key);
|
|
|
|
+ System.out.println(key + " : " + itemMap);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|