OpcUaHelper的基本使用(转载)

首先安装 第三方插件
前期准备
准备好开发的IDE,首选Visual Studio2017版本,新建项目,或是在你原有的项目上进行扩展。注意:项目的.NET Framework版本最低为4.6
在这里插入图片描述
然后在窗体的界面新增引用:

using OpcUaHelper;

接下就可以愉快码代码了。

FromBrowseServer
使用此窗口服务可以查看服务器的节点状态。

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( );

在这里插入图片描述

OPC UA Client
实例化操作

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中,异步执行 使用 ClientUtils.HandleException( “Connected Failed”, ex );抓取对应错误信息

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=欧姆龙.设备 1.001

类型为int16,使用下面方法读取

try
{
    short value = m_OpcUaClient.ReadNode<short>( "ns=2;s=欧姆龙.设备 1.001" );
}
catch(Exception ex)
{
    ClientUtils.HandleException( this.Text, ex );
}

异步读取

try
{
    short value = await m_OpcUaClient.ReadNodeAsync<short>( "ns=2;s=欧姆龙.设备 1.001" );
}
catch (Exception ex)
{
    ClientUtils.HandleException( this.Text, ex );
}

写入节点

try
{
    m_OpcUaClient.WriteNode( "ns=2;s=欧姆龙.设备 1.001", (short)123 );
}
catch (Exception ex)
{
    ClientUtils.HandleException( this.Text, ex );
}

批量读取(类型一致)

try
{
    // 如果你批量读取的值的类型都是一样的,比如float,那么有简便的方式
    List<string> tags = new List<string>( );
    tags.Add( "ns=2;s=欧姆龙.设备 1.001" );
    tags.Add( "ns=2;s=欧姆龙.设备 1.002" );

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

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

批量读取(类型不一致)

try
{
    // 添加所有的读取的节点,此处的示例是类型不一致的情况
    List<NodeId> nodeIds = new List<NodeId>( );
    nodeIds.Add( new NodeId( "ns=2;s=欧姆龙.设备 1.001" ) );
    nodeIds.Add( new NodeId( "ns=2;s=欧姆龙.设备 1.002" ) );
    nodeIds.Add( new NodeId( "ns=2;s=欧姆龙.设备 1.003" ) );
    nodeIds.Add( new NodeId( "ns=2;s=欧姆龙.设备 1.004" ) );
    nodeIds.Add( new NodeId( "ns=2;s=欧姆龙.设备 1.005" ) );
    nodeIds.Add( new NodeId( "ns=2;s=欧姆龙.设备 1.006" ) );
    nodeIds.Add( new NodeId( "ns=2;s=欧姆龙.设备 1.007" ) );

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


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

批量写入

try
{
    // 此处演示写入一个short,2个float类型的数据批量写入操作
    bool success = m_OpcUaClient.WriteNodes( new string[] {
        "ns=2;s=欧姆龙.设备 1.001",
        "ns=2;s=欧姆龙.设备 1.002",
        "ns=2;s=欧姆龙.设备 1.003"},
        new object[] {
            (short)1234,
            123.456f,
            123f
        } );
    if (success)
    {
        // 写入成功
    }
    else
    {
        // 写入失败,一个失败即为失败
    }
}
catch (Exception ex)
{
    ClientUtils.HandleException( this.Text, ex );
}

读取Attrubute

try
{
    OpcNodeAttribute[] nodeAttributes = m_OpcUaClient.ReadNoteAttributes( "ns=2;s=欧姆龙.设备 1.001" );
    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 );
}

读取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 );
}

订阅(单节点订阅)

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" );

订阅(批量订阅)
此处举例批量订阅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( );
        }
    }
}

参考地址:
https://www.cnblogs.com/davisdabing/p/17841183.html

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值