iis服务器助手广告
返回顶部
首页 > 资讯 > 后端开发 > JAVA >【应用】OPC 通讯协议
  • 789
分享到

【应用】OPC 通讯协议

网络java网络协议 2023-10-24 14:10:23 789人浏览 安东尼
摘要

OPC 通讯协议 OPC 通讯协议基础OPC 简介OPC 与 OPC UAOPC 逻辑对象模型OPC 通信方式Java 实现 OPC 的方式 Java 实现 OPC-clientOPC-D

OPC 通讯协议

OPC 通讯协议基础

OPC 简介

OPC 全称 OLE For Process Control,即用于控制过程的 OLE,是一个工业标准,管理该标准的国际组织是 OPC 基金会。

OPC 出现的目的是为不同的供应商设备与应用程序之间的接口标准化从而使其间的数据交换更加简单,因此,使我们可以开发不依靠于特定开发语言和开发环境的、可以自由组合的过程控制软件。

利用驱动器的系统连接
在这里插入图片描述
利用 OPC 控制的系统组成
在这里插入图片描述

OPC 的分层结构

OPC 对象中最上层的对象是 OPC 服务器,一个 OPC 服务器中可以设置一个以上的 OPC 组。OPC 服务器常对应于某种特定的控制设备,如 DCS 以及 PLC 等。

OPC 组是可以进行数据访问的多个 OPC 标签的集合,OPC 应用程序可以将需要的数据分组进行批量读取,也可以以组为单位启动或者停止数据访问。此外,OPC 组还提供组内 OPC 标签数据变化时向 OPC 应用程序通知的事件。

在这里插入图片描述

OPC 与 OPC UA

OPC DA 与 OPC UA 都是 OPC 协议的标准:

  • OPC 是一种通过微软 COM/DCOM 技术来实现自动化控制的协定,采用 C/S 架构。开发人员只需要按照 OPC 的标准编写 OPC-Client 访问 OPC-Server 进行读写操作即可实现与硬件设备的通信。OPC 的协定中包括:

    • DA (Data Access):访问数据的主要规范;

    • A&E (Alarm and Event):基于事件提供 Client 端订阅,事件触发后 Server 主动提交数据;

    • HDA (History Data Access):历史数据访问;

  • OPC UA 是 OPC 协议的新版,其不再依赖于 COM/DCOM 技术,这意味着其具有跨平台性,不再局限于 windows 系统。OPC UA 提供了可靠的通信机制,接口简单一致。

举例说明两者之间的区别:

对传统的三种不同类型OPC服务器的访问:数据访问 DA、报警和事件 AE、历史数据访问 HDA,要获得一个温度传感器的当前值、一个高温度事件和温度的历史平均值,要依次使用不同的命令执行;

而使用 OPC UA,仅用一个组件就非常容易地完成了。配置和工程的时间也因此可以大大缩短。

OPC 逻辑对象模型

包括3类对象:OPC Server 对象、OPC Group 对象、OPC Item 对象,每类对象都包括一系列接口。

OPC Server 对象

主要功能:

  • 创建和管理 OPC Group 对象;

  • 管理服务器内部的状态信息;

OPC Group 对象

主要功能:

  • 创建和管理 OPC Item 对象;

  • 管理 OPC Group 对象的内部状态信息;

  • OPC Server 内部实时数据的读写服务;

属性:

  • name:组名,由客户端自定义;

  • active:组的激活状态,若为 false 则组失效,无法对服务器进行读写;

  • update rate:更新速率(该值应大于服务器设定的最小值);

  • percent data band:数据死区;

注意:

  • Group 分为公共组和私有组:公共组对所有连接到服务器的客户端都有效;而私有组仅对建立该组的客户端有效;

OPC Item 对象

主要功能:

  • 用以描述实时数据,代表了与服务器数据源的连接;

属性:

  • name:项名,在服务器中对应 Item ID;

  • active:项的激活状态;

  • value:项的数据值;

  • quality:项的品质,代表数值的可信度;

  • timestamp:时间戳,代表数据的存取事件;

注意:

  • Item 的存储类型为 VARIANT;Item 的数据类型为 VARTYPE;

  • 一个项不能被 OPC 客户端直接访问,因为 OPC 协议中没有对应于项的 COM 接口,对项的访问必须通过 OPC Group 实现;

  • Item 在服务端的定义对应于硬件的实际地址。客户端连接到服务器后创建并添加 OPC Group,并创建一系列的 OPC Item,将逻辑上等价的一组 OPC Item 添加到 OPC Group 中即可通过组对象对数据进行读写操作;

OPC 通信方式

  • 同步通信:OPC Client 对 OPC Server 进行读取操作时,OPC Client 必须等到 OPC Server 完成对应操作后才能返回,在此期间 OPC Client 处于一直等待的状态。

  • 异步通信:OPC Client 对 OPC Server 进行读取操作时,OPC Client 发送请求后立即返回,不用等待 OPC Server,当 OPC Server 完成操作后再通知 OPC Client 程序。

  • 订阅:需要 OPC Server 支持OPC A&E规范,由 OPC Client 设定数据的变化限度,如果数据源的实时数据变化超过了该限度,OPC Server 通过回调返回数据给OPC Client。

Java 实现 OPC 的方式

OPC Client 开发大致流程

  1. COM 组件初始化;
  2. 创建服务器 Server 对象;
  3. 创建组 Group 对象;
  4. 创建项 Item 对象;
  5. 添加 Item 到 Group 中;
  6. 添加 Group 到 Server 对象中;
  7. 连接服务器,完成相应操作;
  8. COM 组件关闭

OPC DA

Java 关于 OPC DA 的开源库只有 Utgard 和 Jeasyopc,两者区别如下:

UtgardJeasyopc
linux支持不支持
Windows支持不支持
用户名和密码需要不需要
组查询支持不支持
压力测试(单线程同步)略快 7W 点约 4224ms略慢 7W 点约 22540ms
DCOM通过 DCOM 实现,需进行配置不需要配置
开源库现状作者删库跑路只支持 32 位系统

OPC UA

推荐使用 Eclipse 的 milo 开源库

Java 实现 OPC-client

本测试使用的 OPC-Server 软件为 KEPServerEX6,具体下载与使用参考博客OPCServer:使用KEPServer

OPC-DA

因为开源库 Jeasyopc 不支持 windows 和 linux 系统,且只支持 32 位系统,因此此处使用 Utgard 库实现。本测试采用虚拟机实现,使用的系统为 Windows 10 专业版,版本号 1903。

Utgard 开源库通过 DCOM 技术实现,因此首先需要配置 DCOM,参考博客OPC和DCOM配置

引入相应的依赖

        <dependency>            <groupId>org.kohsuke.jinteropgroupId>            <artifactId>j-interopartifactId>            <version>2.0.5version>        dependency>        <dependency>            <groupId>org.openscada.utgardgroupId>            <artifactId>org.openscada.opc.libartifactId>            <version>1.5.0version>        dependency>

从 OPC-Server 读取数据

public class OPCRead {    public static void main(String[] args) {        // 配置连接信息        final ConnectionInfORMation ci = new ConnectionInformation();        ci.setHost("localhost");         // 本机IP        ci.setDomain("");                // 域,为空就行        ci.setUser("OPCServer");         // 用户名        ci.setPassWord("OPCServer");     // 密码        // 配置 KEPServer        ci.setClsid("7BC0CC8E-482C-47CA-ABDC-0FE7F9C6E729"); // KEPServer 的注册表ID,可以在“组件服务”里看到        final String itemId = "通道 1.设备 1.标记 2";    // KEPServer 上配置的项的名字        // 启动服务        final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());        try {            // 连接服务器            server.connect();            // 创建 Group,用于对 Item 的访问            final Group group = server.addGroup("test");            // 将要访问的 Item 加入创建的 Group            final Item item = group.addItem(itemId);            // 读取 Item 状态            ItemState itemState = item.read(true);            // 获取 Item 的数据类型,该类型使用常量定义,见 JIVariant 类            int type = 0;            try {                type = itemState.getValue().getType(); // 类型实际是数字,用常量定义的            } catch (JIException e) {                e.printStackTrace();            }            // 打印 Item 相应状态            System.out.println(">>>监控项的数据类型是:" + type);            System.out.println(">>>监控项的时间戳是:" + itemState.getTimestamp().getTime());            System.out.println(">>>监控项的详细信息是:" + itemState);            // 若读到是 short 类型(对应数字 2)            if (type == JIVariant.VT_I2) {                short value = 0;                try {                    value = itemState.getValue().getObjectAsshort();                } catch (JIException e) {                    e.printStackTrace();                }                System.out.println(">>>short类型值: " + value);            }            // 删除 Group            server.removeGroup(group, true);        } catch (Exception e) {            throw new RuntimeException(e);        }    }}

从 OPC-Server 写入数据

public class OPCWrite {    public static void main(String[] args) {        // 配置连接信息        final ConnectionInformation ci = new ConnectionInformation();        ci.setHost("localhost");         // 本机IP        ci.setDomain("");                // 域,为空就行        ci.setUser("OPCServer");         // 用户名        ci.setPassword("OPCServer");     // 密码        // 配置 KEPServer        ci.setClsid("7BC0CC8E-482C-47CA-ABDC-0FE7F9C6E729"); // KEPServer 的注册表ID,可以在“组件服务”里看到        final String itemId = "通道 1.设备 1.标记 2";    // KEPServer 上配置的项的名字        // 启动服务        final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());        try {            // 连接服务器            server.connect();            // 创建 Group,用于对 Item 的访问            final Group group = server.addGroup("test");            // 将要访问的 Item 加入创建的 Group            final Item item = group.addItem(itemId);            // 写入前:打印 Item 状态及对应数据            printRead(item);            // 写入数据            item.write(new JIVariant("100"));            // 写入后:打印 Item 状态及对应数据            printRead(item);            // 删除 Group            server.removeGroup(group, true);        } catch (Exception e) {            throw new RuntimeException(e);        }    }        public static void printRead(Item item) throws JIException {        // 读取 Item 状态        ItemState itemState = item.read(true);        int type = 0;        try {            type = itemState.getValue().getType(); // 类型实际是数字,用常量定义的        } catch (JIException e) {            e.printStackTrace();        }        // 打印 Item 相应状态        System.out.println(">>>监控项的数据类型是:" + type);        System.out.println(">>>监控项的时间戳是:" + itemState.getTimestamp().getTime());        System.out.println(">>>监控项的详细信息是:" + itemState);        // 若读到是 short 类型(对应数字 2)        if (type == JIVariant.VT_I2) {            short value = 0;            try {                value = itemState.getValue().getObjectAsShort();            } catch (JIException e) {                e.printStackTrace();            }            System.out.println(">>>short类型值: " + value);        }    }}

OPC-UA

OPC-UA 是目前比较流行的协议,采用开源库 milo 实现,引入相应依赖:

        <dependency>            <groupId>org.eclipse.milogroupId>            <artifactId>sdk-clientartifactId>            <version>0.6.3version>        dependency>        <dependency>            <groupId>org.eclipse.milogroupId>            <artifactId>sdk-serverartifactId>            <version>0.6.3version>        dependency>

使用 opc-ua 实现数据读写:

public class OpcUaDemo {    public static void main(String[] args) throws Exception {        // 创建OPC UA客户端        OpcUaClient opcUaClient = createClient();        // 开启连接        opcUaClient.connect().get();        // 遍历节点        browsenode(opcUaClient, null);        // 读        readNode(opcUaClient);        // 写        writeNodeValue(opcUaClient);        readNode(opcUaClient);        // 关闭连接        opcUaClient.disconnect().get();    }        private static OpcUaClient createClient() throws Exception {        String endPointUrl = "opc.tcp://127.0.0.1:49320";        Path securityTmpdir = Paths.get(System.getProperty("java.io.tmpdir"), "security");        Files.createDirectories(securityTmpdir);        if (!Files.exists(securityTmpdir)) {            throw new Exception("unable to create security dir: " + securityTmpdir);        }        return OpcUaClient.create(endPointUrl,                endpoints ->                        endpoints.stream()    .filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri()))    .findFirst(),                configBuilder ->                        configBuilder    .setApplicationName(LocalizedText.english("KEPServerEX/UA Client Driver"))    .setApplicationUri("urn:Thinkbook-ZQF:Kepware.KEPServerEX.V6:UA%20Client%20Driver")    //访问方式    .setIdentityProvider(new AnonymousProvider())    .setRequestTimeout(UInteger.valueOf(5000))    .build()        );    }        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);        }    }        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();        //标识符        System.out.println(identifier + ": " + String.valueOf(value.getValue().getValue()));    }        private static void writeNodeValue(OpcUaClient client) throws Exception {        //节点        NodeId nodeId = new NodeId(2, "通道 1.设备 1.标记 1");        short i = 3;        //创建数据对象,此处的数据对象一定要定义类型,不然会出现类型错误,导致无法写入        DataValue nowValue = new DataValue(new Variant(i), null, null);        //写入节点数据        StatusCode statusCode = client.writeValue(nodeId, nowValue).join();        System.out.println("结果:" + statusCode.isGood());    }}

模拟数据进行代码测试

OPC-DA 代码验证

使用 KEPServerEX 6 作为 OPC-Server 进行测试,百度网盘下载链接如下:

链接:https://pan.baidu.com/s/1pigppR62xTsE_4ecXx9m8Q?pwd=3aig 提取码:3aig

在界面上可以右键单击标记名称进行数据格式的设置

在这里插入图片描述
单击工具栏最后一个,创建一个 OPC Quick client,可以观察到,此时通道 1.设备 1.标记 2的值为 0

在这里插入图片描述
修改 opc-da 写入程序,写入数值为 300

在这里插入图片描述
执行写入程序,查看 client 中的对应值,写入成功

在这里插入图片描述
使用读取程序对数据进行读取,同样可以读取到对应的数值

在这里插入图片描述

OPC-UA 代码验证

在验证之前首先右键项目,选择属性,修改 OPC-UA 属性中的”允许匿名登录“为是

在这里插入图片描述

配置写入数据的方法,将对应的数值从 300 修改为 3

在这里插入图片描述

执行代码,查看输出结果

在这里插入图片描述

来源地址:https://blog.csdn.net/zqf787351070/article/details/128275537

--结束END--

本文标题: 【应用】OPC 通讯协议

本文链接: https://www.lsjlt.com/news/441567.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 【应用】OPC 通讯协议
    OPC 通讯协议 OPC 通讯协议基础OPC 简介OPC 与 OPC UAOPC 逻辑对象模型OPC 通信方式Java 实现 OPC 的方式 Java 实现 OPC-clientOPC-D...
    99+
    2023-10-24
    网络 java 网络协议
  • opc协议golang实现
    随着工业自动化的不断发展,OPC协议越来越成为工业领域中数据通讯的主流协议。而Golang作为一种高性能、可靠性强的编程语言,也越来越受到工业自动化领域的关注。本文将介绍如何使用Golang语言实现OPC协议的数据通讯,以帮助读者更好地理解...
    99+
    2023-05-14
  • MQ基础篇_通讯协议
    通讯协议是指计算机或其他设备之间进行数据交换时所遵循的规则和约定。在MQ(Message Queue)系统中,通讯协议用于定义消息的...
    99+
    2023-10-11
    MQ
  • Java 001:通过OPC UA协议连接KepServerEx进行读、写、订阅操作
    参考前辈的踩坑记录https://blog.csdn.net/weixin_45411740/article/details/124275985spm=1001.2014.3001.5502,我Hyb在2023-3-15调通了自己的Java...
    99+
    2023-09-09
    java 物联网 rabbitmq eclipse Powered by 金山文档
  • 串行通信协议---HART协议
    实际应用中,HART协议是仅次于Modbus协议的最接近统一现场总线的标准,主要是在4~20mA电流信号上面叠加数字信号,物理层采用Bell 202标准的FSK技术成功实现模拟信号和数字信号双向同时通信而互不干扰。HART协议规定了传输的物...
    99+
    2023-08-21
    网络 网络协议 服务器
  • Mysql通讯协议的示例分析
    小编给大家分享一下Mysql通讯协议的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1.Mysql的连接方式要了解Mys...
    99+
    2024-04-02
  • Go语言实现UDP协议及TCP通讯
    ⼀、使用Golang创建⼀一个TCP连接 1.服务端处理理流程 a.监听端口b.接受客户端的链接c.创建Goroutine,处理这个链接(⼀个服务端要链接多个客户端,所以使用Goro...
    99+
    2024-04-02
  • Websocket通信协议在数字孪生中的应用
    目录写在前面数字孪生中的通讯协议Websocket 是什么Websocket 配置基于 Node.js 的 Websocket 服务器搭建基于Vue 的 Websocket 客户端搭...
    99+
    2024-04-02
  • 【网络原理】应用层协议 与 传输层协议
    ✨个人主页:bit me👇 ✨当前专栏:Java EE初阶👇 目 录 🏉一. 应用层协议⚾️二. 传输层协议👒1. UDP 协议...
    99+
    2023-08-18
    网络 服务器 网络协议
  • 如何使用linux shell 脚本实现tcp/upd协议通讯
    本篇内容主要讲解“如何使用linux shell 脚本实现tcp/upd协议通讯”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何使用linux shell 脚本实现tcp/upd协议通讯”吧!...
    99+
    2023-06-09
  • Mqtt通信协议详解
    文章目录 1. 简介mqtt2.mqtt协议实现3.Mqtt数据包4. QoS等级5. mqtt传输安全保证5.1 应用层5.2 传输层5.2.1 TLS安全协议 5.3 网络层 ...
    99+
    2023-09-03
    服务器 网络
  • linux中shell脚本如何实现tcp/upd协议通讯
    小编给大家分享一下linux中shell脚本如何实现tcp/upd协议通讯,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!linux 设备里面有个比较特殊的文件: ...
    99+
    2023-06-13
  • MySQL有几种通信协议
    小编给大家分享一下MySQL有几种通信协议,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Mysql四种通信协议(linux下本地...
    99+
    2024-04-02
  • 模拟实现应用层协议
    模拟实现应用层协议 文章目录 模拟实现应用层协议应用层再谈协议 序列化和反序列化 网络版计算器自定义协议利用Json进行序列化和反序列化json库的安装条件编译 ...
    99+
    2023-09-12
    网络
  • redis protocol通信协议及使用详解
    目录简介redis的高级用法Redis中的piplineRedis中的Pub/SubRESP protocolSimple StringsBulk StringsRESP Integ...
    99+
    2024-04-02
  • go语言中的udp协议及TCP通讯怎么配置
    这篇“go语言中的udp协议及TCP通讯怎么配置”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“go语言中的udp协议及TCP...
    99+
    2023-06-30
  • go语言中的udp协议及TCP通讯实现示例
    目录udp协议server端client端TCP通讯(基本)服务端客户端TCP通讯并发服务器服务端客户端udp协议 server端 package main import ( "f...
    99+
    2024-04-02
  • 一文搞懂UART通信协议
    目录 1、UART简介 2、UART特性 3、UART协议帧 3.1、起始位 3.2、数据位 3.3、奇偶校验位 3.4、停止位 4、UART通信步骤 1、UART简介 UART(Universal Asynchronous Receiv...
    99+
    2023-10-12
    UART协议 嵌入式 通信协议 单片机
  • java支持哪些应用层协议
    java中支持的应用层协议有:1.HTTP协议,超文本传输协议;2.DNS协议,将域名转换为IP地址;3.FTP协议,高精度时间同步协议;4.SMTP协议,电子邮件传输协议;java中支持的应用层协议有以下几种HTTP协议HTTP协议是一种...
    99+
    2024-04-02
  • mysql中有哪些通信协议
    这期内容当中小编将会给大家带来有关mysql中有哪些通信协议,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1、说明MySQL客户端/服务器通信协议是半双工的:无论何时,无论是服务器向客户端发送数据,还是客...
    99+
    2023-06-15
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作