.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/3f7a8a50-7623-4582-a788-1727f4b734e0.vsidxBinary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/49ec3933-2a6b-4835-ab77-24f5cfc05e26.vsidxBinary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/72178599-9865-468a-a3b6-7e0cf3fce2a8.vsidxBinary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/74bd051a-76c6-4faf-9203-3846175eb944.vsidxBinary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/79fc4010-d1c2-42bb-9f8f-a7b972ec34f6.vsidxBinary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/848a02bc-1e77-4a4d-8129-5fd396f4d138.vsidxBinary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/c30fdd47-6615-4811-b8bd-dfc4b98d2d2f.vsidxBinary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/cfeb14b9-8063-424f-8831-ddd93cd9c6f5.vsidxBinary files differ
HH.WCS.Mobox3.DSZSH.csproj
@@ -235,6 +235,7 @@ <Compile Include="core\Monitor.cs" /> <Compile Include="core\WCSCore.cs" /> <Compile Include="core\WMSCore.cs" /> <Compile Include="device\TcpClientHelper.cs" /> <Compile Include="process\TaskProcess.cs" /> <Compile Include="util\SqlHelper.cs" /> <Compile Include="models\TN_Container_Item.cs" /> Models/TN_CG_Detail.cs
@@ -69,9 +69,18 @@ /// </summary> public string S_QUALITY_GRADE { get; set; } = string.Empty; /// <summary> /// 产线号 /// </summary> public int N_PRODUCT_LINE { get; set; } = 0; // NOTE 后续MES可能会提供,先创建 // ---------------- // TODO ///// <summary> ///// 产线号 ///// 物料所在的区域 ///// </summary> //public int N_PRODUCT_LINE { get; set; } = 0; // NOTE 后续MES可能会提供,先创建 //public string S_AREA_CODE { get; set; } = string.Empty; } } Program.cs
@@ -22,9 +22,9 @@ // 2.0 开启tcp StartTcp(); // 3.0 开启S7 StartS7(); //StartS7(); // 4.0 开启Modbus StartModbus(); //StartModbus(); // 5.0 开启线程 var rc = HostFactory.Run(x => { @@ -113,6 +113,8 @@ { List<Task> tasks = new List<Task>(); tasks.Add(GetTask(WCSCore.Dispatch)); // 轮询:出库单状态 tasks.Add(GetTask(Monitor.CheckOutboundOrder)); api/ApiHelper.cs
@@ -32,7 +32,7 @@ try { // 将PDA提供的物料编码与贴标机的信息比对 var cgDetail = db.Queryable<TN_CG_Detail>() .Where(d => d.S_ITEM_CODE == model.s_item_code && d.S_BATCH_NO == model.s_batch) // 指定:物料编码、批次号 .Where(d => d.S_ITEM_CODE == model.ItemCode && d.S_BATCH_NO == model.BatchNo) // 指定:物料编码、批次号 .Where(d => d.N_ITEM_STATE == 1 && d.S_ITEM_STATE == "待检") // NOTE 冗余检查:物料状态应该为 1待检 .First(); @@ -43,19 +43,19 @@ } var startLoc = db.Queryable<TN_Location>() .Where(a => a.S_CODE == model.s_start_loc) // 指定:起点货位号 .Where(a => a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y") // 筛选:未上锁 .Where(l => l.S_CODE == model.StartLoc) // 指定:起点货位号 .Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y") // 筛选:未上锁 .First(); if (startLoc == null) { info = $"起点位置 '{model.s_start_loc}' 不存在或不具备取货要求"; info = $"起点位置 '{model.StartLoc}' 不存在或不具备取货要求"; LogHelper.Info(info); return NewSimpleResult(3, info); } // 绑定货位和容器号 var locCntrRel = new TN_Loc_Container { S_LOC_CODE = model.s_start_loc, S_LOC_CODE = model.StartLoc, S_CNTR_CODE = cgDetail.S_CNTR_CODE, S_CNTR_TYPE = "好运箱", }; @@ -72,7 +72,7 @@ .Where(a => a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y") // 筛选:未上锁 .Where(a => a.N_CURRENT_NUM == 0) // 筛选:空货位 .OrderBy(l => l.N_LAYER) .OrderBy(l => l.S_AREA_CODE).First(); .First(); if (endLoc == null) { info = "满箱入库暂时没有合适的货位可以入库"; @@ -83,8 +83,8 @@ var cntId = locCntrRel.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 LocationHelper.LockLoc(ref startLoc, 2); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 1); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_Location>(startLoc).UpdateColumns(it => new { @@ -94,7 +94,7 @@ it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; info = $"生成任务'{taskName}'失败:更新起点货位{startLoc.S_CODE}锁状态失败"; LogHelper.Info(info); return NewSimpleResult(4, info); } @@ -105,29 +105,28 @@ it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"; info = $"生成任务'{taskName}'失败:更新终点货位{endLoc.S_CODE}锁状态失败"; LogHelper.Info(info); return NewSimpleResult(4, info); } if (db.Insertable<TN_Task>(task).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"; info = $"生成任务'{taskName}'失败,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); return NewSimpleResult(4, info); } tran.CommitTran(); info = $"生成 {taskName} 成功,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"; info = $"生成任务'{taskName}'成功,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); return NewSimpleResult(0, info); } } catch (Exception ex) { info = $"发生了异常:{ex.Message}"; LogHelper.Info(info); LogHelper.InfoEx(ex); return NewSimpleResult(1, info); } } @@ -249,7 +248,9 @@ .First(); if (startLoc == null) { return NewSimpleResult(2, $"起点位置 '{model.StartLoc}' 不存在或不具备取货要求"); info = $"起点位置{model.StartLoc}不存在或不具备取货要求"; LogHelper.Info(info); return NewSimpleResult(2, info); } // 查看容器与起点货位是否绑定 @@ -258,55 +259,70 @@ .First(); if (locCntrRel == null) { return NewSimpleResult(3, $"起点位置 '{model.StartLoc}' 没有绑定容器 '{model.CntrCode}'"); info = $"起点位置{model.StartLoc}没有绑定容器{model.CntrCode}"; LogHelper.Info(info); return NewSimpleResult(3, info); } // TODO 暂定选择最低层按区位顺序入库,后面待修改 var endLoc = db.Queryable<TN_Location>() .Where(a => Settings.AreaMap[AreaName.空托存放区].Contains(a.S_AREA_CODE)) .OrderBy(l => l.N_LAYER) .OrderBy(l => l.S_AREA_CODE).First(); .First(); if (endLoc == null) { return NewSimpleResult(4, $"暂时没有符合条件的终点放货位"); info = $"暂时没有符合条件的终点放货位"; LogHelper.Info(info); return NewSimpleResult(4, info); } var cntId = locCntrRel.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 LocationHelper.LockLoc(ref startLoc, 2); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 1); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_Location>(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'失败:更新起点货位{startLoc.S_CODE}锁状态失败"; LogHelper.Info(info); return NewSimpleResult(4, info); } if (db.Updateable<TN_Location>(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'失败:更新终点货位{endLoc.S_CODE}锁状态失败"; LogHelper.Info(info); return NewSimpleResult(4, info); } if (db.Insertable<TN_Task>(task).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'失败,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); return NewSimpleResult(4, info); } tran.CommitTran(); return NewSimpleResult(0, $"生成 {taskName} 成功,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'成功,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); return NewSimpleResult(0, info); } } catch (Exception ex) { info = $"发生了异常:{ex.Message}"; LogHelper.Info(info); LogHelper.InfoEx(ex); return NewSimpleResult(1, info); } } @@ -327,7 +343,9 @@ .First(); if (startLoc == null) { return NewSimpleResult(2, $"起点位置 '{model.StartLoc}' 不存在或不具备取货要求"); info = $"起点位置{model.StartLoc}不存在或不具备取货要求"; LogHelper.Info(info); return NewSimpleResult(2, info); } // 查看容器与起点货位是否绑定 @@ -336,7 +354,9 @@ .First(); if (locCntrRel == null) { return NewSimpleResult(3, $"起点位置 '{model.StartLoc}' 没有绑定容器 '{model.CntrCode}'"); info = $"起点位置{model.StartLoc}没有绑定容器{model.CntrCode}"; LogHelper.Info(info); return NewSimpleResult(3, info); } // TODO 暂定选择最低层按区位顺序入库,后面待修改 @@ -352,38 +372,51 @@ var cntId = locCntrRel.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 LocationHelper.LockLoc(ref startLoc, 2); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 1); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_Location>(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'失败:更新起点货位{startLoc.S_CODE}锁状态失败"; LogHelper.Info(info); return NewSimpleResult(4, info); } if (db.Updateable<TN_Location>(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'失败:更新终点货位{endLoc.S_CODE}锁状态失败"; LogHelper.Info(info); return NewSimpleResult(4, info); } if (db.Insertable<TN_Task>(task).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'失败,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); return NewSimpleResult(4, info); } tran.CommitTran(); return NewSimpleResult(0, $"生成 {taskName} 成功,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'成功,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); return NewSimpleResult(0, info); } } catch (Exception ex) { return BuildSimpleEx(ex); info = $"发生了异常:{ex.Message}"; LogHelper.InfoEx(ex); return NewSimpleResult(1, info); } } @@ -431,8 +464,8 @@ var cntId = locCntrRel.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 LocationHelper.LockLoc(ref startLoc, 2); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 1); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_Location>(startLoc).UpdateColumns(it => new { @@ -442,8 +475,9 @@ it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'失败:更新起点货位{startLoc.S_CODE}锁状态失败"; LogHelper.Info(info); return NewSimpleResult(4, info); } if (db.Updateable<TN_Location>(endLoc).UpdateColumns(it => new { @@ -452,25 +486,29 @@ it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'失败:更新终点货位{endLoc.S_CODE}锁状态失败"; LogHelper.Info(info); return NewSimpleResult(4, info); } if (db.Insertable<TN_Task>(task).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'失败,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); return NewSimpleResult(4, info); } tran.CommitTran(); return NewSimpleResult(0, $"生成 {taskName} 成功,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'成功,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); return NewSimpleResult(0, info); } } catch (Exception ex) { return BuildSimpleEx(ex); info = $"发生了异常:{ex.Message}"; LogHelper.InfoEx(ex); return NewSimpleResult(1, info); } } @@ -517,38 +555,51 @@ var cntId = locCntrRel.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 LocationHelper.LockLoc(ref startLoc, 2); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 1); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_Location>(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'失败:更新起点货位{startLoc.S_CODE}锁状态失败"; LogHelper.Info(info); return NewSimpleResult(4, info); } if (db.Updateable<TN_Location>(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'失败:更新终点货位{endLoc.S_CODE}锁状态失败"; LogHelper.Info(info); return NewSimpleResult(4, info); } if (db.Insertable<TN_Task>(task).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'失败,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); return NewSimpleResult(4, info); } tran.CommitTran(); return NewSimpleResult(0, $"生成 {taskName} 成功,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); info = $"生成任务'{taskName}'成功,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); return NewSimpleResult(0, info); } } catch (Exception ex) { return BuildSimpleEx(ex); info = $"发生了异常:{ex.Message}"; LogHelper.InfoEx(ex); return NewSimpleResult(1, info); } } @@ -621,7 +672,9 @@ return NewSimpleResult(0, $"创建 抽检单 成功"); } catch (Exception ex) { return BuildSimpleEx(ex); info = $"发生了异常:{ex.Message}"; LogHelper.InfoEx(ex); return NewSimpleResult(1, info); } } /// <summary> @@ -693,8 +746,8 @@ var cntId = locCntrRel.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 LocationHelper.LockLoc(ref startLoc, 2); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 1); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_CG_Detail>(cgDetail).UpdateColumns(it => @@ -744,7 +797,7 @@ } catch (Exception ex) { info = $"发生了异常:{ex.Message}"; LogHelper.Info(info); LogHelper.InfoEx(ex); return NewSimpleResult(1, info); } } @@ -798,8 +851,8 @@ var cntId = locCntrRel.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 LocationHelper.LockLoc(ref startLoc, 2); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 1); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_CG_Detail>(cgDetail).UpdateColumns(it => @@ -848,7 +901,9 @@ } } catch (Exception ex) { return BuildSimpleEx(ex); info = $"发生了异常:{ex.Message}"; LogHelper.InfoEx(ex); return NewSimpleResult(1, info); } } @@ -859,6 +914,7 @@ try { var startLoc = db.Queryable<TN_Location>() .Where(l => l.S_CODE == model.StartLoc) .Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y") // 筛选:未上锁 .First(); var locCntrRel = db.Queryable<TN_Loc_Container>() @@ -879,8 +935,8 @@ var cntId = locCntrRel.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 LocationHelper.LockLoc(ref startLoc, 2); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 1); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_Location>(startLoc).UpdateColumns(it => new { @@ -922,8 +978,9 @@ } } catch (Exception ex) { return BuildSimpleEx(ex); info = $"发生了异常:{ex.Message}"; LogHelper.InfoEx(ex); return NewSimpleResult(1, info); } } @@ -1047,7 +1104,9 @@ return NewSimpleResult(0, "生成出库单成功"); } catch (Exception ex) { return BuildSimpleEx(ex); info = $"发生了异常:{ex.Message}"; LogHelper.InfoEx(ex); return NewSimpleResult(1, info); } } @@ -1107,7 +1166,9 @@ return NewSimpleResult(0, "生成出库单成功"); } catch (Exception ex) { return BuildSimpleEx(ex); info = $"发生了异常:{ex.Message}"; LogHelper.InfoEx(ex); return NewSimpleResult(1, info); } } @@ -1172,7 +1233,7 @@ } catch (Exception ex) { info = $"发生了异常:{ex.Message}"; LogHelper.Info(info); LogHelper.InfoEx(ex); return result; } } @@ -1246,7 +1307,9 @@ return NewSimpleResult(0, $"创建 抽检单 成功"); } catch (Exception ex) { return BuildSimpleEx(ex); info = $"发生了异常:{ex.Message}"; LogHelper.InfoEx(ex); return NewSimpleResult(1, info); } } @@ -1266,11 +1329,10 @@ } catch (Exception ex) { info = $"发生了异常:{ex.Message}"; LogHelper.Info(info); LogHelper.InfoEx(ex); return result; } } private static string GenerateOrderNo(string snType, string prefix) { var id = SYSHelper.GetSerialNumber(snType, prefix); @@ -1286,12 +1348,13 @@ public static WmsResult CgInfoSync(CgInfoSyncInfo model) { var db = new SqlHelper<object>().GetInstance(); var random = new Random(); var info = ""; try { var detail = new TN_CG_Detail { S_ITEM_CODE = model.ItemCode, S_ITEM_NAME = model.ItemName, S_CNTR_CODE = Guid.NewGuid().ToString("D"), // NOTE 容器号:目前随机(后期可能会指定,或者PDA绑定时再填入) S_CNTR_CODE = GenerateOrderNo("容器号", "CN"), // NOTE 容器号:目前随机(后期可能会指定,或者PDA绑定时再填入) S_BATCH_NO = model.BatchNo, S_STANDARD = model.Standard, S_NET_WEIGHT = model.NetWeight, @@ -1299,31 +1362,35 @@ //N_PRODUCT_LINE = random.Next(0, 3), // NOTE 产线号:目前随机(后期可能会指定,或者PDA绑定时再填入) }; // 货位容器绑定的逻辑,在好运箱下线PDA的流程中操作 //var locCntrRel = new TN_Loc_Container { // //S_LOC_CODE = Settings.Config.ProductionLines[detail.N_PRODUCT_LINE].OffLoc[0], // 好运箱的位置是操作区,不是产线 // S_CNTR_CODE = detail.S_CNTR_CODE, // S_CNTR_TYPE = "好运箱", // 贴标机只针对好运箱 //}; //using (var tran = db.Ado.UseTran()) { // if (db.Insertable<TN_CG_Detail>(detail).ExecuteCommand() <= 0 // && db.Insertable<TN_Loc_Container>(detail).ExecuteCommand() <= 0) { // tran.RollbackTran(); // return MesResultBuilder(2, "插入物料信息失败:" + JsonConvert.SerializeObject(detail)); // } // tran.CommitTran(); //} using (var tran = db.Ado.UseTran()) { if (db.Insertable<TN_CG_Detail>(detail).ExecuteCommand() <= 0) { tran.RollbackTran(); info = "插入物料信息失败:" + JsonConvert.SerializeObject(detail); return NewWmsResult(2, info); } if (db.Insertable<TN_CG_Detail>(detail).ExecuteCommand() <= 0) { return MesResultBuilder(2, "插入物料信息失败:" + JsonConvert.SerializeObject(detail)); //if (db.Insertable<TN_Loc_Container>(locCntrRel).ExecuteCommand() <= 0) { // tran.RollbackTran(); // info = "插入物料信息失败:" + JsonConvert.SerializeObject(detail); // return NewWmsResult(2, info); //} tran.CommitTran(); } return MesResultBuilder(0, "插入物料信息成功"); info = "插入物料信息成功"; return NewWmsResult(0, info); } catch (Exception ex) { return MesResultBuilder(1, ex.Message); info = $"发生了异常:{ex.Message}"; LogHelper.InfoEx(ex); return NewWmsResult(1, info); } } } api/ApiModel.cs
@@ -28,20 +28,6 @@ } /// <summary> /// 构建 <see cref="SimpleResult"/> 异常返回值,选择打印异常日志信息(默认打印) /// </summary> /// <param name="ex"></param> /// <param name="exCode"></param> /// <param name="pringLog"></param> /// <returns></returns> public static SimpleResult BuildSimpleEx(Exception ex, int exCode = 1, bool pringLog = true) { if (pringLog) { LogHelper.InfoEx(ex); } return new SimpleResult { resultCode = exCode, resultMsg = ex.Message }; } /// <summary> /// HostToAGV 上报任务状态 /// </summary> public class AgvTaskState { @@ -69,7 +55,7 @@ public class SafetyInteractionInfo { public int station_id { get; set; } //public int station_id { get; set; } /// <summary> /// 请求上线/下线的的站台库位名称,例如work6、work8 @@ -80,7 +66,7 @@ /// 请求码 /// </summary> public string apply_code { get; set; } public string task_no { set; get; } //public string task_no { set; get; } } /// <summary> @@ -89,6 +75,10 @@ public class ReturnResult { public int ResultCode { get; set; } public string ResultMsg { get; set; } } public static ReturnResult NewReturnResult(int code, string message) { return new ReturnResult { ResultCode = code, ResultMsg = message }; } public class orderStatusReportParme { @@ -153,13 +143,10 @@ /// 返回给GZ /// </summary> public class GzResult { public int resultCode { get; set; } public string msg { get; set; } public int orderID { get; set; } } } @@ -172,7 +159,8 @@ /// <summary> /// 物料编码 /// </summary> public string s_item_code { get; set; } [JsonProperty("s_item_code")] public string ItemCode { get; set; } ///// <summary> ///// 物料名称 ///// </summary> @@ -181,20 +169,23 @@ /// <summary> /// 批次号 /// </summary> public string s_batch { get; set; } [JsonProperty("s_batch")] public string BatchNo { get; set; } /// <summary> /// 物料规格 /// </summary> [JsonProperty("s_spec")] public string s_spec { get; set; } /// <summary> /// 数量 /// </summary> [JsonProperty("n_num")] public int n_num { get; set; } /// <summary> /// 起点货位信息 /// </summary> public string s_start_loc { get; set; } [JsonProperty("s_start_loc")] public string StartLoc { get; set; } } /// <summary> /// 空托/空箱入库绑定(PDA)数据类 @@ -559,10 +550,7 @@ public string Data { get; set; } } public static WmsResult MesResultBuilder(int code, string message = "", bool printLog = true) { if (printLog && string.IsNullOrEmpty(message)) { LogHelper.Info(message); } public static WmsResult NewWmsResult(int code, string message = "", bool printLog = true) { return new WmsResult { Result = code, Success = code == 0, // 仅当code=0时,success=true api/DebugController.cs
@@ -3,6 +3,7 @@ using System.Runtime.ConstrainedExecution; using System.Web.Http; using HH.WCS.Mobox3.DSZSH.core; using HH.WCS.Mobox3.DSZSH.models; using HH.WCS.Mobox3.DSZSH.util; @@ -18,15 +19,45 @@ public class DebugController : ApiController { /// <summary> /// 模拟 AGV 多次回报任务状态 /// AGV状态一键回报134562 /// </summary> /// <param name="model">容器号</param> /// <returns></returns> [HttpPost] [Route("AgvSeriesReports")] public ReturnResults AgvSeriesReports(UpdateTaskState model) { return new ReturnResults(); [Route("AGVSeriesReports")] public ReturnResults AGVSeriesReports(UpdateTaskState model) { var agvTaskState = new AgvTaskState() { task_no = model.TaskID, forklift_no = model.ForkliftNo, state = 1 }; ReturnResults returnResult = new ReturnResults(); returnResult.ResultList = new List<ReturnResult>(); var temp1 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp1); agvTaskState.state = 3; var temp3 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp3); agvTaskState.state = 4; var temp4 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp4); agvTaskState.state = 5; var temp5 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp5); agvTaskState.state = 6; var temp6 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp6); agvTaskState.state = 2; var temp2 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp2); return returnResult; } /// <summary> api/MoboxController.cs
@@ -21,7 +21,9 @@ [HttpPost] [Route("goodpack-offline")] public SimpleResult GoodpackOffline(GoodpackOfflineInfo model) { LogHelper.InfoApi("好运箱-满托下线入库(PDA)", model); var apiName = "好运箱-满托下线入库(PDA)"; LogHelper.InfoApi(apiName, model); return ApiHelper.GoodpackOffline(model); } @@ -54,7 +56,8 @@ [HttpPost] [Route("empty-inbound")] public SimpleResult EmptyInbound(EmptyInboundInfo model) { LogHelper.InfoApi("空托/空箱入库", model); var apiName = "空托/空箱入库"; LogHelper.InfoApi(apiName, model); if (model.CntrType == "托盘") { return ApiHelper.EmptyInboundPallet(model); @@ -107,6 +110,8 @@ [HttpPost] [Route("empty-online-pallet")] public SimpleResult EmptyOnlinePallet(EmptyOnlinePalletInfo model) { var apiName = "托盘-空托上线(PDA)"; LogHelper.InfoApi(apiName, model); return ApiHelper.EmptyOnlinePallet(model); } @@ -118,6 +123,8 @@ [HttpPost] [Route("empty-online-goodpack")] public SimpleResult EmptyOnlineGoodpack(EmptyOnlineGoodpackInfo model) { var apiName = "好运箱-空箱上线(PDA)"; LogHelper.InfoApi(apiName, model); return ApiHelper.EmptyOnlineGoodpack(model); } @@ -146,6 +153,8 @@ [HttpPost] [Route("qualified-back")] public SimpleResult QualifiedBack(QualifiedBackInfo model) { var apiName = "合格回库(PDA)"; LogHelper.InfoApi(apiName, model); return ApiHelper.QualifiedBack(model); } @@ -156,6 +165,8 @@ [HttpPost] [Route("unqualified-shift")] public SimpleResult UnqualifiedShift(UnqualifiedShiftInfo model) { var apiName = "不合格移库(PDA)"; LogHelper.InfoApi(apiName, model); return ApiHelper.UnqualifiedShift(model); } @@ -167,6 +178,8 @@ [HttpPost] [Route("rest-back")] public SimpleResult RestBack(RestBackInfo model) { var apiName = "余料尾箱回库(PDA)"; LogHelper.InfoApi(apiName, model); return ApiHelper.RestBack(model); } @@ -178,7 +191,8 @@ [HttpPost] [Route("finished-outbound")] public SimpleResult FinishedOutbound(FinishedOutboundInfo model) { LogHelper.InfoApi("成品胶出库(PDA)", model); var apiName = "成品胶出库(PDA)"; LogHelper.InfoApi(apiName, model); if (model.ForcedOut) { return ApiHelper.FinishedOutboundForce(model); @@ -188,26 +202,26 @@ } } /// <summary> /// 抽检-创建抽检单(WMS) /// </summary> /// <param name="model"></param> /// <returns></returns> [HttpPost] [Route("create-check-order")] public SimpleResult CreateCheckOrder(CreateCheckOrderInfo model) { return ApiHelper.CreateCheckOrder(model); } ///// <summary> ///// 抽检-创建抽检单(WMS) ///// </summary> ///// <param name="model"></param> ///// <returns></returns> //[HttpPost] //[Route("create-check-order")] //public SimpleResult CreateCheckOrder(CreateCheckOrderInfo model) { // return ApiHelper.CreateCheckOrder(model); //} /// <summary> /// 移库-创建移库任务(WMS) /// </summary> /// <param name="model"></param> /// <returns></returns> [HttpPost] [Route("shift-storage")] public SimpleResult CreateShiftOrder(CreateShiftOrderInfo model) { return ApiHelper.CreateShiftOrder(model); } ///// <summary> ///// 移库-创建移库任务(WMS) ///// </summary> ///// <param name="model"></param> ///// <returns></returns> //[HttpPost] //[Route("shift-storage")] //public SimpleResult CreateShiftOrder(CreateShiftOrderInfo model) { // return ApiHelper.CreateShiftOrder(model); //} } } core/Monitor.cs
@@ -11,10 +11,42 @@ namespace HH.WCS.Mobox3.DSZSH.core { public class Monitor { public static void CheckInbound() { var taskName = TaskName.托盘_满托下线入库; var db = new SqlHelper<object>().GetInstance(); var info = ""; try { // 查产线是否有物料信息 var itemCode = ""; var batchNo = ""; var cntrCode = ""; var startLocCode = ""; var cgDetail = new TN_CG_Detail { S_ITEM_CODE = itemCode, S_BATCH_NO = batchNo, S_CNTR_CODE = cntrCode, }; var startLoc = db.Queryable<TN_Location>() .Where(l => l.S_CODE == startLocCode) // 指定:起点货位号 .Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y") // 筛选:未上锁 .First(); } catch (Exception ex) { LogHelper.InfoEx(ex); } } public static void CheckOutboundOrder() { var taskName = TaskName.成品胶出库; var db = new SqlHelper<object>().GetInstance(); var info = ""; var info = $"轮询--{taskName}--"; try { var orderList = db.Queryable<TN_Outbound_Order>() @@ -23,7 +55,8 @@ .ToList(); if (orderList.Count == 0) { LogHelper.Info("轮询--出库--暂无待执行的Order"); info += $"暂无待执行的{taskName}单"; LogHelper.Info(info); return; } @@ -33,7 +66,8 @@ .Count(d => d.S_OO_NO == order.S_NO && d.N_B_STATE >= 2); // 执行中 var allCount = db.Queryable<TN_Outbound_Detail>() .Count(d => d.S_OO_NO == order.S_NO); LogHelper.Info($"轮询--出库--统计出库单'{order.S_NO}'任务已下发:{doingCount}/{allCount}"); info += $"统计{taskName}单'{order.S_NO}'任务已下发:{doingCount}/{allCount}"; LogHelper.Info(info); if (doingCount == allCount) { order.N_B_STATE = 2; // 所有任务都已执行 @@ -44,16 +78,20 @@ var lastDetail = db.Queryable<TN_Outbound_Detail>() .Where(d => d.S_OO_NO == order.S_NO && d.N_B_STATE == 2) // TODO 或者改成查task .First(); if (lastDetail != null) { LogHelper.Info($"轮询--出库--出库单'{order.S_NO}'上一个任务仍在进行中:" + JsonConvert.SerializeObject(lastDetail)); info += $"{taskName}单'{order.S_NO}'上一个任务仍在进行中:" + JsonConvert.SerializeObject(lastDetail); LogHelper.Info(info); continue; } var outboundDetail = db.Queryable<TN_Outbound_Detail>() .Where(a => a.S_OO_NO == order.S_NO && a.N_B_STATE == 1) // 已下发 .First(); if (outboundDetail != null) { LogHelper.Info($"轮询--出库--"); if (outboundDetail == null) { info += $"仍有任务未执行完成,但当前没有已下发的任务"; LogHelper.Info(info); continue; } @@ -61,13 +99,9 @@ } if (detailList.Count == 0) { // 上面流程已经打印过日志 return; } var startLocList = new List<TN_Location>(); var endLocList = new List<TN_Location>(); var taskList = new List<TN_Task>(); foreach (var detail in detailList) { var startLoc = db.Queryable<TN_Location>() @@ -76,7 +110,7 @@ .First(); if (startLoc == null) { LogHelper.Info($"轮询--出库:没有找到合适的起点货位!"); LogHelper.Info($"轮询--{taskName}:没有找到合适的起点货位!"); continue; } @@ -86,7 +120,7 @@ .Where(a => a.N_CURRENT_NUM == 0).First(); if (endLoc == null) { LogHelper.Info($"轮询--出库:没有找到合适的终点货位!S_NO为 '{detail.S_OO_NO}',要求Area为 '{detail.S_END_AREA}'"); LogHelper.Info($"轮询--{taskName}:没有找到合适的终点货位!单号'{detail.S_OO_NO}'要求终点库区为'{detail.S_END_AREA}'"); continue; } @@ -95,13 +129,15 @@ var cntId = detail.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 LocationHelper.LockLoc(ref startLoc, 2); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 1); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_Outbound_Detail>(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand() <= 0) { tran.RollbackTran(); LogHelper.Info($"轮询--出库--修改明细表状态为完成失败!"); info += $"修改明细表状态为完成--失败!"; LogHelper.Info(info); continue; } if (db.Updateable<TN_Location>(startLoc).UpdateColumns(it => new { @@ -111,7 +147,7 @@ it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; info += $"生成任务'{taskName}'失败:更新起点货位{startLoc.S_CODE}锁状态失败"; LogHelper.Info(info); continue; } @@ -122,28 +158,28 @@ it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; info += $"生成任务'{taskName}'失败:更新终点货位{endLoc.S_CODE}锁状态失败"; LogHelper.Info(info); continue; } if (db.Insertable<TN_Task>(task).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; info += $"生成任务'{taskName}'失败,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); continue; } tran.CommitTran(); info = $"生成 {taskName} 成功,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; info += $"生成任务'{taskName}'成功,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); continue; } } } catch (Exception ex) { info += $"发生了异常:{ex.Message}"; LogHelper.InfoEx(ex); } } @@ -152,6 +188,7 @@ var taskName = TaskName.抽检_出库; var db = new SqlHelper<object>().GetInstance(); var info = ""; try { var orderList = db.Queryable<TN_Check_Order>() .Where(c => c.N_B_STATE == 1) @@ -182,7 +219,7 @@ .ToList(); if (checkDetailList.Count == 0) { LogHelper.Info($"轮询--"); LogHelper.Info($"轮询--{taskName}--仍有任务未执行完成,但当前没有已下发的任务"); continue; } @@ -217,8 +254,8 @@ var cntId = detail.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 LocationHelper.LockLoc(ref startLoc, 2); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 1); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_Check_Detail>(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand() <= 0) { @@ -234,7 +271,7 @@ it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; info = $"生成任务'{taskName}'失败:更新起点货位{startLoc.S_CODE}锁状态失败"; LogHelper.Info(info); continue; } @@ -246,20 +283,20 @@ it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; info = $"生成任务'{taskName}'失败:更新终点货位{endLoc.S_CODE}锁状态失败"; LogHelper.Info(info); continue; } if (db.Insertable<TN_Task>(task).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; info = $"生成任务'{taskName}'失败,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); continue; } tran.CommitTran(); info = $"生成 {taskName} 成功,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; info = $"生成任务'{taskName}'成功,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); continue; } @@ -304,7 +341,7 @@ .ToList(); if (checkDetailList.Count == 0) { LogHelper.Info($"轮询--"); LogHelper.Info($"轮询--{taskName}--仍有任务未执行完成,但当前没有已下发的任务"); continue; } @@ -339,8 +376,8 @@ var cntId = detail.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 LocationHelper.LockLoc(ref startLoc, 2); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 1); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_Shift_Detail>(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand() <= 0) { @@ -356,7 +393,7 @@ it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; info = $"生成任务'{taskName}'失败:更新起点货位{startLoc.S_CODE}锁状态失败"; LogHelper.Info(info); continue; } @@ -368,20 +405,20 @@ it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; info = $"生成任务'{taskName}'失败:更新终点货位{endLoc.S_CODE}锁状态失败"; LogHelper.Info(info); continue; } if (db.Insertable<TN_Task>(task).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; info = $"生成任务'{taskName}'失败,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); continue; } tran.CommitTran(); info = $"生成 {taskName} 成功,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; info = $"生成任务'{taskName}'成功,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); continue; } core/WCSCore.cs
@@ -5,7 +5,6 @@ using System.Threading.Tasks; using HH.WCS.Mobox3.DSZSH.device; using HH.WCS.Mobox3.DSZSH.models; using HH.WCS.Mobox3.DSZSH.process; using HH.WCS.Mobox3.DSZSH.util; @@ -14,7 +13,6 @@ using Newtonsoft.Json; using static HH.WCS.Mobox3.DSZSH.api.ApiModel; namespace HH.WCS.Mobox3.DSZSH.core { public class WCSCore { @@ -102,11 +100,11 @@ case 2: // 完成 WCSHelper.End(TN_Task); // 任务状态改成结束 if (TN_Task.S_TYPE == TaskName.抽检_出库) { var checkCompleteTask = Task.Run(() => { UpdateCheckTaskState(3); }); } //if (TN_Task.S_TYPE == TaskName.抽检_出库) { // var checkCompleteTask = Task.Run(() => { // UpdateCheckTaskState(3); // }); //} break; case 7: // 异常 @@ -123,45 +121,90 @@ } public static ReturnResult SafetyInteraction(SafetyInteractionInfo model) { var gzResult = new ReturnResult(); var db = new SqlHelper<object>().GetInstance(); ModbusHelper.Relink(); var info = ""; try { ModbusHelper.Relink(); var prodLineInfo = Settings.ProductionLines[0]; var prodLineDevice = new ProductionLineDevice(prodLineInfo.PlcIp, prodLineInfo.PlcPort); if (!prodLineDevice.LoadDeviceStateOk()) { LogHelper.Info("加载设备信息失败"); info = "与产线设备通讯失败"; LogHelper.Info(info); return NewReturnResult(2, info); } var tn_task = db.Queryable<TN_Task>().First(a => a.S_CODE == model.task_no); if (tn_task == null) { LogHelper.Info($"任务号 '{model.task_no}' 不存在"); //var tn_task = db.Queryable<TN_Task>().First(a => a.S_CODE == model.task_no); //if (tn_task == null) { // LogHelper.Info($"任务号 '{model.task_no}' 不存在"); //} //if (prodLineDevice.SystemState == 1) { // if (prodLineDevice.FullOffline == 1 && tn_task.S_TYPE == TaskName.托盘_满托下线入库) { // prodLineDevice.AgvPicking = 1; // } // if (prodLineDevice.AllowAgvPlacePallet == 1 && tn_task.S_TYPE == TaskName.托盘_空托上线) { // prodLineDevice.AgvPlacingPallet = 1; // } //} if (prodLineDevice.SystemState != 1) { info = $"当前产线无法与AGV联动:状态{prodLineDevice.SystemState}"; LogHelper.Info(info); return NewReturnResult(3, info); } // 待修改:补充不同分支AGV判断 if (prodLineDevice.SystemState == 1) { if (prodLineDevice.FullOffline == 1 && tn_task.S_TYPE == TaskName.托盘_满托下线入库) { prodLineDevice.AgvPicking = 1; if (model.apply_code == "5") { if (prodLineDevice.FullOffline != 1) { info = $"当前输送线满料下线信号不为1,无法取货"; LogHelper.Info(info); return NewReturnResult(4, info); } if (prodLineDevice.AllowAgvPlacePallet == 1 && tn_task.S_TYPE == TaskName.托盘_空托上线) { prodLineDevice.AgvPlacingPallet = 1; if (!prodLineDevice.SetAgvPicking(1)) { info = $"向输送线写入允许取货信号失败"; LogHelper.Info(info); return NewReturnResult(5, info); } info = $"向输送线写入允许取货信号成功"; LogHelper.Info(info); return NewReturnResult(0, info); } else if (model.apply_code == "1") { if (prodLineDevice.AllowAgvPlacePallet != 1) { info = $"当前输送线允许放托盘信号不为1,无法放货"; LogHelper.Info(info); return NewReturnResult(6, info); } if (!prodLineDevice.SetAgvPlacingPallet(1)) { info = $"向输送线写入允许放货信号失败"; LogHelper.Info(info); return NewReturnResult(7, info); } info = $"向输送线写入允许放货信号成功"; LogHelper.Info(info); return NewReturnResult(0, info); } else { info = $"当前输送线允许"; LogHelper.Info(info); return NewReturnResult(8, info); } LogHelper.Info(JsonConvert.SerializeObject(prodLineDevice, Formatting.Indented)); return gzResult; } catch (Exception ex) { LogHelper.Info($"发生了异常:{ex.Message}"); return gzResult; info = $"发生了异常:{ex.Message}"; LogHelper.InfoEx(ex); return NewReturnResult(1, info); } } public static void UpdateOutboundTaskState(int spotStateCode) { var db = new SqlHelper<object>().GetInstance(); var detail = db.Queryable<TN_Outbound_Detail>() @@ -280,5 +323,26 @@ tran.CommitTran(); } } /// <summary> /// 任务分发,根据调度类型发给不同的调度系统 /// </summary> internal static void Dispatch() { //查询任务 //获取所有等待的任务 var list = WCSHelper.GetWaitingTaskList(); LogHelper.Info("等待任务信息" + JsonConvert.SerializeObject(list), "API"); if (list.Count > 0) { list.ForEach(task => { //使用自定义任务推送 TaskProcess.SendTask(task);//调度NDC或杭奥或国自设备 //TaskProcess.SendGZTask(task);///调度国自设备 }); } else { LogHelper.Info("暂无任务"); } } } } device/ProductionLineDevice.cs
@@ -1,6 +1,7 @@ using System; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace HH.WCS.Mobox3.DSZSH.device { /// <summary> @@ -46,29 +47,65 @@ /// </summary> public int AllowAgvPlacePallet { get; set; } private int _agvPicking; private int _agvPlacingPallet; //private int _agvPicking; //private int _agvPlacingPallet; ///// <summary> ///// AGV 正在取货:下线AGV写入1,取货完成后恢复0 ///// </summary> //public int AgvPicking { // get => _agvPicking; // set { // var isOk = ModbusHelper.WriteSingleRegister(10, value, Ip, Port); // _agvPicking = isOk ? value : throw new Exception($"修改 [AGV 正在取货] 为 '{value}' 失败"); // } //} /// <summary> /// AGV 正在取货:下线AGV写入1,取货完成后恢复0 /// </summary> public int AgvPicking { get => _agvPicking; set { var isOk = ModbusHelper.WriteSingleRegister(10, value, Ip, Port); _agvPicking = isOk ? value : throw new Exception($"修改 [AGV 正在取货] 为 '{value}' 失败"); public int AgvPicking { get; set; } /// <summary> /// AGV 正在取货:下线AGV写入1,取货完成后恢复0 /// </summary> /// <param name="value"></param> /// <returns></returns> public bool SetAgvPicking(int value) { if (!ModbusHelper.WriteSingleRegister(10, value, Ip, Port)) { return false; } AgvPicking = value; return true; } ///// <summary> ///// AGV 正在放托盘垛:上线AGV写入1,放托完成后恢复0 ///// </summary> //public int AgvPlacingPallet { // get => _agvPlacingPallet; // set { // var isOk = ModbusHelper.WriteSingleRegister(11, value, Ip, Port); // _agvPlacingPallet = isOk ? value : throw new Exception($"修改 [AGV 正在放托盘垛] 为 '{value}' 失败"); // } //} /// <summary> /// AGV 正在放托盘垛:上线AGV写入1,放托完成后恢复0 /// </summary> public int AgvPlacingPallet { get => _agvPlacingPallet; set { var isOk = ModbusHelper.WriteSingleRegister(11, value, Ip, Port); _agvPlacingPallet = isOk ? value : throw new Exception($"修改 [AGV 正在放托盘垛] 为 '{value}' 失败"); public int AgvPlacingPallet { get; set; } /// <summary> /// AGV 正在放托盘垛:上线AGV写入1,放托完成后恢复0 /// </summary> public bool SetAgvPlacingPallet(int value) { if (!ModbusHelper.WriteSingleRegister(11, value, Ip, Port)) { return false; } AgvPlacingPallet = value; return true; } public bool LoadDeviceStateOk() { @@ -83,8 +120,10 @@ CallPallet = readArray[2]; AllowAgvPlacePallet = readArray[3]; // 可写地址数据 _agvPicking = readArray[10]; _agvPlacingPallet = readArray[11]; //_agvPicking = readArray[10]; //_agvPlacingPallet = readArray[11]; AgvPicking = readArray[10]; AgvPlacingPallet = readArray[11]; var log = JsonConvert.SerializeObject(readArray); LogHelper.Info(log); device/TcpClientHelper.cs
New file @@ -0,0 +1,323 @@ using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using Newtonsoft.Json; namespace HH.WCS.Mobox3.DSZSH.device { public class TcpClientHelper { private static Socket _clientSocket; private static byte[] _buffer = new byte[1024]; public static Dictionary<string, byte[]> _receivedDataQueue = new Dictionary<string, byte[]>(); public static string _ip { get; set; } public static int _port { get; set; } private static bool _isConnecting = false; // 标记是否正在连接中 private static readonly object _connectLock = new object(); // 连接操作的同步锁 /// <summary> /// 重连的话调用方再实例化一个就行了 /// </summary> /// <param name="ip"></param> /// <param name="port"></param> public static bool Init(string ip, int port) { lock (_connectLock) { try { // 若正在连接中,直接返回 if (_isConnecting) { LogHelper.Info("已有连接正在尝试中,禁止重复操作"); return false; } _isConnecting = true; // 标记为连接中 // 释放旧 Socket(仅在未连接时) if (_clientSocket != null && !_clientSocket.Connected) { SafeCloseSocket(); } // 创建新 Socket 并连接 _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress ipAdd = IPAddress.Parse(ip); IPEndPoint endPoint = new IPEndPoint(ipAdd, port); _clientSocket.BeginConnect(endPoint, ConnectCallback, null); // 更新 IP 和端口 _ip = ip; _port = port; return true; } catch (SocketException ex) { _isConnecting = false; LogHelper.Error($"初始化连接失败: {ex.Message}", ex); return false; } } } private static readonly object _linkLock = new object(); public static bool Link(string ip, int port) { lock (_linkLock) { try { // 若Socket存在但实际已断开,强制清理 if (_clientSocket != null && (_clientSocket.Poll(0, SelectMode.SelectRead) && _clientSocket.Available == 0)) { SafeCloseSocket(); } // 原有逻辑 if (_clientSocket != null && _clientSocket.Connected) { LogHelper.Info($"电梯已连接,无需重连,IP:{ip},端口:{port}"); return false; } return Init(ip, port); } catch (Exception ex) { LogHelper.Error($"电梯重连失败,IP:{ip},端口:{port},异常:{ex.Message}", ex); return false; } } } public static bool TcpClose() { try { _clientSocket?.Close(); return true; } catch { return false; } } public static void SendMsg(string ip, int port, string message) { try { if (_clientSocket?.Connected == true) { byte[] data = Encoding.UTF8.GetBytes(message); _clientSocket.BeginSend(data, 0, data.Length, SocketFlags.None, SendCallback, null); } else { Link(ip, port); } } catch { /* 异常处理 */ } } private static void SendCallback(IAsyncResult ar) { try { _clientSocket.EndSend(ar); } catch { /* 发送异常处理 */ } } private static void ConnectCallback(IAsyncResult ar) { try { lock (_connectLock) { // 检查 Socket 是否有效 if (_clientSocket == null || !ar.IsCompleted) { LogHelper.Info("连接已取消或Socket无效"); return; } // 完成连接 _clientSocket.EndConnect(ar); // 仅在连接成功时启动接收 if (_clientSocket.Connected) { LogHelper.Info($"成功连接到服务端:{_ip}:{_port}"); _clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceiveCallback, null); } else { LogHelper.Info("连接未成功,关闭Socket"); SafeCloseSocket(); } } } catch (ObjectDisposedException) { LogHelper.Info("连接过程中Socket被释放"); } catch (Exception ex) { LogHelper.Error($"连接失败:{ex.Message}", ex); SafeCloseSocket(); } finally { _isConnecting = false; // 重置连接状态 } } // 安全的Socket关闭方法 private static void SafeCloseSocket() { try { if (_clientSocket != null) { // 避免重复关闭 if (_clientSocket.Connected) { _clientSocket.Shutdown(SocketShutdown.Both); } _clientSocket.Close(); _clientSocket.Dispose(); // 断开后:清除对应IP:Port的接收数据 string key = $"{_ip}:{_port}"; if (_receivedDataQueue.ContainsKey(key)) { _receivedDataQueue.Remove(key); LogHelper.Info($"已清理队列数据,Key:{key}"); } } } catch (Exception ex) { LogHelper.Error($"释放Socket资源异常:{ex.Message}", ex); } finally { _clientSocket = null; _isConnecting = false; // 确保重置连接标记 } } private static void ReceiveCallback(IAsyncResult ar) { try { if (_clientSocket == null) { return; } int bytesRead = _clientSocket.EndReceive(ar); if (bytesRead > 0) { // 复制有效数据到新数组 byte[] receivedBytes = new byte[bytesRead]; Array.Copy(_buffer, 0, receivedBytes, 0, bytesRead); // 存入队列 string key = $"{_ip}:{_port}"; string receivedMessage = Encoding.UTF8.GetString(receivedBytes); _receivedDataQueue[key] = receivedBytes; // 继续接收下一批数据 _clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceiveCallback, null); } else { // 服务端主动关闭连接,触发清理 LogHelper.Info("连接已被服务端关闭"); SafeCloseSocket(); } } catch (Exception ex) { LogHelper.Error($"接收数据异常:{ex.Message}", ex); SafeCloseSocket(); // 异常时主动关闭 } } public static bool WriteElevatorDownOk(byte[] sends) { try { if (_clientSocket?.Connected == true) { _clientSocket.BeginSend(sends, 0, sends.Length, SocketFlags.None, SendCallback, null); return true; } else { Link(_ip, _port); LogHelper.Info($"写电梯入货数据失败(未连接):{Encoding.UTF8.GetString(sends)}"); return false; } } catch (Exception ex) { LogHelper.Error($"写电梯入货数据失败(发送了异常):{ex.Message}", ex); return false; } } public static byte[] ReadElevatorOutOk() { try { if (_clientSocket != null && _clientSocket?.Connected == true) { _receivedDataQueue.TryGetValue($"{_ip}:{_port}", out byte[] result); LogHelper.Info($"读电梯出货数据成功:{BitConverter.ToString(result)}"); return result; } else { Link(_ip, _port); LogHelper.Info($"读电梯出货数据失败(未连接),准备重连"); return null; } } catch (Exception ex) { LogHelper.Error($"读电梯出货数据失败(发生了异常:{JsonConvert.SerializeObject(ex)}):{ex.Message}", ex); return null; /* 异常处理 */ } } public static string ChekElevator() { try { var res = "读取电梯数据的model,索引从1开始,满足以下条件才能发任务 \r\n " + "字段,isNormal ,是否正常模式,1:正常模式,第7个Byte右侧第一位Bit \r\n" + "字段,isValid,当前位置是否有效,1:有效,0:不用管,第9个Byte右侧第一位Bit \r\n" + "字段,runMode,电梯运行模式,9=空闲泊停,7=自动运行,第10个Byte\r\n" + "字段,isLock_1_Out,一层出口是否占用,1 = 占用,第14个Byte右侧第一位Bit\r\n" + "字段,isLock_2_Out,二层出口是否占用,1 = 占用,第14个Byte右侧第二位Bit\r\n" + "字段,taskNO,任务号\r\n" + "判断电梯是否符合2楼到1楼搬送条件:isNormal 且 (runMode == 9 或 runMode == 7) 且 !isLock_1_Out \r\n" + "判断电梯是否符合1楼到成品库区条件:isNormal 且 (runMode == 9 或 runMode == 7) 且 isLock_1_Out\r\n"; var isRead = ReadElevatorOutOk(); var log = BitConverter.ToString(isRead); res += "读取到的电梯byte数组:" + log + "\r\n"; //if (isRead != null && isRead.Length >= 14) { // var elevatorReadInfo = new ElevatorReadInfo() { // isNormal = (isRead[6] & 1) == 1, // isValid = (isRead[8] & 1) == 1, // runMode = isRead[9], // isLock_1_Out = (isRead[13] & 1) == 1, // isLock_2_Out = (isRead[13] & (1 << 1)) == 1, // }; // log = JsonConvert.SerializeObject(elevatorReadInfo); // res += "解析后的电梯信息" + log + "\r\n"; // var res1 = elevatorReadInfo.is2To1Ok(); // res += "判断电梯是否符合2楼到1楼搬送条件,如果符合则返回true,结果" + res1 + "\r\n"; // var res2 = elevatorReadInfo.is1ToOk(); // res += "判断电梯是否符合1楼到成品库区条件,如果符合则返回true,结果" + res2 + "\r\n"; //} //else { // return "读取电梯状态失败,byte数组要求大于等于14个且不为空"; //} return res; } catch (Exception ex) { return ex.Message; } } public static bool IsDuanDian() { try { var isRead = ReadElevatorOutOk(); //if (isRead != null && isRead.Length >= 14) { // var elevatorReadInfo = new ElevatorReadInfo() { // isNormal = (isRead[6] & 1) == 1, // isValid = (isRead[8] & 1) == 1, // runMode = isRead[9], // isLock_1_Out = (isRead[13] & 1) == 1, // isLock_2_Out = (isRead[13] & (1 << 1)) == 1, // }; // if (elevatorReadInfo.runMode == 5)//5=断电重连 // { // SafeCloseSocket(); // return true; // } //} return false; } catch (Exception ex) { LogHelper.Error($"判断电梯是否断电(发生了异常:{JsonConvert.SerializeObject(ex)}):{ex.Message}", ex); return false; } } } } process/TaskProcess.cs
@@ -112,81 +112,120 @@ var start = "0"; var end = "0"; var taskType = mst.S_TYPE.Trim(); if (mst.N_B_STATE == 0) { if (mst.N_SCHEDULE_TYPE == 1)//通过NDC,hosttoagv调度设备 { start = LocationHelper.GetAgvSite(mst.S_START_LOC); end = LocationHelper.GetAgvSite(mst.S_END_LOC); start = LocationHelper.GetAgvSite(mst.S_START_LOC); end = LocationHelper.GetAgvSite(mst.S_END_LOC); //if (mst.S_TYPE == "空托下线堆叠") { // end = LocationHelper.GetAgvSite(mst.S_END_LOC, true); //} //if (mst.S_TYPE == "空托下线堆叠") { // end = LocationHelper.GetAgvSite(mst.S_END_LOC, true); //} LogHelper.Info($"NDC推送任务 {mst.S_CODE};" + "start=" + start + "end= " + end); var startLoc = LocationHelper.GetLoc(mst.S_START_LOC); var endLoc = LocationHelper.GetLoc(mst.S_END_LOC); var dic = new List<param>(); dic.Add(new param() { name = "IKey", value = "IKey" }); dic.Add(new param() { name = "From", value = start.ToString() }); dic.Add(new param() { name = "To", value = end.ToString() }); dic.Add(new param() { name = "FUNC", value = startLoc.N_LAYER.ToString() }); LogHelper.Info($"NDC推送任务 {mst.S_CODE};" + "start=" + start + "end= " + end); var startLoc = LocationHelper.GetLoc(mst.S_START_LOC); var endLoc = LocationHelper.GetLoc(mst.S_END_LOC); var dic = new List<param>(); dic.Add(new param() { name = "IKey", value = "IKey" }); dic.Add(new param() { name = "From", value = start.ToString() }); dic.Add(new param() { name = "To", value = end.ToString() }); dic.Add(new param() { name = "FUNC", value = startLoc.N_LAYER.ToString() }); dic.Add(new param() { name = "Ctype", value = "0" }); dic.Add(new param() { name = "Ctype", value = "0" }); //if (mst.S_TYPE == "余料下线入库" || mst.S_TYPE == "人工拆盘入库") { // dic.Add(new param() { name = "DATA", value = "1024" }); //} //else { // dic.Add(new param() { name = "DATA", value = "0" }); //} //if (mst.S_TYPE == "余料下线入库" || mst.S_TYPE == "人工拆盘入库") { // dic.Add(new param() { name = "DATA", value = "1024" }); //} //else { // dic.Add(new param() { name = "DATA", value = "0" }); //} var res = NDCApi.AddOrderNew(1, 1, mst.S_CODE, dic);//添加新命令 if (res != null && (res.err_code == 0 || res.err_code == 50009)) { //推送成功,修改任务优先级 mst.N_B_STATE = 1; mst.S_B_STATE = TN_Task.GetStateStr(1); WCSHelper.UpdateStatus(mst);//更新任务状态 result = true; LogHelper.Info($"NDC推送任务成功 {mst.S_CODE}start= {mst.S_START_LOC} + end = {mst.S_END_LOC}"); } else { LogHelper.Info($"NDC推送任务失败 {mst.S_CODE};Res:" + JsonConvert.SerializeObject(res)); } var res = NDCApi.AddOrderNew(1, 1, mst.S_CODE, dic);//添加新命令 if (res != null && (res.err_code == 0 || res.err_code == 50009)) { //推送成功,修改任务优先级 mst.N_B_STATE = 1; mst.S_B_STATE = TN_Task.GetStateStr(1); WCSHelper.UpdateStatus(mst);//更新任务状态 result = true; LogHelper.Info($"NDC推送任务成功 {mst.S_CODE}start= {mst.S_START_LOC} + end = {mst.S_END_LOC}"); } else if (mst.N_SCHEDULE_TYPE == 5)//通过杭奥调度设备 { //调第三方接口 var model = new HanAo.TaskInfoModel { requestPk = mst.S_CODE, frmPos = mst.S_START_LOC, toPos = mst.S_END_LOC, trkType = mst.S_OP_NAME == "入库" ? "1" : "2", contNo = mst.S_CNTR_CODE }; if (HanAo.CreateOrder(model)) { mst.N_B_STATE = 1; WCSHelper.UpdateStatus(mst); LogHelper.Info($"杭奥推送任务成功 {mst.S_CODE};" + "start=" + model.frmPos + "end= " + model.toPos); } else { LogHelper.Info($"杭奥推送任务失败 {mst.S_CODE};" + JsonConvert.SerializeObject(model)); } else { LogHelper.Info($"NDC推送任务失败 {mst.S_CODE};Res:" + JsonConvert.SerializeObject(res)); } else if (mst.N_SCHEDULE_TYPE == 3) //通过国自调度设备 { var code = GZRobot.CreateOrder(mst.S_CODE, mst.N_PRIORITY, JsonConvert.SerializeObject(new { src = mst.S_START_LOC, dst = mst.S_END_LOC }), "p2p"); if (code > 0) { //更新任务状态 mst.N_B_STATE = 1; mst.S_EQ_TASK_CODE = code.ToString(); WCSHelper.UpdateStatus(mst); WCSHelper.UpdateEQNo(mst); LogHelper.Info($"国自推送任务成功 {mst.S_CODE};" + "start=" + mst.S_START_LOC + "end= " + mst.S_END_LOC); } else { LogHelper.Info($"国自推送任务失败 {mst.S_CODE};" + JsonConvert.SerializeObject(mst)); } } //if (mst.N_SCHEDULE_TYPE == 1)//通过NDC,hosttoagv调度设备 //{ // start = LocationHelper.GetAgvSite(mst.S_START_LOC); // end = LocationHelper.GetAgvSite(mst.S_END_LOC); // //if (mst.S_TYPE == "空托下线堆叠") { // // end = LocationHelper.GetAgvSite(mst.S_END_LOC, true); // //} // LogHelper.Info($"NDC推送任务 {mst.S_CODE};" + "start=" + start + "end= " + end); // var startLoc = LocationHelper.GetLoc(mst.S_START_LOC); // var endLoc = LocationHelper.GetLoc(mst.S_END_LOC); // var dic = new List<param>(); // dic.Add(new param() { name = "IKey", value = "IKey" }); // dic.Add(new param() { name = "From", value = start.ToString() }); // dic.Add(new param() { name = "To", value = end.ToString() }); // dic.Add(new param() { name = "FUNC", value = startLoc.N_LAYER.ToString() }); // dic.Add(new param() { name = "Ctype", value = "0" }); // //if (mst.S_TYPE == "余料下线入库" || mst.S_TYPE == "人工拆盘入库") { // // dic.Add(new param() { name = "DATA", value = "1024" }); // //} // //else { // // dic.Add(new param() { name = "DATA", value = "0" }); // //} // var res = NDCApi.AddOrderNew(1, 1, mst.S_CODE, dic);//添加新命令 // if (res != null && (res.err_code == 0 || res.err_code == 50009)) { // //推送成功,修改任务优先级 // mst.N_B_STATE = 1; // mst.S_B_STATE = TN_Task.GetStateStr(1); // WCSHelper.UpdateStatus(mst);//更新任务状态 // result = true; // LogHelper.Info($"NDC推送任务成功 {mst.S_CODE}start= {mst.S_START_LOC} + end = {mst.S_END_LOC}"); // } // else { // LogHelper.Info($"NDC推送任务失败 {mst.S_CODE};Res:" + JsonConvert.SerializeObject(res)); // } //} //else if (mst.N_SCHEDULE_TYPE == 5)//通过杭奥调度设备 //{ // //调第三方接口 // var model = new HanAo.TaskInfoModel { // requestPk = mst.S_CODE, // frmPos = mst.S_START_LOC, // toPos = mst.S_END_LOC, // trkType = mst.S_OP_NAME == "入库" ? "1" : "2", // contNo = mst.S_CNTR_CODE // }; // if (HanAo.CreateOrder(model)) { // mst.N_B_STATE = 1; // WCSHelper.UpdateStatus(mst); // LogHelper.Info($"杭奥推送任务成功 {mst.S_CODE};" + "start=" + model.frmPos + "end= " + model.toPos); // } // else { // LogHelper.Info($"杭奥推送任务失败 {mst.S_CODE};" + JsonConvert.SerializeObject(model)); // } //} //else if (mst.N_SCHEDULE_TYPE == 3) //通过国自调度设备 //{ // var code = GZRobot.CreateOrder(mst.S_CODE, mst.N_PRIORITY, JsonConvert.SerializeObject(new { src = mst.S_START_LOC, dst = mst.S_END_LOC }), "p2p"); // if (code > 0) { // //更新任务状态 // mst.N_B_STATE = 1; // mst.S_EQ_TASK_CODE = code.ToString(); // WCSHelper.UpdateStatus(mst); // WCSHelper.UpdateEQNo(mst); // LogHelper.Info($"国自推送任务成功 {mst.S_CODE};" + "start=" + mst.S_START_LOC + "end= " + mst.S_END_LOC); // } // else { // LogHelper.Info($"国自推送任务失败 {mst.S_CODE};" + JsonConvert.SerializeObject(mst)); // } //} } return result; util/LogHelper.cs
@@ -70,15 +70,15 @@ } } #region 自定义方法 public static void InfoEx(Exception ex) { Info($"异常:{ex.Message}"); } // ------------ public static void InfoApi(string taskType, object model) { Info($"触发API:{taskType} " + JsonConvert.SerializeObject(model), "API"); public static void InfoEx(Exception ex) { Info($"发生了异常:{ex.Message}\n{ex.StackTrace}"); } #endregion public static void InfoApi(string apiName, object model) { Info($"触发API:{apiName} " + JsonConvert.SerializeObject(model), "API"); } } util/Settings.cs
@@ -13,9 +13,9 @@ public static string SqlServer { get; set; } public static string TcpServerIp { get; set; } public static int TcpServerPort { get; set; } public static List<Config.Area> Areas { get; set; } public static List<Config.Task> Tasks { get; set; } public static List<Config.ProductionLine> ProductionLines { get; set; } public static List<Config.Area> Areas { get; set; } = new List<Config.Area>(); public static List<Config.Task> Tasks { get; set; } = new List<Config.Task>(); public static List<Config.ProductionLine> ProductionLines { get; set; } = new List<Config.ProductionLine>(); /// <summary> /// 库区字典(加载后就不变) @@ -26,6 +26,8 @@ /// 任务字典(加载后就不变) /// </summary> public static Dictionary<string, Config.Task> TaskMap { get; set; } = new Dictionary<string, Config.Task>(); public static Dictionary<string, int> AgvSite_ProdLineCodeMap { get; set; } = new Dictionary<string, int>(); public static void Init() { // 加载配置文件 @@ -83,6 +85,13 @@ TaskMap.Add(task.Name, task); } } private static void LoadProdLines() { foreach (var prod in ProductionLines) { } } } public class Config { wms/LocationHelper.cs
@@ -131,7 +131,7 @@ /// 你创建任务锁定货位的时候,把锁的来源就是任务号也写上去(加锁的方法加个参数,可空的参数),解锁的时候把来源置空。 /// </summary> /// <param name="loc"></param> /// <param name="lockState">1:入库锁、2:出库锁、2:其它锁</param> /// <param name="lockState">1:入库锁、2:出库锁、3:其它锁</param> /// <param name="lockSource">锁的来源=任务号</param> /// <returns></returns> public static bool LockLoc(ref TN_Location loc, int lockState, string lockSource = "") {