using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using PlcSiemens.Core.Extension; using ServiceCenter; using ServiceCenter.Attributes; using ServiceCenter.Extensions; using ServiceCenter.Logs; 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.AGV.Response; 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 { /// /// WCS相关接口控制器 /// [ApiController] [Route("api/[controller]/[action]")] public class WcsController : ControllerBase, IDeviceWriter { /// /// 任务处理接口 /// /// /// [HttpPost, Log("任务处理接口")] public SRes HandleTask([FromBody] HandleTaskRequest req) { SRes response = new SRes() { ResCode = ResponseStatusCodeEnum.Sucess, ResDataList = new List() }; //取消任务 if (req.Type == HandleTaskTypeEnum.取消任务) { SqlSugarHelper.Do(db => { foreach (var item in req.TaskIds) { var task = db.Default.Queryable().Where(t => t.ID == item).First(); if (task != null) { //验证wms是否能取消 SRes res = HandleTaskVerify(response, item, 106); if (res == null) continue; switch (task.Type) { case TaskType.SetPlate: if (task.Status != Entity.TaskStatus.WaitingToExecute) { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"只能取消待执行状态组盘任务", }); continue; } break; case TaskType.EnterDepot: if (task.Status > Entity.TaskStatus.WaitingToExecute && task.Status > Entity.TaskStatus.AGVExecution) { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"只能取消待执行状态入库任务", }); continue; } break; case TaskType.OutDepot: if (task.Status > Entity.TaskStatus.WaitingToExecute) { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"只能取消待执行状态出库任务", }); continue; } break; case TaskType.TransferDepot: if (task.Status > Entity.TaskStatus.WaitingToExecute) { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"无法取消{task.Status.GetDescription()}的移库任务,只能取消新建/待执行的移库任务", }); continue; } break; case TaskType.Delivery: break; case TaskType.EmptyInit: if (task.Status != Entity.TaskStatus.WaitingToExecute) { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"只能取消待执行状态空轮初始化任务", }); continue; } break; } SRes cancelRes = CarryTaskInfo(response, item, 106); 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.Cancel; agv.AgvStatus = AGVTaskStatus.Cancel; db.Default.Updateable(agv).SplitTable().ExecuteCommand(); } //更新任务状态 task.Status = Entity.TaskStatus.Cancel; task.EedTime = DateTime.Now; task.EditWho = req.User; task.ManualRemarks = req.ManualRemarks; task.AddWCS_TASK_DTL(db, "未知", "任务取消"); db.Default.Updateable(task).ExecuteCommand(); task.CompleteOrCancelTasks(db); } else { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"未找到对应任务{item}" }); } } }); } // 完成任务 else if (req.Type == HandleTaskTypeEnum.完成任务) { SqlSugarHelper.Do(db => { foreach (var item in req.TaskIds) { var task = db.Default.Queryable().Where(t => t.ID == item).First(); if (task != null) { if (task.Type == TaskType.OutDepot) { SRes res = 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; } break; } SRes cancelRes = 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().ExecuteCommand(); } //更新任务状态 task.Status = Entity.TaskStatus.Finish; task.EedTime = DateTime.Now; task.EditWho = req.User; task.ManualRemarks = req.ManualRemarks; task.AddWCS_TASK_DTL(db, "未知", "任务完成"); db.Default.Updateable(task).ExecuteCommand(); task.CompleteOrCancelTasks(db); } else if (task.Type == TaskType.EnterDepot) { SRes res = 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; } SRes cancelRes = 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().ExecuteCommand(); } //更新任务状态 task.Status = Entity.TaskStatus.Finish; task.EedTime = DateTime.Now; task.EditWho = req.User; task.ManualRemarks = req.ManualRemarks; task.AddWCS_TASK_DTL(db, "未知", "任务完成"); db.Default.Updateable(task).ExecuteCommand(); task.CompleteOrCancelTasks(db); } else { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"未找到对应任务{item}" }); } } } }); } else if (req.Type == 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) { if (task.Type == TaskType.SetPlate) //组盘任务 { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"组盘任务无AGV执行流程", }); continue; } else if (task.Type == TaskType.EnterDepot) //入库任务 { if (task.Floor == 1) //一楼入库 { } else if (task.Floor == 2) //二楼入库 { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"二楼入库任务重新下发AGV未实现", }); continue; } } else if (task.Type == TaskType.OutDepot) //出库 { } else if (task.Type == TaskType.TransferDepot) //移库 { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"组盘任务无AGV执行流程", }); continue; } else if (task.Type == TaskType.Delivery) //搬运 { if (task.Floor == 1) { } else if (task.Floor == 2) { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"二楼搬运任务重新下发AGV未实现", }); continue; } } else if (task.Type == 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().ExecuteCommand(); } if (task.Floor == 1) { task.Status = Entity.TaskStatus.WaitingToExecute; } else if (task.Floor == 2) { task.Status = Entity.TaskStatus.ConveyorExecution; } task.AddWCS_TASK_DTL(db, "AGV", "重新下发AGV任务"); db.Default.Updateable(task).ExecuteCommand(); } else { response.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = item, Message = $"未找到对应任务{item}" }); } } }); } return response; } /// /// WMS完成或取消任务验证 /// /// /// /// 需要取消任务的AGV任务号 /// public CancelTaskResponse? CancelAgvTask(SRes sRes, int id, string agvTask) { try { var res = AgvApi.CancelAgvTask(agvTask); return res; } catch (Exception ex) { sRes.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = id, Message = $"AGV错误:{ex.Message}", }); return null; } } /// /// WMS完成或取消任务验证 /// /// /// /// 99完成,106取消 /// public SRes? HandleTaskVerify(SRes sRes, int id, int type) { try { var res = WmsApi.HandleTaskVerify(new List() { id }, type); return res; } catch (Exception ex) { sRes.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = id, Message = $"WMS错误:{ex.Message}", }); return null; } } /// /// WMS完成或取消任务执行 /// /// /// /// 99完成,106取消 /// public SRes? CarryTaskInfo(SRes sRes, int id, int type) { try { var res = WmsApi.CarryTaskInfo(new List() { id }, type); return res; } catch (Exception ex) { sRes.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = id, Message = $"WMS错误:{ex.Message}", }); return null; } } /// /// /// /// /// /// /// public SRes? CancelAgvTaskUpdate(SRes sRes, int id, int type) { try { var res = WmsApi.CarryTaskInfo(new List() { id }, type); return res; } catch (Exception ex) { sRes.ResDataList.Add(new HandleTaskResponse() { IsSuccess = false, TaskNo = id, Message = ex.Message, }); return null; } } /// /// 设备信息写入接口 /// /// 需要写入信息的设备类型 /// 设备编号 /// 设备协议类名 /// 写入字段名 /// 值 [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 }); } /// /// 设备信息写入接口 /// /// 需要写入信息的设备类型 /// 设备编号 /// 设备协议类名 /// 写入字段名 /// 值 [HttpPost] public void GetDevList() { var a = RedisHub.Monitor.LRange("Packs", 0, 80000); List packs = new List(); foreach (var item in a) { packs.Add(JsonConvert.DeserializeObject(item)); } } /// /// 获取设备配置信息接口 /// /// [HttpGet] public List GetDeviceList() { return Device.All.ToList(); } /// /// 获取设备信息 /// /// 设备名称 /// [HttpGet] public object GetDeviceInfo(string name) { var remoteIpAddress = HttpContext.Connection.RemoteIpAddress.ToString(); LogHub.InterfacePublish(nameof(GetDeviceInfo), $"IP:{remoteIpAddress}--传入参数--{JsonConvert.SerializeObject(name)}"); var obj = World.GetSystemInstance().Invoke(name); LogHub.InterfacePublish(nameof(GetDeviceInfo), $"IP:{remoteIpAddress}--返回结果--{JsonConvert.SerializeObject(obj)}"); return obj; } /// /// 堆垛机测试 /// /// 堆垛机编号 /// 任务类型 /// 起始行 /// 起始列 /// 起始层 /// 目标行 /// 目标列 /// 目标层 [HttpPost] public void SrmDeBug(string srmcod, SrmTaskTypeEnum 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 }); } #region 设备IP相关 /// /// 获取设备Ip集合 /// /// 设备Ip集合 [HttpGet] public List GetDeviceIpList() { if (!ServiceHub.DeviceIPList.Any()) throw new Exception("未配置任何Ip"); return ServiceHub.DeviceIPList; } /// /// 获取设备IP检测结果 /// /// 设备IP检测结果 [HttpGet] public List DeviceIpTest() { if (!ServiceHub.DeviceIPList.Any()) throw new Exception("未配置任何Ip"); List deviceIpTestResults = new List(); ServiceHub.DeviceIPList.ForEach(ip => { deviceIpTestResults.Add(new DeviceIpTestResults { Ip = ip, Result = PingIpOrDomainName(ip) }); }); return deviceIpTestResults; } /// /// 检查Ip是否正常联通 /// /// 输入参数,表示IP地址或域名 /// public static bool PingIpOrDomainName(string strIpOrDName) { try { Ping objPingSender = new Ping(); PingOptions objPinOptions = new PingOptions(); objPinOptions.DontFragment = true; string data = ""; byte[] buffer = Encoding.UTF8.GetBytes(data); int intTimeout = 120; PingReply objPinReply = objPingSender.Send(strIpOrDName, intTimeout, buffer, objPinOptions); string strInfo = objPinReply.Status.ToString(); if (strInfo == "Success") { return true; } else { return false; } } catch (Exception) { return false; } } #endregion 设备IP相关 } 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; } } }