|
@@ -1,15 +1,12 @@
|
|
package com.example.opc_ua.util;
|
|
package com.example.opc_ua.util;
|
|
|
|
|
|
-import com.alibaba.fastjson.JSON;
|
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
-import com.example.opc_common.entity.DataModel;
|
|
|
|
import com.example.opc_common.entity.DataSource;
|
|
import com.example.opc_common.entity.DataSource;
|
|
import com.example.opc_common.entity.Item;
|
|
import com.example.opc_common.entity.Item;
|
|
import com.example.opc_common.enums.ResultEnum;
|
|
import com.example.opc_common.enums.ResultEnum;
|
|
import com.example.opc_common.exception.CustomException;
|
|
import com.example.opc_common.exception.CustomException;
|
|
import com.example.opc_common.util.Blank;
|
|
import com.example.opc_common.util.Blank;
|
|
import com.example.opc_common.util.ConstantStr;
|
|
import com.example.opc_common.util.ConstantStr;
|
|
-import com.example.opc_common.util.MathUtil;
|
|
|
|
import com.example.opc_common.util.Result;
|
|
import com.example.opc_common.util.Result;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
|
|
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
|
|
@@ -21,30 +18,27 @@ import org.eclipse.milo.opcua.stack.core.BuiltinDataType;
|
|
import org.eclipse.milo.opcua.stack.core.Identifiers;
|
|
import org.eclipse.milo.opcua.stack.core.Identifiers;
|
|
import org.eclipse.milo.opcua.stack.core.UaException;
|
|
import org.eclipse.milo.opcua.stack.core.UaException;
|
|
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
|
|
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
|
|
-import org.eclipse.milo.opcua.stack.core.types.builtin.*;
|
|
|
|
|
|
+import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
|
|
|
|
+import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
|
|
|
|
+import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
|
|
|
|
+import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName;
|
|
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
|
|
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
|
|
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort;
|
|
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort;
|
|
import org.eclipse.milo.opcua.stack.core.types.enumerated.MonitoringMode;
|
|
import org.eclipse.milo.opcua.stack.core.types.enumerated.MonitoringMode;
|
|
import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass;
|
|
import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass;
|
|
import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
|
|
import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
|
|
import org.eclipse.milo.opcua.stack.core.types.structured.*;
|
|
import org.eclipse.milo.opcua.stack.core.types.structured.*;
|
|
-import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
|
|
|
-import java.math.BigDecimal;
|
|
|
|
-import java.nio.file.Files;
|
|
|
|
-import java.nio.file.Path;
|
|
|
|
-import java.nio.file.Paths;
|
|
|
|
-import java.util.*;
|
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.HashMap;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
import java.util.concurrent.ExecutionException;
|
|
import java.util.concurrent.ExecutionException;
|
|
import java.util.function.Predicate;
|
|
import java.util.function.Predicate;
|
|
-import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
@Slf4j
|
|
@Slf4j
|
|
public class OpcUaUtil {
|
|
public class OpcUaUtil {
|
|
|
|
|
|
- @Value("${certPath}")
|
|
|
|
- private static String certPath;
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* 创建OPC UA客户端
|
|
* 创建OPC UA客户端
|
|
*
|
|
*
|
|
@@ -52,12 +46,12 @@ public class OpcUaUtil {
|
|
*/
|
|
*/
|
|
public static OpcUaClient createClient(DataSource dataSource) throws Exception {
|
|
public static OpcUaClient createClient(DataSource dataSource) throws Exception {
|
|
String endPointUrl = "opc.tcp://" + dataSource.getIpAddress() + ":" + dataSource.getIpPort();
|
|
String endPointUrl = "opc.tcp://" + dataSource.getIpAddress() + ":" + dataSource.getIpPort();
|
|
- Path securityTempDir = Paths.get(certPath, "security");
|
|
|
|
-
|
|
|
|
- Files.createDirectories(securityTempDir);
|
|
|
|
- if (!Files.exists(securityTempDir)) {
|
|
|
|
- throw new Exception("无法创建安全目录: " + securityTempDir);
|
|
|
|
- }
|
|
|
|
|
|
+// Path securityTempDir = Paths.get(certPath, "security");
|
|
|
|
+//
|
|
|
|
+// Files.createDirectories(securityTempDir);
|
|
|
|
+// if (!Files.exists(securityTempDir)) {
|
|
|
|
+// throw new Exception("无法创建安全目录: " + securityTempDir);
|
|
|
|
+// }
|
|
return OpcUaClient.create(endPointUrl,
|
|
return OpcUaClient.create(endPointUrl,
|
|
endpoints ->
|
|
endpoints ->
|
|
endpoints.stream()
|
|
endpoints.stream()
|
|
@@ -106,24 +100,6 @@ public class OpcUaUtil {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- public static Result opcUaGetTree(DataSource dataSource) {
|
|
|
|
- OpcUaClient opcUaClient = null;
|
|
|
|
- try {
|
|
|
|
- opcUaClient = createClient(dataSource);
|
|
|
|
- if (Blank.isEmpty(opcUaClient)) {
|
|
|
|
- return Result.no(ResultEnum.REQUEST_TIME_OUT.getRespCode(), "客户端创建失败");
|
|
|
|
- }
|
|
|
|
- opcUaClient.connect().get();
|
|
|
|
- return Result.ok(generOpcUaTree(opcUaClient, null));
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- throw new CustomException(ResultEnum.REQUEST_TIME_OUT.getRespCode(), OpcUaUtil.genException(e.getMessage()));
|
|
|
|
- } finally {
|
|
|
|
- if (Blank.isNotEmpty(opcUaClient)) {
|
|
|
|
- opcUaClient.disconnect();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
public static void subscribe(OpcUaClient client, List<Item> itemList) throws ExecutionException, InterruptedException {
|
|
public static void subscribe(OpcUaClient client, List<Item> itemList) throws ExecutionException, InterruptedException {
|
|
//创建发布间隔1000ms的订阅对象
|
|
//创建发布间隔1000ms的订阅对象
|
|
client.getSubscriptionManager()
|
|
client.getSubscriptionManager()
|
|
@@ -156,67 +132,6 @@ public class OpcUaUtil {
|
|
Thread.sleep(Long.MAX_VALUE);
|
|
Thread.sleep(Long.MAX_VALUE);
|
|
}
|
|
}
|
|
|
|
|
|
- public static List<JSONObject> generOpcUaTree(OpcUaClient client, UaNode uaNode) throws UaException, ExecutionException, InterruptedException {
|
|
|
|
- if (Blank.isEmpty(client)) {
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
- List<JSONObject> jsonList = new ArrayList<>();
|
|
|
|
- List<? extends UaNode> nodes;
|
|
|
|
- if (uaNode == null) {
|
|
|
|
- nodes = client.getAddressSpace().browseNodes(Identifiers.RootFolder);//从根目录
|
|
|
|
-// nodes = client.getAddressSpace().browseNodes(Identifiers.ObjectsFolder);//从根目录
|
|
|
|
-// nodes = client.getAddressSpace().browseNodes(Identifiers.ViewsFolder);
|
|
|
|
- } else {
|
|
|
|
- nodes = client.getAddressSpace().browseNodes(uaNode);
|
|
|
|
- }
|
|
|
|
- for (UaNode nd : nodes) {
|
|
|
|
- if (Blank.isEmpty(nd)) {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- //排除系统行性节点,这些系统性节点名称一般都是以"_"开头
|
|
|
|
- if (Objects.requireNonNull(nd.getBrowseName().getName()).contains("_")) {
|
|
|
|
-// continue;
|
|
|
|
- }
|
|
|
|
- JSONObject jsonObject = new JSONObject();
|
|
|
|
- jsonObject.put("label", nd.getBrowseName().getName());
|
|
|
|
- jsonObject.put("nodeId", nd.getNodeId());
|
|
|
|
-// nd.getNodeId().getNamespaceIndex()
|
|
|
|
-// jsonObject.put("nodeIndex", nd.getNodeId().getNamespaceIndex());
|
|
|
|
- jsonObject.put("nodeIndex", nd.getNodeId().getNamespaceIndex().intValue());
|
|
|
|
- jsonObject.put("itemReadName", nd.getNodeId().getIdentifier());
|
|
|
|
- jsonObject.put("dataType", nd.getNodeId().getType());
|
|
|
|
-// jsonObject.put("value", client.readValue(0.0, TimestampsToReturn.Both, nd.getNodeId()).get());
|
|
|
|
-// jsonObject.put("dataType", client.readValue(0.0, TimestampsToReturn.Neither, nd.getNodeId()).get().getValue().getDataType().get().getType());
|
|
|
|
- jsonObject.put("description", nd.getDescription());
|
|
|
|
-// PropertyTypeNode nd1 = (PropertyTypeNode) nd;
|
|
|
|
-// nd1.getMinimumSamplingInterval();
|
|
|
|
- DataValue dataValue = client.readValue(0.0, TimestampsToReturn.Both, nd.getNodeId()).get();
|
|
|
|
- StatusCode statusCode = dataValue.getStatusCode();
|
|
|
|
-// if (Blank.isNotEmpty(statusCode)) {
|
|
|
|
-// if (statusCode.isGood()) {
|
|
|
|
-// jsonObject.put("value", dataValue.getValue().getValue());
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
- jsonObject.put("value", dataValue.getValue().getValue());
|
|
|
|
-
|
|
|
|
-// Variant value = dataValue.getValue();
|
|
|
|
-// Object value1 = value.getValue();
|
|
|
|
-// Optional<ExpandedNodeId> dataType = value.getDataType();
|
|
|
|
-// int value2 = dataType.get().getType().getValue();
|
|
|
|
-// UShort serverPicoseconds = dataValue.getServerPicoseconds();
|
|
|
|
-// DateTime serverTime = dataValue.getServerTime();
|
|
|
|
-// UShort sourcePicoseconds = dataValue.getSourcePicoseconds();
|
|
|
|
-// DateTime sourceTime = dataValue.getSourceTime();
|
|
|
|
-// StatusCode statusCode = dataValue.getStatusCode();
|
|
|
|
-// jsonObject.put("value",client.readValue(0.0, TimestampsToReturn.Neither, nd.getNodeId()).get());
|
|
|
|
-// jsonObject.put("nodeId",nd.);
|
|
|
|
-// jsonObject.put("value",client.readValue(0.0, TimestampsToReturn.Neither, nd.getNodeId()).get());
|
|
|
|
- jsonObject.put("children", generOpcUaTree(client, nd));
|
|
|
|
- jsonList.add(jsonObject);
|
|
|
|
- }
|
|
|
|
- return jsonList;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
public static List<NodeId> genNodeId(List<Item> itemList) {
|
|
public static List<NodeId> genNodeId(List<Item> itemList) {
|
|
if (Blank.isEmpty(itemList)) {
|
|
if (Blank.isEmpty(itemList)) {
|
|
return null;
|
|
return null;
|
|
@@ -242,73 +157,6 @@ public class OpcUaUtil {
|
|
return historyReadValueIdList;
|
|
return historyReadValueIdList;
|
|
}
|
|
}
|
|
|
|
|
|
- public static List<JSONObject> opcUaReadNodeIdList(DataSource dataSource, List<Item> itemList, Map<String, DataModel> dmMap) {
|
|
|
|
- OpcUaClient client = null;
|
|
|
|
- try {
|
|
|
|
- client = OpcUaUtil.createClient(dataSource);
|
|
|
|
- client.connect().get();
|
|
|
|
- Map<String, Object> map = new HashMap<>();
|
|
|
|
- Map<String, String> mapName = new HashMap<>();
|
|
|
|
- Map<String, Integer> mapEventMode = new HashMap<>();
|
|
|
|
- for (Item item : itemList) {
|
|
|
|
- map.put(item.getItemReadName(), item.getDescribe());
|
|
|
|
- mapName.put(item.getItemReadName(), item.getItemName());
|
|
|
|
-// mapEventMode.put(item.getItemReadName(), item.getEventMode());
|
|
|
|
- }
|
|
|
|
- List<NodeId> nodeIdList = OpcUaUtil.genNodeId(itemList);
|
|
|
|
- List<JSONObject> jsonObjectList = new ArrayList<>();
|
|
|
|
- Date date = new Date();
|
|
|
|
- for (NodeId n : nodeIdList) {
|
|
|
|
- String itemName = n.getIdentifier().toString();
|
|
|
|
- DataModel dm = dmMap.get(itemName);
|
|
|
|
- JSONObject jsonObject = new JSONObject();
|
|
|
|
- DataValue dataValue = client.readValue(0.0, TimestampsToReturn.Both, n).get();
|
|
|
|
- String name = mapName.get(itemName);
|
|
|
|
- jsonObject.put("dataSourceName", dataSource.getDataSourceName());
|
|
|
|
- jsonObject.put("itemName", name);
|
|
|
|
- jsonObject.put("itemReadName", name);
|
|
|
|
- StatusCode statusCode = dataValue.getStatusCode();
|
|
|
|
- jsonObject.put("quality", statusCode.isGood() ? "good" : "bad");
|
|
|
|
- Variant value = dataValue.getValue();
|
|
|
|
- ExpandedNodeId expandedNodeId = value.getDataType().get();
|
|
|
|
- String javaType = OpcUaUtil.getValType(dataValue);
|
|
|
|
- jsonObject.put("dataType", javaType);
|
|
|
|
- jsonObject.put("eventMode", mapEventMode.get(itemName));
|
|
|
|
- jsonObject.put("dataOrgValue", value.getValue());
|
|
|
|
- if (Blank.isNotEmpty(dm) && dm.getModelType().equals(ConstantStr.VALUE_REPLACE)) {
|
|
|
|
- jsonObject.put("dataValue", DataModel.valueReplace(dm, value.toString()));
|
|
|
|
- } else {
|
|
|
|
- if (javaType.toLowerCase().equals("boolean")) {
|
|
|
|
- jsonObject.put("dataValue", value.getValue());
|
|
|
|
- } else {
|
|
|
|
- try {
|
|
|
|
- BigDecimal bigDecimal = JSON.parseObject(value.getValue().toString(), BigDecimal.class);
|
|
|
|
- jsonObject.put("dataValue", Blank.isNotEmpty(dm) ? MathUtil.quadricOperation(dm.getMathParameter(), dm.getOperationRule(), bigDecimal) : bigDecimal);
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- jsonObject.put("dataValue", value.getValue());
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- jsonObject.put("dataType", expandedNodeId.getType().toString());
|
|
|
|
- jsonObject.put("operationRule", Blank.isNotEmpty(dm) ? dm.getOperationRule() : "");
|
|
|
|
- jsonObject.put("describe", map.get(itemName));
|
|
|
|
- jsonObject.put("createTime", date);
|
|
|
|
- jsonObjectList.add(jsonObject);
|
|
|
|
- }
|
|
|
|
- jsonObjectList.stream()
|
|
|
|
- .sorted(Comparator.comparing((JSONObject jsonObject) -> jsonObject.getInteger("eventMode"), Comparator.nullsFirst(Integer::compareTo)).reversed()
|
|
|
|
- .thenComparing(jsonObject -> jsonObject.getString("itemName")
|
|
|
|
- )).collect(Collectors.toList());
|
|
|
|
- return jsonObjectList;
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- throw new CustomException(ResultEnum.REQUEST_TIME_OUT.getRespCode(), OpcUaUtil.genException(e.getMessage()));
|
|
|
|
- } finally {
|
|
|
|
- if (Blank.isNotEmpty(client)) {
|
|
|
|
- client.disconnect();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* 通过itemid获取相应的值
|
|
* 通过itemid获取相应的值
|
|
*
|
|
*
|