#region << 版 本 注 释 >> /*---------------------------------------------------------------- * 命名空间:WIDESEAWCS_Tasks.ConveyorLineJob * 创建者:胡童庆 * 创建时间:2024/8/2 16:13:36 * 版本:V1.0.0 * 描述: * * ---------------------------------------------------------------- * 修改人: * 修改时间: * 版本:V1.0.1 * 修改说明: * *----------------------------------------------------------------*/ #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.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 :JobBase, IJob { private readonly ITaskService _taskService; private readonly ITaskRepository _taskRepository; private readonly ITaskExecuteDetailService _taskExecuteDetailService; private readonly IRouterService _routerService; private readonly IDt_StationManagerService _stationManagerService; private readonly IMapper _mapper; private readonly ICacheService _cacheService; private readonly INoticeService _noticeService; private static List? userTokenIds; private static List? userIds; 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; _stationManagerService = stationManagerService; _mapper = mapper; _cacheService = cacheService; _noticeService = noticeService; _taskRepository = taskRepository; } public async Task Execute(IJobExecutionContext context) { try { CommonConveyorLine conveyorLine = (CommonConveyorLine)context.JobDetail.JobDataMap.Get("JobParams"); if (conveyorLine != null) { // 获取所有站点管理器 List 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()); } return; } private Task ProcessDeviceAsync(CommonConveyorLine conveyorLine, Dt_StationManager station) { try { ConveyorLineTaskCommand command = conveyorLine.ReadCustomer(station.stationName); if (command != null) { #region 调用事件总线通知前端 // 获取缓存中的用户信息 var tokenInfos = _cacheService.Get>("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? 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; } /// /// 生成取货任务,放至上料位 /// /// 输送线实例对象 /// 读取的请求信息Request outbound /// 子设备编号 public async Task RequestInbound(CommonConveyorLine conveyorLine, Dt_StationManager station) { try { // 输出信息,表示站台请求取货 var log = $"【{conveyorLine._deviceName}】站台【{station.stationName}】请求取货"; await LogAndWarn(conveyorLine.DeviceName, log); // 获取所有任务源地址 List taskSourceAddress = _taskService.QueryConveyorLineTask(); if (_taskService.QueryConveyorLineTask(station.stationName) != null) { ConveyorLineSendFinish(conveyorLine, station.stationName); await LogAndWarn(conveyorLine.DeviceName, $"【{conveyorLine._deviceName}】站台【{station.stationName}】存在任务"); return; } // 根据设备编号和任务源地址查询所有未执行的任务 List 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) { CommonConveyorLine commonConveyorLine = (CommonConveyorLine)device; ConveyorLineTaskCommand command = commonConveyorLine.ReadCustomer(item.stationName); if (command != null) { var structs = BitConverter.GetBytes(command.InteractiveSignal).Reverse().ToArray().ToBoolArray(); if (structs[2]) { 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 { taskDTO }); ConveyorLineSendFinish(conveyorLine,station.stationName); return; } else { await LogAndWarn(conveyorLine.DeviceName, $"站台{item.stationName}状态不可用{structs[2]}"); } } else { WriteInfo(conveyorLine.DeviceName, $"通讯连接错误,{item.stationName}未找到读取模块地址"); } } else { var logerror = $"【{conveyorLine.DeviceName}】站台:【{item.stationName}】未配置设备表头"; await LogAndWarn(conveyorLine.DeviceName, logerror); } } } catch (Exception ex) { WriteInfo(conveyorLine.DeviceName, ex.Message); } } /// /// 输送线交互完成 /// /// 输送线实例对象 /// 子设备编号 /// 线体当前bool读取偏移地址 /// 值 public void ConveyorLineSendFinish(CommonConveyorLine conveyorLine, string childDeviceCode) { 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); } } }