using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Documents; using Admin.Core.Common; using Admin.Core.IService; using Admin.Core.Model; using Admin.Core.Model.ViewModels; using Admin.Core.Service; using Aucma.Core.HwPLc; using Microsoft.Extensions.DependencyInjection; using NetTaste; using NPOI.SS.Formula.Functions; namespace Aucma.Core.SheetMetal.Business; /// /// 箱壳计划任务处理 /// public class SheetMetalPlanTaskHandle { #region 刷新创建计划 /// /// 刷新创建计划 /// public delegate Task RefreshCretaePlanInfo(); public static event RefreshCretaePlanInfo RefreshCreatePlanInfoEvent; #endregion #region 刷新图表 /// /// 刷新创建计划 /// public delegate Task RefreshChat(); public static event RefreshChat RefreshChatEvent; #endregion #region 刷新当前正在执行的计划 /// /// 刷新当前正在执行的计划 /// public delegate void RefreshCurrentPlanInfo(); public static event RefreshCurrentPlanInfo RefreshCurrentPlanInfoEvent; #endregion #region 给设备监控模块显示 /// /// 刷新当前正在执行的计划 /// public delegate void RefreshExecInfo(string message); public static event RefreshExecInfo RefreshExecInfoEvent; #endregion protected readonly IExecutePlanInfoServices? _executePlanInfoServices; protected readonly IRecordSidePanelComplateServices _sidePanelComplateServices; protected readonly IRecordBackPanelComplateServices _backPanelComplateServices; public HwPLc.PlcModel plc1 = null; public SheetMetalPlanTaskHandle() { _executePlanInfoServices = App.ServiceProvider.GetService(); _sidePanelComplateServices = App.ServiceProvider.GetService(); _backPanelComplateServices = App.ServiceProvider.GetService(); } #region 下发多个计划同步执行 /// /// 初始化下发生产计划,获取已拆分的计划进行下发——后板任务 /// public void InitSendBackPanelPlan() { Thread.Sleep(5000); var obj_backPanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("BackPanelPLC")); while (true) { var planInfoList = _executePlanInfoServices.QuerySheetMetalSendPlanData("1001").Where(d => d.PlanAmount > d.BackPanelAmount).ToList(); planInfoList = planInfoList.Where(d => d.ExecuteStatus == 1 || d.ExecuteStatus == 2).ToList(); if (planInfoList == null|| planInfoList.Count==0) continue; var planInfos = planInfoList.Where(d => d.PlanType == 3 || d.PlanType == 1).ToList(); if (planInfos!=null) { if (planInfos.Count > 0) { SheetMetaSendPlanInfoView planInfo = planInfos.FirstOrDefault(d => d.BackPanelAmount != d.PlanAmount); if (planInfo == null) continue; if (planInfo.PlanType == 3||planInfo.PlanType == 1)//如果为3或者为1 后板计划单独下发 以前板完成为主 { SendPlanTaskToBackPanel(planInfo, obj_backPanel); UpdateBackPanelPlanTaskByComplate(planInfo); } } else { Console.WriteLine("未获取到需要下发的任务"); } } Thread.Sleep(3000); } } /// /// 初始化下发生产计划,获取已拆分的计划进行下发——前板任务 /// public void InitSendSidePanelPlan() { Thread.Sleep(5000); var obj_sidePanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("SidePanelPlc")); while (true) { var planInfoList = _executePlanInfoServices.QuerySheetMetalSendPlanData("1001").Where(d=>d.PlanAmount > d.SidePanelAmount).ToList(); planInfoList = planInfoList.Where(d => d.ExecuteStatus == 1 || d.ExecuteStatus == 2).ToList(); if (planInfoList == null || planInfoList.Count == 0) continue; var planInfos = planInfoList.Where(d => d.PlanType == 2 || d.PlanType == 1).ToList(); if (planInfos != null) { if (planInfos.Count > 0) { SheetMetaSendPlanInfoView planInfo = planInfos.FirstOrDefault(d => d.SidePanelAmount != d.PlanAmount); if (planInfo == null) continue; if (planInfo.PlanType == 2 || planInfo.PlanType == 1)//如果为2或者为1 前板板计划单独下发 以前板完成为主 { SendPlanTaskToSidPanel(planInfo, obj_sidePanel); UpdateSidPanelPlanTaskByComplate(planInfo); } } else { Console.WriteLine("未获取到需要下发的任务"); } } Thread.Sleep(3000); } } /// /// 下发前板生产计划 /// /// /// public void SendPlanTaskToSidPanel(SheetMetaSendPlanInfoView planInfo, PlcModel obj_sidePanel) { try { Task.Run(() => { if (obj_sidePanel != null) { //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021 obj_sidePanel.plc.WriteString("D6000", planInfo.TaskCode); string processNumber = GetProcessNumberBy(planInfo.MaterialCode); obj_sidePanel.plc.WriteString("D6010", planInfo.MaterialSpecificatons); obj_sidePanel.plc.WriteInt32("D6020", planInfo.PlanAmount); obj_sidePanel.plc.WriteInt32("D6021", 1); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待背板设备应答。。。。。。"); RefreshExecInfoEvent?.Invoke($"等待背板设备应答。。。。。。"); #region PLC反馈信号逻辑处理 //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中 bool isFlag = true; do { if (obj_sidePanel.plc.ReadInt32("D6021") == 2) { obj_sidePanel.plc.WriteInt32("D6021", 0); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>收到背板板设备应答信号,复位应答地址"); RefreshExecInfoEvent?.Invoke($"收到背板板设备应答信号,复位应答地址"); isFlag = false; } Thread.Sleep(2000); } while (isFlag); //更新计划状态为2执行中 planInfo.ExecuteStatus = 2; bool result = _executePlanInfoServices.UpdateSheetMetalExecutePlanInfo(planInfo.ObjId, planInfo.ExecuteStatus).Result; if (result) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } #endregion //读取设备进度,完成后再次下发新任务 ReadDeviceComplate_SidePanel(obj_sidePanel); if (!isFlag) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } } }); } catch (Exception ex) { MessageBox.Show($"背板⽣产计划下发异常:{ex.Message}", "提示", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly); } } /// /// 下发背板生产计划 /// /// /// public void SendPlanTaskToBackPanel(SheetMetaSendPlanInfoView planInfo, PlcModel obj_backPanel) { try { Task.Run(() => { if (obj_backPanel != null) { //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021 obj_backPanel.plc.WriteString("D4000", planInfo.TaskCode); string processNumber = GetProcessNumberBy(planInfo.MaterialCode); obj_backPanel.plc.WriteString("D4010", planInfo.MaterialSpecificatons); obj_backPanel.plc.WriteInt32("D4020", planInfo.PlanAmount); obj_backPanel.plc.WriteInt32("D4021", 1); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待背板设备应答。。。。。。"); RefreshExecInfoEvent?.Invoke($"等待背板设备应答。。。。。。"); #region PLC反馈信号逻辑处理 //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中 bool isFlag = true; do { if (obj_backPanel.plc.ReadInt32("D4021") == 2) { obj_backPanel.plc.WriteInt32("D4021", 0); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>收到背板板设备应答信号,复位应答地址"); RefreshExecInfoEvent?.Invoke($"收到背板板设备应答信号,复位应答地址"); isFlag = false; } Thread.Sleep(2000); } while (isFlag); //更新计划状态为2执行中 planInfo.ExecuteStatus = 2; bool result = _executePlanInfoServices.UpdateSheetMetalExecutePlanInfo(planInfo.ObjId, planInfo.ExecuteStatus).Result; if (result) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } #endregion //读取设备进度,完成后再次下发新任务 ReadDeviceComplate_BackPanel(obj_backPanel); if (!isFlag) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } } }); } catch (Exception ex) { MessageBox.Show($"背板⽣产计划下发异常:{ex.Message}", "提示", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly); } } /// /// 根据后板完成记录更新生产计划 /// /// private void UpdateBackPanelPlanTaskByComplate(SheetMetaSendPlanInfoView planInfo) { try { lock (string.Empty) { bool isComplate = true; do { //等待计划执行完成 List sidePanelComplates = _sidePanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planInfo.TaskCode); int sumSidePanelAmount = sidePanelComplates.Sum(x => x.OutPutAmount); List backPanelComplates = _backPanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planInfo.TaskCode); int sumBackPanelAmount = backPanelComplates.Sum(x => x.OutPutAmount); Console.WriteLine($"当前计划:{planInfo.TaskCode};计划产量:{planInfo.PlanAmount};前板完成:{sumSidePanelAmount};背板完成:{sumBackPanelAmount}"); RefreshExecInfoEvent?.Invoke($"当前计划:{planInfo.TaskCode};计划产量:{planInfo.PlanAmount};前板完成:{sumSidePanelAmount};背板完成:{sumBackPanelAmount}"); int sumAmount = 0; if (planInfo.PlanType == 1) { if(planInfo.PlanAmount == sumBackPanelAmount) { if (sumSidePanelAmount<= sumBackPanelAmount) { sumAmount = sumSidePanelAmount; isComplate = false; } else { sumAmount = planInfo.PlanAmount; isComplate = false; } } else { sumAmount = sumSidePanelAmount; } } if (planInfo.PlanType == 3) { sumAmount = sumBackPanelAmount; if (planInfo.PlanAmount - sumAmount == 0) { planInfo.ExecuteStatus = 3; isComplate = false; } planInfo.CompleteAmount = sumAmount; } var obj = _executePlanInfoServices.FirstAsync(d => d.ObjId == planInfo.ObjId).Result; obj.ExecuteStatus = planInfo.ExecuteStatus; if (obj.PlanType==1) { obj.CompleteAmount = sumAmount; } else { obj.CompleteAmount = sumAmount; } bool result = _executePlanInfoServices.UpdateExecutePlanInfo(obj).Result; if (result) { //更新前端展示图表 // RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } Thread.Sleep(5000); } while (isComplate); } } catch (Exception ex) { Console.WriteLine($"计划任务信息更新异常:{ex.Message}"); RefreshExecInfoEvent?.Invoke($"计划任务信息更新异常:{ex.Message}"); } } /// /// 根据前板完成记录更新生产计划 /// /// private void UpdateSidPanelPlanTaskByComplate(SheetMetaSendPlanInfoView planInfo) { try { lock (string.Empty) { bool isComplate = true; do { //等待计划执行完成 List sidePanelComplates = _sidePanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planInfo.TaskCode); int sumSidePanelAmount = sidePanelComplates.Sum(x => x.OutPutAmount); List backPanelComplates = _backPanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planInfo.TaskCode); int sumBackPanelAmount = backPanelComplates.Sum(x => x.OutPutAmount); Console.WriteLine($"当前计划:{planInfo.TaskCode};计划产量:{planInfo.PlanAmount};围板完成:{sumSidePanelAmount};背板完成:{sumBackPanelAmount}"); RefreshExecInfoEvent?.Invoke($"当前计划:{planInfo.TaskCode};计划产量:{planInfo.PlanAmount};围板完成:{sumSidePanelAmount};背板完成:{sumBackPanelAmount}"); int sumAmount = 0; if (planInfo.PlanType == 1) { if (sumSidePanelAmount >= sumBackPanelAmount) { sumAmount = sumBackPanelAmount; } else { sumAmount = sumSidePanelAmount; } } else if (planInfo.PlanType == 2) { sumAmount = sumSidePanelAmount; } else { sumAmount = sumBackPanelAmount; } if (planInfo.PlanAmount - sumAmount == 0) { planInfo.ExecuteStatus = 3; isComplate = false; } planInfo.CompleteAmount = sumAmount; var obj = _executePlanInfoServices.FirstAsync(d => d.ObjId == planInfo.ObjId).Result; obj.CompleteAmount = planInfo.CompleteAmount; obj.ExecuteStatus = planInfo.ExecuteStatus; bool result = _executePlanInfoServices.UpdateExecutePlanInfo(obj).Result; if (result) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } Thread.Sleep(5000); } while (isComplate); } } catch (Exception ex) { Console.WriteLine($"计划任务信息更新异常:{ex.Message}"); RefreshExecInfoEvent?.Invoke($"计划任务信息更新异常:{ex.Message}"); } } #endregion #region 下发单个计划逻辑 /// /// 初始化下发生产计划,获取已拆分的计划进行下发 /// public void InitSendPlan() { Thread.Sleep(5000); var obj_sidePanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("SidePanelPlc")); var obj_backPanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("BackPanelPLC")); while (true) { var planInfos = _executePlanInfoServices.Query(d => d.ProductLineCode.Equals("1001") && d.ExecuteStatus == 1 || d.ExecuteStatus == 2); if (planInfos != null) { if (planInfos.Count > 0) { ExecutePlanInfo planInfo = planInfos.First(); if (planInfo.PlanType == 1) //联合下发 { SendPlanTask(planInfo, obj_sidePanel, obj_backPanel); UpdatePlanTaskByComplate(planInfo); } else if (planInfo.PlanType == 2) { SendPlanTask_SidePanel(planInfo, obj_sidePanel); UpdatePlanTaskByComplate(planInfo); } else if (planInfo.PlanType == 3) { SendPlanTaskTo_BackPanel(planInfo, obj_backPanel); UpdatePlanTaskByComplate(planInfo); } } else { Console.WriteLine("未获取到需要下发的任务"); } } Thread.Sleep(3000); } } /// /// 根据完成记录更新生产计划 /// /// private void UpdatePlanTaskByComplate(ExecutePlanInfo planInfo) { try { lock (string.Empty) { bool isComplate = true; do { //等待计划执行完成 List sidePanelComplates = _sidePanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planInfo.TaskCode); int sumSidePanelAmount = sidePanelComplates.Sum(x => x.OutPutAmount); List backPanelComplates = _backPanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planInfo.TaskCode); int sumBackPanelAmount = backPanelComplates.Sum(x => x.OutPutAmount); Console.WriteLine($"当前计划:{planInfo.TaskCode};计划产量:{planInfo.PlanAmount};围板完成:{sumSidePanelAmount};背板完成:{sumBackPanelAmount}"); RefreshExecInfoEvent?.Invoke($"当前计划:{planInfo.TaskCode};计划产量:{planInfo.PlanAmount};围板完成:{sumSidePanelAmount};背板完成:{sumBackPanelAmount}"); int sumAmount = 0; if (planInfo.PlanType == 1) { if (sumSidePanelAmount >= sumBackPanelAmount) { sumAmount = sumBackPanelAmount; } else { sumAmount = sumSidePanelAmount; } } else if (planInfo.PlanType == 2) { sumAmount = sumSidePanelAmount; } else { sumAmount = sumBackPanelAmount; } if (planInfo.PlanAmount - sumAmount == 0) { planInfo.ExecuteStatus = 3; isComplate = false; } planInfo.CompleteAmount = sumAmount; bool result = _executePlanInfoServices.UpdateExecutePlanInfo(planInfo).Result; if (result) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } Thread.Sleep(5000); } while (isComplate); } } catch (Exception ex) { Console.WriteLine($"计划任务信息更新异常:{ex.Message}"); RefreshExecInfoEvent?.Invoke($"计划任务信息更新异常:{ex.Message}"); } } /// /// 联合下发 /// /// /// /// private void SendPlanTask(ExecutePlanInfo planInfo, PlcModel obj_sidePanel, PlcModel obj_backPanel) { try { //前板 Task.Run(() => { if (obj_sidePanel != null) { //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021 obj_sidePanel.plc.WriteString("D6000", planInfo.TaskCode); string processNumber = GetProcessNumberBy(planInfo.MaterialCode); obj_sidePanel.plc.WriteString("D6010", planInfo.MaterialSpecificatons); obj_sidePanel.plc.WriteInt32("D6020", planInfo.PlanAmount); obj_sidePanel.plc.WriteInt32("D6021", 1); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待围板设备应答。。。。。。"); RefreshExecInfoEvent?.Invoke("等待围板设备应答......"); //下发完成后读取PLC应答,应答后复位应答信号 #region PLC反馈信号逻辑处理 //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中 bool isFlag = true; do { //开始做计划的时候给我 if (obj_sidePanel.plc.ReadInt32("D6021") == 2) { obj_sidePanel.plc.WriteInt32("D6021", 0); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>收到围板设备应答信号,复位应答地址"); RefreshExecInfoEvent?.Invoke("收到围板设备应答信号,复位应答地址"); isFlag = false; } Thread.Sleep(2000); } while (isFlag); //更新计划状态为2执行中 planInfo.ExecuteStatus = 2; bool result = _executePlanInfoServices.UpdateExecutePlanInfo(planInfo).Result; if (result) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } #endregion //读取设备进度,完成后再次下发新任务 ReadDeviceComplate_SidePanel(obj_sidePanel); if (!isFlag) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } } }); //背板 Task.Run(() => { if (obj_backPanel != null) { //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021 obj_backPanel.plc.WriteString("D4000", planInfo.TaskCode); string processNumber = GetProcessNumberBy(planInfo.MaterialCode); obj_backPanel.plc.WriteString("D4010", "BCD/310NF"); obj_backPanel.plc.WriteInt32("D4020", planInfo.PlanAmount); obj_backPanel.plc.WriteInt32("D4021", 1); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待背板设备应答。。。。。。"); RefreshExecInfoEvent?.Invoke($"等待背板设备应答。。。。。。"); #region PLC反馈信号逻辑处理 //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中 bool isFlag = true; do { if (obj_backPanel.plc.ReadInt32("D4021") == 2) { obj_backPanel.plc.WriteInt32("D4021", 0); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>收到背板板设备应答信号,复位应答地址"); RefreshExecInfoEvent?.Invoke("收到背板板设备应答信号,复位应答地址"); isFlag = false; } Thread.Sleep(2000); } while (isFlag); //更新计划状态为2执行中 planInfo.ExecuteStatus = 2; bool result = _executePlanInfoServices.UpdateExecutePlanInfo(planInfo).Result; if (result) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } #endregion //读取设备进度,完成后再次下发新任务 ReadDeviceComplate_BackPanel(obj_backPanel); if (!isFlag) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } } }); } catch (Exception ex) { MessageBox.Show($"围板⽣产计划下发异常:{ex.Message}", "提示", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly); } } /// /// 下发围板生产计划 /// /// /// public void SendPlanTask_SidePanel(ExecutePlanInfo planInfo, PlcModel obj_sidePanel) { try { Task.Run(() => { if (obj_sidePanel != null) { //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021 obj_sidePanel.plc.WriteString("D6000", planInfo.TaskCode); string processNumber = GetProcessNumberBy(planInfo.MaterialCode); obj_sidePanel.plc.WriteString("D6010", planInfo.MaterialSpecificatons); obj_sidePanel.plc.WriteInt32("D6020", planInfo.PlanAmount); obj_sidePanel.plc.WriteInt32("D6021", 1); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待围板设备应答。。。。。。"); RefreshExecInfoEvent?.Invoke("等待围板设备应答......"); //下发完成后读取PLC应答,应答后复位应答信号 #region PLC反馈信号逻辑处理 //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中 bool isFlag = true; do { if (obj_sidePanel.plc.ReadInt32("D6021") == 2) { obj_sidePanel.plc.WriteInt32("D6021", 0); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>收到围板设备应答信号,复位应答地址"); RefreshExecInfoEvent?.Invoke("收到围板设备应答信号......"); isFlag = false; } Thread.Sleep(2000); } while (isFlag); //更新计划状态为2执行中 planInfo.ExecuteStatus = 2; bool result = _executePlanInfoServices.UpdateExecutePlanInfo(planInfo).Result; if (result) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 RefreshCurrentPlanInfoEvent?.Invoke(); } #endregion //读取设备进度,完成后再次下发新任务 ReadDeviceComplate_SidePanel(obj_sidePanel); if (!isFlag) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } } }); } catch (Exception ex) { MessageBox.Show($"围板⽣产计划下发异常:{ex.Message}", "提示", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly); } } /// /// 读取围板生产数据 /// /// public void ReadDeviceComplate_SidePanel(PlcModel obj) { bool isFlag = true; try { do { //D6030 //计划编号:D6030-D6039,物料编号:D6040-D6049,计划完成数:D6050,计划下线数:D6051,设备状态:D6052-D6056,生产节拍:D6057-D6058 byte[] info = obj.plc.Read("D6030", 59); if (info == null) { Thread.Sleep(1000); continue; } //计划编号 string planCode = Encoding.ASCII.GetString(info.Skip(0).Take(20).ToArray()); //物料编号 string materialCode = Encoding.ASCII.GetString(info.Skip(20).Take(20).ToArray()); //完成数量 int complateAmount = short.Parse(bytesToHexStr(info.Skip(40).Take(1).ToArray(), 1), System.Globalization.NumberStyles.HexNumber); //下线数量 int offLineAmount = short.Parse(bytesToHexStr(info.Skip(41).Take(2).ToArray(), 2), System.Globalization.NumberStyles.HexNumber); //设备状态 int deviceStatus = short.Parse(bytesToHexStr(info.Skip(43).Take(2).ToArray(), 2), System.Globalization.NumberStyles.HexNumber); //生产节拍 int productionBeat = short.Parse(bytesToHexStr(info.Skip(51).Take(4).ToArray(), 4), System.Globalization.NumberStyles.HexNumber); Console.WriteLine($"围板设备数据读取====>>>>当前计划:{planCode},物料编号:{materialCode},完成数量:{complateAmount},下线数量:{offLineAmount},设备状态:{deviceStatus},生产节拍:{productionBeat}"); RefreshExecInfoEvent?.Invoke($"围板设备数据读取====>>>>当前计划:{planCode},物料编号:{materialCode},完成数量:{complateAmount},下线数量:{offLineAmount},设备状态:{deviceStatus},生产节拍:{productionBeat}"); //添加完工记录 RecordSidePanelComplate sidePanelComplate = new RecordSidePanelComplate() { ProductlineCode = "1001", PlanCode = planCode.Substring(0, 16), //MaterialCode = string.IsNullOrEmpty(materialCode) ? "" : materialCode, MaterialCode = materialCode.Replace("\0", "").Trim(),//"BCD/310NF", CompleteAmount = complateAmount, OffLineAmount = offLineAmount, DeviceStatus = deviceStatus, ProductionBeat = productionBeat, RecordTime = DateTime.Now, IsFlag = 1 }; if (string.IsNullOrEmpty(planCode)) { Thread.Sleep(5000); continue; } //先查询该计划编号下的前一条完工记录,如果不存在本条记录产量为0 List sidePanelComplates = _sidePanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planCode.Substring(0, 16)); int lastComplateAmount = 0; //前一条完成记录的计划完成数量 int sumComplateAmount = 0; //当前计划总产量 if (sidePanelComplates != null) { if (sidePanelComplates.Count > 0) { sidePanelComplates = sidePanelComplates.OrderByDescending(x => x.RecordTime).ToList(); lastComplateAmount = sidePanelComplates.First().CompleteAmount; sidePanelComplate.OutPutAmount = complateAmount - lastComplateAmount; sumComplateAmount = sidePanelComplates.Sum(x => x.OutPutAmount) + sidePanelComplate.OutPutAmount; if (sidePanelComplate.OutPutAmount == 0) { Thread.Sleep(5000); continue; } else { List planInfos = _executePlanInfoServices.Query(x => x.TaskCode.Equals(planCode.Substring(0, 16)) && x.ExecuteStatus == 2); if (planInfos != null) { if (planInfos.Count > 0) { ExecutePlanInfo planInfo = planInfos.First(); if (planInfo != null) { if (planInfo.PlanAmount - sumComplateAmount == 0) { isFlag = false; Console.WriteLine($"围板计划执行完成,计划数量:{planInfo.PlanAmount};实际产量:{sumComplateAmount};差异值:{planInfo.PlanAmount - sumComplateAmount}"); RefreshExecInfoEvent?.Invoke($"围板计划执行完成,计划数量:{planInfo.PlanAmount};实际产量:{sumComplateAmount};差异值:{planInfo.PlanAmount - sumComplateAmount}"); } } } } } } } _sidePanelComplateServices.InsertSidePanelCimplate(sidePanelComplate); if (complateAmount != lastComplateAmount) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 RefreshCreatePlanInfoEvent?.Invoke(); } Thread.Sleep(5000); } while (isFlag); if (!isFlag) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } } catch (Exception e) { Console.WriteLine($"读取围板设备完成数据异常:{e.Message}"); RefreshExecInfoEvent?.Invoke($"读取围板设备完成数据异常:{e.Message}"); } } /// /// 下发背板生产计划 /// /// /// public void SendPlanTaskTo_BackPanel(ExecutePlanInfo planInfo, PlcModel obj_backPanel) { try { Task.Run(() => { if (obj_backPanel != null) { //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021 obj_backPanel.plc.WriteString("D4000", planInfo.TaskCode); string processNumber = GetProcessNumberBy(planInfo.MaterialCode); obj_backPanel.plc.WriteString("D4010", planInfo.MaterialSpecificatons); obj_backPanel.plc.WriteInt32("D4020", planInfo.PlanAmount); obj_backPanel.plc.WriteInt32("D4021", 1); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待背板设备应答。。。。。。"); RefreshExecInfoEvent?.Invoke($"等待背板设备应答。。。。。。"); #region PLC反馈信号逻辑处理 //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中 bool isFlag = true; do { if (obj_backPanel.plc.ReadInt32("D4021") == 2) { obj_backPanel.plc.WriteInt32("D4021", 0); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>收到背板板设备应答信号,复位应答地址"); RefreshExecInfoEvent?.Invoke($"收到背板板设备应答信号,复位应答地址"); isFlag = false; } Thread.Sleep(2000); } while (isFlag); //更新计划状态为2执行中 planInfo.ExecuteStatus = 2; bool result = _executePlanInfoServices.UpdateExecutePlanInfo(planInfo).Result; if (result) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } #endregion //读取设备进度,完成后再次下发新任务 ReadDeviceComplate_BackPanel(obj_backPanel); if (!isFlag) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } } }); } catch (Exception ex) { MessageBox.Show($"背板⽣产计划下发异常:{ex.Message}", "提示", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly); } } /// /// 读取背板生产数据 /// /// public void ReadDeviceComplate_BackPanel(PlcModel obj) { bool isFlag = true; try { do { //计划编号:D6030-D6039,物料编号:D6040-D6049,计划完成数:D6050,计划下线数:D6051,设备状态:D6052-D6056,生产节拍:D6057-D6058 byte[] info = obj.plc.Read("D4030", 59); if (info == null) { Thread.Sleep(1000); continue; } //计划编号 string planCode = Encoding.ASCII.GetString(info.Skip(0).Take(20).ToArray()).Replace("\0", "").Trim(); //物料编号 string materialCode = Encoding.ASCII.GetString(info.Skip(20).Take(20).ToArray()).Replace("\0", "").Trim(); //完成数量 int complateAmount = short.Parse(bytesToHexStr(info.Skip(40).Take(1).ToArray(), 1), System.Globalization.NumberStyles.HexNumber); //下线数量 int offLineAmount = short.Parse(bytesToHexStr(info.Skip(41).Take(2).ToArray(), 2), System.Globalization.NumberStyles.HexNumber); //设备状态 int deviceStatus = short.Parse(bytesToHexStr(info.Skip(43).Take(2).ToArray(), 2), System.Globalization.NumberStyles.HexNumber); //生产节拍 int productionBeat = short.Parse(bytesToHexStr(info.Skip(51).Take(4).ToArray(), 4), System.Globalization.NumberStyles.HexNumber); Console.WriteLine($"背板设备数据读取====>>>>当前计划:{planCode},物料编号:{materialCode},完成数量:{complateAmount},下线数量:{offLineAmount},设备状态:{deviceStatus},生产节拍:{productionBeat}"); RefreshExecInfoEvent?.Invoke($"当前计划:{planCode},物料编号:{materialCode},完成数量:{complateAmount},下线数量:{offLineAmount},设备状态:{deviceStatus},生产节拍:{productionBeat}"); //添加完工记录 RecordBackPanelComplate backPanelComplate = new RecordBackPanelComplate() { ProductlineCode = "1001", PlanCode = planCode.Substring(0, 16).Replace("\0", "").Trim(), //MaterialCode = string.IsNullOrEmpty(materialCode) ? "" : materialCode, MaterialCode = materialCode.Replace("\0", "").Trim(),//"BCD/310NF", CompleteAmount = complateAmount, OffLineAmount = offLineAmount, DeviceStatus = deviceStatus, ProductionBeat = productionBeat, RecordTime = DateTime.Now, IsFlag = 1 }; if (string.IsNullOrEmpty(planCode)) { Thread.Sleep(5000); continue; } //先查询该计划编号下的前一条完工记录,如果不存在本条记录产量为0 List backPanelComplates = _backPanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planCode.Substring(0, 16)); int lastComplateAmount = 0; //前一条完成记录的计划完成数量 int sumComplateAmount = 0; //当前计划总产量 if (backPanelComplates != null) { if (backPanelComplates.Count > 0) { backPanelComplates = backPanelComplates.OrderByDescending(x => x.RecordTime).ToList(); lastComplateAmount = backPanelComplates.First().CompleteAmount; backPanelComplate.OutPutAmount = complateAmount - lastComplateAmount; sumComplateAmount = backPanelComplates.Sum(x => x.OutPutAmount) + backPanelComplate.OutPutAmount; if (backPanelComplate.OutPutAmount == 0) { Thread.Sleep(5000); continue; } else { List planInfos = _executePlanInfoServices.Query(x => x.TaskCode == planCode.Substring(0, 16) && x.ExecuteStatus == 2); if (planInfos != null) { if (planInfos.Count > 0) { ExecutePlanInfo planInfo = planInfos.First(); if (planInfo != null) { if (planInfo.PlanAmount - sumComplateAmount == 0) { isFlag = false; Console.WriteLine($"背板计划执行完成,计划数量:{planInfo.PlanAmount};实际产量:{sumComplateAmount};差异值:{planInfo.PlanAmount - sumComplateAmount}"); RefreshExecInfoEvent?.Invoke($"背板计划执行完成,计划数量:{planInfo.PlanAmount};实际产量:{sumComplateAmount};差异值:{planInfo.PlanAmount - sumComplateAmount}"); } } } } } } } _backPanelComplateServices.InsertBackPanelCimplate(backPanelComplate); if (complateAmount != lastComplateAmount) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } Thread.Sleep(5000); } while (isFlag); if (!isFlag) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } } catch (Exception e) { Console.WriteLine($"读取背板设备完成数据异常:{e.Message}"); RefreshExecInfoEvent?.Invoke($"背板⽣产计划下发异常:{e.Message}"); } } /// /// 通过物料编号获取工艺编号 /// /// /// private string GetProcessNumberBy(string materialCode) { return System.Guid.NewGuid().ToString("N").Substring(0, 20); } public static string bytesToHexStr(byte[] bytes, int iLen)//e.g. { 0x01, 0x01} ---> " 01 01" { string returnStr = ""; if (bytes != null) { for (int i = 0; i < iLen; i++) { returnStr += bytes[i].ToString("X2"); } } return returnStr; } #endregion }