【应用】OPC 通讯协议

这篇具有很好参考价值的文章主要介绍了【应用】OPC 通讯协议。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

OPC 通讯协议基础

OPC 简介

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

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

利用驱动器的系统连接
【应用】OPC 通讯协议
利用 OPC 控制的系统组成
【应用】OPC 通讯协议

OPC 的分层结构

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

OPC 组是可以进行数据访问的多个 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,两者区别如下:

Utgard Jeasyopc
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.jinterop</groupId>
            <artifactId>j-interop</artifactId>
            <version>2.0.5</version>
        </dependency>
        <dependency>
            <groupId>org.openscada.utgard</groupId>
            <artifactId>org.openscada.opc.lib</artifactId>
            <version>1.5.0</version>
        </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);
        }
    }

    /**
     * 读取 Item 状态、数据
     * @param item item
     * @throws JIException
     */
    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.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>

使用 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();
    }

    /**
     * 创建 opc-ua 客户端
     * @return OpcUaClient
     * @throws Exception
     */
    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()
        );
    }

    /**
     * 遍历树形节点
     * @param client 客户端
     * @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();
        //标识符
        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.标记 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 通讯协议
单击工具栏最后一个,创建一个 OPC Quick client,可以观察到,此时通道 1.设备 1.标记 2的值为 0

【应用】OPC 通讯协议
修改 opc-da 写入程序,写入数值为 300

【应用】OPC 通讯协议
执行写入程序,查看 client 中的对应值,写入成功

【应用】OPC 通讯协议
使用读取程序对数据进行读取,同样可以读取到对应的数值

【应用】OPC 通讯协议

OPC-UA 代码验证

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

【应用】OPC 通讯协议

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

【应用】OPC 通讯协议

执行代码,查看输出结果

【应用】OPC 通讯协议文章来源地址https://www.toymoban.com/news/detail-414331.html

到了这里,关于【应用】OPC 通讯协议的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 通讯协议048——全网独有的OPC HDA知识一之接口(三)IOPCHDA_Server

    本文简单介绍OPC HDA规范的IOPCHDA_Server接口方法,更多通信资源请登录网信智汇(wangxinzhihui.com)。 1)HRESULT   GetItemAttributes (pdwCount , ppdwAttrID, ppszAttrName, ppszAttrDesc, ppvtAttrDataType) 此函数返回服务器支持的项属性。也支持供应商特定的属性。供应商提供的属性可用于允许客户端访问

    2024年02月11日
    浏览(36)
  • RS-485 通讯协议简介

    与 CAN 类似,RS-485 是一种工业控制环境中常用的通讯协议,它具有抗干扰能力强、传输距离远的特点。RS-485 通讯协议由 RS-232协议改进而来,协议层不变,只是改进了物理层,因而保留了串口通讯协议应用简单的特点。 1 RS-485的物理层 从《CAN—通讯实验》章节中了解到,差分

    2024年02月05日
    浏览(40)
  • OPC通信从入门到精通_1_OPC基础知识及简单C#程序编写(OPCDA,OPCUA简介;OPC通信数据流框架图;C#程序编写)

    OPC的诞生及历史 :软件进行开发时需要与各种不同的协议进行对接,例如Modbus协议等,当设备很多,协议很多的情况下,上位机与硬件的沟通就会变得很麻烦,所以就有了将这些协议抽象出一个标准接口,对于软件人员就无需和协议对接,只需要对接接口即可,因此OPC就诞生

    2024年02月15日
    浏览(46)
  • 【Java基础教程】(四十七)网络编程篇:网络通讯概念,TCP、UDP协议,Socket与ServerSocket类使用实践与应用场景~

    了解多线程与网络编程的操作关系; 了解网络程序开发的主要模式; 了解 TCP 程序的基本实现; 在Java中,网络编程的核心意义是实现不同电脑主机之间的数据交互。Java采用了一种简化的概念,将这个过程进一步抽象为JVM(Java虚拟机)进程之间的通信。可以在同一台电脑上

    2024年02月15日
    浏览(63)
  • 通讯编程006——NodeJS OPC UA Client开发简单教程

    本文介绍如何在NodeJS环境下开发OPC UA Client,通过本文可以对OPC UA的基本概念有所了解,掌握OPC UA的本质。相关软件请登录网信智汇(wangxinzhihui.com)。 开发步骤如下: 1)首先需要安装nodejs,要求版本至少是12。 2)创建项目目录,在cmd下进入项目目录下,执行如下指令: 1)n

    2024年02月09日
    浏览(38)
  • Node-Red如何与OPC UA服务器通讯

    本篇内容主要介绍Node-Red如何通过插件node-red-contrib-opcua来从OPC UA服务器读写数据,仍然用KEPServer来模拟OPC UA服务器,UaExpert用来测试连接和获取变量NodeId。 KEPServer的安装参考文章Node-Red如何与OPC DA服务器通讯。 安装UaExpert没有太多要注意的地方,依次下一步就行了 接下来安装

    2024年03月17日
    浏览(56)
  • 通讯网关软件014——利用CommGate X2HTTP实现HTTP访问OPC Server

    本文介绍利用CommGate X2HTTP实现HTTP访问OPC Server。CommGate X2HTTP是宁波科安网信开发的网关软件,软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示,SCADA系统配置OPC Server,现在上位机需要通过Http Client软件来获SCADA的数据。 【解决方案】设置网关机,与OP

    2024年02月07日
    浏览(51)
  • 根据源码,模拟实现 RabbitMQ - 网络通讯设计,自定义应用层协议,实现 BrokerServer (8)

    目录 一、网络通讯协议设计 1.1、交互模型 1.2、自定义应用层协议 1.2.1、请求和响应格式约定 ​编辑 1.2.2、参数说明 1.2.3、具体例子 1.2.4、特殊栗子 1.3、实现 BrokerServer 1.3.1、属性和构造 1.3.2、启动 BrokerServer 1.3.3、停止 BrokerServer 1.3.4、处理每一个客户端连接 1.3.5、读取请求

    2024年02月10日
    浏览(48)
  • 通讯网关软件003——利用CommGate X2Mbt实现Modbus TCP访问OPC Server

    本文介绍利用CommGate X2Mbt实现Modbus访问OPC Server。CommGate X2MBT是宁波科安网信开发的网关软件,软件可以登录到网信智汇(wangxinzhihui.com)下载。 【案例】如下图所示,SCADA系统配置OPC Server,现在上位机需要通过Modbus主站软件来获SCADA的数据。 【解决方案】设置网关机,与OP CServ

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

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

    2024年02月14日
    浏览(46)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包