#region << 版 本 注 释 >> /*---------------------------------------------------------------- * 命名空间:WIDESEAWCS_Tasks.ConveyorLineJob * 创建者:胡童庆 * 创建时间:2024/8/2 16:13:36 * 版本:V1.0.0 * 描述: * * ---------------------------------------------------------------- * 修改人: * 修改时间: * 版本:V1.0.1 * 修改说明: * *----------------------------------------------------------------*/ #endregion << 版 本 注 释 >> using AutoMapper; using Newtonsoft.Json; using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime; using OfficeOpenXml.FormulaParsing.Excel.Functions.Math; using OfficeOpenXml.FormulaParsing.Excel.Functions.Text; using OfficeOpenXml.Packaging.Ionic.Zip; using Quartz; using SqlSugar; using StackExchange.Profiling.Internal; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Reflection.Metadata; using System.Text; using System.Threading.Tasks; using WIDESEA_Common.Log; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_Communicator; using WIDESEAWCS_Core; using WIDESEAWCS_Core.Helper; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob; using WIDESEAWCS_QuartzJob.DeviceBase; using WIDESEAWCS_QuartzJob.DTO; using WIDESEAWCS_QuartzJob.Models; using WIDESEAWCS_QuartzJob.Service; using WIDESEAWCS_Tasks.ConveyorLineJob; using WIDESEAWCS_Tasks.StackerCraneJob; using static Microsoft.IO.RecyclableMemoryStreamManager; namespace WIDESEAWCS_Tasks { [DisallowConcurrentExecution] public class CommonConveyorLineJob : IJob { private readonly ITaskService _taskService; private readonly ITaskExecuteDetailService _taskExecuteDetailService; private readonly IRouterService _routerService; private readonly IMapper _mapper; public CommonConveyorLineJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, IRouterService routerService, IMapper mapper) { _taskService = taskService; _taskExecuteDetailService = taskExecuteDetailService; _routerService = routerService; _mapper = mapper; } public Task Execute(IJobExecutionContext context) { try { CommonConveyorLine conveyorLine = (CommonConveyorLine)context.JobDetail.JobDataMap.Get("JobParams"); if (conveyorLine != null) { WriteLog.GetLog("Job日志运行").Write(conveyorLine.DeviceCode + "运行日志,开始时间" + DateTime.Now, "Job日志运行"); if (conveyorLine.DeviceCode == "1002") { RequestInbound(conveyorLine); //一楼C,B区业务 } if (conveyorLine.DeviceCode == "1003") { RequestInbound2(conveyorLine); } if (conveyorLine.DeviceCode == "1004") { RequestInbound3(conveyorLine); //一楼C,B区业务 } } WriteLog.GetLog("Job日志运行").Write(conveyorLine.DeviceCode + "运行日志,结束时间" + DateTime.Now, "Job日志运行"); //RequestInNextAddress(conveyorLine); } catch (Exception ex) { //Console.Out.WriteLine(nameof(CommonConveyorLineJob) + ":" + ex.ToString()); } finally { //Console.Out.WriteLine(DateTime.Now); } return Task.CompletedTask; } public void RequestInbound(CommonConveyorLine conveyorLine) { //1楼输送线判断 HandleEvent2(conveyorLine, "PLC_WCS_B._03_PLC_EVENT", "PLC_WCS_B._03_PLC_LPN", "WCS_PLC_B._03_WCS_TO"); //判断巷道 HandleEvent2(conveyorLine, "PLC_WCS_C._02_PLC_EVENT", "PLC_WCS_C._02_PLC_LPN", "WCS_PLC_C._02_WCS_TO"); //判断巷道 CheckForEmptyPallet(conveyorLine, "PLC_WCS_B._02_PLC_EVENT", "PLC_WCS_B._02_PLC_LPN", "PLC_WCS_B._02_PLC_PUT", "R02-002-027-001-01"); //判断是否取空托出库 CheckForEmptyPallet(conveyorLine, "PLC_WCS_C._01_PLC_EVENT", "PLC_WCS_C._01_PLC_LPN", "PLC_WCS_C._01_PLC_PUT", "R01-002-041-001-01"); //判断是否取空托出库 ProcessConveyorEvent(conveyorLine, "PLC_WCS_B._01_PLC_EVENT", "PLC_WCS_B._01_PLC_LPN", "R02-003-027-001-01", "WCS_PLC_B._03_WCS_TO");// 处理 B ProcessConveyorEvent(conveyorLine, "PLC_WCS_C._03_PLC_EVENT", "PLC_WCS_C._03_PLC_LPN", "R01-003-041-001-01", "WCS_PLC_C._02_WCS_TO");// 处理 C } public void RequestInbound2(CommonConveyorLine conveyorLine) { //顶楼楼输送线判断 ProcessConveyorEvent(conveyorLine, "PLC_WCS_D._01_PLC_EVENT", "PLC_WCS_D._01_PLC_LPN", "R01-003-041-011-01", "WCS_PLC_D._01_WCS_TO");// 处理 1巷道 站台事件入空 ProcessConveyorEvent(conveyorLine, "PLC_WCS_D._03_PLC_EVENT", "PLC_WCS_D._03_PLC_LPN", "R02-003-027-011-01", "WCS_PLC_D._03_WCS_TO");// 处理 2巷道 站台事件 入空 //ConveyorLineInFinish(conveyorLine, "R02-002-027-011-01"); //写入输送线去向 //CheckForEmptyPallet2(conveyorLine, "PLC_WCS_D._02_PLC_EVENT", "PLC_WCS_D._02_PLC_LPN", "PLC_WCS_D._02_PLC_PUT", "R02-002-027-011-01"); //原材料出库 读取条码选库区出库 //CheckForEmptyPallet2(conveyorLine, "PLC_WCS_D._04_PLC_EVENT", "PLC_WCS_D._04_PLC_LPN", "PLC_WCS_D._04_PLC_PUT", "R01-002-041-011-01"); //原材料出库 读取条码选库区出库 } public void RequestInbound3(CommonConveyorLine conveyorLine) { ProcessConveyorEvent(conveyorLine, "PLC_WCS_A._02_PLC_EVENT", "PLC_WCS_A._02_PLC_LPN", "R01-002-043-001-01", "WCS_PLC_A._02_WCS_TO");// 处理 A21 站台事件入库 ProcessConveyorEvent(conveyorLine, "PLC_WCS_A._03_PLC_EVENT", "PLC_WCS_A._03_PLC_LPN", "R01-002-042-001-01", "WCS_PLC_A._03_WCS_TO");// 处理 A22 站台事件 入料 } public void ConveyorLineInFinish(CommonConveyorLine conveyorLine, string SCAddress) { DeviceProDTO? deviceProDTO2 = GetDeviceProDTO(conveyorLine, SCAddress, "R_StackerCraneLowered"); //读取输送线 “堆垛机放下” 信号 if (deviceProDTO2 != null) { byte strsd = GetLine(conveyorLine, deviceProDTO2.DeviceChildCode); if (strsd == 1) { Dt_Task task = _taskService.IngStackerCraneTask2(conveyorLine.DeviceCode); if (task != null && task.TaskType == (int)TaskOutboundTypeEnum.Outbound) { byte PLCtypeTo = 1; if (task.TargetAddress == "R02-002-027-011-01") { PLCtypeTo = 2; } DeviceProDTO? deviceProDTO3 = GetDeviceProDTO(conveyorLine, SCAddress, "W_PalletBarcode"); //写入条码 DeviceProDTO? deviceProDTO4 = GetDeviceProDTO(conveyorLine, SCAddress, "W_PalletLayers"); //层数 DeviceProDTO? deviceProDTO5 = GetDeviceProDTO(conveyorLine, SCAddress, "W_PalletType"); //类型 DeviceProDTO? deviceProDTO6 = GetDeviceProDTO(conveyorLine, SCAddress, "W_Destination"); //类型 if (deviceProDTO3 != null && deviceProDTO4 != null && deviceProDTO5 != null && deviceProDTO6 != null) { if (SetLinestring(conveyorLine, deviceProDTO3.DeviceProDataBlock, task.PalletCode) && SetLine(conveyorLine, deviceProDTO4.DeviceProDataBlock, (byte)task.PalletCodequantity) && SetLine(conveyorLine, deviceProDTO5.DeviceProDataBlock, PLCtypeTo) && SetLine(conveyorLine, deviceProDTO6.DeviceProDataBlock, (byte)task.PLCTo)) { LogSignalStatus($"写入放货完成信息,托盘条码,层数,类型信息成功", deviceProDTO2.DeviceChildCode); } else { LogSignalStatus($"写入放货完成信息,托盘条码,层数,类型信息失败", deviceProDTO2.DeviceChildCode); } } else { LogSignalStatus($"未找到输送线协议信息", task.TargetAddress); } } } } } //获取输送线实例 public DeviceProDTO? GetDeviceProDTO(CommonConveyorLine conveyorLine, string SCAddress, string Interactivet) { return conveyorLine.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == SCAddress && x.DeviceProParamName == Interactivet); } /// /// 用于入库判断巷道 /// /// /// /// /// private void HandleEvent(CommonConveyorLine conveyorLine, string eventTag, string barcodeTag, string writeTag) { try { byte events = conveyorLine.Communicator.Read(eventTag); // 读取事件 if (events == 1) { string barcode = conveyorLine.Communicator.Read(barcodeTag); // 读取条码 if (barcode != "1" || barcode != "0") { if ((_taskService.ToPlatform(barcode)).Status) { if (conveyorLine.Communicator.Read("PLC_WCS_B._01_PLC_LPN") == "") { // 写入去向2号堆垛机 bool result = conveyorLine.Communicator.Write(writeTag, (byte)3); //原材料去向 if (result) { WriteLog.GetLog("PLC日志").Write("写入去向:3", "去向"); } } } } if (barcode == "1") { // 写入去向2号堆垛机 bool result = conveyorLine.Communicator.Write(writeTag, (byte)1); //空托去向 if (result) { WriteLog.GetLog("PLC日志").Write("空托入库,写入去向:1", "去向"); } } /*else { // 写入去向1号堆垛机 bool result = conveyorLine.Communicator.Write(writeTag, (byte)1); if (result) { WriteLog.GetLog("PLC日志").Write("写入去向:2", "去向"); } WriteLog.GetLog("PLC日志").Write("入库失败", "入库组盘"); }*/ } } catch (Exception ex) { throw; } } //新的巷道判断 private void HandleEvent2(CommonConveyorLine conveyorLine, string eventTag, string barcodeTag, string writeTag) { byte events = conveyorLine.Communicator.Read(eventTag); // 读取事件 if (events == 1) { string barcode = conveyorLine.Communicator.Read(barcodeTag).Trim(); // 读取条码 if (barcode != "1" || barcode != "0") { WebResponseContent content = _taskService.ToPlatform(barcode); if (content != null) { if (content.Status) { if (content.Data != null) { if (content.Data.ToString() == "1") { if (conveyorLine.Communicator.Read("PLC_WCS_C._03_PLC_LPN") == "") { // 写入去向2号堆垛机 bool result = conveyorLine.Communicator.Write(writeTag, (byte)1); //写入去向为长巷道 if (result) { WriteLog.GetLog("PLC日志").Write($"条码{barcode},写入去向:1", "去向"); } } } else if (content.Data.ToString() == "3") { if (conveyorLine.Communicator.Read("PLC_WCS_B._01_PLC_LPN") == "") { // 写入去向2号堆垛机 bool result = conveyorLine.Communicator.Write(writeTag, (byte)3); //写入去向为短巷道 if (result) { WriteLog.GetLog("PLC日志").Write($"条码{barcode},写入去向:3", "去向"); } } } } } else { WriteLog.GetLog("PLC日志").Write($"失败信息:{content.Message}", "去向失败信息"); } } } else if (barcode == "1") { bool result = conveyorLine.Communicator.Write(writeTag, (byte)1); //空托去向 if (result) { WriteLog.GetLog("PLC日志").Write("空托入库,写入去向:1", "去向"); } } } } //用于判断是否补空托 A区 private void CheckForEmptyPallet(CommonConveyorLine conveyorLine, string eventTag, string barcodeTag, string plcput, string Loc) { try { Byte events = conveyorLine.Communicator.Read(eventTag); // 读取事件 if (events == 1) //1为空,0为有 { string barcode = conveyorLine.Communicator.Read(barcodeTag); // 读取条码 if (barcode == "") { WriteLog.GetLog("PLC日志出库日志").Write($"读取到出库口补空托信号:{events}", "需要空托"); // 生成堆垛机取空托任务 byte plcputts = conveyorLine.Communicator.Read(plcput); if (plcputts != 1) { if ((_taskService.RequestWMSTask2("", Loc)).Status) { WriteLog.GetLog("PLC日志出库日志").Write($"已生成空托出库任务:{events}", "需要空托"); } else { WriteLog.GetLog("PLC日志出库日志").Write($"未生成空托出库任务:{events}", "需要空托"); } } } } } catch (Exception ex) { throw; } } //用于判断是否出空托 D区 private void CheckForEmptyPallet2(CommonConveyorLine conveyorLine, string eventTag, string barcodeTag, string plcput, string Loc) { Byte events = conveyorLine.Communicator.Read(eventTag); // 读取事件 if (events == 1) //1为空,0为有 { string barcode = conveyorLine.Communicator.Read(barcodeTag); // 读取条码 if (barcode != "1" || barcode != "0") { WriteLog.GetLog("PLC日志出库日志").Write($"读取到原材料出库信息,条码信息:{barcode}", "原材料出库"); byte outCount = conveyorLine.Communicator.Read(plcput); if ((_taskService.RequestWMSTask3(barcode, outCount, Loc)).Status) { //写入输送线清除信息 WriteLog.GetLog("PLC日志出库日志").Write($"已生成原材料出库任务,条码信息:{barcode}", "原材料出库"); } else { WriteLog.GetLog("PLC日志出库日志").Write($"未生成原材料出库任务,条码信息:{barcode}", "原材料出库"); } } } } //用于判断入库站台 private void ProcessConveyorEvent(CommonConveyorLine conveyorLine, string eventTag, string barcodeTag, string taskCode, string writeTag) { byte eventStatus = conveyorLine.Communicator.Read(eventTag); if (eventStatus == 1) { WriteLog.GetLog("PLC入库站台日志").Write($"读取到输送线申请入库信息EVENT为:{eventStatus},站台编号为:{taskCode}", "站台信息"); string barcode = conveyorLine.Communicator.Read(barcodeTag).Trim(); /*if(barcode == "1") { string currentTime = DateTime.Now.ToString("HHmmss"); barcode = "KTP" + currentTime; }*/ if (barcode != null) { bool result = conveyorLine.Communicator.Write(writeTag, (byte)0); /*if(taskCode== "R01-003-042-001-01") { if ((_taskService.ToPlatform(barcode)).Status) { WriteLog.GetLog("PLC入库站台日志").Write($"组盘成功,站台编号为:{taskCode}", "站台信息"); } }*/ // 拿取托盘条码申请入库信息 WebResponseContent content = _taskService.RequestWMSTask(barcode, taskCode); // 申请入库,生成堆垛机任务 if (content != null) { if (content.Status) { WriteLog.GetLog("PLC入库站台日志").Write($"申请入库成功,站台编号为:{taskCode}", "站台信息"); } else { WriteLog.GetLog("PLC入库站台日志").Write($"申请入库失败,站台编号为:{taskCode}", "站台信息"); } } } else { WriteLog.GetLog("PLC入库站台日志").Write($"读取到输送线信息为空,站台编号为:{taskCode}", "站台信息"); } } else if (eventStatus == 6) { if (taskCode == "R02-003-027-011-01") { WebResponseContent content = _taskService.RequestWMSTask4(); if (content != null) { if (content.Status) { if (content.Data != null) { if (content.Data.ToString() == "1") { if (conveyorLine.Communicator.Read("PLC_WCS_D._01_PLC_LPN") == "") { if (conveyorLine.Communicator.Write(writeTag, (byte)1)) { WriteLog.GetLog("PLC入库站台日志").Write($"写入成功,去向:1,站台编号为:{taskCode}", "空托入库去向"); } else { WriteLog.GetLog("PLC入库站台日志").Write($"写入失败,去向:1,站台编号为:{taskCode}", "空托入库去向"); } } } else if (content.Data.ToString() == "3") { if (conveyorLine.Communicator.Read("PLC_WCS_D._03_PLC_LPN") == "") { if (conveyorLine.Communicator.Write(writeTag, (byte)3)) { WriteLog.GetLog("PLC入库站台日志").Write($"写入成功,去向:3,站台编号为:{taskCode}", "空托入库去向"); } else { WriteLog.GetLog("PLC入库站台日志").Write($"写入失败,去向:3,站台编号为:{taskCode}", "空托入库去向"); } } } } } } } else if (taskCode == "R01-003-041-011-01") { if (conveyorLine.Communicator.Read("PLC_WCS_D._03_PLC_LPN") == "") { if (conveyorLine.Communicator.Write(writeTag, (byte)1)) { WriteLog.GetLog("PLC入库站台日志").Write($"写入成功,去向:1,站台编号为:{taskCode}", "空托入库去向"); } else { WriteLog.GetLog("PLC入库站台日志").Write($"写入失败,去向:1,站台编号为:{taskCode}", "空托入库去向"); } } } } } public bool SetLine(CommonConveyorLine conveyorLine, string DeviceProDataBlock, byte Pali) { return conveyorLine.Communicator.Write(DeviceProDataBlock, Pali); } public bool SetLinestring(CommonConveyorLine conveyorLine, string DeviceProDataBlock, string Pali) { return conveyorLine.Communicator.Write(DeviceProDataBlock, Pali); } public byte GetLine(CommonConveyorLine conveyorLine, string DeviceProDataBlock) { return conveyorLine.Communicator.Read(DeviceProDataBlock); } private void LogSignalStatus(string message, string sourceAddress) { WriteLog.GetLog("堆垛机与plc交互信号").Write($"站台编号:{sourceAddress},信息:{message}", $"{sourceAddress}"); } } }