Product_Wms/WcsMain/CirculationJob/Stacker/ExecuteWcsTask.cs

395 lines
19 KiB
C#
Raw Permalink Normal View History

2024-10-07 09:51:55 +08:00
using CirculateTool.Attribute;
using WcsMain.Business.CommonAction;
using WcsMain.Common;
using WcsMain.Constant.Enum.Stacker;
using WcsMain.Constant.Enum.TaskEnum;
2024-11-15 11:51:41 +08:00
using WcsMain.Constant.ExtendMethod;
2024-10-07 09:51:55 +08:00
using WcsMain.DataBase.Dao;
using WcsMain.DataBase.TableEntity;
using WcsMain.EquipOperation.Entity.Stacker;
using WcsMain.EquipOperation.Stacker;
using WcsMain.ExtendMethod;
namespace WcsMain.CirculationJob.Stacker;
2024-10-07 09:51:55 +08:00
/// <summary>
/// 执行堆垛机任务类
/// </summary>
//[Circulation(tags: ["stacker"])]
public class ExecuteWcsTask(StackerOperation stackerOperation, AppWcsTaskDao wcsTaskDao, WCSTaskExecuteEvent wcsTaskEvent)
{
/// <summary>
/// 执行堆垛机任务
/// </summary>
/// <returns></returns>
[Circulation("执行堆垛机任务")]
public bool ExecuteStackerTask()
{
foreach (var stacker in CommonData.AppStackers.Open())
{
var stackerUseStatus = stackerOperation.StackerCanUse(stacker.StackerId, out int plcId, out int _);
if (stackerUseStatus == StackerUseStatusEnum.Free)
{
/* 空闲时正常执行任务 */
// 入库
if (!CommonData.AppConfig.ExcuteStackerInTaskWithScan.ToBool()) // 不是扫码入库
{
bool exeInTask = ExecuteInTask(stacker.StackerId);
if (exeInTask) continue;
}
// 出库
bool exeOutTask = ExecuteOutTask(stacker.StackerId);
if (exeOutTask) continue;
// 拣选
bool exePickTask = ExecutePickTask(stacker.StackerId);
if (exePickTask) continue;
// 移库
bool exeMoveTask = ExecuteMoveTask(stacker.StackerId);
if (exeMoveTask) continue;
}
if (stackerUseStatus == StackerUseStatusEnum.waitTask)
{
/* 重复入库时执行任务 */
bool exeDoubleInTask = ExecuteDoubleInTask(stacker.StackerId, plcId);
if (exeDoubleInTask) continue;
}
}
return true;
}
/// <summary>
/// 执行堆垛机入库任务,若执行了任务则返回 true
/// </summary>
/// <param name="stackerId"></param>
/// <returns></returns>
private bool ExecuteInTask(int? stackerId)
{
if (stackerId == default) return false;
var wcsTasks = wcsTaskDao.SelectInTaskWithStacker((int)stackerId!); // 此处方法内已经判断状态
if (wcsTasks == default)
{
ConsoleLog.Error($"【异常】{stackerId} 号堆垛机入库任务查询失败,与数据库连接异常");
Thread.Sleep(5000);
return false;
}
if (wcsTasks.Count == 0) return false;
var wcsTask = wcsTasks[0]; // 取第一条任务
/* 校验入库站台是否可以取货 */
// TODO
/* 检验并返回起点终点信息 */
var originLocationInfo = CommonData.AppLocations.DetailWithWcsLocation(wcsTask.Origin);
var destinationLocationInfo = CommonData.AppLocations.DetailWithWcsLocation(wcsTask.Destination);
if (destinationLocationInfo == default || originLocationInfo == default) // 起点终点错误,直接标记错误
{
// 已经在接口内做了检查,按道理此处不会出错。直接返回异常,任务直接取消
ConsoleLog.Warning($"【警告】任务号:{wcsTask.TaskId}Plc任务号{wcsTask.PlcId} 无法执行,起点或者终点存在异常");
wcsTaskEvent.ErrTaskEvent(wcsTask, $"起点或者终点存在异常");
return false;
}
StackerPlcTask stackerTask = new()
{
StackerId = stackerId,
PlcId = wcsTask.PlcId,
TaskType = Convert.ToInt16(wcsTask.TaskType),
GetStand = 0,
InTunnelId = Convert.ToInt16(stackerId),
OutTunnelId = Convert.ToInt16(stackerId),
SetStand = 0,
GetQueue = Convert.ToInt16(originLocationInfo.Queue),
GetLine = Convert.ToInt16(originLocationInfo.Line),
GetLayer = Convert.ToInt16(originLocationInfo.Layer),
GetDeep = Convert.ToInt16(originLocationInfo.Depth),
SetQueue = Convert.ToInt16(destinationLocationInfo.Queue),
SetLine = Convert.ToInt16(destinationLocationInfo.Line),
SetLayer = Convert.ToInt16(destinationLocationInfo.Layer),
SetDeep = Convert.ToInt16(destinationLocationInfo.Depth),
Size = Convert.ToInt16(wcsTask.VehicleSize),
Weight = Convert.ToInt16(wcsTask.Weight),
Code = wcsTask.PlcVehicleNo ?? 0,
};
var writeStackerTaskErrText = stackerOperation.WriteTask(stackerTask);
if (string.IsNullOrEmpty(writeStackerTaskErrText))
{
ConsoleLog.Success($"堆垛机:{stackerId} 写入入库任务成功,箱号:{wcsTask.VehicleNo}PlcId{wcsTask.PlcId}{wcsTask.Origin} => {wcsTask.Destination}");
wcsTaskEvent.StartTaskEvent(wcsTask);
return true;
}
else
{
ConsoleLog.Warning($"【警告】堆垛机:{stackerId} 写入入库任务失败,箱号:{wcsTask.VehicleNo}PlcId{wcsTask.PlcId}{wcsTask.Origin} => {wcsTask.Destination},异常信息:{writeStackerTaskErrText}");
wcsTaskEvent.ErrTaskEvent(wcsTask, $"写入任务失败,异常信息:{writeStackerTaskErrText}");
}
return false;
}
/// <summary>
/// 执行堆垛机出库任务,若执行了任务则返回 true
/// </summary>
/// <param name="stackerId"></param>
/// <returns></returns>
public bool ExecuteOutTask(int? stackerId)
{
if (stackerId == default) return false;
var wcsTasks = wcsTaskDao.SelectOutTaskWithStacker((int)stackerId!);
if (wcsTasks == default)
{
ConsoleLog.Error($"【异常】{stackerId} 号堆垛机出库任务查询失败,与数据库连接异常");
Thread.Sleep(5000);
return false;
}
if (wcsTasks.Count == 0) return false;
var wcsTask = wcsTasks[0]; // 取第一条任务
/* 校验出库站台是否可以卸货 */
// TODO
/* 检验并返回起点终点信息 */
var originLocationInfo = CommonData.AppLocations.DetailWithWcsLocation(wcsTask.Origin);
var destinationLocationInfo = CommonData.AppLocations.DetailWithWcsLocation(wcsTask.Destination);
if (destinationLocationInfo == default || originLocationInfo == default) // 起点终点错误,直接标记错误
{
// 已经在接口内做了检查,按道理此处不会出错。直接返回异常,任务直接取消
ConsoleLog.Warning($"【警告】任务号:{wcsTask.TaskId}Plc任务号{wcsTask.PlcId} 无法执行,起点或者终点存在异常");
wcsTaskEvent.ErrTaskEvent(wcsTask, $"起点或者终点存在异常");
return false;
}
StackerPlcTask stackerTask = new()
{
StackerId = stackerId,
PlcId = wcsTask.PlcId,
TaskType = Convert.ToInt16(wcsTask.TaskType),
GetStand = 0,
InTunnelId = Convert.ToInt16(stackerId),
OutTunnelId = Convert.ToInt16(stackerId),
SetStand = 0,
GetQueue = Convert.ToInt16(originLocationInfo.Queue),
GetLine = Convert.ToInt16(originLocationInfo.Line),
GetLayer = Convert.ToInt16(originLocationInfo.Layer),
GetDeep = Convert.ToInt16(originLocationInfo.Depth),
SetQueue = Convert.ToInt16(destinationLocationInfo.Queue),
SetLine = Convert.ToInt16(destinationLocationInfo.Line),
SetLayer = Convert.ToInt16(destinationLocationInfo.Layer),
SetDeep = Convert.ToInt16(destinationLocationInfo.Depth),
Size = Convert.ToInt16(wcsTask.VehicleSize),
Weight = Convert.ToInt16(wcsTask.Weight),
Code = wcsTask.PlcVehicleNo ?? 0,
};
var writeStackerTaskErrText = stackerOperation.WriteTask(stackerTask);
if (string.IsNullOrEmpty(writeStackerTaskErrText))
{
ConsoleLog.Success($"堆垛机:{stackerId} 写入出库任务成功,箱号:{wcsTask.VehicleNo}PlcId{wcsTask.PlcId}{wcsTask.Origin} => {wcsTask.Destination}");
wcsTaskEvent.StartTaskEvent(wcsTask);
return true;
}
else
{
ConsoleLog.Warning($"【警告】堆垛机:{stackerId} 写入出库任务失败,箱号:{wcsTask.VehicleNo}PlcId{wcsTask.PlcId}{wcsTask.Origin} => {wcsTask.Destination},异常信息:{writeStackerTaskErrText}");
wcsTaskEvent.ErrTaskEvent(wcsTask, $"写入任务失败,异常信息:{writeStackerTaskErrText}");
}
return false;
}
/// <summary>
/// 执行堆垛机拣选任务,若执行了任务则返回 true
/// </summary>
/// <param name="stackerId"></param>
/// <returns></returns>
public bool ExecutePickTask(int? stackerId)
{
if (stackerId == default) return false;
var wcsTasks = wcsTaskDao.SelectPickOutTaskWithStacker((int)stackerId!);
if (wcsTasks == default)
{
ConsoleLog.Error($"【异常】{stackerId} 号堆垛机拣选任务查询失败,与数据库连接异常");
Thread.Sleep(5000);
return false;
}
if (wcsTasks.Count == 0) return false;
var wcsTask = wcsTasks[0]; // 取第一条任务
/* 校验出库站台是否可以卸货 */
// TODO
/* 检验并返回起点终点信息 */
var originLocationInfo = CommonData.AppLocations.DetailWithWcsLocation(wcsTask.Origin);
var destinationLocationInfo = CommonData.AppLocations.DetailWithWcsLocation(wcsTask.Destination);
if (destinationLocationInfo == default || originLocationInfo == default) // 起点终点错误,直接标记错误
{
// 已经在接口内做了检查,按道理此处不会出错。直接返回异常,任务直接取消
ConsoleLog.Warning($"【警告】任务号:{wcsTask.TaskId}Plc任务号{wcsTask.PlcId} 无法执行,起点或者终点存在异常");
wcsTaskEvent.ErrTaskEvent(wcsTask, $"起点或者终点存在异常");
return false;
}
StackerPlcTask stackerTask = new()
{
StackerId = stackerId,
PlcId = wcsTask.PlcId,
TaskType = Convert.ToInt16(wcsTask.TaskType),
GetStand = 0,
InTunnelId = Convert.ToInt16(stackerId),
OutTunnelId = Convert.ToInt16(stackerId),
SetStand = 0,
GetQueue = Convert.ToInt16(originLocationInfo.Queue),
GetLine = Convert.ToInt16(originLocationInfo.Line),
GetLayer = Convert.ToInt16(originLocationInfo.Layer),
GetDeep = Convert.ToInt16(originLocationInfo.Depth),
SetQueue = Convert.ToInt16(destinationLocationInfo.Queue),
SetLine = Convert.ToInt16(destinationLocationInfo.Line),
SetLayer = Convert.ToInt16(destinationLocationInfo.Layer),
SetDeep = Convert.ToInt16(destinationLocationInfo.Depth),
Size = Convert.ToInt16(wcsTask.VehicleSize),
Weight = Convert.ToInt16(wcsTask.Weight),
Code = wcsTask.PlcVehicleNo ?? 0,
};
var writeStackerTaskErrText = stackerOperation.WriteTask(stackerTask);
if (string.IsNullOrEmpty(writeStackerTaskErrText))
{
ConsoleLog.Success($"堆垛机:{stackerId} 写入拣选任务成功,箱号:{wcsTask.VehicleNo}PlcId{wcsTask.PlcId}{wcsTask.Origin} => {wcsTask.Destination}");
wcsTaskEvent.StartTaskEvent(wcsTask);
return true;
}
else
{
ConsoleLog.Warning($"【警告】堆垛机:{stackerId} 写入拣选任务失败,箱号:{wcsTask.VehicleNo}PlcId{wcsTask.PlcId}{wcsTask.Origin} => {wcsTask.Destination},异常信息:{writeStackerTaskErrText}");
wcsTaskEvent.ErrTaskEvent(wcsTask, $"写入任务失败,异常信息:{writeStackerTaskErrText}");
}
return false;
}
/// <summary>
/// 执行堆垛机移库任务,若执行了任务则返回 true
/// </summary>
/// <param name="stackerId"></param>
/// <returns></returns>
public bool ExecuteMoveTask(int? stackerId)
{
if (stackerId == default) return false;
var wcsTasks = wcsTaskDao.SelectMoveTaskWithStacker((int)stackerId!);
if (wcsTasks == default)
{
ConsoleLog.Error($"【异常】{stackerId} 号堆垛机移库任务查询失败,与数据库连接异常");
Thread.Sleep(5000);
return false;
}
if (wcsTasks.Count == 0) return false;
var wcsTask = wcsTasks[0]; // 取第一条任务
/* 检验并返回起点终点信息 */
var originLocationInfo = CommonData.AppLocations.DetailWithWcsLocation(wcsTask.Origin);
var destinationLocationInfo = CommonData.AppLocations.DetailWithWcsLocation(wcsTask.Destination);
if (destinationLocationInfo == default || originLocationInfo == default) // 起点终点错误,直接标记错误
{
// 已经在接口内做了检查,按道理此处不会出错。直接返回异常,任务直接取消
ConsoleLog.Warning($"【警告】任务号:{wcsTask.TaskId}Plc任务号{wcsTask.PlcId} 无法执行,起点或者终点存在异常");
wcsTaskEvent.ErrTaskEvent(wcsTask, $"起点或者终点存在异常");
return false;
}
StackerPlcTask stackerTask = new()
{
StackerId = stackerId,
PlcId = wcsTask.PlcId,
TaskType = Convert.ToInt16(wcsTask.TaskType),
GetStand = 0,
InTunnelId = Convert.ToInt16(stackerId),
OutTunnelId = Convert.ToInt16(stackerId),
SetStand = 0,
GetQueue = Convert.ToInt16(originLocationInfo.Queue),
GetLine = Convert.ToInt16(originLocationInfo.Line),
GetLayer = Convert.ToInt16(originLocationInfo.Layer),
GetDeep = Convert.ToInt16(originLocationInfo.Depth),
SetQueue = Convert.ToInt16(destinationLocationInfo.Queue),
SetLine = Convert.ToInt16(destinationLocationInfo.Line),
SetLayer = Convert.ToInt16(destinationLocationInfo.Layer),
SetDeep = Convert.ToInt16(destinationLocationInfo.Depth),
Size = Convert.ToInt16(wcsTask.VehicleSize),
Weight = Convert.ToInt16(wcsTask.Weight),
Code = wcsTask.PlcVehicleNo ?? 0,
};
var writeStackerTaskErrText = stackerOperation.WriteTask(stackerTask);
if (string.IsNullOrEmpty(writeStackerTaskErrText))
{
ConsoleLog.Success($"堆垛机:{stackerId} 写入移库任务成功,箱号:{wcsTask.VehicleNo}PlcId{wcsTask.PlcId}{wcsTask.Origin} => {wcsTask.Destination}");
wcsTaskEvent.StartTaskEvent(wcsTask);
return true;
}
else
{
ConsoleLog.Warning($"【警告】堆垛机:{stackerId} 写入移库任务失败,箱号:{wcsTask.VehicleNo}PlcId{wcsTask.PlcId}{wcsTask.Origin} => {wcsTask.Destination},异常信息:{writeStackerTaskErrText}");
wcsTaskEvent.ErrTaskEvent(wcsTask, $"写入任务失败,异常信息:{writeStackerTaskErrText}");
}
return false;
}
/// <summary>
/// 执行重复入库新任务若执行了返回true
/// </summary>
/// <param name="stackerId"></param>
/// <param name="plcId"></param>
/// <returns></returns>
public bool ExecuteDoubleInTask(int? stackerId, int plcId)
{
if (stackerId == default || plcId == 0) return false;
/* 查找这个PlcId对应的wms任务 */
List<AppWcsTask>? doubleInTasks = wcsTaskDao.Select(new AppWcsTask { PlcId = plcId });
if (doubleInTasks == default)
{
ConsoleLog.Error($"【异常】{stackerId} 号堆垛机重复入库任务检验失败,与数据库连接异常");
Thread.Sleep(5000);
return false;
}
if (doubleInTasks.Count == 0) return false; // 找不到对应的PlcId的任务
var doubleTask = doubleInTasks[0];
/* 查找这个任务的新任务 */
List<AppWcsTask>? newTasks = wcsTaskDao.Select(new AppWcsTask { TaskId = doubleTask.TaskId, TaskType = (int)TaskTypeEnum.newTaskForDoubleIn, TaskStatus = (int)WmsTaskStatusEnum.create });
if (newTasks == default)
{
ConsoleLog.Error($"【异常】{stackerId} 号堆垛机重复入库任务新任务查询失败,与数据库连接异常");
Thread.Sleep(5000);
return false;
}
if (newTasks.Count == 0) return false;
var newTask = newTasks[0];
var destinationLocationInfo = CommonData.AppLocations.DetailWithWcsLocation(newTask.Destination);
if (destinationLocationInfo == default) // 终点错误,直接标记错误
{
// 已经在接口内做了检查,按道理此处不会出错。直接返回异常,任务直接取消
ConsoleLog.Warning($"【警告】任务号:{newTask.TaskId}Plc任务号{newTask.PlcId} 无法执行,新终点存在异常");
wcsTaskEvent.ErrTaskEvent(newTask, $"新终点存在异常");
return false;
}
StackerPlcTask stackerTask = new()
{
StackerId = stackerId,
PlcId = newTask.PlcId,
TaskType = Convert.ToInt16(TaskTypeEnum.inTask),
GetStand = 0,
InTunnelId = Convert.ToInt16(stackerId),
OutTunnelId = Convert.ToInt16(stackerId),
SetStand = 0,
GetQueue = 0,
GetLine = 0,
GetLayer = 0,
GetDeep = 0,
SetQueue = Convert.ToInt16(destinationLocationInfo.Queue),
SetLine = Convert.ToInt16(destinationLocationInfo.Line),
SetLayer = Convert.ToInt16(destinationLocationInfo.Layer),
SetDeep = Convert.ToInt16(destinationLocationInfo.Depth),
Size = Convert.ToInt16(newTask.VehicleSize),
Weight = Convert.ToInt16(newTask.Weight),
Code = newTask.PlcVehicleNo ?? 0,
};
var writeStackerTaskErrText = stackerOperation.WriteTask(stackerTask);
if (string.IsNullOrEmpty(writeStackerTaskErrText))
{
ConsoleLog.Success($"堆垛机:{stackerId} 写入重复入库新任务成功,箱号:{newTask.VehicleNo}PlcId{newTask.PlcId};新目的地:{newTask.Destination}");
wcsTaskEvent.StartTaskEvent(newTask);
return true;
}
else
{
ConsoleLog.Warning($"【警告】堆垛机:{stackerId} 写入重复入库新任务失败,箱号:{newTask.VehicleNo}PlcId{newTask.PlcId};新目的地:{newTask.Destination},异常信息:{writeStackerTaskErrText}");
wcsTaskEvent.ErrTaskEvent(newTask, $"写入任务失败,异常信息:{writeStackerTaskErrText}");
}
return false;
}
}