1
huangxiaoqiang
2025-06-23 2d2d6bf8565f5b89fc9ee054bf6e62f9592f8673
ÏîÄ¿´úÂë/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs
@@ -1,20 +1,18 @@
using Autofac.Core;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Hosting;
using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup;
using Newtonsoft.Json;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Logical;
using Quartz;
using System;
using SqlSugar;
using SqlSugar.Extensions;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using WIDESEA_Common.Log;
using WIDESEAWCS_Common.TaskEnum;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.Enums;
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;
@@ -23,8 +21,12 @@
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
{
@@ -34,14 +36,18 @@
        private readonly ITaskService _taskService;
        private readonly ITaskExecuteDetailService _taskExecuteDetailService;
        private readonly ITaskRepository _taskRepository;
        private readonly IRouterService _routerService;
        private readonly IDt_StationManagerRepository _stationManagerRepository;
        private readonly ICacheService _cacheService;
        private readonly INoticeService _noticeService;
        public CommonStackerCraneJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService)
        public CommonStackerCraneJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository,IDt_StationManagerRepository stationManagerRepository, ICacheService cacheService, INoticeService noticeService)
        {
            _taskService = taskService;
            _taskExecuteDetailService = taskExecuteDetailService;
            _taskRepository = taskRepository;
            _routerService = routerService;
            _stationManagerRepository = stationManagerRepository;
            _cacheService = cacheService;
            _noticeService = noticeService;
        }
        public Task Execute(IJobExecutionContext context)
@@ -51,14 +57,50 @@
                CommonStackerCrane commonStackerCrane = (CommonStackerCrane)context.JobDetail.JobDataMap.Get("JobParams");
                if (commonStackerCrane != null)
                {
                    //添加判断agv状态是否可下发
                    if (ReadAGVstatus(commonStackerCrane) == 1 && ReadAGVworkingmode(commonStackerCrane) == 1)
                    if (!commonStackerCrane.IsEventSubscribed)
                    {
                        GetTask(commonStackerCrane);
                        commonStackerCrane.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler;//订阅任务完成事件
                    }
                    //处理agv是否完成任务
                    if (commonStackerCrane.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && commonStackerCrane.StackerCraneStatusValue == StackerCraneStatus.Normal)
                    {
                        commonStackerCrane.CheckStackerCraneTaskCompleted();//检测堆垛机任务完成事件
                        if (commonStackerCrane.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Idle)
                        {
                            if (commonStackerCrane.GetValue<StackerCraneDBName, float>(StackerCraneDBName.Electricity) > 20)
                            {
                                GetTask(commonStackerCrane);
                            }
                        }
                    }
                    #region è°ƒç”¨äº‹ä»¶æ€»çº¿é€šçŸ¥å‰ç«¯
                    var tokenInfos = _cacheService.Get<List<UserInfo>>("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, short>(StackerCraneDBName.StartAddress),
                            TargetAddress = commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.EndAddress),
                            Command = commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.Command),
                            Electricity = commonStackerCrane.GetValue<StackerCraneDBName, float>(StackerCraneDBName.Electricity),
                        };
                        _noticeService.StackerData(userIds?.FirstOrDefault(), userTokenIds, new { commonStackerCrane.DeviceName, data = obj });
                    }
                    #endregion è°ƒç”¨äº‹ä»¶æ€»çº¿é€šçŸ¥å‰ç«¯
                }
            }
            catch (Exception ex)
@@ -73,17 +115,14 @@
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CommonStackerCrane_StackerCraneTaskCompletedEventHandler(object? sender, WIDESEAWCS_QuartzJob.StackerCrane.StackerCraneTaskCompletedEventArgs e)
        private void CommonStackerCrane_StackerCraneTaskCompletedEventHandler(object? sender, StackerCraneTaskCompletedEventArgs e)
        {
            CommonStackerCrane? commonStackerCrane = sender as CommonStackerCrane;
           CommonStackerCrane? commonStackerCrane = sender as CommonStackerCrane;
            if (commonStackerCrane != null)
            {
                if (commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.WorkType) != 5)
                {
                    Console.Out.WriteLine("TaskCompleted" + e.TaskNum);
                    _taskService.StackCraneTaskCompleted(e.TaskNum);
                    commonStackerCrane.SetValue(StackerCraneDBName.WorkType, 5);
                }
                _taskService.StackCraneTaskCompleted(e.TaskNum);
                commonStackerCrane.SetValue(StackerCraneDBName.TaskCompleted, 1);
            }
        }
@@ -98,40 +137,187 @@
            task = _taskService.QueryStackerCraneTask(commonStackerCrane.DeviceCode);
            if (task != null)
            {
                StackerCraneTaskCommand? stackerCraneTaskCommand = ConvertToStackerCraneTaskCommand(task);
                if (stackerCraneTaskCommand != null)
                if (task.Roadway == "3")
                {
                    bool sendFlag = commonStackerCrane.SendCommand(stackerCraneTaskCommand);
                    if (sendFlag)
                    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 ReadAGVstatus(CommonStackerCrane commonStackerCrane)
        /// <summary>
        /// è¯»å–AGV收到作业信号
        /// </summary>
        /// <param name="commonStackerCrane"></param>
        /// <returns></returns>
        public int ReadReceived(CommonStackerCrane commonStackerCrane)
        {
            var deviceProDTO = commonStackerCrane.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == commonStackerCrane.DeviceCode && x.DeviceProParamName == "AGVCraneStatus");
            return deviceProDTO != null ? commonStackerCrane.Communicator.Read<int>(deviceProDTO.DeviceProAddress) : 99;
        }
        //读取AGV工作模式
        public int ReadAGVworkingmode(CommonStackerCrane commonStackerCrane)
        {
            var deviceProDTO = commonStackerCrane.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == commonStackerCrane.DeviceCode && x.DeviceProParamName == "AGVWorkingmode");
            return deviceProDTO != null ? commonStackerCrane.Communicator.Read<int>(deviceProDTO.DeviceProAddress) : 99;
            return commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.Received);
        }
        //读取任务号
        public int Readtasknumber(CommonStackerCrane commonStackerCrane)
        /// <summary>
        /// è°ƒåº¦AGV去封边区域
        /// </summary>
        /// <param name="commonStackerCrane"></param>
        /// <param name="value"></param>
        public void AGVToEdgeBanding(CommonStackerCrane commonStackerCrane)
        {
            var deviceProDTO = commonStackerCrane.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == commonStackerCrane.DeviceCode && x.DeviceProParamName == "AGVWorkingmode");
            return deviceProDTO != null ? commonStackerCrane.Communicator.Read<int>(deviceProDTO.DeviceProAddress) : 99;
            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);
            }
        }
        /// <summary>
        /// è¯»å–AGV是否在砂边
        /// </summary>
        /// <param name="commonStackerCrane"></param>
        /// <returns></returns>
        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<bool>(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<int>(devicePro.DeviceProAddress);
                    if (read == 0)
                    {
                        return true;
                    }
                    else
                    {
                        commonStackerCrane.Communicator.Write(devicePro.DeviceProAddress, Convert.ToInt16(0));
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// è¯»å–AGV是否在封边
        /// </summary>
        /// <param name="commonStackerCrane"></param>
        /// <returns></returns>
        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<bool>(devicePro.DeviceProAddress);
        }
        /// <summary>
        /// è°ƒåº¦AGV去砂边区域
        /// </summary>
        /// <param name="commonStackerCrane"></param>
        /// <param name="value"></param>
        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);
            }
        }
        /// <summary>
        /// ä»»åŠ¡å®žä½“è½¬æ¢æˆå‘½ä»¤Model
        /// </summary>
@@ -140,17 +326,23 @@
        /// <exception cref="Exception"></exception>
        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.TrayType = 0;
            stackerCraneTaskCommand.StartAdder = Convert.ToInt16(task.SourceAddress);
            stackerCraneTaskCommand.EndAdder = Convert.ToInt16(task.TargetAddress);
            stackerCraneTaskCommand.WriteConfirm = 1;
            stackerCraneTaskCommand.StartAddress = Convert.ToInt16(SourceAddress.stationCode);
            stackerCraneTaskCommand.EndAddress = Convert.ToInt16(TargetAddress.stationCode);
            return stackerCraneTaskCommand;
            return stackerCraneTaskCommand;
        }
    }
}