0
点赞
收藏
分享

微信扫一扫

PLC通讯

小迁不秃头 2023-08-17 阅读 45


import lombok.extern.slf4j.Slf4j;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider;
import org.eclipse.milo.opcua.sdk.client.api.identity.IdentityProvider;
import org.eclipse.milo.opcua.sdk.client.api.identity.UsernameProvider;
import org.eclipse.milo.opcua.stack.client.DiscoveryClient;
import org.eclipse.milo.opcua.stack.core.Identifiers;
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.unsigned.UInteger;
import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseDirection;
import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseResultMask;
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.structured.BrowseDescription;
import org.eclipse.milo.opcua.stack.core.types.structured.BrowseResult;
import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;
import org.eclipse.milo.opcua.stack.core.types.structured.ReferenceDescription;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.ExecutionException;

/**
 * @author TARZAN
 */
@Slf4j
public class OpcUaUtil {

    /**
     * 方法描述: 创建客户端
     *
     * @param endPointUrl
     * @param username
     * @param password
     * @return {@link OpcUaClient}
     * @throws
     */
    public static OpcUaClient createClient(String endPointUrl,String username,String password){
        log.info(endPointUrl);
        try {
            //获取安全策略
            List<EndpointDescription> endpointDescription = DiscoveryClient.getEndpoints(endPointUrl).get();
            //过滤出一个自己需要的安全策略
            EndpointDescription endpoint = endpointDescription.stream()
                    .filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri()))
                    .findFirst().orElse(null);
            IdentityProvider identityProvider=new AnonymousProvider();
            if(!StringUtils.isEmpty(username)||!StringUtils.isEmpty(password)){
                identityProvider=new UsernameProvider(username,password);
            }
            // 设置配置信息
            OpcUaClientConfig config = OpcUaClientConfig.builder()
                    // opc ua 自定义的名称
                    .setApplicationName(LocalizedText.english("plc"))
                    // 地址
                    .setApplicationUri(endPointUrl)
                    // 安全策略等配置
                    .setEndpoint(endpoint)
                    .setIdentityProvider(identityProvider)
                    //等待时间
                    .setRequestTimeout(UInteger.valueOf(5000))
                    .build();
            // 准备连接
            OpcUaClient opcClient =OpcUaClient.create(config);
            //开启连接
            opcClient.connect().get();
            log.info("连接成功。。。success");
            return opcClient;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("======== opc connection fail ========");
        }
        return null;
    }


    /**
     * 方法描述: 查询所有节点
     *
     * @param client
     * @return {@link Set<String>}
     * @throws
     * @author liwenbin
     * @date 2023年07月03日 13:05:55
     */
    public static Set<String> getAllKeys(OpcUaClient client) throws Exception {
        return browse(null,client);
    }


    /**
     * 方法描述: 查询某个节点下的所有节点
     *
     * @param identifier
     * @param client
     * @return
     * @throws
     */
    public static Set<String> browse(String identifier, OpcUaClient client) throws Exception {
        Set<String> keys=new HashSet<>(500);
        browse(identifier,keys,client);
        return keys;
    }

    /**
     * 方法描述: 查询某个节点下的所有节点
     *
     * @param identifier
     * @param client
     * @return
     * @throws
     */
    private static Set<String> browse(String identifier, Set<String> keys, OpcUaClient client) throws Exception {
        NodeId nodeId = Identifiers.ObjectsFolder;
        if(!StringUtils.isEmpty(identifier)){
            nodeId = new NodeId(2, identifier);
        }
        BrowseDescription browse = new BrowseDescription(
                nodeId,
                BrowseDirection.Forward,
                Identifiers.References,
                true,
                UInteger.valueOf(NodeClass.Object.getValue() | NodeClass.Variable.getValue()),
                UInteger.valueOf(BrowseResultMask.All.getValue())
        );
        BrowseResult browseResult = client.browse(browse).get();
        ReferenceDescription[] references = browseResult.getReferences();
        for (ReferenceDescription reference : references) {
            System.out.println(reference.getNodeId().getIdentifier().toString()+" "+reference.getNodeClass().getValue());
            keys.add(identifier);
            if(reference.getNodeClass().getValue()==NodeClass.Object.getValue()){
                browse(reference.getNodeId().getIdentifier().toString(),keys,client);
            }
        }
        return keys;
    }


    /**
     * 方法描述: 读取单个节点值
     *
     * @param identifier
     * @param client
     * @return {@link Object}
     * @throws
     */
    public static Object readValue(String identifier, OpcUaClient client){
        NodeId nodeId = new NodeId(2, identifier);
        DataValue value = null;
        try {
            client.readValue(0.0, TimestampsToReturn.Both,nodeId);
            value = client.readValue(0.0, TimestampsToReturn.Both, nodeId).get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        if(Objects.nonNull(value)&&Objects.nonNull(value.getValue())&&Objects.nonNull(value.getValue().getValue())) {
            return value.getValue().getValue();
        }
        return null;
    }

    /**
     * 方法描述: 读取多个点位的值
     *
     * @param keys 点位集合
     * @param client 客户端
     * @return {@link List<DataValue>}
     * @throws
     */
    public static List<DataValue> readValues(Set<String> keys, OpcUaClient client){
        List<NodeId> nodeIdList=new ArrayList<>(500);
        keys.forEach(e->{
            NodeId nodeId = new NodeId(2, e);
            nodeIdList.add(nodeId);
        });
        try {
            List<DataValue> dataValues=client.readValues(0.0, TimestampsToReturn.Both,nodeIdList).get();
            return dataValues;
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 写入值
     *
     * @param identifier
     * @param value
     * @throws Exception
     */
    public static void writeValue(String identifier, Object value,OpcUaClient client) throws Exception {
        //创建变量节点
        NodeId nodeId = new NodeId(2, identifier);
        //创建Variant对象和DataValue对象
        Variant v = new Variant(value);
        DataValue dataValue = new DataValue(v, null, null);
        StatusCode statusCode = client.writeValue(nodeId, dataValue).get();
        if(statusCode.isGood()){
            log.info("数据写入成功");
        }else {
            log.error("数据写入失败");
        }
    }


    /**
     * 方法描述:  写入多个节点的值
     *
     * @param keys  节点集合
     * @param values  值集合
     * @param client  客户端
     * @return {@link Object}
     * @throws
     */
    public static Object writeValues(Set<String> keys,List<Object> values,OpcUaClient client){
        List<NodeId> nodeIs=new ArrayList<>(keys.size());
        keys.forEach(e->{
            NodeId nodeId = new NodeId(2, e);
            nodeIs.add(nodeId);
        });
        List<DataValue> dataValues=new ArrayList<>(values.size());
        values.forEach(e->{
            Variant value=new Variant(Double.parseDouble(e.toString()));
            DataValue dataValue=new DataValue(value);
            dataValues.add(dataValue);
        });
        try {
            client.writeValues(nodeIs,dataValues).get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 方法描述: 断开连接
     *
     * @param client
     * @return
     */
    public static void disconnect(OpcUaClient client){
        try {
            client.disconnect().get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }

}


举报

相关推荐

0 条评论