• Stars
    star
    710
  • Rank 63,371 (Top 2 %)
  • Language
    C#
  • License
    GNU Lesser Genera...
  • Created about 6 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

一个通用的opc ua客户端类库,基于.net 4.6.1创建,基于官方opc ua基金会跨平台库创建,封装了节点读写,批量节点读写,引用读取,特性读取,历史数据读取,方法调用,节点订阅,批量订阅等操作。还提供了一个节点浏览器工具。

OpcUaHelper

Build status NuGet Status NuGet Download Gitter NetFramework Visual Studio License status copyright status

一个通用的二次封装的opc ua客户端类库,基于.net 4.6.1创建,基于官方opc ua基金会跨平台库创建,方便的实现和OPC Server进行数据交互。本类库每个几个月就同步官方的类库。

免责声明

OpcUa相关的组件版权归OPC UA基金会所有,使用本库时请遵循OPC UA基金会的授权规则。

  1. 非商用情况,如果你的项目仅仅是自己公司使用的,那么需要注册为OPC基金会的成员,否则,必须开源。
  2. 商用都是需要额外授权的,请联系OPC基金会。

FormBrowseServer

在开发客户端之前,需要使用本窗口来进行查看服务器的节点状态,因为在请求服务器的节点数据之前,必须知道节点的名称,而节点的名称可以通过这个窗口获取。以下演示实例化操作

OpcUaHelper.Forms.FormBrowseServer formBrowseServer = new Forms.FormBrowseServer( );
formBrowseServer.ShowDialog( );

当然你可以固定住这个地址,传入地址即可,此处为示例:

OpcUaHelper.Forms.FormBrowseServer formBrowseServer = new Forms.FormBrowseServer( "opc.tcp://127.0.0.1:62541/SharpNodeSettings/OpcUaServer" );
formBrowseServer.ShowDialog( );

界面效果如下,包含了节点的查看,订阅操作,双击值表格,还可以修改服务器的值(如果这个节点支持修改的话),查看节点的信息: Picture

Server Prepare

如果你没有opc ua的服务器的话,可以参照本示例的服务器,本示例的服务器是项目 SharpNodeSettings 的示例。可以直接下载这个项目运行服务器软件。

或者选择在线的客户端测试: opc.tcp://118.24.36.220:62547/DataAccessServer

OpcUaClient

实例化操作

OpcUaClient m_OpcUaClient = new OpcUaClient();

设置匿名连接

m_OpcUaClient.UserIdentity = new UserIdentity( new AnonymousIdentityToken( ) );

设置用户名连接

m_OpcUaClient.UserIdentity = new UserIdentity( "user", "password" );

使用证书连接

X509Certificate2 certificate = new X509Certificate2( "[证书的路径]", "[密钥]", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable );
m_OpcUaClient.UserIdentity = new UserIdentity( certificate );

设置完连接的权限之后,就可以真正的启动连接操作了,连接的操作必须要放到try...catch...之前,必须使用async标记方法

private async void button1_Click( object sender, EventArgs e )
{
    // connect to server, this is a sample
    try
    {
        await m_OpcUaClient.ConnectServer( "opc.tcp://127.0.0.1:62541/SharpNodeSettings/OpcUaServer" );
    }
    catch (Exception ex)
    {
        ClientUtils.HandleException( "Connected Failed", ex );
    }
}

Read/Write Node

如果我们想要读取上图节点浏览器的温度数据,节点字符串为

ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度

类型为Int16, 所以我们使用下面的方法读取

try
{
    short value = m_OpcUaClient.ReadNode<short>( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度" );
}
catch(Exception ex)
{
    ClientUtils.HandleException( this.Text, ex );
}

你也可以使用异步读取,只是外面的方法上需要使用async标记

try
{
    short value = await m_OpcUaClient.ReadNodeAsync<short>( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度" );
}
catch (Exception ex)
{
    ClientUtils.HandleException( this.Text, ex );
}

接下来写入节点操作,如果该节点的权限不支持写的话,就会触发异常

try
{
    m_OpcUaClient.WriteNode( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度", (short)123 );
}
catch (Exception ex)
{
    ClientUtils.HandleException( this.Text, ex );
}

批量读取的操作,分为类型不一致和类型一致两种操作,下面都做个示例

try
{
    // 添加所有的读取的节点,此处的示例是类型不一致的情况
    List<NodeId> nodeIds = new List<NodeId>( );
    nodeIds.Add( new NodeId( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度" ) );
    nodeIds.Add( new NodeId( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/风俗" ) );
    nodeIds.Add( new NodeId( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/转速" ) );
    nodeIds.Add( new NodeId( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/机器人关节" ) );
    nodeIds.Add( new NodeId( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/cvsdf" ) );
    nodeIds.Add( new NodeId( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/条码" ) );
    nodeIds.Add( new NodeId( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/开关量" ) );

    // dataValues按顺序定义的值,每个值里面需要重新判断类型
    List<DataValue> dataValues = m_OpcUaClient.ReadNodes( nodeIds.ToArray() );



    // 如果你批量读取的值的类型都是一样的,比如float,那么有简便的方式
    List<string> tags = new List<string>( );
    tags.Add( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/风俗" );
    tags.Add( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/转速" );

    // 按照顺序定义的值
    List<float> values = m_OpcUaClient.ReadNodes<float>( tags.ToArray() );

}
catch (Exception ex)
{
    ClientUtils.HandleException( this.Text, ex );
}

批量写入的操作如下:

try
{
    // 此处演示写入一个short,2个float类型的数据批量写入操作
    bool success = m_OpcUaClient.WriteNodes( new string[] {
        "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度",
        "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/风俗",
        "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/转速"},
        new object[] {
            (short)1234,
            123.456f,
            123f
        } );
    if (success)
    {
        // 写入成功
    }
    else
    {
        // 写入失败,一个失败即为失败
    }
}
catch (Exception ex)
{
    ClientUtils.HandleException( this.Text, ex );
}

Read History

try
{
    // 此处演示读取历史数据的操作,读取8月18日12点到13点的数据,如果想要读取成功,该节点是支持历史记录的
    List<float> values = m_OpcUaClient.ReadHistoryRawDataValues<float>( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/转速",
        new DateTime( 2018, 8, 18, 12, 0, 0 ), new DateTime( 2018, 8, 18, 13, 0, 0 ) ).ToList( );
    // 列表数据可用于显示曲线之类的操作

}
catch (Exception ex)
{
    ClientUtils.HandleException( this.Text, ex );
}

Read Attribute

本类库支持读取一个节点的相关的所有的属性,主要包含了值,描述,名称,权限等级,等等操作

try
{
    OpcNodeAttribute[] nodeAttributes = m_OpcUaClient.ReadNoteAttributes( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度" );
    foreach (var item in nodeAttributes)
    {
        Console.Write( string.Format( "{0,-30}", item.Name ) );
        Console.Write( string.Format( "{0,-20}", item.Type ) );
        Console.Write( string.Format( "{0,-20}", item.StatusCode ) );
        Console.WriteLine( string.Format( "{0,20}", item.Value ) );
    }
                
    // 输出如下
    //  Name                          Type                StatusCode                         Vlaue

    //  NodeClass                     Int32               Good                                   2
    //  BrowseName                    QualifiedName       Good                              2:温度
    //  DisplayName                   LocalizedText       Good                                温度
    //  Description                   LocalizedText       Good                                    
    //  WriteMask                     UInt32              Good                                  96
    //  UserWriteMask                 UInt32              Good                                  96
    //  Value                         Int16               Good                              -11980
    //  DataType                      NodeId              Good                                 i=4
    //  ValueRank                     Int32               Good                                  -1
    //  ArrayDimensions               Null                Good                                    
    //  AccessLevel                   Byte                Good                                   3
    //  UserAccessLevel               Byte                Good                                   3
    //  MinimumSamplingInterval       Double              Good                                   0
    //  Historizing                   Boolean             Good                               False
}
catch (Exception ex)
{
    ClientUtils.HandleException( this.Text, ex );
}

Read Reference

本类库支持读取一个节点的关联节点,包含了几个简单的基本信息

try
{
    ReferenceDescription[] references = m_OpcUaClient.BrowseNodeReference( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端" );
    foreach (var item in references)
    {
        Console.Write( string.Format( "{0,-30}", item.NodeClass ) );
        Console.Write( string.Format( "{0,-30}", item.BrowseName ) );
        Console.Write( string.Format( "{0,-20}", item.DisplayName ) );
        Console.WriteLine( string.Format( "{0,-20}", item.NodeId.ToString( ) ) );
    }

    ;
    // 输出如下
    //  NodeClass                     BrowseName                      DisplayName           NodeId

    //  Variable                      2:温度                          温度                  ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度
    //  Variable                      2:风俗                          风俗                  ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/风俗
    //  Variable                      2:转速                          转速                  ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/转速
    //  Variable                      2:机器人关节                    机器人关节            ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/机器人关节
    //  Variable                      2:cvsdf                         cvsdf                 ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/cvsdf
    //  Variable                      2:条码                          条码                  ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/条码
    //  Variable                      2:开关量                        开关量                ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/开关量
}
catch (Exception ex)
{
    ClientUtils.HandleException( this.Text, ex );
}

Subscript

订阅数据分为订阅单个节点和批量订阅操作,下面分别演示,本订阅的机制基于官方库进行了二次设计,方便扩展实现

  1. 举例说明,有个节点,ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度 的数据需要订阅,订阅后再界面上的 textBox3 上显示出来
m_OpcUaClient.AddSubscription( "A", "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度", SubCallback );

这个关键字 A 是自己定义的,方便回调判断或是取消订阅用的,方法 SubCallback 是一个回调方法,代码如下:

private void SubCallback(string key, MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args )
{
    if (InvokeRequired)
    {
        Invoke( new Action<string, MonitoredItem, MonitoredItemNotificationEventArgs>( SubCallback ), key, monitoredItem, args );
        return;
    }

    if (key == "A")
    {
        // 如果有多个的订阅值都关联了当前的方法,可以通过key和monitoredItem来区分
        MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
        if (notification != null)
        {
            textBox3.Text = notification.Value.WrappedValue.Value.ToString( );
        }
    }
}

当服务器的值变化之后,文本框的值也会变化。如果想要取消订阅

m_OpcUaClient.RemoveSubscription( "A" );
  1. 举例说明批量订阅,此处举例批量订阅3个点节点,按顺序在 textBox5 , textBox9 , textBox10 文本框按照顺序进行显示,此处比上面的操作需要麻烦一点, 需要缓存下批量订阅的节点信息
// 缓存的批量订阅的节点
private string[] MonitorNodeTags = null;

private void button5_Click( object sender, EventArgs e )
{
    // 多个节点的订阅
    MonitorNodeTags = new string[]
    {
        textBox6.Text,
        textBox7.Text,
        textBox8.Text,
    };
    m_OpcUaClient.AddSubscription( "B", MonitorNodeTags, SubCallback );
}

然后修改下回调函数

private void SubCallback(string key, MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args )
{
    if (InvokeRequired)
    {
        Invoke( new Action<string, MonitoredItem, MonitoredItemNotificationEventArgs>( SubCallback ), key, monitoredItem, args );
        return;
    }

    if (key == "A")
    {
        // 如果有多个的订阅值都关联了当前的方法,可以通过key和monitoredItem来区分
        MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
        if (notification != null)
        {
            textBox3.Text = notification.Value.WrappedValue.Value.ToString( );
        }
    }
    else if(key == "B")
    {
        // 需要区分出来每个不同的节点信息
        MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
        if (monitoredItem.StartNodeId.ToString( ) == MonitorNodeTags[0])
        {
            textBox5.Text = notification.Value.WrappedValue.Value.ToString( );
        }
        else if (monitoredItem.StartNodeId.ToString( ) == MonitorNodeTags[1])
        {
            textBox9.Text = notification.Value.WrappedValue.Value.ToString( );
        }
        else if (monitoredItem.StartNodeId.ToString( ) == MonitorNodeTags[2])
        {
            textBox10.Text = notification.Value.WrappedValue.Value.ToString( );
        }
    }
}

Thanks

感谢使用本库,如何有任何的疑问,可以联系作者,也可以加群讨论:592132877

创作不易,感谢打赏

Picture

More Repositories

1

HslCommunication

A very popular industrial Internet of Things communication plug-in. Using this dll can be very convenient, stable, and fast to obtain data from PLC equipment of multiple brands, and also supports redis, mqtt, websocket, etc., which can let your data on the network Free transmission, reducing enterprise development costs.
C#
1,316
star
2

ClientServerProject

一个C-S模版,该模版由三部分的程序组成,一个服务端运行的程序,一个客户端运行的程序,还有一个公共的组件,实现了基础的账户管理功能,版本控制,软件升级,公告管理,消息群发,共享文件上传下载,批量文件传送功能。具体的操作方法见演示就行。本项目的一个目标是:提供一个基础的中小型系统的C-S框架,客户端有三种模式,无缝集成访问,winform版本,wpf版本,asp.net mvc版本,方便企业进行中小型系统的二次开发和个人学习。同时网络组件方便的支持读写三菱和西门子PLC的数据,详细见Readme
C#
1,226
star
3

HslControlsDemo

HslControls控件库的使用demo,HslControls是一个工业物联网的控件库,基于C#开发,配套HslCommunication组件可以实现工业上位机软件的快速开发,支持常用的工业图形化控件,快速的集成界面开发。 主要包含了按钮,开关,进度条,信号灯,数码管,时钟,曲线显示控件,仪表盘控件,管道控件,瓶子控件,饼图控件,传送带控件,温度计控件,鼓风机控件,阀门控件,电池控件等等。
C#
595
star
4

SharpNodeSettings

一个设备及节点配置类库,基于HslCommunication.dll创建,方便的实现PLC根据配置文件动态创建,并支持自动写入相应的服务器对象。
C#
233
star
5

RemoteMonitor

本项目是一个利用HslCommunication组件读取PLC的示例项目,演示了后台从PLC循环读取到前台显示,并推送给在线客户端,客户端同步显示并画实时曲线图。支持web端同步的数据显示,支持web端远程操作PLC,安卓端数据显示,远程操作PLC
JavaScript
211
star
6

ModBusTcpTools

一个Modbus的C#开发示例,运用HslCommunication.dll组件库实现,包含了一个服务端的演示和一个客户端演示,客户端可用于进行Modbus测试,详细见ReadMe.md。
C#
66
star
7

HslCommunicationJavaDemo

HslCommunication的Java版本的项目
Java
63
star
8

HslCommunicationPython

HslCommunication的python版本
Python
43
star
9

OpcUaHelperOld

一个OPC UA客户端二次封装类,使用本组件提供的类库,可以简单便捷的读写OPC-UA服务器上的数据,引用,方法等等操作。本版本为旧版,新版请参照:https://github.com/dathlin/OpcUaHelper
C#
31
star
10

NetChatRoom

一个基于HslCommunication实现的局域网实时聊天的项目,采用C-S架构实现,除了实现基本的消息发送,还包括了在线信息的管理,系统消息的查看。
C#
23
star
11

FileManagment

一个使用HslCommunication组件实现了文件管理引擎,在客户端块演示了文件的上传,下载,删除,文件集获取操作。
C#
22
star
12

WebSpiderLearnAndTest

A simple C# web spider application , It catches all the hotels of hangzhou from xiecheng 【一个简单的爬虫程序,提供了一个基础的框架,实现了对AJAX页面爬虫,并测试学习几个例子,详细见README。】
C#
22
star
13

HslRedisDesktop

Redis Winform Desktop
C#
18
star
14

HSLSharp

采集框架第一个版本,如有bug,希望大家发起pull request
C#
17
star
15

ClassicGame

some simple games base on C# ,such as Tetris. [一个简单的C#游戏,以俄罗斯方块为基础,提炼一个简单的游戏框架,方便学习算法,GDI+,C#]
C#
13
star
16

ThriftDemo

一个Thrift的学习测试项目,服务器端实现从PLC进行采集数据,推送到Thrift,以接口的形式对外公开数据,方便客户端获取到服务器的不同数据,并且支持从客户端进行远程操控PLC
C#
8
star
17

HslMRpcLearn

基于HslCommunication的远程读写PLC,JAVA,Python远程读写PLC的示例代码。
C#
7
star
18

OpcUaStudy

A project for personal learning opc ua technology, opc part of the code from the opc Foundation, where only for learning and testing.
C#
7
star
19

Gobang-

a simple computer game, you can play with computer , we designed a simple computer AI , we need you to improve the AI level , to build a more smart AI , and also helps improve our program skills [一个简单的五子棋游戏,实现了初级算法,需要大家一起来努力创建一个更加聪明的电脑AI,也用来方便新手学习。]
C#
6
star
20

MyNuGet

一个基于本地的NuGet服务器,用于本地或是公司的.net的包管理器。
ASP
4
star
21

RoboDKHelper

RoboDK通讯用的C#组件
C#
4
star
22

GameHelper3366

this is a game help tool, help user to play hige score on 3366.com
C#
2
star
23

HslWebApplication

一个用于ASP.NET MVC和ASP.NET CORE学习的项目
CSS
1
star
24

WebApplicationLearn

一个用于自身学习ASP.NET的项目,不具有生产条件,仅用于学习,测试技术
JavaScript
1
star
25

Static

Static Resources For test
C#
1
star