Ffu.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO.Ports;
  4. using System.Linq;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using Aitex.Core.RT.Device;
  8. using Aitex.Core.RT.Event;
  9. using Aitex.Core.RT.Log;
  10. using Aitex.Core.RT.OperationCenter;
  11. using Aitex.Core.RT.SCCore;
  12. using Aitex.Core.Util;
  13. using MECF.Framework.Common.Communications;
  14. namespace EFEM.RT.Devices
  15. {
  16. public class Ffu : BaseDevice, IDevice, IConnection
  17. {
  18. private static SerialPort _port;
  19. private readonly object _locker = new object();
  20. public Ffu(string module, string name, string station, string port) : base(module, name, name, "")
  21. {
  22. _port = new SerialPort
  23. {
  24. PortName = port,
  25. BaudRate = 9600,
  26. DataBits = 8,
  27. Parity = Parity.None,
  28. StopBits = StopBits.One,
  29. RtsEnable = false,
  30. DtrEnable = false,
  31. ReadTimeout = 1000,
  32. WriteTimeout = 1000,
  33. NewLine = "\r",
  34. Handshake = Handshake.None
  35. };
  36. _port.DataReceived += OnDataChanged;
  37. _port.ErrorReceived += OnErrorHandler;
  38. Initalized = false;
  39. Station = station;
  40. Address = port;
  41. }
  42. public static bool SpeedSet1 { get; private set; }
  43. public static bool SpeedSet2 { get; private set; }
  44. public string Station { get; }
  45. public bool Initalized { get; set; }
  46. public string Address { get; }
  47. public bool IsConnected => _port.IsOpen;
  48. public bool Connect()
  49. {
  50. Task.Factory.StartNew(() =>
  51. {
  52. var count = SC.ContainsItem("System.ComPortRetryCount")
  53. ? SC.GetValue<int>("System.ComPortRetryCount")
  54. : 3;
  55. var sleep = SC.ContainsItem("System.ComPortRetryDelayTime")
  56. ? SC.GetValue<int>("System.ComPortRetryDelayTime")
  57. : 2;
  58. if (sleep <= 0 || sleep > 10)
  59. sleep = 2;
  60. var retry = 0;
  61. do
  62. {
  63. if (Open())
  64. {
  65. EV.PostInfoLog(Module, $"Connected with {Module}.{Name} .");
  66. break;
  67. }
  68. if (count > 0 && retry++ > count)
  69. {
  70. LOG.Write($"Retry connect {Module}.{Name} stop retry.");
  71. EV.PostAlarmLog(Module, $"Can't connect to {Module}.{Name}.");
  72. break;
  73. }
  74. {
  75. Thread.Sleep(sleep * 1000);
  76. LOG.Write($"Retry connect {Module}.{Name} for the {retry + 1} time.");
  77. }
  78. } while (true);
  79. });
  80. return true;
  81. }
  82. public bool Disconnect()
  83. {
  84. return true;
  85. }
  86. public bool Initialize()
  87. {
  88. ConnectionManager.Instance.Subscribe($"{Name}", this);
  89. Connect();
  90. RegisterOperation();
  91. return true;
  92. }
  93. public void Monitor()
  94. {
  95. }
  96. public void Terminate()
  97. {
  98. Close();
  99. }
  100. public void Reset()
  101. {
  102. }
  103. private void OnDataChanged(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
  104. {
  105. try
  106. {
  107. lock (_locker)
  108. {
  109. if (_port.IsOpen)
  110. {
  111. var str = _port.ReadExisting(); //字符串方式读
  112. var send = str.Split(' ');
  113. switch (send[1])
  114. {
  115. case "03":
  116. if (send.Length > 14)
  117. if (CheckCrc(send))
  118. {
  119. var numStr = string.Join("", send.Skip(9).Take(2).ToArray());
  120. var num = Convert.ToInt32(numStr, 16);
  121. EV.PostInfoLog(Module, $"{Name} speed query result: {num}");
  122. }
  123. break;
  124. case "10":
  125. if (CheckCrc(send))
  126. {
  127. switch (send[0])
  128. {
  129. case "01":
  130. EV.PostInfoLog(Module, "FFU1 : Command had been executed.");
  131. SpeedSet1 = true;
  132. break;
  133. case "02":
  134. EV.PostInfoLog(Module, "FFU2 : Command had been executed.");
  135. SpeedSet2 = true;
  136. break;
  137. }
  138. }
  139. break;
  140. }
  141. LOG.Info($"Communication {_port.PortName} Receive {str}.");
  142. }
  143. }
  144. }
  145. catch (Exception ex)
  146. {
  147. LOG.Write($" {Name} has exception:" + ex.Message);
  148. }
  149. }
  150. private void OnErrorHandler(object sender, SerialErrorReceivedEventArgs serialErrorReceivedEventArgs)
  151. {
  152. Initalized = false;
  153. EV.PostAlarmLog(Module, $"{Display} Communication error, {serialErrorReceivedEventArgs}");
  154. }
  155. private void RegisterOperation()
  156. {
  157. OP.Subscribe($"{Name}.SetSpeed", (cmd, param) =>
  158. {
  159. if (!int.TryParse((string) param[0], out var speed))
  160. {
  161. EV.PostWarningLog(Module, "invalid speed.");
  162. return false;
  163. }
  164. StartAndSetSpeed(speed);
  165. EV.PostInfoLog(Module, $"{Name} speed set to {speed}");
  166. return true;
  167. });
  168. OP.Subscribe($"{Name}.CheckSpeed", (cmd, param) =>
  169. {
  170. QuerySpeed();
  171. EV.PostInfoLog(Module, $"Query {Name} speed");
  172. return true;
  173. });
  174. }
  175. public void StartAndSetSpeed(int speed)
  176. {
  177. lock (_locker)
  178. {
  179. switch (Station)
  180. {
  181. case "01":
  182. SpeedSet1 = false;
  183. break;
  184. case "02":
  185. SpeedSet2 = false;
  186. break;
  187. }
  188. var commandList = new List<string>
  189. {
  190. Station,
  191. "10",
  192. "00",
  193. "01",
  194. "00",
  195. "02",
  196. "04",
  197. "00",
  198. "09"
  199. };
  200. commandList.AddRange(ParseSpeed(speed));
  201. var command = commandList.ToArray();
  202. var add = ModRTU_CRC(command);
  203. _port.Write(string.Join(" ", command) + " " + string.Join(" ", add) + "\r");
  204. }
  205. }
  206. public void QuerySpeed()
  207. {
  208. lock (_locker)
  209. {
  210. var commandList = new List<string>
  211. {
  212. Station,
  213. "03",
  214. "00",
  215. "20",
  216. "00",
  217. "05"
  218. };
  219. var command = commandList.ToArray();
  220. var add = ModRTU_CRC(command);
  221. _port.Write(string.Join(" ", command) + " " + string.Join(" ", add) + "\r");
  222. }
  223. }
  224. public static string[] ParseSpeed(int speed)
  225. {
  226. var x = BitConverter.GetBytes(speed);
  227. var c = new string[2];
  228. c[0] = x[1].ToString("X").Length < 2 ? $"0{x[1]:X}" : $"{x[1]:X}";
  229. c[1] = x[0].ToString("X").Length < 2 ? $"0{x[0]:X}" : $"{x[0]:X}";
  230. return c;
  231. }
  232. private bool Open()
  233. {
  234. lock (_locker)
  235. {
  236. if (_port.IsOpen) Close();
  237. try
  238. {
  239. _port.Open();
  240. _port.DiscardInBuffer();
  241. _port.DiscardOutBuffer();
  242. }
  243. catch (Exception e)
  244. {
  245. // LOG.Write($"Port open failed, {e.Message}");
  246. var reason = _port.PortName + " port open failed,please check configuration。" + e.Message;
  247. //OnErrorHappened(new ErrorEventArgs(reason));
  248. LOG.Write(reason);
  249. return false;
  250. }
  251. }
  252. return true;
  253. }
  254. private bool Close()
  255. {
  256. lock (_locker)
  257. {
  258. if (_port.IsOpen)
  259. try
  260. {
  261. _port.Close();
  262. }
  263. catch (Exception e)
  264. {
  265. var reason = _port.PortName + " port close failed。" + e.Message;
  266. EV.PostInfoLog(Module, reason);
  267. return false;
  268. }
  269. }
  270. return true;
  271. }
  272. private static bool CheckCrc(string[] buffer)
  273. {
  274. return string.Join("", ModRTU_CRC(buffer.Take(buffer.Length - 2).ToArray())) ==
  275. string.Join("", buffer.Skip(buffer.Length - 2).ToArray());
  276. }
  277. private static string[] ModRTU_CRC(string[] buffer)
  278. {
  279. ushort crc = 0xFFFF;
  280. // var buf = System.Text.Encoding.UTF8.GetBytes(String.Join(Environment.NewLine, buffer));
  281. var buf = Array.ConvertAll(buffer.ToArray(), input => Convert.ToByte(input, 16));
  282. var len = buffer.Length;
  283. for (var pos = 0; pos < len; pos++)
  284. {
  285. crc ^= buf[pos]; // XOR byte into least sig. byte of crc
  286. for (var i = 8; i != 0; i--)
  287. // Loop over each bit
  288. if ((crc & 0x0001) != 0)
  289. {
  290. // If the LSB is set
  291. crc >>= 1; // Shift right and XOR 0xA001
  292. crc ^= 0xA001;
  293. }
  294. else // Else LSB is not set
  295. {
  296. crc >>= 1; // Just shift right
  297. }
  298. }
  299. // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
  300. var array = BitConverter.GetBytes(crc);
  301. var retArray = new string[array.Length];
  302. for (var i = 0; i < retArray.Length; i++)
  303. retArray[i] = array[i].ToString("X").Length < 2 ? $"0{array[i]:X}" : array[i].ToString("X");
  304. return retArray;
  305. }
  306. }
  307. }