using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Threading; using System.Windows; using System.Windows.Documents; using Admin.Core.Common; using Admin.Core.IService; using Admin.Core.Model; using Aucma.Core.HwPLc; using Microsoft.Extensions.DependencyInjection; namespace Aucma.Core.SheetMetal.Business; /// /// 箱壳计划任务处理 /// public class SheetMetalPlanTaskHandle { /// /// 刷新当前正在执行的计划 /// public delegate void RefreshCurrentPlanInfo(ExecutePlanInfo planInfo); public event RefreshCurrentPlanInfo RefreshCurrentPlanInfoEvent; protected readonly IExecutePlanInfoServices? _executePlanInfoServices; protected readonly IRecordSidePanelComplateServices _sidePanelComplateServices; public HwPLc.PlcModel plc1 = null; public SheetMetalPlanTaskHandle() { _executePlanInfoServices = App.ServiceProvider.GetService(); _sidePanelComplateServices = App.ServiceProvider.GetService(); } /// /// 下发围板生产计划 /// /// /// public void SendPlanTask_WB(ExecutePlanInfo planInfo, PlcModel obj) { Thread.Sleep(5000); try { lock (string.Empty) { if (obj != null) { //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021 obj.plc.WriteString("D6000", planInfo.TaskCode); string processNumber = GetProcessNumberBy(planInfo.MaterialCode); obj.plc.WriteString("D6010", "BCD/310NF"); obj.plc.WriteInt32("D6020", planInfo.PlanAmount); obj.plc.WriteInt32("D6021", 1); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待围板设备应答。。。。。。"); //下发完成后读取PLC应答,应答后复位应答信号 #region PLC反馈信号逻辑处理 //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中 bool isFlag = true; do { if (obj.plc.ReadInt32("D6021") == 2) { obj.plc.WriteInt32("D6021", 0); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>收到围板设备应答信号,复位应答地址"); isFlag = false; } Thread.Sleep(2000); } while (isFlag); //更新计划状态为2执行中 planInfo.ExecuteStatus = 2; //SheetMetalPlanTaskHandle handle = new SheetMetalPlanTaskHandle(); //plc1 = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("OldMelsecPlc1")); //handle.SendPlanTask_WB(list, plc1); _executePlanInfoServices.UpdateExecutePlanInfo(planInfo); RefreshCurrentPlanInfoEvent?.Invoke(planInfo); #endregion //读取设备进度,完成后再次下发新任务 ReadDeviceComplate_WB(obj); } } } catch (Exception ex) { MessageBox.Show($"围板⽣产计划下发异常:{ex.Message}", "提示", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly); } } /// /// 读取围板生产数据 /// /// public void ReadDeviceComplate_WB(PlcModel obj) { bool isFlag = true; try { do { //计划编号:D6030-D6039,物料编号:D6040-D6049,计划完成数:D6050,计划下线数:D6051,设备状态:D6052-D6056,生产节拍:D6057-D6058 byte[] info = obj.plc.Read("D6030", 59); //计划编号 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}"); //添加完工记录 RecordSidePanelComplate sidePanelComplate = new RecordSidePanelComplate() { ProductlineCode = "1001", PlanCode = planCode, MaterialCode = materialCode, CompleteAmount = complateAmount, OffLineAmount = offLineAmount, DeviceStatus = deviceStatus, ProductionBeat = productionBeat, RecordTime = DateTime.Now }; //先查询该计划编号下的前一条完工记录,如果不存在本条记录产量为0 List sidePanelComplates = _sidePanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planCode); 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 { if (sumComplateAmount > 0) { ExecutePlanInfo planInfo = _executePlanInfoServices.Query(x => x.TaskCode.Equals(planCode.Substring(0, 13)) && x.ExecuteStatus == 2).FirstOrDefault(); if (planInfo != null) { if (sumComplateAmount > planInfo.CompleteAmount) { if (planInfo.PlanAmount - sumComplateAmount == 0) { Console.WriteLine($"计划:{planCode},执行完成!!!"); planInfo.CompleteAmount = sumComplateAmount; planInfo.ExecuteStatus = 3; _executePlanInfoServices.UpdateExecutePlanInfo(planInfo); isFlag = false; } else { Console.WriteLine( $"设备当前计划:{planCode},计划数量:{planInfo.PlanAmount},实际完成:{sumComplateAmount},差异:{planInfo.PlanAmount - sumComplateAmount}"); planInfo.CompleteAmount = sumComplateAmount; _executePlanInfoServices.UpdateExecutePlanInfo(planInfo); } RefreshCurrentPlanInfoEvent?.Invoke(planInfo); } } } } } } _sidePanelComplateServices.InsertSidePanelCimplate(sidePanelComplate); Thread.Sleep(5000); } while (isFlag); } catch (Exception e) { Console.WriteLine($"读取设备完成数据异常:{e.Message}"); } } /// /// 下发背板生产计划 /// /// /// public void SendPlanTaskTo_BB(ExecutePlanInfo planInfo, PlcModel obj) { Thread.Sleep(5000); try { lock (string.Empty) { if (obj != null) { //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021 obj.plc.WriteString("D6000", planInfo.TaskCode); string processNumber = GetProcessNumberBy(planInfo.MaterialCode); obj.plc.WriteString("D6010", "BCD/310NF"); obj.plc.WriteInt32("D6020", planInfo.PlanAmount); obj.plc.WriteInt32("D6021", 1); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待背板设备应答。。。。。。"); #region PLC反馈信号逻辑处理 //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中 bool isFlag = true; do { if (obj.plc.ReadInt32("D6021") == 2) { obj.plc.WriteInt32("D6021", 0); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>收到背板板设备应答信号,复位应答地址"); isFlag = false; } Thread.Sleep(2000); } while (isFlag); //更新计划状态为2执行中 planInfo.ExecuteStatus = 2; _executePlanInfoServices.UpdateExecutePlanInfo(planInfo); RefreshCurrentPlanInfoEvent?.Invoke(planInfo); #endregion //读取设备进度,完成后再次下发新任务 ReadDeviceComplate_BB(obj); } else { return; } } } catch (Exception ex) { MessageBox.Show($"背板⽣产计划下发异常:{ex.Message}", "提示", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly); } } /// /// 读取背板生产数据 /// /// public void ReadDeviceComplate_BB(PlcModel obj) { bool isFlag = true; try { do { //计划编号:D6030-D6039,物料编号:D6040-D6049,计划完成数:D6050,计划下线数:D6051,设备状态:D6052-D6056,生产节拍:D6057-D6058 byte[] info = obj.plc.Read("D6030", 59); //计划编号 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}"); //添加完工记录 RecordSidePanelComplate sidePanelComplate = new RecordSidePanelComplate() { ProductlineCode = "1002", PlanCode = planCode, MaterialCode = materialCode, CompleteAmount = complateAmount, OffLineAmount = offLineAmount, DeviceStatus = deviceStatus, ProductionBeat = productionBeat, RecordTime = DateTime.Now }; //先查询该计划编号下的前一条完工记录,如果不存在本条记录产量为0 List sidePanelComplates = _sidePanelComplateServices.Query(x => x.ProductlineCode == "1002" && x.PlanCode == planCode); 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 { if (sumComplateAmount > 0) { ExecutePlanInfo planInfo = _executePlanInfoServices.Query(x=>x.TaskCode.Equals(planCode.Substring(0,13)) && x.ExecuteStatus == 2).FirstOrDefault(); if (planInfo != null) { if (sumComplateAmount > planInfo.CompleteAmount) { if (planInfo.PlanAmount - sumComplateAmount == 0) { Console.WriteLine($"计划:{planCode},执行完成!!!"); planInfo.CompleteAmount = sumComplateAmount; planInfo.ExecuteStatus = 3; _executePlanInfoServices.UpdateExecutePlanInfo(planInfo); isFlag = false; } else { Console.WriteLine( $"设备当前计划:{planCode},计划数量:{planInfo.PlanAmount},实际完成:{sumComplateAmount},差异:{planInfo.PlanAmount - sumComplateAmount}"); planInfo.CompleteAmount = sumComplateAmount; _executePlanInfoServices.UpdateExecutePlanInfo(planInfo); } RefreshCurrentPlanInfoEvent?.Invoke(planInfo); } } } } } } _sidePanelComplateServices.InsertSidePanelCimplate(sidePanelComplate); Thread.Sleep(5000); } while (isFlag); } catch (Exception e) { Console.WriteLine($"读取设备完成数据异常:{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; } }