using Admin.Core.Common; using Admin.Core.IService; using Admin.Core.Model.Model_New; using Admin.Core.Model; using Admin.Core.Model.ViewModels; using System.Text; using Aucma.Core.HwPLc; using log4net; using Aucma.Core.SheetMetalTasks.Models; using StackExchange.Profiling.Internal; namespace Aucma.Core.SheetMetalTasks { /// /// 任务列表 /// public class AucamSheetMetalTaskService : IAucamSheetMetalTaskService { private static readonly log4net.ILog logHelper = LogManager.GetLogger(typeof(AucamSheetMetalTaskService)); #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 RefreshPlanInfo(SheetMetaSendPlanInfoView planInfo); public static event RefreshPlanInfo RefreshPlanInfoEvent; #endregion #region 刷新当前正在执行的计划 /// /// 刷新当前正在执行的计划 /// public delegate void RefreshCurrentPlanInfo(); public static event RefreshCurrentPlanInfo RefreshCurrentPlanInfoEvent; #endregion #region 给设备监控模块显示 /// /// 刷新当前正在执行的计划 /// public delegate void RefreshExecInfo(string message, string color); public static event RefreshExecInfo RefreshExecInfoEvent; #endregion protected readonly IExecutePlanInfoServices? _executePlanInfoServices; protected readonly IRecordSidePanelComplateServices _sidePanelComplateServices; protected readonly IRecordBackPanelComplateServices _backPanelComplateServices; protected readonly IProductPlanInfoServices _productPlanInfoServices; protected readonly ISysUserInfoServices? _sysUserInfoServices; protected readonly IMaterialCompletionServices? _materialCompletionServices; protected readonly ISmSyncModelServices? _smSyncModelServices; public HwPLc.PlcModel obj_backPanel = null; public HwPLc.PlcModel obj_sidePanel = null; bool backFlag = true;//后板标识 bool sideFlag = true;//前板标识 bool statusFlag = true;//计划任务状态标识 bool complatePlanFlag = true;//计划完成 #region 构造函数 /// /// 构造函数 /// /// /// /// /// /// /// public AucamSheetMetalTaskService(IExecutePlanInfoServices executePlanInfoServices, IRecordSidePanelComplateServices recordSidePanelComplateServices, IRecordBackPanelComplateServices recordBackPanelComplateServices, IProductPlanInfoServices productPlanInfoServices, ISysUserInfoServices sysUserInfoServices, IMaterialCompletionServices materialCompletionServices, ISmSyncModelServices smSyncModelServices) { _executePlanInfoServices = executePlanInfoServices; _sidePanelComplateServices = recordSidePanelComplateServices; _backPanelComplateServices = recordBackPanelComplateServices; _productPlanInfoServices = productPlanInfoServices; _sysUserInfoServices = sysUserInfoServices; _materialCompletionServices = materialCompletionServices; _smSyncModelServices = smSyncModelServices; } #endregion #region 启动任务下发 public async Task SendSidePanelPlan() { // await InitSendSidePanelPlan();//前板任务 // 设备状态刷新定时器 System.Timers.Timer timer = new System.Timers.Timer(1000); timer.Elapsed += new System.Timers.ElapsedEventHandler(InitSendSidePanelPlan); timer.AutoReset = true; timer.Enabled = true; timer.Start(); await Task.CompletedTask; } public async Task SendBackPanelPlan() { System.Timers.Timer timer = new System.Timers.Timer(1000); timer.Elapsed += new System.Timers.ElapsedEventHandler(InitSendBackPanelPlan); timer.AutoReset = true; timer.Enabled = true; timer.Start(); await Task.CompletedTask; } public async Task ExecUpdateComplatePlan() { System.Timers.Timer timer = new System.Timers.Timer(1000); timer.Elapsed += new System.Timers.ElapsedEventHandler(UpdateComplatePlan); timer.AutoReset = true; timer.Enabled = true; timer.Start(); await Task.CompletedTask; } public async Task ExecProcessTheEndTask() { // 设备状态刷新定时器 System.Timers.Timer timer = new System.Timers.Timer(1000); timer.Elapsed += new System.Timers.ElapsedEventHandler(ProcessTheEndTask); timer.AutoReset = true; timer.Enabled = true; timer.Start(); await Task.CompletedTask; } public Task SheetMetalTasks() { //Task.Run(async () => //{ // await InitSendSidePanelPlan(); //}); //Task.Run(async () => //{ // await InitSendBackPanelPlan(); //}); //Task.Run(() => //{ // UpdateComplatePlan();//更新计划数 //}); //Task.Run(async () => //{ // await ReadSideBlanking();//获取前板下料 //}); //Task.Run(async () => //{ // await QuerySidePanelMode();//获取前板型号 //}); //Task.Run(async () => //{ // await QueryBackPanelMode();//获取前板型号 //}); //Task.Run(async () => //{ // await ProcessTheEndTask(); //}); return Task.CompletedTask; } #endregion #region 计划下达 #region 下发多个计划同步执行 #region 前板任务 /// /// 初始化下发生产计划,获取已拆分的计划进行下发——前板任务 /// public void InitSendSidePanelPlan(object sender, System.Timers.ElapsedEventArgs e) { var obj_sidePanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("SidePanelPlc")); if (obj_sidePanel == null) return; var obj_backPanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("BackPanelPLC")); if (obj_backPanel == null) return; if (sideFlag) { sideFlag = false; try { List planInfoList = _executePlanInfoServices.QuerySheetMetalSendPlanData("1001").Result; if (planInfoList == null || planInfoList.Count == 0) { Console.WriteLine($"【{DateTime.Now.ToString("HH:m:s")}】===>未获取到需要下发的前板任务"); return; } planInfoList = planInfoList.Where(d => d.PlanAmount > d.SidePanelAmount && (d.ExecuteStatus == 1 || d.ExecuteStatus == 2) && d.PlanType == 2).ToList(); if (planInfoList == null || planInfoList.Count == 0) return; planInfoList = planInfoList.Where(d => d.ExecuteStatus == 1 || d.ExecuteStatus == 2).ToList(); if (planInfoList == null || planInfoList.Count == 0) return; var planInfos = planInfoList.Where(d => d.PlanType == 2).ToList(); if (planInfos != null) { if (planInfos.Count > 0) { //do //{ { SheetMetaSendPlanInfoView planInfo = planInfos.FirstOrDefault(d => d.SidePanelAmount != d.PlanAmount); if (planInfo == null) return; if (planInfo.PlanType == 2)//如果类型为2,前板计划单独下发 { List binList = GetSideBinStatus(obj_sidePanel); SmSyncModel smSyncModel = _smSyncModelServices.FirstAsync(d => d.MaterialSpecifications.Equals(planInfo.MaterialSpecificatons) && d.Category == "0").Result; if (smSyncModel == null) return; Bin bin = binList.SingleOrDefault(d => d.ProductId.Equals(smSyncModel.SmProductId)); if (bin == null) return; SendPlanTaskToSidPanel(planInfo, obj_sidePanel, smSyncModel.SmProductId.ObjToInt()); //UpdateSidPanelPlanTaskByComplate(planInfo); // sideFlag = false; } if (planInfo.PlanType == 1) { //联合下发,检测前后板是否都设置了此型号,如果没有执行下一条任务 List backBinList = GetBackBinStatus(obj_backPanel); List sideBinList = GetSideBinStatus(obj_sidePanel); if (backBinList != null && sideBinList != null) { SmSyncModel smSyncModel = _smSyncModelServices.FirstAsync(d => d.MaterialSpecifications.Equals(planInfo.MaterialSpecificatons) && d.Category == "2").Result; Bin backBin = backBinList.FirstOrDefault(d => d.ProductId.Equals(smSyncModel.SmProductId)); Bin sideBin = sideBinList.FirstOrDefault(d => d.ProductId.Equals(smSyncModel.SmProductId)); if (backBin == null || sideBin == null) { planInfos.Remove(planInfo);//移除list中当前的对象,执行下一个计划 Console.WriteLine($"移除数据:{planInfo.ToJson()}"); //sideFlag = true; } else { SendPlanTaskToSidPanel(planInfo, obj_sidePanel, smSyncModel.SmProductId.ObjToInt()); //UpdateSidPanelPlanTaskByComplate(planInfo); // sideFlag = false; } } } } //} while (true); } else { Console.WriteLine("未获取到需要下发的前板任务"); } } else { Console.WriteLine("未获取到需要下发的前板任务"); } } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { sideFlag = true; } Thread.Sleep(5000); } } #endregion #region 下发前板生产计划 /// /// 下发前板生产计划 /// /// /// public void SendPlanTaskToSidPanel(SheetMetaSendPlanInfoView planInfo, PlcModel obj_sidePanel, int SmProductId) { try { //Task.Run(() => //{ if (obj_sidePanel != null) { //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021 obj_sidePanel.plc.WriteString("D6000", planInfo.TaskCode); obj_sidePanel.plc.WriteInt16("D6022", SmProductId.ToString());//产品号 string processNumber = GetProcessNumberBy(planInfo.MaterialCode); obj_sidePanel.plc.WriteString("D6010", planInfo.MaterialSpecificatons); obj_sidePanel.plc.WriteInt16("D6020", planInfo.PlanAmount.ToString()); Thread.Sleep(500); obj_sidePanel.plc.WriteInt16("D6021", "1"); Console.WriteLine($"【{DateTime.Now.ToString("HH:m:s")}】===>下发机头号为:{planInfo.MaterialSpecificatons}"); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>计划【{planInfo.TaskCode}】已下发,等待前板设备应答......."); RefreshExecInfoEvent?.Invoke($"计划【{planInfo.TaskCode}】已下发,等待前板设备应答.......", "White"); #region PLC反馈信号逻辑处理 //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中 bool isFlag = true; DateTime startTime = DateTime.Now; do { int answer = obj_sidePanel.plc.ReadInt16("D6021"); if (answer == 2) { obj_sidePanel.plc.WriteInt16("D6021", "0"); Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>计划【{planInfo.TaskCode}】,收到前板设备应答信号,复位应答地址"); RefreshExecInfoEvent?.Invoke($"计划【{planInfo.TaskCode}】,收到前板板设备应答信号,复位应答地址", "White"); startTime = DateTime.Now; isFlag = false; } Thread.Sleep(5000); } while (isFlag); //更新计划状态为2执行中 planInfo.ExecuteStatus = 2; bool result = _executePlanInfoServices.UpdateSheetMetalExecutePlanInfo(planInfo.ObjId, planInfo.ExecuteStatus, startTime).Result; if (result) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 RefreshPlanInfoEvent?.Invoke(planInfo);//刷新计划执行 } #endregion //读取设备进度,完成后再次下发新任务 ReadDeviceComplate_SidePanel(obj_sidePanel); } // }); } catch (Exception ex) { RefreshExecInfoEvent?.Invoke($"前板⽣产计划下发异常:{ex.Message}", "Red"); } } #endregion #region 根据前板完成记录更新生产计划 /// /// 根据前板完成记录更新生产计划 /// /// private void UpdateSidPanelPlanTaskByComplate(SheetMetaSendPlanInfoView planInfo) { lock (string.Empty) { bool isComplate = true; do { try { //等待计划执行完成 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}", "White"); int sumAmount = 0; if (planInfo.PlanType == 1) { if (planInfo.PlanAmount == sumSidePanelAmount) { if (sumSidePanelAmount == sumBackPanelAmount && sumSidePanelAmount != 0 && sumBackPanelAmount != 0) { sumAmount = sumSidePanelAmount; planInfo.ExecuteStatus = 3; } if (sumSidePanelAmount < sumBackPanelAmount && sumBackPanelAmount == planInfo.PlanAmount) { sumAmount = sumSidePanelAmount; } if (sumSidePanelAmount > sumBackPanelAmount && sumSidePanelAmount == planInfo.PlanAmount) { sumAmount = sumBackPanelAmount; } if (sumSidePanelAmount == 0 && sumBackPanelAmount == 0) sumAmount = 0; isComplate = false; } else { if (sumSidePanelAmount < sumBackPanelAmount && sumBackPanelAmount == planInfo.PlanAmount) { sumAmount = sumSidePanelAmount; } if (sumSidePanelAmount > sumBackPanelAmount && sumSidePanelAmount == planInfo.PlanAmount) { sumAmount = sumBackPanelAmount; } if (sumSidePanelAmount == 0 && sumBackPanelAmount == 0) sumAmount = 0; } } if (planInfo.PlanType == 2) { sumAmount = sumSidePanelAmount; if (planInfo.PlanAmount - sumAmount == 0) { planInfo.ExecuteStatus = 3; isComplate = false; } planInfo.CompleteAmount = sumAmount; } 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();//刷新图表 RefreshCreatePlanInfoEvent?.Invoke(); } Thread.Sleep(5000); } catch (Exception ex) { Console.WriteLine($"计划任务信息更新异常:{ex.Message}"); RefreshExecInfoEvent?.Invoke($"计划任务信息更新异常:{ex.Message}", "Red"); } } while (isComplate); if (!isComplate) { //更新前端展示图表 //RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 //SheetMetaSendPlanInfoView planInfo = planInfoList.FirstOrDefault(d => d.TaskCode == planCode); RefreshPlanInfoEvent?.Invoke(planInfo);//刷新计划执行 } } } #endregion #region 后板任务 /// /// 初始化下发生产计划,获取已拆分的计划进行下发——后板任务 /// public void InitSendBackPanelPlan(object sender, System.Timers.ElapsedEventArgs e) { var obj_backPanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("BackPanelPLC")); if (obj_backPanel == null) return; var obj_sidePanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("SidePanelPlc")); if (obj_sidePanel == null) return; if (backFlag) { backFlag = false; try { var planInfoList = _executePlanInfoServices.QuerySheetMetalSendPlanData("1001").Result; if (planInfoList == null || planInfoList.Count == 0) { Console.WriteLine("未获取到需要下发的后板任务"); Thread.Sleep(3000); return; } planInfoList = planInfoList.Where(d => d.PlanAmount > d.SidePanelAmount).ToList(); if (planInfoList == null || planInfoList.Count == 0) return; planInfoList = planInfoList.Where(d => d.ExecuteStatus == 1 || d.ExecuteStatus == 2).ToList(); if (planInfoList == null || planInfoList.Count == 0) return; 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) return; if (planInfo.PlanType == 3)//如果为3或者为1 后板计划单独下发 { //获取设置的型号查询对应的型号,下发计划 List binList = GetBackBinStatus(obj_backPanel); SmSyncModel smSyncModel = _smSyncModelServices.FirstAsync(d => d.MaterialSpecifications.Equals(planInfo.MaterialSpecificatons) && d.Category == "1").Result; if (smSyncModel == null) return; Bin bin = binList.FirstOrDefault(d => d.ProductId.Equals(smSyncModel.SmProductId)); if (bin == null) { Console.WriteLine($"未查询到钣金设备对计划!当前计划【{planInfo.TaskCode}】"); // backFlag = true; Thread.Sleep(1000); return; }; SendPlanTaskToBackPanel(planInfo, obj_backPanel, smSyncModel.SmProductId.ObjToInt()); //UpdateBackPanelPlanTaskByComplate(planInfo); //backFlag = false; } if (planInfo.PlanType == 1) { //联合下发,检测前后板是否都有此型号,没有执行下一条任务 List backBinList = GetBackBinStatus(obj_backPanel); List sideBinList = GetSideBinStatus(obj_sidePanel); if (backBinList != null && sideBinList != null) { SmSyncModel smSyncModel = _smSyncModelServices.FirstAsync(d => d.MaterialSpecifications.Equals(planInfo.MaterialSpecificatons) && d.Category == "2").Result; if (smSyncModel == null) { planInfos.Remove(planInfo);//连接计划如果没有查询到,移除当前计划执行下一个计划 Console.WriteLine($"移除数据:{planInfo.ToJson()}"); //backFlag = true; return; } Bin backBin = backBinList.FirstOrDefault(d => d.ProductId.Equals(smSyncModel.SmProductId)); Bin sideBin = sideBinList.FirstOrDefault(d => d.ProductId.Equals(smSyncModel.SmProductId)); if (backBin == null || sideBin == null) { planInfos.Remove(planInfo); Console.WriteLine($"移除数据:{planInfo.ToJson()}"); // backFlag = true; } else { SendPlanTaskToBackPanel(planInfo, obj_backPanel, smSyncModel.SmProductId.ObjToInt()); UpdateBackPanelPlanTaskByComplate(planInfo); // backFlag = false; } } else { // backFlag = false; } } } else { Console.WriteLine("未获取到需要下发的后板任务"); } } else { Console.WriteLine("未获取到需要下发的后板任务"); } Thread.Sleep(3000); } catch (Exception ex) { logHelper.Error(ex.Message); Console.WriteLine(ex.Message); } finally { backFlag = true; } } } #endregion #region 下发背板生产计划 /// /// 下发背板生产计划 /// /// /// public void SendPlanTaskToBackPanel(SheetMetaSendPlanInfoView planInfo, PlcModel obj_backPanel, int productId) { try { //Task.Run(() => //{ if (obj_backPanel != null) { //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021 obj_backPanel.plc.WriteString("D4000", planInfo.TaskCode); obj_backPanel.plc.WriteInt16("D4022", productId.ToString()); string processNumber = GetProcessNumberBy(planInfo.MaterialCode); obj_backPanel.plc.WriteString("D4010", planInfo.MaterialSpecificatons); obj_backPanel.plc.WriteInt16("D4020", planInfo.PlanAmount.ToString()); Thread.Sleep(500); obj_backPanel.plc.WriteInt16("D4021", "1"); Console.WriteLine($"【{DateTime.Now.ToString("HH:m:s")}】===>下发机头号为:{planInfo.MaterialSpecificatons}"); Console.WriteLine($"【{DateTime.Now.ToString("HH:m:s")}】===>计划【{planInfo.TaskCode}】已下发,等待背板设备应答......."); RefreshExecInfoEvent?.Invoke($"计划【{planInfo.TaskCode}】已下发,等待背板设备应答......", "White"); #region PLC反馈信号逻辑处理 //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中 bool isFlag = true; DateTime startTime = DateTime.Now; do { int backPalnelAnswer = obj_backPanel.plc.ReadInt16("D4021"); Console.WriteLine($"【{DateTime.Now.ToString("HH:m:s")}】===>应答信号:{backPalnelAnswer}"); if (backPalnelAnswer == 2) { obj_backPanel.plc.WriteInt16("D4021", "0"); Console.WriteLine($"【{DateTime.Now.ToString("HH:m:s")}】===>收到背板板设备应答信号,复位应答地址"); RefreshExecInfoEvent?.Invoke($"收到背板板设备应答信号,复位应答地址", "White"); startTime = DateTime.Now; isFlag = false; } Thread.Sleep(2000); } while (isFlag); //更新计划状态为2执行中 planInfo.ExecuteStatus = 2; bool result = _executePlanInfoServices.UpdateSheetMetalExecutePlanInfo(planInfo.ObjId, planInfo.ExecuteStatus, startTime).Result; if (result) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshPlanInfoEvent?.Invoke(planInfo); RefreshChatEvent?.Invoke();//刷新图表 } #endregion //读取设备进度,完成后再次下发新任务 ReadDeviceComplate_BackPanel(obj_backPanel); } //}); } catch (Exception ex) { RefreshExecInfoEvent?.Invoke($"背板⽣产计划下发异常:{ex.Message}", "Red"); } } #endregion #region 根据后板完成记录更新生产计划 /// /// 根据后板完成记录更新生产计划 /// 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}", "White"); int sumAmount = 0; if (planInfo.PlanType == 1) { if (planInfo.PlanAmount == sumBackPanelAmount) { if (sumSidePanelAmount == sumBackPanelAmount && sumSidePanelAmount != 0 && sumBackPanelAmount != 0) { sumAmount = sumSidePanelAmount; planInfo.ExecuteStatus = 3; } if (sumSidePanelAmount < sumBackPanelAmount && sumBackPanelAmount == planInfo.PlanAmount) { sumAmount = sumSidePanelAmount; } if (sumSidePanelAmount > sumBackPanelAmount && sumSidePanelAmount == planInfo.PlanAmount) { sumAmount = sumBackPanelAmount; } if (sumSidePanelAmount == 0 && sumBackPanelAmount == 0) sumAmount = 0; isComplate = false; } else { if (sumSidePanelAmount < sumBackPanelAmount && sumBackPanelAmount == planInfo.PlanAmount) { sumAmount = sumSidePanelAmount; } if (sumSidePanelAmount > sumBackPanelAmount && sumSidePanelAmount == planInfo.PlanAmount) { sumAmount = sumBackPanelAmount; } if (sumSidePanelAmount == 0 && sumBackPanelAmount == 0) sumAmount = 0; } } 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; if (obj.PlanType == 1 && planInfo.ExecuteStatus == 3) { obj.CompleteAmount = sumAmount; obj.EndTime = DateTime.Now; } if (obj.PlanType == 3 && planInfo.ExecuteStatus == 3) { obj.ExecuteStatus = 3; obj.EndTime = DateTime.Now; } bool result = _executePlanInfoServices.UpdateExecutePlanInfo(obj).Result; if (result) { RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshPlanInfoEvent?.Invoke(planInfo); RefreshChatEvent?.Invoke();//刷新图表 } Thread.Sleep(5000); } while (isComplate); if (!isComplate) { RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshPlanInfoEvent?.Invoke(planInfo); RefreshChatEvent?.Invoke();//刷新图表 } } } catch (Exception ex) { Console.WriteLine($"计划任务信息更新异常:{ex.Message}"); RefreshExecInfoEvent?.Invoke($"计划任务信息更新异常:{ex.Message}", "Red"); } } #endregion #endregion #region 下发单个计划逻辑 #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); } } #endregion #region 根据完成记录更新生产计划 /// /// 根据完成记录更新生产计划 /// /// 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); if (sidePanelComplates == null || sidePanelComplates.Count == 0) continue; 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}", "White"); 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}", "Red"); } } #endregion #region 联合下发 /// /// 联合下发 /// /// /// /// 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("等待前板设备应答......", "Red"); //下发完成后读取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("收到前板设备应答信号,复位应答地址", "White"); 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($"等待背板设备应答。。。。。。", "White"); #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("收到背板板设备应答信号,复位应答地址", "White"); 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) { Console.WriteLine($"前板⽣产计划下发异常:{ex.Message}"); RefreshExecInfoEvent?.Invoke($"前板⽣产计划下发异常:{ex.Message}", "Red"); } } #endregion #region 下发前板生产计划 /// /// 下发前板生产计划 /// /// /// 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("等待前板设备应答......", "White"); //下发完成后读取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("收到前板设备应答信号......", "White"); 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) { Console.WriteLine($"前板⽣产计划下发异常:{ex.Message}"); RefreshExecInfoEvent?.Invoke($"前板⽣产计划下发异常:{ex.Message}", "Red"); } } #endregion #region 读取前板生产数据 /// /// 读取前板生产数据 /// /// public async void ReadDeviceComplate_SidePanel(PlcModel obj) { bool isFlag = true; do { try { //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()).Replace("\0", "").Trim(); //物料编号 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); if (string.IsNullOrEmpty(planCode)) { Thread.Sleep(5000); continue; } Console.WriteLine($"前板设备数据读取====>>>>当前计划:{planCode},物料编号:{materialCode},完成数量:{complateAmount},下线数量:{offLineAmount},设备状态:{deviceStatus},生产节拍:{productionBeat}"); RefreshExecInfoEvent?.Invoke($"前板设备数据读取====>>>>当前计划:{planCode},物料编号:{materialCode},完成数量:{complateAmount},下线数量:{offLineAmount},设备状态:{deviceStatus},生产节拍:{productionBeat}", "White"); var planInfo = _executePlanInfoServices.FirstAsync(x => x.TaskCode == planCode && x.ExecuteStatus == 2).Result; if (planInfo == null) { Console.WriteLine($"未查询到【{planCode}】运行任务!"); RefreshExecInfoEvent?.Invoke($"未查询到【{planCode}】计划信息!", "Red"); Thread.Sleep(5000); continue; } //添加完工记录 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 }; //先查询该计划编号下的前一条完工记录,如果不存在本条记录产量为0 List sidePanelComplates = _sidePanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planCode.Substring(0, 16)); int lastComplateAmount = 0; //前一条完成记录的计划完成数量 int sumComplateAmount = 0; //当前计划总产量 if (sidePanelComplates != null && sidePanelComplates.Count != 0) { 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 (planInfo.PlanAmount - sumComplateAmount == 0) { isFlag = false; Console.WriteLine($"前板计划执行完成,计划数量:{planInfo.PlanAmount};实际产量:{sumComplateAmount};差异值:{planInfo.PlanAmount - sumComplateAmount}"); RefreshExecInfoEvent?.Invoke($"前板计划执行完成,计划数量:{planInfo.PlanAmount};实际产量:{sumComplateAmount};差异值:{planInfo.PlanAmount - sumComplateAmount}", "White"); planInfo.CompleteAmount = planInfo.PlanAmount; _ = _sidePanelComplateServices.InsertSidePanelCimplate(sidePanelComplate).Result; _ = _executePlanInfoServices.UpdateAsync(planInfo).Result; //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 } else { planInfo.CompleteAmount = sumComplateAmount; var r =await _executePlanInfoServices.UpdateAsync(planInfo); _ = _sidePanelComplateServices.InsertSidePanelCimplate(sidePanelComplate).Result; RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 RefreshCreatePlanInfoEvent?.Invoke(); } } } } } else { //如果没有完成记录插入一条默认完成数量为0 _ = _sidePanelComplateServices.InsertSidePanelCimplate(sidePanelComplate).Result; } // _sidePanelComplateServices.InsertSidePanelCimplate(sidePanelComplate); //if (complateAmount != lastComplateAmount) //{ // //更新前端展示图表 // RefreshCreatePlanInfoEvent?.Invoke();//更新界面 // RefreshChatEvent?.Invoke();//刷新图表 // RefreshCreatePlanInfoEvent?.Invoke(); // var planInfoList = await _executePlanInfoServices.QuerySheetMetalSendPlanData("1001"); // if (planInfoList != null && planInfoList.Count != 0) // { // SheetMetaSendPlanInfoView planInfo = planInfoList.FirstOrDefault(d => d.TaskCode == planCode.Replace("\0", "").Trim()); // RefreshPlanInfoEvent?.Invoke(planInfo);//刷新计划执行 // } //} Thread.Sleep(5000); } catch (Exception e) { Console.WriteLine($"读取前板设备完成数据异常:{e.Message}"); RefreshExecInfoEvent?.Invoke($"读取前板设备完成数据异常:{e.Message}", "Red"); } } while (isFlag); } #endregion #region 下发背板生产计划 /// /// 下发背板生产计划 /// /// /// 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($"等待背板设备应答。。。。。。", "White"); #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($"收到背板板设备应答信号,复位应答地址", "White"); 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) { Console.WriteLine($"读取前板设备完成数据异常:{ex.Message}"); RefreshExecInfoEvent?.Invoke($"背板⽣产计划下发异常:{ex.Message}", "Red"); } } #endregion #region 读取背板生产数据 /// /// 读取背板生产数据 /// /// public void ReadDeviceComplate_BackPanel(PlcModel obj) { bool isFlag = true; try { do { //计划编号:D4030-D4039,物料编号:D4040-D4049,计划完成数:D4050,计划下线数:D4051,设备状态:D4052-D4056,生产节拍:D4057-D4058 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($"【{DateTime.Now.ToString("HH:m:s")}】背板设备数据读取====>>>>当前计划:{planCode},物料编号:{materialCode},完成数量:{complateAmount},下线数量:{offLineAmount},设备状态:{deviceStatus},生产节拍:{productionBeat}"); RefreshExecInfoEvent?.Invoke($"当前计划:{planCode},物料编号:{materialCode},完成数量:{complateAmount},下线数量:{offLineAmount},设备状态:{deviceStatus},生产节拍:{productionBeat}", "White"); if (string.IsNullOrEmpty(planCode)) { Thread.Sleep(5000); continue; } var planInfo = _executePlanInfoServices.FirstAsync(x => x.TaskCode == planCode && x.ExecuteStatus == 2).Result; if (planInfo == null) { Console.WriteLine($"未查询到【{planCode}】运行任务!"); RefreshExecInfoEvent?.Invoke($"未查询到【{planCode}】计划信息!", "White"); Thread.Sleep(5000); continue; } //var planInfoStatus = _executePlanInfoServices.FirstAsync(x => x.TaskCode == planCode && x.ExecuteStatus == 3).Result; //if (planInfoStatus != null) //{ // break; //} //添加完工记录 RecordBackPanelComplate backPanelComplate = new RecordBackPanelComplate() { ProductlineCode = "1001", PlanCode = planCode.Replace("\0", "").Trim(), MaterialCode = string.IsNullOrEmpty(materialCode) ? "" : materialCode.Replace("\0", "").Trim(), //MaterialCode = materialCode.Replace("\0", "").Trim(),//"BCD/310NF", CompleteAmount = complateAmount,//完成数量(计划完成) OffLineAmount = offLineAmount,//下线 DeviceStatus = deviceStatus, ProductionBeat = productionBeat, RecordTime = DateTime.Now, IsFlag = 1 }; //先查询该计划编号下的前一条完工记录,如果不存在任务,默认创建,记录产量为0 List backPanelComplates = _backPanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planCode.Substring(0, 16)); int lastComplateAmount = 0; //前一条完成记录的计划完成数量 int sumComplateAmount = 0; //当前计划总产量 if (backPanelComplates != null && backPanelComplates.Count != 0) { 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 { 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}", "White"); //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 planInfo.CompleteAmount = planInfo.PlanAmount; _backPanelComplateServices.InsertBackPanelCimplate(backPanelComplate); _executePlanInfoServices.UpdateAsync(planInfo); } else { planInfo.CompleteAmount = sumComplateAmount; _executePlanInfoServices.UpdateAsync(planInfo); _backPanelComplateServices.InsertBackPanelCimplate(backPanelComplate); } } } if (complateAmount != lastComplateAmount) { //更新前端展示图表 RefreshCreatePlanInfoEvent?.Invoke();//更新界面 RefreshChatEvent?.Invoke();//刷新图表 } } } else { //如果没有完成记录插入一条默认完成数量为0 _backPanelComplateServices.InsertBackPanelCimplate(backPanelComplate); } Thread.Sleep(5000); } while (isFlag); //if (!isFlag) //{ // //更新前端展示图表 // RefreshCreatePlanInfoEvent?.Invoke();//更新界面 // RefreshChatEvent?.Invoke();//刷新图表 //} } catch (Exception e) { Console.WriteLine($"读取背板设备完成数据异常:{e.Message}"); RefreshExecInfoEvent?.Invoke($"背板⽣产计划下发异常:{e.Message}", "Red"); } } #endregion #region 通过物料编号获取工艺编号 /// /// 通过物料编号获取工艺编号 /// /// /// private string GetProcessNumberBy(string materialCode) { return System.Guid.NewGuid().ToString("N").Substring(0, 20); } #endregion 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 #region 更新计划列表数量 /// /// 更新计划列表数量 /// public void UpdateComplatePlan(object sender, System.Timers.ElapsedEventArgs e) { string stationCode = Appsettings.app("StationInfo", "StationCode"); string productLineCode = Appsettings.app("StationInfo", "ProductLineCode"); if (complatePlanFlag) { List pPlanInfoList = new List(); complatePlanFlag = false; try { var planInfoList = _executePlanInfoServices.QueryAsync(d => d.ProductLineCode.Contains(stationCode) && d.PlanAmount != d.CompleteAmount).Result; if (planInfoList == null || planInfoList.Count == 0) return; var list = from d in planInfoList select new { d.OrderCode, d.CompleteAmount }; var grouplist = (from d in list group d by d.OrderCode into g select new { OrderCode = g.Key, CompleteAmount = g.Sum(d => d.CompleteAmount) }).OrderBy(t => t.OrderCode).ToList(); var productPlanInfoList = _productPlanInfoServices.QueryAsync(d => d.ProductLineCode.Contains(stationCode) && d.CompleteAmount <= d.PlanAmount).Result; productPlanInfoList.ForEach(t => { // var materialCompletionList = _materialCompletionServices.QueryAsync(d => d.ProductLineCode.Contains(productLineCode) && d.StationName.Equals(stationCode)).Result; var obj = grouplist.FirstOrDefault(d => d.OrderCode.Equals(t.OrderCode)); if (obj != null) { if (obj.CompleteAmount == 1 && t.CompleteAmount == 0) { t.EndTime = DateTime.Now; _sysUserInfoServices.UpdateSapPlan(obj.OrderCode);//第一次执行更新日历表 } if (t.PlanAmount == obj.CompleteAmount) { t.CompleteAmount = obj.CompleteAmount; t.EndTime = DateTime.Now; } if (t.PlanAmount > obj.CompleteAmount) { t.CompleteAmount = obj.CompleteAmount; } else { t.CompleteAmount = t.PlanAmount; } } if (pPlanInfoList.Count != 0 && pPlanInfoList != null) { _ = _productPlanInfoServices.UpdateAsync(t).Result; } }); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { complatePlanFlag = true; } } } #endregion #endregion #region 同步钣金设置型号 /// /// 获取所有设置的钣金前板型号 /// /// public async Task QuerySidePanelMode() { while (true) { Thread.Sleep(50000); obj_sidePanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("SidePanelPlc")); if (obj_sidePanel == null) { continue; } if (obj_sidePanel.plc.IsConnected) { Console.WriteLine("===============采集前板开始==============="); RefreshExecInfoEvent?.Invoke($"===============采集前板开始配置开始===============", "White"); byte[] info = obj_sidePanel.plc.Read("D7000", 3000); if (info == null) { Thread.Sleep(1000); continue; } int j = 1; string mode = string.Empty; List addList = new List(); List updateList = new List(); var smSyncModelList = _smSyncModelServices.QueryAsync(d=>d.Category=="0").Result; for (int i = 1; i <= 600; i++) { if (i % 2 == 0) { //设置型号 mode = Encoding.ASCII.GetString(info.Skip(i * 10).Take(10).ToArray()).Replace("\0", "").Trim(); if (smSyncModelList.Count == 0 || smSyncModelList == null) { SmSyncModel sm = new SmSyncModel(); sm.SmProductId = j.ToString(); sm.SmModel = mode.Trim(); sm.SyncTime = DateTime.Now; sm.CreateTime = DateTime.Now; sm.Category = "0"; addList.Add(sm); } else { var obj = smSyncModelList.First(d => d.SmProductId == j.ToString()); if (obj == null) { SmSyncModel sm = new SmSyncModel(); sm.SmProductId = j.ToString(); sm.SmModel = mode.Trim(); sm.SyncTime = DateTime.Now; sm.Category = "0"; addList.Add(sm); } else { if (string.IsNullOrEmpty(obj.SmModel) && string.IsNullOrEmpty(mode)) continue; if (string.IsNullOrEmpty(obj.SmModel) && !string.IsNullOrEmpty(mode)) { obj.SmProductId = j.ToString(); obj.SmModel = mode.Trim(); obj.SyncTime = DateTime.Now; obj.Category = "0"; updateList.Add(obj); } if (!string.IsNullOrEmpty(obj.SmModel) && !string.IsNullOrEmpty(mode) && obj.SmModel!= mode) { obj.SmProductId = j.ToString(); obj.SmModel = mode.Trim(); obj.SyncTime = DateTime.Now; obj.Category = "0"; updateList.Add(obj); } } } j++; } } if (addList != null && addList.Count > 0) await _smSyncModelServices.AddAsync(addList); if (updateList != null&&updateList.Count > 0) await _smSyncModelServices.UpdateAsync(updateList); RefreshExecInfoEvent?.Invoke($"===============采集前板配置结束===============", "White"); Console.WriteLine("===============采集结束==============="); } } } /// /// 获取所有设置的钣金前板型号 /// /// public async Task QueryBackPanelMode() { while (true) { Thread.Sleep(5000); obj_backPanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("BackPanelPLC")); if (obj_backPanel == null) { continue; } if (obj_backPanel.plc.IsConnected) { RefreshExecInfoEvent?.Invoke($"===============采集后板开始配置===============", "White"); Console.WriteLine("===============采集后板开始==============="); byte[] info = obj_backPanel.plc.Read("D7000", 3000); if (info == null) { Thread.Sleep(1000); continue; } int j = 1; string mode = string.Empty; List addList = new List(); List updateList = new List(); var smSyncModelList = _smSyncModelServices.QueryAsync(d=>d.Category=="1").Result; for (int i = 1; i <= 600; i++) { if (i % 2 == 0) { //设置型号 mode = Encoding.ASCII.GetString(info.Skip(i * 10).Take(10).ToArray()).Replace("\0", "").Trim(); if (smSyncModelList.Count == 0 || smSyncModelList == null) { SmSyncModel sm = new SmSyncModel(); sm.SmProductId = j.ToString(); sm.SmModel = mode.Trim(); sm.SyncTime = DateTime.Now; sm.CreateTime = DateTime.Now; sm.Category = "1"; addList.Add(sm); } else { var obj = smSyncModelList.First(d => d.SmProductId == j.ToString()); if (obj == null) { SmSyncModel sm = new SmSyncModel(); sm.SmProductId = j.ToString(); sm.SmModel = mode.Trim(); sm.SyncTime = DateTime.Now; sm.Category = "1"; addList.Add(sm); } else { if (string.IsNullOrEmpty(obj.SmModel) && string.IsNullOrEmpty(mode)) continue; if (string.IsNullOrEmpty(obj.SmModel) && !string.IsNullOrEmpty(mode)) { obj.SmProductId = j.ToString(); obj.SmModel = mode.Trim(); obj.SyncTime = DateTime.Now; obj.Category = "1"; updateList.Add(obj); } if (!string.IsNullOrEmpty(obj.SmModel) && !string.IsNullOrEmpty(mode) && obj.SmModel != mode) { obj.SmProductId = j.ToString(); obj.SmModel = mode.Trim(); obj.SyncTime = DateTime.Now; obj.Category = "1"; updateList.Add(obj); } } } j++; } } if (addList != null && addList.Count > 0) await _smSyncModelServices.AddAsync(addList); if (updateList != null && updateList.Count > 0) await _smSyncModelServices.UpdateAsync(updateList); RefreshExecInfoEvent?.Invoke($"===============采集后板配置结束===============", "White"); Console.WriteLine("===============采集结束==============="); } } } #endregion #region 获取后板设置的型号 /// /// 获取后板设置的型号 /// /// /// public List GetBackBinStatus(PlcModel obj_SidePanel) { List list = new List(); if (!obj_SidePanel.plc.IsConnected) { Console.WriteLine("plc为 false"); return null; } var startb0 = obj_SidePanel.plc.ReadBool("M60"); if (startb0) { string productId = obj_SidePanel.plc.ReadInt16("D2002").ToString();//读取产品编码 Bin bin = new Bin(); bin.ProductId = productId; bin.Status = startb0; list.Add(bin); } var startb2 = obj_SidePanel.plc.ReadBool("M61"); if (startb2) { string productId = obj_SidePanel.plc.ReadInt16("D2026").ToString(); Bin bin = new Bin(); bin.ProductId = productId; bin.Status = startb2; list.Add(bin); } var startb4 = obj_SidePanel.plc.ReadBool("M62"); if (startb4) { string productId = obj_SidePanel.plc.ReadInt16("D2050").ToString(); Bin bin = new Bin(); bin.ProductId = productId; bin.Status = startb4; list.Add(bin); } var startb6 = obj_SidePanel.plc.ReadBool("M63"); if (startb6) { string productId = obj_SidePanel.plc.ReadInt16("D2075").ToString(); Bin bin = new Bin(); bin.ProductId = productId; bin.Status = startb6; list.Add(bin); } var startb7 = obj_SidePanel.plc.ReadBool("M64"); if (startb7) { string productId = obj_SidePanel.plc.ReadInt16("D2098").ToString(); Bin bin = new Bin(); bin.ProductId = productId; bin.Status = startb7; list.Add(bin); } var startb8 = obj_SidePanel.plc.ReadBool("M65"); if (startb8) { string productId = obj_SidePanel.plc.ReadInt16("D2122").ToString(); Bin bin = new Bin(); bin.ProductId = productId; bin.Status = startb8; list.Add(bin); } return list; } #endregion #region 获取前板设置的型号 /// /// 获取前板设置的型号 /// /// /// public List GetSideBinStatus(PlcModel obj_SidePanel) { List list = new List(); var startb0 = obj_SidePanel.plc.ReadBool("M140"); if (startb0) { string productId = obj_SidePanel.plc.ReadInt16("D1402").ToString(); Bin bin = new Bin(); bin.ProductId = productId; bin.Status = startb0; list.Add(bin); } var startb2 = obj_SidePanel.plc.ReadBool("M141"); if (startb2) { string productId = obj_SidePanel.plc.ReadInt16("D1426").ToString(); Bin bin = new Bin(); bin.ProductId = productId; bin.Status = startb0; list.Add(bin); } var startb4 = obj_SidePanel.plc.ReadBool("M142"); if (startb4) { string productId = obj_SidePanel.plc.ReadInt16("D1450").ToString(); Bin bin = new Bin(); bin.ProductId = productId; bin.Status = startb4; list.Add(bin); } var startb6 = obj_SidePanel.plc.ReadBool("M143"); if (startb6) { string productId = obj_SidePanel.plc.ReadInt16("D1474").ToString(); Bin bin = new Bin(); bin.ProductId = productId; bin.Status = startb6; list.Add(bin); } return list; } #endregion #region 前板下线数量 /// /// 前板下线数量 /// public async Task ReadSideBlanking() { while (true) { string stationCode = Appsettings.app("StationInfo", "StationCode"); string productLineCode = Appsettings.app("StationInfo", "ProductLineCode"); Thread.Sleep(5000); obj_sidePanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("SidePanelPlc")); if (obj_sidePanel.plc.IsConnected) { byte[] info = obj_sidePanel.plc.Read("D2100", 20); if (info == null) { Thread.Sleep(1000); continue; } //计划编号 string planCode = Encoding.ASCII.GetString(info.Skip(0).Take(20).ToArray()).Replace("\n", "").Trim(); var offLineAmount = obj_sidePanel.plc.ReadInt16("D6051"); RefreshExecInfoEvent?.Invoke($"下线计划号:{planCode}》》》》下线数量:{offLineAmount}", "White"); Console.WriteLine($"计划号:{planCode}》》》》下线数量:{offLineAmount}"); List sidePanelComplates = _sidePanelComplateServices.Query(x => x.ProductlineCode == stationCode && x.PlanCode == planCode); sidePanelComplates = sidePanelComplates.OrderByDescending(d => d.RecordTime).ToList(); RecordSidePanelComplate recordSidePanelComplate = sidePanelComplates.First(); int sumSidePanelAmount = recordSidePanelComplate.OffLineAmount; if (recordSidePanelComplate.OffLineAmount < offLineAmount) { //更新计划数量 ExecutePlanInfo executePlanInfo = _executePlanInfoServices.FirstAsync(x => x.TaskCode == planCode).Result; var productPlanInfoList = _productPlanInfoServices.FirstAsync(d => d.ProductLineCode.Contains(stationCode) && d.PlanCode.Contains(executePlanInfo.ProductPlanCode)).Result; productPlanInfoList.CompleteAmount = productPlanInfoList.CompleteAmount + (offLineAmount - recordSidePanelComplate.OffLineAmount); await _productPlanInfoServices.UpdateAsync(productPlanInfoList);//更新计划 } } } } #endregion #region 后板下线数量 /// /// 后板下线数量 /// public void ReadBackBlanking() { while (true) { string stationCode = Appsettings.app("StationInfo", "StationCode"); string productLineCode = Appsettings.app("StationInfo", "ProductLineCode"); Thread.Sleep(5000); obj_sidePanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("SidePanelPlc")); if (obj_sidePanel.plc.IsConnected) { byte[] info = obj_sidePanel.plc.Read("D2100", 20); if (info == null) { Thread.Sleep(1000); continue; } //计划编号 string planCode = Encoding.ASCII.GetString(info.Skip(0).Take(20).ToArray()).Replace("\n", "").Trim(); var offLineAmount = obj_sidePanel.plc.ReadInt16("D6051"); RefreshExecInfoEvent?.Invoke($"下线计划号:{planCode}》》》》下线数量:{offLineAmount}", "White"); Console.WriteLine($"计划号:{planCode}》》》》下线数量:{offLineAmount}"); List sidePanelComplates = _sidePanelComplateServices.Query(x => x.ProductlineCode == stationCode && x.PlanCode == planCode); sidePanelComplates = sidePanelComplates.OrderByDescending(d => d.RecordTime).ToList(); RecordSidePanelComplate recordSidePanelComplate = sidePanelComplates.First(); int sumSidePanelAmount = recordSidePanelComplate.OffLineAmount; if (recordSidePanelComplate.OffLineAmount < offLineAmount) { //更新计划数量 ExecutePlanInfo executePlanInfo = _executePlanInfoServices.FirstAsync(x => x.TaskCode == planCode).Result; var productPlanInfoList = _productPlanInfoServices.FirstAsync(d => d.ProductLineCode.Contains(stationCode) && d.PlanCode.Contains(executePlanInfo.ProductPlanCode)).Result; productPlanInfoList.CompleteAmount = productPlanInfoList.CompleteAmount + (offLineAmount - recordSidePanelComplate.OffLineAmount); _ = _productPlanInfoServices.UpdateAsync(productPlanInfoList).Result;//更新计划 } } } } #endregion #region 处理任务未结束情况 /// /// 处理任务未结束情况 public void RefreshStatus(object sender, System.Timers.ElapsedEventArgs e) /// /// public void ProcessTheEndTask(object sender, System.Timers.ElapsedEventArgs e) { if (statusFlag) { statusFlag=false; try { var result = _executePlanInfoServices.QueryAsync(d => d.ExecuteStatus == 2 && d.PlanAmount == d.CompleteAmount).Result; if (result == null || result.Count == 0) return; List list = new List(); foreach (var item in result) { item.ExecuteStatus = 3; list.Add(item); } var back = _executePlanInfoServices.UpdateAsync(list).Result; if (back) { RefreshCurrentPlanInfoEvent?.Invoke();//刷新计划执行 } } catch (Exception ex) { Console.WriteLine( ); logHelper.Error($"更新钣金计划任务状态异常:{ex.Message}"); } finally { statusFlag = true; } } } #endregion } }