C# 中,使用OpcUaHelper读写OPC服务器
nuget包
帮助类:
using Opc.Ua.Client;
using Opc.Ua;
using OpcUaHelper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace MyOPCUATest
{
public class OPCUAHelper
{
#region 基础参数
//OPCUA客户端
private OpcUaClient opcUaClient;
#endregion
///
/// 构造函数
///
public OPCUAHelper()
{
opcUaClient = new OpcUaClient();
}
///
/// 连接状态
///
public bool ConnectStatus
{
get { return opcUaClient.Connected; }
}
#region 公有方法
///
/// 打开连接【匿名方式】
///
///
服务器URL【格式:opc.tcp://服务器IP地址/服务名称】
public async void OpenConnectOfAnonymous(string serverUrl)
{
if (!string.IsNullOrEmpty(serverUrl))
{
try
{
opcUaClient.UserIdentity = new UserIdentity(new AnonymousIdentityToken());
await opcUaClient.ConnectServer(serverUrl);
}
catch (Exception ex)
{
ClientUtils.HandleException("连接失败!!!", ex);
}
}
}
///
/// 打开连接【账号方式】
///
///
服务器URL【格式:opc.tcp://服务器IP地址/服务名称】
///
用户名称
///
用户密码
public async void OpenConnectOfAccount(string serverUrl, string userName, string userPwd)
{
if (!string.IsNullOrEmpty(serverUrl) &&
!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(userPwd))
{
try
{
opcUaClient.UserIdentity = new UserIdentity(userName, userPwd);
await opcUaClient.ConnectServer(serverUrl);
}
catch (Exception ex)
{
ClientUtils.HandleException("连接失败!!!", ex);
}
}
}
///
/// 打开连接【证书方式】
///
///
服务器URL【格式:opc.tcp://服务器IP地址/服务名称】
///
证书路径
///
密钥
public async void OpenConnectOfCertificate(string serverUrl, string certificatePath, string secreKey)
{
if (!string.IsNullOrEmpty(serverUrl) &&
!string.IsNullOrEmpty(certificatePath) && !string.IsNullOrEmpty(secreKey))
{
try
{
X509Certificate2 certificate = new X509Certificate2(certificatePath, secreKey, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
opcUaClient.UserIdentity = new UserIdentity(certificate);
await opcUaClient.ConnectServer(serverUrl);
}
catch (Exception ex)
{
ClientUtils.HandleException("连接失败!!!", ex);
}
}
}
///
/// 关闭连接
///
public void CloseConnect()
{
if (opcUaClient != null)
{
try
{
opcUaClient.Disconnect();
}
catch (Exception ex)
{
ClientUtils.HandleException("关闭连接失败!!!", ex);
}
}
}
///
/// 获取到当前节点的值【同步读取】
///
///
节点对应的数据类型
///
节点
///
返回当前节点的值
public T GetCurrentNodeValue
(string nodeId)
{
T value = default(T);
if (!string.IsNullOrEmpty(nodeId) && ConnectStatus)
{
try
{
value = opcUaClient.ReadNode(nodeId);
}
catch (Exception ex)
{
ClientUtils.HandleException("读取失败!!!", ex);
}
}
return value;
}
///
/// 获取到当前节点数据【同步读取】
///
/// 节点对应的数据类型
/// 节点
/// 返回当前节点的值
public DataValue GetCurrentNodeValue(string nodeId)
{
DataValue dataValue = null;
if (!string.IsNullOrEmpty(nodeId) && ConnectStatus)
{
try
{
dataValue = opcUaClient.ReadNode(nodeId);
}
catch (Exception ex)
{
ClientUtils.HandleException("读取失败!!!", ex);
}
}
return dataValue;
}
///
/// 获取到批量节点数据【同步读取】
///
/// 节点列表
/// 返回节点数据字典
public Dictionary GetBatchNodeDatasOfSync(List nodeIdList)
{
Dictionary dicNodeInfo = new Dictionary();
if (nodeIdList != null && nodeIdList.Count > 0 && ConnectStatus)
{
try
{
List dataValues = opcUaClient.ReadNodes(nodeIdList.ToArray());
int count = nodeIdList.Count;
for (int i = 0; i < count; i++)
{
AddInfoToDic(dicNodeInfo, nodeIdList[i].ToString(), dataValues[i]);
}
}
catch (Exception ex)
{
ClientUtils.HandleException("读取失败!!!", ex);
}
}
return dicNodeInfo;
}
///
/// 获取到当前节点的值【异步读取】
///
/// 节点对应的数据类型
/// 节点
/// 返回当前节点的值
public async Task GetCurrentNodeValueOfAsync(string nodeId)
{
T value = default(T);
if (!string.IsNullOrEmpty(nodeId) && ConnectStatus)
{
try
{
value = await opcUaClient.ReadNodeAsync(nodeId);
}
catch (Exception ex)
{
ClientUtils.HandleException("读取失败!!!", ex);
}
}
return value;
}
///
/// 获取到批量节点数据【异步读取】
///
/// 节点列表
/// 返回节点数据字典
public async Task> GetBatchNodeDatasOfAsync(List nodeIdList)
{
Dictionary dicNodeInfo = new Dictionary();
if (nodeIdList != null && nodeIdList.Count > 0 && ConnectStatus)
{
try
{
List dataValues = await opcUaClient.ReadNodesAsync(nodeIdList.ToArray());
int count = nodeIdList.Count;
for (int i = 0; i < count; i++)
{
AddInfoToDic(dicNodeInfo, nodeIdList[i].ToString(), dataValues[i]);
}
}
catch (Exception ex)
{
ClientUtils.HandleException("读取失败!!!", ex);
}
}
return dicNodeInfo;
}
///
/// 获取到当前节点的关联节点
///
/// 当前节点
/// 返回当前节点的关联节点
public ReferenceDescription[] GetAllRelationNodeOfNodeId(string nodeId)
{
ReferenceDescription[] referenceDescriptions = null;
if (!string.IsNullOrEmpty(nodeId) && ConnectStatus)
{
try
{
referenceDescriptions = opcUaClient.BrowseNodeReference(nodeId);
}
catch (Exception ex)
{
string str = "获取当前: " + nodeId + " 节点的相关节点失败!!!";
ClientUtils.HandleException(str, ex);
}
}
return referenceDescriptions;
}
///
/// 获取到当前节点的所有属性
///
/// 当前节点
/// 返回当前节点对应的所有属性
public OpcNodeAttribute[] GetCurrentNodeAttributes(string nodeId)
{
OpcNodeAttribute[] opcNodeAttributes = null;
if (!string.IsNullOrEmpty(nodeId) && ConnectStatus)
{
try
{
opcNodeAttributes = opcUaClient.ReadNoteAttributes(nodeId);
}
catch (Exception ex)
{
string str = "读取节点;" + nodeId + " 的所有属性失败!!!";
ClientUtils.HandleException(str, ex);
}
}
return opcNodeAttributes;
}
///
/// 写入单个节点【同步方式】
///
/// 写入节点值得数据类型
/// 节点
/// 节点对应的数据值(比如:(short)123))
/// 返回写入结果(true:表示写入成功)
public bool WriteSingleNodeId(string nodeId, T value)
{
bool success = false;
if (opcUaClient != null && ConnectStatus)
{
if (!string.IsNullOrEmpty(nodeId))
{
try
{
success = opcUaClient.WriteNode(nodeId, value);
}
catch (Exception ex)
{
string str = "当前节点:" + nodeId + " 写入失败";
ClientUtils.HandleException(str, ex);
}
}
}
return success;
}
///
/// 批量写入节点
///
/// 节点数组
/// 节点对应数据数组
/// 返回写入结果(true:表示写入成功)
public bool BatchWriteNodeIds(string[] nodeIdArray, object[] nodeIdValueArray)
{
bool success = false;
if (nodeIdArray != null && nodeIdArray.Length > 0 &&
nodeIdValueArray != null && nodeIdValueArray.Length > 0)
{
try
{
success = opcUaClient.WriteNodes(nodeIdArray, nodeIdValueArray);
}
catch (Exception ex)
{
ClientUtils.HandleException("批量写入节点失败!!!", ex);
}
}
return success;
}
///
/// 写入单个节点【异步方式】
///
/// 写入节点值得数据类型
/// 节点
/// 节点对应的数据值
/// 返回写入结果(true:表示写入成功)
public async Task WriteSingleNodeIdOfAsync(string nodeId, T value)
{
bool success = false;
if (opcUaClient != null && ConnectStatus)
{
if (!string.IsNullOrEmpty(nodeId))
{
try
{
success = await opcUaClient.WriteNodeAsync(nodeId, value);
}
catch (Exception ex)
{
string str = "当前节点:" + nodeId + " 写入失败";
ClientUtils.HandleException(str, ex);
}
}
}
return success;
}
///
/// 读取单个节点的历史数据记录
///
/// 节点的数据类型
/// 节点
/// 开始时间
/// 结束时间
/// 返回该节点对应的历史数据记录
public List ReadSingleNodeIdHistoryDatas(string nodeId, DateTime startTime, DateTime endTime)
{
List nodeIdDatas = null;
if (!string.IsNullOrEmpty(nodeId) && startTime != null && endTime != null && endTime > startTime)
{
try
{
nodeIdDatas = opcUaClient.ReadHistoryRawDataValues(nodeId, startTime, endTime).ToList();
}
catch (Exception ex)
{
ClientUtils.HandleException("读取失败", ex);
}
}
return nodeIdDatas;
}
///
/// 读取单个节点的历史数据记录
///
/// 节点的数据类型
/// 节点
/// 开始时间
/// 结束时间
/// 返回该节点对应的历史数据记录
public List ReadSingleNodeIdHistoryDatas(string nodeId, DateTime startTime, DateTime endTime)
{
List nodeIdDatas = null;
if (!string.IsNullOrEmpty(nodeId) && startTime != null && endTime != null && endTime > startTime)
{
if (ConnectStatus)
{
try
{
nodeIdDatas = opcUaClient.ReadHistoryRawDataValues(nodeId, startTime, endTime).ToList();
}
catch (Exception ex)
{
ClientUtils.HandleException("读取失败", ex);
}
}
}
return nodeIdDatas;
}
///
/// 单节点数据订阅
///
/// 订阅的关键字(必须唯一)
/// 节点
/// 数据订阅的回调方法
public void SingleNodeIdDatasSubscription(string key, string nodeId, Action callback)
{
if (ConnectStatus)
{
try
{
opcUaClient.AddSubscription(key, nodeId, callback);
}
catch (Exception ex)
{
string str = "订阅节点:" + nodeId + " 数据失败!!!";
ClientUtils.HandleException(str, ex);
}
}
}
///
/// 取消单节点数据订阅
///
/// 订阅的关键字
public bool CancelSingleNodeIdDatasSubscription(string key)
{
bool success = false;
if (!string.IsNullOrEmpty(key))
{
if (ConnectStatus)
{
try
{
opcUaClient.RemoveSubscription(key);
success = true;
}
catch (Exception ex)
{
string str = "取消 " + key + " 的订阅失败";
ClientUtils.HandleException(str, ex);
}
}
}
return success;
}
///
/// 批量节点数据订阅
///
/// 订阅的关键字(必须唯一)
/// 节点数组
/// 数据订阅的回调方法
public void BatchNodeIdDatasSubscription(string key, string[] nodeIds, Action callback)
{
if (!string.IsNullOrEmpty(key) && nodeIds != null && nodeIds.Length > 0)
{
if (ConnectStatus)
{
try
{
opcUaClient.AddSubscription(key, nodeIds, callback);
}
catch (Exception ex)
{
string str = "批量订阅节点数据失败!!!";
ClientUtils.HandleException(str, ex);
}
}
}
}
///
/// 取消所有节点的数据订阅
///
///
public bool CancelAllNodeIdDatasSubscription()
{
bool success = false;
if (ConnectStatus)
{
try
{
opcUaClient.RemoveAllSubscription();
success = true;
}
catch (Exception ex)
{
ClientUtils.HandleException("取消所有的节点数据订阅失败!!!", ex);
}
}
return success;
}
///
/// 取消单节点的数据订阅
///
///
public bool CancelNodeIdDatasSubscription(string key)
{
bool success = false;
if (ConnectStatus)
{
try
{
opcUaClient.RemoveSubscription(key);
success = true;
}
catch (Exception ex)
{
ClientUtils.HandleException("取消节点数据订阅失败!!!", ex);
}
}
return success;
}
#endregion
#region 私有方法
///
/// 添加数据到字典中(相同键的则采用最后一个键对应的值)
///
/// 字典
/// 键
/// 值
private void AddInfoToDic(Dictionary dic, string key, DataValue dataValue)
{
if (dic != null)
{
if (!dic.ContainsKey(key))
{
dic.Add(key, dataValue);
}
else
{
dic[key] = dataValue;
}
}
}
#endregion
}//Class_end
}
Winform:
using Opc.Ua;
using Opc.Ua.Client;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MyOPCUATest
{
public partial class FrmMain : Form
{
public FrmMain()
{
InitializeComponent();
}
private OPCUAHelper opcClient;
private string[] MonitorNodeTags = null;
Dictionary myDic = new Dictionary();
private void BtnConn_Click(object sender, EventArgs e)
{
string url = "opc.tcp://192.168.2.11:4840";
string userName = "Administrator";
string password = "123456";
opcClient = new OPCUAHelper();
//opcClient.OpenConnectOfAccount(url, userName, password);
opcClient.OpenConnectOfAnonymous(url);
MessageBox.Show(opcClient.ConnectStatus.ToString());
}
private void BtnCurrentNode_Click(object sender, EventArgs e)
{
//string nodeId = "\"S7MesData\".\"S7Real\"[0]";
string nodeId = "ns=3;s=\"S7MesData\".\"S7Real\"[0]";
DataValue myValue= opcClient.GetCurrentNodeValue(nodeId);
this.Txtbox.Text = myValue.ToString();
}
private void BtnCertificate_Click(object sender, EventArgs e)
{
string url = "opc.tcp://192.168.2.11:4840";
string path = "D:\\zhengshu\\security\\zg-client.pfx";
string key = "123456";
opcClient = new OPCUAHelper();
opcClient.OpenConnectOfCertificate(url, path, key);
MessageBox.Show(opcClient.ConnectStatus.ToString());
}
private void BtnSigleScribe_Click(object sender, EventArgs e)
{
List list = new List();
list.Add("ns=3;s=\"S7MesData\".\"S7Real\"[0]");
list.Add("ns=3;s=\"S7MesData\".\"S7Real\"[1]");
MonitorNodeTags = list.ToArray();
opcClient.BatchNodeIdDatasSubscription("B", MonitorNodeTags, SubCallback);
}
private void SubCallback(string key, MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args)
{
if (key == "B")
{
MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
if (monitoredItem.StartNodeId.ToString() == MonitorNodeTags[0])
{
textBox2.Invoke(new Action(() =>
{
textBox2.Text = notification.Value.WrappedValue.Value.ToString();
}));
}
else if (monitoredItem.StartNodeId.ToString() == MonitorNodeTags[1])
{
textBox3.Invoke(new Action(() =>
{
textBox3.Text = notification.Value.WrappedValue.Value.ToString();
}));
}
if (myDic.ContainsKey(monitoredItem.StartNodeId.ToString()))
{
myDic[monitoredItem.StartNodeId.ToString()] = notification.Value.WrappedValue.Value;
}
else
{
myDic.Add(monitoredItem.StartNodeId.ToString(), notification.Value.WrappedValue.Value);
}
string str = "";
//foreach (var item in myDic)
//{
// Console.WriteLine(item.Key);
// Console.WriteLine(item.Value);
//}
}
}
private void btnWrite_Click(object sender, EventArgs e)
{
string myTxt = textBox4.Text.Trim();
string nodeId = "ns=3;s=\"S7MesData\".\"S7Real\"[0]";
opcClient.WriteSingleNodeId(nodeId, (float)Convert.ToDouble(myTxt));
}
}
}
KepServer 设置:
using Opc.Ua;
using Opc.Ua.Client;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace MyOPCUATest
{
public partial class FrmMain : Form
{
public FrmMain()
{
InitializeComponent();
}
private OPCUAHelper opcClient;
private string[] MonitorNodeTags = null;
Dictionary myDic = new Dictionary();
private void BtnConn_Click(object sender, EventArgs e)
{
//string url = "opc.tcp://192.168.2.11:4840"; //PLC
string url = "opc.tcp://192.168.2.125:49320"; //KepServer
string userName = "Administrator";
string password = "123456";
opcClient = new OPCUAHelper();
opcClient.OpenConnectOfAccount(url, userName, password);
//opcClient.OpenConnectOfAnonymous(url);
MessageBox.Show(opcClient.ConnectStatus.ToString());
}
private void BtnCurrentNode_Click(object sender, EventArgs e)
{
//string nodeId = "\"S7MesData\".\"S7Real\"[0]";
//string nodeId = "ns=3;s=\"S7MesData\".\"S7Real\"[0]"; //PLC
string nodeId = "ns=2;s=KxOPC.KX1500.电压1"; //Kep
DataValue myValue = opcClient.GetCurrentNodeValue(nodeId);
this.Txtbox.Text = myValue.ToString();
}
private void BtnCertificate_Click(object sender, EventArgs e)
{
//string url = "opc.tcp://192.168.2.11:4840";
string url = "opc.tcp://192.168.2.125:49320"; //KepServer
string path = @"D:\zhengshu\security\zg-client.pfx";
string key = "123456";
opcClient = new OPCUAHelper();
opcClient.OpenConnectOfCertificate(url, path, key);
MessageBox.Show(opcClient.ConnectStatus.ToString());
}
private void BtnSigleScribe_Click(object sender, EventArgs e)
{
List list = new List();
list.Add("ns=3;s=\"S7MesData\".\"S7Real\"[0]");
list.Add("ns=3;s=\"S7MesData\".\"S7Real\"[1]");
MonitorNodeTags = list.ToArray();
opcClient.BatchNodeIdDatasSubscription("B", MonitorNodeTags, SubCallback);
}
private void SubCallback(string key, MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args)
{
if (key == "B")
{
MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
if (monitoredItem.StartNodeId.ToString() == MonitorNodeTags[0])
{
textBox2.Invoke(new Action(() =>
{
textBox2.Text = notification.Value.WrappedValue.Value.ToString();
}));
}
else if (monitoredItem.StartNodeId.ToString() == MonitorNodeTags[1])
{
textBox3.Invoke(new Action(() =>
{
textBox3.Text = notification.Value.WrappedValue.Value.ToString();
}));
}
if (myDic.ContainsKey(monitoredItem.StartNodeId.ToString()))
{
myDic[monitoredItem.StartNodeId.ToString()] = notification.Value.WrappedValue.Value;
}
else
{
myDic.Add(monitoredItem.StartNodeId.ToString(), notification.Value.WrappedValue.Value);
}
string str = "";
//foreach (var item in myDic)
//{
// Console.WriteLine(item.Key);
// Console.WriteLine(item.Value);
//}
}
}
private void btnWrite_Click(object sender, EventArgs e)
{
string myTxt = textBox4.Text.Trim();
string nodeId = "ns=3;s=\"S7MesData\".\"S7Real\"[0]";
opcClient.WriteSingleNodeId(nodeId, (float)Convert.ToDouble(myTxt));
}
}
}
结果: