//#define ModelSwitch using BPA.Helper; using BPASmartClient.SmallBatchingSystem; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using BPASmartClient.CustomResource.Pages.Model; using BPASmartClient.CustomResource.UserControls.MessageShow; using BPASmartClient.CustomResource.UserControls; namespace BPASmartClient.SmallBatchingSystem { public class Control { private volatile static Control _Instance; public static Control GetInstance => _Instance ?? (_Instance = new Control()); private Control() { } public ConcurrentQueue MakeOrderQueue { get; set; } = new ConcurrentQueue(); public bool IsCancel { get; set; } public void Init() { ThreadManage.GetInstance().Start(new Action(() => { PlcServer.GetInstance.Connect(); }), "设备初始化"); ThreadManage.GetInstance().StartLong(new Action(() => { while (MakeOrderQueue.Count > 0) { if (MakeOrderQueue.TryDequeue(out RecipeInfo recipeInfo)) { ProcessOne(recipeInfo); //ProcessTwo(recipeInfo); } } Thread.Sleep(10); }), "配方流程控制"); } private void ProcessOne(RecipeInfo recipeInfo) { IsCancel = false; List OutletInfo = new List(); recipeInfo.SiloInfoModels.ToList()?.ForEach(item => { var res = Json.Data.OutletInfoModels.FirstOrDefault(p => p.SiloInfos.FirstOrDefault(s => s.Contains(item.SiloName)) != null); if (res != null) if (!OutletInfo.Contains(res.OutletLoc)) OutletInfo.Add(res.OutletLoc); }); foreach (var temp in OutletInfo) { PlcServer.GetInstance.WriteData("VW302", (ushort)temp);//设置出料口位置 PlcServer.GetInstance.WriteData("M10.0", true);//定位启动 RunLog($"启动定位,出料口位置:{temp}"); int index = temp - 1; if (index >= 0) { RunLog("等待定位完成"); while (!PlcDataModel.TargetLocComplete && !IsCancel) Thread.Sleep(1);//等待定位反馈 if (IsCancel) break; RunLog("定位完成"); PlcServer.GetInstance.WriteData("M20.0", false); while (PlcDataModel.TargetLocComplete && !IsCancel) Thread.Sleep(1); if (IsCancel) break; RunLog("定位完成,复位成功"); foreach (var temp1 in recipeInfo.SiloInfoModels) { var rest = Json.Data.OutletInfoModels.FirstOrDefault(p => p.SiloInfos.FirstOrDefault(s => s.Contains(temp1.SiloName)) != null); if (rest != null && rest.OutletLoc == temp) { var res = Json.Data.SiloInfoModels.FirstOrDefault(p => p.SiloName == temp1.SiloName); if (res != null) { StatusNotify(res.SiloName, Status.正在配料); RunLog($"写重量地址:{GetWeightAdd(res.SiloLoc)},重量:{temp1.SiloWeight * 10}"); PlcServer.GetInstance.WriteData(GetWeightAdd(res.SiloLoc), (ushort)(temp1.SiloWeight * 10)); RunLog($"写启动信号地址:{GetStartSingleAdd(res.SiloLoc)}"); PlcServer.GetInstance.WriteData(GetStartSingleAdd(res.SiloLoc), true); while (!PlcDataModel.BatchingCompleted && !IsCancel) Thread.Sleep(1);//等待出料完成 if (IsCancel) break; RunLog("出料完成,复位出料完成状态"); PlcServer.GetInstance.WriteData("M4.0", false);//复位出料完成信号 while (PlcDataModel.BatchingCompleted && !IsCancel) Thread.Sleep(1);//等待出料完成信号复位成功 if (IsCancel) break; RunLog("出料完成复位成功"); StatusNotify(res.SiloName, Status.配料完成); } } } if (IsCancel) return; } } if (!IsCancel) { RunLog($"写入配方执行完成信号"); PlcServer.GetInstance.WriteData("M10.4", true); RunLog("等待配方执行完成"); while (!PlcDataModel.RecipeBatchingComplete && !IsCancel) Thread.Sleep(1); if (IsCancel) return; RunLog($"【{recipeInfo.RecipeName}】配方执行完成"); ActionManage.GetInstance.Send("GrindArenaceousCancel"); } // IsCancel = false; // Dictionary> DeviceSoilInfo = new Dictionary>(); // List OutletInfo = new List(); // recipeInfo.SiloInfoModels.ToList()?.ForEach(item => // { // var res = Json.Data.OutletInfoModels.FirstOrDefault(p => p.SiloInfos.FirstOrDefault(s => s == item.SiloName) != null); // if (res != null) // { // var soliInfo = Json.Data.SiloInfoModels.FirstOrDefault(p => p.SiloName == item.SiloName); // if (soliInfo != null) // { // if (!DeviceSoilInfo.ContainsKey(res.OutletLoc)) // { // DeviceSoilInfo.Add(res.OutletLoc, new List()); // DeviceSoilInfo[res.OutletLoc].Add(soliInfo.SiloLoc); // } // else // { // DeviceSoilInfo[res.OutletLoc].Add(soliInfo.SiloLoc); // } // } // } // }); // foreach (var temp in DeviceSoilInfo) // { // PlcServer.GetInstance.WriteData("VW302", (ushort)temp.Key);//设置出料口位置 //#if ModelSwitch // PlcServer.GetInstance.WriteData("M10.4", true);//定位启动 //#else // PlcServer.GetInstance.WriteData("M10.0", true);//定位启动 //#endif // RunLog($"启动定位,出料口位置:{temp.Key}"); // int index = temp.Key - 1; // if (index >= 0) // { // RunLog("等待定位完成"); // while (!PlcDataModel.TargetLocComplete && !IsCancel) Thread.Sleep(1);//等待定位反馈 // if (IsCancel) break; // RunLog("定位完成"); // PlcServer.GetInstance.WriteData("M20.0", false); // while (PlcDataModel.TargetLocComplete && !IsCancel) Thread.Sleep(1); // if (IsCancel) break; // RunLog("定位完成,复位成功"); // foreach (var temp1 in temp.Value) // { // //var rest = Json.Data.OutletInfoModels.FirstOrDefault(p => p.SiloInfos.FirstOrDefault(s => s.Contains(temp1.SiloName)) != null); // //if (rest != null && rest.OutletLoc == temp) // //{ // var res = Json.Data.SiloInfoModels.FirstOrDefault(p => p.SiloLoc == temp1); // if (res != null) // { // var tempRecipe = recipeInfo.SiloInfoModels.FirstOrDefault(p => p.SiloName == res.SiloName); // if (tempRecipe != null) // { // StatusNotify(res.SiloName, Status.正在配料); // RunLog($"写重量地址:{GetWeightAdd(res.SiloLoc)},重量:{tempRecipe.SiloWeight}"); // PlcServer.GetInstance.WriteData(GetWeightAdd(res.SiloLoc), (ushort)(tempRecipe.SiloWeight * 10)); // RunLog($"写启动信号地址:{GetStartSingleAdd(res.SiloLoc)}"); // PlcServer.GetInstance.WriteData(GetStartSingleAdd(res.SiloLoc), true); // while (!PlcDataModel.BatchingCompleted && !IsCancel) Thread.Sleep(1);//等待出料完成 // if (IsCancel) break; // RunLog("出料完成,复位出料完成状态"); //#if ModelSwitch // PlcServer.GetInstance.WriteData("M10.0", false);//复位出料完成信号 //#else // PlcServer.GetInstance.WriteData("M4.0", false);//复位出料完成信号 //#endif // while (PlcDataModel.BatchingCompleted && !IsCancel) Thread.Sleep(1);//等待出料完成信号复位成功 // if (IsCancel) break; // RunLog("出料完成复位成功"); // StatusNotify(res.SiloName, Status.配料完成); // } // } // //} // } // if (IsCancel) return; // } // } } /// /// 计时配料 /// /// private void ProcessTwo(RecipeInfo recipeInfo) { IsCancel = false; Dictionary> DeviceSoilInfo = new Dictionary>(); List OutletInfo = new List(); recipeInfo.SiloInfoModels.ToList()?.ForEach(item => { var res = Json.Data.OutletInfoModels.FirstOrDefault(p => p.SiloInfos.FirstOrDefault(s => s == item.SiloName) != null); if (res != null) { var soliInfo = Json.Data.SiloInfoModels.FirstOrDefault(p => p.SiloName == item.SiloName); if (soliInfo != null) { if (!DeviceSoilInfo.ContainsKey(res.OutletLoc)) { DeviceSoilInfo.Add(res.OutletLoc, new List()); DeviceSoilInfo[res.OutletLoc].Add(soliInfo.SiloLoc); } else { DeviceSoilInfo[res.OutletLoc].Add(soliInfo.SiloLoc); } } } }); foreach (var temp in DeviceSoilInfo) { PlcServer.GetInstance.WriteData("VW302", (ushort)temp.Key);//设置出料口位置 //PlcServer.GetInstance.WriteData("M10.0", true);//定位启动 PlcServer.GetInstance.WriteData("M10.4", true);//定位启动 RunLog($"启动定位,出料口位置:{temp}"); int index = temp.Key - 1; if (index >= 0) { RunLog("等待定位完成"); while (!PlcDataModel.TargetLocComplete && !IsCancel) Thread.Sleep(1);//等待定位反馈 if (IsCancel) break; RunLog("定位完成"); PlcServer.GetInstance.WriteData("M20.0", false); while (PlcDataModel.TargetLocComplete && !IsCancel) Thread.Sleep(1); if (IsCancel) break; RunLog("定位完成,复位成功"); foreach (var temp1 in temp.Value) { //var rest = Json.Data.OutletInfoModels.FirstOrDefault(p => p.SiloInfos.FirstOrDefault(s => s.Contains(temp1.SiloName)) != null); //if (rest != null && rest.OutletLoc == temp) //{ var res = Json.Data.SiloInfoModels.FirstOrDefault(p => p.SiloLoc == temp1); if (res != null) { var tempRecipe = recipeInfo.SiloInfoModels.FirstOrDefault(p => p.SiloName == res.SiloName); if (tempRecipe != null) { StatusNotify(res.SiloName, Status.正在配料); RunLog($"写重量地址:{GetWeightAdd(res.SiloLoc)},重量:{tempRecipe.SiloWeight}"); PlcServer.GetInstance.WriteData(GetWeightAdd(res.SiloLoc), (ushort)(tempRecipe.SiloWeight * 10)); RunLog($"写启动信号地址:{GetStartSingleAdd(res.SiloLoc)}"); PlcServer.GetInstance.WriteData(GetStartSingleAdd(res.SiloLoc), true); while (!PlcDataModel.BatchingCompleted && !IsCancel) Thread.Sleep(1);//等待出料完成 if (IsCancel) break; RunLog("出料完成,复位出料完成状态"); #if ModelSwitch PlcServer.GetInstance.WriteData("M10.0", false);//复位出料完成信号 #else PlcServer.GetInstance.WriteData("M4.0", false);//复位出料完成信号 #endif while (PlcDataModel.BatchingCompleted && !IsCancel) Thread.Sleep(1);//等待出料完成信号复位成功 if (IsCancel) break; RunLog("出料完成复位成功"); StatusNotify(res.SiloName, Status.配料完成); } } //} } if (IsCancel) return; } } //IsCancel = false; //List OutletInfo = new List(); //recipeInfo.SiloInfoModels.ToList()?.ForEach(item => //{ // var res = Json.Data.OutletInfoModels.FirstOrDefault(p => p.SiloInfos.FirstOrDefault(s => s.Contains(item.SiloName)) != null); // if (res != null) if (!OutletInfo.Contains(res.OutletLoc)) OutletInfo.Add(res.OutletLoc); //}); //foreach (var temp in OutletInfo) //{ // PlcServer.GetInstance.WriteData("VW302", (ushort)temp);//设置出料口位置 // //PlcServer.GetInstance.WriteData("M10.0", true);//定位启动 // PlcServer.GetInstance.WriteData("M10.4", true);//定位启动 // RunLog($"启动定位,出料口位置:{temp}"); // int index = temp - 1; // if (index >= 0) // { // RunLog("等待定位完成"); // while (!PlcDataModel.TargetLocComplete && !IsCancel) Thread.Sleep(1);//等待定位反馈 // if (IsCancel) break; // RunLog("定位完成"); // PlcServer.GetInstance.WriteData("M20.0", false); // while (PlcDataModel.TargetLocComplete && !IsCancel) Thread.Sleep(1); // if (IsCancel) break; // RunLog("定位完成,复位成功"); // foreach (var temp1 in recipeInfo.SiloInfoModels) // { // var rest = Json.Data.OutletInfoModels.FirstOrDefault(p => p.SiloInfos.FirstOrDefault(s => s.Contains(temp1.SiloName)) != null); // if (rest != null && rest.OutletLoc == temp) // { // var res = Json.Data.SiloInfoModels.FirstOrDefault(p => p.SiloName == temp1.SiloName); // if (res != null) // { // StatusNotify(res.SiloName, Status.正在配料); // RunLog($"写重量地址:{GetWeightAdd(res.SiloLoc)},重量:{temp1.SiloWeight}"); // PlcServer.GetInstance.WriteData(GetWeightAdd(res.SiloLoc), (ushort)(temp1.SiloWeight * 10)); // RunLog($"写启动信号地址:{GetStartSingleAdd(res.SiloLoc)}"); // PlcServer.GetInstance.WriteData(GetStartSingleAdd(res.SiloLoc), true); // while (!PlcDataModel.BatchingCompleted && !IsCancel) Thread.Sleep(1);//等待出料完成 // if (IsCancel) break; // RunLog("出料完成,复位出料完成状态"); //#if test // PlcServer.GetInstance.WriteData("M10.0", false);//复位出料完成信号 //#else //PlcServer.GetInstance.WriteData("M4.0", false);//复位出料完成信号 //#endif // while (PlcDataModel.BatchingCompleted && !IsCancel) Thread.Sleep(1);//等待出料完成信号复位成功 // if (IsCancel) break; // RunLog("出料完成复位成功"); // StatusNotify(res.SiloName, Status.配料完成); // } // } // } // if (IsCancel) return; // } //} if (!IsCancel) { RunLog($"写入配方执行完成信号"); //PlcServer.GetInstance.WriteData("M10.4", true); PlcServer.GetInstance.WriteData("M10.5", true); RunLog("等待配方执行完成"); while (!PlcDataModel.RecipeBatchingComplete && !IsCancel) Thread.Sleep(1); if (IsCancel) return; RunLog($"【{recipeInfo.RecipeName}】配方执行完成"); ActionManage.GetInstance.Send("GrindArenaceousCancel"); } } /// /// 获取重量设置地址 /// /// /// private string GetWeightAdd(int num) { #if ModelSwitch if (num > 0) { int add = 0; if (num >= 1 && num <= 18) { add = 200 + (num - 1) * 2; } return $"VW{add}"; } return default; #else if (num > 0) { int add = 0; if (num >= 1 && num <= 8) { add = 100 + (num - 1) * 2; } else if (num >= 9 && num <= 18) { add = 102 + (num - 1) * 2; } return $"VW{add}"; } return default; #endif } private void StatusNotify(string SiloName, Status Status) { ActionManage.GetInstance.Send("StatusNotify", new RecipeStatus() { RawMaterialName = SiloName, Status = Status.ToString() }); } public void RunLog(string info) { BPA.Helper.MessageLog.GetInstance.Show(info); BPASmartClient.CustomResource.Pages.Model.MessageNotify.GetInstance.ShowRunLog(info); Debug.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")}:{info}"); } public void OperationLog(string info) { BPA.Helper.MessageLog.GetInstance.Show(info); BPASmartClient.CustomResource.Pages.Model.MessageNotify.GetInstance.ShowUserLog(info); Debug.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")}:{info}"); } public void DebugLog(string info) { BPASmartClient.Message.MessageLog.GetInstance.DebugLog(info); } public void NotifyPrompt(string info) { App.Current.Dispatcher.Invoke(() => { NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", info); }); } /// /// 获取启动信号地址 /// /// /// private string GetStartSingleAdd(int num) { #if ModelSwitch if (num > 0) { string Add = string.Empty; var t = num / 8; var c = (num % 8); if (c == 0) { t--; c = 7; } else c--; Add = $"M{t + 4}.{c}"; return Add; } return default; #else if (num > 0) { string Add = string.Empty; var t = num / 8; var c = (num % 8); if (c == 0) { t--; c = 7; } else c--; Add = $"M{t}.{c}"; return Add; } return default; #endif } } }