using BPASmartClient.EventBus; using BPASmartClient.Helper; using BPASmartClient.Message; using BPASmartClient.Model; using BPASmartClient.Model.冰淇淋.Enum; using BPASmartClient.Peripheral; using BPASmartClient.SerialPort; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using static BPASmartClient.EventBus.EventBus; using static BPASmartClient.GSIceCream.MessageDefine; namespace BPASmartClient.GSIceCream { public class IceCreamMachine :BasePeripheral { //通讯代理 SerialPortClient commProxy = null; //是否下发指令,主线程等待 private bool free = false; //心跳指令 private byte[] cmdHeartDW; //数据仓库 private DataStorage dataStorage = new DataStorage(); //串口COM口 public string PortName { get; set; } //串口波特率 public string BaudRate { get; set; } //心跳时间 private DateTime lastRefreshTime = DateTime.MinValue; //是否在线 public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } } //private volatile static IceCreamMachine _Instance; //public static IceCreamMachine GetInstance => _Instance ?? (_Instance = new IceCreamMachine()); public IceCreamMachine() { ICMSG_Heart_DW heartDW = new ICMSG_Heart_DW(); cmdHeartDW = IcPack.StructureToByte(heartDW); } /// /// 主线程开始运行 /// public override void Start() { try { commProxy.Start(); free = false; MainLoop(); } catch (Exception ex) { MessageLog.GetInstance.ShowEx($"BPASmartClient.GSIceCream 中引发错误,IceCreamMachine 类,描述:[{ex.Message}]"); } } /// /// 停止运行 /// public override void Stop() { try { commProxy.Stop(); IsConnected = false; free = true; } catch (Exception ex) { MessageLog.GetInstance.ShowEx($"BPASmartClient.GSIceCream 中引发错误,IceCreamMachine 类,描述:[{ex.Message}]"); } } private MSG_RESOLVE_STEP currentStep; private void MainLoop() { ThreadManage.GetInstance().StartLong(new Action(() => { if (!free) { commProxy.SendData(cmdHeartDW); } Thread.Sleep(500); }), "冰淇淋询问线程"); ThreadManage.GetInstance().StartLong(new Action(() => { ResolveMsg(); }), "冰淇淋解析线程"); } int contentLength = 0; int currentContentOffset = 0; private void ResolveMsg() { List temp = new List(); //一系列解包 while (dataStorage.GetSize() > 0) { byte item = dataStorage.GetData(); switch (currentStep) { case MSG_RESOLVE_STEP.NONE: if (item == MessageDefine.HEADER1) { temp.Add(item); currentStep = MSG_RESOLVE_STEP.HEADER1; continue; } break; case MSG_RESOLVE_STEP.HEADER1: if (item == MessageDefine.HEADER2_UP) { temp.Add(item); currentStep = MSG_RESOLVE_STEP.HEADER2; continue; } else { temp.Clear(); currentStep = MSG_RESOLVE_STEP.NONE; continue; } case MSG_RESOLVE_STEP.HEADER2: switch ((IC_CMD)item) { case IC_CMD.HEART: temp.Add(item); contentLength = MessageDefine.MSG_LENGTH[(IC_CMD)item]; currentContentOffset = 0; currentStep = MSG_RESOLVE_STEP.CMD; break; default: temp.Clear(); currentStep = MSG_RESOLVE_STEP.NONE; break; } break; } int retry = 3; while (dataStorage.GetSize() < contentLength + 2 && retry >= 0) { retry--; Thread.Sleep(100); } if (retry < 0) { currentStep = MSG_RESOLVE_STEP.NONE; currentContentOffset = 0; contentLength = 0; continue; } while (currentContentOffset < contentLength) { item = dataStorage.GetData(); temp.Add(item); currentContentOffset++; } retry = 3; while (dataStorage.GetSize() < 2 && retry >= 0) { retry--; Thread.Sleep(100); } temp.Add(dataStorage.GetData()); temp.Add(dataStorage.GetData()); ProcessMsg(temp.ToArray()); currentStep = MSG_RESOLVE_STEP.NONE; continue; } Thread.Sleep(5); } private void ProcessHeart(ICMSG_Heart_UP heartUpMsg) { IsConnected = OnLine; status["IceCreamIsConnected"] = OnLine; status["CurrentMode"] = heartUpMsg.MS; status["YLWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.YLWD_L,heartUpMsg.YLWD_H },0); status["HQWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.HQWD_L,heartUpMsg.HQWD_H },0); status["HJWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.HJWD_L,heartUpMsg.HJWD_H },0); status["DL"] = BitConverter.ToInt16(new byte[] { heartUpMsg.DL_L, heartUpMsg.DL_H }, 0); status["Fault"] = (MORKI_FAULT)BitConverter.ToInt16(new byte[] { heartUpMsg.GZ_L,heartUpMsg.GZ_H },0); status["CXB"] = heartUpMsg.CXB; status["DLCompleted"] = (heartUpMsg.DLTJ >> 4 & 1) == 1; if (RTrig.GetInstance("打料完成检测").Start((bool)status["DLCompleted"])) { MessageLog.GetInstance.Show("打料完成"); } if (RTrig.GetInstance("打料中检测").Start(!(bool)status["DLCompleted"])) { MessageLog.GetInstance.Show("打料中"); } Thread.Sleep(100); } private void ProcessModeUp(ICMSG_MODE_UP modeUpMsg) { MessageLog.GetInstance.Show(string.Format("模式返回为:{0}",modeUpMsg.Mode)); } public void ProcessMsg(byte[] data) { lastRefreshTime = DateTime.Now; try { if (data.Length < 5) return; switch (data[2]) { case (byte)IC_CMD.HEART: var msg = IcPack.ByteToStructure(data.ToArray()); ProcessHeart(msg); break; case (byte)IC_CMD.MODE: var modeUp = IcPack.ByteToStructure(data.ToArray()); ProcessModeUp(modeUp); break; } } catch (Exception ex) { } } protected override void InitStatus() { status["YLWD"] = (short)0; status["HQWD"] = (short)0; status["HJWD"] = (short)0; status["DL"] = (short)0; status["DY"] = (short)0; status["CurrentMode"] = MORKI_MODE.待机模式; status["Fault"] = MORKI_FAULT.未发生故障; status["CXB"] = (byte)0; status["CXB_Threshold"] = (byte)0; status["DLCompleted"] = true; } public override void Init() { //广深冰淇淋机模式设置 commProxy = new SerialPortClient(communicationPar.SerialPort, (BaudRates)communicationPar.BaudRate); commProxy.SetDataStorage(dataStorage); EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) { try { free = true; Thread.Sleep(200); var data = IcPack.StructureToByte(ICMSG_MODE_DW.Build(((GSIceCream_ModeSetEvent)@event).Mode)); commProxy.SendData(data); Thread.Sleep(200); free = false; MessageLog.GetInstance.Show(string.Format("设置模式[{0}]", Enum.GetName(typeof(MORKI_MODE), ((GSIceCream_ModeSetEvent)@event).Mode))); } catch (Exception ex) { MessageLog.GetInstance.ShowEx($"BPASmartClient.GSIceCream 中引发错误,IceCreamMachine 类,描述:[{ex.Message}]"); } }); //广深冰淇淋机打料 EventBus.EventBus.GetInstance().Subscribe(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack) { try { if ((MORKI_FAULT)status["Fault"] != MORKI_FAULT.未发生故障) { MessageLog.GetInstance.Show(string.Format("当前存在故障[{0}%],不允许制作",(MORKI_FAULT)status["Fault"])); new GSIceCream_EndCookEvent() { DeviceId = DeviceId,Status = false }.Publish(); return; } if ((byte)status["CXB"] <= 86) { MessageLog.GetInstance.Show(string.Format("当前成型比[{0}%],低于86%,不允许制作",(byte)status["CXB"])); new GSIceCream_EndCookEvent() { DeviceId = DeviceId,Status = false }.Publish(); return; } bool modeRight = (MORKI_MODE)status["CurrentMode"] == MORKI_MODE.制冷模式; if (!modeRight) { free = true; Thread.Sleep(200); var temp = IcPack.StructureToByte(ICMSG_MODE_DW.Build(MORKI_MODE.制冷模式)); commProxy.SendData(temp); Thread.Sleep(200); free = false; MessageLog.GetInstance.Show(string.Format("出料操作->设置模式[{0}]",MORKI_MODE.制冷模式)); DateTime freeTime = DateTime.Now.AddSeconds(5); while (DateTime.Now < freeTime) { Thread.Sleep(10); modeRight = (MORKI_MODE)status["CurrentMode"] == MORKI_MODE.制冷模式; if (modeRight) break; } } if (modeRight) { free = true; Thread.Sleep(200); var data = IcPack.StructureToByte(ICMSG_MODE_DW.Build(MORKI_MODE.打料)); commProxy.SendData(data); Thread.Sleep(200); free = false; new GSIceCream_EndCookEvent() { DeviceId = DeviceId,Status =true}.Publish(); MessageLog.GetInstance.Show(string.Format("出料操作->设置模式[{0}]",MORKI_MODE.打料)); } else { MessageLog.GetInstance.Show(string.Format("出料操作->模式切换失败,当前模式[{0}],不允许出料",(MORKI_MODE)status["CurrentMode"])); new GSIceCream_EndCookEvent() { DeviceId = DeviceId,Status = false }.Publish(); } } catch (Exception ex) { MessageLog.GetInstance.ShowEx($"BPASmartClient.GSIceCream 中引发错误,IceCreamMachine 类,描述:[{ex.Message}]"); } }); InitStatus(); //测试用 Start(); MessageLog.GetInstance.Show("冰淇淋机器初始化完成"); } } }