DeviceOPCUat.cs 22 KB

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