懒羊羊
2023-10-17 5d91e0a52879bf16511817b3cd20496f07717ab1
提交 | 用户 | 时间
487b2f 1 package cn.stylefeng.guns.opcua.client;
YY 2
3 import com.google.common.collect.ImmutableList;
4 import cn.stylefeng.guns.opcua.entity.NodeEntity;
5 import lombok.extern.slf4j.Slf4j;
6 import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
7 import org.eclipse.milo.opcua.sdk.client.api.nodes.VariableNode;
8 import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
9 import org.eclipse.milo.opcua.stack.core.AttributeId;
10 import org.eclipse.milo.opcua.stack.core.BuiltinDataType;
11 import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
12 import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
13 import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
14 import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
15 import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned;
16 import org.eclipse.milo.opcua.stack.core.types.enumerated.MonitoringMode;
17 import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
18 import org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemCreateRequest;
19 import org.eclipse.milo.opcua.stack.core.types.structured.MonitoringParameters;
20 import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId;
21 import org.springframework.beans.factory.annotation.Autowired;
22 import org.springframework.stereotype.Service;
23 import org.springframework.util.CollectionUtils;
24
25 import java.lang.reflect.InvocationTargetException;
26 import java.lang.reflect.Method;
27 import java.util.ArrayList;
28 import java.util.List;
29
30 /**
31  * @ClassName: ClientHandler
32  * @Description: 客户端处理
33  * @author Jellyleo
34  * @date 2019年12月12日
35  */
36 @Slf4j
37 @Service
38 public class ClientHandler {
39
40     // 客户端实例
41     private OpcUaClient client = null;
42
43     @Autowired
44     private ClientRunner clientRunner;
45
46     /**
47      * 
48      * @MethodName: connect
49      * @Description: connect
50      * @throws Exception
51      * @CreateTime 2019年12月18日 上午10:41:09
52      */
53     public String connect() throws Exception {
54
55         if (client != null) {
56             return "客户端已创建";
57         }
58
59         client = clientRunner.run();
60
61         if (client == null) {
62             return "客户端配置实例化失败";
63         }
64
65         // 创建连接
66         client.connect().get();
67         return "创建连接成功";
68     }
69
70     /**
71      * @MethodName: disconnect
72      * @Description: 断开连接
73      * @return
74      * @throws Exception
75      * @CreateTime 2019年12月18日 上午10:45:21
76      */
77     public String disconnect() throws Exception {
78
79         if (client == null) {
80             return "连接已断开";
81         }
82
83         // 断开连接
84         clientRunner.getFuture().complete(client);
85         client = null;
86         return "断开连接成功";
87     }
88
89     /**
90      * @MethodName: subscribe
91      * @Description: 订阅节点变量
92      * @throws Exception
93      * @CreateTime 2019年12月18日 上午10:38:11
94      */
95     public String subscribe(List<NodeEntity> nodes) throws Exception {
96
97         if (client == null) {
98             return "找不到客户端,操作失败";
99         }
100
101 //        List<Node> ns = client.getAddressSpace().browse(new NodeId(2, "模拟通道一.模拟设备一")).get();
102
103         // 查询订阅对象,没有则创建
104         UaSubscription subscription = null;
105         ImmutableList<UaSubscription> subscriptionList = client.getSubscriptionManager().getSubscriptions();
106         if (CollectionUtils.isEmpty(subscriptionList)) {
107             subscription = client.getSubscriptionManager().createSubscription(1000.0).get();
108         } else {
109             subscription = subscriptionList.get(0);
110         }
111
112         // 监控项请求列表
113         List<MonitoredItemCreateRequest> requests = new ArrayList<>();
114
115         if (!CollectionUtils.isEmpty(nodes)) {
116             for (NodeEntity node : nodes) {
117                 // 创建监控的参数
118                 MonitoringParameters parameters = new MonitoringParameters(subscription.nextClientHandle(), 1000.0, // sampling
119                         // interval
120                         null, // filter, null means use default
121                         Unsigned.uint(10), // queue size
122                         true // discard oldest
123                 );
124                 // 创建订阅的变量, 创建监控项请 求
125                 MonitoredItemCreateRequest request = new MonitoredItemCreateRequest(
126                         new ReadValueId(new NodeId(node.getIndex(), node.getIdentifier()), AttributeId.Value.uid(),
127                                 null, null),
128                         MonitoringMode.Reporting, parameters);
129                 requests.add(request);
130             }
131         }
132
133         // 创建监控项,并且注册变量值改变时候的回调函数
134         subscription.createMonitoredItems(TimestampsToReturn.Both, requests, (item, id) -> {
135             item.setValueConsumer((i, v) -> {
136                 handle(i.getReadValueId().getNodeId(), v.getValue());
137             });
138         }).get();
139
140         return "订阅成功";
141     }
142
143     /**
144      * * @MethodName: write
145      * @Description: 回调函数
146      * @CreateTime 2023年10月13日
147      */
148
149     public void handle(NodeId id, Variant value){
150         String className = "cn.stylefeng.guns.opcua.cert.MethodName";
151         String methodName = "a";
152         String str1 = id.getIdentifier().toString()+":"+value.getValue().toString();
153         try {
154             Class<?> clazz = Class.forName(className);
155             Method method = clazz.getMethod(methodName, String.class);
156
157             method.invoke(clazz.newInstance(), str1);
158         } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException |
159                  InvocationTargetException e) {
160             e.printStackTrace();
161         }
162         //if(id.getIdentifier().toString().equals("my.device.x1")){
163         //    log.info("item={}, value={},{}", id.getIdentifier().toString(), value,"返回一个SN号");
164         //}
165     }
166
167     /**
168      * @MethodName: write
169      * @Description: 变节点量写入
170      * @param node
171      * @throws Exception
172      * @CreateTime 2019年12月18日 上午9:51:40
173      */
174     public String write(NodeEntity node) throws Exception {
175
176         if (client == null) {
177             return "找不到客户端,操作失败";
178         }
179
180         NodeId nodeId = new NodeId(node.getIndex(), node.getIdentifier());
181         Variant value = null;
182         switch (node.getType()) {
183         case "int":
184             value = new Variant(Integer.parseInt(node.getValue().toString()));
185             break;
186         case "boolean":
187             value = new Variant(Boolean.parseBoolean(node.getValue().toString()));
188             break;
189         }
190         DataValue dataValue = new DataValue(value, null, null);
191
192         StatusCode statusCode = client.writeValue(nodeId, dataValue).get();
193
194         return "节点【" + node.getIdentifier() + "】写入状态:" + statusCode.isGood();
195     }
196
197     /**
198      * @MethodName: read
199      * @Description: 读取
200      * @param node
201      * @return
202      * @throws Exception
203      * @CreateTime 2019年12月19日 下午2:40:34
204      */
205     public String read(NodeEntity node) throws Exception {
206
207         if (client == null) {
208             return "找不到客户端,操作失败";
209         }
210
211         NodeId nodeId = new NodeId(node.getIndex(), node.getIdentifier());
212         VariableNode vnode = client.getAddressSpace().createVariableNode(nodeId);
213         DataValue value = vnode.readValue().get();
214         log.info("Value={}", value);
215
216         Variant variant = value.getValue();
217         log.info("Variant={}", variant.getValue());
218
219         log.info("BackingClass={}", BuiltinDataType.getBackingClass(variant.getDataType().get()));
220
221         return "节点【" + node.getIdentifier() + "】:" + variant.getValue();
222     }
223 }