1
huangxiaoqiang
2025-06-23 2d2d6bf8565f5b89fc9ee054bf6e62f9592f8673
ÏîÄ¿´úÂë/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/CommonConveyorLineJob.cs
@@ -15,240 +15,244 @@
 *----------------------------------------------------------------*/
#endregion << ç‰ˆ æœ¬ æ³¨ é‡Š >>
using AngleSharp.Dom;
using Autofac.Core;
using AutoMapper;
using HslCommunication;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Newtonsoft.Json;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using Quartz;
using System.Reflection;
using WIDESEA_Common.Log;
using WIDESEAWCS_Common.TaskEnum;
using WIDESEAWCS_Core.Caches;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_Core.HttpContextUser;
using WIDESEAWCS_DTO.Enum;
using WIDESEAWCS_DTO.TaskInfo;
using WIDESEAWCS_IBasicInfoService;
using WIDESEAWCS_ISystemServices;
using WIDESEAWCS_ITaskInfoRepository;
using WIDESEAWCS_ITaskInfoService;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_Model.Models.System;
using WIDESEAWCS_Model.Models.BasicInfo;
using WIDESEAWCS_QuartzJob;
using WIDESEAWCS_QuartzJob.DeviceBase;
using WIDESEAWCS_QuartzJob.DTO;
using WIDESEAWCS_QuartzJob.Service;
using WIDESEAWCS_SignalR;
using WIDESEAWCS_Tasks.ConveyorLineJob;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
namespace WIDESEAWCS_Tasks
{
    [DisallowConcurrentExecution]
    public class CommonConveyorLineJob : IJob
    public class CommonConveyorLineJob :JobBase, IJob
    {
        private readonly ITaskService _taskService;
        private readonly ITaskRepository _taskRepository;
        private readonly ITaskExecuteDetailService _taskExecuteDetailService;
        private readonly IRouterService _routerService;
        private readonly IAgvStationService _agvStationService;
        private readonly IDt_StationManagerService _stationManagerService;
        private readonly IMapper _mapper;
        private readonly ICacheService _cacheService;
        private readonly INoticeService _noticeService;
        private static List<string>? userTokenIds;
        private static List<int>? userIds;
        public CommonConveyorLineJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, IRouterService routerService, IAgvStationService agvStation, IMapper mapper)
        public CommonConveyorLineJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, IRouterService routerService, IDt_StationManagerService stationManagerService, IMapper mapper, ICacheService cacheService, INoticeService noticeService, ITaskRepository taskRepository)
        {
            _taskService = taskService;
            _taskExecuteDetailService = taskExecuteDetailService;
            _routerService = routerService;
            _agvStationService = agvStation;
            _stationManagerService = stationManagerService;
            _mapper = mapper;
            _cacheService = cacheService;
            _noticeService = noticeService;
            _taskRepository = taskRepository;
        }
        public Task Execute(IJobExecutionContext context)
        public async Task Execute(IJobExecutionContext context)
        {
            try
            {
                wcsWriteLog("LineJob", "运行状态", $"开始时间:{DateTime.Now}");
                CommonConveyorLine conveyorLine = (CommonConveyorLine)context.JobDetail.JobDataMap.Get("JobParams");
                if (conveyorLine != null)
                {
                    //生成取货任务,放至上料位
                    RequestInbound(conveyorLine);
                    //根据agv下料任务,把料放至上料口或缓存位
                    RequestOutbound(conveyorLine);  //上料口需要找任务,找缓存区
                    // èŽ·å–æ‰€æœ‰ç«™ç‚¹ç®¡ç†å™¨
                    List<Dt_StationManager> stationManagers = _stationManagerService.GetAllStationByDeviceCode(conveyorLine.DeviceCode);
                    // å¹¶è¡Œå¤„理每个子设备
                    var tasks = stationManagers.Select(station => ProcessDeviceAsync(conveyorLine, station)).ToList();
                    await Task.WhenAll(tasks);
                }
            }
            catch (Exception ex)
            {
                //Console.Out.WriteLine(nameof(CommonConveyorLineJob) + ":" + ex.ToString());
                wcsWriteLog("LineJob错误信息", "异常信息", ex.ToString());
                Console.Out.WriteLine(nameof(CommonConveyorLineJob) + ":" + ex.ToString());
            }
            wcsWriteLog("LineJob", "运行状态", $"结束时间:{DateTime.Now}");
            return;
        }
        private Task ProcessDeviceAsync(CommonConveyorLine conveyorLine, Dt_StationManager station)
        {
            try
            {
                ConveyorLineTaskCommand command = conveyorLine.ReadCustomer<ConveyorLineTaskCommand>(station.stationName);
                if (command != null)
                {
                    #region è°ƒç”¨äº‹ä»¶æ€»çº¿é€šçŸ¥å‰ç«¯
                    // èŽ·å–ç¼“å­˜ä¸­çš„ç”¨æˆ·ä¿¡æ¯
                    var tokenInfos = _cacheService.Get<List<UserInfo>>("Cache_UserToken");
                    if (tokenInfos != null && tokenInfos.Any())
                    {
                        userTokenIds = tokenInfos.Select(x => x.Token_ID).ToList();
                        userIds = tokenInfos.Select(x => x.UserId).ToList();
                    }
                    #endregion è°ƒç”¨äº‹ä»¶æ€»çº¿é€šçŸ¥å‰ç«¯
                    // å°†äº¤äº’信号转换为布尔数组
                    var structs = BitConverter.GetBytes(command.InteractiveSignal).Reverse().ToArray().ToBoolArray();
                    // èŽ·å–è®¾å¤‡åè®®è¯¦æƒ…
                    List<DeviceProtocolDetailDTO>? deviceProtocolDetails = conveyorLine.DeviceProtocolDetailDTOs.Where(x => x.DeviceProParamName == nameof(ConveyorLineTaskCommand.InteractiveSignal)).ToList();
                    if (deviceProtocolDetails != null)
                    {
                        foreach (var item in deviceProtocolDetails)
                        {
                            int itemValue = Convert.ToInt32(item.ProtocalDetailValue);
                            if (structs[itemValue] == true)
                            {
                                // èŽ·å–å¤„ç†æ–¹æ³•
                                MethodInfo? method = GetType().GetMethod(item.ProtocolDetailType);
                                if (method != null)
                                {
                                    method.Invoke(this, new object[] { conveyorLine, station });
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                WriteInfo(conveyorLine.DeviceName, ex.Message);
            }
            return Task.CompletedTask;
        }
        /// <summary>
        /// è¾“送线请求入库
        /// ç”Ÿæˆå–货任务,放至上料位
        /// </summary>
        /// <param name="conveyorLine">输送线实例对象</param>
        /// <param name="command">读取的请求信息</param>Request outbound
        /// <param name="childDeviceCode">子设备编号</param>
        public void RequestInbound(CommonConveyorLine conveyorLine)
        public async Task RequestInbound(CommonConveyorLine conveyorLine, Dt_StationManager station)
        {
            List<string> _Task = _taskService.QueryConveyorLineTaskSourceAddress();
            List<AGVStation> childDeviceCodes = _agvStationService.QuerypLatform(conveyorLine.DeviceCode, _Task);  //对应每个ip找全部的下料站点与垫板回收点站台点
            foreach (var childDeviceCode in childDeviceCodes)
            try
            {
                ConveyorLineCommand command = conveyorLine.ReadCustomer<ConveyorLineCommand>(childDeviceCode.Station_name);
                if (command != null)
                {
                    if (command.R_Releasespermitted == 1)
                    {
                        if (childDeviceCode.Station_material==(int)AgvStationEnum.PadRecycle)
                        {
                            RequestHcdbst(conveyorLine, childDeviceCode.Station_Area, childDeviceCode.Station_name, childDeviceCode.Station_remark);
                        }
                        else
                        {
                            Dt_Task taskDTO = new Dt_Task()
                            {
                                TaskNum = Convert.ToInt32(DateTime.Now.ToString("HHmmss")) + childDeviceCode.Station_code,
                                Grade = 1,
                                Roadway = childDeviceCode.Station_Area.ToString(),
                                SourceAddress = childDeviceCode.Station_name,
                                CurrentAddress = childDeviceCode.Station_name,
                                TaskState = (int)TaskInStatusEnum.InNew,
                                TaskType = (int)childDeviceCode.Station_material,
                            };
                            _taskService.ReceiveWMSTask(taskDTO);
                        }
                    }
                    else
                    {
                        wcsWriteLog(childDeviceCode.Station_name, "读取信息", $"未找到该读取模块");
                    }
                }
                else
                {
                    wcsWriteLog(childDeviceCode.Station_name, "读取信息", $"通讯连接错误,未找到读取模块地址");
                }
            }
        }
                // è¾“出信息,表示站台请求取货
                var log = $"【{conveyorLine._deviceName}】站台【{station.stationName}】请求取货";
                await LogAndWarn(conveyorLine.DeviceName, log);
        /// <summary>
        /// è¾“送线请求出站
        /// </summary>
        /// <param name="conveyorLine">输送线实例对象</param>
        /// <param name="command">读取的请求信息</param>
        /// <param name="childDeviceCode">子设备编号</param>
        public void RequestOutbound(CommonConveyorLine conveyorLine)
        {
            List<AGVStation> AGVStationListdata = _agvStationService.QuerypLatformarer(conveyorLine.DeviceCode);
            foreach (var AGVStationitem in AGVStationListdata)
            {
                ConveyorLineCommand command = conveyorLine.ReadCustomer<ConveyorLineCommand>(AGVStationitem.Station_name);
                if (command != null)
                // èŽ·å–æ‰€æœ‰ä»»åŠ¡æºåœ°å€
                List<string> taskSourceAddress = _taskService.QueryConveyorLineTask();
                if (_taskService.QueryConveyorLineTask(station.stationName) != null)
                {
                    if (command.R_Pickuppermitted == 1)
                    ConveyorLineSendFinish(conveyorLine, station.stationName);
                    await LogAndWarn(conveyorLine.DeviceName, $"【{conveyorLine._deviceName}】站台【{station.stationName}】存在任务");
                    return;
                }
                // æ ¹æ®è®¾å¤‡ç¼–号和任务源地址查询所有未执行的任务
                List<Dt_StationManager> childDeviceCodes = _stationManagerService.QueryPlatform(station, taskSourceAddress);  //对应每个ip找全部的下料站点与垫板回收点站台点
                if(childDeviceCodes.Count()==0|| childDeviceCodes == null)
                {
                    ConveyorLineSendFinish(conveyorLine, station.stationName);
                    await LogAndWarn(conveyorLine.DeviceName, $"【{conveyorLine._deviceName}】站台【{station.stationName}】未找到可前往站台");
                    return;
                }
                foreach (var item in childDeviceCodes)
                {
                    IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == item.DeviceCode);
                    if (device != null)
                    {
                        if (AGVStationitem.Station_material == (int)AgvStationEnum.BoardLoad)
                        CommonConveyorLine commonConveyorLine = (CommonConveyorLine)device;
                        ConveyorLineTaskCommand command = commonConveyorLine.ReadCustomer<ConveyorLineTaskCommand>(item.stationName);
                        if (command != null)
                        {
                            Dt_Task agvstack= _taskService.QueryConveyorLineTaskRoadway(AGVStationitem.Station_Area);
                            if(agvstack != null)
                            var structs = BitConverter.GetBytes(command.InteractiveSignal).Reverse().ToArray().ToBoolArray();
                            if (structs[2])
                            {
                                _taskService.UpdateTargetAddress(agvstack.TaskId, AGVStationitem.Station_name);
                                Dt_Task taskDTO = new Dt_Task()
                                {
                                    TaskNum = _taskRepository.GetTaskNo().Result,
                                    Grade = 1,
                                    Roadway = item.stationArea.ToString(),
                                    SourceAddress = station.stationName,
                                    CurrentAddress= station.stationName,
                                    TargetAddress = item.stationName,
                                    NextAddress = item.stationName,
                                    TaskState = (int)AGVTaskStatusEnum.AGVNew,
                                    TaskType = (int)AGVTaskTypeEnum.AGVCarry,
                                    AGVName = item.stationArea switch
                                    {
                                        1 => "AGV01",
                                        4 => "AGV03",
                                        _ => "AGV02",
                                    }
                                };
                                _taskService.ReceiveWMSTask(new List<Dt_Task> { taskDTO });
                                ConveyorLineSendFinish(conveyorLine,station.stationName);
                                return;
                            }
                            else
                            {
                                //去找缓存区库存
                                RequestHcst(conveyorLine, AGVStationitem.Station_Area, AGVStationitem.Station_name, AGVStationitem.Station_remark);
                                await LogAndWarn(conveyorLine.DeviceName, $"站台{item.stationName}状态不可用{structs[2]}");
                            }
                        }
                    }
                    else
                    {
                        wcsWriteLog(AGVStationitem.Station_name, "读取信息", $"通讯连接错误,未找到读取模块地址");
                    }
                }
            }
        }
        public void RequestHcst(CommonConveyorLine conveyorLine,int Station_Area,string Station_names,string Station_remark)
        {
            List<AGVStation> AGVStationListdata = _agvStationService.QuerypLatformmaterial(Station_Area);   //查出缓存位
            if (Station_remark != null)   //找寻对应的放货站台
            {
                AGVStationListdata = _agvStationService.QuerypStation_Area2(Station_remark);
            }
            foreach (var AGVStationitem in AGVStationListdata)
            {
                ConveyorLineCommand command = conveyorLine.ReadCustomer<ConveyorLineCommand>(AGVStationitem.Station_name);
                if (command != null)
                {
                    if (command.R_Releasespermitted == 1)
                    {
                        if (_taskService.QueryConveyorLinetaeersuadd(AGVStationitem.Station_name))
                        else
                        {
                            Dt_Task taskDTO = new Dt_Task()
                            {
                                TaskNum = Convert.ToInt32(DateTime.Now.ToString("HHmmss")) + AGVStationitem.Station_code,
                                Grade = 1,
                                Roadway = AGVStationitem.Station_Area.ToString(),
                                SourceAddress = AGVStationitem.Station_name,
                                CurrentAddress = AGVStationitem.Station_name,
                                TaskState = (int)TaskInStatusEnum.InNew,
                                TaskType = (int)AGVStationitem.Station_material,
                                TargetAddress = Station_names,
                                NextAddress = Station_names,
                            };
                            _taskService.ReceiveWMSTask(taskDTO);
                            WriteInfo(conveyorLine.DeviceName, $"通讯连接错误,{item.stationName}未找到读取模块地址");
                        }
                    }
                    else
                    {
                        wcsWriteLog(AGVStationitem.Station_name, "读取信息", $"通讯连接错误,未找到读取模块地址");
                        var logerror = $"【{conveyorLine.DeviceName}】站台:【{item.stationName}】未配置设备表头";
                        await LogAndWarn(conveyorLine.DeviceName, logerror);
                    }
                }
            }
        }
        public void RequestHcdbst(CommonConveyorLine conveyorLine, int Station_Area, string Station_names,string Station_remark)
        {
            List<AGVStation> AGVStationListdata = _agvStationService.QuerypStation_Area(Station_Area);   //查出缓存位
            if(Station_remark !=null)   //找寻对应的放货站台
            catch (Exception ex)
            {
                AGVStationListdata= _agvStationService.QuerypStation_Area2(Station_remark);
            }
            foreach (var AGVStationitem in AGVStationListdata)
            {
                ConveyorLineCommand command = conveyorLine.ReadCustomer<ConveyorLineCommand>(AGVStationitem.Station_name);
                if (command != null)
                {
                    if (command.R_Releasespermitted == 1)
                    {
                        if (_taskService.QueryConveyorLinetaeersuadd(AGVStationitem.Station_name))
                        {
                            Dt_Task taskDTO = new Dt_Task()
                            {
                                TaskNum = Convert.ToInt32(DateTime.Now.ToString("HHmmss")) + AGVStationitem.Station_code,
                                Grade = 1,
                                Roadway = AGVStationitem.Station_Area.ToString(),
                                SourceAddress = Station_names,
                                CurrentAddress = Station_names,
                                TaskState = (int)TaskInStatusEnum.InNew,
                                TaskType = (int)AGVStationitem.Station_material,
                                TargetAddress = AGVStationitem.Station_name,
                                NextAddress = AGVStationitem.Station_name,
                            };
                            _taskService.ReceiveWMSTask(taskDTO);
                        }
                    }
                    else
                    {
                        wcsWriteLog(AGVStationitem.Station_name, "读取信息", $"读取放货信号为:{command.R_Releasespermitted}");
                    }
                }
                WriteInfo(conveyorLine.DeviceName, ex.Message);
            }
        }
        /// <summary>
        /// è¯»å–信息记录
        /// è¾“送线交互完成
        /// </summary>
        /// <param name="SCLLinStack"></param>
        /// <param name="Logtype"></param>
        /// <param name="Magessadd"></param>
        public void wcsWriteLog(string SCLLinStack,string Logtype,string Magessadd)
        /// <param name="conveyorLine">输送线实例对象</param>
        /// <param name="childDeviceCode">子设备编号</param>
        /// <param name="ProtocalDetailValue">线体当前bool读取偏移地址</param>
        /// <param name="value">值</param>
        public void ConveyorLineSendFinish(CommonConveyorLine conveyorLine, string childDeviceCode)
        {
            WriteLog.Write_Log("站台读取信息记录", SCLLinStack+"站台", Logtype, new{信息 = Magessadd });
            DeviceProDTO? devicePro = conveyorLine.DeviceProDTOs.Where(x => x.DeviceProParamType == nameof(DeviceCommand) && x.DeviceChildCode == childDeviceCode && x.DeviceProParamName == "WriteInteractiveSignal").OrderBy(x => x.DeviceProOffset).FirstOrDefault();
            conveyorLine.Communicator.Write(devicePro.DeviceProAddress, true);
        }
        public async Task LogAndWarn(string deviceName, string log, string color = "red")
        {
            ConsoleHelper.WriteWarningLine(log);
            await _noticeService.Logs(userTokenIds, new { deviceName, log = log, time = DateTime.Now.ToString("G"), color = color });
            WriteInfo(deviceName, log);
        }
    }
}