终端一体化运控平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

342 line
13 KiB

  1. using BPASmartClient.EventBus;
  2. using BPASmartClient.Helper;
  3. using BPASmartClient.Message;
  4. using BPASmartClient.Model;
  5. using BPASmartClient.Model.冰淇淋.Enum;
  6. using BPASmartClient.Peripheral;
  7. using BPASmartClient.SerialPort;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Threading;
  12. using static BPASmartClient.EventBus.EventBus;
  13. using static BPASmartClient.GSIceCream.MessageDefine;
  14. namespace BPASmartClient.GSIceCream
  15. {
  16. public class IceCreamMachine :BasePeripheral
  17. {
  18. //通讯代理
  19. SerialPortClient commProxy = null;
  20. //是否下发指令,主线程等待
  21. private bool free = false;
  22. //心跳指令
  23. private byte[] cmdHeartDW;
  24. //数据仓库
  25. private DataStorage<byte> dataStorage = new DataStorage<byte>();
  26. //串口COM口
  27. public string PortName { get; set; }
  28. //串口波特率
  29. public string BaudRate { get; set; }
  30. //心跳时间
  31. private DateTime lastRefreshTime = DateTime.MinValue;
  32. //是否在线
  33. public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } }
  34. //private volatile static IceCreamMachine _Instance;
  35. //public static IceCreamMachine GetInstance => _Instance ?? (_Instance = new IceCreamMachine());
  36. public IceCreamMachine()
  37. {
  38. ICMSG_Heart_DW heartDW = new ICMSG_Heart_DW();
  39. cmdHeartDW = IcPack.StructureToByte(heartDW);
  40. }
  41. /// <summary>
  42. /// 主线程开始运行
  43. /// </summary>
  44. public override void Start()
  45. {
  46. try
  47. {
  48. commProxy.Start();
  49. free = false;
  50. MainLoop();
  51. }
  52. catch (Exception ex)
  53. {
  54. MessageLog.GetInstance.ShowEx($"BPASmartClient.GSIceCream 中引发错误,IceCreamMachine 类,描述:[{ex.Message}]");
  55. }
  56. }
  57. /// <summary>
  58. /// 停止运行
  59. /// </summary>
  60. public override void Stop()
  61. {
  62. try
  63. {
  64. commProxy.Stop();
  65. IsConnected = false;
  66. free = true;
  67. }
  68. catch (Exception ex)
  69. {
  70. MessageLog.GetInstance.ShowEx($"BPASmartClient.GSIceCream 中引发错误,IceCreamMachine 类,描述:[{ex.Message}]");
  71. }
  72. }
  73. private MSG_RESOLVE_STEP currentStep;
  74. private void MainLoop()
  75. {
  76. ThreadManage.GetInstance().StartLong(new Action(() =>
  77. {
  78. if (!free)
  79. {
  80. commProxy.SendData(cmdHeartDW);
  81. }
  82. Thread.Sleep(500);
  83. }), "冰淇淋询问线程");
  84. ThreadManage.GetInstance().StartLong(new Action(() =>
  85. {
  86. ResolveMsg();
  87. }), "冰淇淋解析线程");
  88. }
  89. int contentLength = 0;
  90. int currentContentOffset = 0;
  91. private void ResolveMsg()
  92. {
  93. List<byte> temp = new List<byte>();
  94. //一系列解包
  95. while (dataStorage.GetSize() > 0)
  96. {
  97. byte item = dataStorage.GetData();
  98. switch (currentStep)
  99. {
  100. case MSG_RESOLVE_STEP.NONE:
  101. if (item == MessageDefine.HEADER1)
  102. {
  103. temp.Add(item);
  104. currentStep = MSG_RESOLVE_STEP.HEADER1;
  105. continue;
  106. }
  107. break;
  108. case MSG_RESOLVE_STEP.HEADER1:
  109. if (item == MessageDefine.HEADER2_UP)
  110. {
  111. temp.Add(item);
  112. currentStep = MSG_RESOLVE_STEP.HEADER2;
  113. continue;
  114. }
  115. else
  116. {
  117. temp.Clear();
  118. currentStep = MSG_RESOLVE_STEP.NONE;
  119. continue;
  120. }
  121. case MSG_RESOLVE_STEP.HEADER2:
  122. switch ((IC_CMD)item)
  123. {
  124. case IC_CMD.HEART:
  125. temp.Add(item);
  126. contentLength = MessageDefine.MSG_LENGTH[(IC_CMD)item];
  127. currentContentOffset = 0;
  128. currentStep = MSG_RESOLVE_STEP.CMD;
  129. break;
  130. default:
  131. temp.Clear();
  132. currentStep = MSG_RESOLVE_STEP.NONE;
  133. break;
  134. }
  135. break;
  136. }
  137. int retry = 3;
  138. while (dataStorage.GetSize() < contentLength + 2 && retry >= 0)
  139. {
  140. retry--;
  141. Thread.Sleep(100);
  142. }
  143. if (retry < 0)
  144. {
  145. currentStep = MSG_RESOLVE_STEP.NONE;
  146. currentContentOffset = 0;
  147. contentLength = 0;
  148. continue;
  149. }
  150. while (currentContentOffset < contentLength)
  151. {
  152. item = dataStorage.GetData();
  153. temp.Add(item);
  154. currentContentOffset++;
  155. }
  156. retry = 3;
  157. while (dataStorage.GetSize() < 2 && retry >= 0)
  158. {
  159. retry--;
  160. Thread.Sleep(100);
  161. }
  162. temp.Add(dataStorage.GetData());
  163. temp.Add(dataStorage.GetData());
  164. ProcessMsg(temp.ToArray());
  165. currentStep = MSG_RESOLVE_STEP.NONE;
  166. continue;
  167. }
  168. Thread.Sleep(5);
  169. }
  170. private void ProcessHeart(ICMSG_Heart_UP heartUpMsg)
  171. {
  172. IsConnected = OnLine;
  173. status["IceCreamIsConnected"] = OnLine;
  174. status["CurrentMode"] = heartUpMsg.MS;
  175. status["YLWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.YLWD_L,heartUpMsg.YLWD_H },0);
  176. status["HQWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.HQWD_L,heartUpMsg.HQWD_H },0);
  177. status["HJWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.HJWD_L,heartUpMsg.HJWD_H },0);
  178. status["DL"] = BitConverter.ToInt16(new byte[] { heartUpMsg.DL_L, heartUpMsg.DL_H }, 0);
  179. status["Fault"] = (MORKI_FAULT)BitConverter.ToInt16(new byte[] { heartUpMsg.GZ_L,heartUpMsg.GZ_H },0);
  180. status["CXB"] = heartUpMsg.CXB;
  181. status["DLCompleted"] = (heartUpMsg.DLTJ >> 4 & 1) == 1;
  182. if (RTrig.GetInstance("打料完成检测").Start((bool)status["DLCompleted"]))
  183. {
  184. MessageLog.GetInstance.Show("打料完成");
  185. }
  186. if (RTrig.GetInstance("打料中检测").Start(!(bool)status["DLCompleted"]))
  187. {
  188. MessageLog.GetInstance.Show("打料中");
  189. }
  190. Thread.Sleep(100);
  191. }
  192. private void ProcessModeUp(ICMSG_MODE_UP modeUpMsg)
  193. {
  194. MessageLog.GetInstance.Show(string.Format("模式返回为:{0}",modeUpMsg.Mode));
  195. }
  196. public void ProcessMsg(byte[] data)
  197. {
  198. lastRefreshTime = DateTime.Now;
  199. try
  200. {
  201. if (data.Length < 5)
  202. return;
  203. switch (data[2])
  204. {
  205. case (byte)IC_CMD.HEART:
  206. var msg = IcPack.ByteToStructure<ICMSG_Heart_UP>(data.ToArray());
  207. ProcessHeart(msg);
  208. break;
  209. case (byte)IC_CMD.MODE:
  210. var modeUp = IcPack.ByteToStructure<ICMSG_MODE_UP>(data.ToArray());
  211. ProcessModeUp(modeUp);
  212. break;
  213. }
  214. }
  215. catch (Exception ex)
  216. {
  217. }
  218. }
  219. protected override void InitStatus()
  220. {
  221. status["YLWD"] = (short)0;
  222. status["HQWD"] = (short)0;
  223. status["HJWD"] = (short)0;
  224. status["DL"] = (short)0;
  225. status["DY"] = (short)0;
  226. status["CurrentMode"] = MORKI_MODE.待机模式;
  227. status["Fault"] = MORKI_FAULT.未发生故障;
  228. status["CXB"] = (byte)0;
  229. status["CXB_Threshold"] = (byte)0;
  230. status["DLCompleted"] = true;
  231. }
  232. public override void Init()
  233. {
  234. //广深冰淇淋机模式设置
  235. commProxy = new SerialPortClient(communicationPar.SerialPort, (BaudRates)communicationPar.BaudRate);
  236. commProxy.SetDataStorage(dataStorage);
  237. EventBus.EventBus.GetInstance().Subscribe<GSIceCream_ModeSetEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  238. {
  239. try
  240. {
  241. free = true;
  242. Thread.Sleep(200);
  243. var data = IcPack.StructureToByte(ICMSG_MODE_DW.Build(((GSIceCream_ModeSetEvent)@event).Mode));
  244. commProxy.SendData(data);
  245. Thread.Sleep(200);
  246. free = false;
  247. MessageLog.GetInstance.Show(string.Format("设置模式[{0}]", Enum.GetName(typeof(MORKI_MODE), ((GSIceCream_ModeSetEvent)@event).Mode)));
  248. }
  249. catch (Exception ex)
  250. {
  251. MessageLog.GetInstance.ShowEx($"BPASmartClient.GSIceCream 中引发错误,IceCreamMachine 类,描述:[{ex.Message}]");
  252. }
  253. });
  254. //广深冰淇淋机打料
  255. EventBus.EventBus.GetInstance().Subscribe<GSIceCream_DischargeEvent>(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack)
  256. {
  257. try
  258. {
  259. if ((MORKI_FAULT)status["Fault"] != MORKI_FAULT.未发生故障)
  260. {
  261. MessageLog.GetInstance.Show(string.Format("当前存在故障[{0}%],不允许制作",(MORKI_FAULT)status["Fault"]));
  262. new GSIceCream_EndCookEvent() { DeviceId = DeviceId,Status = false }.Publish();
  263. return;
  264. }
  265. if ((byte)status["CXB"] <= 86)
  266. {
  267. MessageLog.GetInstance.Show(string.Format("当前成型比[{0}%],低于86%,不允许制作",(byte)status["CXB"]));
  268. new GSIceCream_EndCookEvent() { DeviceId = DeviceId,Status = false }.Publish();
  269. return;
  270. }
  271. bool modeRight = (MORKI_MODE)status["CurrentMode"] == MORKI_MODE.制冷模式;
  272. if (!modeRight)
  273. {
  274. free = true;
  275. Thread.Sleep(200);
  276. var temp = IcPack.StructureToByte(ICMSG_MODE_DW.Build(MORKI_MODE.制冷模式));
  277. commProxy.SendData(temp);
  278. Thread.Sleep(200);
  279. free = false;
  280. MessageLog.GetInstance.Show(string.Format("出料操作->设置模式[{0}]",MORKI_MODE.制冷模式));
  281. DateTime freeTime = DateTime.Now.AddSeconds(5);
  282. while (DateTime.Now < freeTime)
  283. {
  284. Thread.Sleep(10);
  285. modeRight = (MORKI_MODE)status["CurrentMode"] == MORKI_MODE.制冷模式;
  286. if (modeRight)
  287. break;
  288. }
  289. }
  290. if (modeRight)
  291. {
  292. free = true;
  293. Thread.Sleep(200);
  294. var data = IcPack.StructureToByte(ICMSG_MODE_DW.Build(MORKI_MODE.打料));
  295. commProxy.SendData(data);
  296. Thread.Sleep(200);
  297. free = false;
  298. new GSIceCream_EndCookEvent() { DeviceId = DeviceId,Status =true}.Publish();
  299. MessageLog.GetInstance.Show(string.Format("出料操作->设置模式[{0}]",MORKI_MODE.打料));
  300. }
  301. else
  302. {
  303. MessageLog.GetInstance.Show(string.Format("出料操作->模式切换失败,当前模式[{0}],不允许出料",(MORKI_MODE)status["CurrentMode"]));
  304. new GSIceCream_EndCookEvent() { DeviceId = DeviceId,Status = false }.Publish();
  305. }
  306. }
  307. catch (Exception ex)
  308. {
  309. MessageLog.GetInstance.ShowEx($"BPASmartClient.GSIceCream 中引发错误,IceCreamMachine 类,描述:[{ex.Message}]");
  310. }
  311. });
  312. InitStatus();
  313. //测试用
  314. Start();
  315. MessageLog.GetInstance.Show("冰淇淋机器初始化完成");
  316. }
  317. }
  318. }