diff --git a/BPASmartClient.Device/VariableMonitorAttribute.cs b/BPASmartClient.Device/VariableMonitorAttribute.cs index 5fd99243..8d4ba870 100644 --- a/BPASmartClient.Device/VariableMonitorAttribute.cs +++ b/BPASmartClient.Device/VariableMonitorAttribute.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -17,10 +18,42 @@ namespace BPASmartClient.Device public VariableMonitorAttribute(string Notes, string PLCAddress = "", string ModbusTcpAddress = "") { this.PLCAddress = PLCAddress; - this.ModbusTcpAddress = ModbusTcpAddress; + this.ModbusTcpAddress = GetModbusTcpAdd(PLCAddress);// ModbusTcpAddress; this.Notes = Notes; } + private string GetModbusTcpAdd(string address) + { + if (address == null) return ""; + if (address.Length > 0) + { + address = address.Trim(); + if (address.ToUpper().Contains("M") && address.Length >= 4) + { + var res = address.Substring(1).Split('.'); + if (res != null && res.Length == 2) + { + if (int.TryParse(res[0], out int firstAddress) && int.TryParse(res[1], out int ExitAddress)) + { + if (ExitAddress >= 0 && ExitAddress <= 7) + { + return ((firstAddress * 8) + 320 + ExitAddress).ToString(); + } + } + } + } + else if ((address.ToUpper().Contains("VW") || address.ToUpper().Contains("VD")) && address.Length >= 3) + { + var res = address.Substring(2); + if (res != null && int.TryParse(res, out int tempAddress)) + { + return ((tempAddress / 2) + 100).ToString(); + } + } + } + return ""; + } + /// /// PLC 地址 /// diff --git a/BPASmartClient.MorkMV1/Control_MorkMV1.cs b/BPASmartClient.MorkMV1/Control_MorkMV1.cs index 733dc452..ddbf8687 100644 --- a/BPASmartClient.MorkMV1/Control_MorkMV1.cs +++ b/BPASmartClient.MorkMV1/Control_MorkMV1.cs @@ -23,6 +23,7 @@ using BPA.Models; using System.Windows.Forms; using System.Media; using BPASmartClient.CustomResource; +using Microsoft.EntityFrameworkCore.Metadata.Internal; //using BPA.Helper; namespace BPASmartClient.MorkMV1 @@ -69,10 +70,10 @@ namespace BPASmartClient.MorkMV1 string guid = new Guid().ToString(); - mORKM.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { Loc = (ushort)NoodleLoc, SuborderId = guid }); + mORKM.RBTakeNoodleTask.Enqueue(new MOrderLocInfo() { Loc = (ushort)NoodleLoc, SuborderId = guid }); MessageLog.GetInstance.Show($"添加订单:面条位置【{NoodleLoc}】"); - mORKM.TakeBowlTask.Enqueue(new OrderLocInfo() { Loc = (ushort)BowlLoc, SuborderId = guid }); + mORKM.TakeBowlTask.Enqueue(new MOrderLocInfo() { Loc = (ushort)BowlLoc, SuborderId = guid }); MessageLog.GetInstance.Show($"添加订单:碗位置【{BowlLoc}】"); Thread.Sleep(60000); }), "ForOrder"); @@ -255,11 +256,12 @@ namespace BPASmartClient.MorkMV1 } })); - GetStatus("M16.7", new Action((obj) => + GetStatus("M16.6", new Action((obj) => { - if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 1) + if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 2) { - mORKM.RobotTakeNoodleCom = bools[0]; + mORKM.RobotInvertedSurfaceCom = bools[0]; + mORKM.RobotTakeNoodleCom = bools[1]; } })); @@ -348,6 +350,7 @@ namespace BPASmartClient.MorkMV1 OrderChange(order.MorkOrder.SuborderId, ORDER_STATUS.WAIT); DeviceProcessLogShow($"接收到{OrderCount}次订单,订单ID:{order.MorkOrder.SuborderId}"); mORKM.HistorySuborderId.Add(order.MorkOrder.SuborderId); + List oli = new List(); foreach (var item in order.MorkOrder.GoodBatchings) { var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId); @@ -357,38 +360,104 @@ namespace BPASmartClient.MorkMV1 { if (loc >= 1 && loc <= 5) { - if (mORKM.RBTakeNoodleTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) - mORKM.RBTakeNoodleTask.Enqueue(new OrderLocInfo() - { - GoodName = order.MorkOrder.GoodsName, - Loc = ushort.Parse(res.BatchingLoc), - SuborderId = order.MorkOrder.SuborderId, - SortNum = order.MorkOrder.SortNum, - BatchingId = res.BatchingId - }); - } - else if (loc >= 10 && loc <= 11) - { - int index = 0; - if (recipeBoms != null) + var x = Json.Data.DishLibraryParSets.FirstOrDefault(p => p.TextBlockContext == loc.ToString()); + if (x != null) { - index = Array.FindIndex(recipeBoms.RecipeIds?.ToArray(), p => p.RecipeId == order.MorkOrder.RecipeId); - index++; - } - if (mORKM.TakeBowlTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) - mORKM.TakeBowlTask.Enqueue(new OrderLocInfo() + oli.Add(new MOrderLocInfo() { - BatchingId = res.BatchingId, GoodName = order.MorkOrder.GoodsName, Loc = ushort.Parse(res.BatchingLoc), SuborderId = order.MorkOrder.SuborderId, SortNum = order.MorkOrder.SortNum, - RecipeNumber = (index >= 1 && index <= 10) ? (ushort)index : (ushort)0 + BatchingId = res.BatchingId, + Minute = x.Minute, + Second = x.Second, + LocDishType = x.LocDishType }); + } + //if (mORKM.RBTakeNoodleTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) + // mORKM.RBTakeNoodleTask.Enqueue(new OrderLocInfo() + // { + // GoodName = order.MorkOrder.GoodsName, + // Loc = ushort.Parse(res.BatchingLoc), + // SuborderId = order.MorkOrder.SuborderId, + // SortNum = order.MorkOrder.SortNum, + // BatchingId = res.BatchingId + // }); } + //else if (loc >= 10 && loc <= 11) + //{ + // int index = 0; + // if (recipeBoms != null) + // { + // index = Array.FindIndex(recipeBoms.RecipeIds?.ToArray(), p => p.RecipeId == order.MorkOrder.RecipeId); + // index++; + // } + // if (mORKM.TakeBowlTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) + // mORKM.TakeBowlTask.Enqueue(new OrderLocInfo() + // { + // BatchingId = res.BatchingId, + // GoodName = order.MorkOrder.GoodsName, + // Loc = ushort.Parse(res.BatchingLoc), + // SuborderId = order.MorkOrder.SuborderId, + // SortNum = order.MorkOrder.SortNum, + // RecipeNumber = (index >= 1 && index <= 10) ? (ushort)index : (ushort)0 + // }); + //} } } } + + for (int i = 0; i <= 1; i++) + { + oli.Where(p => p.LocDishType == i).ToList()?.ForEach(y => + { + mORKM.RBTakeNoodleTask.Enqueue(new MOrderLocInfo() + { + GoodName = y.GoodName, + Loc = y.Loc, + SuborderId = y.SuborderId, + SortNum = y.SortNum, + BatchingId = y.BatchingId, + LocDishType = y.LocDishType, + Minute = y.Minute, + RecipeId = y.RecipeId, + RecipeNumber = y.RecipeNumber, + Recipes = y.Recipes, + Second = y.Second + }); + }); + } + + if (mORKM.TakeBowlTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) + mORKM.TakeBowlTask.Enqueue(new OrderLocInfo() + { + GoodName = order.MorkOrder.GoodsName, + Loc = 11, + SuborderId = order.MorkOrder.SuborderId, + SortNum = order.MorkOrder.SortNum, + }); + + if (!mORKM.SuborderCount.ContainsKey(order.MorkOrder.SuborderId)) + { + mORKM.SuborderCount.TryAdd(order.MorkOrder.SuborderId, new SuborderInfo() + { + ActualCount = oli.Count, + AcMeatDishesCount = oli.Where(p => p.LocDishType == 0).ToList().Count, + AcVegetableCount = oli.Where(p => p.LocDishType == 1).ToList().Count, + }); + } + + //if (mORKM.RBTakeNoodleTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) + // mORKM.RBTakeNoodleTask.Enqueue(new OrderLocInfo() + // { + // GoodName = order.MorkOrder.GoodsName, + // Loc = ushort.Parse(res.BatchingLoc), + // SuborderId = order.MorkOrder.SuborderId, + // SortNum = order.MorkOrder.SortNum, + // BatchingId = res.BatchingId + // }); + } }); } @@ -575,18 +644,15 @@ namespace BPASmartClient.MorkMV1 { if (mORKM.CurrentLoc == mORKM.CurrentFeedbackLoc) { - //int loc = Array.FindIndex(mORKS.NoodleCookerStatus, p => p == false);//查找煮面炉空闲位置 int loc = mORKM.nsm.ToList().FindIndex(p => p.NoodleCookerStatus == false && p.IsShield == false);//查找煮面炉空闲位置 if (loc >= 0 && loc <= 5) { - //if (!Json.Data.parSets.ElementAt(loc).IsShield)//检查该煮面篮是否被屏蔽 - //{ - if (mORKM.RBTakeNoodleTask.TryDequeue(out OrderLocInfo orderLocInfo)) + if (mORKM.RBTakeNoodleTask.TryDequeue(out MOrderLocInfo orderLocInfo)) { //写入煮面时间 List values = new List(); - values.Add(Json.Data.parSets.ElementAt(loc).Minute); - values.Add(Json.Data.parSets.ElementAt(loc).Second); + values.Add(orderLocInfo.Minute); + values.Add(orderLocInfo.Second); WriteData($"VW{324 + (loc * 4)}", values.ToArray()); mORKM.CurrentLoc = 0; @@ -597,6 +663,14 @@ namespace BPASmartClient.MorkMV1 OrderChange(orderLocInfo.SuborderId, ORDER_STATUS.COOKING); DeviceProcessLogShow($"订单【{orderLocInfo.SuborderId}】,机器人倒面至【{loc + 1}】号煮面栏"); + if (mORKM.SuborderCount.ContainsKey(orderLocInfo.SuborderId)) + { + if (orderLocInfo.LocDishType == 0) + mORKM.SuborderCount[orderLocInfo.SuborderId].MeatDishesLoc.Add(loc + 1); + else if (orderLocInfo.LocDishType == 1) + mORKM.SuborderCount[orderLocInfo.SuborderId].VegetableLoc.Add(loc + 1); + } + mORKM.TakeNoodleInterlock = true; } } @@ -609,28 +683,89 @@ namespace BPASmartClient.MorkMV1 /// private void OutNoodleTask() { - if (mORKM.AllowInvertedFace && mORKM.RobotTaskInterlock && !mORKM.TakeNoodleInterlock && mORKM.RobotStatus) + if (mORKM.AllowInvertedFace && !mORKM.RobotOutDinnigLock && mORKM.RobotTaskInterlock && !mORKM.TakeNoodleInterlock && mORKM.RobotStatus) { - int loc = Array.FindIndex(mORKM.CookNodelId, p => p == mORKM.IngredientsCompleteId && p.Length > 0); - if (loc >= 0 && loc <= 5) + for (int i = 0; i < mORKM.CookNodelId.Length; i++) { - if (mORKM.CookNoodleCom[loc]) + if (mORKM.CookNodelId[i] == mORKM.IngredientsCompleteId && !string.IsNullOrEmpty(mORKM.CookNodelId[i])) { - SetTakeNoodleLoc((ushort)(loc + 1)); - mORKM.NoodleCookerStatus[loc] = false; - WriteData($"VW260", (ushort)0);//设置出汤时间 - OrderChange(mORKM.IngredientsCompleteId, ORDER_STATUS.COMPLETED_COOK); - DeviceProcessLogShow($"订单【{mORKM.IngredientsCompleteId}】制作完成"); - mORKM.CookCompleteFlatBit = true; - mORKM.OutMealId = mORKM.IngredientsCompleteId; - mORKM.OutMealName = mORKM.IngredientsCompleteName; - mORKM.OutMealSortNum = mORKM.IngredientsCompleteSortNum; - mORKM.IngredientsCompleteId = string.Empty; - mORKM.CookNodelId[loc] = string.Empty; - DeviceProcessLogShow($"{loc + 1} 号位置出餐控制,订单ID:{mORKM.OutMealId}"); - mORKM.CookNoodleCom[loc] = false; + if (mORKM.CookNoodleCom[i] && mORKM.SuborderCount.ContainsKey(mORKM.CookNodelId[i])) + { + var x = mORKM.SuborderCount[mORKM.CookNodelId[i]]; + + //执行取素菜操作 + if (x.AcVegetableCount != x.CuVegetableCount) + { + int index = x.VegetableLoc.FindIndex(p => p == i + 1); + if (index >= 0) + { + //SetTakeNoodleLoc((ushort)(index + 1)); + SetTakeNoodleLoc((ushort)(x.VegetableLoc.ElementAt(index))); + mORKM.NoodleCookerStatus[i] = false; + WriteData($"VW260", (ushort)0);//设置出汤时间 + DeviceProcessLogShow($"{x.VegetableLoc.ElementAt(index)} 号位置-[素菜]-出餐控制,订单ID:{mORKM.CookNodelId[i]}"); + mORKM.CookNodelId[i] = string.Empty; + mORKM.CookNoodleCom[i] = false; + x.VegetableLoc.RemoveAt(index); + x.CuVegetableCount++; + mORKM.RobotOutDinnigLock = true; + } + } + + //执行取荤菜 + if (x.AcVegetableCount == x.CuVegetableCount && x.AcMeatDishesCount != x.CuMeatDishesCount) + { + int index = x.MeatDishesLoc.FindIndex(p => p == i + 1); + if (index >= 0) + { + //SetTakeNoodleLoc((ushort)(index + 1)); + SetTakeNoodleLoc((ushort)(x.VegetableLoc.ElementAt(index))); + mORKM.NoodleCookerStatus[i] = false; + WriteData($"VW260", (ushort)0);//设置出汤时间 + DeviceProcessLogShow($"{x.VegetableLoc.ElementAt(index)} 号位置-[荤菜]-出餐控制,订单ID:{mORKM.CookNodelId[i]}"); + mORKM.CookNodelId[i] = string.Empty; + mORKM.CookNoodleCom[i] = false; + x.MeatDishesLoc.RemoveAt(index); + x.CuMeatDishesCount++; + mORKM.RobotOutDinnigLock = true; + } + } + + //if (x.CuMeatDishesCount + x.CuVegetableCount == x.ActualCount) + //{ + // OrderChange(mORKM.IngredientsCompleteId, ORDER_STATUS.COMPLETED_COOK); + // DeviceProcessLogShow($"订单【{mORKM.IngredientsCompleteId}】制作完成"); + // mORKM.CookCompleteFlatBit = true; + // mORKM.OutMealId = mORKM.IngredientsCompleteId; + // mORKM.OutMealName = mORKM.IngredientsCompleteName; + // mORKM.OutMealSortNum = mORKM.IngredientsCompleteSortNum; + // mORKM.IngredientsCompleteId = string.Empty; + //} + } } } + + + //int loc = Array.FindIndex(mORKM.CookNodelId, p => p == mORKM.IngredientsCompleteId && p.Length > 0); + //if (loc >= 0 && loc <= 5) + //{ + // if (mORKM.CookNoodleCom[loc]) + // { + // SetTakeNoodleLoc((ushort)(loc + 1)); + // mORKM.NoodleCookerStatus[loc] = false; + // WriteData($"VW260", (ushort)0);//设置出汤时间 + // OrderChange(mORKM.IngredientsCompleteId, ORDER_STATUS.COMPLETED_COOK); + // DeviceProcessLogShow($"订单【{mORKM.IngredientsCompleteId}】制作完成"); + // mORKM.CookCompleteFlatBit = true; + // mORKM.OutMealId = mORKM.IngredientsCompleteId; + // mORKM.OutMealName = mORKM.IngredientsCompleteName; + // mORKM.OutMealSortNum = mORKM.IngredientsCompleteSortNum; + // mORKM.IngredientsCompleteId = string.Empty; + // mORKM.CookNodelId[loc] = string.Empty; + // DeviceProcessLogShow($"{loc + 1} 号位置出餐控制,订单ID:{mORKM.OutMealId}"); + // mORKM.CookNoodleCom[loc] = false; + // } + //} } } @@ -677,6 +812,27 @@ namespace BPASmartClient.MorkMV1 DeviceProcessLogShow("机器人取面完成信号检测"); } + if (RTrig.GetInstance("RobotInvertedSurfaceCom").Start(mORKM.RobotInvertedSurfaceCom)) + { + if (mORKM.SuborderCount.ContainsKey(mORKM.IngredientsCompleteId)) + { + var x = mORKM.SuborderCount[mORKM.IngredientsCompleteId]; + if (x.CuMeatDishesCount + x.CuVegetableCount == x.ActualCount) + { + OrderChange(mORKM.IngredientsCompleteId, ORDER_STATUS.COMPLETED_COOK); + DeviceProcessLogShow($"订单【{mORKM.IngredientsCompleteId}】制作完成"); + mORKM.CookCompleteFlatBit = true; + mORKM.OutMealId = mORKM.IngredientsCompleteId; + mORKM.OutMealName = mORKM.IngredientsCompleteName; + mORKM.OutMealSortNum = mORKM.IngredientsCompleteSortNum; + mORKM.IngredientsCompleteId = string.Empty; + CookComplete(); + DeviceProcessLogShow($"倒面完成"); + } + } + mORKM.RobotOutDinnigLock = false; + } + int OutMealRequstCount = mORKM.CookNoodleCom.Where(p => p == true).ToList().Count; //int mlCount = mORKS.NoodleCookerStatus.Where(p => p == true).ToList().Count - Json.Data.parSets.Where(x => x.IsShield == true).ToList().Count; int mlCount = mORKM.nsm.Where(p => p.NoodleCookerStatus == true && p.IsShield == false).ToList().Count; @@ -770,6 +926,14 @@ namespace BPASmartClient.MorkMV1 WriteData($"M15.{loc - 1}", true); } + /// + /// 上位机单订单执行完成 + /// + private void CookComplete() + { + WriteData("M11.0", true); + } + public override void SimOrder() @@ -781,7 +945,7 @@ namespace BPASmartClient.MorkMV1 string guid = Guid.NewGuid().ToString(); if (msm.NoodleLoc >= 1 && msm.NoodleLoc <= 5) { - mORKM.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { Loc = (ushort)msm.NoodleLoc, SuborderId = guid }); + mORKM.RBTakeNoodleTask.Enqueue(new MOrderLocInfo() { Loc = (ushort)msm.NoodleLoc, SuborderId = guid }); MessageLog.GetInstance.Show($"添加订单:面条位置【{(ushort)msm.NoodleLoc}】"); } diff --git a/BPASmartClient.MorkMV1/GVL_MorkMV1.cs b/BPASmartClient.MorkMV1/GVL_MorkMV1.cs index faca957a..1d1d96d3 100644 --- a/BPASmartClient.MorkMV1/GVL_MorkMV1.cs +++ b/BPASmartClient.MorkMV1/GVL_MorkMV1.cs @@ -30,6 +30,12 @@ namespace BPASmartClient.MorkMV1 [VariableMonitor("机器人任务互锁信号")] public bool RobotTaskInterlock { get; set; } + /// + /// 机器人倒冒菜互锁 + /// + [VariableMonitor("机器人倒冒菜互锁")] + public bool RobotOutDinnigLock { get; set; } + /// /// 取碗互锁信号 /// @@ -96,7 +102,7 @@ namespace BPASmartClient.MorkMV1 /// /// 机器人取面位置队列 /// - public ConcurrentQueue RBTakeNoodleTask { get; set; } = new ConcurrentQueue(); + public ConcurrentQueue RBTakeNoodleTask { get; set; } = new ConcurrentQueue(); /// /// 出碗队列 @@ -106,7 +112,10 @@ namespace BPASmartClient.MorkMV1 public List doOrderEvents { get; set; } = new List(); - public ConcurrentDictionary doe { get; set; } = new ConcurrentDictionary(); + /// + /// 子订单对应的物料数量 + /// + public ConcurrentDictionary SuborderCount { get; set; } = new ConcurrentDictionary(); public List HistorySuborderId { get; set; } = new List(); @@ -271,6 +280,12 @@ namespace BPASmartClient.MorkMV1 [VariableMonitor("料仓到位", "M13.5", "429")] public bool SiloInPlace { get; set; } + /// + /// 机器人将面倒入碗中完成 + /// + [VariableMonitor("机器人取面倒入碗中完成", "M16.6")] + public bool RobotInvertedSurfaceCom { get; set; } + /// /// 机器人料仓取面完成 /// diff --git a/BPASmartClient.MorkMV1/Model/MOrderLocInfo.cs b/BPASmartClient.MorkMV1/Model/MOrderLocInfo.cs new file mode 100644 index 00000000..7c2af170 --- /dev/null +++ b/BPASmartClient.MorkMV1/Model/MOrderLocInfo.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MorkMV1.Model +{ + public class MOrderLocInfo : OrderLocInfo + { + public ushort Minute { get; set; } + + public ushort Second { get; set; } + + /// + /// 库位菜品类型,0,荤菜,1素菜 + /// + public int LocDishType { get; set; } + } +} diff --git a/BPASmartClient.MorkMV1/Model/SuborderInfo.cs b/BPASmartClient.MorkMV1/Model/SuborderInfo.cs new file mode 100644 index 00000000..a651fc5b --- /dev/null +++ b/BPASmartClient.MorkMV1/Model/SuborderInfo.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MorkMV1.Model +{ + public class SuborderInfo + { + /// + /// 实际荤素物料总数 + /// + public int ActualCount { get; set; } + + /// + /// 当前荤菜总数 + /// + public int CuMeatDishesCount { get; set; } + /// + /// 实际荤菜出餐数量 + /// + public int AcMeatDishesCount { get; set; } + + /// + /// 荤菜位置集合信息 + /// + public List MeatDishesLoc { get; set; } = new List(); + + /// + /// 当前素菜总数 + /// + public int CuVegetableCount { get; set; } + /// + /// 实际素菜出餐数量 + /// + public int AcVegetableCount { get; set; } + /// + /// 素菜位置集合信息 + /// + public List VegetableLoc { get; set; } = new List(); + + } +}