using AutoMapper; using HslCommunication; using NetTaste; using Newtonsoft.Json; using Quartz; using SqlSugar; using System.Reflection; using WIDESEAWCS_BasicInfoRepository; using WIDESEAWCS_BasicInfoService; using WIDESEAWCS_Common; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_Core; using WIDESEAWCS_Core.Helper; using WIDESEAWCS_Core.HttpContextUser; using WIDESEAWCS_DTO.MOM; using WIDESEAWCS_DTO.TaskInfo; using WIDESEAWCS_IProcessRepository; using WIDESEAWCS_ISystemServices; using WIDESEAWCS_ITaskInfoRepository; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob; using WIDESEAWCS_QuartzJob.DeviceBase; using WIDESEAWCS_QuartzJob.DTO; using WIDESEAWCS_QuartzJob.Repository; using WIDESEAWCS_QuartzJob.Service; using WIDESEAWCS_SignalR; using WIDESEAWCS_Tasks.ConveyorLineJob; using ICacheService = WIDESEAWCS_Core.Caches.ICacheService; namespace WIDESEAWCS_Tasks { [DisallowConcurrentExecution] public partial class CommonConveyorLineJob : JobBase, IJob { private readonly ITaskService _taskService; private readonly ITaskRepository _taskRepository; private readonly ITaskExecuteDetailService _taskExecuteDetailService; private readonly IRouterService _routerService; private readonly IPlatFormRepository _platFormRepository; private readonly ISys_ConfigService _sys_ConfigService; private readonly IMapper _mapper; private readonly IDt_StationManagerService _stationManagerService; private readonly IDt_StationManagerRepository _stationManagerRepository; private readonly ICacheService _cacheService; private readonly INoticeService _noticeService; private readonly IDeviceInfoRepository _deviceInfoRepository; private static List? userTokenIds; private static List? userIds; public CommonConveyorLineJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, IRouterService routerService, IMapper mapper, ITaskRepository taskRepository, IPlatFormRepository platFormRepository, ISys_ConfigService sys_ConfigService, IDt_StationManagerService stationManagerService, IDt_StationManagerRepository stationManagerRepository, ICacheService cacheService, INoticeService noticeService, IDeviceInfoRepository deviceInfoRepository) { _taskService = taskService; _taskExecuteDetailService = taskExecuteDetailService; _routerService = routerService; _mapper = mapper; _taskRepository = taskRepository; _platFormRepository = platFormRepository; _sys_ConfigService = sys_ConfigService; _stationManagerService = stationManagerService; _stationManagerRepository = stationManagerRepository; _cacheService = cacheService; _noticeService = noticeService; _deviceInfoRepository = deviceInfoRepository; } public async Task Execute(IJobExecutionContext context) { string jobName = context.JobDetail.Key.Name; try { // 从JobDataMap中获取传递的参数 CommonConveyorLine conveyorLine = (CommonConveyorLine)context.JobDetail.JobDataMap.Get("JobParams"); if (conveyorLine != null) { // 查询所有子设备的位置 List childDeviceCodes = _routerService.QueryAllPositions(conveyorLine.DeviceCode); // 并行处理每个子设备 var tasks = childDeviceCodes.Select(childDeviceCode => ProcessDeviceAsync(conveyorLine, childDeviceCode)).ToList(); await Task.WhenAll(tasks); // 获取所有站点管理器 List stationManagers = _stationManagerService.GetAllStationByDeviceCode(conveyorLine.DeviceCode); foreach (var station in stationManagers) { if (station.stationType == 11) { // 读取任务命令和设备命令 ConveyorLineTaskCommand command = conveyorLine.ReadCustomer(station.stationChildCode); ConveyorLineTaskCommandWrite commandWrite = conveyorLine.ReadCustomer(station.stationChildCode, "DeviceCommand"); if (command != null && commandWrite != null) { // 将交互信号转换为布尔数组 var structs = BitConverter.GetBytes(commandWrite.WriteInteractiveSignal).Reverse().ToArray().ToBoolArray(); if (structs[0] == true) { // 输出警告信息 ConsoleHelper.WriteWarningLine($"【{conveyorLine.DeviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{station.stationChildCode}】空托盘请求扫码入库"); // 处理入库请求 NGRequestTaskInbound(conveyorLine, command, station.stationChildCode, 0, station.stationLocation); } else { // 发送完成信号 ConveyorLineSendFinish(conveyorLine, station.stationChildCode, 0, false); } } } else if (station.stationType == 5) { // 读取任务命令和设备命令 ConveyorLineTaskCommand command = conveyorLine.ReadCustomer(station.stationChildCode); ConveyorLineTaskCommandWrite commandWrite = conveyorLine.ReadCustomer(station.stationChildCode, "DeviceCommand"); if (command != null && commandWrite != null) { // 将交互信号转换为布尔数组 var structs = BitConverter.GetBytes(commandWrite.WriteInteractiveSignal).Reverse().ToArray().ToBoolArray(); if (structs[0] == true) { // 检查是否存在任务 if (_taskRepository.QueryData(x => x.SourceAddress == station.stationChildCode).Count() > 0) { return; } // 输出警告信息 ConsoleHelper.WriteWarningLine($"【{conveyorLine.DeviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{station.stationChildCode}】异常口请求扫码入库"); // 处理新任务 await HandleNewTaskAsync(conveyorLine, command, station.stationChildCode, 0); } else { // 发送完成信号 ConveyorLineSendFinish(conveyorLine, station.stationChildCode, 0, false); } } } } } } catch (Exception ex) { // 输出异常信息 Console.Out.WriteLine(nameof(CommonConveyorLineJob) + ":" + ex.ToString()); } return; } private Task ProcessDeviceAsync(CommonConveyorLine conveyorLine, string childDeviceCode) { try { // 读取任务命令和设备命令 ConveyorLineTaskCommand command = conveyorLine.ReadCustomer(childDeviceCode); ConveyorLineTaskCommandWrite commandWrite = conveyorLine.ReadCustomer(childDeviceCode, "DeviceCommand"); if (command != null && commandWrite != null) { #region 调用事件总线通知前端 // 获取缓存中的用户信息 if (userTokenIds == null && userIds == null) { 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(); // 构造通知数据 object obj = new { command, commandWrite }; // 发送通知 _noticeService.LineData(userIds.FirstOrDefault(), userTokenIds, new { conveyorLine.DeviceName, childDeviceCode, data = obj }); } } else { // 构造通知数据 object obj = new { command, commandWrite }; // 发送通知 _noticeService.LineData(userIds.FirstOrDefault(), userTokenIds, new { conveyorLine.DeviceName, childDeviceCode, data = obj }); } #endregion 调用事件总线通知前端 // 将交互信号转换为布尔数组 var writeInteractiveSignal = commandWrite.WriteInteractiveSignal; var structs = BitConverter.GetBytes(writeInteractiveSignal).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 = item.ProtocalDetailValue.ObjToInt(); if (structs[itemValue] == true) { // 获取处理方法 MethodInfo? method = GetType().GetMethod(item.ProtocolDetailType); if (method != null) { command.InteractiveSignal = writeInteractiveSignal; // 调用处理方法 method.Invoke(this, new object[] { conveyorLine, command, childDeviceCode, itemValue }); } } else { // 发送完成信号 ConveyorLineSendFinish(conveyorLine, childDeviceCode, itemValue, false); } } } // 查询平台信息 Platform platform = _platFormRepository.QueryFirst(x => x.PLCCode == conveyorLine.DeviceCode && x.PlatCode == childDeviceCode && x.Status == "Active"); if (platform != null && !string.IsNullOrEmpty(platform.Location)) { var strings = platform.Location.Split(',').ToList(); foreach (var ite in strings) { // 读取任务命令 ConveyorLineTaskCommand command1 = conveyorLine.ReadCustomer(ite); if (command1.InteractiveSignal != 2) { command.InteractiveSignal = writeInteractiveSignal; int count = strings.Count; // 获取处理方法 MethodInfo? method = GetType().GetMethod(platform.ExecutionMethod); if (method != null) { command.InteractiveSignal = commandWrite.WriteInteractiveSignal; // 调用处理方法 method.Invoke(this, new object[] { conveyorLine, command, childDeviceCode, count, platform }); }; } } } //if (conveyorLine.DeviceCode == "1001") //{ // ConsoleHelper.WriteSuccessLine("ProcessDeviceAsync方法结束时间:" + DateTime.Now.ToString("G") + $"点位:{childDeviceCode}"); //} } } catch (Exception ex) { } return Task.CompletedTask; } #region 入库 /// /// 输送线请求入库 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 /// 线体当前bool读取偏移地址 public async Task RequestInbound(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, string childDeviceCode, int ProtocalDetailValue) { try { // 输出警告信息,表示任务已到达子设备并请求扫码入库 var log = $"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{childDeviceCode}】请求扫码入库"; ConsoleHelper.WriteWarningLine(log); // 发送通知 await _noticeService.Logs(userTokenIds, new { conveyorLine.DeviceName, log = log, time = DateTime.Now.ToString("G"), color = "red" }); WriteInfo(conveyorLine.DeviceName, log); // 查询条码对应的任务 var task = _taskService.QueryBarCodeConveyorLineTask(command.Barcode, childDeviceCode); if (task != null) { // 如果任务类型是出库或出托盘,则处理出库任务 if (task.TaskType == (int)TaskOutboundTypeEnum.OutTray || task.TaskType == (int)TaskOutboundTypeEnum.Outbound) { HandleTaskOut(conveyorLine, command, childDeviceCode, ProtocalDetailValue, task); } else { // 获取任务的下一目标地址 var next = task.NextAddress; // 将任务映射为命令 var taskCommand = MapTaskCommand(task, command); // 恢复任务的下一目标地址 task.NextAddress = next; // 发送命令到子设备 conveyorLine.SendCommand(taskCommand, childDeviceCode); // 输出警告信息,表示任务已到达子设备并请求扫码入库,下一目标地址 ConsoleHelper.WriteWarningLine($"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{childDeviceCode}】请求扫码入库,下一目标地址【{taskCommand.TargetAddress}】"); // 发送任务完成通知 ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true); // 更新任务状态为下一状态 _taskService.UpdateTaskStatusToNext(task); } } else { // 如果任务为空且条码不为"NoRead"且条码不为空,则处理新任务 if (task == null && command.Barcode != "NoRead" && command.Barcode.IsNotEmptyOrNull()) { // 查询条码对应的任务 task = _taskService.QueryBarcodeTask(command.Barcode, childDeviceCode); if (task == null) // 异步处理新任务 await HandleNewTaskAsync(conveyorLine, command, childDeviceCode, ProtocalDetailValue); } } } catch (Exception ex) { // 捕获并输出异常信息 Console.Out.WriteLine(ex.ToString()); } } #region 输送线请求入库下一地址 /// /// 输送线请求入库下一地址 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 public void RequestInNextAddress(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, string childDeviceCode) { ConsoleHelper.WriteWarningLine($"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{childDeviceCode}】请求入库下一地址"); Dt_Task task = _taskService.QueryExecutingConveyorLineTask(command.TaskNum, childDeviceCode); if (task != null) { if (command.Barcode == task.PalletCode) { Dt_Task? newTask = _taskService.UpdatePosition(task.TaskNum, task.CurrentAddress); if (newTask != null) { //ConveyorLineTaskCommand taskCommand = _mapper.Map(newTask); //taskCommand.InteractiveSignal = command.InteractiveSignal; var next = newTask.NextAddress; var taskCommand = MapTaskCommand(newTask, command); newTask.NextAddress = next; ConsoleHelper.WriteWarningLine($"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{childDeviceCode}】请求入库下一地址,下一目标地址【{taskCommand.TargetAddress}】"); conveyorLine.SendCommand(taskCommand, childDeviceCode); } } } } #endregion 输送线请求入库下一地址 /// /// 输送线入库完成 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 /// 线体当前bool读取偏移地址 public void ConveyorLineInFinish(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, string childDeviceCode, int ProtocalDetailValue) { try { ConsoleHelper.WriteWarningLine($"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{childDeviceCode}】输送线入库完成"); var task = _taskService.QueryExecutingConveyorLineTask(command.TaskNum, childDeviceCode); if (task != null && task.TaskState != (int)TaskInStatusEnum.Line_InFinish) { if (command.Barcode == task.PalletCode && childDeviceCode == task.NextAddress) { //conveyorLine.SetValue(ConveyorLineDBName.ConveyorLineTargetAddress, "1000", childDeviceCode); ConsoleHelper.WriteWarningLine($"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{childDeviceCode}】输送线入库完成,下一目标地址【等待分配货位,并写入1000】"); ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true); if (task.TaskType == (int)TaskInboundTypeEnum.InNG) { int nextStatus = task.TaskState.GetNextNotCompletedStatus(); var station = _stationManagerRepository.QueryFirst(x => x.stationChildCode == task.SourceAddress); task.CurrentAddress = station.stationLocation; task.NextAddress = station.stationNGLocation; task.TargetAddress = task.NextAddress; task.TaskState = nextStatus; task.ModifyDate = DateTime.Now; task.Modifier = "System"; _taskRepository.UpdateData(task); } else { WebResponseContent content = _taskService.UpdateTaskStatusToNext(task); Console.Out.WriteLine(content.ToJsonString()); } } } } catch (Exception ex) { } } #endregion 入库 #region 出库 /// /// 输送线请求出信息 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 /// 线体当前bool读取偏移地址 public void RequestOutbound(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, string childDeviceCode, int ProtocalDetailValue) { try { // 查询输送线任务,根据输送线设备和子设备代码获取任务信息 var task = _taskService.QueryConveyorLineTask(conveyorLine.DeviceCode, childDeviceCode); // 输出成功信息,包括输送线名称、任务号、托盘条码和子设备代码,以及任务信息 ConsoleHelper.WriteSuccessLine($"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{childDeviceCode}】输送线请求出库,task{task.ToJsonString()}"); // 如果任务不为空,则执行以下操作 if (task != null) { // 获取任务的下一目标地址 var next = task.NextAddress; // 将任务命令映射到当前任务 var taskCommand = MapTaskCommand(task, command); // 恢复任务的下一目标地址 task.NextAddress = next; // 输出成功信息,包括输送线名称、任务号、托盘条码、子设备代码和下一目标地址 ConsoleHelper.WriteSuccessLine($"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{childDeviceCode}】输送线请求出库,下一目标地址【{taskCommand.TargetAddress}】"); // 向输送线发送命令 conveyorLine.SendCommand(taskCommand, childDeviceCode); // 完成输送线发送任务,并更新任务状态 ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true); // 更新任务状态到下一个状态 _taskService.UpdateTaskStatusToNext(task); // 如果任务的目标地址是"1020-1",则再次更新任务状态到下一个状态 if (task.TargetAddress == "1020-1") { _taskService.UpdateTaskStatusToNext(task); } } } catch (Exception ex) { } } /// /// 输送线请求出库下一地址 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 public void RequestOutNextAddress(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, string childDeviceCode, int ProtocalDetailValue) { // 打印成功日志,显示当前设备名称、任务号、托盘条码以及请求出库下一地址的子设备代码 ConsoleHelper.WriteSuccessLine($"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{childDeviceCode}】输送线请求出库下一地址"); // 查询正在执行的输送线任务,根据任务号和子设备代码获取任务信息 Dt_Task task = _taskService.QueryExecutingConveyorLineTask(command.TaskNum, childDeviceCode); // 如果任务存在 if (task != null) { // 检查任务中的托盘条码是否与命令中的托盘条码一致 if (command.Barcode == task.PalletCode) { // 更新任务的位置信息,并获取更新后的任务对象 Dt_Task? newTask = _taskService.UpdatePosition(task.TaskNum, task.CurrentAddress); // 如果更新后的任务对象不为空 if (newTask != null) { // 获取下一目标地址 var next = newTask.NextAddress; // 将新任务对象映射为任务命令对象 var taskCommand = MapTaskCommand(newTask, command); // 恢复新任务对象的下一目标地址 newTask.NextAddress = next; // 打印成功日志,显示当前设备名称、任务号、托盘条码、子设备代码以及下一目标地址 ConsoleHelper.WriteSuccessLine($"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{childDeviceCode}】输送线请求出库下一地址,下一目标地址【{taskCommand.TargetAddress}】"); // 发送任务命令到子设备 conveyorLine.SendCommand(taskCommand, childDeviceCode); // 标记输送线发送任务完成 ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true); } } } } /// /// 输送线出库完成 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 public void ConveyorLineOutFinish(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, string childDeviceCode, int ProtocalDetailValue) { try { // 打印成功信息,表示托盘已到达指定输送线并完成出库 ConsoleHelper.WriteSuccessLine($"【{conveyorLine.DeviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{childDeviceCode}】输送线出库完成"); // 查询正在执行的输送线任务 var task = _taskService.QueryExecutingConveyorLineTask(command.TaskNum, childDeviceCode); // 如果任务存在 if (task != null) { // 如果任务中的托盘条码与命令中的托盘条码一致 if (command.Barcode == task.PalletCode) { // 创建一个空的WebResponseContent对象 WebResponseContent content = new WebResponseContent(); // 保存任务的下一目标地址 var next = task.NextAddress; // 将任务映射为命令 var taskCommand = MapTaskCommand(task, command); // 恢复任务的下一目标地址 task.NextAddress = next; // 如果任务的托盘条码与命令中的托盘条码不一致或者任务备注为"NG" if (task.PalletCode != command.Barcode || task.Remark == "NG") { // 查询目标地址的容量 var NGAddress = _platFormRepository.QueryFirst(x => x.PlatCode == task.TargetAddress).Capacity; // 设置命令的目标地址为NG地址 taskCommand.TargetAddress = NGAddress; } else { // 设置命令的目标地址为1000 taskCommand.TargetAddress = 1000; } // 打印成功信息,表示托盘已到达指定输送线并完成出库,下一目标地址已确定 ConsoleHelper.WriteSuccessLine($"【{conveyorLine.DeviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{childDeviceCode}】输送线出库完成,下一目标地址【{taskCommand.TargetAddress}】"); // 发送命令到输送线 conveyorLine.SendCommand(taskCommand, childDeviceCode); // 完成输送线发送 ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true); // 更新任务状态到下一个状态 content = _taskService.UpdateTaskStatusToNext(task); } else { // 查询目标地址的容量 var NGAddress = _platFormRepository.QueryFirst(x => x.PlatCode == task.TargetAddress).Capacity; // 打印成功信息,表示托盘已到达指定输送线并完成出库,下一目标地址已确定 ConsoleHelper.WriteSuccessLine($"【{conveyorLine.DeviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{childDeviceCode}】输送线出库完成,下一目标地址【{NGAddress}】"); // 设置输送线的目标地址为NG地址 conveyorLine.SetValue(ConveyorLineDBName.ConveyorLineTargetAddress, NGAddress, childDeviceCode); // 完成输送线发送 ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true); // 更新任务状态到下一个状态 _taskService.UpdateTaskStatusToNext(task); } } } catch (Exception ex) { } } #endregion 出库 /// /// 输送线交互完成 /// /// 输送线实例对象 /// 子设备编号 /// 线体当前bool读取偏移地址 /// 值 public void ConveyorLineSendFinish(CommonConveyorLine conveyorLine, string childDeviceCode, int ProtocalDetailValue, bool value) { // 从conveyorLine中的DeviceProDTOs列表中查找第一个符合条件的DeviceProDTO对象 // 条件是DeviceProParamType等于DeviceCommand,且DeviceChildCode等于childDeviceCode // 查找结果按DeviceProOffset升序排列 DeviceProDTO? devicePro = conveyorLine.DeviceProDTOs.Where(x => x.DeviceProParamType == nameof(DeviceCommand) && x.DeviceChildCode == childDeviceCode).OrderBy(x => x.DeviceProOffset).FirstOrDefault(); // 将devicePro的DeviceProAddress按'.'分割成字符串数组x string[] x = devicePro.DeviceProAddress.Split('.'); // 将数组x的最后一个元素替换为ProtocalDetailValue加1后的字符串形式 x[x.Length - 1] = (ProtocalDetailValue + 1).ToString(); // 将修改后的数组x重新拼接成字符串,作为新的DeviceProAddress string DeviceProAddress = string.Join(".", x); // 使用conveyorLine的Communicator对象的Write方法,将value写入新的DeviceProAddress地址 conveyorLine.Communicator.Write(DeviceProAddress, value); } #region 检测空盘实盘任务 /// /// 监测空托盘实盘出库 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 /// 线体当前bool读取偏移地址 // 定义一个异步方法,用于处理空托盘返回任务 public async void EmptyTrayReturn(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, string childDeviceCode, int index, Platform platform) { try { // 定义任务类型枚举变量 TaskOutboundTypeEnum taskOutboundTypeEnum; // 根据平台类型设置任务类型枚举 if (platform.PlatformType.Contains("OutTray")) taskOutboundTypeEnum = TaskOutboundTypeEnum.OutTray; else taskOutboundTypeEnum = TaskOutboundTypeEnum.Outbound; // 调用检查并创建任务的方法 await CheckAndCreateTask(taskOutboundTypeEnum, childDeviceCode, index, platform); } catch (Exception) { // 捕获并忽略异常 } } /// /// 检查任务并创建新任务 /// private async Task CheckAndCreateTask(TaskOutboundTypeEnum taskType, string childDeviceCode, int index, Platform platform) { // 查询数据库中已有的任务 var tasks = _taskRepository.QueryData(x => x.TaskType == (int)taskType && x.TargetAddress == childDeviceCode); // 如果已有任务数量小于指定索引 if (tasks.Count < index) { // 调用WMS获取出库任务 #region 调用WMS获取出库任务 // 定义WMS任务数据传输对象 WMSTaskDTO taskDTO = new WMSTaskDTO(); // 获取WMS IP地址配置 var config = _sys_ConfigService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress); var wmsBase = config.FirstOrDefault(x => x.ConfigKey == SysConfigKeyConst.WMSIP_BASE)?.ConfigValue; var requestTrayOutTask = config.FirstOrDefault(x => x.ConfigKey == SysConfigKeyConst.RequestTrayOutTask)?.ConfigValue; // 如果WMS IP地址未配置,抛出异常 if (wmsBase == null || requestTrayOutTask == null) { throw new InvalidOperationException("WMS IP 未配置"); } var wmsIpAddress = wmsBase + requestTrayOutTask; var device = _deviceInfoRepository.QueryData(x => x.DeviceStatus == "1" && x.DeviceRemark == platform.Id.ToString()); var deviceCode = device.Select(x => x.DeviceCode).ToList(); // 发送HTTP POST请求获取任务数据 var result = await HttpHelper.PostAsync(wmsIpAddress, new { position = childDeviceCode, tag = (int)taskType, areaCdoe = platform.Stacker, AreaCdoes = deviceCode, platform.ProductionLine }.ToJsonString()); // 解析返回的JSON数据 WebResponseContent content = JsonConvert.DeserializeObject(result); // 检查返回状态,如果失败则返回 if (!content.Status) return; // 解析任务数据 taskDTO = JsonConvert.DeserializeObject(content.Data.ToString()); #endregion 调用WMS获取出库任务 // 创建并发送任务 CreateAndSendTask(taskDTO); } } /// /// 创建任务 /// public WebResponseContent CreateAndSendTask(WMSTaskDTO taskDTO) { var content = _taskService.ReceiveWMSTask(new List { taskDTO }); if (content.Status) { Console.WriteLine($"{taskDTO.TaskType}呼叫成功"); } return content; } #endregion 检测空盘实盘任务 #region 设备NG口入库 public void NGRequestTaskInbound(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, string childDeviceCode, int ProtocalDetailValue, string TargetAddress) { var config = _sys_ConfigService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress); var wmsBase = config.FirstOrDefault(x => x.ConfigKey == SysConfigKeyConst.MOMIP_BASE)?.ConfigValue; var ipAddress = config.FirstOrDefault(x => x.ConfigKey == SysConfigKeyConst.TrayCellsStatus)?.ConfigValue; if (wmsBase == null || ipAddress == null) { throw new InvalidOperationException("MOM IP 未配置"); } Dt_StationManager stationManager = _stationManagerRepository.QueryFirst(x => x.stationPLC == conveyorLine.DeviceCode && x.stationChildCode == childDeviceCode); TrayCellsStatusDto trayCells = new TrayCellsStatusDto() { Software = "WMS", TrayBarcode = command.Barcode, EquipmentCode = stationManager.stationEquipMOM, SessionId = Guid.NewGuid().ToString(), EmployeeNo = "MITest", SceneType = "1", RequestTime = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now).ToString("yyyy-MM-ddTHH:mm:ss.fffZ") }; var MOMIpAddress = wmsBase + ipAddress; var result = HttpHelper.PostAsync(MOMIpAddress, trayCells.ToJsonString()).Result; WriteInfo("入站校验", $"【{childDeviceCode}】入站校验请求参数【{trayCells.ToJsonString()}】"); WriteInfo("入站校验", ""); WriteInfo("入站校验", $"【{childDeviceCode}】入站校验返回参数【{result}】"); ResultTrayCellsStatus result1 = JsonConvert.DeserializeObject(result); if (result1.Success) { var serialNosError = result1.SerialNos.Where(x => x.SerialNoStatus != 1).ToList(); if (serialNosError.Count > 0) { return; } if (result1.SerialNos.Count <= 0) { // 空托盘入库逻辑 Dt_Task dt_Task = new Dt_Task() { TargetAddress = TargetAddress, PalletCode = command.Barcode, NextAddress = TargetAddress, TaskNum = 0 }; var next = dt_Task.NextAddress; var taskCommand = MapTaskCommand(dt_Task, command); dt_Task.NextAddress = next; conveyorLine.SendCommand(taskCommand, childDeviceCode); ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true); } else { conveyorLine.SetValue(ConveyorLineDBName.ConveyorLineTargetAddress, 1000, childDeviceCode); ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true); } } else { ConsoleHelper.WriteErrorLine(result1.MOMMessage); } } #endregion 化成NG口入库 } }