using Microsoft.AspNetCore.Components.Routing; using Newtonsoft.Json; using Quartz; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net.Http.Json; using System.Net.NetworkInformation; using System.Reflection; using System.Reflection.Metadata; using System.Reflection.PortableExecutable; using System.Text; using System.Text.Json.Nodes; using System.Threading.Tasks; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_Core; using WIDESEAWCS_Core.Caches; 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_TaskInfoService; using WIDESEAWCS_Tasks.StackerCraneJob; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using WIDESEAWCS_QuartzJob.StackerCrane; using WIDESEAWCS_Core.BaseRepository; using Autofac.Core; using WIDESEAWCS_Tasks.ConveyorLineJob; namespace WIDESEAWCS_Tasks { [DisallowConcurrentExecution] public partial class CommonStackerCraneJob : JobBase, IJob { private readonly ITaskService _taskService; private readonly IRouterService _routerService; private readonly ICacheService _cacheService; private readonly IRepository _routerRepository; private readonly IRepository _stationMangerRepository; private readonly IRepository _taskRepository; public CommonStackerCraneJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, IRouterService routerService, ICacheService cacheService, IRepository routerRepository, IRepository stationMangerRepository, IRepository taskRepository) { _taskService = taskService; _routerService = routerService; _cacheService = cacheService; _routerService = routerService; _stationMangerRepository = stationMangerRepository; _taskRepository = taskRepository; } public Task Execute(IJobExecutionContext context) { try { SpeStackerCrane speStackerCrane = (SpeStackerCrane)context.JobDetail.JobDataMap.Get("JobParams"); if (speStackerCrane != null) { GetStackerObject getStackerObject = new GetStackerObject(speStackerCrane); if (!getStackerObject.IsEventSubscribed) { getStackerObject.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler; } getStackerObject.CheckStackerCraneTaskCompleted(); if (getStackerObject.StackerCraneStatusValue == StackerCraneStatus.Normal) { var a = speStackerCrane.GetValue(StackerCraneDBName.CurrentTaskNum); Dt_Task? task = GetTasks(speStackerCrane); if (task != null) { WriteInfo("查找堆垛机任务号", $"任务信息,任务号:{task.TaskNum},堆垛机编号{speStackerCrane.DeviceCode}"); bool sendFlag = true; if (sendFlag) { StackerCraneTaskCommand? stackerCraneTaskCommand = ConvertToStackerCraneTaskCommand(task); if (stackerCraneTaskCommand != null) { sendFlag = getStackerObject.SendCommand(stackerCraneTaskCommand); if (sendFlag) { speStackerCrane.SetValue(StackerCraneDBName.CommandSend, 1);//启动命令 speStackerCrane.LastTaskType = task.TaskType; task.Dispatchertime = DateTime.Now; task.ExceptionMessage = ""; WebResponseContent webResponseContent = _taskService.UpdateTaskStatusToNext(task.TaskNum); //延时1s Thread.Sleep(1000); } } } } } } } catch (Exception) { throw; } return Task.CompletedTask; } private void CommonStackerCrane_StackerCraneTaskCompletedEventHandler(object? sender, StackerCraneTaskCompletedEventArgs e) { SpeStackerCrane? speStackerCrane = sender as SpeStackerCrane; if (speStackerCrane != null) { if (speStackerCrane.GetValue(StackerCraneDBName.WorkType) != 5) { var TaskNum = speStackerCrane.GetValue(StackerCraneDBName.CurrentTaskNum); WriteInfo("堆垛机任务完成", $"任务号:{TaskNum}"); _taskService.StackCraneTaskCompleted(e.TaskNum); WriteInfo("堆垛机任务完成反馈任务号", $"任务信息,任务号:{e.TaskNum}"); speStackerCrane.SetValue(StackerCraneDBName.WorkType, 5); } } } /// /// 获取任务 /// /// /// private Dt_Task? GetTasks(SpeStackerCrane commonStackerCrane) { Dt_Task? task; //堆垛机执行中 if (_taskRepository.QueryFirst(x => x.DeviceCode == commonStackerCrane.DeviceCode && x.TaskState == TaskStatusEnum.SC_Executing.ObjToInt()) != null) { return null; } task = _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode); //获取入库任务 if (task != null) { if(task.Roadway=="SC02") return task; //如果有任务则直接下发给堆垛机 if(task.Depth==1) return task; //2深位进行判断是否要移库 Dt_Task dt_Task = _taskService.RequestWMSTaskMovelibrary(task); if (dt_Task != null) return dt_Task; } else { //进行获取堆垛机出库任务 List tasks = _taskService.QueryStackerCraneOutTasks(commonStackerCrane.DeviceCode); foreach (var item in tasks) { if (OutTaskStationIsOccupied(item) != null) { if (item.Roadway == "SC01") { if (item.Depth == 1) return item; //调取WMS接口进行判断是否需要进行移库 Dt_Task dt_Task = OutTaskMovelibrary(item); if (dt_Task != null) return dt_Task; } else { return item; } } } } return task; } private Dt_Task? OutTaskMovelibrary([NotNull] Dt_Task task) { 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); //找浅库位是否有任务 if (tasks != null) return tasks; //向wms申请判断浅库位是否有货,是否需要进行移库 Dt_Task? taskst = _taskService.RequestWMSTaskMovelibrary(task); if (taskst != null) return taskst; return null; } /// /// 出库任务判断出库站台是否被占用 /// /// 任务实体 /// 如果未被占用,返回传入的任务信息,否则,返回null private Dt_Task? OutTaskStationIsOccupied([NotNull] Dt_Task task) { try { IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == "CL01"); if (device != null) { OtherDevice conveyorLine = (OtherDevice)device; DeviceProDTO? deviceProDTO = conveyorLine.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == task.NextAddress && x.DeviceProParamName == "IsOccupied"); //根据堆垛机地址,地址名称找协议 if (deviceProDTO != null) { bool B_Event_Test = conveyorLine.Communicator.Read(deviceProDTO.DeviceProAddress); //判断输送线是否允许放货信号 if (!B_Event_Test) { return task; } } } } 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 = 1; if (task.TaskType == (int)TaskInboundTypeEnum.Inbound)//判断是否是入库任务 { Dt_StationManger dt_StationManger = _stationMangerRepository.QueryFirst(x => x.StationCode == task.SourceAddress); string[] startCodes = dt_StationManger.StackerCraneStationCode.Split("-"); if (startCodes.Length == 3) { stackerCraneTaskCommand.StartRow = Convert.ToInt16(startCodes[0]); stackerCraneTaskCommand.StartColumn = Convert.ToInt16(startCodes[1]); stackerCraneTaskCommand.StartLayer = Convert.ToInt16(startCodes[2]); } 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 == (int)TaskOutboundTypeEnum.Outbound) { Dt_StationManger dt_StationManger = _stationMangerRepository.QueryFirst(x => x.StationCode == task.TargetAddress); string[] targetCodes = dt_StationManger.StackerCraneStationCode.Split("-"); stackerCraneTaskCommand.EndRow = Convert.ToInt16(targetCodes[0]); stackerCraneTaskCommand.EndColumn = Convert.ToInt16(targetCodes[1]); stackerCraneTaskCommand.EndLayer = Convert.ToInt16(targetCodes[2]); 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; } } else if (task.TaskType == (int)TaskRelocationTypeEnum.Relocation) //判断移库任务 { 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; } } }