using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using HslCommunication.WebSocket; using Quartz; using WIDESEAWCS_Common; using WIDESEAWCS_Core.Helper; using WIDESEAWCS_IBasicInfoRepository; using WIDESEAWCS_IBasicInfoService; using WIDESEAWCS_ITaskInfoRepository; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob; using WIDESEAWCS_QuartzJob.DTO; using WIDESEAWCS_Tasks.Gantry; namespace WIDESEAWCS_Tasks { /// /// 龙门架 /// [DisallowConcurrentExecution] public class GantryJob2 : JobBase, IJob { private readonly ITaskRepository _taskRepository; private readonly ITaskService _taskService; private readonly IContainerItemRepository _containerItemRepository; private readonly WebSocketServer _webSocketServer; private readonly IOrderDetailsService _orderDetailsService; public GantryJob2(ITaskRepository taskRepository, ITaskService taskService, IContainerItemRepository containerItemRepository, WebSocketServer webSocketServer, IOrderDetailsService orderDetailsService) { _taskRepository = taskRepository; _taskService = taskService; _containerItemRepository = containerItemRepository; _webSocketServer = webSocketServer; _orderDetailsService = orderDetailsService; } public Task Execute(IJobExecutionContext context) { bool flag = context.JobDetail.JobDataMap.TryGetValue("JobParams", out object? value); if (flag && value != null && value is OtherDevice otherDevice) { try { byte gantryStatus = otherDevice.GetValue(GantryDBName.GantryStatus); byte gantryAutoStatus = otherDevice.GetValue(GantryDBName.GantryAutoStatus); byte gantryWorkStatus = otherDevice.GetValue(GantryDBName.GantryWorkStatus); if (gantryStatus == 1 && gantryAutoStatus == 3 && gantryWorkStatus == 0) { // 逻辑处理 // 1. 读取任务 // 2. 任务执行 // 3. 任务完成 Dt_Task? task = _taskService.QueryAGantryUnExecuteTask(otherDevice.DeviceCode); if (task != null) { GantryCommand? command = TaskToCommand(task, otherDevice); if (command == null) { WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}", "坐标转换错误"); return Task.CompletedTask; } if(IsPositionValid(otherDevice, command)) { WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}", "坐标超出范围"); return Task.CompletedTask; } otherDevice.SetValue(GantryDBName.TwoHand, true); otherDevice.SetValue(GantryDBName.TaskNum, task.TaskNum); otherDevice.SetValue(GantryDBName.TakePositionX, command.TakePoX); otherDevice.SetValue(GantryDBName.TakePositionY, command.TakePoY); otherDevice.SetValue(GantryDBName.TakePositionZ, command.TakePoZ); otherDevice.SetValue(GantryDBName.TakePositionR, command.TakePoR); otherDevice.SetValue(GantryDBName.PutPositionX, command.PutPoX); otherDevice.SetValue(GantryDBName.PutPositionY, command.PutPoY); otherDevice.SetValue(GantryDBName.PutPositionZ, command.PutPoZ); otherDevice.SetValue(GantryDBName.PutPositionR, command.PutPoR); otherDevice.SetValue(GantryDBName.Length, command.ItemLength); otherDevice.SetValue(GantryDBName.Width, command.ItemWidth); otherDevice.SetValue(GantryDBName.Height, command.ItemHeight); otherDevice.SetValue(GantryDBName.WorkType, 1); otherDevice.SetValue(GantryDBName.StartCommand, 1); task.TaskState = TaskStatusEnum.Gantry_Executing.ObjToInt(); _taskRepository.UpdateData(task); } } else if (gantryWorkStatus == 5) { int currentTaskNum = otherDevice.GetValue(GantryDBName.TaskNum); if (currentTaskNum > 0) { Dt_Task task = _taskRepository.QueryFirst(x => x.TaskNum == currentTaskNum); if (task != null) { _taskService.TaskComplete(task); _orderDetailsService.ToMes(task.PalletCode, 4); string[] putPositions = task.NextAddress.Split("*"); if (putPositions.Length != 5) { //WriteError return Task.CompletedTask; } if (LightStatusStorage.LightStatusDic.TryGetValue(putPositions[0], out LightStatusEnum lightStatusDic)) { if (lightStatusDic != LightStatusEnum.Ready) { LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.Ready; } } } } otherDevice.SetValue(GantryDBName.WorkType, 5); } } catch (Exception ex) { WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}", ex.Message, ex); } } else { WriteError(nameof(GantryJob), "参数错误,未传递设备参数或设备类型错误"); } return Task.CompletedTask; } public GantryCommand? TaskToCommand(Dt_Task task, OtherDevice otherDevice) { if (TaskValid(task, out string[] takePositions, out string[] putPositions, out Dt_ContainerItem containerItem)) { int takePoX = Convert.ToInt32(takePositions[1]); int takePoY = Convert.ToInt32(takePositions[2]); int takePoZ = OPositions.HPositions[takePositions[0]].PositionZ + 30 * 1000 - Convert.ToInt32(takePositions[3]) * 1000; int takePoR = 0; int putPoX = Convert.ToInt32(putPositions[1]); int putPoY = Convert.ToInt32(putPositions[2]); int putPoZ = OPositions.HPositions[putPositions[0]].PositionZ - Convert.ToInt32(putPositions[3]) * 1000; int putPoR = 0; if (OPositions.HPositions[takePositions[0]].PositionZ == 0) { WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}", "取货Z坐标读取为0"); return null; } if (OPositions.HPositions[putPositions[0]].PositionZ == 0) { WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}", "放货Z坐标读取为0"); return null; } if (Convert.ToInt32(takePositions[4]) == 1 || Convert.ToInt32(takePositions[4]) == 2) { takePoX = takePoX * 1000 + OPositions.HPositions[takePositions[0]].PositionX; takePoY = takePoY * 1000 + OPositions.HPositions[takePositions[0]].PositionY; putPoX = putPoX * 1000 + OPositions.HPositions[putPositions[0]].PositionX; putPoY = putPoY * 1000 + OPositions.HPositions[putPositions[0]].PositionY; takePoR = OPositions.HPositions[takePositions[0]].PositionR; if (Convert.ToInt32(takePositions[4]) == 1) putPoR = OPositions.HPositions[putPositions[0]].PositionR; else { if (otherDevice.DeviceCode == "GT03") putPoR = otherDevice.Communicator.Read("DB10.840"); else if (otherDevice.DeviceCode == "GT02") putPoR = otherDevice.Communicator.Read("DB10.836"); else if (otherDevice.DeviceCode == "GT01") putPoR = otherDevice.Communicator.Read("DB10.832"); else { WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}", "R坐标错误"); return null; } } WriteDebug($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}-坐标", $"取货位:{takePositions[0]},放货位:{putPositions[0]}{Environment.NewLine}取货坐标:X:{takePoX} Y:{takePoY} Z:{takePoZ} R:{takePoR}{Environment.NewLine}放货坐标:X:{putPoX} Y:{putPoY} Z:{putPoZ} R:{putPoR}{Environment.NewLine}读取PLC取货坐标:X:{OPositions.HPositions[takePositions[0]].PositionX} Y:{OPositions.HPositions[takePositions[0]].PositionY} Z:{OPositions.HPositions[takePositions[0]].PositionZ} R:{OPositions.HPositions[takePositions[0]].PositionR}{Environment.NewLine}读取PLC放货坐标:X:{OPositions.HPositions[putPositions[0]].PositionX} Y:{OPositions.HPositions[putPositions[0]].PositionY} Z:{OPositions.HPositions[putPositions[0]].PositionZ} R:{OPositions.HPositions[putPositions[0]].PositionR}"); } else { takePoX = takePoX * 1000 + OPositions.ZPositions[takePositions[0]].PositionX; takePoY = takePoY * 1000 + OPositions.ZPositions[takePositions[0]].PositionY; putPoX = putPoX * 1000 + OPositions.ZPositions[putPositions[0]].PositionX; putPoY = putPoY * 1000 + OPositions.ZPositions[putPositions[0]].PositionY; takePoR = OPositions.ZPositions[takePositions[0]].PositionR; putPoR = OPositions.ZPositions[putPositions[0]].PositionR; WriteDebug($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}-坐标", $"取货位:{takePositions[0]},放货位:{putPositions[0]}{Environment.NewLine}取货坐标:X:{takePoX} Y:{takePoY} Z:{takePoZ} R:{takePoR}{Environment.NewLine}放货坐标:X:{putPoX} Y:{putPoY} Z:{putPoZ} R:{putPoR}{Environment.NewLine}读取PLC取货坐标:X:{OPositions.ZPositions[takePositions[0]].PositionX} Y:{OPositions.ZPositions[takePositions[0]].PositionY} Z:{OPositions.ZPositions[takePositions[0]].PositionZ} R:{OPositions.ZPositions[takePositions[0]].PositionR}{Environment.NewLine}读取PLC放货坐标:X:{OPositions.ZPositions[putPositions[0]].PositionX} Y:{OPositions.ZPositions[putPositions[0]].PositionY} Z:{OPositions.ZPositions[putPositions[0]].PositionZ} R:{OPositions.ZPositions[putPositions[0]].PositionR}"); } GantryCommand command = new GantryCommand() { TakePoX = takePoX, TakePoY = takePoY, TakePoZ = takePoZ, TakePoR = takePoR, PutPoX = putPoX, PutPoY = putPoY, PutPoZ = putPoZ, PutPoR = putPoR, ItemLength = containerItem.ItemLength, ItemWidth = containerItem.ItemWidth, ItemHeight = containerItem.ItemHeight }; return command; } return null; } public bool TaskValid(Dt_Task task, out string[] takePositions, out string[] putPositions, out Dt_ContainerItem containerItem) { putPositions = null; containerItem = new Dt_ContainerItem(); takePositions = task.CurrentAddress.Split("*"); if (takePositions.Length != 5) { //WriteError return false; } putPositions = task.NextAddress.Split("*"); if (putPositions.Length != 5) { //WriteError return false; } containerItem = _containerItemRepository.QueryFirst(x => x.ItemCode == task.PalletCode); if (containerItem == null) { //WriteError return false; } if (LightStatusStorage.LightStatusDic.TryGetValue(putPositions[0], out LightStatusEnum lightStatusDic)) { if (lightStatusDic != LightStatusEnum.LightWorking) { LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightWorking; } } return true; } public bool IsPositionValid(OtherDevice otherDevice, GantryCommand command) { #region List devicePros = otherDevice.DeviceProDTOs.Where(x => x.DeviceProParamType == "MaxPosition").ToList(); DeviceProDTO? devicePro = devicePros.OrderBy(x => x.DeviceProOffset).FirstOrDefault(); if (devicePro == null) { WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}", "设备协议参数错误,未找到最大最小坐标地址"); return false; } int[] data = otherDevice.Communicator.Read(devicePro.DeviceProAddress, (ushort)(devicePros.Count)); int maxX = data[0]; int minX = data[1]; int maxY = data[2]; int minY = data[3]; int maxZ = data[4]; int minZ = data[5]; int maxR = data[6]; int minR = data[7]; //int maxX = otherDevice.GetValue(GantryDBName.MaxX); //int minX = otherDevice.GetValue(GantryDBName.MinX); //int maxY = otherDevice.GetValue(GantryDBName.MaxY); //int minY = otherDevice.GetValue(GantryDBName.MinY); //int maxZ = otherDevice.GetValue(GantryDBName.MaxZ); //int minZ = otherDevice.GetValue(GantryDBName.MinZ); //int maxR = otherDevice.GetValue(GantryDBName.MaxR); //int minR = otherDevice.GetValue(GantryDBName.MinR); if (command.TakePoX < minX || command.TakePoX > maxX) { WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}-坐标", $"X取货坐标超出范围,取货坐标:{command.TakePoX},最大值:{maxX},最小值:{minX}"); return false; } if (command.PutPoX < minX || command.PutPoX > maxX) { WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}-坐标", $"X放货坐标超出范围,取货坐标:{command.PutPoX},最大值:{maxX},最小值:{minX}"); return false; } if (command.TakePoY < minY || command.TakePoY > maxY) { WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}-坐标", $"Y取货坐标超出范围,取货坐标:{command.TakePoY},最大值:{maxY},最小值:{minY}"); return false; } if (command.PutPoY < minY || command.PutPoY > maxY) { WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}-坐标", $"Y放货坐标超出范围,取货坐标:{command.PutPoY},最大值:{maxY},最小值:{minY}"); return false; } if (command.TakePoZ < minZ || command.TakePoZ > maxZ) { WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}-坐标", $"Z取货坐标超出范围,取货坐标:{command.TakePoZ},最大值:{maxZ},最小值:{minZ}"); return false; } if (command.PutPoZ < minZ || command.PutPoZ > maxZ) { WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}-坐标", $"Z放货坐标超出范围,取货坐标:{command.PutPoZ},最大值:{maxZ},最小值:{minZ}"); return false; } if (command.TakePoR < minR || command.TakePoR > maxR) { WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}-坐标", $"R取货坐标超出范围,取货坐标:{command.TakePoR},最大值:{maxR},最小值:{minR}"); return false; } if (command.PutPoR < minR || command.PutPoR > maxR) { WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}-坐标", $"R放货坐标超出范围,取货坐标:{command.PutPoR},最大值:{maxR},最小值:{minR}"); return false; } return true; #endregion } } }