yantian yue
2023-10-25 affbb7b8e8189127121d15dcc94b53639656d332
提交 | 用户 | 时间
487b2f 1 package cn.stylefeng.guns.opcua.client;
YY 2
f4a343 3 import cn.stylefeng.guns.opcua.controller.OpcuaConfController;
YY 4 import cn.stylefeng.guns.opcua.model.params.OpcuaConfParam;
5 import cn.stylefeng.guns.opcua.model.result.OpcuaConfResult;
487b2f 6 import com.google.common.collect.ImmutableList;
YY 7 import cn.stylefeng.guns.opcua.entity.NodeEntity;
8 import lombok.extern.slf4j.Slf4j;
9 import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
10 import org.eclipse.milo.opcua.sdk.client.api.nodes.VariableNode;
11 import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
12 import org.eclipse.milo.opcua.stack.core.AttributeId;
13 import org.eclipse.milo.opcua.stack.core.BuiltinDataType;
14 import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
15 import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
16 import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
17 import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
18 import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned;
19 import org.eclipse.milo.opcua.stack.core.types.enumerated.MonitoringMode;
20 import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
21 import org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemCreateRequest;
22 import org.eclipse.milo.opcua.stack.core.types.structured.MonitoringParameters;
23 import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId;
24 import org.springframework.beans.factory.annotation.Autowired;
25 import org.springframework.stereotype.Service;
26 import org.springframework.util.CollectionUtils;
0d7d6a 27 import cn.stylefeng.guns.base.enums.MicroTimestamp;
487b2f 28
YY 29 import java.lang.reflect.InvocationTargetException;
30 import java.lang.reflect.Method;
31 import java.util.ArrayList;
32 import java.util.List;
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     // 客户端实例
47eb81 45     public static OpcUaClient client = null;
487b2f 46
a7c91f 47     public List<OpcuaConfResult> b = null;
YY 48
487b2f 49     @Autowired
YY 50     private ClientRunner clientRunner;
f4a343 51
YY 52     @Autowired
53     private OpcuaConfController opcuaConfController;
69fbaa 54
487b2f 55
YY 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) -> {
a7c91f 144                 handle2(i.getReadValueId().getNodeId(), v.getValue());
487b2f 145             });
YY 146         }).get();
147
148         return "订阅成功";
149     }
150
151     /**
152      * * @MethodName: write
153      * @Description: 回调函数
154      * @CreateTime 2023年10月13日
155      */
156
a7c91f 157     /*public void handle(NodeId id, Variant value){
69fbaa 158         long startTime = System.currentTimeMillis();
YY 159
f4a343 160         OpcuaConfParam opcuaConfParam=new OpcuaConfParam();
YY 161         opcuaConfParam.setNode(id.getIdentifier().toString());
69fbaa 162         List<OpcuaConfResult> a=opcuaConfController.mylist(opcuaConfParam);
a7c91f 163         log.info("数据库访问代码执行时间:" + (System.currentTimeMillis() - startTime) + "毫秒");
487b2f 164         String str1 = id.getIdentifier().toString()+":"+value.getValue().toString();
YY 165         try {
f4a343 166             Class<?> clazz = Class.forName(a.get(0).getRModule());
YY 167             Method method = clazz.getMethod(a.get(0).getRFunction(), String.class);
487b2f 168
YY 169             method.invoke(clazz.newInstance(), str1);
170         } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException |
171                  InvocationTargetException e) {
172             e.printStackTrace();
173         }
69fbaa 174         log.info("代码执行时间:" + (System.currentTimeMillis() - startTime) + "毫秒");
a7c91f 175     }*/
YY 176     public void handle2(NodeId id, Variant value){
0d7d6a 177
YY 178         MicroTimestamp t = null;
179         String sTime=t.INSTANCE.get();
180
181
a7c91f 182         if (b == null || 0 > b.size()) {
YY 183             OpcuaConfParam opcuaConfParam=new OpcuaConfParam();
184             opcuaConfParam.setSubscribe(1);
185             b=opcuaConfController.mylist(opcuaConfParam);
186         }
6b317a 187         //使用Stream API在List<T>中查找元素
a7c91f 188         OpcuaConfResult opcuaConfResult = b.stream()
YY 189                 .filter(customer ->id.getIdentifier().toString().equals(customer.getNode()))
190                 .findAny()
191                 .orElse(null);
192         try {
193             Class<?> clazz = Class.forName(opcuaConfResult.getRModule());
affbb7 194             Method method = clazz.getMethod(opcuaConfResult.getRFunction(), new Class[] { String.class,
YY 195                     String.class });
196             method.invoke(clazz.newInstance(),new Object[] {
197                     new String(id.getIdentifier().toString()), new String(value.getValue().toString()) });
a7c91f 198         } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException |
YY 199                  InvocationTargetException e) {
200             e.printStackTrace();
201         }
0d7d6a 202         log.info("代码执行开始时间为:"+ sTime +",结束时间为:"+t.INSTANCE.get()+".");
487b2f 203     }
YY 204
a7c91f 205
487b2f 206     /**
YY 207      * @MethodName: write
208      * @Description: 变节点量写入
209      * @param node
210      * @throws Exception
211      * @CreateTime 2019年12月18日 上午9:51:40
212      */
213     public String write(NodeEntity node) throws Exception {
214
215         if (client == null) {
216             return "找不到客户端,操作失败";
217         }
218
219         NodeId nodeId = new NodeId(node.getIndex(), node.getIdentifier());
220         Variant value = null;
221         switch (node.getType()) {
222         case "int":
223             value = new Variant(Integer.parseInt(node.getValue().toString()));
224             break;
225         case "boolean":
226             value = new Variant(Boolean.parseBoolean(node.getValue().toString()));
227             break;
47eb81 228         case "long":
YY 229             value = new Variant(Long.parseLong(node.getValue().toString()));
230             break;
487b2f 231         }
YY 232         DataValue dataValue = new DataValue(value, null, null);
233
234         StatusCode statusCode = client.writeValue(nodeId, dataValue).get();
235
236         return "节点【" + node.getIdentifier() + "】写入状态:" + statusCode.isGood();
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 "节点【" + node.getIdentifier() + "】:" + variant.getValue();
264     }
265 }