using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System.Text; using WIDESEA_DTO.Agv; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_Core; using WIDESEAWCS_Core.Enums; using WIDESEAWCS_Core.Helper; using WIDESEAWCS_Core.LogHelper; using WIDESEAWCS_DTO.Agv; using WIDESEAWCS_IBasicInfoRepository; using WIDESEAWCS_ITaskInfoRepository; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob; using WIDESEAWCS_QuartzJob.DTO; using WIDESEAWCS_QuartzJob.Models; using WIDESEAWCS_QuartzJob.Repository; using WIDESEAWCS_Tasks; using WIDESEAWCS_Tasks.ConveyorLineJob; using WIDESEAWCS_Tasks.DBNames; using static Dm.net.buffer.ByteArrayBuffer; namespace WIDESEAWCS_Server.Controllers { [Route("api/[controller]")] [ApiController] public class AGVController : ControllerBase { private readonly IStationMangerRepository _stationMangerRepository; private readonly ITaskService _taskService; private readonly ITaskRepository _taskRepository; private readonly IRouterRepository _routerRepository; public AGVController(IStationMangerRepository stationMangerRepository, ITaskService taskService, ITaskRepository taskRepository,IRouterRepository routerRepository) { _stationMangerRepository = stationMangerRepository; _taskService = taskService; _taskRepository = taskRepository; _routerRepository = routerRepository; } /// /// 安全信号申请 AGV-WCS /// /// /// [HttpPost, HttpGet, Route("AgvSecureApply"), AllowAnonymous] public AgvResponse AgvSecureApply([FromBody] AgvSecureApplyDTO secureApplyModel) { AgvResponse agvResponse = new AgvResponse(); try { var task = _taskRepository.QueryFirst(x => secureApplyModel.ReceiveTaskID.ObjToInt() == x.TaskNum); if (task == null) throw new Exception("未找到任务"); if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) { if (task.TaskState==TaskStatusEnum.AGV_Executing.ObjToInt())//出库取货请求 { var content = TakeRequest(secureApplyModel.WbCode); if (!content.Status) { throw new Exception(content.Message); } } else//出库放货请求 { var content = PutRequest(secureApplyModel.WbCode, task.PalletType); if (!content.Status) { throw new Exception(content.Message); } } } else { if (task.TaskState == TaskStatusEnum.AGV_Executing.ObjToInt())//入库取货请求 { var content = TakeRequest(secureApplyModel.WbCode); if (!content.Status) { throw new Exception(content.Message); } } else//入库放货请求 { var content = PutRequest(secureApplyModel.WbCode, task.TaskNum); if (!content.Status) { throw new Exception(content.Message); } } } agvResponse.OK("成功","0"); } catch (Exception ex) { agvResponse.Error(ex.Message); } return agvResponse; } /// /// 提升机申请 AGV-WCS /// /// /// [HttpPost, HttpGet, Route("AgvHoisterApply"), AllowAnonymous] public AgvResponse AgvHoisterApply([FromBody] AgvHoisterApplyDTO agvHoisterApplyDTO) { AgvResponse agvResponse = new AgvResponse(); try { IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == agvHoisterApplyDTO.HoisterCode); if (device == null) { return agvResponse.Error($"未找到对应设备{agvHoisterApplyDTO.HoisterCode}"); } OtherDevice otherDevice = (OtherDevice)device; //获取设备协议 DeviceProDTO? deviceProRead = otherDevice.DeviceProDTOs.Where(x => x.DeviceChildCode == device.DeviceCode && x.DeviceProParamType == nameof(R_HoisterDB)).OrderBy(x => x.DeviceProOffset).FirstOrDefault(); DeviceProDTO? deviceProWrite = otherDevice.DeviceProDTOs.Where(x => x.DeviceChildCode == device.DeviceCode && x.DeviceProParamType == nameof(W_HoisterDB)).OrderBy(x => x.DeviceProOffset).FirstOrDefault(); if (deviceProRead == null || deviceProWrite == null) { return agvResponse.Error($"未找到设备{device.DeviceCode}协议"); } //获取读取和写入 R_HoisterInfo r_HoisterInfo = otherDevice.Communicator.ReadCustomer(deviceProRead.DeviceProAddress); W_HoisterInfo w_HoisterInfo = otherDevice.Communicator.ReadCustomer(deviceProWrite.DeviceProAddress); if (r_HoisterInfo == null || w_HoisterInfo == null) { return agvResponse.Error($"未读取到设备{device.DeviceCode}信号"); } if (r_HoisterInfo.R_HoisterSysStatus!=3) { return agvResponse.Error($"设备状态不为自动"); } QuartzLogger.WriteLogToFile("Info_" + device.DeviceCode, $"r_HoisterInfo:{r_HoisterInfo.Serialize()}{Environment.NewLine}w_HoisterInfo:{w_HoisterInfo.Serialize()}{Environment.NewLine}"); bool IsSuccess = false; switch (agvHoisterApplyDTO.Request) { case "1": //判断提升机是否在当前层 如果当前层,关门状态,无货待命直接写入开门信号 if (r_HoisterInfo.R_HoisterCurrent == agvHoisterApplyDTO.CurrentLayer && r_HoisterInfo.R_HoisterLoadStatus == 2 && r_HoisterInfo.R_HoisterDoorStatus == 2) { otherDevice.SetValue(W_HoisterDB.W_HoisterDoorStatus, 1); IsSuccess = true; } else if (r_HoisterInfo.R_HoisterCurrent == agvHoisterApplyDTO.CurrentLayer && r_HoisterInfo.R_HoisterLoadStatus == 2 && r_HoisterInfo.R_HoisterDoorStatus == 1) { IsSuccess = true; } else if (r_HoisterInfo.R_HoisterCurrent != agvHoisterApplyDTO.CurrentLayer && r_HoisterInfo.R_HoisterLoadStatus == 2 && r_HoisterInfo.R_HoisterDoorStatus == 1) { otherDevice.SetValue(W_HoisterDB.W_HoisterDoorStatus, 2); } //判断提升机不在当前层 如果不在当前层,关门状态,无货待命直接写入移动开门信号(当前) else if (r_HoisterInfo.R_HoisterCurrent != agvHoisterApplyDTO.CurrentLayer && r_HoisterInfo.R_HoisterLoadStatus == 2 && r_HoisterInfo.R_HoisterDoorStatus == 2) { otherDevice.SetValue(W_HoisterDB.W_HoisterTarget, agvHoisterApplyDTO.CurrentLayer); otherDevice.SetValue(W_HoisterDB.W_HoisterTask, 99); } return IsSuccess ? agvResponse.OK($"请求{agvHoisterApplyDTO.Request}成功,任务{agvHoisterApplyDTO.ReceiveTaskID}","1"): agvResponse.Error($"请求{agvHoisterApplyDTO.Request}失败,任务{agvHoisterApplyDTO.ReceiveTaskID}"); case "2": //判断提升机是否在当前层 如果当前层,开门状态,无货待命 放行 if (r_HoisterInfo.R_HoisterCurrent == agvHoisterApplyDTO.CurrentLayer && r_HoisterInfo.R_HoisterLoadStatus == 2 && r_HoisterInfo.R_HoisterDoorStatus == 1) { IsSuccess = true; } return IsSuccess ? agvResponse.OK($"请求{agvHoisterApplyDTO.Request}成功,任务{agvHoisterApplyDTO.ReceiveTaskID}", "2") : agvResponse.Error($"请求{agvHoisterApplyDTO.Request}失败,任务{agvHoisterApplyDTO.ReceiveTaskID}"); case "3": //判断提升机是否在当前层 如果当前层,开门状态,有货待命写入关门信号 if (r_HoisterInfo.R_HoisterCurrent == agvHoisterApplyDTO.CurrentLayer && r_HoisterInfo.R_HoisterLoadStatus == 1 && r_HoisterInfo.R_HoisterDoorStatus == 1 && w_HoisterInfo.W_HoisterDoorStatus!=2) { otherDevice.SetValue(W_HoisterDB.W_HoisterDoorStatus, 2); } //判断提升机是否在当前层 如果当前层,关门状态,有货待命写入移动开门信号(目的) if (r_HoisterInfo.R_HoisterCurrent == agvHoisterApplyDTO.CurrentLayer && r_HoisterInfo.R_HoisterLoadStatus == 1 && r_HoisterInfo.R_HoisterDoorStatus == 2) { otherDevice.SetValue(W_HoisterDB.W_HoisterTarget, agvHoisterApplyDTO.TargetLayer); otherDevice.SetValue(W_HoisterDB.W_HoisterDoorStatus, 1); otherDevice.SetValue(W_HoisterDB.W_HoisterTask, 99); IsSuccess = true; } return IsSuccess ? agvResponse.OK($"请求{agvHoisterApplyDTO.Request}成功,任务{agvHoisterApplyDTO.ReceiveTaskID}", "3") : agvResponse.Error($"请求{agvHoisterApplyDTO.Request}失败,任务{agvHoisterApplyDTO.ReceiveTaskID}"); case "4": //判断提升机是否在目的层 如果目的层,开门状态,有货待命 放行 if (r_HoisterInfo.R_HoisterCurrent == agvHoisterApplyDTO.TargetLayer && r_HoisterInfo.R_HoisterLoadStatus == 1 && r_HoisterInfo.R_HoisterDoorStatus == 1) { IsSuccess = true; } return IsSuccess ? agvResponse.OK($"请求{agvHoisterApplyDTO.Request}成功,任务{agvHoisterApplyDTO.ReceiveTaskID}", "4") : agvResponse.Error($"请求{agvHoisterApplyDTO.Request}失败,任务{agvHoisterApplyDTO.ReceiveTaskID}"); case "5": //判断提升机是否在目的层 如果目的层,开门状态,无货待命写入关门信号 if (r_HoisterInfo.R_HoisterCurrent == agvHoisterApplyDTO.TargetLayer && r_HoisterInfo.R_HoisterLoadStatus == 2 && r_HoisterInfo.R_HoisterDoorStatus == 1) { otherDevice.SetValue(W_HoisterDB.W_HoisterDoorStatus, 2); IsSuccess = true; } return IsSuccess ? agvResponse.OK($"请求{agvHoisterApplyDTO.Request}成功,任务{agvHoisterApplyDTO.ReceiveTaskID}", "5") : agvResponse.Error($"请求{agvHoisterApplyDTO.Request}失败,任务{agvHoisterApplyDTO.ReceiveTaskID}"); default: return agvResponse.Error($"未找到对应请求,Request:{agvHoisterApplyDTO.Request}"); } } catch (Exception ex) { agvResponse.Error($"请求{agvHoisterApplyDTO.Request}失败,错误{ex.Message},任务{agvHoisterApplyDTO.ReceiveTaskID}"); } return agvResponse; } /// /// AGV任务更新/完成 /// /// /// [HttpPost, HttpGet, Route("AgvCallback"), AllowAnonymous] public AgvResponse AgvCallback([FromBody] AgvUpdateDTO agvUpdateModel) { AgvResponse agvResponse = new AgvResponse(); try { var task = _taskRepository.QueryFirst(x => agvUpdateModel.ReceiveTaskID == x.TaskNum.ToString()); if (task == null) throw new Exception($"未找到任务,任务号【{agvUpdateModel.ReceiveTaskID}】"); switch (agvUpdateModel.GoodsState) { case "1"://出库根据这个信号判断取货完成 //更新任务状态 _taskService.UpdateTask(task, TaskStatusEnum.AGV_TakeFinish); if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) { var content = TakeFinish(task.CurrentAddress); if (!content.Status) { throw new Exception(content.Message); }; } else { if (task.TaskType == TaskTypeEnum.PrintInbound.ObjToInt() || task.TaskType == TaskTypeEnum.PrintBackInbound.ObjToInt()) { var content = TakeFinish(task.CurrentAddress); if (!content.Status) { throw new Exception(content.Message); }; } } return agvResponse.OK("成功", "0"); case "2"://入库根据这个信号判断放货完成 if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup) { Dt_StationManger dt_Station = _stationMangerRepository.QueryFirst(x => x.StationCode == task.NextAddress); if (dt_Station == null) { throw new Exception($"{task.NextAddress}AGV站台未定义"); } if (task.TaskType == TaskTypeEnum.PrintInbound.ObjToInt() || task.TaskType == TaskTypeEnum.PrintBackInbound.ObjToInt()) { List routers = _routerRepository.QueryData(x => x.InOutType == task.TaskType && task.NextAddress == x.StartPosi); Dt_Router router = routers.FirstOrDefault(); if (router == null) { throw new Exception($"任务号:{task.TaskNum}未找到路由配置信息"); } string oldAddress = task.NextAddress; //更新任务状态 task.CurrentAddress = router.NextPosi; task.NextAddress = ""; task.DeviceCode = router.ChildPosiDeviceCode; _taskService.UpdateTask(task, TaskStatusEnum.AGV_Finish); PutFinish(oldAddress, task.TaskNum); } else { task.CurrentAddress = dt_Station.StationCode; task.NextAddress = ""; task.TaskState = TaskStatusEnum.AGV_Finish.ObjToInt(); task.DeviceCode = dt_Station.StationDeviceCode; _taskRepository.UpdateData(task); } return agvResponse.OK("成功","0"); } else { _taskService.TaskCompleted(task.TaskNum); if (task.TaskType==TaskTypeEnum.PrintOutbound.ObjToInt()) { PutFinish(task.NextAddress); } return agvResponse.OK("成功", "0"); } default: throw new Exception($"未定义方法名【{agvUpdateModel.TaskState}】"); } } catch (Exception ex) { agvResponse.Error(ex.Message); } return agvResponse; } /// /// 放货请求 /// /// /// /// [HttpPost, HttpGet, Route("PutRequest"), AllowAnonymous] public WebResponseContent PutRequest(string code, int taskNum) { WebResponseContent content = new WebResponseContent(); try { Dt_StationManger stationManger = _stationMangerRepository.QueryFirst(x => x.AGVStationCode == code); if (stationManger == null) { return content.Error($"未找到站台配置"); } IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == stationManger.StationDeviceCode); if (device == null) { return content.Error($"未找到对应设备"); } OtherDevice otherDevice = (OtherDevice)device; if (device.DeviceCode.Contains("CP"))//成品输送线 { short Command = otherDevice.GetValue(R_ConveyorLineCPDB.Command, stationManger.StationCode); if (Command == 3) { content.OK("允许放料"); } else { return content.Error("禁止放料"); } } else if (device.DeviceCode.Contains("Coveryor"))//接驳台 { bool RequestPut = otherDevice.GetValue(CoveryorDB.C_RequestPut, stationManger.StationDeviceCode); if (!RequestPut) { otherDevice.SetValue(CoveryorDB.C_InTaskNum, taskNum, stationManger.StationDeviceCode); otherDevice.SetValue(CoveryorDB.C_RequestPut, true, stationManger.StationDeviceCode); Thread.Sleep(1000); } bool AllowFinish = otherDevice.GetValue(CoveryorDB.C_AllowFinish, stationManger.StationDeviceCode); if (AllowFinish) { content.OK("允许放料"); } else { return content.Error("禁止放料"); } } else if (device.DeviceCode.Contains("Retract"))//伸缩货叉 { bool RequestPut = otherDevice.GetValue(RetractDB.Ret_RequestPut, stationManger.StationDeviceCode); if (!RequestPut) { otherDevice.SetValue(RetractDB.Ret_TargetAddress, Convert.ToInt16(stationManger.StationCode), stationManger.StationDeviceCode); otherDevice.SetValue(RetractDB.Ret_RequestPut, true, stationManger.StationDeviceCode); Thread.Sleep(1000); } bool AllowFinish = otherDevice.GetValue(RetractDB.Ret_AllowFinish, stationManger.StationDeviceCode); if (AllowFinish) { content.OK("允许放料"); } else { return content.Error("禁止放料"); } } return content; } catch (Exception ex) { return content.Error(ex.Message); } } //[HttpPost, HttpGet, Route("PutFinish"), AllowAnonymous] /// /// 放货完成 /// /// /// [HttpPost, HttpGet, Route("PutFinish"), AllowAnonymous] public WebResponseContent PutFinish(string code,int taskNum=0) { try { Dt_StationManger stationManger = _stationMangerRepository.QueryFirst(x => x.StationCode == code); if (stationManger == null) { return WebResponseContent.Instance.Error($"未找到站台配置"); } IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == stationManger.StationDeviceCode); if (device == null) { return WebResponseContent.Instance.Error($"未找到对应设备"); } OtherDevice otherDevice = (OtherDevice)device; if (device.DeviceCode.Contains("Coveryor"))//接驳台 { otherDevice.SetValue(CoveryorDB.C_PutFinish, true, stationManger.StationDeviceCode); } else if (device.DeviceCode.Contains("Retract"))//伸缩货叉 { otherDevice.SetValue(RetractDB.Ret_PutFinish, true, stationManger.StationDeviceCode); } return WebResponseContent.Instance.OK(); } catch (Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } //[HttpPost, HttpGet, Route("TakeRequest"), AllowAnonymous] /// /// 取货请求 /// /// /// [HttpPost, HttpGet, Route("TakeRequest"), AllowAnonymous] public WebResponseContent TakeRequest(string code) { WebResponseContent content = new WebResponseContent(); try { Dt_StationManger stationManger = _stationMangerRepository.QueryFirst(x => x.AGVStationCode == code); if (stationManger == null) { return WebResponseContent.Instance.Error($"未找到站台配置{code}"); } IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == stationManger.StationDeviceCode); if (device == null) { return WebResponseContent.Instance.Error($"未找到对应设备{stationManger.StationDeviceCode}"); } OtherDevice otherDevice = (OtherDevice)device; if (otherDevice.DeviceCode.Contains("CP"))//成品输送线 { short Command = otherDevice.GetValue(R_ConveyorLineCPDB.Command, stationManger.StationCode); if (Command == 2) { content.OK("允许取料"); } else { return content.Error("禁止取料"); } } else if (device.DeviceCode.Contains("Coveryor"))//接驳台 { bool AllowTake = otherDevice.GetValue(CoveryorDB.C_AllowTake, stationManger.StationDeviceCode); if (AllowTake) { content.OK("允许取料"); } else { return content.Error("禁止取料"); } } else if (device.DeviceCode.Contains("Retract"))//伸缩货叉 { bool AllowTake = otherDevice.GetValue(RetractDB.Ret_AllowTake, stationManger.StationDeviceCode); if (AllowTake) { content.OK("允许取料"); } else { return content.Error("禁止取料"); } } return content; } catch (Exception ex) { return content.Error(ex.Message); } } //[HttpPost, HttpGet, Route("TakeFinish"), AllowAnonymous] /// /// 取货完成 /// /// /// [HttpPost, HttpGet, Route("TakeFinish"), AllowAnonymous] public WebResponseContent TakeFinish(string code) { try { Dt_StationManger stationManger = _stationMangerRepository.QueryFirst(x => x.StationCode == code); if (stationManger == null) { return WebResponseContent.Instance.Error($"未找到站台配置"); } IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == stationManger.StationDeviceCode); if (device == null) { return WebResponseContent.Instance.Error($"未找到对应设备"); } OtherDevice otherDevice = (OtherDevice)device; if (device.DeviceCode.Contains("CP")) { otherDevice.SetValue(W_ConveyorLineCPDB.W_Command, 2, stationManger.StationCode); } else if (device.DeviceCode.Contains("Coveryor")) { otherDevice.SetValue(CoveryorDB.C_TakeFinish, true, stationManger.StationDeviceCode); } else if (device.DeviceCode.Contains("Retract"))//伸缩货叉 { otherDevice.SetValue(RetractDB.Ret_TakeFinish, true, stationManger.StationDeviceCode); } return WebResponseContent.Instance.OK(); } catch (Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } } }