diff --git a/Aucma.Core.SheetMetal/Business/SheetMetalPlanTaskHandle.cs b/Aucma.Core.SheetMetal/Business/SheetMetalPlanTaskHandle.cs
new file mode 100644
index 00000000..8dfa5764
--- /dev/null
+++ b/Aucma.Core.SheetMetal/Business/SheetMetalPlanTaskHandle.cs
@@ -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;
+
+///
+/// 箱壳计划任务处理
+///
+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") == 2)
+ {
+ 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;
+ }
+}
\ No newline at end of file
diff --git a/Aucma.Core.SheetMetal/ViewModels/IndexPageViewModel.cs b/Aucma.Core.SheetMetal/ViewModels/IndexPageViewModel.cs
index 352e36bf..d52e6e64 100644
--- a/Aucma.Core.SheetMetal/ViewModels/IndexPageViewModel.cs
+++ b/Aucma.Core.SheetMetal/ViewModels/IndexPageViewModel.cs
@@ -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 list = new List() { 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();
StationName = Appsettings.app("StoreInfo", "StationName");
Job_SheetMetalTask_Quartz.SmEverDayDelegateEvent += InitEveryDayMethod;
@@ -610,5 +620,18 @@ namespace Aucma.Core.SheetMetal.ViewModels
return model;
}
#endregion
+
+ ///
+ /// 刷新当前执行的计划进度
+ ///
+ ///
+ private void RefreshCurrentPlanInfo(ExecutePlanInfo planInfo)
+ {
+ App.Current.Dispatcher.BeginInvoke((Action)(() =>
+ {
+ PlanInfoDataGrid.Clear();
+ LoadData();
+ }));
+ }
}
}
diff --git a/Aucma.Core.SheetMetal/appsettings.json b/Aucma.Core.SheetMetal/appsettings.json
index 1c94b625..98ad211f 100644
--- a/Aucma.Core.SheetMetal/appsettings.json
+++ b/Aucma.Core.SheetMetal/appsettings.json
@@ -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
}
]
}