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

226 lines
9.0 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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") == 1)
{
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;
}
}