JAVA使用OPC UA 方式与设备通信(milo)

背景

基于生产过程控制系统(MES)与生产设备(PLC)通信的需求,PLC型号西门子S7-1500,设备数据采集使用KEPwareEX6.4 , 将kepware 作为服务端来开发一个Java服务,用于生产过程控制系统与设备数据交互,达到控制生产过程的目的。关于kepware服务端部分文章不涉及

SpringBoot集成Milo

这里我使用的是Github上的一个开源的milo-spring-boot-starter

  1. 引入maven
<!--引入Milo库-->
<dependency>
    <groupId>com.kangaroohy</groupId>
    <artifactId>milo-spring-boot-starter</artifactId>
    <version>3.0.5</version>
</dependency>
<!--如果引入有错误的话可以尝试在引入下面的依赖-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.11.1</version>
</dependency>
  1. 配置application.properties
// 具体的配置信息可以参考github中
kangaroohy.milo.primary=default
// false则启动不检测
kangaroohy.milo.enabled=true
kangaroohy.milo.config.default.endpoint=opc.tcp://XXXX:49320
kangaroohy.milo.config.default.security-policy=none
  1. 编写测试类
package com.libsept24.limit;

import cn.hutool.core.collection.ListUtil;
import com.kangaroohy.milo.model.ReadWriteEntity;
import com.kangaroohy.milo.service.MiloService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.List;

@SpringBootTest
public class MiloTests {

    @Resource
    private MiloService miloService;
    
    @Test
    void contextLoads() throws Exception {
        // 读取这个目录下的所有点位
        List<String> strings1 = miloService.browseNode("NG.ktxt.kt.kzs5");
        System.out.println(strings1);
        // 读取点位为1的值
        ReadWriteEntity readWriteEntity = miloService.readFromOpcUa("id");
        System.out.println(readWriteEntity.getValue());
        // 写入点位1,值为1
        ReadWriteEntity writeEntity = new ReadWriteEntity();
        writeEntity.setIdentifier("1");
        writeEntity.setValue("1");
        miloService.writeToOpcUa(ListUtil.toList(writeEntity));
    }
}

  1. 如何重写MiloService,使得写入的结果可以返回
package com.libsept24.limit.milo;

import com.kangaroohy.milo.configuration.MiloProperties;
import com.kangaroohy.milo.model.ReadWriteEntity;
import com.kangaroohy.milo.model.WriteEntity;
import com.kangaroohy.milo.pool.MiloConnectPool;
import com.kangaroohy.milo.runner.BrowseNodeRunner;
import com.kangaroohy.milo.runner.BrowseRunner;
import com.kangaroohy.milo.runner.ReadValuesRunner;
import com.kangaroohy.milo.runner.subscription.SubscriptionCallback;
import com.kangaroohy.milo.runner.subscription.SubscriptionRunner;
import com.kangaroohy.milo.utils.CustomUtil;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

@Lazy
@Service
public class MiloServicePro {
    private static final Logger log = LoggerFactory.getLogger(com.kangaroohy.milo.service.MiloService.class);
    private final MiloConnectPool connectPool;
    private final MiloProperties properties;

    public MiloServicePro(MiloConnectPool connectPool, MiloProperties properties) {
        this.connectPool = connectPool;
        this.properties = properties;
    }

    public List<StatusCode> writeToOpcUa(List<ReadWriteEntity> entities, String clientName) throws Exception {
        MiloProperties.Config config = CustomUtil.getConfig(this.properties, clientName);
        List<WriteEntity> writeEntityList = new ArrayList();
        if (!entities.isEmpty()) {
            Iterator var5 = entities.iterator();

            while (var5.hasNext()) {
                ReadWriteEntity entity = (ReadWriteEntity) var5.next();
                writeEntityList.add(WriteEntity.builder().identifier(entity.getIdentifier()).variant(new Variant(entity.getValue())).build());
            }
        }

        WriteValuesRunner runner = new WriteValuesRunner(writeEntityList);
        OpcUaClient client = (OpcUaClient) this.connectPool.borrowObject(config);
        if (client != null) {
            try {
                return runner.run(client);
            } finally {
                this.connectPool.returnObject(config, client);
            }
        }
        return null;
    }
}
package com.libsept24.limit.milo;


import com.kangaroohy.milo.model.WriteEntity;
import com.kangaroohy.milo.utils.CustomUtil;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
import org.eclipse.milo.opcua.stack.core.types.builtin.DateTime;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class WriteValuesRunner {
    private static final Logger log = LoggerFactory.getLogger(com.kangaroohy.milo.runner.WriteValuesRunner.class);
    private final List<WriteEntity> entities;

    public WriteValuesRunner(List<WriteEntity> entities) {
        this.entities = entities;
    }

    public List<StatusCode> run(OpcUaClient opcUaClient) {
        try {
            if (!this.entities.isEmpty()) {
                List<NodeId> nodeIds = new LinkedList();
                List<DataValue> dataValues = new LinkedList();
                Iterator var4 = this.entities.iterator();

                while(var4.hasNext()) {
                    WriteEntity entity = (WriteEntity)var4.next();
                    nodeIds.add(CustomUtil.parseNodeId(entity.getIdentifier()));
                    dataValues.add(new DataValue(entity.getVariant(), (StatusCode)null, (DateTime)null));
                }

                List<StatusCode> statusCodeList = (List)opcUaClient.writeValues(nodeIds, dataValues).join();

                for(int i = 0; i < statusCodeList.size(); ++i) {
                    if (((StatusCode)statusCodeList.get(i)).isGood()) {
                        log.info("将值 '{}' 写入到点位:{} 成功", ((DataValue)dataValues.get(i)).getValue(), nodeIds.get(i));
                    } else {
                        log.error("点位:{} 写入时出现了异常:{}", nodeIds.get(i), statusCodeList.get(i));
                    }
                }
                return statusCodeList;
            }
        } catch (Exception var6) {
            log.error("批量写值出现异常出现了异常:{}", var6.getMessage(), var6);
        }
        return null;
    }
}


文章作者: LibSept24_
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LibSept24_
OPC UA
喜欢就支持一下吧
打赏
微信 微信
支付宝 支付宝