|
@@ -1,4 +1,5 @@
|
|
|
-using ServiceCenter.Extensions;
|
|
|
+using ServiceCenter;
|
|
|
+using ServiceCenter.Extensions;
|
|
|
using ServiceCenter.SqlSugars;
|
|
|
using System.ComponentModel;
|
|
|
using WCS.Core;
|
|
@@ -6,9 +7,11 @@ using WCS.Entity;
|
|
|
using WCS.Entity.Protocol.SRM;
|
|
|
using WCS.Entity.Protocol.Station;
|
|
|
using WCS.WorkEngineering.Extensions;
|
|
|
+using WCS.WorkEngineering.WebApi.Controllers;
|
|
|
using WCS.WorkEngineering.Worlds;
|
|
|
using WCS.WorkEngineering.Worlds.Logs;
|
|
|
using KnownException = WCS.WorkEngineering.Worlds.Logs.KnownException;
|
|
|
+using TaskStatus = WCS.Entity.TaskStatus;
|
|
|
|
|
|
namespace WCS.WorkEngineering.Systems
|
|
|
{
|
|
@@ -17,42 +20,40 @@ namespace WCS.WorkEngineering.Systems
|
|
|
/// </summary>
|
|
|
[BelongTo(typeof(MainWorld))]
|
|
|
[Description("堆垛机系统")]
|
|
|
- public class SrmSystems : DeviceSystem<Device<ISRM520, ISRM521, ISRM523>>
|
|
|
+ public class SrmSystems : DeviceSystem<SRM>
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 取货点设备集合
|
|
|
/// </summary>
|
|
|
- private List<Device<IStation520, IStation521, IStation523>> PickUpDevices;
|
|
|
+ private Dictionary<string, List<Station>> PickUpDevices = new Dictionary<string, List<Station>>();
|
|
|
|
|
|
/// <summary>
|
|
|
/// 放货设备
|
|
|
/// </summary>
|
|
|
- private List<Device<IStation520, IStation521, IStation523>> PutDevices;
|
|
|
+ private Dictionary<string, List<Station>> PutDevices = new Dictionary<string, List<Station>>();
|
|
|
|
|
|
public SrmSystems()
|
|
|
{
|
|
|
- //分拣库1
|
|
|
- PickUpDevices = World.Devices.Where(v => v.Code is "" or "")
|
|
|
- .Select(v => new Device<IStation520, IStation521, IStation523>(v)).ToList();
|
|
|
- PutDevices = World.Devices.Where(v => v.Code is "" or "")
|
|
|
- .Select(v => new Device<IStation520, IStation521, IStation523>(v)).ToList();
|
|
|
- //分拣库2
|
|
|
- PickUpDevices = World.Devices.Where(v => v.Code is "" or "")
|
|
|
- .Select(v => new Device<IStation520, IStation521, IStation523>(v)).ToList();
|
|
|
- PutDevices = World.Devices.Where(v => v.Code is "" or "")
|
|
|
- .Select(v => new Device<IStation520, IStation521, IStation523>(v)).ToList();
|
|
|
- //分拣库3
|
|
|
- PickUpDevices = World.Devices.Where(v => v.Code is "" or "")
|
|
|
- .Select(v => new Device<IStation520, IStation521, IStation523>(v)).ToList();
|
|
|
- PutDevices = World.Devices.Where(v => v.Code is "" or "")
|
|
|
- .Select(v => new Device<IStation520, IStation521, IStation523>(v)).ToList();
|
|
|
+ //获取所有的巷道集合
|
|
|
+ var devices = ServiceHub.deviceInfos.Where(x => x.IsTunnel());
|
|
|
+
|
|
|
+ //开始分配
|
|
|
+ foreach (var item in devices)
|
|
|
+ {
|
|
|
+ //取货设备
|
|
|
+ var deviceCode = item.FormerRoutes.Select(v => v.DeviceCode).ToList();
|
|
|
+ PickUpDevices.Add(item.NextRoutes.First().DeviceCode, World.Devices.Where(v => deviceCode.Contains(v.Code)).Select(v => new Station(v)).ToList());
|
|
|
+ //放货设备
|
|
|
+ deviceCode = ServiceHub.deviceInfos.First(x => item.NextRoutes.First().DeviceCode == x.Code).NextRoutes.Select(v => v.NextCode).ToList();
|
|
|
+ PutDevices.Add(item.NextRoutes.First().DeviceCode, World.Devices.Where(v => deviceCode.Contains(v.Code)).Select(v => new Station(v)).ToList());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
protected override bool ParallelDo => true;
|
|
|
|
|
|
protected override bool SaveLogsToFile => true;
|
|
|
|
|
|
- public override void Do(Device<ISRM520, ISRM521, ISRM523> obj)
|
|
|
+ public override void Do(SRM obj)
|
|
|
{
|
|
|
//判断堆垛机是否报警
|
|
|
if (obj.Data2.Status.HasFlag(SrmStatus.Alarm)) throw new KnownException(obj.Data3.Alarm.ToString(), LogLevelEnum.High);
|
|
@@ -80,7 +81,7 @@ namespace WCS.WorkEngineering.Systems
|
|
|
break;
|
|
|
|
|
|
case TaskType.OutDepot:
|
|
|
- task.Status = Entity.TaskStatus.ConveyorInProgress;
|
|
|
+ task.Status = Entity.TaskStatus.ConveyorExecution;
|
|
|
task.AddWCS_TASK_DTL(db, task.SrmStation, "出库任务到达放货站台");
|
|
|
break;
|
|
|
|
|
@@ -129,9 +130,8 @@ namespace WCS.WorkEngineering.Systems
|
|
|
{
|
|
|
//获取出库任务中新建状态最大优先级
|
|
|
var outPriorityNewBuild = tasks.Where(v => v.Type == TaskType.OutDepot && v.Status == Entity.TaskStatus.NewBuild).Max(v => v.Priority);
|
|
|
- //获取入库任务中最后一个交互点是取货点任务的最大优先级
|
|
|
- var enterPriority = tasks.Where(v => v.Type == TaskType.EnterDepot && v.Status < Entity.TaskStatus.StackerExecution && PickUpDevices.Any(p => p.Entity.Code == v.LastInteractionPoint))
|
|
|
- .Max(v => v.Priority);
|
|
|
+ //获取入库任务中最大优先级
|
|
|
+ var enterPriority = tasks.Where(v => v.Type == TaskType.EnterDepot && v.Status < Entity.TaskStatus.StackerExecution).Max(v => v.Priority);
|
|
|
//出入库最大优先级相加大于零
|
|
|
if (outPriorityNewBuild + enterPriority > 0)
|
|
|
{
|
|
@@ -186,14 +186,97 @@ namespace WCS.WorkEngineering.Systems
|
|
|
if (enterOrOut == 2 || (lastIsOut && enterOrOut == 1)) //入库任务
|
|
|
{
|
|
|
//判断本次优先执行楼层,并设置下次执行时优先楼层
|
|
|
- var floor = obj.Entity.Get<int>("Floor");
|
|
|
+ var floor = obj.Entity.Get<int>("FloorIn");
|
|
|
floor = floor % 2 + 1;
|
|
|
- obj.Entity.Set("Floor", floor);
|
|
|
-
|
|
|
+ obj.Entity.Set("FloorIn", floor);
|
|
|
+
|
|
|
//获取当前堆垛机所有的取货站台
|
|
|
+ var arrIn = PickUpDevices.First(v => v.Key == obj.Entity.Code).Value;
|
|
|
+ if (!arrIn.Any()) throw new KnownException($"堆垛机{obj.Entity.Code}无取货路径点", LogLevelEnum.High);
|
|
|
+
|
|
|
+ //获取有货的设备
|
|
|
+ arrIn = arrIn.Where(v => v.Data2.TaskNumber > 0 && v.Data3.Status.HasFlag(StatusEunm.PH_Status) && !v.Data3.Status.HasFlag(StatusEunm.Run)).ToList();
|
|
|
+ if (!arrIn.Any()) throw new KnownException($"[{obj.Entity.Code}]等待入库任务输送到位", LogLevelEnum.Mid);
|
|
|
+ WCS_TaskInfo taskInfo = null;
|
|
|
+ Station station = null;
|
|
|
+ var result = SqlSugarHelper.Do(db =>
|
|
|
+ {
|
|
|
+ //根据有货设备的任务号获取所有类型为入库状态为输送机执行中的任务
|
|
|
+ var tasks = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.Type == TaskType.EnterDepot && v.Status == TaskStatus.ConveyorExecution && arrIn.Select(p => p.Data2.TaskNumber).Contains(v.ID));
|
|
|
+ //按条件先后排序获取一条排序后第一条结果1.优先级2.所在楼层与本次优先执行楼层 TODO:待验证排序结果
|
|
|
+ var task = tasks.OrderByDescending(v => v.Priority).OrderByDescending(v => v.Floor == floor ? 1 : 0).First() ?? throw new KnownException($"{obj.Entity.Code}未找到入库任务", LogLevelEnum.High);
|
|
|
+ //获取任务所有设备
|
|
|
+ station = arrIn.First(v => v.Data2.TaskNumber == task.ID);
|
|
|
+ //获取当前货物巷道
|
|
|
+ var loc = WmsApi.GetLocalIn(task.ID, task.Tunnel, station.Entity.Code);
|
|
|
+
|
|
|
+ task.Status = TaskStatus.StackerExecution;
|
|
|
+ task.AddrTo = $"{loc.Row}-{loc.Colomn}-{loc.Layer}";
|
|
|
+ task.LastInteractionPoint = station.Entity.Code;
|
|
|
+ task.EditWho = "WCS";
|
|
|
+ task.AddWCS_TASK_DTL(db, station.Entity.Code, task.AddrTo, "任务下发堆垛机执行");
|
|
|
+ db.Default.Updateable(task).AddQueue();
|
|
|
+ db.Default.SaveQueues();
|
|
|
+ });
|
|
|
+
|
|
|
+ if (taskInfo == null || !result) throw new KnownException("数据更新错误", LogLevelEnum.High);
|
|
|
+ var addrTo = taskInfo.AddrTo.Split("-");
|
|
|
+ //下发任务
|
|
|
+ obj.Data.TaskNumber = taskInfo.ID;
|
|
|
+ obj.Data.RowPos1 = station.Entity.Code.ToShort();
|
|
|
+ obj.Data.RowPos2 = addrTo[0].ToShort();
|
|
|
+ obj.Data.TravelPos2 = addrTo[1].ToShort();
|
|
|
+ obj.Data.LiftPos2 = addrTo[2].ToShort();
|
|
|
+ obj.Data.VoucherNo++;
|
|
|
}
|
|
|
else if (enterOrOut == 3 || !lastIsOut) //出库任务
|
|
|
{
|
|
|
+ //判断本次优先执行楼层,并设置下次执行时优先楼层
|
|
|
+ var floor = obj.Entity.Get<int>("FloorOut");
|
|
|
+ floor = floor % 2 + 1;
|
|
|
+ obj.Entity.Set("FloorOut", floor);
|
|
|
+
|
|
|
+ //获取当前堆垛机所有的取货站台
|
|
|
+ var arrOut = PickUpDevices.First(v => v.Key == obj.Entity.Code).Value;
|
|
|
+ if (!arrOut.Any()) throw new KnownException($"堆垛机{obj.Entity.Code}无放货路径点", LogLevelEnum.High);
|
|
|
+
|
|
|
+ //获取可以放货的设备集合
|
|
|
+ arrOut = arrOut.Where(v => !v.Data3.Status.HasFlag(StatusEunm.PH_Status) //无光电
|
|
|
+ && !v.Data3.Status.HasFlag(StatusEunm.Run) //未运行
|
|
|
+ && !v.Data3.Status.HasFlag(StatusEunm.OT_Status) //无任务
|
|
|
+ && !v.Data3.Status.HasFlag(StatusEunm.UnassignedTask) //未分配任务
|
|
|
+ && v.Data3.Status.HasFlag(StatusEunm.Auto)).ToList(); //自动
|
|
|
+ if (!arrOut.Any()) throw new KnownException($"[{obj.Entity.Code}]等待出库任务输送到位", LogLevelEnum.Mid);
|
|
|
+ WCS_TaskInfo taskInfo = null;
|
|
|
+ string[] addrFrom = null;
|
|
|
+
|
|
|
+ var result = SqlSugarHelper.Do(db =>
|
|
|
+ {
|
|
|
+ var allOutCode = arrOut.Select(v => v.Entity.Code).ToList();
|
|
|
+ //按条件先后排序获取一条排序后第一条结果1.优先级2.所在楼层与本次优先执行楼层 TODO:待验证排序结果
|
|
|
+ var task = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.Type == TaskType.OutDepot && v.Status == TaskStatus.WaitingToExecute)
|
|
|
+ .Where(v => allOutCode.Contains(v.SrmStation))
|
|
|
+ .OrderByDescending(v => v.Priority)
|
|
|
+ .OrderByDescending(v => v.Floor == floor ? 1 : 0)
|
|
|
+ .First() ?? throw new KnownException($"{obj.Entity.Code}未找到出库任务", LogLevelEnum.High);
|
|
|
+
|
|
|
+ addrFrom = task.AddrFrom.Split("-");
|
|
|
+ task.Status = TaskStatus.StackerExecution;
|
|
|
+ task.LastInteractionPoint = task.Device;
|
|
|
+ task.EditWho = "WCS";
|
|
|
+ task.AddWCS_TASK_DTL(db, task.Device, task.SrmStation, "任务下发堆垛机执行");
|
|
|
+ db.Default.Updateable(task).AddQueue();
|
|
|
+ taskInfo = task;
|
|
|
+ db.Default.SaveQueues();
|
|
|
+ });
|
|
|
+
|
|
|
+ obj.Data.TaskNumber = taskInfo.ID;
|
|
|
+ obj.Data.RowPos1 = addrFrom[0].ToShort();
|
|
|
+ obj.Data.TravelPos1 = addrFrom[1].ToShort();
|
|
|
+ obj.Data.LiftPos1 = addrFrom[2].ToShort();
|
|
|
+ obj.Data.RowPos2 = taskInfo.SrmStation.ToShort();
|
|
|
+ obj.Data.TravelPos2 = taskInfo.AddrNext.ToShort();
|
|
|
+ obj.Data.VoucherNo++;
|
|
|
}
|
|
|
|
|
|
#endregion 出入库
|