JAVA 使用 Milo 实现 OPCUA 客户端

本次采用KEPServerEX6模拟服务端,使用milo开发的程序作为客户端

一、Milo库

本文使用Milo库实现OPC UA客户端,以达到通过java读、写、订阅变量的目的。

官网:https://github.com/eclipse/milo

二、JAVA连接OPCUA客户端

  1. pom添加依赖
    
                org.eclipse.milo
                sdk-server
                0.2.4
            
            
                org.eclipse.milo
                sdk-client
                0.2.4
            
            
                org.bouncycastle
                bcpkix-jdk15on
                1.57
            

  2. 安全策略                                                                                                                                    

    对应的OPC UA服务地址(也就是上面定义的字符串)的节点并不止一个,因为在一个对应的OPC UA服务地址里面可能也有不一样的服务器安全策略,每种不同安全策略对应一个节点。

    无安全设置
    Basic128Rsa15 - 签名
    Basic128Rsa15 - 签名和加密
    Basic256 - 签名
    Basic256 - 签名和加密
    Basic256Sha256 - 签名
    Basic256Sha256 - 签名和加密

    以下用的是无安全设置策略
  3. 创建客户端
    public static OpcUaClient creatClient() {
            try {
                // 连接地址端口号
                String EndPointUrl = "opc.tcp://192.168.1.120:49320";
                //安全策略选择
                EndpointDescription[] endpointDescription = UaTcpStackClient.getEndpoints(EndPointUrl).get();
                //过滤掉不需要的安全策略,选择一个自己需要的安全策略
                EndpointDescription endpoint = Arrays.stream(endpointDescription)
                        .filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.NONE))
                        .findFirst().orElseThrow(() -> new Exception("no desired endpoints returned"));
    
                OpcUaClientConfig config = OpcUaClientConfig.builder()
                        .setApplicationName(LocalizedText.english("test")) // opc ua 定义的名
                        .setApplicationUri(EndPointUrl)// 地址
                        .setEndpoint(endpoint)// 安全策略等配置
                        .setIdentityProvider(new UsernameProvider("username", "password"))
                        .setRequestTimeout(UInteger.valueOf(50000)) //等待时间
                        .build();
    
                OpcUaClient opcClient = new OpcUaClient(config);// 准备连接
                return opcClient;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

  4. 读取节点数据
    public static void readValue(OpcUaClient client) {
            try {
    
                NodeId nodeId = new NodeId(2, "通道 1.设备 1.ua1");//int
    
                DataValue value = client.readValue(0.0, TimestampsToReturn.Both, nodeId).get();
    
                System.out.println("=====读取ua1====:" + value.getValue().getValue());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

  5. 写入节点数据
    public static void writeValue(OpcUaClient client) {
            try {
    
                //创建变量节点
                NodeId nodeId = new NodeId(2, "通道 1.设备 1.ua3");
    
                //uda3 boolean
                boolean value = true;
                //创建Variant对象和DataValue对象
                Variant v = new Variant(value);
                DataValue dataValue = new DataValue(v, null, null);
    
                StatusCode statusCode = client.writeValue(nodeId, dataValue).get();
                System.out.println(statusCode);
                System.out.println("=====写入ua1====:" +statusCode.isGood());
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

  6. 订阅
    private static void subscribe(OpcUaClient client) throws Exception {
            //创建发布间隔1000ms的订阅对象
            client.getSubscriptionManager()
                    .createSubscription(1000.0)
                    .thenAccept(t -> {
                        //节点
                        NodeId nodeId = new NodeId(2, "通道 1.设备 1.ua1");
                        ReadValueId readValueId = new ReadValueId(nodeId, AttributeId.Value.uid(), null, null);
                        //创建监控的参数
                        MonitoringParameters parameters = new MonitoringParameters(UInteger.valueOf(1), 1000.0, null, UInteger.valueOf(10), true);
                        //创建监控项请求
                        //该请求最后用于创建订阅。
                        MonitoredItemCreateRequest request = new MonitoredItemCreateRequest(readValueId, MonitoringMode.Reporting, parameters);
                        List requests = new ArrayList<>();
                        requests.add(request);
                        //创建监控项,并且注册变量值改变时候的回调函数。
                        t.createMonitoredItems(
                                TimestampsToReturn.Both,
                                requests,
                                (item, id) -> item.setValueConsumer((it, val) -> {
                                    System.out.println("=====订阅nodeid====== :" + it.getReadValueId().getNodeId());
                                    System.out.println("=====订阅value===== :" + val.getValue().getValue());
                                })
                        );
                    }).get();
    
            //持续订阅
            Thread.sleep(Long.MAX_VALUE);
        }

    订阅成功后,main线程会被阻塞,修改OPC UA中的变量值后,就可以即时查看到订阅的消息。订阅时间可以通过修改Thread.sleep的沉睡时间实现。

  7. main测试
    public static void main(String[] args) {
            try {
                //创建OPC UA客户端
                OpcUaClient opcUaClient = creatClient();
    
                //创建连接
                opcUaClient.connect().get();
    
                //读取
                readValue(opcUaClient);
    
                //写入
                writeValue(opcUaClient);
    
                //订阅
                subscribe(opcUaClient);
    
                //关闭连接
                opcUaClient.disconnect().get();
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

  8. 运行结果 JAVA 使用 Milo 实现 OPCUA 客户端_第1张图片 

你可能感兴趣的:(java)