#region << 版 本 注 释 >> /*---------------------------------------------------------------- * 命名空间:WIDESEAWCS_TaskInfoService * 创建者:胡童庆 * 创建时间:2024/8/2 16:13:36 * 版本:V1.0.0 * 描述: * * ---------------------------------------------------------------- * 修改人: * 修改时间: * 版本:V1.0.1 * 修改说明: * *----------------------------------------------------------------*/ #endregion << 版 本 注 释 >> using AutoMapper; using AutoMapper.Internal; using Castle.Components.DictionaryAdapter.Xml; using HslCommunication; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.OpenApi.Any; using NetTaste; using Newtonsoft.Json; using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime; using OfficeOpenXml.FormulaParsing.Excel.Functions.Math; using OfficeOpenXml.FormulaParsing.Excel.Functions.Text; using SqlSugar; using StackExchange.Profiling.Internal; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Metadata; using System.Security.Cryptography.Xml; using System.Security.Policy; using System.Text; using System.Threading.Tasks; using WIDESEA_Comm.Http; using WIDESEA_Common.Log; using WIDESEA_Core.Enums; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_Core; using WIDESEAWCS_Core.BaseServices; using WIDESEAWCS_Core.Enums; using WIDESEAWCS_Core.Utilities; using WIDESEAWCS_DTO.Enum; using WIDESEAWCS_DTO.TaskInfo; using WIDESEAWCS_ITaskInfoRepository; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob; using WIDESEAWCS_QuartzJob.DTO; using WIDESEAWCS_QuartzJob.Models; using WIDESEAWCS_QuartzJob.Service; using WIDESEAWCS_TaskInfoRepository; using static Microsoft.IO.RecyclableMemoryStreamManager; namespace WIDESEAWCS_TaskInfoService { public partial class TaskService { //============================================以下是后续新增内容查找任务============================================================= #region wms任务模块 //任务下发 public ApiResponse saveTask(TransferTask transfer) { WriteLog.Write_Log("WMS任务下发接口", "WMS任务下发接口信息", "调取参数", transfer); ApiResponse apiResponse = new ApiResponse(); try { if (transfer == null) return apiResponse.ErrorResponse("接收的WMS任务下发参数为空"); // 进一步校验必要字段 if (string.IsNullOrEmpty(transfer.taskType)) return apiResponse.ErrorResponse("任务类型不能为空"); if (string.IsNullOrEmpty(transfer.barCode)) return apiResponse.ErrorResponse("条码不能为空"); if (transfer.from == null || string.IsNullOrEmpty(transfer.from.code)) return apiResponse.ErrorResponse("起始位置不能为空"); if (transfer.to == null || string.IsNullOrEmpty(transfer.to.code)) return apiResponse.ErrorResponse("目标位置不能为空"); if (transfer.device == null || string.IsNullOrEmpty(transfer.device.uuid)) return apiResponse.ErrorResponse("设备标识不能为空"); Dt_Task? setask = BaseDal.QueryData(x => x.WMStaskid == transfer.barCode).FirstOrDefault(); if (setask != null) return apiResponse.ErrorResponse($"WCS已有当前任务,不可重复下发,托盘编号:{transfer.barCode}"); (int TaskType, int TaskState) = transfer.taskType switch { "in" => ((int)TaskTypeEnum.Inbound, (int)TaskInStatusEnum.InNew), "out" => ((int)TaskTypeEnum.Outbound, (int)TaskOutStatusEnum.OutNew), "check" => ((int)TaskTypeEnum.Inventorybound, (int)TaskinventoryStatusEnum.inventoryNew), _ => (0, 0) // 保持原有的默认值 }; Dt_Task task = new Dt_Task(); task.TaskNum = BaseDal.GetTaskNum(nameof(SequenceEnum.SeqTaskNum)); //任务编号 task.PalletCode = transfer.original_barCode; task.Roadway = transfer.from.code.Substring(0, 1); task.TaskType = TaskType; task.TaskState = TaskState; task.SourceAddress = transfer.from.code; task.TargetAddress = transfer.to.code; task.CurrentAddress = transfer.from.code; task.NextAddress = transfer.to.code; task.Grade = 1; task.Creater = "WMS"; task.CreateDate = DateTime.Now; task.WMStaskid = transfer.barCode; task.deviceuuid = transfer.device.uuid; _unitOfWorkManage.BeginTran(); BaseDal.AddData(task); _unitOfWorkManage.CommitTran(); return apiResponse.SuccessResponse(); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return apiResponse.ErrorResponse($"WCS任务添加错误,原因:{ex.Message}"); } } //通知库口上料完成 public ApiResponse scanData(TaskReportingData taskReporting) { WriteLog.Write_Log("通知库口上料完成接口", "通知库口上料完成信息", "调取参数", taskReporting); ApiResponse apiResponse = new ApiResponse(); try { if (taskReporting == null) return apiResponse.ErrorResponse("接收的WMS任务下发参数为空"); if (taskReporting.baseInfo == null) return apiResponse.ErrorResponse("库口基础数据baseInfo不能为空"); if (string.IsNullOrWhiteSpace(taskReporting.baseInfo.code)) return apiResponse.ErrorResponse("任务类型不能为空"); if (taskReporting.details == null || !taskReporting.details.Any()) return apiResponse.ErrorResponse("库口详情集合details不能为空/无数据"); return apiResponse.SuccessResponse(); } catch (Exception ex) { return apiResponse.ErrorResponse($"WCS任务添加错误,原因:{ex.Message}"); } } //获取库口状态 public ApiResponse getPortStatus(string[] datas) { WriteLog.Write_Log("获取库口状态接口", "获取库口状态信息", "调取参数", datas); ApiResponse apiResponse = new ApiResponse(); try { Dictionary portStatusDict = new Dictionary(); foreach (string DeStateName in datas) { string DeciceCodes = "1003"; if (DeStateName.StartsWith("C")) DeciceCodes = "1004"; IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == DeciceCodes); if (device == null) return apiResponse.ErrorResponse("WCS未能获取到库口实例"); CommonConveyorLine conveyorLine = (CommonConveyorLine)device; //是否可进出 DeviceProDTO? deviceProDTO = conveyorLine.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == DeStateName && x.DeviceProParamName == "PermitHandShake"); //是否有货 DeviceProDTO? StationNumProDTO = conveyorLine.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == DeStateName && x.DeviceProParamName == "StationNum"); if (deviceProDTO == null || StationNumProDTO ==null) return apiResponse.ErrorResponse($"WCS未找到库口:{DeStateName},对应的协议"); int statusValue = 0; //1允许取 2允许放 int portStatus = conveyorLine.Communicator.Read(deviceProDTO.DeviceProAddress); //是否有货 int StationStatus = conveyorLine.Communicator.Read(StationNumProDTO.DeviceProAddress); if(DeStateName== "G01" || DeStateName == "G06" || DeStateName == "G07") { //有货,可进信号 statusValue = (portStatus == 1 && StationStatus == 1) ? 1 : (portStatus == 2 && StationStatus == 0) ?0: (portStatus == 0) ? 0 : 0; } else { statusValue = StationStatus == 1 ? 0 : 1; } portStatusDict[DeStateName] = statusValue; } return apiResponse.SuccessResponse(portStatusDict); } catch (Exception ex) { return apiResponse.ErrorResponse($"WCS任务添加错误,原因:{ex.Message}"); } } //获取光幕状态 public ApiResponse getSafeStatus(string[] datas) { WriteLog.Write_Log("获取光幕状态接口", "获取光幕状态信息", "调取参数", setCurtain); ApiResponse apiResponse = new ApiResponse(); try { Dictionary portStatusDict = new Dictionary(); foreach (string DeStateName in datas) { portStatusDict[DeStateName] = 1; } return apiResponse.SuccessResponse(portStatusDict); } catch (Exception ex) { return apiResponse.ErrorResponse($"WCS任务添加错误,原因:{ex.Message}"); } } //设置光幕 public ApiResponse setCurtain(SetCurtainRequest setCurtain) { ApiResponse apiResponse = new ApiResponse(); bool HandShakeboolOPEN = false; bool HandShakeboolCLOSE = false; try { Dictionary portStatusDict = new Dictionary(); foreach (string DeStateName in setCurtain.Datas) { string DeciceCodes = "1003"; if (DeStateName.StartsWith("C")) DeciceCodes = "1004"; IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == DeciceCodes); if (device == null) return apiResponse.ErrorResponse("WCS未能获取到库口实例"); CommonConveyorLine conveyorLine = (CommonConveyorLine)device; DeviceProDTO? HandShake = conveyorLine.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == DeStateName && x.DeviceProParamName == "HandShake"); if (HandShake == null) return apiResponse.ErrorResponse($"WCS未找到库口:{setCurtain.Datas},对应的协议"); DeviceProDTO? Request = conveyorLine.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == DeStateName && x.DeviceProParamName == "Request"); if (HandShake == null) return apiResponse.ErrorResponse($"WCS未找到库口:{setCurtain.Datas},对应的协议"); if (setCurtain.Operate.Equals("OPEN")) { //写入plc,agv退出中打开信号 HandShakeboolOPEN = conveyorLine.Communicator.Write(Request.DeviceProAddress, 0); WriteLog.Write_Log("设置打开光幕接口", "设置打开光幕信息", $"库口名称:【{DeStateName}】,打开光幕信号地址:【{Request.DeviceProAddress}】,读取数据:【{conveyorLine.Communicator.Read(Request.DeviceProAddress)}】\n" + $"写入打开光幕信号是否成功返回值:【{HandShakeboolOPEN}】"); } else { //写入plc,agv进入关闭光栅信号 HandShakeboolCLOSE = conveyorLine.Communicator.Write(HandShake.DeviceProAddress, 1)&& conveyorLine.Communicator.Write(Request.DeviceProAddress, 1); WriteLog.Write_Log("设置关闭光幕接口", "设置关闭光幕接口信息", $"库口名称:【{DeStateName}】,关闭光幕信号地址:【{HandShake.DeviceProAddress}】,读取数据:【{conveyorLine.Communicator.Read(HandShake.DeviceProAddress)}】" + $"关闭光幕信号备用地址:【{Request.DeviceProAddress}】,读取数据:【{conveyorLine.Communicator.Read(Request.DeviceProAddress)}】\n" + $"写入关闭光幕信号是否成功返回值:【{HandShakeboolCLOSE}】"); } } if ((HandShakeboolOPEN && setCurtain.Operate.Equals("OPEN") )|| (HandShakeboolCLOSE && setCurtain.Operate.Equals("CLOSE"))) { return apiResponse.SuccessResponse(); } else { return apiResponse.ErrorResponse("写入plc进入信号失败"); } } catch (Exception ex) { return apiResponse.ErrorResponse($"WCS任务添加错误,原因:{ex.Message}"); } } //agv进出状态反馈 public ApiResponse getAGVStatus(AgvUpdateRequest agvUpdateRequest) { //获取WMS调取的参数 WriteLog.Write_Log("agv进出状态反馈接口", "agv进出状态信息", "调取参数", setCurtain); ApiResponse apiResponse = new ApiResponse(); try { string DeciceCodes = "1003"; if (agvUpdateRequest.warehousenumber.StartsWith("C")) DeciceCodes = "1004"; IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == DeciceCodes); if (device == null) return apiResponse.ErrorResponse("WCS未能获取到库口实例"); CommonConveyorLine conveyorLine = (CommonConveyorLine)device; //是否可进出 DeviceProDTO? HandShake = conveyorLine.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == agvUpdateRequest.warehousenumber && x.DeviceProParamName == "HandShake"); if (HandShake == null) return apiResponse.ErrorResponse($"WCS未找到库口:{agvUpdateRequest.warehousenumber},对应的协议"); DeviceProDTO? Request = conveyorLine.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == agvUpdateRequest.warehousenumber && x.DeviceProParamName == "Request"); if (agvUpdateRequest.agvstatus == 1) { bool HandShakebool = conveyorLine.Communicator.Write(HandShake.DeviceProAddress, 1); if (HandShakebool) { if (Request != null) { conveyorLine.Communicator.Write(Request.DeviceProAddress, 1); } //是否可进出 1允许取 2允许放 DeviceProDTO? deviceProDTO = conveyorLine.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == agvUpdateRequest.warehousenumber && x.DeviceProParamName == "PermitHandShake"); //是否有货 DeviceProDTO? StationNumProDTO = conveyorLine.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == agvUpdateRequest.warehousenumber && x.DeviceProParamName == "StationNum"); if (deviceProDTO == null || StationNumProDTO == null) return apiResponse.ErrorResponse($"WCS未找到库口:{agvUpdateRequest.warehousenumber},对应的协议"); int statusValue = 0; int portStatus = conveyorLine.Communicator.Read(deviceProDTO.DeviceProAddress); int StationStatus = conveyorLine.Communicator.Read(StationNumProDTO.DeviceProAddress); //有货,可进信号 statusValue = ((portStatus == 1 && StationStatus == 1) || (portStatus == 2 && StationStatus == 0)) ? 1 : (portStatus == 0) ? 0 : 0; WriteLog.Write_Log("申请进入AGV反馈信号信息", "申请进入AGV反馈信号信息", $"库口编号:【{agvUpdateRequest.warehousenumber}】,是否允许进入地址:【{deviceProDTO.DeviceProAddress}】,读取数据:【{portStatus}】\n" + $"是否有货地址:【{StationNumProDTO.DeviceProAddress}】,读取数据:【{StationStatus}】\n" + $"是否可进入信号:【{statusValue}】"); if (agvUpdateRequest.warehousenumber == "G01" || agvUpdateRequest.warehousenumber == "G06" || agvUpdateRequest.warehousenumber == "G07") { if (statusValue == 1) { return apiResponse.SuccessResponse(); } else { conveyorLine.Communicator.Write(Request.DeviceProAddress, 0); return apiResponse.ErrorResponse("读取plc不可进入信息"); } } else { return apiResponse.SuccessResponse(); } } else { return apiResponse.ErrorResponse("写入plc进入信号失败"); } } else if (agvUpdateRequest.agvstatus == 2) { //写入输送线信号 bool portStatus = conveyorLine.Communicator.Write(HandShake.DeviceProAddress, 0); if (portStatus) { if (Request != null) { conveyorLine.Communicator.Write(Request.DeviceProAddress, 0); WriteLog.Write_Log("申请离开AGV反馈信号信息", "申请离开AGV反馈信号信息", $"库口编号:【{agvUpdateRequest.warehousenumber}】,申请信号地址:【{HandShake.DeviceProAddress}】,读取数据:【{conveyorLine.Communicator.Read(HandShake.DeviceProAddress)}】\n" + $"备用信号地址:【{Request.DeviceProAddress}】,读取数据:【{conveyorLine.Communicator.Read(Request.DeviceProAddress)}】"); } else { WriteLog.Write_Log("申请离开AGV反馈信号信息", "申请离开AGV反馈信号信息", $"库口编号:【{agvUpdateRequest.warehousenumber}】,申请信号地址:【{HandShake.DeviceProAddress}】,读取数据:【{conveyorLine.Communicator.Read(HandShake.DeviceProAddress)}】\n" ); } return apiResponse.SuccessResponse(); } else { return apiResponse.ErrorResponse("写入plc清除信号失败"); } } else { return apiResponse.ErrorResponse($"agv对应的申请错误,字段:agvstatus,申请的值:{agvUpdateRequest.agvstatus}"); } } catch (Exception ex) { return apiResponse.ErrorResponse($"WCS任务添加错误,原因:{ex.Message}"); } } #endregion #region 调取上游接口 public CommandResult taskreturn(int taskId, string taskType, string invType, string psd) { CommandResult commandResult = new CommandResult(); try { TaskInfo taskInfo1 = new TaskInfo(); taskInfo1.taskId = taskId; taskInfo1.taskType = taskType; taskInfo1.invType = invType; taskInfo1.psd = "akjfapjfpadaoif"; commandResult = HttpHelper.Post(urlWMStaskreturn, taskInfo1, "任务状态回调"); WriteLog.Write_Log("同步给上游反馈任务完成", "任务信息", $"任务号:{taskId}", $"调取参数:{taskInfo1.ToJsonString()},返回参数:{commandResult.ToJsonString()}"); return commandResult; } catch (Exception ex) { Console.WriteLine("调取上游接口错误:原因:"+ex.Message); commandResult.status = "error"; string resujos = $"WCS接口错误,原因:{ex.Message}"; commandResult.result = resujos.ToJsonString(); WriteLog.Write_Log("同步给上游反馈任务完成", "任务信息", $"任务号:{taskId}", $"需要上传WMS信息内容:{commandResult.ToJsonString()},WCS接口错误,原因:{ex.Message}"); return commandResult; } } public CommandResult deverror(string devuuid, string id, string errorcode, string errorinfo, string erroraddress, string warehouse, string remark, string devname, string dealType, string psd) { CommandResult commandResult = new CommandResult(); try { DeviceErrorRequest deviceErrorRequest = new DeviceErrorRequest { devErrorJsons = new List { new DeviceErrorInfo { devuuid = devuuid, id = id, errorcode = errorcode, errorinfo = errorinfo, erroraddress = erroraddress, warehouse = warehouse, remark = remark, devname = devname } }, dealType = dealType, psd = "akjfapjfpadaoif", }; commandResult = HttpHelper.Post(urlWMSdeverror, deviceErrorRequest, "设备故障回调"); WriteLog.Write_Log("同步给上游设备故障信息", "设备故障信息", $"设备id:{devuuid},成功", $"调取参数:{deviceErrorRequest.ToJson()},返回参数:{commandResult.ToJson()}"); return commandResult; } catch (Exception ex) { commandResult.status = "error"; string resujos = $"WCS接口错误,原因:{ex.Message}"; commandResult.result = resujos.ToJsonString(); WriteLog.Write_Log("同步给上游设备故障信息", "设备故障信息", $"设备id:{devuuid},失败", $"WCS接口错误,原因:{ex.Message}"); return commandResult; } } public CommandResult liftinposition(string invtype, string invcode, string kloccode) { CommandResult commandResult = new CommandResult(); try { ShelvesPosition deviceErrorRequest = new ShelvesPosition { invtype= invtype, invcode = invcode, kloccode = kloccode }; commandResult = HttpHelper.Post(urlWMSliftinposition, deviceErrorRequest, "设备故障回调"); WriteLog.Write_Log("同步给上游提升到位信息", "信息内容", $"库口编号:{kloccode},成功信息", $"调取参数:{deviceErrorRequest.ToJson()},返回参数:{commandResult.ToJson()}"); return commandResult; } catch (Exception ex) { commandResult.status = "error"; string resujos = $"WCS接口错误,原因:{ex.Message}"; commandResult.result = resujos.ToJsonString(); WriteLog.Write_Log("同步给上游提升到位信息", "信息内容", $"错误信息", $"WCS接口错误,原因:{ex.Message}"); return commandResult; } } #endregion } }