using Hanhe.iWCS.Business; using Hanhe.iWCS.Common; using Hanhe.iWCS.Interface; using Hanhe.iWCS.MData; using Hanhe.iWCS.Model; using Hanhe.iWCS.Model.AMS; using Microsoft.Owin.Hosting; using MongoDB.Bson; using MongoDB.Driver; using MongoDB.Driver.Builders; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using static Hanhe.iWCS.JingmenGEMNorthProtocol.ApiHelper; using static Hanhe.iWCS.JingmenGEMNorthProtocol.EnentListen; using static Hanhe.iWCS.JingmenGEMNorthProtocol.MESHelper; using static Hanhe.iWCS.JingmenGEMNorthProtocol.PLCControl; using static Hanhe.iWCS.JingmenGEMNorthProtocol.ProcessHelper; namespace Hanhe.iWCS.JingmenGEMNorthProtocol { /// /// 设备协议解析类 /// public class ProtocolAnalysis : IProtocolAnalysis { private EquipmentCommandEQBLL CommandEQBLL = new EquipmentCommandEQBLL(); private ICallTaskProcessing iCallTask = new ICallTaskProcessing(); private Logger AMSLoggerAPI = new Logger(); public void StringRequestInfo(string protocolMsg, string address, int port) { } public void StringRequestInfo(string protocolMsg, string address, int port, string sessionID) { //16进制接收 protocolMsg = protocolMsg.Trim();//3f 00 11 20 30 40 50 60 70 80 90 A0 24 24 if (protocolMsg != "") { } #region 握手反馈指令 //UpdateHandshakeFeedbackCode(protocolMsg); PLCControl.Analysis(protocolMsg); #endregion } public void UpdateHandshakeFeedbackCode(string commandText) { var query = Query.And(Query.EQ("CommandText", commandText + "$$"), Query.EQ("Status", Constants.COMMANDEQ_STATUS_SENDED)); EquipmentCommandEQ eq = MongoDBSingleton.Instance.FindOne(query, typeof(EquipmentCommandEQ).Name); if (eq != null) { UpdateBuilder updateBuider = Update.Set("isHandshake", 1).Set("FeedbackCode", commandText); MongoDBSingleton.Instance.Update(query, updateBuider, UpdateFlags.None); } } private static bool api = false; public ProtocolAnalysis() { if (!api) { Startup(); api = true; } } public static void Startup() { Console.WriteLine("Startup ApiController"); Task.Run(() => { var url = "http://+:8801"; using (WebApp.Start(url)) { Console.WriteLine("Running on {0}", url); Console.ReadLine(); } }); } public int workflowToDeviceDriver(TN_I_TASK_DTL_ACTION action) { int iResult = 0; CMMLog.Info($"任务处理:Action Code:{action.CN_N_ACTION_CODE},TaskNo:{action.CN_S_TASK_NO}"); switch (action.CN_N_ACTION_CODE) { case 1012: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "起点申请进入"); break; case 1312: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "电梯安全对接"); break; case 1112: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "滚筒车起点到位"); break; case 1212: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "滚筒车取货完成通知PLC"); break; case 1013: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "终点申请进入"); break; case 1113: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "滚筒车终点到位"); break; case 1213: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "滚筒车卸货完成通知PLC"); break; case 1313: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "拍照扫码"); break; } if (action.CN_N_ACTION_CODE == 1027) { var mst = iCallTask.FindTask(action.CN_S_TASK_NO); if (mst != null ) { if (ProcessHelper.Intercept(mst)) iResult = 1027;//拦截更改 WCS 任务类型(将 WMS 任务类型更改为 WCS 任务类型,因为 WCS 需要根据任务类型进行对应任务流程处理) else { CMMLog.Info($"推送任务:任务号{mst.CN_S_TASK_NO},任务类型:{mst.CN_S_BUSS_TYPE}"); bool IsSendTask = true; // 3楼缓存架入叠托 任务 取货完成才允许推送下一条 if (mst.CN_S_BUSS_TYPE.Contains("缓存架入叠托")) { var taskInfoList = MongoDBSingleton.Instance.Find(Query.And(Query.NotIn("CN_S_STATUS", new List() { "未执行", "待推送" }), Query.EQ("CN_S_END_BIT", mst.CN_S_END_BIT)), "TN_I_TASK_MST"); if (taskInfoList.Count > 0) { // 遍历查询执行中的这些任务是否都已经取货完成,如果都取货完成,则可以推送此任务 for (int i = 0; i < taskInfoList.Count; i++) { if (!ProcessHelper.CheckStartFreeTwo(taskInfoList[i].CN_S_START_BIT)) { IsSendTask = false; Console.WriteLine($"缓存架入叠托 任务拦截:该任务 :{taskInfoList[i].CN_S_TASK_NO} 未取货完成,不允许推送当前任务:{mst.CN_S_TASK_NO}"); } } } } if (IsSendTask) ProcessHelper.SendTask(mst); } } iResult = 1027; } #region 取消 if (action.CN_N_ACTION_CODE == 7) { TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO); string agvNo = action.CN_S_DEVICE_CODE; if (mst != null) { //请求前 if (action.CN_N_ORDER == 0) { WorkFlowAction.TrackLog(action.CN_S_TASK_NO, 0, 7, "收到ams取消请求"); } if (action.CN_N_ORDER == 1 || action.CN_N_ORDER == 0) { ProcessHelper.TaskCancel(mst); iCallTask.CancelTask(mst.CN_S_TASK_NO, "1"); AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, "7", "0", true); if (mst.CN_S_BUSS_TYPE != "电梯取货" && mst.CN_S_BUSS_TYPE != "电梯卸货" && !mst.CN_S_BUSS_TYPE.Contains("包装取料")) WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE); iCallTask.DeleteTask(mst.CN_S_TASK_NO); } if (mst.CN_S_BUSS_TYPE == "电梯取货" || mst.CN_S_BUSS_TYPE == "电梯卸货" || mst.CN_S_BUSS_TYPE == "满托转运" || mst.CN_S_BUSS_TYPE == "空托出库") { ProcessHelper.ForceCancel(mst, action); MongoDBSingleton.Instance.Remove(Query.EQ("timeStamp", mst.CN_S_BATCH_NO), "TimeCuoInfoCom", RemoveFlags.None); } if (mst.CN_S_BUSS_TYPE.Contains("包装补空")) PLCControl.PickUpBlankComplete(mst.CN_S_END_BIT); } } #endregion #region 强制完成 if (action.CN_N_ACTION_CODE == 1022) { TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO); if (mst != null) { ProcessHelper.ForceComplete(mst, action); if (mst.CN_S_BUSS_TYPE.Contains("缓存架入叠托")) { 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:" + 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); } } } MongoDBSingleton.Instance.Remove(Query.EQ("TaskNo", mst.CN_S_TASK_NO), RemoveFlags.Single); WorkFlowAction.TrackLog(mst.CN_S_TASK_NO, 1, 1022, "收到ams强制完成请求"); AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, "1022", "0", true); iCallTask.CancelTask(mst.CN_S_TASK_NO, "1"); if (mst.CN_S_BUSS_TYPE != "电梯取货" && mst.CN_S_BUSS_TYPE != "电梯卸货" && !mst.CN_S_BUSS_TYPE.Contains("包装取料")) WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE); //if (mst.CN_S_BUSS_TYPE == "电梯取货" && mst.CN_S_BUSS_TYPE == "电梯卸货") // MongoDBSingleton.Instance.ReomveAll(); if (mst.CN_S_BUSS_TYPE == "包装线补空") PLCControl.PickUpBlankComplete(mst.CN_S_END_BIT); if (ERPService.SendERPTaskType.Contains(mst.CN_S_BUSS_TYPE) && ERPService.ERPSwitch01 == "1") ERPService.SendERPTaskInfo(mst); iCallTask.DeleteTask(mst.CN_S_TASK_NO); } } #endregion if (action.CN_N_ACTION_CODE == 13) { var task = iCallTask.FindTask(action.CN_S_TASK_NO); AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), "", "AGV调整任务优先级成功" + action.Ext1); } #region 任务状态委托(1-开始;3-开始取货;4-取货完成;5-开始卸货;6-卸货完成;2-完成) if (action.CN_N_ACTION_CODE == 1 || action.CN_N_ACTION_CODE == 4 || action.CN_N_ACTION_CODE == 5 || action.CN_N_ACTION_CODE == 6 || action.CN_N_ACTION_CODE == 2) { WorkFlowAction.TrackLog(action.CN_S_TASK_NO, 1, action.CN_N_ACTION_CODE, ""); AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, action.CN_N_ACTION_CODE.ToString(), action.CN_S_DEVICE_CODE, true); if (action.CN_N_ACTION_CODE == 2) AMSHelper.SetStatusTwo(action.CN_S_TASK_NO); TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO); if (mst != null) { if (!string.IsNullOrEmpty(action.CN_S_DEVICE_CODE)) { // 因调用AMSAPI无法在开始取货时更新车号,因此此处直接连接AMS数据库进行更新 MoboxHelper.UpdateEndBit(mst.CN_S_TASK_NO, action.CN_S_DEVICE_CODE); if (action.CN_N_ACTION_CODE != 1 && action.CN_N_ACTION_CODE != 2) MoboxHelper.UpdateTaskState(mst.CN_S_TASK_NO, action.CN_N_ACTION_CODE); } #region 写入小车状态 writeAGVState(action); #endregion if (action.CN_N_ACTION_CODE == 1) { if (mst.CN_S_BUSS_TYPE != "电梯取货" && mst.CN_S_BUSS_TYPE != "电梯卸货" && !mst.CN_S_BUSS_TYPE.Contains("包装取料")) WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE); } if (action.CN_N_ACTION_CODE == 4) { CMMLog.Info($"SetStatus:收到任务号 4:{action.CN_S_TASK_NO}"); CMMLog.Info($"收到信号:{action.CN_N_ACTION_CODE},任务号:{action.CN_S_TASK_NO},开始根据任务号查询主表中对应数据!"); if (mst.CN_S_BUSS_TYPE == "包装线补空") PLCControl.PickUpBlankComplete(mst.CN_S_END_BIT, mst.CN_S_START_BIT); if (mst.CN_S_BUSS_TYPE.Contains("包装取料")) PLCControl.CheckUpReqUnload(mst.CN_S_END_BIT, mst.CN_S_TASK_NO); if (mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托") WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE); } if (action.CN_N_ACTION_CODE == 5) { } if (action.CN_N_ACTION_CODE == 6) { if (mst.CN_S_BUSS_TYPE.Contains("缓存架入叠托")) { CMMLog.Info($"缓存架入叠托:收到信号6,开始准备写入叠盘机数据。"); PLCControl.writeStackingMouth6(mst.CN_S_END_BIT, mst.CN_S_TASK_NO); } if (mst.CN_S_BUSS_TYPE.Contains("包装取料")) { //卸货完成,中间表SecondWeighState full改为1 string x = mst.CN_S_END_BIT.Contains("2") ? "23" : "2"; string PlcBit02 = Settings.GetPlcInfo().Where(a => a.deviceType == x).FirstOrDefault().location; UpdateBuilder update = Update.Set("full", 1); MongoDBSingleton.Instance.Update(Query.EQ("location", PlcBit02), update, "SecondWeighState", UpdateFlags.None); } if (mst.CN_S_BUSS_TYPE.Contains("包装补空")) { //将数据记录到中间表 var agvloc = Settings.GetAGVLocationList().Where(a => a.location == mst.CN_S_END_BIT).First(); if (agvloc != null) { var quantity = agvloc.quantity; CMMLog.Info($"包装补空,终点{mst.CN_S_END_BIT}站点个数:{quantity}"); var emptyInfo = MongoDBSingleton.Instance.FindOne(Query.EQ("Bit", mst.CN_S_END_BIT), "BZEmptyPoint"); if (emptyInfo != null) { MongoDBSingleton.Instance.Update(Query.EQ("Bit", mst.CN_S_END_BIT), Update.Set("Quantity", quantity), UpdateFlags.None); } else { MongoDBSingleton.Instance.Insert(new BZEmptyPoint { Bit = mst.CN_S_END_BIT, Quantity = quantity }); } } } if (mst.CN_S_BUSS_TYPE.Contains("打包下线")) { var connInfo = MongoDBSingleton.Instance.FindOne(Query.EQ("Bit", mst.CN_S_START_BIT), "ConnectingBits"); if (connInfo != null) { CMMLog.Info($"connInfo:{connInfo.timeCuo}"); var time = MongoDBSingleton.Instance.FindOne(Query.EQ("timeStamp", int.Parse(connInfo.timeCuo)), "TimeCuoInfoCom"); //var db = new SqlHelper().GetInstance(false); if(time != null) { string date = time.BusinessDate.Substring(0, 4) + "-" + time.BusinessDate.Substring(4, 2) + "-" + time.BusinessDate.Substring(6); //double qty = time.totalWeight CMMLog.Info($"date:{date}"); string fStockNumber = "CK004"; //物料编码GEM-6A-5、GEM-4A-5入CK007,其余的入CK004 if (time.batchNumber == "GEM-6A-5" || time.batchNumber == "GEM-4A-5") { fStockNumber = "CK007"; } string FDept = "G02000501"; if(mst.CN_S_BUSS_TYPE .Contains("一号厂房")) FDept = "G02001106"; CMMLog.Info($"INSERT INTO T_JY_BARCODESync (FBarCode, FBarCodeRule,FMaterialNumber,FCreateOrgNumber,FLot,FUnit,FQty,FStockNumber,FDept,FBillDate,F_JY_CZZ,FOpStatus) VALUES ('{time.barcode}','01','{time.materialCode}','02','{time.batchNumber}','{time.measurementUnit}','{time.totalWeight / 100}','{fStockNumber}','{FDept}','{date}','{time.employeeId}','0')"); new SqlHelper().ExecuteSql($" INSERT INTO T_JY_BARCODESync (FBarCode, FBarCodeRule,FMaterialNumber,FCreateOrgNumber,FLot,FUnit,FQty,FStockNumber,FDept,FBillDate,F_JY_CZZ,FOpStatus) VALUES ('{time.barcode}','01','{time.materialCode}','02','{time.batchNumber}','{time.measurementUnit}','{time.totalWeight / 100}','{fStockNumber}','{FDept}','{date}','{time.employeeId}','0')", false); MongoDBSingleton.Instance.Remove(Query.EQ("_id", time._id), RemoveFlags.Single); MongoDBSingleton.Instance.Update(Query.EQ("_id", connInfo._id), Update.Set("timeStamp", ""), UpdateFlags.None); } } } WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE); } if (action.CN_N_ACTION_CODE == 2) { CMMLog.Info($"完成任务处理:收到2信号之后特殊任务类型处理:任务号:{mst.CN_S_TASK_NO},任务类型:{mst.CN_S_BUSS_TYPE}"); if (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, action.CN_N_ACTION_CODE); MongoDBSingleton.Instance.Remove(Query.EQ("taskNo", mst.CN_S_SOURCE_NO), RemoveFlags.Single); } } if (mst.CN_S_BUSS_TYPE != "电梯取货" && mst.CN_S_BUSS_TYPE != "电梯卸货" && !mst.CN_S_BUSS_TYPE.Contains("包装取料")) WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE); if (mst.CN_S_BUSS_TYPE.Contains("包装补空")) PLCControl.PickUpBlankComplete(mst.CN_S_END_BIT); if (ERPService.SendERPTaskType.Contains(mst.CN_S_BUSS_TYPE) && ERPService.ERPSwitch01 == "1") ERPService.SendERPTaskInfo(mst); iCallTask.DeleteTask(mst.CN_S_TASK_NO); } } } #endregion #region 小车状态写入通道 (1-开始;2-完成 4-取货完成 6-卸货完成) if (action.CN_N_ACTION_CODE == 1 || action.CN_N_ACTION_CODE == 2 || action.CN_N_ACTION_CODE == 4 || action.CN_N_ACTION_CODE == 6) { WorkFlowAction.TrackLog(action.CN_S_TASK_NO, 1, action.CN_N_ACTION_CODE, ""); TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO); CMMLog.Info($"小车状态写入通道处理开始"); if (mst != null) { CMMLog.Info($"车号:{mst.CN_S_ForkliftNo}"); var stateInfo = Settings.GetAGVStateList().Where(a => a.AgvNo == mst.CN_S_ForkliftNo && a.enable == 1).FirstOrDefault(); if (stateInfo != null) { if (action.CN_N_ACTION_CODE == 1) { //开始,往通道写入1 var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel { host = stateInfo.ip, port = stateInfo.port, addr = stateInfo.writeAddr + 5, data = 1 }); CMMLog.Info($"在通道{stateInfo.writeAddr + 5}中写入1,ip:{stateInfo.ip},端口:{stateInfo.port}"); } if (action.CN_N_ACTION_CODE == 2) { //完成,往通道写入0 var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel { host = stateInfo.ip, port = stateInfo.port, addr = stateInfo.writeAddr + 5, data = 0 }); CMMLog.Info($"在通道{stateInfo.writeAddr + 5}中写入0,ip:{stateInfo.ip},端口:{stateInfo.port}"); } if (action.CN_N_ACTION_CODE == 4) { //取货完成,往通道写入1 var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel { host = stateInfo.ip, port = stateInfo.port, addr = stateInfo.writeAddr + 6, data = 1 }); CMMLog.Info($"在通道{stateInfo.writeAddr + 6}中写入1,ip:{stateInfo.ip},端口:{stateInfo.port}"); } if (action.CN_N_ACTION_CODE == 6) { //卸货完成,往通道写入0 var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel { host = stateInfo.ip, port = stateInfo.port, addr = stateInfo.writeAddr + 6, data = 0 }); CMMLog.Info($"在通道{stateInfo.writeAddr + 6}中写入1,ip:{stateInfo.ip},端口:{stateInfo.port}"); } } else CMMLog.Info($"小车{mst.CN_S_ForkliftNo}信号未配置"); } } #endregion #region 3楼设备任务 //起点安全对接 1012:安全请求进入 4:安全请求退出 if (action.CN_N_ACTION_CODE == 1012 || action.CN_N_ACTION_CODE == 4 || action.CN_N_ACTION_CODE == 1312 ) { CMMLog.Info($"起点安全对接:收到信号:{action.CN_N_ACTION_CODE},任务号:{action.CN_S_TASK_NO},开始根据任务号查询主表中对应数据!"); var mst = iCallTask.FindTask(action.CN_S_TASK_NO); if (mst != null) { CMMLog.Info($"起点安全对接:收到任务号:{mst.CN_S_TASK_NO},任务类型:{mst.CN_S_BUSS_TYPE},任务信号:{action.CN_N_ACTION_CODE}"); //3楼拆盘补空:拆盘机补空托盘 3楼包装补空:包装机补空托 if (mst.CN_S_BUSS_TYPE.Contains("包装取料") || mst.CN_S_BUSS_TYPE.Contains("复称入缓存架") || mst.CN_S_BUSS_TYPE.Contains("复称入缓存架NG") || mst.CN_S_BUSS_TYPE.Contains("缓存架入叠托") || mst.CN_S_BUSS_TYPE.Contains("叠盘下线") || mst.CN_S_BUSS_TYPE.Contains("打包下线")) { CMMLog.Info($"起点安全对接:即将进入任务流程:{mst.CN_S_BUSS_TYPE},状态号为:{action.CN_N_ACTION_CODE}"); ProcessHelper.StartPickUpDoorSafe(mst, action.CN_N_ACTION_CODE); } else if (mst.CN_S_BUSS_TYPE == "电梯卸货" || mst.CN_S_BUSS_TYPE == "电梯取货" || mst.CN_S_BUSS_TYPE == "满托转运") { if(mst.CN_S_BUSS_TYPE == "电梯取货" && action.CN_N_ACTION_CODE != 1012) { ProcessHelper.OperateDoor(mst, action.CN_N_ACTION_CODE == 1312 ? 1012 : 4); } } } } //滚筒车起点到位信号、取货完成信号 1112 1212 3、4 只对滚筒车对接 if (action.CN_N_ACTION_CODE == 1112 || action.CN_N_ACTION_CODE == 1212) { var mst = iCallTask.FindTask(action.CN_S_TASK_NO); if (mst != null) { if (mst.CN_S_BUSS_TYPE.Contains("包装取料")) { ProcessHelper.PickupAndUnload(mst, action.CN_N_ACTION_CODE); } } } if (action.CN_N_ACTION_CODE == 8) { var mst = iCallTask.FindTask(action.CN_S_TASK_NO); if (mst != null) { var plc = Settings.GetPlcInfo().Where(a => a.location == mst.CN_S_START_BIT).FirstOrDefault(); if (mst.CN_S_BUSS_TYPE.Contains("缓存架入叠托")) { CMMLog.Debug($"缓存架入叠托NG:TaskNo:{action.CN_S_TASK_NO},叠包NG写入值4。"); PLCControl.CacheStackingMouth8(plc); } } } //终点安全对接 1013:安全请求进入 6:安全请求退出 if (action.CN_N_ACTION_CODE == 1013 || action.CN_N_ACTION_CODE == 6 || action.CN_N_ACTION_CODE == 1312) { CMMLog.Info($"终点安全对接:收到信号:{action.CN_N_ACTION_CODE},任务号:{action.CN_S_TASK_NO},开始根据任务号查询主表中对应数据!"); TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO); if (mst != null) { CMMLog.Info($"终点安全对接:收到任务号:{mst.CN_S_TASK_NO},任务类型:{mst.CN_S_BUSS_TYPE},任务信号:{action.CN_N_ACTION_CODE}"); //3楼拆盘补空:拆盘机补空托盘 3楼包装补空:包装机补空托 if (mst.CN_S_BUSS_TYPE.Contains("包装取料") || mst.CN_S_BUSS_TYPE.Contains("复称入缓存架") || mst.CN_S_BUSS_TYPE.Contains("缓存架入叠托") || mst.CN_S_BUSS_TYPE == "包装线补空" || mst.CN_S_BUSS_TYPE.Contains("拆盘补空") ) { ProcessHelper.EndPickUpDoorSafe(mst, action.CN_N_ACTION_CODE); } if (mst.CN_S_BUSS_TYPE == "电梯取货" || mst.CN_S_BUSS_TYPE == "电梯卸货" || mst.CN_S_BUSS_TYPE == "满托转运") { //二段电梯任务终点交互 if (mst.CN_S_BUSS_TYPE == "电梯取货" && action.CN_N_ACTION_CODE != 1312) { //电梯取货任务 终点不需要进行安全交互 } else if (mst.CN_S_BUSS_TYPE == "电梯卸货") { //小车到达等待点之后发送信号,判断哪部电梯可以使用,然后创建电梯生成任务 //异常情况需要打印:1.两部电梯都不可以使用,2.两部电梯都可以使用,默认使用第一台电梯设备 CMMLog.Info($"终点安全对接:电梯卸货:收到信号{action.CN_N_ACTION_CODE}"); if (action.CN_N_ACTION_CODE == 1312 || action.CN_N_ACTION_CODE == 6) { var taskBit = MongoDBSingleton.Instance.FindOne(Query.EQ("taskNo", mst.CN_S_SOURCE_NO), "ElevatorTask"); CMMLog.Info($"终点安全对接:电梯卸货:taskno:{mst.CN_S_TASK_NO},occupy:{taskBit.occupy}"); if (taskBit.occupy == "") { string eleBit = PLCControl.ElevatorTaskBit(mst.CN_S_START_BIT); CMMLog.Info("终点安全对接:电梯卸货:获取电梯点位elebit" + eleBit); if (eleBit == "0") { CMMLog.Info("终点安全对接:电梯卸货:当前无电梯可以使用!"); Console.WriteLine("终点安全对接:电梯卸货:当前无电梯可以使用!"); } else { //改终点为开启的电梯 //TSHelper.GoToAGV(mst.CN_S_TASK_NO, 1, StockInstance.Instance.GetAGVCodeForBitCode(eleBit)); //TSHelper.GoToAGV(mst.CN_S_TASK_NO, 2, StockInstance.Instance.GetAGVCodeForBitCode(eleBit)); //AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "修改终点"); var taskInfo = MongoDBSingleton.Instance.FindOne(Query.EQ("taskNo", mst.CN_S_SOURCE_NO), "ElevatorTask"); //赋值 二段电梯点位 MongoDBSingleton.Instance.Update(Query.EQ("_id", mst._id), Update.Set("Ext3",eleBit), UpdateFlags.None); string endBit02 = PLCControl.ElevatorTaskBit02(eleBit); MongoDBSingleton.Instance.Update(Query.EQ("taskNo", taskInfo.taskNo), Update.Set("taskNo", taskInfo.wmsTaskNo + "_1").Set("endBit02", endBit02).Set("occupy", eleBit).Set("endBit",eleBit), UpdateFlags.None); CMMLog.Info("终点安全对接:电梯卸货:elebit:" + eleBit); //写入当前楼层--呼叫电梯 PLCControl.ElevatorTaskFloor(taskInfo.startFloor, eleBit); } } else { CMMLog.Info("终点安全对接:电梯卸货:电梯occupy占用字段不为空,进入电梯开门关门服务!"); ProcessHelper.OperateDoor(mst, action.CN_N_ACTION_CODE); } } } } } } //滚筒车终点到位信号、卸货完成信号 1113 1213 5、6 只对滚筒车对接 if (action.CN_N_ACTION_CODE == 1113 || action.CN_N_ACTION_CODE == 1213) { var mst = iCallTask.FindTask(action.CN_S_TASK_NO); if (mst != null) { //3楼拆盘补空:拆盘机补空托盘 3楼包装补空:包装机补空托 if (mst.CN_S_BUSS_TYPE.Contains("包装取料")) ProcessHelper.DiscRemoverEmptySupport(mst, action.CN_N_ACTION_CODE); } } //缓存架入叠托,小车扫码 if(action.CN_N_ACTION_CODE == 1313) { TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO); var plc = Settings.GetPlcInfo().Where(a => a.location == mst.CN_S_END_BIT).FirstOrDefault(); if(plc != null) { PLCControl.CacheStackingMouth1313(plc.deviceType, mst.CN_S_TASK_NO); //AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "小车扫码"); } } //电动安全门对接 if(action.CN_N_ACTION_CODE == 1023 || action.CN_N_ACTION_CODE == 1025) { CMMLog.Info($"收到信号{action.CN_N_ACTION_CODE},门号:{action.Ext2}"); var plc = Settings.GetPlcInfo().Where(a => a.Extend == action.Ext2 && a.enable == 1).FirstOrDefault(); if (plc != null) { try { if (action.CN_N_ACTION_CODE == 1023) { var wirte = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel { addr = plc.writeAddr, host = plc.ip, port = plc.port, data = 1 }); CMMLog.Debug($"DoorSafe:写入ip:{plc.ip},端口:{plc.port},通道:{plc.writeAddr}里面数据为:1."); var result = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel { dataNum = 2, addr = plc.readAddr, host = plc.ip, port = plc.port }); CMMLog.Debug($"DoorSafe:读取ip:{plc.ip},端口:{plc.port},通道{plc.readAddr + 1}里面数据为{JsonConvert.SerializeObject(result)}."); if (result != null && result.errCode == 0) { if (result.result[0] == 1 && result.result[1] == 1) { //推送小车进去 CMMLog.Info($"电动门已经打开,门号:{action.Ext2}"); TSHelper.Traffic(action.Ext2); } } } else if (action.CN_N_ACTION_CODE == 1025) { var wirte = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel { addr = plc.writeAddr, host = plc.ip, port = plc.port, data = 2 }); CMMLog.Debug($"DoorSafe:写入ip:{plc.ip},端口:{plc.port},通道:{plc.writeAddr}里面数据为:2."); } } catch (Exception ex) { CMMLog.Info($"DoorSafe err:" + ex.Message); } } else CMMLog.Info($"门号为【{action.Ext2}】的门为在配置文件配置或者未启用"); //CMMLog.Info($"电动门安全请求对接:收到任务号:{mst.CN_S_TASK_NO},任务类型:{mst.CN_S_BUSS_TYPE},任务信号:{action.CN_N_ACTION_CODE}"); // if(mst.CN_S_BUSS_TYPE == "成品入发货架") // { // PLCControl.DoorSafe(mst, action.CN_N_ACTION_CODE); // } } if(action.CN_N_ACTION_CODE == 1024) { CMMLog.Info($"安全对接:收到信号:{action.CN_N_ACTION_CODE},任务号:{action.CN_S_TASK_NO},开始根据任务号查询主表中对应数据!"); TN_I_TASK_MST mst = MongoDBSingleton.Instance.FindOne(Query.EQ("CN_S_BUSS_TYPE", "一号厂房叠盘下线"), "TN_I_TASK_MST"); //TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO); if (mst != null) { if (mst.CN_S_BUSS_TYPE == "一号厂房叠盘下线") { var plc = Settings.GetPlcInfo().Where(a => a.location == mst.CN_S_START_BIT).FirstOrDefault(); if (plc != null) { PLCControl.PalletStacker1024(plc,mst.CN_S_TASK_NO); } } } } #endregion return iResult; } internal void writeAGVState(TN_I_TASK_DTL_ACTION action) { #region 小车状态写入通道 (1-开始;2-完成 4-取货完成 6-卸货完成) if (action.CN_N_ACTION_CODE == 1 || action.CN_N_ACTION_CODE == 2 || action.CN_N_ACTION_CODE == 4 || action.CN_N_ACTION_CODE == 6) { TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO); CMMLog.Info($"小车状态写入通道处理开始"); if (mst != null) { CMMLog.Info($"车号:{action.CN_S_DEVICE_CODE}"); var agvInfo = MongoDBSingleton.Instance.FindOne(Query.EQ("forkliftNo", action.CN_S_DEVICE_CODE), "AGV_STATE"); if (agvInfo != null) { if (action.CN_N_ACTION_CODE == 1) { MongoDBSingleton.Instance.Update(Query.EQ("forkliftNo", action.CN_S_DEVICE_CODE), Update.Set("agvState", 1), UpdateFlags.None); } if (action.CN_N_ACTION_CODE == 2) { MongoDBSingleton.Instance.Update(Query.EQ("forkliftNo", action.CN_S_DEVICE_CODE), Update.Set("agvState", 0), UpdateFlags.None); } if (action.CN_N_ACTION_CODE == 4) { MongoDBSingleton.Instance.Update(Query.EQ("forkliftNo", action.CN_S_DEVICE_CODE), Update.Set("haveItem", 1), UpdateFlags.None); } if (action.CN_N_ACTION_CODE == 6) { MongoDBSingleton.Instance.Update(Query.EQ("forkliftNo", action.CN_S_DEVICE_CODE), Update.Set("haveItem", 0), UpdateFlags.None); } } else CMMLog.Info($"未在中间表查询到该车号的数据,车号:{action.CN_S_DEVICE_CODE}"); } writeAGVInfo(action.CN_S_DEVICE_CODE); } #endregion } #region AGV车体状态信息 public void HangChaAGVEvent(HangChaAGV _hangChaAGV) { } public void HangChaAGVEvent(List agvs) { } #endregion public class ConnectingBits { public ObjectId _id { get; set; } /// /// 货位编码 /// public string Bit { get; set; } /// /// 时间戳 /// public string timeCuo { get; set; } } } }