using HslCommunication; using HslCommunication.Profinet.OpenProtocol; using Mapster; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.CodeAnalysis; using Microsoft.VisualBasic; using MoYu.Logging; using Newtonsoft.Json; using System.Text.RegularExpressions; using System.Threading.Tasks; using WIDESEAWCS_Common; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_Core; using WIDESEAWCS_Core.Helper; using WIDESEAWCS_DTO.MOM; using WIDESEAWCS_DTO.TaskInfo; using WIDESEAWCS_DTO.WMS; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob; using WIDESEAWCS_Tasks.ConveyorLineJob; using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; namespace WIDESEAWCS_Tasks { public partial class CommonConveyorLineJob { /// /// 处理出库任务 /// private void HandleTaskOut(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, string childDeviceCode, int ProtocalDetailValue, Dt_Task taskOut) { if (taskOut == null) return; //ConveyorLineTaskCommand? taskCommand = MapTaskCommand(taskOut, command); var next = taskOut.NextAddress; var taskCommand = MapTaskCommand(taskOut, command); taskOut.NextAddress = next; bool isOutTray = taskOut.TaskType == (int)TaskOutboundTypeEnum.OutTray; bool isOutboundAndOutFinish = taskOut.TaskType == (int)TaskOutboundTypeEnum.Outbound && taskOut.TaskState == (int)TaskOutStatusEnum.SC_OutFinish; bool isOutboundAndLineOutExecuting = taskOut.TaskType == (int)TaskOutboundTypeEnum.Outbound && taskOut.TaskState == (int)TaskOutStatusEnum.Line_OutExecuting; if (isOutTray || isOutboundAndOutFinish || !isOutboundAndLineOutExecuting) { conveyorLine.SendCommand(taskCommand, childDeviceCode); var log = $"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{childDeviceCode}】请求扫码入库,下一目标地址【{taskCommand.TargetAddress}】"; ConsoleHelper.WriteWarningLine(log); _noticeService.Logs(userTokenIds, new { conveyorLine.DeviceName, log = log, time = DateTime.Now.ToString("G"), color = "red" }); WriteInfo(conveyorLine.DeviceName, log); ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true); _taskService.UpdateTaskStatusToNext(taskOut); } else if (taskOut.TaskType == (int)TaskOutboundTypeEnum.OutTray && taskOut.TaskState == (int)TaskOutStatusEnum.Line_OutExecuting) { CompleteWmsTask(taskOut, command, conveyorLine, childDeviceCode, ProtocalDetailValue); } } /// /// 处理新任务 /// public async Task HandleNewTaskAsync(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, string childDeviceCode, int ProtocalDetailValue) { var stationManager = _stationManagerRepository.QueryFirst(x => x.stationChildCode == childDeviceCode && x.stationPLC == conveyorLine.DeviceCode); switch (stationManager.stationType) { case 5: case 1: await RequestWmsTask(conveyorLine, command, childDeviceCode, ProtocalDetailValue, stationManager); break; case 2: case 3: case 4: case 6: await CreateAndSendEmptyTrayTask(conveyorLine, command, childDeviceCode, ProtocalDetailValue, stationManager); break; case 7: RequestOutNextAddress(conveyorLine, command, childDeviceCode, ProtocalDetailValue); break; case 10: ConveyorLineOutFinish(conveyorLine, command, childDeviceCode, ProtocalDetailValue); break; case 20: await JZRequestInBound(conveyorLine, command, childDeviceCode, ProtocalDetailValue, stationManager); break; default: break; } } /// /// 映射任务命令 /// private ConveyorLineTaskCommand MapTaskCommand(Dt_Task task, ConveyorLineTaskCommand command) { // 使用正则表达式匹配类似 -数字 的模式,并替换为空字符串 task.NextAddress = Regex.Replace(task.NextAddress, @"-(\d+)", ""); //if (Convert.ToInt32(task.NextAddress) > 2999) //{ // task.NextAddress = (Convert.ToInt32(task.NextAddress) - 1000).ToString(); //} var comm = _mapper.Map(task); comm.InteractiveSignal = command.InteractiveSignal; return comm; } /// /// 完成WMS任务 /// private void CompleteWmsTask(Dt_Task taskOut, ConveyorLineTaskCommand command, CommonConveyorLine conveyorLine, string childDeviceCode, int ProtocalDetailValue) { if (command.Barcode == "NoRead") { var NGAddress = _platFormRepository.QueryFirst(x => x.PlatCode == taskOut.TargetAddress).Capacity; taskOut.TargetAddress = NGAddress.ToString(); } var keys = new Dictionary() { {"taskNum", taskOut.TaskNum} }; var config = _sys_ConfigService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress); var wmsBase = config.FirstOrDefault(x => x.ConfigKey == SysConfigKeyConst.WMSIP_BASE)?.ConfigValue; var completeTask = config.FirstOrDefault(x => x.ConfigKey == SysConfigKeyConst.CompleteTask)?.ConfigValue; if (wmsBase == null || completeTask == null) { throw new InvalidOperationException("WMS IP 未配置"); } var wmsIpAddress = wmsBase + completeTask; var result = HttpHelper.GetAsync(wmsIpAddress, keys).Result; WebResponseContent content = JsonConvert.DeserializeObject(result); if (content.Status) { ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true); _taskService.UpdateTaskStatusToNext(taskOut); } } /// /// 创建并发送空托盘任务 /// public Task CreateAndSendEmptyTrayTask(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, string childDeviceCode, int ProtocalDetailValue, Dt_StationManager stationManager) { if (command.Barcode != "NoRead") { string isTrue = string.Empty; ResultTrayCellsStatus result = GetResultTrayCellsStatus(command, stationManager); List strings = stationManager.Roadway.Split(",").ToList(); foreach (string item in strings) { isTrue = RequestInboundPlatform(item, result.ProductionLine, true); if (isTrue != null) { break; } } WMSTaskDTO taskDTO = null; if (isTrue != null && isTrue != string.Empty) { taskDTO = new WMSTaskDTO { TaskNum = _taskRepository.GetTaskNo().Result, Grade = 1, PalletCode = command.Barcode, RoadWay = childDeviceCode, SourceAddress = childDeviceCode, TargetAddress = isTrue, TaskState = (int)TaskOutStatusEnum.SC_OutFinish, Id = 2, TaskType = (int)TaskOutboundTypeEnum.OutTray, ProductionLine = result.ProductionLine, }; } else { taskDTO = CreateEmptyTrayTaskDto(command.Barcode, childDeviceCode); ; } if (_taskRepository.QueryFirst(x => x.PalletCode == taskDTO.PalletCode) != null) { WriteInfo(conveyorLine.DeviceName, "当前托盘存在任务"); } CreateEmptyTryTask(conveyorLine, command, childDeviceCode, ProtocalDetailValue, taskDTO); } return Task.CompletedTask; } public Task CreateEmptyTryTask(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, string childDeviceCode, int ProtocalDetailValue, WMSTaskDTO taskDTO) { var content = CreateAndSendTask(taskDTO); if (content.Status) { //var task = _taskService.QueryConveyorLineTask(conveyorLine.DeviceCode, childDeviceCode); var task = _taskService.QueryConveyorLineTask(conveyorLine.DeviceCode, childDeviceCode, command.Barcode); if (task != null) { var next = task.NextAddress; var taskCommand = MapTaskCommand(task, command); task.NextAddress = next; var log = $"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{childDeviceCode}】请求扫码入库(空托盘),下一目标地址【{taskCommand.TargetAddress}】"; ConsoleHelper.WriteWarningLine(log); _noticeService.Logs(userTokenIds, new { conveyorLine.DeviceName, log = log, time = DateTime.Now.ToString("G"), color = "red" }); WriteInfo(conveyorLine.DeviceName, log); conveyorLine.SendCommand(taskCommand, childDeviceCode); ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true); _taskService.UpdateTaskStatusToNext(task); } } return Task.CompletedTask; } public ResultTrayCellsStatus GetResultTrayCellsStatus(ConveyorLineTaskCommand command, Dt_StationManager stationManager) { 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 未配置"); } TrayCellsStatusDto trayCells = new TrayCellsStatusDto() { Software = "WMS", TrayBarcode = command.Barcode, EquipmentCode = stationManager.stationEquipMOM, SessionId = Guid.NewGuid().ToString(), EmployeeNo = "MITest", SceneType = "4", 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("入站校验", $"【{stationManager.stationChildCode}】入站校验请求参数【{trayCells.ToJsonString()}】"); WriteInfo("入站校验", ""); WriteInfo("入站校验", $"【{stationManager.stationChildCode}】入站校验返回参数【{result}】"); ResultTrayCellsStatus result1 = JsonConvert.DeserializeObject(result); return result1; } /// /// 创建空托盘任务DTO /// private WMSTaskDTO CreateEmptyTrayTaskDto(string barcode, string childDeviceCode) { var request = new RequestTaskDto() { Position = childDeviceCode, PalletCode = barcode, }; var config = _sys_ConfigService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress); var wmsBase = config.FirstOrDefault(x => x.ConfigKey == SysConfigKeyConst.WMSIP_BASE)?.ConfigValue; var requestTrayInTask = config.FirstOrDefault(x => x.ConfigKey == SysConfigKeyConst.RequestTrayInTask)?.ConfigValue; if (wmsBase == null || requestTrayInTask == null) { throw new InvalidOperationException("WMS IP 未配置"); } var wmsIpAddrss = wmsBase + requestTrayInTask; var result = HttpHelper.PostAsync(wmsIpAddrss, request.ToJsonString()).Result; if (result == null) return new WMSTaskDTO(); WebResponseContent content = JsonConvert.DeserializeObject(result); if (!content.Status) return new WMSTaskDTO(); return JsonConvert.DeserializeObject(content.Data.ToString()); } /// /// 请求WMS任务 /// private async Task RequestWmsTask(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, string childDeviceCode, int ProtocalDetailValue, Dt_StationManager stationManager) { ResultTrayCellsStatus result = GetResultTrayCellsStatus(command, stationManager); if (childDeviceCode == "1435") { ExecuteConveyorLineTask(conveyorLine, command, ProtocalDetailValue, childDeviceCode); var serialNosError = result.SerialNos.Where(x => x.SerialNoStatus != 1 && x.SerialNoStatus != 4).ToList(); if (serialNosError.Count > 0 || !result.Success || result.SerialNos.Count == 0) { WMSTaskDTO taskDTO = new WMSTaskDTO { TaskNum = _taskRepository.GetTaskNo().Result, Grade = 1, PalletCode = command.Barcode, RoadWay = "CHSC4", SourceAddress = childDeviceCode, TargetAddress = "CHSC4", TaskState = (int)TaskInStatusEnum.InNew, Id = 2, TaskType = (int)TaskInboundTypeEnum.InNG, ProductionLine = result.ProductionLine, }; var Taskcontent = _taskService.ReceiveWMSTask(new List { taskDTO }); if (Taskcontent.Status) { ExecuteConveyorLineTask(conveyorLine, command, ProtocalDetailValue, childDeviceCode); } ConsoleHelper.WriteSuccessLine($"【{stationManager.stationRemark}】【{stationManager.stationChildCode}】{result.MOMMessage}"); return; } else { var Taskcontent = await _taskService.RequestWMSTask(command.Barcode, childDeviceCode); if (Taskcontent.Status) { ExecuteConveyorLineTask(conveyorLine, command, ProtocalDetailValue, childDeviceCode); } } } else { string isTrue = string.Empty; ExecuteConveyorLineTask(conveyorLine, command, ProtocalDetailValue, childDeviceCode); if (result.SerialNos.Count == 0) { var Traycontent = await _taskService.RequestWMSTask(command.Barcode, childDeviceCode); if (Traycontent.Status) { ConsoleHelper.WriteSuccessLine("二封空框请求回流"); ExecuteConveyorLineTask(conveyorLine, command, ProtocalDetailValue, childDeviceCode); } } List strings = stationManager.Roadway.Split(",").ToList(); foreach (string item in strings) { isTrue = RequestInboundPlatform(item, result.ProductionLine, false); if (isTrue != null) { break; } } if (isTrue != null && isTrue != string.Empty) { WMSTaskDTO taskDTO = new WMSTaskDTO { TaskNum = _taskRepository.GetTaskNo().Result, Grade = 1, PalletCode = command.Barcode, RoadWay = childDeviceCode, SourceAddress = childDeviceCode, TargetAddress = isTrue, TaskState = (int)TaskOutStatusEnum.SC_OutFinish, Id = 2, TaskType = (int)TaskOutboundTypeEnum.OutTray, ProductionLine = result.ProductionLine, }; var Taskcontent = _taskService.ReceiveWMSTask(new List { taskDTO }); if (Taskcontent.Status) { ExecuteConveyorLineTask(conveyorLine, command, ProtocalDetailValue, childDeviceCode); } } else { var Taskcontent = await _taskService.RequestWMSTask(command.Barcode, childDeviceCode); if (Taskcontent.Status) { ExecuteConveyorLineTask(conveyorLine, command, ProtocalDetailValue, childDeviceCode); } } } } /// /// 成化入静置 /// /// /// /// /// /// /// /// private async Task JZRequestInBound(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, string childDeviceCode, int ProtocalDetailValue, Dt_StationManager stationManager) { try { StaticVariable.isLineRun = false; if (StaticVariable.isStackerRun) { ExecuteConveyorLineTask(conveyorLine, command, ProtocalDetailValue, childDeviceCode); } ResultTrayCellsStatus resultTrayCellsStatus = GetResultTrayCellsStatus(command, stationManager); //todo判断是否为空框 var serialNosError = resultTrayCellsStatus.SerialNos.Where(x => x.SerialNoStatus != 1 && x.SerialNoStatus != 4).ToList(); if (serialNosError.Count > 0 || !resultTrayCellsStatus.Success) { //NG流程 var platform = _platFormRepository.QueryFirst(x => x.ProductionLine == resultTrayCellsStatus.ProductionLine && x.DeviceCode == "1005"); ConveyorLineTaskCommand conveyorLineTaskCommand = new ConveyorLineTaskCommand() { TaskNum = 1, TargetAddress = Convert.ToInt32(platform.Capacity), Barcode = resultTrayCellsStatus.TrayBarcode, InteractiveSignal = command.InteractiveSignal }; conveyorLine.SendCommand(conveyorLineTaskCommand, childDeviceCode); var logMessage = $"MOM数据异常,送至二封【{resultTrayCellsStatus.ProductionLine}】异常口【{Convert.ToInt32(platform.Capacity)}】"; LogAndSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, logMessage, conveyorLineTaskCommand.TargetAddress.ToString()); return; } if (resultTrayCellsStatus.SerialNos.Count == 0) { var Traycontent = await _taskService.RequestWMSTask(command.Barcode, childDeviceCode); if (Traycontent.Status) { ConsoleHelper.WriteSuccessLine("化成空框请求回流静置"); if (StaticVariable.isStackerRun) { ExecuteConveyorLineTask(conveyorLine, command, ProtocalDetailValue, childDeviceCode); } return; } } else { var configz = _sys_ConfigService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress); var wmsbase = configz.Where(x => x.ConfigKey == SysConfigKeyConst.WMSIP_BASE).FirstOrDefault()?.ConfigValue; var address = configz.Where(x => x.ConfigKey == SysConfigKeyConst.QueryStockInfoForRealTrayJZAsync).FirstOrDefault()?.ConfigValue; if (wmsbase == null || address == null) { throw new InvalidOperationException("WMS IP 未配置"); } var wmsIpAddrss = wmsbase + address; var result = await HttpHelper.PostAsync(wmsIpAddrss, new { ProductLine = resultTrayCellsStatus.ProductionLine, PalletCode = command.Barcode }.ToJsonString()); var StockInfocontent = JsonConvert.DeserializeObject(result); if (StockInfocontent.Status) { var Taskcontent = await _taskService.RequestWMSTask(command.Barcode, childDeviceCode); ConsoleHelper.WriteErrorLine($"{JsonConvert.SerializeObject(Taskcontent)}"); if (Taskcontent.Status) { if (StaticVariable.isStackerRun) { ExecuteConveyorLineTask(conveyorLine, command, ProtocalDetailValue, childDeviceCode); } } else { WriteInfo(conveyorLine.DeviceName, Taskcontent.Message); return; } } else { string isTrue = string.Empty; List strings = stationManager.Roadway.Split(",").ToList(); foreach (string item in strings) { isTrue = RequestInboundPlatform(item, resultTrayCellsStatus.ProductionLine, false); if (isTrue != null) { break; } } if (isTrue != null && isTrue != string.Empty) { WMSTaskDTO taskDTO = new WMSTaskDTO { TaskNum = _taskRepository.GetTaskNo().Result, Grade = 1, PalletCode = command.Barcode, RoadWay = isTrue, SourceAddress = childDeviceCode, TargetAddress = isTrue, TaskState = (int)TaskOutStatusEnum.SC_OutFinish, Id = 2, TaskType = (int)TaskOutboundTypeEnum.InToOut, ProductionLine = resultTrayCellsStatus.ProductionLine, }; var Taskcontent = _taskService.ReceiveWMSTask(new List { taskDTO }); if (Taskcontent.Status) { if (StaticVariable.isStackerRun) { ExecuteConveyorLineTask(conveyorLine, command, ProtocalDetailValue, childDeviceCode); } return; } else { WriteInfo(conveyorLine.DeviceName, Taskcontent.Message); return; } } else { var Task = await _taskService.RequestWMSTask(command.Barcode, childDeviceCode); ConsoleHelper.WriteErrorLine($"{JsonConvert.SerializeObject(Task)}"); if (Task.Status) { if (StaticVariable.isStackerRun) { ExecuteConveyorLineTask(conveyorLine, command, ProtocalDetailValue, childDeviceCode); } } ConsoleHelper.WriteWarningLine("二封缓存位已满"); return; } } } } catch (Exception ex) { ConsoleHelper.WriteWarningLine($"{ex.Message}"); } finally { StaticVariable.isLineRun = true; } } /// /// 执行输送线任务 /// /// 输送线对象 /// 输送线任务命令 /// 协议明细值 /// 子设备编号 public void ExecuteConveyorLineTask(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, int ProtocalDetailValue, string childDeviceCode) { // 查询任务信息 var task = _taskService.QueryBarCodeConveyorLineTask(command.Barcode, childDeviceCode); if (task == null) return; // 获取配置值并转换为列表 var value = _sys_ConfigService.GetByConfigKey(CateGoryConst.CONFIG_SYS_InStation, SysConfigKeyConst.JZNGInBoundStation).ConfigValue; var valueList = value.Split(',').ToList(); // 日志模板 var logMessage = $"【{conveyorLine._deviceName}】任务号:【{task.TaskNum}】,托盘条码:【{task.PalletCode}】已到达【{childDeviceCode}】请求扫码入库(实盘),下一目标地址【{{0}}】"; // 判断任务的起始地址是否在配置列表中 if (valueList.Contains(task.SourceAddress)) { // 设置目标地址为 "1000" conveyorLine.SetValue(ConveyorLineDBName.WriteConveyorLineTargetAddress, "1000", childDeviceCode); // 记录日志并发送完成信号 LogAndSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, logMessage, "1000"); } else if (task.Roadway.Contains("JZ")) { // 查询是否存在静置出库任务 var outJZTask = _taskRepository.QueryData(x => x.Roadway == task.Roadway && task.TaskType == (int)TaskOutboundTypeEnum.Outbound && (x.TaskState == (int)TaskOutStatusEnum.SC_OutExecuting || x.TaskState == (int)TaskOutStatusEnum.SC_OutFinish || x.TaskState == (int)TaskOutStatusEnum.OutNew)); if (!outJZTask.Any()) { // 映射任务命令 var taskCommand = MapTaskCommand(task, command); // 发送任务命令 conveyorLine.SendCommand(taskCommand, childDeviceCode); // 记录日志并发送完成信号 LogAndSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, logMessage, taskCommand.TargetAddress.ToString()); // 更新任务状态 _taskService.UpdateTaskStatusToNext(task); } else { ConsoleHelper.WriteErrorLine("已存在静置出库任务,静置入库任务无法下发至线体"); } } else { // 映射任务命令 var taskCommand = MapTaskCommand(task, command); // 发送任务命令 conveyorLine.SendCommand(taskCommand, childDeviceCode); // 记录日志并发送完成信号 LogAndSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, logMessage, taskCommand.TargetAddress.ToString()); // 更新任务状态 _taskService.UpdateTaskStatusToNext(task); } } /// /// 记录日志并发送完成信号 /// /// 输送线对象 /// 子设备编号 /// 协议明细值 /// 日志消息模板 /// 目标地址 private void LogAndSendFinish(CommonConveyorLine conveyorLine, string childDeviceCode, int ProtocalDetailValue, string logMessage, string targetAddress) { // 格式化日志消息 var log = string.Format(logMessage, targetAddress); // 输出警告日志 ConsoleHelper.WriteWarningLine(log); // 记录日志 _noticeService.Logs(userTokenIds, new { conveyorLine.DeviceName, log, time = DateTime.Now.ToString("G"), color = "red" }); WriteInfo(conveyorLine.DeviceName, log); // 发送完成信号 ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true); } } }