|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
using SlnMesnac.Business.@base;
|
|
|
using SlnMesnac.Model.domain;
|
|
|
using SlnMesnac.Model.dto.taskType;
|
|
|
using SlnMesnac.Plc;
|
|
|
using SlnMesnac.Serilog;
|
|
|
using SlnMesnac.WCS.Global;
|
|
|
using SlnMesnac.WCS.Library;
|
|
|
using SqlSugar;
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
namespace SlnMesnac.WCS.WCS
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 根据条件创建任务
|
|
|
/// </summary>
|
|
|
public class CreateTaskByRecord : BaseBusiness
|
|
|
{
|
|
|
private readonly SerilogHelper _logger;
|
|
|
|
|
|
//3#车间上料点plc
|
|
|
private readonly PlcAbsractFactory workShop3Plc;
|
|
|
|
|
|
//2#计量室相关点位
|
|
|
private readonly PlcAbsractFactory workShop2Plc;
|
|
|
|
|
|
private readonly ISqlSugarClient sqlSugarClient;
|
|
|
|
|
|
public CreateTaskByRecord(IServiceProvider serviceProvider) : base(serviceProvider)
|
|
|
{
|
|
|
workShop3Plc = base.GetPlcByKey("workShop3Plc");
|
|
|
workShop2Plc = base.GetPlcByKey("workShop2Plc");
|
|
|
sqlSugarClient = serviceProvider.GetRequiredService<ISqlSugarClient>();
|
|
|
_logger = serviceProvider.GetRequiredService<SerilogHelper>();
|
|
|
//test();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 启动扫描监听
|
|
|
/// </summary>
|
|
|
public void StartPoint()
|
|
|
{
|
|
|
CreateTaskByReadPlcSignal();
|
|
|
|
|
|
//监听2#计量室旋转移栽plc信号,处理相关流程
|
|
|
var CreateProductTaskByLocationCodeThread = new Thread(ListeningWorkShop2TransplantingMachine);
|
|
|
CreateProductTaskByLocationCodeThread.IsBackground = true;
|
|
|
CreateProductTaskByLocationCodeThread.Name = "监听1#2#计量室旋转移栽plc信号处理连廊箱体旋转相关流程";
|
|
|
CreateProductTaskByLocationCodeThread.Start();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 通过读plc条件创建任务
|
|
|
///
|
|
|
/// </summary>
|
|
|
private void CreateTaskByReadPlcSignal()
|
|
|
{
|
|
|
Task.Run(() =>
|
|
|
{
|
|
|
while (true)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (workShop3Plc == null || !workShop3Plc.IsConnected)
|
|
|
{
|
|
|
_logger.Plc(DateTime.Now + "3#PLC未连接,请检查网络!");
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
#region 3#车间补四宫格空箱流程---监听3#1号光电状态
|
|
|
|
|
|
bool signal1 = workShop3Plc.readBoolByAddress(StaticData.GetPlcAddress("3#大料箱进料为空"));
|
|
|
if (signal1)
|
|
|
{
|
|
|
CreateSupplementBigPalletTask();
|
|
|
}
|
|
|
|
|
|
#endregion 3#车间补四宫格空箱流程---监听3#1号光电状态
|
|
|
|
|
|
#region 从下料点到1-16机台送料任务--或者1-12移库任务 --监听3#2号光电状态
|
|
|
|
|
|
bool getBigFlag = workShop3Plc.readBoolByAddress(StaticData.GetPlcAddress("3#大料箱agv取料通知"));
|
|
|
string machineCodeS = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#四宫格下料点机台号")).ToString();
|
|
|
string rfidS = workShop3Plc.readStringByAddress(StaticData.GetPlcAddress("3#四宫格下料点RFID号"), 12).Replace("\0", "");
|
|
|
int amount = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#四宫格下料点数量"));
|
|
|
|
|
|
if (getBigFlag && machineCodeS != "0" && rfidS.Contains("SH"))
|
|
|
{
|
|
|
CreatDeliverWorkShop3Task(machineCodeS, rfidS, amount);
|
|
|
}
|
|
|
|
|
|
#endregion 从下料点到1-16机台送料任务--或者1-12移库任务 --监听3#2号光电状态
|
|
|
|
|
|
#region 3#往2#计量室送料流程
|
|
|
|
|
|
bool getSmallFlag = workShop3Plc.readBoolByAddress(StaticData.GetPlcAddress("3#小料箱agv取料通知"));
|
|
|
int smallAmount = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#小料箱下料点数量"));
|
|
|
string machineCodeX = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#小料箱下料点机台号")).ToString();
|
|
|
string rfidX = workShop3Plc.readStringByAddress(StaticData.GetPlcAddress("3#小料箱下料点RFID号"), 12).Replace("\0", "");
|
|
|
|
|
|
if (getSmallFlag && machineCodeX != "0" && rfidX.Contains("SH"))
|
|
|
{
|
|
|
if (machineCodeX == "1")
|
|
|
{
|
|
|
machineCodeX = "1006";
|
|
|
}
|
|
|
CreatDeliverWorkShop2Task(machineCodeX, rfidX);
|
|
|
}
|
|
|
|
|
|
#endregion 3#往2#计量室送料流程
|
|
|
|
|
|
#region 3#补充小空托盘流程--3#车间从色粉存放点补充小托盘任务 或者 3#车间从2#接驳位补充小托盘任务
|
|
|
|
|
|
int work3EmptyAmount = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#缓存皮带线库存数"));
|
|
|
int busy3Flag = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#线体忙碌状态"));
|
|
|
if ((work3EmptyAmount == 1 && busy3Flag == 0) || work3EmptyAmount == 0)
|
|
|
{
|
|
|
//3#车间从色粉存放点补充小托盘任务 或者 3#车间从2#接驳位补充小托盘任务
|
|
|
CreateSupplySmallPalletToWorkshop3Task();
|
|
|
}
|
|
|
|
|
|
#endregion 3#补充小空托盘流程--3#车间从色粉存放点补充小托盘任务 或者 3#车间从2#接驳位补充小托盘任务
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.Error($"CreateTaskByReadPlcSignal方法异常:" + ex.StackTrace);
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
Thread.Sleep(1000);
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 监听2#计量室旋转移栽plc信号,处理连廊箱体旋转相关流程
|
|
|
/// </summary>
|
|
|
private void ListeningWorkShop2TransplantingMachine()
|
|
|
{
|
|
|
while (true)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (workShop2Plc == null || !workShop2Plc.IsConnected)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
#region 2#计量室料箱返回处理流程:空箱入缓存链条线,色粉派送至色粉存放点
|
|
|
|
|
|
//2#接驳位色粉派送至色粉存放点任务
|
|
|
if (workShop2Plc != null && workShop2Plc.IsConnected)
|
|
|
{
|
|
|
bool returnJudgeSignal = workShop2Plc.readBoolByAddress(StaticData.GetPlcAddress("2#料箱运回RFID读取"));
|
|
|
int busy2Flag = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"));
|
|
|
int Amount = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#缓存链条线库存数"));
|
|
|
//是否还有未在色粉库位的色粉箱体
|
|
|
bool anyTonerPallet = HasAnyTonerInLine();
|
|
|
if (returnJudgeSignal && busy2Flag == 0 && (Amount < 3 || anyTonerPallet))
|
|
|
{
|
|
|
string rfid = ReadEpcStrByRfidKey("2#Transplant");
|
|
|
if (string.IsNullOrEmpty(rfid))
|
|
|
{//二次读取
|
|
|
rfid = ReadEpcStrByRfidKey("2#Transplant");
|
|
|
}
|
|
|
if (!string.IsNullOrEmpty(rfid))
|
|
|
{
|
|
|
if (Amount < 3)
|
|
|
{
|
|
|
Thread.Sleep(2000);
|
|
|
}
|
|
|
else if (anyTonerPallet) //有色粉空转
|
|
|
{
|
|
|
Thread.Sleep(4500);
|
|
|
}
|
|
|
|
|
|
busy2Flag = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"));
|
|
|
if (busy2Flag == 0)
|
|
|
{
|
|
|
// 判断有无色粉, 如果没有色粉,wcs给 旋转移栽方向信号 写2,plc将料箱运到 缓存皮带线。
|
|
|
WmsPalletInfo? wmsPalletInfo = sqlSugarClient.Queryable<WmsPalletInfo>().First(it => it.PalletInfoCode == rfid);
|
|
|
if (wmsPalletInfo != null && wmsPalletInfo.Amount > 0 && wmsPalletInfo.TonerFlag == 1) //携带色粉
|
|
|
{
|
|
|
//注意:plc上旋转移栽必须锁住线体状态才可以,2#接驳位如果有满料,那么通知plc信号,plc在连廊不再把箱体放到旋转移栽上
|
|
|
//调度系统结合上面缓存链条线库存,如果上面低于3,那么空箱可以上来缓存线
|
|
|
bool createResult = CreateDeliverTonerTask(rfid);
|
|
|
if (createResult)
|
|
|
{
|
|
|
//3色粉上提升机移栽等待
|
|
|
_logger.Info($"2#移栽===={rfid}携带色粉去往色粉库位");
|
|
|
workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"), 1);
|
|
|
workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#移栽平台任务"), 3);
|
|
|
workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#料箱运回RFID读取"), false);
|
|
|
}
|
|
|
else
|
|
|
{ //色粉库位无空闲位置,空转一圈
|
|
|
//2空箱转运
|
|
|
_logger.Info($"2#移栽===={rfid}携带色粉,色粉库位无空闲位置,空转一圈");
|
|
|
workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"), 1);
|
|
|
workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#移栽平台任务"), 2);
|
|
|
workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#料箱运回RFID读取"), false);
|
|
|
}
|
|
|
}
|
|
|
else if (wmsPalletInfo != null && wmsPalletInfo.Amount > 0 && wmsPalletInfo.TonerFlag == 0) //携带满料
|
|
|
{
|
|
|
//2转运
|
|
|
_logger.Info($"2#移栽===={rfid}携带满料,空转一圈");
|
|
|
workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"), 1);
|
|
|
workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#移栽平台任务"), 2);
|
|
|
workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#料箱运回RFID读取"), false);
|
|
|
}
|
|
|
else if (wmsPalletInfo != null && wmsPalletInfo.Amount == 0) //空托盘
|
|
|
{
|
|
|
if (Amount < 3)
|
|
|
{
|
|
|
//1上提升机去缓存线
|
|
|
_logger.Info($"2#移栽===={rfid}空箱,去缓存区");
|
|
|
workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"), 1);
|
|
|
workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#移栽平台任务"), 1);
|
|
|
workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#料箱运回RFID读取"), false);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//2空箱转运
|
|
|
_logger.Info($"2#移栽===={rfid}空箱,空箱转运");
|
|
|
workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"), 1);
|
|
|
workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#移栽平台任务"), 2);
|
|
|
workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#料箱运回RFID读取"), false);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//没读到2空箱转运
|
|
|
// _logger.Info($"1#移栽====没读到,空箱转运");
|
|
|
//workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"), 1);
|
|
|
//workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#移栽平台任务"), 2);
|
|
|
//workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#料箱运回RFID读取"), false);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#endregion 2#计量室料箱返回处理流程:空箱入缓存链条线,色粉派送至色粉存放点
|
|
|
|
|
|
#region 1#连廊料箱在计量室连廊移栽处理流程:wcs读RFID判断是否空箱,空箱下plc信号旋转,非空箱通知plc上提升机计量室
|
|
|
|
|
|
if (workShop2Plc != null && workShop2Plc.IsConnected)
|
|
|
{
|
|
|
bool returnJudgeSignal = workShop2Plc.readBoolByAddress(StaticData.GetPlcAddress("2#料箱运进计量室RFID读取"));
|
|
|
int busy1Flag = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("1#提升机忙碌状态"));
|
|
|
if (returnJudgeSignal && busy1Flag == 0)
|
|
|
{
|
|
|
//test
|
|
|
|
|
|
string rfid = ReadEpcStrByRfidKey("1#MetrologyRoom");
|
|
|
if (string.IsNullOrEmpty(rfid))
|
|
|
{
|
|
|
rfid = ReadEpcStrByRfidKey("1#MetrologyRoom");
|
|
|
}
|
|
|
if (!string.IsNullOrEmpty(rfid))
|
|
|
{
|
|
|
// 判断有无料, 如果没有料,wcs下发空箱旋转信号,有料,通知plc上提升机计量室
|
|
|
WmsPalletInfo? wmsPalletInfo = sqlSugarClient.Queryable<WmsPalletInfo>().First(it => it.PalletInfoCode == rfid);
|
|
|
if (wmsPalletInfo != null && wmsPalletInfo.Amount > 0 && wmsPalletInfo.TonerFlag == 1) //携带色粉
|
|
|
{
|
|
|
//2空箱转运
|
|
|
_logger.Info($"1#移栽===={rfid}携带色粉,空箱转运");
|
|
|
workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("1#移栽平台任务"), 2);
|
|
|
workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#料箱运进计量室RFID读取"), false);
|
|
|
}
|
|
|
if (wmsPalletInfo != null && wmsPalletInfo.Amount > 0 && wmsPalletInfo.TonerFlag == 0) //携带满料
|
|
|
{
|
|
|
//1#移栽平台任务(1上提升机,2空箱转运)
|
|
|
_logger.Info($"1#移栽===={rfid}携带满料,去提升机计量室");
|
|
|
workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("1#移栽平台任务"), 1);
|
|
|
workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#料箱运进计量室RFID读取"), false);
|
|
|
}
|
|
|
else if (wmsPalletInfo != null && wmsPalletInfo.Amount == 0)
|
|
|
{
|
|
|
//1#移栽平台任务(1上提升机,2空箱转运)
|
|
|
_logger.Info($"1#移栽===={rfid}空箱,空箱转运");
|
|
|
workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("1#移栽平台任务"), 2);
|
|
|
workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#料箱运进计量室RFID读取"), false);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//没读到,当成空箱子旋转一圈
|
|
|
//1#移栽平台任务(1上提升机,2空箱转运)
|
|
|
// _logger.Info($"1#移栽====没读到,空箱转运");
|
|
|
//workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("1#移栽平台任务"), 2);
|
|
|
//workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#料箱运进计量室RFID读取"), false);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#endregion 1#连廊料箱在计量室连廊移栽处理流程:wcs读RFID判断是否空箱,空箱下plc信号旋转,非空箱通知plc上提升机计量室
|
|
|
|
|
|
#region 暂时不使用--色粉存放点空托盘派送至2#接驳位
|
|
|
|
|
|
/////如果色粉存放点可用空库位小于等于2个,并且有空托盘在库位,判断2#缓存链条线库存(容量3)低于2个,并且无 从3#接驳位到2#接驳位的送料任务或 色粉存放点到2#缓存链条线任务,
|
|
|
/////2.生成色粉存放点到2#缓存链条线任务
|
|
|
//int canUseAmount = sqlSugarClient.Queryable<WcsBaseEquip>().Count(it => it.EquipType == 7 && it.EquipStatus == 0 && string.IsNullOrEmpty(it.ContainerCode));
|
|
|
////判断色粉存放处是否有空托盘
|
|
|
//WcsBaseEquip? startEquip = sqlSugarClient.Queryable<WcsBaseEquip>().InnerJoin<WmsPalletInfo>(
|
|
|
// (wbe, wpi) => wbe.ContainerCode == wpi.PalletInfoCode && wpi.Amount == 0 && wbe.EquipStatus == 0)
|
|
|
// .Where(wbe => wbe.EquipType == 7 && !string.IsNullOrEmpty(wbe.ContainerCode)).First();
|
|
|
//if (canUseAmount < 2 && startEquip != null)
|
|
|
//{
|
|
|
// int cacheLineAmount = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#缓存链条线库存数"));
|
|
|
// bool hasTask = sqlSugarClient.Queryable<WcsTask>().Any(it => it.TaskType == StaticTaskType.EmptyReturnFromTonerTask || it.TaskType == StaticTaskType.TransferMaterialMetrologyRoomBoxTask);
|
|
|
// if (cacheLineAmount < 2 && !hasTask)
|
|
|
// {
|
|
|
// try
|
|
|
// {
|
|
|
// sqlSugarClient.AsTenant().BeginTran();
|
|
|
// WcsTask task = new WcsTask();
|
|
|
// task.TaskType = StaticTaskType.EmptyReturnFromTonerTask;
|
|
|
// task.CurrPointNo = startEquip.AgvPositionCode;
|
|
|
// task.EndPointNo = "2DeliverMetrologyRoomPoint";
|
|
|
// task.TaskStatus = 0;
|
|
|
// task.CreatedTime = DateTime.Now;
|
|
|
// task.CreatedBy = "wcs";
|
|
|
// task.TaskName = "色粉存放点空托盘派送至2#接驳位";
|
|
|
// task.PalletInfoCode = startEquip.ContainerCode;
|
|
|
// int id = sqlSugarClient.Insertable(task).ExecuteReturnIdentity();
|
|
|
// WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(task);
|
|
|
// wcsTaskLog.Id = id;
|
|
|
// startEquip.EquipStatus = 1;
|
|
|
// sqlSugarClient.Updateable(startEquip).ExecuteCommand();
|
|
|
// sqlSugarClient.Insertable(wcsTaskLog).ExecuteCommand();
|
|
|
// sqlSugarClient.AsTenant().CommitTran();
|
|
|
// _logger.Agv($"生成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}");
|
|
|
// }
|
|
|
// catch (Exception ex)
|
|
|
// {
|
|
|
// sqlSugarClient.AsTenant().RollbackTran();
|
|
|
// _logger.Error($"色粉存放点空托盘派送至2#接驳位任务提交事务异常{ex.Message}");
|
|
|
// }
|
|
|
// }
|
|
|
//}
|
|
|
|
|
|
#endregion 暂时不使用--色粉存放点空托盘派送至2#接驳位
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.Error($"ListeningWorkShop2TransplantingMachine方法异常:" + ex.StackTrace);
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
Thread.Sleep(1000 * 1);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#region 任务流程
|
|
|
|
|
|
/// <summary>
|
|
|
/// 3#车间补四宫格空箱流程
|
|
|
/// </summary>
|
|
|
private async void CreateSupplementBigPalletTask()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
//判断agv是否有来这里的任务
|
|
|
bool hasTask = sqlSugarClient.Queryable<WcsTask>().Any(it => it.TaskType == StaticTaskType.SupplyEmptyPalletTask && it.EndPointNo == "3SuppleEmptyPalletPoint");
|
|
|
if (hasTask)
|
|
|
{
|
|
|
//_logger.Info("Agv已有3#车间补四宫格空箱任务");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
#region 寻找机台空托盘
|
|
|
|
|
|
WmsBaseLocation? startLocation = null;
|
|
|
//todo:优化点:为避免送料时尽可能少的移库任务,因此在这里可以先读取下一个料包要去的机台号,提前调度这里的空箱
|
|
|
string nextGoMachineCode = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#实时机台号")).ToString();
|
|
|
bool hasAny = StaticData.WmsMachineInfos.Any(x => x.MachineCode == nextGoMachineCode && x.WorkshopId == 3);
|
|
|
if (hasAny)
|
|
|
{
|
|
|
int machineId = StaticData.WmsMachineInfos.First(x => x.MachineCode == nextGoMachineCode).MachineId;
|
|
|
if (machineId >= 12 && machineId <= 16)
|
|
|
{
|
|
|
//12 - 16号机台都送往12号机台
|
|
|
machineId = 12;
|
|
|
}
|
|
|
//判断该机台有无空料箱,优先补充
|
|
|
string sql = $"SELECT wbl.* FROM wms_base_location wbl join wms_pallet_info wpi on wbl.container_code = wpi.pallet_info_code where wbl.container_code is not null and wbl.container_code!='' and wbl.location_status=0 and wbl.machineid ={machineId} and wpi.amount=0";
|
|
|
List<WmsBaseLocation> startLocations = sqlSugarClient.Ado.SqlQuery<WmsBaseLocation>(sql).OrderByDescending(x => x.MachineId).ToList();
|
|
|
if (startLocations.Count > 0)
|
|
|
{
|
|
|
startLocation = startLocations[0];
|
|
|
}
|
|
|
}
|
|
|
//1-12机台,优先12
|
|
|
if (startLocation == null)
|
|
|
{
|
|
|
string sql = "SELECT wbl.* FROM wms_base_location wbl join wms_pallet_info wpi on wbl.container_code = wpi.pallet_info_code where wbl.container_code is not null and wbl.container_code!='' and wbl.location_status=0 and wbl.machineid<=12 and wpi.amount=0";
|
|
|
|
|
|
List<WmsBaseLocation> emptyLocations = sqlSugarClient.Ado.SqlQuery<WmsBaseLocation>(sql).OrderBy(x => x.MachineId).ToList();
|
|
|
if (emptyLocations.Count == 0)
|
|
|
{
|
|
|
_logger.Info("暂时没有可用空托盘库位");
|
|
|
//todo报警
|
|
|
return;
|
|
|
}
|
|
|
//暂时排序,后期结合小料正在生产的计划提前调度要配送机台的空托盘,或者可以根据实际位置调度最近的空料箱
|
|
|
startLocation = emptyLocations.First();
|
|
|
}
|
|
|
|
|
|
WcsBaseEquip? endEquip = sqlSugarClient.Queryable<WcsBaseEquip>().Where(it => it.EquipNo == "3SuppleEmptyPalletPoint").ToList().First();
|
|
|
|
|
|
#endregion 寻找机台空托盘
|
|
|
|
|
|
sqlSugarClient.AsTenant().BeginTran();
|
|
|
|
|
|
WcsTask task = new WcsTask();
|
|
|
task.TaskType = StaticTaskType.SupplyEmptyPalletTask;
|
|
|
task.TaskName = StaticTaskType.GetDescription(task.TaskType);
|
|
|
|
|
|
task.CurrPointNo = startLocation.AgvPositionCode;
|
|
|
startLocation.LocationStatus = 1;
|
|
|
sqlSugarClient.Updateable(startLocation).ExecuteCommand();
|
|
|
// task.NextPointNo = agvEquip.AgvPositionCode;
|
|
|
task.EndPointNo = endEquip.AgvPositionCode;
|
|
|
task.TaskStatus = 0;
|
|
|
task.CreatedTime = DateTime.Now;
|
|
|
task.CreatedBy = "wcs";
|
|
|
task.PalletInfoCode = startLocation.ContainerCode;
|
|
|
int id = sqlSugarClient.Insertable(task).ExecuteReturnIdentity();
|
|
|
WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(task);
|
|
|
wcsTaskLog.Id = id;
|
|
|
sqlSugarClient.Insertable(wcsTaskLog).ExecuteCommand();
|
|
|
sqlSugarClient.AsTenant().CommitTran();
|
|
|
_logger.Agv($"生成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}");
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
sqlSugarClient.AsTenant().RollbackTran();
|
|
|
_logger.Error($"生成3#车间补四宫格空箱流程异常{ex.Message}");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 从下料点到1-16机台送料任务 创建移库任务
|
|
|
/// </summary>
|
|
|
private async void CreatDeliverWorkShop3Task(string machineCode, string rfid, int amount)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
bool hasMachineCode = StaticData.WmsMachineInfos.Any(x => x.MachineCode == machineCode);
|
|
|
if (!string.IsNullOrEmpty(rfid) && hasMachineCode)
|
|
|
{
|
|
|
//判断该料箱是否已经有送料任务
|
|
|
bool hasTask = sqlSugarClient.Queryable<WcsTask>().Any(it => it.TaskType == StaticTaskType.TransferMaterialBoxTask && it.PalletInfoCode == rfid);
|
|
|
if (hasTask)
|
|
|
{
|
|
|
_logger.Info($"该托盘{rfid}已有下料点到1-16机台送料任务");
|
|
|
return;
|
|
|
}
|
|
|
//判断该托盘是否已经在库里
|
|
|
bool isInLocation = sqlSugarClient.Queryable<WmsBaseLocation>().Any(it => it.ContainerCode == rfid);
|
|
|
if (isInLocation)
|
|
|
{
|
|
|
//todo推送报警
|
|
|
_logger.Info($"该托盘{rfid}已存在库位,请检查托盘号是否重复");
|
|
|
return;
|
|
|
}
|
|
|
List<WmsBaseLocation> AllWmsBaseLocationList = await sqlSugarClient.Queryable<WmsBaseLocation>().Where(x => x.MachineId <= 12).ToListAsync();
|
|
|
|
|
|
WmsBaseLocation? targetLocation;
|
|
|
// 根据机台号寻找终点库位、判断机台的两个库位是否有空位置、没有的话先生成移库任务
|
|
|
targetLocation = GetTargetLocation(machineCode, AllWmsBaseLocationList);
|
|
|
if (targetLocation == null)
|
|
|
{
|
|
|
//todo:推送预警
|
|
|
_logger.Info($"机台:{machineCode}没有可用空库位,无法配送");
|
|
|
return;
|
|
|
}
|
|
|
WcsBaseEquip startEquip = sqlSugarClient.Queryable<WcsBaseEquip>().First(it => it.EquipNo == "3DeliverBigGoodsStartPoint");
|
|
|
WmsPalletInfo wmsPalletInfo = sqlSugarClient.Queryable<WmsPalletInfo>().First(it => it.PalletInfoCode == rfid);
|
|
|
WcsTask task = new WcsTask();
|
|
|
task.TaskType = StaticTaskType.TransferMaterialBoxTask;
|
|
|
task.CurrPointNo = startEquip.AgvPositionCode;
|
|
|
task.EndPointNo = targetLocation.AgvPositionCode;
|
|
|
task.TaskStatus = 0;
|
|
|
task.CreatedTime = DateTime.Now;
|
|
|
task.CreatedBy = "wcs";
|
|
|
task.TaskName = "下料点到1-16机台送料任务";
|
|
|
task.PalletInfoCode = rfid;
|
|
|
task.MachineCode = machineCode;
|
|
|
sqlSugarClient.AsTenant().BeginTran();
|
|
|
try
|
|
|
{
|
|
|
int id = sqlSugarClient.Insertable(task).ExecuteReturnIdentity();
|
|
|
WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(task);
|
|
|
wcsTaskLog.Id = id;
|
|
|
targetLocation.LocationStatus = 1;
|
|
|
sqlSugarClient.Updateable(targetLocation).ExecuteCommand();
|
|
|
sqlSugarClient.Insertable(wcsTaskLog).ExecuteCommand();
|
|
|
|
|
|
#region 修改托盘信息
|
|
|
|
|
|
if (wmsPalletInfo != null)
|
|
|
{
|
|
|
wmsPalletInfo.Amount = amount != 0 ? amount : 1;
|
|
|
wmsPalletInfo.UpdatedTime = DateTime.Now;
|
|
|
sqlSugarClient.Updateable(wmsPalletInfo).ExecuteCommand();
|
|
|
}
|
|
|
|
|
|
#endregion 修改托盘信息
|
|
|
|
|
|
sqlSugarClient.AsTenant().CommitTran();
|
|
|
workShop3Plc.writeBoolByAddress(StaticData.GetPlcAddress("3#大料箱agv取料通知"), false);
|
|
|
_logger.Agv($"生成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}");
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
sqlSugarClient.AsTenant().RollbackTran();
|
|
|
_logger.Error($"生成3#车间从下料点到1-16机台送料任务提交事务异常{ex.Message}");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
sqlSugarClient.AsTenant().RollbackTran();
|
|
|
_logger.Error($"生成3#车间从下料点到1-16机台送料任务异常{ex.Message}");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 从3#接驳位到2#计量室接驳位的送料任务
|
|
|
/// </summary>
|
|
|
private void CreatDeliverWorkShop2Task(string machineCode, string rfid)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
bool hasMachineCode = StaticData.WmsMachineInfos.Any(x => x.MachineCode == machineCode);
|
|
|
if (!string.IsNullOrEmpty(rfid) && hasMachineCode)
|
|
|
{
|
|
|
//判断agv是否有来这里的任务
|
|
|
bool hasTask = sqlSugarClient.Queryable<WcsTask>().Any(it => it.TaskType == StaticTaskType.TransferMaterialMetrologyRoomBoxTask && it.PalletInfoCode == rfid);
|
|
|
if (hasTask)
|
|
|
{
|
|
|
_logger.Info($"该托盘{rfid}已有3#接驳位到2#计量室接驳位的送料任务");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//起点库位 3#车间小料箱取送货接驳点
|
|
|
WcsBaseEquip startEquip = sqlSugarClient.Queryable<WcsBaseEquip>().First(it => it.EquipNo == "3DeliverSmallGoodsPoint");
|
|
|
//终点库位 2#车间计量室接驳点
|
|
|
WcsBaseEquip endEquip = sqlSugarClient.Queryable<WcsBaseEquip>().First(it => it.EquipNo == "2DeliverMetrologyRoomPoint");
|
|
|
WmsPalletInfo wmsPalletInfo = sqlSugarClient.Queryable<WmsPalletInfo>().First(it => it.PalletInfoCode == rfid);
|
|
|
sqlSugarClient.AsTenant().BeginTran();
|
|
|
WcsTask task = new WcsTask();
|
|
|
task.TaskType = StaticTaskType.TransferMaterialMetrologyRoomBoxTask;
|
|
|
task.CurrPointNo = startEquip.AgvPositionCode;
|
|
|
// task.NextPointNo = agvEquip.AgvPositionCode;
|
|
|
task.EndPointNo = endEquip.AgvPositionCode;
|
|
|
task.TaskStatus = 0;
|
|
|
task.CreatedTime = DateTime.Now;
|
|
|
task.CreatedBy = "wcs";
|
|
|
task.TaskName = "3#接驳位到2#计量室接驳位的送料任务";
|
|
|
task.PalletInfoCode = rfid;
|
|
|
task.MachineCode = machineCode;
|
|
|
int id = sqlSugarClient.Insertable(task).ExecuteReturnIdentity();
|
|
|
WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(task);
|
|
|
wcsTaskLog.Id = id;
|
|
|
|
|
|
sqlSugarClient.Insertable(wcsTaskLog).ExecuteCommand();
|
|
|
|
|
|
#region 修改托盘信息
|
|
|
|
|
|
if (wmsPalletInfo != null)
|
|
|
{
|
|
|
wmsPalletInfo.TonerFlag = 0;
|
|
|
wmsPalletInfo.Amount = 1;
|
|
|
wmsPalletInfo.UpdatedTime = DateTime.Now;
|
|
|
sqlSugarClient.Updateable(wmsPalletInfo).ExecuteCommand();
|
|
|
}
|
|
|
|
|
|
#endregion 修改托盘信息
|
|
|
|
|
|
sqlSugarClient.AsTenant().CommitTran();
|
|
|
workShop3Plc.writeBoolByAddress(StaticData.GetPlcAddress("3#小料箱agv取料通知"), false);
|
|
|
_logger.Agv($"生成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}");
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
sqlSugarClient.AsTenant().RollbackTran();
|
|
|
_logger.Error($"3#接驳位到2#计量室接驳位的送料任务{ex.Message}");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 3#车间从色粉存放点补充小托盘任务 或者 3#车间从2#接驳位补充小托盘任务
|
|
|
/// .wcs检测到 3#缓存皮带线库存数 (容量2)不满时,且色粉存放处有空托盘时,优先生成色粉存放处补充小料箱任务
|
|
|
///2.如果色粉存放处无空托盘,且2#缓存链条线库存数 大于0个,并且 2#线体忙碌状态 0时,2s后 2#线体忙碌状态 0时,wcs把 2#线体忙碌状态 改为1,wcs下发缓存链条线 2#出一个空托盘信号(plc自己复位), wcs并且生成一个3#补充空托盘任务呼叫agv
|
|
|
/// </summary>
|
|
|
private void CreateSupplySmallPalletToWorkshop3Task()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
//判断是否已经有空托盘补充任务
|
|
|
bool hasTask = sqlSugarClient.Queryable<WcsTask>().Any(x => x.TaskType == StaticTaskType.SupplySmallPalletTask || x.TaskType == StaticTaskType.SupplySmallPalletFromTonerTask);
|
|
|
if (hasTask)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
//判断色粉存放处是否有空托盘
|
|
|
WcsBaseEquip? emptyPalletEquip = sqlSugarClient.Queryable<WcsBaseEquip>().InnerJoin<WmsPalletInfo>(
|
|
|
(wbe, wpi) => wbe.ContainerCode == wpi.PalletInfoCode && wpi.Amount == 0 && wbe.EquipStatus == 0)
|
|
|
.Where(wbe => wbe.EquipType == 7 && !string.IsNullOrEmpty(wbe.ContainerCode)).OrderBy(wbe => wbe.Id).First();
|
|
|
if (emptyPalletEquip != null) //从色粉存放处生成补充空托盘任务
|
|
|
{
|
|
|
WcsTask task = new WcsTask();
|
|
|
task.TaskType = StaticTaskType.SupplySmallPalletFromTonerTask;
|
|
|
task.CurrPointNo = emptyPalletEquip.AgvPositionCode;
|
|
|
task.EndPointNo = "3DeliverSmallGoodsPoint";
|
|
|
task.TaskStatus = 0;
|
|
|
task.CreatedTime = DateTime.Now;
|
|
|
task.CreatedBy = "wcs";
|
|
|
task.TaskName = "3#车间从色粉存放点补充小托盘任务";
|
|
|
task.PalletInfoCode = emptyPalletEquip.ContainerCode;
|
|
|
|
|
|
sqlSugarClient.AsTenant().BeginTran();
|
|
|
try
|
|
|
{
|
|
|
int id = sqlSugarClient.Insertable(task).ExecuteReturnIdentity();
|
|
|
WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(task);
|
|
|
wcsTaskLog.Id = id;
|
|
|
sqlSugarClient.Insertable(wcsTaskLog).ExecuteCommand();
|
|
|
//锁住开始色粉库位
|
|
|
emptyPalletEquip.EquipStatus = 1;
|
|
|
sqlSugarClient.Updateable(emptyPalletEquip).ExecuteCommand();
|
|
|
sqlSugarClient.AsTenant().CommitTran();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
sqlSugarClient.AsTenant().RollbackTran();
|
|
|
_logger.Error($"3#车间从色粉存放点补充小托盘任务生成提交事务异常{ex.Message}");
|
|
|
}
|
|
|
_logger.Agv($"生成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}");
|
|
|
return;
|
|
|
}
|
|
|
else //从2#缓存链条线生成补充空托盘任务
|
|
|
{
|
|
|
if (workShop2Plc == null || !workShop2Plc.IsConnected)
|
|
|
{
|
|
|
_logger.Plc(DateTime.Now + "2#PLC未连接,请检查网络!");
|
|
|
return;
|
|
|
}
|
|
|
int work2EmptyAmount = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#缓存链条线库存数"));
|
|
|
int work2BusyFlag = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"));
|
|
|
if (work2EmptyAmount > 0 && work2BusyFlag == 0)
|
|
|
{
|
|
|
//防止抢占其他任务节奏
|
|
|
Thread.Sleep(1000);
|
|
|
work2BusyFlag = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"));
|
|
|
work2EmptyAmount = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#缓存链条线库存数"));
|
|
|
if (work2EmptyAmount > 0 && work2BusyFlag == 0)
|
|
|
{
|
|
|
workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"), 1);
|
|
|
|
|
|
WcsTask task = new WcsTask();
|
|
|
task.TaskType = StaticTaskType.SupplySmallPalletTask;
|
|
|
task.CurrPointNo = "2DeliverMetrologyRoomPoint";
|
|
|
task.EndPointNo = "3DeliverSmallGoodsPoint";
|
|
|
task.TaskStatus = 0;
|
|
|
task.CreatedTime = DateTime.Now;
|
|
|
task.CreatedBy = "wcs";
|
|
|
task.TaskName = " 3#车间从2#接驳位补充小托盘任务";
|
|
|
sqlSugarClient.AsTenant().BeginTran();
|
|
|
try
|
|
|
{
|
|
|
int id = sqlSugarClient.Insertable(task).ExecuteReturnIdentity();
|
|
|
WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(task);
|
|
|
wcsTaskLog.Id = id;
|
|
|
sqlSugarClient.Insertable(wcsTaskLog).ExecuteCommand();
|
|
|
|
|
|
sqlSugarClient.AsTenant().CommitTran();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
sqlSugarClient.AsTenant().RollbackTran();
|
|
|
_logger.Error($"3#车间从2#接驳位补充小托盘任务生成提交事务异常{ex.Message}");
|
|
|
workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"), 0);
|
|
|
}
|
|
|
_logger.Agv($"生成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}");
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.Error($"CreateSupplySmallPalletToWorkshop3Task异常{ex.Message}");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 从2#接驳位到3#接驳位补小空箱任务 :3#车间补小空箱流程
|
|
|
/// </summary>
|
|
|
private void CreateSupplementSmallPalletTask()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
//判断是否有该任务
|
|
|
bool hasTask = sqlSugarClient.Queryable<WcsTask>().Any(it => it.TaskType == StaticTaskType.SupplySmallPalletTask && it.TaskStatus < 5);
|
|
|
if (hasTask)
|
|
|
{
|
|
|
_logger.Info("Agv已有2#接驳位到3#接驳位补小空箱任务");
|
|
|
return;
|
|
|
}
|
|
|
//寻找可用agv
|
|
|
//WcsBaseEquip? agvEquip = GetCanUseAgv();
|
|
|
//if (agvEquip == null)
|
|
|
//{
|
|
|
// _logger.Info("暂时没有可用agv");
|
|
|
// return;
|
|
|
//}
|
|
|
//起点库位 3#车间小料箱取送货接驳点
|
|
|
WcsBaseEquip startEquip = sqlSugarClient.Queryable<WcsBaseEquip>().First(it => it.EquipNo == "2DeliverMetrologyRoomPoint");
|
|
|
//终点库位 2#车间计量室接驳点
|
|
|
WcsBaseEquip endEquip = sqlSugarClient.Queryable<WcsBaseEquip>().First(it => it.EquipNo == "3DeliverSmallGoodsPoint");
|
|
|
sqlSugarClient.AsTenant().BeginTran();
|
|
|
WcsTask task = new WcsTask();
|
|
|
task.TaskType = StaticTaskType.SupplySmallPalletTask;
|
|
|
task.CurrPointNo = startEquip.AgvPositionCode;
|
|
|
// task.NextPointNo = agvEquip.AgvPositionCode;
|
|
|
task.EndPointNo = endEquip.AgvPositionCode;
|
|
|
task.TaskStatus = 0;
|
|
|
task.CreatedTime = DateTime.Now;
|
|
|
task.CreatedBy = "wcs";
|
|
|
task.TaskName = "2#接驳位到3#接驳位补小空箱任务";
|
|
|
int id = sqlSugarClient.Insertable(task).ExecuteReturnIdentity();
|
|
|
WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(task);
|
|
|
wcsTaskLog.Id = id;
|
|
|
startEquip.EquipStatus = 1;
|
|
|
endEquip.EquipStatus = 1;
|
|
|
sqlSugarClient.Updateable(startEquip).ExecuteCommand();
|
|
|
sqlSugarClient.Updateable(endEquip).ExecuteCommand();
|
|
|
sqlSugarClient.Insertable(wcsTaskLog).ExecuteCommand();
|
|
|
sqlSugarClient.AsTenant().CommitTran();
|
|
|
_logger.Agv($"生成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}");
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
sqlSugarClient.AsTenant().RollbackTran();
|
|
|
_logger.Error($"2#接驳位到3#接驳位补小空箱任务异常{ex.Message}");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 2#色粉派送至色粉存放点任务
|
|
|
/// </summary>
|
|
|
private bool CreateDeliverTonerTask(string rfid)
|
|
|
{
|
|
|
bool createResult = false;
|
|
|
try
|
|
|
{
|
|
|
//判断是否有该任务
|
|
|
bool hasTask = sqlSugarClient.Queryable<WcsTask>().Any(it => it.TaskType == StaticTaskType.DeliverTonerTask && it.PalletInfoCode == rfid);
|
|
|
if (hasTask)
|
|
|
{
|
|
|
_logger.Info($"Agv已有托盘:{rfid}2#色粉派送至色粉存放点任务");
|
|
|
return true;
|
|
|
}
|
|
|
//起点库位 2#计量室车间小料箱取送货接驳点
|
|
|
WcsBaseEquip startEquip = sqlSugarClient.Queryable<WcsBaseEquip>().First(it => it.EquipNo == "2DeliverMetrologyRoomPoint");
|
|
|
//终点库位 2#返程色粉人工拿取点
|
|
|
WcsBaseEquip? endEquip = sqlSugarClient.Queryable<WcsBaseEquip>().Where(it => it.EquipStatus == 0 && it.EquipType == 7 && string.IsNullOrEmpty(it.ContainerCode)).OrderBy(x => x.Id).First();
|
|
|
if (endEquip == null)
|
|
|
{
|
|
|
//todo推送报警
|
|
|
_logger.Error("暂时没有可用色粉存放点库位");
|
|
|
return false;
|
|
|
}
|
|
|
sqlSugarClient.AsTenant().BeginTran();
|
|
|
try
|
|
|
{
|
|
|
WcsTask task = new WcsTask();
|
|
|
task.TaskType = StaticTaskType.DeliverTonerTask;
|
|
|
task.CurrPointNo = startEquip.AgvPositionCode;
|
|
|
task.EndPointNo = endEquip.AgvPositionCode;
|
|
|
task.TaskStatus = 0;
|
|
|
task.CreatedTime = DateTime.Now;
|
|
|
task.CreatedBy = "wcs";
|
|
|
task.TaskName = "2#色粉派送至色粉存放点任务";
|
|
|
task.PalletInfoCode = rfid;
|
|
|
int id = sqlSugarClient.Insertable(task).ExecuteReturnIdentity();
|
|
|
WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(task);
|
|
|
wcsTaskLog.Id = id;
|
|
|
startEquip.EquipStatus = 1;
|
|
|
endEquip.EquipStatus = 1;
|
|
|
sqlSugarClient.Updateable(startEquip).ExecuteCommand();
|
|
|
sqlSugarClient.Updateable(endEquip).ExecuteCommand();
|
|
|
sqlSugarClient.Insertable(wcsTaskLog).ExecuteCommand();
|
|
|
sqlSugarClient.AsTenant().CommitTran();
|
|
|
_logger.Agv($"生成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}");
|
|
|
createResult = true;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
sqlSugarClient.AsTenant().RollbackTran();
|
|
|
_logger.Error($"2#色粉派送至色粉存放点任务提交事务异常{ex.Message}");
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
sqlSugarClient.AsTenant().RollbackTran();
|
|
|
_logger.Error($"生成2#色粉派送至色粉存放点并空箱送回2#接驳位任务异常{ex.Message}");
|
|
|
}
|
|
|
return createResult;
|
|
|
}
|
|
|
|
|
|
#endregion 任务流程
|
|
|
|
|
|
#region 辅助方法
|
|
|
|
|
|
/// <summary>
|
|
|
/// 判断是否还有色粉在连廊输送线或者没在色粉库位
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
private bool HasAnyTonerInLine()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 色粉料箱
|
|
|
List<WmsPalletInfo> tonerPallets = sqlSugarClient.Queryable<WmsPalletInfo>().Where(x => x.TonerFlag == 1 && x.Amount > 0).ToList();
|
|
|
|
|
|
// 色粉库位的料箱码
|
|
|
List<WcsBaseEquip> equipPalletInfos = sqlSugarClient.Queryable<WcsBaseEquip>().Where(x => x.EquipType == 7 && !string.IsNullOrEmpty(x.ContainerCode)).ToList();
|
|
|
|
|
|
// 获取 tonerPallets 中的所有 PalletInfoCode
|
|
|
var tonerPalletCodes = tonerPallets.Select(x => x.PalletInfoCode).ToList();
|
|
|
|
|
|
// 获取 equipPalletInfos 中的所有 ContainerCode
|
|
|
var equipPalletCodes = equipPalletInfos.Select(x => x.ContainerCode).ToList();
|
|
|
|
|
|
// 检查是否有 tonerPalletCodes 不在 equipPalletCodes 中
|
|
|
bool result = tonerPalletCodes.Any(code => !equipPalletCodes.Contains(code));
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
///// <summary>
|
|
|
///// 从12号机台获取空托盘,返回库位信息
|
|
|
///// </summary>
|
|
|
///// <param name="machineId"></param>
|
|
|
///// <returns></returns>
|
|
|
//private async Task<WmsBaseLocation?> GetEmptyContainerByMachine12Async(string rfidKey)
|
|
|
//{
|
|
|
// try
|
|
|
// {
|
|
|
// bool flag1 = await ReadSignalByRfidKeyAsync(rfidKey);
|
|
|
// if (flag1)
|
|
|
// {
|
|
|
// string code = await ReadEpcStrByRfidKeyAsync(rfidKey);
|
|
|
// if (!string.IsNullOrEmpty(code))
|
|
|
// {
|
|
|
// // 通过该料箱是否绑定有物料来判断是否为空托盘
|
|
|
// bool hasMaterial = await sqlSugarClient.Queryable<WmsPalletInfo>().AnyAsync(it => it.PalletInfoCode == code);
|
|
|
// if (!hasMaterial)
|
|
|
// {
|
|
|
// WmsBaseLocation? location = await sqlSugarClient.Queryable<WmsBaseLocation>().FirstAsync(it => it.EquipKey == rfidKey);
|
|
|
// return location;
|
|
|
// }
|
|
|
// }
|
|
|
// }
|
|
|
// //_logger.Error($"12号机台库位{rfidKey}无空托盘");
|
|
|
// return null;
|
|
|
// }
|
|
|
// catch (Exception ex)
|
|
|
// {
|
|
|
// return null;
|
|
|
// }
|
|
|
//}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 根据机台号寻找终点库位、判断机台的两个库位是否有空位置、没有的话先生成移库任务
|
|
|
/// machineId为该料箱目的地机台号
|
|
|
/// </summary>
|
|
|
/// <param name="machineId"></param>
|
|
|
/// <returns></returns>
|
|
|
private WmsBaseLocation? GetTargetLocation(string machineCode, List<WmsBaseLocation> AllWmsBaseLocationList)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
bool hasMoveTask = sqlSugarClient.Queryable<WcsTask>().Any(it => it.TaskType == StaticTaskType.MoveLocationTask && it.TaskStatus < 3);
|
|
|
if (hasMoveTask)
|
|
|
{
|
|
|
_logger.Info($"目标库位无空位置,正在执行移库任务,暂时不生成送料任务,请等待....");
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
WmsBaseLocation? targetLocation;
|
|
|
//移库起点终点
|
|
|
WmsBaseLocation? moveStartLocation;
|
|
|
WmsBaseLocation? moveEndLocation;
|
|
|
int machineId = StaticData.WmsMachineInfos.First(x => x.MachineCode == machineCode).MachineId;
|
|
|
if (machineId >= 12 && machineId <= 16)
|
|
|
{
|
|
|
//12 - 16号机台都送往12号机台
|
|
|
machineId = 12;
|
|
|
}
|
|
|
//12号机台读RFID判断
|
|
|
//if (machineId >= 12)
|
|
|
//{
|
|
|
// //光电信号
|
|
|
// bool flag1 = await ReadSignalByRfidKeyAsync("12-1");
|
|
|
// bool flag2 = await ReadSignalByRfidKeyAsync("12-2");
|
|
|
// if (!flag1)
|
|
|
// { //12-1有空位
|
|
|
// targetLocation = AllWmsBaseLocationList.First(it => it.EquipKey == "12-1" && it.LocationStatus == 1);
|
|
|
// return targetLocation;
|
|
|
// }
|
|
|
// //if (!flag2) //12-2有空位
|
|
|
// {
|
|
|
// //默认全送到12-2库位,如果有料箱,agv送过去停着,人工取走库位上的箱子
|
|
|
// targetLocation = AllWmsBaseLocationList.First(it => it.EquipKey == "12-2" && it.LocationStatus == 1);
|
|
|
// return targetLocation;
|
|
|
// }
|
|
|
// // 后期考虑优化,12号机台暂不考虑移库,因为库位距离其他机台比较远
|
|
|
//}
|
|
|
//else if (machineId >= 1 && machineId <= 11)
|
|
|
{
|
|
|
targetLocation = AllWmsBaseLocationList.FirstOrDefault(it => it.MachineId == machineId && it.LocationStatus == 0 && string.IsNullOrEmpty(it.ContainerCode));
|
|
|
if (targetLocation != null) return targetLocation;
|
|
|
//目标机台两个都有料箱,判断是否有机台里面的料箱是空的,有空箱可生成移库任务,否则等待
|
|
|
String sql = $"SELECT wbl.* FROM wms_base_location wbl join wms_pallet_info wpi on wbl.container_code = wpi.pallet_info_code where wbl.container_code is not null and wbl.container_code!='' and wbl.location_status=0 and wbl.machineid={machineId} and wpi.amount=0";
|
|
|
moveStartLocation = sqlSugarClient.SqlQueryable<WmsBaseLocation>(sql).First();
|
|
|
if (moveStartLocation == null)
|
|
|
{
|
|
|
return null;
|
|
|
// todo推送预警 // 目标机台没有空库位,没有可移库的空箱,等待
|
|
|
}
|
|
|
//需要生成从该库位到其他机台的移库任务,找寻移库终点库位
|
|
|
moveEndLocation = AllWmsBaseLocationList.FirstOrDefault(x => x.LocationId != moveStartLocation.LocationId && x.LocationStatus == 0 && string.IsNullOrEmpty(x.ContainerCode));
|
|
|
if (moveEndLocation == null)
|
|
|
{
|
|
|
// 没有可以移库的库位,请等待
|
|
|
return null;
|
|
|
// todo:推送预警
|
|
|
}
|
|
|
else //生成移库任务
|
|
|
{
|
|
|
//二次确认寻找可用agv,避免在这期间agv被其他线程占用
|
|
|
try
|
|
|
{
|
|
|
//WcsBaseEquip? agvEquip = GetCanUseAgv();
|
|
|
//if (agvEquip == null)
|
|
|
//{
|
|
|
// _logger.Info("暂时没有可用agv");
|
|
|
// return null;
|
|
|
//}
|
|
|
WcsTask task = new WcsTask();
|
|
|
task.TaskType = StaticTaskType.MoveLocationTask;
|
|
|
task.CurrPointNo = moveStartLocation.AgvPositionCode;
|
|
|
task.EndPointNo = moveEndLocation.AgvPositionCode;
|
|
|
task.TaskStatus = 0;
|
|
|
task.CreatedTime = DateTime.Now;
|
|
|
task.CreatedBy = "wcs";
|
|
|
task.TaskName = "1-12机台之间空托盘移库任务";
|
|
|
task.PalletInfoCode = moveStartLocation.ContainerCode;
|
|
|
sqlSugarClient.AsTenant().BeginTran();
|
|
|
try
|
|
|
{
|
|
|
int id = sqlSugarClient.Insertable(task).ExecuteReturnIdentity();
|
|
|
WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(task);
|
|
|
wcsTaskLog.Id = id;
|
|
|
//锁定库位
|
|
|
moveStartLocation.LocationStatus = 1;
|
|
|
moveEndLocation.LocationStatus = 1;
|
|
|
sqlSugarClient.Updateable(moveStartLocation).ExecuteCommand();
|
|
|
sqlSugarClient.Updateable(moveEndLocation).ExecuteCommand();
|
|
|
sqlSugarClient.Insertable(wcsTaskLog).ExecuteCommand();
|
|
|
sqlSugarClient.AsTenant().CommitTran();
|
|
|
_logger.Agv($"生成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}");
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.Error($"生成移库任务提交事务异常:{ex.Message}");
|
|
|
sqlSugarClient.AsTenant().RollbackTran();
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.Error($"生成移库任务异常:{ex.Message}");
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.Error($"GetTargetLocationAsync方法异常:{ex.StackTrace}");
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#endregion 辅助方法
|
|
|
|
|
|
#region 测试方法
|
|
|
|
|
|
private async void test()
|
|
|
{
|
|
|
// 读RFID条码
|
|
|
// string code = await ReadEpcStrByRfidKeyAsync("1");
|
|
|
//读光电信号
|
|
|
//bool flag = await ReadSignalByRfidKeyAsync("1");
|
|
|
//bool flag1 = await ReadSignalByRfidKeyAsync("1");
|
|
|
|
|
|
//testTransitional();
|
|
|
//testTransitionalRollback();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 测多线程事务影响程度
|
|
|
/// </summary>
|
|
|
private void testTransitional()
|
|
|
{
|
|
|
Task.Run(() =>
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
sqlSugarClient.AsTenant().BeginTran();
|
|
|
for (int i = 0; i < 10; i++)
|
|
|
{
|
|
|
Console.WriteLine($"线程1{i}");
|
|
|
//WmsStock stock = new WmsStock();
|
|
|
// stock.WorkshopId = i;
|
|
|
// sqlSugarClient.Insertable(stock).ExecuteCommand();
|
|
|
Thread.Sleep(1000);
|
|
|
}
|
|
|
sqlSugarClient.AsTenant().CommitTran();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
sqlSugarClient.AsTenant().RollbackTran();
|
|
|
}
|
|
|
});
|
|
|
|
|
|
Task.Run(() =>
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
sqlSugarClient.AsTenant().BeginTran();
|
|
|
for (int i = 20; i < 30; i++)
|
|
|
{
|
|
|
//Console.WriteLine($"线程2{i}");
|
|
|
//WmsStock stock = new WmsStock();
|
|
|
//stock.WorkshopId = i;
|
|
|
//sqlSugarClient.Insertable(stock).ExecuteCommand();
|
|
|
//Thread.Sleep(1000);
|
|
|
//if (i == 25)
|
|
|
//{
|
|
|
// Console.WriteLine($"事务回滚");
|
|
|
// throw new Exception("事务回滚");
|
|
|
//}
|
|
|
}
|
|
|
sqlSugarClient.AsTenant().CommitTran();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
sqlSugarClient.AsTenant().RollbackTran();
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 测事务未开启但回滚
|
|
|
/// </summary>
|
|
|
private void testTransitionalRollback()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
throw new Exception("事务回滚");
|
|
|
sqlSugarClient.AsTenant().BeginTran();
|
|
|
for (int i = 0; i < 10; i++)
|
|
|
{
|
|
|
//Console.WriteLine($"线程1{i}");
|
|
|
//WmsStock stock = new WmsStock();
|
|
|
//stock.WorkshopId = i;
|
|
|
//sqlSugarClient.Insertable(stock).ExecuteCommand();
|
|
|
//Thread.Sleep(1000);
|
|
|
}
|
|
|
sqlSugarClient.AsTenant().CommitTran();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
sqlSugarClient.AsTenant().RollbackTran();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#endregion 测试方法
|
|
|
}
|
|
|
} |