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; /// /// 箱壳计划任务处理 /// public class SheetMetalPlanTaskHandle { /// /// 刷新当前正在执行的计划 /// public delegate void RefreshCurrentPlanInfo(ExecutePlanInfo planInfo); public event RefreshCurrentPlanInfo RefreshCurrentPlanInfoEvent; protected readonly IExecutePlanInfoServices? _executePlanInfoServices; public SheetMetalPlanTaskHandle() { _executePlanInfoServices = App.ServiceProvider.GetService(); } /// /// 箱壳计划任务下发⾄设备PLC /// /// 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); } } /// /// 读取PLC应答反馈,PLC反馈后复位应答地址 /// 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); } } /// /// 读取设备完成数据 /// /// 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}"); } } /// /// 通过物料编号获取工艺编号 /// /// /// 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; } }