using Newtonsoft.Json;
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.Model.WMS;
using WCS.WorkEngineering.WebApi.Controllers;
using WCS.WorkEngineering.WebApi.Models.WMS.Request;
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().NoLock().Where(x => x.Status == 0).ToList()
.Where(x => x.Type != TaskType.SetPlate || (x.Type == TaskType.SetPlate && x.AddrFrom != "Robot") && x.BusType!="芯股用空托盘入库" && !x.BarCode.Contains("Error")).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 && x.ContGrpBarCode.Contains("TPB"));
if (timeOut4 > 0) World.Log($"共有{timeOut4}个库存信息超过24小时未执行,请检查相关库存信息并处理", LogLevelEnum.High);
var time4 = DateTime.Now.AddHours(-12);
var timeOut5 = db.Default.Queryable().NoLock().Where(x => x.AddTime < time4 && !x.Finish).ToList();
if (timeOut5.Count > 0) World.Log($"共有{timeOut5.Count}个桁架码垛信息超过12小时未结束,请检查相关码垛信息并处理,具体在{JsonConvert.SerializeObject(timeOut5.Select(x=>x.PalletizingStation).ToList())}", 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().RowLock().Where(t => t.ID == item && t.Status== TaskStatus.NewBuild).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 if (task.BusType == TaskBusType.芯股用空托盘入库.GetDescription()) return;
else if (task.BusType == TaskBusType.人工满托入库.GetDescription())
{
var agv = new WCS_AgvTaskInfo()
{
ID = db.GetAgvTaskId(),
TaskType = AGVTaskType.EnterDepot,
Status = AGVTaskStatus.NewBuild,
TaskId = task.ID,
Position = task.WorkBench,
Station = task.WarehouseCode switch
{
"1N" => "2535",
"1S" => "2735",
"2N" => "2935",
"2S" => "3135",
_ => "2535"
},
AddWho = "WCS",
AddTime = DateTime.Now
};
db.Default.InsertableRowLock(agv).SplitTable().ExecuteCommand();
task.AgvTaskID = agv.ID;
task.Device = task.WarehouseCode switch
{
"1N" => "TY1",
"1S" => "TY2",
"2N" => "TY3",
"2S" => "TY4",
_ => "TY1"
};
task.Height = 1;
task.Status = Entity.TaskStatus.WaitingToExecute;
db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.AgvTaskID, x.Device, x.Height }).ExecuteCommand();
task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化人工满托入库任务");
}
else if (task.BusType == TaskBusType.UT人工满托入库.GetDescription())
{
var agv = new WCS_AgvTaskInfo()
{
ID = db.GetAgvTaskId(),
TaskType = AGVTaskType.EnterDepot,
Status = AGVTaskStatus.NewBuild,
TaskId = task.ID,
Position = task.WorkBench,
Station = task.WarehouseCode switch
{
"1N" => "2533",
"1S" => "2733",
"2N" => "2933",
"2S" => "3133",
_ => "2533"
},
AddWho = "WCS",
AddTime = DateTime.Now
};
db.Default.InsertableRowLock(agv).SplitTable().ExecuteCommand();
task.AgvTaskID = agv.ID;
task.Device = task.WarehouseCode switch
{
"1N" => "TY1",
"1S" => "TY2",
"2N" => "TY3",
"2S" => "TY4",
_ => "TY1"
};
task.Height = 1;
task.Status = Entity.TaskStatus.WaitingToExecute;
db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.AgvTaskID, x.Device, x.Height }).ExecuteCommand();
task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化UT人工满托入库任务");
}
else if (task.BusType == TaskBusType.重绕满托入库.GetDescription())
{
task.Status = Entity.TaskStatus.WaitingToExecute;
db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status }).ExecuteCommand();
task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化入库任务信息");
}
else if (task.BusType == TaskBusType.帘线退料重绕.GetDescription())
{
var agv = new WCS_AgvTaskInfo()
{
ID = db.GetAgvTaskId(),
TaskType = AGVTaskType.EnterDepot,
Status = AGVTaskStatus.NewBuild,
TaskId = task.ID,
Position = task.WorkBench,
WorkShop = 222,
Station = "9001",
AddWho = "WCS",
AddTime = DateTime.Now
};
db.Default.InsertableRowLock(agv).SplitTable().ExecuteCommand();
task.Status = Entity.TaskStatus.WaitingToExecute;
task.AgvTaskID = agv.ID;
task.AddrTo = agv.Station;
db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status,x.AgvTaskID,x.AddrTo }).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;
//var des1 = task.AddrNext;
//var des2 = "1";
////分拣一
//if (task.AddrNext == "1604")
//{
// des2 = "1606";
//}
////else if (task.AddrNext == "1614")
////{
//// des2 = "1616";
////}
//var num1 = db.Default.Queryable().RowLock().Where(t => t.WorkBench == des1 && t.Status < TaskStatus.Finish && t.Type == TaskType.EnterDepot).Count();
//var num2 = db.Default.Queryable().RowLock().Where(t => t.WorkBench == des2 && t.Status < TaskStatus.Finish && t.Type == TaskType.EnterDepot).Count();
//if (task.AddrNext == "1604")
//{
// task.AddrNext = num1 <= num2 ? des2 : des1;
//}
//task.WorkBench = task.AddrNext;
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, x.WorkBench }).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.Device == "FJXG") //芯股仓库的任务
{
if (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();
}
var agvId = DateTime.Now.GetFormat(GetFormatterEnum.only) + task.ID;
var agvTask = new WCS_AgvTaskInfo()
{
ID = db.GetAgvTaskId(),
TaskType = AGVTaskType.CallMaterial,
Status = AGVTaskStatus.NewBuild,
TaskId = task.ID,
Position = task.WorkBench,
Station = task.AddrFrom,
AddWho = "WCS",
AddTime = DateTime.Now,
AgvID = agvId
};
//开始处理车间叫料AGV任务任务
db.Default.InsertableRowLock(agvTask).SplitTable().ExecuteCommand();
agvTask = db.Default.Queryable().RowLock().SplitTable(x => x.Take(2)).Single(x => x.TaskId == task.ID && x.TaskType == AGVTaskType.CallMaterial);
if (agvTask.Status != AGVTaskStatus.NewBuild)
{
World.Log($"AGV任务{agvTask.ID}状态不是新建", LogLevelEnum.High);
return;
}
agvId = agvTask.AgvID;
agvTask.Status = AGVTaskStatus.Confirm;
agvTask.AgvStatus = AGVTaskStatus.Confirm;
db.Default.UpdateableRowLock(agvTask).UpdateColumns(x => new { x.AgvID, x.Status, x.AgvStatus }).SplitTable(x => x.Take(2)).ExecuteCommand();
task.Status = TaskStatus.AGVExecution;
task.AgvTaskID = agvTask.ID;
task.EditTime = DateTime.Now;
task.EditWho = "WCS";
db.Default.Updateable(task).UpdateColumns(x => new { x.Status, x.AgvTaskID, x.EditTime, x.EditWho }).ExecuteCommand();
task.AddWCS_TASK_DTL(db.Default, task.AddrFrom, "AGV", $"任务下发至AGV{agvId}");
var res = AgvApi.机台叫料(task.AddrFrom, task.WorkBench, agvId);
isEnd = true;
}
else if (task.BusType == TaskBusType.芯股站台送空托.GetDescription())
{
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 = "";
//if (srmStation[0] == "2534"/* || srmStation[0] == "2934"*/)
//{
// task.AddrTo = srmStation[0];
//}
//else
{
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;
}
//更新任务状态
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;
}
else if (task.Device == "CR")
{
if (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 = "2501",//默认去分拣一
AddWho = "WCS",
AddTime = DateTime.Now
};
db.Default.InsertableRowLock(agv).SplitTable().ExecuteCommand();
}
//更新任务状态
task.Status = Entity.TaskStatus.WaitingToExecute;
task.AddrTo = task.WorkBench;
db.Default.UpdateableRowLock(task).UpdateColumns(x => new {x.Status , x.AddrTo }).ExecuteCommand();
task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化出库任务信息,重绕组盘区{task.AddrFrom}");
isEnd = true;
break;
}
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 = "";
//if (srmStation[0] == "2534"/* || srmStation[0] == "2934"*/)
//{
// task.AddrTo = srmStation[0];
//}
//else
{
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的目标站台
///
/// 任务信息
/// 数据库操作对象
/// 目标站台
private string GetAgvStation(WCS_TaskInfo task, SqlSugarHelper db)
{
// 默认站台
var defaultStation = "2701";
var sta = defaultStation;
// 定义仓库与站台的映射关系
var stationMap = new Dictionary
{
["1"] = ("2501", "2701"),
["2"] = ("2901", "3101"),
["3"] = ("3301", "3501")
};
var oldWarehouseCode = task.WarehouseCode;
// 检查是否需要更新 warehouseCode
if (task.BusType == TaskBusType.皮盘入库.GetDescription() || task.BusType == TaskBusType.车间叫料.GetDescription())
{
task.WarehouseCode = task.MaterialCode switch
{
"分拣库1北" => "1N",
"分拣库1南" => "1S",
"分拣库2北" => "2N",
"分拣库2南" => "2S",
"分拣库3北" => "3N",
"分拣库3南" => "3S",
_ => task.WarehouseCode
};
}
// 确定站台初始值
if (stationMap.TryGetValue(task.WarehouseCode[0].ToString(), out var stationPair))
sta = task.WarehouseCode.Contains("N") ? stationPair.N : stationPair.S;
// 配置值获取
var num = db.Default.Queryable()
.NoLock()
.First(x => x.Code == "SameSideTaskNum")?.SContent.ToInt() ?? 5;
// 判断当前侧任务数量是否超出限制
var currentTaskCount = GetStationTaskCount(db, sta);
if (currentTaskCount > num)
{
// 同一分拣库的两侧均分任务
if (task.WarehouseCode.StartsWith("1") || task.WarehouseCode.StartsWith("2") ||
task.WarehouseCode.StartsWith("3"))
{
var (northCount, southCount) = GetNorthAndSouthTaskCounts(db, stationPair);
sta = southCount > northCount ? stationPair.N : stationPair.S;
}
else
{
return defaultStation;
}
}
// 配置值获取
num = db.Default.Queryable()
.NoLock()
.First(x => x.Code == "TasksInSameWarehouse")?.SContent.ToInt() ?? 10;
// 判断是否需要在三个分拣中心中选取任务数量较少的一侧进行分配
currentTaskCount = GetStationTaskCount(db, sta);
var otherSide = stationMap.First(x => x.Value.N == sta || x.Value.S == sta);
currentTaskCount += GetStationTaskCount(db, otherSide.Value.N==sta ? otherSide.Value.S : otherSide.Value.N);
if (currentTaskCount > num)
{
sta = db.Default.Queryable()
.NoLock()
.Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 &&
v.TaskType == AGVTaskType.EnterDepot &&
(v.Station != "2535" && v.Station != "2735" && v.Station != "2935" && v.Station != "3135" && !v.Station.StartsWith("9")))
.SplitTable(v => v.Take(2))
.ToList()
.GroupBy(x => x.Station)
.Select(g => new { Station = g.Key, Count = g.Count() })
.OrderBy(x => x.Count)
.FirstOrDefault()?.Station ?? defaultStation;
}
task.WarehouseCode = oldWarehouseCode;
return sta;
}
///
/// 获取指定站台的任务数量
///
private int GetStationTaskCount(SqlSugarHelper db, string station)
{
return db.Default.Queryable()
.NoLock()
.Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 &&
v.TaskType == AGVTaskType.EnterDepot && v.Station == station)
.SplitTable(v => v.Take(2))
.Count();
}
///
/// 获取北侧和南侧的任务数量
///
private (int NorthCount, int SouthCount) GetNorthAndSouthTaskCounts(SqlSugarHelper db,
(string N, string S) stationPair)
{
var northCount = GetStationTaskCount(db, stationPair.N);
var southCount = GetStationTaskCount(db, stationPair.S);
return (northCount, southCount);
}
///
/// 获取AGV的目标站台
///
///
///
///
private string GetAgvStation1(WCS_TaskInfo task, SqlSugarHelper db)
{
string sta = "";
var n = 0;
var s = 0;
var warehouseCode = task.WarehouseCode;
if (task.BusType == TaskBusType.皮盘入库.GetDescription() || task.BusType == TaskBusType.车间叫料.GetDescription())
{
warehouseCode = task.MaterialCode switch
{
"分拣库1北" => "1N",
"分拣库1南" => "1S",
"分拣库2北" => "2N",
"分拣库2南" => "2S",
"分拣库3北" => "3N",
"分拣库3南" => "3S",
_ => task.WarehouseCode
};
}
#region 判断是否需要在同一分拣库的两侧进行均分
//获取配置值
var num = 5;
var config = db.Default.Queryable().NoLock().First(x => x.Code == "SameSideTaskNum");
if (config != null)
{
num = config.SContent.ToInt();
}
sta = warehouseCode switch
{
"1N" => "2501",
"1S" => "2701",
"2N" => "2901",
"2S" => "3101",
"3N" => "3301",
"3S" => "3501",
_ => "2501",
};
//获取当前侧的已有任务数量
var staNumber = 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 (staNumber > num)
{
//同侧之间均分
if (warehouseCode.Contains("1"))
{
n = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station=="2501")
.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=="2701")
.SplitTable(v => v.Take(2)).Count();
sta = n > s ? "2701" : "2501";
}
else if (warehouseCode.Contains("2"))
{
n = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station=="2901")
.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=="3101")
.SplitTable(v => v.Take(2)).Count();
sta = n > s ? "3101" : "2901";
}
else if (warehouseCode.Contains("3"))
{
n = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station=="3301")
.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=="3501")
.SplitTable(v => v.Take(2)).Count();
sta = n > s ? "3501" : "3301";
}
else
{
return default;
}
}
#endregion
#region 判断是否需要在三个分拣中心中选取任务数量较少的一侧进行分配
staNumber = 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();
num = 10;
config = db.Default.Queryable().NoLock().First(x => x.Code == "TasksInSameWarehouse");
if (config != null)
{
num = config.SContent.ToInt();
}
if (staNumber > num)
{
sta = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot
&& (v.Station != "2535" && v.Station != "2735" && v.Station != "2935" && v.Station != "3135" && !v.Station.StartsWith("9")))//过滤掉人工满托入库和重绕区任务
.SplitTable(v => v.Take(2)).ToList().GroupBy(x => x.Station).Select(x => new { x.Key, Count = x.Count() }).MinBy(x => x.Count).Key;
}
#endregion
return sta;
}
///
/// 获取AGV返空可用目标站台
///
/// 仓库
/// 需要获取的方向
/// 目标站台列表
public List GetAgvStation(string warehouseCode, string direction)
{
// 定义方向和仓库与站台的映射关系
var stationMap = new Dictionary>>
{
["N"] = new()
{
["1"] = new List { "2501", "2505", "2509", "2513" },
["2"] = new List { "2901", "2905", "2909", "2913" },
["3"] = new List { "3301", "3305", "3309", "3313" }
},
["S"] = new()
{
["1"] = new List { "2701", "2705", "2709", "2713" },
["2"] = new List { "3101", "3105", "3109", "3113" },
["3"] = new List { "3501", "3505", "3509", "3513" }
}
};
// 查找方向和仓库对应的站台
if (stationMap.TryGetValue(direction, out var warehouseStations))
{
var warehouseKey = warehouseStations.Keys.FirstOrDefault(warehouseCode.Contains);
if (warehouseKey != null) return warehouseStations[warehouseKey];
}
// 如果没有找到匹配的站台,则返回空列表
return new List();
}
}
}