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.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.JingmenGEMTwoProtocol.EnentListen; using static Hanhe.iWCS.JingmenGEMTwoProtocol.MESHelper; using static Hanhe.iWCS.JingmenGEMTwoProtocol.ProcessHelper; using static Hanhe.iWCS.JingmenGEMTwoProtocol.PLCControl; using MongoDB.Bson; using static Hanhe.iWCS.JingmenGEMTwoProtocol.ERPService; using static Hanhe.iWCS.JingmenGEMTwoProtocol.ApiHelper; using System.Security.Policy; using Hanhe.iWCS.DeviceDriver; using System.Web.UI.WebControls; namespace Hanhe.iWCS.JingmenGEMTwoProtocol { /// /// 设备协议解析类 /// public class ProtocolAnalysis : IProtocolAnalysis { private EquipmentCommandEQBLL CommandEQBLL = new EquipmentCommandEQBLL(); public ICallTaskProcessing iCallTask = new ICallTaskProcessing(); HardwareAccessObject hao = HardwareAccessHelper.Instance.GetEquipmentsHAO(Constants.WMS_DEVICE_TYPE_WMS); 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 需要根据任务类型进行对应任务流程处理) iCallTask.UpdateTask(mst.CN_S_TASK_NO, "未执行"); } else { CMMLog.Info($"推送任务:任务号{mst.CN_S_TASK_NO},任务类型:{mst.CN_S_BUSS_TYPE}"); iCallTask.UpdateTask(mst.CN_S_TASK_NO, "已推送"); 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 (!WorkFlowAction.ExistsTrackLogs(mst.CN_S_TASK_NO, 1, 4)) { CMMLog.Info("action.CN_N_ORDER:" + action.CN_N_ORDER); //请求前 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 != "3楼包装取料") 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), RemoveFlags.None); } //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.SendERPTaskInfoTwo(mst); } else { CMMLog.Info("该任务以取货完成,无法取消,如果需要停止此任务,请强制完成"); } } } #endregion #region 强制完成 if (action.CN_N_ACTION_CODE == 1022) { TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO); if (mst != null) { if(WorkFlowAction.ExistsTrackLogs(mst.CN_S_TASK_NO, 1, 4)) { ProcessHelper.ForceComplete(mst, action); 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数据 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 }); #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 != "3楼包装取料") 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 (mst.CN_S_BUSS_TYPE == "3楼复称入缓存架" || mst.CN_S_BUSS_TYPE == "3楼复称入缓存架NG") { var plc = Settings.GetPlcInfo().Where(a => a.location == mst.CN_S_START_BIT && a.enable == 1).FirstOrDefault(); if (plc != null) { PLCControl.SecondWeightInCache4(plc.ip, mst.CN_S_TASK_NO); } } if (ERPService.SendERPTaskType.Contains(mst.CN_S_BUSS_TYPE) && ERPService.ERPSwitch01 == "1") ERPService.SendERPTaskInfo(mst); } else { CMMLog.Info("该任务未取货完成,取消此任务"); iCallTask.CancelTask(mst.CN_S_TASK_NO, "1"); } 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 == 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); if (mst != null) { if (string.IsNullOrEmpty(mst.CN_S_ForkliftNo) && !string.IsNullOrEmpty(action.CN_S_DEVICE_CODE)) { MongoDBSingleton.Instance.Update(Query.EQ("_id", mst._id), Update.Set("CN_S_ForkliftNo", action.CN_S_DEVICE_CODE), UpdateFlags.None); } if (action.CN_N_ACTION_CODE != 1) ProcessHelper.UpdateTaskState(mst.CN_S_TASK_NO, action.CN_N_ACTION_CODE); #region 写入小车状态 writeAGVState(action); #endregion var url = hao.WebUrl + "GlmTrayItemSet"; if (action.CN_N_ACTION_CODE == 1) { AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, "1", action.CN_S_DEVICE_CODE, true); WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE); if (mst.CN_S_BUSS_TYPE.Contains("缓存架入立库")) { if (mst.CN_S_BUSS_TYPE.Contains("电钴")) { //将任务号插入到中间表 var erpInfo = MongoDBSingleton.Instance.FindOne(Query.And(Query.EQ("Bit", mst.CN_S_START_BIT), Query.EQ("taskNo", "")), "SendErpTaskInfoTableDG"); if (erpInfo != null) { MongoDBSingleton.Instance.Update(Query.And(Query.EQ("Bit", mst.CN_S_START_BIT), Query.EQ("taskNo", "")), Update.Set("taskNo", mst.CN_S_SOURCE_NO), UpdateFlags.None); } } else { //将任务号插入到中间表 var erpInfo = MongoDBSingleton.Instance.FindOne(Query.And(Query.EQ("Bit", mst.CN_S_START_BIT), Query.EQ("taskNo", "")), "SendErpTaskInfoTable"); if (erpInfo != null) { MongoDBSingleton.Instance.Update(Query.And(Query.EQ("Bit", mst.CN_S_START_BIT), Query.EQ("taskNo", "")), Update.Set("taskNo", mst.CN_S_SOURCE_NO), UpdateFlags.None); } } } if (mst.CN_S_BUSS_TYPE == "老物料缓存架入立库") { MongoDBSingleton.Instance.Insert(new SendErpTaskInfoTable { taskNo = mst.CN_S_SOURCE_NO, Bit = mst.CN_S_START_BIT, //materiCode = time.materialCode, //lotCode = time.batchNumber, totalWeight = 1000, productTime = mst.CN_T_CREATE, invalidationTime = mst.CN_T_CREATE.AddDays(365), dateTime = DateTime.Now.AddHours(8) }, "ERPItemTable"); } if (mst.CN_S_BUSS_TYPE == "3楼成品出库") { string day = DateTime.Now.ToString("yyyyMMdd"); //根据托盘号获取入库物料信息 CJWareNum model = new CJWareNum { TrayCode = mst.CN_S_BATCH_NO }; string msgData = JsonConvert.SerializeObject(model); var feedback = helper.WebPost(url, msgData).Replace(@"\", "").Trim(); CMMLog.Info($"writeCJQtt:【调用wms获取物料信息】:接收数据:" + feedback); if (!string.IsNullOrEmpty(feedback)) { var wmsResponse = JsonConvert.DeserializeObject(feedback); if (wmsResponse.Success == true) { string itemCode = wmsResponse.Data.CN_S_LOT_NO.Contains("-") ? wmsResponse.Data.CN_S_LOT_NO.Substring(0, wmsResponse.Data.CN_S_LOT_NO.LastIndexOf('-')) : wmsResponse.Data.CN_S_LOT_NO; var itemInfo = MongoDBSingleton.Instance.FindOne(Query.And(Query.EQ("Type", "出库"), Query.EQ("Day", day), Query.EQ("itemBatch", itemCode)), "InAndOutQuantity"); if (itemInfo != null) { itemInfo.Quntity = itemInfo.Quntity + 1; MongoDBSingleton.Instance.Update(Query.And(Query.EQ("Type", "出库"), Query.EQ("Day", day), Query.EQ("itemBatch", itemCode)), Update.Set("Quntity", itemInfo.Quntity), UpdateFlags.None); } else { itemInfo = new InAndOutitem { Type = "出库", itemBatch = itemCode, Day = day, Quntity = 1, }; MongoDBSingleton.Instance.Insert(itemInfo); } } } } if (mst.CN_S_BUSS_TYPE == "3楼打包下线") { var connInfo = MongoDBSingleton.Instance.FindOne(Query.EQ("Bit", mst.CN_S_END_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}"); 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}','CK020','BM000161','{date}','{time.employeeID1}','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}','CK020','BM000161','{date}','{time.employeeID1}','0')", false); } } } if (mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托") { //四小包流程 根据托盘号调用接口,判断是否是四小包 url = hao.WebUrl + "AmsSeleTrayType"; var feedback = helper.WebGet(url + "?TrayCode=" + mst.CN_S_BATCH_NO).Replace(@"\", "").Trim(); CMMLog.Info($"调用wms查询托盘信息接口回报数据:{feedback}"); if (!string.IsNullOrEmpty(feedback)) { //var wmsResponse = JsonConvert.DeserializeObject(feedback.Substring(1, feedback.Length - 2)); var wmsResponse = JsonConvert.DeserializeObject(feedback); if (wmsResponse.Success == true) { CMMLog.Info("【调用wms查询托盘信息】成功!返回结果=" + wmsResponse.Success + ";调用WebUrl=" + url + ";输入参数=" + mst.CN_S_BATCH_NO); //将托盘号存入MachineInfoTwo表中 //根据物料编码查询物料信息 if (wmsResponse.Data.trayItemMsts.Count == 4) { string itemCode = wmsResponse.Data.trayItemMsts[0].CN_S_ITEM_CODE; var twoInfo = MongoDBSingleton.Instance.Find(Query.And(Query.EQ("materialCode", itemCode),Query.EQ("trayType", "3")), "MachineInfoTwo"); if (twoInfo.Count % 4 == 0) { twoInfo = twoInfo.Where(a => a.trayCode.Substring(0,3) != "VWT").OrderBy(a => a.modify).ToList(); int x = 0; foreach(var a in twoInfo) { MongoDBSingleton.Instance.Update(Query.EQ("_id", a._id), Update.Set("trayCode", mst.CN_S_BATCH_NO), UpdateFlags.None); x = x + 1; if(x == 4) { break; } } } else { CMMLog.Info($"四小包叠包任务异常,machineInfoTwo表中该物料编码的叠包物料不为4,物料编码:{itemCode}"); } } } else { string errMsg = wmsResponse.Msg; CMMLog.Info("【调用wms查询托盘信息】失败!错误原因=" + errMsg + ";调用WebUrl=" + url + ";输入参数=" + mst.CN_S_BATCH_NO); } } else { CMMLog.Info("【调用wms查询托盘信息】失败!错误原因= 参数反馈空值 ;调用WebUrl=" + url + ";输入参数=" + mst.CN_S_BATCH_NO); } } } if (action.CN_N_ACTION_CODE == 4) { CMMLog.Info($"收到信号:{action.CN_N_ACTION_CODE},任务号:{action.CN_S_TASK_NO},开始根据任务号查询主表中对应数据!"); AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, "4", action.CN_S_DEVICE_CODE, true); WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE); if (mst.CN_S_BUSS_TYPE == "包装线补空") PLCControl.PickUpBlankComplete(mst.CN_S_END_BIT, mst.CN_S_START_BIT); //if (mst.CN_S_BUSS_TYPE == "3楼包装取料") PLCControl.CheckUpReqUnload(mst.CN_S_END_BIT, mst.CN_S_TASK_NO,); if (mst.CN_S_BUSS_TYPE == "缓存架入立库" || mst.CN_S_BUSS_TYPE == "辅材出库(二段)") { MongoDBSingleton.Instance.Update(Query.EQ("Bit", mst.CN_S_START_BIT), Update.Set("trayCode", "").Set("state", "0").Set("END_LOC", ""), UpdateFlags.None); //MongoDBSingleton.Instance.Update(Query.EQ("Bit", mst.CN_S_START_BIT), Update.Set("trayCode", "").Set("state", "0"), UpdateFlags.None); } if (mst.CN_S_BUSS_TYPE == "电钴缓存架入立库" || mst.CN_S_BUSS_TYPE == "电钴生产退库(二段)") { MongoDBSingleton.Instance.Update(Query.EQ("Bit", mst.CN_S_START_BIT), Update.Set("trayCode", "").Set("state", "0").Set("END_LOC", ""), UpdateFlags.None); MongoDBSingleton.Instance.Remove(Query.EQ("trayCode", mst.CN_S_BATCH_NO), RemoveFlags.None); } //if (mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托") WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE); if (mst.CN_S_BUSS_TYPE == "3楼打包下线") { //打包下线取货完成,将数据写入中间表 } } if (action.CN_N_ACTION_CODE == 6) { AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, "6", action.CN_S_DEVICE_CODE, true); WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE); if (mst.CN_S_BUSS_TYPE == "3楼包装补空") { //将数据记录到中间表 var agvloc = Settings.GetDDSiteList().Where(a => a.ddLoc == mst.CN_S_END_BIT).First(); if (agvloc != null) { var quantity = agvloc.quantity; CMMLog.Info($"3楼包装补空,终点{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 == "3楼包装取料") { //卸货完成,中间表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 == "3楼打包下线" || mst.CN_S_BUSS_TYPE == "PDA打包下线" || mst.CN_S_BUSS_TYPE == "辅材出库") { MongoDBSingleton.Instance.Update(Query.EQ("Bit", mst.CN_S_END_BIT), Update.Set("state", "1"), UpdateFlags.None); } if (mst.CN_S_BUSS_TYPE == "包装机满托下线" || mst.CN_S_BUSS_TYPE == "电钴生产退库") { MongoDBSingleton.Instance.Update(Query.EQ("Bit", mst.CN_S_END_BIT), Update.Set("state", "1"), UpdateFlags.None); } if (mst.CN_S_BUSS_TYPE == "3楼成品出库") { //3楼成品出库收到6之后,终点货位数量减1,(注:6信号会发多次) var slptInfo = MongoDBSingleton.Instance.FindOne(Query.And(Query.EQ("locCode", mst.CN_S_END_BIT), Query.EQ("count", 0)), "SLPTLoc"); if (slptInfo != null) { MongoDBSingleton.Instance.Update(Query.EQ("locCode", mst.CN_S_END_BIT), Update.Set("taskNum", slptInfo.taskNum - 1).Set("count", slptInfo.count + 1), UpdateFlags.None); } } } if (action.CN_N_ACTION_CODE == 2) { AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, "2", action.CN_S_DEVICE_CODE, true); WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE); CMMLog.Info($"完成任务处理:收到2信号之后特殊任务类型处理:任务号:{mst.CN_S_TASK_NO},任务类型:{mst.CN_S_BUSS_TYPE}"); //if (mst.CN_S_BUSS_TYPE == "包装线补空") ProcessHelper.EndPickUpDoorSafe(mst, action.CN_N_ACTION_CODE); //2024-08-08变更,计算当日入库出库数量 if (mst.CN_S_BUSS_TYPE == "缓存架入立库" || mst.CN_S_BUSS_TYPE == "3楼成品出库") { string type = mst.CN_S_BUSS_TYPE == "缓存架入立库" ? "入库" : "出库"; DateTime time = DateTime.Now; string year = time.ToString("yyyy"); string month = time.ToString("MM"); string day = time.ToString("dd"); var qutInfo = MongoDBSingleton.Instance.FindOne(Query.And(Query.EQ("Type", type), Query.EQ("Year", year), Query.EQ("Month", month), Query.EQ("Day", day)), "InAndOutQuantity"); if (qutInfo != null) { qutInfo.Quntity = qutInfo.Quntity + 1; MongoDBSingleton.Instance.Update(Query.And(Query.EQ("Type", type), Query.EQ("Year", year), Query.EQ("Month", month), Query.EQ("Day", day)), Update.Set("Quntity", qutInfo.Quntity), UpdateFlags.None); } else { qutInfo = new InAndOutQuantity { Type = type, Year = year, Month = month, Day = day, Quntity = 1, }; MongoDBSingleton.Instance.Insert(qutInfo); } if (type == "入库") { //根据托盘号获取入库物料信息 CJWareNum model = new CJWareNum { TrayCode = mst.CN_S_BATCH_NO }; string msgData = JsonConvert.SerializeObject(model); var feedback = helper.WebPost(url, msgData).Replace(@"\", "").Trim(); CMMLog.Info($"writeCJQtt:【调用wms获取物料信息】:接收数据:" + feedback); if (!string.IsNullOrEmpty(feedback)) { var wmsResponse = JsonConvert.DeserializeObject(feedback); if (wmsResponse.Success == true) { string itemCode = wmsResponse.Data.CN_S_LOT_NO.Contains("-") ? wmsResponse.Data.CN_S_LOT_NO.Substring(0, wmsResponse.Data.CN_S_LOT_NO.LastIndexOf('-')) : wmsResponse.Data.CN_S_LOT_NO; var itemInfo = MongoDBSingleton.Instance.FindOne(Query.And(Query.EQ("Type", type), Query.EQ("Day", DateTime.Now.ToString("yyyyMMdd")), Query.EQ("itemBatch", itemCode)), "InAndOutQuantity"); if (itemInfo != null) { itemInfo.Quntity = itemInfo.Quntity + 1; MongoDBSingleton.Instance.Update(Query.And(Query.EQ("Type", type), Query.EQ("Day", DateTime.Now.ToString("yyyyMMdd")), Query.EQ("itemBatch", itemCode)), Update.Set("Quntity", itemInfo.Quntity), UpdateFlags.None); } else { itemInfo = new InAndOutitem { Type = type, itemBatch = itemCode, Day = DateTime.Now.ToString("yyyyMMdd"), Quntity = 1, }; MongoDBSingleton.Instance.Insert(itemInfo); } } } } PLCControl.writeLKQtt(); } if (mst.CN_S_BUSS_TYPE == "3楼成品出库") { //3楼成品出库收到2信号之后 将中间表count数量清除 var slptInfo = MongoDBSingleton.Instance.FindOne(Query.EQ("locCode", mst.CN_S_END_BIT), "SLPTLoc"); if (slptInfo != null) { MongoDBSingleton.Instance.Update(Query.EQ("locCode", mst.CN_S_END_BIT), Update.Set("count", 0), UpdateFlags.None); } } if (ERPService.SendERPTaskType.Contains(mst.CN_S_BUSS_TYPE) && ERPService.ERPSwitch01 == "1") ERPService.SendERPTaskInfo(mst); iCallTask.DeleteTask(mst.CN_S_TASK_NO); } } } #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 == "3楼包装取料" || mst.CN_S_BUSS_TYPE == "3楼复称入缓存架" || mst.CN_S_BUSS_TYPE == "3楼复称入缓存架NG" || mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托" || mst.CN_S_BUSS_TYPE == "3楼叠盘下线" || mst.CN_S_BUSS_TYPE == "3楼打包下线" || mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托NG" || mst.CN_S_BUSS_TYPE == "辅材入库" || mst.CN_S_BUSS_TYPE == "PDA打包下线" || mst.CN_S_BUSS_TYPE == "烘干机满托下线" || mst.CN_S_BUSS_TYPE == "剪切机空托下线" || mst.CN_S_BUSS_TYPE == "包装机满托下线") { 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 == "3楼包装取料") { ProcessHelper.PickupAndUnload(mst, action.CN_N_ACTION_CODE); } } } #region //if (action.CN_N_ACTION_CODE == 8 || action.CN_N_ACTION_CODE == 2) //{ // var mst = iCallTask.FindTask(action.CN_S_TASK_NO); // if (mst != null) // { // var plc = Settings.GetPlcInfo().Where(a => a.location == mst.CN_S_END_BIT).FirstOrDefault(); // // if (mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托") // { // if (!WorkFlowAction.ExistsTrackLogs(mst.CN_S_TASK_NO, 1, 8) && action.CN_N_ACTION_CODE == 2) // PLCControl.CacheStackingMouth6(plc.deviceType, mst.CN_S_TASK_NO); // else PLCControl.CacheStackingMouth6(plc.deviceType, mst.CN_S_TASK_NO); // } // } //} #endregion //终点安全对接 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 == "3楼包装取料" ||mst.CN_S_BUSS_TYPE == "地面货位取料" || mst.CN_S_BUSS_TYPE == "3楼复称入缓存架" || mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托" || mst.CN_S_BUSS_TYPE == "3楼拆盘补空" || mst.CN_S_BUSS_TYPE == "包装线补空" || mst.CN_S_BUSS_TYPE == "3楼打包下线" || mst.CN_S_BUSS_TYPE == "3楼成品出库" || mst.CN_S_BUSS_TYPE == "PDA打包下线" || mst.CN_S_BUSS_TYPE == "剪切机满托上线" || mst.CN_S_BUSS_TYPE == "烘干机空托上线") { ProcessHelper.EndPickUpDoorSafe(mst, action.CN_N_ACTION_CODE); } } } //滚筒车终点到位信号、卸货完成信号 1113 1213 5、6 只对滚筒车对接 if (action.CN_N_ACTION_CODE == 4 || action.CN_N_ACTION_CODE == 1213) { var mst = iCallTask.FindTask(action.CN_S_TASK_NO); CMMLog.Info($"4 或 1213 信号,{mst.CN_S_BUSS_TYPE},{mst.CN_S_END_BIT}"); if (mst != null) { //3楼拆盘补空:拆盘机补空托盘 3楼包装补空:包装机补空托 if (mst.CN_S_BUSS_TYPE == "3楼包装取料") 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); if (mst != null) { CMMLog.Info($"1313信号,{mst.CN_S_BUSS_TYPE},{mst.CN_S_END_BIT}"); 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(), "小车扫码"); } else CMMLog.Info($"点位为{mst.CN_S_END_BIT}的设备未配置"); } } #region 电动门A门交管信号(1023-开门 1025-关门) B门交管信号(1013-开门 6--关门) if (action.CN_N_ACTION_CODE == 1023) { CMMLog.Info($"收到信号{action.CN_N_ACTION_CODE},门号:{action.Ext2}"); //电动门开门 var doorInfo = Settings.GetPlcInfo().Where(a => a.Extend == action.Ext2 && a.enable == 1).FirstOrDefault(); if (doorInfo != null) { //电动门开门步骤: //1、在通道【40101】中写入1,发送开门信号 //2、读取通道【40001】中的值,如果为1,表示开门到位,通知小车进去 var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel { host = doorInfo.ip, port = doorInfo.port, addr = doorInfo.writeAddr, data = 1 }); CMMLog.Info($"发送开门信号,在通道{doorInfo.writeAddr}中写入1,ip:{doorInfo.ip},端口:{doorInfo.port}"); var result = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel { dataNum = 2, addr = doorInfo.readAddr, host = doorInfo.ip, port = doorInfo.port }); if (result != null && result.errCode == 0) { CMMLog.Info($"电动门开门流程:读取电动门通道号为:{doorInfo.readAddr}里面的值为{result.result[0]},{doorInfo.readAddr + 1}里面的值为{result.result[1]},门号:{action.Ext2}"); if(action.Ext2 == "4" || action.Ext2 == "5") { if (result.result[0] == 1) { //推送小车进去 CMMLog.Info($"电动门已经打开,门号:{action.Ext2}"); TSHelper.Traffic(action.Ext2); } } else if(result.result[0] == 1 && result.result[1] == 1) { //推送小车进去 CMMLog.Info($"电动门已经打开,门号:{action.Ext2}"); TSHelper.Traffic(action.Ext2); } } else CMMLog.Info($"电动门开门流程:未读取到包装机通道{doorInfo.readAddr}里面的数据!!!result:{JsonConvert.SerializeObject(result)}"); } else CMMLog.Info($"门号为【{action.Ext2}】的门为在配置文件配置或者未启用"); } else if (action.CN_N_ACTION_CODE == 1025) { //电动门关门 var doorInfo = Settings.GetPlcInfo().Where(a => a.Extend == action.Ext2 && a.enable == 1).FirstOrDefault(); if (doorInfo != null) { //电动门关门步骤 //1、小车通过电动门后,在通道【40101】中写入2 var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel { host = doorInfo.ip, port = doorInfo.port, addr = doorInfo.writeAddr, data = 2 }); CMMLog.Info($"电动门关门流程,在通道{doorInfo.writeAddr}中写入2,ip:{doorInfo.ip},端口:{doorInfo.port}"); } else CMMLog.Info($"门号为【{action.Ext2}】的门为在配置文件配置或者未启用"); } #endregion #endregion return iResult; } #region AGV车体状态信息 public void HangChaAGVEvent(HangChaAGV _hangChaAGV) { } public void HangChaAGVEvent(List agvs) { } #endregion /// /// 周转托盘位 /// public class BZEmptyPoint { public ObjectId _id { get; set; } /// /// 空托缓存点 /// public string Bit { get; set; } /// /// 托盘数量 /// public int Quantity { get; set; } } /// /// 立库入库ERP节拍 /// public class ERPInfoTable { public ObjectId _id { get; set; } /// /// 批次号 /// public string batchNo { get; set; } /// /// 入库数量 /// public int num { get; set; } = 1; /// /// 尾托时间 /// public DateTime time { get; set; } /// /// 是否执行完成 1:待执行 2:执行完成 /// public int flage { get; set; } = 1; } #region 设备合格率清单 public class ProductList { public ObjectId _id { get; set; } /// /// 日期 /// public string Date { get; set; } /// /// 设备 /// public string machine { get; set; } /// /// 设备生产数 /// public double total { get; set; } /// /// 合格数 /// public double qualifiedQuantity { get; set; } /// /// 合格率 /// public double percentOfPass { get; set; } /// /// 当天总合格数 /// public double overallPassRate { get; set; } } #endregion #region 打包下线口接驳位 public class ConnectingBits { public ObjectId _id { get; set; } /// /// 货位编码 /// public string Bit { get; set; } /// /// 托盘号 /// public string trayCode { get; set; } /// /// 货位状态 0 无货 1 有货 /// public string state { get; set; } /// /// 时间戳 /// public string timeCuo { get; set; } /// /// 二段任务的终点货位 /// public string END_LOC { get; set; } } public class DGConnectingBits { public ObjectId _id { get; set; } /// /// 货位编码 /// public string Bit { get; set; } /// /// 托盘号 /// public string trayCode { get; set; } /// /// 货位状态 0 无货 1 有货 /// public string state { get; set; } /// /// 二段任务的终点货位 /// public string END_LOC { get; set; } } #endregion public class InAndOutQuantity { public ObjectId _id { get; set; } /// /// 类型 出库 - 入库 /// public string Type { get; set; } /// /// 年 /// public string Year { get; set; } /// /// 月 /// public string Month { get; set; } /// /// 周 /// //public string Week { get; set; } /// /// 日 /// public string Day { get; set; } /// /// 数量 /// public int Quntity { get; set; } } public class InAndOutitem { public ObjectId _id { get; set; } public string Type { get; set; } public string itemBatch { get; set; } public string Day { get; set; } public int Quntity { get; set; } } 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 } /// /// 托盘信息 /// public class WMSResponseTrayModel1 { public int Status { get; set; } public object Code { get; set; } public string Msg { get; set; } public Data Data { get; set; } public int AffectedRows { get; set; } public bool Success { get; set; } } public class Data { public string CN_S_TRAY_CODE { get; set; } public string CN_S_TRAY_TYPE { get; set; } public List trayItemMsts { get; set; } } public class TrayItemMst { public string CN_S_ITEM_CODE { get; set; } } } }