2024-05-23 07:27:57 +08:00
|
|
|
|
using CirculateTool;
|
|
|
|
|
|
using WcsMain.Business.CommonAction;
|
|
|
|
|
|
using WcsMain.Common;
|
|
|
|
|
|
using WcsMain.DataBase.Dao;
|
|
|
|
|
|
using WcsMain.DataBase.MixDao;
|
|
|
|
|
|
using WcsMain.DataBase.TableEntity;
|
|
|
|
|
|
using WcsMain.DataService;
|
|
|
|
|
|
using WcsMain.Enum.Stacker;
|
|
|
|
|
|
using WcsMain.Enum.TaskEnum;
|
2024-05-30 15:34:20 +08:00
|
|
|
|
using WcsMain.EquipOperation.Convey;
|
|
|
|
|
|
using WcsMain.EquipOperation.Entity.Stacker;
|
|
|
|
|
|
using WcsMain.EquipOperation.Stacker;
|
2024-05-23 07:27:57 +08:00
|
|
|
|
using WcsMain.ExtendMethod;
|
|
|
|
|
|
using static Dm.net.buffer.ByteArrayBuffer;
|
|
|
|
|
|
|
|
|
|
|
|
namespace WcsMain.Business.CirculationTask.Stacker;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 双货叉单深位执行堆垛机任务 ---- 卡特模式
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[Circulation("双货叉单深位执行堆垛机任务")]
|
|
|
|
|
|
public class ExeTaskDoubleFork(
|
|
|
|
|
|
StackerOperation stackerOperation, AppWcsTaskDao wcsTaskDao, WCSTaskExecuteEvent wcsTaskEvent,
|
|
|
|
|
|
ConveyOperation conveyOperation, DataBaseData dataBaseData)
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly WCSTaskExecuteEvent _wcsTaskEvent = wcsTaskEvent;
|
|
|
|
|
|
private readonly AppWcsTaskDao _wcsTaskDao = wcsTaskDao;
|
|
|
|
|
|
private readonly StackerOperation _stackerOperation = stackerOperation;
|
|
|
|
|
|
private readonly ConveyOperation _conveyOperation = conveyOperation;
|
|
|
|
|
|
private readonly DataBaseData _dataBaseData = dataBaseData;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 执行堆垛机任务
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[Circulation("执行堆垛机任务")]
|
|
|
|
|
|
public bool ExecuteStackerTask()
|
|
|
|
|
|
{
|
|
|
|
|
|
List<Task> tasks = [];
|
|
|
|
|
|
foreach (var stacker in CommonData.AppStackers.Open())
|
|
|
|
|
|
{
|
|
|
|
|
|
tasks.Add(Task.Factory.StartNew(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var stackerUseStatus = _stackerOperation.StackerCanUse(stacker.StackerId, out int plcId, out int spare1);
|
|
|
|
|
|
if (stackerUseStatus == StackerUseStatusEnum.Free)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* 空闲时正常执行任务 */
|
|
|
|
|
|
// 移库
|
|
|
|
|
|
bool exeMoveTask = ExecuteMoveTask(stacker.StackerId);
|
|
|
|
|
|
if (exeMoveTask) return;
|
|
|
|
|
|
// 出库
|
|
|
|
|
|
bool exeOutTask = ExecuteOutTask(stacker.StackerId);
|
|
|
|
|
|
if (exeOutTask) return;
|
|
|
|
|
|
// 入库
|
|
|
|
|
|
bool exeInTask = ExecuteInTask(stacker.StackerId);
|
|
|
|
|
|
if (exeInTask) return;
|
|
|
|
|
|
// 拣选
|
|
|
|
|
|
//bool exePickTask = ExecutePickTask(stacker.StackerId);
|
|
|
|
|
|
//if (exePickTask) return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (stackerUseStatus == StackerUseStatusEnum.waitTask)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* 重复入库时执行任务 */
|
|
|
|
|
|
bool exeDoubleInTask = ExecuteDoubleInTask(stacker.StackerId, plcId, 1);
|
|
|
|
|
|
if (exeDoubleInTask) return;
|
|
|
|
|
|
exeDoubleInTask = ExecuteDoubleInTask(stacker.StackerId, spare1, 2);
|
|
|
|
|
|
if (exeDoubleInTask) return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}));
|
|
|
|
|
|
}
|
|
|
|
|
|
Task.WaitAll([.. tasks]);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 执行堆垛机入库任务,若执行了任务则返回 true
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="stackerId"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
private bool ExecuteInTask(int? stackerId)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (stackerId == default) return false;
|
|
|
|
|
|
/* 检查入库站台是否允许取货 */
|
|
|
|
|
|
bool allowGetGoods = _conveyOperation.AllGetVehicle(stackerId.ToString());
|
|
|
|
|
|
if(!allowGetGoods) return false; // 入库站台不允许取货
|
|
|
|
|
|
/* 读取入库站台的条码 */
|
|
|
|
|
|
var codes = _conveyOperation.ReadConveyCode(stackerId.ToString());
|
|
|
|
|
|
if(codes == default || codes.Count != 2) return false;
|
|
|
|
|
|
/* 构造任务数据 */
|
|
|
|
|
|
bool isWriteTask = false; // 指示是否写入任务
|
|
|
|
|
|
for (int i = 0; i < 2; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* 校验货叉开启 */
|
|
|
|
|
|
string forkStatus = CommonData.AppStackers.First(f => f.StackerId == stackerId).ForkStatus ?? "";
|
|
|
|
|
|
if (forkStatus.Length <= i || forkStatus[i] != '1') continue; // 获取数据失败或者货叉未开启
|
|
|
|
|
|
var code = codes[i];
|
|
|
|
|
|
if (string.IsNullOrEmpty(code)) continue; // 检查条码是否为空
|
|
|
|
|
|
ConsoleLog.Warning($"【警告】{stackerId} 号堆垛机,入库位置:{i + 1} 返回:{code}");
|
|
|
|
|
|
if (code == "NoRead") // 检查条码是否为 NoRead
|
|
|
|
|
|
{
|
|
|
|
|
|
/* 检查卸货站台是否允许卸货 */
|
|
|
|
|
|
bool allowSetGoods = _conveyOperation.AllSetVehicle(stackerId.ToString());
|
|
|
|
|
|
if (!allowSetGoods) continue; // 出库站台不允许取货
|
|
|
|
|
|
/* 生成一个直接卸货出去的任务 */
|
|
|
|
|
|
int? plcId = _dataBaseData.GetNewPlcTaskId();
|
|
|
|
|
|
if(plcId == default || plcId == 0) continue;
|
|
|
|
|
|
StackerPlcTask errTask = StackerPlcTask.DefaultErrTask((int)plcId!, (int)stackerId!, i + 1);
|
|
|
|
|
|
string WriteTaskErrText = _stackerOperation.WriteTask(errTask, i + 1);
|
|
|
|
|
|
if(string.IsNullOrEmpty(WriteTaskErrText)) // 写入成功
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Success($"{stackerId} 号堆垛机,入库位置:{i + 1} 条码:{code},写入任务成功,{errTask}");
|
|
|
|
|
|
isWriteTask = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Warning($"【警告】{stackerId} 号堆垛机,入库位置:{i + 1} 条码:{code},写入任务失败,{errTask},异常信息:{WriteTaskErrText},");
|
|
|
|
|
|
}
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
var wcsTasks = _wcsTaskDao.Select(new AppWcsTask { VehicleNo = code, TaskStatus = (int)WcsTaskStatusEnum.create });
|
|
|
|
|
|
if(wcsTasks == default) // 查询任务失败
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Exception($"【警告】{stackerId} 号堆垛机,入库位置:{i + 1} 条码:{code} 查找任务失败,和数据库服务器连接中断");
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(wcsTasks.Count < 1) // 没有任务
|
|
|
|
|
|
{
|
|
|
|
|
|
/* 检查卸货站台是否允许卸货 */
|
|
|
|
|
|
bool allowSetGoods = _conveyOperation.AllSetVehicle(stackerId.ToString());
|
|
|
|
|
|
if (!allowSetGoods) continue; // 出库站台不允许取货
|
|
|
|
|
|
/* 生成一个直接卸货出去的任务 */
|
|
|
|
|
|
ConsoleLog.Warning($"【警告】{stackerId} 号堆垛机,入库位置:{i + 1} 条码:{code} 没有找到对应任务");
|
|
|
|
|
|
int? plcId = _dataBaseData.GetNewPlcTaskId();
|
|
|
|
|
|
if (plcId == default || plcId == 0) continue;
|
|
|
|
|
|
StackerPlcTask errTask = StackerPlcTask.DefaultErrTask((int)plcId!, (int)stackerId!, i + 1, code.ToPlcVehicleNo());
|
|
|
|
|
|
string WriteTaskErrText = _stackerOperation.WriteTask(errTask, i + 1);
|
|
|
|
|
|
if (string.IsNullOrEmpty(WriteTaskErrText)) // 写入成功
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Success($"{stackerId} 号堆垛机,入库位置:{i + 1} 条码:{code},写入任务成功,{errTask}");
|
|
|
|
|
|
isWriteTask = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Warning($"【警告】{stackerId} 号堆垛机,入库位置:{i + 1} 条码:{code},写入任务失败,{errTask},异常信息:{WriteTaskErrText},");
|
|
|
|
|
|
}
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
var wcsTask = wcsTasks[0]; // 找出第一个任务
|
|
|
|
|
|
/* 校验终点是否正确 */
|
|
|
|
|
|
var destinationLocationInfo = CommonData.AppLocations.DetailWithWcsLocation(wcsTask.Destination);
|
|
|
|
|
|
if(destinationLocationInfo == default) // 任务终点错误,理论上此处不应该出现异常
|
|
|
|
|
|
{
|
|
|
|
|
|
/* 检查卸货站台是否允许卸货 */
|
|
|
|
|
|
bool allowSetGoods = _conveyOperation.AllSetVehicle(stackerId.ToString());
|
|
|
|
|
|
if (!allowSetGoods) continue; // 出库站台不允许取货
|
|
|
|
|
|
/* 生成一个直接卸货出去的任务 */
|
|
|
|
|
|
ConsoleLog.Warning($"【警告】{stackerId} 号堆垛机,入库位置:{i + 1} 条码:{code} 无法识别的入库库位");
|
|
|
|
|
|
int? plcId = _dataBaseData.GetNewPlcTaskId();
|
|
|
|
|
|
if (plcId == default || plcId == 0) continue;
|
|
|
|
|
|
StackerPlcTask errTask = StackerPlcTask.DefaultErrTask((int)plcId!, (int)stackerId!, i + 1, code.ToPlcVehicleNo());
|
|
|
|
|
|
string WriteTaskErrText = _stackerOperation.WriteTask(errTask, i + 1);
|
|
|
|
|
|
if (string.IsNullOrEmpty(WriteTaskErrText)) // 写入成功
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Success($"{stackerId} 号堆垛机,入库位置:{i + 1} 条码:{code},写入任务成功,{errTask}");
|
|
|
|
|
|
_wcsTaskEvent.ErrTaskEvent(wcsTask, "入库库位不正确");
|
|
|
|
|
|
isWriteTask = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Warning($"【警告】{stackerId} 号堆垛机,入库位置:{i + 1} 条码:{code},写入任务失败,{errTask},异常信息:{WriteTaskErrText},");
|
|
|
|
|
|
}
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
/* 判断冲突货位是否有任务 */
|
|
|
|
|
|
var runningWcsTasks = _wcsTaskDao.QueryTaskWithWcsLocation(destinationLocationInfo.InterveneLocation);
|
|
|
|
|
|
if (runningWcsTasks == default) continue; // 查询失败
|
|
|
|
|
|
if(runningWcsTasks.Count > 0) continue; // 存在冲突点位,等待
|
|
|
|
|
|
/* 下发任务 */
|
|
|
|
|
|
StackerPlcTask stackerTask = wcsTask.ToStackerInTask((int)stackerId!, i + 1, destinationLocationInfo);
|
|
|
|
|
|
string WriteStackerTaskErrText = _stackerOperation.WriteTask(stackerTask, i + 1);
|
|
|
|
|
|
if (string.IsNullOrEmpty(WriteStackerTaskErrText)) // 写入成功
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Success($"{stackerId} 号堆垛机,入库位置:{i + 1} 条码:{code},写入任务成功,{stackerTask}");
|
|
|
|
|
|
_wcsTaskEvent.StartTaskEvent(wcsTask); // 任务开始
|
|
|
|
|
|
isWriteTask = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Warning($"【警告】{stackerId} 号堆垛机,入库位置:{i + 1} 条码:{code},写入任务失败,{stackerTask},异常信息:{WriteStackerTaskErrText},");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (isWriteTask)
|
|
|
|
|
|
{
|
|
|
|
|
|
string confirmResult = _stackerOperation.WriteTaskConfirm(stackerId); // 写入任务确认
|
|
|
|
|
|
ConsoleLog.Info($"堆垛机入库任务写任务确认;信息:{(string.IsNullOrEmpty(confirmResult) ? "成功" : confirmResult)}");
|
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
|
}
|
|
|
|
|
|
return isWriteTask;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 执行堆垛机出库任务,若执行了任务则返回 true
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="stackerId"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public bool ExecuteOutTask(int? stackerId)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (stackerId == default) return false;
|
|
|
|
|
|
/* 检查出库站台是否可以卸货 */
|
|
|
|
|
|
bool allowSetGoods = _conveyOperation.AllSetVehicle(stackerId.ToString());
|
|
|
|
|
|
if (!allowSetGoods) return false; // 出库站台不允许取货
|
|
|
|
|
|
var wcsTasks = _wcsTaskDao.SelectOutTaskWithStacker((int)stackerId!);
|
|
|
|
|
|
if (wcsTasks == default)
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Exception(string.Format("【异常】{0} 号堆垛机出库任务查询失败,与数据库连接异常", stackerId));
|
|
|
|
|
|
Thread.Sleep(5000);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (wcsTasks.Count == 0) return false;
|
|
|
|
|
|
bool isWriteTask = false; // 指示是否写入任务
|
|
|
|
|
|
int writeTaskCount = 0; // 表示执行了多少条任务
|
|
|
|
|
|
for (int i = 0; i < wcsTasks.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (writeTaskCount >= 2) break; // 最多执行两条
|
|
|
|
|
|
/* 校验货叉开启 */
|
|
|
|
|
|
string forkStatus = CommonData.AppStackers.First(f => f.StackerId == stackerId).ForkStatus ?? "";
|
|
|
|
|
|
if (forkStatus.Length <= i || forkStatus[i] != '1')
|
|
|
|
|
|
{
|
|
|
|
|
|
writeTaskCount ++;
|
|
|
|
|
|
continue; // 获取数据失败或者货叉未开启
|
|
|
|
|
|
}
|
|
|
|
|
|
var wcsTask = wcsTasks[i];
|
|
|
|
|
|
/* 校验起点是否正确 */
|
|
|
|
|
|
var originLocationInfo = CommonData.AppLocations.DetailWithWcsLocation(wcsTask.Origin);
|
|
|
|
|
|
if (originLocationInfo == default) // 任务起点错误,理论上此处不应该出现异常
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Warning($"【警告】{stackerId} 号堆垛机,出库库位:{wcsTask.Origin} 条码:{wcsTask.VehicleNo} 无法识别的出库库位");
|
|
|
|
|
|
_wcsTaskEvent.ErrTaskEvent(wcsTask, "出库的库位不正确");
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
/* 判断冲突货位是否有任务 */
|
|
|
|
|
|
var runningWcsTasks = _wcsTaskDao.QueryTaskWithWcsLocation(originLocationInfo.InterveneLocation);
|
|
|
|
|
|
if (runningWcsTasks == default) continue; // 查询失败
|
|
|
|
|
|
if (runningWcsTasks.Count > 0) continue; // 存在冲突点位,等待
|
|
|
|
|
|
/* 下发任务 */
|
|
|
|
|
|
StackerPlcTask stackerTask = wcsTask.ToStackerOutTask((int)stackerId!, i + 1, originLocationInfo);
|
|
|
|
|
|
string WriteStackerTaskErrText = _stackerOperation.WriteTask(stackerTask, i + 1);
|
|
|
|
|
|
if (string.IsNullOrEmpty(WriteStackerTaskErrText)) // 写入成功
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Success($"{stackerId} 号堆垛机,出库位置:{i + 1} 条码:{wcsTask.VehicleNo},写入任务成功,{stackerTask}");
|
|
|
|
|
|
_wcsTaskEvent.StartTaskEvent(wcsTask); // 任务开始
|
|
|
|
|
|
writeTaskCount++;
|
|
|
|
|
|
isWriteTask = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Warning($"【警告】{stackerId} 号堆垛机,出库位置:{i + 1} 条码:{wcsTask.VehicleNo},写入任务失败,{stackerTask},异常信息:{WriteStackerTaskErrText},");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (isWriteTask)
|
|
|
|
|
|
{
|
|
|
|
|
|
string confirmResult = _stackerOperation.WriteTaskConfirm(stackerId); // 写入任务确认
|
|
|
|
|
|
ConsoleLog.Info($"堆垛机出库任务写任务确认;信息:{(string.IsNullOrEmpty(confirmResult) ? "成功" : confirmResult)}");
|
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
|
}
|
|
|
|
|
|
return isWriteTask;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <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;
|
|
|
|
|
|
bool isWriteTask = false; // 指示是否写入任务
|
|
|
|
|
|
int writeTaskCount = 0; // 表示执行了多少条任务
|
|
|
|
|
|
for (int i = 0; i < wcsTasks.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (writeTaskCount >= 2) break; // 最多执行两条
|
|
|
|
|
|
/* 校验货叉开启 */
|
|
|
|
|
|
string forkStatus = CommonData.AppStackers.First(f => f.StackerId == stackerId).ForkStatus ?? "";
|
|
|
|
|
|
if (forkStatus.Length <= i || forkStatus[i] != '1')
|
|
|
|
|
|
{
|
|
|
|
|
|
writeTaskCount++;
|
|
|
|
|
|
continue; // 获取数据失败或者货叉未开启
|
|
|
|
|
|
}
|
|
|
|
|
|
var wcsTask = wcsTasks[i];
|
|
|
|
|
|
/* 校验起点是否正确 */
|
|
|
|
|
|
var originLocationInfo = CommonData.AppLocations.DetailWithWcsLocation(wcsTask.Origin);
|
|
|
|
|
|
var destinationLocationInfo = CommonData.AppLocations.DetailWithWcsLocation(wcsTask.Origin);
|
|
|
|
|
|
if (originLocationInfo == default || destinationLocationInfo == default) // 任务起点终点错误,理论上此处不应该出现异常
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Warning($"【警告】{stackerId} 号堆垛机,移库库位:{wcsTask.Origin} 条码:{wcsTask.VehicleNo} 无法识别的库位");
|
|
|
|
|
|
_wcsTaskEvent.ErrTaskEvent(wcsTask, "移库的库位不正确");
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
/* 判断冲突货位是否有任务,起点终点都要判断 */
|
|
|
|
|
|
var runningWcsTasks = _wcsTaskDao.QueryTaskWithWcsLocation(destinationLocationInfo.InterveneLocation, originLocationInfo.InterveneLocation);
|
|
|
|
|
|
if (runningWcsTasks == default) continue; // 查询失败
|
|
|
|
|
|
if (runningWcsTasks.Count > 0) continue; // 存在冲突点位,等待
|
|
|
|
|
|
/* 下发任务 */
|
|
|
|
|
|
StackerPlcTask stackerTask = wcsTask.ToStackerMoveTask((int)stackerId!, originLocationInfo, destinationLocationInfo);
|
|
|
|
|
|
string WriteStackerTaskErrText = _stackerOperation.WriteTask(stackerTask, i + 1);
|
|
|
|
|
|
if (string.IsNullOrEmpty(WriteStackerTaskErrText)) // 写入成功
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Success($"{stackerId} 号堆垛机,移库位置:{i + 1} 条码:{wcsTask.VehicleNo},写入任务成功,{stackerTask}");
|
|
|
|
|
|
_wcsTaskEvent.StartTaskEvent(wcsTask); // 任务开始
|
|
|
|
|
|
writeTaskCount++;
|
|
|
|
|
|
isWriteTask = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleLog.Warning($"【警告】{stackerId} 号堆垛机,移库位置:{i + 1} 条码:{wcsTask.VehicleNo},写入任务失败,{stackerTask},异常信息:{WriteStackerTaskErrText},");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (isWriteTask)
|
|
|
|
|
|
{
|
|
|
|
|
|
string confirmResult = _stackerOperation.WriteTaskConfirm(stackerId); // 写入任务确认
|
|
|
|
|
|
ConsoleLog.Info($"堆垛机移库任务写任务确认;信息:{(string.IsNullOrEmpty(confirmResult) ? "成功" : confirmResult)}");
|
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
|
}
|
|
|
|
|
|
return isWriteTask;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 执行重复入库新任务,若执行了返回true
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="stackerId"></param>
|
|
|
|
|
|
/// <param name="plcId"></param>
|
|
|
|
|
|
/// <param name="forkId">货叉编号</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public bool ExecuteDoubleInTask(int? stackerId, int plcId, int forkId)
|
|
|
|
|
|
{
|
|
|
|
|
|
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];
|
|
|
|
|
|
/* 判断这个任务是否出现卸货位置有货 */
|
|
|
|
|
|
if(doubleTask.TaskStatus != (int)WcsTaskStatusEnum.doubleIn) { return false; } // 没有重复入库不执行下面方法
|
|
|
|
|
|
/* 查找这个任务的新任务 */
|
|
|
|
|
|
List<AppWcsTask>? newTasks = _wcsTaskDao.Select(new AppWcsTask { TaskId = doubleTask.TaskId, TaskType = (int)WcsTaskTypeEnum.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;
|
|
|
|
|
|
}
|
|
|
|
|
|
/* 判断冲突货位是否有任务 */
|
|
|
|
|
|
var runningWcsTasks = _wcsTaskDao.QueryTaskWithWcsLocation(destinationLocationInfo.InterveneLocation);
|
|
|
|
|
|
if (runningWcsTasks == default) return false; // 查询失败
|
|
|
|
|
|
if (runningWcsTasks.Count > 0) return false; // 存在冲突点位,等待
|
|
|
|
|
|
/* 下发任务 */
|
|
|
|
|
|
StackerPlcTask stackerTask = newTask.ToStackerInTask((int)stackerId!, forkId, destinationLocationInfo);
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|