diff --git a/BPASmartClient.DRCoffee/CoffeeMachine.cs b/BPASmartClient.DRCoffee/CoffeeMachine.cs index e1874dd0..db3bd144 100644 --- a/BPASmartClient.DRCoffee/CoffeeMachine.cs +++ b/BPASmartClient.DRCoffee/CoffeeMachine.cs @@ -16,7 +16,7 @@ namespace BPASmartClient.DRCoffee /// /// 咖啡机 /// - public class CoffeeMachine :BasePeripheral + public class CoffeeMachine : BasePeripheral { //通讯代理 SerialPortClient commProxy = null; @@ -95,7 +95,7 @@ namespace BPASmartClient.DRCoffee commProxy.SendData(cmdAsk); } Thread.Sleep(200); - }),"咖啡机询问线程"); + }), "咖啡机询问线程"); ThreadManage.GetInstance().StartLong(new Action(() => { @@ -132,7 +132,7 @@ namespace BPASmartClient.DRCoffee } } Thread.Sleep(5); - }),"咖啡机解析线程"); + }), "咖啡机解析线程"); } /// @@ -153,17 +153,17 @@ namespace BPASmartClient.DRCoffee status["CoffeeAppStatus"] = package.ApplicationStatus; status["CoffeeWarning"] = package.Warning; status["CoffeeFault"] = package.Fault; - + if ((DrCoffeeStatus)status["CoffeeStatus"] == DrCoffeeStatus.Warning || (DrCoffeeStatus)status["CoffeeStatus"] == DrCoffeeStatus.Fault || (DrCoffeeWarning)status["CoffeeWarning"] != DrCoffeeWarning.无警告 || (DrCoffeeFault)status["CoffeeFault"] != DrCoffeeFault.无故障 ) { - IsWork = false; + IsWork = false; } else - IsWork = true; + IsWork = true; } protected override void InitStatus() @@ -176,68 +176,71 @@ namespace BPASmartClient.DRCoffee public override void Init() { - commProxy = new SerialPortClient(communicationPar.SerialPort,(BaudRates)communicationPar.BaudRate); + 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); - drinksOrder.CommCmd = DrCoffeeCommCmd.饮品制作指令; - drinksOrder.DrinksCode = ((DRCoffee_MakeCoffeeEvent)@event).DrinkCode; - commProxy.SendData(DrCoffee.Packe(drinksOrder)); - Thread.Sleep(200); - free = false; - } - catch (Exception ex) - { - MessageLog.GetInstance.ShowEx($"BPASmartClient.DRCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); - } - }); + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + try + { + free = true; + Thread.Sleep(200); + drinksOrder.CommCmd = DrCoffeeCommCmd.饮品制作指令; + drinksOrder.DrinksCode = ((DRCoffee_MakeCoffeeEvent)@event).DrinkCode; + commProxy.SendData(DrCoffee.Packe(drinksOrder)); + Thread.Sleep(200); + free = false; + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx($"BPASmartClient.DRCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); + } + }); //咖博士咖啡机取消制作咖啡 - EventBus.EventBus.GetInstance().Subscribe(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack) - { - try - { - free = true; - Thread.Sleep(200); - drinksOrder.CommCmd = DrCoffeeCommCmd.取消应用指令; - drinksOrder.DrinksCode = 0; - commProxy.SendData(DrCoffee.Packe(drinksOrder)); - Thread.Sleep(200); - free = false; - } - catch (Exception ex) - { - MessageLog.GetInstance.ShowEx($"BPASmartClient.DRCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); - } - }); + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + try + { + free = true; + Thread.Sleep(200); + drinksOrder.CommCmd = DrCoffeeCommCmd.取消应用指令; + drinksOrder.DrinksCode = 0; + commProxy.SendData(DrCoffee.Packe(drinksOrder)); + Thread.Sleep(200); + free = false; + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx($"BPASmartClient.DRCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); + } + }); //咖博士咖啡机模式设置 - EventBus.EventBus.GetInstance().Subscribe(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack) - { - try - { - free = true; - Thread.Sleep(200); - drinksOrder.CommCmd = ((DRCoffee_CoffeeCommCmdEvent)@event).CommCmd; - commProxy.SendData(DrCoffee.Packe(drinksOrder)); - Thread.Sleep(200); - free = false; - } - catch (Exception ex) - { - MessageLog.GetInstance.ShowEx($"BPASmartClient.DRCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); - } - }); + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + try + { + free = true; + Thread.Sleep(200); + drinksOrder.CommCmd = ((DRCoffee_CoffeeCommCmdEvent)@event).CommCmd; + commProxy.SendData(DrCoffee.Packe(drinksOrder)); + Thread.Sleep(200); + free = false; + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx($"BPASmartClient.DRCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); + } + }); InitStatus(); //测试 Start(); } + public override void WriteData(string address, object value) + { + } } } diff --git a/BPASmartClient.Device/AlarmHelper.cs b/BPASmartClient.Device/AlarmHelper.cs index 4e18d268..dcdfb10d 100644 --- a/BPASmartClient.Device/AlarmHelper.cs +++ b/BPASmartClient.Device/AlarmHelper.cs @@ -15,6 +15,7 @@ namespace BPASmartClient.Device public List Alarms { get; set; } = new List(); public List HistoryAlarms { get; set; } = new List(); ConcurrentDictionary flagbit = new ConcurrentDictionary(); + ConcurrentDictionary delays = new ConcurrentDictionary(); public Action AddAction { get; set; } public Action RemoveAction { get; set; } public Action ChangeAction { get; set; } @@ -25,20 +26,25 @@ namespace BPASmartClient.Device /// 触发变量 /// 报警信息 /// 触发类型,上升沿 或 下降沿 - public void EdgeAlarm(bool Trigger, string text, AlarmLevel alarmLevel = AlarmLevel.一般报警, AlarmTriggerType edgeType = AlarmTriggerType.Rising) + public void EdgeAlarm(bool Trigger, string text, int delay = 2, AlarmLevel alarmLevel = AlarmLevel.一般报警, AlarmTriggerType edgeType = AlarmTriggerType.Rising) { if (!flagbit.ContainsKey(text)) flagbit.TryAdd(text, false); - if (edgeType == AlarmTriggerType.Rising ? Trigger : !Trigger) + if (!delays.ContainsKey(text)) delays.TryAdd(text, Delay.GetInstance(text)); + //if (edgeType == AlarmTriggerType.Rising ? Trigger : !Trigger) + if (edgeType == AlarmTriggerType.Rising ? delays[text].Start(Trigger, delay) : delays[text].Start(!Trigger, delay)) { if (edgeType == AlarmTriggerType.Rising ? !flagbit[text] : flagbit[text]) { - AddAlarm(Trigger, text, alarmLevel); + //AddAlarm(Trigger, text, alarmLevel); + AddAlarm(Trigger, text.Substring(0, text.LastIndexOf("-")), alarmLevel); + flagbit[text] = edgeType == AlarmTriggerType.Rising ? true : false; } } else { - RemoveAlarm(text); + //RemoveAlarm(text); + RemoveAlarm(text.Substring(0, text.LastIndexOf("-"))); } if (edgeType == AlarmTriggerType.Rising ? flagbit[text] : !flagbit[text]) flagbit[text] = Trigger; } diff --git a/BPASmartClient.Device/BaseDevice.cs b/BPASmartClient.Device/BaseDevice.cs index 60943f21..aca710eb 100644 --- a/BPASmartClient.Device/BaseDevice.cs +++ b/BPASmartClient.Device/BaseDevice.cs @@ -110,6 +110,17 @@ namespace BPASmartClient.Device #endregion + public void WriteControl(string address, object value) + { + if (peripherals != null) + { + for (int i = 0; i < peripherals.Count; i++) + { + peripherals.ElementAt(i).WriteData(address, value); + } + } + } + /// /// 设备过程日志显示 /// @@ -279,7 +290,7 @@ namespace BPASmartClient.Device if (item.CustomAttributes.Count() > 0 && item.CustomAttributes.ElementAt(0)?.ConstructorArguments.Count() > 0) { var info = item.GetCustomAttribute().AlarmInfo; - if (info != null) alarmHelper.EdgeAlarm(blen, info.ToString()); + if (info != null) alarmHelper.EdgeAlarm(blen, $"{info.ToString()}-{DeviceId}"); } } } diff --git a/BPASmartClient.Device/HardwareStatusAttribute.cs b/BPASmartClient.Device/HardwareStatusAttribute.cs new file mode 100644 index 00000000..8e322a07 --- /dev/null +++ b/BPASmartClient.Device/HardwareStatusAttribute.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.Device +{ + public class HardwareStatusAttribute : Attribute + { + public HardwareStatusAttribute(string describe, string address) + { + Describe = describe; + this.Address = address; + } + + /// + /// 描述 + /// + public string Describe { get; set; } + + + /// + /// 地址 + /// + public string Address { get; set; } + } +} diff --git a/BPASmartClient.Device/IHardwareStatus.cs b/BPASmartClient.Device/IHardwareStatus.cs new file mode 100644 index 00000000..b9a95b53 --- /dev/null +++ b/BPASmartClient.Device/IHardwareStatus.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.Device +{ + /// + /// 硬件状态接口 + /// + public interface IHardwareStatus + { + } +} diff --git a/BPASmartClient.GSIceCream/IceCreamMachine.cs b/BPASmartClient.GSIceCream/IceCreamMachine.cs index 93b661f3..0005faff 100644 --- a/BPASmartClient.GSIceCream/IceCreamMachine.cs +++ b/BPASmartClient.GSIceCream/IceCreamMachine.cs @@ -14,8 +14,8 @@ using static BPASmartClient.GSIceCream.MessageDefine; namespace BPASmartClient.GSIceCream { - public class IceCreamMachine :BasePeripheral - { + public class IceCreamMachine : BasePeripheral + { //通讯代理 SerialPortClient commProxy = null; //是否下发指令,主线程等待 @@ -179,13 +179,13 @@ namespace BPASmartClient.GSIceCream IsConnected = OnLine; status["IceCreamIsConnected"] = OnLine; status["IceCreamCurrentMode"] = heartUpMsg.MS; - status["IceCreamYLWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.YLWD_L,heartUpMsg.YLWD_H },0); - status["IceCreamHQWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.HQWD_L,heartUpMsg.HQWD_H },0); - status["IceCreamHJWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.HJWD_L,heartUpMsg.HJWD_H },0); + status["IceCreamYLWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.YLWD_L, heartUpMsg.YLWD_H }, 0); + status["IceCreamHQWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.HQWD_L, heartUpMsg.HQWD_H }, 0); + status["IceCreamHJWD"] = BitConverter.ToInt16(new byte[] { heartUpMsg.HJWD_L, heartUpMsg.HJWD_H }, 0); status["IceCreamDL"] = BitConverter.ToInt16(new byte[] { heartUpMsg.DL_L, heartUpMsg.DL_H }, 0); - status["IceCreamFault"] = (MORKI_FAULT)BitConverter.ToInt16(new byte[] { heartUpMsg.GZ_L,heartUpMsg.GZ_H },0); + status["IceCreamFault"] = (MORKI_FAULT)BitConverter.ToInt16(new byte[] { heartUpMsg.GZ_L, heartUpMsg.GZ_H }, 0); status["IceCreamCXB"] = heartUpMsg.CXB; - status["IceCreamDLCompleted"] = (heartUpMsg.DLTJ >> 4 & 1) == 1; + status["IceCreamDLCompleted"] = (heartUpMsg.DLTJ >> 4 & 1) == 1; if (RTrig.GetInstance("打料完成检测").Start((bool)status["IceCreamDLCompleted"])) { @@ -201,7 +201,7 @@ namespace BPASmartClient.GSIceCream private void ProcessModeUp(ICMSG_MODE_UP modeUpMsg) { - MessageLog.GetInstance.Show(string.Format("模式返回为:{0}",modeUpMsg.Mode)); + MessageLog.GetInstance.Show(string.Format("模式返回为:{0}", modeUpMsg.Mode)); } public void ProcessMsg(byte[] data) @@ -269,79 +269,83 @@ namespace BPASmartClient.GSIceCream }); //广深冰淇淋机打料 - EventBus.EventBus.GetInstance().Subscribe(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack) - { - try - { - if ((MORKI_FAULT)status["IceCreamFault"] != MORKI_FAULT.未发生故障) - { - MessageLog.GetInstance.Show(string.Format("当前存在故障[{0}%],不允许制作",(MORKI_FAULT)status["IceCreamFault"])); - new GSIceCream_EndCookEvent() { DeviceId = DeviceId,Status = false }.Publish(); - callBack?.Invoke(false); - return; - } - if ((byte)status["IceCreamCXB"] <= 86) - { - MessageLog.GetInstance.Show(string.Format("当前成型比[{0}%],低于86%,不允许制作",(byte)status["IceCreamCXB"])); - new GSIceCream_EndCookEvent() { DeviceId = DeviceId,Status = false }.Publish(); - callBack?.Invoke(false ); - return; - } + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + try + { + if ((MORKI_FAULT)status["IceCreamFault"] != MORKI_FAULT.未发生故障) + { + MessageLog.GetInstance.Show(string.Format("当前存在故障[{0}%],不允许制作", (MORKI_FAULT)status["IceCreamFault"])); + new GSIceCream_EndCookEvent() { DeviceId = DeviceId, Status = false }.Publish(); + callBack?.Invoke(false); + return; + } + if ((byte)status["IceCreamCXB"] <= 86) + { + MessageLog.GetInstance.Show(string.Format("当前成型比[{0}%],低于86%,不允许制作", (byte)status["IceCreamCXB"])); + new GSIceCream_EndCookEvent() { DeviceId = DeviceId, Status = false }.Publish(); + callBack?.Invoke(false); + return; + } - bool modeRight = (MORKI_MODE)status["IceCreamCurrentMode"] == MORKI_MODE.制冷模式; + bool modeRight = (MORKI_MODE)status["IceCreamCurrentMode"] == MORKI_MODE.制冷模式; - if (!modeRight) - { - free = true; - Thread.Sleep(200); + if (!modeRight) + { + free = true; + Thread.Sleep(200); - var temp = IcPack.StructureToByte(ICMSG_MODE_DW.Build(MORKI_MODE.制冷模式)); - commProxy.SendData(temp); + 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.制冷模式)); + 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["IceCreamCurrentMode"] == MORKI_MODE.制冷模式; - if (modeRight) - break; - } - } + DateTime freeTime = DateTime.Now.AddSeconds(5); + while (DateTime.Now < freeTime) + { + Thread.Sleep(10); + modeRight = (MORKI_MODE)status["IceCreamCurrentMode"] == 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.打料)); - callBack?.Invoke(true); - } - else - { - MessageLog.GetInstance.Show(string.Format("出料操作->模式切换失败,当前模式[{0}],不允许出料",(MORKI_MODE)status["IceCreamCurrentMode"])); - new GSIceCream_EndCookEvent() { DeviceId = DeviceId,Status = false }.Publish(); - callBack?.Invoke(false); - } - } - catch (Exception ex) - { - MessageLog.GetInstance.ShowEx($"BPASmartClient.GSIceCream 中引发错误,IceCreamMachine 类,描述:[{ex.Message}]"); - callBack?.Invoke(false); - } - }); + 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.打料)); + callBack?.Invoke(true); + } + else + { + MessageLog.GetInstance.Show(string.Format("出料操作->模式切换失败,当前模式[{0}],不允许出料", (MORKI_MODE)status["IceCreamCurrentMode"])); + new GSIceCream_EndCookEvent() { DeviceId = DeviceId, Status = false }.Publish(); + callBack?.Invoke(false); + } + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx($"BPASmartClient.GSIceCream 中引发错误,IceCreamMachine 类,描述:[{ex.Message}]"); + callBack?.Invoke(false); + } + }); InitStatus(); //测试用 Start(); MessageLog.GetInstance.Show("冰淇淋机器初始化完成"); } + + public override void WriteData(string address, object value) + { + } } } diff --git a/BPASmartClient.IoT/DataVClient.cs b/BPASmartClient.IoT/DataVClient.cs index a0315030..ce6b9913 100644 --- a/BPASmartClient.IoT/DataVClient.cs +++ b/BPASmartClient.IoT/DataVClient.cs @@ -41,7 +41,7 @@ namespace BPASmartClient.IoT DeviceSecret = System.Configuration.ConfigurationManager.AppSettings["DeviceSecret"].ToString(); StartupMode = System.Configuration.ConfigurationManager.AppSettings["StartupMode"].ToString(); BroadcastPubTopic = InternetInfo.BroadcastPubTopic; - + //MaintainTable maintainTable = new MaintainTable(); //maintainTable.Id = Guid.NewGuid().ToString(); @@ -70,6 +70,7 @@ namespace BPASmartClient.IoT /// 客户端ID /// public string ClientId { set; get; } + public List ListDeviceId { set; get; } = new List(); /// /// MQTT上报集合 /// @@ -199,7 +200,17 @@ namespace BPASmartClient.IoT string message = string.Empty; if (StartupMode == "API") { - if (DeviceDataV.Initialize(DataVApiAddress, ClientId, "", ref message)) + while (ListDeviceId.Count == 0) + { + Plugin.GetInstance()?.GetPlugin()?.GetDevices()?.ForEach(device => + { + if (device != null) + { + ListDeviceId.Add(device.DeviceId); + } + }); + } + if (DeviceDataV.Initialize(DataVApiAddress, ClientId, ListDeviceId.Count==0?"": ListDeviceId?.First().ToString(), ref message)) { ProductKey = DeviceDataV.deviceTable.productkey; DeviceName = DeviceDataV.deviceTable.devicename; diff --git a/BPASmartClient.KLMCoffee/CoffeeMachine.cs b/BPASmartClient.KLMCoffee/CoffeeMachine.cs index 0b803647..ae5519cf 100644 --- a/BPASmartClient.KLMCoffee/CoffeeMachine.cs +++ b/BPASmartClient.KLMCoffee/CoffeeMachine.cs @@ -19,7 +19,7 @@ namespace BPASmartClient.KLMCoffee /// /// 伽乐美咖啡机 /// - public class CoffeeMachine :BasePeripheral + public class CoffeeMachine : BasePeripheral { //通讯代理 SerialPortClient commProxy = null; @@ -92,12 +92,12 @@ namespace BPASmartClient.KLMCoffee commProxy.SendData(cmdAsk); } Thread.Sleep(200); - }),"咖啡机询问线程"); + }), "咖啡机询问线程"); ThreadManage.GetInstance().StartLong(new Action(() => { ResolveMsg(); - }),"咖啡机解析线程"); + }), "咖啡机解析线程"); } private void ResolveMsg() @@ -117,7 +117,7 @@ namespace BPASmartClient.KLMCoffee { temp.Add(dataStorage.GetData()); } - List vs = new List() { temp[temp.Count - 4],temp[temp.Count - 3],temp[temp.Count - 2],temp[temp.Count - 1] }; + List vs = new List() { temp[temp.Count - 4], temp[temp.Count - 3], temp[temp.Count - 2], temp[temp.Count - 1] }; //帧尾 if (Encoding.ASCII.GetString(vs.ToArray()).ToLower() == "\\r\\n" || Encoding.ASCII.GetString(vs.ToArray()).ToLower() == "\r\n") @@ -146,9 +146,9 @@ namespace BPASmartClient.KLMCoffee status["Warning"] = systemStatus.faultMessage.dataFault(); status["Keep"] = systemStatus.upkeepMessage; if (systemStatus.faultMessage.IsFault() || systemStatus.upkeepMessage.IsUpkeep()) - IsWork=false; + IsWork = false; else - IsWork=true; + IsWork = true; } } @@ -164,128 +164,130 @@ namespace BPASmartClient.KLMCoffee status["drinkType"] = DrinkType.意式; status["AppStatus"] = TaskIndex.无任务; status["progress"] = 0; - status["Warning"] = new FaultMessage(0x00,0x00).dataFault(); + status["Warning"] = new FaultMessage(0x00, 0x00).dataFault(); status["Keep"] = new UpkeepMessage(0x00).dataFault(); } public override void Init() { - commProxy = new SerialPortClient(PortName,(BaudRates)Enum.Parse(typeof(BaudRates),BaudRate)); + commProxy = new SerialPortClient(PortName, (BaudRates)Enum.Parse(typeof(BaudRates), BaudRate)); commProxy.SetDataStorage(dataStorage); //伽乐美咖啡机制作 - EventBus.EventBus.GetInstance().Subscribe(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack) - { - try - { - free = true; - Thread.Sleep(200); - byte[] data=command.ReturnsCommandData(K95CommandEnum.配方咖啡制作.GetString(),new RecipeModel().Packe(((KLMCoffee_MakeCoffeeEvent)@event).DrinkCode)); - commProxy.SendData(data); - Thread.Sleep(200); - free = false; - } - catch (Exception ex) - { - MessageLog.GetInstance.ShowEx($"BPASmartClient.KLMCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); - } - }); + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + try + { + free = true; + Thread.Sleep(200); + byte[] data = command.ReturnsCommandData(K95CommandEnum.配方咖啡制作.GetString(), new RecipeModel().Packe(((KLMCoffee_MakeCoffeeEvent)@event).DrinkCode)); + commProxy.SendData(data); + Thread.Sleep(200); + free = false; + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx($"BPASmartClient.KLMCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); + } + }); //伽乐美咖啡机取消制作咖啡 - EventBus.EventBus.GetInstance().Subscribe(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack) - { - try - { - free = true; - Thread.Sleep(200); - byte[] data = command.ReturnsCancelMake(); - commProxy.SendData(data); - Thread.Sleep(200); - free = false; - } - catch (Exception ex) - { - MessageLog.GetInstance.ShowEx($"BPASmartClient.KLMCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); - } - }); + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + try + { + free = true; + Thread.Sleep(200); + byte[] data = command.ReturnsCancelMake(); + commProxy.SendData(data); + Thread.Sleep(200); + free = false; + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx($"BPASmartClient.KLMCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); + } + }); //伽乐美咖啡机清洗冲泡器 - EventBus.EventBus.GetInstance().Subscribe(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack) - { - try - { - free = true; - Thread.Sleep(200); - byte[] data = command.ReturnsWashCPJ(); - commProxy.SendData(data); - Thread.Sleep(200); - free = false; - } - catch (Exception ex) - { - MessageLog.GetInstance.ShowEx($"BPASmartClient.KLMCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); - } - }); + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + try + { + free = true; + Thread.Sleep(200); + byte[] data = command.ReturnsWashCPJ(); + commProxy.SendData(data); + Thread.Sleep(200); + free = false; + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx($"BPASmartClient.KLMCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); + } + }); //伽乐美咖啡机放杯确认 - EventBus.EventBus.GetInstance().Subscribe(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack) - { - try - { - free = true; - Thread.Sleep(200); - byte[] data = command.ReturnsCupIsOK(); - commProxy.SendData(data); - Thread.Sleep(200); - free = false; - } - catch (Exception ex) - { - MessageLog.GetInstance.ShowEx($"BPASmartClient.KLMCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); - } - }); + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + try + { + free = true; + Thread.Sleep(200); + byte[] data = command.ReturnsCupIsOK(); + commProxy.SendData(data); + Thread.Sleep(200); + free = false; + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx($"BPASmartClient.KLMCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); + } + }); //伽乐美咖啡机清洗奶沫器 - EventBus.EventBus.GetInstance().Subscribe(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack) - { - try - { - free = true; - Thread.Sleep(200); - byte[] data = command.ReturnsWashNMJ(); - commProxy.SendData(data); - Thread.Sleep(200); - free = false; - } - catch (Exception ex) - { - MessageLog.GetInstance.ShowEx($"BPASmartClient.KLMCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); - } - }); + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + try + { + free = true; + Thread.Sleep(200); + byte[] data = command.ReturnsWashNMJ(); + commProxy.SendData(data); + Thread.Sleep(200); + free = false; + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx($"BPASmartClient.KLMCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); + } + }); //伽乐美咖啡机清洗奶沫器确认 - EventBus.EventBus.GetInstance().Subscribe(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack) - { - try - { - free = true; - Thread.Sleep(200); - byte[] data = command.ReturnsWashNMJIsOK(); - commProxy.SendData(data); - Thread.Sleep(200); - free = false; - } - catch (Exception ex) - { - MessageLog.GetInstance.ShowEx($"BPASmartClient.KLMCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); - } - }); + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + try + { + free = true; + Thread.Sleep(200); + byte[] data = command.ReturnsWashNMJIsOK(); + commProxy.SendData(data); + Thread.Sleep(200); + free = false; + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx($"BPASmartClient.KLMCoffee 中引发错误,CoffeeMachine 类,描述:[{ex.Message}]"); + } + }); InitStatus(); } - + public override void WriteData(string address, object value) + { + } } } diff --git a/BPASmartClient.Lebai/LebaiRobot.cs b/BPASmartClient.Lebai/LebaiRobot.cs index 945029ea..97ac0220 100644 --- a/BPASmartClient.Lebai/LebaiRobot.cs +++ b/BPASmartClient.Lebai/LebaiRobot.cs @@ -19,7 +19,7 @@ using BPASmartClient.Model.乐白机器人; namespace BPASmartClient.Lebai { - public class LebaiRobot: BasePeripheral + public class LebaiRobot : BasePeripheral { /// @@ -51,7 +51,7 @@ namespace BPASmartClient.Lebai if (LebaiHelper.GetInstance().robotData != null) status["RobotMode"] =(ELebaiRModel)LebaiHelper.GetInstance().robotData.RobotMode.Mode; LebaiHelper.GetInstance().GetRobotModeStatus(); Thread.Sleep(10); - },"获取乐白机器人数据"); + }, "获取乐白机器人数据"); } @@ -62,7 +62,7 @@ namespace BPASmartClient.Lebai public override void Init() { - EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack ) + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) { }); @@ -90,7 +90,7 @@ namespace BPASmartClient.Lebai if (@event == null) return; if (@event is LebaiRobot_SetValueEvent SetValueEvent) { - LebaiHelper.GetInstance().SetValue(SetValueEvent.RobotSetValue); + LebaiHelper.GetInstance().SetValue(SetValueEvent.RobotSetValue); } }); //控制机器人 @@ -116,7 +116,7 @@ namespace BPASmartClient.Lebai default: break; } - + } }); //选择机器人场景 @@ -134,6 +134,8 @@ namespace BPASmartClient.Lebai MessageLog.GetInstance.Show("乐白机器人初始化完成"); } - + public override void WriteData(string address, object value) + { + } } } diff --git a/BPASmartClient.MORKSM.BK.PLC/PLCMachine.cs b/BPASmartClient.MORKSM.BK.PLC/PLCMachine.cs index b7b11c7f..3551f1ff 100644 --- a/BPASmartClient.MORKSM.BK.PLC/PLCMachine.cs +++ b/BPASmartClient.MORKSM.BK.PLC/PLCMachine.cs @@ -48,7 +48,7 @@ namespace BPASmartClient.PLC { if (@event == null) return; var par = @event as WriteModel; - + //M32.7地址复位 modbusTcp.Write(par?.Address, par?.Value); }); } @@ -63,6 +63,12 @@ namespace BPASmartClient.PLC } + public override void WriteData(string address, object value) + { + if (address != null && value != null) + modbusTcp.Write(address, value); + } + protected override void InitStatus() { diff --git a/BPASmartClient.MorkF/BPASmartClient.MorkF.csproj b/BPASmartClient.MorkF/BPASmartClient.MorkF.csproj index feae8a16..dd2bae25 100644 --- a/BPASmartClient.MorkF/BPASmartClient.MorkF.csproj +++ b/BPASmartClient.MorkF/BPASmartClient.MorkF.csproj @@ -18,4 +18,8 @@ + + + + diff --git a/BPASmartClient.MorkF/Control_MorkF.cs b/BPASmartClient.MorkF/Control_MorkF.cs index 51d6a30b..290e39d4 100644 --- a/BPASmartClient.MorkF/Control_MorkF.cs +++ b/BPASmartClient.MorkF/Control_MorkF.cs @@ -15,9 +15,11 @@ namespace BPASmartClient.MorkF public class Control_MorkF : BaseDevice { public override DeviceClientType DeviceType => DeviceClientType.MORKSF; - + public AutoResetEvent minorReset = new AutoResetEvent(false); + public AutoResetEvent mainReset = new AutoResetEvent(false); GVL_MorkF morkF = new GVL_MorkF();//全局对象声明 public StirFryBom stirFryBom = new StirFryBom();//创建获取流程的对象 + List resultorder = new List();//调试变量 public static readonly object taskLock = new object(); /// @@ -28,7 +30,7 @@ namespace BPASmartClient.MorkF CommandRegist();//调试 ServerInit(); DataParse();//数据解析 - MessageLog.GetInstance.Show("MORKF 设备初始化完成"); + DeviceProcessLogShow("MORKF 设备初始化完成"); } #region 调试代码 public void CommandRegist() @@ -62,19 +64,16 @@ namespace BPASmartClient.MorkF } //流程 stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T1, RobotActions = new List() { StirFryRobotAction.清洗槽取锅 } }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T2, PotActions = new List() { StirFryPotAction.中火持续, StirFryPotAction.加油, StirFryPotAction.搅拌臂下位, StirFryPotAction.低速旋转 }, During = 25 }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T3, PotActions = new List() { StirFryPotAction.停止火力, StirFryPotAction.停止旋转, StirFryPotAction.搅拌臂上位 } }); - //stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T5, PotActions = new List() { StirFryPotAction.搅拌臂下位, StirFryPotAction.大火持续, StirFryPotAction.低速旋转 }, During = 5 }); - //stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T6, PotActions = new List() { StirFryPotAction.快速旋转 }, During = 50 }); - //stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T7, PotActions = new List() { StirFryPotAction.停止火力, StirFryPotAction.停止旋转, StirFryPotAction.搅拌臂上位 } }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T4, RobotActions = new List() { StirFryRobotAction.加入A料 } }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T5, PotActions = new List() { StirFryPotAction.大火持续, StirFryPotAction.搅拌臂下位, StirFryPotAction.快速旋转 }, During = 25 }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T6, PotActions = new List() { StirFryPotAction.停止火力, StirFryPotAction.停止旋转, StirFryPotAction.搅拌臂上位 } }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T7, RobotActions = new List() { StirFryRobotAction.加入B料 } }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T5, PotActions = new List() { StirFryPotAction.大火持续, StirFryPotAction.搅拌臂下位, StirFryPotAction.快速旋转 }, During = 15 }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T6, PotActions = new List() { StirFryPotAction.停止火力, StirFryPotAction.停止旋转, StirFryPotAction.搅拌臂上位 } }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T8, RobotActions = new List() { StirFryRobotAction.加入C料 } }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T9, PotActions = new List() { StirFryPotAction.大火持续, StirFryPotAction.搅拌臂下位, StirFryPotAction.快速旋转 }, During = 55 }); + stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T2, PotActions = new List() { StirFryPotAction.大火持续 }, During = 5 }); + stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T3, RobotActions = new List() { StirFryRobotAction.加入A料 }, PotActions = new List() { StirFryPotAction.加油, StirFryPotAction.搅拌臂下位, StirFryPotAction.低速旋转 }, During = 6 }); + stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T4, PotActions = new List() { StirFryPotAction.停止旋转, StirFryPotAction.停止火力, StirFryPotAction.搅拌臂上位 } });//加A料 + stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T5, RobotActions = new List() { StirFryRobotAction.加入B料 }, PotActions = new List() { StirFryPotAction.中火持续, StirFryPotAction.搅拌臂下位, StirFryPotAction.快速旋转 }, During = 6 }); + stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T6, PotActions = new List() { StirFryPotAction.停止火力, StirFryPotAction.停止旋转, StirFryPotAction.搅拌臂上位 } });//加B料 + + stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T7, RobotActions = new List() { StirFryRobotAction.加入C料 }, PotActions = new List() { StirFryPotAction.中火持续, StirFryPotAction.搅拌臂下位, StirFryPotAction.快速旋转 }, During = 9 }); + + stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T8, PotActions = new List() { StirFryPotAction.停止火力, StirFryPotAction.停止旋转, StirFryPotAction.搅拌臂上位 } });//加C料 + stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T9, PotActions = new List() { StirFryPotAction.中火持续, StirFryPotAction.搅拌臂下位, StirFryPotAction.快速旋转 }, During = 30 }); stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T10, PotActions = new List() { StirFryPotAction.停止火力, StirFryPotAction.停止旋转, StirFryPotAction.搅拌臂上位 } }); stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T11, RobotActions = new List() { StirFryRobotAction.灶取锅 } }); } @@ -117,29 +116,28 @@ namespace BPASmartClient.MorkF } //流程 stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T1, RobotActions = new List() { StirFryRobotAction.清洗槽取锅 } }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T2, PotActions = new List() { StirFryPotAction.停止火力, StirFryPotAction.搅拌臂下位, StirFryPotAction.低速旋转 }, During = 5 }); + stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T2, RobotActions = new List() { StirFryRobotAction.加入A料 }, PotActions = new List() { StirFryPotAction.中火持续, StirFryPotAction.搅拌臂下位, StirFryPotAction.低速旋转 }, During = 5 }); stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T3, PotActions = new List() { StirFryPotAction.加油 }, During = 12 }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T4, PotActions = new List() { StirFryPotAction.停止旋转, StirFryPotAction.搅拌臂上位 } }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T5, RobotActions = new List() { StirFryRobotAction.加入A料 } }); + stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T4, PotActions = new List() { StirFryPotAction.停止旋转, StirFryPotAction.搅拌臂上位 } });//加A料 + stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T6, RobotActions = new List() { StirFryRobotAction.加入B料 }, PotActions = new List() { StirFryPotAction.搅拌臂下位, StirFryPotAction.快速旋转 }, During = 25 }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T6, PotActions = new List() { StirFryPotAction.搅拌臂下位, StirFryPotAction.低速旋转 }, During = 25 }); + stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T7, PotActions = new List() { StirFryPotAction.停止旋转, StirFryPotAction.搅拌臂上位 } });//加B料 - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T7, PotActions = new List() { StirFryPotAction.停止旋转, StirFryPotAction.搅拌臂上位 } }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T8, RobotActions = new List() { StirFryRobotAction.加入B料 } }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T9, PotActions = new List() { StirFryPotAction.搅拌臂下位, StirFryPotAction.低速旋转 }, During = 30 }); + stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T9, RobotActions = new List() { StirFryRobotAction.加入C料 }, PotActions = new List() { StirFryPotAction.搅拌臂下位, StirFryPotAction.快速旋转 }, During = 30 }); - stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T10, PotActions = new List() { StirFryPotAction.停止火力, StirFryPotAction.停止旋转, StirFryPotAction.搅拌臂上位 } }); + stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T10, PotActions = new List() { StirFryPotAction.停止火力, StirFryPotAction.停止旋转, StirFryPotAction.搅拌臂上位 } });//加C料 + stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T6, PotActions = new List() { StirFryPotAction.搅拌臂下位, StirFryPotAction.快速旋转 }, During = 55 }); stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T11, RobotActions = new List() { StirFryRobotAction.灶取锅 } }); } public void TakePot() { - + WriteData("M14.0", true); } public void TakePotReset() { - + WriteData("M14.0", false); } public void TakeOff() @@ -163,7 +161,7 @@ namespace BPASmartClient.MorkF } public void ThreeBlock() { - // WriteData("M4.0", new bool[] { true, true, false, false, false, false, false, false });//0000 0001 + // WriteData("M4.0", new bool[] { true, true, false, false, false, false, false, false });//0000 0001 WriteData("M4.0", new bool[] { false, true, true, false, false, false, false, false }); } public void OverTurnOff() @@ -226,6 +224,7 @@ namespace BPASmartClient.MorkF morkF.TakeMaterialQueue.Enqueue(new OrderLocInfo() { SuborderId = subId, MaterialLoc = 3 });//C料 morkF.TakePlateQueue.Enqueue(new OrderLocInfo() { SuborderId = subId }); resultorder.AddRange(new int[] { 1, 2, 3 }); + morkF.listStirBom.Add(stirFryBom); } #endregion @@ -325,7 +324,7 @@ namespace BPASmartClient.MorkF // //配方数据地址范围:VW2000 - VW2278 // WriteData("VW2000", recipeBoms.ToArray()); //} - //else { MessageLog.GetInstance.Show("配方数据为空"); } + //else {DeviceProcessLogShow("配方数据为空"); } } /// @@ -340,7 +339,7 @@ namespace BPASmartClient.MorkF { if (order.MorkOrder.GoodBatchings == null) return; OrderCount++; - MessageLog.GetInstance.Show($"接收到{OrderCount}次订单"); + DeviceProcessLogShow($"接收到{OrderCount}次订单"); foreach (var item in order.MorkOrder.GoodBatchings) { var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId); @@ -348,6 +347,7 @@ namespace BPASmartClient.MorkF { if (ushort.TryParse(res.BatchingLoc, out ushort loc)) { + //if (morkF.TakeMaterialQueue.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) //将一个商品的ABC料位置存入队列 morkF.TakeMaterialQueue.Enqueue(new OrderLocInfo() { SuborderId = order.MorkOrder.SuborderId, BatchingId = res.BatchingId, MaterialLoc = ushort.Parse(res.BatchingLoc) }); @@ -372,7 +372,7 @@ namespace BPASmartClient.MorkF } } - //根据ID 查找对应制作流程 + //根据ID 查找对应制作流程, } }); @@ -385,22 +385,146 @@ namespace BPASmartClient.MorkF { TakePlatelTask(); TurntableControl(); - ProcessExecute(); + MainProcessExecute(); + MinorProcessExcute(); SingleProcess(); } - //机器人,锅灶流程执行 - public void ProcessExecute() + //辅流程执行 + private void MinorProcessExcute() { - if (!morkF.ProcessExcuteLock) + if (!morkF.MinorProcessExcuteLock) { - morkF.ProcessExcuteLock = true; + morkF.MinorProcessExcuteLock = true; + Task.Run(() => + { + if (morkF.MinorProcessFlag && !morkF.RoobotIdle && morkF.TakeMaterialQueue.Count > 0) + { + morkF.MinorProessStatus = true; + morkF.MainProcessStatus = false; + StirFryBom bom = morkF.listStirBom.ElementAt(0); + morkF.listStirBom.RemoveAt(0); + foreach (var res in bom.StirFryActions) + { + DeviceProcessLogShow($"执行流程{res.Time}"); + //机器人线程 + Task taskRobot = Task.Run(new Action(() => + { + foreach (var temp in res.RobotActions) + { + switch (temp) + { + case StirFryRobotAction.清洗槽取锅: + TakePotTask();//执行取锅操作 + break; + case StirFryRobotAction.加入A料: + TakeBurdenATask();//执行取A料操作 + break; + case StirFryRobotAction.加入B料: + TakeBurdenATask();//执行取B料操作 + break; + case StirFryRobotAction.加入C料: + TakeBurdenCTask();//执行取C料操作 + break; + case StirFryRobotAction.灶取锅: + OutDishTask();//执行出餐操作 + CleanPotTask();//洗锅操作 + break; + } + + } + + })); + //炒锅线程操作 + Task taskPot = Task.Run(new Action(() => + { + foreach (var temp in res.PotActions) + { + switch (temp) + { + case StirFryPotAction.NONE: + break; + case StirFryPotAction.大火t1s: + KitchenAdjustGears(3); + Task.Delay(1000).Wait(); //大火加热1s//执行大火锅干操作 + break; + case StirFryPotAction.加油: + AddOil();//注油//执行加油操作 + break; + case StirFryPotAction.中火t2s: + KitchenAdjustGears(2); + Task.Delay(2000).Wait();//执行操作 + break; + case StirFryPotAction.小火持续: + KitchenAdjustGears(1); + break; + case StirFryPotAction.中火持续: + KitchenAdjustGears(5); + break; + case StirFryPotAction.大火持续: + KitchenAdjustGears(7); + break; + case StirFryPotAction.停止火力: + KitchenAdjustGears(0);//关闭灶加热 + break; + case StirFryPotAction.搅拌臂上位: + TurnUpStatusDetect();//执行搅拌臂上位操作 + break; + case StirFryPotAction.搅拌臂下位: + TurnDownStatusDetect();//执行搅拌臂下位操作 + break; + case StirFryPotAction.低速旋转: + TurnMachineGearsControl(1);//执行搅拌臂速度1挡操作 + break; + case StirFryPotAction.快速旋转: + TurnMachineGearsControl(2);//执行搅拌臂速度3挡操作 + break; + case StirFryPotAction.停止旋转: + TurnMachineGearsControl(0);//执行搅拌臂速度0挡操作 + break; + } + } + })); + Task.WhenAll(taskRobot, taskPot).Wait();//等待所有线程结束 + Task.Delay(res.During * 1000).Wait();//当前流程延迟 + if (morkF.MainProcessWait) + { + + KitchenAdjustGears(0);//关闭灶加热 + morkF.MinorProessStatus = false; + morkF.MainProcessStatus = true; + //阻塞辅流程 + minorReset.WaitOne(); + } + morkF.MinorProessStatus = true; + morkF.MainProcessStatus = false; + } + morkF.MinorOutMealComplete = true; + } + else + { + morkF.MinorProcessExcuteLock = false;//解除辅流程自锁 + } + }); + } + } + + //机器人,锅灶主流程执行 + public void MainProcessExecute() + { + if (!morkF.MainProcessExcuteLock) + { + morkF.MainProcessExcuteLock = true; Task.Run(new Action(() => { - if (!morkF.RoobotIdle && morkF.InitialComplete && morkF.TakeMaterialQueue.Count > 0) + if (!morkF.RoobotIdle && morkF.InitialComplete && morkF.TakeMaterialQueue.Count > 0 && morkF.MainProcessFlag) { - foreach (var res in stirFryBom.StirFryActions)//遍历所有流程 + morkF.MainProcessStatus = true; + morkF.MinorProessStatus = false; + StirFryBom bom = morkF.listStirBom.ElementAt(0); + morkF.listStirBom.RemoveAt(0); + foreach (var res in bom.StirFryActions)//遍历所有流程 { - MessageLog.GetInstance.Show($"执行流程{res.Time}"); + DeviceProcessLogShow($"执行流程{res.Time}"); //机器人线程 Task taskRobot = Task.Run(new Action(() => { @@ -415,12 +539,10 @@ namespace BPASmartClient.MorkF TakeBurdenATask();//执行取A料操作 break; case StirFryRobotAction.加入B料: - // TakeBurdenBTask();//执行取B料操作 TakeBurdenATask();//执行取B料操作 break; case StirFryRobotAction.加入C料: - //TakeBurdenCTask();//执行取C料操作 - TakeBurdenATask();//执行取C料操作 + TakeBurdenCTask();//执行取C料操作 break; case StirFryRobotAction.灶取锅: OutDishTask();//执行出餐操作 @@ -458,7 +580,7 @@ namespace BPASmartClient.MorkF KitchenAdjustGears(5); break; case StirFryPotAction.大火持续: - KitchenAdjustGears(6); + KitchenAdjustGears(7); break; case StirFryPotAction.停止火力: KitchenAdjustGears(0);//关闭灶加热 @@ -481,14 +603,26 @@ namespace BPASmartClient.MorkF } } })); + Task.WhenAll(taskRobot, taskPot).Wait();//等待所有线程结束 - Task.Delay(res.During * 1000).Wait();//当前流程延迟 + Task.Delay(res.During * 1000).Wait();//当前流程延迟 + if (morkF.MinorProcessWait) + { + KitchenAdjustGears(0);//关闭灶加热 + morkF.MinorProessStatus = true; + morkF.MainProcessStatus = false; + //阻塞主流程 + mainReset.WaitOne(); + } + morkF.MinorProessStatus = false; + morkF.MainProcessStatus = true; + } - morkF.OutMealComplete = true; + morkF.MainOutMealComplete = true; } else { - morkF.ProcessExcuteLock = false;//解除流程互锁 + morkF.MainProcessExcuteLock = false;//解除流程自锁 } })); } @@ -501,13 +635,21 @@ namespace BPASmartClient.MorkF { - //出餐完成,相应变量复位 - if (morkF.OutMealComplete) + //主流程出餐完成,相应变量复位 + if (morkF.MainOutMealComplete) { morkF.TakePlateLock = false; - morkF.TakePotLock = false; morkF.PotInPlace = false; - morkF.ProcessExcuteLock = false; + morkF.MainProcessExcuteLock = false; + morkF.MainOrderMaterialCom = false; + } + //辅流程出餐完成,相应变量复位 + if (morkF.MinorOutMealComplete) + { + morkF.TakePlateLock = false; + morkF.PotInPlace = false; + morkF.MinorProcessExcuteLock = false; + morkF.MinorOrderMaterialCom = false; } } @@ -527,11 +669,11 @@ namespace BPASmartClient.MorkF // if (ushort.TryParse(result[0].BatchingLoc, out ushort loc)) // { // TurnMaterialStore(loc); - // MessageLog.GetInstance.Show($"转台转到【{loc}】位置"); + // DeviceProcessLogShow($"转台转到【{loc}】位置"); // morkF.TurnTableLock = true; //取料完成后置false // } // } - // else MessageLog.GetInstance.Show("未找到可用的物料信息"); + // elseDeviceProcessLogShow("未找到可用的物料信息"); //} //调试代码 @@ -542,12 +684,15 @@ namespace BPASmartClient.MorkF { TurnMaterialStore(resultorder[0]); - MessageLog.GetInstance.Show($"转台转到【{resultorder[0]}】位置"); + DeviceProcessLogShow($"转台转到【{resultorder[0]}】位置"); resultorder.RemoveAt(0); morkF.TurnTableLock = true; //取料完成后置false } - else MessageLog.GetInstance.Show("未找到可用的物料信息"); + else + { + DeviceProcessLogShow("未找到可用的物料信息"); + } } } @@ -565,11 +710,15 @@ namespace BPASmartClient.MorkF if (morkF.TakePlateQueue.TryDequeue(out OrderLocInfo order)) { StartTakePlate(); - morkF.CurrentOrderId = order.SuborderId; + if (morkF.MainProcessStatus) + morkF.MainCurrentOrderId = order.SuborderId; + if (morkF.MinorProessStatus) + morkF.MinorCurrentOrderId = order.SuborderId; morkF.TakePlateLock = true; //订单完成后置false - morkF.OutMealComplete = false; - // OrderChange(morkF.CurrentOrderId, ORDER_STATUS.COOKING); - MessageLog.GetInstance.Show($"订单【{ morkF.CurrentOrderId}】执行取碗控制"); + morkF.MainOutMealComplete = false; + morkF.MinorOutMealComplete = false; + // OrderChange(morkF.CurrentOrderId, ORDER_STATUS.COOKING); + DeviceProcessLogShow($"订单【{order.SuborderId}】执行取碗控制"); } } } @@ -580,7 +729,11 @@ namespace BPASmartClient.MorkF /// private void TakePotTask() { - while (!(!morkF.CleanModule && !morkF.KitchenOneStatus && morkF.CleanComplete))//等待清洗1准备就绪 + //while (!((!morkF.CleanModule && !morkF.KitchenOneStatus && morkF.CleanComplete) || (!morkF.SecondCleanModule && !morkF.KitchenSecondStatus && morkF.SecondCleanComplete))) + //{ + // Task.Delay(5).Wait(); + //} + while (!(!morkF.CleanModule || !morkF.SecondCleanModule) && (!morkF.KitchenOneStatus || !morkF.KitchenSecondStatus) && (morkF.CleanComplete || morkF.SecondCleanComplete))//等待取锅条件满足 { Task.Delay(5).Wait(); } @@ -590,7 +743,12 @@ namespace BPASmartClient.MorkF } TakePotToKitchen(); WriteData("M1.5", false);//清洗模组1完成复位 - MessageLog.GetInstance.Show($"订单【{ morkF.CurrentOrderId}】执行取锅到灶台控制"); + WriteData("M2.0", false);//清洗模组2完成复位 + if (morkF.MainProcessStatus) + DeviceProcessLogShow($"订单【{ morkF.MainCurrentOrderId}】执行取锅到灶台控制"); + if (morkF.MinorProessStatus) + DeviceProcessLogShow($"订单【{ morkF.MinorCurrentOrderId}】执行取锅到灶台控制"); + while (!morkF.PutPotToKitchenComlete) { Task.Delay(5).Wait(); @@ -635,20 +793,17 @@ namespace BPASmartClient.MorkF TakeBurden(loc); TurnReset(loc);//转台复位 - MessageLog.GetInstance.Show($"订单【{ order.SuborderId}】,执行到转台{loc}位置取料"); + DeviceProcessLogShow($"订单【{ order.SuborderId}】,执行到转台{loc}位置取料"); } //等待取料完成 while (!morkF.TakeMaterialComplete) { Task.Delay(5).Wait(); } + morkF.MainOrderMaterialCom = false; WriteData("M14.1", false);//机器人取料完成复位 morkF.TurnTableLock = false;//转台互锁解除 - while (!morkF.FallMaterialComplete)//等待倒料完成 - { - Task.Delay(5).Wait(); - } - MessageLog.GetInstance.Show($"订单【{ order.SuborderId}】,转台{loc}配料倒料完成"); + } /// @@ -665,21 +820,21 @@ namespace BPASmartClient.MorkF int loc = order.MaterialLoc; TakeBurden(loc); TurnReset(loc);//转台复位 - MessageLog.GetInstance.Show($"订单【{ order.SuborderId}】,执行取B料"); + DeviceProcessLogShow($"订单【{ order.SuborderId}】,执行取B料"); } //等待取料完成 while (!morkF.TakeMaterialComplete) { Task.Delay(5).Wait(); } - + morkF.MainOrderMaterialCom = false; WriteData("M14.1", false);//机器人取料完成复位 morkF.TurnTableLock = false;//转台互锁解除 - while (!morkF.FallMaterialComplete)//等待倒料完成 - { - Task.Delay(5).Wait(); - } - MessageLog.GetInstance.Show($"订单【{ order.SuborderId}】,B料倒料完成"); + //while (!morkF.FallMaterialComplete)//等待倒料完成 + //{ + // Task.Delay(5).Wait(); + //} + //MessageLog.GetInstance.Show($"订单【{ order.SuborderId}】,B料倒料完成"); } /// /// 取调味品C料 @@ -696,21 +851,23 @@ namespace BPASmartClient.MorkF int loc = order.MaterialLoc; TakeBurden(loc); TurnReset(loc);//转台复位 - MessageLog.GetInstance.Show($"订单【{ order.SuborderId}】,执行取C料"); + DeviceProcessLogShow($"订单【{ order.SuborderId}】,执行取C料"); } - MessageLog.GetInstance.ShowEx($"剩余配料数量{morkF.TakeMaterialQueue.Count}"); + DeviceProcessLogShow($"剩余配料数量{morkF.TakeMaterialQueue.Count}"); //等待取料完成 while (!morkF.TakeMaterialComplete) { Task.Delay(5).Wait(); } + morkF.MainOrderMaterialCom = false; WriteData("M14.1", false);//机器人取料完成复位 morkF.TurnTableLock = false;//转台互锁解除 - while (!morkF.FallMaterialComplete) - { - Task.Delay(5).Wait(); - } - MessageLog.GetInstance.Show($"订单【{ order.SuborderId}】,C料倒料完成"); + //while (!morkF.FallMaterialComplete) + //{ + // Task.Delay(5).Wait(); + //} + //morkF.SingelOrderMaterialCom = true; + //MessageLog.GetInstance.Show($"订单【{ order.SuborderId}】,C料倒料完成"); //} } /// @@ -718,17 +875,25 @@ namespace BPASmartClient.MorkF /// private void OutDishTask() { - while (morkF.RoobotIdle || morkF.CleanModule || !morkF.ProvidePlateComplete)//等待条件满足 + //while (morkF.RoobotIdle || morkF.CleanModule || !morkF.ProvidePlateComplete)//等待条件满足 + //{ + // Task.Delay(5).Wait(); + //} + while (morkF.RoobotIdle || (!morkF.CleanComplete && !morkF.SecondCleanComplete) || !morkF.ProvidePlateComplete)//等待条件满足 { Task.Delay(5).Wait(); } + if (morkF.TakePlateQueue.Count == 0) { WriteData("M0.7", false);//无订单关闭抽风机 } RobotOutMeal(); WriteData("M1.2", false);//供盘复位 - MessageLog.GetInstance.Show($"订单【{morkF.CurrentOrderId}】正在出餐"); + if (morkF.MainProcessStatus) + DeviceProcessLogShow($"订单【{ morkF.MainCurrentOrderId}】执行取锅到灶台控制"); + if (morkF.MinorProessStatus) + DeviceProcessLogShow($"订单【{ morkF.MinorCurrentOrderId}】执行取锅到灶台控制"); } @@ -737,17 +902,27 @@ namespace BPASmartClient.MorkF /// private void CleanPotTask() { - - while (!morkF.PlaceRinseTableComplete || morkF.CleanModule) { Task.Delay(5).Wait(); } - MessageLog.GetInstance.Show($"订单【{morkF.CurrentOrderId}】出餐完成"); + if (morkF.MainProcessStatus) + DeviceProcessLogShow($"订单【{ morkF.MainCurrentOrderId}】执行取锅到灶台控制"); + if (morkF.MinorProessStatus) + DeviceProcessLogShow($"订单【{ morkF.MinorCurrentOrderId}】执行取锅到灶台控制"); WriteData("M14.2", false);//机器人出餐完成复位 - //OrderChange(morkF.CurrentOrderId, ORDER_STATUS.COMPLETED_COOK); - + //OrderChange(morkF.CurrentOrderId, ORDER_STATUS.COMPLETED_COOK); CleanModuleControl("Start"); + if (morkF.MainProcessStatus)//主流程 + { + morkF.MainProcessFlag = false; + minorReset.Set(); + } + else if (morkF.MinorProessStatus)//辅流程 + { + morkF.MinorProcessFlag = false; + mainReset.Set(); + } } /// /// 任务复位重启 @@ -787,8 +962,15 @@ namespace BPASmartClient.MorkF Task.Delay(5).Wait(); } WriteData("M8.3", false);//下降完成复位 - MessageLog.GetInstance.Show($"翻转机下降完成"); - + DeviceProcessLogShow($"翻转机下降完成"); + //if (morkF.MaterialCount == 3 && morkF.MainProcessStatus) + //{ + // morkF.MainProcessWait = true; + //} + //else if (morkF.MaterialCount == 3 && morkF.MinorProessStatus) + //{ + // morkF.MinorProcessWait = true; + //} } /// @@ -806,7 +988,60 @@ namespace BPASmartClient.MorkF Task.Delay(5).Wait(); } WriteData("M8.1", false);//上升完成复位 - MessageLog.GetInstance.Show("翻转机上升完成"); + if (morkF.MainProcessStatus)//代表主流程执行的操作 + { + if (!morkF.MainOrderMaterialCom) + { + WriteData("M14.3", true);//倒料 + while (!morkF.FallMaterialComplete)//等待倒料完成 + { + Task.Delay(5).Wait(); + } + morkF.MaterialCount++; + WriteData("M14.3", false);//倒料复位 + if (morkF.MaterialCount == 3) + { + //允许执行下一个订单流程 + morkF.MaterialCount = 0; + morkF.MinorProcessFlag = true; + + } + morkF.MainOrderMaterialCom = true; + DeviceProcessLogShow($"订单【{ morkF.MainCurrentOrderId}】,配料倒料完成"); + } + else //辅程准备阻塞 + { + morkF.MainProcessWait = true; + } + } + else if (morkF.MinorProessStatus)//代表辅流程执行的操作 + { + if (!morkF.MinorOrderMaterialCom) + { + WriteData("M14.3", true);//倒料 + while (!morkF.FallMaterialComplete)//等待倒料完成 + { + Task.Delay(5).Wait(); + } + morkF.MaterialCount++; + WriteData("M14.3", false);//倒料复位 + if (morkF.MaterialCount == 3) + { + //允许执行下一个订单流程 + morkF.MaterialCount = 0; + morkF.MainProcessFlag = true; + + } + morkF.MinorOrderMaterialCom = true; + DeviceProcessLogShow($"订单【{ morkF.MinorCurrentOrderId}】,配料倒料完成"); + } + else //主流程准备阻塞 + { + morkF.MinorProcessWait = true; + } + } + + DeviceProcessLogShow("翻转机上升完成"); } private void GetStatus(string key, Action action) @@ -869,8 +1104,10 @@ namespace BPASmartClient.MorkF break; } - MessageLog.GetInstance.Show($"订单【{morkF.CurrentOrderId}】,加热档位调至{number}挡"); - + if (morkF.MainProcessStatus) + DeviceProcessLogShow($"订单【{ morkF.MainCurrentOrderId}】执行取锅到灶台控制"); + if (morkF.MinorProessStatus) + DeviceProcessLogShow($"订单【{ morkF.MinorCurrentOrderId}】执行取锅到灶台控制"); } public void TurnMaterialStore(int loc) { @@ -931,13 +1168,13 @@ namespace BPASmartClient.MorkF } WriteData("M2.7", true);//加油 - WriteData("M0.7",true);//打开抽风机 - MessageLog.GetInstance.Show("开始注油"); + WriteData("M0.7", true);//打开抽风机 + DeviceProcessLogShow("开始注油"); while (!morkF.FallOilComplete) { Task.Delay(5).Wait(); } - MessageLog.GetInstance.Show("注油完成"); + DeviceProcessLogShow("注油完成"); } /// @@ -952,7 +1189,7 @@ namespace BPASmartClient.MorkF // case "Middle": WriteData("", 1); break; case "Down": WriteData("M8.2", true); break; } - MessageLog.GetInstance.Show($"翻转机执行{orientation}操作"); + DeviceProcessLogShow($"翻转机执行{orientation}操作"); } /// /// 翻转机档位控制 @@ -970,7 +1207,7 @@ namespace BPASmartClient.MorkF case 2: WriteData("M7.2", true); break;//翻炒机2挡 case 3: WriteData("M7.3", true); break;//翻炒机3挡 } - MessageLog.GetInstance.Show($"翻转机档位调至{gear}挡"); + DeviceProcessLogShow($"翻转机档位调至{gear}挡"); } /// /// 取A,B,C料 @@ -992,7 +1229,7 @@ namespace BPASmartClient.MorkF { WriteData("M1.4", false); } - MessageLog.GetInstance.Show($"清洗模组执行【{status}】操作"); + DeviceProcessLogShow($"清洗模组执行【{status}】操作"); } public override void Stop() diff --git a/BPASmartClient.MorkF/GVL_MorkF.cs b/BPASmartClient.MorkF/GVL_MorkF.cs index b08a3621..2c656889 100644 --- a/BPASmartClient.MorkF/GVL_MorkF.cs +++ b/BPASmartClient.MorkF/GVL_MorkF.cs @@ -1,4 +1,5 @@ -using System; +using BPA.Models; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; @@ -25,14 +26,29 @@ namespace BPASmartClient.MorkF /// 清洗模组1状态 忙碌1 空闲0 /// public bool CleanModule { get; set; } + + /// + /// 清洗模组2状态 忙碌1 空闲0 + /// + public bool SecondCleanModule { get; set; } /// /// 清洗模组1完成状态 /// public bool CleanComplete { get; set; } + + // + /// 清洗模组2完成状态 + /// + public bool SecondCleanComplete { get; set; } /// /// 锅灶1状态 忙碌1 空闲0 /// public bool KitchenOneStatus { get; set; } + + /// + /// 锅灶1状态 忙碌1 空闲0 + /// + public bool KitchenSecondStatus { get; set; } /// /// 注油完成状态 /// @@ -75,9 +91,13 @@ namespace BPASmartClient.MorkF /// public ConcurrentQueue TakePlateQueue = new ConcurrentQueue(); /// - /// 存放当前订单唯一ID + /// 存放主流程当前订单唯一ID /// - public string CurrentOrderId { get; set; } + public string MainCurrentOrderId { get; set; } + /// + /// 存放辅流程当前订单唯一ID + /// + public string MinorCurrentOrderId { get; set; } /// /// PLC上升沿初始化触发信号 /// @@ -159,17 +179,68 @@ namespace BPASmartClient.MorkF /// 转台互锁 /// public bool TurnTableLock { get; set; } - - public bool ProcessExcuteLock { get; set; } + /// + /// 主流程自锁 + /// + public bool MainProcessExcuteLock { get; set; } + /// + /// 辅流程自锁 + /// + public bool MinorProcessExcuteLock { get; set; } /// /// 开始取料标志 /// public bool AllowTakeMaterial { get; set; } /// - /// 当前订单完成标志 + /// 主流程订单完成标志 + /// + public bool MainOutMealComplete { get; set; } + /// + /// 辅流程订单完成标志 + /// + public bool MinorOutMealComplete { get; set; } + /// + /// 主流程订单取料结束 + /// + public bool MainOrderMaterialCom { get; set; } + /// + /// 主流程等待 + /// + public bool MainProcessWait { get; set; } + /// + /// 辅流程等待 /// - public bool OutMealComplete { get; set; } + public bool MinorProcessWait { get; set; } + /// + /// 辅流程订单取料结束 + /// + public bool MinorOrderMaterialCom { get; set; } + /// + /// 存储订单对应流程对象 + /// + public List listStirBom=new List(); + + /// + /// 下配料次数 + /// + public int MaterialCount { get; set; } + /// + /// 允许执行辅流程标识 + /// + public bool MinorProcessFlag { get; set; } + /// + /// 辅流程执行状态 + /// + public bool MinorProessStatus { get; set; } + /// + /// 允许执行主流程标识 + /// + public bool MainProcessFlag { get; set; } = true; + /// + /// 主流程执行状态 + /// + public bool MainProcessStatus { get; set; } } } diff --git a/BPASmartClient.MorkF/View/DebugView.xaml b/BPASmartClient.MorkF/View/DebugView.xaml new file mode 100644 index 00000000..af377ca3 --- /dev/null +++ b/BPASmartClient.MorkF/View/DebugView.xaml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BPASmartClient.MorkF/View/DebugView.xaml.cs b/BPASmartClient.MorkF/View/DebugView.xaml.cs new file mode 100644 index 00000000..2812751f --- /dev/null +++ b/BPASmartClient.MorkF/View/DebugView.xaml.cs @@ -0,0 +1,30 @@ +using BPASmartClient.MorkF.ViewModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BPASmartClient.MorkF.View +{ + /// + /// DebugView.xaml 的交互逻辑 + /// + public partial class DebugView : UserControl + { + public DebugView() + { + InitializeComponent(); + this.DataContext = new DebugViewModel(); + } + } +} diff --git a/BPASmartClient.MorkF/ViewModel/DebugViewModel.cs b/BPASmartClient.MorkF/ViewModel/DebugViewModel.cs new file mode 100644 index 00000000..ddbc8129 --- /dev/null +++ b/BPASmartClient.MorkF/ViewModel/DebugViewModel.cs @@ -0,0 +1,55 @@ +using BPASmartClient.Helper; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.Input; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MorkF.ViewModel +{ + internal class DebugViewModel : ObservableObject + { + + public RelayCommand PlcInite { get; set; } + public RelayCommand SimulateOrder { get; set; } + public RelayCommand TakePot { get; set; } + public RelayCommand TakePotReset { get; set; } + public RelayCommand TempTurnOff { get; set; } + public RelayCommand OneBlock { get; set; } + public RelayCommand TwoBlock { get; set; } + public RelayCommand ThreeBlock { get; set; } + + public RelayCommand OverTurnOff { get; set; } + public RelayCommand OverOneBlock { get; set; } + public RelayCommand OverTwoBlock { get; set; } + public RelayCommand OverThreeBlock { get; set; } + public RelayCommand OverGoOn { get; set; } + public RelayCommand OverGoDown { get; set; } + public RelayCommand ShreddCabbage { get; set; } + public RelayCommand FryPork { get; set; } + public RelayCommand XingBaoGu { get; set; } + public DebugViewModel() + { + PlcInite = new RelayCommand(() => { ActionManage.GetInstance.Send("InitCommand"); }); + SimulateOrder = new RelayCommand(() => { ActionManage.GetInstance.Send("SimultaorOrder"); }); + TakePot = new RelayCommand(() => { ActionManage.GetInstance.Send("TakePot"); }); + TakePotReset = new RelayCommand(() => { ActionManage.GetInstance.Send("TakePotReset"); }); + TempTurnOff = new RelayCommand(() => { ActionManage.GetInstance.Send("TakeOff"); }); + OneBlock = new RelayCommand(() => { ActionManage.GetInstance.Send("OneBlock"); }); + TwoBlock = new RelayCommand(() => { ActionManage.GetInstance.Send("TwoBlock"); }); + ThreeBlock = new RelayCommand(() => { ActionManage.GetInstance.Send("ThreeBlock"); }); + OverTurnOff = new RelayCommand(() => { ActionManage.GetInstance.Send("OverTurnOff"); }); + OverOneBlock = new RelayCommand(() => { ActionManage.GetInstance.Send("OverOneBlock"); }); + OverTwoBlock = new RelayCommand(() => { ActionManage.GetInstance.Send("OverTwoBlock"); }); + OverThreeBlock = new RelayCommand(() => { ActionManage.GetInstance.Send("OverThreeBlock"); }); + OverGoOn = new RelayCommand(() => { ActionManage.GetInstance.Send("OverGoOn"); }); + OverGoDown = new RelayCommand(() => { ActionManage.GetInstance.Send("OverGoDown"); }); + ShreddCabbage = new RelayCommand(() => { ActionManage.GetInstance.Send("ShreddCabbage"); }); + FryPork = new RelayCommand(() => { ActionManage.GetInstance.Send("FryPork"); }); + XingBaoGu = new RelayCommand(() => { ActionManage.GetInstance.Send("XingBaoGu"); }); + } + + } +} diff --git a/BPASmartClient.MorkM/Alarm.cs b/BPASmartClient.MorkM/Alarm.cs new file mode 100644 index 00000000..3bf2d5d7 --- /dev/null +++ b/BPASmartClient.MorkM/Alarm.cs @@ -0,0 +1,207 @@ +using BPASmartClient.Device; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MorkM +{ + public class Alarm : IAlarm + { + + /// + /// 煮面机左侧低温报警 + /// PLC ---> M230.0 + /// ModbusTcp --> 1570 + /// + [Alarm("煮面机左侧低温报警")] + public bool MachineLeftLowTemperature { get; set; } + + /// + /// 煮面机左侧低温报警 + /// PLC ---> M230.1 + /// ModbusTcp --> 1571 + /// + [Alarm("煮面机右侧低温报警")] + public bool MachineRightLowTemperature { get; set; } + + /// + /// 供碗1缺碗 + /// PLC ---> 230.2 + /// ModbusTcp --> 1572 + /// + [Alarm("供碗1缺碗")] + public bool Supply1_LossBowl { get; set; } + + /// + /// 供碗2缺碗 + /// PLC ---> M230.3 + /// ModbusTcp --> 1573 + /// + [Alarm("供碗2缺碗")] + public bool Supply2_LossBowl { get; set; } + + /// + /// 供碗1出碗检测异常 + /// PLC ---> M230.4 + /// ModbusTcp --> 1574 + /// + [Alarm("供碗1出碗检测异常")] + public bool Supply1_ErrorOutBowl { get; set; } + + /// + /// 供碗2出碗检测异常 + /// PLC ---> M230.5 + /// ModbusTcp --> 1575 + /// + [Alarm("供碗2出碗检测异常")] + public bool Supply2_ErrorOutBowl { get; set; } + + /// + /// 推碗气缸故障 + /// PLC ---> M230.6 + /// ModbusTcp --> 1576 + /// + [Alarm("推碗气缸故障")] + public bool PushBowlCylinderError { get; set; } + + /// + /// 煮面机通讯异常 + /// PLC ---> M230.7 + /// ModbusTcp --> 1577 + /// + [Alarm("煮面机通讯异常")] + public bool NoodleMacCommunicateError { get; set; } + + /// + /// 配料机通讯异常 + /// PLC ---> M231.0 + /// ModbusTcp --> 1580 + /// + [Alarm("配料机通讯异常")] + public bool DosingMacCommunicateError { get; set; } + + /// + /// 机器人通讯异常 + /// PLC ---> M231.1 + /// ModbusTcp --> 1581 + /// + [Alarm("机器人通讯异常")] + public bool RobotMacCommunicateError { get; set; } + + /// + /// 机器人通讯异常 + /// PLC ---> M231.2 + /// ModbusTcp --> 1581 + /// + [Alarm("设备急停")] + public bool DeviceEstop { get; set; } + + /// + /// PLC电池电压低 + /// PLC ---> M231.3 + /// ModbusTcp --> 1583 + /// + [Alarm("PLC电池电压低")] + public bool RobotInitError { get; set; } + + /// + /// 机器人急停 + /// PLC ---> M231.4 + /// ModbusTcp --> 1584 + /// + [Alarm("机器人急停")] + public bool RobotUrgentStop { get; set; } + + /// + /// 机器人不在远程模式 + /// PLC ---> M231.5 + /// ModbusTcp --> 1585 + /// + [Alarm("机器人不在远程模式")] + public bool RobotNotInRemoteMode { get; set; } + + /// + /// 机器人伺服未就绪 + /// PLC ---> M231.6 + /// ModbusTcp --> 1586 + /// + [Alarm("机器人伺服未就绪")] + public bool RobotNotInReady { get; set; } + + /// + /// 机器人本体异常 + /// PLC ---> M231.7 + /// ModbusTcp --> 1587 + /// + [Alarm("机器人本体异常")] + public bool RobotSelfInException { get; set; } + + /// + /// 煮面机左侧缺水 + /// PLC ---> M232.0 + /// ModbusTcp --> 1570 + /// + [Alarm("煮面机左侧缺水报警")] + public bool LeftLackWater { get; set; } + + /// + /// 煮面机右侧缺水 + /// PLC ---> M232.1 + /// ModbusTcp --> 1571 + /// + [Alarm("煮面机右侧缺水报警")] + public bool RightLackWater { get; set; } + + /// + /// 丝杆初始化失败 + /// PLC ---> M232.2 + /// ModbusTcp --> 1571 + /// + [Alarm("丝杆初始化失败")] + public bool SvrewInitFail { get; set; } + + /// + /// 转盘初始化失败 + /// PLC ---> M232.3 + /// ModbusTcp --> 1571 + /// + [Alarm("转盘初始化失败")] + public bool TurntableInitFail { get; set; } + + /// + /// 机器人初始化失败 + /// PLC ---> M232.4 + /// ModbusTcp --> 1571 + /// + [Alarm("机器人初始化失败")] + public bool RobotInitFail { get; set; } + + /// + /// 煮面机初始化失败 + /// PLC ---> M232.5 + /// ModbusTcp --> 1571 + /// + [Alarm("煮面机初始化失败")] + public bool NoodleCookerInitFail { get; set; } + + /// + /// 推碗1步进推杆初始化失败 + /// PLC ---> M232.6 + /// ModbusTcp --> 1571 + /// + [Alarm("推碗1步进推杆初始化失败")] + public bool PushBowlInitFail1 { get; set; } + + /// + /// 推碗2步进推杆初始化失败 + /// PLC ---> M232.7 + /// ModbusTcp --> 1571 + /// + [Alarm("推碗2步进推杆初始化失败")] + public bool PushBowlInitFail2 { get; set; } + + + } +} diff --git a/BPASmartClient.MorkM/BPASmartClient.MorkM.csproj b/BPASmartClient.MorkM/BPASmartClient.MorkM.csproj new file mode 100644 index 00000000..69d03903 --- /dev/null +++ b/BPASmartClient.MorkM/BPASmartClient.MorkM.csproj @@ -0,0 +1,35 @@ + + + + net6.0-windows + enable + true + + + + + + + + + + + Code + + + Code + + + + + + $(DefaultXamlRuntime) + Designer + + + $(DefaultXamlRuntime) + Designer + + + + diff --git a/BPASmartClient.MorkM/Control_MORKM.cs b/BPASmartClient.MorkM/Control_MORKM.cs new file mode 100644 index 00000000..c521ac8a --- /dev/null +++ b/BPASmartClient.MorkM/Control_MORKM.cs @@ -0,0 +1,1000 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Diagnostics; +using BPASmartClient.Device; +using BPASmartClient.Helper; +using BPA.Message.Enum; +using BPASmartClient.Model; +using BPASmartClient.EventBus; +using static BPASmartClient.EventBus.EventBus; +using BPASmartClient.MorkM.Model; +using System.Collections.ObjectModel; +using BPASmartClient.Model.PLC; +using BPASmartClient.MorkM.ViewModel; + +namespace BPASmartClient.MorkM +{ + public class Control_MORKM : BaseDevice + { + public override DeviceClientType DeviceType => DeviceClientType.MORKM; + GVL_MORKM mORKS = new GVL_MORKM(); + Alarm alarm = new Alarm(); + HardwareStatus hardwareStatus = new HardwareStatus(); + + + + public void SimOrder(T simOrder) + { + + if (simOrder != null) + { + + if (simOrder is List locs) + { + OrderInformation newOrder = new OrderInformation();//新加 + List orders = new List(); + string subId = Guid.NewGuid().ToString(); + foreach (var item in locs) + { + if (item >= 1 && item <= 5) + { + orders.Add(new OrderLocInfo() { Loc = item, SuborderId = subId, MakeType = false }); + //mORKS.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { Loc = item, SuborderId = subId }); + //DeviceProcessLogShow($"添加订单:面条位置【{item}】"); + } + if (item >= 10 && item <= 11) + { + mORKS.TakeBowlTask.Enqueue(new OrderLocInfo() { Loc = item, SuborderId = subId, MakeType = false }); + DeviceProcessLogShow($"添加订单:碗位置【{item}】"); + } + } + mORKS.DishNumber = orders.Count;//订单中配菜的数量 + while (orders.Count > 0) + { + for (int i = 0; i < orders.Count; i++) + { + var res = orders.FirstOrDefault(p => p.Loc % 2 != 0); + if (res != null) + { + //if (mORKS.RBTakeNoodleTask.FirstOrDefault(p => p.SuborderId == res.SuborderId) == null) + mORKS.RBTakeNoodleTask.Enqueue(res); + + orders.Remove(res); + + } + else + { + //if (mORKS.RBTakeNoodleTask.FirstOrDefault(p => p.SuborderId == orders[i].SuborderId) == null) + mORKS.RBTakeNoodleTask.Enqueue(orders[i]); + mORKS.VegtabNum++; + orders.RemoveAt(i); + + } + } + } + Dictionary dic = new Dictionary(); + newOrder.DishNum = mORKS.DishNumber; + newOrder.VegatableNumber = mORKS.VegtabNum; + dic.Add(subId, newOrder); + mORKS.Conqueue.Enqueue(dic); + mORKS.VegtabNum = 0; + mORKS.DishNumber = 0; + } + } + } + + ///// + ///// IOT 广播消息命令 + ///// + //public void IotBroadcast(T broadcast) + //{ + // if (broadcast != null && broadcast is IOTCommandModel iOTCommand) + // { + // DeviceProcessLogShow($"IOT 广播消息命令 {iOTCommand.deviceName} 设备命令 {iOTCommand.CommandName} 控制变量{iOTCommand.CommandValue.Keys.First()}{iOTCommand.CommandValue[iOTCommand.CommandValue.Keys.First()]}"); + // switch (iOTCommand.CommandName) + // { + // case 0://控制类 + // if (iOTCommand.CommandValue != null) + // { + // if (iOTCommand.CommandValue.ContainsKey("order")) + // { + // List vs = new List(); + // vs.Add((ushort)(new Random().Next(1, 5))); + // vs.Add(ushort.Parse(iOTCommand.CommandValue["order"])); + // SimOrder(vs); + // } + // else if (iOTCommand.CommandValue.ContainsKey("init")) + // { + // DeviceInit(); + // } + // else if (iOTCommand.CommandValue.ContainsKey("stop")) + // { + // } + // else if (iOTCommand.CommandValue.ContainsKey("start")) + // { + // } + // } + // break; + // case 1://设置属性 + + // break; + // case 2://通知消息 + + // break; + // default: + // break; + // } + // } + //} + + int OrderCount = 0; + ///// + ///// 数据解析 + ///// + public void DataParse() + { + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBackHandle) + { + if (@event == null) return; + if (@event is DoOrderEvent order) + { + mORKS.doOrderEvents.Add(order); + if (order.MorkOrder.GoodBatchings == null) return; + OrderCount++; + OrderChange(order.MorkOrder.SuborderId, ORDER_STATUS.WAIT); + DeviceProcessLogShow($"接收到{OrderCount}次订单"); + //if (order is MorkOrderPush morkOrderPush) + //{ + OrderInformation newOrder = new OrderInformation();//2022.4.30 修改 + List locs = new List(); + foreach (var item in order.MorkOrder.GoodBatchings) + { + var res = Json.Data.orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId); + if (res != null) + { + if (ushort.TryParse(res.BatchingLoc, out ushort loc)) + { + if (loc >= 1 && loc <= 5) + { + locs.Add(new OrderLocInfo() { Loc = ushort.Parse(res.BatchingLoc), SuborderId = order.MorkOrder.SuborderId, BatchingId = res.BatchingId, MakeType = order.MorkOrder.MakeID == "2" }); //新增冒菜干拌or加汤 + } + else if (loc >= 10 && loc <= 11) + { + int index = 0; + if (Json.Data.recipeBoms != null) + { + index = Array.FindIndex(Json.Data.recipeBoms?.RecipeIds.ToArray(), p => p.RecipeId == order.MorkOrder.RecipeId); + index++; + } + if (mORKS.TakeBowlTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) + mORKS.TakeBowlTask.Enqueue(new OrderLocInfo() + { + Loc = 11, + SuborderId = order.MorkOrder.SuborderId, + RecipeNumber = (index >= 1 && index <= 10) ? (ushort)index : (ushort)0 + }); + } + } + } + } + //手动供碗 调试用 + mORKS.TakeBowlTask.Enqueue(new OrderLocInfo() + { + Loc = 11, + SuborderId = order.MorkOrder.SuborderId, + MakeType = order.MorkOrder.MakeID == "2" + }); + mORKS.DishNumber = locs.Count;//订单中配菜的数量 2022.4.30 修改 + while (locs.Count > 0) + { + for (int i = 0; i < locs.Count; i++) + { + var res = locs.FirstOrDefault(p => p.Loc % 2 != 0); + if (res != null) + { + //if (mORKS.RBTakeNoodleTask.FirstOrDefault(p => p.SuborderId == res.SuborderId) == null) + mORKS.RBTakeNoodleTask.Enqueue(res); + locs.Remove(res); + + } + else + { + //if (mORKS.RBTakeNoodleTask.FirstOrDefault(p => p.SuborderId == locs[i].SuborderId) == null) + mORKS.RBTakeNoodleTask.Enqueue(locs[i]); + mORKS.VegtabNum++; + locs.RemoveAt(i); + + } + } + } + + Dictionary dic = new Dictionary(); + newOrder.DishNum = mORKS.DishNumber; + newOrder.VegatableNumber = mORKS.VegtabNum; + //newOrder.MakeType = morkOrderPush.MakeType; + dic.Add(order.MorkOrder.SuborderId, newOrder); + mORKS.Conqueue.Enqueue(dic); + mORKS.VegtabNum = 0; + mORKS.DishNumber = 0; + //} + } + }); + } + + public override void MainTask() + { + mORKS.AllowRun = mORKS.InitComplete; + if (Json.Data.IsVerify) + IsHealth = mORKS.Error && mORKS.InitComplete; + else + IsHealth = true; + + //if (mORKS.AllowRun) + //{ + TakeBowlTask(); + + TakeNoodleTask(); + + OutNoodleTask(); + + SingleDetect(); + + TurntableControl(); + } + + /// + /// 取碗控制 + /// + private void TakeBowlTask() + { + if (mORKS.AllowRun && mORKS.TakeBowlTask.Count > 0 && !mORKS.TakeBowlIdle && !mORKS.TakeBowlInterlock) + { + if (mORKS.TakeBowlTask.TryDequeue(out OrderLocInfo orderLocInfo)) + { + mORKS.TakeBowlId = orderLocInfo.SuborderId; + mORKS.OutMealType = orderLocInfo.MakeType;//新增冒菜干拌or加汤 + TakeBowlControl(orderLocInfo.Loc); + SetRecipeNumber(orderLocInfo.RecipeNumber); + OrderChange(mORKS.TakeBowlId, ORDER_STATUS.COOKING); + DeviceProcessLogShow($"订单【{ mORKS.TakeBowlId}】执行取碗控制,位置:[{orderLocInfo.Loc}]"); + } + mORKS.TakeBowlInterlock = true; + } + } + + /// + /// 转台控制 + /// + private void TurntableControl() + { + if (GeneralConfig.EnableLocalSimOrder) + { + //不做轮询,直接取面,模拟订单使用 + if (mORKS.TurntableMoveInPlace && !mORKS.Feeding && mORKS.InitComplete && !mORKS.AllowTakeNoodle && mORKS.RBTakeNoodleTask.Count > 0) + { + if (mORKS.TurntableLowerLimit) + { + TurntableStart(mORKS.RBTakeNoodleTask.ElementAt(0).Loc); + if (mORKS.RBTakeNoodleTask.ElementAt(0).Loc == mORKS.TurntableFeedbackloc) + { + mORKS.TurntableLocLists.Clear(); + mORKS.AllowTakeNoodle = true; + DeviceProcessLogShow($"控制机器人去转台【{mORKS.RBTakeNoodleTask.ElementAt(0).Loc}】号位置取面"); + } + } + } + } + else + { + //正常轮询 + if (mORKS.TurntableMoveInPlace && !mORKS.Feeding && mORKS.InitComplete && !mORKS.AllowTakeNoodle && mORKS.RBTakeNoodleTask.Count > 0) + { + var result = Json.Data.orderMaterialDelivery.BatchingInfo.Where(p => p.BatchingId == mORKS.RBTakeNoodleTask.ElementAt(0).BatchingId).ToList(); + if (result != null) + { + var res = result.FirstOrDefault(P => P.BatchingLoc == mORKS.TurntableFeedbackloc.ToString()); + if (mORKS.TurntableLowerLimit && res != null) + { + TurntableStart(mORKS.TurntableFeedbackloc); + mORKS.TurntableLocLists.Clear(); + mORKS.AllowTakeNoodle = true; + DeviceProcessLogShow($"控制机器人去转台【{mORKS.TurntableFeedbackloc}】号位置取面"); + } + else + { + if (!mORKS.TurntableInterlock) + { + foreach (var item in result) + { + if (ushort.TryParse(item.BatchingLoc, out ushort loc)) + { + if (mORKS.TurntableFeedbackloc != loc && !mORKS.TurntableLocLists.Contains(loc)) + { + TurntableStart(loc); + DeviceProcessLogShow($"没有物料检测的启动转台控制,转台位置:[{loc}]"); + break; + } + else if (mORKS.TurntableFeedbackloc == loc && !mORKS.TurntableLocLists.Contains(loc)) mORKS.TurntableLocLists.Add(loc); + } + } + } + } + } + else DeviceProcessLogShow("未找到可用的物料信息"); + } + } + + //转台到位检测 + if (RTrig.GetInstance("TurntableInPlace").Start(mORKS.TurntableMoveInPlace && mORKS.CurrentLoc == mORKS.TurntableFeedbackloc)) + { + mORKS.CurrentLoc = 0; + mORKS.TurntableInterlock = false; + DeviceProcessLogShow("转台到位检测"); + } + + //补料完成检测 + if (RTrig.GetInstance("FeedComplete").Start(mORKS.FeedComplete)) + { + if (!mORKS.AllowTakeNoodle && mORKS.TurntableLocLists.Count > 0) + { + mORKS.TurntableLocLists.Clear(); + mORKS.TurntableInterlock = false; + DeviceProcessLogShow("补料完成检测"); + } + } + } + /// + /// 取面任务 + /// + private void TakeNoodleTask() + { + //取面控制 + if (mORKS.AllowRun && mORKS.RobotIdle && !mORKS.Feeding && (!mORKS.RobotTaskInterlock || !mORKS.VegNoodlesLock && mORKS.relock) && mORKS.AllowTakeNoodle && mORKS.TurntableMoveInPlace && !mORKS.TakeNoodleInterlock && !mORKS.OutNoodleing && mORKS.RBTakeNoodleTask.Count > 0) + { + + int loc = Array.FindIndex(mORKS.NoodleCookerStatus, p => p == false);//查找煮面炉空闲位置 + if (loc >= 0 && loc <= 5) + { + + if (mORKS.RBTakeNoodleTask.TryDequeue(out OrderLocInfo orderLocInfo)) + { + + // mORKS.CookNodelId[loc] = orderLocInfo.SuborderId; + mORKS.orderLocInfos[loc] = orderLocInfo; + SetFallNoodleLoc((ushort)(loc + 1)); + //机器人开始取面 + RobotTakeNoodle(); + // SimpleFactory.GetInstance.OrderChanged(orderLocInfo.SuborderId, ORDER_STATUS.COOKING); + DeviceProcessLogShow($"订单【{orderLocInfo.SuborderId}】,机器人倒面至【{loc + 1}】号煮面栏"); + + //写入煮菜时间 + List values = new List(); + if (mORKS.orderLocInfos[loc].Loc % 2 == 0)//素菜 + { + values.Add(2);//分 + values.Add(0);//秒 + EventBus.EventBus.GetInstance().Publish(new WriteModel() { DeviceId = DeviceId, Address =$"VW{ 116 + (loc * 6) }" , Value = values.ToArray() }); + } + else //荤菜 + { + values.Add(4);//分 + values.Add(0);//秒 + EventBus.EventBus.GetInstance().Publish(new WriteModel() { DeviceId = DeviceId, Address = $"VW{ 116 + (loc * 6) }", Value = values.ToArray() }); + } + + + mORKS.TakeNoodleInterlock = true; + } + } + + } + } + + /// + /// 出餐控制 + /// + private void OutNoodleTask() + { + if (mORKS.AllowFallNoodle && mORKS.RobotTaskInterlock && !mORKS.TakeNoodleInterlock && mORKS.RobotIdle && !mORKS.TakeMealDetect) + { + // var list= mORKS.CookNoodlesComplete.Where(p => p == true).ToList(); + mORKS.HasVeg = false; + for (int i = 0; i < mORKS.CookNoodlesComplete.Length; i++) + { + if (mORKS.CookNoodlesComplete[i] && mORKS.orderLocInfos[i] != null && mORKS.orderLocInfos[i].SuborderId == mORKS.IngredientsCompleteId) + { + if (!mORKS.relock) + { + if (mORKS.Conqueue.TryDequeue(out Dictionary dic)) + { + mORKS.Vnum = dic[mORKS.orderLocInfos[i].SuborderId].VegatableNumber; + mORKS.TotalNum = dic[mORKS.orderLocInfos[i].SuborderId].DishNum; + mORKS.relock = true; + } + } + if (mORKS.orderLocInfos[i].Loc % 2 == 0) + { + mORKS.HasVeg = true; + mORKS.ListOrder.Add(i, mORKS.orderLocInfos[i]);//找出当前订单煮熟的素菜 + } + else if (!mORKS.HasVeg) + { + mORKS.ListOrderMeat.Add(i, mORKS.orderLocInfos[i]);//找出当前订单煮熟的荤菜 + } + } + } + if (mORKS.ListOrder.Count > 0) + { + foreach (KeyValuePair item in mORKS.ListOrder) + { + while (!mORKS.RobotIdle) + { + + } + int location = item.Key; //煮面炉位置 + ushort number = item.Value.Loc;//荤素编号 + SetTakeNoodleLoc((ushort)(location + 1)); + RobotOutMeal(); + CookNoodleStatusReset((ushort)(location + 1)); + // ResetAllowFallNoodle(); + mORKS.OutMealId = mORKS.IngredientsCompleteId; + // mORKS.CookNodelId[loc] = string.Empty; + mORKS.orderLocInfos[location] = null; + + DeviceProcessLogShow($"{location + 1}号位置出餐控制"); + mORKS.OutNoodleing = true; + mORKS.Count++; + CheckLastDish(); + } + + } + if (mORKS.ListOrderMeat.Count > 0 && mORKS.Count == mORKS.Vnum && mORKS.ListOrder.Count == 0) + { + foreach (KeyValuePair item in mORKS.ListOrderMeat) + { + while (!mORKS.RobotIdle) + { + + } + int location = item.Key; //煮面炉位置 + ushort number = item.Value.Loc;//荤素编号 + SetTakeNoodleLoc((ushort)(location + 1)); + RobotOutMeal(); + CookNoodleStatusReset((ushort)(location + 1)); + // ResetAllowFallNoodle(); + mORKS.OutMealId = mORKS.IngredientsCompleteId; + // mORKS.CookNodelId[loc] = string.Empty; + mORKS.orderLocInfos[location] = null; + // mORKS.Count++; + DeviceProcessLogShow($"{location + 1}号位置出餐控制"); + mORKS.OutNoodleing = true; + mORKS.CountMeat++; + CheckLastDish(); + } + + } + mORKS.ListOrder.Clear(); + mORKS.ListOrderMeat.Clear(); + } + } + + /// + /// 检查是否是当前订单最后一个配菜 + /// + public void CheckLastDish() + { + mORKS.Num = 0; + foreach (var item1 in mORKS.orderLocInfos) + { + if (item1 != null) + { + if (item1.SuborderId == mORKS.OutMealId) + { + mORKS.Num++; + //mORKS.Count++; + //mORKS.CountMeat++; + } + } + + } + if (mORKS.Num == 0 && mORKS.Count + mORKS.CountMeat == mORKS.TotalNum) + { + if (mORKS.OutMealType) + { + AddSoup();//加汤 + DeviceProcessLogShow("正在加汤"); + } + else + { + //不加汤 + } + CookComplete(); //告诉机器人冒菜已经煮完 + ResetAllowFallNoodle(); + //mORKS.VegNoodlesLock = false; + mORKS.VegN = 0; + mORKS.relock = false; + mORKS.Count = 0; + mORKS.CountMeat = 0; + mORKS.IngredientsCompleteId = string.Empty; + mORKS.TakeBowlId = string.Empty; + mORKS.TakeBowlInterlock = false; + + } + else + { + + while (mORKS.RobotIdle) + { + + } + // Thread.Sleep(3000); + } + + } + /// + /// 信号检测 + /// + private void SingleDetect() + { + + //允许倒面信号检测 + if (RTrig.GetInstance("AllowFallNoodle").Start(mORKS.AllowFallNoodle)) + { + + mORKS.IngredientsCompleteId = mORKS.TakeBowlId; + // mORKS.TakeBowlId = string.Empty; + // DeviceProcessLogShow("碗到位,允许到面"); + DeviceProcessLogShow($"碗到位,允许到面,{mORKS.IngredientsCompleteId}"); + // mORKS.TakeBowlInterlock = false; + } + + //出餐完成信号检测 + if (RTrig.GetInstance("CompleteChange").Start(mORKS.RbOutMealComplete)) + { + + OrderChange(mORKS.OutMealId, ORDER_STATUS.COMPLETED_COOK); + DeviceProcessLogShow($"订单【{mORKS.OutMealId}】制作完成"); + mORKS.OutNoodleing = false; + } + + //取餐完成逻辑处理 + if (DelayRTrig.GetInstance("CompleteChange1").Start(mORKS.RbOutMealComplete && !mORKS.TakeMealDetect, 2)) + { + OrderChange(mORKS.OutMealId, ORDER_STATUS.COMPLETED_TAKE); + DeviceProcessLogShow($"订单【{mORKS.OutMealId}】取餐完成"); + ResetCookComplete(); + mORKS.OutMealId = string.Empty; + } + + //机器人取面完成信号检测 + if (RTrig.GetInstance("TakeNoodleComplete").Start(mORKS.RbTakeNoodleComplete)) + { + mORKS.TakeNoodleInterlock = false; + mORKS.AllowTakeNoodle = false; + mORKS.TurntableInterlock = false; + DeviceProcessLogShow("机器人取面完成信号检测"); + TakeNoodleCompleteReset(); + } + + //转台到位检测 + //if (RTrig.GetInstance("TurntableInPlace").Start(mORKS.TurntableMoveInPlace)) + //{ + // mORKS.TurntableInterlock = false; + //} + + mORKS.VegNoodlesLock = false; + + for (int i = 0; i < mORKS.CookNoodlesComplete.Length; i++) + { + if (mORKS.CookNoodlesComplete[i] && mORKS.orderLocInfos[i] != null && mORKS.orderLocInfos[i].SuborderId == mORKS.IngredientsCompleteId) + { + if ((mORKS.orderLocInfos[i].Loc % 2 == 0 || mORKS.Vnum == 0) && mORKS.relock) + { + mORKS.VegNoodlesLock = true; + mORKS.VegN++; + break; + } + + + } + } + if (mORKS.VegN == mORKS.Vnum && mORKS.VegN < mORKS.TotalNum && mORKS.relock) + { + mORKS.VegNoodlesLock = true; + } + int OutMealRequstCount = mORKS.CookNoodlesComplete.Where(p => p == true).ToList().Count; + int mlCount = mORKS.NoodleCookerStatus.Where(p => p == true).ToList().Count; + mORKS.RobotTaskInterlock = OutMealRequstCount > 0 && mORKS.AllowFallNoodle && (mlCount >= 1 || mORKS.RBTakeNoodleTask.Count == 0); + if (mORKS.RobotIdle && mORKS.RobotTaskInterlock == false) + { + mORKS.OutNoodleing = false; + } + } + + + #region PLC 控制函数 + + /// + /// 写入配方数据到 PLC + /// + private void WriteRecipeBoms() + { + List recipeBoms = new List(); + if (this.recipeBoms == null) return; + foreach (var item in this.recipeBoms.RecipeIds) + { + foreach (var rec in item.Recipes) + { + recipeBoms.Add((ushort)rec); + } + } + if (recipeBoms.Count > 0) + { + //配方数据地址范围:VW2000 - VW2278 + WriteData("VW2000", recipeBoms.ToArray()); + DeviceProcessLogShow("写配方成功"); + } + else { DeviceProcessLogShow("配方数据为空"); } + } + + /// + /// 取面完成复位 + /// + private void TakeNoodleCompleteReset() + { + WriteData("M100.4", false); + } + + /// + /// 指定煮面口状态复位 + /// + /// + private void CookNoodleStatusReset(int num) + { + if (num >= 1 && num <= 6) + { + WriteData($"102.{num - 1}", false); + DeviceProcessLogShow($"{num}号煮面口占用复位"); + } + + } + + /// + /// 写配方编号 + /// + /// + private void SetRecipeNumber(ushort num) + { + WriteData("VW0", num); + } + + /// + /// 启动转台 + /// + /// + private void TurntableStart(ushort loc) + { + mORKS.CurrentLoc = loc; + mORKS.TurntableInterlock = true; + mORKS.TurntableLocLists.Add(loc); + WriteData("VW2", loc); + WriteData("M0.5", true); + } + + /// + /// 设置倒面位置 + /// + /// + private void SetFallNoodleLoc(ushort loc) + { + WriteData("VW4", loc); + } + + /// + /// 设置取面位置 + /// + /// + private void SetTakeNoodleLoc(ushort loc) + { + WriteData("VW6", loc); + } + + /// + /// 取碗控制 + /// + /// + private void TakeBowlControl(ushort loc) + { + if (loc == 10)//小碗 + { + WriteData("M0.1", true); + } + else if (loc == 11)//大碗 + { + WriteData("M0.2", true); + } + } + + /// + /// 机器人取面 + /// + private void RobotTakeNoodle() + { + WriteData("M0.3", true); + } + + /// + /// 机器人取餐 + /// + private void RobotOutMeal() + { + WriteData("M0.4", true); + } + + /// + /// 制作完成信号复位 + /// + private void ResetCookComplete() + { + WriteData("M100.6", false); + } + + /// + /// 复位允许取面信号 + /// + private void ResetAllowFallNoodle() + { + WriteData("M100.3", false); + } + + /// + /// 设备初始化 + /// + public async void DeviceInit() + { + WriteData("M0.0", true); + await Task.Delay(1000); + WriteData("M0.0", false); + + } + + /// + /// 制作完成,允许机器人往外推碗 + /// + public void CookComplete() + { + ////ModbusTcpHelper.GetInstance.Write((ushort)ModbusTcpHelper.GetInstance.GetBoolAddress("M0.6"), WriteType.Coils, true); + EventBus.EventBus.GetInstance().Publish(new WriteModel() { DeviceId = DeviceId, Address = "M0.6", Value = true }); + } + + /// + /// 是否加汤 + /// + public void AddSoup() + { + ////ModbusTcpHelper.GetInstance.Write((ushort)ModbusTcpHelper.GetInstance.GetBoolAddress("M0.7"), WriteType.Coils, true); + EventBus.EventBus.GetInstance().Publish(new WriteModel() { DeviceId = DeviceId, Address = "M0.7", Value = true }); + } + + private void ServerInit() + { + //物料信息 + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + if (@event == null) return; + if (@event is MaterialDeliveryEvent material) + { + orderMaterialDelivery = material.orderMaterialDelivery; + } + }); + + //配方数据信息 + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + if (@event == null) return; + if (@event is RecipeBomEvent recipe) + { + recipeBoms = recipe.recipeBoms; + WriteRecipeBoms(); + } + }); + } + + public override void DoMain() + { + MonitorViewModel.DeviceId = DeviceId; + ServerInit(); + DataParse(); + + Json.Read(); + if (Json.Data.parSets == null) Json.Data.parSets = new ObservableCollection(); + if (Json.Data.parSets.Count < 6) + { + Json.Data.parSets.Clear(); + for (int i = 0; i < 6; i++) + { + Json.Data.parSets.Add(new ParSet() + { + CheckBoxContext = $"煮面口{i + 1}屏蔽", + Minute = 1, + Second = 0, + IsShield = false, + TextBlockContext = $"煮面口{i + 1}时间设定" + }); + } + } + + ActionManage.GetInstance.Register(new Action((o) => + { + if (o != null && o is WritePar writePar) WriteData(writePar.Address, writePar.Value); + }), "WriteVW"); + ActionManage.GetInstance.Register(new Action((o) => + { + if (o != null && o is WritePar writePar) WriteData(writePar.Address, writePar.Value); + }), "WriteBools"); + ActionManage.GetInstance.Register(new Action(() => { DeviceInit(); }), "InitDevice");//设备初始化注册 + ActionManage.GetInstance.Register(new Action((o) => {SimOrder(o); }), "SimOrder");//模拟订单委托注册 + + } + private void WriteData(string address, object value) + { + EventBus.EventBus.GetInstance().Publish(new WriteModel() { DeviceId = DeviceId, Address = address, Value = value }); + } + public override void ResetProgram() + { + mORKS = null; + mORKS = new GVL_MORKM(); + } + + private void GetStatus(string key, Action action) + { + if (peripheralStatus.ContainsKey(key)) + { + if (peripheralStatus[key] != null) + { + action?.Invoke(peripheralStatus[key]); + } + } + } + + private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS) + { + var res = mORKS.doOrderEvents.FirstOrDefault(p => p.MorkOrder.SuborderId == subid); + string goodName = string.Empty; + string SortNum = string.Empty; + if (res != null) + { + goodName = res.MorkOrder.GoodsName; + SortNum = res.MorkOrder.SortNum.ToString(); + } + EventBus.EventBus.GetInstance().Publish(new OrderStatusChangedEvent() { SortNum = SortNum, GoodName = goodName, Status = oRDER_STATUS, SubOrderId = subid, deviceClientType = DeviceType }); + } + + + public override void Stop() + { + + } + + public override void ReadData() + { + GetStatus("M230.0", new Action((obj) => + { + if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 24) + { + alarm.MachineLeftLowTemperature = bools[0]; + alarm.MachineRightLowTemperature = bools[1]; + alarm.Supply1_LossBowl = bools[2]; + alarm.Supply2_LossBowl = bools[3]; + alarm.Supply1_ErrorOutBowl = bools[4]; + alarm.Supply2_ErrorOutBowl = bools[5]; + alarm.PushBowlCylinderError = bools[6]; + alarm.NoodleMacCommunicateError = bools[7]; + alarm.DosingMacCommunicateError = bools[8]; + alarm.RobotMacCommunicateError = bools[9]; + alarm.DeviceEstop = bools[10]; + alarm.RobotInitError = bools[11]; + alarm.RobotUrgentStop = bools[12]; + alarm.RobotNotInRemoteMode = bools[13]; + alarm.RobotNotInReady = bools[14]; + alarm.RobotSelfInException = bools[15]; + alarm.LeftLackWater = bools[16]; + alarm.RightLackWater = bools[17]; + alarm.SvrewInitFail = bools[18]; + alarm.TurntableInitFail = bools[19]; + alarm.RobotInitFail = bools[20]; + alarm.NoodleCookerInitFail = bools[21]; + alarm.PushBowlInitFail1 = bools[22]; + alarm.PushBowlInitFail2 = bools[23]; + } + })); + + GetStatus("M0.3", new Action((obj) => + { + if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 3) + { + mORKS.RobotTakeNoodle = bools[0]; + mORKS.RobotOutMeal = bools[1]; + mORKS.MoveTurntable = bools[2]; + } + })); + + GetStatus("M100.0", new Action((obj) => + { + if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 16) + { + mORKS.InitComplete = bools[0]; + mORKS.TakeBowlIdle = bools[1]; + mORKS.TemperatureReached = bools[2]; + mORKS.AllowFallNoodle = bools[3]; + mORKS.RbTakeNoodleComplete = bools[4]; + mORKS.RbFallNoodleComplete = bools[5]; + mORKS.RbOutMealComplete = bools[6]; + mORKS.RobotIdle = bools[7]; + mORKS.TakeMealDetect = bools[8]; + mORKS.MissingBowl = bools[9]; + Initing = bools[10]; + mORKS.TurntableLowerLimit = bools[11]; + mORKS.MissingBowlSignal2 = bools[12]; + mORKS.TurntableUpLimit = bools[13]; + mORKS.FeedComplete = bools[14]; + mORKS.TurntableMoveInPlace = bools[15]; + } + + })); + + GetStatus("M235.0", new Action((obj) => + { + if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 1) + { + mORKS.Error = bools[0]; + } + })); + + + GetStatus("M102.0", new Action((obj) => + { + if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 7) + { + for (int i = 0; i < 6; i++) + { + mORKS.NoodleCookerStatus[i] = bools[i]; + } + mORKS.Feeding = bools[6]; + } + })); + + GetStatus("M103.0", new Action((obj) => + { + if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 6) + { + for (int i = 0; i < 6; i++) + { + mORKS.CookNoodlesComplete[i] = bools[i]; + } + } + + })); + + GetStatus("VW372", new Action((obj) => + { + if (obj is ushort[] UshortValue && UshortValue.Length > 0 && UshortValue.Length <= 1) + mORKS.TurntableFeedbackloc = UshortValue[0]; + })); + } + + + + #endregion + + + + } + +} + + diff --git a/BPASmartClient.MorkM/GVL_MORKM.cs b/BPASmartClient.MorkM/GVL_MORKM.cs new file mode 100644 index 00000000..27aaf9b0 --- /dev/null +++ b/BPASmartClient.MorkM/GVL_MORKM.cs @@ -0,0 +1,402 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Collections.Concurrent; +using BPA.Message; +using BPASmartClient.Device; +using BPASmartClient.Model; + +namespace BPASmartClient.MorkM +{ + /// + /// MORKS 设备数据 + /// + public class GVL_MORKM : IStatus + { + public GVL_MORKM() + { + for (int i = 0; i < 6; i++) + { + CookNodelId.Add(new CookNodleLocAndId() { CookNodelId = "", Loc = -1 }); + } + } + + /// + /// 机器人取面 + /// PLC -> M0.3 + /// ModbusTcp -> 323 + /// + public bool RobotTakeNoodle { get; set; } + + /// + /// 机器人出餐 + /// PLC -> M0.4 + /// ModbusTcp -> 324 + /// + public bool RobotOutMeal { get; set; } + + /// + /// 移动转台 + /// PLC -> M0.5 + /// ModbusTcp -> 325 + /// + public bool MoveTurntable { get; set; } + + + #region 临时变量 + /// + /// 允许运行 + /// + [VariableMonitor("允许运行")] + public bool AllowRun { get; set; } + + /// + /// //机器人任务互锁信号 + /// + [VariableMonitor("机器人任务互锁信号")] + public bool RobotTaskInterlock { get; set; } + + /// + /// 取碗互锁信号 + /// + [VariableMonitor("取碗互锁信号")] + public bool TakeBowlInterlock { get; set; } + + /// + /// 取面互锁信号 + /// + [VariableMonitor("取面互锁信号")] + public bool TakeNoodleInterlock { get; set; } + + /// + /// 出面中 + /// + [VariableMonitor("出面中")] + public bool OutNoodleing { get; set; } + + /// + /// 允许取面 + /// + [VariableMonitor("允许取面")] + public bool AllowTakeNoodle { get; set; } + + /// + /// 转台互锁信号 + /// + [VariableMonitor("转台互锁信号")] + public bool TurntableInterlock { get; set; } + + /// + /// 荤素出餐互锁 + /// + [VariableMonitor("荤素出餐互锁")] + public bool ERLoc { get; set; } = false; + + /// + /// 当前取餐位置 + /// + [VariableMonitor("当前取餐位置")] + public int CurrentTakeMeakLoc { get; set; } = -1; + #endregion + + + /// + /// 初始化完成 + /// PLC -> M100.0 + /// ModbusTcp -> 1120 + /// + [VariableMonitor("初始化完成", "M100.0", "1120")] + public bool InitComplete { get; set; } + + /// + /// 取碗机构空闲,True:忙碌,false:空闲 + /// PLC -> M100.1 + /// ModbusTcp -> 1121 + /// + [VariableMonitor("取碗机构空闲", "M100.1", "1121")] + public bool TakeBowlIdle { get; set; } + + /// + /// 温度到达,True:表示到达,false:未到达 + /// PLC -> M100.2 + /// ModbusTcp -> 1122 + /// + [VariableMonitor("温度到达", "M100.2", "1122")] + public bool TemperatureReached { get; set; } + + /// + /// 允许到面,配料完成 + /// PLC -> M100.3 + /// ModbusTcp -> 1123 + /// + [VariableMonitor("允许到面", "M100.3", "1123")] + public bool AllowFallNoodle { get; set; } + + /// + /// 机器人取面完成 + /// PLC -> M100.4 + /// ModbusTcp -> 1124 + /// + [VariableMonitor("机器人取面完成", "M100.4", "1124")] + public bool RbTakeNoodleComplete { get; set; } + + /// + /// 机器人倒面完成 + /// PLC -> M100.5 + /// ModbusTcp -> 1125 + /// + [VariableMonitor("机器人倒面完成", "M100.5", "1125")] + public bool RbFallNoodleComplete { get; set; } + + /// + /// 机器人出餐完成,上报取餐完成 + /// PLC -> M100.6 + /// ModbusTcp -> 1126 + /// + [VariableMonitor("机器人出餐完成", "M100.6", "1126")] + public bool RbOutMealComplete { get; set; } + + /// + /// 机器人空闲 + /// PLC -> M100.7 + /// ModbusTcp -> 1127 + /// + [VariableMonitor("机器人空闲", "M100.7", "1127")] + public bool RobotIdle { get; set; } + + /// + /// 取餐口检测 + /// PLC -> M101.0 + /// ModbusTcp -> 1128 + /// + [VariableMonitor("取餐口检测", "M101.0", "1128")] + public bool TakeMealDetect { get; set; } + + /// + /// 缺碗信号,false:缺碗,true:有碗 + /// PLC -> M101.1 + /// ModbusTcp -> 1129 + /// + [VariableMonitor("缺碗信号", "M101.1", "1129")] + public bool MissingBowl { get; set; } + + /// + /// 设备初始化中,执行中等于1,2秒后复位 + /// PLC -> M101.2 + /// ModbusTcp -> 1130 + /// + [VariableMonitor("设备初始化中", "M101.2", "1130")] + public bool DeviceIniting { get; set; } + + /// + /// 转台下限检测 + /// PLC -> M101.3 + /// ModbusTcp -> 1131 + /// + [VariableMonitor("转台下限检测", "M101.3", "1131")] + public bool TurntableLowerLimit { get; set; } + + /// + /// 缺碗信号 2 + /// PLC -> M101.4 + /// ModbusTcp -> 1132 + /// + [VariableMonitor("缺碗信号 2", "M101.4", "1132")] + public bool MissingBowlSignal2 { get; set; } + + /// + /// 转台上限检测 + /// PLC -> M101.5 + /// ModbusTcp -> 1133 + /// + [VariableMonitor("转台上限检测", "M101.5", "1133")] + public bool TurntableUpLimit { get; set; } + + /// + /// 补料完成 + /// PLC -> M101.6 + /// ModbusTcp -> 1134 + /// + [VariableMonitor("补料完成", "M101.6", "1134")] + public bool FeedComplete { get; set; } + + /// + /// 转台移动到位 + /// PLC -> M101.7 + /// ModbusTcp -> 1135 + /// + [VariableMonitor("转台移动到位", "M101.7", "1135")] + public bool TurntableMoveInPlace { get; set; } + + /// + /// 煮面炉状态,True:忙碌,false:空闲 + /// M102.0 - M102.5 + /// 1136 - 1141 + /// + [VariableMonitor("煮面炉状态", "M102.0", "1136")] + public bool[] NoodleCookerStatus { get; set; } = new bool[6] { false, false, false, false, false, false }; + + /// + /// 补料中 + /// M102.6 + /// 1142 + /// + [VariableMonitor("补料中", "M102.6", "1142")] + public bool Feeding { get; set; } + + /// + /// 煮面完成,上升后给信号 + /// M103.0 - M103.5 + /// 1144 - 1149 + /// + [VariableMonitor("煮面完成", "M103.0", "1144")] + public bool[] CookNoodlesComplete { get; set; } = new bool[6] { false, false, false, false, false, false }; + + /// + /// 硬件设备异常 + /// PLC -> M235.0 + /// True:设备正常,False:设备异常 + /// + [VariableMonitor("硬件设备异常", "M235.0", "")] + public bool Error { get; set; } = false; + + /// + /// 配方编号 + /// PLC -> VW0 + /// ModbusTcp -> 100 + /// + [VariableMonitor("配方编号", "VW0", "100")] + public ushort RecipeNumber { get; set; } + + /// + /// 转台设置位置 + /// PLC -> VW2 + /// ModbusTcp -> 101 + /// + [VariableMonitor("转台设置位置", "VW2", "101")] + public ushort TurntableLoc { get; set; } + + /// + /// 到面至煮面炉位置 + /// PLC -> VW4 + /// ModbusTcp -> 102 + /// + [VariableMonitor("到面至煮面炉位置", "VW4", "102")] + public ushort FallNoodleLoc { get; set; } + + /// + /// 取面位置 + /// PLC -> VW6 + /// ModbusTcp -> 103 + /// + [VariableMonitor("取面位置", "VW6", "103")] + public ushort TakeNoodleLoc { get; set; } + + /// + /// 转台反馈位置 + /// PLC -> VW372 + /// ModbusTcp -> 286 + /// + [VariableMonitor("转台反馈位置", "VW372", "286")] + public ushort TurntableFeedbackloc { get; set; } + + /// + /// 机器人取面位置队列 + /// + public ConcurrentQueue RBTakeNoodleTask { get; set; } = new ConcurrentQueue(); + + /// + /// 出碗队列 + /// + public ConcurrentQueue TakeBowlTask { get; set; } = new ConcurrentQueue(); + + /// + /// 是否有面条 + /// + public bool IsNoodles { get; set; } = true; + + public Dictionary ListOrder { get; set; } = new Dictionary(); //存放当前订单已做好素菜 + + public Dictionary ListOrderMeat { get; set; } = new Dictionary(); //存放当前订单已做好荤菜 + + public int DishNumber { set; get; } = 0; //当前订单中配菜的数量 + + #region 订单ID记录 + /// + /// 取碗订单ID + /// + public string TakeBowlId = string.Empty; + + /// + /// 配料完成订单ID + /// + public string IngredientsCompleteId = string.Empty; + + /// + /// 煮面口对应的订单ID + /// + //public string[] CookNodelId = new string[6] { string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, }; + public List CookNodelId { get; set; } = new List(); + + + //public string[] CookNodelId = new string[6] { string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, }; + + public OrderLocInfo[] orderLocInfos = new OrderLocInfo[6] { null, null, null, null, null, null }; + /// + /// 出餐订单ID + /// + public string OutMealId = string.Empty; + + + /// + /// 冒菜制作方式,true:加汤,false:不加汤 + /// + public bool OutMealType { get; set; } = false; + + /// + /// 转台位置轮询 + /// + public List TurntableLocLists = new List(); + + /// + /// 转台当前启动位置 + /// + [VariableMonitor("转台当前启动位置")] + public ushort CurrentLoc { get; set; } = 0; + + public List doOrderEvents { get; set; } = new List(); + + + + public int Num { get; set; } //记录同一个订单是否所有配菜均已出锅 + + public int Count { get; set; } = 0; //用于素菜的计数 + + public int CountMeat { get; set; } = 0;//用于荤菜计数 + + public int Vnum { get; set; } = 0; //单次订单素菜的总数 + public int VegtabNum { get; set; } = 0;//记录一个订单中素菜的数量 + + public int TotalNum { get; set; } = 0; //单次订单的配菜总数 + + public ConcurrentQueue> Conqueue = new ConcurrentQueue>(); //记录订单的ID 以及素菜数量 + public bool relock { get; set; } = false; //单次订单互锁 + + public bool HasVeg { get; set; } //是否有素菜判断 + + + public bool VegNoodlesLock { get; set; } = false; //取面和取餐互锁 + + public int VegN { get; set; } = 0; //素菜出餐计数 + #endregion + } + + public class CookNodleLocAndId + { + public string CookNodelId { get; set; } + + public int Loc { get; set; } + } +} diff --git a/BPASmartClient.MorkM/HardwareStatus.cs b/BPASmartClient.MorkM/HardwareStatus.cs new file mode 100644 index 00000000..ac34e10a --- /dev/null +++ b/BPASmartClient.MorkM/HardwareStatus.cs @@ -0,0 +1,18 @@ +using BPASmartClient.Device; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MorkM +{ + public class HardwareStatus : IHardwareStatus + { + [HardwareStatus("输入状态", "I0.0")] + public bool Input1 { get; set; } + + [HardwareStatus("输出状态", "Q0.0")] + public bool OutPut1 { get; set; } + } +} diff --git a/BPASmartClient.MorkM/Model/GeneralConfig.cs b/BPASmartClient.MorkM/Model/GeneralConfig.cs new file mode 100644 index 00000000..bbc76b18 --- /dev/null +++ b/BPASmartClient.MorkM/Model/GeneralConfig.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MorkM.Model +{ + internal class GeneralConfig + { + /// + /// 激活本地模拟订单 + /// + public static bool EnableLocalSimOrder { get; set; } + } +} diff --git a/BPASmartClient.MorkM/Model/MorksPar.cs b/BPASmartClient.MorkM/Model/MorksPar.cs new file mode 100644 index 00000000..6f97207c --- /dev/null +++ b/BPASmartClient.MorkM/Model/MorksPar.cs @@ -0,0 +1,16 @@ +using BPASmartClient.Model; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Toolkit.Mvvm.ComponentModel; + +namespace BPASmartClient.MorkM.Model +{ + internal class MorksPar + { + public ObservableCollection parSets { get; set; } = new ObservableCollection(); + } +} diff --git a/BPASmartClient.MorkM/Model/ParSet.cs b/BPASmartClient.MorkM/Model/ParSet.cs new file mode 100644 index 00000000..39eb45a6 --- /dev/null +++ b/BPASmartClient.MorkM/Model/ParSet.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MorkM.Model +{ + public class ParSet + { + public ushort Minute { get { return _mMinute; } set { _mMinute = value; } } + private ushort _mMinute; + + public ushort Second { get { return _mSecond; } set { _mSecond = value; } } + private ushort _mSecond; + + + public bool IsShield { get { return _mIsShield; } set { _mIsShield = value; } } + private bool _mIsShield; + + + public string TextBlockContext { get { return _mTextBlockContext; } set { _mTextBlockContext = value; } } + private string _mTextBlockContext; + + public string CheckBoxContext { get { return _mCheckBoxContext; } set { _mCheckBoxContext = value; } } + private string _mCheckBoxContext; + + } +} diff --git a/BPASmartClient.MorkM/Model/WritePar.cs b/BPASmartClient.MorkM/Model/WritePar.cs new file mode 100644 index 00000000..b3c769fd --- /dev/null +++ b/BPASmartClient.MorkM/Model/WritePar.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MorkM.Model +{ + public class WritePar + { + public string Address { get; set; } + public object Value { get; set; } + } +} diff --git a/BPASmartClient.MorkM/OrderLocInfo.cs b/BPASmartClient.MorkM/OrderLocInfo.cs new file mode 100644 index 00000000..ba5367a3 --- /dev/null +++ b/BPASmartClient.MorkM/OrderLocInfo.cs @@ -0,0 +1,32 @@ +using BPA.Message; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MorkM +{ + public class OrderLocInfo + { + public string SuborderId { get; set; } + public ushort Loc { get; set; } + public ushort RecipeNumber { get; set; } + public int BatchingId { get; set; } + public string GoodName { get; set; } + public bool MakeType { get; set; } + } + + /// + /// 存储订单中素菜荤菜数量 + /// + public class OrderInformation + { + public int VegatableNumber { get; set; } + + public int DishNum { get; set; } + + + // public GoodsMakeType MakeType { get; set; } + } +} diff --git a/BPASmartClient.MorkM/View/DebugView.xaml b/BPASmartClient.MorkM/View/DebugView.xaml new file mode 100644 index 00000000..ba96c7ce --- /dev/null +++ b/BPASmartClient.MorkM/View/DebugView.xaml @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +