using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Threading; using System.Collections.Concurrent; using System.Diagnostics; using System.Threading.Tasks; using BPASmartClient.Device; using BPA.Message.Enum; using BPA.Message; using BPASmartClient.Helper; using BPASmartClient.Model.咖啡机.Enum; using BPASmartClient.Model; using BPASmartClient.EventBus; using static BPASmartClient.EventBus.EventBus; using BPASmartClient.Message; using BPASmartClient.Model.乐白机器人; using BPASmartClient.Model.单片机; namespace BPASmartClient.MorkTLebaiJC { /* * 冰淇淋咖啡机组合套装 * 物料位置: * 1:冰淇料 * 2:冰淇淋杯 * 5:咖啡 * 6:咖啡杯 * 9: 茶 * 10: 茶杯 */ public class Control_MORKJC2 : BaseDevice { private Dictionary batchings = new Dictionary(); //容器位置 private string holderLoc; //主料位置 private string mainMaterialLoc; public override global::BPA.Message.Enum.DeviceClientType DeviceType { get { return BPA.Message.Enum.DeviceClientType.MORKT; } } GVL_MorkTLebaiJC morkTLebaiJC =new GVL_MorkTLebaiJC(); /// /// 果汁机做法,true:热饮,false:冷饮 /// private bool GuMake = false; public override void DoMain() { if (Json.Data.IsVerify) { IsHealth = true; } IsHealth = true; serverInit(); DataParse(); ActionManage.GetInstance.Register(new Action((o) => { SimOrder(o); }), "SimOrder");//模拟订单委托注册 } 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; } }); } private void DataParse() { EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBackHandle) { if (@event == null) return; if (@event is DoOrderEvent order) { if (order.MorkOrder.GoodBatchings == null) return; OrderCount++; DeviceProcessLogShow($"接收到{OrderCount}次订单"); batchings = PolymerBatching.BuildAll(); //商品类型 GOODS_TYPE currentGoodsType = GOODS_TYPE.NEITHER; foreach (var item in order.MorkOrder.GoodBatchings) { var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId); if (res != null) { //验证商品是做的某种饮料 if (ValidateGoodsByBatching(res.BatchingLoc) != GOODS_TYPE.NEITHER) { //获取当前物料所属商品类型 currentGoodsType = ValidateGoodsByBatching(res.BatchingLoc); } // switch (batchings[res.BatchingLoc].BatchingClass) { case BATCHING_CLASS.HOLDER: holderLoc = res.BatchingLoc; break; case BATCHING_CLASS.MAIN_MATERIAL: mainMaterialLoc = res.BatchingLoc; break; } //根据商品类型执行具体制作流程 switch (currentGoodsType) { case GOODS_TYPE.COFFEE: if (morkTLebaiJC.morkOrderPushesCoffee.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) { morkTLebaiJC.morkOrderPushesCoffee.Enqueue(new OrderLocInfo() { SuborderId = order.MorkOrder.SuborderId, BatchingId = res.BatchingId, Loc = ushort.Parse( mainMaterialLoc), GoodName = order.MorkOrder.GoodsName, }); } break; case GOODS_TYPE.JUICE: GuMake = order.MorkOrder.MakeID == "2";//判断果汁的冷热 if (morkTLebaiJC.morkOrderPushesJuicer.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) { morkTLebaiJC.morkOrderPushesJuicer.Enqueue(new OrderLocInfo() { SuborderId = order.MorkOrder.SuborderId, BatchingId = res.BatchingId, Loc = ushort.Parse(mainMaterialLoc), GoodName = order.MorkOrder.GoodsName, }); } break; case GOODS_TYPE.TEA: if (morkTLebaiJC.morkOrderPushesTea.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) { morkTLebaiJC.morkOrderPushesTea.Enqueue(new OrderLocInfo() { SuborderId = order.MorkOrder.SuborderId, BatchingId = res.BatchingId, Loc = ushort.Parse(mainMaterialLoc), GoodName = order.MorkOrder.GoodsName, }); } break; case GOODS_TYPE.WATER: if (morkTLebaiJC.morkOrderPushesWater.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) { morkTLebaiJC.morkOrderPushesWater.Enqueue(new OrderLocInfo() { SuborderId = order.MorkOrder.SuborderId, BatchingId = res.BatchingId, Loc = ushort.Parse(mainMaterialLoc), GoodName = order.MorkOrder.GoodsName, }); } break; case GOODS_TYPE.NEITHER: DeviceProcessLogShow("未知的商品类型"); break; } } } } }); } private bool bFirstTrig_TeaWater = false; /// /// 延迟的超时时间 /// DateTime delayTimeOut; private bool bFirstTrig_Coffee = false; DateTime delayTimeOut_Coffee; private bool bFirstTrig_Juice = false; DateTime delayTimeOut_Juice; public override void MainTask() { EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) { if (morkTLebaiJC.IsHaveCoffeeCup) morkTLebaiJC.MakeCoffeeEnd = true; }); if (pickUpCoffeeHaveCup) { if (!bFirstTrig_Coffee) { bFirstTrig_Coffee = true; delayTimeOut_Coffee = DateTime.Now; } else if (DateTime.Now.Subtract(delayTimeOut_Coffee).TotalSeconds > 180 && bFirstTrig_Coffee == true) { bFirstTrig_Coffee = false; if (morkTLebaiJC.IsHaveCoffeeCup) morkTLebaiJC.MakeCoffeeEnd = true; } } if (morkTLebaiJC.IsHaveJuiceCup) { var Juicestate = GetStatus("GetDeviceStatus"); if (Juicestate != null) { if (Juicestate.Length > 0) { var Juicestate1 = Convert.ToString(Juicestate[0], 2); var Juicestate2 = Juicestate[1]; if (Juicestate1.IndexOf("0") == 1 && Juicestate2 == 0) { morkTLebaiJC.MakeJuiceEnd = true; } } } //若无状态返回 则加延迟 if (!bFirstTrig_Juice) { bFirstTrig_Juice = true; delayTimeOut_Juice = DateTime.Now; } else if (DateTime.Now.Subtract(delayTimeOut_Juice).TotalSeconds > 30 && bFirstTrig_Juice == true) { bFirstTrig_Juice = false; morkTLebaiJC.MakeJuiceEnd = true; } } if (morkTLebaiJC.IsHaveTeaWaterCup) { if (!bFirstTrig_TeaWater) { bFirstTrig_TeaWater = true; delayTimeOut = DateTime.Now; } else if (DateTime.Now.Subtract(delayTimeOut).TotalSeconds >= 50 && bFirstTrig_TeaWater == true) { bFirstTrig_TeaWater = false; morkTLebaiJC.MakeTeaEnd = true; } } DoCoffee(); DoJuice(); DoBoiledTea(); DoBoiledWater(); } /// /// 订单状态改变 /// /// /// private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS) { EventBus.EventBus.GetInstance().Publish(new OrderStatusChangedEvent() { Status = oRDER_STATUS, SubOrderId = subid, deviceClientType = DeviceType }); } /// /// 验证商品是做的某种饮料 /// /// 物料位置 private GOODS_TYPE ValidateGoodsByBatching(string batchingLoc) { if (batchings.ContainsKey(batchingLoc)) return batchings[batchingLoc].GoodsType; return GOODS_TYPE.NEITHER; } /// /// 乐白的场景结束等待 /// /// private void Wait(int value = 101) { while (!((bool)peripheralStatus["RobotOK"] && (int)peripheralStatus["RobotValue"] == value)) { Thread.Sleep(5); } new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); } /// /// 乐白的场景 /// /// private void Sence(int sen) { new LebaiRobot_LebaiSenceEvent { DeviceId = DeviceId, LebaiSence = sen }.Publish(); } /// /// 乐白的数字量输出 /// /// /// private void Output(bool value,int pin) { new LebaiRobot_SetOutPutEvent { DeviceId = DeviceId, Pin = pin,Value=value }.Publish(); } private T GetStatus(string key) { if (peripheralStatus.ContainsKey(key)) { if (peripheralStatus[key] != null) { return (T)(peripheralStatus[key]); } } return default; } int[] devStatusBy = new int[2] { 0, 0 }; bool outCupCheck = false;//放纸杯位置有无判断 /// /// 判断接咖啡的位置是否有杯子 /// bool pickUpCoffeeHaveCup = false; /// /// 判断接果汁的位置是否有杯子 /// bool pickUpJuiceHaveCup = false; /// /// 判断接开水的位置是否有杯子 /// bool pickUpHotWaterHaveCup = false; /// /// 传感器的输入信号 0:无意义 1:有信号 2:无信号 3:信号不正确 /// int bSensorInput; private bool IsMakeCoffee() { bool bMake = (IsHealth && morkTLebaiJC.morkOrderPushesCoffee.Count > 0 && !morkTLebaiJC.IsHaveCoffeeCup) ? true : false; return bMake; } private bool IsMakeJuice() { bool bMake = (IsHealth && morkTLebaiJC.morkOrderPushesJuicer.Count > 0 && !morkTLebaiJC.IsHaveJuiceCup) ? true : false; return bMake; } private bool IsMakeTeaWater() { bool bMake = (IsHealth && morkTLebaiJC.morkOrderPushesTea.Count > 0 && !morkTLebaiJC.IsHaveTeaWaterCup) ? true : false; return bMake; } private bool IsMakeWater() { bool bMake = (IsHealth && morkTLebaiJC.morkOrderPushesWater.Count > 0 && !morkTLebaiJC.IsHaveTeaWaterCup) ? true : false; return bMake; } /// /// 做咖啡流程 /// private void DoCoffee() { if (IsMakeCoffee()) { if (morkTLebaiJC.morkOrderPushesCoffee.TryDequeue(out OrderLocInfo orderLoc)) { PickUpCoffee();//接咖啡 morkTLebaiJC.IsHaveCoffeeCup = true; } } else if(morkTLebaiJC.MakeCoffeeEnd) { PutCoffeeCup(); pickUpCoffeeHaveCup = false; morkTLebaiJC.IsHaveCoffeeCup = false; } } private void DoJuice() { if (IsMakeJuice()) { if (morkTLebaiJC.morkOrderPushesJuicer.TryDequeue(out OrderLocInfo orderLoc)) { PickUpJuicer(); morkTLebaiJC.IsHaveJuiceCup = true; } } else if (morkTLebaiJC.MakeJuiceEnd) { Thread.Sleep(5000);//延迟五秒,防止接饮料口滴饮料 putJuice(); pickUpJuiceHaveCup = false; morkTLebaiJC.IsHaveJuiceCup = false; morkTLebaiJC.MakeJuiceEnd = false; } } private void DoBoiledTea() { if (IsMakeTeaWater()) { if (morkTLebaiJC.morkOrderPushesTea.TryDequeue(out OrderLocInfo orderLoc)) { PickUpTea(); morkTLebaiJC.IsHaveTeaWaterCup = true; } } else if(morkTLebaiJC.MakeTeaEnd) { PutWaterCup(); pickUpHotWaterHaveCup = false; morkTLebaiJC.IsHaveTeaWaterCup = false ; morkTLebaiJC.MakeTeaEnd = false; } } private void DoBoiledWater() { if (IsMakeWater()) { if (morkTLebaiJC.morkOrderPushesWater.TryDequeue(out OrderLocInfo orderLoc)) { PickUpWater(); } } else if (morkTLebaiJC.MakeTeaEnd) { PutWaterCup(); pickUpHotWaterHaveCup = false; morkTLebaiJC.IsHaveTeaWaterCup = false; morkTLebaiJC.MakeTeaEnd = false; } } #region 做咖啡流程 /// /// 接咖啡 /// private void PickUpCoffee() { //while (GetStatus("RobotValue1"))//判断放杯位置是否有物品 //{ // if (!outCupCheck) // DeviceProcessLogShow("成品处有纸杯存在,请取走!!"); // outCupCheck = true; //} if (!pickUpCoffeeHaveCup) { outCupCheck = false; OrderChange(morkTLebaiJC.morkOrderPushesCoffee.ElementAt(0).SuborderId, BPA.Message.Enum.ORDER_STATUS.COOKING); int resultTakeCup = takeCup(); if (resultTakeCup == 1) { DeviceProcessLogShow("咖啡杯取杯完成"); new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.接咖啡); Wait(); pickUpCoffeeHaveCup = true; new DRCoffee_MakeCoffeeEvent() { DrinkCode = (DrCoffeeDrinksCode)int.Parse(mainMaterialLoc) }.Publish(); //接咖啡控制 //DrCoffeeDrinksCode.热水 } else { DeviceProcessLogShow("取杯失败 回到初始位,请及时处理!!"); Sence(GVL_MorkTLebaiJC.机器人初始位); } } } /// /// 咖啡杯接好,放咖啡杯 /// private void PutCoffeeCup() { while (GetStatus("RobotValue1"))//判断放杯位置是否有物品 { if (!outCupCheck) DeviceProcessLogShow("成品处有纸杯存在,请取走!!"); outCupCheck = true; } outCupCheck = false; new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.放咖啡杯); Wait(); OrderChange(morkTLebaiJC.morkOrderPushesCoffee.ElementAt(0).SuborderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE); DeviceProcessLogShow("咖啡制作完成"); } #endregion #region 做开水流程 /// /// 接开水 /// private void PickUpWater() { #region 接水流程 if (!pickUpHotWaterHaveCup) { OrderChange(morkTLebaiJC.morkOrderPushesWater.ElementAt(0).SuborderId, BPA.Message.Enum.ORDER_STATUS.COOKING); int resultTakeCup = takeCup(); if (resultTakeCup == 1) { new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.接开水); Wait(); Output(false, 1); Output(false, 0); Thread.Sleep(100); Output(true, 0); Thread.Sleep(3000); Output(false, 0); Thread.Sleep(100); Output(false, 1); Thread.Sleep(100); Output(true, 1); Thread.Sleep(500); Output(false, 1); } else { return; } } #endregion } #endregion #region 做茶流程 /// /// 做茶 /// private void PickUpTea() { #region 接茶流程 if (!pickUpHotWaterHaveCup) { OrderChange(morkTLebaiJC.morkOrderPushesTea.ElementAt(0).SuborderId, BPA.Message.Enum.ORDER_STATUS.COOKING); int resultTakeCup = takeCup(); if (resultTakeCup == 1) { DeviceProcessLogShow("取茶杯完成"); new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.接茶叶); Wait(); new WriteMcu() { TagName = "ServoControl", Address = "1", Value = 90 }.Publish(); Thread.Sleep(1000); new WriteMcu() { TagName = "ServoControl", Address = "1", Value = 150 }.Publish(); Thread.Sleep(1000); new WriteMcu() { TagName = "ServoControl", Address = "1", Value = 90 }.Publish(); Thread.Sleep(3000); new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.接茶水); Wait(); Output(false, 1); Output(false, 0); Thread.Sleep(100); Output(true, 0); Thread.Sleep(3000); Output(false, 0); Thread.Sleep(100); Output(false, 1); Thread.Sleep(100); Output(true, 1); Thread.Sleep(500); Output(false, 1); pickUpHotWaterHaveCup = true; } else { return; } } #endregion } /// /// 放水杯流程 /// private void PutWaterCup() { while (GetStatus("RobotValue1"))//判断放杯位置是否有物品 { if (!outCupCheck) DeviceProcessLogShow("成品处有纸杯存在,请取走!!"); outCupCheck = true; } outCupCheck = false; new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.放水杯); Wait(); OrderChange(morkTLebaiJC.morkOrderPushesWater.ElementAt(0).SuborderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE); DeviceProcessLogShow("茶水制作完成"); } #endregion #region 做果汁流程 /// /// 果汁机控制信号 /// private byte JuicerNum; private int JuiceCH; /// /// 接果汁 /// private void PickUpJuicer() { #region 接果汁流程 if (!pickUpJuiceHaveCup) { OrderChange(morkTLebaiJC.morkOrderPushesJuicer.ElementAt(0).SuborderId, BPA.Message.Enum.ORDER_STATUS.COOKING); int resultTakeCup = takeCup(); JuiceCH = int.Parse(mainMaterialLoc); if (resultTakeCup == 1) { switch (JuiceCH) { case 52: if (GuMake) JuicerNum = 0x00; else JuicerNum = 0x01; new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.接果汁1); Wait(); break; case 53: if (GuMake) JuicerNum = 0x02; else JuicerNum = 0x03; new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.接果汁2); Wait(); break; case 54: if (GuMake) JuicerNum = 0x04; else JuicerNum = 0x05; new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.接果汁3); Wait(); break; case 55: if (GuMake) JuicerNum = 0x06; else JuicerNum = 0x07; new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.接果汁4); Wait(); break; default: JuicerNum = 0x00; new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.接果汁1); Wait(); break; } new WriteJuicer() { Value = JuicerNum }.Publish(); pickUpJuiceHaveCup = true; } else { return; } } #endregion } /// /// 取接好果汁杯 /// private void putJuice() { while (GetStatus("RobotValue1"))//判断放杯位置是否有物品 { if (!outCupCheck) DeviceProcessLogShow("成品处有纸杯存在,请取走!!"); outCupCheck = true; } outCupCheck = false; switch (JuiceCH) { case 52: new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.放果汁杯1); Wait(); break; case 53: new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.放果汁杯2); Wait(); break; case 54: new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.放果汁杯3); Wait(); break; case 55: new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.放果汁杯4); Wait(); break; default: new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.放果汁杯1); Wait(); break; } OrderChange(morkTLebaiJC.morkOrderPushesJuicer.ElementAt(0).SuborderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE); DeviceProcessLogShow("果汁制作完成"); } #endregion /// /// 取杯的次数 /// private int nCnt; /// /// 传感器的检测次数 /// private int checkCnt; /// /// 取杯流程 /// /// 0:无意义,1:取杯成功 2:取杯失败 private int takeCup() { try { nCnt = 0; new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.机器人初始位); Wait(); new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.取纸杯); Wait(); new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.取纸杯检测); Wait(); nCnt++; Thread.Sleep(2000); while (!GetStatus("GetInput")) //读取传感器的值 { if (nCnt > 3) { nCnt = 0; DeviceProcessLogShow("三次取杯失败,回原点"); new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.机器人初始位); Wait(); return 2; } else { nCnt++; new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.二次取杯); Wait(); new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); Sence(GVL_MorkTLebaiJC.取纸杯检测); Wait(); } Thread.Sleep(1000); } } catch (Exception ex) { DeviceProcessLogShow(ex.ToString()); } return 2; } /// /// 放杯 /// /// 0:无意义 1:放杯成功 2:执行失败(传感器还有信号) 3:放杯异常 private int putCup() { try { if (GetStatus("RobotValue1")) return 2; Sence(GVL_MorkTLebaiJC.JUICE_放杯); Wait(); new LebaiRobot_SetValueEvent() { RobotSetValue = 1 }.Publish(); Sence(GVL_MorkTLebaiJC.JUICE_放杯检测); Wait(); new LebaiRobot_SetValueEvent() { RobotSetValue = 1 }.Publish(); if (GetStatus("GetInput2")) { return 1; } else { return 3; } } catch (Exception ex) { DeviceProcessLogShow(ex.ToString()); return 0; } } /// /// 检测放杯位,是否有杯子 /// /// 0:无意义 1:没有杯子 2:有杯子 private int checkCup() { try { while (GetStatus("RobotValue1")) { Thread.Sleep(100); if (DateTime.Now.Subtract(delayTimeOut).TotalSeconds >= 1) return 2; } DeviceProcessLogShow("放杯位有杯子未取走,等待取走,最多等待60s,即跳出流程"); return 1; } catch (Exception ex) { DeviceProcessLogShow(ex.ToString()); return 0; } } public void SimOrder(T simOrder) { if (simOrder != null) { if (simOrder is List locs) { List orders = new List(); string subId = Guid.NewGuid().ToString(); foreach (var item in locs) { if (true) { orders.Add(new OrderLocInfo() { Loc = item, SuborderId = subId }); } } } } } public override void Stop() { } public override void ReadData() { } public override void ResetProgram() { } public override void SimOrder() { } } }