|
@@ -1,6 +1,11 @@
|
|
|
-using System.ComponentModel;
|
|
|
+using DBHelper;
|
|
|
+using ServiceCenter.Extensions;
|
|
|
+using System.ComponentModel;
|
|
|
using WCS.Core;
|
|
|
+using WCS.Entity;
|
|
|
+using WCS.Entity.Protocol.SRM;
|
|
|
using WCS.Entity.Protocol.Station;
|
|
|
+using WCS.WorkEngineering.Extensions;
|
|
|
using WCS.WorkEngineering.Worlds;
|
|
|
|
|
|
namespace WCS.WorkEngineering.Systems
|
|
@@ -10,18 +15,34 @@ namespace WCS.WorkEngineering.Systems
|
|
|
/// </summary>
|
|
|
[BelongTo(typeof(MainWorld))]
|
|
|
[Description("堆垛机系统")]
|
|
|
- public class SrmSystems : DeviceSystem<Device<IStation520, IStation521, IStation522>>
|
|
|
+ public class SrmSystems : DeviceSystem<Device<ISRM520, ISRM521, ISRM523>>
|
|
|
{
|
|
|
- //TODO:堆垛机相关信息未完善等待完善之后再处理
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// 取货点设备集合
|
|
|
/// </summary>
|
|
|
private List<Device<IStation520, IStation521, IStation522>> PickUpDevices;
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 放货设备
|
|
|
+ /// </summary>
|
|
|
+ private List<Device<IStation520, IStation521, IStation522>> PutDevices;
|
|
|
+
|
|
|
public SrmSystems()
|
|
|
{
|
|
|
- PickUpDevices = World.Devices.Where(v => v.Code is "1601" or "1603" or "1605" or "1611" or "1613" or "1615" or "2527" or "2528" or "2727" or "")
|
|
|
+ //分拣库1
|
|
|
+ PickUpDevices = World.Devices.Where(v => v.Code is "" or "")
|
|
|
+ .Select(v => new Device<IStation520, IStation521, IStation522>(v)).ToList();
|
|
|
+ PutDevices = World.Devices.Where(v => v.Code is "" or "")
|
|
|
+ .Select(v => new Device<IStation520, IStation521, IStation522>(v)).ToList();
|
|
|
+ //分拣库2
|
|
|
+ PickUpDevices = World.Devices.Where(v => v.Code is "" or "")
|
|
|
+ .Select(v => new Device<IStation520, IStation521, IStation522>(v)).ToList();
|
|
|
+ PutDevices = World.Devices.Where(v => v.Code is "" or "")
|
|
|
+ .Select(v => new Device<IStation520, IStation521, IStation522>(v)).ToList();
|
|
|
+ //分拣库3
|
|
|
+ PickUpDevices = World.Devices.Where(v => v.Code is "" or "")
|
|
|
+ .Select(v => new Device<IStation520, IStation521, IStation522>(v)).ToList();
|
|
|
+ PutDevices = World.Devices.Where(v => v.Code is "" or "")
|
|
|
.Select(v => new Device<IStation520, IStation521, IStation522>(v)).ToList();
|
|
|
}
|
|
|
|
|
@@ -29,14 +50,148 @@ namespace WCS.WorkEngineering.Systems
|
|
|
|
|
|
protected override bool SaveLogsToFile => true;
|
|
|
|
|
|
- public override void Do(Device<IStation520, IStation521, IStation522> obj)
|
|
|
+ public override void Do(Device<ISRM520, ISRM521, ISRM523> obj)
|
|
|
{
|
|
|
- throw new NotImplementedException();
|
|
|
+ //判断堆垛机是否报警
|
|
|
+ if (obj.Data2.Status.HasFlag(SrmStatus.Alarm)) throw new KnownException(obj.Data3.Alarm.ToString(), LogLevel.High);
|
|
|
+
|
|
|
+ //判断DB520 完成任务确认清除信号 是否为1
|
|
|
+ if (obj.Data.OkAck == 1) throw new KnownException("任务完成确认信号未清除", LogLevel.Mid);
|
|
|
+
|
|
|
+ //判断完成任务号是否大于0
|
|
|
+ if (obj.Data2.TaskFinishiId > 0)
|
|
|
+ {
|
|
|
+ Db.Do(db =>
|
|
|
+ {
|
|
|
+ //根据DB521任务号获取对应任务
|
|
|
+ var task = db.Default.Queryable<WCS_TASK>().First(v => v.ID == obj.Data2.TaskFinishiId) ?? throw new KnownException($"未找到任务{obj.Data2.TaskFinishiId}", LogLevel.High);
|
|
|
+ if (task.STATUS != Entity.TaskStatus.StackerExecution)
|
|
|
+ throw new KnownException($"任务{task.ID}状态是{task.STATUS.Description()}.堆垛机完成任务需要对应任务状态处于堆垛机执行中", LogLevel.High);
|
|
|
+ //根据任务类型做不同的处理
|
|
|
+ switch (task.TYPE)
|
|
|
+ {
|
|
|
+ case TaskType.EnterDepot:
|
|
|
+ //完成任务
|
|
|
+ task.STATUS = Entity.TaskStatus.Finish;
|
|
|
+ task.UPDATETIME = DateTime.Now;
|
|
|
+ task.ENDTIME = DateTime.Now;
|
|
|
+ task.AddWCS_TASK_DTL(db, task.ADDRTO, "入库任务结束");
|
|
|
+ break;
|
|
|
+
|
|
|
+ case TaskType.OutDepot:
|
|
|
+ task.STATUS = Entity.TaskStatus.ConveyorInProgress;
|
|
|
+ task.UPDATETIME = DateTime.Now;
|
|
|
+ task.AddWCS_TASK_DTL(db, task.SRMSTATION, "出库任务到达放货站台");
|
|
|
+ break;
|
|
|
+
|
|
|
+ case TaskType.TransferDepot:
|
|
|
+ task.STATUS = Entity.TaskStatus.Finish;
|
|
|
+ task.UPDATETIME = DateTime.Now;
|
|
|
+ task.ENDTIME = DateTime.Now;
|
|
|
+ task.AddWCS_TASK_DTL(db, task.ADDRTO, "移库任务结束");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ db.Default.Updateable(task).AddQueue();
|
|
|
+ db.Default.SaveQueues();
|
|
|
+ obj.Data.OkAck = 1;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ //堆垛机是否可以下发任务
|
|
|
+ if (obj.Data2.VoucherNo != obj.Data.VoucherNo) throw new KnownException($"凭证号不一致,DB520:{obj.Data.VoucherNo},DB521:{obj.Data2.VoucherNo}", LogLevel.Mid);
|
|
|
+ if (obj.Data2.AutoStatus != SrmAutoStatus.Automatic) throw new KnownException($"堆垛机处于{obj.Data2.AutoStatus}模式", LogLevel.Low);
|
|
|
+ if (obj.Data2.RunStatus != SrmRunStatus.Idle) throw new KnownException($"堆垛机处于{obj.Data2.RunStatus}状态", LogLevel.High);
|
|
|
+
|
|
|
+ //默认没有移库任务
|
|
|
+ bool isTransfer = false;
|
|
|
+
|
|
|
+ //出入库优先级任务 1:无优先 2:入库 3:出库
|
|
|
+ int enterOrOut = 1;
|
|
|
+
|
|
|
+ //再检查是否有等待执行的货物
|
|
|
+ Db.Do(db =>
|
|
|
+ {
|
|
|
+ //获取当前堆垛机的所有未完成任务
|
|
|
+ var tasks = db.Default.Queryable<WCS_TASK>().Where(v => v.STATUS < Entity.TaskStatus.Finish && (v.DEVICE == obj.Entity.Code));
|
|
|
+ //任务集合是否有处于堆垛机执行状态的任务
|
|
|
+ if (tasks.Any(v => v.STATUS == Entity.TaskStatus.StackerExecution)) throw new KnownException($"有任务处于堆垛机执行状态", LogLevel.High);
|
|
|
+
|
|
|
+ //判断是否存在调整优先级任务
|
|
|
+ if (!tasks.Any(v => v.TYPE != TaskType.TransferDepot && v.STATUS < Entity.TaskStatus.StackerExecution && v.Priority > 0))
|
|
|
+ {
|
|
|
+ //不存在调整优先级任务,判断是否存在移库任务
|
|
|
+ isTransfer = tasks.Any(v => v.TYPE == TaskType.TransferDepot && v.STATUS == Entity.TaskStatus.NewBuild);
|
|
|
+ }
|
|
|
+ else //存在调整优先级任务
|
|
|
+ {
|
|
|
+ //获取出库任务中新建状态最大优先级
|
|
|
+ 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);
|
|
|
+ //出入库最大优先级相加大于零
|
|
|
+ if (outPriorityNewBuild + enterPriority > 0)
|
|
|
+ {
|
|
|
+ //出入库优先级任务 1:无优先 2:入库 3:出库
|
|
|
+ enterOrOut = enterPriority > outPriorityNewBuild ? 2 : 3;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ #region 移库
|
|
|
+
|
|
|
+ if (isTransfer)
|
|
|
+ {
|
|
|
+ Db.Do(db =>
|
|
|
+ {
|
|
|
+ //获取一条当前堆垛机优先级最高的新建移库任务
|
|
|
+ var task = db.Default.Queryable<WCS_TASK>().Where(v => v.DEVICE == obj.Entity.Code && v.TYPE == TaskType.TransferDepot && v.STATUS == Entity.TaskStatus.NewBuild)
|
|
|
+ .OrderByDescending(v => v.Priority)
|
|
|
+ .First() ?? throw new KnownException("未找到移库任务", LogLevel.High);
|
|
|
+ //任务状态改为堆垛机执行中
|
|
|
+ task.STATUS = Entity.TaskStatus.StackerExecution;
|
|
|
+ task.STARTTIME = DateTime.Now;
|
|
|
+ task.UPDATETIME = DateTime.Now;
|
|
|
+ task.AddWCS_TASK_DTL(db, task.ADDRFROM, task.DEVICE, $"堆垛机{obj.Entity.Code}开始执行任务");
|
|
|
+ db.Default.Updateable(task).AddQueue();
|
|
|
+ db.Default.SaveQueues();
|
|
|
+ var addrFrom = task.ADDRFROM.Split("-");
|
|
|
+ var addrTo = task.ADDRTO.Split("-");
|
|
|
+ //下发任务
|
|
|
+ obj.Data.TaskNumber = task.ID;
|
|
|
+ obj.Data.RowPos1 = addrFrom[0].ToShort();
|
|
|
+ obj.Data.TravelPos1 = addrFrom[1].ToShort();
|
|
|
+ obj.Data.LiftPos1 = addrFrom[2].ToShort();
|
|
|
+ obj.Data.RowPos2 = addrTo[0].ToShort();
|
|
|
+ obj.Data.TravelPos2 = addrTo[1].ToShort();
|
|
|
+ obj.Data.LiftPos2 = addrTo[2].ToShort();
|
|
|
+ obj.Data.VoucherNo++;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion 移库
|
|
|
+
|
|
|
+ #region 出入库
|
|
|
+
|
|
|
+ //上一个周期是不是出库任务 第一次获取返回结果会是false
|
|
|
+ var lastIsOut = obj.Entity.Get<bool>("LastIsOut");
|
|
|
+ obj.Entity.Set("LastIsOut", !lastIsOut);
|
|
|
+
|
|
|
+ //入库任务优先 或 上一个周期是出库任务并且出库任务无优先
|
|
|
+ if (enterOrOut == 2 || (lastIsOut && enterOrOut == 1)) //入库任务
|
|
|
+ {
|
|
|
+ }
|
|
|
+ else if (enterOrOut == 3 || !lastIsOut)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion 出入库
|
|
|
}
|
|
|
|
|
|
public override bool Select(Device dev)
|
|
|
{
|
|
|
- throw new NotImplementedException();
|
|
|
+ return dev.Code.Contains("SRM");
|
|
|
}
|
|
|
}
|
|
|
}
|