DeviceOPCUat.cs 22 KB

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