add-钣金业务

dev
liuwf 1 year ago
parent d3f652c485
commit 5bd3129b45

@ -0,0 +1,226 @@
using System;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
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;
/// <summary>
/// 箱壳计划任务处理
/// </summary>
public class SheetMetalPlanTaskHandle
{
/// <summary>
/// 刷新当前正在执行的计划
/// </summary>
public delegate void RefreshCurrentPlanInfo(ExecutePlanInfo planInfo);
public event RefreshCurrentPlanInfo RefreshCurrentPlanInfoEvent;
protected readonly IExecutePlanInfoServices? _executePlanInfoServices;
public SheetMetalPlanTaskHandle()
{
_executePlanInfoServices =
App.ServiceProvider.GetService<IExecutePlanInfoServices>();
}
/// <summary>
/// 箱壳计划任务下发⾄设备PLC
/// </summary>
/// <returns></returns>
public void SendPlanTaskToDevice()
{
Thread.Sleep(5000);
try
{
lock (string.Empty)
{
string stationCode = Appsettings.app("StoreInfo", "StationCode");
//获取待执⾏的计划,根据计划序号进⾏排序依次下发
var list = _executePlanInfoServices.Query(d =>
d.ProductLineCode.Equals(stationCode) && d.ExecuteStatus == 1);
if (list != null)
{
if (list.Count > 0)
{
ExecutePlanInfo task = list.OrderBy(x => x.ExecuteOrder).First();
var obj = PlcHelper.melsecList.FirstOrDefault(d =>
d.EquipName.Equals("OldTypePlc1"));
if (obj != null)
{
//计划编号10个字D6000-D6009、物料编号10个字D6010-D6019、计划数量1个字D6020、应答字1个字D6021
obj.plc.WriteString("D6000", task.TaskCode);
string processNumber = GetProcessNumberBy(task.MaterialCode);
obj.plc.WriteString("D6010", "BCD/310NF");
obj.plc.WriteInt32("D6020", task.PlanAmount);
obj.plc.WriteInt32("D6021", 1);
Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待设备应答。。。。。。");
//下发完成后读取PLC应答应答后复位应答信号
ReadPlcFeedBack(obj);
//更新计划状态为2执行中
task.ExecuteStatus = 2;
_executePlanInfoServices.UpdateExecutePlanInfo(task);
RefreshCurrentPlanInfoEvent?.Invoke(task);
//读取设备进度,完成后再次下发新任务
ReadDeviceComplate(obj);
}
}
else
{
Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>未获取到需要下发的生产计划!");
}
}
}
}
catch (Exception ex)
{
MessageBox.Show($"箱壳⽣产计划下发异常:{ex.Message}", "提示", MessageBoxButton.OK, MessageBoxImage.Error,
MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly);
}
}
/// <summary>
/// 读取PLC应答反馈PLC反馈后复位应答地址
/// </summary>
private void ReadPlcFeedBack(PlcModel obj)
{
bool isFlag = true;
if (obj != null)
{
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);
}
}
/// <summary>
/// 读取设备完成数据
/// </summary>
/// <param name="obj"></param>
public void ReadDeviceComplate(PlcModel obj)
{
bool isFlag = true;
try
{
if (obj != null)
{
do
{
//计划编号D6030-D6039物料编号D6040-D6049计划完成数D6050计划下线数D6051设备状态D6052-D6056,生产节拍D6057-D6058
#region 单个地址读取
/*
string planCode = obj.plc.ReadString("D6030");
string materialCode = obj.plc.ReadString("D6040");
int complateAmount = obj.plc.ReadInt32("D6050");
int offLineAmount = obj.plc.ReadInt32("D6051");
int productionBeat = obj.plc.ReadInt32("D6057");
*/
#endregion
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}");
//更新执行计划差异值为0后任务结束再次下发新任务
ExecutePlanInfo planInfo = _executePlanInfoServices.Query(x=>x.TaskCode.Equals(planCode.Substring(0,13)) && x.ExecuteStatus == 2).FirstOrDefault();
if (planInfo != null)
{
if (complateAmount > planInfo.CompleteAmount)
{
if (planInfo.PlanAmount - complateAmount == 0)
{
Console.WriteLine($"计划:{planCode},执行完成!!!");
planInfo.CompleteAmount = complateAmount;
planInfo.ExecuteStatus = 3;
_executePlanInfoServices.UpdateExecutePlanInfo(planInfo);
isFlag = false;
}
else
{
Console.WriteLine(
$"设备当前计划:{planCode},计划数量:{planInfo.PlanAmount},实际完成:{complateAmount},差异:{planInfo.PlanAmount - complateAmount}");
planInfo.CompleteAmount = complateAmount;
_executePlanInfoServices.UpdateExecutePlanInfo(planInfo);
}
RefreshCurrentPlanInfoEvent?.Invoke(planInfo);
}
}
Thread.Sleep(5000);
} while (isFlag);
}
}
catch (Exception e)
{
Console.WriteLine($"读取设备完成数据异常:{e.Message}");
}
}
/// <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;
}
}

@ -20,6 +20,9 @@ using System.Windows.Media;
using log4net;
using Admin.Core.Common;
using LiveCharts.Defaults;
using Aucma.Core.SheetMetal.Business;
using static Aucma.Core.SheetMetal.Business.SheetMetalPlanTaskHandle;
using System.Threading;
/*
*
*
@ -29,6 +32,7 @@ namespace Aucma.Core.SheetMetal.ViewModels
public partial class IndexPageViewModel : ObservableObject
{
protected readonly IExecutePlanInfoServices? _taskExecutionPlanInfoServices;
private SheetMetalPlanTaskHandle _taskHandle = new SheetMetalPlanTaskHandle();
private AppConfigHelper appConfig = new AppConfigHelper();
List<SelectModel> list = new List<SelectModel>() { new SelectModel()
@ -46,6 +50,12 @@ namespace Aucma.Core.SheetMetal.ViewModels
#region 构造函数
public IndexPageViewModel()
{
_taskHandle.RefreshCurrentPlanInfoEvent += RefreshCurrentPlanInfo;
Task.Run(() =>
{
Thread.Sleep(5000);
_taskHandle.SendPlanTaskToDevice();
});
_taskExecutionPlanInfoServices = App.ServiceProvider.GetService<IExecutePlanInfoServices>();
StationName = Appsettings.app("StoreInfo", "StationName");
Job_SheetMetalTask_Quartz.SmEverDayDelegateEvent += InitEveryDayMethod;
@ -610,5 +620,18 @@ namespace Aucma.Core.SheetMetal.ViewModels
return model;
}
#endregion
/// <summary>
/// 刷新当前执行的计划进度
/// </summary>
/// <param name="planInfo"></param>
private void RefreshCurrentPlanInfo(ExecutePlanInfo planInfo)
{
App.Current.Dispatcher.BeginInvoke((Action)(() =>
{
PlanInfoDataGrid.Clear();
LoadData();
}));
}
}
}

@ -124,15 +124,19 @@
"PLCServer": [
{
"Id": 1,
"EquipName": "FrontPlatePlc",
"EquipName": "OldTypePlc1",
"PlcType": "Melsec",
"Enabled": true,
"IP": "10.10.91.1",
"Port": 6000
"Port": 5552
},
{
"Id": 2,
"Id": 1,
"EquipName": "RearPanelPLC",
"IP": "10.10.91.12",
"Port": 6000
"PlcType": "Siemens",
"Enabled": true,
"IP": "10.10.93.41",
"Port": 102
}
]
}

Loading…
Cancel
Save