using HH.WCS.Mobox3.AnGang.Helpers; using HH.WCS.Mobox3.AnGang.Models; using HH.WCS.Mobox3.AnGang.process; using HH.WCS.Mobox3.AnGang.config; using HH.WCS.Mobox3.AnGang.Helper; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using static HH.WCS.Mobox3.AnGang.Dtos.Request.AgvRequest; using static HH.WCS.Mobox3.AnGang.Dtos.Response.AgvResponse; using HH.WCS.Mobox3.AnGang.Consts; using HH.WCS.Mobox3.AnGang.Dispatch; using HH.WCS.Mobox3.AnGang.Devices; namespace HH.WCS.Mobox3.AnGang.Services { public class AgvService { public static ReturnResult OperateAgvTaskStatus(AgvTaskState model) { var result = new ReturnResult(); try { switch (model.state) { case 1023: break; case 1025: break; case 1012: break; case 1004: break; case 1103: break; default: // AGV 执行任务的逻辑处理 if (!AgvTaskProcessOk(model)) { // 执行不OK,说明没有找到任务 result.ResultCode = 1; result.ResultMsg = $"根据Model.No未找到对应的任务,{model.task_no}"; LogHelper.Info(result.ResultMsg, "API"); return result; } break; } result.ResultCode = 0; result.ResultMsg = "success"; LogHelper.Info(result.ResultMsg, "API"); return result; } catch (Exception ex) { result.ResultCode = -1; result.ResultMsg = $"发生了异常:+{ex.Message}"; LogHelper.Info(result.ResultMsg, "Error"); return result; } } /// /// 执行 AGV 任务,查询不到任务返回 /// /// /// internal static bool AgvTaskProcessOk(AgvTaskState model) { var TN_Task = WCSHelper.GetTask(model.task_no); // 根据当前model编号查询任务 if (TN_Task == null) { return false; } if (model.state > 7) { //安全请求等 TaskHelper.OperateReq(model.task_no, model.state, model.forklift_no, model.ext_data); return true; } // AGV 任务 134562(7) 状态处理 switch (model.state) { case AgvStateCode.执行: WCSHelper.Begin(TN_Task, model.forklift_no); // 已推送的任务的状态改成执行 break; case AgvStateCode.开始取货: WCSHelper.UpdateStatus(TN_Task, "开始取货"); // 任务状态改成开始取货 break; case AgvStateCode.取货完成: WCSHelper.UpdateStatus(TN_Task, "取货完成"); // 任务状态改成取货完成 var captureTask = Task.Run(() => { if (TN_Task.S_TYPE == TaskName.货品入库 || TN_Task.S_TYPE == TaskName.产品部分回库) { CapturePic(TN_Task); } }); var setEndLocTask = Task.Run(() => { // 只要任务为产品入库(PDA),就需要重新指定终点(默认endLoc为"") if (TN_Task.S_TYPE == "产品入库(PDA)") { SetEndLoc(TN_Task); } }); TaskHelper.OperateStatus(TN_Task, 4); // 起点容器货位解绑,解锁起点 break; case AgvStateCode.开始卸货: WCSHelper.UpdateStatus(TN_Task, "开始卸货"); // 任务状态改成开始卸货 break; case AgvStateCode.卸货完成: WCSHelper.UpdateStatus(TN_Task, "卸货完成"); // 任务状态改成卸货完成 TaskHelper.OperateStatus(TN_Task, 6); // 终点容器货位绑定,解锁终点 break; case AgvStateCode.完成: WCSHelper.End(TN_Task); // 任务状态改成结束 break; case AgvStateCode.异常: TaskHelper.OperateStatus(TN_Task, 7); // 异常处理 WCSHelper.Fail(TN_Task); // 任务状态改成错误 break; } WCSHelper.AddActionRecord(model.task_no, model.state, model.forklift_no, model.ext_data); //调用第三方接口(如果有)TaskProcess.ReportStatus,添加任务动作关系表 return true; } public static void CapturePic(TN_Task model) { var db = DbHelper.GetDbClient(); var filepath = SnapManager.GetCapturePicturePath(); if (string.IsNullOrEmpty(filepath)) { return; } if (db.Updateable() .SetColumns(d => d.S_IMG_URL == filepath) .Where(d => d.S_CNTR_CODE == model.S_CNTR_CODE).ExecuteCommand() <= 0) { LogHelper.Info($"图片URL '{filepath}' 写入数据库失败"); return; } } public static void SetEndLoc(TN_Task tn_task) { var db = DbHelper.GetDbClient(); var endLoc = new TN_Location(); var data = GZRobot.CustomBuf(); if (data.Count == 0) { LogHelper.Info("设置终点货位失败:没有接受到来自国自AGV的重量信息"); //return; } else { var weight = float.Parse(data[0].parameter_varchar200_up); tn_task.F_WEIGHT = weight; if (db.Updateable(tn_task).UpdateColumns(it => it.F_WEIGHT).ExecuteCommand() <= 0) { LogHelper.Info("修改Task重量失败"); return; } } // 终点货架为空时,不判断,交给人工处理 if (tn_task.S_END_AREA == "") { LogHelper.Info("终点货架为空,不处理"); } // 只当之前指定终点货架后,才尝试计算终点货位 if (tn_task.F_WEIGHT > 1500) { // 重量超过1.5t,需要选择1-3层货架 endLoc = db.Queryable().First(a => a.S_SHELF_CODE == tn_task.S_END_AREA && LocationHelper.IsFree(a) && a.N_CURRENT_NUM == 0 && a.N_LAYER <= 3); } else if (tn_task.F_WEIGHT > 0) { // 重量未超过1.5t,在指定货架随便选择1个 endLoc = db.Queryable().First(a => a.S_SHELF_CODE == tn_task.S_END_AREA && LocationHelper.IsFree(a) && a.N_CURRENT_NUM == 0); } else { // 没有接收到重量,或重量出错 endLoc = null; LogHelper.Info($"错误的重量信息:{tn_task.F_WEIGHT}"); return; } // 如果没有符合条件的货位,置空,等待PDA重新确定 if (endLoc == null) { tn_task.S_END_AREA = ""; tn_task.S_END_LOC = ""; // 不需要再给GZ AGV传空值,一开始就没给具体货位,只给了Area //var request = new UpdateInteractInfo { // interaction_info_id = 3, // 更改终点信息 // info_status = "active", // return_value = "", //}; //GZRobot.UpdateInteractInfo(request); using (var trans = db.Ado.UseTran()) { if (db.Updateable(tn_task).UpdateColumns(it => new { it.S_END_LOC, it.F_WEIGHT }) .ExecuteCommand() > 0) { //LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁 trans.CommitTran(); LogHelper.Info($"重新计算后没有合适货位,任务 {tn_task.S_CODE} 修改成功,修改终点货架和货位为空"); } else { trans.RollbackTran(); LogHelper.Info($"重新计算后没有合适货位,任务 {tn_task.S_CODE} 修改失败,修改终点货架和货位为空"); } } } else { // 找到合适的货位,推送 tn_task.S_END_LOC = endLoc.S_CODE; using (var trans = db.Ado.UseTran()) { if (db.Updateable(tn_task).UpdateColumns(it => new { it.S_END_LOC, it.F_WEIGHT }) .ExecuteCommand() > 0) { LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁 trans.CommitTran(); LogHelper.Info($"计算货位成功,任务 {tn_task.S_CODE} 修改成功,终点货架为 {endLoc.S_SHELF_CODE},修改终点位置为 {endLoc.S_CODE}"); } else { trans.RollbackTran(); LogHelper.Info($"计算货位成功,任务 {tn_task.S_CODE} 修改失败,终点货架为 {endLoc.S_SHELF_CODE},修改终点位置为 {endLoc.S_CODE}"); } } } } public static ReturnResult SafetyInteraction(SafetyInteractionInfo model) { var gzResult = new ReturnResult(); //var db = DbHelper.GetDbClient(); //ModbusHelper.Relink(); //var productionLineInfo = Settings.ProductionLines[0]; //var prodLineDevice = new ProductionLineDevice(productionLineInfo.PlcIp, productionLineInfo.PlcPort); //if (!prodLineDevice.LoadDeviceStateOk()) { // LogHelper.Info("加载设备信息失败"); //} //var tn_task = db.Queryable().First(a => a.S_CODE == model.task_no); //if (tn_task == null) { // LogHelper.Info($"任务号 '{model.task_no}' 不存在"); //} //if (prodLineDevice.SystemState == 1 // && prodLineDevice.FullOffline == 1 && tn_task.S_TYPE == "成品胶下线-托盘(WMS)") { // if (!prodLineDevice.SetAgvPicking(1)) { // LogHelper.Info("写入输送线 PLC 失败"); // } //} //if (prodLineDevice.SystemState == 1 // && prodLineDevice.AllowAgvPlacePallet == 1 && tn_task.S_TYPE == "空托盘上线(WMS)") { // if (!prodLineDevice.SetAgvPlacingPallet(1)) { // LogHelper.Info("写入输送线 PLC 失败"); // } //} //LogHelper.Info(JsonConvert.SerializeObject(prodLineDevice, Formatting.Indented)); return gzResult; } } }