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_Model.Models.System; 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.ConveyorLineJob; 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) { RequestOutIn(commonStackerCrane); if (commonStackerCrane.Communicator.Read("DB37.32")) //读取堆垛机允许信号 { Dt_Task? task = GetTask(commonStackerCrane); if (task != null) { StackerCraneTaskCommand? stackerCraneTaskCommand = ConvertToStackerCraneTaskCommand(task); if (stackerCraneTaskCommand != null) { commonStackerCrane.Communicator.Write("DB36.0", (string)task.PalletCode); bool sendFlag = commonStackerCrane.SendCommand(stackerCraneTaskCommand); if (sendFlag) { _taskService.UpdateTaskStatusToNext(task.TaskNum); } } } } /*else { WriteLog.Write_Log("堆垛机", "堆垛机信号", "允许信号", new { 信息 = "未读取到堆垛机允许信号" }); }*/ } } catch (Exception ex) { //Console.WriteLine(nameof(CommonStackerCraneJob) + ":" + ex.ToString()); } return Task.CompletedTask; } /// /// 获取任务进行下发 /// /// 输送线实例对象 public void RequestInbound(CommonStackerCrane commonStackerCrane) { try { 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) { throw; } } /// /// 放货完成信号 /// /// 输送线实例对象 public void RequestOutIn(CommonStackerCrane commonStackerCrane) { try { bool StackerStb = commonStackerCrane.Communicator.Read("DB37.32.2"); if (StackerStb && commonStackerCrane.CurrentTaskNum !=0) { _taskService.StackCraneTaskCompleted(commonStackerCrane.CurrentTaskNum); commonStackerCrane.Communicator.Write("DB37.33.6", (bool)true); WriteLog.Write_Log("堆垛机", "堆垛机信号", "堆垛机放货完成信号,正确信息", new { 信息 = $"读取到堆垛机放货完成信号:{StackerStb},任务号:{commonStackerCrane.CurrentTaskNum},写入堆垛机反馈失败信号:true" }); } else { commonStackerCrane.Communicator.Write("DB37.33.6", (bool)false); WriteLog.Write_Log("堆垛机", "堆垛机信号", "堆垛机放货完成信号,错误信息", new { 信息 = $"读取到堆垛机放货完成信号:{StackerStb},任务号:{commonStackerCrane.CurrentTaskNum},写入堆垛机反馈失败信号:false" }); } } catch (Exception ex) { throw; } } /// /// 获取任务 /// /// 堆垛机对象 /// private Dt_Task? GetTask(CommonStackerCrane commonStackerCrane) { List task; task = _taskService.QueryStackerCraneTask(commonStackerCrane.DeviceCode); if(task.Count > 0) { foreach (Dt_Task taskItem in task) { if (task != null && (taskItem.TaskType == (int)TaskOutboundTypeEnum.Outbound || taskItem.TaskType == (int)TaskOtherTypeEnum.PalletMaintenanceout)) { if (OutTaskStationIsOccupied(taskItem) != null) { return taskItem; } } else if(task != null && (taskItem.TaskType == (int)TaskInboundTypeEnum.Inbound || taskItem.TaskType == (int)TaskOtherTypeEnum.PalletMaintenancein)) { return taskItem; } } } return null; } /// /// 出库任务判断出库站台是否被占用 /// /// 任务实体 /// 如果未被占用,返回传入的任务信息,否则,返回null private Dt_Task? OutTaskStationIsOccupied([NotNull] Dt_Task task) { IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == "1002"); if (device != null) { CommonConveyorLine conveyorLine = (CommonConveyorLine)device; if (task.TaskType == (int)TaskOutboundTypeEnum.Outbound) { DeviceProDTO? deviceProDTO = GetDeviceProDTO(conveyorLine, task.NextAddress, "StationFree"); if (deviceProDTO != null) { bool B_Event_Test = GetLine(conveyorLine, deviceProDTO.DeviceProAddress); //判断输送线是否允许放货信号 if (B_Event_Test) { return task; } } } else if (task.TaskType == (int)TaskOtherTypeEnum.PalletMaintenanceout) { DeviceProDTO? deviceProDTO3 = GetDeviceProDTO(conveyorLine, "1060", "StationFree"); if (deviceProDTO3 != null) { bool B_Event_Test3 = GetLine(conveyorLine, deviceProDTO3.DeviceProAddress); //判断输送线是否允许放货信号 if (B_Event_Test3) { DeviceProDTO? deviceProDTO = GetDeviceProDTO(conveyorLine, task.NextAddress, "StationFree"); if (deviceProDTO != null) { bool B_Event_Test = GetLine(conveyorLine, deviceProDTO.DeviceProAddress); //判断输送线是否允许放货信号 if (B_Event_Test) { WriteLog.Write_Log("检修台任务下发", task.NextAddress + "站台", $"条码:{task.PalletCode}", new { 信息 = $"读取到输送线站台信号为:{B_Event_Test}" }); return task; } else { //编辑查找逻辑 string StaticAddress = _PlatformStationService.GetOutSCName(task.NextAddress); DeviceProDTO? deviceProDTO2 = GetDeviceProDTO(conveyorLine, StaticAddress, "StationFree"); bool B_Event2 = GetLine(conveyorLine, deviceProDTO2.DeviceProAddress); if (B_Event2) { WriteLog.Write_Log("检修台任务下发", task.NextAddress + "站台", $"条码:{task.PalletCode}", new { 信息 = $"读取到输送线站台信号为:{B_Event2}" }); return task; } } } } } } } return null; } /// /// 任务实体转换成命令Model /// /// 任务实体 /// /// public StackerCraneTaskCommand? ConvertToStackerCraneTaskCommand([NotNull] Dt_Task task) { StackerCraneTaskCommand stackerCraneTaskCommand = new StackerCraneTaskCommand(); stackerCraneTaskCommand.TaskNum = task.TaskNum; stackerCraneTaskCommand.WorkType = 1; if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup || task.TaskType == (int)TaskOtherTypeEnum.PalletMaintenancein)//判断是否是入库任务 { int coty = 1; /*if(task.TaskType == (int)TaskOtherTypeEnum.PalletMaintenancein) { coty = 2; }*/ //根据当前地址,查找堆垛机货位地址 task.CurrentAddress = _PlatformStationService.GetSCAdder(int.Parse(task.CurrentAddress), coty); string[] targetCodest = task.CurrentAddress.Split("-"); if (targetCodest.Length == 3) { targetCodest[0] = (targetCodest[0] == "A") ? "001" : "002"; stackerCraneTaskCommand.StartRow = Convert.ToInt16(targetCodest[0]); stackerCraneTaskCommand.StartColumn = Convert.ToInt16(targetCodest[1]); stackerCraneTaskCommand.StartLayer = Convert.ToInt16(targetCodest[2]); } else { //数据配置错误 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"入库起点错误,起点:【{task.SourceAddress}】"); return null; } string[] targetCodes = task.NextAddress.Split("-"); if (targetCodes.Length == 3) { targetCodes[0] = (targetCodes[0] == "A") ? "001" : "002"; stackerCraneTaskCommand.EndRow = Convert.ToInt16(targetCodes[0]); stackerCraneTaskCommand.EndColumn = Convert.ToInt16(targetCodes[1]); stackerCraneTaskCommand.EndLayer = Convert.ToInt16(targetCodes[2]); } else { //数据配置错误 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"入库任务终点错误,起点:【{task.NextAddress}】"); return null; } } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup || task.TaskType == (int)TaskOtherTypeEnum.PalletMaintenanceout) { int coty = 1; if (task.TaskType == (int)TaskOtherTypeEnum.PalletMaintenanceout) { coty = 2; } task.NextAddress = _PlatformStationService.GetSCAdder(int.Parse(task.NextAddress), coty); string[] sourceCodes = task.SourceAddress.Split("-"); if (sourceCodes.Length == 3) { sourceCodes[0] = (sourceCodes[0] == "A") ? "001" : "002"; stackerCraneTaskCommand.StartRow = Convert.ToInt16(sourceCodes[0]); stackerCraneTaskCommand.StartColumn = Convert.ToInt16(sourceCodes[1]); stackerCraneTaskCommand.StartLayer = Convert.ToInt16(sourceCodes[2]); } else { //数据配置错误 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"出库任务起点错误,起点:【{task.CurrentAddress}】"); return null; } string[] sourceCodest = task.NextAddress.Split("-"); if (sourceCodest.Length == 3) { sourceCodest[0] = (sourceCodest[0] == "A") ? "001" : "002"; stackerCraneTaskCommand.EndRow = Convert.ToInt16(sourceCodest[0]); stackerCraneTaskCommand.EndColumn = Convert.ToInt16(sourceCodest[1]); stackerCraneTaskCommand.EndLayer = Convert.ToInt16(sourceCodest[2]); } else { //数据配置错误 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"出库任务终点错误,起点:【{task.TargetAddress}】"); 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); } } }