hfxc226 2 年 前
コミット
4bc18b7a9e

+ 245 - 0
platform-opc/src/main/java/com/platform/opc/util/OpcDAClient.java

@@ -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);
+        }
+    }
+}
+