using HH.WCS.JunzhouNongfu.device;
|
using HH.WCS.Mobox3.YNJT_BZP.api;
|
using HH.WCS.Mobox3.YNJT_BZP.dispatch;
|
using HH.WCS.Mobox3.YNJT_BZP.models;
|
using HH.WCS.Mobox3.YNJT_BZP.process;
|
using HH.WCS.Mobox3.YNJT_BZP.util;
|
using HH.WCS.Mobox3.YNJT_BZP.wms;
|
using Newtonsoft.Json;
|
using Org.BouncyCastle.Asn1.X509;
|
using S7.Net;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Net.Sockets;
|
using System.Runtime.Remoting.Metadata.W3cXsd2001;
|
using System.Threading.Tasks;
|
using static HH.WCS.Mobox3.YNJT_BZP.api.AgvController;
|
using static HH.WCS.Mobox3.YNJT_BZP.api.ApiModel;
|
using static HH.WCS.Mobox3.YNJT_BZP.dispatch.GtDispatch;
|
using static HH.WCS.Mobox3.YNJT_BZP.util.Settings;
|
|
namespace HH.WCS.Mobox3.YNJT_BZP.core {
|
internal class WCSCore {
|
public static void OperateAgvTaskStatus(AgvTaskState model) {
|
LogHelper.Info($"AGV任务状态反馈,入参:{JsonConvert.SerializeObject(model)}", "AGV");
|
try
|
{
|
if (string.IsNullOrEmpty(model.No))
|
{
|
LogHelper.Info("任务号为空", "AGV");
|
}
|
else
|
{
|
var TN_Task = WCSHelper.GetTask(model.No);
|
if (TN_Task != null)
|
{
|
var wmsTask = WMSHelper.GetWmsTask(TN_Task.S_OP_CODE);
|
if (wmsTask != null && wmsTask.N_B_STATE < 2)
|
{
|
if (model.State <= 7)
|
{
|
//有任务号请求
|
switch (model.State)
|
{
|
case 1:
|
TN_Task.S_EQ_NO = model.ForkliftNo;
|
WCSHelper.Begin(TN_Task);
|
break;
|
#region MyRegion
|
case 3:
|
WCSHelper.UpdateStatus(TN_Task, "开始取货");
|
break;
|
case 4:
|
WCSHelper.UpdateStatus(TN_Task, "取货完成");
|
TaskProcess.OperateStatus(TN_Task, 4);
|
break;
|
case 5:
|
WCSHelper.UpdateStatus(TN_Task, "开始卸货");
|
break;
|
case 6:
|
TaskProcess.OperateStatus(TN_Task, 6);
|
WCSHelper.UpdateStatus(TN_Task, "卸货完成");
|
|
// AGV卸货输送线,触发入库任务
|
if (TN_Task.S_END_LOC != wmsTask.S_END_LOC)
|
{
|
LogHelper.Info($"任务号:{TN_Task.S_CODE},AGV卸货输送线,触发WCS入库任务", "AGV");
|
Container container = ContainerHelper.GetCntr(TN_Task.S_CNTR_CODE);
|
if (container != null)
|
{
|
WCSCore.createLastTask(TN_Task.S_END_LOC, wmsTask, 1);
|
}
|
}
|
break;
|
#endregion
|
case 2:
|
WCSHelper.End(TN_Task);
|
|
var cntrItemRels = ContainerHelper.GetCntrItemRel(TN_Task.S_CNTR_CODE);
|
if (cntrItemRels.Count > 0)
|
{
|
LogHelper.Info($"任务号:{TN_Task.S_CODE},AGV任务完成,任务信息回报GT", "AGV");
|
string shift = ApiHelper.getShift(DateTime.Now.TimeOfDay);
|
string ydate_shiftName = "";
|
if (shift == "III")
|
{
|
ydate_shiftName = DateTime.Now.AddDays(-1).ToString("yy/MM/dd") + "-" + shift;
|
}
|
else
|
{
|
ydate_shiftName = DateTime.Now.ToString("yy/MM/dd") + "-" + shift;
|
}
|
WmsToGtLokasiModel wmsToGtLokasiModel = new WmsToGtLokasiModel()
|
{
|
ydate_shiftName = ydate_shiftName,
|
bc_entried = cntrItemRels[0].S_CG_ID,
|
loc_from = TN_Task.S_START_LOC,
|
loc_to = TN_Task.S_END_LOC,
|
qty = 1,
|
lot = 1,
|
scantime = TN_Task.T_CREATE.ToString("yyyy-MM-dd HH:mm:ss"),
|
pic = model.ForkliftNo
|
};
|
GtDispatch.agvTaskFeedback(wmsToGtLokasiModel);
|
}
|
break;
|
case 7:
|
LogHelper.Info($"任务号:{TN_Task.S_CODE},AGV任务取消", "AGV");
|
//判断是否收到过强制取消,有就不做任何处理
|
if (!WCSHelper.CheckActionRecordExist(TN_Task.S_CODE, 17))
|
{
|
TaskProcess.OperateStatus(TN_Task, 7);
|
WCSHelper.Cancel(TN_Task);
|
}
|
break;
|
}
|
}
|
else if (model.State == 1003)
|
{
|
LogHelper.Info($"任务号:{TN_Task.S_CODE},AGV小车进入等待位:{TN_Task.S_END_LOC}", "AGV");
|
// 卸货前等待
|
// 查询当前终点是等待区,则查询入库agv接驳位
|
var waitLoc = Settings.getAgvWaitLoc(TN_Task.S_END_LOC);
|
if (waitLoc != null)
|
{
|
if (TN_Task.S_TYPE.Contains("入库"))
|
{
|
var endLoc = AGVApplyEndLoc(model.No);
|
if (endLoc != null)
|
{
|
LogHelper.Info($"任务号:{TN_Task.S_CODE},AGV小车变更终点:{endLoc.S_CODE}", "AGV");
|
// 通知AGV更改终点
|
ChangeParamModel paramModel = new ChangeParamModel()
|
{
|
task_no = model.No,
|
param_no = 0,
|
param = $"{model.No};{TN_Task.S_START_LOC};{TN_Task.S_END_LOC};0;400;0;2"
|
};
|
LogHelper.Info($"通知AGV更改终点,参数:{paramModel}", "AGV");
|
/* NDCApi.ChangeOrderParam(paramModel);*/
|
}
|
}
|
}
|
}
|
else if (model.State == 1004)
|
{
|
LogHelper.Info($"任务号:{TN_Task.S_CODE},AGV小车卸货后在接驳位:{TN_Task.S_END_LOC}等待", "AGV");
|
// 卸货后等待
|
// 查询终点货位是否是入库接驳位
|
var agvJBLoc = Settings.getAgvJBLoc(TN_Task.S_END_LOC);
|
if (agvJBLoc != null && agvJBLoc.action == 1)
|
{
|
//是则查询WCS的任务执行情况
|
var wcsTask = WCSHelper.GetTaskBySrcNoAndScheduleType(TN_Task.S_OP_CODE, "WCS" , wmsTask.S_TYPE);
|
if (wcsTask != null)
|
{
|
bool existAction = WCSHelper.CheckActionRecordExist(wcsTask.S_CODE, 7);
|
if (existAction)
|
{
|
LogHelper.Info($"下游任务:{wcsTask.S_CODE}取消入库,rfid校验失败,生成新任务到异常区", "AGV");
|
//如果WCS反馈7取消任务,则rfid校验失败,生成新任务到异常区,并变更agv任务号、起点、终点
|
var mst = WMSHelper.GetWmsTask(TN_Task.S_OP_CODE);
|
var endLoc = WMSHelper.getErrorBufferAreaLoc();
|
if (endLoc != null)
|
{
|
LocationHelper.UnLockLoc(mst.S_END_LOC);
|
mst.S_END_LOC = endLoc.S_CODE;
|
mst.S_END_AREA = endLoc.S_AREA_CODE;
|
|
var newWcsTask = WCSCore.createLastTask(TN_Task.S_END_LOC, mst, 2, "出库异常区任务");
|
LogHelper.Info($"任务号:{TN_Task.S_CODE},AGV小车改道终点:{newWcsTask.S_END_LOC}", "AGV");
|
if (newWcsTask != null)
|
{
|
WCSHelper.End(TN_Task);
|
|
// 通知AGV更改终点
|
ChangeParamModel paramModel = new ChangeParamModel()
|
{
|
task_no = model.No,
|
param_no = 0,
|
param = $"{model.No};{newWcsTask.S_START_LOC};{newWcsTask.S_END_LOC};0;0;0;1"
|
};
|
LogHelper.Info($"通知AGV更改终点,参数:{paramModel}", "AGV");
|
/*NDCApi.ChangeOrderParam(paramModel);*/
|
}
|
return;
|
}
|
else
|
{
|
LogHelper.Info("异常区没有空货位,无法入库异常区", "AGV");
|
}
|
}
|
|
existAction = WCSHelper.CheckActionRecordExist(wcsTask.S_CODE, 3);
|
if (existAction)
|
{
|
LogHelper.Info($"任务号:{TN_Task.S_CODE},RFID检测通过,AGV任务正常完成", "AGV");
|
//WCS反馈3已取货,则agv任务正常结束 ,通知AGV完成任务
|
ChangeParamModel paramModel = new ChangeParamModel()
|
{
|
task_no = model.No,
|
param_no = 0,
|
param = $"{model.No};{TN_Task.S_START_LOC};{TN_Task.S_END_LOC};0;0;0;1"
|
};
|
LogHelper.Info($"通知AGV完成任务,参数:{paramModel}", "AGV");
|
/*NDCApi.ChangeOrderParam(paramModel);*/
|
}
|
}
|
}
|
}
|
else
|
{
|
//安全请求等
|
TaskProcess.OperateReq(model.No, model.State, model.ForkliftNo, model.ExtData);
|
}
|
|
WCSHelper.AddActionRecord(model.No, model.State, model.ForkliftNo, model.ExtData);
|
}
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Info($"agv回报错误,错误原因:{ex.Message}", "AGV");
|
}
|
}
|
|
/// <summary>
|
/// 创建最后一个任务
|
/// </summary>
|
/// <param name="startLocCode"></param>
|
/// <param name="mst"></param>
|
/// <param name="actType">1.入库 2.出库</param>
|
/// <returns></returns>
|
public static WCSTask createLastTask(string startLocCode , WMSTask mst ,int actType ,string typeName = null)
|
{
|
LogHelper.Info($"作业号:{mst.S_CODE},创建下一段任务", "WMS");
|
var existTask = WCSHelper.GetTaskByStart(startLocCode);
|
if (existTask == null)
|
{
|
var startLoc = LocationHelper.GetLoc(startLocCode);
|
if (startLoc != null)
|
{
|
string cntrCode = "";
|
string scheduleType = "";
|
if (actType == 1)
|
{
|
var locCntrRels = LocationHelper.GetLocCntr(startLocCode);
|
if (locCntrRels.Count > 0)
|
{
|
foreach (var cntr in locCntrRels)
|
{
|
cntrCode = cntrCode + "," + cntr.S_CNTR_CODE;
|
}
|
cntrCode = cntrCode.Substring(1, cntrCode.Length - 1);
|
}
|
scheduleType = "WCS";
|
}
|
|
if (actType == 2)
|
{
|
cntrCode = mst.S_CNTR_CODE;
|
scheduleType = "AGV";
|
}
|
string type = "";
|
if (typeName == null)
|
{
|
type = mst.S_TYPE + "-2";
|
}
|
else
|
{
|
type = typeName;
|
}
|
|
// 创建一段入库任务
|
WCSTask wcsTask = new WCSTask()
|
{
|
S_OP_NAME = mst.S_OP_DEF_NAME,
|
S_OP_CODE = mst.S_CODE,
|
S_CODE = WCSHelper.GenerateTaskNo(),
|
S_CNTR_CODE = cntrCode,
|
S_TYPE = type,
|
S_START_LOC = startLoc.S_CODE,
|
S_START_AREA = startLoc.S_AREA_CODE,
|
S_END_LOC = mst.S_END_LOC,
|
S_END_AREA = mst.S_END_AREA,
|
S_SCHEDULE_TYPE = scheduleType,
|
N_PRIORITY = mst.N_PRIORITY,
|
T_START_TIME = DateTime.Now,
|
};
|
|
if (WCSHelper.CreateTask(wcsTask))
|
{
|
// 起点、接驳点、终点加锁
|
LocationHelper.LockLoc(wcsTask.S_START_LOC, 2);
|
LocationHelper.LockLoc(wcsTask.S_END_LOC, 1);
|
|
WMSHelper.UpdateTaskEnd(mst);
|
return wcsTask;
|
}
|
}
|
}
|
return null;
|
}
|
|
/// <summary>
|
/// 任务分发,根据调度类型发给不同的调度系统
|
/// </summary>
|
internal static void Dispatch() {
|
var db = new SqlHelper<object>().GetInstance();
|
//查询任务
|
//获取所有等待的任务
|
var list = WCSHelper.GetWaitingTaskList();
|
if (list.Count > 0) {
|
foreach (var task in list)
|
{
|
if (!TaskProcess.Intercept(task))
|
{
|
//使用自定义任务推送
|
TaskProcess.SendTask(task);
|
}
|
}
|
}
|
}
|
|
private static readonly object emptyTrayInLock = new object(); // 静态锁对象
|
|
/// <summary>
|
/// agv申请终点
|
/// </summary>
|
/// <param name="taskNo"></param>
|
public static Location AGVApplyEndLoc(string taskNo)
|
{
|
LogHelper.Info($"任务号:{taskNo},AGV等待区申请终点", "AGV");
|
var cst = WCSHelper.GetTask(taskNo);
|
if (cst != null && cst.N_B_STATE < 3)
|
{
|
var mst = WMSHelper.GetWmsTask(cst.S_OP_CODE);
|
if (mst != null && mst.N_B_STATE < 2 && mst.S_END_LOC == "虚拟货位")
|
{
|
var container = ContainerHelper.GetCntr(cst.S_CNTR_CODE);
|
if (container != null)
|
{
|
string itemCode = null;
|
var cntrItemRels = ContainerHelper.GetCntrItemRel(cst.S_CNTR_CODE);
|
if (cntrItemRels.Count > 0)
|
{
|
// 满料托盘入库
|
itemCode = cntrItemRels[0].S_ITEM_CODE;
|
var endLoc = WMSHelper.GetInstockEndLoc(container.N_TYPE, null, 1, itemCode);
|
if (endLoc != null)
|
{
|
Location agvLoc = null;
|
var locCodes = Settings.getAgvJBLocList( endLoc.N_ROADWAY, 1);
|
if (locCodes.Count > 0)
|
{
|
foreach (var locCode in locCodes)
|
{
|
agvLoc = LocationHelper.GetLoc(locCode);
|
if (agvLoc != null && agvLoc.C_ENABLE == "Y")
|
{
|
cst.S_END_LOC = agvLoc.S_CODE;
|
cst.S_END_AREA = agvLoc.S_AREA_CODE;
|
WCSHelper.UpdateTaskEnd(cst);
|
|
mst.S_END_LOC = endLoc.S_CODE;
|
mst.S_END_AREA = endLoc.S_AREA_CODE;
|
WMSHelper.UpdateTaskEnd(mst);
|
LocationHelper.LockLoc(endLoc.S_CODE, 1);
|
|
LogHelper.Info($"任务号:{taskNo},AGV申请的终点:{agvLoc.S_CODE}", "AGV");
|
return agvLoc;
|
}
|
}
|
LogHelper.Info($"任务号:{taskNo},入库接驳位货位都已禁用", "AGV");
|
}
|
else
|
{
|
LogHelper.Info($"任务号:{taskNo},没有配置立库接驳位", "AGV");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"任务号:{taskNo},立库没有满足条件的空货位", "AGV");
|
}
|
}
|
else
|
{
|
// 空托盘回库
|
lock (emptyTrayInLock)
|
{
|
var emptyTrayBuffers = WMSHelper.getEmptyTrayBufferList();
|
if (emptyTrayBuffers.Count > 0)
|
{
|
var emptyTray = emptyTrayBuffers.Where(a => a.TRAY_TYPE == container.N_TYPE).OrderBy(a => a.T_CREATE).FirstOrDefault();
|
if (emptyTray != null)
|
{
|
var endLoc = LocationHelper.GetLoc(emptyTray.END_LOC);
|
cst.S_END_LOC = endLoc.S_CODE;
|
cst.S_END_AREA = endLoc.S_AREA_CODE;
|
WCSHelper.UpdateTaskEnd(cst);
|
|
mst.S_END_LOC = endLoc.S_CODE;
|
mst.S_END_AREA = endLoc.S_AREA_CODE;
|
WMSHelper.UpdateTaskEnd(mst);
|
LocationHelper.LockLoc(endLoc.S_CODE, 1);
|
|
emptyTray.IS_CREATED = "Y";
|
WMSHelper.updateEmptyTrayBuffer(emptyTray);
|
}
|
}
|
else
|
{
|
var endLoc = WMSHelper.GetInstockEndLoc(container.N_TYPE, null, 1);
|
if (endLoc != null)
|
{
|
Location agvLoc = null;
|
var locCodes = Settings.getAgvJBLocList(endLoc.N_ROADWAY, 1);
|
if (locCodes.Count > 0)
|
{
|
foreach (var locCode in locCodes)
|
{
|
agvLoc = LocationHelper.GetLoc(locCode);
|
if (agvLoc != null && agvLoc.C_ENABLE == "Y")
|
{
|
cst.S_END_LOC = agvLoc.S_CODE;
|
cst.S_END_AREA = agvLoc.S_AREA_CODE;
|
WCSHelper.UpdateTaskEnd(cst);
|
|
mst.S_END_LOC = endLoc.S_CODE;
|
mst.S_END_AREA = endLoc.S_AREA_CODE;
|
WMSHelper.UpdateTaskEnd(mst);
|
LocationHelper.LockLoc(endLoc.S_CODE, 1);
|
|
LogHelper.Info($"任务号:{taskNo},AGV申请的终点:{agvLoc.S_CODE}", "AGV");
|
return agvLoc;
|
}
|
}
|
|
LogHelper.Info($"任务号:{taskNo},入库接驳位货位都已禁用", "AGV");
|
}
|
else
|
{
|
LogHelper.Info($"任务号:{taskNo},没有配置立库接驳位", "AGV");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"任务号:{taskNo},立库没有满足条件的空货位", "AGV");
|
}
|
}
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info($"任务号:{taskNo},AGV任务的容器:{cst.S_CNTR_CODE}不存在", "AGV");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"任务号:{taskNo},AGV任务已申请终点,请勿重复申请", "AGV");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"任务号:{taskNo},AGV任务已完成或取消", "AGV");
|
}
|
return null;
|
}
|
|
}
|
}
|