You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AUCMA_SCADA/Aucma.Core.SheetMetal/Business/SheetMetalPlanTaskHandle.cs

607 lines
26 KiB
C#

using System;
1 year ago
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
1 year ago
using System.Windows.Documents;
using Admin.Core.Common;
using Admin.Core.IService;
using Admin.Core.Model;
using Aucma.Core.HwPLc;
using Microsoft.Extensions.DependencyInjection;
using NetTaste;
namespace Aucma.Core.SheetMetal.Business;
/// <summary>
/// 箱壳计划任务处理
/// </summary>
public class SheetMetalPlanTaskHandle
{
/// <summary>
/// 刷新当前正在执行的计划
/// </summary>
public delegate void RefreshCurrentPlanInfo(ExecutePlanInfo planInfo);
public event RefreshCurrentPlanInfo RefreshCurrentPlanInfoEvent;
protected readonly IExecutePlanInfoServices? _executePlanInfoServices;
1 year ago
protected readonly IRecordSidePanelComplateServices _sidePanelComplateServices;
protected readonly IRecordBackPanelComplateServices _backPanelComplateServices;
1 year ago
public HwPLc.PlcModel plc1 = null;
public SheetMetalPlanTaskHandle()
{
_executePlanInfoServices =
App.ServiceProvider.GetService<IExecutePlanInfoServices>();
1 year ago
_sidePanelComplateServices = App.ServiceProvider.GetService<IRecordSidePanelComplateServices>();
_backPanelComplateServices = App.ServiceProvider.GetService<IRecordBackPanelComplateServices>();
}
/// <summary>
/// 初始化下发生产计划,获取已拆分的计划进行下发
/// </summary>
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);
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);
}
}
/// <summary>
/// 根据完成记录更新生产计划
/// </summary>
/// <param name="planInfo"></param>
private void UpdatePlanTaskByComplate(ExecutePlanInfo planInfo)
{
try
{
lock (string.Empty)
{
bool isComplate = true;
do
{
//等待计划执行完成
List<RecordSidePanelComplate> sidePanelComplates = _sidePanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planInfo.TaskCode);
int sumSidePanelAmount = sidePanelComplates.Sum(x => x.OutPutAmount);
List<RecordBackPanelComplate> 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}");
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;
_executePlanInfoServices.UpdateExecutePlanInfo(planInfo);
Thread.Sleep(5000);
} while (isComplate);
}
}catch(Exception ex)
{
Console.WriteLine($"计划任务信息更新异常:{ex.Message}");
}
}
/// <summary>
/// 联合下发
/// </summary>
/// <param name="planInfo"></param>
/// <param name="obj_sidePanel"></param>
/// <param name="obj_backPanel"></param>
private void SendPlanTask(ExecutePlanInfo planInfo, PlcModel obj_sidePanel,PlcModel obj_backPanel)
{
try
{
Task.Run(() =>
{
if (obj_sidePanel != null)
{
1 year ago
//计划编号10个字D6000-D6009、物料编号10个字D6010-D6019、计划数量1个字D6020、应答字1个字D6021
obj_sidePanel.plc.WriteString("D6000", planInfo.TaskCode);
1 year ago
string processNumber = GetProcessNumberBy(planInfo.MaterialCode);
obj_sidePanel.plc.WriteString("D6010", "BCD/310NF");
obj_sidePanel.plc.WriteInt32("D6020", planInfo.PlanAmount);
obj_sidePanel.plc.WriteInt32("D6021", 1);
1 year ago
Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待围板设备应答。。。。。。");
//下发完成后读取PLC应答应答后复位应答信号
1 year ago
#region PLC反馈信号逻辑处理
//循环读取PLC应答信号PLC应答后复位应答信号、更新计划状态为执行中
bool isFlag = true;
do
{
if (obj_sidePanel.plc.ReadInt32("D6021") == 2)
{
obj_sidePanel.plc.WriteInt32("D6021", 0);
1 year ago
Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>收到围板设备应答信号,复位应答地址");
isFlag = false;
}
1 year ago
Thread.Sleep(2000);
} while (isFlag);
1 year ago
//更新计划状态为2执行中
planInfo.ExecuteStatus = 2;
_executePlanInfoServices.UpdateExecutePlanInfo(planInfo);
RefreshCurrentPlanInfoEvent?.Invoke(planInfo);
#endregion
//读取设备进度,完成后再次下发新任务
ReadDeviceComplate_SidePanel(obj_sidePanel);
}
});
Task.Run(() =>
{
if (obj_backPanel != null)
{
//计划编号10个字D6000-D6009、物料编号10个字D6010-D6019、计划数量1个字D6020、应答字1个字D6021
obj_backPanel.plc.WriteString("D6000", planInfo.TaskCode);
string processNumber = GetProcessNumberBy(planInfo.MaterialCode);
obj_backPanel.plc.WriteString("D6010", "BCD/310NF");
obj_backPanel.plc.WriteInt32("D6020", planInfo.PlanAmount);
obj_backPanel.plc.WriteInt32("D6021", 1);
Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待背板设备应答。。。。。。");
#region PLC反馈信号逻辑处理
//循环读取PLC应答信号PLC应答后复位应答信号、更新计划状态为执行中
bool isFlag = true;
do
{
if (obj_backPanel.plc.ReadInt32("D6021") == 2)
{
obj_backPanel.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_BackPanel(obj_backPanel);
}
});
}
catch (Exception ex)
{
MessageBox.Show($"围板⽣产计划下发异常:{ex.Message}", "提示", MessageBoxButton.OK, MessageBoxImage.Error,
MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly);
}
}
/// <summary>
/// 下发围板生产计划
/// </summary>
/// <param name="planInfo"></param>
/// <param name="obj"></param>
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", "BCD/310NF");
obj_sidePanel.plc.WriteInt32("D6020", planInfo.PlanAmount);
obj_sidePanel.plc.WriteInt32("D6021", 1);
1 year ago
Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待围板设备应答。。。。。。");
//下发完成后读取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")}===>收到围板设备应答信号,复位应答地址");
isFlag = false;
}
Thread.Sleep(2000);
} while (isFlag);
//更新计划状态为2执行中
planInfo.ExecuteStatus = 2;
_executePlanInfoServices.UpdateExecutePlanInfo(planInfo);
RefreshCurrentPlanInfoEvent?.Invoke(planInfo);
1 year ago
#endregion
//读取设备进度,完成后再次下发新任务
ReadDeviceComplate_SidePanel(obj_sidePanel);
1 year ago
}
});
}
catch (Exception ex)
{
1 year ago
MessageBox.Show($"围板⽣产计划下发异常:{ex.Message}", "提示", MessageBoxButton.OK, MessageBoxImage.Error,
MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly);
}
}
1 year ago
/// <summary>
1 year ago
/// 读取围板生产数据
/// </summary>
1 year ago
/// <param name="obj"></param>
public void ReadDeviceComplate_SidePanel(PlcModel obj)
{
bool isFlag = true;
1 year ago
try
{
do
{
1 year ago
//D6030
1 year ago
//计划编号D6030-D6039物料编号D6040-D6049计划完成数D6050计划下线数D6051设备状态D6052-D6056,生产节拍D6057-D6058
byte[] info = obj.plc.Read("D6030", 59);
if(info == null)
{
Thread.Sleep(1000);
continue;
}
1 year ago
//计划编号
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}");
1 year ago
//添加完工记录
RecordSidePanelComplate sidePanelComplate = new RecordSidePanelComplate()
{
ProductlineCode = "1001",
PlanCode = planCode.Substring(0, 13),
//MaterialCode = string.IsNullOrEmpty(materialCode) ? "" : materialCode,
MaterialCode = "BCD/310NF",
1 year ago
CompleteAmount = complateAmount,
OffLineAmount = offLineAmount,
DeviceStatus = deviceStatus,
ProductionBeat = productionBeat,
RecordTime = DateTime.Now,
IsFlag = 1
1 year ago
};
if(string.IsNullOrEmpty(planCode))
{
Thread.Sleep(5000);
continue;
}
1 year ago
//先查询该计划编号下的前一条完工记录如果不存在本条记录产量为0
List<RecordSidePanelComplate> sidePanelComplates = _sidePanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planCode.Substring(0, 13));
1 year ago
int lastComplateAmount = 0; //前一条完成记录的计划完成数量
int sumComplateAmount = 0; //当前计划总产量
if (sidePanelComplates != null)
{
1 year ago
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;
1 year ago
if (sidePanelComplate.OutPutAmount == 0)
{
Thread.Sleep(5000);
continue;
}
else
{
List<ExecutePlanInfo> planInfos = _executePlanInfoServices.Query(x => x.TaskCode == planCode.Substring(0, 13) && x.ExecuteStatus == 2);
if(planInfos != null)
1 year ago
{
if(planInfos.Count > 0)
1 year ago
{
ExecutePlanInfo planInfo = planInfos.First();
if (planInfo != null)
1 year ago
{
if (planInfo.PlanAmount - sumComplateAmount == 0)
{
isFlag = false;
Console.WriteLine($"围板计划执行完成,计划数量:{planInfo.PlanAmount};实际产量:{sumComplateAmount};差异值:{planInfo.PlanAmount - sumComplateAmount}");
1 year ago
}
}
}
1 year ago
}
}
}
}
1 year ago
_sidePanelComplateServices.InsertSidePanelCimplate(sidePanelComplate);
Thread.Sleep(5000);
} while (isFlag);
}
1 year ago
catch (Exception e)
{
Console.WriteLine($"读取围板设备完成数据异常:{e.Message}");
1 year ago
}
}
1 year ago
/// <summary>
1 year ago
/// 下发背板生产计划
/// </summary>
1 year ago
/// <param name="planInfo"></param>
/// <param name="obj"></param>
public void SendPlanTaskTo_BackPanel(ExecutePlanInfo planInfo, PlcModel obj_backPanel)
{
try
{
Task.Run(() =>
{
if (obj_backPanel != null)
{
1 year ago
//计划编号10个字D6000-D6009、物料编号10个字D6010-D6019、计划数量1个字D6020、应答字1个字D6021
obj_backPanel.plc.WriteString("D6000", planInfo.TaskCode);
1 year ago
string processNumber = GetProcessNumberBy(planInfo.MaterialCode);
obj_backPanel.plc.WriteString("D6010", "BCD/310NF");
obj_backPanel.plc.WriteInt32("D6020", planInfo.PlanAmount);
obj_backPanel.plc.WriteInt32("D6021", 1);
1 year ago
Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待背板设备应答。。。。。。");
1 year ago
#region PLC反馈信号逻辑处理
//循环读取PLC应答信号PLC应答后复位应答信号、更新计划状态为执行中
bool isFlag = true;
do
{
if (obj_backPanel.plc.ReadInt32("D6021") == 2)
1 year ago
{
obj_backPanel.plc.WriteInt32("D6021", 0);
1 year ago
Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>收到背板板设备应答信号,复位应答地址");
isFlag = false;
}
Thread.Sleep(2000);
} while (isFlag);
1 year ago
//更新计划状态为2执行中
planInfo.ExecuteStatus = 2;
_executePlanInfoServices.UpdateExecutePlanInfo(planInfo);
RefreshCurrentPlanInfoEvent?.Invoke(planInfo);
#endregion
1 year ago
//读取设备进度,完成后再次下发新任务
ReadDeviceComplate_BackPanel(obj_backPanel);
1 year ago
}
});
1 year ago
}
catch (Exception ex)
{
MessageBox.Show($"背板⽣产计划下发异常:{ex.Message}", "提示", MessageBoxButton.OK, MessageBoxImage.Error,
MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly);
}
}
/// <summary>
/// 读取背板生产数据
/// </summary>
/// <param name="obj"></param>
public void ReadDeviceComplate_BackPanel(PlcModel obj)
1 year ago
{
bool isFlag = true;
try
{
do
{
//计划编号D6030-D6039物料编号D6040-D6049计划完成数D6050计划下线数D6051设备状态D6052-D6056,生产节拍D6057-D6058
byte[] info = obj.plc.Read("D6030", 59);
if (info == null)
1 year ago
{
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}");
//添加完工记录
RecordBackPanelComplate backPanelComplate = new RecordBackPanelComplate()
{
ProductlineCode = "1001",
PlanCode = planCode.Substring(0, 13),
//MaterialCode = string.IsNullOrEmpty(materialCode) ? "" : materialCode,
MaterialCode = "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<RecordBackPanelComplate> backPanelComplates = _backPanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planCode.Substring(0, 13));
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<ExecutePlanInfo> planInfos = _executePlanInfoServices.Query(x => x.TaskCode == planCode.Substring(0, 13) && x.ExecuteStatus == 2);
if (planInfos != null)
{
if(planInfos.Count > 0)
1 year ago
{
ExecutePlanInfo planInfo = planInfos.First();
1 year ago
if (planInfo != null)
{
if (planInfo.PlanAmount - sumComplateAmount == 0)
1 year ago
{
isFlag = false;
Console.WriteLine($"背板计划执行完成,计划数量:{planInfo.PlanAmount};实际产量:{sumComplateAmount};差异值:{planInfo.PlanAmount - sumComplateAmount}");
1 year ago
}
}
}
}
}
}
}
_backPanelComplateServices.InsertBackPanelCimplate(backPanelComplate);
Thread.Sleep(5000);
} while (isFlag);
}
catch (Exception e)
{
Console.WriteLine($"读取背板设备完成数据异常:{e.Message}");
}
}
1 year ago
/// <summary>
/// 通过物料编号获取工艺编号
/// </summary>
/// <param name="materialCode"></param>
/// <returns></returns>
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;
}
}