| | |
| | | namespace HH.WCS.Mobox3.DSZSH.core { |
| | | public class WCSCore { |
| | | public static ReturnResult OperateAgvTaskStatus(AgvTaskState model) { |
| | | var result = new ReturnResult(); |
| | | const string preLog = "AGV:任务状态回报:"; |
| | | try { |
| | | if (model.state > 0) { |
| | | // AGV 执行任务的逻辑处理 |
| | | if (!AgvTaskProcessOk(model)) { |
| | | // 执行不OK,说明没有找到任务 |
| | | result.ResultCode = 1; |
| | | result.ResultMsg = $"根据Model.No未找到对应的任务,{model.task_no}"; |
| | | LogHelper.Info(result.ResultMsg, "API"); |
| | | return result; |
| | | return NewReturnResult(1, preLog + $"根据任务号'{model.task_no}'未找到对应的任务!"); |
| | | } |
| | | } |
| | | |
| | | result.ResultCode = 0; |
| | | result.ResultMsg = "success"; |
| | | LogHelper.Info(result.ResultMsg, "API"); |
| | | return result; |
| | | return NewReturnResult(0, "success"); // 不返回详细成功日志,避免NDC以msg=success作为成功判定(参考国自) |
| | | } |
| | | catch (Exception ex) { |
| | | result.ResultCode = -1; |
| | | result.ResultMsg = $"发生了异常:{ex.Message}"; |
| | | LogHelper.Info(result.ResultMsg, "Error"); |
| | | return result; |
| | | return NewReturnResult(-1, $"发生了异常:{ex.Message}\n{ex.StackTrace}"); |
| | | } |
| | | |
| | | } |
| | |
| | | WCSHelper.UpdateStatus(TN_Task, "取货完成"); // 任务状态改成取货完成 |
| | | TaskProcess.OperateStatus(TN_Task, 4); // 起点容器货位解绑,解锁起点 |
| | | |
| | | if (TN_Task.S_TYPE == TaskName.C成品胶出库) { |
| | | if (TN_Task.S_TYPE == ETask.C成品胶出库.Name()) { |
| | | var nextOutboundTask = Task.Run(() => { |
| | | UpdateOutboundTaskState(3); |
| | | }); |
| | |
| | | var cgDetail = new TN_CG_Detail(); // 如果没有信息,默认就是空值,可以直接填入,不需要判断 |
| | | |
| | | //var emptyTask = false; // 空托/空箱任务 |
| | | if (task.S_TYPE != TaskName.H好运箱_空箱上线 && task.S_TYPE != TaskName.H好运箱_空箱入库 && |
| | | task.S_TYPE != TaskName.T托盘_空托上线 && task.S_TYPE != TaskName.T托盘_空托入库) { |
| | | if (task.S_TYPE != ETask.K空托上线出库.Name() && task.S_TYPE != ETask.K空托入库.Name() && |
| | | task.S_TYPE != ETask.K空箱上线出库.Name() && task.S_TYPE != ETask.K空箱入库.Name()) { |
| | | // 非空托/空箱任务(空托/空箱任务无法在CGDetail查到物料信息) |
| | | //emptyTask= true; |
| | | cgDetail = db.Queryable<TN_CG_Detail>() |
| | |
| | | |
| | | var isInbound = false; // 入库类型的任务(包括移库类任务) |
| | | var inboundTasks = new List<string> { |
| | | TaskName.H好运箱_满箱下线入库, TaskName.H好运箱_空箱入库, TaskName.T托盘_满托下线入库, TaskName.T托盘_空托入库, |
| | | TaskName.C抽检_合格回库, TaskName.C抽检_不合格移库, TaskName.Y移库 |
| | | ETask.M满托下线入库.Name(), ETask.M满箱下线入库.Name(), ETask.K空托入库.Name(), ETask.K空箱入库.Name(), |
| | | ETask.C抽检合格回库.Name(), ETask.C抽检不合格移库.Name(), ETask.Y移库.Name() |
| | | }; |
| | | if (inboundTasks.Contains(task.S_TYPE)) { |
| | | isInbound= true; |
| | |
| | | /// <returns></returns> |
| | | public static ReturnResult SafetyInteraction(SafetyInteractionInfo model) { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var info = ""; |
| | | const string preLog = "AGV:产线安全交互:"; |
| | | |
| | | try { |
| | | ModbusHelper.Relink(); |
| | | |
| | | //var loc = db.Queryable<TN_Location>() |
| | | // .Where(l => l.S_AGV_SITE == model.station_name && Settings.AreaMap[AreaName.包装区].Contains(l.S_AREA_CODE)) |
| | | // .First(); |
| | | var BZQ = Settings.GetTaskInfo(ETask.M满托下线入库).StartAreas; |
| | | var loc = db.Queryable<TN_Location>() |
| | | .Where(l => BZQ.Contains(l.S_AREA_CODE) && l.S_AGV_SITE == model.station_name).First(); |
| | | |
| | | if (!Settings.AgvSite_ProdLineCodeMap.TryGetValue(model.station_name, out int prodIndex)) { |
| | | info = $"AGV 站点{model.station_name}不是合法的产线接驳位站点"; |
| | | LogHelper.Info(info); |
| | | return NewReturnResult(1, info); |
| | | if (loc == null) { |
| | | return NewReturnResult(1, preLog + $"AGV 站点{model.station_name}不是合法的产线接驳位站点"); |
| | | } |
| | | |
| | | if (!Settings.LocProdIdMap.TryGetValue(loc.S_CODE, out var prodIndex)) { |
| | | return NewReturnResult(1, preLog + $"AGV 站点{model.station_name}不是合法的产线接驳位站点"); |
| | | } |
| | | |
| | | var prodLineInfo = Settings.ProductionLines[prodIndex]; |
| | | |
| | | var prodLineDevice = new ProductionLineDevice(prodLineInfo); |
| | | if (!prodLineDevice.LoadDeviceStateOk()) { |
| | | info = "与产线设备通讯失败"; |
| | | LogHelper.Info(info); |
| | | return NewReturnResult(2, info); |
| | | return NewReturnResult(2, preLog + "与产线设备通讯失败"); |
| | | } |
| | | |
| | | //var tn_task = db.Queryable<TN_Task>().First(a => a.S_CODE == model.task_no); |
| | |
| | | //} |
| | | |
| | | if (prodLineDevice.SystemState != 1) { |
| | | info = $"当前产线无法与AGV联动:状态{prodLineDevice.SystemState}"; |
| | | LogHelper.Info(info); |
| | | return NewReturnResult(3, info); |
| | | return NewReturnResult(3, preLog + $"当前产线无法与AGV联动:状态{prodLineDevice.SystemState}"); |
| | | } |
| | | |
| | | if (model.apply_code == "5") { // 请求取货 |
| | | // 请求取货 |
| | | if (model.apply_code == "5") { |
| | | if (prodLineDevice.FullOffline != 1) { |
| | | info = $"当前输送线满料下线信号不为1,无法取货"; |
| | | LogHelper.Info(info); |
| | | return NewReturnResult(4, info); |
| | | return NewReturnResult(4, preLog + $"当前输送线满料下线信号不为1,无法取货"); |
| | | } |
| | | |
| | | if (!prodLineDevice.SetAgvPicking(1)) { |
| | | info = $"向输送线写入允许取货信号失败"; |
| | | LogHelper.Info(info); |
| | | return NewReturnResult(5, info); |
| | | return NewReturnResult(5, preLog + $"向输送线写入允许取货信号失败"); |
| | | } |
| | | |
| | | info = $"向输送线写入允许取货信号成功"; |
| | | LogHelper.Info(info); |
| | | return NewReturnResult(0, info); |
| | | return NewReturnResult(0, preLog + $"向输送线写入允许取货信号成功"); |
| | | } |
| | | else if (model.apply_code == "1") { // 请求卸货 |
| | | // 请求卸货 |
| | | else if (model.apply_code == "1") { |
| | | if (prodLineDevice.AllowAgvPlacePallet != 1) { |
| | | info = $"当前输送线允许放托盘信号不为1,无法放货"; |
| | | LogHelper.Info(info); |
| | | return NewReturnResult(6, info); |
| | | return NewReturnResult(6, preLog + $"当前输送线允许放托盘信号不为1,无法放货"); |
| | | } |
| | | |
| | | if (!prodLineDevice.SetAgvPlacingPallet(1)) { |
| | | info = $"向输送线写入允许放货信号失败"; |
| | | LogHelper.Info(info); |
| | | return NewReturnResult(7, info); |
| | | return NewReturnResult(7, preLog + $"向输送线写入允许放货信号失败"); |
| | | } |
| | | |
| | | info = $"向输送线写入允许放货信号成功"; |
| | | LogHelper.Info(info); |
| | | return NewReturnResult(0, info); |
| | | return NewReturnResult(0, preLog + $"向输送线写入允许放货信号成功"); |
| | | } |
| | | else { |
| | | info = $"当前AGV请求码不为 5取货 或 1卸货"; |
| | | LogHelper.Info(info); |
| | | return NewReturnResult(8, info); |
| | | return NewReturnResult(8, preLog + $"当前AGV请求码不为 5取货 或 1卸货"); |
| | | } |
| | | |
| | | } |
| | | catch (Exception ex) { |
| | | info = $"发生了异常:{ex.Message}"; |
| | | LogHelper.InfoEx(ex); |
| | | return NewReturnResult(1, info); |
| | | return NewReturnResult(1, preLog + $"发生了异常:{ex.Message}\n{ex.StackTrace}"); |
| | | } |
| | | } |
| | | |
| | | public static void UpdateOutboundTaskState(int spotStateCode) { |
| | | var taskName = TaskName.C成品胶出库; |
| | | var taskName = ETask.C成品胶出库.Name(); |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | |
| | | var detail = db.Queryable<TN_Outbound_Detail>() |
| | |
| | | model.hwzt = "已出库"; |
| | | |
| | | var jsonInfo = JsonConvert.SerializeObject(model); |
| | | var result = httpH.WebPost(Settings.ErpApiUrl + "PickUpReturn", jsonInfo); |
| | | var result = httpH.WebPost(Settings.ErpApiUrl + Settings.ErpRoute.PickUpReturn, jsonInfo); |
| | | |
| | | LogHelper.InfoApi($"取货完成反馈ERP接口,结果={result},调用参数:", model); |
| | | |
| | |
| | | // TCP 非轮询方式 模拟产线下线的尝试 |
| | | |
| | | public static void StartServer() { |
| | | var ListenPort = 6000; |
| | | var ListenPort = Settings.TcpServerPort; |
| | | TcpListener listener = new TcpListener(IPAddress.Any, ListenPort); |
| | | listener.Start(); |
| | | Console.WriteLine($"后台服务已启动,监听端口 {ListenPort}..."); |
| | |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var info = ""; |
| | | |
| | | const string taskName = TaskName.T托盘_满托下线入库; |
| | | const string startAreaName = AreaName.B包装区; |
| | | const string endAreaName = AreaName.M满托货架区; |
| | | var taskInfo = Settings.GetTaskInfo(ETask.M满托下线入库); |
| | | var taskName = taskInfo.TaskName; |
| | | var startAreas = taskInfo.StartAreas; |
| | | var endAreas = taskInfo.EndAreas; |
| | | const string cntrType = "托盘"; |
| | | |
| | | try { |
| | | var startLoc = db.Queryable<TN_Location>() |
| | | .Where(l => l.S_CODE == startLocCode) |
| | | .Where(l => Settings.AreaMap[startAreaName].Contains(l.S_AREA_CODE)) |
| | | .Where(l => startAreas.Contains(l.S_AREA_CODE)) |
| | | .Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y") |
| | | //.Where(l => l.N_CURRENT_NUM == 0) // 绑定前 |
| | | .First(); |
| | | |
| | | if (startLoc == null) { |
| | | info = $"在'{startAreaName}'中没有找到起点货位'{startLocCode}',或不满足要求:未上锁、当前容器数量=0"; |
| | | info = $"没有找到起点货位'{startLocCode}',或不满足要求:未上锁、当前容器数量=0"; |
| | | LogHelper.Info(info); |
| | | return new Result<bool>(false, info); |
| | | } |
| | |
| | | startLoc.N_CURRENT_NUM = 1; // 绑定后 |
| | | |
| | | var endLoc = db.Queryable<TN_Location>() |
| | | .Where(a => Settings.AreaMap[endAreaName].Contains(a.S_AREA_CODE)) |
| | | .Where(a => endAreas.Contains(a.S_AREA_CODE)) |
| | | .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) |
| | | .First(); |
| | | |
| | | if (endLoc == null) { |
| | | info = $"在终点货区'{endAreaName}'中,没有找到合适的【终点货位】,需要满足要求:未上锁、当前容器数量=0"; |
| | | info = $"没有找到合适的【终点货位】,需要满足要求:未上锁、当前容器数量=0"; |
| | | LogHelper.Info(info); |
| | | return new Result<bool>(false, info); |
| | | } |
| | |
| | | var cntId = locCntrRel.S_CNTR_CODE; |
| | | var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); |
| | | |
| | | LocationHelper.LockStartLoc(ref startLoc); // 起点出库锁 |
| | | LocationHelper.LockEndLoc(ref endLoc); // 终点入库锁 |
| | | WCSHelper.LockStartLoc(ref startLoc); // 起点出库锁 |
| | | WCSHelper.LockEndLoc(ref endLoc); // 终点入库锁 |
| | | |
| | | using (var tran = db.Ado.UseTran()) { |
| | | if (locCntrRelOld != null) { |
| | |
| | | } |
| | | } |
| | | catch (Exception ex) { |
| | | LogHelper.InfoEx(ex); |
| | | return new Result<bool>(false, ex.Message); |
| | | return NewResult(false, ex.Message); |
| | | } |
| | | } |
| | | |
| | | private static Result<bool> NewResult(bool res, string msg, bool log = true) { |
| | | if (log) { LogHelper.Info(msg); } |
| | | return new Result<bool>(res, msg); |
| | | } |
| | | |
| | | } |
| | | |
| | | public class ProductCompletedMessage { |