using HH.WCS.Mobox3.SXJK.api;
|
using HH.WCS.Mobox3.SXJK.device;
|
using HH.WCS.Mobox3.SXJK.dispatch;
|
using HH.WCS.Mobox3.SXJK.models;
|
using HH.WCS.Mobox3.SXJK.process;
|
using HH.WCS.Mobox3.SXJK.util;
|
using HH.WCS.Mobox3.SXJK.wms;
|
using Newtonsoft.Json;
|
using NLog.Fluent;
|
using System;
|
using System.Collections;
|
using System.Collections.Generic;
|
using System.Data.Odbc;
|
using System.Linq;
|
using System.Reflection;
|
using System.Reflection.Emit;
|
using System.Text;
|
using System.Threading;
|
using System.Threading.Tasks;
|
using System.Xml.Linq;
|
using static EasyModbus.ModbusServer;
|
using static HH.WCS.Mobox3.SXJK.api.WmsController;
|
using static HH.WCS.Mobox3.SXJK.dispatch.WMSDispatch;
|
using static HH.WCS.Mobox3.SXJK.dispatch.WMSDispatch.TrayRequestInStockData;
|
using static HH.WCS.Mobox3.SXJK.util.Settings;
|
using static HH.WCS.Mobox3.SXJK.wms.WCSHelper;
|
using static System.Runtime.CompilerServices.RuntimeHelpers;
|
|
namespace HH.WCS.Mobox3.SXJK.core
|
{
|
/// <summary>
|
/// 定时轮询任务
|
/// </summary>
|
internal class Monitor
|
{
|
internal static void CheckThirdOutWork() {
|
//第三方读中间表
|
//var db= new SqlHelper<object>().GetInstance("中间表的sql连接字符串");
|
// db.Queryable<object>
|
|
//读到了出库单,插入到我们的表
|
|
|
}
|
|
internal static void CheckOutWork() {
|
//读自己的中间表,我们自己的表有表有个字段计数,计数小于最大值,继续出库,一次生成一条任务
|
|
}
|
|
|
internal static void CheckDevice() {
|
//检测输送线状态
|
|
S7Helper.ReadStr("plc1", 100, 1, 8);
|
S7Helper.ReadBit("plc1", 101, 1, 2);
|
S7Helper.ReadInt("plc1", 102, 1, 6);
|
//1 设备plc的ip deviceNo 自动建立连接
|
//2 设备对应的通讯项和线体类型(输送线入口、输送线出口、提升机的入口。。。。)起始读的偏移地址,写的偏移地址
|
//{ "deviceNo":"5","code":"9001","location":"F1CJ-SSX1-01","writeAddr900":0,"writeAddr905":-1,"writeAddr710":0,"readAddr901":2,"readAddr902":0,"lineType":1},
|
//3 通讯项自动读plc,读到的数据根据lineType做处理,自动创建任务或者更新任务状态(创建一个设备动作或任务动作,如果是任务动作有个线程去读)
|
}
|
|
|
|
/// <summary>
|
/// 监听输送线,入库同步单入库
|
/// </summary>
|
///
|
internal static void MonitorDevice()
|
{
|
var lineDeviceInfos = Settings.lineDeviceInfos.ToList();
|
foreach (var line in lineDeviceInfos)
|
{
|
// 1.查询输送线信息,货位托盘码
|
PipelineSignalInfo pipelineSignalInfo = WCSHelper.readPipelineInfo(line);
|
if (pipelineSignalInfo != null)
|
{
|
// agv任务反馈,取托完成 = 1
|
if (pipelineSignalInfo.agvTaskFeedback == 1 || pipelineSignalInfo.agvTaskFeedback == 2)
|
{
|
// 清除AGV任务反馈
|
S7Helper.WriteInt(line.deviceNo, 101, line.writeAddr + 14, 0);
|
LogHelper.Info("清除输送线【" + line.code + "】的AGV任务反馈", "输送线");
|
}
|
|
// 指令已读,清除指令
|
if (pipelineSignalInfo.receiveInstruction == 2)
|
{
|
issueCommand(line, 0, 0, 0);
|
LogHelper.Info("入库指令已读,清除入库指令", "输送线");
|
}
|
else if (pipelineSignalInfo.receiveInstruction == 3)
|
{
|
issueCommand(line, 0, 0, 0);
|
LogHelper.Info("退回指令已读,清除退回指令", "输送线");
|
}
|
|
// 2.输送线线体光电 = 1 有托盘
|
if ( pipelineSignalInfo.linePhotoelectric == 1 )
|
{
|
// 当前输送线只返回下层托盘码
|
string downTrayCode = pipelineSignalInfo.downTrayCode;
|
if (downTrayCode != null && downTrayCode != "")
|
{
|
// 3.查询任务托盘码
|
string taskTrayCode = downTrayCode;
|
List<string> trayCodes = new List<string>() { downTrayCode };
|
/*string upTrayCode = ContainerHelper.GetUpTrayCode(downTrayCode); // 上层托盘*/
|
string upTrayCode = pipelineSignalInfo.upTrayCode;
|
if (upTrayCode != null && upTrayCode != "")
|
{
|
taskTrayCode = taskTrayCode + "," + upTrayCode;
|
trayCodes.Add(upTrayCode);
|
}
|
|
// 4.查询托盘作业任务
|
WMSTask wmsTask = WMSHelper.GetWmsTaskByCntr(taskTrayCode);
|
|
// 判断 1.线体type = 1(输送线入口接驳线体) 2.线体请求去向 = 1 3.托盘没有执行中的任务
|
if (line.type == 1 && pipelineSignalInfo.requestReadCode == 1 && wmsTask == null)
|
{
|
bool isAllow = true;
|
string asnNo = null; // 预期入库单号
|
string orientSign = null; // 定向标识 定向 JD,非定向是 F
|
|
// 5.查询托盘码是否在入库同步单中
|
List<InStockListChild> inStocks = new List<InStockListChild>();
|
foreach (var tray in trayCodes)
|
{
|
var cntrItemRels = ContainerHelper.GetCntrItemRel(tray);
|
if (cntrItemRels != null && cntrItemRels.Count() > 0)
|
{
|
isAllow = false;
|
LogHelper.Info("托盘码:" + tray + ",托盘已入库使用中", "Mobox");
|
break;
|
}
|
|
var inStockListChilds = WMSHelper.getInstockListChild(tray);
|
if (inStockListChilds == null || inStockListChilds.Count == 0)
|
{
|
// 6.如果不是则调用托盘请求入库接口,查询托盘的物料信息,再进行入库
|
inStockListChilds = getInStockTrayInfo(tray);
|
}
|
|
if (inStockListChilds != null && inStockListChilds.Count > 0)
|
{
|
foreach (var child in inStockListChilds)
|
{
|
|
float weight = pipelineSignalInfo.weight / trayCodes.Count;
|
float furWeight = WMSHelper.getFurWeight(child.LOTATT10); // 毛皮重量
|
child.F_NET_WEIGHT = weight - furWeight;
|
asnNo = child.S_ASN_NO;
|
orientSign = child.LOTATT18;
|
inStocks.Add(child);
|
}
|
}
|
else
|
{
|
isAllow = false;
|
LogHelper.Info("托盘码:" + tray + ",未找到该托盘相关的入库单和请求入库信息", "Mobox");
|
break;
|
}
|
}
|
|
// 判断该托盘满足入库条件
|
if (isAllow)
|
{
|
// 6.创建入库任务
|
Location startLoc = LocationHelper.GetLoc(line.localtion);
|
Location endLoc = new Location() { S_CODE = "虚拟货位", S_AREA_CODE = "虚拟库区" };
|
if (startLoc != null)
|
{
|
wmsTask = new WMSTask()
|
{
|
S_CNTR_CODE = taskTrayCode,
|
S_CODE = WMSHelper.GenerateTaskNo(),
|
S_START_LOC = startLoc.S_CODE,
|
S_START_AREA = startLoc.S_AREA_CODE,
|
S_END_LOC = endLoc.S_CODE,
|
S_END_AREA = endLoc.S_AREA_CODE,
|
S_TYPE = "入库任务",
|
S_OP_DEF_CODE = asnNo,
|
S_OP_DEF_NAME = "入库同步单",
|
T_START_TIME = DateTime.Now,
|
};
|
|
if (WMSHelper.CreateWmsTask(wmsTask))
|
{
|
// 5.创建容器并绑定物料信息
|
foreach (var order in inStocks)
|
{
|
BindCntrItemRel(order);
|
}
|
LogHelper.Info("开始下发输送线指令,作业任务号:" + wmsTask.S_CODE + ",目标地址:" + line.descLine + ",指令入库 = 2", "输送线");
|
issueCommand(line, int.Parse(wmsTask.S_CODE.Substring(7)), (short)line.descLine, 2);
|
LogHelper.Info("开始下发输送线指令成功", "输送线");
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info("托盘入库条件不满足,开始下发输送线退回指令", "输送线");
|
issueCommand(line, 0, (short)line.descLine, 3);
|
LogHelper.Info("托盘入库条件不满足,下发输送线退回指令成功", "输送线");
|
}
|
}
|
|
// 判断 1.线体type = 2(输送线出口接驳线体) 2.存在该托盘的作业任务且状态为等待
|
if (line.type == 2 && wmsTask != null && wmsTask.N_B_STATE == 0 && wmsTask.S_TYPE == "入库任务")
|
{
|
var cntrItemRel = ContainerHelper.GetCntrItemRel(trayCodes[0]).FirstOrDefault();
|
if (cntrItemRel != null)
|
{
|
string asnNo = cntrItemRel.S_ASN_NO;
|
string orientSign = cntrItemRel.LOTATT18;
|
Location endLoc = WMSHelper.getEndLocation(orientSign, asnNo, 2); //trayCodes.Count()
|
if (endLoc != null)
|
{
|
WCSTask wcsTask = new WCSTask
|
{
|
S_OP_CODE = wmsTask.S_CODE,
|
S_OP_NAME = wmsTask.S_OP_DEF_NAME,
|
S_CODE = WCSHelper.GenerateTaskNo(),
|
S_TYPE = wmsTask.S_TYPE,
|
S_START_LOC = wmsTask.S_START_LOC,
|
S_START_AREA = wmsTask.S_START_AREA,
|
S_END_LOC = endLoc.S_CODE,
|
S_END_AREA = endLoc.S_AREA_CODE,
|
S_CNTR_CODE = taskTrayCode,
|
N_CNTR_COUNT = trayCodes.Count,
|
S_SCHEDULE_TYPE = "国自",
|
T_START_TIME = DateTime.Now,
|
};
|
if (WCSHelper.CreateTask(wcsTask))
|
{
|
// 对终点货位进行加锁
|
LocationHelper.LockLoc(wcsTask.S_END_LOC, 1, asnNo);
|
LocationHelper.LockLoc(wcsTask.S_START_LOC, 2, asnNo);
|
|
ContainerHelper.deleteTrayRelation(downTrayCode);
|
|
wmsTask.N_B_STATE = 1;
|
wmsTask.S_END_LOC = endLoc.S_CODE;
|
wmsTask.S_END_AREA = endLoc.S_AREA_CODE;
|
WMSHelper.UpdateTaskEnd(wmsTask);
|
}
|
}
|
else
|
{
|
LogHelper.Info("未找到入库任务:" + wmsTask.S_CODE + "的终点货位", "Mobox");
|
}
|
}
|
else
|
{
|
LogHelper.Info("未找到该任务:" + wmsTask.S_CODE + "的容器货品信息", "Mobox");
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
/// <summary>
|
/// 清除输送线命令
|
/// </summary>
|
/// <param name="line"></param>
|
/// <param name="taskId"></param>
|
/// <param name="descLine"></param>
|
/// <param name="command"></param>
|
public static void issueCommand(LineDeviceInfo line, int taskId, short descLine, short command)
|
{
|
S7Helper.WriteDint(line.deviceNo, 101, line.writeAddr + 2, taskId); // 任务号
|
S7Helper.WriteInt(line.deviceNo, 101, line.writeAddr + 6, descLine); // 目标线体
|
S7Helper.WriteInt(line.deviceNo, 101, line.writeAddr + 8, command); // 下发指令(默认=0 入库=2 出库=1 不合格退回=3)
|
}
|
|
public static List<InStockListChild> getInStockTrayInfo(string trayCode)
|
{
|
List<RequestData> requestDatas = new List<RequestData>();
|
RequestData requestData = new RequestData()
|
{
|
organizationId = Settings.orgInfo.organizationId,
|
warehouseId = Settings.orgInfo.warehouseId,
|
customerId = Settings.orgInfo.customerId,
|
traceId = trayCode,
|
};
|
requestDatas.Add(requestData);
|
WMSTrayRequestResponse response = WMSDispatch.TrayRequestInStock(requestDatas);
|
if (response != null)
|
{
|
List<InStockListChild> inStockListChildren = new List<InStockListChild>();
|
foreach (var item in response.IT_DATA)
|
{
|
InStockListChild inStockListChild = new InStockListChild()
|
{
|
S_SKU = item.sku,
|
S_SKU_DESCR = item.skuDescr,
|
N_QTY = float.Parse(item.qty),
|
S_TRACE_ID = item.traceId,
|
S_SERIAL_NO = item.serialNo,
|
LOTATT01 = item.lotAtt01,
|
LOTATT02 = item.lotAtt02,
|
LOTATT03 = item.lotAtt03,
|
LOTATT04 = item.lotAtt04,
|
LOTATT05 = item.lotAtt05,
|
LOTATT06 = item.lotAtt06,
|
LOTATT07 = item.lotAtt07,
|
LOTATT08 = item.lotAtt08,
|
LOTATT09 = item.lotAtt09,
|
LOTATT10 = item.lotAtt10,
|
LOTATT11 = item.lotAtt11,
|
LOTATT12 = item.lotAtt12,
|
LOTATT13 = item.lotAtt13,
|
LOTATT14 = item.lotAtt14,
|
LOTATT15 = item.lotAtt15,
|
LOTATT16 = item.lotAtt16,
|
LOTATT17 = item.lotAtt17,
|
LOTATT18 = item.lotAtt18,
|
LOTATT19 = item.lotAtt19,
|
LOTATT20 = item.lotAtt20,
|
LOTATT21 = item.lotAtt21,
|
LOTATT22 = item.lotAtt22,
|
LOTATT23 = item.lotAtt23,
|
LOTATT24 = item.lotAtt24,
|
|
};
|
inStockListChildren.Add(inStockListChild);
|
};
|
return inStockListChildren;
|
}
|
return null;
|
}
|
|
public static bool BindCntrItemRel(InStockListChild inStockListChild) {
|
bool result = false;
|
try
|
{
|
CntrItemRel cntrItemRel = new CntrItemRel()
|
{
|
S_ITEM_CODE = inStockListChild.S_SKU,
|
S_ITEM_NAME = inStockListChild.S_SKU_DESCR,
|
F_QTY = inStockListChild.N_QTY,
|
S_CNTR_CODE = inStockListChild.S_TRACE_ID,
|
S_SERIAL_NO = inStockListChild.S_SERIAL_NO,
|
F_GROSS_WEIGHT = inStockListChild.S_CONTAINER_WEIGHT,
|
F_NET_WEIGHT = inStockListChild.F_NET_WEIGHT,
|
S_ASN_NO = inStockListChild.S_ASN_NO,
|
T_INBOUND_TIME = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
|
LOTATT01 = inStockListChild.LOTATT01,
|
LOTATT02 = inStockListChild.LOTATT02,
|
LOTATT03 = inStockListChild.LOTATT03 == null ? DateTime.Now.ToString("yyyy-MM-dd") : inStockListChild.LOTATT03,
|
LOTATT04 = inStockListChild.LOTATT04,
|
LOTATT05 = inStockListChild.LOTATT05,
|
LOTATT06 = inStockListChild.LOTATT06,
|
LOTATT07 = inStockListChild.LOTATT07,
|
LOTATT08 = inStockListChild.LOTATT08,
|
LOTATT09 = inStockListChild.LOTATT09,
|
LOTATT10 = inStockListChild.LOTATT10,
|
LOTATT11 = inStockListChild.LOTATT11,
|
LOTATT12 = inStockListChild.LOTATT12,
|
LOTATT13 = inStockListChild.LOTATT13,
|
LOTATT14 = inStockListChild.LOTATT14,
|
LOTATT15 = inStockListChild.LOTATT15,
|
LOTATT16 = inStockListChild.LOTATT16,
|
LOTATT17 = inStockListChild.LOTATT17,
|
LOTATT18 = inStockListChild.LOTATT18,
|
LOTATT19 = inStockListChild.LOTATT19,
|
LOTATT20 = inStockListChild.LOTATT20,
|
LOTATT21 = inStockListChild.LOTATT21,
|
LOTATT22 = inStockListChild.LOTATT22,
|
LOTATT23 = inStockListChild.LOTATT23,
|
LOTATT24 = inStockListChild.LOTATT24
|
};
|
result = ContainerHelper.BindCntrItemSingle(inStockListChild.S_TRACE_ID, cntrItemRel);
|
}
|
catch (Exception ex) {
|
LogHelper.Info("绑定容器物料信息失败,错误信息:"+ex.Message, "WMS");
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 监听出库同步单
|
/// </summary>
|
internal static void Monitor0utStockOrder()
|
{
|
LogHelper.Info("1", "Mobox");
|
// 开关控制
|
var formControlSwitch = WCSHelper.GetFormControlSwitch("CKBD");
|
if (formControlSwitch != null && formControlSwitch.S_B_STATUS == "是")
|
{
|
LogHelper.Info("2", "Mobox");
|
// 集货区
|
var areaList = LocationHelper.GetAreaByCode(Settings.WHCode, 7);
|
if (areaList != null)
|
{
|
string endAreaCode = areaList[0].S_CODE;
|
LogHelper.Info("3", "Mobox");
|
// 1.查询是否有新建的出库同步单
|
List<OutStockList> outStockLists = WMSHelper.getOutstockListByStatus("执行");
|
foreach (var item in outStockLists)
|
{
|
LogHelper.Info($"4.执行的出库单号:{item.S_ORDER_NO}", "Mobox");
|
// 2.有则根据同步单列表进行出库
|
List<OutStockListChild> outStockListChilds = WMSHelper.getOutstockListChilds(item.S_ORDER_NO);
|
foreach (var child in outStockListChilds)
|
{
|
if (child.PRE_COMPLETED_QTY < child.N_QTY)
|
{
|
string asnNo = "";
|
|
// 查询开始货位
|
LogHelper.Info("查询开始货位", "Mobox");
|
Location startLoc = WMSHelper.getStartLoc(child);
|
LogHelper.Info("开始货位:"+ JsonConvert.SerializeObject(startLoc), "Mobox");
|
if (startLoc != null)
|
{
|
// 1.开始货位排是否有锁,有锁暂时不生成任务
|
if (LocationHelper.isLocRowLock(startLoc))
|
{
|
LogHelper.Info(" 开始货位或终点货位排有锁,暂时不生成任务;开始货位:" + startLoc.S_CODE + ",ORDER_NO :" + child.S_ORDER_NO, "Mobox");
|
continue;
|
};
|
|
List<LocCntrRel> locCntrs = LocationHelper.GetLocCntr(startLoc.S_CODE);
|
|
// 查询任务容器编码
|
string taskTrayCode = "";
|
if (locCntrs.Count > 0)
|
{
|
for (int i = 0; i < locCntrs.Count; i++)
|
{
|
var cntrItemRels = ContainerHelper.GetCntrItemRel(locCntrs[i].S_CNTR_CODE);
|
if (cntrItemRels.Count > 0)
|
{
|
asnNo = cntrItemRels[0].S_ASN_NO;
|
if (i == 0)
|
{
|
taskTrayCode = locCntrs[i].S_CNTR_CODE;
|
}
|
else
|
{
|
taskTrayCode = taskTrayCode + "," + locCntrs[i].S_CNTR_CODE;
|
}
|
}
|
}
|
// 查询集货区货位
|
Location endLoc = WMSHelper.getEndLocation(child.LOTATT18, asnNo, locCntrs.Count(), endAreaCode);
|
|
if (endLoc != null)
|
{
|
var wmsTask = new WMSTask()
|
{
|
S_CNTR_CODE = taskTrayCode,
|
S_CODE = WMSHelper.GenerateTaskNo(),
|
S_START_LOC = startLoc.S_CODE,
|
S_START_AREA = startLoc.S_AREA_CODE,
|
S_END_LOC = endLoc.S_CODE,
|
S_END_AREA = endLoc.S_AREA_CODE,
|
S_TYPE = "出库任务",
|
S_OP_DEF_CODE = child.S_ORDER_NO,
|
S_OP_DEF_NAME = "出库同步单",
|
T_START_TIME = DateTime.Now,
|
};
|
|
if (WMSHelper.CreateWmsTask(wmsTask))
|
{
|
WCSTask wcsTask = new WCSTask
|
{
|
S_OP_CODE = wmsTask.S_CODE,
|
S_OP_NAME = wmsTask.S_OP_DEF_NAME,
|
S_CODE = WCSHelper.GenerateTaskNo(),
|
S_TYPE = wmsTask.S_TYPE,
|
S_START_LOC = startLoc.S_CODE,
|
S_START_AREA = startLoc.S_AREA_CODE,
|
S_END_LOC = endLoc.S_CODE,
|
S_END_AREA = endLoc.S_AREA_CODE,
|
S_CNTR_CODE = taskTrayCode,
|
N_CNTR_COUNT = locCntrs.Count,
|
S_SCHEDULE_TYPE = "国自",
|
T_START_TIME = DateTime.Now,
|
S_DATA = child.S_SEQ_NO,
|
};
|
if (WCSHelper.CreateTask(wcsTask))
|
{
|
// 对终点货位进行加锁
|
LocationHelper.LockLoc(startLoc.S_CODE, 2);
|
LocationHelper.LockLoc(endLoc.S_CODE, 1);
|
|
wmsTask.N_B_STATE = 1;
|
WMSHelper.UpdateTaskState(wmsTask);
|
|
|
// 更新预出库数量
|
float qty = 0;
|
for (int i = 0; i < locCntrs.Count; i++)
|
{
|
var cntrItemRels = ContainerHelper.GetCntrItemRel(locCntrs[i].S_CNTR_CODE);
|
foreach (var cntrItemRel in cntrItemRels)
|
{
|
qty += cntrItemRel.F_QTY;
|
}
|
}
|
child.PRE_COMPLETED_QTY = child.PRE_COMPLETED_QTY + qty;
|
WMSHelper.updateOutStockListChild(child);
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info("出库单:" + JsonConvert.SerializeObject(child) + " 没有满足条件的终点货位","Mobox");
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info("出库单:" + JsonConvert.SerializeObject(child) + " 没有满足条件的开始货位", "Mobox");
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
/// <summary>
|
/// agv 自动移库
|
/// 用途:用于取货过程中,前方有货位阻塞,进行的自动移库
|
/// </summary>
|
/// <param name="shiftLoc"></param>
|
/// <param name="endLoc"></param>
|
/// <param name="opName"></param>
|
/// <param name="opCode"></param>
|
public static void agvAutoShiftStock(string opCode, string opName ,Location shiftLoc , Location endLoc = null) {
|
string shiftCntr = "";
|
List<LocCntrRel> locCntrRels = LocationHelper.GetLocCntr(shiftLoc.S_CODE);
|
|
if (locCntrRels != null && locCntrRels.Count > 0) {
|
for (int i = 0; i < locCntrRels.Count; i++)
|
{
|
if (i == 0)
|
{
|
shiftCntr = locCntrRels[0].S_CNTR_CODE;
|
}
|
else
|
{
|
shiftCntr = shiftCntr + "," + locCntrRels[i].S_CNTR_CODE;
|
}
|
}
|
|
var wcsTask = WCSHelper.GetTaskByCntrNo(shiftCntr);
|
if (wcsTask == null)
|
{
|
var cntrItemRels = ContainerHelper.GetCntrItemRel(locCntrRels[0].S_CNTR_CODE);
|
Location shiftEndLoc = null;
|
if (endLoc != null)
|
{
|
shiftEndLoc = endLoc;
|
}
|
else
|
{
|
string araCode = null;
|
var area = LocationHelper.getArea(shiftLoc.S_AREA_CODE);
|
if (area.N_TYPE != 1) {
|
araCode = area.S_CODE;
|
}
|
shiftEndLoc = WMSHelper.getEndLocation(cntrItemRels[0].LOTATT18, cntrItemRels[0].S_ASN_NO, locCntrRels.Count(), araCode ,shiftLoc.N_ROW);
|
}
|
|
if (shiftEndLoc != null)
|
{
|
wcsTask = new WCSTask
|
{
|
S_OP_CODE = opCode,
|
S_OP_NAME = opName,
|
S_CODE = WCSHelper.GenerateTaskNo(),
|
S_TYPE = "移库任务",
|
S_START_LOC = shiftLoc.S_CODE,
|
S_START_AREA = shiftLoc.S_AREA_CODE,
|
S_END_LOC = shiftEndLoc.S_CODE,
|
S_END_AREA = shiftEndLoc.S_AREA_CODE,
|
S_CNTR_CODE = shiftCntr,
|
N_CNTR_COUNT = 1,
|
S_SCHEDULE_TYPE = "国自",
|
T_START_TIME = DateTime.Now,
|
};
|
if (WCSHelper.CreateTask(wcsTask))
|
{
|
// 对终点货位进行加锁
|
LocationHelper.LockLoc(shiftLoc.S_CODE, 2);
|
LocationHelper.LockLoc(shiftEndLoc.S_CODE, 1);
|
|
var wmsTask = WMSHelper.GetWmsTask(opCode);
|
wmsTask.N_B_STATE = 1;
|
WMSHelper.UpdateTaskState(wmsTask);
|
}
|
}
|
else
|
{
|
LogHelper.Info("AGV自动移库失败,未获取到移库终点", "Mobox");
|
}
|
}
|
}
|
}
|
|
/// <summary>
|
/// 监听移库同步单
|
/// </summary>
|
internal static void MonitorShiftStockOrder()
|
{
|
// 1.查询是否有新建的移库同步单
|
List<ShiftStockList> shiftStockLists = WMSHelper.getShiftstockListByStatus("执行");
|
foreach (var shiftStockList in shiftStockLists)
|
{
|
var shiftStockListChilds = WMSHelper.getShiftstockListChilds(shiftStockList.S_MDOC_NO);
|
foreach (var child in shiftStockListChilds)
|
{
|
string taskTrayCode = "";
|
var locCntr = LocationHelper.GetLocCntrRelByCntr(child.S_TRACE_ID);
|
if (locCntr != null)
|
{
|
List<LocCntrRel> locCntrRels = LocationHelper.GetLocCntr(locCntr.S_LOC_CODE);
|
if (locCntrRels != null && locCntrRels.Count > 0)
|
{
|
for (int i = 0; i < locCntrRels.Count; i++)
|
{
|
if (i == 0)
|
{
|
taskTrayCode = locCntrRels[0].S_CNTR_CODE;
|
}
|
else
|
{
|
taskTrayCode = taskTrayCode + "," + locCntrRels[i].S_CNTR_CODE;
|
}
|
}
|
}
|
var wmsTask = WMSHelper.GetWmsTaskByCntr(taskTrayCode);
|
if (wmsTask == null)
|
{
|
Location startLoc = LocationHelper.GetLoc(locCntr.S_LOC_CODE);
|
/*var fullerList = LocationHelper.getFullerByFullerCode(child.S_TO_LOCATION);*/
|
Location endLoc = LocationHelper.getShiftEndLoc(child.S_TO_LOCATION, locCntrRels.Count);
|
|
if (startLoc != null && endLoc != null )
|
{
|
// 1.开始货位\终点货位排是否有锁,有锁暂时不生成任务
|
if (LocationHelper.isLocRowLock(startLoc) || LocationHelper.isLocRowLock(endLoc))
|
{
|
LogHelper.Info(" 开始货位或终点货位排有锁,暂时不生成任务;开始货位:" + startLoc.S_CODE + ",终点货位:" + endLoc.S_CODE + ",MDOC_NO:" + child.S_MDOC_NO, "Mobox");
|
continue;
|
};
|
|
wmsTask = new WMSTask()
|
{
|
S_CNTR_CODE = taskTrayCode,
|
S_CODE = WMSHelper.GenerateTaskNo(),
|
S_START_LOC = startLoc.S_CODE,
|
S_START_AREA = startLoc.S_AREA_CODE,
|
S_END_LOC = endLoc.S_CODE,
|
S_END_AREA = endLoc.S_AREA_CODE,
|
S_TYPE = "移库任务",
|
S_OP_DEF_CODE = child.S_MDOC_NO,
|
S_OP_DEF_NAME = "移库同步单",
|
T_START_TIME = DateTime.Now,
|
};
|
|
if (WMSHelper.CreateWmsTask(wmsTask))
|
{
|
WCSTask wcsTask = new WCSTask
|
{
|
S_OP_CODE = wmsTask.S_CODE,
|
S_OP_NAME = wmsTask.S_OP_DEF_NAME,
|
S_CODE = WCSHelper.GenerateTaskNo(),
|
S_TYPE = wmsTask.S_TYPE,
|
S_START_LOC = startLoc.S_CODE,
|
S_START_AREA = startLoc.S_AREA_CODE,
|
S_END_LOC = endLoc.S_CODE,
|
S_END_AREA = endLoc.S_AREA_CODE,
|
S_CNTR_CODE = taskTrayCode,
|
N_CNTR_COUNT = locCntrRels.Count,
|
S_SCHEDULE_TYPE = "国自",
|
T_START_TIME = DateTime.Now,
|
};
|
if (WCSHelper.CreateTask(wcsTask))
|
{
|
// 对终点货位进行加锁
|
LocationHelper.LockLoc(startLoc.S_CODE, 2);
|
LocationHelper.LockLoc(endLoc.S_CODE, 1);
|
|
wmsTask.N_B_STATE = 1;
|
WMSHelper.UpdateTaskState(wmsTask);
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
/// <summary>
|
/// 创建有抽检任务
|
/// </summary>
|
/// <param name="startLocCode"></param>
|
/// <param name="orientSign"></param>
|
/// <param name="asnNo"></param>
|
/// <param name="taskTrayCode"></param>
|
public static void createCheckTask(string startLocCode, string orientSign, string asnNo, string taskTrayCode)
|
{
|
LogHelper.Info("开始创建抽检任务,参数:startLocCode="+ startLocCode+ ",orientSign="+ orientSign+ ",asnNo="+ asnNo+ ",taskTrayCode="+ taskTrayCode, "Mobox");
|
Location startLoc = LocationHelper.GetLoc(startLocCode);
|
var area = LocationHelper.GetAreaByCode(Settings.WHCode, 3);
|
var endLoc = WMSHelper.getEndLocation(orientSign, asnNo, 1, area[0].S_CODE);
|
var locCntrRel = LocationHelper.GetLocCntrRelByCntr(taskTrayCode);
|
if (endLoc != null && startLoc != null && startLoc.N_LOCK_STATE == 0)
|
{
|
var wmsTask = new WMSTask()
|
{
|
S_CNTR_CODE = taskTrayCode,
|
S_CODE = WMSHelper.GenerateTaskNo(),
|
S_START_LOC = startLoc.S_CODE,
|
S_START_AREA = startLoc.S_AREA_CODE,
|
S_END_LOC = endLoc.S_CODE,
|
S_END_AREA = endLoc.S_AREA_CODE,
|
S_TYPE = "抽检任务",
|
S_OP_DEF_CODE = asnNo,
|
S_OP_DEF_NAME = "入库抽检任务",
|
T_START_TIME = DateTime.Now,
|
};
|
|
if (WMSHelper.CreateWmsTask(wmsTask))
|
{
|
var wcsTask = new WCSTask
|
{
|
S_OP_CODE = wmsTask.S_CODE,
|
S_OP_NAME = wmsTask.S_OP_DEF_NAME,
|
S_CODE = WCSHelper.GenerateTaskNo(),
|
S_TYPE = wmsTask.S_TYPE,
|
S_START_LOC = startLoc.S_CODE,
|
S_START_AREA = startLoc.S_AREA_CODE,
|
S_END_LOC = endLoc.S_CODE,
|
S_END_AREA = endLoc.S_AREA_CODE,
|
S_CNTR_CODE = taskTrayCode,
|
N_CNTR_COUNT = 1,
|
S_SCHEDULE_TYPE = "国自",
|
T_START_TIME = DateTime.Now,
|
};
|
if (WCSHelper.CreateTask(wcsTask))
|
{
|
// 对终点货位进行加锁
|
LocationHelper.LockLoc(startLoc.S_CODE, 2);
|
LocationHelper.LockLoc(endLoc.S_CODE, 1);
|
|
wmsTask.N_B_STATE = 1;
|
WMSHelper.UpdateTaskState(wmsTask);
|
LogHelper.Info("创建抽检任务成功", "Mobox");
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info("抽检区没有空余货位", "入库同步单");
|
}
|
}
|
|
/// <summary>
|
/// 监听待出库的抽检单,并进行出库
|
/// </summary>
|
internal static void MonitorOutStockSpotCheckOrder()
|
{
|
// 1.查询需要抽检的容器,并进行出库到抽检区
|
var outStockSpotCheckList = WMSHelper.GetShopCheckListByStatus("待出库");
|
if (outStockSpotCheckList != null && outStockSpotCheckList.Count() > 0) {
|
foreach (var item in outStockSpotCheckList)
|
{
|
var wmsTask = WMSHelper.GetWmsTaskByAsnNo(item.S_ASN_NO);
|
if (wmsTask == null) {
|
createCheckTask(item.S_LOC_CODE, null, item.S_ASN_NO, item.S_TRACE_ID);
|
}
|
}
|
}
|
}
|
|
/// <summary>
|
/// 监听已检验的抽检单,并进行回库
|
/// </summary>
|
internal static void MonitorInspectedSpotCheckOrder()
|
{
|
// 2.查询已检验的抽检单
|
var asnNoList = WMSHelper.getFinishSpotCheckList();
|
if (asnNoList != null && asnNoList.Count > 0)
|
{
|
foreach (var asnNo in asnNoList)
|
{
|
WMSTask wmsTask = WMSHelper.GetWmsTaskByAsnNo(asnNo);
|
if (wmsTask == null)
|
{
|
var spotCheckList = WMSHelper.GetShopCheckListByAsnNo(asnNo);
|
foreach (var item in spotCheckList)
|
{
|
// 质量状态为 N 合格,进行入库,为 Y 不合格,入库不合格区
|
if (item.S_QUALITY_STATUS == "Y")
|
{
|
// 更改同批次的入库货物质量状态
|
WMSHelper.updateCntrItemStatusByAsnNO(item.S_ASN_NO, item.S_QUALITY_STATUS);
|
}
|
}
|
|
foreach (var item in spotCheckList)
|
{
|
if (item.N_STATUS == 3)
|
{
|
var locCntrRel = LocationHelper.GetLocCntrRelByCntr(item.S_TRACE_ID);
|
if (locCntrRel != null)
|
{
|
var startLoc = LocationHelper.GetLoc(locCntrRel.S_LOC_CODE);
|
var endLoc = LocationHelper.GetLoc(item.S_LOC_CODE);
|
if (endLoc.N_LOCK_STATE == 0 && endLoc.N_CURRENT_NUM < endLoc.N_CAPACITY)
|
{
|
LogHelper.Info("创建抽检品回库任务", "Mobox");
|
wmsTask = WMSHelper.GetWmsTaskByAsnNo(item.S_ASN_NO);
|
if (wmsTask == null)
|
{
|
wmsTask = new WMSTask()
|
{
|
S_CNTR_CODE = item.S_TRACE_ID,
|
S_CODE = WMSHelper.GenerateTaskNo(),
|
S_START_LOC = startLoc.S_CODE,
|
S_START_AREA = startLoc.S_AREA_CODE,
|
S_END_LOC = endLoc.S_CODE,
|
S_END_AREA = endLoc.S_AREA_CODE,
|
S_TYPE = "移库任务",
|
S_OP_DEF_CODE = asnNo,
|
S_OP_DEF_NAME = "创建抽检品回库任务",
|
T_START_TIME = DateTime.Now,
|
};
|
|
if (WMSHelper.CreateWmsTask(wmsTask))
|
{
|
agvAutoShiftStock(wmsTask.S_CODE, wmsTask.S_OP_DEF_NAME, startLoc, endLoc);
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
/// <summary>
|
/// 扫描库区内的不合格物料,将其移到不合格区
|
/// </summary>
|
internal static void scanAreaUnacceptedProduct()
|
{
|
// 不合格区
|
var areaCodes = LocationHelper.GetAreaByCode(Settings.WHCode, 5);
|
if (areaCodes == null) {
|
return;
|
}
|
string areaCode = areaCodes[0].S_CODE;
|
|
// 查询抽检区完成回库的批次列表(抽检区整个批次全部回库后,才触发库区不合格品移库)
|
var spotCheckList = WMSHelper.getBackStockSpotCheckList();
|
var locList = WMSHelper.getUnacceptedLocList();
|
if (locList != null && locList.Count > 0)
|
{
|
foreach (var item in locList)
|
{
|
string asnNo = "";
|
string taskTrayCode = "";
|
string lotatt18 = null;
|
|
// 查询开始货位
|
Location startLoc = item;
|
List<LocCntrRel> locCntrs = LocationHelper.GetLocCntr(startLoc.S_CODE);
|
if (locCntrs == null || locCntrs.Count() == 0) {
|
continue;
|
}
|
for (int i = 0; i < locCntrs.Count; i++)
|
{
|
var cntrItemRels = ContainerHelper.GetCntrItemRel(locCntrs[i].S_CNTR_CODE);
|
asnNo = cntrItemRels[0].S_ASN_NO;
|
lotatt18 = cntrItemRels[0].LOTATT18;
|
if (i == 0)
|
{
|
taskTrayCode = locCntrs[i].S_CNTR_CODE;
|
}
|
else
|
{
|
taskTrayCode = taskTrayCode + "," + locCntrs[i].S_CNTR_CODE;
|
}
|
}
|
|
if (spotCheckList.Contains(asnNo))
|
{
|
var locCntrRel = LocationHelper.GetLocCntr(item.S_CODE);
|
Location endLoc = WMSHelper.getEndLocation(lotatt18, asnNo, locCntrs.Count(), areaCode);
|
|
if (startLoc != null && endLoc != null)
|
{
|
// 1.开始货位排是否有锁,有锁暂时不生成任务
|
if (LocationHelper.isLocRowLock(startLoc))
|
{
|
LogHelper.Info(" 开始货位排有锁,暂时不生成任务;开始货位:" + startLoc.S_CODE + ", asnNo:" + asnNo, "Mobox");
|
continue;
|
};
|
|
var wmsTask = WMSHelper.GetWmsTaskByCntr(taskTrayCode);
|
if (wmsTask == null)
|
{
|
LogHelper.Info("库区不合格品移库不合格区", "Mobox");
|
wmsTask = new WMSTask()
|
{
|
S_CNTR_CODE = taskTrayCode,
|
S_CODE = WMSHelper.GenerateTaskNo(),
|
S_START_LOC = startLoc.S_CODE,
|
S_START_AREA = startLoc.S_AREA_CODE,
|
S_END_LOC = endLoc.S_CODE,
|
S_END_AREA = endLoc.S_AREA_CODE,
|
S_TYPE = "移库任务",
|
S_OP_DEF_CODE = asnNo,
|
S_OP_DEF_NAME = "库区不合格品移库不合格区",
|
T_START_TIME = DateTime.Now,
|
};
|
|
if (WMSHelper.CreateWmsTask(wmsTask))
|
{
|
var wcsTask = WCSHelper.GetTaskByStart(startLoc.S_CODE);
|
if (wcsTask == null)
|
{
|
// agv 自动移库
|
LogHelper.Info("扫描库区内的不合格物料,移库到不合格区", "Mobox");
|
agvAutoShiftStock(wmsTask.S_CODE, wmsTask.S_OP_DEF_NAME, startLoc, endLoc);
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
public static Dictionary<List<ReceiveGoodsFeedbackData.FeedbackData>, int> keyValuePairs1 = new Dictionary<List<ReceiveGoodsFeedbackData.FeedbackData>, int>();
|
public static Dictionary<List<ShipmentsTrayFeedbackData.FeedbackData>, int> keyValuePairs2 = new Dictionary<List<ShipmentsTrayFeedbackData.FeedbackData>, int>();
|
public static Dictionary<List<ShiftingStockOrderFeedbackData.FeedbackData>, int> keyValuePairs3 = new Dictionary<List<ShiftingStockOrderFeedbackData.FeedbackData>, int>();
|
|
/// <summary>
|
/// 对反馈上游失败的数据,进行重复反馈
|
/// </summary>
|
public static void feedbackUpstreamSystem()
|
{
|
// 1.物料入库反馈
|
var inStockFeedbackDatas = WCSCore.inStockFeedbackDatas;
|
if (inStockFeedbackDatas.Count > 0) {
|
for (int i = 0; i < inStockFeedbackDatas.Count; i++)
|
{
|
var feedbackResult = WMSDispatch.ReceiveGoodsFeedback(inStockFeedbackDatas[i]);
|
if (feedbackResult)
|
{
|
WCSCore.inStockFeedbackDatas.Remove(inStockFeedbackDatas[i]);
|
}
|
else
|
{
|
keyValuePairs1.TryGetValue(inStockFeedbackDatas[i], out int num);
|
keyValuePairs1[inStockFeedbackDatas[i]] = num + 1;
|
if (num > 3) {
|
WCSCore.inStockFeedbackDatas.Remove(inStockFeedbackDatas[i]);
|
}
|
}
|
}
|
}
|
|
// 2.物料出库反馈
|
var outStockFeedbackDatas = WCSCore.outStockFeedbackDatas;
|
if (outStockFeedbackDatas.Count > 0)
|
{
|
for (int i = 0; i < outStockFeedbackDatas.Count; i++)
|
{
|
var feedbackResult = WMSDispatch.ShipmentsTrayFeedback(outStockFeedbackDatas[i]);
|
if (feedbackResult)
|
{
|
WCSCore.outStockFeedbackDatas.Remove(outStockFeedbackDatas[i]);
|
}
|
else
|
{
|
keyValuePairs2.TryGetValue(outStockFeedbackDatas[i], out int num);
|
keyValuePairs2[outStockFeedbackDatas[i]] = num + 1;
|
if (num > 3)
|
{
|
WCSCore.outStockFeedbackDatas.Remove(outStockFeedbackDatas[i]);
|
}
|
}
|
}
|
}
|
|
// 3.物料移库反馈
|
var shiftFeedbackDatas = WCSCore.shiftFeedbackDatas;
|
if (shiftFeedbackDatas.Count > 0)
|
{
|
for (int i = 0; i < shiftFeedbackDatas.Count; i++)
|
{
|
var feedbackResult = WMSDispatch.ShiftingStockOrderFeedback(shiftFeedbackDatas[i]);
|
if (feedbackResult)
|
{
|
WCSCore.shiftFeedbackDatas.Remove(shiftFeedbackDatas[i]);
|
}
|
else
|
{
|
keyValuePairs3.TryGetValue(shiftFeedbackDatas[i], out int num);
|
keyValuePairs3[shiftFeedbackDatas[i]] = num + 1;
|
if (num > 3)
|
{
|
WCSCore.shiftFeedbackDatas.Remove(shiftFeedbackDatas[i]);
|
}
|
}
|
}
|
}
|
}
|
|
// 每十分钟对未连接的pic,尝试进行重新连接
|
public static void PlcAgainLink()
|
{
|
foreach (var item in S7Helper.plcDic)
|
{
|
S7Helper.Link(item.Value);
|
}
|
}
|
|
}
|
}
|