using HslCommunication; 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.Text; using System.Threading.Tasks; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_Communicator; using WIDESEAWCS_Core.Enums; using WIDESEAWCS_IBasicRepository; 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.Repository; using WIDESEAWCS_QuartzJob.Service; using WIDESEAWCS_QuartzJob.StackerCrane; using WIDESEAWCS_QuartzJob.StackerCrane.Enum; using WIDESEAWCS_TaskInfoService; using WIDESEAWCS_Tasks.StackerCraneJob; namespace WIDESEAWCS_Tasks { [DisallowConcurrentExecution] public class DoubleStackerCraneJob : JobBase, IJob { private readonly ITaskService _taskService; private readonly ITaskExecuteDetailService _taskExecuteDetailService; private readonly ITaskRepository _taskRepository; private readonly IRouterService _routerService; private readonly IDeviceInfoService _deviceInfoService; private readonly IDeviceInfoRepository _deviceInfoRepository; private readonly ILocationInfoRepository _locationInfoRepository; public DoubleStackerCraneJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IDeviceInfoService deviceInfoService, IDeviceInfoRepository deviceInfoRepository, ILocationInfoRepository locationInfoRepository) { _taskService = taskService; _taskExecuteDetailService = taskExecuteDetailService; _taskRepository = taskRepository; _routerService = routerService; _deviceInfoService = deviceInfoService; _deviceInfoRepository = deviceInfoRepository; _locationInfoRepository = locationInfoRepository; } public Task Execute(IJobExecutionContext context) { WriteDebug("小堆垛机运行日志", "开始时间" + DateTime.Now); CommonStackerCrane? stackerCraneOne = Storage.Devices.FirstOrDefault(x => x.DeviceCode == "SC02") as CommonStackerCrane; CommonStackerCrane? stackerCraneTwo = Storage.Devices.FirstOrDefault(x => x.DeviceCode == "SC03") as CommonStackerCrane; WriteDebug(nameof(DoubleStackerCraneJob), $"小堆垛机任务执行中..."); try { Dt_Task? task = GetTask(); if (task != null) { WriteDebug("小堆垛机运行日志", $"小堆垛机任务号{task.TaskNum}"); CommonStackerCrane? StackerCrane = GetStrackerCrane(task, stackerCraneOne, stackerCraneTwo); if (StackerCrane != null) { StackerCraneTaskCommand? stackerCraneTaskCommand = ConvertToStackerCraneTaskCommand(task); if (stackerCraneTaskCommand != null) { bool sendFlag = StackerCrane.SendCommand(stackerCraneTaskCommand); ; if (sendFlag) { _taskService.UpdateTaskStatus(task.TaskId, (int)TaskOutStatusEnum.SC_OutExecuting); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"堆垛机出库执行中"); } else { _taskService.UpdateTaskExceptionMessage(task.TaskNum, "堆垛机执行任务命令失败!"); WriteDebug(nameof(DoubleStackerCraneJob), "堆垛机执行任务命令失败!"); } } } else { WriteDebug(nameof(DoubleStackerCraneJob), "未查询到当前可以执行上料任务的小堆垛机!"); } } } catch (Exception ex) { WriteError(nameof(CommonStackerCraneJob), "小堆垛机执行任务异常!", ex); } //读取堆垛机任务号和任务完成确认状态 //Task.Run(delegate //{ try { if (stackerCraneOne != null) { byte IsFinish = stackerCraneOne.Communicator.Read("DB106.22"); int tasknum = stackerCraneOne.Communicator.Read("DB106.18"); if (IsFinish == 6) { if (stackerCraneOne.GetValue(StackerCraneDBName.WorkType) != 5) { //暂时 先写5:完成确认 信号 _taskService.StackCraneTaskCompleted(tasknum); stackerCraneOne.SetValue(StackerCraneDBName.WorkType, 5); } } } if (stackerCraneTwo != null) { //读取堆垛机任务号和任务完成确认状态 byte IsFinish = stackerCraneTwo.Communicator.Read("DB106.22"); int tasknum = stackerCraneTwo.Communicator.Read("DB106.18"); if (IsFinish == 6) { if (stackerCraneTwo.GetValue(StackerCraneDBName.WorkType) != 5) { _taskService.StackCraneTaskCompleted(tasknum); stackerCraneTwo.SetValue(StackerCraneDBName.WorkType, 5); } } } } catch (Exception ex) { WriteError(nameof(DoubleStackerCraneJob), "查询或写入PLC状态失败!", ex); } //}); WriteDebug("小堆垛机运行日志", "结束时间" + DateTime.Now); 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) { Console.Out.WriteLine("TaskCompleted" + e.TaskNum); _taskService.StackCraneTaskCompleted(e.TaskNum); commonStackerCrane.SetValue(StackerCraneDBName.WorkType, 5); } } } /// /// 获取任务 /// /// 堆垛机对象 /// private Dt_Task? GetTask() { Dt_Task task; task = _taskService.QueryStackerCraneTask(); return task; } /// /// 查询上料的堆垛机,先查询默认堆垛机,如果不正常,再查询另外一台堆垛机,如果都不正常返回null /// /// private CommonStackerCrane? GetStrackerCrane(Dt_Task task, CommonStackerCrane stackerCraneOne, CommonStackerCrane stackerCraneTwo) { if(task.Roadway=="SC02") { if (stackerCraneOne != null) { if (stackerCraneOne.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && stackerCraneOne.StackerCraneStatusValue == StackerCraneStatus.Normal) { if (stackerCraneOne.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby) { return stackerCraneOne; } } else//SC02不能正常工作状态,这里需要判断sc02是否禁用,如果已禁用,才可以启动sc03 { Dt_DeviceInfo deviceSC02 = _deviceInfoRepository.QueryFirst(x => x.DeviceCode == "SC02"); if (deviceSC02.DeviceStatus=="0"&& stackerCraneTwo != null) { //if (!stackerCraneTwo.IsEventSubscribed) //{ // stackerCraneTwo.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler;//订阅任务完成事件 //} if (stackerCraneTwo.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && stackerCraneTwo.StackerCraneStatusValue == StackerCraneStatus.Normal) { //stackerCraneTwo.CheckStackerCraneTaskCompleted();//防止任务完成事件监测超时,再手动触发一次 if (stackerCraneTwo.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby) { //todo:任务表中的RoadWay切换为SC03 return stackerCraneTwo; } } } } } else { if(stackerCraneTwo != null) { if (stackerCraneTwo.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && stackerCraneTwo.StackerCraneStatusValue == StackerCraneStatus.Normal) { if (stackerCraneTwo.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby) { //todo:任务表中的RoadWay切换为SC03 return stackerCraneTwo; } } } } } else if (task.Roadway=="SC03") { if (stackerCraneTwo != null) { // if (!stackerCraneTwo.IsEventSubscribed) // { // stackerCraneTwo.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler;//订阅任务完成事件 // } if (stackerCraneTwo.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && stackerCraneOne.StackerCraneStatusValue == StackerCraneStatus.Normal) { //stackerCraneTwo.CheckStackerCraneTaskCompleted();//防止任务完成事件监测超时,再手动触发一次 if (stackerCraneTwo.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby) { return stackerCraneTwo; } } else//SC03不能正常工作状态,这里需要判断sc03是否禁用,如果已禁用,才可以启动sc02 { Dt_DeviceInfo deviceSC03 = _deviceInfoRepository.QueryFirst(x => x.DeviceCode == "SC03"); if (deviceSC03.DeviceStatus=="0"&&stackerCraneOne != null) { //if (!stackerCraneOne.IsEventSubscribed) //{ // stackerCraneOne.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler;//订阅任务完成事件 //} if (stackerCraneOne.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && stackerCraneTwo.StackerCraneStatusValue == StackerCraneStatus.Normal) { //stackerCraneOne.CheckStackerCraneTaskCompleted();//防止任务完成事件监测超时,再手动触发一次 if (stackerCraneOne.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby) { //todo:任务表中的RoadWay切换为SC03 return stackerCraneOne; } } } } } else { if(stackerCraneOne != null) { if (stackerCraneOne.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && stackerCraneOne.StackerCraneStatusValue == StackerCraneStatus.Normal) { if (stackerCraneOne.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby) { return stackerCraneOne; } } } } } 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; if(string.IsNullOrEmpty(task.Remark))//总层数和层数是否为空 { return null; } string[] Levels = task.Remark.Split("-"); if (Levels.Length == 2) { //托盘类型 1:9层 2:4层 if (!string.IsNullOrEmpty(Levels[0])) { if (Levels[0].ToString()=="9") { stackerCraneTaskCommand.TrayType = 1; } else { stackerCraneTaskCommand.TrayType = 2; } } //料车具体的层数 if (!string.IsNullOrEmpty(Levels[1])) { stackerCraneTaskCommand.StartLayer =Convert.ToInt16(Levels[1]); } } else { return null; } string[] SourceCodes = task.SourceAddress.Split("-"); if (SourceCodes.Length == 4) { stackerCraneTaskCommand.StartRow = Convert.ToInt16(SourceCodes[1]); stackerCraneTaskCommand.StartColumn = Convert.ToInt16(SourceCodes[2]); // stackerCraneTaskCommand.StartLayer = Convert.ToInt16(SourceCodes[3]); } else { //数据配置错误 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"任务源地址配置错误!"); return null; } string[] targetCodes = task.TargetAddress.Split("-"); if (targetCodes.Length == 4) { stackerCraneTaskCommand.EndRow = Convert.ToInt16(targetCodes[1]); stackerCraneTaskCommand.EndColumn = Convert.ToInt16(targetCodes[2]); stackerCraneTaskCommand.EndLayer = Convert.ToInt16(targetCodes[3]); } else { //数据配置错误 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"任务目标地址配置错误"); return null; } return stackerCraneTaskCommand; } } }