Java 001:通过OPC UA协议连接KepServerEx进行读、写、订阅操作

这篇具有很好参考价值的文章主要介绍了Java 001:通过OPC UA协议连接KepServerEx进行读、写、订阅操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

参考前辈的踩坑记录https://blog.csdn.net/weixin_45411740/article/details/124275985?spm=1001.2014.3001.5502,我Hyb在2023-3-15调通了自己的JavaOpcUaDemo。具体Java代码和KepServerEX延时补丁都在资源中。

Java 001:通过OPC UA协议连接KepServerEx进行读、写、订阅操作

第1步:安装激活KepServer,补丁在资源中,不详述。

第2步:在KepServer中做OpcUa配置。

2.1 先看桌面右下角有没EX图标

Java 001:通过OPC UA协议连接KepServerEx进行读、写、订阅操作

2.2 如果没有EX图标,要去开始菜单中找到KEPServerEX 6 Administration,点击打开它后,桌面右下角就会出现EX图标:

Java 001:通过OPC UA协议连接KepServerEx进行读、写、订阅操作

2.3 右键点击EX图标,选择“OPC UA 配置”,设置过程看这个动图:(一定要关注动图中192.168.10.60这个ip及端口的设置,它要与你代码中一致!

Java 001:通过OPC UA协议连接KepServerEx进行读、写、订阅操作

第3步:在KepServer中设置用户名密码。

3.1 再一次点桌面右下角的EX图标,选择“设置”,点“用户管理器”,在Administrators右键选择“添加用户”。见图操作:

Java 001:通过OPC UA协议连接KepServerEx进行读、写、订阅操作

第4步:在KepServer中设置opcua匿名账户登录。

在KepServerEX界面,在“项目”右键,选择“属性”,选择“OPC UA”。在“客户端会话”、“允许匿名登录”中,选择“是”。如图:

Java 001:通过OPC UA协议连接KepServerEx进行读、写、订阅操作

以上KepServerEX设置完成后,就可以构建Java项目了。


第5步:首先搭建环境。下载Eclipse、配置Maven

Java 001:通过OPC UA协议连接KepServerEx进行读、写、订阅操作

上图分别对应:

5.1 从Maven下载安装包:apache-maven-3.9.0-bin.zip

5.2 配置Maven本地仓库在:conf/settings.xml

<localRepository>${MAVEN_HOME}/repoHyb</localRepository>

5.3 配置Maven镜像:从阿里云Maven镜像同步和下载jar

<mirror><!--配置具体的仓库的下载镜像 从阿里云Maven仓库下载-->
    <id>nexus-aliyun</id><!-- 此镜像的唯一标识符,用来区分不同的mirror元素 -->
    <mirrorOf>central</mirrorOf><!-- 对哪种仓库进行镜像,简单说就是替代哪个仓库-->
    <name>Nexus aliyun</name><!-- 镜像名称 -->
    <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

5.4 在Eclipse中设置Maven安装路径

5.5 在Eclipse中设置Maven的配置文件


第6步:以上环境搭建好后,就可以正式coding了。

6.1 在eclipse中创建maven项目,并在pom.xml中配置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>

Milo是Eclipse旗下的一个物联网的项目,是一个高性能的OPC UA栈,提供了一组客户端和服务端的API,支持对实时数据的访问,监控,报警,订阅数据,支持事件,历史数据访问,和数据建模。官网https://projects.eclipse.org/projects/iot.milo

在Milo中大量的采用了java 8的新特性CompletableFuture来进行异步操作,Milo中有大量的操作都是直接返回CompletableFuture对象,所以JDK的版本必须要8.0,对CompletableFuture不太熟悉的可以先去了解CompletableFuture的相关概念在来看Milo的官方例子会轻松很多。

6.2 然后就是java代码,只有一个类TestOpcUA.java,代码全部在这一个java文件中。直接复制到你java文件中,不用再导入任何类,加个包名,直接可以运行。

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider;
import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscriptionManager;
import org.eclipse.milo.opcua.sdk.client.nodes.UaNode;
import org.eclipse.milo.opcua.sdk.client.subscriptions.ManagedDataItem;
import org.eclipse.milo.opcua.sdk.client.subscriptions.ManagedSubscription;
import org.eclipse.milo.opcua.stack.core.AttributeId;
import org.eclipse.milo.opcua.stack.core.Identifiers;
import org.eclipse.milo.opcua.stack.core.UaException;
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
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.LocalizedText;
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.UInteger;
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;

public class TestOpcUA {
    private final static String endPointUrl = "opc.tcp://192.168.10.60:49320";

    /**
     * 创建OPC UA客户端
     */
    private static OpcUaClient createClient() throws Exception {
        //opc ua服务端地址
        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);
        }
        return OpcUaClient.create(endPointUrl, endpoints -> endpoints.stream().filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri())).findFirst(), configBuilder -> configBuilder.setApplicationName(LocalizedText.english("eclipse milo opc-ua client")).setApplicationUri("urn:eclipse:milo:examples:client")
        //访问方式
                .setIdentityProvider(new AnonymousProvider()).setRequestTimeout(UInteger.valueOf(500)).build());
    }

    /**
     * 遍历树形节点
     *
     * @param client OPC UA客户端
     * @param uaNode 节点
     * @throws Exception
     */
    private static void browseNode(OpcUaClient client, UaNode uaNode) throws Exception {
        List<? extends UaNode> nodes;
        if (uaNode == null) {
            nodes = client.getAddressSpace().browseNodes(Identifiers.ObjectsFolder);
        } else {
            nodes = client.getAddressSpace().browseNodes(uaNode);
        }
        for (UaNode nd : nodes) {
            //排除系统行性节点,这些系统性节点名称一般都是以"_"开头
            if (Objects.requireNonNull(nd.getBrowseName().getName()).contains("_")) {
                continue;
            }
            System.out.println("Node= " + nd.getBrowseName().getName());
            browseNode(client, nd);
        }
    }

    /**
     * 读取节点数据
     *
     * @param client OPC UA客户端
     * @throws Exception
     */
    private static void readNode(OpcUaClient client) throws Exception {
        int namespaceIndex = 2;
        String identifier = "通道 1.设备 1.标记 1";
        //节点
        NodeId nodeId = new NodeId(namespaceIndex, identifier);
        //读取节点数据
        DataValue value = client.readValue(0.0, TimestampsToReturn.Neither, nodeId).get();
        //标识符
        identifier = String.valueOf(nodeId.getIdentifier());
        System.out.println(identifier + ": " + String.valueOf(value.getValue().getValue()));
    }

    /**
     * 写入节点数据
     *
     * @param client
     * @throws Exception
     */
    private static void writeNodeValue(OpcUaClient client) throws Exception {
        //节点
        NodeId nodeId = new NodeId(2, "通道 1.设备 1.标记 4");
        Short i = 48;
        //创建数据对象,此处的数据对象一定要定义类型,不然会出现类型错误,导致无法写入
        DataValue nowValue = new DataValue(new Variant(i), null, null);
        //写入节点数据
        StatusCode statusCode = client.writeValue(nodeId, nowValue).join();
        System.out.println("结果:" + statusCode.isGood());
    }

    /**
    * 订阅(单个)
    *
    * @param client
    * @throws Exception
    */
    private static void subscribe(OpcUaClient client) throws Exception {
        AtomicInteger a = new AtomicInteger();
        //创建发布间隔1000ms的订阅对象
        client.getSubscriptionManager().createSubscription(1000.0).thenAccept(t -> {
            //节点
                NodeId nodeId = new NodeId(2, "通道 1.设备 1.标记 1");
                ReadValueId readValueId = new ReadValueId(nodeId, AttributeId.Value.uid(), null, null);
                //创建监控的参数
                MonitoringParameters parameters = new MonitoringParameters(UInteger.valueOf(a.getAndIncrement()), 1000.0, null, UInteger.valueOf(10), true);
                //创建监控项请求
                //该请求最后用于创建订阅。
                MonitoredItemCreateRequest request = new MonitoredItemCreateRequest(readValueId, MonitoringMode.Reporting, parameters);
                List<MonitoredItemCreateRequest> 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);
    }

    /**
     * 批量订阅
     *
     * @param client
     * @throws Exception
     */
//  private static void managedSubscriptionEvent(OpcUaClient client) throws Exception {
//      final CountDownLatch eventLatch = new CountDownLatch(1);
//
//      //处理订阅业务
//      handlerNode(client);
//
//      //持续监听
//      eventLatch.await();
//  }

    /**
     * 处理订阅业务
     *
     * @param client OPC UA客户端
     */
    private static void handlerNode(OpcUaClient client) {
        try {
            //创建订阅
            ManagedSubscription subscription = ManagedSubscription.create(client);

            //你所需要订阅的key
            List<String> key = new ArrayList<>();
            key.add("通道 1.设备 1.标记 4");
            key.add("通道 1.设备 1.标记 1");

            List<NodeId> nodeIdList = new ArrayList<>();
            for (String s : key) {
                nodeIdList.add(new NodeId(2, s));
            }

            //监听
            List<ManagedDataItem> dataItemList = subscription.createDataItems(nodeIdList);
            for (ManagedDataItem managedDataItem : dataItemList) {
                managedDataItem.addDataValueListener((t) -> {
                    System.out.println(managedDataItem.getNodeId().getIdentifier().toString() + ":" + t.getValue().getValue().toString());
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 自定义订阅监听
     */
    private static class CustomSubscriptionListener implements UaSubscriptionManager.SubscriptionListener {

        private OpcUaClient client;

        CustomSubscriptionListener(OpcUaClient client) {
            this.client = client;
        }

        public void onKeepAlive(UaSubscription subscription, DateTime publishTime) {
            System.out.println("onKeepAlive");
        }

        public void onStatusChanged(UaSubscription subscription, StatusCode status) {
            System.out.println("onStatusChanged");
        }

        public void onPublishFailure(UaException exception) {
            System.out.println("onPublishFailure");
        }

        public void onNotificationDataLost(UaSubscription subscription) {
            System.out.println("onNotificationDataLost");
        }

        /**
         * 重连时 尝试恢复之前的订阅失败时 会调用此方法
         * @param uaSubscription 订阅
         * @param statusCode 状态
         */
        public void onSubscriptionTransferFailed(UaSubscription uaSubscription, StatusCode statusCode) {
            System.out.println("恢复订阅失败 需要重新订阅");
            //在回调方法中重新订阅
            handlerNode(client);
        }
    }

    /**
     * 批量订阅
     *
     * @param client
     * @throws Exception
     */
    private static void managedSubscriptionEvent(OpcUaClient client) throws Exception {
        final CountDownLatch eventLatch = new CountDownLatch(1);

        //添加订阅监听器,用于处理断线重连后的订阅问题
        client.getSubscriptionManager().addSubscriptionListener(new CustomSubscriptionListener(client));

        //处理订阅业务
        handlerNode(client);

        //持续监听
        eventLatch.await();
    }

    public static void main(String[] args) throws Exception {
        OpcUaClient client = createClient();
        client.connect().get();
//        browseNode(client, null);
//        readNode(client);
//        writeNodeValue(client);
        subscribe(client);
//    managedSubscriptionEvent(client);
    }

}

本文涉及的java项目代码和KepServerEX补丁下载地址:https://download.csdn.net/download/qq_28530139/87579334

Hyb✈✈✈本文结束,谢谢浏览【VX:m3920752】!个人资源的解压密码是: hyb文章来源地址https://www.toymoban.com/news/detail-482020.html


到了这里,关于Java 001:通过OPC UA协议连接KepServerEx进行读、写、订阅操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot集成Milo库实现OPC UA客户端:连接、遍历节点、读取、写入、订阅与批量订阅

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

    2024年02月09日
    浏览(45)
  • 在 .NET 中使用 OPC UA 协议

    目录 什么是 OPC UA UaExpert 的使用 下载 UaExpert 首次启动 添加 OPC UA 服务器 连接 OPC UA 服务器 查看 PLC 数据 使用 C# 读写 OPC UA 数据 连接到 OPC UA 服务器 获取节点的值 写入节点的值 OPC UA (OPC Unified Architecture,开放平台通信统一架构)是 OPC 基金会应用在自动化技术的机器对机器

    2024年03月25日
    浏览(28)
  • 嵌入式物联网技术栈【协议篇】OPC UA协议

    OPC UA前身是OPC,第一个OPC规范在1996年发布,包括一整套接口、属性和方法的标准集 OPC全称是Object Linking and Embedding(OLE) for Process Control, 微软公司对象链接和嵌入技术在过程控制方面的应用,是一系列接口、方法和属性的标准集,是将通讯协议与设备/应用隔离的技术。 微软

    2024年02月14日
    浏览(35)
  • PLC物联网网关BL104实现PLC协议转MQTT、OPC UA、Modbus TCP

    随着物联网技术的迅猛发展,人们深刻认识到在智能化生产和生活中,实时、可靠、安全的数据传输至关重要。在此背景下,高性能的物联网数据传输解决方案——协议转换网关应运而生,广泛应用于工业自动化和数字化工厂应用环境中。 无缝衔接工业4.0时代 尽享数字工厂

    2024年01月21日
    浏览(52)
  • Java实现 OPC Ua Server服务器创建

    我们除了使用KEPServerEX6 创建OPC Ua Server 服务器以外,还可以使用 开源项目org.eclipse.milo 创建一个java项目OPC Ua Server的服务。相对于KEPServerEX6 属于收费的商用版本来说,后者更为简单轻便。下面附加代码和文字说明,教你如何创建一个OPC Ua Server的java服务。 可以不是web项目的,

    2024年01月24日
    浏览(29)
  • Java使用Milo实现OPC UA客户端,封装spring boot starter

    最新版本更新日志查看:https://github.com/kangaroo1122/milo-spring-boot-starter/blob/main/UPDATE.md、https://gitee.com/vampire001/milo-spring-boot-starter/blob/master/UPDATE.md,此处不再更新 由eclipse开源,地址:https://github.com/eclipse/milo,可以基于此开发OPC UA客户端或者服务端。 本文介绍基于milo 封装的sp

    2024年02月09日
    浏览(40)
  • OPC UA服务端(Prosys OPC UA Simulation Server)和客户端(OPC UA Explorer)工具使用

    1.Prosys OPC UA Simulation Server下载地址 https://downloads.prosysopc.com/opc-ua-simulation-server-downloads.php 2.简单使用 2.1 特殊项设置 【1】端口设置 【2】OPC UA Simulation Server运行状态 2.2 新加需要模拟上数的点 2.3 模拟动态变化值,修改ValueType 效果图如下: 2.4 模拟固定值(手动修改值) 1.Matriko

    2024年02月14日
    浏览(35)
  • 【OPC UA】使用C#读取OPC UA电液控数据

    OPC UA与OPC DA协议常见于工业生产中使用,例如煤矿的综采支架电液控系统。OPC UA 是OPC 的后继标准,只是后面增加了UA ,意指”统一架构”(Unified Architecture).它的主要目的是摆脱windows! 实现与平台无关的OPC.从OPC 演进到OPC UA,它的目的并没有改变,依然是为了实现分布式控制系统中

    2024年02月15日
    浏览(22)
  • OPC UA 云端模型库

            UA 云库(opc ua cloud library)是互联网上可用的中央库,可以在其中上传配套规范 (CS) 并将其提供给其他人。许多CS是由OPC基金会的联合工作组开发和发布的。来自不同行业和应用领域的几位专家共同努力,为许多机器和系统提供了标准化的数据结构。此外,还可

    2024年02月07日
    浏览(35)
  • OPC UA:工业领域的“HTML”

            OPC   UA 是工业自动化领域的一项重要的通信协议。它的特点是包括了信息模型构建方法。能够建立工业领域各种事物的信息模型。在工业自动化行业,OPCUA 类似互联网行业的HTTP协议和“HTML”语言。能够准确,可靠地描述复杂系统中各个元素,并且实现系统组件

    2024年02月08日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包