using BPA.Message; using HBLConsole.Communication; using HBLConsole.Factory; using HBLConsole.Interface; using HBLConsole.Model; using HBLConsole.Service; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using BPA.Message.Enum; namespace HBLConsole.Business.Devices { public class MORKS : IBusiness { private volatile static MORKS _Instance; public static MORKS GetInstance => _Instance ?? (_Instance = new MORKS()); private MORKS() { } GVL.MORKS mORKS = new GVL.MORKS(); /// /// 写入配方数据到 PLC /// private void WriteRecipeBoms() { List recipeBoms = new List(); foreach (var item in Json.GetInstance.Base.recipeBoms.RecipeIds) { foreach (var rec in item.Recipes) { recipeBoms.Add((ushort)rec); } } if (ModbusTcpHelper.GetInstance.Write(1100, WriteType.HoldingRegisters, recipeBoms.ToArray())) { MessageLog.GetInstance.Show("成功写入配方数据"); } } public void Init() { //Modbus TCP连接成功 ActionManagerment.GetInstance.Register(new Action(() => { WriteRecipeBoms(); ReadPlcData(); DataParse(); Main(); }), "ConnectOk"); //获取物料信息 SimpleFactory.GetInstance.GetBatchingInfo(); //Modbus Tcp 连接 ModbusTcpHelper.GetInstance.ModbusTcpConnect("127.0.0.1"); } /// /// 数据读取 /// private void ReadPlcData() { ThreadManagerment.GetInstance.StartLong(new Action(() => { object result; result = ModbusTcpHelper.GetInstance.Read(1120, ReadType.Coils, 16); if (result != null) { if (result is bool[] bools) { if (bools.Length == 16) { mORKS.InitComplete = bools[0]; mORKS.TakeBowlIdle = bools[1]; mORKS.TemperatureReached = bools[2]; mORKS.AllowFallNoodle = bools[3]; mORKS.RbTakeNoodleComplete = bools[4]; mORKS.RbFallNoodleComplete = bools[5]; mORKS.RbOutMealComplete = bools[6]; mORKS.RobotIdle = bools[7]; mORKS.TakeMealDetect = bools[8]; mORKS.MissingBowl = bools[9]; mORKS.TurntableLowerLimit = bools[11]; } } } //读取煮面栏状态 result = ModbusTcpHelper.GetInstance.Read(1136, ReadType.Coils, 6); if (result != null) { if (result is bool[] bools) { if (bools.Length == 6) { for (int i = 0; i < 6; i++) { mORKS.NoodleCookerStatus[i] = bools[i]; } } } } //读取煮面炉完成信号 result = ModbusTcpHelper.GetInstance.Read(1144, ReadType.Coils, 6); if (result != null) { if (result is bool[] bools) { if (bools.Length == 6) { for (int i = 0; i < 6; i++) { mORKS.CookNoodlesComplete[i] = bools[i]; } } } } Thread.Sleep(500); }), "Read PLC Data"); } /// /// 数据解析 /// private void DataParse() { ActionManagerment.GetInstance.Register(new Action((o) => { if (o is MorkOrderPush morkOrderPush) { foreach (var item in morkOrderPush.GoodBatchings) { var res = Json.GetInstance.Base.orderMaterialDelivery.BatchingInfo.FirstOrDefault(p => p.BatchingId == item.BatchingId); if (res != null) { if (ushort.TryParse(res.BatchingLoc, out ushort loc)) { if (loc >= 1 && loc <= 5) { mORKS.RBTakeNoodleTask.Enqueue(new GVL.OrderLocInfo() { Loc = loc, SuborderId = morkOrderPush.SuborderId }); } else if (loc >= 10 && loc <= 11) { mORKS.TakeBowlTask.Enqueue(new GVL.OrderLocInfo() { Loc = loc, SuborderId = morkOrderPush.SuborderId, RecipeNumber = (ushort)morkOrderPush.RecipeId }); } } } } } }), "MorksParse"); } bool AllowRun = false; string TakeBowlId = string.Empty;//取碗订单ID string IngredientsCompleteId = string.Empty;//配料完成订单ID string[] CookNodelId = new string[6] { string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, }; bool RobotTaskInterlock = false;//机器人任务互锁信号 string OutMealId = string.Empty; private void Main() { ThreadManagerment.GetInstance.StartLong(new Action(() => { AllowRun = mORKS.InitComplete && mORKS.TemperatureReached; if (AllowRun) { TakeBowlTask(); TakeNoodleTask(); } OutNoodleTask(); SingleDetect(); Thread.Sleep(1); }), "Main Task"); } /// /// 取碗控制 /// private void TakeBowlTask() { //取碗控制 if (RTrig.GetInstance("TakeBowl").Start(mORKS.TakeBowlIdle && mORKS.TakeBowlTask.Count > 0)) { if (mORKS.TakeBowlTask.TryDequeue(out GVL.OrderLocInfo orderLocInfo)) { TakeBowlId = orderLocInfo.SuborderId; TakeBowlControl(orderLocInfo.Loc); SetRecipeNumber(orderLocInfo.RecipeNumber); SimpleFactory.GetInstance.OrderChanged(TakeBowlId, ORDER_STATUS.COOKING); MessageLog.GetInstance.Show($"订单【{TakeBowlId}】,位置:[{orderLocInfo.Loc}]"); } } } /// /// 取面任务 /// private void TakeNoodleTask() { //取面控制 if (!RobotTaskInterlock) { if (RTrig.GetInstance("TakeNoodle").Start(mORKS.RobotIdle && mORKS.RBTakeNoodleTask.Count > 0)) { if (mORKS.RBTakeNoodleTask.TryDequeue(out GVL.OrderLocInfo orderLocInfo)) { //设置转台位置 SetTurntableLoc(orderLocInfo.Loc); //设置倒面位置 int loc = Array.FindIndex(mORKS.NoodleCookerStatus, p => p == false);//查找煮面炉空闲位置 if (loc >= 0 && loc <= 5) { CookNodelId[loc] = orderLocInfo.SuborderId; SetFallNoodleLoc((ushort)(loc + 1)); } //机器人开始取面 RobotTakeNoodle(); SimpleFactory.GetInstance.OrderChanged(orderLocInfo.SuborderId, ORDER_STATUS.COOKING); MessageLog.GetInstance.Show($"订单【{orderLocInfo.SuborderId}】,转台:[{orderLocInfo.Loc}],煮面栏:[{loc}]"); } } } } /// /// 出餐控制 /// private void OutNoodleTask() { if (RobotTaskInterlock) { if (mORKS.AllowFallNoodle && mORKS.RobotIdle && !mORKS.TakeMealDetect) { int loc = Array.FindIndex(CookNodelId, p => p == IngredientsCompleteId); if (loc >= 0 && loc <= 5) { if (mORKS.CookNoodlesComplete[loc]) { SetTakeNoodleLoc((ushort)(loc + 1)); RobotOutMeal(); CookNoodleStatusReset((ushort)(loc + 1)); OutMealId = IngredientsCompleteId; IngredientsCompleteId = string.Empty; CookNodelId[loc] = string.Empty; } } } } } /// /// 信号检测 /// private void SingleDetect() { if (RTrig.GetInstance("AllowFallNoodle").Start(mORKS.AllowFallNoodle)) { IngredientsCompleteId = TakeBowlId; TakeBowlId = string.Empty; } if (RTrig.GetInstance("CompleteChange").Start(mORKS.RbOutMealComplete)) { SimpleFactory.GetInstance.OrderChanged(OutMealId, ORDER_STATUS.COMPLETED_COOK); MessageLog.GetInstance.Show($"订单【{OutMealId}】制作完成"); } if (DelayRTrig.GetInstance("CompleteChange1").Start(mORKS.RbOutMealComplete && !mORKS.TakeMealDetect, 2)) { SimpleFactory.GetInstance.OrderChanged(OutMealId, ORDER_STATUS.COMPLETED_TAKE); MessageLog.GetInstance.Show($"订单【{OutMealId}】取餐完成"); OutMealId = string.Empty; } RobotTaskInterlock = mORKS.RobotIdle && mORKS.AllowFallNoodle && mORKS.NoodleCookerStatus.Where(p => p == true).ToList().Count >= 3; } /// /// 取面完成复位 /// private void TakeNoodleCompleteReset() { ModbusTcpHelper.GetInstance.Write(1124, WriteType.Coils, false); } /// /// 指定煮面口状态复位 /// /// private void CookNoodleStatusReset(int num) { if (num >= 1 && num <= 6) { ushort addRess = (ushort)(1136 + num - 1); ModbusTcpHelper.GetInstance.Write(1136, WriteType.Coils, false); } } /// /// 写配方编号 /// /// private void SetRecipeNumber(ushort num) { ModbusTcpHelper.GetInstance.Write(100, WriteType.HoldingRegisters, num); } /// /// 设置转台位置 /// /// private void SetTurntableLoc(ushort loc) { ModbusTcpHelper.GetInstance.Write(101, WriteType.HoldingRegisters, loc); } /// /// 设置倒面位置 /// /// private void SetFallNoodleLoc(ushort loc) { ModbusTcpHelper.GetInstance.Write(102, WriteType.HoldingRegisters, loc); } /// /// 设置取面位置 /// /// private void SetTakeNoodleLoc(ushort loc) { ModbusTcpHelper.GetInstance.Write(103, WriteType.HoldingRegisters, loc); } /// /// 取碗控制 /// /// private void TakeBowlControl(ushort loc) { if (loc == 10) { ModbusTcpHelper.GetInstance.Write(321, WriteType.Coils, true); } else if (loc == 11) { ModbusTcpHelper.GetInstance.Write(322, WriteType.Coils, true); } } /// /// 机器人取面 /// private void RobotTakeNoodle() { ModbusTcpHelper.GetInstance.Write(323, WriteType.Coils, true); } /// /// 机器人取餐 /// private void RobotOutMeal() { ModbusTcpHelper.GetInstance.Write(324, WriteType.Coils, true); } } }