using BPA.Helper; using BPA.Message.Enum; using BPA.Models; using BPASmartClient.Device; using BPASmartClient.EventBus; using BPASmartClient.Modbus; using BPASmartClient.Model; using BPASmartClient.Model.PLC; using BPASmartClient.Model.订单; using BPASmartClient.Model.调酒机; using BPASmartClient.MorkMW.Model; using Newtonsoft.Json; using Org.BouncyCastle.Bcpg.OpenPgp; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Net.Http.Json; using System.Reflection; using System.Threading; using System.Windows.Documents; using static BPASmartClient.EventBus.EventBus; namespace BPASmartClient.MorkMW { public class Control_MorkMW : BaseDevice { int id = 0; ModbusTcp modbus; public override DeviceClientType DeviceType => DeviceClientType.MORKMW; GVL_MorkMW morkMW = new GVL_MorkMW(); public override void DoMain() { Json.Read(); VaribleMonitorDis(); ConnectKlpRobot("192.168.0.100", 8001); ServerInit(); DataParse(); ThreadManage.GetInstance().StartLong(new Action(() => { VariableMonitor(); Thread.Sleep(5); }), "机器人变量状态监控线程", true); } private void VaribleMonitorDis() { PropertyInfo[] pros = morkMW.GetType().GetProperties(); foreach (var item in pros) { var res = item.GetCustomAttribute(); if (res != null) { GVL_MorkMW.varibleInfos.Add(new VaribleModel { Id = id + 1, VaribleName = res.VarName, RobotAddress = res.RobotAddress, ModbusAddress = res.ModbusTcpAddress, Notes = res.Notes }); id++; } } } private void ServerInit() { //配方数据信息 EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) { if (@event == null) return; if (@event is MorkMWGoodsEvent recipe) { listMorkMWGoods = recipe.morkMWPushMessage?.MorkMWGoods; DeviceProcessLogShow($"接收到调酒机【{listMorkMWGoods?.Count}】个商品配方数据"); } }); } public override void MainTask() { if (Json.Data.IsVerify) IsHealth = modbus.Connected; else IsHealth = true;//心跳上报 ToGetWink(); ToMixWink(); ToPourWink(); SignalDetect(); } /// /// 接酒过程 /// public void ToGetWink() { if (!GVL_MorkMW.AllowLocalSimOrder) { if (morkMW.RobotIdle && orderLocInfos.Count > 0 && !morkMW.TaskLock && !morkMW.PourWinkComplete && morkMW.CupSignal && modbus.Connected) { DeviceProcessLogShow("订单开始制作"); morkMW.TaskLock = true; if (orderLocInfos.TryDequeue(out BPASmartClient.MorkMW.Model.OrderLocInfo res)) { morkMW.CurrentSuborderId = res.SuborderId; OrderChange(res.SuborderId, ORDER_STATUS.COOKING); foreach (var item in res.mixWink) { switch (item.Loc) { // case 7: ToMixWink(); break; case 1: ToSpecifiedLocTakeWink(item.Loc, item.Qty); break; case 2: ToSpecifiedLocTakeWink(item.Loc, item.Qty); break; case 3: ToSpecifiedLocTakeWink(item.Loc, item.Qty); break; case 4: ToSpecifiedLocTakeWink(item.Loc, item.Qty); break; case 5: ToSpecifiedLocTakeWink(item.Loc, item.Qty); break; case 6: ToSpecifiedLocTakeWink(item.Loc, item.Qty); break; } switch (item.Loc) { //case 7: while (!morkMW.MixWinkComplte) { Thread.Sleep(5); } break; case 1: while (!morkMW.TakeWinkOneComplete) { Thread.Sleep(5); } break; case 2: while (!morkMW.TakeWinkTwoComplete) { Thread.Sleep(5); } break; case 3: while (!morkMW.TakeWinkThreeComplete) { Thread.Sleep(5); } break; case 4: while (!morkMW.TakeWinkFourComplete) { Thread.Sleep(5); } break; case 5: while (!morkMW.TakeWinkFiveComplete) { Thread.Sleep(5); } break; case 6: while (!morkMW.TakeWinkSixComplete) { Thread.Sleep(5); } break; } } morkMW.AllowMixWink = true;//接酒完成,允许调酒 // morkMW.AllowPourWink = true;//调酒完成,允许倒酒 } } } else { if (morkMW.RobotIdle && simOrderLocInfos.Count > 0 && !morkMW.TaskLock && !morkMW.PourWinkComplete && morkMW.CupSignal) { DeviceProcessLogShow("订单开始制作"); morkMW.TaskLock = true; if (simOrderLocInfos.TryDequeue(out SimOrderLocInfo res)) { foreach (var item in res.mixWink) { switch (item.Loc) { // case 7: ToMixWink(); break; case 1: ToSpecifiedLocTakeWink(item.Loc, item.Time); break; case 2: ToSpecifiedLocTakeWink(item.Loc, item.Time); break; case 3: ToSpecifiedLocTakeWink(item.Loc, item.Time); break; case 4: ToSpecifiedLocTakeWink(item.Loc, item.Time); break; case 5: ToSpecifiedLocTakeWink(item.Loc, item.Time); break; case 6: ToSpecifiedLocTakeWink(item.Loc, item.Time); break; } switch (item.Loc) { //case 7: while (!morkMW.MixWinkComplte) { Thread.Sleep(5); } break; case 1: while (!morkMW.TakeWinkOneComplete) { Thread.Sleep(5); } break; case 2: while (!morkMW.TakeWinkTwoComplete) { Thread.Sleep(5); } break; case 3: while (!morkMW.TakeWinkThreeComplete) { Thread.Sleep(5); } break; case 4: while (!morkMW.TakeWinkFourComplete) { Thread.Sleep(5); } break; case 5: while (!morkMW.TakeWinkFiveComplete) { Thread.Sleep(5); } break; case 6: while (!morkMW.TakeWinkSixComplete) { Thread.Sleep(5); } break; } } DeviceProcessLogShow($"所有位置接酒完成"); morkMW.AllowMixWink = true;//接酒完成,允许调酒 // morkMW.AllowPourWink = true;//调酒完成,允许倒酒 } } } } /// /// 调酒过程 /// public void ToMixWink() { // modbus.WriteSingleRegister(0000, 7);//机器人调酒 if (morkMW.AllowMixWink && modbus.Connected) { DeviceProcessLogShow("开始调酒"); modbus.WriteSingleRegister(0000, 7);//机器人调酒 morkMW.AllowMixWink = false; } } /// /// 去对应位置接酒 /// /// /// public void ToSpecifiedLocTakeWink(int loc, int time) { //发送接酒信号 switch (loc) { case 1: modbus.WriteSingleRegister(0000, 1); DeviceProcessLogShow($"开始接【{loc}】号位置原酒"); break; case 2: modbus.WriteSingleRegister(0000, 2); DeviceProcessLogShow($"开始接【{loc}】号位置原酒"); break; case 3: modbus.WriteSingleRegister(0000, 3); DeviceProcessLogShow($"开始接【{loc}】号位置原酒"); break; case 4: modbus.WriteSingleRegister(0000, 4); DeviceProcessLogShow($"开始接【{loc}】号位置原酒"); break; case 5: modbus.WriteSingleRegister(0000, 5); DeviceProcessLogShow($"开始接【{loc}】号位置原酒"); break; case 6: modbus.WriteSingleRegister(0000, 6); DeviceProcessLogShow($"开始接【{loc}】号位置原酒"); break; } //等待机器人到达接酒位置 switch (loc) { case 1: while (!morkMW.ArriveWinkOneLoc) { Thread.Sleep(5); } DeviceProcessLogShow($"机械臂到达【{loc}】号接酒位置"); break; case 2: while (!morkMW.ArriveWinkTwoLoc) { Thread.Sleep(5); } DeviceProcessLogShow($"机械臂到达【{loc}】号接酒位置"); break; case 3: while (!morkMW.ArriveWinkThreeLoc) { Thread.Sleep(5); } DeviceProcessLogShow($"机械臂到达【{loc}】号接酒位置"); break; case 4: while (!morkMW.ArriveWinkFourLoc) { Thread.Sleep(5); } DeviceProcessLogShow($"机械臂到达【{loc}】号接酒位置"); break; case 5: while (!morkMW.ArriveWinkFiveLoc) { Thread.Sleep(5); } DeviceProcessLogShow($"机械臂到达【{loc}】号接酒位置"); break; case 6: while (!morkMW.ArriveWinkSixLoc) { Thread.Sleep(5); } DeviceProcessLogShow($"机械臂到达【{loc}】号接酒位置"); break; } Thread.Sleep(time * 1000);//接酒等待时间 //发送接酒完成信号 switch (loc) { case 1: modbus.WriteSingleCoil(4596, true); DeviceProcessLogShow($"【{loc}】号位置接酒完成"); break; case 2: modbus.WriteSingleCoil(4597, true); DeviceProcessLogShow($"【{loc}】号位置接酒完成"); break; case 3: modbus.WriteSingleCoil(4598, true); DeviceProcessLogShow($"【{loc}】号位置接酒完成"); break; case 4: modbus.WriteSingleCoil(4599, true); DeviceProcessLogShow($"【{loc}】号位置接酒完成"); break; case 5: modbus.WriteSingleCoil(4600, true); DeviceProcessLogShow($"【{loc}】号位置接酒完成"); break; case 6: modbus.WriteSingleCoil(4601, true); DeviceProcessLogShow($"【{loc}】号位置接酒完成"); break; } } /// /// 倒酒过程 /// public void ToPourWink() { //if (morkMW.AllowPourWink && morkMW.CupSignal) //{ // morkMW.AllowPourWink = false; // modbus.WriteSingleRegister(0000, 8);//倒酒 //} if (morkMW.CupSignal && RTrig.GetInstance("AllowOut").Start(morkMW.MixWinkComplte) && modbus.Connected) { DeviceProcessLogShow("开始倒酒"); modbus.WriteSingleRegister(0000, 8);//倒酒 } } /// /// 信号检测 /// public void SignalDetect() { if (RTrig.GetInstance("AllComplete").Start(morkMW.ProcessComplete)) { OrderChange(morkMW.CurrentSuborderId, ORDER_STATUS.COMPLETED_COOK); morkMW.PourWinkComplete = true; DeviceProcessLogShow("订单制作完成,请取走调好酒杯"); } if (morkMW.PourWinkComplete) { if (TTrig.GetInstance("PoutWinkCom").Start(morkMW.CupSignal)) { OrderChange(morkMW.CurrentSuborderId, ORDER_STATUS.COMPLETED_TAKE); DeviceProcessLogShow("客户取走调好酒杯,请放置空酒杯,以待下次订单制作"); } if (RTrig.GetInstance("PoutWinkCom").Start(morkMW.CupSignal)) { DeviceProcessLogShow("空酒杯就位,允许执行下一订单"); morkMW.PourWinkComplete = false; morkMW.TaskLock = false; Thread.Sleep(2000); } } } /// /// 读卡乐普机器人状态 /// public override void ReadData() { //GetStatus("M230.0", new Action((obj) => //{ //})); if (modbus.Connected) { morkMW.ArriveWinkOneLoc = modbus.ReadCoils(4616); morkMW.ArriveWinkTwoLoc = modbus.ReadCoils(4617); morkMW.ArriveWinkThreeLoc = modbus.ReadCoils(4618); morkMW.ArriveWinkFourLoc = modbus.ReadCoils(4619); morkMW.ArriveWinkFiveLoc = modbus.ReadCoils(4620); morkMW.ArriveWinkSixLoc = modbus.ReadCoils(4621); morkMW.RobotIdle = modbus.ReadCoils(4201); morkMW.CupSignal = modbus.ReadInputs(0); morkMW.TakeWinkOneComplete = modbus.ReadCoils(4606); morkMW.TakeWinkTwoComplete = modbus.ReadCoils(4607); morkMW.TakeWinkThreeComplete = modbus.ReadCoils(4608); morkMW.TakeWinkFourComplete = modbus.ReadCoils(4609); morkMW.TakeWinkFiveComplete = modbus.ReadCoils(4610); morkMW.TakeWinkSixComplete = modbus.ReadCoils(4611); morkMW.MixWinkComplte = modbus.ReadCoils(4612); morkMW.ProcessComplete = modbus.ReadCoils(4613); } else { modbus.ModbusTcpConnect("192.168.0.100", 8001); } } public void VariableMonitor() { GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "ArriveWinkOneLoc").CurrentValue = morkMW.ArriveWinkOneLoc; GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "ArriveWinkTwoLoc").CurrentValue = morkMW.ArriveWinkTwoLoc; GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "ArriveWinkThreeLoc").CurrentValue = morkMW.ArriveWinkThreeLoc; GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "ArriveWinkFourLoc").CurrentValue = morkMW.ArriveWinkFourLoc; GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "ArriveWinkFiveLoc").CurrentValue = morkMW.ArriveWinkFiveLoc; GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "ArriveWinkSixLoc").CurrentValue = morkMW.ArriveWinkSixLoc; GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "RobotIdle").CurrentValue = morkMW.RobotIdle; GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "CupSignal").CurrentValue = morkMW.CupSignal; GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "TakeWinkOneComplete").CurrentValue = morkMW.TakeWinkOneComplete; GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "TakeWinkTwoComplete").CurrentValue = morkMW.TakeWinkTwoComplete; GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "TakeWinkThreeComplete").CurrentValue = morkMW.TakeWinkThreeComplete; GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "TakeWinkFourComplete").CurrentValue = morkMW.TakeWinkFourComplete; GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "TakeWinkFiveComplete").CurrentValue = morkMW.TakeWinkFiveComplete; GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "TakeWinkSixComplete").CurrentValue = morkMW.TakeWinkSixComplete; GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "MixWinkComplte").CurrentValue = morkMW.MixWinkComplte; GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "ProcessComplete").CurrentValue = morkMW.ProcessComplete; } public override void ResetProgram() { morkMW = null; morkMW = new GVL_MorkMW(); } public override void SimOrder() { EventBus.EventBus.GetInstance().Subscribe(0, delegate (IEvent @event, EventCallBackHandle callBackHandle) { if (@event != null && @event is MorkMWSimOrder order) { if (order.mixWink.Count > 0) { string guid = Guid.NewGuid().ToString(); simOrderLocInfos.Enqueue(new SimOrderLocInfo { mixWink = order.mixWink, SuborderId = guid }); DeviceProcessLogShow("收到模拟订单"); } } }); } public override void Stop() { } private void GetStatus(string key, Action action) { if (peripheralStatus.ContainsKey(key)) { if (peripheralStatus[key] != null) { action?.Invoke(peripheralStatus[key]); } } } /// /// 卡乐普写数据 /// /// /// private void WriteData(string address, object value) { EventBus.EventBus.GetInstance().Publish(new WriteModel() { DeviceId = DeviceId, Address = address, Value = value }); } /// /// 数据解析 /// public void DataParse() { EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBackHandle) { if (@event != null && @event is DoOrderEvent order) { morkMW.doOrderEvents.Add(order); if (listMorkMWGoods.Count == 0) return; if (morkMW.historySuborderId.FirstOrDefault(p => p == order.MorkOrder.SuborderId) != null) return; OrderCount++; var res = listMorkMWGoods?.FirstOrDefault(p => p.GoodsKey == order.MorkOrder.GoodsKey); if (res != null) { string guid = Guid.NewGuid().ToString(); orderLocInfos.Enqueue(new BPASmartClient.MorkMW.Model.OrderLocInfo { mixWink = res.MorkMWBoms, SuborderId = order.MorkOrder.SuborderId }); morkMW.historySuborderId.Add(order.MorkOrder.SuborderId); OrderChange(order.MorkOrder.SuborderId, ORDER_STATUS.WAIT); DeviceProcessLogShow($"收到【{OrderCount}】次小程序订单,当前订单【{order.MorkOrder.GoodsName}】,订单号【{order.MorkOrder.SuborderId}】"); } else { DeviceProcessLogShow($"未找到订单对应商品,订单号【{order.MorkOrder.SuborderId}】"); } } }); } /// /// 订单状态上报 /// /// /// private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS) { try { var res = morkMW.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 }); } catch (Exception) { DeviceProcessLogShow($"订单状态上报失败,订单号【{morkMW.CurrentSuborderId}】"); //throw; } } /// /// 连接卡乐普机器人 /// /// /// public void ConnectKlpRobot(string ip, int port) { modbus = new ModbusTcp(); modbus.Show += new Action((s) => { if (s != null) DeviceProcessLogShow(s); }); modbus.ShowEx += new Action((s) => { if ((s != null)) DeviceProcessLogShow(s); }); modbus.ModbusTcpConnect(ip, port); } /// /// 调酒小程序订单队列 /// public ConcurrentQueue orderLocInfos = new ConcurrentQueue(); /// /// 调酒模拟订单队列 /// public ConcurrentQueue simOrderLocInfos = new ConcurrentQueue(); /// /// 调酒机配方集合 /// public List listMorkMWGoods = new List(); } }