using BPA.Message; using BPA.Message.Enum; using BPA.Message.IOT; using BPASmartClient.Device; using BPASmartClient.DRCoffee; using BPASmartClient.EventBus; using BPASmartClient.GSIceCream; using BPASmartClient.Helper; using BPASmartClient.Lebai; using BPASmartClient.Message; using BPASmartClient.Model; using BPASmartClient.Model.冰淇淋.Enum; using BPASmartClient.Model.单片机; using BPASmartClient.Model.单片机.Enum; using BPASmartClient.Model.咖啡机.Enum; using BPASmartClient.SCChip; using Robotc; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading; using static BPASmartClient.EventBus.EventBus; namespace BPASmartClient.MORKIC { /* * 冰淇淋咖啡机组合套装 * 物料位置: * 1:冰淇料 * 2:冰淇淋杯 * 5:咖啡 * 6:咖啡杯 */ public class Control_MORKIC : BaseDevice { //咖啡机主控程序 private CoffeeMachine coffeeMachine; //单片机主控程序 private ICChipMachine icchipMachine; //广绅单口冰淇淋机 private IceCreamMachine iceCreamMachine; //物料存放位置 private Dictionary batchings = new Dictionary(); /// /// 获取乐百机器人的数据 /// SignalResult lebai = new SignalResult(); /// /// 咖啡位置是否有东西 /// private bool IsCoffeeMake = false; private bool enableFunny = false; private DateTime lastRecvdOrder = DateTime.Now; private bool working = false; private bool IceIsOK = true; public void ConnectOk() { } /// /// 当前正在制作咖啡 /// SimOrderData MakeCoffeeOrder = new SimOrderData(); /// /// 咖啡订单队列 /// ConcurrentQueue morkOrderPushesCoffee = new ConcurrentQueue(); /// /// 冰淇淋订单队列 /// ConcurrentQueue morkOrderPushesIceCream = new ConcurrentQueue(); /// /// 等待取餐的订单,只有一个 /// ConcurrentQueue WaitTakeMealOrder = new ConcurrentQueue(); public void Init() { ActionManage.GetInstance.Register(new Action((s) => { if (s is DrCoffeeDrinksCode cf) { DoCoffee(new SimOrderData { Loc = ((int)cf).ToString() }); } else if (s is Dictionary ms) { if (ms.ContainsKey("Button")) { switch (ms["Button"]) { case "启动示教": LebaiRobot.GetInstance.StartTeachMode(); break; case "停止示教": LebaiRobot.GetInstance.EndtTeachMode(); break; case "启动机器人": LebaiRobot.GetInstance.StartRobot(); break; case "急停": LebaiRobot.GetInstance.EStopRobot(); break; default: break; } } } }), "SimCoffee"); //构建所有商品物料信息 batchings = PolymerBatching.BuildAll(); EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) { if (MakeCoffeeOrder != null) MakeCoffeeOrder.OrderStatus = 1; }); System.Configuration.Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None); //一系列外围基础配置 var com_Coffee = config.AppSettings.Settings["COM_Coffee"].Value; var baud_Coffee = config.AppSettings.Settings["BAUD_Coffee"].Value; var com_IceCream = config.AppSettings.Settings["COM_IceCream"].Value; var baud_IceCream = config.AppSettings.Settings["BAUD_IceCream"].Value; var iceCreamCXBThreshold = int.Parse(config.AppSettings.Settings["IceCream_CXB_Threshold"].Value); var com_ICChip = config.AppSettings.Settings["COM_ICChip"].Value; var baud_ICChip = config.AppSettings.Settings["BAUD_IChip"].Value; if (iceCreamCXBThreshold > 0) { //设置冰淇淋成型比 MorkIStatus.GetInstance().CXB_Threshold = (byte)iceCreamCXBThreshold; } //咖啡机创建 coffeeMachine = new CoffeeMachine(); //单片机机创建 icchipMachine = new ICChipMachine(); //冰淇淋机创建 iceCreamMachine = new IceCreamMachine(); Main(); ReadRobotData(); OrderMake(); } private int NoOrderTime = 0; public override DeviceClientType DeviceType => DeviceClientType.MORKT; //订单制作 public void OrderMake() { ThreadManage.GetInstance().StartLong(new Action(() => { while (IsHealth && (morkOrderPushesCoffee.Count > 0 || morkOrderPushesIceCream.Count > 0 || IsCoffeeMake)) { working = true; NoOrderTime = 0; //1.有咖啡订单 取杯去制作 if (!IsCoffeeMake)//位置无杯子 { if (morkOrderPushesCoffee.Count > 0 && morkOrderPushesCoffee.TryDequeue(out SimOrderData simOrder)) { IsCoffeeMake = true; MakeCoffeeOrder = simOrder; MessageLog.GetInstance.Show($"开始制作 [咖啡] 订单[{simOrder.morkOrder.SortNum}]"); DoCoffee(simOrder); } } if (!LebaiRobot.GetInstance.GetInput())//取餐口是否有餐饮 { //取餐位的订单完成 if (WaitTakeMealOrder.TryDequeue(out SimOrderData waitOrder)) OrderChange(waitOrder.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE); //1.制作冰淇淋 if (morkOrderPushesIceCream.Count > 0 && MorkIStatus.GetInstance().CurrentMode != MORKI_MODE.制冷模式) new GSIceCream_ModeSetEvent() { Mode = MORKI_MODE.制冷模式 }.Publish(); if (MorkIStatus.GetInstance().CXB >= 86 && morkOrderPushesIceCream.Count > 0)//成型比大于80 我才会制作 { if (LebaiRobot.GetInstance.GetInput(3)) { if (IceIsOK) MessageLog.GetInstance.Show("请擦拭冰淇淋机出口"); IceIsOK = false; } else if (morkOrderPushesIceCream.TryDequeue(out SimOrderData order)) { IceIsOK = true; MessageLog.GetInstance.Show($"开始制作 [冰淇淋] 订单[{order.morkOrder.SortNum}]"); DoIceCream(order); } } //2.取咖啡到取餐口 if (IsCoffeeMake) { if (MakeCoffeeOrder != null && MakeCoffeeOrder.OrderStatus == 1) { MessageLog.GetInstance.Show($"将咖啡移动到取餐位 [咖啡] 订单[{MakeCoffeeOrder.morkOrder.SortNum}]"); DoCoffeeQC(MakeCoffeeOrder); MakeCoffeeOrder = null; IsCoffeeMake = false; } } } working = false; lastRecvdOrder = DateTime.Now; } if (IsHealth == false && (morkOrderPushesCoffee.Count > 0 || morkOrderPushesIceCream.Count > 0 || IsCoffeeMake)) { MessageLog.GetInstance.Show($"机器连接问题 订单,不允许制作,请检查设备连接后尝试," + $"乐白:{LebaiRobot.GetInstance.IsConnected}咖啡机:{MorkIStatus.GetInstance().CanDo}单片机:{ChipStatus.GetInstance().CanDo}"); if (LebaiRobot.GetInstance.IsConnected && IsCoffeeMake && !LebaiRobot.GetInstance.GetInput())//乐白有订单 { MessageLog.GetInstance.Show($"将咖啡移动到取餐位 [咖啡] 订单[{MakeCoffeeOrder.morkOrder.SortNum}]"); DoCoffeeQC(MakeCoffeeOrder); MakeCoffeeOrder = null; IsCoffeeMake = false; } } if (!LebaiRobot.GetInstance.GetInput()) { if (WaitTakeMealOrder.TryDequeue(out SimOrderData waitOrder)) OrderChange(waitOrder.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE); } Thread.Sleep(1000); }), "订单制作"); } private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS) { EventBus.EventBus.GetInstance().Publish(new OrderStatusChangedEvent() { Status = oRDER_STATUS, SubOrderId = subid, deviceClientType = DeviceType }); } public void Main() { //咖啡机开启主线程 coffeeMachine.Start(); //单片机开启主线程 icchipMachine.Start(); //冰淇淋机开启主线程 iceCreamMachine.Start(); new GSIceCream_ModeSetEvent() { Mode = MORKI_MODE.制冷模式 }.Publish(); //开始心跳刷新,根据咖啡机及冰淇淋机来判断 //ThreadManage.GetInstance().StartLong(new Action(() => //{ // GeneralConfig.Healthy = // LebaiRobot.GetInstance.IsConnected && // MorkCStatus.GetInstance().CanDo && // ChipStatus.GetInstance().CanDo; // //GeneralConfig.Healthy = true; // Thread.Sleep(100); //}), "MORK-IC心跳刷新"); ThreadManage.GetInstance().Start(new Action(() => { while (!LebaiRobot.GetInstance.IsConnected) { Thread.Sleep(10); } //LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_欢迎); }), "MORK-IC欢迎"); } public void DataParse(T order) { if (order is MorkOrderPush morkOrderPush) { //商品类型 GOODS_TYPE currentGoodsType = GOODS_TYPE.NEITHER; string loc_coffe = string.Empty; string loc_cup = string.Empty; #region 订单分类 //遍历物料 foreach (var item in morkOrderPush.GoodBatchings) { var res = Json.Data.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: loc_cup = res.BatchingLoc; break; case BATCHING_CLASS.MAIN_MATERIAL: loc_coffe = res.BatchingLoc; break; } } } //根据商品类型执行具体制作流程 switch (currentGoodsType) { case GOODS_TYPE.COFFEE: morkOrderPushesCoffee.Enqueue(new SimOrderData { Loc = loc_coffe, morkOrder = morkOrderPush }); break; case GOODS_TYPE.ICECREAM: morkOrderPushesIceCream.Enqueue(new SimOrderData { Loc = loc_coffe, morkOrder = morkOrderPush }); break; case GOODS_TYPE.NEITHER: MessageLog.GetInstance.Show("未知的商品类型"); break; } #endregion } } /// /// 验证当前是做咖啡还是做冰淇淋 /// /// 物料位置 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 (!(lebai.Ok && lebai.Value == value)) { Thread.Sleep(5); } } /// /// 做咖啡-接杯子 并且 回到 安全位置 /// private void DoCoffee(SimOrderData order) { #region 且时且多入场设备程序 int checkeNum = 0; // are.Reset(); LebaiRobot.GetInstance.SetValue(0); OrderChange(order.morkOrder.SuborderId, ORDER_STATUS.COOKING); //SimpleFactory.GetInstance.OrderChanged(order.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COOKING); LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_取咖啡杯); Wait(); new SCChip_TakeCupEvent() { Cup = IC_CUP.CUP_COFFEE }.Publish();//落碗控制 Thread.Sleep(500); MessageLog.GetInstance.Show("尝试取咖啡杯!"); LebaiRobot.GetInstance.SetValue(1); int count = 2; p: LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_咖啡杯检测); Wait(); LebaiRobot.GetInstance.SetValue(1); if (!LebaiRobot.GetInstance.GetInput()) { if (count >= 3) { //退出循环回到初始位置 DeviceProcessLogShow($"执行{count}次取咖啡杯,仍为成功,订单默认废弃,机器人回到初始位置!"); LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_咖啡杯回原点); Wait(); LebaiRobot.GetInstance.SetValue(1); return; } DeviceProcessLogShow("执行二次取咖啡杯"); LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_二次取咖啡杯); Wait(); new SCChip_TakeCupEvent() { Cup = IC_CUP.CUP_COFFEE }.Publish();//落碗控制 LebaiRobot.GetInstance.SetValue(1); count++; goto p; } DeviceProcessLogShow("咖啡杯取杯完成"); LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_接咖啡后回原点); Wait(); LebaiRobot.GetInstance.SetValue(1); //加场景 回初始位置 new DRCoffee_MakeCoffeeEvent() { DrinkCode = (Model.咖啡机.Enum.DrCoffeeDrinksCode)int.Parse(order.Loc) }.Publish(); //接咖啡控制 DeviceProcessLogShow($"发送咖啡机制作{order.Loc}!"); #endregion } /// /// 将咖啡杯子 取走到 取餐口 /// private void DoCoffeeQC(SimOrderData order) { LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_取咖啡出餐); Wait(); LebaiRobot.GetInstance.SetValue(1); //订单状态改变:完成 OrderChange(order.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_COOK); //SimpleFactory.GetInstance.OrderChanged(order.morkOrder.SuborderId,BPA.Message.Enum.ORDER_STATUS.COMPLETED_COOK); DeviceProcessLogShow($"{order.morkOrder.GoodsName}等待取餐"); WaitTakeMealOrder.Enqueue(order); } /// /// 做冰淇淋 /// private void DoIceCream(SimOrderData order) { //if (LebaiRobot.GetInstance.GetInput(3)) //{ // MessageLog.GetInstance.Show("请擦拭冰淇淋机出口"); // return; //} #region 且时且多入场设备程序 int checkeNum = 0; //are.Reset(); LebaiRobot.GetInstance.SetValue(0); LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_取冰淇淋杯); Wait(); new SCChip_TakeCupEvent() { Cup = IC_CUP.CUP_ICECREAM }.Publish();//落碗控制 Thread.Sleep(500); MessageLog.GetInstance.Show("尝试取冰淇淋杯!"); LebaiRobot.GetInstance.SetValue(1); int count = 2; p: LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_冰淇淋杯检测); Wait(); LebaiRobot.GetInstance.SetValue(1); if (!LebaiRobot.GetInstance.GetInput()) { if (count >= 3) { //退出循环回到初始位置 MessageLog.GetInstance.Show($"执行{count}次取冰淇淋杯,仍未成功,订单默认废弃,机器人回到初始位置!"); LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_冰淇淋杯回原点); Wait(); LebaiRobot.GetInstance.SetValue(1); return; } MessageLog.GetInstance.Show($"执行{count}次取冰淇淋杯!"); LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_二次取冰淇淋杯); new SCChip_TakeCupEvent() { Cup = IC_CUP.CUP_ICECREAM }.Publish();//落碗控制 Wait(); LebaiRobot.GetInstance.SetValue(1); count++; goto p; } MessageLog.GetInstance.Show("冰淇淋杯检测完成"); #region 通讯冰淇淋机 //制冷模式 new GSIceCream_ModeSetEvent() { Mode = MORKI_MODE.制冷模式 }.Publish(); LebaiRobot.GetInstance.SetValue(0); OrderChange(order.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COOKING); //SimpleFactory.GetInstance.OrderChanged(order.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COOKING); LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_接1号冰淇淋); Wait(); bool doItResult = true; //出料 new GSIceCream_DischargeEvent().Publish(delegate (object[] args) { doItResult = (bool)args[0]; }); if (doItResult) { IceCreamCookCheck(); } else { int count_1 = 0; while (MorkIStatus.GetInstance().CXB <= 86) { Thread.Sleep(5); count_1++; if (count_1 >= 2000) break; } IceCreamCookCheck(); } LebaiRobot.GetInstance.SetValue(1); #endregion while (LebaiRobot.GetInstance.GetInput()) { Thread.Sleep(500); } LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_放冰淇淋位置); Wait(); LebaiRobot.GetInstance.SetValue(1); //订单状态改变:完成 OrderChange(order.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_COOK); //SimpleFactory.GetInstance.OrderChanged(order.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_COOK); MessageLog.GetInstance.Show($"{order.morkOrder.GoodsName}等待取餐"); WaitTakeMealOrder.Enqueue(order); #endregion } /// /// 冰淇淋制作 /// public void IceCreamCookCheck() { int retry = 3; DateTime beginTime = DateTime.Now; while (!LebaiRobot.GetInstance.GetInput(3)) { if (retry <= 0 && DateTime.Now.Subtract(beginTime).TotalSeconds >= 10) { MessageLog.GetInstance.Show("超时未出料,重试次数用尽"); break; } if (DateTime.Now.Subtract(beginTime).TotalSeconds > 5) { MessageLog.GetInstance.Show("超时未出料,重新发送打料指令"); new GSIceCream_ModeSetEvent() { Mode = MORKI_MODE.打料 }.Publish(); beginTime = DateTime.Now; retry--; } Thread.Sleep(10); } MessageLog.GetInstance.Show("开始等待6s"); Thread.Sleep(5000); } //private void CoffeEndCookHandle(IEvent @event, EventBus.EventCallBackHandle callBack) //{ // //are.Set(); // if(MakeCoffeeOrder!=null) // MakeCoffeeOrder.OrderStatus = 1; //} public void ReadRobotData() { ThreadManage.GetInstance().StartLong(new Action(() => { lebai = LebaiRobot.GetInstance.GetValueAsync(); LebaiRobot.GetInstance.GetRobotModeStatus(); //LebaiRobot.GetInstance.GetInput(); Thread.Sleep(100); }), "乐百机器人数据读取", true); } public void SimOrder(T simOrder) { } /// /// IOT 广播消息命令 /// public void IotBroadcast(T broadcast) { if (broadcast != null && broadcast is IOTCommandModel iOTCommand) { switch (iOTCommand.CommandName) { case 0://控制类 if (iOTCommand.CommandValue != null) { if (iOTCommand.CommandValue.ContainsKey("SimOrder")) { //SimOrder(new SimOrderData { NoodleLoc = 1, BowlLoc = 10 }); } } break; case 1://设置属性 break; case 2://通知消息 break; default: break; } } } public override void DoMain() { } public override void Stop() { } public override void ReadData() { } public override void MainTask() { } public override void ResetProgram() { } } public class SimOrderData { public string id { get; set; } public int OrderStatus { get; set; } public string Loc { get; set; } public MorkOrderPush morkOrder { get; set; } public SimOrderData() { id = Guid.NewGuid().ToString(); OrderStatus = 0; } } }