using PlcSiemens.Core.Extension;
using ServiceCenter.Extensions;
using ServiceCenter.Logs;
using ServiceCenter.SqlSugars;
using SqlSugar;
using System.ComponentModel;
using WCS.Core;
using WCS.Entity;
using WCS.Entity.Protocol.Station;
using WCS.WorkEngineering.Extensions;
using WCS.WorkEngineering.Worlds;
using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
using TaskStatus = WCS.Entity.TaskStatus;
namespace WCS.WorkEngineering.Systems
{
///
/// 无交互系统
///
[BelongTo(typeof(NoInteractionWorld))]
[Description("无交互系统")]
public class NoInteractionSystems : DeviceSystem>
{
protected override bool ParallelDo => true;
public override void Do(Device obj)
{
var taskInfos = new List();
var sqlSugar = new SqlSugarHelper();
SqlSugarHelper.Do(db =>
{
//获取所有的新建任务,组盘任务不需要
taskInfos = db.Default.Queryable().ReadPastUpdLock().Where(x => x.Status == 0).ToList()
.Where(x => x.Type != TaskType.SetPlate || (x.Type == TaskType.SetPlate && x.AddrFrom != "Robot")).Where(x => x.BusType != "人工满托入库").Select(x => x.ID).ToList();
var time = DateTime.Now.AddMinutes(-20);
var time1 = DateTime.Now.AddMinutes(-40);
var timeOut = db.Default.Queryable().NoLock().Count(x => x.BusType == "车间叫料" && x.Status < TaskStatus.StackerExecution && x.AddTime < time);
if (timeOut > 0) World.Log($"共有{timeOut}个车间叫料任务超过二十分钟未执行,请检查相关相关任务对应的堆垛机是否正常、堆垛机放货点是否卡任务等", LogLevelEnum.High);
var timeOut1 = db.Default.Queryable().NoLock().Count(x => x.BusType == "车间叫料" && x.Status < TaskStatus.StackerExecution && x.AddTime < time1);
if (timeOut1 > 0) World.Log($"共有{timeOut1}个车间叫料任务超过四十分钟未执行,请检查相关相关任务对应的堆垛机是否正常、堆垛机放货点是否卡任务等", LogLevelEnum.High);
var timeOut2 = db.Default.Queryable().NoLock().Count(x => x.BusType == "皮盘入库" && x.Status < TaskStatus.StackerExecution && x.AddTime < time);
if (timeOut2 > 0) World.Log($"共有{timeOut2}个皮盘入库任务超过二十分钟未执行,请检查相关相关任务及对应agv设备", LogLevelEnum.High);
var timeOut3 = db.Default.Queryable().NoLock().Count(x => x.BusType == "皮盘入库" && x.Status < TaskStatus.StackerExecution && x.AddTime < time1);
if (timeOut3 > 0) World.Log($"共有{timeOut3}个皮盘入库任务超过四十分钟未执行,请检查相关相关任务及对应agv设备", LogLevelEnum.High);
var time3 = DateTime.Now.AddHours(-24);
var timeOut4 = db.Default.Queryable().NoLock().Count(x => x.AddTime < time3);
if (timeOut4 > 0) World.Log($"共有{timeOut4}个库存信息超过24小时未执行,请检查相关库存信息并处理", LogLevelEnum.High);
});
if (!taskInfos.Any())
{
return;
}
var isEnd = false; //每个周期只处理一个任务
foreach (var item in taskInfos)
{
if (isEnd) return;
try
{
SqlSugarHelper.Do(db =>
{
var task = db.Default.Queryable().Where(t => t.ID == item).First();
switch (task.Type)
{
case TaskType.SetPlate:
if (task.AddrFrom != "Robot")
{
//更新任务状态
task.Status = TaskStatus.WaitingToExecute;
db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status }).ExecuteCommand();
task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化入库任务信息");
isEnd = true;
}
break;
case TaskType.EnterDepot:
if (task.LastInteractionPoint == "2")
{
var sta = GetAgvStation(task, db);
var agv = new WCS_AgvTaskInfo()
{
ID = db.GetAgvTaskId(),
TaskType = AGVTaskType.EnterDepot,
Status = AGVTaskStatus.NewBuild,
TaskId = task.ID,
Position = task.WorkBench,
Station = sta,
AddWho = "WCS",
AddTime = DateTime.Now
};
db.Default.InsertableRowLock(agv).SplitTable().ExecuteCommand();
task.AgvTaskID = agv.ID;
task.Status = Entity.TaskStatus.WaitingToExecute;
db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.AgvTaskID }).ExecuteCommand();
task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化单独返皮盘任务");
}
else
{
//更新任务状态
task.Status = Entity.TaskStatus.WaitingToExecute;
task.Device = task.WarehouseCode switch
{
"1N" => "SRM1",
"1S" => "SRM2",
"2N" => "SRM3",
"2S" => "SRM4",
"3N" => "SRM5",
"3S" => "SRM6",
_ => task.Device
};
task.Device = task.AddrFrom switch
{
"1666" or "1661" => "SRM1",
"1681" or "1676" => "SRM2",
"1696" or "1691" => "SRM3",
"1711" or "1706" => "SRM4",
"1726" or "1721" => "SRM5",
"1741" or "1736" => "SRM6",
_ => task.Device
};
//计算下一个地址
var path1 = DevicePath.GetPath(task.AddrFrom, task.Device);
task.AddrNext = path1.Points[1].Code;
task.SrmStation = task.BarCode.Contains("TPA") || task.BarCode.Contains("TPB") ? task.AddrFrom : path1.Points[2].Code;
db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.Device, x.AddrNext, x.SrmStation }).ExecuteCommand();
task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化入库任务信息");
}
isEnd = true;
break;
case TaskType.OutDepot:
{
if (task.Device.Contains("Robot"))
{
var lastTask = db.Default.Queryable().NoLock().First(x => x.Type == TaskType.OutDepot && x.AddrTo == task.AddrTo && x.Status > TaskStatus.WaitingToExecute && x.Status < TaskStatus.Finish);
if (lastTask != null)
{
World.Log($"等待任务结束:{task.AddrTo}上一组码垛任务未结束,等待{lastTask.ID}任务完成后开始初始化当前任务{task.ID}");
return;
}
var pos = task.AddrFrom.Split("-");
task.Status = Entity.TaskStatus.WaitingToExecute;
task.Line = pos[0].ToShort();
task.Col = pos[1].ToShort();
task.Layer = pos[2].ToShort();
task.Depth = pos[3].ToShort();
db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.Line, x.Col, x.Layer, x.Depth }).ExecuteCommand();
task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化出库任务信息,放货站台:{task.SrmStation}");
isEnd = true;
}
else
{
if (task.SrmStation == "1")
{
var srmStation = new string[2];
switch (task.Device)
{
case "SRM1":
srmStation[0] = "2534";
srmStation[1] = "2533";
break;
case "SRM2":
srmStation[0] = "2734";
srmStation[1] = "2733";
break;
case "SRM3":
srmStation[0] = "2934";
srmStation[1] = "2933";
break;
case "SRM4":
srmStation[0] = "3134";
srmStation[1] = "3133";
break;
case "SRM5":
srmStation[0] = "3334";
srmStation[1] = "3333";
break;
case "SRM6":
srmStation[0] = "3534";
srmStation[1] = "3533";
break;
}
//开始计算当前这个任务要从哪个站台出
//计算两个站台小于取货完成数量的AGV任务
var agv1 = db.Default.Queryable().NoLock().Where(x => x.Status <= TaskStatus.StackerExecution && x.AddrTo == srmStation[0]).Count();
var agv2 = db.Default.Queryable().NoLock().Where(x => x.Status <= TaskStatus.StackerExecution && x.AddrTo == srmStation[1]).Count();
task.SrmStation = "";
task.AddrTo = agv1 > agv2 ? srmStation[1] : srmStation[0];
}
if (task.SrmStation.IsNullOrEmpty()) //如果没有指定放货站台
{
if (task.Device.IsNullOrEmpty())
{
task.Device = "SRM" + task.Tunnel.GetLastDigit();
}
//获取堆垛机到目标地址的路径信息
var path = DevicePath.GetPath(task.Device, task.AddrTo);
task.SrmStation = path.Points[1].Code;
}
var devs = Device.All.Where(x => x.HasFlag(DeviceFlags.AGV取货站台口)).Select(x => x.Code);
if (devs.Contains(task.SrmStation) && task.LastInteractionPoint != "3") //车间叫料任务,此值为3时是单独取满任务
{
var sta = GetAgvStation(task, db);
var agv = new WCS_AgvTaskInfo()
{
ID = db.GetAgvTaskId(),
TaskType = AGVTaskType.EnterDepot,
Status = AGVTaskStatus.NewBuild,
TaskId = task.ID,
Position = task.WorkBench,
Station = sta,
AddWho = "WCS",
AddTime = DateTime.Now
};
db.Default.InsertableRowLock(agv).SplitTable().ExecuteCommand();
}
//更新任务状态
task.Status = Entity.TaskStatus.WaitingToExecute;
db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.SrmStation, x.AddrTo, x.Status }).ExecuteCommand();
task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化出库任务信息,放货站台:{task.SrmStation}");
isEnd = true;
}
break;
}
case TaskType.Delivery:
break;
case TaskType.EmptyInit:
break;
}
});
}
catch (Exception ex)
{
if (ex.Message.Contains("Index")) World.Log($"{ex.Message}:{ex.StackTrace}");
if (ex.Message.Contains("SqlTransaction")) World.Log($"{ex.Message}:{ex.StackTrace}");
World.Log(ex.Message, LogLevelEnum.Mid);
}
}
}
public override bool Select(Device dev)
{
return dev.Code == nameof(NoInteractionSystems);
}
///
/// 获取AGV的目标站台
///
///
///
///
public string GetAgvStation(WCS_TaskInfo task, SqlSugarHelper db)
{
string sta = "";
var n = 0;
var s = 0;
//同侧之间均分
if (task.WarehouseCode.Contains("1"))
{
n = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station.Contains("25"))
.SplitTable(v => v.Take(2)).Count();
s = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station.Contains("27"))
.SplitTable(v => v.Take(2)).Count();
sta = n > s ? "2701" : "2501";
}
else if (task.WarehouseCode.Contains("2"))
{
n = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station.Contains("29"))
.SplitTable(v => v.Take(2)).Count();
s = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station.Contains("31"))
.SplitTable(v => v.Take(2)).Count();
sta = n > s ? "3101" : "2901";
}
else if (task.WarehouseCode.Contains("3"))
{
n = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station.Contains("33"))
.SplitTable(v => v.Take(2)).Count();
s = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station.Contains("35"))
.SplitTable(v => v.Take(2)).Count();
sta = n > s ? "3501" : "3301";
}
else
{
return default;
}
n = db.Default.Queryable().NoLock().Where(v =>
v.Status >= AGVTaskStatus.Confirm &&
v.Status < AGVTaskStatus.Complete1 &&
v.TaskType == AGVTaskType.EnterDepot && v.Station == sta)
.SplitTable(v => v.Take(2)).Count();
if (n > 5)
{
sta = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot)
.SplitTable(v => v.Take(2)).ToList().GroupBy(x => x.Station).Select(x => new { x.Key, Count = x.Count() }).MinBy(x => x.Count).Key;
}
return sta;
}
}
}