DeviceOPCUat.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. using Opc.Ua;
  2. using Opc.Ua.Client;
  3. using SinumerikOpcUaAPI;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using WCS;
  10. using WCS.Entitys;
  11. using WCS.Utils;
  12. namespace YG.Device
  13. {
  14. public class DeviceOPCUat
  15. {
  16. Server opcserver;
  17. EndpointDescription endpointDescription;
  18. public bool IsOn { get; set; } = false;
  19. public DeviceOPCUat(string url, string username = "OpcUaClient", string pwd = "12345678")
  20. {
  21. if (opcserver == null || !opcserver.Session.Connected)
  22. {
  23. IsOn = OpcUa_Connection(url, username, pwd);
  24. Log.Instance.WriteLogAdd("OPCUA 连接是否成功===>>" + IsOn,EnumHelper.GetEnumDescription<WcsActionType>("opcua"));
  25. }
  26. }
  27. public bool IsConnection { get; set; } = false;
  28. private void Notification_KeepAlive(Session sender, KeepAliveEventArgs e)
  29. {
  30. try
  31. {
  32. if (sender != this.opcserver.Session || !ServiceResult.IsBad(e.Status))
  33. return;
  34. this.opcserver.Session.Reconnect();
  35. Log.Instance.WriteLogAdd($"35----->>----->>----->>----->>----->>----->>----->>----->>----->>----->>----->>Notification_KeepAlive", EnumHelper.GetEnumDescription<WcsActionType>("opcua"));
  36. IsConnection = true;
  37. }
  38. catch (Exception ex)
  39. {
  40. IsConnection = false;
  41. Log.Instance.WriteLogAdd($"41-->>{ex}", EnumHelper.GetEnumDescription<WcsActionType>("opcua"));
  42. }
  43. }
  44. /// <summary>
  45. /// 获取NC下边的文件列表
  46. /// </summary>
  47. /// <returns></returns>
  48. public ReferenceDescriptionCollection OpcUa_BrowseNode()
  49. {
  50. return opcserver.BrowseNode(new NodeId("Sinumerik/FileSystem/NCExtend/webApiMESFILE/", (ushort)2).ToString());
  51. }
  52. #region 终止连接
  53. public void OpcUa_Close()
  54. {
  55. if (OpcUa_ConState())
  56. {
  57. opcserver.Disconnect();
  58. }
  59. }
  60. private bool OpcUa_ConState()
  61. {
  62. if (opcserver != null && opcserver.Session.Connected)
  63. {
  64. return true;
  65. }
  66. else
  67. {
  68. Log.Instance.WriteLogAdd("OPC没有连接", EnumHelper.GetEnumDescription<WcsActionType>("opcua"));
  69. }
  70. return false;
  71. }
  72. #endregion
  73. #region 写入
  74. public bool OpcUa_Write(string address, object value)
  75. {
  76. try
  77. {
  78. if (OpcUa_ConState())
  79. {
  80. opcserver.WriteValues(new List<string>() { value.ToString() }, new List<string>() { address });
  81. return true;
  82. }
  83. return false;
  84. }
  85. catch (Exception ex)
  86. {
  87. Log.Instance.WriteLogAdd($"92-->{ex}", EnumHelper.GetEnumDescription<WcsActionType>("opcua"));
  88. return false;
  89. }
  90. }
  91. public bool OpcUa_WriteValue(string address, object value)
  92. {
  93. try
  94. {
  95. string str = new NodeId(address, (ushort)2).ToString();
  96. if (OpcUa_ConState())
  97. {
  98. opcserver.WriteValues(new List<string>() { value.ToString() }, new List<string>() { str });
  99. return true;
  100. }
  101. return false;
  102. }
  103. catch (Exception ex)
  104. {
  105. Log.Instance.WriteLogAdd($"110->{ex}", EnumHelper.GetEnumDescription<WcsActionType>("opcua"));
  106. return false;
  107. }
  108. }
  109. public bool OpcUa_WriteValue(List<string> addresses, List<string> values)
  110. {
  111. try
  112. {
  113. if (OpcUa_ConState())
  114. {
  115. opcserver.WriteValues(addresses, values);
  116. return true;
  117. }
  118. return false;
  119. }
  120. catch (Exception ex)
  121. {
  122. //YG.Log.Instance.WriteLogAdd($"110->{ex.Message}");
  123. return false;
  124. }
  125. }
  126. #endregion
  127. #region 选中
  128. public bool OpcUa_Select(string filename)
  129. {
  130. bool result = false;
  131. try
  132. {
  133. if (OpcUa_ConState())
  134. {
  135. string extension = System.IO.Path.GetExtension(filename);
  136. if (string.IsNullOrWhiteSpace(extension) || !extension.ToUpper().Equals(".MPF"))
  137. {
  138. // System.Windows.Forms.MessageBox.Show("请选择要上传的文件");
  139. return false;
  140. }
  141. try
  142. {
  143. string value = opcserver.MethodCallSelectProgram(filename, Convert.ToUInt32(1)).status;
  144. if (value.Equals("Good"))
  145. {
  146. result = true;
  147. }
  148. }
  149. catch (Exception ex)
  150. {
  151. // YG.Log.Instance.WriteLogAdd($"{ex.Message}");
  152. //System.Windows.Forms.MessageBox.Show($"{ex.Message}");
  153. }
  154. }
  155. return result;
  156. }
  157. catch (Exception ex)
  158. {
  159. //YG.Log.Instance.WriteLogAdd($"154--->{ex.Message}");
  160. return false;
  161. }
  162. }
  163. public bool OpcUa_Select(string path, string filename)
  164. {
  165. bool result = false;
  166. try
  167. {
  168. if (OpcUa_ConState())
  169. {
  170. string extension = System.IO.Path.GetExtension(filename);
  171. if (string.IsNullOrWhiteSpace(extension) || !extension.ToUpper().Equals(".MPF"))
  172. {
  173. //System.Windows.Forms.MessageBox.Show("请选择要上传的文件");
  174. return false;
  175. }
  176. try
  177. {
  178. string value = opcserver.MethodCallSelectProgram(path + filename, Convert.ToUInt32(1)).status;
  179. if (value.Equals("Good"))
  180. {
  181. result = true;
  182. }
  183. }
  184. catch (Exception ex)
  185. {
  186. //YG.Log.Instance.WriteLogAdd($"182-->{ex.Message}");
  187. //System.Windows.Forms.MessageBox.Show($"{ex.Message}");
  188. }
  189. }
  190. return result;
  191. }
  192. catch (Exception ex)
  193. {
  194. //YG.Log.Instance.WriteLogAdd($"192-->{ex.Message}");
  195. return false;
  196. }
  197. }
  198. #endregion
  199. #region 读取
  200. public bool OpcUa_Read(string address, out string value)
  201. {
  202. bool result = false;
  203. value = "";
  204. if (OpcUa_ConState())
  205. {
  206. try
  207. {
  208. string itemaddress = $"/Plc/{address}";
  209. string str = new NodeId(itemaddress, (ushort)2).ToString();
  210. if (opcserver != null && opcserver.Session.Connected)
  211. {
  212. value = opcserver.ReadValues(new List<string>() { str })[0];
  213. }
  214. result = true;
  215. }
  216. catch (Exception ex)
  217. {
  218. //YG.Log.Instance.WriteLogAdd($"{ex.Message}");
  219. //System.Windows.Forms.MessageBox.Show($"{ex.Message}");
  220. }
  221. }
  222. return result;
  223. }
  224. /// <summary>
  225. ///
  226. /// </summary>
  227. /// <param name="address">list里边的地址格式为I2.0,I2.1,DB2.DBX35.0等格式</param>
  228. /// <param name="value">查询出来的值和上面的值是一一对应的关系</param>
  229. /// <returns></returns>
  230. public bool OpcUa_Read(List<string> address, out List<string> value)
  231. {
  232. value = new List<string>();
  233. try
  234. {
  235. List<string> nodeIdStrings = new List<string>();
  236. foreach (string s in address)
  237. {
  238. nodeIdStrings.Add(new NodeId($"/Plc/{s}", (ushort)2).ToString());
  239. }
  240. if (opcserver != null && opcserver.Session.Connected)
  241. {
  242. value = opcserver.ReadValues(nodeIdStrings);
  243. }
  244. return true;
  245. }
  246. catch (Exception ex)
  247. {
  248. //YG.Log.Instance.WriteLogAdd($"{ex.Message}");
  249. //System.Windows.Forms.MessageBox.Show($"{ex.Message}");
  250. return false;
  251. }
  252. }
  253. public List<string> OpcUa_Read(List<string> address)
  254. {
  255. List<string> value = new List<string>();
  256. try
  257. {
  258. List<string> nodeIdStrings = new List<string>();
  259. if (opcserver != null && opcserver.Session != null && opcserver.Session.Connected)
  260. {
  261. value = opcserver.ReadValues(nodeIdStrings);
  262. }
  263. return value;
  264. }
  265. catch (Exception ex)
  266. {
  267. try
  268. {
  269. OpcUa_Connection(opcserver.Session.ConfiguredEndpoint.ToString());
  270. }
  271. catch (Exception esx)
  272. {
  273. //YG.Log.Instance.WriteLogAdd($"284------->>esx---->{esx.Message} {ex.Message}--->>>");
  274. }
  275. return value;
  276. }
  277. }
  278. public bool OpcUa_Read(List<string> address, out Dictionary<string, string> value)
  279. {
  280. value = new Dictionary<string, string>();
  281. try
  282. {
  283. List<string> nodeIdStrings = new List<string>();
  284. foreach (string s in address)
  285. {
  286. nodeIdStrings.Add(new NodeId($"/Plc/{s}", (ushort)2).ToString());
  287. value.Add(s, "");
  288. }
  289. if (opcserver != null && opcserver.Session.Connected)
  290. {
  291. List<string> Keys = value.Keys.ToList();
  292. List<string> items = opcserver.ReadValues(nodeIdStrings);
  293. for (int i = 0; i < items.Count; i++)
  294. {
  295. value[Keys[i]] = items[i];
  296. }
  297. }
  298. return true;
  299. }
  300. catch (Exception ex)
  301. {
  302. //YG.Log.Instance.WriteLogAdd($"{ex.Message}");
  303. //System.Windows.Forms.MessageBox.Show($"{ex.Message}");
  304. return false;
  305. }
  306. }
  307. #endregion
  308. #region OPCUA连接
  309. /// <summary>
  310. /// 连接opcua
  311. /// </summary>
  312. /// <param name="url"></param>
  313. /// <param name="username"></param>
  314. /// <param name="pwd"></param>
  315. public bool OpcUa_Connection(string url, string username = "OpcUaClient", string pwd = "12345678")
  316. {
  317. bool result = false;
  318. try
  319. {
  320. opcserver = new Server();
  321. ApplicationDescriptionCollection applicationDescriptions = opcserver.FindServers(url);
  322. if (applicationDescriptions.Count == 0)
  323. {
  324. // YG.Log.Instance.WriteLogAdd("没有找到服务!");
  325. }
  326. else if (applicationDescriptions.Count == 1)
  327. {
  328. applicationDescriptions[0].DiscoveryUrls.Where(m => m.Equals(url)).FirstOrDefault().FirstOrDefaultYG(
  329. (t) =>
  330. {
  331. try
  332. {
  333. var cc = opcserver.GetEndpoints(t);
  334. opcserver.GetEndpoints(t).Where(n => n.EndpointUrl.Equals(url)).FirstOrDefault().FirstOrDefaultYG((tt) =>
  335. {
  336. try
  337. {
  338. endpointDescription = tt;
  339. opcserver.KeepAliveNotification += new KeepAliveEventHandler(this.Notification_KeepAlive);
  340. opcserver.Connect(tt, true, username, pwd);
  341. if (opcserver.Session.Connected)
  342. {
  343. IsConnection = true;
  344. result = true;
  345. }
  346. else
  347. {
  348. result = false;
  349. }
  350. }
  351. catch (Exception ex)
  352. {
  353. // YG.Log.Instance.WriteLogAdd($"355-->{ex.Message}");
  354. result = false;
  355. }
  356. });
  357. }
  358. catch (Exception ext)
  359. {
  360. // YG.Log.Instance.WriteLogAdd($"362-->{ext.Message}");
  361. }
  362. });
  363. }
  364. }
  365. catch (Exception eex) {
  366. // YG.Log.Instance.WriteLogAdd($"368-->{eex.Message}-->{url}");
  367. }
  368. return result;
  369. }
  370. /// <summary>
  371. /// 连接opcua
  372. /// </summary>
  373. /// <param name="url"></param>
  374. /// <param name="username"></param>
  375. /// <param name="pwd"></param>
  376. public static Server OpcUa_Connection1(string url, string username = "OpcUaClient", string pwd = "12345678")
  377. {
  378. Server serverOpcUa = new Server();
  379. try
  380. {
  381. ApplicationDescriptionCollection applicationDescriptions = serverOpcUa.FindServers(url);
  382. if (applicationDescriptions.Count == 0)
  383. {
  384. // YG.Log.Instance.WriteLogAdd("没有找到服务!");
  385. }
  386. else if (applicationDescriptions.Count == 1)
  387. {
  388. applicationDescriptions[0].DiscoveryUrls.Where(m => m.Equals(url)).FirstOrDefault().FirstOrDefaultYG(
  389. (t) =>
  390. {
  391. try
  392. {
  393. var cc = serverOpcUa.GetEndpoints(t);
  394. serverOpcUa.GetEndpoints(t).Where(n => n.EndpointUrl.Equals(url)).FirstOrDefault().FirstOrDefaultYG((tt) =>
  395. {
  396. try
  397. {
  398. serverOpcUa.Connect(tt, true, username, pwd);
  399. }
  400. catch (Exception ex)
  401. {
  402. // YG.Log.Instance.WriteLogAdd($"355-->{ex.Message}");
  403. }
  404. });
  405. }
  406. catch (Exception ext)
  407. {
  408. // YG.Log.Instance.WriteLogAdd($"362-->{ext.Message}");
  409. }
  410. });
  411. }
  412. }
  413. catch (Exception eex) {
  414. // YG.Log.Instance.WriteLogAdd($"368-->{eex.Message}-->{url}");
  415. }
  416. return serverOpcUa;
  417. }
  418. #endregion
  419. #region 添加用户权限
  420. /// <summary>
  421. /// 添加用户权限
  422. /// </summary>
  423. /// <param name="username"></param>
  424. public bool OpcUa_Access(string username = "OpcUaClient")
  425. {
  426. bool resultb = true;
  427. if (OpcUa_ConState())
  428. {
  429. try
  430. {
  431. string result = "";
  432. string strValue = "StateRead,StateWrite,FrameRead,FrameWrite,SeaRead,SeaWrite,TeaRead,TeaWrite,ToolRead,ToolWrite,DriveRead,DriveWrite,GudRead,GudWrite,PlcRead,PlcWrite,AlarmRead,FsRead,FsWrite,ApWrite,CsomReadx,CsomWritex,PlcReadDBx,PlcWriteDBx,SinuReadAll,SinuWriteAll";
  433. {
  434. string[] vs = strValue.Split(new string[] { "," }, StringSplitOptions.None);
  435. foreach (string s in vs)
  436. {
  437. Server.MethodCallResult methodCallResult = opcserver.MethodCall("/Methods/GiveUserAccess", username, s);
  438. if (methodCallResult != null && !methodCallResult.status.Equals("Good"))
  439. {
  440. result += s + methodCallResult.status;
  441. }
  442. }
  443. }
  444. if (result.Length > 0)
  445. {
  446. resultb = false;
  447. // YG.Log.Instance.WriteLogAdd($"执行权限添加是出现异常:{result}");
  448. }
  449. }
  450. catch (Exception ex)
  451. {
  452. resultb = false;
  453. // YG.Log.Instance.WriteLogAdd($"409-->{ex.Message}");
  454. }
  455. }
  456. return resultb;
  457. }
  458. #endregion
  459. #region 上传文件
  460. /// <summary>
  461. /// 上传文件,不能是文件夹,只能是一个文件,已经默认了一个文件位置, 如果有其他需求后期做调整
  462. /// </summary>
  463. /// <param name="file">需要上传的文件的名字,这个名字是有后缀的,</param>
  464. public void OpcUa_UpLoadFile(string file)
  465. {
  466. try
  467. {
  468. string extension = System.IO.Path.GetExtension(file);
  469. if (string.IsNullOrWhiteSpace(extension))
  470. {
  471. //System.Windows.Forms.MessageBox.Show("请选择要上传的文件");
  472. return;
  473. }
  474. try
  475. {
  476. opcserver.MethodCallCreateNewFile("Sinumerik/FileSystem/NCExtend/webApiMESFILE/", System.IO.Path.GetFileName(file), true);
  477. byte[] data = opcserver.ReadFile(file);
  478. int copylen = 5000;
  479. bool isover = true;
  480. byte[] bt = new byte[copylen];
  481. if (data.Length > copylen)
  482. {
  483. int runcount = data.Length / copylen;
  484. for (int i = 0; i < runcount; i++)
  485. {
  486. Array.Copy(data, i * copylen, bt, 0, copylen);
  487. if (i > 0)
  488. {
  489. isover = false;
  490. }
  491. var cc = opcserver.MethodCallCopyFileToServer($"/Methods/CopyFileToServer", $"Sinumerik/FileSystem/NCExtend/webApiMESFILE/{System.IO.Path.GetFileName(file)}", data, isover);
  492. System.Console.WriteLine($"当前循环到的位置:{i}-->>{cc.status}");
  493. }
  494. int lastleng = data.Length % copylen;
  495. bt = new byte[lastleng];
  496. Array.Copy(data, runcount * copylen, bt, 0, lastleng);
  497. Server.MethodCallResult methodCallResult = opcserver.MethodCallCopyFileToServer($"/Methods/CopyFileToServer", $"Sinumerik/FileSystem/NCExtend/webApiMESFILE/{System.IO.Path.GetFileName(file)}", data, isover);
  498. if (methodCallResult.status.ToUpper().Equals("GOOD"))
  499. {
  500. // YG.Log.Instance.WriteLogAdd("上传文件成功");
  501. }
  502. else
  503. {
  504. // YG.Log.Instance.WriteLogAdd("上传文件失败");
  505. }
  506. }
  507. else
  508. {
  509. Server.MethodCallResult methodCallResult = opcserver.MethodCallCopyFileToServer($"/Methods/CopyFileToServer", $"Sinumerik/FileSystem/NCExtend/webApiMESFILE/{System.IO.Path.GetFileName(file)}", data, isover);
  510. if (methodCallResult.status.ToUpper().Equals("GOOD"))
  511. {
  512. // YG.Log.Instance.WriteLogAdd("上传文件成功");
  513. }
  514. else
  515. {
  516. // YG.Log.Instance.WriteLogAdd("上传文件失败");
  517. }
  518. }
  519. }
  520. catch (Exception ex)
  521. {
  522. // YG.Log.Instance.WriteLogAdd($"{ex.Message}");
  523. //System.Windows.Forms.MessageBox.Show($"{ex.Message}");
  524. }
  525. }
  526. catch (Exception ex)
  527. {
  528. // YG.Log.Instance.WriteLogAdd($"493-->{ex.Message}");
  529. }
  530. }
  531. #endregion
  532. #region 删除文件
  533. /// <summary>
  534. /// 删除文件,只能是一个文件,已经默认了一个文件位置, 如果有其他需求后期做调整
  535. /// </summary>
  536. /// <param name="file">需要删除的文件的名字,这个名字是有后缀的</param>
  537. public void OpcUa_DeleteFile(string file)
  538. {
  539. try
  540. {
  541. Server.MethodCallResult methodCallResult = opcserver.MethodCallDeleteFile($"Sinumerik/FileSystem/NCExtend/webApiMESFILE/{file}");
  542. if (methodCallResult.status.ToUpper().Equals("GOOD"))
  543. {
  544. // YG.Log.Instance.WriteLogAdd("删除文件成功");
  545. }
  546. else
  547. {
  548. // YG.Log.Instance.WriteLogAdd("删除文件失败");
  549. }
  550. }
  551. catch (Exception ex)
  552. {
  553. // YG.Log.Instance.WriteLogAdd($"519-->{ex.Message}");
  554. }
  555. }
  556. public string OpcUa_DeleteFile(string path, string file)
  557. {
  558. string status = "";
  559. try
  560. {
  561. status = opcserver.MethodCallDeleteFile(path + file).status;
  562. if (status.ToUpper().Equals("GOOD"))
  563. {
  564. // YG.Log.Instance.WriteLogAdd("删除文件成功");
  565. }
  566. else
  567. {
  568. // YG.Log.Instance.WriteLogAdd("删除文件失败");
  569. }
  570. }
  571. catch (Exception ex)
  572. {
  573. // YG.Log.Instance.WriteLogAdd($"539-->{ex.Message}");
  574. }
  575. return status;
  576. }
  577. #endregion
  578. #region 创建文件目录
  579. /// <summary>
  580. /// 创建文件目录,,
  581. /// </summary>
  582. /// <param name="file">类似于文件夹名称</param>
  583. public void OpcUa_CreateNewFile(string file = "webApiMESFILE")
  584. {
  585. try
  586. {
  587. Server.MethodCallResult methodCallResult = opcserver.MethodCallCreateNewDir($"Sinumerik/FileSystem/NCExtend", file);
  588. if (methodCallResult.status.ToUpper().Equals("GOOD"))
  589. {
  590. // YG.Log.Instance.WriteLogAdd("删除文件成功");
  591. }
  592. else
  593. {
  594. // YG.Log.Instance.WriteLogAdd("删除文件失败");
  595. }
  596. }
  597. catch (Exception ex)
  598. {
  599. // YG.Log.Instance.WriteLogAdd($"565-->{ex.Message}");
  600. }
  601. }
  602. #endregion
  603. public void disConnect()
  604. {
  605. if (opcserver.Session.Connected)
  606. {
  607. opcserver.Disconnect();
  608. }
  609. }
  610. }
  611. }