首页 > 其他分享 >OpcUaHelper的基本使用

OpcUaHelper的基本使用

时间:2023-11-18 21:57:06浏览次数:31  
标签:基本 Devices 分厂 OpcUaHelper 使用 new ModbusTcp ns 客户端

  • FromBrowseServer

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

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

2 formBrowseServer.ShowDialog( ); 

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

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

2 formBrowseServer.ShowDialog( ); 

  •  OPC UA Client

  • 实例化操作

 1 OpcUaClient m_OpcUaClient = new OpcUaClient(); 

  • 设置匿名连接

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

  • 设置用户名连接

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

  • 使用证书连接

1 X509Certificate2 certificate = new X509Certificate2( "[证书的路径]", "[密钥]", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable );
2 m_OpcUaClient.UserIdentity = new UserIdentity( certificate );
  • 正式开始连接服务器,连接操作必须放在Try中,异步执行。

 1 private async void button1_Click( object sender, EventArgs e )
 2 {
 3     // connect to server, this is a sample
 4     try
 5     {
 6         await m_OpcUaClient.ConnectServer( "opc.tcp://127.0.0.1:62541/SharpNodeSettings/OpcUaServer" );
 7     }
 8     catch (Exception ex)
 9     {
10         ClientUtils.HandleException( "Connected Failed", ex );
11     }
12 }
  • Read/Write Node

  • 节点字符设为

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

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

1 try
2 {
3     short value = m_OpcUaClient.ReadNode<short>( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度" );
4 }
5 catch(Exception ex)
6 {
7     ClientUtils.HandleException( this.Text, ex );
8 }
  • 异步读取

1 try
2 {
3     short value = await m_OpcUaClient.ReadNodeAsync<short>( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度" );
4 }
5 catch (Exception ex)
6 {
7     ClientUtils.HandleException( this.Text, ex );
8 }
  • 写入节点

1 try
2 {
3     m_OpcUaClient.WriteNode( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度", (short)123 );
4 }
5 catch (Exception ex)
6 {
7     ClientUtils.HandleException( this.Text, ex );
8 }
  • 批量读取(类型一致)

 1 try
 2 {
 3     // 如果你批量读取的值的类型都是一样的,比如float,那么有简便的方式
 4     List<string> tags = new List<string>( );
 5     tags.Add( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/风俗" );
 6     tags.Add( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/转速" );
 7 
 8     // 按照顺序定义的值
 9     List<float> values = m_OpcUaClient.ReadNodes<float>( tags.ToArray() );
10 
11 }
12 catch (Exception ex)
13 {
14     ClientUtils.HandleException( this.Text, ex );
15 }
  • 批量读取(类型不一致)

 1 try
 2 {
 3     // 添加所有的读取的节点,此处的示例是类型不一致的情况
 4     List<NodeId> nodeIds = new List<NodeId>( );
 5     nodeIds.Add( new NodeId( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度" ) );
 6     nodeIds.Add( new NodeId( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/风俗" ) );
 7     nodeIds.Add( new NodeId( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/转速" ) );
 8     nodeIds.Add( new NodeId( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/机器人关节" ) );
 9     nodeIds.Add( new NodeId( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/cvsdf" ) );
10     nodeIds.Add( new NodeId( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/条码" ) );
11     nodeIds.Add( new NodeId( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/开关量" ) );
12 
13     // dataValues按顺序定义的值,每个值里面需要重新判断类型
14     List<DataValue> dataValues = m_OpcUaClient.ReadNodes( nodeIds.ToArray() );
15 
16 
17 }
18 catch (Exception ex)
19 {
20     ClientUtils.HandleException( this.Text, ex );
21 }
  • 批量写入

 1 try
 2 {
 3     // 此处演示写入一个short,2个float类型的数据批量写入操作
 4     bool success = m_OpcUaClient.WriteNodes( new string[] {
 5         "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度",
 6         "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/风俗",
 7         "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/转速"},
 8         new object[] {
 9             (short)1234,
10             123.456f,
11             123f
12         } );
13     if (success)
14     {
15         // 写入成功
16     }
17     else
18     {
19         // 写入失败,一个失败即为失败
20     }
21 }
22 catch (Exception ex)
23 {
24     ClientUtils.HandleException( this.Text, ex );
25 }
  • 读取Attrubute

 1 try
 2 {
 3     OpcNodeAttribute[] nodeAttributes = m_OpcUaClient.ReadNoteAttributes( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度" );
 4     foreach (var item in nodeAttributes)
 5     {
 6         Console.Write( string.Format( "{0,-30}", item.Name ) );
 7         Console.Write( string.Format( "{0,-20}", item.Type ) );
 8         Console.Write( string.Format( "{0,-20}", item.StatusCode ) );
 9         Console.WriteLine( string.Format( "{0,20}", item.Value ) );
10     }
11                 
12     // 输出如下
13     //  Name                          Type                StatusCode                         Vlaue
14 
15     //  NodeClass                     Int32               Good                                   2
16     //  BrowseName                    QualifiedName       Good                              2:温度
17     //  DisplayName                   LocalizedText       Good                                温度
18     //  Description                   LocalizedText       Good                                    
19     //  WriteMask                     UInt32              Good                                  96
20     //  UserWriteMask                 UInt32              Good                                  96
21     //  Value                         Int16               Good                              -11980
22     //  DataType                      NodeId              Good                                 i=4
23     //  ValueRank                     Int32               Good                                  -1
24     //  ArrayDimensions               Null                Good                                    
25     //  AccessLevel                   Byte                Good                                   3
26     //  UserAccessLevel               Byte                Good                                   3
27     //  MinimumSamplingInterval       Double              Good                                   0
28     //  Historizing                   Boolean             Good                               False
29 }
30 catch (Exception ex)
31 {
32     ClientUtils.HandleException( this.Text, ex );
33 }
  • 读取Reference

 1 try
 2 {
 3     ReferenceDescription[] references = m_OpcUaClient.BrowseNodeReference( "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端" );
 4     foreach (var item in references)
 5     {
 6         Console.Write( string.Format( "{0,-30}", item.NodeClass ) );
 7         Console.Write( string.Format( "{0,-30}", item.BrowseName ) );
 8         Console.Write( string.Format( "{0,-20}", item.DisplayName ) );
 9         Console.WriteLine( string.Format( "{0,-20}", item.NodeId.ToString( ) ) );
10     }
11 
12     ;
13     // 输出如下
14     //  NodeClass                     BrowseName                      DisplayName           NodeId
15 
16     //  Variable                      2:温度                          温度                  ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度
17     //  Variable                      2:风俗                          风俗                  ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/风俗
18     //  Variable                      2:转速                          转速                  ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/转速
19     //  Variable                      2:机器人关节                    机器人关节            ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/机器人关节
20     //  Variable                      2:cvsdf                         cvsdf                 ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/cvsdf
21     //  Variable                      2:条码                          条码                  ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/条码
22     //  Variable                      2:开关量                        开关量                ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/开关量
23 }
24 catch (Exception ex)
25 {
26     ClientUtils.HandleException( this.Text, ex );
27 }
  • 订阅(单节点订阅)

 1 m_OpcUaClient.AddSubscription( "A", "ns=2;s=Devices/分厂一/车间二/ModbusTcp客户端/温度", SubCallback ); 

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

 1 private void SubCallback(string key, MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args )
 2 {
 3     if (InvokeRequired)
 4     {
 5         Invoke( new Action<string, MonitoredItem, MonitoredItemNotificationEventArgs>( SubCallback ), key, monitoredItem, args );
 6         return;
 7     }
 8 
 9     if (key == "A")
10     {
11         // 如果有多个的订阅值都关联了当前的方法,可以通过key和monitoredItem来区分
12         MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
13         if (notification != null)
14         {
15             textBox3.Text = notification.Value.WrappedValue.Value.ToString( );
16         }
17     }
18 }

取消订阅代码如下:

 1 m_OpcUaClient.RemoveSubscription( "A" ); 

  • 订阅(批量订阅)

此处举例批量订阅3个点节点,按顺序在 textBox5 , textBox9 , textBox10 文本框按照顺序进行显示,此处比上面的操作需要麻烦一点, 需要缓存下批量订阅的节点信息

 1 // 缓存的批量订阅的节点
 2 private string[] MonitorNodeTags = null;
 3 
 4 private void button5_Click( object sender, EventArgs e )
 5 {
 6     // 多个节点的订阅
 7     MonitorNodeTags = new string[]
 8     {
 9         textBox6.Text,
10         textBox7.Text,
11         textBox8.Text,
12     };
13     m_OpcUaClient.AddSubscription( "B", MonitorNodeTags, SubCallback );
14 }

修改上述的回调方法如下:

 1 private void SubCallback(string key, MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args )
 2 {
 3     if (InvokeRequired)
 4     {
 5         Invoke( new Action<string, MonitoredItem, MonitoredItemNotificationEventArgs>( SubCallback ), key, monitoredItem, args );
 6         return;
 7     }
 8 
 9     if (key == "A")
10     {
11         // 如果有多个的订阅值都关联了当前的方法,可以通过key和monitoredItem来区分
12         MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
13         if (notification != null)
14         {
15             textBox3.Text = notification.Value.WrappedValue.Value.ToString( );
16         }
17     }
18     else if(key == "B")
19     {
20         // 需要区分出来每个不同的节点信息
21         MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
22         if (monitoredItem.StartNodeId.ToString( ) == MonitorNodeTags[0])
23         {
24             textBox5.Text = notification.Value.WrappedValue.Value.ToString( );
25         }
26         else if (monitoredItem.StartNodeId.ToString( ) == MonitorNodeTags[1])
27         {
28             textBox9.Text = notification.Value.WrappedValue.Value.ToString( );
29         }
30         else if (monitoredItem.StartNodeId.ToString( ) == MonitorNodeTags[2])
31         {
32             textBox10.Text = notification.Value.WrappedValue.Value.ToString( );
33         }
34     }
35 }

 

标签:基本,Devices,分厂,OpcUaHelper,使用,new,ModbusTcp,ns,客户端
From: https://www.cnblogs.com/davisdabing/p/17841183.html

相关文章

  • USB基本概念二
    Q1.USB总线驱动是干嘛用的?A1.1.识别USB设备2.给USB设备找到并安装对应的驱动程序3.提供USB读写函数新接入的USB设备默认地址(编号)为0,在未分配新编号前,PC主机使用0地址与其通信。(指匹配到驱动之前,会先与USB设备的prot0进行沟通,然后配置,当总线添加设备后,与驱动匹配后,择交给驱......
  • 无涯教程-RSpec - 基本语法
    让无涯教程仔细看看HelloWorld示例的代码。首先,如果不清楚,正在测试HelloWorld类的函数。当然,这是一个非常简单的类,仅包含一个方法say_hello()。这又是RSpec代码-describeHelloWorlddocontext“WhentestingtheHelloWorldclass”doit"Thesay_......
  • STL和基本数据结构
    STL和基本数据结构一、vector用法:vector是STL的动态数组。圆桌问题****TimeLimit:3000/1000MS(Java/Others)***MemoryLimit:65535/32768K(Java/Others)*ProblemDescription圆桌上围坐着2n个人。其中n个人是好人,另外n个人是坏人。如果从第一个人开始数数,数到......
  • python使用wandb login报错
    python使用wandblogin报错问题描述wandb是一个可视化在pipinstallwandb后使用importwandb或者运行命令wandblogin产生如下报错:cannotimportname'COMMON_SAFE_ASCII_CHARACTERS'解决方法报错可能是由于charset_normalizer模块的版本问题引起的。卸载重装:pipuninst......
  • Flutter应用-使用sqflite升级数据库
    问题描述使用fluttter开发的应用程序发布后,发现数据库有些设计不合理。如何来更新数据库呢?使用sqflite来处理数据库,但是第一版软件发布后,发现数据库不太合理要改动,想新的应用安装启动后更新数据库。下面以将一张表名称叫timerdata的表在新版应用启动时将这张表的名称改为taskdat......
  • VM新建虚拟机使用Xshell连接
        使用桥接模式 打开网络  ......
  • 使用 Filebeat+Easysearch+Console 打造日志管理平台
    近年来,日志管理平台越来越流行。使用日志管理平台可以实时地、统一地、方便地管理和查看日志,挖掘日志数据价值,驱动运维、运营,提升服务管理效率。方案架构Beats是轻量级采集器,包括Filebeat、Metricbeat等。Easysearch是个分布式搜索引擎,提供搜集、分析、存储数据等主要功能。Con......
  • while和do-while语句的使用
    ......
  • Dockerfile及docker简单使用
    Dockerfile个人使用总结Dockerfile的编写FROMpython#从基础镜像开始构建COPY./app#复制文件到镜像层WORKDIR/app#指定工作目录EXPOSE80#暴露端口供外部使用RUNpipinstall-rrequirements.txt#构建镜像时的命令,一个RUN构建一层,因此......
  • 使用 Filebeat+Easysearch+Console 打造日志管理平台
    近年来,日志管理平台越来越流行。使用日志管理平台可以实时地、统一地、方便地管理和查看日志,挖掘日志数据价值,驱动运维、运营,提升服务管理效率。方案架构Beats是轻量级采集器,包括Filebeat、Metricbeat等。Easysearch是个分布式搜索引擎,提供搜集、分析、存储数据等主要功......