C#操作OPCUA
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Opc.Ua;
using OpcUaHelper;
namespace ISCS_AutoTest
{
/// <summary>
/// 读写FEP和RETDB中的数据
/// </summary>
public class OperatorOPCUa
{
public ExpandedNodeId TypeDefinition { get; set; }
private OpcUaClient opcUaClient = new OpcUaClient();
/// <summary>
/// 连接OPC ua Server
/// </summary>
/// <param name="serverUrl">服务地址</param>
public bool ConnectOpcUa(string serverUrl)
{
try
{
if(opcUaClient.Connected == true)
{
return true;
}
else
{
opcUaClient.ConnectServer(serverUrl);
return true;
}
}
catch (Exception ex)
{
// 使用了opc ua的错误处理机制来处理错误,网络不通或是读取拒绝
Opc.Ua.Client.Controls.ClientUtils.HandleException(serverUrl, ex);
return false;
}
}
/// <summary>
/// 关闭连接OPC ua Server
/// </summary>
public void CloseOpcUa()
{
opcUaClient.Disconnect();
}
/// <summary>
/// 读取标签值,如果标签不存在则返回false
/// </summary>
/// <param name="dbNumber">OBJ或FEP在server中的数据库编号</param>
/// <param name="itemLabel">标签名称</param>
/// <param name="itemValue">返回值</param>
/// <returns></returns>
public bool ReadItemValue(string dbNumber,string itemLabel,ref string itemValue)
{
try
{
string sendCmd = "ns=" + dbNumber + ";s=" + itemLabel;
Opc.Ua.DataValue value = opcUaClient.ReadNode(sendCmd);
itemValue = SetDataValueToString(value);
return true;
}
catch (Exception ex)
{
Common.WriteLog(dbNumber + itemLabel+ ex);
itemValue = "";
return false;
}
}
/// <summary>
/// 获取点最小周期
/// </summary>
/// <param name="sendCmd">点命令信息</param>
/// <param name="miniTime">最小时间周期</param>
/// <returns></returns>
public bool GetPropertyMiniTime(string sendCmd,ref int miniTime)
{
Common.WriteLog("sendCmd: " + sendCmd);
OpcNodeAttribute[] nodeAttributes = opcUaClient.ReadNoteAttributes(sendCmd);
foreach (var item in nodeAttributes)
{
Common.WriteLog("item.Name: " + item.Name+ "item.Value" + item.Value);
if (item.Name == "MinimumSamplingInterval")
{
Common.WriteLog("item.Value: " + item.Value);
string result = System.Text.RegularExpressions.Regex.Replace(item.Value.ToString(), @"[^0-9]+", "");
miniTime = int.Parse(result);
if (result != "")
{
miniTime = int.Parse(result);
//当时钟周期未获取到则设置为200毫秒,如果获取到时钟周期则设置其周期+100毫秒
if (miniTime < 100)
{
miniTime = 100;
}
}
else
{
miniTime = 200;
}
Common.WriteLog("miniTime" + miniTime);
return true;
}
}
return false;
}
/// <summary>
/// 获取节点的属性描述信息
/// </summary>
/// <param name="sendCmd"></param>
/// <returns></returns>
public bool GetPropertyDiscription(string sendCmd,ref string discription)
{
Common.WriteLog("sendCmd: " + sendCmd);
OpcNodeAttribute[] nodeAttributes = opcUaClient.ReadNoteAttributes(sendCmd);
int count = 0;
foreach (var item in nodeAttributes)
{
if (item.Name == "Description")
{
count++;
discription = item.Value.ToString();
}
}
return false;
}
/// <summary>
/// 读取标签值,如果标签不存在则返回false
/// </summary>
/// <param name="sendCmd">读取命令</param>
/// <param name="itemValue">返回值</param>
/// <returns></returns>
public bool ReadItemValue(string sendCmd, ref string itemValue)
{
Common.WriteLog("sendCmd---------:"+ sendCmd);
try
{
itemValue = SetDataValueToString(opcUaClient.ReadNode(sendCmd));
}
catch
{
return false;
}
return true;
}
/// <summary>
/// 读取标签值,如果标签不存在则返回false
/// </summary>
/// <param name="sendCmd">读取命令数组</param>
/// <param name="itemValue">返回值</param>
/// <returns></returns>
public bool ReadItemValue(string[] sendCmd, ref string itemValue)
{
try
{
int valueCount = sendCmd.Count();
switch(valueCount)//最大为三位
{
case 1://表示1个FEP点控制1个OBJ点值
itemValue = SetDataValueToString( opcUaClient.ReadNode(sendCmd[0]));
break;
case 2://表示2个FEP点控制1个OBJ点值
itemValue = (int.Parse(SetDataValueToString(opcUaClient.ReadNode(sendCmd[0])))
+ int.Parse(SetDataValueToString(opcUaClient.ReadNode(sendCmd[1]))) * 2).ToString();
break;
case 3://表示3个FEP点控制1个OBJ点值
itemValue = (int.Parse(SetDataValueToString(opcUaClient.ReadNode(sendCmd[0])))
+ int.Parse(SetDataValueToString(opcUaClient.ReadNode(sendCmd[1]))) * 2
+ int.Parse(SetDataValueToString(opcUaClient.ReadNode(sendCmd[2]))) * 4).ToString();
break;
default:
break;
}
return true;
}
catch (Exception ex)
{
Common.WriteLog(sendCmd[0] + ex);
itemValue = "";
try
{
int valueCount = sendCmd.Count();
switch (valueCount)//最大为三位
{
case 1://表示1个FEP点控制1个OBJ点值
itemValue = SetDataValueToString(opcUaClient.ReadNode(sendCmd[0].Replace(".In_Channel0","")));
break;
case 2://表示2个FEP点控制1个OBJ点值
itemValue = (int.Parse(SetDataValueToString(opcUaClient.ReadNode(sendCmd[0].Replace(".In_Channel0", ""))))
+ int.Parse(SetDataValueToString(opcUaClient.ReadNode(sendCmd[1].Replace(".In_Channel1", "")))) * 2).ToString();
break;
case 3://表示3个FEP点控制1个OBJ点值
itemValue = (int.Parse(SetDataValueToString(opcUaClient.ReadNode(sendCmd[0].Replace(".In_Channel0", ""))))
+ int.Parse(SetDataValueToString(opcUaClient.ReadNode(sendCmd[1].Replace(".In_Channel1", "")))) * 2
+ int.Parse(SetDataValueToString(opcUaClient.ReadNode(sendCmd[2].Replace(".In_Channel2", "")))) * 4).ToString();
break;
default:
break;
}
return true;
}
catch
{
Common.WriteLog(sendCmd[0] + ex);
}
return false;
}
}
/// <summary>
/// 设置节点下的所有设备为使能状态
/// </summary>
/// <param name="rootNodeCmd">节点名称编号命令</param>
/// <returns></returns>
public bool SetAllDeviceEnable(string rootNodeCmd)
{
Common.WriteLog("rootNodeCmd"+ rootNodeCmd);
string str = "";
try
{
Opc.Ua.ReferenceDescription[] reference = opcUaClient.BrowseNodeReference(rootNodeCmd);
foreach (var refer in reference)
{
CallMethod(refer.NodeId.ToString(), 5, "ns=9;i=232");
//CallMethod(refer.NodeId.ToString(), 5, "SendCmd");
str += refer.NodeId.ToString()+"\r\n";
}
Common.WriteLog(str);
return true;
}
catch (Exception ex)
{
Common.WriteLog(rootNodeCmd + ex);
return false;
}
}
/// <summary>
/// 设置节点下的所有设备为使能状态
/// </summary>
/// <param name="rootNodeCmd">节点名称编号命令</param>
/// <returns></returns>
public Dictionary<string, List<string>> GetAllDeviceInfo(string rootNodeName,string rootID,string DBNumber)
{
Dictionary<string, List<string>> itemInfo = new Dictionary<string, List<string>>();
try
{
//获取所有设备名称
string discriptonCmd = "ns=" + rootID + ";s=" + rootNodeName;
Common.WriteLog("discriptonCmd "+ discriptonCmd);
Opc.Ua.ReferenceDescription[] refeRoot = opcUaClient.BrowseNodeReference(discriptonCmd);
foreach (var deviceName in refeRoot)
{
try
{
//获取所有设备的描述
string propertyCmd = "ns=" + rootID + ";s=" + deviceName.DisplayName.ToString() + "." + deviceName.DisplayName.ToString();
Common.WriteLog("propertyCmd " + propertyCmd);
Opc.Ua.ReferenceDescription[] refeProperty = opcUaClient.BrowseNodeReference(propertyCmd);
foreach (var property in refeProperty)
{
try
{
string sttributeCmd = "ns=9002;s=" + property.DisplayName.ToString().Insert(property.DisplayName.ToString().Length - 4, ".");
Common.WriteLog("sttributeCmd " + sttributeCmd);
OpcNodeAttribute[] nodeAttributes = opcUaClient.ReadNoteAttributes(sttributeCmd);
foreach (var attr in nodeAttributes)
{
if (attr.Name == "Description")
{
Common.WriteLog("设备名 " + deviceName.DisplayName.ToString() + "属性标签 " + property.DisplayName.ToString() + "属性描述 " + attr.Value);
}
}
}
catch
{
continue;
}
}
}
catch
{
continue;
}
}
return itemInfo;
}
catch (Exception ex)
{
Common.WriteLog(ex.Message);
return itemInfo;
}
}
/// <summary>
/// 设置节点下的所有设备为使能状态
/// </summary>
/// <param name="rootNodeCmd">节点名称编号命令</param>
/// <returns></returns>
public Dictionary<string, string> GetAllDeviceNameAndDesp(string rootNodeCmd)
{
Dictionary<string, string> nameAndDesp = new Dictionary<string, string>();
try
{
Opc.Ua.ReferenceDescription[] reference = opcUaClient.BrowseNodeReference(rootNodeCmd);
foreach (var refer in reference)
{
nameAndDesp.Add(refer.NodeId.ToString(), refer.DisplayName.ToString());
}
return nameAndDesp;
}
catch (Exception ex)
{
Common.WriteLog(rootNodeCmd + ex);
return nameAndDesp;
}
}
/// <summary>
/// 调用call函数
/// </summary>
/// <param name="sendCmd">调用命令</param>
/// <param name="nodeNumber">节点数据</param>
/// <param name="nodeString">节点名称</param>
/// <returns></returns>
public bool CallMethod(string sendCmd, object nodeNumber,string nodeString)
{
try
{
if(nodeNumber.GetType() == typeof(int))
{
if ((int)nodeNumber == 5)
{
opcUaClient.CallMethodByNodeId(sendCmd, nodeString, nodeNumber, "04")[0].ToString();
}
else if ((int)nodeNumber == 6)
{
opcUaClient.CallMethodByNodeId(sendCmd, nodeString, nodeNumber, "0")[0].ToString();
}
}
else if(nodeNumber.GetType() == typeof(bool) || nodeNumber.GetType() == typeof(Boolean))
{
opcUaClient.CallMethodByNodeId(sendCmd, nodeString, true, nodeNumber);
}
else if(nodeNumber.GetType() == typeof(string))
{
if(nodeNumber.ToString() == "取消强制")
{
Common.WriteLog("CallMethodByNodeId-----");
opcUaClient.CallMethodByNodeId(sendCmd, nodeString, false, nodeNumber);
}
}
else
{
return false;
}
return true;
}
catch (Exception ex)
{
Common.WriteLog(sendCmd + ex);
return false;
}
}
/// <summary>
/// 读取设备属性描述
/// </summary>
/// <param name="dbNumber">数据库编号</param>
/// <param name="itemLabel">标签名称</param>
/// <param name="itemValue">返回属性描述</param>
/// <returns></returns>
public bool ReadDiaplayName(string dbNumber, string itemLabel, ref string itemValue)
{
try
{
string sendCmd = "ns=" + dbNumber + ";s=" + itemLabel;
sendCmd = sendCmd.Replace(".PV", ".ValueDesp");
Opc.Ua.DataValue value = opcUaClient.ReadNode(sendCmd);
itemValue = SetDataValueToString(value);
return true;
}
catch (Exception ex)
{
Common.WriteLog(dbNumber + itemLabel + ex);
itemValue = "";
return false;
}
}
/// <summary>
/// 读取设备属性描述
/// </summary>
/// <param name="sendCmd">读取属性描述命令</param>
/// <param name="itemValue">返回属性描述</param>
/// <returns></returns>
public bool ReadDiaplayName(string sendCmd, ref string itemValue)
{
try
{
Opc.Ua.DataValue value = opcUaClient.ReadNode(sendCmd);
itemValue = SetDataValueToString(value);
return true;
}
catch (Exception ex)
{
Common.WriteLog(sendCmd + ex);
itemValue = "";
return false;
}
}
/// <summary>
/// 写入标签值,如果标签不存在则返回false
/// </summary>
/// <param name="dbNumber">OBJ或FEP在server中的数据库编号</param>
/// <param name="itemLabel">标签名称</param>
/// <param name="itemValue">写入值</param>
/// <returns></returns>
public bool WriteItemValue(string dbNumber, string itemLabel, object itemValue)
{
try
{
string sendCmd = "ns=" + dbNumber + ";s=" + itemLabel;
bool IsSuccess = opcUaClient.WriteNode(sendCmd, itemValue);
return IsSuccess;
}
catch (Exception ex)
{
Common.WriteLog(dbNumber + itemLabel + ex);
return false;
}
}
/// <summary>
/// 写入标签值,如果标签不存在则返回false
/// </summary>
/// <param name="sendCmd">写入值命令</param>
/// <param name="itemValue">写入值</param>
/// <returns></returns>
public bool WriteItemValue(string[] sendCmd, object[] itemValue)
{
try
{
bool IsSuccess = opcUaClient.WriteNodes(sendCmd, itemValue);
return IsSuccess;
}
catch (Exception ex)
{
Common.WriteLog(sendCmd[0] + ex);
return false;
}
}
/// <summary>
/// 将未知类型的值转换为string
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
private string SetDataValueToString(Opc.Ua.DataValue value)
{
string tempValue = "";
// 一个数据的类型是不是数组由 value.WrappedValue.TypeInfo.ValueRank 来决定的
// -1 说明是一个数值
// 1 说明是一维数组,如果类型BuiltInType是Int32,那么实际是int[]
// 2 说明是二维数组,如果类型BuiltInType是Int32,那么实际是int[,]
if(value == null)
{
return "";
}
switch(value.WrappedValue.TypeInfo.BuiltInType)
{
case Opc.Ua.BuiltInType.Int32:
{
if (value.WrappedValue.TypeInfo.ValueRank == -1)
{
int temp = (int)value.WrappedValue.Value;
tempValue = temp.ToString();
}
else if (value.WrappedValue.TypeInfo.ValueRank == 1)
{
int[] temp = (int[])value.WrappedValue.Value;
foreach (int singleValue in temp)
{
tempValue += singleValue.ToString() + ",";
}
}
else if (value.WrappedValue.TypeInfo.ValueRank == 2)
{
int[,] temp = (int[,])value.WrappedValue.Value;
tempValue = temp[0, 0].ToString();
foreach (int singleValue in temp)
{
tempValue += singleValue.ToString() + ",";
}
}
}
break;
case Opc.Ua.BuiltInType.Int16:
{
Int16 temp = (Int16)value.WrappedValue.Value;
tempValue = temp.ToString();
}
break;
case Opc.Ua.BuiltInType.UInt16:
{
UInt16 temp = (UInt16)value.WrappedValue.Value;
tempValue = temp.ToString();
}
break;
case Opc.Ua.BuiltInType.Int64:
{
Int64 temp = (Int64)value.WrappedValue.Value;
tempValue = temp.ToString();
}
break;
case Opc.Ua.BuiltInType.UInt64:
{
UInt64 temp = (UInt64)value.WrappedValue.Value;
tempValue = temp.ToString();
}
break;
case Opc.Ua.BuiltInType.UInt32:
{
UInt32 temp = (UInt32)value.WrappedValue.Value;
tempValue = temp.ToString();
}
break;
case Opc.Ua.BuiltInType.Float:
{
float temp = (float)value.WrappedValue.Value;
tempValue = temp.ToString();
}
break;
case Opc.Ua.BuiltInType.String:
{
string temp = (string)value.WrappedValue.Value;
tempValue = temp.ToString();
}
break;
case Opc.Ua.BuiltInType.DateTime:
{
DateTime temp = (DateTime)value.WrappedValue.Value;
tempValue = temp.ToString();
}
break;
case Opc.Ua.BuiltInType.LocalizedText:
{
LocalizedText temp = (LocalizedText)value.WrappedValue.Value;
tempValue = temp.ToString();
}
break;
case Opc.Ua.BuiltInType.Byte:
{
Byte temp = (Byte)value.WrappedValue.Value;
tempValue = temp.ToString();
}
break;
case Opc.Ua.BuiltInType.Boolean:
{
Boolean temp = (Boolean)value.WrappedValue.Value;
if(temp == true)
{
tempValue = "1";
}
else
{
tempValue = "0";
}
}
break;
default:
break;
}
return tempValue;
}
}
}