wankeda
4 天以前 6cc35000a6e138cfad96e7b02f8aeddcdb4ba6bf
´úÂë¹ÜÀí/NEWCode/WIDESEAWCS_Server/WIDESEAWCS_Tasks/AGVJob/UpdateTaskAGV.cs
@@ -1,10 +1,12 @@
using WIDESEAWCS_Common.AGVEnum;
using System.Threading.Tasks;
using WIDESEAWCS_Common.AGVEnum;
using WIDESEAWCS_Common.TaskEnum;
using WIDESEAWCS_DTO.TaskInfo;
using WIDESEAWCS_ITaskInfoRepository;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob;
namespace WIDESEAWCS_Tasks.AGVJob
namespace WIDESEAWCS_Tasks
{
    public class UpdateTaskAGV
    {
@@ -176,6 +178,31 @@
                                plcClient.Communicator.Write(taskFbInteractive2, 1);
                                //throw new Exception("任务状态更改为4终点已完成失败,任务ID:" + agvTask.agv_tasknum + DateTime.Now + ",任务状态不是终点执行中!");
                            }
                            if (agvTask.TargetAddress.Contains("HXWLX"))
                            {
                                if (agvTask.SourceAddress.Contains("KPHLX"))
                                {
                                    // ç©ºç›˜çº¿è¿›çƒ˜ç®±
                                    // TODO: è°ƒç”¨åˆ›æ™ºæŽ¥å£èŽ·å–å®Œæ•´æ¡ç 
                                    var materials = new List<BakingClass>
                                    {
                                            new BakingClass { BarCode = "1", MaterialType = "1" },
                                    };
                                    MESback WMSbackresult = MESAPIInvoke.BakingFeedingBinding(agvTask.TargetAddress, materials);
                                    if (WMSbackresult.Code > 0) { new Exception(WMSbackresult.Message); return; }
                                }
                                else
                                {
                                    // æå‡æœºè¿›çƒ˜ç®±
                                    // TODO: è°ƒç”¨åˆ›æ™ºæŽ¥å£èŽ·å–å®Œæ•´æ¡ç 
                                    var materials = new List<BakingClass>
                                    {
                                            new BakingClass { BarCode = "1", MaterialType = "1" },
                                    };
                                    MESback WMSbackresult = MESAPIInvoke.BakingFeedingBinding(agvTask.TargetAddress, materials);
                                    if (WMSbackresult.Code > 0) { new Exception(WMSbackresult.Message); return; }
                                }
                            }
                            //agvtask_HtyRepository.AddTaskHistory(agvTask, OperateType.Finished.ToString());
                            _taskRepository.DeleteData(agvTask);
@@ -231,7 +258,7 @@
            }
        }
        public static void UpdateTask(AGV plcClient, ITaskRepository taskRepository)
        public static void UpdateTask(AGV plcClient, ITaskRepository taskRepository, ITaskCZRepository _taskCZRepository, ITaskCZDetailsRepository _detailsRepository)
        {
            // ä½¿ç”¨Interlocked.Exchange保证同一时间只有一个线程可以执行任务更新
            if (Interlocked.Exchange(ref _readUpdateAGVTaskSignalso, 1) == 0)
@@ -257,22 +284,22 @@
                    }
                    // è¯»å–任务状态
                    int taskFbInteractive = plcClient.Communicator.Read<int>(taskFbInteractiveR);
                    int taskFbInteractiveW = plcClient.Communicator.Read<int>(taskFbInteractive2);
                    int resetTaskFbInteractiveRValue = plcClient.Communicator.Read<int>(resetTaskFbInteractiveR);
                    int taskFbInteractive = plcClient.Communicator.Read<ushort>(taskFbInteractiveR);
                    int taskFbInteractiveW = plcClient.Communicator.Read<ushort>(taskFbInteractive2);
                    int resetTaskFbInteractiveRValue = plcClient.Communicator.Read<ushort>(resetTaskFbInteractiveR);
                    // å¦‚æžœresetTaskFbInteractiveR为1,则重置taskFbInteractiveW为0,并等待其变为0
                    if (resetTaskFbInteractiveRValue == 1)
                    {
                        plcClient.Communicator.Write(taskFbInteractive2, 0);
                        plcClient.Communicator.Write<ushort>(taskFbInteractive2, 0);
                        // é¿å…ä½¿ç”¨Thread.Sleep来等待状态变化,使用更高效的等待机制
                        for (int i = 0; i < 5; i++)
                        {
                            Task.Delay(300).Wait(); // ä½¿ç”¨Task.Delay替代Thread.Sleep,避免阻塞线程池中的线程
                            int agvNumber = plcClient.Communicator.Read<int>(taskFbInteractive2);
                            int agvNumber = plcClient.Communicator.Read<ushort>(taskFbInteractive2);
                            if (agvNumber != 0)
                            {
                                plcClient.Communicator.Write(taskFbInteractive2, 0);
                                plcClient.Communicator.Write<ushort>(taskFbInteractive2, 0);
                            }
                            else
                            {
@@ -284,8 +311,8 @@
                    // åªæœ‰å½“taskFbInteractive为1且taskFbInteractiveW为0时才处理任务状态
                    if (taskFbInteractive == 1 && taskFbInteractiveW == 0)
                    {
                        string taskId = plcClient.Communicator.Read<int>(taskIDFb).ToString(); // ä»»åŠ¡ID
                        int taskState = plcClient.Communicator.Read<int>(taskStatusFb); // ä»»åŠ¡çŠ¶æ€
                        string taskId = plcClient.Communicator.Read<string>(taskIDFb).ToString(); // ä»»åŠ¡ID
                        int taskState = plcClient.Communicator.Read<ushort>(taskStatusFb); // ä»»åŠ¡çŠ¶æ€
                        // å¦‚果任务状态无效,则直接返回
                        if (taskState == 0)
@@ -294,10 +321,11 @@
                        }
                        // æ ¹æ®ä»»åŠ¡ID查询数据库中的任务
                        var agvTask = taskRepository.QueryFirst(r => r.TaskNum.ToString() == taskId);
                        int tasknum = int.Parse(taskId.Split('-')[1]);
                        var agvTask = taskRepository.QueryFirst(r => r.TaskNum.ToString() == tasknum.ToString());
                        if (agvTask == null)
                        {
                            plcClient.Communicator.Write(taskFbInteractive2, 1);
                            plcClient.Communicator.Write<ushort>(taskFbInteractive2, 1);
                            return; // å¦‚果任务不存在,直接返回,不需要再次写入
                        }
@@ -316,27 +344,84 @@
                        }
                        else if (taskState == 4) // ä»»åŠ¡ç»ˆç‚¹å®Œæˆ
                        {
                            if (agvTask.TaskState != (int)TaskInStatusEnum.SC_InExecuting)
                            if (agvTask.TaskState != (int)TaskInStatusEnum.SC_InFinish)
                            {
                                // å¦‚果任务状态不是终点执行中,抛出异常
                                throw new Exception($"任务状态更改为4终点已完成失败,任务ID:{taskId},当前状态:{agvTask.TaskState}");
                            }
                            if (agvTask.TargetAddress.Contains("HXWLX"))
                            {
                                if (agvTask.SourceAddress.Contains("KPHLX"))
                                {
                                    // ç©ºç›˜çº¿è¿›çƒ˜ç®±
                                    // TODO: ä»»åŠ¡æˆªå–å®Œæ•´æ¡ç 
                                    var details = agvTask.ExceptionMessage;
                                    string[] splitDetails = details.Split(',');
                                    var materials = splitDetails
                                        .Select(part => new BakingClass
                                        {
                                            MaterialType = "",
                                            BarCode = part
                                        })
                                        .ToList();
                                    MESback WMSbackresult = MESAPIInvoke.BakingFeedingBinding(agvTask.TargetAddress, materials);
                                    if (WMSbackresult.Code > 0) { new Exception(WMSbackresult.Message); return; }
                                }
                                else
                                {
                                    // æå‡æœºè¿›çƒ˜ç®±
                                    // TODO: è°ƒç”¨åˆ›æ™ºæŽ¥å£èŽ·å–å®Œæ•´æ¡ç 
                                    //var czTask = _taskCZRepository.QueryFirst(x => x.Id == agvTask.WMSId);
                                    //CZTaskBarCodeDto barCodeDto = JsonConvert.DeserializeObject<CZTaskBarCodeDto>(czTask.DtCZTaskDetails);
                                    //var materials = Enumerable.Range(0, 2)
                                    //        .Select(i => new BakingClass
                                    //        {
                                    //            MaterialType = czTask.TaskProductCode,
                                    //            BarCode = GetBarCodeByIndex(barCodeDto, i, hasDesc: !string.IsNullOrEmpty(czTask.TaskDesc))
                                    //        })
                                    //        .ToList();
                                    var details = _detailsRepository.QueryData(x => x.TaskEndAddress == agvTask.TargetAddress).ToList();
                                    if (details.Count >= 2)
                                    {
                                        details = details.Take(2).ToList();
                                    }
                                    var materials = details.Select(x => new BakingClass
                                    {
                                        MaterialType = x.MaterialType,
                                        BarCode = x.MaterialBarCode,
                                    }).ToList();
                                    MESback WMSbackresult = MESAPIInvoke.BakingFeedingBinding(agvTask.TargetAddress, materials);
                                    if (WMSbackresult.Code > 0) { new Exception(WMSbackresult.Message); return; }
                                    else
                                    {
                                        // åˆ é™¤details数据
                                        _detailsRepository.DeleteData(details);
                                    }
                                }
                            }
                            // åˆ é™¤å·²å®Œæˆçš„任务
                            taskRepository.DeleteData(agvTask);
                            plcClient.Communicator.Write(taskFbInteractive2, 1);
                            plcClient.Communicator.Write<ushort>(taskFbInteractive2, 1);
                            EnsureTaskFeedback(taskFbInteractive2, plcClient);
                        }
                        else if (taskState == 5)
                        {
                            plcClient.Communicator.Write(taskFbInteractive2, 1);
                            plcClient.Communicator.Write<ushort>(taskFbInteractive2, 1);
                        }
                    }
                    // å¦‚æžœtaskFbInteractive为0且taskFbInteractiveW为1,则重置taskFbInteractiveW为0
                    if (taskFbInteractive == 0 && taskFbInteractiveW == 1)
                    {
                        plcClient.Communicator.Write(taskFbInteractive2, 0);
                        plcClient.Communicator.Write<ushort>(taskFbInteractive2, 0);
                        EnsureTaskFeedback(taskFbInteractive2, plcClient);
                    }
                }
@@ -355,15 +440,15 @@
        // æ›´æ–°ä»»åŠ¡çŠ¶æ€å¹¶å†™å…¥AGV反馈地址
        private static void UpdateTaskStatus(AGV plcClient, Dt_Task agvTask, TaskInStatusEnum targetStatus, ITaskRepository taskRepository, string taskFbInteractive2)
        {
            if (agvTask.TaskState != (int)targetStatus)
            {
                plcClient.Communicator.Write(taskFbInteractive2, 1); // çŠ¶æ€ä¸åŒ¹é…ï¼Œå†™å…¥åé¦ˆ
            }
            //if (agvTask.TaskState != (int)targetStatus)
            //{
            //    plcClient.Communicator.Write<ushort>(taskFbInteractive2, 1); // çŠ¶æ€ä¸åŒ¹é…ï¼Œå†™å…¥åé¦ˆ
            //}
            // æ›´æ–°ä»»åŠ¡çŠ¶æ€ä¸ºä¸‹ä¸€ä¸ªæœªå®ŒæˆçŠ¶æ€
            agvTask.TaskState = agvTask.TaskState.GetNextNotCompletedStatus<TaskInStatusEnum>();
            taskRepository.UpdateData(agvTask);
            plcClient.Communicator.Write(taskFbInteractive2, 1);
            plcClient.Communicator.Write<ushort>(taskFbInteractive2, 1);
            EnsureTaskFeedback(taskFbInteractive2, plcClient);
        }
@@ -376,7 +461,7 @@
                int agvNumber = plcClient.Communicator.Read<int>(taskFbInteractive2);
                if (agvNumber != 1)
                {
                    plcClient.Communicator.Write(taskFbInteractive2, 1);
                    plcClient.Communicator.Write<ushort>(taskFbInteractive2, 1);
                }
                else
                {
@@ -384,5 +469,31 @@
                }
            }
        }
        // è¾…助方法
        private static string GetBarCodeByIndex(CZTaskBarCodeDto dto, int index, bool hasDesc)
        {
            return (index, hasDesc) switch
            {
                (0, false) => dto.BarCode1,
                (1, false) => dto.BarCode2,
                (0, true) => dto.BarCode3,
                (1, true) => dto.BarCode4,
                _ => throw new IndexOutOfRangeException()
            };
        }
    }
    public class BakingFeedingClass
    {
        public string Devid { get; set; }
        public List<BakingClass> Materials { get; set; }
    }
    public class BakingClass
    {
        public string MaterialType { get; set; }
        public string BarCode { get; set; }
    }
}