using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using PlcSiemens.Core.Extension; using ServiceCenter; using ServiceCenter.Extensions; using ServiceCenter.Redis; using ServiceCenter.SqlSugars; using System.Net.NetworkInformation; using System.Text; using WCS.Core; using WCS.Entity; using WCS.Entity.Protocol.DataStructure; using WCS.Entity.Protocol.SRM; using WCS.WorkEngineering.Extensions; using WCS.WorkEngineering.Systems; using WCS.WorkEngineering.WebApi.Models.WCS.Request; using WCS.WorkEngineering.WebApi.Models.WCS.Response; using WCS.WorkEngineering.WebApi.Models.WMS.Response; namespace WCS.WorkEngineering.WebApi.Controllers { public interface IDeviceWriter { [HttpPost] void Write(DeviceTypeEnum deviceType, string devCode, string protocol, string propName, string value); } /// /// 设备Ip通讯检测结构 /// public class DeviceIpTestResults { public string Ip { get; set; } public bool Result { get; set; } } /// /// WCS相关接口控制器 /// [ApiController] [Route("api/[controller]/[action]")] public class WcsController : ControllerBase, IDeviceWriter { /// /// 获取设备信息 /// /// /// 设备名称 /// [HttpGet] public object GetDeviceInfo(string type, string name) { var obj = World.GetSystemInstance().Invoke(new Tuple(type, name)); return obj; } /// /// 获取设备配置信息接口 /// /// [HttpGet] public List GetDeviceList() { return Device.All.ToList(); } /// /// 任务处理接口 /// /// /// [HttpPost] public SRes HandleTask([FromBody] HandleTaskRequest req) { var response = new SRes() { ResCode = ResponseStatusCodeEnum.Sucess, ResDataList = new List() }; switch (req.Type) { //取消任务 case HandleTaskTypeEnum.取消任务: SqlSugarHelper.Do(db => { foreach (var item in req.TaskIds) { var task = db.Default.Queryable().Where(t => t.ID == item && t.Status < Entity.TaskStatus.Finish).First(); if (task != null) { //验证wms是否能取消 //var res = WmsApi.HandleTaskVerify(response, item, 106); //if (res == null) continue; switch (task.Type) { case TaskType.EnterDepot: if (task.Status > Entity.TaskStatus.WaitingToExecute && task.BusType != "皮盘入库") { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"只能取消待执行状态入库任务", }); continue; } break; case TaskType.OutDepot: if (task.Status > Entity.TaskStatus.WaitingToExecute || (task.BusType != "车间叫料" && task.BusType != "芯股站台送空托")) { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"只能取消待执行状态出库任务", }); continue; } break; default: throw new ArgumentOutOfRangeException(); } var cancelRes = WmsApi.CancelTask(item); if (cancelRes.ResCode != ResponseStatusCodeEnum.Sucess) { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = cancelRes.ResMsg, }); continue; } //找到对应的AGV任务 var agv = db.Default.Queryable().Where(v => v.ID == task.AgvTaskID && v.AgvStatus < AGVTaskStatus.MissionCompleted).SplitTable(v => v.Take(2)).First(); if (agv != null) { if (!agv.AgvID.IsNullOrEmpty()) { var cancelTaskUpdateRes = AgvApi.CancelAgvTask(response, item, agv.AgvID); //if (cancelTaskUpdateRes == null) continue; } agv.Status = AGVTaskStatus.Cancel; agv.AgvStatus = AGVTaskStatus.Cancel; db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand(); } //更新任务状态 task.Status = Entity.TaskStatus.Cancel; task.EndTime = DateTime.Now; task.EditWho = req.User; task.ManualRemarks = req.ManualRemarks; db.Default.Updateable(task).UpdateColumns(x => new { x.Status, x.EndTime, x.EditTime, x.ManualRemarks }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, "未知", "任务取消"); } else { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"未找到对应任务{item}" }); } } }); break; // 完成任务 case HandleTaskTypeEnum.完成任务: SqlSugarHelper.Do(db => { foreach (var item in req.TaskIds) { var task = db.Default.Queryable().Where(t => t.ID == item).First(); if (task == null) continue; if (task.BusType != "车间叫料" && task.BusType != "芯股站台送空托") { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"该类型任务不支持完成", }); continue; } if (db.Default.Queryable().SplitTable(v => v.Take(2)).Any(v => v.ParentTaskCode == task.ID && v.Desc.Contains("允许AGV任务"))) { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"该任务尚未取货,不能完成", }); continue; } switch (task.Type) { case TaskType.OutDepot: { //var res = WmsApi.HandleTaskVerify(response, item, 99); //if (res == null) continue; switch (task.Type) { case TaskType.OutDepot: if (task.Status >= Entity.TaskStatus.Finish) { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"只能完成未完成状态的任务", }); continue; } else { switch (task.Status) { case Entity.TaskStatus.NewBuild: response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"不能完成新建任务", }); continue; case Entity.TaskStatus.WaitingToExecute: response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"不能完成待执行任务", }); continue; case Entity.TaskStatus.StackerExecution: response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"不能完成堆垛机执行任务", }); continue; }; } break; case TaskType.SetPlate: break; case TaskType.EnterDepot: break; case TaskType.TransferDepot: break; case TaskType.Delivery: break; case TaskType.EmptyInit: break; default: throw new ArgumentOutOfRangeException(); } //var cancelRes = WmsApi.CarryTaskInfo(response, item, 99); //if (cancelRes == null) continue; //找到对应的AGV任务 var agv = db.Default.Queryable().Where(v => v.ID == task.AgvTaskID && v.AgvStatus < AGVTaskStatus.MissionCompleted).SplitTable(v => v.Take(2)).First(); if (agv != null) { //if (!agv.AgvID.IsNullOrEmpty()) //{ // var cancelTaskUpdateRes = CancelAgvTask(response, item, agv.AgvID); // if (cancelTaskUpdateRes == null) continue; //} agv.Status = AGVTaskStatus.MissionCompleted; agv.AgvStatus = AGVTaskStatus.MissionCompleted; db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand(); } //更新任务状态 task.Status = Entity.TaskStatus.Finish; task.EndTime = DateTime.Now; task.EditWho = req.User; task.ManualRemarks = req.ManualRemarks; db.Default.Updateable(task).UpdateColumns(x => new { x.Status, x.EndTime, x.EditWho, x.ManualRemarks }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, "未知", "任务完成"); break; } case TaskType.EnterDepot: { var res = WmsApi.HandleTaskVerify(response, item, 99); if (res == null) continue; switch (task.Type) { case TaskType.EnterDepot: if (task.Status >= Entity.TaskStatus.Finish) { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"只能完成未完成状态的任务", }); continue; } if (task.AddrTo.Length < 6) { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"只能完成已分配货位的任务", }); continue; } break; case TaskType.SetPlate: break; case TaskType.OutDepot: break; case TaskType.TransferDepot: break; case TaskType.Delivery: break; case TaskType.EmptyInit: break; default: throw new ArgumentOutOfRangeException(); } //var cancelRes = WmsApi.CancelTask(item); //if (cancelRes == null) continue; //找到对应的AGV任务 var agv = db.Default.Queryable().Where(v => v.ID == task.AgvTaskID && v.AgvStatus < AGVTaskStatus.MissionCompleted).SplitTable(v => v.Take(2)).First(); if (agv != null) { //if (!agv.AgvID.IsNullOrEmpty()) //{ // var cancelTaskUpdateRes = CancelAgvTask(response, item, agv.AgvID); // if (cancelTaskUpdateRes == null) continue; //} agv.Status = AGVTaskStatus.MissionCompleted; agv.AgvStatus = AGVTaskStatus.MissionCompleted; db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand(); } //更新任务状态 task.Status = Entity.TaskStatus.Finish; task.EndTime = DateTime.Now; task.EditWho = req.User; task.ManualRemarks = req.ManualRemarks; db.Default.Updateable(task).UpdateColumns(x => new { x.Status, x.EndTime, x.EditTime, x.ManualRemarks }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, "未知", "任务完成"); break; } case TaskType.SetPlate: case TaskType.TransferDepot: case TaskType.Delivery: case TaskType.EmptyInit: default: response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"未找到对应任务{item}" }); break; } } }); break; case HandleTaskTypeEnum.重新下发AGV任务: SqlSugarHelper.Do(db => { foreach (var item in req.TaskIds) { var task = db.Default.Queryable().Where(t => t.ID == item).First(); if (task != null) { switch (task.Type) { //组盘任务 case TaskType.SetPlate: response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"组盘任务无AGV执行流程", }); continue; //入库任务 //一楼入库 case TaskType.EnterDepot when task.Floor == 1: break; //二楼入库 case TaskType.EnterDepot when task.Floor == 2: response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"二楼入库任务重新下发AGV未实现", }); continue; //出库 case TaskType.OutDepot: break; //移库 case TaskType.TransferDepot: response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"组盘任务无AGV执行流程", }); continue; //搬运 case TaskType.Delivery when task.Floor == 1: break; case TaskType.Delivery when task.Floor == 2: response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"二楼搬运任务重新下发AGV未实现", }); continue; //空轮初始化 case TaskType.EmptyInit: response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"空轮初始化无AGV执行流程", }); continue; } //找到对应的AGV任务 var agv = db.Default.Queryable().Where(v => v.ID == task.AgvTaskID).SplitTable(v => v.Take(2)).First(); if (agv != null) { agv.Status = AGVTaskStatus.NewBuild; agv.AgvStatus = AGVTaskStatus.NewBuild; db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand(); } task.Status = task.Floor switch { 1 => Entity.TaskStatus.WaitingToExecute, 2 => Entity.TaskStatus.ConveyorExecution, _ => task.Status }; task.AddWCS_TASK_DTL(db.Default, "AGV", "重新下发AGV任务"); db.Default.Updateable(task).UpdateColumns(x => new { x.Status }).ExecuteCommand(); } else { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"未找到对应任务{item}" }); } } }); break; case HandleTaskTypeEnum.调整优先级: break; default: throw new ArgumentOutOfRangeException(); } return response; } /// /// 堆垛机测试 /// /// 堆垛机编号 /// 任务类型 /// 起始行 /// 起始列 /// 起始层 /// 目标行 /// 目标列 /// 目标层 [HttpPost] public void SrmDeBug(string srmcod, SrmTaskType typeEnum, short value1, short value2, short value3, short value4, short value5, short value6) { World.GetSystemInstance().Invoke(new SrmDebugInfo { SrmCode = srmcod, srmTaskType = typeEnum, SLine = value1, SCol = value2, SLayer = value3, ELine = value4, ECol = value5, ELayer = value6 }); } /// /// 设备信息写入接口 /// /// 需要写入信息的设备类型 /// 设备编号 /// 设备协议类名 /// 写入字段名 /// 值 [HttpPost] public void Write(DeviceTypeEnum deviceType, string devCode, string protocol, string propName, string value) { World.GetSystemInstance().Invoke(new DeviceWriteInfo { DeviceType = deviceType, Code = devCode, Protocol = protocol, Property = propName, Value = value }); } #region 设备IP相关 /// /// 检查Ip是否正常联通 /// /// 输入参数,表示IP地址或域名 /// [HttpGet] public static bool PingIpOrDomainName(string strIpOrDName) { try { var objPingSender = new Ping(); var objPinOptions = new PingOptions { DontFragment = true }; const string data = ""; var buffer = Encoding.UTF8.GetBytes(data); const int intTimeout = 120; var objPinReply = objPingSender.Send(strIpOrDName, intTimeout, buffer, objPinOptions); var strInfo = objPinReply.Status.ToString(); return strInfo == "Success"; } catch (Exception) { return false; } } /// /// 获取设备IP检测结果 /// /// 设备IP检测结果 [HttpGet] public List DeviceIpTest() { if (!ServiceHub.DeviceIPList.Any()) throw new Exception("未配置任何Ip"); var deviceIpTestResults = new List(); ServiceHub.DeviceIPList.ForEach(ip => { deviceIpTestResults.Add(new DeviceIpTestResults { Ip = ip, Result = PingIpOrDomainName(ip) }); }); return deviceIpTestResults; } /// /// 获取设备Ip集合 /// /// 设备Ip集合 [HttpGet] public List GetDeviceIpList() { if (!ServiceHub.DeviceIPList.Any()) throw new Exception("未配置任何Ip"); return ServiceHub.DeviceIPList; } #endregion 设备IP相关 } }