package cn.stylefeng.guns.modular.opcua.client;
|
|
import cn.stylefeng.guns.base.enums.MicroTimestamp;
|
import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
|
import cn.stylefeng.guns.modular.opcua.controller.OpcuaConfController;
|
import cn.stylefeng.guns.modular.opcua.entity.NodeEntity;
|
import cn.stylefeng.guns.modular.opcua.model.params.OpcuaConfParam;
|
import cn.stylefeng.guns.modular.opcua.model.result.OpcuaConfResult;
|
import cn.stylefeng.guns.sys.core.constant.cache.Cache;
|
import com.google.common.collect.ImmutableList;
|
import lombok.extern.slf4j.Slf4j;
|
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
|
import org.eclipse.milo.opcua.sdk.client.api.nodes.VariableNode;
|
import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
|
import org.eclipse.milo.opcua.stack.core.AttributeId;
|
import org.eclipse.milo.opcua.stack.core.BuiltinDataType;
|
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
|
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
|
import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
|
import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
|
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned;
|
import org.eclipse.milo.opcua.stack.core.types.enumerated.MonitoringMode;
|
import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
|
import org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemCreateRequest;
|
import org.eclipse.milo.opcua.stack.core.types.structured.MonitoringParameters;
|
import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.util.CollectionUtils;
|
|
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.Method;
|
import java.util.ArrayList;
|
import java.util.List;
|
|
/**
|
* @ClassName: ClientHandler
|
* @Description: 客户端处理
|
* @author Jellyleo
|
* @date 2019年12月12日
|
*/
|
@Slf4j
|
@Service
|
public class ClientHandler {
|
|
// 客户端实例
|
public static OpcUaClient client = null;
|
|
public List<OpcuaConfResult> b = null;
|
|
@Autowired
|
private cn.stylefeng.guns.modular.opcua.client.ClientRunner clientRunner;
|
|
@Autowired
|
private OpcuaConfController opcuaConfController;
|
|
|
/**
|
*
|
* @MethodName: connect
|
* @Description: connect
|
* @throws Exception
|
* @CreateTime 2019年12月18日 上午10:41:09
|
*/
|
public String connect() throws Exception {
|
|
if (client != null) {
|
return "客户端已创建";
|
}
|
|
client = clientRunner.run();
|
|
if (client == null) {
|
return "客户端配置实例化失败";
|
}
|
|
// 创建连接
|
client.connect().get();
|
return "创建连接成功";
|
}
|
|
/**
|
* @MethodName: disconnect
|
* @Description: 断开连接
|
* @return
|
* @throws Exception
|
* @CreateTime 2019年12月18日 上午10:45:21
|
*/
|
public String disconnect() throws Exception {
|
|
if (client == null) {
|
return "连接已断开";
|
}
|
|
// 断开连接
|
clientRunner.getFuture().complete(client);
|
client = null;
|
return "断开连接成功";
|
}
|
|
/**
|
* @MethodName: subscribe
|
* @Description: 订阅节点变量
|
* @throws Exception
|
* @CreateTime 2019年12月18日 上午10:38:11
|
*/
|
public String subscribe(List<NodeEntity> nodes) throws Exception {
|
|
if (client == null) {
|
return "找不到客户端,操作失败";
|
}
|
|
// 查询订阅对象,没有则创建
|
UaSubscription subscription = null;
|
ImmutableList<UaSubscription> subscriptionList = client.getSubscriptionManager().getSubscriptions();
|
if (CollectionUtils.isEmpty(subscriptionList)) {
|
subscription = client.getSubscriptionManager().createSubscription(1000.0).get();
|
} else {
|
subscription = subscriptionList.get(0);
|
}
|
|
// 监控项请求列表
|
List<MonitoredItemCreateRequest> requests = new ArrayList<>();
|
|
if (!CollectionUtils.isEmpty(nodes)) {
|
for (NodeEntity node : nodes) {
|
// 创建监控的参数
|
MonitoringParameters parameters = new MonitoringParameters(subscription.nextClientHandle(), 1000.0, // sampling
|
// interval
|
null, // filter, null means use default
|
Unsigned.uint(10), // queue size
|
true // discard oldest
|
);
|
// 创建订阅的变量, 创建监控项请 求
|
MonitoredItemCreateRequest request = new MonitoredItemCreateRequest(
|
new ReadValueId(new NodeId(node.getIndex(), node.getIdentifier()), AttributeId.Value.uid(),
|
null, null),
|
MonitoringMode.Reporting, parameters);
|
requests.add(request);
|
}
|
}
|
|
// 创建监控项,并且注册变量值改变时候的回调函数
|
subscription.createMonitoredItems(TimestampsToReturn.Both, requests, (item, id) -> {
|
item.setValueConsumer((i, v) -> {
|
handle2(i.getReadValueId().getNodeId(), v.getValue());
|
});
|
}).get();
|
|
return "订阅成功";
|
}
|
|
/**
|
* * @MethodName: write
|
* @Description: 回调函数
|
* @CreateTime 2023年10月13日
|
*/
|
|
/*public void handle(NodeId id, Variant value){
|
long startTime = System.currentTimeMillis();
|
|
OpcuaConfParam opcuaConfParam=new OpcuaConfParam();
|
opcuaConfParam.setNode(id.getIdentifier().toString());
|
List<OpcuaConfResult> a=opcuaConfController.mylist(opcuaConfParam);
|
log.info("数据库访问代码执行时间:" + (System.currentTimeMillis() - startTime) + "毫秒");
|
String str1 = id.getIdentifier().toString()+":"+value.getValue().toString();
|
try {
|
Class<?> clazz = Class.forName(a.get(0).getRModule());
|
Method method = clazz.getMethod(a.get(0).getRFunction(), String.class);
|
|
method.invoke(clazz.newInstance(), str1);
|
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException |
|
InvocationTargetException e) {
|
e.printStackTrace();
|
}
|
log.info("代码执行时间:" + (System.currentTimeMillis() - startTime) + "毫秒");
|
}*/
|
public void handle2(NodeId id, Variant value){
|
|
MicroTimestamp t = null;
|
String sTime=t.INSTANCE.get();
|
|
|
if (b == null || 0 > b.size()) {
|
OpcuaConfParam opcuaConfParam=new OpcuaConfParam();
|
opcuaConfParam.setSubscribe(1);
|
b=opcuaConfController.mylist(opcuaConfParam);
|
}
|
//使用Stream API在List<T>中查找元素
|
OpcuaConfResult opcuaConfResult = b.stream()
|
.filter(customer ->id.getIdentifier().toString().equals(customer.getNode()))
|
.findAny()
|
.orElse(null);
|
try {
|
Class<?> clazz = Class.forName(opcuaConfResult.getRModule());
|
Method method = clazz.getMethod(opcuaConfResult.getRFunction(), new Class[] { String.class,
|
String.class });
|
method.invoke(clazz.newInstance(),new Object[] {
|
new String(id.getIdentifier().toString()), new String(value.getValue().toString()) });
|
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException |
|
InvocationTargetException e) {
|
e.printStackTrace();
|
}
|
log.info("代码执行开始时间为:"+ sTime +",结束时间为:"+t.INSTANCE.get()+".");
|
}
|
|
|
/**
|
* @MethodName: write
|
* @Description: 变节点量写入
|
* @param node
|
* @throws Exception
|
* @CreateTime 2019年12月18日 上午9:51:40
|
*/
|
public static Boolean write(NodeEntity node) throws Exception {
|
|
if (client == null) {
|
log.info("找不到客户端,操作失败");
|
return false;
|
}
|
|
NodeId nodeId = new NodeId(node.getIndex(), node.getIdentifier());
|
Variant value = null;
|
switch (node.getType()) {
|
case "int":
|
value = new Variant(Integer.parseInt(node.getValue().toString()));
|
break;
|
case "boolean":
|
value = new Variant(Boolean.parseBoolean(node.getValue().toString()));
|
break;
|
case "short":
|
value = new Variant(Short.parseShort(node.getValue().toString()));
|
break;
|
case "long":
|
value = new Variant(Long.parseLong(node.getValue().toString()));
|
break;
|
case "string":
|
value = new Variant(node.getValue().toString());
|
break;
|
case "char":
|
value = new Variant(node.getValue().toString().charAt(0));
|
break;
|
}
|
DataValue dataValue = new DataValue(value, null, null);
|
|
StatusCode statusCode = client.writeValue(nodeId, dataValue).get();
|
|
return statusCode.isGood();
|
}
|
|
/**
|
* @MethodName: read
|
* @Description: 读取
|
* @param node
|
* @return
|
* @throws Exception
|
* @CreateTime 2019年12月19日 下午2:40:34
|
*/
|
public String read(NodeEntity node) throws Exception {
|
|
if (client == null) {
|
return "找不到客户端,操作失败";
|
}
|
|
NodeId nodeId = new NodeId(node.getIndex(), node.getIdentifier());
|
VariableNode vnode = client.getAddressSpace().createVariableNode(nodeId);
|
DataValue value = vnode.readValue().get();
|
log.info("Value={}", value);
|
|
Variant variant = value.getValue();
|
log.info("Variant={}", variant.getValue());
|
|
log.info("BackingClass={}", BuiltinDataType.getBackingClass(variant.getDataType().get()));
|
|
return variant.getValue().toString();
|
}
|
}
|