using Newtonsoft.Json; using OfficeOpenXml.FormulaParsing.Excel.Functions.Logical; using Quartz; using SqlSugar; using SqlSugar.Extensions; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using WIDESEA_Core.Enums; using WIDESEAWCS_Core.Caches; using WIDESEAWCS_Core.Helper; using WIDESEAWCS_Core.HttpContextUser; using WIDESEAWCS_DTO.Enum; using WIDESEAWCS_IBasicInfoRepository; using WIDESEAWCS_ISystemRepository; 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; using WIDESEAWCS_QuartzJob.StackerCrane.Enum; using WIDESEAWCS_SignalR; using WIDESEAWCS_Tasks.StackerCraneJob; using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; using ICacheService = WIDESEAWCS_Core.Caches.ICacheService; namespace WIDESEAWCS_Tasks { [DisallowConcurrentExecution] public class CommonStackerCraneJob : IJob { private readonly ITaskService _taskService; private readonly ITaskExecuteDetailService _taskExecuteDetailService; private readonly ITaskRepository _taskRepository; private readonly IDt_StationManagerRepository _stationManagerRepository; private readonly ICacheService _cacheService; private readonly INoticeService _noticeService; public CommonStackerCraneJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository,IDt_StationManagerRepository stationManagerRepository, ICacheService cacheService, INoticeService noticeService) { _taskService = taskService; _taskExecuteDetailService = taskExecuteDetailService; _taskRepository = taskRepository; _stationManagerRepository = stationManagerRepository; _cacheService = cacheService; _noticeService = noticeService; } 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.Idle) { if (commonStackerCrane.GetValue(StackerCraneDBName.Electricity) > 20) { GetTask(commonStackerCrane); } } } #region 调用事件总线通知前端 var tokenInfos = _cacheService.Get>("Cache_UserToken"); if (tokenInfos != null && tokenInfos.Any()) { var userTokenIds = tokenInfos?.Select(x => x.Token_ID).ToList(); var userIds = tokenInfos?.Select(x => x.UserId).ToList(); object obj = new { commonStackerCrane.StackerCraneStatusDes, commonStackerCrane.StackerCraneAutoStatusDes, commonStackerCrane.StackerCraneWorkStatusDes, commonStackerCrane.DeviceCode, commonStackerCrane.DeviceName, commonStackerCrane.CurrentTaskNum, commonStackerCrane.LastTaskNum, SourceAddress = commonStackerCrane.GetValue(StackerCraneDBName.StartAddress), TargetAddress = commonStackerCrane.GetValue(StackerCraneDBName.EndAddress), Command = commonStackerCrane.GetValue(StackerCraneDBName.Command), Electricity = commonStackerCrane.GetValue(StackerCraneDBName.Electricity), }; _noticeService.StackerData(userIds?.FirstOrDefault(), userTokenIds, new { commonStackerCrane.DeviceName, data = obj }); } #endregion 调用事件总线通知前端 } } catch (Exception ex) { //Console.WriteLine(nameof(CommonStackerCraneJob) + ":" + ex.ToString()); } return Task.CompletedTask; } /// /// 任务完成事件订阅的方法 /// /// /// private void CommonStackerCrane_StackerCraneTaskCompletedEventHandler(object? sender, StackerCraneTaskCompletedEventArgs e) { CommonStackerCrane? commonStackerCrane = sender as CommonStackerCrane; if (commonStackerCrane != null) { _taskService.StackCraneTaskCompleted(e.TaskNum); commonStackerCrane.SetValue(StackerCraneDBName.TaskCompleted, 1); } } /// /// 获取任务 /// /// 堆垛机对象 /// private void GetTask(CommonStackerCrane commonStackerCrane) { Dt_Task task; task = _taskService.QueryStackerCraneTask(commonStackerCrane.DeviceCode); if (task != null) { if (task.Roadway == "3") { if (AGVToSandyEdgeRead(commonStackerCrane)) { WriteAGVTask(task, commonStackerCrane); } else { AGVToSandyEdge(commonStackerCrane); } } else if (task.Roadway == "2") { if (AGVToEdgeBandingRead(commonStackerCrane)) { WriteAGVTask(task, commonStackerCrane); } else { AGVToEdgeBanding(commonStackerCrane); } } else { WriteAGVTask(task, commonStackerCrane); } } } public void WriteAGVTask(Dt_Task task, CommonStackerCrane commonStackerCrane) { StackerCraneTaskCommand? stackerCraneTaskCommand = ConvertToStackerCraneTaskCommand(task); if (stackerCraneTaskCommand != null) { bool sendFlag = commonStackerCrane.SendCommand(stackerCraneTaskCommand); Thread.Sleep(2000); if (ReadReceived(commonStackerCrane) == 1) { if (Clear(commonStackerCrane)) { _taskService.UpdateTaskStatusToNext(task.TaskNum); } } } } /// /// 读取AGV收到作业信号 /// /// /// public int ReadReceived(CommonStackerCrane commonStackerCrane) { return commonStackerCrane.GetValue(StackerCraneDBName.Received); } /// /// 调度AGV去封边区域 /// /// /// public void AGVToEdgeBanding(CommonStackerCrane commonStackerCrane) { DeviceProDTO? devicePro = commonStackerCrane.DeviceProDTOs.Where(x => x.DeviceProParamType == "AreaWrite" && x.DeviceChildCode == commonStackerCrane.DeviceCode && x.DeviceProParamName == "AreaWrite").OrderBy(x => x.DeviceProOffset).FirstOrDefault(); commonStackerCrane.Communicator.Write(devicePro.DeviceProAddress, true); commonStackerCrane.SetValue(StackerCraneDBName.WorkType, 3); commonStackerCrane.SetValue(StackerCraneDBName.WriteConfirm, 1); Thread.Sleep(1000); if (ReadReceived(commonStackerCrane) == 1) { Clear(commonStackerCrane); } } /// /// 读取AGV是否在砂边 /// /// /// public bool AGVToSandyEdgeRead(CommonStackerCrane commonStackerCrane) { DeviceProDTO? devicePro = commonStackerCrane.DeviceProDTOs.Where(x => x.DeviceProParamType == "AreaRead" && x.DeviceChildCode == commonStackerCrane.DeviceCode && x.DeviceProParamName == "AreaRead").OrderBy(x => x.DeviceProOffset).FirstOrDefault(); if (devicePro == null) { ConsoleHelper.WriteColorLine($"【未找到配置调度AGV区域协议】", ConsoleColor.Magenta); return false; } string[] x = devicePro.DeviceProAddress.Split('.'); x[x.Length - 1] = (int.Parse(x[x.Length - 1]) + 1).ToString(); string DeviceProAddress = string.Join(".", x); bool read = commonStackerCrane.Communicator.Read(DeviceProAddress); return read; } public bool Clear(CommonStackerCrane commonStackerCrane) { DeviceProDTO? devicePro = commonStackerCrane.DeviceProDTOs.Where(x => x.DeviceProParamType == "WriteConfirm" && x.DeviceChildCode == commonStackerCrane.DeviceCode && x.DeviceProParamName == "WriteConfirm").OrderBy(x => x.DeviceProOffset).FirstOrDefault(); if (devicePro == null) { ConsoleHelper.WriteColorLine($"【未找到配置调度AGV区域协议】", ConsoleColor.Magenta); return false; } commonStackerCrane.Communicator.Write(devicePro.DeviceProAddress,Convert.ToInt16(0)); for (int i = 0; i < 6; i++) { if (i == 5) { return false; } else { int read = commonStackerCrane.Communicator.Read(devicePro.DeviceProAddress); if (read == 0) { return true; } else { commonStackerCrane.Communicator.Write(devicePro.DeviceProAddress, Convert.ToInt16(0)); } } } return false; } /// /// 读取AGV是否在封边 /// /// /// public bool AGVToEdgeBandingRead(CommonStackerCrane commonStackerCrane) { DeviceProDTO? devicePro = commonStackerCrane.DeviceProDTOs.Where(x => x.DeviceProParamType == "AreaRead" && x.DeviceChildCode == commonStackerCrane.DeviceCode && x.DeviceProParamName == "AreaRead").OrderBy(x => x.DeviceProOffset).FirstOrDefault(); if (devicePro == null) { ConsoleHelper.WriteColorLine($"【未找到配置调度AGV区域协议】", ConsoleColor.Magenta); return false; } return commonStackerCrane.Communicator.Read(devicePro.DeviceProAddress); } /// /// 调度AGV去砂边区域 /// /// /// public void AGVToSandyEdge(CommonStackerCrane commonStackerCrane) { DeviceProDTO? devicePro = commonStackerCrane.DeviceProDTOs.Where(x => x.DeviceProParamType == "AreaWrite" && x.DeviceChildCode == commonStackerCrane.DeviceCode && x.DeviceProParamName == "AreaWrite").OrderBy(x => x.DeviceProOffset).FirstOrDefault(); if (devicePro == null) { ConsoleHelper.WriteColorLine($"【未找到配置调度AGV区域协议】", ConsoleColor.Magenta); return; } string[] x = devicePro.DeviceProAddress.Split('.'); x[x.Length - 1] = (int.Parse(x[x.Length - 1]) + 1).ToString(); string DeviceProAddress = string.Join(".", x); commonStackerCrane.Communicator.Write(DeviceProAddress, true); commonStackerCrane.SetValue(StackerCraneDBName.WorkType, 4); commonStackerCrane.SetValue(StackerCraneDBName.WriteConfirm, 1); Thread.Sleep(1000); if (ReadReceived(commonStackerCrane) == 1) { Clear(commonStackerCrane); } } /// /// 任务实体转换成命令Model /// /// 任务实体 /// /// public StackerCraneTaskCommand? ConvertToStackerCraneTaskCommand([NotNull] Dt_Task task) { var SourceAddress = _stationManagerRepository.QueryFirst(x => x.stationName == task.SourceAddress); var TargetAddress = _stationManagerRepository.QueryFirst(x => x.stationName == task.TargetAddress); if(SourceAddress == null || TargetAddress == null) { ConsoleHelper.WriteColorLine($"【任务{JsonConvert.SerializeObject(task)}未找到站台配置】", ConsoleColor.Magenta); return null; } StackerCraneTaskCommand stackerCraneTaskCommand = new StackerCraneTaskCommand(); stackerCraneTaskCommand.TaskNum = task.TaskNum; stackerCraneTaskCommand.WorkType = 1; stackerCraneTaskCommand.WriteConfirm = 1; stackerCraneTaskCommand.StartAddress = Convert.ToInt16(SourceAddress.stationCode); stackerCraneTaskCommand.EndAddress = Convert.ToInt16(TargetAddress.stationCode); return stackerCraneTaskCommand; } } }