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相关
}
}