终端一体化运控平台
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.
 
 
 

348 lines
14 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["IceCreamCurrentMode"] = heartUpMsg.MS;
  175. status["IceCreamYLWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.YLWD_L,heartUpMsg.YLWD_H },0);
  176. status["IceCreamHQWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.HQWD_L,heartUpMsg.HQWD_H },0);
  177. status["IceCreamHJWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.HJWD_L,heartUpMsg.HJWD_H },0);
  178. status["IceCreamDL"] = BitConverter.ToInt16(new byte[] { heartUpMsg.DL_L, heartUpMsg.DL_H }, 0);
  179. status["IceCreamFault"] = (MORKI_FAULT)BitConverter.ToInt16(new byte[] { heartUpMsg.GZ_L,heartUpMsg.GZ_H },0);
  180. status["IceCreamCXB"] = heartUpMsg.CXB;
  181. status["IceCreamDLCompleted"] = (heartUpMsg.DLTJ >> 4 & 1) == 1;
  182. if (RTrig.GetInstance("打料完成检测").Start((bool)status["IceCreamDLCompleted"]))
  183. {
  184. MessageLog.GetInstance.Show("打料完成");
  185. }
  186. if (RTrig.GetInstance("打料中检测").Start(!(bool)status["IceCreamDLCompleted"]))
  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["IceCreamYLWD"] = (short)0;
  222. status["IceCreamHQWD"] = (short)0;
  223. status["IceCreamHJWD"] = (short)0;
  224. status["IceCreamDL"] = (short)0;
  225. status["IceCreamDY"] = (short)0;
  226. status["IceCreamCurrentMode"] = MORKI_MODE.待机模式;
  227. status["IceCreamFault"] = MORKI_FAULT.未发生故障;
  228. status["IceCreamCXB"] = (byte)0;
  229. status["IceCreamCXB_Threshold"] = (byte)0;
  230. status["IceCreamDLCompleted"] = true;
  231. status["IceCreamIsConnected"] = false;
  232. }
  233. public override void Init()
  234. {
  235. //广深冰淇淋机模式设置
  236. commProxy = new SerialPortClient(communicationPar.SerialPort, (BaudRates)communicationPar.BaudRate);
  237. commProxy.SetDataStorage(dataStorage);
  238. EventBus.EventBus.GetInstance().Subscribe<GSIceCream_ModeSetEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  239. {
  240. try
  241. {
  242. free = true;
  243. Thread.Sleep(200);
  244. var data = IcPack.StructureToByte(ICMSG_MODE_DW.Build(((GSIceCream_ModeSetEvent)@event).Mode));
  245. commProxy.SendData(data);
  246. Thread.Sleep(200);
  247. free = false;
  248. MessageLog.GetInstance.Show(string.Format("设置模式[{0}]", Enum.GetName(typeof(MORKI_MODE), ((GSIceCream_ModeSetEvent)@event).Mode)));
  249. }
  250. catch (Exception ex)
  251. {
  252. MessageLog.GetInstance.ShowEx($"BPASmartClient.GSIceCream 中引发错误,IceCreamMachine 类,描述:[{ex.Message}]");
  253. }
  254. });
  255. //广深冰淇淋机打料
  256. EventBus.EventBus.GetInstance().Subscribe<GSIceCream_DischargeEvent>(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack)
  257. {
  258. try
  259. {
  260. if ((MORKI_FAULT)status["IceCreamFault"] != MORKI_FAULT.未发生故障)
  261. {
  262. MessageLog.GetInstance.Show(string.Format("当前存在故障[{0}%],不允许制作",(MORKI_FAULT)status["IceCreamFault"]));
  263. new GSIceCream_EndCookEvent() { DeviceId = DeviceId,Status = false }.Publish();
  264. callBack?.Invoke(false);
  265. return;
  266. }
  267. if ((byte)status["IceCreamCXB"] <= 86)
  268. {
  269. MessageLog.GetInstance.Show(string.Format("当前成型比[{0}%],低于86%,不允许制作",(byte)status["IceCreamCXB"]));
  270. new GSIceCream_EndCookEvent() { DeviceId = DeviceId,Status = false }.Publish();
  271. callBack?.Invoke(false );
  272. return;
  273. }
  274. bool modeRight = (MORKI_MODE)status["IceCreamCurrentMode"] == MORKI_MODE.制冷模式;
  275. if (!modeRight)
  276. {
  277. free = true;
  278. Thread.Sleep(200);
  279. var temp = IcPack.StructureToByte(ICMSG_MODE_DW.Build(MORKI_MODE.制冷模式));
  280. commProxy.SendData(temp);
  281. Thread.Sleep(200);
  282. free = false;
  283. MessageLog.GetInstance.Show(string.Format("出料操作->设置模式[{0}]",MORKI_MODE.制冷模式));
  284. DateTime freeTime = DateTime.Now.AddSeconds(5);
  285. while (DateTime.Now < freeTime)
  286. {
  287. Thread.Sleep(10);
  288. modeRight = (MORKI_MODE)status["IceCreamCurrentMode"] == MORKI_MODE.制冷模式;
  289. if (modeRight)
  290. break;
  291. }
  292. }
  293. if (modeRight)
  294. {
  295. free = true;
  296. Thread.Sleep(200);
  297. var data = IcPack.StructureToByte(ICMSG_MODE_DW.Build(MORKI_MODE.打料));
  298. commProxy.SendData(data);
  299. Thread.Sleep(200);
  300. free = false;
  301. new GSIceCream_EndCookEvent() { DeviceId = DeviceId,Status =true}.Publish();
  302. MessageLog.GetInstance.Show(string.Format("出料操作->设置模式[{0}]",MORKI_MODE.打料));
  303. callBack?.Invoke(true);
  304. }
  305. else
  306. {
  307. MessageLog.GetInstance.Show(string.Format("出料操作->模式切换失败,当前模式[{0}],不允许出料",(MORKI_MODE)status["IceCreamCurrentMode"]));
  308. new GSIceCream_EndCookEvent() { DeviceId = DeviceId,Status = false }.Publish();
  309. callBack?.Invoke(false);
  310. }
  311. }
  312. catch (Exception ex)
  313. {
  314. MessageLog.GetInstance.ShowEx($"BPASmartClient.GSIceCream 中引发错误,IceCreamMachine 类,描述:[{ex.Message}]");
  315. callBack?.Invoke(false);
  316. }
  317. });
  318. InitStatus();
  319. //测试用
  320. Start();
  321. MessageLog.GetInstance.Show("冰淇淋机器初始化完成");
  322. }
  323. }
  324. }