java(springboot)集成Milo实现OPCUA客户端,读取OPCUA服务端节点数据

1.背景
前面我们搭建了一个本地的 PLC 仿真环境,并通过 KEPServerEX6 读取 PLC 上的数据,最后还使用 UAExpert 作为OPC客户端完成从 KEPServerEX6 这个OPC服务器的数据读取与订阅功能。在这篇文章中,我们将通过 SpringBoot 集成 Milo 库实现一个 OPC UA 客户端,包括连接、遍历节点、读取、写入、订阅与批量订阅等功能。

引入依赖
SpringBoot 后端项目中引入 Milo 库依赖(客户端 SDK )

        <!--start milo-->
        <dependency>
            <groupId>org.eclipse.milo</groupId>
            <artifactId>sdk-client</artifactId>
            <version>0.6.3</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.milo</groupId>
            <artifactId>sdk-server</artifactId>
            <version>0.6.3</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcpkix-jdk15on</artifactId>
            <version>1.57</version>
        </dependency>
        <!--end milo-->

连接

    public OpcUaClient opcUaClientConnect() throws Exception {

        OpcUaClient opcUaClient = null;

        //安全权限
        Path securityTempDir = Paths.get(System.getProperty("java.io.tmpdir"), "security");
        Files.createDirectories(securityTempDir);
        if (!Files.exists(securityTempDir)) {
            throw new Exception("unable to create security dir: " + securityTempDir);
        }

        opcUaClient = OpcUaClient.create(endPointUrl,
                endpoints -> {
                    final Optional<EndpointDescription> endpoint = endpoints
                            .stream()
                            .filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri()))
                            .findFirst();
                    EndpointDescription newEndpoint = new EndpointDescription(this.endPointUrl, endpoint.get().getServer(), endpoint.get().getServerCertificate(),
                            endpoint.get().getSecurityMode(), endpoint.get().getSecurityPolicyUri(), endpoint.get().getUserIdentityTokens(),
                            endpoint.get().getTransportProfileUri(), endpoint.get().getSecurityLevel());
                    return Optional.of(newEndpoint);
                },

                configBuilder ->
                        configBuilder
                                .setApplicationName(LocalizedText.english("eclipse milo opc-ua client"))
                                .setApplicationUri("urn:eclipse:milo:examples:client")
                                .setIdentityProvider(new AnonymousProvider())
                                .setRequestTimeout(UInteger.valueOf(500))
                                .build()


        );


        try {

            CompletableFuture<UaClient> connect = opcUaClient.connect();
            connect.get();
            //Thread.sleep(2000);

        } catch (ExecutionException e) {

            logger.error("连接失败opc opcUaClientConnect方法");
            //e.printStackTrace();
        }

        return opcUaClient;
    }

获取节点值

    //获取节点的数据信息
    public DataValue getOpcUaNodeValue(OpcUaClient connectionFromPool, String machineName) {


        NodeId nodeId = new NodeId(2, machineName);//"OPC_Test.设备 1.TAG1"

        //读取节点数据
        DataValue value = null;


        try {


            value = connectionFromPool.readValue(0.0, TimestampsToReturn.Neither, nodeId).get();
            // 状态==false 连接上  true没有连接上
            //System.out.println("Status: " + value.getStatusCode().isBad());
            //标识符
            // String id = String.valueOf(nodeId.getIdentifier());
            // System.out.println(id + ": " + value.getValue().getValue());


        } catch (Exception e) {

            e.printStackTrace();
        }


        return value;

    }

批量订阅指定节点



@Configuration
public class OpcUaConfig {

    private Logger logger = LoggerFactory.getLogger(RedisTimer.class);


    @Autowired
    TableConsumeMapperService tableConsumeMapperService;

    @Autowired
    private DataNode dataNode;

    @Bean
    public DataNode transferService() {

        return dataNode;
    }
     OpcUaMiloTemplate opcUaMiloTemplate = new OpcUaMiloTemplate();

     OpcUaClient connectionFromPool = opcUaMiloTemplate.getConnectionFromPool();


    @Bean
    public void handlerMultipleNodeListen() throws Exception {

        //final CountDownLatch eventLatch = new CountDownLatch(1);

        List<TableConsume> tableConsumeList = tableConsumeMapperService.getTableConsumeList();


        List<String> batchIdentifiers = new ArrayList<>();
        //batchIdentifiers.add("OPC_Test.Q.TAG1");
        for (TableConsume tableConsume : tableConsumeList) {
            //batchIdentifiers.add(getConsumePosition);
            batchIdentifiers.add(tableConsume.getConsumePosition());
        }

        try {

            //OpcUaClient connectionFromPool = opcUaClientConnect();
            //创建订阅
            ManagedSubscription subscription = ManagedSubscription.create(connectionFromPool);

            List<NodeId> nodeIdList = new ArrayList<>();
            for (String id : batchIdentifiers) {
                nodeIdList.add(new NodeId(2, id));
            }
            //监听
            List<ManagedDataItem> dataItemList = subscription.createDataItems(nodeIdList);

            for (ManagedDataItem managedDataItem : dataItemList) {

                managedDataItem.addDataValueListener((t) -> {

                    //DataNode node = new DataNode();
                    //System.out.println(managedDataItem.getNodeId().getIdentifier().toString() + ":" + t.getValue().getValue().toString());
                    dataNode.setNodeAdress(managedDataItem.getNodeId().getIdentifier().toString());
                    dataNode.setDateValue(t.getValue().getValue().toString());
                    DataNode dataNode = transferService();
                    ToolUtils.nodeList.add(dataNode);
                });

            }


            Thread.sleep(2000);//是指订阅的时间长度
            //eventLatch.await();
            logger.error("订阅获取的值::::" + ToolUtils.nodeList.toString());

        } catch (Exception e) {

            e.printStackTrace();

        }

    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值