using ServiceCenter.Extensions;
using ServiceCenter.Logs;
using ServiceCenter.SqlSugars;
using System.ComponentModel;
using WCS.Core;
using WCS.Entity;
using WCS.Entity.Protocol.Protocol.BCR;
using WCS.Entity.Protocol.Protocol.RGV;
using WCS.Entity.Protocol.Protocol.Robot;
using WCS.Entity.Protocol.Protocol.Station;
using WCS.Entity.Protocol.Protocol.Truss;
using WCS.WorkEngineering.Extensions;
using WCS.WorkEngineering.Worlds;
using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
using TaskStatus = WCS.Entity.TaskStatus;
namespace WCS.WorkEngineering.Systems
{
///
/// Agv交互系统
///
[BelongTo(typeof(MainWorld))]
[Description("RGV交互系统")]
public class RGVSystems : DeviceSystem>
{
protected override bool ParallelDo => true;
protected override bool SaveLogsToFile => true;
///
/// 取货点设备集合
///
private readonly Dictionary>> _pickUpDevices = new();
public RGVSystems()
{
//获取所有的巷道集合
var rgvList = Device.All.Where(v => v.HasFlag(DeviceFlags.RGV));
foreach (var rgv in rgvList)
{
_pickUpDevices.Add(rgv.Code, rgv.Sources.Where(v => v.HasFlag(DeviceFlags.输送机)).Select(v => new Device(v, this.World)).ToList());
}
}
public override void Do(Device obj)
{
if (obj.Data.VoucherNo != obj.Data2.VoucherNo) throw new KnownException($"凭证号不一致,DB520:{obj.Data.VoucherNo}-DB521:{obj.Data2.VoucherNo}", LogLevelEnum.High);
if (obj.Data2.WorkMode != RGVWorkMode.Automatic) return;
if (obj.Data.RES1 == 1) return; //wcs任务完成确认信号未清除
if (obj.Data2.Status.HasFlag(RGVStatus.Taskfinishi))
{
switch (obj.Data2.CmdType)
{
case RGVCmdType.PickGoods: //单独取货任务完成,默认只有空托盘才会下发单独取货任务
//开始申请读码信息
var bcrCode = obj.Data3.GetBCRCode();
int taskNumber = 0;
SqlSugarHelper.Do(_db =>
{
var db = _db.Default;
var dev = Device.All.First(x => x.Code == obj.Data2.StartPosition.ToString());
if (dev.HasFlag(DeviceFlags.拆盘机09))
{
//开始绑定任务,并下发新的任务信息到小车
WCS_Palletizing palletizingInfo = db.Queryable().Single(x => x.Id == obj.Data2.TaskNumber);
if (palletizingInfo == null) return;
palletizingInfo.PalleCode = bcrCode;
db.Updateable(palletizingInfo).ExecuteCommand();
taskNumber = palletizingInfo.Id;
}
else if (dev.HasFlag(DeviceFlags.拆盘机非09))
{
//开始处理对应的搬运任务信息
var task = db.Queryable().First(x => x.Type == TaskType.Delivery && x.ID == obj.Data2.TaskNumber && x.AddrTo == obj.Data2.DestPosition.ToString());
task.BarCode = bcrCode;
db.Updateable(task).ExecuteCommand();
task.AddWCS_TASK_DTL(db, obj.Entity.Code, obj.Data2.DestPosition.ToString(), $"环形库码垛位{obj.Data2.DestPosition}搬运任务绑定条码信息{bcrCode}");
taskNumber = task.ID;
}
});
if (taskNumber == 0) return;
//清空起始点信息
var staDev = new Device(Device.All.FirstOrDefault(x => x.Code == obj.Data2.DestPosition.ToString())!, World);
staDev.Data.TaskNumber = 0;
staDev.Data.GoodsStart = 0;
staDev.Data.GoodsEnd = 0;
obj.Data2.TaskNumber = taskNumber;
obj.Data.RES1 = 1;
break;
case RGVCmdType.PutGoods:
WCS_TaskInfo finishiTask = null;
var startPosition = Device.All.Where(x => x.Code == obj.Data2.StartPosition.ToString()).Select(x => new Device(x, World)).FirstOrDefault();
var destPosition = Device.All.FirstOrDefault(x => x.Code == obj.Data2.DestPosition.ToString());
var isPalletizing = destPosition!.HasFlag(DeviceFlags.桁架码垛位, DeviceFlags.环形库码垛工位);
short countQty = 0;
short shortCode = 0;
SqlSugarHelper.Do(_db =>
{
var db = _db.Default;
if (isPalletizing)
{
if (destPosition.HasFlag(DeviceFlags.桁架码垛位))
{
var palletizingInfo = db.Queryable().First(x => x.Id == obj.Data.TaskNumber);
countQty = palletizingInfo.CountQty.ToShort();
shortCode = palletizingInfo.ShortCode;
}
else if (destPosition.HasFlag(DeviceFlags.环形库码垛工位))
{
var deliveryTask = db.Queryable().First(x => x.ID == obj.Data.TaskNumber);
countQty = deliveryTask.FullQty;
shortCode = deliveryTask.PalletType;
deliveryTask.Status = TaskStatus.RgvCompleted;
deliveryTask.EditTime = DateTime.Now;
deliveryTask.LastInteractionPoint = obj.Entity.Code;
db.Updateable(deliveryTask).ExecuteCommand();
deliveryTask.AddWCS_TASK_DTL(db, deliveryTask.AddrTo, $"RGV任务执行结束");
}
}
});
//初始化起始点信息
startPosition.Data.TaskNumber = 0;
startPosition.Data.GoodsEnd = 0;
//目标地址是码垛工位
if (isPalletizing)
{
if (destPosition.HasFlag(DeviceFlags.桁架码垛位))
{
var dest = new Device(destPosition!, World);
dest.Data.MaxQuantity = countQty;
dest.Data.Type = shortCode;
dest.Data.VoucherNo++;
}
else if (destPosition.HasFlag(DeviceFlags.环形库码垛工位))
{
var dest = new Device(destPosition!, World);
dest.Data.MaxQuantity = countQty;
dest.Data.Type = shortCode;
dest.Data.VoucherNo++;
}
}
obj.Data.RES1 = 1;
break;
case RGVCmdType.Move:
obj.Data.RES1 = 1;
break;
case RGVCmdType.ChangePutGoods:
break;
case RGVCmdType.ChangePickGoods:
break;
case RGVCmdType.PickPutGoods:
staDev = new Device(Device.All.FirstOrDefault(x => x.Code == obj.Data.DestPosition.ToString())!, World);
staDev.Data.TaskNumber = 0;
staDev.Data.GoodsStart = 0;
staDev.Data.GoodsEnd = 0;
obj.Data.RES1 = 1;
break;
default:
throw new ArgumentOutOfRangeException();
}
return;
}
if (obj.Data2.SystemStatus != RGVSystemStatus.空闲) return;
if (obj.Data2.Status.HasFlag(RGVStatus.RES1))
{
obj.Data.TaskNumber = obj.Data.TaskNumber;
obj.Data.CmdType = RGVCmdType.Move;
obj.Data.DestPosition = 1668;
obj.Data.VoucherNo++;
return;
}
if (obj.Data2.CmdType == RGVCmdType.PickGoods && !obj.Data2.Status.HasFlag(RGVStatus.Taskfinishi))
{
if (obj.Data2.Status.HasFlag(RGVStatus.PH_Status))
{
obj.Data.TaskNumber = obj.Data.TaskNumber;
obj.Data.CmdType = RGVCmdType.PutGoods;
obj.Data.StartPosition = obj.Data2.StartPosition;
obj.Data.DestPosition = obj.Data2.DestPosition;
obj.Data.VoucherNo++;
return;
}
}
var pickUpDevices = _pickUpDevices.FirstOrDefault(x => x.Key == obj.Entity.Code).Value;
//有货且需要搬运货物的站台
var devs = pickUpDevices.Where(v => v.Data3.Status.HasFlag(StationStatus.PH_Status) && v.Data.TaskNumber != 0)
.Where(v => v.Entity.Code.ToShort() != v.Data.GoodsEnd && v.Data.GoodsEnd != 0)
.ToList();
//筛选出目标站台无货的站台
var putDev = obj.Entity.Targets.Where(x => x.HasFlag(DeviceFlags.输送机))
.Select(x => new Device(x, World))
.Where(x => !x.Data3.Status.HasFlag(StationStatus.PH_Status))
.Select(x => x.Entity.Code.ToShort());
var dev = devs.OrderBy(x => x.Entity.Code).FirstOrDefault(x => putDev.Contains(x.Data.GoodsEnd));
if (dev == null) return;
//区分任务是拆盘机到码垛工位,还是码垛工位到拆盘机
if (dev.Entity.HasFlag(DeviceFlags.拆盘机09, DeviceFlags.拆盘机非09))
{
obj.Data.TaskNumber = dev.Data.TaskNumber;
obj.Data.CmdType = RGVCmdType.PickGoods;
obj.Data.StartPosition = dev.Entity.Code.ToShort();
obj.Data.DestPosition = dev.Data.GoodsEnd;
obj.Data.VoucherNo++;
}
else //非拆盘机起始任务
{
//站台中的任务号
WCS_TaskInfo task = null;
SqlSugarHelper.Do(_db =>
{
var db = _db.Default;
var taskInfo = db.Queryable().First(p => p.ID == dev.Data.TaskNumber && p.Status == TaskStatus.WaitingToExecute);
if (taskInfo == null) return;
taskInfo.Status = TaskStatus.RgvExecution;
taskInfo.AddrNext = obj.Entity.Code;
taskInfo.EditWho = "WCS";
taskInfo.EditTime = DateTime.Now; ;
db.Updateable(taskInfo).ExecuteCommand();
taskInfo.AddWCS_TASK_DTL(db, dev.Entity.Code, obj.Entity.Code, $"任务分配至{obj.Entity.Code}");
task = taskInfo;
});
if (task == null) return;
obj.Data.TaskNumber = task.ID;
obj.Data.CmdType = RGVCmdType.PickPutGoods;
obj.Data.StartPosition = dev.Entity.Code.ToShort();
obj.Data.DestPosition = dev.Data.GoodsEnd;
obj.Data.VoucherNo++;
}
}
public override bool Select(Device dev)
{
return dev.Code == "RGV1";
//return dev.HasFlag(Extensions.DeviceFlags.RGV);
}
}
}