终端一体化运控平台
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 

355 righe
14 KiB

  1. using BPA.Helper;
  2. using BPASmartClient.Model;
  3. using BPASmartClient.Model.冰淇淋.Enum;
  4. using BPASmartClient.Peripheral;
  5. using BPASmartClient.SerialPort;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Threading;
  10. using static BPA.Helper.EventBus;
  11. using static BPASmartClient.GSIceCream.MessageDefine;
  12. namespace BPASmartClient.GSIceCream
  13. {
  14. public class IceCreamMachine : BasePeripheral
  15. {
  16. //通讯代理
  17. SerialPortClient commProxy = null;
  18. //是否下发指令,主线程等待
  19. private bool free = false;
  20. //心跳指令
  21. private byte[] cmdHeartDW;
  22. //数据仓库
  23. private DataStorage<byte> dataStorage = new DataStorage<byte>();
  24. //串口COM口
  25. public string PortName { get; set; }
  26. //串口波特率
  27. public string BaudRate { get; set; }
  28. //心跳时间
  29. private DateTime lastRefreshTime = DateTime.MinValue;
  30. //是否在线
  31. public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } }
  32. //private volatile static IceCreamMachine _Instance;
  33. //public static IceCreamMachine GetInstance => _Instance ?? (_Instance = new IceCreamMachine());
  34. public IceCreamMachine()
  35. {
  36. ICMSG_Heart_DW heartDW = new ICMSG_Heart_DW();
  37. cmdHeartDW = IcPack.StructureToByte(heartDW);
  38. }
  39. /// <summary>
  40. /// 主线程开始运行
  41. /// </summary>
  42. public override void Start()
  43. {
  44. try
  45. {
  46. commProxy.Start();
  47. free = false;
  48. MainLoop();
  49. }
  50. catch (Exception ex)
  51. {
  52. MessageLog.GetInstance.ShowEx($"BPASmartClient.GSIceCream 中引发错误,IceCreamMachine 类,描述:[{ex.Message}]");
  53. }
  54. }
  55. /// <summary>
  56. /// 停止运行
  57. /// </summary>
  58. public override void Stop()
  59. {
  60. try
  61. {
  62. commProxy.Stop();
  63. IsConnected = false;
  64. free = true;
  65. }
  66. catch (Exception ex)
  67. {
  68. MessageLog.GetInstance.ShowEx($"BPASmartClient.GSIceCream 中引发错误,IceCreamMachine 类,描述:[{ex.Message}]");
  69. }
  70. }
  71. private MSG_RESOLVE_STEP currentStep;
  72. private void MainLoop()
  73. {
  74. TaskManage.GetInstance.StartLong(new Action(() =>
  75. {
  76. if (!free)
  77. {
  78. commProxy.SendData(cmdHeartDW);
  79. }
  80. Thread.Sleep(500);
  81. }), "冰淇淋询问线程");
  82. TaskManage.GetInstance.StartLong(new Action(() =>
  83. {
  84. ResolveMsg();
  85. }), "冰淇淋解析线程");
  86. }
  87. int contentLength = 0;
  88. int currentContentOffset = 0;
  89. private void ResolveMsg()
  90. {
  91. List<byte> temp = new List<byte>();
  92. //一系列解包
  93. while (dataStorage.GetSize() > 0)
  94. {
  95. byte item = dataStorage.GetData();
  96. switch (currentStep)
  97. {
  98. case MSG_RESOLVE_STEP.NONE:
  99. if (item == MessageDefine.HEADER1)
  100. {
  101. temp.Add(item);
  102. currentStep = MSG_RESOLVE_STEP.HEADER1;
  103. continue;
  104. }
  105. break;
  106. case MSG_RESOLVE_STEP.HEADER1:
  107. if (item == MessageDefine.HEADER2_UP)
  108. {
  109. temp.Add(item);
  110. currentStep = MSG_RESOLVE_STEP.HEADER2;
  111. continue;
  112. }
  113. else
  114. {
  115. temp.Clear();
  116. currentStep = MSG_RESOLVE_STEP.NONE;
  117. continue;
  118. }
  119. case MSG_RESOLVE_STEP.HEADER2:
  120. switch ((IC_CMD)item)
  121. {
  122. case IC_CMD.HEART:
  123. temp.Add(item);
  124. contentLength = MessageDefine.MSG_LENGTH[(IC_CMD)item];
  125. currentContentOffset = 0;
  126. currentStep = MSG_RESOLVE_STEP.CMD;
  127. break;
  128. default:
  129. temp.Clear();
  130. currentStep = MSG_RESOLVE_STEP.NONE;
  131. break;
  132. }
  133. break;
  134. }
  135. int retry = 3;
  136. while (dataStorage.GetSize() < contentLength + 2 && retry >= 0)
  137. {
  138. retry--;
  139. Thread.Sleep(100);
  140. }
  141. if (retry < 0)
  142. {
  143. currentStep = MSG_RESOLVE_STEP.NONE;
  144. currentContentOffset = 0;
  145. contentLength = 0;
  146. continue;
  147. }
  148. while (currentContentOffset < contentLength)
  149. {
  150. item = dataStorage.GetData();
  151. temp.Add(item);
  152. currentContentOffset++;
  153. }
  154. retry = 3;
  155. while (dataStorage.GetSize() < 2 && retry >= 0)
  156. {
  157. retry--;
  158. Thread.Sleep(100);
  159. }
  160. temp.Add(dataStorage.GetData());
  161. temp.Add(dataStorage.GetData());
  162. ProcessMsg(temp.ToArray());
  163. currentStep = MSG_RESOLVE_STEP.NONE;
  164. continue;
  165. }
  166. Thread.Sleep(5);
  167. }
  168. private void ProcessHeart(ICMSG_Heart_UP heartUpMsg)
  169. {
  170. IsConnected = OnLine;
  171. status["IceCreamIsConnected"] = OnLine;
  172. status["IceCreamCurrentMode"] = heartUpMsg.MS;
  173. status["IceCreamYLWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.YLWD_L, heartUpMsg.YLWD_H }, 0);
  174. status["IceCreamHQWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.HQWD_L, heartUpMsg.HQWD_H }, 0);
  175. status["IceCreamHJWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.HJWD_L, heartUpMsg.HJWD_H }, 0);
  176. status["IceCreamDL"] = BitConverter.ToInt16(new byte[] { heartUpMsg.DL_L, heartUpMsg.DL_H }, 0);
  177. status["IceCreamFault"] = (MORKI_FAULT)BitConverter.ToInt16(new byte[] { heartUpMsg.GZ_L, heartUpMsg.GZ_H }, 0);
  178. heartUpMsg.HasGZ(out string msg);
  179. status["IceCreamError"] = msg;
  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.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.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. public override void WriteData(string address, object value)
  324. {
  325. }
  326. }
  327. }