1、Opc 基金会git地址:OPC Foundation · GitHub
其中:UA-.NETStandard 、UA-.NETStandard-Samples比价有参考价值
2、参数传递方式:ns=2;s=参数名(ns表示命名空间索引,一般为2)
特殊情况可以查看所有命名空间:ns=0;i=2255,也可以用(OpcUaHelper.Tool)工具查看
下载地址:C#opc学习资源代码-其它文档类资源-CSDN下载
3、根据opc基金会提供方法整理出调用代码:OPCUAC#控制类库-制造文档类资源-CSDN下载
using Opc.Ua;
using Opc.Ua.Client;
using Opc.Ua.Configuration;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace OPCUALink
{
/// <summary>
/// OPC UA Client with examples of basic functionality.
/// </summary>
public class UAClient
{
#region Constructors
public UAClient(bool isdebug = false)
{
if (isdebug)
{
return;
}
ApplicationInstance application = new ApplicationInstance();
application.ApplicationName = SessionName;
application.ApplicationType = ApplicationType.Client;
//加载配置文件
application.LoadApplicationConfiguration(ConfigPath, silent: false).Wait();
// check the application certificate.
//application.CheckApplicationInstanceCertificate(silent: false, minimumKeySize: 0).Wait();
m_validateResponse = ClientBase.ValidateResponse;
m_configuration = application.ApplicationConfiguration;
m_configuration.CertificateValidator.CertificateValidation += CertificateValidation;
ReceiveMsg += Msg;
}
#endregion
#region Public Properties
/// <summary>
/// session.
/// </summary>
public Session Session => m_session;
public static string conStr = "ns=3;s=";
/// <summary>
/// session名称
/// </summary>
public string SessionName { get; set; } = "DefaultSession";
/// <summary>
/// opcua服务地址
/// </summary>
public string ServerUrl { get; set; } = "opc.tcp://192.168.0.1/";
/// <summary>
/// 配置文件
/// </summary>
public string ConfigPath { get; set; } = "ConsoleReferenceClient.Config.xml";
/// <summary>
/// 日志委托
/// </summary>
public Action<string> LogAction { get; set; } = t => { Console.Write(t); };
/// <summary>
/// 订阅委托
/// </summary>
/// <param name="DisplayName"></param>
/// <param name="Value"></param>
public delegate void ShowMonitoredItemNotification(string DisplayName, string Value);
public ShowMonitoredItemNotification ReceiveMsg;
#endregion
#region Public Methods
/// <summary>
/// 连接服务器
/// </summary>
public async Task<bool> ConnectAsync()
{
try
{
//if (m_session != null && m_session.Connected && m_session.SessionId.ToString() == null)
//{
// LogAction?.Invoke("Session already connected!");
//}
//else
//{
// LogAction?.Invoke("Connecting...");
// EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(ServerUrl, false);
// EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
// Session session = await Session.Create(endpoint: new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration), configuration: m_configuration, updateBeforeConnect: false, checkDomain: false, sessionName: m_configuration.ApplicationName, sessionTimeout: 1800000u, identity: new UserIdentity(), preferredLocales: null);
// if (session?.Connected ?? false)
// {
// m_session = session;
// }
// LogAction?.Invoke("New Session Created with SessionName = " + m_session.SessionName);
// WriteLogWorkDate_n("OpcUa", "连接成功:" + ServerUrl);
//}
if (m_session != null && m_session.Connected == true && m_session.SessionId.ToString() == null)
{
LogAction?.Invoke("Session already connected!");
}
else
{
//Conect();
LogAction?.Invoke("Connecting...");
// Get the endpoint by connecting to server's discovery endpoint.
// Try to find the first endopint without security.
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(ServerUrl, false);
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
// Create the session
Session session = await Session.Create(
m_configuration,
endpoint,
false,
false,
m_configuration.ApplicationName,
30 * 60 * 1000,//30 * 60 * 10,//
new UserIdentity(),
null
);
// Assign the created session
if (session != null && session.Connected)
{
m_session = session;
}
// Session created successfully.
LogAction?.Invoke($"New Session Created with SessionName = {m_session.SessionName}");
WriteLogWorkDate_n("OpcUa", "连接成功:" + ServerUrl);
}
return true;
}
catch (Exception ex)
{
// Log Error
LogAction?.Invoke($"Create Session Error : {ex.Message}");
WriteLogWorkDate_n("OpcUa", "连接失败:" + ServerUrl + ":" + ex.Message);
ConnectAsync().Wait();
return false;
}
}
private async void Conect()
{
LogAction?.Invoke("Connecting...");
// Get the endpoint by connecting to server's discovery endpoint.
// Try to find the first endopint without security.
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(ServerUrl, false);
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
// Create the session
Session session = await Session.Create(
m_configuration,
endpoint,
false,
false,
m_configuration.ApplicationName,
30 * 60 * 10,//30 * 60 * 1000,
new UserIdentity(),
null
);
// Assign the created session
if (session != null && session.Connected)
{
m_session = session;
}
// Session created successfully.
LogAction?.Invoke($"New Session Created with SessionName = {m_session.SessionName}");
}
/// <summary>
/// 断开链接
/// </summary>
public void Disconnect()
{
try
{
WriteLogWorkDate_n("OpcUa", "断开连接:" + ServerUrl);
if (m_session != null)
{
LogAction?.Invoke("Disconnecting...");
m_session.Close();
m_session.Dispose();
m_session = null;
// Log Session Disconnected event
LogAction?.Invoke("Session Disconnected.");
}
else
{
LogAction?.Invoke("Session not created!");
}
}
catch (Exception ex)
{
// Log Error
LogAction?.Invoke($"Disconnect Error : {ex.Message}");
}
}
string oldword = "";
/// <summary>
/// 读单个节点
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="location">ns=4;s=A_AGV到周转桶</param>
/// <returns>ns=0;i=2255 查看所有命名空间</returns>
public T ReadNode<T>(string location)
{
#region
//DataValue dataValue = null;
//if (m_session == null || !m_session.Connected)
//{
// ConnectAsync();
//}
//try
//{
// dataValue = m_session.ReadValue(conStr + location);
//}
//catch
//{
// ConnectAsync();
// dataValue = m_session.ReadValue(conStr + location);
//}
//return (T)dataValue.Value;
#endregion
if (m_session == null || m_session.Connected == false)
{
ConnectAsync().Wait();
}
DataValue value = null;
try
{
value = m_session.ReadValue(conStr + location);
}
catch (Exception)
{
ConnectAsync().Wait();
value = m_session.ReadValue(conStr + location);
}
string newword = "读单个节点:" + location + ":" + value.Value;
if (newword != oldword)
{
WriteLogWorkDate_n("OpcUa", newword);
oldword = newword;
}
return (T)value.Value;
}
/// <summary>
/// 读多个节点
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="locations"></param>
/// <returns></returns>
public List<T> ReadNodes<T>(List<string> locations)
{
for (int i = 0; i < locations.Count; i++)
{
locations[i] = conStr + locations[i];
}
if (m_session == null || m_session.Connected == false)
{
ConnectAsync().Wait();
}
var typeList = new List<Type>();
foreach (var location in locations)
{
typeList.Add(typeof(T));
}
var nodeIds = locations.Select(t => new NodeId(t)).ToList();
List<object> values = new List<object>();
try
{
m_session.ReadValues(nodeIds, typeList, out values, out List<ServiceResult> errors);
}
catch (Exception)
{
ConnectAsync().Wait();
m_session.ReadValues(nodeIds, typeList, out values, out List<ServiceResult> errors);
}
return values.Select(t => (T)t).ToList();
}
/// <summary>
/// 写单个节点
/// </summary>
/// <param name="location"></param>
/// <param name="value"></param>
public void WriteNode(string location, object value)
{
location = conStr + location;
if (m_session == null || m_session.Connected == false)
{
ConnectAsync().Wait();
}
WriteLogWorkDate_n("OpcUa", "写单个节点:" + location + ":" + value);
WriteValueCollection nodesToWrite = new WriteValueCollection();
WriteValue intWriteVal = new WriteValue();
intWriteVal.NodeId = new NodeId(location);
intWriteVal.AttributeId = Attributes.Value;
intWriteVal.Value = new DataValue();
intWriteVal.Value.Value = value;
nodesToWrite.Add(intWriteVal);
try
{
m_session.Write(null,
nodesToWrite,
out StatusCodeCollection results,
out DiagnosticInfoCollection diagnosticInfos);
}
catch (Exception)
{
ConnectAsync().Wait();
m_session.Write(null,
nodesToWrite,
out StatusCodeCollection results,
out DiagnosticInfoCollection diagnosticInfos);
}
}
/// <summary>
/// 写多个节点
/// </summary>
/// <param name="locations"></param>
/// <param name="values"></param>
public void WriteNodes(List<string> locations, List<object> values)
{
if (m_session == null || m_session.Connected == false)
{
ConnectAsync().Wait();
}
WriteValueCollection nodesToWrite = new WriteValueCollection();
for (int i = 0; i < locations.Count; i++)
{
WriteLogWorkDate_n("OpcUa", "写多个节点:" + locations[i] + ":" + values[i]);
WriteValue intWriteVal = new WriteValue();
intWriteVal.NodeId = new NodeId(conStr + locations[i]);
intWriteVal.AttributeId = Attributes.Value;
intWriteVal.Value = new DataValue();
intWriteVal.Value.Value = values[i];
nodesToWrite.Add(intWriteVal);
}
m_session.Write(null,
nodesToWrite,
out StatusCodeCollection results,
out DiagnosticInfoCollection diagnosticInfos);
}
/// <summary>
///订阅多个节点
/// </summary>
public void SubscribeToDataChanges(List<string> locations)
{
if (m_session == null || m_session.Connected == false)
{
ConnectAsync().Wait();
return;
}
try
{
// 创建订阅以接收数据更改通知
// 定义订阅参数
Subscription subscription = new Subscription(m_session.DefaultSubscription);
subscription.DisplayName = "Console ReferenceClient Subscription";
subscription.PublishingEnabled = true;
subscription.PublishingInterval = 1000;
m_session.AddSubscription(subscription);
//在服务器端创建订阅
subscription.Create();
foreach (string loa in locations)
{
MonitoredItem intMonitoredItem = new MonitoredItem(subscription.DefaultItem);
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
intMonitoredItem.StartNodeId = new NodeId(conStr + loa);
intMonitoredItem.AttributeId = Attributes.Value;
intMonitoredItem.DisplayName = conStr + loa;
intMonitoredItem.SamplingInterval = 1000;
intMonitoredItem.Notification += OnMonitoredItemNotification;
subscription.AddItem(intMonitoredItem);
}
// 在服务器端创建监控项
subscription.ApplyChanges();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
/// <summary>
/// 从服务器读取值节点,不分类型
/// </summary>
/// <param name="nodeId">node id</param>
/// <returns>DataValue</returns>
public string ReadAllNode()//DataValue ReadAllNode()
{
NodeId nodeId = new NodeId(conStr + $"\"上位机读取交互数据\".\"培养箱抓取完成\"");
string res = "";
ReadValueIdCollection nodesToRead = new ReadValueIdCollection
{
new ReadValueId( )
{
NodeId = nodeId,
AttributeId = Attributes.Value
}
};
// read the current value
try
{
m_session.Read(
null,
0,
TimestampsToReturn.Neither,
nodesToRead,
out DataValueCollection results,
out DiagnosticInfoCollection diagnosticInfos);
ClientBase.ValidateResponse(results, nodesToRead);
ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);
DataValue dv = results[0];
}
catch
{
ConnectAsync().Wait();
m_session.Read(
null,
0,
TimestampsToReturn.Neither,
nodesToRead,
out DataValueCollection results,
out DiagnosticInfoCollection diagnosticInfos);
ClientBase.ValidateResponse(results, nodesToRead);
ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);
DataValue dv = results[0];
res = dv.Value.ToString();
}
return res;
}
#endregion
#region Private Methods
private void Msg(string DisplayName, string Value)
{
}
private void OnMonitoredItemNotification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
{
try
{
// Log MonitoredItem Notification event
MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
WriteLogWorkDate_n("OpcUa", "订阅反馈:" + monitoredItem.DisplayName + ":" + notification.Value.ToString());
ReceiveMsg(monitoredItem.DisplayName, notification.Value.ToString());
}
catch (Exception ex)
{
throw new Exception(ex.Message);
WriteLogWorkDate_n("OpcUa", "订阅反馈:" + monitoredItem.DisplayName + ":" + ex.Message);
}
}
/// <summary>
/// Handles the certificate validation event.
/// This event is triggered every time an untrusted certificate is received from the server.
/// </summary>
private void CertificateValidation(CertificateValidator sender, CertificateValidationEventArgs e)
{
bool certificateAccepted = true;
// ****
// Implement a custom logic to decide if the certificate should be
// accepted or not and set certificateAccepted flag accordingly.
// The certificate can be retrieved from the e.Certificate field
// ***
ServiceResult error = e.Error;
while (error != null)
{
LogAction?.Invoke(error.ToString());
error = error.InnerResult;
}
if (certificateAccepted)
{
LogAction?.Invoke($"Untrusted Certificate accepted. SubjectName = {e.Certificate.SubjectName}");
}
e.AcceptAll = certificateAccepted;
}
#endregion
#region Private Fields
private ApplicationConfiguration m_configuration;
private Session m_session;
private readonly Action<IList, IList> m_validateResponse;
#endregion
public static void WriteLogWorkDate_n(string fstyle, string messagestr)
{
#region 日志文件写入每天生成一个文件 txt
try
{
//创建一个文件流,用以写入或者创建一个StreamWriter
string filenamenew = fstyle + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
string date = DateTime.Now.ToString("yyyy-MM-dd");
//信息中下上时间直接写入 wqy 20180319
string msg = "";
if (messagestr == "")
{
msg = messagestr;
}
else
{
msg = DateTime.Now.ToString("HH:mm:ss:fff") + " " + messagestr;
}
//包装箱文件夹不存在创建
string xhpath = AppDomain.CurrentDomain.BaseDirectory + "log\\" + date + "\\";
//文件夹不存在创建
if (!Directory.Exists(xhpath))
{
Directory.CreateDirectory(xhpath);
}
filenamenew = xhpath + filenamenew;
FileStream fs = new FileStream(filenamenew, FileMode.OpenOrCreate, FileAccess.ReadWrite);
StreamWriter m_streamWriter = new StreamWriter(fs);
m_streamWriter.Flush();
// 使用StreamWriter来往文件中写入内容
m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
// 把richTextBox1中的内容写入文件
m_streamWriter.Write(msg + "\r\n");
//关闭此文件
m_streamWriter.Flush();
m_streamWriter.Close();
fs.Close();
}
catch (Exception ex)
{
}
#endregion
}
}
}