using BPA.Message; using BPA.Message.Enum; using BPASmartClient.Device; using BPA.Helper; using BPASmartClient.Model; using BPASmartClient.Model.PLC; using BPASmartClient.MorkTM; using BPASmartClient.MorkTM.Model; using System.Collections.Concurrent; using static BPA.Helper.EventBus; namespace BPASmartClient.MorkTM { public class Control_MorkTM : BaseDevice { public override global::BPA.Message.Enum.DeviceClientType DeviceType { get { return BPA.Message.Enum.DeviceClientType.TMC_MT; } } GVL_MorkTM morkTM = new GVL_MorkTM(); PolymerBatching polymer = new PolymerBatching(); //浮点数放大倍数 const int expand = 100; public override void DoMain() { ServerInit(); DataParse(); polymer.GetMaterialInfo(); ActionManage.GetInstance.Register(new Action((o) => { if(o.Length > 0) { Dictionary res = new Dictionary(); res.Add(Convert.ToInt32(o[0]), Convert.ToSingle(o[1])); SetMatertialWeight(res); Thread.Sleep(100); OpenUsePassageWay(Convert.ToInt32(o[0])); } }), "通道口出料"); ActionManage.GetInstance.Register(new Action((o) => { if(o.Length > 0) { PosionTurnOnTest(Convert.ToInt32(o[0])); } }), "转盘转动"); ActionManage.GetInstance.Register(new Action((o) => { if (o.Length > 0) { OpenPassway(Convert.ToInt32(o[0])); } }), "开启通道"); ActionManage.GetInstance.Register(new Action((o) => { if (o.Length > 0) { CheckPassway(Convert.ToInt32(o[0]), Convert.ToInt32(o[1])); } }), "开始矫正"); ActionManage.GetInstance.Register(new Action((o) => { if (o.Length > 0) { CheckMaterailWeight(Convert.ToInt32(o[0]), Convert.ToInt32(o[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"); morkTM.ReachPosions = new List() { morkTM.ReachPosion_1, morkTM.ReachPosion_2, morkTM.ReachPosion_3, morkTM.ReachPosion_4, morkTM.ReachPosion_5, morkTM.ReachPosion_6 , morkTM.ReachOutPosion_0, }; DeviceProcessLogShow("设备初始化完成"); } private void ServerInit() { //物料信息 EventBus.GetInstance.Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) { if (@event == null) return; if (@event is MaterialDeliveryEvent material) { orderMaterialDelivery = material.orderMaterialDelivery; } }); //配方数据信息 EventBus.GetInstance.Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) { if (@event == null) return; if (@event is RecipeBomEvent recipe) { recipeBoms = recipe.recipeBoms; } }); } private void DataParse() { EventBus.GetInstance.Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) { if(@event == null) return; if(@event is DoOrderEvent order) { if (order.MorkOrder.GoodBatchings == null) return; OrderCount++; morkTM.doOrderEvents.Add(order); OrderChange(order.MorkOrder.SuborderId, ORDER_STATUS.WAIT); DeviceProcessLogShow($"接收到{OrderCount}次订单"); Dictionary OrderPushes = new Dictionary(); foreach (var item in order.MorkOrder.GoodBatchings) { var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId); if (res != null) { OrderPushes.TryAdd(int.Parse(res.BatchingLoc), item.BatchingCount); } } morkTM.morkOrderPushesTeaWithMilk.Enqueue(new OrderLocInfo() { GoodName = order.MorkOrder.GoodsName, SuborderId = order.MorkOrder.SuborderId, GoodPushes = OrderPushes }); } }); } private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS) { var res = morkTM.doOrderEvents.FirstOrDefault(p => p.MorkOrder.SuborderId == subid); string goodName = string.Empty; string SortNum = string.Empty; EventBus.GetInstance.Publish(new OrderStatusChangedEvent() { SortNum = res.MorkOrder. SortNum.ToString(), GoodName = res.MorkOrder.GoodsName, Status = oRDER_STATUS, SubOrderId = res.MorkOrder.SuborderId, deviceClientType = DeviceType }); if(oRDER_STATUS == ORDER_STATUS.COMPLETED_COOK) morkTM.doOrderEvents.Remove(res); } public override void MainTask() { IsHealth = true; MakeTeaWithMilkProcess(); } private void MakeTeaWithMilkProcess() { if (morkTM.morkOrderPushesTeaWithMilk.Count > 0) { if (morkTM.morkOrderPushesTeaWithMilk.TryDequeue(out OrderLocInfo orderLoc)) //&&原点位置是否有杯子) { DeviceProcessLogShow($"开始制作奶茶{orderLoc.GoodName}"); morkTM.MakeCount = 0; SetMatertialWeight(orderLoc.GoodPushes);//设置物料出料量 morkTM.RecipesPushes.Clear(); morkTM.RecipesPushes = orderLoc.GoodPushes; MakeProcess(orderLoc.GoodName, morkTM.MakeCount, morkTM.RecipesPushes.Count);//制作进度 OrderChange(orderLoc.SuborderId, ORDER_STATUS.COOKING); foreach (var item in morkTM.RecipesPushes) { morkTM.MakeCount++; PosionTurnOn(item.Key);//设定转盘位置并等待到位信号 Thread.Sleep(1000); OpenUsePassageWay(item.Key);//打开通道并等待出料完成 DeviceProcessLogShow($"奶茶{orderLoc.GoodName}:配料{item.Key}:添加量{item.Value}"); MakeProcess(orderLoc.GoodName,morkTM.MakeCount,morkTM.RecipesPushes.Count); } TurnOutPosion(); OrderChange(orderLoc.SuborderId, ORDER_STATUS.COMPLETED_COOK); MakeProcess(orderLoc.GoodName, 1, 1); DeviceProcessLogShow($"奶茶{orderLoc.GoodName}制作完成"); } } } /// /// 打开出料通道 /// private void OpenUsePassageWay(int pos) { string address = ""; foreach (var item in polymer.OutPosionPLCs)//根据位置筛选物料plc点位 { if(item.posion is MaterialPosion posion) { if(posion == (MaterialPosion)pos) { WriteData(item.SetPLCPosion,true); address = item.GetPLCPosion; return; } } } while(!morkTM.outMaterialCompletes[pos]) //等待出料完成 { Thread.Sleep(1000); } WriteData(address, false); } /// /// 转盘旋转位置设定 /// /// private void PosionTurnOn(int posion) { int i = 0; string address = ""; foreach (var item in polymer.GoodsMaterialPosion) { if (item.Key.Contains((MaterialPosion)posion)) { WriteData(item.Value.SetPLCPosion,true); i = Convert.ToInt32(item.Value.posion); address = item.Value.GetPLCPosion; return; } } while(!morkTM.ReachPosions[i-1])//等待转盘到达信号 { Thread.Sleep(1000); } if(address != null) WriteData(address, false);//把信号置为0 } #region 调试功能 /// /// 转盘回原点 /// private void TurnOutPosion() { WriteData("M4.6", true); while (!morkTM.ReachPosions[6]) { Thread.Sleep(1000); } WriteData("M14.6", false); } /// /// 调试转盘 /// /// private void PosionTurnOnTest(int posion) { if(posion==0) TurnOutPosion(); else { string address = string.Empty; int i = 0; foreach (var item in polymer.TurnPosionPLCs) { if ((OutMaterialPosion)item.posion == (OutMaterialPosion)posion) { WriteData(item.SetPLCPosion, true); address = item.GetPLCPosion; i = Convert.ToInt32(item.posion); return ; } } while(morkTM.ReachPosions[posion - 1]) { Thread.Sleep(1000); } WriteData(address,false); DeviceProcessLogShow($"转盘转动到位置{i}"); } } /// /// 开启通道 /// private void OpenPassway(int posion) { foreach(var item in polymer.OutPosionPLCs) { if((MaterialPosion)item.posion == (MaterialPosion)posion) { WriteData(item.SetPLCPosion,true); return ; } } } /// /// 开始校正 /// /// /// private void CheckPassway(int passway,int time) { WriteData(polymer.PasswayPosionList[(MaterialPosion)passway], Convert.ToInt32(time * expand));//写入出料时间 Thread.Sleep(100); WriteData("M5.0", true);//开始校正 } /// /// 确认校正重量 /// private void CheckMaterailWeight(int passway,float weight) { WriteData(polymer.PasswayPosionList[(MaterialPosion)passway], weight*expand); } /// /// 奶茶制作进度 /// private void MakeProcess(string goodName,int percent,int count) { int res = Convert.ToInt32(Math.Floor((double)percent / count)) * 100; ActionManage.GetInstance.Send("奶茶制作进度",new object[] {goodName, res }); } #endregion /// /// 把每一个物料的用量写入plc /// /// private void SetMatertialWeight(Dictionary materials) { foreach (var material in materials) { int value = Convert.ToInt32(material.Value*expand); WriteData(polymer.MaterialPosionList[(MaterialPosion)material.Key], value); DeviceProcessLogShow($"通道{material.Key}预设料{material.Value}g"); Thread.Sleep(200); } } public override void ReadData() { //启用通道的地址1 GetStatus("M0.0", new Action((obj) => { if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 28) { } })); GetStatus("M10.0",new Action((obj) => { if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 28) { for (int i = 0; i < 28; i++) { if (morkTM.outMaterialCompletes.ContainsKey(i+1)) { morkTM.outMaterialCompletes[i+1] = bools[i]; } else { morkTM.outMaterialCompletes.Add(i+1, bools[i]); } } } })); //转盘移动的地址 GetStatus("M4.0", new Action((obj) => { if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 7) { } })); //装盘移动到位的地址 GetStatus("M14.0", new Action((obj) => { if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 7) { morkTM.ReachPosion_1 = bools[0]; morkTM.ReachPosion_2 = bools[1]; morkTM.ReachPosion_3 = bools[2]; morkTM.ReachPosion_4 = bools[3]; morkTM.ReachPosion_5 = bools[4]; morkTM.ReachPosion_6 = bools[5]; morkTM.ReachOutPosion_0 = bools[6]; for (int i = 0; i < 7; i++) { morkTM.ReachPosions[i] = bools[i]; } } })); } public override void ResetProgram() { morkTM = null; morkTM = new GVL_MorkTM(); } private void WriteData(string address, object value) { EventBus.GetInstance.Publish(new WriteModel() { DeviceId = DeviceId, Address = address, Value = value }); } private void GetStatus(string key, Action action) { if (peripheralStatus.ContainsKey(key)) { if (peripheralStatus[key] != null) { action?.Invoke(peripheralStatus[key]); } } } public override void SimOrder() { ActionManage.GetInstance.Register(new Action((o) => { if (o is string goodName) { } }), ""); } public override void Stop() { throw new NotImplementedException(); } } }