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;
}
}
}