1
z8018
2025-06-10 e46aa927d231af83724683c7286d9db503e24cf7
ÏîÄ¿´úÂë/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/Gantry/GantryJob.cs
@@ -18,8 +18,25 @@
namespace WIDESEAWCS_Tasks
{
    /// <summary>
    /// é¾™é—¨æž¶
    /// é¾™é—¨æž¶ä»»åŠ¡å¤„ç†ç±»ï¼Œç»§æ‰¿è‡ªJobBase并实现IJob接口 <br/>
    /// ç‰¹æ€§[DisallowConcurrentExecution]表示禁止并发执行
    /// </summary>
    /// <remarks>
    /// ä¸»è¦åŠŸèƒ½ï¼š <br/>
    /// 1. æ£€æŸ¥é¾™é—¨åŠçŠ¶æ€ï¼ˆè‡ªåŠ¨çŠ¶æ€/工作状态) <br/>
    /// 2. å¤„理取货/放货任务: <br/>
    ///    - éªŒè¯ä½ç½®åæ ‡æ ¼å¼ <br/>
    ///    - èŽ·å–æ¿æå°ºå¯¸ä¿¡æ¯ <br/>
    ///    - æ ¡éªŒå·¥ä½å’Œå®¹å™¨ä¿¡æ¯ <br/>
    ///    - è®¡ç®—并校验坐标范围 <br/>
    ///    - æ›´æ–°PLC控制参数 <br/>
    /// 3. å¤„理任务完成状态: <br/>
    ///    - æ›´æ–°ä»»åŠ¡çŠ¶æ€ <br/>
    ///    - é€šçŸ¥MES系统 <br/>
    ///    - é‡ç½®å·¥ä½çŠ¶æ€ <br/>
    /// 4. é”™è¯¯å¤„理:记录各种校验失败的异常情况 <br/>
    /// ä¾èµ–多个仓储和服务接口进行数据操作
    /// </remarks>
    [DisallowConcurrentExecution]
    public class GantryJob : JobBase, IJob
    {
@@ -28,21 +45,25 @@
        private readonly IContainerItemRepository _containerItemRepository;
        private readonly WebSocketServer _webSocketServer;
        private readonly IOrderDetailsService _orderDetailsService;
        public GantryJob(ITaskRepository taskRepository, ITaskService taskService, IContainerItemRepository containerItemRepository, WebSocketServer webSocketServer, IOrderDetailsService orderDetailsService)
        private readonly IContainerRepository _containerRepository;
        private readonly IOrderContainerRepository _orderContainerRepository;
        public GantryJob(ITaskRepository taskRepository, ITaskService taskService, IContainerItemRepository containerItemRepository, WebSocketServer webSocketServer, IOrderDetailsService orderDetailsService, IContainerRepository containerRepository, IOrderContainerRepository orderContainerRepository)
        {
            _taskRepository = taskRepository;
            _taskService = taskService;
            _containerItemRepository = containerItemRepository;
            _webSocketServer = webSocketServer;
            _orderDetailsService = orderDetailsService;
            _containerRepository = containerRepository;
            _orderContainerRepository = orderContainerRepository;
        }
        public Task Execute(IJobExecutionContext context)
        {
            bool flag = context.JobDetail.JobDataMap.TryGetValue("JobParams", out object? value);
            if (flag && value != null && value is OtherDevice)
            if (flag && value is OtherDevice otherDevice)
            {
                OtherDevice otherDevice = (OtherDevice)value;
                try
                {
                    byte gantryStatus = otherDevice.GetValue<GantryDBName, byte>(GantryDBName.GantryStatus);
@@ -51,13 +72,10 @@
                    if (gantryStatus == 1 && gantryAutoStatus == 3 && gantryWorkStatus == 0)
                    {
                        // é€»è¾‘处理
                        // 1. è¯»å–任务
                        // 2. ä»»åŠ¡æ‰§è¡Œ
                        // 3. ä»»åŠ¡å®Œæˆ
                        Dt_Task? task = _taskService.QueryAGantryUnExecuteTask(otherDevice.DeviceCode);
                        if (task != null)
                        {
                            #region å–货位置判断
                            string[] takePositions = task.CurrentAddress.Split("*");
                            if (takePositions.Length != 5)
                            {
@@ -69,7 +87,9 @@
                                }
                                return Task.CompletedTask;
                            }
                            #endregion
                            #region æ”¾è´§ä½ç½®åˆ¤æ–­
                            string[] putPositions = task.NextAddress.Split("*");
                            if (putPositions.Length != 5)
                            {
@@ -81,7 +101,9 @@
                                }
                                return Task.CompletedTask;
                            }
                            #endregion
                            #region æ¿æå°ºå¯¸èŽ·å–
                            Dt_ContainerItem containerItem = _containerItemRepository.QueryFirst(x => x.ItemCode == task.PalletCode);
                            if (containerItem == null)
                            {
@@ -91,9 +113,51 @@
                                    task.ExceptionMessage = "板材尺寸获取错误";
                                    _taskRepository.UpdateData(task);
                                }
                                if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                {
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                }
                                return Task.CompletedTask;
                            }
                            #endregion
                            #region æ”¾è´§å·¥ä½åˆ¤æ–­
                            Dt_Container container = _containerRepository.QueryFirst(x => x.ContainerCode == putPositions[0]);
                            if (container == null)
                            {
                                WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}", $"放货工位【{takePositions[0]}】未找到");
                                if (task.ExceptionMessage?.Contains($"放货工位【{takePositions[0]}】未找到") ?? true)
                                {
                                    task.ExceptionMessage = $"放货工位【{takePositions[0]}】未找到";
                                    _taskRepository.UpdateData(task);
                                }
                                if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                {
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                }
                                return Task.CompletedTask;
                            }
                            #endregion
                            #region å·¥ä½è®¢å•信息判断
                            Dt_OrderContainer orderContainer = _orderContainerRepository.QueryFirst(x => x.ContainerCode == putPositions[0] && x.ContainerId == container.Id);
                            if (orderContainer == null && container.ContainerType != ContainerTypeEnum.ExceptionContainer.ObjToInt())
                            {
                                WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}", $"放货工位【{takePositions[0]}】未找到订单信息");
                                if (task.ExceptionMessage?.Contains($"放货工位【{takePositions[0]}】未找到订单信息") ?? true)
                                {
                                    task.ExceptionMessage = $"放货工位【{takePositions[0]}】未找到订单信息";
                                    _taskRepository.UpdateData(task);
                                }
                                if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                {
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                }
                                return Task.CompletedTask;
                            }
                            #endregion
                            #region å·¥ä½åž«æ¿è¯»å–数据判断
                            if (!LightStatusStorage.StationStautsDic.TryGetValue(putPositions[0],out bool stationStatus))
                            {
                                WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}", $"工位【{putPositions[0]}】有无垫板数据错误,{LightStatusStorage.StationStautsDic.Serialize()}");
@@ -102,8 +166,15 @@
                                    task.ExceptionMessage = $"工位【{putPositions[0]}】有无垫板数据错误";
                                    _taskRepository.UpdateData(task);
                                }
                                if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                {
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                }
                                return Task.CompletedTask;
                            }
                            #endregion
                            #region å·¥ä½åž«æ¿çŠ¶æ€åˆ¤æ–­
                            if (!stationStatus)
                            {
                                WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}", $"工位【{putPositions[0]}】无垫板,{LightStatusStorage.StationStautsDic.Serialize()}");
@@ -114,11 +185,9 @@
                                }
                                return Task.CompletedTask;
                            }
                            #endregion
                            
                            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;
                            #region å–è´§Z坐标判断
                            if (OPositions.HPositions[takePositions[0]].PositionZ == 0)
                            {
                                WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}", "读取取货Z坐标读取为0");
@@ -127,16 +196,16 @@
                                    task.ExceptionMessage = $"读取取货Z坐标读取为0";
                                    _taskRepository.UpdateData(task);
                                }
                                if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                {
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                }
                                return Task.CompletedTask;
                            }
                            #endregion
                            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;
                            if (OPositions.HPositions[takePositions[0]].PositionZ == 0)
                            #region æ”¾è´§Z坐标判断
                            if (OPositions.HPositions[putPositions[0]].PositionZ == 0)
                            {
                                WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}", "读取放货Z坐标读取为0");
                                if (task.ExceptionMessage?.Contains($"读取放货Z坐标读取为0") ?? true)
@@ -144,16 +213,37 @@
                                    task.ExceptionMessage = $"读取放货Z坐标读取为0";
                                    _taskRepository.UpdateData(task);
                                }
                                if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                {
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                }
                                return Task.CompletedTask;
                            }
                            int putPoR = 0;
                            #endregion
                            #region ä»»åŠ¡å®žä½“å‚æ•°è½¬æ¢å¤„ç†
                            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;
                            #endregion
                            #region åæ ‡ä¹˜ä»¥1000处理,2#龙门架取反(乘以-1000)
                            int temp = 1000;
                            if(otherDevice.DeviceCode == "GT02")
                            {
                                temp = -1000;
                            }
                            #endregion
                            #region åæ ‡è®¡ç®—
                            if (Convert.ToInt32(takePositions[4]) == 1 || Convert.ToInt32(takePositions[4]) == 2)
                            {
                                takePoX = takePoX * temp + OPositions.HPositions[takePositions[0]].PositionX;
@@ -180,11 +270,13 @@
                                            task.ExceptionMessage = $"R坐标错误";
                                            _taskRepository.UpdateData(task);
                                        }
                                        if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                        {
                                            LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                        }
                                        return Task.CompletedTask;
                                    }
                                }
                                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
                            {
@@ -194,10 +286,22 @@
                                putPoY = putPoY * temp + 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}");
                            }
                            #region
                            #endregion
                            #region Debug日志记录,记录取货和放货坐标信息
                            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}");
                            #endregion
                            #region è¶…过容器宽度处理
                            bool isMoreWidth = orderContainer == null ? false : orderContainer.MaxWidth > container.ContainerWidth;
                            if (isMoreWidth)
                            {
                                putPoX = putPoX - (orderContainer.MaxWidth - container.ContainerWidth) / 2 * temp;
                            }
                            #endregion
                            #region åæ ‡èŒƒå›´åˆ¤æ–­
                            List<DeviceProDTO> devicePros = otherDevice.DeviceProDTOs.Where(x => x.DeviceProParamType == "MaxPosition").ToList();
                            DeviceProDTO? devicePro = devicePros.OrderBy(x => x.DeviceProOffset).FirstOrDefault();
@@ -209,8 +313,13 @@
                                    task.ExceptionMessage = $"设备协议参数错误,未找到最大最小坐标地址";
                                    _taskRepository.UpdateData(task);
                                }
                                if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                {
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                }
                                return Task.CompletedTask;
                            }
                            int[] data = otherDevice.Communicator.Read<int>(devicePro.DeviceProAddress, (ushort)(devicePros.Count));
                            int maxX = data[0];
@@ -222,16 +331,6 @@
                            int maxR = data[6];
                            int minR = data[7];
                            //int maxX = otherDevice.GetValue<GantryDBName, int>(GantryDBName.MaxX);
                            //int minX = otherDevice.GetValue<GantryDBName, int>(GantryDBName.MinX);
                            //int maxY = otherDevice.GetValue<GantryDBName, int>(GantryDBName.MaxY);
                            //int minY = otherDevice.GetValue<GantryDBName, int>(GantryDBName.MinY);
                            //int maxZ = otherDevice.GetValue<GantryDBName, int>(GantryDBName.MaxZ);
                            //int minZ = otherDevice.GetValue<GantryDBName, int>(GantryDBName.MinZ);
                            //int maxR = otherDevice.GetValue<GantryDBName, int>(GantryDBName.MaxR);
                            //int minR = otherDevice.GetValue<GantryDBName, int>(GantryDBName.MinR);
                            if (takePoX < minX || takePoX > maxX)
                            {
                                WriteError($"{otherDevice.DeviceCode}-{otherDevice.DeviceName}-坐标", $"X取货坐标超出范围,取货坐标:{takePoX},最大值:{maxX},最小值:{minX}");
@@ -239,6 +338,10 @@
                                {
                                    task.ExceptionMessage = $"X取货坐标超出范围,取货坐标:{takePoX},最大值:{maxX},最小值:{minX}";
                                    _taskRepository.UpdateData(task);
                                }
                                if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                {
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                }
                                return Task.CompletedTask;
                            }
@@ -251,6 +354,10 @@
                                    task.ExceptionMessage = $"X放货坐标超出范围,取货坐标:{putPoX},最大值:{maxX},最小值:{minX}";
                                    _taskRepository.UpdateData(task);
                                }
                                if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                {
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                }
                                return Task.CompletedTask;
                            }
@@ -261,6 +368,10 @@
                                {
                                    task.ExceptionMessage = $"Y取货坐标超出范围,取货坐标:{takePoY},最大值:{maxY},最小值:{minY}";
                                    _taskRepository.UpdateData(task);
                                }
                                if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                {
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                }
                                return Task.CompletedTask;
                            }
@@ -273,6 +384,10 @@
                                    task.ExceptionMessage = $"Y放货坐标超出范围,取货坐标:{putPoY},最大值:{maxY},最小值:{minY}";
                                    _taskRepository.UpdateData(task);
                                }
                                if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                {
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                }
                                return Task.CompletedTask;
                            }
@@ -283,6 +398,10 @@
                                {
                                    task.ExceptionMessage = $"Z取货坐标超出范围,取货坐标:{takePoZ},最大值:{maxZ},最小值:{minZ}";
                                    _taskRepository.UpdateData(task);
                                }
                                if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                {
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                }
                                return Task.CompletedTask;
                            }
@@ -295,6 +414,10 @@
                                    task.ExceptionMessage = $"Z放货坐标超出范围,取货坐标:{putPoZ},最大值:{maxZ},最小值:{minZ}";
                                    _taskRepository.UpdateData(task);
                                }
                                if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                {
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                }
                                return Task.CompletedTask;
                            }
@@ -305,6 +428,10 @@
                                {
                                    task.ExceptionMessage = $"R取货坐标超出范围,取货坐标:{takePoR},最大值:{maxR},最小值:{minR}";
                                    _taskRepository.UpdateData(task);
                                }
                                if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                {
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                }
                                return Task.CompletedTask;
                            }
@@ -317,10 +444,15 @@
                                    task.ExceptionMessage = $"R放货坐标超出范围,取货坐标:{putPoR},最大值:{maxR},最小值:{minR}";
                                    _taskRepository.UpdateData(task);
                                }
                                if (LightStatusStorage.LightStatusDic.ContainsKey(putPositions[0]))
                                {
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightError;
                                }
                                return Task.CompletedTask;
                            }
                            #endregion
                            #region ä»»åŠ¡å‘é€
                            otherDevice.SetValue(GantryDBName.TwoHand, true);
                            otherDevice.SetValue(GantryDBName.TaskNum, task.TaskNum);
                            otherDevice.SetValue(GantryDBName.TakePositionX, takePoX);
@@ -336,10 +468,14 @@
                            otherDevice.SetValue(GantryDBName.Height, containerItem.ItemHeight);
                            otherDevice.SetValue(GantryDBName.WorkType, 1);
                            otherDevice.SetValue(GantryDBName.StartCommand, 1);
                            #endregion
                            #region ä»»åŠ¡çŠ¶æ€æ›´æ–°
                            task.TaskState = TaskStatusEnum.Gantry_Executing.ObjToInt();
                            _taskRepository.UpdateData(task);
                            #endregion
                            #region ä¸‰è‰²ç¯çŠ¶æ€æ›´æ–°
                            if (LightStatusStorage.LightStatusDic.TryGetValue(putPositions[0], out LightStatusEnum lightStatusDic))
                            {
                                if (lightStatusDic != LightStatusEnum.LightWorking)
@@ -347,6 +483,7 @@
                                    LightStatusStorage.LightStatusDic[putPositions[0]] = LightStatusEnum.LightWorking;
                                }
                            }
                            #endregion
                        }
                    }
                    else if (gantryWorkStatus == 5)
@@ -364,11 +501,9 @@
                                    _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))
@@ -393,11 +528,6 @@
                WriteError(nameof(GantryJob), "参数错误,未传递设备参数或设备类型错误");
            }
            return Task.CompletedTask;
        }
        public Dt_Task GetTask()
        {
            return new Dt_Task();
        }
    }
}