当前位置:   article > 正文

C#调用OPC UA 解决方案_c# opcua

c# opcua

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下载

  1. using Opc.Ua;
  2. using Opc.Ua.Client;
  3. using Opc.Ua.Configuration;
  4. using System;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Threading.Tasks;
  10. namespace OPCUALink
  11. {
  12. /// <summary>
  13. /// OPC UA Client with examples of basic functionality.
  14. /// </summary>
  15. public class UAClient
  16. {
  17. #region Constructors
  18. public UAClient(bool isdebug = false)
  19. {
  20. if (isdebug)
  21. {
  22. return;
  23. }
  24. ApplicationInstance application = new ApplicationInstance();
  25. application.ApplicationName = SessionName;
  26. application.ApplicationType = ApplicationType.Client;
  27. //加载配置文件
  28. application.LoadApplicationConfiguration(ConfigPath, silent: false).Wait();
  29. // check the application certificate.
  30. //application.CheckApplicationInstanceCertificate(silent: false, minimumKeySize: 0).Wait();
  31. m_validateResponse = ClientBase.ValidateResponse;
  32. m_configuration = application.ApplicationConfiguration;
  33. m_configuration.CertificateValidator.CertificateValidation += CertificateValidation;
  34. ReceiveMsg += Msg;
  35. }
  36. #endregion
  37. #region Public Properties
  38. /// <summary>
  39. /// session.
  40. /// </summary>
  41. public Session Session => m_session;
  42. public static string conStr = "ns=3;s=";
  43. /// <summary>
  44. /// session名称
  45. /// </summary>
  46. public string SessionName { get; set; } = "DefaultSession";
  47. /// <summary>
  48. /// opcua服务地址
  49. /// </summary>
  50. public string ServerUrl { get; set; } = "opc.tcp://192.168.0.1/";
  51. /// <summary>
  52. /// 配置文件
  53. /// </summary>
  54. public string ConfigPath { get; set; } = "ConsoleReferenceClient.Config.xml";
  55. /// <summary>
  56. /// 日志委托
  57. /// </summary>
  58. public Action<string> LogAction { get; set; } = t => { Console.Write(t); };
  59. /// <summary>
  60. /// 订阅委托
  61. /// </summary>
  62. /// <param name="DisplayName"></param>
  63. /// <param name="Value"></param>
  64. public delegate void ShowMonitoredItemNotification(string DisplayName, string Value);
  65. public ShowMonitoredItemNotification ReceiveMsg;
  66. #endregion
  67. #region Public Methods
  68. /// <summary>
  69. /// 连接服务器
  70. /// </summary>
  71. public async Task<bool> ConnectAsync()
  72. {
  73. try
  74. {
  75. //if (m_session != null && m_session.Connected && m_session.SessionId.ToString() == null)
  76. //{
  77. // LogAction?.Invoke("Session already connected!");
  78. //}
  79. //else
  80. //{
  81. // LogAction?.Invoke("Connecting...");
  82. // EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(ServerUrl, false);
  83. // EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
  84. // 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);
  85. // if (session?.Connected ?? false)
  86. // {
  87. // m_session = session;
  88. // }
  89. // LogAction?.Invoke("New Session Created with SessionName = " + m_session.SessionName);
  90. // WriteLogWorkDate_n("OpcUa", "连接成功:" + ServerUrl);
  91. //}
  92. if (m_session != null && m_session.Connected == true && m_session.SessionId.ToString() == null)
  93. {
  94. LogAction?.Invoke("Session already connected!");
  95. }
  96. else
  97. {
  98. //Conect();
  99. LogAction?.Invoke("Connecting...");
  100. // Get the endpoint by connecting to server's discovery endpoint.
  101. // Try to find the first endopint without security.
  102. EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(ServerUrl, false);
  103. EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
  104. ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
  105. // Create the session
  106. Session session = await Session.Create(
  107. m_configuration,
  108. endpoint,
  109. false,
  110. false,
  111. m_configuration.ApplicationName,
  112. 30 * 60 * 1000,//30 * 60 * 10,//
  113. new UserIdentity(),
  114. null
  115. );
  116. // Assign the created session
  117. if (session != null && session.Connected)
  118. {
  119. m_session = session;
  120. }
  121. // Session created successfully.
  122. LogAction?.Invoke($"New Session Created with SessionName = {m_session.SessionName}");
  123. WriteLogWorkDate_n("OpcUa", "连接成功:" + ServerUrl);
  124. }
  125. return true;
  126. }
  127. catch (Exception ex)
  128. {
  129. // Log Error
  130. LogAction?.Invoke($"Create Session Error : {ex.Message}");
  131. WriteLogWorkDate_n("OpcUa", "连接失败:" + ServerUrl + ":" + ex.Message);
  132. ConnectAsync().Wait();
  133. return false;
  134. }
  135. }
  136. private async void Conect()
  137. {
  138. LogAction?.Invoke("Connecting...");
  139. // Get the endpoint by connecting to server's discovery endpoint.
  140. // Try to find the first endopint without security.
  141. EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(ServerUrl, false);
  142. EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
  143. ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
  144. // Create the session
  145. Session session = await Session.Create(
  146. m_configuration,
  147. endpoint,
  148. false,
  149. false,
  150. m_configuration.ApplicationName,
  151. 30 * 60 * 10,//30 * 60 * 1000,
  152. new UserIdentity(),
  153. null
  154. );
  155. // Assign the created session
  156. if (session != null && session.Connected)
  157. {
  158. m_session = session;
  159. }
  160. // Session created successfully.
  161. LogAction?.Invoke($"New Session Created with SessionName = {m_session.SessionName}");
  162. }
  163. /// <summary>
  164. /// 断开链接
  165. /// </summary>
  166. public void Disconnect()
  167. {
  168. try
  169. {
  170. WriteLogWorkDate_n("OpcUa", "断开连接:" + ServerUrl);
  171. if (m_session != null)
  172. {
  173. LogAction?.Invoke("Disconnecting...");
  174. m_session.Close();
  175. m_session.Dispose();
  176. m_session = null;
  177. // Log Session Disconnected event
  178. LogAction?.Invoke("Session Disconnected.");
  179. }
  180. else
  181. {
  182. LogAction?.Invoke("Session not created!");
  183. }
  184. }
  185. catch (Exception ex)
  186. {
  187. // Log Error
  188. LogAction?.Invoke($"Disconnect Error : {ex.Message}");
  189. }
  190. }
  191. string oldword = "";
  192. /// <summary>
  193. /// 读单个节点
  194. /// </summary>
  195. /// <typeparam name="T"></typeparam>
  196. /// <param name="location">ns=4;s=A_AGV到周转桶</param>
  197. /// <returns>ns=0;i=2255 查看所有命名空间</returns>
  198. public T ReadNode<T>(string location)
  199. {
  200. #region
  201. //DataValue dataValue = null;
  202. //if (m_session == null || !m_session.Connected)
  203. //{
  204. // ConnectAsync();
  205. //}
  206. //try
  207. //{
  208. // dataValue = m_session.ReadValue(conStr + location);
  209. //}
  210. //catch
  211. //{
  212. // ConnectAsync();
  213. // dataValue = m_session.ReadValue(conStr + location);
  214. //}
  215. //return (T)dataValue.Value;
  216. #endregion
  217. if (m_session == null || m_session.Connected == false)
  218. {
  219. ConnectAsync().Wait();
  220. }
  221. DataValue value = null;
  222. try
  223. {
  224. value = m_session.ReadValue(conStr + location);
  225. }
  226. catch (Exception)
  227. {
  228. ConnectAsync().Wait();
  229. value = m_session.ReadValue(conStr + location);
  230. }
  231. string newword = "读单个节点:" + location + ":" + value.Value;
  232. if (newword != oldword)
  233. {
  234. WriteLogWorkDate_n("OpcUa", newword);
  235. oldword = newword;
  236. }
  237. return (T)value.Value;
  238. }
  239. /// <summary>
  240. /// 读多个节点
  241. /// </summary>
  242. /// <typeparam name="T"></typeparam>
  243. /// <param name="locations"></param>
  244. /// <returns></returns>
  245. public List<T> ReadNodes<T>(List<string> locations)
  246. {
  247. for (int i = 0; i < locations.Count; i++)
  248. {
  249. locations[i] = conStr + locations[i];
  250. }
  251. if (m_session == null || m_session.Connected == false)
  252. {
  253. ConnectAsync().Wait();
  254. }
  255. var typeList = new List<Type>();
  256. foreach (var location in locations)
  257. {
  258. typeList.Add(typeof(T));
  259. }
  260. var nodeIds = locations.Select(t => new NodeId(t)).ToList();
  261. List<object> values = new List<object>();
  262. try
  263. {
  264. m_session.ReadValues(nodeIds, typeList, out values, out List<ServiceResult> errors);
  265. }
  266. catch (Exception)
  267. {
  268. ConnectAsync().Wait();
  269. m_session.ReadValues(nodeIds, typeList, out values, out List<ServiceResult> errors);
  270. }
  271. return values.Select(t => (T)t).ToList();
  272. }
  273. /// <summary>
  274. /// 写单个节点
  275. /// </summary>
  276. /// <param name="location"></param>
  277. /// <param name="value"></param>
  278. public void WriteNode(string location, object value)
  279. {
  280. location = conStr + location;
  281. if (m_session == null || m_session.Connected == false)
  282. {
  283. ConnectAsync().Wait();
  284. }
  285. WriteLogWorkDate_n("OpcUa", "写单个节点:" + location + ":" + value);
  286. WriteValueCollection nodesToWrite = new WriteValueCollection();
  287. WriteValue intWriteVal = new WriteValue();
  288. intWriteVal.NodeId = new NodeId(location);
  289. intWriteVal.AttributeId = Attributes.Value;
  290. intWriteVal.Value = new DataValue();
  291. intWriteVal.Value.Value = value;
  292. nodesToWrite.Add(intWriteVal);
  293. try
  294. {
  295. m_session.Write(null,
  296. nodesToWrite,
  297. out StatusCodeCollection results,
  298. out DiagnosticInfoCollection diagnosticInfos);
  299. }
  300. catch (Exception)
  301. {
  302. ConnectAsync().Wait();
  303. m_session.Write(null,
  304. nodesToWrite,
  305. out StatusCodeCollection results,
  306. out DiagnosticInfoCollection diagnosticInfos);
  307. }
  308. }
  309. /// <summary>
  310. /// 写多个节点
  311. /// </summary>
  312. /// <param name="locations"></param>
  313. /// <param name="values"></param>
  314. public void WriteNodes(List<string> locations, List<object> values)
  315. {
  316. if (m_session == null || m_session.Connected == false)
  317. {
  318. ConnectAsync().Wait();
  319. }
  320. WriteValueCollection nodesToWrite = new WriteValueCollection();
  321. for (int i = 0; i < locations.Count; i++)
  322. {
  323. WriteLogWorkDate_n("OpcUa", "写多个节点:" + locations[i] + ":" + values[i]);
  324. WriteValue intWriteVal = new WriteValue();
  325. intWriteVal.NodeId = new NodeId(conStr + locations[i]);
  326. intWriteVal.AttributeId = Attributes.Value;
  327. intWriteVal.Value = new DataValue();
  328. intWriteVal.Value.Value = values[i];
  329. nodesToWrite.Add(intWriteVal);
  330. }
  331. m_session.Write(null,
  332. nodesToWrite,
  333. out StatusCodeCollection results,
  334. out DiagnosticInfoCollection diagnosticInfos);
  335. }
  336. /// <summary>
  337. ///订阅多个节点
  338. /// </summary>
  339. public void SubscribeToDataChanges(List<string> locations)
  340. {
  341. if (m_session == null || m_session.Connected == false)
  342. {
  343. ConnectAsync().Wait();
  344. return;
  345. }
  346. try
  347. {
  348. // 创建订阅以接收数据更改通知
  349. // 定义订阅参数
  350. Subscription subscription = new Subscription(m_session.DefaultSubscription);
  351. subscription.DisplayName = "Console ReferenceClient Subscription";
  352. subscription.PublishingEnabled = true;
  353. subscription.PublishingInterval = 1000;
  354. m_session.AddSubscription(subscription);
  355. //在服务器端创建订阅
  356. subscription.Create();
  357. foreach (string loa in locations)
  358. {
  359. MonitoredItem intMonitoredItem = new MonitoredItem(subscription.DefaultItem);
  360. // Int32 Node - Objects\CTT\Scalar\Simulation\Int32
  361. intMonitoredItem.StartNodeId = new NodeId(conStr + loa);
  362. intMonitoredItem.AttributeId = Attributes.Value;
  363. intMonitoredItem.DisplayName = conStr + loa;
  364. intMonitoredItem.SamplingInterval = 1000;
  365. intMonitoredItem.Notification += OnMonitoredItemNotification;
  366. subscription.AddItem(intMonitoredItem);
  367. }
  368. // 在服务器端创建监控项
  369. subscription.ApplyChanges();
  370. }
  371. catch (Exception ex)
  372. {
  373. throw new Exception(ex.Message);
  374. }
  375. }
  376. /// <summary>
  377. /// 从服务器读取值节点,不分类型
  378. /// </summary>
  379. /// <param name="nodeId">node id</param>
  380. /// <returns>DataValue</returns>
  381. public string ReadAllNode()//DataValue ReadAllNode()
  382. {
  383. NodeId nodeId = new NodeId(conStr + $"\"上位机读取交互数据\".\"培养箱抓取完成\"");
  384. string res = "";
  385. ReadValueIdCollection nodesToRead = new ReadValueIdCollection
  386. {
  387. new ReadValueId( )
  388. {
  389. NodeId = nodeId,
  390. AttributeId = Attributes.Value
  391. }
  392. };
  393. // read the current value
  394. try
  395. {
  396. m_session.Read(
  397. null,
  398. 0,
  399. TimestampsToReturn.Neither,
  400. nodesToRead,
  401. out DataValueCollection results,
  402. out DiagnosticInfoCollection diagnosticInfos);
  403. ClientBase.ValidateResponse(results, nodesToRead);
  404. ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);
  405. DataValue dv = results[0];
  406. }
  407. catch
  408. {
  409. ConnectAsync().Wait();
  410. m_session.Read(
  411. null,
  412. 0,
  413. TimestampsToReturn.Neither,
  414. nodesToRead,
  415. out DataValueCollection results,
  416. out DiagnosticInfoCollection diagnosticInfos);
  417. ClientBase.ValidateResponse(results, nodesToRead);
  418. ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);
  419. DataValue dv = results[0];
  420. res = dv.Value.ToString();
  421. }
  422. return res;
  423. }
  424. #endregion
  425. #region Private Methods
  426. private void Msg(string DisplayName, string Value)
  427. {
  428. }
  429. private void OnMonitoredItemNotification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
  430. {
  431. try
  432. {
  433. // Log MonitoredItem Notification event
  434. MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
  435. WriteLogWorkDate_n("OpcUa", "订阅反馈:" + monitoredItem.DisplayName + ":" + notification.Value.ToString());
  436. ReceiveMsg(monitoredItem.DisplayName, notification.Value.ToString());
  437. }
  438. catch (Exception ex)
  439. {
  440. throw new Exception(ex.Message);
  441. WriteLogWorkDate_n("OpcUa", "订阅反馈:" + monitoredItem.DisplayName + ":" + ex.Message);
  442. }
  443. }
  444. /// <summary>
  445. /// Handles the certificate validation event.
  446. /// This event is triggered every time an untrusted certificate is received from the server.
  447. /// </summary>
  448. private void CertificateValidation(CertificateValidator sender, CertificateValidationEventArgs e)
  449. {
  450. bool certificateAccepted = true;
  451. // ****
  452. // Implement a custom logic to decide if the certificate should be
  453. // accepted or not and set certificateAccepted flag accordingly.
  454. // The certificate can be retrieved from the e.Certificate field
  455. // ***
  456. ServiceResult error = e.Error;
  457. while (error != null)
  458. {
  459. LogAction?.Invoke(error.ToString());
  460. error = error.InnerResult;
  461. }
  462. if (certificateAccepted)
  463. {
  464. LogAction?.Invoke($"Untrusted Certificate accepted. SubjectName = {e.Certificate.SubjectName}");
  465. }
  466. e.AcceptAll = certificateAccepted;
  467. }
  468. #endregion
  469. #region Private Fields
  470. private ApplicationConfiguration m_configuration;
  471. private Session m_session;
  472. private readonly Action<IList, IList> m_validateResponse;
  473. #endregion
  474. public static void WriteLogWorkDate_n(string fstyle, string messagestr)
  475. {
  476. #region 日志文件写入每天生成一个文件 txt
  477. try
  478. {
  479. //创建一个文件流,用以写入或者创建一个StreamWriter
  480. string filenamenew = fstyle + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
  481. string date = DateTime.Now.ToString("yyyy-MM-dd");
  482. //信息中下上时间直接写入 wqy 20180319
  483. string msg = "";
  484. if (messagestr == "")
  485. {
  486. msg = messagestr;
  487. }
  488. else
  489. {
  490. msg = DateTime.Now.ToString("HH:mm:ss:fff") + " " + messagestr;
  491. }
  492. //包装箱文件夹不存在创建
  493. string xhpath = AppDomain.CurrentDomain.BaseDirectory + "log\\" + date + "\\";
  494. //文件夹不存在创建
  495. if (!Directory.Exists(xhpath))
  496. {
  497. Directory.CreateDirectory(xhpath);
  498. }
  499. filenamenew = xhpath + filenamenew;
  500. FileStream fs = new FileStream(filenamenew, FileMode.OpenOrCreate, FileAccess.ReadWrite);
  501. StreamWriter m_streamWriter = new StreamWriter(fs);
  502. m_streamWriter.Flush();
  503. // 使用StreamWriter来往文件中写入内容
  504. m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
  505. // 把richTextBox1中的内容写入文件
  506. m_streamWriter.Write(msg + "\r\n");
  507. //关闭此文件
  508. m_streamWriter.Flush();
  509. m_streamWriter.Close();
  510. fs.Close();
  511. }
  512. catch (Exception ex)
  513. {
  514. }
  515. #endregion
  516. }
  517. }
  518. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/80704
推荐阅读