using Hanhe.iWCS.Business; using Hanhe.iWCS.Common; using Hanhe.iWCS.DeviceDriver; using Hanhe.iWCS.MData; using Hanhe.iWCS.Model; using Hanhe.iWCS.Model.AMS; using MongoDB.Bson; using MongoDB.Driver; using MongoDB.Driver.Builders; using MongoDB.Driver.Linq; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Security.Policy; using System.Text; using static Hanhe.iWCS.TaizhouGEMTwoProtocol.ApiHelper; using static Hanhe.iWCS.TaizhouGEMTwoProtocol.EnentListen; using static Hanhe.iWCS.TaizhouGEMTwoProtocol.MESHelper; using static Hanhe.iWCS.TaizhouGEMTwoProtocol.PLCControl; using static Hanhe.iWCS.TaizhouGEMTwoProtocol.ProtocolAnalysis; namespace Hanhe.iWCS.TaizhouGEMTwoProtocol { public class ProcessHelper { private static ICallTaskProcessing callTaskProcessing = new ICallTaskProcessing(); private static WebApiHelper webApiHelper = new WebApiHelper(); public static bool CheckStartFree(string bit) { var result = false; var tasks = MongoDBSingleton.Instance.Find(Query.EQ("CN_S_START_BIT", bit), "TN_I_TASK_MST"); if (tasks.Count == 0) { result = true; } else { for (int i = 0; i < tasks.Count; i++) { if (!WorkFlowAction.ExistsTrackLogs(tasks[i].CN_S_TASK_NO, 1, 4)) { break; } } } return result; } public static bool CheckStartFreeTwo(string bit) { var result = false; var tasks = MongoDBSingleton.Instance.Find(Query.EQ("CN_S_START_BIT", bit), "TN_I_TASK_MST"); if (tasks.Count == 0) { result = true; } else { result = true; for (int i = 0; i < tasks.Count; i++) { if (!WorkFlowAction.ExistsTrackLogs(tasks[i].CN_S_TASK_NO, 1, 4)) { result = false; break; } } } return result; } public static bool PickUpStartFree(string bit) { var result = false; var tasks = MongoDBSingleton.Instance.Find(Query.EQ("CN_S_START_BIT", bit), "TN_I_TASK_MST"); if (tasks.Count == 0) { result = true; } else { result = true; for (int i = 0; i < tasks.Count; i++) { if (!WorkFlowAction.ExistsTrackLogs(tasks[i].CN_S_TASK_NO, 1, 4)) { result = false; break; } } } return result; } public static bool PickUpEndFree(string bit) { var result = false; var tasks = MongoDBSingleton.Instance.Find(Query.EQ("CN_S_END_BIT", bit), "TN_I_TASK_MST"); if (tasks.Count == 0) { result = true; } else { result = true; for (int i = 0; i < tasks.Count; i++) { if (!WorkFlowAction.ExistsTrackLogs(tasks[i].CN_S_TASK_NO, 1, 6)) { result = false; break; } } } return result; } internal static bool CheckEndFree(string bit) { var count = MongoDBSingleton.Instance.FindCount(Query.EQ("CN_S_END_BIT", bit), "TN_I_TASK_MST"); return count == 0; } /// /// 发送任务——已增加起点终点层数,特殊AGV站点推送 /// /// internal static void SendTask(TN_I_TASK_MST mst) { if(mst.CN_S_STATUS=="未执行" || mst.CN_S_STATUS == "待推送") { StringBuilder sbMsg = new StringBuilder(); var start = StockInstance.Instance.GetLocationInfoTwo(mst.CN_S_START_BIT); var end = StockInstance.Instance.GetLocationInfoTwo(mst.CN_S_END_BIT); string FRow = string.IsNullOrEmpty(start.CN_S_FLOOR) ? "1" : start.CN_S_FLOOR; string TRow = string.IsNullOrEmpty(end.CN_S_FLOOR) ? "1" : end.CN_S_FLOOR; CMMLog.Info($"任务推送:货位编码:起点信息:{JsonConvert.SerializeObject(start)},终点信息:{JsonConvert.SerializeObject(end)};任务信息:{JsonConvert.SerializeObject(mst)}"); var trayInfo = MongoDBSingleton.Instance.FindOne(Query.EQ("locCode", mst.CN_S_START_BIT), "trayTypeTable"); if (trayInfo != null && trayInfo.trayType == "2") { start.CN_N_AGV_LOCATION = start.CN_N_AGV_LOCATION + 400; end.CN_N_AGV_LOCATION = end.CN_N_AGV_LOCATION + 400; CMMLog.Info($"任务推送:田字托起点终点 站点更改,起点:{start.CN_N_AGV_LOCATION},终点:{end.CN_N_AGV_LOCATION}"); } if (mst.CN_S_BUSS_TYPE == "3楼复称入缓存架") { CMMLog.Info($"任务推送特殊任务处理-3楼复称入缓存架:任务号:{mst.CN_S_TASK_NO},准备获取 sendBit 配置数据。备注:此任务类型仅获取起点。"); var plc = Settings.GetSendBit().Where(a => a.taskType == mst.CN_S_BUSS_TYPE && a.bit == mst.CN_S_START_BIT).FirstOrDefault(); if (plc != null) { start.CN_N_AGV_LOCATION = plc.agv; FRow = string.IsNullOrEmpty(plc.floor) ? "1" : plc.floor; CMMLog.Info($"任务推送特殊任务处理-3楼复称入缓存架-成功:获取数据成功,获取后的点位:{start.CN_N_AGV_LOCATION},FRow 参数:{FRow}"); } else CMMLog.Info($"任务推送特殊任务处理-3楼复称入缓存架-失败:未获取到 settings 配置文件中的相关数据,请根据日志提供的相关数据对比 sendBit 配置数据。"); } if (mst.CN_S_BUSS_TYPE == "包装线补空") { CMMLog.Info($"任务推送特殊任务处理-包装线补空:任务号:{mst.CN_S_TASK_NO},准备获取 AGVLocationList 配置数据。备注:此任务类型仅获取起点。"); var agvLoc = Settings.GetDDSiteList().Where(a => a.ddLoc == mst.CN_S_START_BIT).FirstOrDefault(); if (agvLoc != null) { var emp = MongoDBSingleton.Instance.FindOne(Query.EQ("Bit", mst.CN_S_START_BIT), "BZEmptyPoint"); if (emp != null) { start.CN_N_AGV_LOCATION = agvLoc.Site[emp.Quantity - 1]; } if(agvLoc.trayType == 2) { end.CN_N_AGV_LOCATION = MongoDBSingleton.Instance.FindOne(Query.EQ("CN_S_LOCATION_CODE", mst.CN_S_END_BIT), "STOCK_LOCATION_Two").CN_N_AGV_LOCATION; } } } try { var req = $""; CMMLog.Info($"任务推送:下发 Hosttoagv 数据:{req}."); HardwareAccessObject AGVHao = HardwareAccessHelper.Instance.GetEquipmentsHAO("1"); if (AGVHao != null) { object[] args = new object[1]; args[0] = req; object xmlData = AGVHao._WebServiceInstance.Invoke("AddNewOrder", args); string errMsg = string.Empty; int errCode = -1; if (xmlData != null) { errCode = Hanhe.iWCS.AGVWebService.AGVHelper.Instance.AGVXmlResult((string)xmlData, out errMsg); } var msg = "WCS To AGV send task; errcode=" + errCode + "!data=" + sbMsg.ToString() + ";url=" + AGVHao.WebUrl; CMMLog.Info($"任务推送:接收 Hosttoagv 数据:{msg}."); if (errCode == Constants.WCS_AGV_ERRCode || errCode == 99999) { MongoDBSingleton.Instance.Update(Query.EQ("_id", mst._id), Update.Set("CN_S_STATUS", "未执行"), UpdateFlags.None); AMSHelper.TaskTrackLogMessage(mst.CN_S_TASK_NO, "1", "1027", "AGV任务拦截推送失败", errCode.ToString()); Console.WriteLine(mst.CN_S_TASK_NO + ", \"1\", \"1027\", \"AGV任务拦截推送失败\"," + errCode.ToString()); CMMLog.Info(mst.CN_S_TASK_NO + ", \"1\", \"1027\", \"AGV任务拦截推送失败\"," + errCode.ToString()); } else { if (errCode == 0 || errCode == 50009) { MongoDBSingleton.Instance.Update(Query.EQ("_id", mst._id), Update.Set("CN_S_STATUS", "已推送"), UpdateFlags.None); } AMSHelper.TaskTrackLogMessage(mst.CN_S_TASK_NO, "1", "1027", "AGV任务下达成功"); Console.WriteLine(mst.CN_S_TASK_NO + "\"1\", \"1027\", \"AGV任务下达成功\""); CMMLog.Info(mst.CN_S_TASK_NO + "\"1\", \"1027\", \"AGV任务下达成功\""); } } else { Console.WriteLine("WCS To AGV send task fail; ts1 not set in ams work center"); CMMLog.Info("WCS To AGV send task fail; ts1 not set in ams work center"); } } catch (Exception ex) { MongoDBSingleton.Instance.Update(Query.EQ("_id", mst._id), Update.Set("CN_S_STATUS", "未执行"), UpdateFlags.None); CMMLog.Error("WCS To AGV send task fail;param=" + mst.CN_S_TASK_NO + ";err=" + ex.Message); AMSHelper.TaskTrackLogMessage(mst.CN_S_TASK_NO, "1", "1027", "AGV任务拦截推送失败"); } } } #region 3楼设备任务 /// /// 终点安全对接:1013安全请求进入;6安全请求退出 /// /// /// internal static void EndPickUpDoorSafe(TN_I_TASK_MST mst, int code) { //3楼包装补空:包装机补空托流程——3楼包装机安全门交互 var plc = Settings.GetPlcInfo().Where(a => a.location == mst.CN_S_END_BIT).FirstOrDefault(); if (plc != null || mst.CN_S_BUSS_TYPE == "3楼复称入缓存架") { if (code == 1013) { //卸货申请,先判断设备是否允许进料,如果是直接改参数,并通知设备 if (mst.CN_S_BUSS_TYPE.Contains("3楼包装取料")) PLCControl.SecondWeightSafe(plc.ip, mst.CN_S_TASK_NO); if (mst.CN_S_BUSS_TYPE == "3楼复称入缓存架") PLCControl.SecondWeightInCache1013(mst.CN_S_TASK_NO); if (mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托") PLCControl.CacheStackingMouth1013(plc.deviceType, mst.CN_S_TASK_NO); if (mst.CN_S_BUSS_TYPE == "3楼拆盘补空") PLCControl.DiscRemoverReqUnload(plc.deviceType, mst.CN_S_TASK_NO); if (mst.CN_S_BUSS_TYPE == "包装线补空") PLCControl.PackingLine(plc.ip, mst.CN_S_TASK_NO); if (mst.CN_S_BUSS_TYPE == "电梯取货") PLCControl.LiftAction(plc,mst.CN_S_TASK_NO,true); if (mst.CN_S_BUSS_TYPE == "四钴成品出库" || mst.CN_S_BUSS_TYPE == "四钴辅材出库") PLCControl.productOutWare(mst.CN_S_END_BIT, mst.CN_S_TASK_NO, true); } if (code == 6) { //卸货完成申请,判断设备那边进料完成,改参数通知agv离开 if (mst.CN_S_BUSS_TYPE.Contains("3楼包装取料")) PLCControl.CheckUpUnloadComplete(plc.ip, mst.CN_S_TASK_NO,plc.port); //if (mst.CN_S_BUSS_TYPE.Contains("3楼包装取料")) PLCControl.SecondWeightSafeComplete(plc.ip, mst.CN_S_TASK_NO); //if (mst.CN_S_BUSS_TYPE == "3楼复称入缓存架") PLCControl.SecondWeightInCache6(plc.ip, mst.CN_S_TASK_NO); if (mst.CN_S_BUSS_TYPE == "3楼拆盘补空") PLCControl.DiscRemoverUnloadComplete(plc.deviceType, mst.CN_S_TASK_NO); if (mst.CN_S_BUSS_TYPE == "包装线补空") PLCControl.PackingLineComplete(plc.ip); if (mst.CN_S_BUSS_TYPE == "电梯取货") PLCControl.LiftAction(plc, mst.CN_S_TASK_NO,false); if (mst.CN_S_BUSS_TYPE == "四钴成品出库" || mst.CN_S_BUSS_TYPE == "四钴辅材出库") PLCControl.productOutWare(mst.CN_S_END_BIT, mst.CN_S_TASK_NO, false); if (mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托") PLCControl.CacheStackingMouth6(plc,mst.CN_S_TASK_NO); } } } /// /// 滚筒车终点到位信号:1113 取货完成:1213 /// /// /// internal static void DiscRemoverEmptySupport(TN_I_TASK_MST mst, int code) { var plc = Settings.GetPlcInfo().Where(a => a.location == mst.CN_S_END_BIT).FirstOrDefault(); if (plc != null) { if (code == 1113) { //卸货申请,先判断设备是否允许进料,如果是直接改参数,并通知设备 if (mst.CN_S_BUSS_TYPE.Contains("3楼包装取料")) PLCControl.CheckUpReqUnload(plc.ip, mst.CN_S_TASK_NO); } //if (code == 1213) //{ // //卸货完成申请,判断设备那边进料完成,改参数通知agv离开 // if (mst.CN_S_BUSS_TYPE.Contains("3楼包装取料")) PLCControl.CheckUpUnloadComplete(plc.ip, mst.CN_S_TASK_NO); //} } } /// /// 起点安全对接:1012安全请求进入;4安全请求退出 /// /// /// internal static void StartPickUpDoorSafe(TN_I_TASK_MST mst, int code) { //3楼包装补空:包装机补空托流程——3楼包装机安全门交互 var plc = Settings.GetPlcInfo().Where(a => a.location == mst.CN_S_START_BIT).FirstOrDefault(); if (plc != null) { if (code == 1012) { //卸货申请,先判断设备是否允许进料,如果是直接改参数,并通知设备 if (mst.CN_S_BUSS_TYPE.Contains("3楼包装取料")) PLCControl.PickUpFullDoorUnload(plc.ip, mst.CN_S_TASK_NO);//进入3楼包装取料流程1012,ip:{plc.ip},task:{mst.CN_S_TASK_NO} if (mst.CN_S_BUSS_TYPE == "3楼复称入缓存架" || mst.CN_S_BUSS_TYPE == "3楼复称入缓存架NG") PLCControl.SecondWeightInCache1012(plc.deviceType, mst.CN_S_TASK_NO);//二期:直接改参数 //if (mst.CN_S_BUSS_TYPE == "3楼复称入缓存架") PLCControl.SecondWeightInCache1012(plc.deviceType, mst.CN_S_TASK_NO);//二期:直接改参数 if (mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托") TSHelper.GoToAGV(mst.CN_S_TASK_NO, 10, 1); if (mst.CN_S_BUSS_TYPE == "3楼叠盘下线") PLCControl.StackingReqUnload(plc.deviceType, mst.CN_S_TASK_NO); if (mst.CN_S_BUSS_TYPE == "3楼打包下线") PLCControl.PackingLineUnload1012(plc.ip, mst.CN_S_TASK_NO,plc.port); if (mst.CN_S_BUSS_TYPE == "四钴辅材入库") PLCControl.productInWare(mst.CN_S_START_BIT, mst.CN_S_TASK_NO, true); } if (code == 4) { //卸货完成申请,判断设备那边进料完成,改参数通知agv离开 if (mst.CN_S_BUSS_TYPE.Contains("3楼包装取料")) PLCControl.PickUpFullDoorComplete(plc.ip, mst.CN_S_TASK_NO); if (mst.CN_S_BUSS_TYPE == "3楼复称入缓存架" || mst.CN_S_BUSS_TYPE == "3楼复称入缓存架NG") PLCControl.SecondWeightInCache4(plc.deviceType, mst.CN_S_TASK_NO); if (mst.CN_S_BUSS_TYPE == "3楼叠盘下线") PLCControl.StackingComplete(plc.deviceType, mst.CN_S_TASK_NO); if (mst.CN_S_BUSS_TYPE == "3楼打包下线") PLCControl.PackingLineComplete4(plc.ip, mst.CN_S_SOURCE_NO,plc.port); if (mst.CN_S_BUSS_TYPE != "3楼包装取料") WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, 4); if (mst.CN_S_BUSS_TYPE == "四钴辅材入库") PLCControl.productInWare(mst.CN_S_START_BIT, mst.CN_S_TASK_NO, false); } } } /// /// 滚筒车起点到位信号:1112 取货完成:1212 /// /// /// internal static void PickupAndUnload(TN_I_TASK_MST mst,int code) { //3楼包装补空:包装机补空托流程——空托输送线交互(取空托,取空托完成) //3楼包装取料:3楼包装机取料去复称平台流程——进入包装机安全门后取料 var plc = Settings.GetPlcInfo().Where(a => a.location == mst.CN_S_START_BIT).FirstOrDefault(); if (plc != null) { if (code == 1112) { //三楼包装机进安全门内对接 if (mst.CN_S_BUSS_TYPE.Contains("3楼包装取料")) PLCControl.PickUpFullUnload(plc.ip, mst.CN_S_TASK_NO); } if (code == 1212) { //三楼包装机安全门内对接 二期没有滚筒车,因此无需向 包装机 写入 滚筒停止指令 //if (mst.CN_S_BUSS_TYPE.Contains("3楼包装取料")) PLCControl.PickUpFullComplete(plc.ip, mst.CN_S_TASK_NO); } } } #endregion #region 任务处理——拦截任务-电梯任务-取消任务 /// /// 拦截WMS发送的任务,因为WCS需要对任务类型进行分类处理 /// /// /// internal static bool Intercept(TN_I_TASK_MST mst) { bool result = false;// false:直接推送 true:拦截不推送 //对WMS下发的任务进行拦截,因为AMS需要对任务类型进行区分处理(调试通过后,可以考虑封装为方法) Console.WriteLine("任务拦截处理:执行开始!"); CMMLog.Info("任务拦截处理:执行开始!"); if (mst.CN_S_BUSS_TYPE == "电梯卸货" || mst.CN_S_BUSS_TYPE == "电梯取货") return result;//不拦截,直接推送 //满托转运任务:需要拦截创建 电梯一段任务,然后更改任务状态为执行中,不进行推送 if (mst.CN_S_BUSS_TYPE == "满托转运") { //插入电梯任务中间表 ElevatorTask ,修改 mst表任务来源号 后面 加_1 表示电梯一段任务 //满托转运 任务 ,目前只需要直接送入库区中,取消一楼拆盘机交互代码 2023.10.10 var task = MongoDBSingleton.Instance.FindOne(Query.EQ("wmsTaskNo", mst.CN_S_TASK_NO), "ElevatorTask"); if (task == null) { MongoDBSingleton.Instance.Update(Query.EQ("_id", mst._id), Update.Set("Ext1", mst.Ext1 + "满托转运").Set("CN_S_STATUS", "执行中"), UpdateFlags.None); MongoDBSingleton.Instance.Insert(new ElevatorTask { taskNo = mst.CN_S_TASK_NO, wmsTaskNo = mst.CN_S_TASK_NO, startBit = mst.CN_S_START_BIT, endBit = "", endBit02 = "", wmsEndBit = mst.CN_S_END_BIT, startFloor = 2, endFloor = 1, sendFlag = 0, create = DateTime.Now.ToString(), wmsSourceNo = mst.CN_S_SOURCE_NO, timeStramp = mst.CN_S_BATCH_NO }); } return result = true; } //辅材入库任务:需要拦截创建 电梯一段任务,然后更改任务状态为执行中,不进行推送 if (mst.CN_S_BUSS_TYPE == "辅材入库") { CMMLog.Info("辅材入库任务处理"); //插入电梯任务中间表 ElevatorTask ,修改 mst表任务来源号 后面 加_1 表示电梯一段任务 //辅材入库 任务 var task = MongoDBSingleton.Instance.FindOne(Query.EQ("wmsTaskNo", mst.CN_S_TASK_NO), "ElevatorTask"); if (task == null) { CMMLog.Info("中间表无电梯任务"); MongoDBSingleton.Instance.Update(Query.EQ("_id", mst._id), Update.Set("Ext1", mst.Ext1 + "辅材入库").Set("CN_S_STATUS", "执行中"), UpdateFlags.None); MongoDBSingleton.Instance.Insert(new ElevatorTask { taskNo = mst.CN_S_TASK_NO, wmsTaskNo = mst.CN_S_TASK_NO, startBit = mst.CN_S_START_BIT, endBit = "", endBit02 = "", wmsEndBit = mst.CN_S_END_BIT, startFloor = 1, endFloor = 2, sendFlag = 0, create = DateTime.Now.ToString(), wmsSourceNo = mst.CN_S_SOURCE_NO, timeStramp = mst.CN_S_BATCH_NO }); } return result = true; } if (mst.CN_S_BUSS_TYPE == "四钴成品出库" || mst.CN_S_BUSS_TYPE == "四钴辅材出库" ) { //3楼成品出库任务拦截 if (!OutWareTask(mst)) { CMMLog.Info($"{mst.CN_S_BUSS_TYPE}流程,任务更改为true"); result = true; } } if (mst.CN_S_BUSS_TYPE == "四钴辅材入库") { //3楼成品出库任务拦截 if (!InWareTask(mst)) { CMMLog.Info($"{mst.CN_S_BUSS_TYPE}流程,任务更改为true"); result = true; } } var bussTypeInfo = Settings.GetHouWeiCodeo().Where(a => a.location == mst.Ext1).FirstOrDefault(); if (bussTypeInfo != null) { if (bussTypeInfo.task != "5" && bussTypeInfo.task != "15") MongoDBSingleton.Instance.Update(Query.EQ("_id", mst._id), Update.Set("CN_S_BUSS_TYPE", bussTypeInfo.taskType).Set("Ext1", mst.Ext1 + bussTypeInfo.taskType), "TN_I_TASK_MST", UpdateFlags.None); else { var wmsinfo = MongoDBSingleton.Instance.FindOne(Query.EQ("trayCode", mst.CN_S_BATCH_NO), "WMSInfo"); if (wmsinfo == null) { MongoDBSingleton.Instance.Update(Query.EQ("_id", mst._id), Update.Set("CN_S_BUSS_TYPE", bussTypeInfo.taskType).Set("Ext1", mst.Ext1 + bussTypeInfo.taskType), "TN_I_TASK_MST", UpdateFlags.None); var transInfo = mst.transportInfo.First(); List list = new List(transInfo.itemWeight.Split(',')); // trayCode 托盘码(如果托盘码为:VWT 开头,表示这个叠包出的任务是 【小料】任务,插入数据时,需要插入多条数据,写入设备信息时,不需要写入托盘码且设备时间戳字段都一致) // itemWeight [产品需求重量,员工编号,单托毛重,是否叠底托] MongoDBSingleton.Instance.Insert(new WMSInfo { trayCode = mst.CN_S_BATCH_NO, itemCode = transInfo.itemCode, itemPCode = transInfo.itemPCode, location = transInfo.itemName, productWeight = list[0], trayCodeWeight = list[1], oneTrayWeight = list[2], palletLayers = list[3], addState = int.Parse(transInfo.itemFeatures), packageCode = transInfo.trayCode, TaskNo = mst.CN_S_TASK_NO, dateTime = DateTime.Now }); } else { Console.WriteLine("任务拦截处理:WMSINFO中间表目前正在有缓存架入叠托的任务在执行!"); CMMLog.Info("任务拦截处理:WMSINFO中间表目前正在有缓存架入叠托的任务在执行!"); } } result = true; } MongoDBSingleton.Instance.Update(Query.EQ("_id", mst._id), Update.Set("CN_S_STATUS", "未执行"), "TN_I_TASK_MST", UpdateFlags.None); Console.WriteLine("任务拦截处理:执行完毕!"); CMMLog.Info("任务拦截处理:执行完毕!"); return result; } internal static bool OutWareTask(TN_I_TASK_MST mst) { bool result = false; CMMLog.Info($"OutWareTask {mst.CN_S_BUSS_TYPE}任务流程处理开始 ,result:{result}"); //3楼成品出库流程 //成品出口输送线上有两个输送口 每条输送口可以生成两条任务,任务推送了之后给输送线数量加一,两条输送口轮流推送任务 //判断输送线模式和中间表模式都是出库模式 try { string endMachLoc = ""; //1、判断上料平台是否空闲,若空闲更改终点到上料平台 var plc = Settings.GetPlcInfo().Where(a => a.deviceType == "51" && a.enable == 1).ToList(); if (plc.Count > 0) { #region 判断输送线模式 变更注释 foreach(var a in plc) { bool action = false; var modeResult = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel { dataNum = 1, addr = a.readAddr, host = a.ip, port = a.port }); if (modeResult != null && modeResult.errCode == 0) { CMMLog.Debug($"OutWareTask:读取滚筒机ip:{a.ip},端口:{a.port}通道号为:{a.readAddr}的值为:{modeResult.result[0]}"); if (modeResult.result[0] == 2) { CMMLog.Debug($"OutWareTask:输送线为 入库模式,输送线点位:{a.location}"); break; } else { //读取中间表模式 var modelInfo = MongoDBSingleton.Instance.FindOne("ModeList"); if (modelInfo != null) { if (modelInfo.Mode == "入库模式") { CMMLog.Debug($"OutWareTask:中间表 ModeList 滚筒线模式不正确"); } else { action = true; int[] num = new int[1] { 1 }; var writeRes = OITcpHelper.RegisterWriteOutPutMulti(new OITcpHelper.RegisterWriteOutPutModelMulti { host = a.ip, addr = a.writeAddr, data = num, port = a.port }); } } else { CMMLog.Debug("OutWareTask:中间表 ModeList 为空"); } } } if (!action) { return false; } }; #endregion CMMLog.Info($"OutWareTask 11111"); string ssx01 = plc[0].location; string ssx02 = plc[1].location; //CMMLog.Info($"查询输送线当前点位:{a.location}"); var slptInfo1 = MongoDBSingleton.Instance.FindOne(Query.EQ("locCode", ssx01), "SLPTLoc"); if (slptInfo1 == null) { CMMLog.Info($"OutWareTask 222222"); endMachLoc = ssx01; slptInfo1 = new SLPTLoc { locCode = ssx01, taskNum = 1 }; MongoDBSingleton.Instance.Insert(slptInfo1); } else { CMMLog.Info($"OutWareTask 3333333"); var slptInfo2 = MongoDBSingleton.Instance.FindOne(Query.EQ("locCode", ssx02), "SLPTLoc"); if (slptInfo2 == null) { endMachLoc = ssx02; slptInfo2 = new SLPTLoc { locCode = ssx02, taskNum = 1 }; MongoDBSingleton.Instance.Insert(slptInfo2); } else { CMMLog.Info($"OutWareTask 44444444444"); var loc = slptInfo1.taskNum <= slptInfo2.taskNum ? slptInfo1 : slptInfo2; CMMLog.Info("OutWareTask :" + JsonConvert.SerializeObject(loc)); if (loc.taskNum < 2) { endMachLoc = loc.locCode; int num = loc.taskNum + 1; MongoDBSingleton.Instance.Update(Query.EQ("locCode", endMachLoc), Update.Set("taskNum", num), UpdateFlags.None); } } } if (!string.IsNullOrEmpty(endMachLoc)) { CMMLog.Info($"OutWareTask 55555"); //设备非空闲,计算终点到货架 //改任务的终点 MongoDBSingleton.Instance.Update(Query.EQ("CN_S_TASK_NO", mst.CN_S_TASK_NO), Update.Set("CN_S_END_BIT", endMachLoc), UpdateFlags.None); new SqlHelper().ExecuteSql($"update dbo.tn_am_task_mst set CN_S_END_BIE='{endMachLoc}',CN_S_END_AGVBIT = '{StockInstance.Instance.GetAGVCodeForBitCode(endMachLoc)}' where CN_S_TASK_NO = '{mst.CN_S_TASK_NO}'"); result = true; } else CMMLog.Info("OutWareTask 输送线不可用"); } else { CMMLog.Info("上料平台设备未配置"); } } catch (Exception ex) { CMMLog.Info($"OutWareTask err:" + ex.Message); } CMMLog.Info($"OutWareTask result:{result}"); return result; } internal static bool InWareTask(TN_I_TASK_MST mst) { bool result = false; CMMLog.Info($"InWareTask {mst.CN_S_BUSS_TYPE}任务流程处理开始 ,result:{result}"); //3楼辅材入库流程 //入库输送线上有两个输送口 //判断输送线模式和中间表模式都是入库模式 try { string endMachLoc = ""; string endLoc = ""; //1、判断上料平台是否空闲,若空闲更改终点到上料平台 var plc = Settings.GetPlcInfo().Where(a => a.location == mst.CN_S_START_BIT && a.enable == 1).First(); if (plc != null) { bool action = true; var modeResult = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel { dataNum = 1, addr = plc.readAddr, host = plc.ip, port = plc.port }); if (modeResult != null && modeResult.errCode == 0) { CMMLog.Debug($"InWareTask:读取滚筒机{plc.ip}通道号为:{plc.readAddr}的值为:{JsonConvert.SerializeObject(modeResult.result)}"); if (modeResult.result[0] == 1) { action = false; CMMLog.Debug($"InWareTask:输送线为 出库模式,输送线点位:{plc.location}"); } else { //读取中间表模式 var modelInfo = MongoDBSingleton.Instance.FindOne("ModeList"); if (modelInfo != null) { if (modelInfo.Mode == "出库模式") { action = false; CMMLog.Debug($"InWareTask:中间表 ModeList 滚筒线模式不正确"); } else { int[] num = new int[1] { 2 }; var writeRes = OITcpHelper.RegisterWriteOutPutMulti(new OITcpHelper.RegisterWriteOutPutModelMulti { host = plc.ip, addr = plc.writeAddr, data = num, port = plc.port }); return true; } } else { action = false; CMMLog.Debug("InWareTask:中间表 ModeList 为空"); } } } if (!action) { return false; } } } catch (Exception ex) { CMMLog.Info($"InWareTask err:" + ex.Message); } CMMLog.Info($"InWareTask result:{result}"); return result; } public class ModeList { public ObjectId _id { get; set; } /// /// 模式 /// public string Mode { get; set; } } /// /// 3楼成品出库任务中间表 /// public class SLPTLoc { public ObjectId _id { get; set; } public string locCode { get; set; } public int taskNum { get; set; } public int count { get; set; } = 0; } /// /// 线程读取电梯任务中间表,推送一条电梯任务 待确认:这里推送应该根据任务号后缀“_2”判断是否为第二段任务,首先推送第二段任务,其次,推送最早的第一段任务 /// internal static void CheckElevatorTask() { CMMLog.Info("电梯任务线程:执行开始!"); //读取mongo ElevatorTask 表任务,先判断有没有 已经推送的,如果没有 try { bool isCreateTask = false;// 是否可以创建电梯任务 var eleTask = MongoDBSingleton.Instance.FindOne(Query.EQ("CN_S_BUSS_TYPE", "电梯卸货"), "TN_I_TASK_MST"); if (eleTask != null) { if (WorkFlowAction.ExistsTrackLogs(eleTask.CN_S_TASK_NO, 1, 6)) isCreateTask = true; } else isCreateTask = true; if (isCreateTask) { var taskInfo = MongoDBSingleton.Instance.FindOne(Query.EQ("sendFlag", 0), "ElevatorTask"); if (taskInfo != null) { CMMLog.Info("电梯任务线程:创建一条从当前起点前往当前楼层等待点的任务"); //创建一条从当前起点前往当前楼层等待点的任务,等收到小车在等待点发送的信号之后, //判断两部电梯哪个可以使用,在创建一段二段电梯任务,回归原始流程 var mst = MongoDBSingleton.Instance.FindOne(Query.EQ("CN_S_TASK_NO", taskInfo.taskNo), "TN_I_TASK_MST"); if (mst != null && mst.CN_S_BUSS_TYPE == "满托转运")//taskInfo.startBit == location { CMMLog.Info($"电梯任务线程:满托转运等待点{Settings.Wait02}"); //满托转运 AMSHelper.CreateTask(taskInfo.wmsTaskNo + "_1", taskInfo.startBit, Settings.Wait02, "电梯卸货", 10, taskInfo.timeStramp); } else { CMMLog.Info($"电梯任务线程:空托出库等待点{Settings.Wait01}"); //空托出库 AMSHelper.CreateTask(taskInfo.wmsTaskNo + "_1", taskInfo.startBit, Settings.Wait01, "电梯卸货", 10, taskInfo.timeStramp); } //根据 taskNo 查询任务,推送,修改ams任务的终点是 电梯任务的起点 sendTask MongoDBSingleton.Instance.Update(Query.EQ("taskNo", taskInfo.taskNo), Update.Set("sendFlag", 1).Set("taskNo", taskInfo.wmsTaskNo + "_1"), "ElevatorTask", UpdateFlags.None); } else CMMLog.Info("电梯任务线程:当前电梯中间表无任务!"); } else Console.WriteLine($"电梯任务线程:当前电梯任务已有两条处于执行中,不允许再创建 电梯卸货 任务。"); } catch(Exception ex) { Console.WriteLine($"电梯任务线程执行异常:{ex.Message}"); } CMMLog.Info("电梯任务线程:执行结束!"); } /// /// 电梯开门关门服务 /// /// /// true 开门请求 false关门请求 /// internal static void OperateDoor(TN_I_TASK_MST mst, int code) { //目前仅存在 入库任务(三楼至一楼) 2023.10.10 更新 //1012-4(二段任务起点) 1013-6(一段任务终点) //根据任务类型或者起点终点判断 这里判断小车是去卸货还是取货 var query = Query.EQ("taskNo",mst.CN_S_SOURCE_NO); //任务号查询 ElevatorTask ElevatorTask task = MongoDBSingleton.Instance.FindOne(query, "ElevatorTask"); // string PlcBit04 = Settings.GetPlcInfo().Where(a => a.deviceType == "4").FirstOrDefault().location;//打包线下线口 // string PlcBit07 = Settings.GetPlcInfo().Where(a => a.deviceType == "7").FirstOrDefault().location;//一楼拆盘机点位 if (code == 1312 || code == 6) { //卸货-请求开门 卸货完成 给plc发消息,卸货任务 让plc startFloor 开门,取货任务 让plc endFloor开门 //入库任务一段任务终点货梯进入 if (code == 1312) PLCControl.RuKuOne1013(mst, task.startFloor);// && task.startBit == PlcBit04 && task.wmsEndBit == PlcBit07 else { //if (task.startBit == PlcBit04 && task.wmsEndBit == PlcBit07) //{ //入库任务一段任务终点货梯退出 //如果是 卸货任务 关门 //给电梯plc发信号,让他从startfloor 到endfloor if (PLCControl.RuKuOne6(mst, task.endFloor)) { //关门同时生成一条对应楼层的取货任务(二段任务) AMSHelper.SetStatus(mst.CN_S_TASK_NO, 1, "2", "0", true); string startBit = (mst.CN_S_START_BIT == Settings.Wait01 || mst.CN_S_END_BIT == Settings.Wait01) ? Settings.Wait02 : Settings.Wait01; AMSHelper.CreateTask(task.wmsTaskNo + "_2", startBit, task.wmsEndBit, "电梯取货", 10, mst.CN_S_BATCH_NO); //查询更新电梯任务中间表的任务号为二段任务 MongoDBSingleton.Instance.Update(Query.EQ("taskNo", mst.CN_S_SOURCE_NO), Update.Set("taskNo", task.wmsTaskNo + "_2"), UpdateFlags.None); } //} } } else if(code == 1012 || code == 4) { // && task.startBit == PlcBit04 && task.wmsEndBit == PlcBit07 // if (task.startBit == PlcBit04 && task.wmsEndBit == PlcBit07) //取货-请求开门 取货完成 4_6 小车离开货梯,一段任务完成,结束一段任务,开始推送二段任务 if (code == 1012) PLCControl.RuKuOne1012(mst, task.endFloor);//入库任务二段任务起点货梯请求开门 else PLCControl.RuKuOne4(mst, task.endFloor);//入库任务二段任务起点货梯请求关门 } } /// /// 取消任务处理 /// /// public static void TaskCancel(TN_I_TASK_MST mst) { CMMLog.Info($"进入取消任务流程!任务类型:{mst.CN_S_BUSS_TYPE}"); if (mst.CN_S_BUSS_TYPE.Contains("3楼包装取料")) { CMMLog.Info($"任务类型:{mst.CN_S_BUSS_TYPE},任务操作:查询表中已当前起点为包装机号的数据machineNo,不为空,删除!任务号:{mst.CN_S_TASK_NO},任务起点:{mst.CN_S_START_BIT},任务终点:{mst.CN_S_END_BIT}"); if (mst.CN_S_BUSS_TYPE.Contains("四钴")) { var tray = MongoDBSingleton.Instance.FindOne(Query.EQ("machineNo", mst.CN_S_START_BIT), "MachineInfo"); if (tray != null) { MongoDBSingleton.Instance.Remove(Query.EQ("machineNo", mst.CN_S_START_BIT), RemoveFlags.Single); if (ERPService.ERPSwitch01 == "0") MongoDBSingleton.Instance.Remove(Query.EQ("machineNo", mst.CN_S_START_BIT), "MachineInfoTetracobalt", RemoveFlags.Single); } } else { var tray = MongoDBSingleton.Instance.FindOne(Query.EQ("machineNo", mst.CN_S_START_BIT), "MachineInfo"); if (tray != null) { MongoDBSingleton.Instance.Remove(Query.EQ("machineNo", mst.CN_S_START_BIT), RemoveFlags.Single); if (ERPService.ERPSwitch01 == "0") MongoDBSingleton.Instance.Remove(Query.EQ("machineNo", mst.CN_S_START_BIT), "MachineInfoTwo", RemoveFlags.Single); } } } if (mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托") { var plc = Settings.GetPlcInfo().Where(a => a.deviceType == "3").FirstOrDefault(); if (plc != null) { var machine = MongoDBSingleton.Instance.FindOne(Query.EQ("trayCode", mst.CN_S_BATCH_NO), "WMSInfo"); if (machine != null) { #region 写多个MODBUS数据 if (Settings.cacheStackWrite == "0") { int[] num = DiePan(machine); CMMLog.Info($"send num:"); CMMLog.Info(JsonConvert.SerializeObject(num)); var wirteall01 = OITcpHelper.RegisterWriteOutPutMulti(new OITcpHelper.RegisterWriteOutPutModelMulti { addr = plc.writeAddr + 10, host = plc.ip, port = plc.port, data = num }); } else WriteCacheStackingData(plc, mst, machine); #endregion MongoDBSingleton.Instance.Remove(Query.EQ("trayCode", mst.CN_S_BATCH_NO), "WMSInfo", RemoveFlags.Single); } } } if (mst.CN_S_BUSS_TYPE == "电梯卸货" || mst.CN_S_BUSS_TYPE == "电梯取货" || mst.CN_S_BUSS_TYPE == "满托转运") { CMMLog.Info($"任务类型:{mst.CN_S_BUSS_TYPE},任务操作:查询表中以当前任务号或来源号为任务号taskNo表字段的数据,不为空,删除!"); CMMLog.Info($"如果是子任务删除,还需设置主任务,也就是当前任务对应的daintiness中间表中wmsSourceNo字段所对应的任务"); var query = Query.Or(Query.EQ("taskNo", mst.CN_S_TASK_NO), Query.EQ("taskNo", mst.CN_S_SOURCE_NO)); var cancel = MongoDBSingleton.Instance.FindOne(query, "ElevatorTask"); if (cancel != null) { CMMLog.Info($"查询主表中以电梯任务当前任务中间表中wmsSource为来源号的任务"); var master = MongoDBSingleton.Instance.FindOne(Query.EQ("CN_S_SOURCE_NO", cancel.wmsSourceNo), "TN_I_TASK_MST"); if (master != null) { callTaskProcessing.CancelTask(master.CN_S_TASK_NO, "1"); AMSHelper.SetStatus(master.CN_S_TASK_NO, 1, "7", "0", true); WMSHelper.ExecuteState(master.CN_S_TASK_NO,7); callTaskProcessing.DeleteTask(master.CN_S_TASK_NO); } MongoDBSingleton.Instance.Remove(query, RemoveFlags.Single); } } MongoDBSingleton.Instance.Remove(Query.EQ("TaskNo", mst.CN_S_TASK_NO), RemoveFlags.None); CMMLog.Info($"取消任务流程结束!"); } /// /// 强制完成任务处理 /// /// /// public static void ForceComplete(TN_I_TASK_MST mst, TN_I_TASK_DTL_ACTION action) { CMMLog.Info($"强制完成任务处理:收到2信号之后特殊任务类型处理:任务号:{mst.CN_S_TASK_NO},任务类型:{mst.CN_S_BUSS_TYPE}"); if (mst.CN_S_BUSS_TYPE == "电梯取货" || mst.CN_S_BUSS_TYPE == "电梯卸货" || mst.CN_S_BUSS_TYPE == "满托转运" || mst.CN_S_BUSS_TYPE == "空托出库") { var ele = MongoDBSingleton.Instance.FindOne(Query.EQ("taskNo", mst.CN_S_SOURCE_NO), "ElevatorTask"); if (ele != null) { AMSHelper.SetStatus(ele.wmsTaskNo, 1, "2", action.CN_S_DEVICE_CODE, true); WMSHelper.ExecuteState(ele.wmsSourceNo, 2); MongoDBSingleton.Instance.Remove(Query.EQ("taskNo", mst.CN_S_SOURCE_NO), RemoveFlags.Single); MongoDBSingleton.Instance.Remove(Query.EQ("CN_S_TASK_NO", ele.wmsTaskNo), RemoveFlags.Single); } } if(mst.CN_S_BUSS_TYPE.Contains("3楼包装取料")) { MongoDBSingleton.Instance.Remove(Query.EQ("trayCode", mst.CN_S_BATCH_NO), RemoveFlags.Single); if (ERPService.ERPSwitch01 == "0") MongoDBSingleton.Instance.Remove(Query.EQ("trayCode", mst.CN_S_BATCH_NO), "MachineInfoTwo", RemoveFlags.Single); } } /// /// 电梯取消删除任务 /// /// /// public static void ForceCancel(TN_I_TASK_MST mst, TN_I_TASK_DTL_ACTION action) { CMMLog.Info($"取消任务处理:收到2信号之后特殊任务类型处理:任务号:{mst.CN_S_TASK_NO},任务类型:{mst.CN_S_BUSS_TYPE}"); if (mst.CN_S_BUSS_TYPE == "电梯取货" || mst.CN_S_BUSS_TYPE == "电梯卸货" || mst.CN_S_BUSS_TYPE == "满托转运" || mst.CN_S_BUSS_TYPE == "空托出库") { var ele = MongoDBSingleton.Instance.FindOne(Query.EQ("taskNo", mst.CN_S_SOURCE_NO), "ElevatorTask"); if (ele != null) { AMSHelper.SetStatus(ele.wmsTaskNo, 1, "7", "0", true); WMSHelper.ExecuteState(ele.wmsSourceNo, 7); MongoDBSingleton.Instance.Remove(Query.EQ("taskNo", mst.CN_S_SOURCE_NO), "ElevatorTask", RemoveFlags.Single); MongoDBSingleton.Instance.Remove(Query.EQ("CN_S_TASK_NO", ele.wmsTaskNo), "TN_I_TASK_MST", RemoveFlags.Single); } } if (mst.CN_S_BUSS_TYPE.Contains("3楼包装取料")) { if (mst.CN_S_BUSS_TYPE.Contains("四钴")) { MongoDBSingleton.Instance.Remove(Query.EQ("trayCode", mst.CN_S_BATCH_NO), RemoveFlags.Single); if (ERPService.ERPSwitch01 == "0") MongoDBSingleton.Instance.Remove(Query.EQ("trayCode", mst.CN_S_BATCH_NO), "MachineInfoTetracobalt", RemoveFlags.Single); } else { MongoDBSingleton.Instance.Remove(Query.EQ("trayCode", mst.CN_S_BATCH_NO), RemoveFlags.Single); if (ERPService.ERPSwitch01 == "0") MongoDBSingleton.Instance.Remove(Query.EQ("trayCode", mst.CN_S_BATCH_NO), "MachineInfoTwo", RemoveFlags.Single); } } } #endregion #region 充电任务 public static string battery = Settings.BatteryTime; internal static void AGVBatteryTime() { CMMLog.Info("进入充电任务流程判断:执行开始!"); var now = DateTime.Today; string date = now.Year.ToString() + "-" + now.Month.ToString() + "-" + now.Day.ToString() + " " + battery; DateTime dt = Convert.ToDateTime(date); //十分钟以内判断当前充电桩是否有小车在充电,没有则推送当前充电桩电量最低的一辆小车去充电,并写入充电桩状态 CMMLog.Info("进入充电任务流程:获取配置文件时间,并判断当前时间减去配置文件时间是否在20分钟以内!"); if (DateTime.Now.Subtract(dt).TotalMinutes <= 20 && DateTime.Now.Subtract(dt).TotalMinutes > 0) { //先判断中间表是否有当前充电桩的状态,有则不操作,反之进入小车电量查询 CMMLog.Info("进入充电任务流程:当前时间满足生成充电任务基本要求,开始判断ChargingPile配置项中当前充电桩状态是否开启");//ChargingPile var list = Settings.GetChargingPile().Where(a => a.enable == "1").ToList(); if (list.Count > 0) { //CMMLog.Info("04"); list.ForEach(a => { //CMMLog.Info("05"); var margin = MongoDBSingleton.Instance.FindOne(Query.EQ("marginGroup", int.Parse(a.charginGroup)), "MarginAGV"); int agvBattery = 1000, agvNo = 0, marginGroup = 0; if (margin == null) { CMMLog.Info($"进入充电任务流程:判断当前充电桩分组{a.charginGroup}能否在ChargingPile配置项中查找到且enable为开启状态!"); var list2 = Settings.GetChargingPile().Where(b => b.charginGroup == a.charginGroup && b.enable == "1").ToList(); list2.ForEach(b => { CMMLog.Info($"进入充电任务流程:判断当前车号能否在小车车身状态表中查询到数据,车号agvNo:{b.agvNo}"); var battery = MongoDBSingleton.Instance.FindOne(Query.EQ("agvNo", b.agvNo), "HangChaAGV"); if(battery != null) { if (int.Parse(battery.agvBattery) < agvBattery) { //CMMLog.Info($"进入充电任务流程:06 "); agvBattery = int.Parse(battery.agvBattery); agvNo = int.Parse(b.agvNo); marginGroup = int.Parse(b.charginGroup); } } else CMMLog.Info($"进入充电任务流程:error:当前车号在HangChaAgv中间表中查询不到数据!车号:{b.agvNo},所属充电桩:{b.charginGroup}"); }); //推送小车前往指定充电桩,并插入中间表状态 var agv = MongoDBSingleton.Instance.FindOne(Query.And(Query.EQ("agvNo", agvNo),Query.EQ("marginGroup", marginGroup)), "MarginAGV"); if(agv == null && agvNo != 0) { TSHelper.SendChargeTask(agvNo.ToString(), true); //增加时间 MongoDBSingleton.Instance.Insert(new MarginAGV { agvNo = agvNo, marginGroup = marginGroup ,dateTime = DateTime.Now}); } } }); } } else { CMMLog.Info("进入充电任务流程:超过十分钟,删除中间表"); //超过十分钟,删除中间表 MongoDBSingleton.Instance.ReomveAll(); } CMMLog.Info("进入充电任务流程判断:执行结束!"); } #endregion /// /// 获取杭叉AGV表里小车电量,并将其写入MODBUS中 /// public static int[] GetBatteryHang() { int[] num = new int[5]; var bits = Settings.GetChargingAgvNo(); CMMLog.Info($"获取小车车号信息:{JsonConvert.SerializeObject(bits)}");//6723 for (int i = 0; i < num.Length; i++) { var battery = MongoDBSingleton.Instance.FindOne(Query.EQ("agvNo", bits[i]), "HangChaAGV"); num[i] = battery == null ? 0 : int.Parse(battery.agvBattery); } CMMLog.Info($"获取小车电量:{JsonConvert.SerializeObject(num)}"); return num; } /// /// 电梯任务中间表,通过线程创建的跨楼层任务都会被拦截放入此表中 /// public class ElevatorTask { public ObjectId _id { get; set; } public string taskNo { get; set; } public string wmsTaskNo { get; set; } /// /// WMS来源号 /// public string wmsSourceNo { get; set; } /// /// 二段电梯任务终点 读配置文件 /// public string wmsEndBit { get; set; } /// /// 一段任务电梯要到达的楼层 /// public int startFloor { get; set; } /// /// 一段电梯任务起点 读配置文件 /// public string startBit { get; set; } /// /// 二段任务电梯要到达的楼层 /// public int endFloor { get; set; } /// /// 一段电梯任务终点/二段电梯任务起点 读配置文件 /// public string endBit { get; set; } /// /// 二段电梯任务起点 /// public string endBit02 { get; set; } /// /// 任务发送状态 0:表示任务未启动 1:表示任务执行中 /// public int sendFlag { get; set; } public string occupy { get; set; } = ""; /// /// 时间戳--满托下线时存在数据,存入ext1字段中 /// public string timeStramp { get; set; } /// /// 任务创建时间 /// public string create { get; set; } } /// /// WMS叠盘机任务中存储信息 /// public class WMSInfo { public ObjectId _id { get; set; } /// /// 产品型号 11 60 /// public string itemCode { get; set; } /// /// 批次号 30 30 /// public string itemPCode { get; set; } /// /// 设备通道数据3——托盘码 /// public string trayCode { get; set; } /// /// 设备通道数据1——包装机号 /// public string location { get; set; } /// /// 设备通道数据2——产品需求重量:32位整数 /// public string productWeight { get; set; } /// /// 设备通道数据2——托盘重量:32位整数 /// public string trayCodeWeight { get; set; } /// /// 设备通道数据2——单托实际重量:32位整数 /// public string oneTrayWeight { get; set; } /// /// 是否叠底托(1-不叠底托,2-叠底托) /// public string palletLayers { get; set; } /// /// 设备通道数据1——是否需要叠包:1:叠包,2:不叠包 /// public int addState { get; set; } /// /// 设备通道数据1——袋号(001,002,003…999) /// public string packageCode { get; set; } public DateTime dateTime { get; set; } public string TaskNo { get; set; } } /// /// 充电任务中间表 /// public class MarginAGV { public ObjectId id { get; set; } public int agvNo { get; set; } public int marginGroup { get; set; } public DateTime dateTime { get; set; } } /// /// 去除字符串中NULL字符串 /// internal static string RemoveNull(string str) { CMMLog.Info($"remove:{str}"); string result = ""; string empty = null; for(int i = 0; i <= str.Length-1; i++) { if(str.Substring(i,1) != empty && str.Substring(i, 1) != "" && str.Substring(i, 1) != " " && str.Substring(i,1) != "\0") { //CMMLog.Debug($"str.substring:{i},{str.Substring(i, 1)}"); result = result + str.Substring(i, 1); } //else //{ // return result; //} } return result; } /// /// 获取时间戳 /// /// 数据位数:值:32|64 含义:32位|64位 /// 获取时间类型:值:1|2 含义:1-秒级 2-毫秒级 /// 获取时间Utc类型:值:1|2 含义:1-本地时间 2-Utc时间 /// public static string GetTimeStamp(int DataBitType, int TimeType, int TimeUtcType) { string timeStamp = ""; //时间戳打印 DateTime dateTime = TimeUtcType == 1 ? DateTime.Now : DateTime.UtcNow;//本地时间|Utc时间获取 TimeSpan ts = dateTime - new DateTime(1970, 1, 1, 0, 0, 0, 0);//时间戳获取 double tsTime = TimeType == 1 ? ts.TotalSeconds : ts.TotalMilliseconds;//秒级|毫秒级时间获取 string TimeTypeInfo = TimeType == 1 ? "秒级" : "毫秒级"; string TimeUtcTypeInfo = TimeUtcType == 1 ? "本地时间" : "Utc时间"; timeStamp = DataBitType == 32 ? Convert.ToInt32(tsTime).ToString() : Convert.ToInt64(tsTime).ToString(); Console.WriteLine($"时间戳打印:{DataBitType}位,{TimeTypeInfo},{TimeUtcTypeInfo},时间戳:{timeStamp}"); return timeStamp; } } }