using HH.WCS.Mobox3.WeiLi.api; using HH.WCS.Mobox3.WeiLi.core; using HH.WCS.Mobox3.WeiLi.dispatch; using HH.WCS.Mobox3.WeiLi.models; using HH.WCS.Mobox3.WeiLi.util; using HH.WCS.Mobox3.WeiLi.wms; using Newtonsoft.Json; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Security.Cryptography; using System.Text; using static HH.WCS.Mobox3.WeiLi.api.OtherModel; namespace HH.WCS.Mobox3.WeiLi.process { internal class TaskProcess { private static HttpHelper httpHelper = new HttpHelper(); #region 任务相关 //--------------------------------------------------任务相关-------------------------------------------------- /// /// 取货卸货完成,缓存位状态更新 /// /// /// internal static void CacheBitUpdate(WCSTask mst, bool load) { var trayCarryCount = mst.N_CNTR_COUNT > 0 ? mst.N_CNTR_COUNT : 1; if (load) { Console.WriteLine($"任务{mst.S_CODE} 货位{mst.S_START_LOC}取货完成,起点解绑容器{mst.S_CNTR_CODE}"); LogHelper.Info($"任务{mst.S_CODE} 货位{mst.S_START_LOC}取货完成,起点解绑容器{mst.S_CNTR_CODE}"); LocationHelper.UnBindingLoc(mst.S_START_LOC, mst.S_CNTR_CODE.Split(',').ToList()); } else { Console.WriteLine($"任务{mst.S_CODE} 货位{mst.S_END_LOC}卸货完成,终点绑定容器{mst.S_CNTR_CODE}"); LogHelper.Info($"任务{mst.S_CODE} 货位{mst.S_END_LOC}卸货完成,终点绑定容器{mst.S_CNTR_CODE}"); LocationHelper.BindingLoc(mst.S_END_LOC, mst.S_CNTR_CODE.Split(',').ToList()); } } /// /// 任务取消,缓存位状态更新 /// /// internal static void CacheBitCancelUpdate(WCSTask mst) { var db = new SqlHelper().GetInstance(); //任务取消,取货完成前的,起点的loadingCount和终点unLoadingCount都清除,取货完成的只处理终点 if (mst.S_SCHEDULE_TYPE == "WCS") { if (WCSHelper.CheckActionRecordExist(mst.S_CODE, 5)) { //根据客户现场要求,如果取货完成任务失败人工拉到终点,我们就当卸货完成处理;如果是人工拉走到其它区域,我们就解锁终点,删除托盘。 //终点绑定 CacheBitUpdate(mst, false); LocationHelper.UnLockLoc(mst.S_END_LOC); var wmsTask = db.Queryable().Where(a => a.S_CODE == mst.S_OP_CODE).First(); if (wmsTask != null) { LocationHelper.UnLockLoc(wmsTask.S_END_LOC); } } else { //起点终点解锁 var wmsTask = db.Queryable().Where(a => a.S_CODE == mst.S_OP_CODE).First(); if (wmsTask != null) { LocationHelper.UnLockLoc(wmsTask.S_END_LOC); LocationHelper.UnLockLoc(mst.S_START_LOC); LocationHelper.UnLockLoc(mst.S_END_LOC); } } } else { if (WCSHelper.CheckActionRecordExist(mst.S_CODE, 4)) { //终点数量置0 db.Updateable().SetColumns(it => new Location() { N_CURRENT_NUM = 0 }).Where(a => a.S_CODE == mst.S_END_LOC).ExecuteCommand(); } else { db.Updateable().SetColumns(it => new Location() { N_CURRENT_NUM = 0 }).Where(a => a.S_CODE == mst.S_START_LOC).ExecuteCommand(); } db.Deleteable().Where(a => a.S_CNTR_CODE == mst.S_CNTR_CODE).ExecuteCommand(); db.Deleteable().Where(a => a.S_CNTR_CODE == mst.S_CNTR_CODE).ExecuteCommand(); LocationHelper.UnLockLoc(mst.S_START_LOC); LocationHelper.UnLockLoc(mst.S_END_LOC); var wmsTask = db.Queryable().Where(a => a.S_CODE == mst.S_OP_CODE).First(); if (wmsTask != null) { LocationHelper.UnLockLoc(wmsTask.S_END_LOC); } } } /// /// 安全请求 /// /// /// /// /// internal static void OperateReq(WCSTask mst, int state, string forkliftNo, string extData) { if (state == 1012) { CheckRfid(mst, forkliftNo); } //信号未定 后续对接 if (state == 1101 || state == 1103) { if (mst != null) { if (state == 1101) { //请求取货 Request(mst, true); } else { //请求卸货 Request(mst, false); } } } //信号未定后续对接 if (state == 1102 || state == 1104) { if (mst != null) { if (state == 1102) { //取货完成 Request2(mst, true); } else { //卸货完成 Request2(mst, false); } } } if (state == 1004) { if (mst.N_ERR == 200) { NDCApi.ChangeOrderParam(mst.S_CODE, 6, "1"); } if (mst.N_ERR == 500) { var db = new SqlHelper().GetInstance(); Location startLoc = null; Location endLoc = null; if (!string.IsNullOrEmpty(mst.S_ERR_LOC)) { endLoc = db.Queryable().Where(a => a.S_CODE == mst.S_ERR_LOC).First(); startLoc = db.Queryable().Where(a => a.S_CODE == mst.S_END_LOC).First(); if (endLoc != null && startLoc != null) { //替换作业终点 及任务起点终点 var wmsTask = db.Queryable().Where(a => a.S_CODE == mst.S_OP_CODE).First(); wmsTask.S_END_LOC = endLoc.S_CODE; wmsTask.S_END_AREA = endLoc.S_AREA_CODE; wmsTask.S_END_WH = endLoc.S_WH_CODE; db.Updateable(wmsTask).UpdateColumns(a => new { a.S_END_LOC, a.S_END_AREA, a.S_END_WH }).ExecuteCommand(); mst.S_END_LOC = endLoc.S_CODE; mst.S_END_AREA = endLoc.S_AREA_CODE; mst.S_END_WH = endLoc.S_WH_CODE; mst.S_START_LOC = startLoc.S_CODE; mst.S_START_AREA = startLoc.S_AREA_CODE; mst.S_START_WH = startLoc.S_WH_CODE; mst.S_ERR_LOC = ""; db.Updateable(mst).UpdateColumns(a => new { a.S_END_LOC, a.S_END_AREA, a.S_END_WH, a.S_START_LOC, a.S_START_AREA, a.S_START_WH, a.S_ERR_LOC }).ExecuteCommand(); //NDCApi.ChangeOrderParam(mst.S_CODE, 1, startLoc.S_AGV_SITE); //NDCApi.ChangeOrderParam(mst.S_CODE, 2, endLoc.S_AGV_SITE); //NDCApi.ChangeOrderParam(mst.S_CODE, 4, "0"); // //NDCApi.ChangeOrderParam(mst.S_CODE, 6, "2"); NDCApi.ChangeOrderParam(mst.S_CODE, 1, $"{startLoc.S_AGV_SITE};{endLoc.S_AGV_SITE};0;0;0;2"); } } } } } internal static void AddTaskAction(ApiModel.AgvTaskState model) { var db = new SqlHelper().GetInstance(); var task = db.Queryable().Where(a => a.TASK_NO == model.task_no && a.STATE == model.State).First(); if (task == null) { task = new Task_Action { TASK_NO = model.task_no, STATE = model.State, LOCKNO = model.LockNo, EXT_DATA = model.ext_data, EXT1 = model.Ext1, EXT2 = model.Ext2, FORKLIFT_NO = model.forklift_no, ERRCODE = model.ErrCode, N_CNTR_COUNT = model.N_CNTR_COUNT }; db.Insertable(task).ExecuteCommand(); } } /// /// 取卸货完成退出安全交互 /// /// /// internal static void Request2(WCSTask mst, bool v) { var db = new SqlHelper().GetInstance(); var Url = Settings.HASeverUrl; if (Url != null) { string trkType = ""; string stnNo = ""; if (v) { //取货请求 trkType = "1"; var info = db.Queryable().Where(a => a.BitCode == mst.S_START_LOC).First(); if (info != null) { stnNo = info.PlcLocation; } } else { //卸货请求 trkType = "2"; var info = db.Queryable().Where(a => a.BitCode == mst.S_END_LOC).First(); if (info != null) { stnNo = info.PlcLocation; } } var req = JsonConvert.SerializeObject(new { requestPk = mst.S_CODE, trkType = trkType, method = "Complete", stnNo = stnNo, carNo = "1001", clientCode = "WMS", reqTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") }); var feed = new HttpHelper().WebPost(Url + "agvCallback", req); LogHelper.Info($"安全交互 任务号={mst.S_CODE} url={Url + "agvCallback"} 传输数据={req} 返回数据={feed}"); if (!string.IsNullOrEmpty(feed)) { var res = JsonConvert.DeserializeObject(feed); if (res.code == "0") { if (res.isAllow == "1") { ////修改任务表数据为请求成功 S_NOTE :1 //mst.S_NOTE = "1"; //db.Updateable(mst).UpdateColumns(it => new { it.S_NOTE }).ExecuteCommand(); } } } } } /// /// 请求取卸货安全交互 /// /// /// internal static void Request(WCSTask mst, bool v) { var db = new SqlHelper().GetInstance(); var Url = Settings.HASeverUrl; if (Url != null) { string trkType = ""; string stnNo = ""; if (v) { //取货请求 trkType = "1"; var info = db.Queryable().Where(a => a.BitCode == mst.S_START_LOC).First(); if (info != null) { stnNo = info.PlcLocation; } } else { //卸货请求 trkType = "2"; var info = db.Queryable().Where(a => a.BitCode == mst.S_END_LOC).First(); if (info != null) { stnNo = info.PlcLocation; } } var req = JsonConvert.SerializeObject(new { requestPk = mst.S_CODE, trkType = trkType, method = "AgvRequest", stnNo = stnNo, carNo = "1001", clientCode = "WMS", reqTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") }); var feed = new HttpHelper().WebPost(Url + "agvCallback", req); LogHelper.Info($"安全交互 任务号={mst.S_CODE} url={Url + "agvCallback"} 传输数据={req} 返回数据={feed}"); if (!string.IsNullOrEmpty(feed)) { var res = JsonConvert.DeserializeObject(feed); if (res.code == "0") { if (res.isAllow == "1") { NDCApi.ChangeOrderParam(mst.S_CODE, 6, "1"); } } } } } internal static void UpdateAgvNo(WCSTask mst, string forkliftNo) { var db = new SqlHelper().GetInstance(); mst.S_EQ_NO = forkliftNo; db.Updateable(mst).UpdateColumns(it => new { it.S_EQ_NO }).ExecuteCommand(); } internal static void ThirdReportStatus(WCSTask mst, int state, string forkliftNo) { var db = new SqlHelper().GetInstance(); if (WCSHelper.CheckActionRecordExist(mst.S_CODE, 4) && state == 7) { state = 2; } //if (state == 2) //{ // if (Settings.DJCodes.Where(a => a.DJAreaCode == mst.S_END_AREA).FirstOrDefault() != null) // { // InspectionAreaStockUpdate(mst.S_CNTR_CODE, mst.S_END_LOC); // } //} if (state == 4 || state == 2 || state == 7) { AgvState(mst, state, forkliftNo); } } internal static void CheckRfid(WCSTask mst, string agv) { Console.WriteLine($"扫码请求 task={mst.S_CODE} agv={agv}"); LogHelper.Info($"扫码请求 task={mst.S_CODE} agv={agv}"); var codeReader = Settings.AgvRfids.Where(a => a.agv == agv).FirstOrDefault(); if (codeReader != null) { LogHelper.Info($"agv={codeReader.agv},ip={codeReader.ip}"); for (int i = 1; i <= 5; i++) { //try //{ //var res = OITcpHelper.HexTransit(new OITcpHelper.StrTransitData { data = "4C 4F 4E 0D", host = codeReader.ip, port = 9004 }); var res = SendHexOnce(codeReader.ip, codeReader.port, "41"); LogHelper.Info($"扫码返回报文{res}"); if (string.IsNullOrEmpty(res)) { NDCApi.ChangeOrderParam(mst.S_CODE, 6, "3"); } else { res = res.Substring(2, 16); var code = hexToStr(res); Console.WriteLine(code); LogHelper.Info($"托盘信息为={mst.S_CNTR_CODE},扫码结果为={code},结果:{mst.S_CNTR_CODE.Trim() == code.Trim()}"); if (res != null && code.Trim() != "ERROR") { if (mst.S_CNTR_CODE.Trim() == code.Trim()) { NDCApi.ChangeOrderParam(mst.S_CODE, 6, "1"); } else { NDCApi.ChangeOrderParam(mst.S_CODE, 6, "2"); } return; } else if (i == 5) { if (res != null) { NDCApi.ChangeOrderParam(mst.S_CODE, 6, "3"); } else { NDCApi.ChangeOrderParam(mst.S_CODE, 6, "4"); } } } //} //catch (Exception ex) //{ // LogHelper.Error($"扫码流程异常 异常信息{ex.Message}", ex); //} } } } private static string hexToStr(string hexString) { hexString = hexString.Replace(" ", ""); if ((hexString.Length % 2) != 0) hexString += " "; byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); return Encoding.ASCII.GetString(returnBytes); } private static string SendHexOnce(string ip, int port, string hex) { var res = string.Empty; Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); client.Connect(ip, port); client.ReceiveTimeout = 2000; if (client.Connected) { client.Send(Hex2Bytes(hex)); byte[] buffer = new byte[1024]; try { var length = client.Receive(buffer, SocketFlags.None); byte[] data = new byte[length]; Array.Copy(buffer, data, length); res = BitConverter.ToString(data).Replace("-", ""); } catch (Exception ex) { LogHelper.Error(ex.Message, ex); } client.Disconnect(true); client.Dispose(); } client = null; return res; } internal static byte[] Hex2Bytes(string hexString) { hexString = hexString.Replace(" ", ""); if ((hexString.Length % 2) != 0) hexString += " "; byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); return returnBytes; } private static void AgvState(WCSTask mst, int state, string forkliftNo) { try { if (!mst.S_OP_CODE.Contains("OP")) { //调用AGV完成接口 var url = Settings.ZTSeverUrl2 + "/business/BU_HX01"; var req = new { TaskNo = mst.S_OP_CODE, State = state, AgvNo = int.Parse(forkliftNo), cntrNo = mst.S_CNTR_CODE, workNo = mst.S_OP_CODE }; LogHelper.Info($"agv完成任务回报 地址{url} 接口参数{JsonConvert.SerializeObject(req)}"); var feedback = new HttpHelper().WebPost(url, JsonConvert.SerializeObject(req)); if (!string.IsNullOrEmpty(feedback)) { var weilires = JsonConvert.DeserializeObject(feedback); if (weilires.code == 200) { LogHelper.Info($"接口反馈成功"); } else { LogHelper.Info($"agv完成任务回报 反馈失败 失败原因={weilires.msg}"); } } else { LogHelper.Info($"agv完成任务回报 反馈超时"); } } else { var db = new SqlHelper().GetInstance(); var wmsTask = db.Queryable().Where(a => a.S_CODE == mst.S_OP_CODE).First(); if (wmsTask != null) { if (!string.IsNullOrEmpty(wmsTask.S_BS_NO)) { //调用AGV完成接口 var url = Settings.ZTSeverUrl2 + "/business/BU_HX01"; var req = new { TaskNo = wmsTask.S_BS_NO, State = state, AgvNo = int.Parse(forkliftNo), cntrNo = mst.S_CNTR_CODE, workNo = wmsTask.S_BS_NO }; LogHelper.Info($"agv完成任务回报 地址{url} 接口参数{JsonConvert.SerializeObject(req)}"); var feedback = new HttpHelper().WebPost(url, JsonConvert.SerializeObject(req)); if (!string.IsNullOrEmpty(feedback)) { var weilires = JsonConvert.DeserializeObject(feedback); if (weilires.code == 200) { LogHelper.Info($"接口反馈成功"); } else { LogHelper.Info($"agv完成任务回报 反馈失败 失败原因={weilires.msg}"); } } else { LogHelper.Info($"agv完成任务回报 反馈超时"); } } } else LogHelper.Info($"任务{mst.S_CODE} 没有找到作业号为{mst.S_OP_CODE}的作业"); } } catch (Exception ex) { LogHelper.Error($"agv完成任务回报异常 异常信息={ex.Message}", ex); } } public static void InspectionAreaStockUpdate(string CNTR_CODE, string END_LOC) { try { var db = new SqlHelper().GetInstance(); var url = Settings.ZTSeverUrl + "InspectionAreaStockUpdate"; var req = new { cntrCode = CNTR_CODE, location = END_LOC, data = new List() }; var cn = db.Queryable().Where(a => a.S_CNTR_CODE == CNTR_CODE).ToList(); if (cn.Count > 0) { var grouplist = cn.GroupBy(a => new { a.S_ITEM_CODE, a.S_BATCH_NO, a.S_OWNER, a.S_ERP_WH_CODE, a.S_SUPPLIER_NO }).ToList(); for (int i = 0; i < grouplist.Count; i++) { var num = 0; var serialNo = new List(); var S_ITEM_CODE = grouplist[i].Key.S_ITEM_CODE; var S_BATCH_NO = grouplist[i].Key.S_BATCH_NO; var S_OWNER = grouplist[i].Key.S_OWNER; var S_ERP_WH_CODE = grouplist[i].Key.S_ERP_WH_CODE; var S_SUPPLIER_NO = grouplist[i].Key.S_SUPPLIER_NO; var itemgroup = cn.Where(it => it.S_ITEM_CODE == S_ITEM_CODE && it.S_BATCH_NO == S_BATCH_NO && it.S_OWNER == S_OWNER && it.S_ERP_WH_CODE == S_ERP_WH_CODE && it.S_SUPPLIER_NO == S_SUPPLIER_NO).ToList(); if (itemgroup.Count > 0) { itemgroup.ForEach(a => { //填充数据 num = num + Convert.ToInt32(a.F_QTY); if (!string.IsNullOrEmpty(a.S_SERIAL_NO)) { serialNo.Add(a.S_SERIAL_NO); } }); req.data.Add(new { itemCode = S_ITEM_CODE, factoryCode = S_OWNER, stockCode = S_ERP_WH_CODE, qty = num, vendorCode = S_SUPPLIER_NO, batchNo = S_BATCH_NO, serialNo = serialNo }); } } LogHelper.Info($"检验区库存增加接口 地址{url} 接口参数{JsonConvert.SerializeObject(req)}"); var feedback = new HttpHelper().WebPost(url, JsonConvert.SerializeObject(req)); LogHelper.Info($"检验区库存增加接口 地址{url} 接口参数{JsonConvert.SerializeObject(req)} 返回参数{feedback}"); if (!string.IsNullOrEmpty(feedback)) { var weilires = JsonConvert.DeserializeObject(feedback); if (weilires.code == 200) { LogHelper.Info($"接口反馈成功"); db.Deleteable().Where(a => a.S_CNTR_CODE == CNTR_CODE).ExecuteCommand(); } else { LogHelper.Info($"检验区库存增加接口 反馈失败 失败原因={weilires.msg}"); } } else { LogHelper.Info($"检验区库存增加接口 反馈超时"); } } else LogHelper.Info($"托盘{CNTR_CODE} 未绑定物料"); } catch (Exception ex) { LogHelper.Error($"检验区库存增加异常 异常信息={ex.Message}", ex); } } public static void receiveUnloadConfirm(string CNTR_CODE, string END_LOC) { try { var db = new SqlHelper().GetInstance(); var url = Settings.ZTSeverUrl + "receiveUnloadConfirm"; var req = new { cntrCode = CNTR_CODE, location = END_LOC, data = new List() }; var cn = db.Queryable().Where(a => a.S_CNTR_CODE == CNTR_CODE).ToList(); if (cn.Count > 0) { var grouplist = cn.GroupBy(a => new { a.S_ITEM_CODE, a.S_BATCH_NO, a.S_OWNER, a.S_ERP_WH_CODE, a.S_SUPPLIER_NO }).ToList(); for (int i = 0; i < grouplist.Count; i++) { var num = 0; var serialNo = new List(); var S_ITEM_CODE = grouplist[i].Key.S_ITEM_CODE; var S_BATCH_NO = grouplist[i].Key.S_BATCH_NO; var S_OWNER = grouplist[i].Key.S_OWNER; var S_ERP_WH_CODE = grouplist[i].Key.S_ERP_WH_CODE; var S_SUPPLIER_NO = grouplist[i].Key.S_SUPPLIER_NO; var itemgroup = cn.Where(it => it.S_ITEM_CODE == S_ITEM_CODE && it.S_BATCH_NO == S_BATCH_NO && it.S_OWNER == S_OWNER && it.S_ERP_WH_CODE == S_ERP_WH_CODE && it.S_SUPPLIER_NO == S_SUPPLIER_NO).ToList(); if (itemgroup.Count > 0) { itemgroup.ForEach(a => { //填充数据 num = num + Convert.ToInt32(a.F_QTY); if (!string.IsNullOrEmpty(a.S_SERIAL_NO)) { serialNo.Add(a.S_SERIAL_NO); } }); req.data.Add(new { itemCode = S_ITEM_CODE, factoryCode = S_OWNER, stockCode = S_ERP_WH_CODE, qty = num, vendorCode = S_SUPPLIER_NO, batchNo = S_BATCH_NO, serialNo = serialNo }); } } LogHelper.Info($"收货装框确认接口 地址{url} 接口参数{JsonConvert.SerializeObject(req)}"); var feedback = new HttpHelper().WebPost(url, JsonConvert.SerializeObject(req)); LogHelper.Info($"收货装框确认接口 地址{url} 接口参数{JsonConvert.SerializeObject(req)} 返回参数{feedback}"); if (!string.IsNullOrEmpty(feedback)) { var weilires = JsonConvert.DeserializeObject(feedback); if (weilires.code == 200) { LogHelper.Info($"接口反馈成功"); } else { LogHelper.Info($"收货装框确认接口 反馈失败 失败原因={weilires.msg}"); } } else { LogHelper.Info($"收货装框确认接口 反馈超时"); } } else LogHelper.Info($"托盘{CNTR_CODE} 未绑定物料"); } catch (Exception ex) { LogHelper.Error($"收货装框确认接口 异常信息={ex.Message}", ex); } } /// /// 任务拦截 /// /// /// internal static bool Intercept(WCSTask mst) { var result = false; //出库任务是批量生成的,初始终点我们先给一个虚拟点,不推送。有单独的现场去判断出库缓存区光电,空了再给出库任务分配终点 if (mst.S_END_LOC.Trim() == "出库虚拟点") { result = true; } return result; } /// /// 任务状态更新处理 /// /// /// internal static void OperateStatus(WCSTask mst, int state) { if (state == 4) { CacheBitUpdate(mst, true); } if (state == 6)//卸货完成 { CacheBitUpdate(mst, false); } if (state == 7) { CacheBitCancelUpdate(mst); } } private static object locLocker = new object(); /// /// 堆叠库区出入库任务申请 /// /// /// /// /// /// /// /// /// internal static bool ApplyTN_Task(Location ls, ref List cntrs, string area, string itemCode, string itemBatch, string taskType, bool insStock = true) { var result = false; lock (locLocker) { try { if (insStock) { Console.WriteLine($"MoboxHelperCreateTask: {area}-{itemCode}-{itemBatch}-{taskType}"); var endTN_Location = GetLocation4In(area, itemCode, itemBatch, 3); if (endTN_Location != null) { var endLayer = endTN_Location.N_CURRENT_NUM == 0 ? 1 : 2; var taskNo = DateTime.Now.Ticks.ToString(); result = TaskProcess.CreateTransport(ls.S_CODE, endTN_Location.S_CODE, taskType, cntrs, 1, endLayer, 3, 70); } else { Console.WriteLine($"MoboxHelperCreateTask: 未找到终点货位"); } } else { var startTN_Location = GetLocation4Out(area, itemCode, itemBatch, 3); if (startTN_Location != null) { var startLayer = startTN_Location.N_CURRENT_NUM <= 3 ? 1 : 2; var taskNo = DateTime.Now.Ticks.ToString(); var carryCount = startTN_Location.N_CURRENT_NUM > 3 ? startTN_Location.N_CURRENT_NUM - 3 : startTN_Location.N_CURRENT_NUM; //出库要从起点获取托盘 var cntrList = LocationHelper.GetLocCntr(startTN_Location.S_CODE); if (cntrList.Count == startTN_Location.N_CURRENT_NUM) { cntrs = cntrList.OrderByDescending(a => a.T_CREATE).Take(carryCount).Select(a => a.S_CNTR_CODE.Trim()).ToList(); result = TaskProcess.CreateTransport(startTN_Location.S_CODE, ls.S_CODE, taskType, cntrs, startLayer, 1, carryCount, 65); } else { Console.WriteLine($"起点托盘数量和货位容器表不符合,请检查【货位表】和【货位容器表】"); } } } } catch (Exception ex) { Console.WriteLine("MoboxHelperCreateTask:" + ex.Message); LogHelper.Error("MoboxHelperCreateTask:" + ex.Message, ex); } } return result; } private static Location GetLocation4Out(string area, string itemCode, string itemBatch, int v) { throw new NotImplementedException(); } private static Location GetLocation4In(string area, string itemCode, string itemBatch, int v) { throw new NotImplementedException(); } /// /// 普通货架区的出入库申请 /// /// /// /// /// /// /// /// internal static bool ApplyNormalTN_Task(Location ls, ref List cntrs, string area, string taskType, string itemCode, bool insStock = true) { var result = false; lock (locLocker) { try { if (insStock) { Console.WriteLine($"MoboxHelperCreateTask: {area}-{taskType}"); var endTN_Location = new Location(); if (endTN_Location != null) { var taskNo = DateTime.Now.Ticks.ToString(); result = TaskProcess.CreateTransport(ls.S_CODE, endTN_Location.S_CODE, taskType, cntrs, 70); } else { Console.WriteLine($"MoboxHelperCreateTask: 未找到终点货位"); } } else { var startTN_Location = new Location(); if (startTN_Location != null) { //出库要从起点获取托盘 var cntrList = LocationHelper.GetLocCntr(startTN_Location.S_CODE); if (cntrList.Count == startTN_Location.N_CURRENT_NUM) { result = TaskProcess.CreateTransport(startTN_Location.S_CODE, ls.S_CODE, taskType, new List { cntrList[0].S_CNTR_CODE }, 65); } else { Console.WriteLine($"起点托盘数量和货位容器表不符合,请检查【货位表】和【货位容器表】"); } } } } catch (Exception ex) { Console.WriteLine("MoboxHelperCreateTask:" + ex.Message); LogHelper.Error("MoboxHelperCreateTask:" + ex.Message, ex); } } return result; } /// /// 推送任务 /// /// internal static bool SendTask(WCSTask mst) { var result = false; var start = "0"; var end = "0"; var Trow = "0"; var taskType = mst.S_TYPE.Trim(); if (mst.N_B_STATE == 0) { start = LocationHelper.GetAgvSite(mst.S_START_LOC); end = LocationHelper.GetAgvSite(mst.S_END_LOC); if (Settings.ConnetAreas.Where(a => a.InLocList.Contains(mst.S_END_LOC)).FirstOrDefault() != null) { Trow = "1024"; } Console.WriteLine($"SendTask {mst.S_CODE}"); Console.WriteLine("start=" + start); Console.WriteLine("end= " + end); var dic = new List(); dic.Add(new param { name = "From", value = start }); dic.Add(new param { name = "To", value = end }); dic.Add(new param { name = "FRow", value = "4" }); dic.Add(new param { name = "TRow", value = Trow }); dic.Add(new param { name = "AGV", value = "0" }); var res = NDCApi.AddOrderNew(1, mst.N_PRIORITY, mst.S_CODE, dic); if (res.err_code == 0) { //推送成功,修改任务优先级 mst.N_B_STATE = 1; WCSHelper.UpdateStatus(mst, "已推送"); result = true; } } return result; } /// /// 设备任务取消 /// /// internal static bool Cancel(WCSTask task) { var result = false; var Url = Settings.HASeverUrl; if (Url != null) { var model = new PlcCancelTaskreq { contNo = task.S_CNTR_CODE, requestPk = task.S_CODE }; var feed = httpHelper.WebPost(Url + "cancel", JsonConvert.SerializeObject(model)); LogHelper.Info($"任务{task.S_CODE} 推送任务参数={JsonConvert.SerializeObject(model)} 下游反馈={feed}"); if (!string.IsNullOrEmpty(feed)) { var res = JsonConvert.DeserializeObject(feed); if (res.code == "0") { LogHelper.Info($"任务{task.S_CODE} 取消成功"); result = true; } else { LogHelper.Info($"任务{task.S_CODE} 取消失败"); } } } else { LogHelper.Info($"取消下游PLC任务 获取API地址配置失败 请检查配置文件"); } return result; } public class PlcCancelTaskreq { /// /// 请求编号 唯一标示 /// public string requestPk { get; set; } /// /// 托盘号 /// public string contNo { get; set; } /// /// 操作人 默认 /// public string clientCode { get; set; } = "WMS"; /// /// 操作时间 默认 /// public string reqTime { get; set; } = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"); } /// /// 设备任务推送 /// /// internal static void PlcSendTask(WCSTask task) { var from = task.S_START_LOC; var to = task.S_END_LOC; //var from = LocationHelper.GetAgvSite(task.S_START_LOC).ToString(); //var to = LocationHelper.GetAgvSite(task.S_END_LOC).ToString(); var db = new SqlHelper().GetInstance(); var Url = Settings.HASeverUrl; if (Url != null) { var agvbit = db.Queryable().Where(a => a.BitCode == task.S_START_LOC || a.BitCode == task.S_END_LOC).ToList(); foreach (var item in agvbit) { if (item.BitCode == task.S_START_LOC) { from = item.PlcLocation; } else { to = item.PlcLocation; } } //var endInfo = Settings.GetInOutLocationList().Where(a => a.Location == task.S_END_LOC).FirstOrDefault(); //if (endInfo != null) //{ // to = endInfo.Code; //} var model = new PlcSendTaskreq { contNo = task.S_CNTR_CODE, //frmPos = LocationHelper.GetAgvSite(task.S_START_LOC).ToString(), //toPos = LocationHelper.GetAgvSite(task.S_END_LOC).ToString(), contType = "", frmPos = from, toPos = to, requestPk = task.S_CODE, trkPrty = task.N_PRIORITY.ToString(), trkType = task.S_OP_NAME == "入库" ? "1" : task.S_OP_NAME == "出库" ? "2" : "3" }; var feed = httpHelper.WebPost(Url + "receive", JsonConvert.SerializeObject(model)); LogHelper.Info($"任务{task.S_CODE} 推送任务参数={JsonConvert.SerializeObject(model)} 下游反馈={feed}"); if (!string.IsNullOrEmpty(feed)) { var res = JsonConvert.DeserializeObject(feed); if (res.code == "0") { task.N_B_STATE = 1; WCSHelper.UpdateStatus(task, "已推送"); } } } else { LogHelper.Info($"推送下游PLC任务 获取API地址配置失败 请检查配置文件"); } } public class PlcSendTaskreq { /// /// 请求编号 唯一标示 /// public string requestPk { get; set; } /// /// 托盘号 /// public string contNo { get; set; } /// /// 托盘类型 默认 /// public string contType { get; set; } = ""; /// /// 任务类型 出库 入库 移动 /// public string trkType { get; set; } /// /// 任务优先级 1-999 /// public string trkPrty { get; set; } /// /// 起始位置 /// public string frmPos { get; set; } /// /// 目的地 /// public string toPos { get; set; } /// /// 托盘空满状态 0:空 1:满 /// public string isFull { get; set; } = "1"; /// /// 搬运组号 默认 /// public string groupNo { get; set; } = ""; /// /// 操作人 默认 /// public string clientCode { get; set; } = "WMS"; /// /// 操作时间 默认 /// public string reqTime { get; set; } = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"); } public class PlcSendTaskres { /// /// 0:成功 /// public string code { get; set; } public string msg { get; set; } /// /// 任务编号 /// public string requestPk { get; set; } public string new_locate_no { get; set; } public string isAllow { get; set; } } /// /// 创建搬运任务 /// /// /// /// /// /// /// /// /// /// public static bool CreateTransport(string start, string end, string taskType, List cntrs, int startLayer, int endLayer, int trayCarryCount = 1, int priority = 1) { var result = false; //批次号存托盘号,1~3个托盘 var trayCodes = string.Join(",", cntrs); var taskNo = DateTime.Now.Ticks.ToString(); var res = WCSHelper.CreateTask(taskNo, start.Trim(), end.Trim(), taskType, priority, trayCodes, trayCarryCount, startLayer, endLayer); if (res) { result = true; //任务创建成功,起点货位出库锁定,终点货位入库锁定 LocationHelper.LockLoc(start, 1); LocationHelper.LockLoc(end, 2); } return result; } public static bool CreateTransport(string start, string end, string taskType, List cntrs, int priority = 1) { var result = false; //批次号存托盘号,1~3个托盘 var trayCodes = string.Join(",", cntrs); var taskNo = DateTime.Now.Ticks.ToString(); var res = WCSHelper.CreateTask(taskNo, start.Trim(), end.Trim(), taskType, priority, trayCodes, 1, 1, 1); if (res) { result = true; LocationHelper.LockLoc(start, 2); LocationHelper.LockLoc(end, 1); } return result; } #endregion } }