TcClient.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. using Microsoft.AspNetCore.SignalR.Protocol;
  2. using MQTTnet.AspNetCore.Client.Tcp;
  3. using Newtonsoft.Json;
  4. using NPOI.SS.Formula.Functions;
  5. using System;
  6. using System.Net.Sockets;
  7. using System.Reflection;
  8. using System.Text;
  9. using TwinCAT.Ads;
  10. namespace AmrControl.ADS
  11. {
  12. public class TcClient
  13. {
  14. protected static TcClient Instance = null;
  15. /// <summary>
  16. /// ADS 通信模块
  17. /// </summary>
  18. AdsClient tcAdsClient;
  19. List<TcValue> tcConfigs = new List<TcValue>();
  20. string netId = "169.254.88.162.1.1";
  21. int port = 851;
  22. private readonly static object balanceLock = new object();
  23. public bool State = false;
  24. public static TcClient GetInstance()
  25. {
  26. lock(balanceLock)
  27. {
  28. if (Instance == null)
  29. Instance = new TcClient();
  30. }
  31. return Instance;
  32. }
  33. private TcClient()
  34. {
  35. LoadConfig();
  36. netId = AppHelper.ReadAppSettings("Ads", "netID");
  37. string strPort = AppHelper.ReadAppSettings("Ads", "port");
  38. port = int.Parse(strPort);
  39. InitAds();
  40. }
  41. /// <summary>
  42. /// 初始化ADS
  43. /// </summary>
  44. /// <returns></returns>
  45. internal bool InitAds()
  46. {
  47. State = false;
  48. try
  49. {
  50. if (tcAdsClient != null)
  51. {
  52. tcAdsClient.Disconnect();
  53. tcAdsClient.Dispose();
  54. }
  55. }
  56. catch (Exception e)
  57. {
  58. throw new Exception("Initads 中发生异常,尝试关闭ads连接的时候发生:" + e.Message);
  59. }
  60. try
  61. {
  62. tcAdsClient = new AdsClient();
  63. tcAdsClient.Connect(netId, port);
  64. if (tcAdsClient.IsConnected == false)
  65. {
  66. throw new Exception("Initads 中IsConnected == false");
  67. return false;
  68. }
  69. StateInfo state = tcAdsClient.ReadState();
  70. if (state.AdsState == AdsState.Run)
  71. {
  72. State = true;
  73. return true;
  74. }
  75. else
  76. {
  77. throw new Exception("Initads中,AdsState != AdsState.Run ,AdsState = " + state.AdsState.ToString());
  78. return false;
  79. }
  80. }
  81. catch(Exception ex)
  82. {
  83. throw new Exception("Initads 中发生异常,创建新的ads连接的时候发生:" + ex.Message);
  84. return false;
  85. }
  86. }
  87. internal void Close()
  88. {
  89. try
  90. {
  91. State = false;
  92. if (tcAdsClient != null)
  93. {
  94. tcAdsClient.Disconnect();
  95. tcAdsClient.Dispose();
  96. tcAdsClient = null;
  97. }
  98. }
  99. catch (Exception e)
  100. {
  101. //throw new Exception("Initads 中发生异常,尝试关闭ads连接的时候发生:" + e.Message);
  102. }
  103. }
  104. /// <summary>
  105. /// 从配置文件加载硬件的参数配置
  106. /// </summary>
  107. void LoadConfig()
  108. {
  109. string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ads.json");
  110. if (File.Exists(path) == false)
  111. throw new Exception("未找到配置文件ads.json");
  112. try
  113. {
  114. FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
  115. byte[] data = new byte[fs.Length];
  116. fs.Read(data, 0, data.Length);
  117. fs.Close();
  118. string strConfig = Encoding.UTF8.GetString(data);
  119. List<TcValue> ls = JsonConvert.DeserializeObject<List<TcValue>>(strConfig);
  120. tcConfigs.Clear();
  121. tcConfigs.AddRange(ls);
  122. }
  123. catch(Exception ee)
  124. {
  125. Console.WriteLine(ee.Message);
  126. }
  127. }
  128. public bool WriteValue<T>(string name , T Data)
  129. {
  130. uint hvar = 0;
  131. bool ok = true;
  132. if (tcAdsClient == null || string.IsNullOrEmpty(name))
  133. {
  134. return false;
  135. }
  136. //从配置中找到当前参数的定义
  137. TcValue item = tcConfigs.FirstOrDefault(val => val.name.Equals(name));
  138. if (item == null)
  139. {
  140. throw new Exception($"配置文件ads.json中未找到参数:{name}");
  141. //return false;
  142. }
  143. try
  144. {
  145. hvar = tcAdsClient.CreateVariableHandle(name);
  146. }
  147. catch (Exception err)
  148. {
  149. throw new Exception("CreateVariableHandle的时候发生异常:" + err.Message);
  150. }
  151. try
  152. {
  153. switch(typeof(T).Name)
  154. {
  155. case "Boolean":
  156. AdsStream datastream = new AdsStream(1); //bool值位为1
  157. BinaryWriter binwrite = new BinaryWriter(datastream);
  158. datastream.Position = 0;
  159. binwrite.Write((bool)(object)Data);
  160. ReadOnlyMemory<byte> buffer = new ReadOnlyMemory<byte>(datastream.ToArray());
  161. tcAdsClient.Write(hvar, buffer);
  162. break;
  163. case "Byte":
  164. datastream = new AdsStream(1);
  165. binwrite = new BinaryWriter(datastream);
  166. datastream.Position = 0;
  167. binwrite.Write((byte)(object)Data);
  168. buffer = new ReadOnlyMemory<byte>(datastream.ToArray());
  169. tcAdsClient.Write(hvar, buffer);
  170. break;
  171. case "Int32":
  172. datastream = new AdsStream(4);
  173. binwrite = new BinaryWriter(datastream);
  174. datastream.Position = 0;
  175. binwrite.Write((int)(object)Data);
  176. buffer = new ReadOnlyMemory<byte>(datastream.ToArray());
  177. tcAdsClient.Write(hvar, buffer);
  178. break;
  179. case "Single":
  180. datastream = new AdsStream(4);
  181. binwrite = new BinaryWriter(datastream);
  182. datastream.Position = 0;
  183. binwrite.Write((float)(object)Data);
  184. buffer = new ReadOnlyMemory<byte>(datastream.ToArray());
  185. tcAdsClient.Write(hvar, buffer);
  186. break;
  187. case "Double":
  188. datastream = new AdsStream(8);
  189. binwrite = new BinaryWriter(datastream);
  190. datastream.Position = 0;
  191. binwrite.Write((double)(object)Data);
  192. buffer = new ReadOnlyMemory<byte>(datastream.ToArray());
  193. tcAdsClient.Write(hvar, buffer);
  194. break;
  195. case "Int16":
  196. datastream = new AdsStream(2);
  197. binwrite = new BinaryWriter(datastream);
  198. datastream.Position = 0;
  199. binwrite.Write((short)(object)Data);
  200. buffer = new ReadOnlyMemory<byte>(datastream.ToArray());
  201. tcAdsClient.Write(hvar, buffer);
  202. break;
  203. case "Byte[]":
  204. byte[] data = (byte[])(object)Data;
  205. int len = 0;
  206. //写入不超过定义的长度
  207. if (data.Length <= item.length)
  208. {
  209. len = data.Length;
  210. }
  211. else
  212. {
  213. len = item.length;
  214. data[len - 1] = 0;
  215. }
  216. datastream = new AdsStream(len);
  217. binwrite = new BinaryWriter(datastream);
  218. datastream.Position = 0;
  219. binwrite.Write(data,0,len);
  220. buffer = new ReadOnlyMemory<byte>(datastream.ToArray());
  221. tcAdsClient.Write(hvar, buffer);
  222. break;
  223. case "String":
  224. string str = (string)(object)Data;
  225. byte[] bufs = Encoding.ASCII.GetBytes(str);
  226. //加一个 '\0'结尾
  227. data = new byte[bufs.Length + 1];
  228. Array.Copy(bufs,data,bufs.Length);
  229. data[data.Length - 1] = 0; // '\0'
  230. len = 0;
  231. //写入不超过定义的长度
  232. if (data.Length <= item.length)
  233. {
  234. len = data.Length;
  235. }
  236. else
  237. {
  238. len = item.length;
  239. data[len - 1] = 0;
  240. }
  241. datastream = new AdsStream(len);
  242. binwrite = new BinaryWriter(datastream);
  243. datastream.Position = 0;
  244. binwrite.Write(data, 0, len);
  245. buffer = new ReadOnlyMemory<byte>(datastream.ToArray());
  246. tcAdsClient.Write(hvar, buffer);
  247. break;
  248. default:
  249. break;
  250. }
  251. }
  252. catch (Exception err)
  253. {
  254. throw new Exception("Write的时候发生异常:" + err.Message);
  255. ok = false;
  256. }
  257. try
  258. {
  259. tcAdsClient.DeleteVariableHandle(hvar);
  260. }
  261. catch (Exception err)
  262. {
  263. throw new Exception("DeleteVariableHandle的时候发生异常:" + err.Message);
  264. }
  265. return ok;
  266. }
  267. public T ReadValue<T>(string name)
  268. {
  269. uint hvar = 0;
  270. bool ok = true;
  271. T t = default(T);
  272. if (tcAdsClient == null)
  273. {
  274. throw new Exception("ADS未初始化!");
  275. }
  276. if (string.IsNullOrEmpty(name))
  277. {
  278. throw new Exception("参数名称name = null");
  279. }
  280. //从配置中找到当前参数的定义
  281. TcValue item = tcConfigs.FirstOrDefault(val => val.name.Equals(name));
  282. if (item == null)
  283. {
  284. throw new Exception($"配置文件ads.json中未找到参数:{name}");
  285. //return false;
  286. }
  287. try
  288. {
  289. hvar = tcAdsClient.CreateVariableHandle(name);
  290. }
  291. catch (Exception err)
  292. {
  293. throw new Exception("CreateVariableHandle的时候发生异常:" + err.Message);
  294. //return false;
  295. }
  296. try
  297. {
  298. switch (typeof(T).Name)
  299. {
  300. case "Boolean":
  301. byte[] buffer = new byte[1];
  302. Memory<byte> buf = new Memory<byte>(buffer);
  303. int len = tcAdsClient.Read(hvar, buf);
  304. if(len > 0)
  305. {
  306. bool val = buf.GetArray()[0] > 0;
  307. t = (T)Convert.ChangeType(val, typeof(T));
  308. }
  309. else
  310. {
  311. throw new Exception("ADS没有读到值!");
  312. }
  313. break;
  314. case "Byte":
  315. buffer = new byte[1];
  316. buf = new Memory<byte>(buffer);
  317. len = tcAdsClient.Read(hvar, buf);
  318. if (len > 0)
  319. {
  320. t = (T)Convert.ChangeType(buf.GetArray()[0], typeof(T));
  321. }
  322. else
  323. {
  324. throw new Exception("ADS没有读到值!");
  325. }
  326. break;
  327. case "Int32":
  328. buffer = new byte[4];
  329. buf = new Memory<byte>(buffer);
  330. len = tcAdsClient.Read(hvar, buf);
  331. if (len > 0)
  332. {
  333. int val = BitConverter.ToInt32(buf.ToArray(), 0);
  334. t = (T)Convert.ChangeType(val, typeof(T));
  335. }
  336. else
  337. {
  338. throw new Exception("ADS没有读到值!");
  339. }
  340. break;
  341. case "Single":
  342. buffer = new byte[4];
  343. buf = new Memory<byte>(buffer);
  344. len = tcAdsClient.Read(hvar, buf);
  345. if (len > 0)
  346. {
  347. float val = BitConverter.ToSingle(buf.ToArray(), 0);
  348. t = (T)Convert.ChangeType(val, typeof(T));
  349. }
  350. else
  351. {
  352. throw new Exception("ADS没有读到值!");
  353. }
  354. break;
  355. case "Double":
  356. buffer = new byte[8];
  357. buf = new Memory<byte>(buffer);
  358. len = tcAdsClient.Read(hvar, buf);
  359. if (len > 0)
  360. {
  361. double val = BitConverter.ToDouble(buf.ToArray(), 0);
  362. t = (T)Convert.ChangeType(val, typeof(T));
  363. }
  364. else
  365. {
  366. throw new Exception("ADS没有读到值!");
  367. }
  368. break;
  369. case "Int16":
  370. buffer = new byte[2];
  371. buf = new Memory<byte>(buffer);
  372. len = tcAdsClient.Read(hvar, buf);
  373. if (len > 0)
  374. {
  375. short val = BitConverter.ToInt16(buf.ToArray(), 0);
  376. t = (T)Convert.ChangeType(val, typeof(T));
  377. }
  378. else
  379. {
  380. throw new Exception("ADS没有读到值!");
  381. }
  382. break;
  383. case "Byte[]":
  384. buffer = new byte[item.length];
  385. buf = new Memory<byte>(buffer);
  386. len = tcAdsClient.Read(hvar, buf);
  387. if (len > 0)
  388. {
  389. t = (T)Convert.ChangeType(buf.ToArray(), typeof(T));
  390. }
  391. else
  392. {
  393. throw new Exception("ADS没有读到值!");
  394. }
  395. break;
  396. case "String":
  397. buffer = new byte[item.length];
  398. buf = new Memory<byte>(buffer);
  399. len = tcAdsClient.Read(hvar, buf);
  400. if (len > 0)
  401. {
  402. t = (T)Convert.ChangeType(Encoding.ASCII.GetString(buf.ToArray()), typeof(T));
  403. }
  404. else
  405. {
  406. throw new Exception("ADS没有读到值!");
  407. }
  408. break;
  409. default:
  410. break;
  411. }
  412. }
  413. catch (Exception err)
  414. {
  415. throw new Exception("Read的时候发生异常:" + err.Message);
  416. ok = false;
  417. }
  418. try
  419. {
  420. tcAdsClient.DeleteVariableHandle(hvar);
  421. }
  422. catch (Exception err)
  423. {
  424. throw new Exception("DeleteVariableHandle的时候发生异常:" + err.Message);
  425. }
  426. return t;
  427. }
  428. public byte[] ReadBytes(string name,int length)
  429. {
  430. uint hvar = 0;
  431. bool ok = true;
  432. byte[] t = new byte[length];
  433. if (tcAdsClient == null)
  434. {
  435. throw new Exception("ADS未初始化!");
  436. }
  437. try
  438. {
  439. hvar = tcAdsClient.CreateVariableHandle(name);
  440. }
  441. catch (Exception err)
  442. {
  443. throw new Exception("CreateVariableHandle的时候发生异常:" + err.Message);
  444. //return false;
  445. }
  446. try
  447. {
  448. byte[] buffer = new byte[length];
  449. Memory<byte> buf = new Memory<byte>(buffer);
  450. int len = tcAdsClient.Read(hvar, buf);
  451. if (len > 0)
  452. {
  453. Array.Copy(buf.ToArray(), t, len);
  454. buf = null;
  455. buffer = null;
  456. }
  457. else
  458. {
  459. throw new Exception("ADS没有读到值!");
  460. }
  461. }
  462. catch (Exception err)
  463. {
  464. throw new Exception("Read的时候发生异常:" + err.Message);
  465. ok = false;
  466. }
  467. try
  468. {
  469. tcAdsClient.DeleteVariableHandle(hvar);
  470. }
  471. catch (Exception err)
  472. {
  473. throw new Exception("DeleteVariableHandle的时候发生异常:" + err.Message);
  474. }
  475. return t;
  476. }
  477. /// <summary>
  478. /// 不知道异步会不会有问题,看这个逻辑,ADS内部应该是会处理的
  479. /// </summary>
  480. /// <param name="name"></param>
  481. /// <param name="Data"></param>
  482. /// <returns></returns>
  483. bool WriteBool(string name , bool Data)
  484. {
  485. if(tcAdsClient == null)
  486. {
  487. return false;
  488. }
  489. uint hvar = 0;
  490. bool ok = true;
  491. try
  492. {
  493. hvar = tcAdsClient.CreateVariableHandle(name);
  494. }
  495. catch (Exception err)
  496. {
  497. Console.WriteLine("WriteBool中发生异常,CreateVariableHandle的时候发生:" + err.Message);
  498. return false;
  499. }
  500. AdsStream datastream = new AdsStream(1); //bool值位为1
  501. BinaryWriter binwrite = new BinaryWriter(datastream);
  502. datastream.Position = 0;
  503. try
  504. {
  505. binwrite.Write(Data);
  506. ReadOnlyMemory<byte> buffer = new ReadOnlyMemory<byte>(datastream.ToArray());
  507. tcAdsClient.Write(hvar, buffer);
  508. }
  509. catch (Exception err)
  510. {
  511. Console.WriteLine("WriteBool中发生异常,Write的时候发生:" + err.Message);
  512. ok = false;
  513. }
  514. try
  515. {
  516. tcAdsClient.DeleteVariableHandle(hvar);
  517. }
  518. catch (Exception err)
  519. {
  520. Console.WriteLine("WriteBool中发生异常,DeleteVariableHandle的时候发生:" + err.Message);
  521. }
  522. return ok;
  523. }
  524. }
  525. }