cl
2024-02-28 26c51e363815011b09411ae74eb8c5f9d2ea8404
提交 | 用户 | 时间
e57a89 1 package com.jcdm.main.da.opcuaconfig.client;
2
3 import com.google.common.collect.ImmutableList;
4 import com.jcdm.main.da.opcuaconfig.domain.DaOpcuaConfig;
5 import com.jcdm.main.da.opcuaconfig.domain.NodeEntity;
6 import com.jcdm.main.da.opcuaconfig.service.IDaOpcuaConfigService;
7 import lombok.extern.slf4j.Slf4j;
8 import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
9 import org.eclipse.milo.opcua.sdk.client.api.nodes.VariableNode;
10 import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
11 import org.eclipse.milo.opcua.stack.core.AttributeId;
12 import org.eclipse.milo.opcua.stack.core.BuiltinDataType;
13 import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
14 import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
15 import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
16 import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
17 import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned;
18 import org.eclipse.milo.opcua.stack.core.types.enumerated.MonitoringMode;
19 import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
20 import org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemCreateRequest;
21 import org.eclipse.milo.opcua.stack.core.types.structured.MonitoringParameters;
22 import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId;
23 import org.springframework.beans.factory.annotation.Autowired;
24 import org.springframework.stereotype.Service;
25 import org.springframework.util.CollectionUtils;
26
27 import java.lang.reflect.InvocationTargetException;
28 import java.lang.reflect.Method;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.Set;
32 import java.util.concurrent.ExecutionException;
33
34 /**
35  * @ClassName: ClientHandler
36  * @Description: 客户端处理
37  * @author Jellyleo
38  * @date 2019年12月12日
39  */
40 @Slf4j
41 @Service
42 public class ClientHandler {
43
44     // 客户端实例
45     public static OpcUaClient client = null;
46
47     public List<DaOpcuaConfig> b = null;
48
49     @Autowired
50     private ClientRunner clientRunner;
51
52     @Autowired
53     private IDaOpcuaConfigService daOpcuaConfigService;
54
55
56     /**
57      * 
58      * @MethodName: connect
59      * @Description: connect
60      * @throws Exception
61      * @CreateTime 2019年12月18日 上午10:41:09
62      */
63     public String connect() throws Exception {
64
65         if (client != null) {
66             return "客户端已创建";
67         }
68
69         client = clientRunner.run();
70
71         if (client == null) {
72             return "客户端配置实例化失败";
73         }
74
75         // 创建连接
76         client.connect().get();
77         return "创建连接成功";
78     }
79
80     /**
81      * @MethodName: disconnect
82      * @Description: 断开连接
83      * @return
84      * @throws Exception
85      * @CreateTime 2019年12月18日 上午10:45:21
86      */
87     public String disconnect() throws Exception {
88
89         if (client == null) {
90             return "连接已断开";
91         }
92
93         // 断开连接
94         clientRunner.getFuture().complete(client);
95         client = null;
96         return "断开连接成功";
97     }
98
99     /**
100      * @MethodName: subscribe
101      * @Description: 订阅节点变量
102      * @throws Exception
103      * @CreateTime 2019年12月18日 上午10:38:11
104      */
105     public String subscribe(List<NodeEntity> nodes) throws Exception {
106
107         if (client == null) {
108             return "找不到客户端,操作失败";
109         }
110
111         // 查询订阅对象,没有则创建
112         UaSubscription subscription = null;
113         ImmutableList<UaSubscription> subscriptionList = client.getSubscriptionManager().getSubscriptions();
114         if (CollectionUtils.isEmpty(subscriptionList)) {
115             subscription = client.getSubscriptionManager().createSubscription(1000.0).get();
116         } else {
117             subscription = subscriptionList.get(0);
118         }
119
120         // 监控项请求列表
121         List<MonitoredItemCreateRequest> requests = new ArrayList<>();
122
123         if (!CollectionUtils.isEmpty(nodes)) {
124             for (NodeEntity node : nodes) {
125                 // 创建监控的参数
126                 MonitoringParameters parameters = new MonitoringParameters(subscription.nextClientHandle(), 1000.0, // sampling
127                         // interval
128                         null, // filter, null means use default
129                         Unsigned.uint(10), // queue size
130                         true // discard oldest
131                 );
132                 // 创建订阅的变量, 创建监控项请 求
133                 MonitoredItemCreateRequest request = new MonitoredItemCreateRequest(
134                         new ReadValueId(new NodeId(node.getIndex(), node.getIdentifier()), AttributeId.Value.uid(),
135                                 null, null),
136                         MonitoringMode.Reporting, parameters);
137                 requests.add(request);
138             }
139         }
140
141         // 创建监控项,并且注册变量值改变时候的回调函数
142         subscription.createMonitoredItems(TimestampsToReturn.Both, requests, (item, id) -> {
143             item.setValueConsumer((i, v) -> {
144                 handle(i.getReadValueId().getNodeId(), v.getValue());
145             });
146         }).get();
147
148         return "订阅成功";
149     }
150
151     /**
152      * * @MethodName: write
153      * @Description: 回调函数
154      * @CreateTime 2023年10月13日
155      */
156     public void handle(NodeId id, Variant value){
157         if (b == null || 0 > b.size()) {
158             DaOpcuaConfig opcuaConfParam=new DaOpcuaConfig();
159             opcuaConfParam.setSubscribe("Y");
160             b=daOpcuaConfigService.selectDaOpcuaConfigList(opcuaConfParam);
161         }
162         //使用Stream API在List<T>中查找元素
163         DaOpcuaConfig daOpcuaConfig = b.stream()
164                 .filter(customer ->id.getIdentifier().toString().equals(customer.getNode()))
165                 .findAny()
166                 .orElse(null);
167         try {
168             Class<?> clazz = Class.forName("com.jcdm.main.da.opcuaconfig.cert.MethodName");
169             Method method = clazz.getMethod(daOpcuaConfig.getrFunction(), new Class[] { String.class, String.class });
170             method.invoke(clazz.newInstance(),new Object[] {
171                     new String(id.getIdentifier().toString()), new String(value.getValue().toString()) });
172         } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException |
173                  InvocationTargetException e) {
174             e.printStackTrace();
175         }
176     }
177
178
179     /**
180      * @MethodName: write
181      * @Description: 变节点量写入
182      * @param node
183      * @throws Exception
184      * @CreateTime 2019年12月18日 上午9:51:40
185      */
186     public static Boolean write(NodeEntity node) throws Exception {
187
188         if (client == null) {
189             log.info("找不到客户端,操作失败");
190             return false;
191         }
192
193         NodeId nodeId = new NodeId(node.getIndex(), node.getIdentifier());
194         Variant value = null;
195         switch (node.getType()) {
196         case "int":
197             value = new Variant(Integer.parseInt(node.getValue().toString()));
198             break;
199         case "boolean":
200             value = new Variant(Boolean.parseBoolean(node.getValue().toString()));
201             break;
202         case "short":
203             value = new Variant(Short.parseShort(node.getValue().toString()));
204             break;
205         case "long":
206             value = new Variant(Long.parseLong(node.getValue().toString()));
207             break;
208         case "string":
209             value = new Variant(node.getValue().toString());
210             break;
211         case "char":
212             value = new Variant(node.getValue().toString().charAt(0));
213             break;
214         }
215         DataValue dataValue = new DataValue(value, null, null);
216
217         StatusCode statusCode = client.writeValue(nodeId, dataValue).get();
218
219         return statusCode.isGood();
220     }
221
222     /**
223      * 方法描述: 读取多个点位的值
224      *
225      * @param nodeIdList 点位集合
226      * @return {@link List<DataValue>}
227      * @throws
228      */
229     public static List<DataValue> readValues(List<NodeId> nodeIdList){
230         try {
231             List<DataValue> dataValues=client.readValues(0.0, TimestampsToReturn.Both,nodeIdList).get();
232             return dataValues;
233         } catch (InterruptedException | ExecutionException e) {
234             e.printStackTrace();
235         }
236         return null;
237     }
238
239     /**
240      * @MethodName: read
241      * @Description: 读取
242      * @param node
243      * @return
244      * @throws Exception
245      * @CreateTime 2019年12月19日 下午2:40:34
246      */
247     public String read(NodeEntity node) throws Exception {
248
249         if (client == null) {
250             return "找不到客户端,操作失败";
251         }
252
253         NodeId nodeId = new NodeId(node.getIndex(), node.getIdentifier());
254         VariableNode vnode = client.getAddressSpace().createVariableNode(nodeId);
255         DataValue value = vnode.readValue().get();
256         log.info("Value={}", value);
257
258         Variant variant = value.getValue();
259         log.info("Variant={}", variant.getValue());
260
261         log.info("BackingClass={}", BuiltinDataType.getBackingClass(variant.getDataType().get()));
262
263         return variant.getValue().toString();
264     }
265
266
267     /**
268      * 方法描述:  写入多个节点的值
269      *
270      * @param keys  节点集合
271      * @param values  值集合
272      * @param client  客户端
273      * @return {@link Object}
274      * @throws
275      */
276     public static Object writeValues(Set<String> keys, List<Object> values, OpcUaClient client){
277         List<NodeId> nodeIs=new ArrayList<>(keys.size());
278         keys.forEach(e->{
279             NodeId nodeId = new NodeId(2, e);
280             nodeIs.add(nodeId);
281         });
282         List<DataValue> dataValues=new ArrayList<>(values.size());
283         values.forEach(e->{
284             Variant value=new Variant(Double.parseDouble(e.toString()));
285             DataValue dataValue=new DataValue(value);
286             dataValues.add(dataValue);
287         });
288         try {
289             client.writeValues(nodeIs,dataValues).get();
290         } catch (InterruptedException | ExecutionException e) {
291             e.printStackTrace();
292         }
293         return null;
294     }
295 }