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; }
}
}