using Autofac.Core; using Microsoft.AspNetCore.Components.Routing; using Microsoft.AspNetCore.Hosting; using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup; using Quartz; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Eventing.Reader; using System.Linq; using System.Reflection.Metadata; using System.Text; using System.Threading.Tasks; using WIDESEA_Common.Log; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_Core; using WIDESEAWCS_Core.Enums; using WIDESEAWCS_ISystemServices; using WIDESEAWCS_ITaskInfoRepository; 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_QuartzJob.StackerCrane.Enum; using WIDESEAWCS_Tasks.StackerCraneJob; namespace WIDESEAWCS_Tasks { [DisallowConcurrentExecution] public class CommonStackerCraneJob : IJob { private readonly ITaskService _taskService; private readonly ITaskExecuteDetailService _taskExecuteDetailService; private readonly ITaskRepository _taskRepository; private readonly IRouterService _routerService; private readonly IPlatformStationService _PlatformStationService; public CommonStackerCraneJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IPlatformStationService platformStation) { _taskService = taskService; _taskExecuteDetailService = taskExecuteDetailService; _taskRepository = taskRepository; _routerService = routerService; _PlatformStationService= platformStation; } public Task Execute(IJobExecutionContext context) { try { CommonStackerCrane commonStackerCrane = (CommonStackerCrane)context.JobDetail.JobDataMap.Get("JobParams"); if (commonStackerCrane != null) { if (!commonStackerCrane.IsEventSubscribed) { commonStackerCrane.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler;//订阅任务完成事件 } if (commonStackerCrane.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && commonStackerCrane.StackerCraneStatusValue == StackerCraneStatus.Normal) { commonStackerCrane.CheckStackerCraneTaskCompleted();//防止任务完成事件监测超时,再手动触发一次 if (commonStackerCrane.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby) { Dt_Task? task = GetTask(commonStackerCrane); if (task != null) { StackerCraneTaskCommand? stackerCraneTaskCommand = ConvertToStackerCraneTaskCommand(task); if (stackerCraneTaskCommand != null) { bool sendFlag = commonStackerCrane.SendCommand(stackerCraneTaskCommand); if (sendFlag) { _taskService.UpdateTaskStatusToNext(task.TaskNum); } } } } } } } catch (Exception ex) { //Console.WriteLine(nameof(CommonStackerCraneJob) + ":" + ex.ToString()); } return Task.CompletedTask; } /// /// 任务完成事件订阅的方法 /// /// /// private void CommonStackerCrane_StackerCraneTaskCompletedEventHandler(object? sender, WIDESEAWCS_QuartzJob.StackerCrane.StackerCraneTaskCompletedEventArgs e) { CommonStackerCrane? commonStackerCrane = sender as CommonStackerCrane; if (commonStackerCrane != null) { if (commonStackerCrane.GetValue(StackerCraneDBName.WorkType) != 5) { _taskService.StackCraneTaskCompleted(e.TaskNum); commonStackerCrane.SetValue(StackerCraneDBName.WorkType, 5); } } } /// /// 获取任务 /// /// 堆垛机对象 /// private Dt_Task? GetTask(CommonStackerCrane commonStackerCrane) { Dt_Task task; task = _taskService.QueryStackerCraneTask(commonStackerCrane.DeviceCode); if (task != null && task.TaskType== (int)TaskOutboundTypeEnum.Outbound) { string[] targetCodes = task.SourceAddress.Split("-"); if (targetCodes[4] == "02") { Dt_Task taskst = OutTaskMovelibrary(task); if (taskst != null) { if(taskst.TaskType == (int)TaskRelocationTypeEnum.Relocation) { return taskst; } else { if(taskst.TargetAddress== "R02-001-021-001-02" || taskst.TargetAddress == "R02-001-022-001-02") { return taskst; } else { if (OutTaskStationIsOccupied(taskst) != null) { return taskst; } } } } task = _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode); } else { if (OutTaskStationIsOccupied(task) != null) { return task; } task = _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode); } } return task; } /// /// 出库任务判断出库站台是否被占用 /// /// 任务实体 /// 如果未被占用,返回传入的任务信息,否则,返回null private Dt_Task? OutTaskStationIsOccupied([NotNull] Dt_Task task) { if(task.TaskType == (int)TaskOutboundTypeEnum.Outbound) { string plcAddress = _PlatformStationService.GetOutSCName(task.Roadway,task.Station_storey); IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == "1002"); if (device != null) { CommonConveyorLine conveyorLine = (CommonConveyorLine)device; DeviceProDTO? deviceProDTO = GetDeviceProDTO(conveyorLine, plcAddress, "Free"); if (deviceProDTO != null) { bool B_Event_Test = GetLine(conveyorLine, deviceProDTO.DeviceProAddress); //判断输送线是否允许放货信号 if (B_Event_Test) { return task; } } } else { _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到出库站台【{task.SourceAddress}】对应的通讯对象,无法判断出库站台是否被占用"); } } return null; } /// /// 出库任务判断是否需要进行移库Move the library /// /// 任务实体 /// 如果未被占用,返回传入的任务信息,否则,返回null private Dt_Task? OutTaskMovelibrary([NotNull] Dt_Task task) { try { string[] targetCodes = task.SourceAddress.Split("-"); if (targetCodes[1] == "001") { targetCodes[1] = "002"; } else if (targetCodes[1] == "004") { targetCodes[1] = "003"; } targetCodes[4] = "01"; string SourceAddress = string.Join("-", targetCodes); //组装浅库位地址 Dt_Task? tasks = _taskService.QueryStationIsOccupiedOutTasks(task.Roadway, SourceAddress).FirstOrDefault(); //找浅库位是否有任务 if (tasks != null) { return tasks; } else { //向wms申请判断浅库位是否有货,是否需要进行移库 Dt_Task? taskst = _taskService.RequestWMSTaskMovelibrary(task); if (taskst != null) { return taskst; } } } catch (Exception ex) { throw; } return null; } /// /// 任务实体转换成命令Model /// /// 任务实体 /// /// public StackerCraneTaskCommand? ConvertToStackerCraneTaskCommand([NotNull] Dt_Task task) { StackerCraneTaskCommand stackerCraneTaskCommand = new StackerCraneTaskCommand(); stackerCraneTaskCommand.Barcode = ""; /*task.PalletCode;*/ stackerCraneTaskCommand.TaskNum = task.TaskNum; stackerCraneTaskCommand.WorkType = 1; stackerCraneTaskCommand.TrayType = (short)task.PalletCodequantity; //待改动 if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup)//判断是否是入库任务 { string[] targetCodest = task.SourceAddress.Split("-"); if (targetCodest.Length == 5) { stackerCraneTaskCommand.StartRow = Convert.ToInt16(targetCodest[1]); stackerCraneTaskCommand.StartColumn = Convert.ToInt16(targetCodest[2]); stackerCraneTaskCommand.StartLayer = Convert.ToInt16(targetCodest[3]); } else { //数据配置错误 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"入库起点错误,起点:【{task.SourceAddress}】"); return null; } string[] targetCodes = task.TargetAddress.Split("-"); if (targetCodes.Length == 5) { stackerCraneTaskCommand.EndRow = Convert.ToInt16(targetCodes[1]); stackerCraneTaskCommand.EndColumn = Convert.ToInt16(targetCodes[2]); stackerCraneTaskCommand.EndLayer = Convert.ToInt16(targetCodes[3]); } else { //数据配置错误 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"入库任务终点错误,起点:【{task.NextAddress}】"); return null; } } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) { string[] sourceCodes = task.SourceAddress.Split("-"); if (sourceCodes.Length == 5) { stackerCraneTaskCommand.StartRow = Convert.ToInt16(sourceCodes[1]); stackerCraneTaskCommand.StartColumn = Convert.ToInt16(sourceCodes[2]); stackerCraneTaskCommand.StartLayer = Convert.ToInt16(sourceCodes[3]); } else { //数据配置错误 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"出库任务起点错误,起点:【{task.CurrentAddress}】"); return null; } string[] sourceCodest = task.TargetAddress.Split("-"); if (sourceCodest.Length == 5) { stackerCraneTaskCommand.EndRow = Convert.ToInt16(sourceCodest[1]); stackerCraneTaskCommand.EndColumn = Convert.ToInt16(sourceCodest[2]); stackerCraneTaskCommand.EndLayer = Convert.ToInt16(sourceCodest[3]); } else { //数据配置错误 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"出库任务终点错误,起点:【{task.TargetAddress}】"); return null; } } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.RelocationGroup) { string[] targetCodes = task.NextAddress.Split("-"); if (targetCodes.Length == 5) { stackerCraneTaskCommand.EndRow = Convert.ToInt16(targetCodes[1]); stackerCraneTaskCommand.EndColumn = Convert.ToInt16(targetCodes[2]); stackerCraneTaskCommand.EndLayer = Convert.ToInt16(targetCodes[3]); } else { //数据配置错误 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"移库任务终点错误,起点:【{task.NextAddress}】"); return null; } string[] sourceCodes = task.CurrentAddress.Split("-"); if (sourceCodes.Length == 5) { stackerCraneTaskCommand.StartRow = Convert.ToInt16(sourceCodes[1]); stackerCraneTaskCommand.StartColumn = Convert.ToInt16(sourceCodes[2]); stackerCraneTaskCommand.StartLayer = Convert.ToInt16(sourceCodes[3]); } else { //数据配置错误 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"移库任务起点错误,起点:【{task.CurrentAddress}】"); return null; } } return stackerCraneTaskCommand; } //根地址读取输送线信息 public bool GetLine(CommonConveyorLine conveyorLine, string DeviceProDataBlock) { return conveyorLine.Communicator.Read(DeviceProDataBlock); } //获取输送线实例 public DeviceProDTO? GetDeviceProDTO(CommonConveyorLine conveyorLine, string SCAddress, string Interactivet) { return conveyorLine.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == SCAddress && x.DeviceProParamName == Interactivet); } } }